状态(2026-07-25):三 Runtime 的结构化失败、工具继承、durable lifecycle 与共享 workflow dependency compiler 均为
Code complete/ targetedTests pass;durable-evidence 的 404/5xx 恢复、Codex route preflight、queued Stop durable cancelled、父 Stop 与 dependency taxonomy 已收口。真实 Qwen → DeepSeek → Kimi 依赖链、Provider 路由与长任务切换聊天复测留给用户 / Claude。 产品取舍见 insights,执行状态见 active plan,事实基线见 research。
| Runtime | 子 Agent 模型选择 | 当前实现 | 事实边界 |
|---|---|---|---|
| CodePilot Runtime | ✅ 同 Runtime、显式 Provider+Model | Native Agent tool 从全量 CodePilot-compatible catalog 选择精确 route;目标 Provider 贯穿 child 工具与模型调用;独立 child session |
真实凭据 smoke 待用户复测 |
| Claude Code Runtime | ✅ 同 Runtime、显式 Provider+Model | codepilot_spawn_subagent 启动独立 Claude SDK 子进程;route 与 Claude Code 模型选择器未置灰集合一致 |
Kimi/GLM/DeepSeek 等可用;Grok/xAI 等置灰模型不进入 route 并明确失败,不回退 Sonnet |
| Codex Runtime(CodePilot Provider) | ✅ 同 Runtime、显式 Provider+Model | proxy bridge 的 codepilot_spawn_subagent 新建独立 app-server child thread,写入目标 Provider+Model,并继承父 sandbox/approval/MCP |
depth 1;真实凭据 smoke 待复测 |
| Codex Runtime(Codex Account) | collabAgentToolCall 进入统一卡片,使用 app-server 原生协作 |
不经过 CodePilot Provider proxy,不宣称可跨到任意 CodePilot Provider |
跨 Runtime Broker、background 与独立 child cancel 不在本版。三条 managed Runtime 的 physical child 都写入 subagent_runs,同一用户任务通过 logical_run_id 聚合 attempt;subagent_run_events 保存 typed lifecycle,Codex 还用最新 attempt 提供跨回合进展查询。
进程拓扑并不统一:Claude managed child 每次通过 Agent SDK query() 启动独立 Claude Code OS 子进程(含隔离 shadow HOME);CodePilot Runtime child 在当前 Next/Electron server 进程内运行独立 runAgentLoop,不是 OS 子进程;Codex managed child 复用既有 app-server 进程/连接,只新建隔离 thread,也不是每个 child 新 spawn 一个 OS 进程。
flowchart LR
P["父 Agent:当前会话 Runtime / Provider / Model"] --> A["同 Runtime delegate"]
A --> V["Runtime catalog 的 Provider+Model 精确校验"]
V --> W["共享 workflow 调度:durable row + dependency edges"]
W -->|"无依赖"| C["独立 child session,继承父工具/权限,depth 1"]
W -->|"有依赖"| Q["queued:等待上游 durable terminal"]
Q --> H["共享 handoff compiler 注入上游真实结果"]
H --> C
C --> R["tool_result / collab completion"]
R --> D["settling → durable terminal"]
D --> M["聊天内 SubagentCard"]
M --> S["Workspace Sidebar agent-run tab"]
父会话路由不变。CodePilot Runtime child 调用使用 delegated_interactive scene;interactive-only Provider 因而可以审计 delegation,但 background/scheduled 无法借道。
src/lib/subagent-orchestration.ts是唯一依赖语义层。Claude MCP、Native Agent tool 和 Codex builtin bridge 都只负责路由/启动,把workflow_id + task_key + depends_on交给同一个 validator、resolver 和 prompt compiler。subagent_runs保存workflow_id/task_key/dependencies_json/dispatch_state。下游调用可以先被接受为queued,但在上游completed前不会占用 Runtime 并发位、不会调用目标 Provider;上游失败、缺失、结果为空或持久化 ownership 丢失时直接结构化失败。- resolver 读取同一 parent session / workflow 下的最新 durable attempt;上游结果只在 child 真正执行前编译进 prompt,并显式标为不可信 task data。父模型同一批次预生成的占位 prompt 不再决定最终输入。
- 父模型应按拓扑顺序先发 upstream tool call。为兼容并行 tool handler,缺失上游有 5 秒 durable-row 创建宽限;宽限后返回
DEPENDENCY_NOT_FOUND,不会让串行 Runtime 因 dependent-first 顺序阻塞三十分钟。 - task key 重复、自依赖和间接循环均在插入/启动前拒绝;没有声明 dependency 却要求 child “等待/待命”的 prompt 返回
DEPENDENCY_DECLARATION_REQUIRED,不能创建 placeholder worker。 - malformed input 等没有成功创建 durable row 的调用不是 Agent run。生产
MessageItem/StreamingMessage传入的 transcript view 也不是持久化证据;SubagentCard只有在 details API 返回 200 后才显示 managed 胶囊。Codex 初始 route 不存在时在startSubagentRun前拒绝,不占 task key;已接受后 route 被移除等执行期失败才按 durable attempt 展示。 - 上游从未创建返回
DEPENDENCY_NOT_FOUND;上游存在但 deadline 前未终止返回DEPENDENCY_TIMEOUT。二者都不启动下游 Provider。 - 这是有向无环依赖的最小产品层,不引入 ADK/LangGraph/AutoGen 运行时依赖。条件分支、循环和跨 Runtime Broker 仍是后续能力;same-runtime 三个 Adapter 不再各自维护等待/结果传递状态机。
src/lib/subagent-models.ts从全部 Provider resolver 生成 CodePilot-compatible route;每条 route 都包含精确providerId + modelId,不会用sonnet之类的跨厂商重复 alias 猜 Provider。src/lib/tools/agent.ts的命名模型 input 必须同时给出provider_id + model;省略两者才继承父路由。任意未启用 pair 返回SUBAGENT_MODEL_UNAVAILABLE。- child 的
assembleTools与runAgentLoop都使用目标 Provider,而非父 Provider。Native SSE error 会归一化 401/403、429、timeout 与 model unavailable,不再把错误当成空成功。 - child 使用 UUID session、独立 AbortController,父 abort 向下传播;每个父 session 并发上限 2。
- 启动 child 前先写
subagent_runs.running;显式 retry 复用 logical id 并生成递增 attempt。child 停止后先写 settling,completed/failed/partial/cancelled/timed_out 的 structured result/provenance 与 terminal event 只收口一次;父 session 或 durable run 无法创建时 fail closed,不调用目标 Provider。 - child 重新装配目标 Provider 下的完整工具 surface;普通 profile 沿用 parent permission wrapper,full access 仅在父会话明确选择时透传。
Agent/codepilot_spawn_subagent被硬移除,所以 depth 固定为 1。 - 结果头包含
Sub-agent / Model / Runbreadcrumb;subagent-view.ts解析后从用户可见 result 中剥离。该 model 是 Native 真正传给runAgentLoop的 canonical ID。
src/lib/claude-subagent-mcp.ts从所有 Provider resolver 读取 enabled catalog,再用getModelCompat(...).supportedRuntimes生成与 picker 未置灰语义一致的 route list;每条 route 是 server-verifiedprovider_id + model。- 父 query 注册 in-process
codepilot_spawn_subagent。handler 二次校验 exact route,使用delegated_interactive解析目标 Provider,创建独立 shadow HOME/凭据环境和 Claude SDK subprocess。 - child 继承父 query 的 Claude built-ins、显式 MCP、permissionMode、allowed/disallowedTools 与
canUseTool;WebSearch/WebFetch、文件/Shell 因而遵循父会话原生能力和审批。只移除 Agent/Task 保持 depth 1;maxTurns 30、每父 session 并发 2。timeout 是五分钟无 SDK activity 的 idle deadline(每条 message 续期)加三十分钟不可续期 hard cap,父 abort 向下传播。 - 每次 managed tool 调用是 one-shot foreground run,不能先启动 placeholder/stand-by child,也不能 resume/steer。依赖任务必须等输入完整后调用一次;重试会产生新的可审计物理 run。
- managed call 是 blocking foreground:tool result 只在 child 到达 completed/failed/partial/cancelled/timed_out 后返回,并带
terminal=true。父模型不得把返回值描述成“已提交、后台处理中”;依赖 child 必须立即消费上一条 terminal output。 - route list 只证明 catalog-compatible,不证明当前账号 entitlement。SDK terminal 必须同时检查
is_error和api_error_status;subtype=success但is_error=true(用户实测 403)仍是 failed。maxTurns / timeout 分别映射为 partial / timed_out。 - 不再自动注入
codepilot-readonly或 model-pinned AgentDefinition,也不显示“继承主 Agent”。Claude 原生 Agent/Task 不能切 Provider,只保留原生用途与 prompt-level 冒充门禁。 - tool use transcript 由 server route enrichment 写入真实 display model/provider;terminal metadata 取 child SDK init 上报的 effective model(拿不到则保留 verified requested route),不会把 SDK 的
sonnetrole slot冒充 Kimi/Grok。 - Grok/xAI 当前不兼容 Claude Code,因此不进入 route list;父模型被明确要求返回
SUBAGENT_MODEL_UNAVAILABLE并询问改用可用模型或切 Runtime。即使模型编造 route,handler 也 fail closed。 - 每次 managed subprocess 同样在调用 SDK 前创建 durable run,并以真实终态收口;assistant 部分正文/effective model 在 running 阶段以 64 KiB 上限 checkpoint,timeout/cancel 会把已有正文带入终态,terminal 后迟到 checkpoint 不可覆盖。这张表补足 chat tool block 尚未写入或页面暂时 detach 时的独立生命周期事实。
- research/事实 task 要求 source URL 与 claim 同传;child 不得从训练知识补写精确数字/日期/引语。child 失败后父 Agent 可以用自身真实工具接管,但必须明确标注执行归属,不能让失败 child 冒领父产物。
src/lib/codex/event-mapper.ts把collabAgentToolCall映射为codex_subagent的tool_started / tool_completed。- 对使用 CodePilot 配置 Provider 的 Codex 会话,
src/lib/codex/proxy/builtin-bridge.ts注册codepilot_spawn_subagent;handler 校验 Codex-compatible exact route,src/lib/codex/subagent.ts通过独立thread/start写入目标 Provider+Model,再执行 one-shot turn。 - app-server 连接会复用,但父
CodexRuntime与 child collector 都按 thread ID 过滤通知;child turn 的 delta/terminal 不会串进父正文或提前关闭父 stream。 - managed child thread 继承父 Codex permission wire、Codex 原生工具与全部 MCP 配置;CodePilot 不再要求父模型声明
required_capabilities,也不按联网/写入/Shell 维护第二套工具白名单。canonical Codex permission wire 对 readOnly/workspaceWrite 显式发送networkAccess:true,因此 Qwen 等没有 hosted search 的第三方 Provider仍可使用 Codex 原生 Shell/Fetch 联网;写入 sandbox 与 approval/reviewer 语义不变。dynamic MCP 调用经mcpServer/tool/call交回 Codex MCP manager。CodePilot builtin bridge 在 child 内只移除递归 spawn,以保持 depth 1。 - proxy 内部执行完的 bridge/hosted tool 会从 Codex-bound function-call stream 抑制,尤其
codepilot_spawn_subagent不会再次回传 app-server 形成unsupported call。目标 SDK 为 xAI、OpenAI Responses 或官方 Anthropic 时,app-server 的web_search描述会翻译为真实 hosted search(xAI 同时提供x_search);其他 Provider 仍可使用 Codex 原生工具或继承的 MCP。 - bridge suppression 意味着 function_call/tool-result 不进入 Codex thread,因此不能再把瞬时 side-channel 当作跨回合事实源。
codepilot_spawn_subagent现在在调用 child 前写入subagent_runs.running,以 side-channel toolId 作为 durable runId;completed/partial/failed/cancelled/timed_out 只允许第一次原子收口。持久化创建失败时 child 不启动,避免不可审计任务。 - 每个后续 Codex proxy 回合都会按 logical run 注入最新 attempt 的 lifecycle-only snapshot(不含 prompt/result,避免把 child/外部内容升格成 system instructions);模型另有只读
codepilot_list_subagent_runs可按需查询最新 attempt 的 prompt/result 摘要。状态来源固定为sqlite.subagent_runs,不得从update_plan、旧正文、耗时或工作区文件推断;详情 API 才展开全部 attempts/events。 - app-server 的
turn.status=completed只表示 child 回合正常结束,不再直接等同任务成功。child final answer 首行使用__CODEPILOT_SUBAGENT_OUTCOME__声明 completed/partial/failed,normalizer 删除该内部标记后再写 durable terminal;旧 child 没有 marker 但明确写“无法完成此任务”时进入 failed。若 marker 声称 completed 而正文明确失败,同样 fail closed。 - Codex Account 绕过 CodePilot Provider proxy,因此仍只展示原生 app-server 实际上报的 collab/model;不能用 managed bridge 跨到任意 CodePilot Provider。
- 无模板 spawn 默认继承父工具与权限;模板可进一步收窄。普通 profile 的写入/Shell 仍需父审批,不能因换模型绕过。
- permission DB row 继续使用真实 parent chat session(满足 FK);SSE 额外携带
agentRunId / childSessionId,批准/拒绝仍由唯一 permissionRequestId 定向。 ProviderCallScene新增delegated_interactive,并被 interactive-only policy 明确列为 allowed;Agent tool 本身只允许interactive_chat父调用。- 页面切换、刷新或 renderer fetch 断开只 detach,不再触发 Runtime abort;server collector 继续执行并持久化。显式 Stop 通过
/api/chat/interrupt取消父回合并向 child 传播;本版没有单独“取消某一个 child”按钮。 - Codex 把父聊天 turn 的 AbortSignal 存入进程级 parent context,dependency wait 与
runCodexSubagent使用同一个组合信号;proxy transport signal 只作 fallback,因此 Stop 在 child queued 时也能取消,而不会等待依赖 deadline。组合优先使用原生AbortSignal.any,Node 18 开发环境没有该 API 时走清理 listener 的兼容实现。
MessageItem与StreamingMessage都把 Agent / Task / managed MCP /codex_subagent从ToolActionsGroup分流为常驻SubagentCard。- 卡片左侧按 model family 使用 LobeHub 品牌图标(Kimi / Zhipu GLM / xAI Grok / DeepSeek / Qwen / MiniMax / MiMo / Doubao / Anthropic / OpenAI);未知模型才退回通用 model icon。
- 卡片不再展示无操作价值的 Runtime 胶囊;Runtime 事实保留在详情面板。
- 卡片渲染在父 Agent 正文与 streaming 状态之后,随输出向下滚动,不固定在回复顶部。
- 主聊天使用单行胶囊:模型图标 → Agent 名称 → 状态 → 详情 → 可选模型名;不展示提示词,不产生第二行,多个 child 可在一行并自动换行。
- requested 与 effective 分开;没有模型事实时不再显示“继承主 Agent”,详情标为 Runtime 未报告。
- 状态不再使用“任意非错误 tool_result = completed”兜底:managed plain receipt 与显式 background input 保持 running;CodePilot terminal envelope 或 Codex collab payload.status 才能进入终态。Codex managed child 还会把“回合结束”与“任务成功”分开归一。
- “详情”在 running 与 terminal 都显示,打开 Workspace Sidebar 的
agent-run:<toolUseId>tab。新会话创建 session 后立即把 AppShell scope 切到真实 session,/chat首轮尚未重定向时也能打开。 - Managed 胶囊只有 details API 200 才获得 durable evidence。404/5xx/网络异常先进行五次快速 probe,随后保持每 30 秒一次的冷却恢复;404 可暂记 missing,transient 仍是 unknown。迟到 row 或 API 恢复后无需整页刷新即可出现,同时避免历史幽灵 id 每秒永久请求。
- tool use ID 是 physical attempt identity,历史渲染不再改写为
hist-N;用户任务与 sidebar tab 使用 logical run identity,同一 retry 链只显示一个胶囊。 - agent-run tab 仍是内存态,
serialize()明确不把 transcript 复制进 localStorage。Claude/Native 历史先从 chat tool blocks 重建,再用 session-scoped details API 合并subagent_runs/subagent_run_events;三条 managed adapter 都写 lifecycle,Codex 因 proxy bridge call/result 不进入 thread 而进一步把该表用作跨回合事实源。 - Schema/migration 初始化不再执行运行态 recovery。进程 owner 只有在上一 owner 缺失或 PID 已死亡时才把遗留 streaming/permission/lock/run 收口;Next route/module 的重复初始化不会把活任务标为
Process restarted。 - Dev HMR 会保留进程级 SQLite handle,因此
getDb()还维护 code-owned schema revision。新增 migration 必须 bump revision;新模块即使没有重新打开 DB,也会在 migration lock 下重跑幂等结构初始化。这个路径只补 schema,不触发 runtime recovery。 - transcript 用
<pre>纯文本渲染,外部/child 内容不会被当 HTML 或 Markdown 指令执行。
- 类型:
npm run typecheck通过。 - 最新定向:
subagent-orchestration.test.ts+subagent-run-persistence.test.ts+codex-builtin-bridge.test.ts+codex-interrupt-contract.test.ts120/120,覆盖三 Adapter 共享 workflow、production transcript durable gate、404/5xx 冷却恢复、invalid Codex route 零持久化、queued Stop durable cancelled、dependency deadline 边界、Node 18 abort fallback、HMR migration 不 recovery,以及既有 route/terminal/permission 合同。另有 Widget/Harness 五文件 + Sub-agent 图标导入回归 211/211。 - P0 可信编排定向:上述两文件加
codex-builtin-bridge.test.ts82/82,覆盖 legacy additive migration、logical retry/latest aggregation、active/completed ID reuse guard、settling、structured result/provenance、typed lifecycle、Claude/Codex route mismatch、三 Adapter conflict wire 与单胶囊 source contract。 - 定向:本轮切换聊天 / live DB owner / 三 Runtime durable run / Claude spawn fail-closed 共 69/69;前序三 Runtime 工具继承、hosted search、route、proxy/thread isolation、Runtime adapter 与 permission 合同均通过。
- 全量:2026-07-25 typecheck 通过、unit 4654/4654。原五个 Widget/Harness 加载失败已关闭:模型图标改为精确导入
@lobehub/icons/es/<Brand>/components/Mono,避免品牌 barrel 经 Avatar 连带加载@lobehub/ui/CodeDiff 和@pierre/diffs/react。 - Lint:
lint:hooks与lint:docs-drift通过。 - 状态回归:managed acknowledgement、background Agent、Codex inProgress/completed 与
terminal=true/falsewire 定向测试通过。 - Durable lifecycle 回归:隔离 legacy/空库验证三 Runtime
subagent_runs/subagent_run_events、logical attempt/backfill、parent FK/cascade、running→settling→terminal、structured result/provenance、terminal immutable、Codex toolId=attemptId、latest logical system snapshot 与详情 attempt/event query;并验证 live process 重复 DB init 不删除 lock/permission/checkpoint。 - UI smoke:开发客户端用真实历史分别验证 completed / running 胶囊;高度 30px、无提示词段落与第二行、running 的详情按钮可立即打开对应等待态 sidebar、console 0 error;未调用外部模型。首轮
/chatsidebar mount 另有 source contract test 覆盖。
- CodePilot Runtime:要求另一个 Provider+Model 的 child 先读取文件,再调用一个需要审批的工具;确认只读工具直接执行、写入/Shell 仍弹父会话权限框,父 picker 不变。
- Claude Code Runtime 正例:分别在 Kimi / GLM / DeepSeek 等兼容 Provider 下要求对应 model-pinned worker;调用必须带完整
required_capabilities,确认实际模型正确,且只有真实 terminal result 后显示终态。该字段仅属于 Claude managed subprocess,不用于 Codex。 - Claude Code Runtime 反例:要求 Grok 子 Agent;Grok 不在 Claude Code 未置灰 route list,必须看到 unavailable,任务不得显示成功,父 Agent 必须询问改用可用模型还是切 Runtime。
- UI:同时启动两个 child,确认胶囊同排/换行;running 时详情可开,提示词只在侧栏;terminal 前不显示 completed;403 / maxTurns / timeout 分别显示失败 / 部分完成 / 已超时。
- One-shot negative:给写作者一个依赖研究结果的任务;父 Agent 必须先等研究结果,再只启动一次写作者,不得先创建“待命”胶囊后重复调用同名 Agent。
- Tool inheritance:Claude child 调用 WebSearch/WebFetch;如果父会话关闭了相关工具才返回
CAPABILITY_UNAVAILABLE。无真实搜索工具时仍不得改用旧文案冒充。 - Codex Runtime(CodePilot Provider):在 child 中分别调用文件、Shell、写入、Codex 原生工具与任意已配置 MCP,确认工具由 app-server 的 sandbox/approval 正常处理且不出现 CodePilot capability gate;用 Qwen 等第三方 route 验证 Shell/Fetch 真实联网,再要求 xAI/OpenAI Responses/官方 Anthropic route 联网检索,确认 hosted search 被调用。模型胶囊与 terminal route 必须一致;无法联网时必须显示 failed 而不是 completed。child 输出不作为父正文重复出现,日志不得出现
unsupported call: codepilot_spawn_subagent。完成后另发“进展怎么样”,父 Agent 必须调用/使用subagent_runs事实回答,不能执行ls猜测。 - 切换与 Stop 对照:运行 CodePilot long child 后切到其他聊天,等待后切回,任务应继续并显示真实 terminal;再启动一条并点击 Stop,只有后一条应取消,父会话不残留 active。
- 共享依赖链:分别在 Claude、CodePilot、Codex managed 路径要求 Qwen
research→ DeepSeekcopy→ Kimiimplementation,三者使用同一 workflow;确认后两项先显示 queued、Provider 只在依赖完成后启动、实际 child 输入含上游 durable result,最终只有三个胶囊。再跑 A→B→A 循环和上游失败反例,必须在下游 Provider 前结构化失败。
- 个别 child cancel、并发事件 mux 压测。
- Provider entitlement health cache;logical run / physical attempt 已完成,真实调用仍全部保留在详情。
- 用户可配置的可选 Agent template UI(身份/工具/预算),仍保持每次 model 动态选择。
- Codex Account 原生 per-child model/provider 能力继续随 app-server 协议演进;当前跨 CodePilot Provider 只走 CodePilot Provider proxy bridge。
- 跨 Runtime Delegation Broker;复用现有三 Runtime logical-run/attempt/result/event 合同,不另造一套状态机。
- 更完整的条件分支、循环/人工审批节点与工作流级 resume/checkpoint;当前共享层只支持声明式 DAG 边,足以解决 same-runtime 的结果依赖,不冒充通用 workflow engine。