refactor(workflow): simplify extraction + thread runtime contract #132

Merged
xiaoju merged 4 commits from refactor/thread-context-runtime into main 2026-05-08 09:34:26 +00:00
Owner

背景

这一波是围绕 workflow 运行时契约做的连续重构,目标是:

  1. 把 ReAct 抽取细节收敛到 ExtractFn 背后,避免在 engine/options 暴露多余配置。
  2. WorkflowFn 直接消费完整 thread 运行态(ThreadContext),由 engine 统一构造,消除 ThreadInput + WorkflowFnOptions 的双入参拆分。
  3. 让 workflow-template 只负责导出 WorkflowDefinition,实例化绑定留在实例层。

主要改造内容

1) 抽取链路统一到 ExtractFn

  • createExtract() 统一走 reactExtract(),不再走单独的 single extract 分支。
  • reactExtract 增加 plain-JSON schema 失败后的 correction 重试路径。
  • 删除 WorkflowFnOptions.llmProvider,provider 仅保留在 createExtract 闭包。
  • 删除 extractMode / ResolveRoleMetaFn 相关路径,runtime 直接调用 runtime.extract(...)

2) WorkflowFn 契约改为 ThreadContext + WorkflowRuntime

  • 删除 ThreadInputWorkflowFnOptions
  • 新增 WorkflowRuntimecas + extract)。
  • WorkflowFn(input, options) 改为 (thread, runtime)
  • ThreadContext 改为完整 thread 状态:
    • threadId
    • depth
    • start
    • steps
  • ModeratorContext 直接基于该 ThreadContext

3) engine 侧统一构造 thread 运行态

  • executeThread 内统一构造 ThreadContext
    • 用启动记录生成 start
    • 用历史 steps(含 prefilled timestamp)生成 steps
  • runtime loop 不再二次拼装 start/steps,只消费完整 thread。

4) template 边界收敛

  • workflow-template-develop / workflow-template-solve-issue 移除 create*Run
  • template 包仅导出 WorkflowDefinition(纯定义层)。
  • README 与对应测试同步更新为实例层显式 createWorkflow(definition, binding)

5) 测试与文档同步

  • 更新 workflow-as-agent 相关测试内置 bundle 的 run 签名。
  • 更新 workflow-util-agent / workflow-agent-llm 对上下文类型的使用。
  • 更新 CLI init 文档提示中的 runtime 类型名。
  • 新增 template 测试覆盖 tool_calls 提取路径,避免仅覆盖 plain-JSON 短路分支。

Breaking Changes

A. createSolveIssueRun / createDevelopRun 已删除

迁移方式:在实例层显式绑定。

import { createWorkflow } from "@uncaged/workflow";
import { solveIssueWorkflowDefinition } from "@uncaged/workflow-template-solve-issue";

const run = createWorkflow(solveIssueWorkflowDefinition, binding);

B. WorkflowFn 签名变化

旧:

run(input, options)

新:

run(thread, runtime)

同时 ThreadInputWorkflowFnOptions 删除,改为 ThreadContextWorkflowRuntime

涉及提交

  • 56ff7bc refactor(workflow): unify extraction behind ExtractFn
  • 709961b refactor(workflow-runtime): use full ThreadContext in WorkflowFn

验证

  • bun test 全量通过:261 pass / 0 fail
  • 针对本次 review 补充验证:
    • bun test packages/workflow-template-solve-issue/__tests__/solve-issue-template.test.ts packages/workflow/__tests__/react-extract.test.ts
## 背景 这一波是围绕 workflow 运行时契约做的连续重构,目标是: 1. 把 ReAct 抽取细节收敛到 `ExtractFn` 背后,避免在 engine/options 暴露多余配置。 2. 让 `WorkflowFn` 直接消费完整 thread 运行态(`ThreadContext`),由 engine 统一构造,消除 `ThreadInput + WorkflowFnOptions` 的双入参拆分。 3. 让 workflow-template 只负责导出 `WorkflowDefinition`,实例化绑定留在实例层。 ## 主要改造内容 ### 1) 抽取链路统一到 `ExtractFn` - `createExtract()` 统一走 `reactExtract()`,不再走单独的 single extract 分支。 - `reactExtract` 增加 plain-JSON schema 失败后的 correction 重试路径。 - 删除 `WorkflowFnOptions.llmProvider`,provider 仅保留在 `createExtract` 闭包。 - 删除 `extractMode` / `ResolveRoleMetaFn` 相关路径,runtime 直接调用 `runtime.extract(...)`。 ### 2) WorkflowFn 契约改为 `ThreadContext + WorkflowRuntime` - 删除 `ThreadInput` 与 `WorkflowFnOptions`。 - 新增 `WorkflowRuntime`(`cas` + `extract`)。 - `WorkflowFn` 由 `(input, options)` 改为 `(thread, runtime)`。 - `ThreadContext` 改为完整 thread 状态: - `threadId` - `depth` - `start` - `steps` - `ModeratorContext` 直接基于该 `ThreadContext`。 ### 3) engine 侧统一构造 thread 运行态 - 在 `executeThread` 内统一构造 `ThreadContext`: - 用启动记录生成 `start` - 用历史 steps(含 prefilled timestamp)生成 `steps` - runtime loop 不再二次拼装 start/steps,只消费完整 thread。 ### 4) template 边界收敛 - `workflow-template-develop` / `workflow-template-solve-issue` 移除 `create*Run`。 - template 包仅导出 `WorkflowDefinition`(纯定义层)。 - README 与对应测试同步更新为实例层显式 `createWorkflow(definition, binding)`。 ### 5) 测试与文档同步 - 更新 workflow-as-agent 相关测试内置 bundle 的 `run` 签名。 - 更新 workflow-util-agent / workflow-agent-llm 对上下文类型的使用。 - 更新 CLI init 文档提示中的 runtime 类型名。 - 新增 template 测试覆盖 `tool_calls` 提取路径,避免仅覆盖 plain-JSON 短路分支。 ## Breaking Changes ### A. `createSolveIssueRun` / `createDevelopRun` 已删除 迁移方式:在实例层显式绑定。 ```ts import { createWorkflow } from "@uncaged/workflow"; import { solveIssueWorkflowDefinition } from "@uncaged/workflow-template-solve-issue"; const run = createWorkflow(solveIssueWorkflowDefinition, binding); ``` ### B. `WorkflowFn` 签名变化 旧: ```ts run(input, options) ``` 新: ```ts run(thread, runtime) ``` 同时 `ThreadInput` 与 `WorkflowFnOptions` 删除,改为 `ThreadContext` 与 `WorkflowRuntime`。 ## 涉及提交 - `56ff7bc` refactor(workflow): unify extraction behind ExtractFn - `709961b` refactor(workflow-runtime): use full ThreadContext in WorkflowFn ## 验证 - `bun test` 全量通过:`261 pass / 0 fail` - 针对本次 review 补充验证: - `bun test packages/workflow-template-solve-issue/__tests__/solve-issue-template.test.ts packages/workflow/__tests__/react-extract.test.ts`
scottwei added 2 commits 2026-05-08 09:00:58 +00:00
Route createExtract through reactExtract with plain-JSON correction retry.

Remove WorkflowFnOptions.llmProvider, ExtractMode, RoleDefinition.extractMode, ResolveRoleMetaFn.

Runtime createWorkflow calls options.extract directly; engine passes extract only.

Update templates, CLI skill docs, and tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Redefine WorkflowFn to accept a complete ThreadContext plus WorkflowRuntime dependencies, removing ThreadInput and WorkflowFnOptions.

Move thread context construction into engine executeThread, update runtime loop/agent paths, and align templates/docs/tests with template-only definition exports.

Co-authored-by: Cursor <cursoragent@cursor.com>
Owner

Code Review — PR #132

Looks Good

  • WorkflowFn 契约(ThreadInput, WorkflowFnOptions)(ThreadContext, WorkflowRuntime) 改得干净
  • createWorkflow (runtime) — 零 I/O import,纯编排
  • Engine 构造 ThreadContext — start/steps 组装正确,WorkflowRuntime 注入 cas + extract
  • Extract 统一extractMode 彻底删除,reactExtract 覆盖原 single 路径
  • Template 简化 — 只导出 WorkflowDefinition
  • Convention 合规 — 无 ?: / interface / class / console.log

⚠️ Warnings

  1. llmExtractWithRetry 变成死代码 — 还在导出但没有生产调用了,应标记废弃或删除
  2. createSolveIssueRun 删除后的迁移 — 原来自动接 workflowAsAgent("develop") 的逻辑没了,消费方需要手动接线,PR body 里没提这个 breaking change

💡 Suggestions

  • putContentBlob 只是 store.put(raw) 的包装,可以直接内联
  • as unknown as 双重 cast 有 3 处,考虑让内部函数泛型无关来消除
  • 测试 mock 现在只走 JSON 短路路径,考虑保留至少一个 tool_calls 提取测试

🔴 Critical

—— 小橘 🍊(NEKO Team)


更新:移除了关于 dashboard 包的 warning,那是 main 上已有的代码,不属于本 PR。

## Code Review — PR #132 ### ✅ Looks Good - **WorkflowFn 契约** — `(ThreadInput, WorkflowFnOptions)` → `(ThreadContext, WorkflowRuntime)` 改得干净 - **createWorkflow (runtime)** — 零 I/O import,纯编排 ✅ - **Engine 构造 ThreadContext** — start/steps 组装正确,WorkflowRuntime 注入 cas + extract ✅ - **Extract 统一** — `extractMode` 彻底删除,`reactExtract` 覆盖原 single 路径 ✅ - **Template 简化** — 只导出 WorkflowDefinition ✅ - **Convention 合规** — 无 `?:` / `interface` / `class` / `console.log` ✅ ### ⚠️ Warnings 1. **`llmExtractWithRetry` 变成死代码** — 还在导出但没有生产调用了,应标记废弃或删除 2. **`createSolveIssueRun` 删除后的迁移** — 原来自动接 `workflowAsAgent("develop")` 的逻辑没了,消费方需要手动接线,PR body 里没提这个 breaking change ### 💡 Suggestions - `putContentBlob` 只是 `store.put(raw)` 的包装,可以直接内联 - `as unknown as` 双重 cast 有 3 处,考虑让内部函数泛型无关来消除 - 测试 mock 现在只走 JSON 短路路径,考虑保留至少一个 tool_calls 提取测试 ### 🔴 Critical **无** —— 小橘 🍊(NEKO Team) --- *更新:移除了关于 dashboard 包的 warning,那是 main 上已有的代码,不属于本 PR。*
xingyue force-pushed refactor/thread-context-runtime from 709961b923 to a11cc62a81 2026-05-08 09:08:10 +00:00 Compare
xingyue added 1 commit 2026-05-08 09:10:41 +00:00
Drop unused llmExtractWithRetry implementation and public exports.

Add solve-issue template coverage for tool_calls extraction path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Author
Owner

根据 review 已补充修改:

  1. 已移除 llmExtractWithRetry 的实现与公开导出(extract/index.tsworkflow/src/index.ts 同步清理)。
  2. PR 描述已补充 breaking changes 与迁移方式,明确说明 createSolveIssueRun/createDevelopRun 删除后的实例层写法。
  3. 已新增 tool_calls 提取路径测试(workflow-template-solve-issue/__tests__/solve-issue-template.test.ts),避免只覆盖 plain-JSON 短路分支。

新增提交:884ff85

根据 review 已补充修改: 1) 已移除 `llmExtractWithRetry` 的实现与公开导出(`extract/index.ts`、`workflow/src/index.ts` 同步清理)。 2) PR 描述已补充 breaking changes 与迁移方式,明确说明 `createSolveIssueRun/createDevelopRun` 删除后的实例层写法。 3) 已新增 `tool_calls` 提取路径测试(`workflow-template-solve-issue/__tests__/solve-issue-template.test.ts`),避免只覆盖 plain-JSON 短路分支。 新增提交:`884ff85`
Author
Owner

已按review修改:1) 删除 llmExtractWithRetry 实现与公开导出;2) PR描述补充 breaking changes 与迁移方式;3) 新增 tool_calls 提取路径测试。新增提交: 884ff85

已按review修改:1) 删除 llmExtractWithRetry 实现与公开导出;2) PR描述补充 breaking changes 与迁移方式;3) 新增 tool_calls 提取路径测试。新增提交: 884ff85
Author
Owner

已按review修改:1) 删除 llmExtractWithRetry 实现与公开导出;2) PR描述补充 breaking changes 与迁移方式;3) 新增 tool_calls 提取路径测试。新增提交: 884ff85

已按review修改:1) 删除 llmExtractWithRetry 实现与公开导出;2) PR描述补充 breaking changes 与迁移方式;3) 新增 tool_calls 提取路径测试。新增提交: 884ff85
xingyue added 1 commit 2026-05-08 09:30:19 +00:00
Move CAS access into extract dependencies so AgentContext stays state-only, and clean up type/lint/check regressions across CLI/dashboard to keep full check green.

Co-authored-by: Cursor <cursoragent@cursor.com>
xiaoju merged commit c65c29c1b5 into main 2026-05-08 09:34:26 +00:00
Sign in to join this conversation.
No Reviewers
No Label
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#132