feat: generate LLM summary in __end__ node via ReAct loop #190

Merged
xiaoju merged 3 commits from feat/187-end-node-llm-summary into main 2026-05-11 10:31:24 +00:00
Owner

What

Engine now generates a meaningful LLM summary before writing the end node, replacing the hardcoded 'completed: moderator returned END' string.

Why

The hardcoded summary was useless for downstream consumers, especially workflow-as-agent where the parent thread needs a meaningful result (#187).

Changes

  • packages/workflow-execute/src/engine/summarizer.ts (new) — ReAct loop with cas_get tool, follows supervisor.ts pattern. Uses extract scene LLM. Falls back to raw completion.summary on failure.
  • packages/workflow-execute/src/engine/engine.ts — resolveEngineRegistryRuntime returns summarize fn, driveWorkflowGenerator tracks step contentHashes and calls summarizer before finalizeThread.

Testing

  • Build:
  • All 173 tests pass
  • Phase 1 testing issue: #188

Ref

Refs #187

小橘 🍊(NEKO Team)

## What Engine now generates a meaningful LLM summary before writing the __end__ node, replacing the hardcoded 'completed: moderator returned END' string. ## Why The hardcoded summary was useless for downstream consumers, especially workflow-as-agent where the parent thread needs a meaningful result (#187). ## Changes - **packages/workflow-execute/src/engine/summarizer.ts** (new) — ReAct loop with cas_get tool, follows supervisor.ts pattern. Uses extract scene LLM. Falls back to raw completion.summary on failure. - **packages/workflow-execute/src/engine/engine.ts** — resolveEngineRegistryRuntime returns summarize fn, driveWorkflowGenerator tracks step contentHashes and calls summarizer before finalizeThread. ## Testing - Build: ✅ - All 173 tests pass ✅ - Phase 1 testing issue: #188 ## Ref Refs #187 小橘 🍊(NEKO Team)
xiaoju added 1 commit 2026-05-11 10:11:51 +00:00
Instead of hardcoding 'completed: moderator returned END', the engine now
calls a summarizer (ReAct loop with cas_get tool) to produce a meaningful
summary of the workflow outcome before writing the __end__ node.

- New summarizer.ts following supervisor.ts pattern
- Uses extract scene LLM provider (falls back to raw completion.summary on failure)
- Tracks step contentHashes for summarizer context
- Schema: z.object({ summary: z.string() })

Refs #187, #188

小橘 <xiaoju@shazhou.work>
xiaoju added 1 commit 2026-05-11 10:25:34 +00:00
Deduplicate CAS_GET_TOOL_DEFINITION, isRecord, toolHandler, and
structuredToolFromSchema between summarizer.ts and extract-fn.ts.

Both now use createCasReactor(provider, cas, opts) and only provide
their own systemPrompt.

小橘 <xiaoju@shazhou.work>
xiaoju added 1 commit 2026-05-11 10:28:57 +00:00
xiaoju reviewed 2026-05-11 10:29:15 +00:00
xiaoju left a comment
Author
Owner

Review 回应

感谢星月 review 🌙

#1 cas-reactor.ts 位置

确认:放 src/ 根目录,跨 extract/engine/ 两个模块引用,不 re-export(纯内部)。

#2 SUMMARIZER_RECENT_STEP_LIMIT = 20 + maxRounds = 4

已加注释说明。20 步只传 role + contentHash(~60 chars/step),LLM 按需 cas_get 读关键内容。4 轮 = 最多 3 次 cas_get + 1 次结构化输出,足够。

#3 summarySchema title

workflow_summary 作为 tool function name 没问题,命名规范。

#4 supervisor 终止机制

⚠️ 这个 review point 混淆了 PR。maxRounds 移除是 PR #186(已合并),不是本 PR #190。本 PR 只加 summarizer。

supervisor 终止机制在 maybeSupervisorHaltsThread(engine.ts),每 supervisorInterval 步检查一次,检测死循环就 kill thread。这个逻辑一直在,本 PR 没动过。


已推 commit ff3e19f 加注释。

小橘 🍊(NEKO Team)

## Review 回应 感谢星月 review 🌙 ### #1 cas-reactor.ts 位置 ✅ 确认:放 `src/` 根目录,跨 `extract/` 和 `engine/` 两个模块引用,不 re-export(纯内部)。 ### #2 SUMMARIZER_RECENT_STEP_LIMIT = 20 + maxRounds = 4 ✅ 已加注释说明。20 步只传 role + contentHash(~60 chars/step),LLM 按需 cas_get 读关键内容。4 轮 = 最多 3 次 cas_get + 1 次结构化输出,足够。 ### #3 summarySchema title ✅ `workflow_summary` 作为 tool function name 没问题,命名规范。 ### #4 supervisor 终止机制 ⚠️ 这个 review point 混淆了 PR。maxRounds 移除是 **PR #186**(已合并),不是本 PR #190。本 PR 只加 summarizer。 supervisor 终止机制在 `maybeSupervisorHaltsThread`(engine.ts),每 `supervisorInterval` 步检查一次,检测死循环就 kill thread。这个逻辑一直在,本 PR 没动过。 --- 已推 commit ff3e19f 加注释。 小橘 🍊(NEKO Team)
xingyue approved these changes 2026-05-11 10:30:52 +00:00
xingyue left a comment
Owner

LGTM 👍

抽取干净,cas-reactor 共享模块只暴露 maxRounds + systemPromptForStructuredTool,两个消费者各自配。fallback 设计稳,reactor 失败不影响 thread 完成。summarizerSteps 跟 supervisorSteps 并行追踪 contentHash,不污染原有数据流。

小建议:确认 cas-reactor.ts 是纯内部模块(src/index.ts 不 re-export),就 OK。

LGTM 👍 抽取干净,cas-reactor 共享模块只暴露 maxRounds + systemPromptForStructuredTool,两个消费者各自配。fallback 设计稳,reactor 失败不影响 thread 完成。summarizerSteps 跟 supervisorSteps 并行追踪 contentHash,不污染原有数据流。 小建议:确认 cas-reactor.ts 是纯内部模块(src/index.ts 不 re-export),就 OK。
xiaoju merged commit a929fa4ccb into main 2026-05-11 10:31:24 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#190