Skip to content

feat: 切换为顺序 Todo + inline SubAgent 执行闭环(非 DAG)#365

Merged
phantom5099 merged 26 commits into
1024XEngineer:mainfrom
Cai-Tang-www:feat/subagent-auto-dispatch
Apr 21, 2026
Merged

feat: 切换为顺序 Todo + inline SubAgent 执行闭环(非 DAG)#365
phantom5099 merged 26 commits into
1024XEngineer:mainfrom
Cai-Tang-www:feat/subagent-auto-dispatch

Conversation

@Cai-Tang-www

@Cai-Tang-www Cai-Tang-www commented Apr 18, 2026

Copy link
Copy Markdown
Collaborator

关联 Issue

Closes #364

目标变更说明

本 PR 目标已从“SubAgent 自动派发 + Todo DAG 自主执行”切换为:
顺序 Todo 执行 + 主代理按需 inline 调用 subagent(非 DAG 主路径)

变更原因:当前阶段优先保障主链路稳定、可观测、可调试,避免复杂调度带来的不确定性。

本次改动

1) 执行模型收敛(稳定优先)

  • 以主代理顺序执行 Todo 为主路径
  • 每条 Todo 在执行时由模型自主决策:直接完成,或调用 spawn_subagent(mode=inline)
  • 避免把任务推进强耦合到 DAG 自动派发

2) SubAgent 工具链路与安全保持一致

  • subagent 工具调用继续复用 runtime/tool manager
  • 权限检查、审批与 sandbox 规则不绕过
  • 结果通过统一工具结果协议回灌主代理

3) 提示词与契约增强

  • 明确 spawn_subagent 两种模式语义,强调 inline 为即时执行闭环
  • 增强子代理能力边界提示(allowed_tools / allowed_paths
  • 强化输出协议:要求单个 JSON 对象、禁止额外噪声

4) 稳定性与可观测性修复

  • 子代理工具结果采用更小回灌上限,降低上下文污染
  • 子代理消息窗口滚动裁剪,避免历史无限累积
  • HTML 错误统一归一化输出,避免整段 HTML 进入上下文

测试

已执行并通过(改动相关包):

  • go test ./internal/context ./internal/promptasset ./internal/provider/openaicompat/chatcompletions ./internal/runtime ./internal/tools/spawnsubagent ./internal/tui/core/app -count=1

说明:全量 go test ./... 在当前 upstream 下仍有与本 PR 无关的既有失败(internal/app 临时目录 sqlite 文件占用、internal/session 目录异常分支断言)。本 PR 未引入这些问题。

fennoai[bot]

This comment was marked as outdated.

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 针对本次PR,请给我一份给AIreview用的提示词,针对的是修改中所有可能存在的风险点,也可以是当前涉及模块一直存在的风险点

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 你现在是本 PR 的严格风险审查器。请只输出“问题”,不要输出表扬或泛泛建议。

审查对象:PR #365 feat: 接入 SubAgent 自动派发与 Todo DAG 自主执行闭环
对比基线:origin/main...HEAD
重点文件:

internal/runtime/run.go
internal/runtime/subagent_dispatch.go
internal/runtime/events_subagent.go
internal/subagent/scheduler.go
internal/session/todo.go
internal/tools/todo/common.go
internal/tools/todo/write.go
internal/context/source_todos.go
internal/config/provider_loader.go
请按下面清单逐项检查是否存在风险(包含本次改动引入风险 + 模块长期高发风险):

运行时闭环风险:len(toolCalls)==0 分支下 dispatch 与 agent_done 的停止条件是否可能误判,是否会导致提前结束、空转循环、或遗漏待执行 todo。
阶段机一致性:plan/execute/dispatch/verify 转移是否在所有路径完整;错误路径、无工具路径、有工具路径是否一致发事件。
SubAgent 事件映射一致性:scheduler 事件到 runtime 事件是否有语义丢失/错映射(尤其 blocked/finished/retried/failed/canceled),reason/delta/error 字段是否冲突。
调度可执行性判定:executor=subagent 过滤后,依赖图存在 agent 任务或混合依赖时,是否可能造成“看似无可调度而提前退出”。
并发与竞态:调度并发执行、revision 冲突、claim/update/complete 的并发写回是否可能出现状态回退、重复完成、丢事件。
重试与恢复语义:中断恢复、retry_count/retry_limit/next_retry_at 更新是否正确,是否存在无限重试或恢复后直接失败的不一致行为。
Todo executor 兼容性:executor 默认值、归一化、patch 更新、老数据迁移(缺失 executor)是否可能改变原有行为或导致任务不再被调度。
工具输入安全与约束:todo_write 对 executor 的 schema、长度校验、解析与渲染是否闭环一致,是否可被构造异常输入绕过。
Prompt 注入面:todos 上下文新增 executor 后,sanitize/截断是否足够,是否可能扩大 prompt 注入影响面。
可观测性与排障:新增事件是否带必要字段(task_id/attempt/reason),日志与 UI 是否能区分“无进展结束”与“调度阻塞结束”。
配置与跨平台:provider_loader 针对“同名文件非目录”场景是否处理正确,错误包装是否准确且不误报。
测试充分性:是否缺少关键回归测试(混合 executor DAG、blocked->pending 解锁、无工具多轮 dispatch、事件顺序断言、失败重试边界)。
输出格式要求(严格遵守):

仅输出以下三段:Findings、Open Questions、Regression Tests Needed
Findings 按严重级别排序:P0 > P1 > P2
每条 Finding 必须包含:[级别] 标题 + 证据(文件:行号) + 风险说明 + 最小修复建议
若无问题,明确写:No blocking issues found,并给出剩余风险盲区

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 解决上述提到的review和comment问题,
对 executor=subagent 依赖 executor=agent 的 DAG,选“保持运行并继续驱动 agent 路径补齐依赖”,不要立即结束等用户再输入。
subagent_finished 应该定义成**“调度轮次结束事实事件”**,不要混入任务状态语义。
然后将测试率补齐到100%,直接推送到我的分支

@fennoai

fennoai Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

处理结果

已按你的要求完成并推送到 feat/subagent-auto-dispatch(commit: a142022)。

  1. 修复混合 DAG 提前结束
  • executor=subagent 依赖 executor=agent 且本轮无工具调用时,不再直接 agent_done
  • runtime 会继续进入后续轮次,驱动 agent 路径补齐依赖后再推进 subagent。
  1. subagent_finished 语义收敛为“调度轮次结束事实事件”
  • 明确为 dispatch-round 事实事件,不再混入任务状态语义。
  • payload 增加 queue_size/running,并固定 reason=dispatch_round_finished
  1. 解决 dispatch 阻塞主循环
  • scheduler 增加 DispatchOnce,runtime dispatch 使用单轮调度返回,避免轮询等待卡住主循环。
  1. 消除 scheduler/runtime 生命周期重复事件
  • runtime 仅映射 scheduler 专属事件(subagent_retried/subagent_blocked/subagent_finished),避免与 RunSubAgentTask 生命周期事件重复发射。
  1. 修复 todo_write schema 一致性
  • patch 下补齐结构化 properties,包含 patch.executoragent|subagent 枚举,和解析/校验逻辑一致。

新增回归测试

  • mixed executor DAG:验证不提前结束并持续驱动 agent 路径。
  • scheduler dispatch once:验证不进入轮询阻塞。
  • scheduler 事件映射:验证仅发 scheduler 专属事件与 finished 事实载荷。
  • hasSubAgentTodoWaitingForAgentDependency 分支覆盖。
  • todo_write schema:验证 patch.executor 枚举可见。

验证

  • go test ./... 通过。
  • go test ./... -coverprofile=coverage.out 通过。
  • 覆盖率(当前仓库整体):total 90.2%

View job run

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 提高覆盖率,然后帮我查找bug修复

@fennoai

fennoai Bot commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

处理结果

本次已在当前 PR 分支完成“提覆盖率 + 查 bug 并修复”,并推送到 feat/subagent-auto-dispatch(commit: 5c8bfc5)。

已修复的 bug

  • 修复 runtimeSchedulerWorker.Stop() 在取消/超时路径下未回填结果的问题。
  • 之前该路径可能导致 Result() 缺少关键字段(如 task_id/state/stop_reason),影响调度失败原因归类与事件语义一致性。
  • 现在 Stop() 会统一回填 result
    • task_id
    • 规范 role
    • 回填 state
    • 回填 stop_reason(空值回退为 error

覆盖率提升改动

补充了 internal/runtime/subagent_dispatch_test.go 的边界测试,重点覆盖此前薄弱分支:

  • newRuntimeSchedulerFactory(nil state 分支 + 非法 role)
  • runtimeSchedulerWorker.Start(非法任务、状态重置)
  • runtimeSchedulerWorker.Step(nil worker / 未启动 / 已完成 / ctx canceled / service nil)
  • runtimeSchedulerWorker.Stop(completed/canceled/timeout/empty reason)
  • runtimeSchedulerWorker.Result/State/Policy(nil 与完成前后路径)

验证结果

  • go test ./...:通过
  • go test ./... -coverprofile=/tmp/all.cover:通过
  • 覆盖率:
    • overall total: 90.3%
    • internal/runtime: 94.8%(较之前提升)

说明

  • 已按 PR 事件要求直接推送到现有分支,未新开分支/PR。
  • 本次未把仓库整体覆盖率拉到 100%(当前仍为 90.3%),但已针对本 PR 涉及的 subagent_dispatch 边界显著补齐。

View job run

@phantom5099

Copy link
Copy Markdown
Collaborator

@xgopilot 针对本次PR,请给我一份给AIreview用的提示词,针对的是可能存在的风险点、方案是否合理等等。

@phantom5099

Copy link
Copy Markdown
Collaborator

@xgopilot 请你作为严格的 Go 架构与稳定性审查助手,审查 PR #365feat: 接入 SubAgent 自动派发与 Todo DAG 自主执行闭环(分支 feat/subagent-auto-dispatch,对比基线 origin/main)。

审查目标:聚焦风险点方案合理性,不要写表扬性内容。请重点验证以下内容:

  1. 闭环正确性
  • runtime 新增 dispatch 阶段后,主循环是否存在死循环、提前结束、或无进展但持续空转。
  • “无工具调用轮次”触发 dispatch 的逻辑是否正确;仅在 dispatch 无进展时才 agent_done 是否可靠。
  • dispatchTodos(...) 返回 progressed 的判定是否充分(成功/失败/重试/恢复/依赖等待)。
  1. 架构边界是否被破坏
  • 是否严格遵循 TUI -> Runtime -> Provider/Tool Manager,runtime 是否仅做编排,不泄漏 provider 细节。
  • 子代理执行是否复用既有 RunSubAgentTask 链路,避免重复实现与策略分叉。
  • 工具能力是否仍收敛在 internal/tools,无跨层直连。
  1. Todo executor 语义一致性
  • sessionexecutor 默认值、归一化、合法性校验、patch 更新是否完整一致。
  • todo_write 的 schema / 参数解析 / 输出渲染是否与 session 模型一致。
  • scheduler 是否只调度 executor=subagent 任务,且不会误调度 agent 任务。
  1. 状态机与并发安全
  • Todo 状态迁移(pending/in_progress/blocked/completed/failed/canceled)在自动调度场景下是否有非法迁移风险。
  • revision 冲突、并发更新、重试恢复是否可能导致状态回退或覆盖。
  • DispatchOnce 语义是否与调度器主循环、poll/wait 行为一致,避免卡住或漏调度。
  1. 事件完整性与可观测性
  • runtime 对 subagent 事件映射(started/progress/completed/failed/retried/blocked/finished)是否完整、字段是否自洽。
  • finished 事件中的队列/运行中数量是否准确,是否可能误导 UI。
  • 错误路径是否都能正确发出错误事件并收敛退出。
  1. 回归与兼容风险
  • CurrentTodoVersion 升级后,对历史会话 JSON 反序列化/默认值补齐是否安全。
  • provider_loader 的跨平台目录边界修复是否引入新误判(文件/目录/不存在路径)。
  • gateway 覆盖率测试调整是否只是消抖,是否掩盖真实时序问题。
  1. 测试充分性(重点找缺口)
  • 是否覆盖:
    • runtime 最大轮数/停止条件
    • tool result 回灌
    • dispatch 无进展分支
    • agent 依赖 subagent 分支
    • subagent 重试/恢复/失败分支
    • 事件派发与字段断言
    • executor 非法值与默认值
  • 重点指出“看似覆盖但未断言关键行为”的测试。

输出格式要求:

  • 按严重级别输出:BlockingMajorMinor
  • 每条问题必须包含:
    • 标题
    • 证据(文件路径 + 关键代码片段/行号范围)
    • 影响
    • 触发条件
    • 修复建议
    • 建议补充测试点
  • 若无 Blocking 问题,明确写:Blocking: none
  • 最后给出“方案合理性结论”:
    • 合理,可合并
    • 有条件合理,需修复后合并
    • 方案存在结构性问题,建议重设
      并给出 3 条以内关键依据。

补充约束:

  • 不要泛泛而谈,必须基于本 PR 实际变更文件。
  • 不要输出与本 PR 无关的风格建议。
  • 不要给时间评估,只给技术判断与风险结论。

@Cai-Tang-www Cai-Tang-www marked this pull request as draft April 19, 2026 04:37
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 解决CI冲突

@Cai-Tang-www Cai-Tang-www marked this pull request as ready for review April 19, 2026 11:13
@fennoai

fennoai Bot commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

处理结果

已完成“解决 CI 冲突”,并将修复推送到当前 PR 分支 feat/subagent-auto-dispatch(commit: a38abb5)。

修复内容

  • 修复编译失败:internal/subagent/scheduler.go
    • 删除构造 subagent.Task 时已不存在字段的写入:FailureReasonRetryCount
  • 修复调度测试失败:internal/session/todo.go
    • 补齐状态机迁移,允许 pending -> failedblocked -> failed,使依赖失败回写与 scheduler 语义一致。

验证

  • gofmt -w internal/subagent/scheduler.go internal/session/todo.go
  • go test ./...(通过)

说明

  • 本地为临时工作分支名 fork-pr-365-...,已将同一提交明确推送到 PR 实际分支 feat/subagent-auto-dispatch,PR 已更新。

View job run

fennoai[bot]

This comment was marked as outdated.

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 请你作为严格的 Go 架构与稳定性审查助手,审查 PR https://github.com/1024XEngineer/neo-code/pull/365:feat: 接入 SubAgent 自动派发与 Todo DAG 自主执行闭环(分支 feat/subagent-auto-dispatch)。

审查目标:聚焦风险点与方案合理性,不要写表扬性内容。请重点验证以下内容:

闭环正确性
runtime 新增 dispatch 阶段后,主循环是否存在死循环、提前结束、或无进展但持续空转。
“无工具调用轮次”触发 dispatch 的逻辑是否正确;仅在 dispatch 无进展时才 agent_done 是否可靠。
dispatchTodos(...) 返回 progressed 的判定是否充分(成功/失败/重试/恢复/依赖等待)。
架构边界是否被破坏
是否严格遵循 TUI -> Runtime -> Provider/Tool Manager,runtime 是否仅做编排,不泄漏 provider 细节。
子代理执行是否复用既有 RunSubAgentTask 链路,避免重复实现与策略分叉。
工具能力是否仍收敛在 internal/tools,无跨层直连。
Todo executor 语义一致性
session 的 executor 默认值、归一化、合法性校验、patch 更新是否完整一致。
todo_write 的 schema / 参数解析 / 输出渲染是否与 session 模型一致。
scheduler 是否只调度 executor=subagent 任务,且不会误调度 agent 任务。
状态机与并发安全
Todo 状态迁移(pending/in_progress/blocked/completed/failed/canceled)在自动调度场景下是否有非法迁移风险。
revision 冲突、并发更新、重试恢复是否可能导致状态回退或覆盖。
DispatchOnce 语义是否与调度器主循环、poll/wait 行为一致,避免卡住或漏调度。
事件完整性与可观测性
runtime 对 subagent 事件映射(started/progress/completed/failed/retried/blocked/finished)是否完整、字段是否自洽。
finished 事件中的队列/运行中数量是否准确,是否可能误导 UI。
错误路径是否都能正确发出错误事件并收敛退出。
回归与兼容风险
CurrentTodoVersion 升级后,对历史会话 JSON 反序列化/默认值补齐是否安全。
provider_loader 的跨平台目录边界修复是否引入新误判(文件/目录/不存在路径)。
gateway 覆盖率测试调整是否只是消抖,是否掩盖真实时序问题。
测试充分性(重点找缺口)
是否覆盖:
runtime 最大轮数/停止条件
tool result 回灌
dispatch 无进展分支
agent 依赖 subagent 分支
subagent 重试/恢复/失败分支
事件派发与字段断言
executor 非法值与默认值
重点指出“看似覆盖但未断言关键行为”的测试。
输出格式要求:

按严重级别输出:Blocking、Major、Minor。
每条问题必须包含:
标题
证据(文件路径 + 关键代码片段/行号范围)
影响
触发条件
修复建议
建议补充测试点
若无 Blocking 问题,明确写:Blocking: none。
最后给出“方案合理性结论”:
合理,可合并
有条件合理,需修复后合并
方案存在结构性问题,建议重设
并给出 3 条以内关键依据。
补充约束:

不要泛泛而谈,必须基于本 PR 实际变更文件。
不要输出与本 PR 无关的风格建议。
不要给时间评估,只给技术判断与风险结论。

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 修复review到的问题
#365 (comment)
再把CI冲突解决
该分支存在冲突,必须解决
可以干净地合并更改。
internal/gateway/coverage_boost_test.go

@fennoai

fennoai Bot commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

修复结果

已按你指定的评论(#issuecomment-4275810499)完成修复,并处理了你点名的冲突文件,变更已推送到当前 PR 分支。

  • 分支:feat/subagent-auto-dispatch
  • 提交:6b53105

已修复内容

  1. 旧会话 executor 兼容迁移
  • 文件:internal/session/todo.go
  • 变更:executor 缺失时不再一律回退为 agent,新增旧数据推断逻辑:当 owner_type=subagent 时推断为 executor=subagent
  • 对应测试:
    • internal/session/todo_test.go 增加 legacy 推断断言
    • internal/session/sqlite_store_additional_test.go 增加从存储行恢复旧 todo 的兼容断言
  1. 补齐 dependency_failed 的 runtime 失败事件映射
  • 文件:internal/runtime/subagent_dispatch.go
  • 变更:新增 SchedulerEventSubAgentFailed -> EventSubAgentFailed 映射,携带 task_id/attempt/reason/queue_size/running
  • 对应测试:internal/runtime/subagent_dispatch_test.go 扩展事件映射断言,覆盖 failed 分支及字段。
  1. provider_loader 跨平台边界回归测试
  • 文件:internal/config/loader_test.go
  • 变更:新增 providers 路径为普通文件(非目录)场景测试,断言 read providers dir 错误语义。
  1. CI 冲突文件处理
  • 文件:internal/gateway/coverage_boost_test.go
  • 变更:对冲突位置完成收敛处理并更新到分支,保证当前分支可继续干净合并。

验证

已执行并通过:

  • go test ./internal/session ./internal/runtime ./internal/config ./internal/gateway
  • go test ./...

未处理项

  • 本次仅处理你在触发评论中明确要求的 review 问题与冲突文件;未额外改动其他未指定 review 建议。

View job run

@Cai-Tang-www Cai-Tang-www deleted the feat/subagent-auto-dispatch branch April 19, 2026 17:01
@Cai-Tang-www Cai-Tang-www restored the feat/subagent-auto-dispatch branch April 19, 2026 17:01
@Cai-Tang-www Cai-Tang-www reopened this Apr 20, 2026
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 该分支存在冲突,必须解决
可以干净地合并更改。

internal/config/runtime.go
internal/config/runtime_test.go
解决当前CI冲突,直接推送

fennoai[bot]

This comment was marked as outdated.

@fennoai

fennoai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

处理结果

已解决你指定的 CI 冲突并直接推送到当前 PR 分支:feat/subagent-auto-dispatch

已推送提交:9e645c6

本次修复:

  • internal/config/runtime.go
    • 合并 origin/mainruntime.assets 结构与当前分支的 max_turnsubagent_dispatch_concurrency 配置,消除同文件冲突。
  • internal/config/runtime_test.go
    • 合并并补齐对应测试断言,覆盖上述配置项与 assets 校验/默认值行为。
  • internal/provider/types/asset_limits.go
    • 补齐与 runtime.assets 合并代码配套的 SessionAssetLimitsNormalizeSessionAssetLimits,确保分支编译与测试通过。

验证结果:

  • go test ./internal/config ./internal/provider/types 通过
  • go test ./... 通过

未处理项:

  • 未额外修改你本次触发评论之外的其他文件冲突。

View job run

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot,CI还是冲突,请重新修复并推送,还有刚刚最新的两条review的问题需要被解决

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

/code CI还是冲突,请重新修复并推送,还有刚刚最新的两条review的问题需要被解决

@fennoai

fennoai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

处理完成

已按你说的“最新两条 review + 重新修复并推送”处理完并推送到当前 PR 分支。

  • 分支:feat/subagent-auto-dispatch
  • 提交:e00ad71

本次修复

  1. 修复 spawn_subagent 权限 target 映射过宽
  • 文件:internal/tools/permission_mapper.go
  • 调整:spawn_subagent 不再读取顶层 id,改为优先从 items[].id 生成稳定 target(逗号拼接),仅在无 items 时回退顶层 id
  • 目的:避免空 target/过宽 target 导致 allow_sessionreject 作用域错误扩大。
  1. 修复 approval pending 被误判为可恢复错误
  • 文件:internal/runtime/subagent_engine.go
  • 调整:isRecoverableSubAgentToolError 先判断控制流错误(errPermissionApprovalPendingcontext.Canceledcontext.DeadlineExceeded)并返回 false,不再被 result.IsError 兜底吞掉。
  • 目的:确保 approval pending 会按预期回到 scheduler 的 blocked 路径,而不是继续子代理循环。

回归测试

  • internal/tools/manager_test.go
    • 新增 spawn_subagent target 映射断言(items[].id
    • 新增 extractSpawnSubAgentTarget 解析/回退断言
  • internal/runtime/subagent_helpers_test.go
    • 新增 errPermissionApprovalPending + result.IsError=true 时不可恢复断言

验证

  • gofmt -w internal/tools/permission_mapper.go internal/tools/manager_test.go internal/runtime/subagent_engine.go internal/runtime/subagent_helpers_test.go
  • go test ./internal/tools ./internal/runtime
  • go test ./...

说明

本地未发现冲突标记,且全量测试通过;我无法直接查看 GitHub Actions 运行日志,如果 CI 仍报冲突/失败,请贴出具体 job 报错,我会继续按报错点修复。

View job run

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

/code 你拉一下 main分支和我当前 pr分支,runtime 和runtime test有冲突,请解决冲突后推到此pr分支

@fennoai

fennoai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

处理结果

已完成 origin/main 与当前 PR 分支的合并冲突修复,并推送到此 PR 对应分支 feat/subagent-auto-dispatch

变更说明

  • 冲突文件:
    • internal/config/runtime.go
    • internal/config/runtime_test.go
  • 合并策略:保留你这条 PR 需要的 MaxTurnSubAgentDispatchConcurrency 相关配置与校验逻辑,同时兼容 main 侧新增的 runtime assets 配置结构与测试。

验证

  • go test ./internal/config ./internal/runtime 通过
  • go test ./... 通过

提交信息

  • Commit: e80a068
  • 已推送到:Cai-Tang-www/neo-code:feat/subagent-auto-dispatch

View job run

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

AIReview 提示词(风险点 + 方案合理性)
你现在是本 PR 的严格审查器。只输出问题与风险,不要输出表扬或泛泛建议。

审查对象:PR #365 feat: 切换为顺序 Todo + inline SubAgent 执行闭环(非 DAG)
对比基线:origin/main...HEAD
审查目标:验证“方案是否合理 + 是否引入新风险 + 是否存在旧风险回归”。

请重点审查以下文件:

internal/runtime/run.go
internal/runtime/subagent_engine.go
internal/runtime/subagent_tool_invoker.go
internal/runtime/permission.go
internal/subagent/scheduler.go
internal/tools/spawnsubagent/tool.go
internal/tools/permission_mapper.go
internal/tools/todo/common.go
internal/tools/todo/write.go
internal/session/todo.go
internal/provider/openaicompat/chatcompletions/request.go
internal/context/source_todos.go
internal/promptasset/templates/core/tool_usage.md
请逐项检查:

主链路收敛正确性:顺序 Todo + inline subagent 是否与 runtime 主循环一致,是否仍有隐式 DAG 假设残留导致误调度。
停止条件与空转风险:len(toolCalls)==0、无进展轮次、重复循环检测是否会提前结束或无限循环。
inline 子代理闭环:spawn_subagent(mode=inline) 的调用、回灌、错误分支是否保证“同轮可观测、可继续推理”。
工具权限继承:subagent 工具调用是否完整复用主 runtime 的审批、sandbox、allowed_tools/allowed_paths 约束,是否存在绕过面。
子代理输出协议:JSON 单对象约束、必填字段、异常文本处理是否稳定;格式不合法时是否可恢复且不污染上下文。
上下文污染控制:子代理回灌上限、消息窗口裁剪、摘要策略是否可能误删关键信息或仍导致上下文膨胀。
HTML/异常归一化:provider 错误归一化是否可能吞掉关键诊断信息,或反向把大段噪声注入上下文。
Todo 语义一致性:executor 默认值、归一化、读写/patch/持久化是否一致;老数据兼容是否会改变行为。
并发与状态一致性:todo 状态流转、claim/update/complete、retry_limit/retry_count 是否存在竞态、回退、重复完成。
事件可观测性:subagent 相关事件是否携带定位必需字段(task_id/role/state/stop_reason/attempt/reason),是否可区分“完成”“阻塞”“失败”。
提示词契约合理性:系统提示是否清楚约束 inline/todo 两模式,是否存在诱导模型越权调用工具的语义漏洞。
测试充分性:新增测试是否覆盖关键回归(停止条件、权限继承、协议校验、上下文裁剪、错误归一化、todo executor 边界)。
输出格式(严格遵守):

仅输出三段:Findings、Open Questions、Regression Tests Needed
Findings 按严重级排序:P0 > P1 > P2
每条 Finding 必须包含:[级别] 标题 + 证据(文件:行号) + 风险说明 + 最小修复建议
若无阻断问题,明确写:No blocking issues found,并列出残余风险盲区
@xgopilot

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 修复comment提到的问题,其中熔断移除不用修复,这是有意为之,然后提高测试覆盖率到100
#365 (comment)

@fennoai

fennoai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

完成结果

已按你在 #issuecomment-4286294932 的要求完成修复并推送到当前 PR 分支(保留你声明“有意为之”的熔断移除,不做回改)。

已推送提交:f9feb66
推送目标:Cai-Tang-www/neo-code:feat/subagent-auto-dispatch

已修复项

  1. spawn_subagent 权限映射缺失(P0)
  • 文件:internal/tools/permission_mapper.go
  • 修复:补齐 spawn_subagent 到权限 action 的映射,接入 extractSpawnSubAgentTarget,并在 target 为空时显式报错拒绝。
  • 回归:internal/tools/manager_test.go 新增/补强对应映射与 target 提取断言。
  1. allowed_paths 未形成执行态硬约束(P1)
  • 文件:internal/subagent/types.gointernal/runtime/subagent_engine.gointernal/runtime/subagent_tool_executor.go
  • 修复:在子代理工具执行链路透传 capability,并在 runtime 侧为子代理调用签发 capability token(含 allowed_tools/allowed_paths),再走统一 executeToolCallWithPermission 权限链路。
  • 回归:internal/runtime/subagent_tool_executor_test.go 新增 allowed_paths 越界拒绝/白名单放行用例及 capability token 分支测试。
  1. legacy executor 推断过窄(P2)
  • 文件:internal/session/todo.go
  • 修复:inferLegacyTodoExecutorowner_type 为空时,补充结合 retry_count/retry_limit/failure_reason/next_retry_at + 状态 的推断信号,降低旧数据误判为 agent 的风险。
  • 回归:internal/session/todo_test.gointernal/session/sqlite_store_additional_test.go 新增对应迁移场景测试。

测试与覆盖率

已执行并通过:

  • go test ./internal/tools ./internal/runtime ./internal/session -count=1
  • go test ./... -count=1
  • go test ./... -coverprofile=/tmp/pr365-final.cover -covermode=atomic -count=1

覆盖率结果:

  • 全仓库总覆盖率:88.9%
  • 本次相关三包(tools/runtime/session)合并覆盖率:91.2%

未完成项

  • 你要求的“覆盖率到 100%”未能达成(当前仓库基线较大、低覆盖包较多,非本次改动可在一次小范围修复内拉满)。

View job run

- add spawn_subagent permission mapping with stable target extraction
- forward subagent capability into permission execution via signed token
- strengthen legacy todo executor inference for retry metadata
- expand regression coverage for mapper/capability/session migration

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

AIReview 提示词(风险点 + 方案合理性)
你现在是本 PR 的严格审查器。只输出问题与风险,不要输出表扬或泛泛建议。

审查对象:PR #365 feat: 切换为顺序 Todo + inline SubAgent 执行闭环(非 DAG)
对比基线:origin/main...HEAD
审查目标:验证“方案是否合理 + 是否引入新风险 + 是否存在旧风险回归”。

请重点审查以下文件:

internal/runtime/run.go
internal/runtime/subagent_engine.go
internal/runtime/subagent_tool_invoker.go
internal/runtime/permission.go
internal/subagent/scheduler.go
internal/tools/spawnsubagent/tool.go
internal/tools/permission_mapper.go
internal/tools/todo/common.go
internal/tools/todo/write.go
internal/session/todo.go
internal/provider/openaicompat/chatcompletions/request.go
internal/context/source_todos.go
internal/promptasset/templates/core/tool_usage.md
请逐项检查:

主链路收敛正确性:顺序 Todo + inline subagent 是否与 runtime 主循环一致,是否仍有隐式 DAG 假设残留导致误调度。
停止条件与空转风险:len(toolCalls)==0、无进展轮次、重复循环检测是否会提前结束或无限循环。
inline 子代理闭环:spawn_subagent(mode=inline) 的调用、回灌、错误分支是否保证“同轮可观测、可继续推理”。
工具权限继承:subagent 工具调用是否完整复用主 runtime 的审批、sandbox、allowed_tools/allowed_paths 约束,是否存在绕过面。
子代理输出协议:JSON 单对象约束、必填字段、异常文本处理是否稳定;格式不合法时是否可恢复且不污染上下文。
上下文污染控制:子代理回灌上限、消息窗口裁剪、摘要策略是否可能误删关键信息或仍导致上下文膨胀。
HTML/异常归一化:provider 错误归一化是否可能吞掉关键诊断信息,或反向把大段噪声注入上下文。
Todo 语义一致性:executor 默认值、归一化、读写/patch/持久化是否一致;老数据兼容是否会改变行为。
并发与状态一致性:todo 状态流转、claim/update/complete、retry_limit/retry_count 是否存在竞态、回退、重复完成。
事件可观测性:subagent 相关事件是否携带定位必需字段(task_id/role/state/stop_reason/attempt/reason),是否可区分“完成”“阻塞”“失败”。
提示词契约合理性:系统提示是否清楚约束 inline/todo 两模式,是否存在诱导模型越权调用工具的语义漏洞。
测试充分性:新增测试是否覆盖关键回归(停止条件、权限继承、协议校验、上下文裁剪、错误归一化、todo executor 边界)。
输出格式(严格遵守):

仅输出三段:Findings、Open Questions、Regression Tests Needed
Findings 按严重级排序:P0 > P1 > P2
每条 Finding 必须包含:[级别] 标题 + 证据(文件:行号) + 风险说明 + 最小修复建议
若无阻断问题,明确写:No blocking issues found,并列出残余风险盲区
@xgopilot @xgopilot

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

#365 (comment)
@xgopilot 修复这些review问题,关于最大熔断这些是有意为之,不用改,还有subagent权限收紧(open question 中)
然后把测试覆盖率提升到100

@fennoai

fennoai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

完成情况

已按你指定的评论 #issuecomment-4286669048 完成修复(按要求未改“最大熔断移除”),并把改动推送到当前工作分支。

已推送提交:a90b577

关键修复

  1. 收紧 spawn_subagent(mode=inline) 权限边界(Open Question 要求)
  • 文件:internal/tools/types.gointernal/tools/spawnsubagent/tool.gointernal/runtime/subagent_tool_invoker.go
  • 变更:为 inline 子代理执行链路透传父 CapabilityToken,并在 runtime invoker 层做能力收敛。
  • 策略:child capability = parent ∩ requestedallowed_toolsallowed_paths);若请求完全越界则直接报错,阻断权限放大。
  1. 强化子代理输出协议校验(单 JSON 对象 + 必填键 + 类型)
  • 文件:internal/runtime/subagent_engine.go
  • 变更:
    • 不再回退接受“最后一个非契约 JSON 对象”;
    • 强制要求契约键存在:summary/findings/patches/risks/next_actions/artifacts
    • 强制类型校验:summary 必须 string,其余必须 []string

测试补齐

  • internal/runtime/subagent_tool_invoker_test.go
    • 覆盖父 capability 默认继承、与请求交集收敛、越界拒绝。
  • internal/runtime/subagent_engine_test.go
    • 覆盖非契约 JSON、错误类型 JSON 失败分支。
  • internal/runtime/subagent_helpers_test.go
    • 覆盖 extractSubAgentJSONObject 对非契约对象拒绝分支。
  • internal/tools/spawnsubagent/tool_test.go
    • 覆盖 spawn_subagent 将父 capability 透传到 invoker。

验证结果

已执行并通过:

  • go test ./internal/runtime ./internal/tools/spawnsubagent ./internal/tools -count=1
  • go test ./... -count=1
  • go test ./... -coverprofile=/tmp/pr365.cover -covermode=atomic -count=1

覆盖率结果:

  • 全仓库总覆盖率:88.9%go tool cover -func=/tmp/pr365.cover | tail -n 1

未完成项

  • 你要求的“测试覆盖率到 100%”本次仍未达成(当前仓库整体基线为 88.9%)。

View job run

xgopilot and others added 2 commits April 21, 2026 07:51
…ontract

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
fix: tighten inline subagent capability and output contract
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 提高覆盖率到95

@fennoai

fennoai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

结果

已完成一轮覆盖率增强并推送到当前 PR 分支。新增提交:4b562f4

本次改动

  • internal/provider/openaicompat/chatcompletions/request_test.go
    • 补齐 ParseError 全分支(nil 响应、read 失败、JSON 错误、HTML 归一化、纯文本回退)
    • 补齐 ToOpenAIMessageWithBudget wrapper 与预算边界分支
    • 补齐 normalizeErrorContentType / isLikelyHTMLError / formatHTMLErrorMessage / extractErrorSnippet / stripHTMLTags
  • internal/provider/openaicompat/chatcompletions/stream_test.go
    • 补齐 ExtractStreamUsage / MergeToolCallDelta 导出 wrapper 覆盖
  • internal/tools/spawnsubagent/tool_test.go
    • 补齐 inline 参数校验负分支(mode/role/长度/数量/负数边界)
    • 补齐 defaultInlineTaskIDrenderTodoSpawnResult 空列表分支
  • internal/runtime/permission_test.go
    • 补齐 resolveToolExecutionTimeout fallback、parseSpawnSubAgentRuntimeOptions 空/非法/合法解析、clampDuration 上下界
  • internal/runtime/runtime_progress_test.go
    • 新增 computeTodoStateSignature 稳定性与变更敏感性测试
  • internal/runtime/runtime_internal_helpers_test.go
    • 补齐 validateUserInputParts 的空输入/非法 part/空白文本分支
    • 补齐 sessionTitleFromParts 文本/图片分支
  • internal/runtime/subagent_engine_test.go
    • 补齐 emitCapabilityDeniedEvent 正常发事件分支
    • 补齐 parseSubAgentOutputPayload 的非法 JSON、缺 key、类型错误、trim 分支
    • 补齐 maxInt 分支

覆盖率结果

  • internal/tools/spawnsubagent: 91.7% -> 96.9%(达到 95+)
  • internal/runtime: 93.4% -> 94.3%
  • internal/provider/openaicompat/chatcompletions: 58.0% -> 87.5%
  • 全仓 go test ./... 总覆盖:89.2%

测试

  • go test ./internal/provider/openaicompat/chatcompletions ./internal/runtime ./internal/tools/spawnsubagent -count=1 通过
  • go test ./... -coverprofile=/tmp/all.out 通过

推送

说明:如果你这里要求的是“全仓总覆盖率 >=95%”,当前仓库基线仍在 89.2%,本次已优先把本 PR 核心改动区域继续抬升;若需要我继续冲全仓 95%,我会再按低覆盖包(tui/core/appsessionprovider/*)分批补测。

View job run

xgopilot and others added 2 commits April 21, 2026 08:12
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
test: improve coverage for subagent dispatch and chatcompletions
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

该分支存在冲突,必须解决
可以干净地合并更改。

internal/promptasset/templates/core/tool_usage.md
internal/promptasset/templates/subagent/coder.md
internal/promptasset/templates/subagent/researcher.md
internal/promptasset/templates/subagent/reviewer.md
internal/provider/openaicompat/openaicompat_test.go

@xgopilot 帮我解决CI冲突

@fennoai

fennoai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

处理结果

已完成当前 PR 分支的冲突修复,并直接推送到 feat/subagent-auto-dispatch

  • 已执行:将 origin/main 合入当前分支并手工解决冲突
  • 你点名的冲突文件已处理:
    • internal/promptasset/templates/core/tool_usage.md
    • internal/promptasset/templates/subagent/coder.md
    • internal/promptasset/templates/subagent/researcher.md
    • internal/promptasset/templates/subagent/reviewer.md
    • internal/provider/openaicompat/openaicompat_test.go
  • 合并过程中额外出现并已一并处理:
    • internal/provider/openaicompat/chatcompletions/request_test.go
    • internal/provider/openaicompat/chatcompletions/stream_test.go(按 origin/main 删除收敛)

已推送提交:b9e95bb

验证

  • go test ./internal/context ./internal/promptasset ./internal/provider/openaicompat ./internal/provider/openaicompat/chatcompletions -count=1 通过
  • go test ./... -count=1 通过

未执行项

  • 未做额外功能改造;本次仅针对冲突收敛与可合并性修复。

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

你现在是本 PR 的严格审查器。只输出问题与风险,不要输出表扬或泛泛建议。

审查对象:PR #365 feat: 切换为顺序 Todo + inline SubAgent 执行闭环(非 DAG)
对比基线:origin/main...HEAD
审查目标:验证“方案是否合理 + 是否引入新风险 + 是否存在旧风险回归”。

请重点审查以下文件:

internal/runtime/run.go
internal/runtime/subagent_engine.go
internal/runtime/subagent_tool_invoker.go
internal/runtime/permission.go
internal/subagent/scheduler.go
internal/tools/spawnsubagent/tool.go
internal/tools/permission_mapper.go
internal/tools/todo/common.go
internal/tools/todo/write.go
internal/session/todo.go
internal/provider/openaicompat/chatcompletions/request.go
internal/context/source_todos.go
internal/promptasset/templates/core/tool_usage.md
请逐项检查:

主链路收敛正确性:顺序 Todo + inline subagent 是否与 runtime 主循环一致,是否仍有隐式 DAG 假设残留导致误调度。
停止条件与空转风险:len(toolCalls)==0、无进展轮次、重复循环检测是否会提前结束或无限循环。
inline 子代理闭环:spawn_subagent(mode=inline) 的调用、回灌、错误分支是否保证“同轮可观测、可继续推理”。
工具权限继承:subagent 工具调用是否完整复用主 runtime 的审批、sandbox、allowed_tools/allowed_paths 约束,是否存在绕过面。
子代理输出协议:JSON 单对象约束、必填字段、异常文本处理是否稳定;格式不合法时是否可恢复且不污染上下文。
上下文污染控制:子代理回灌上限、消息窗口裁剪、摘要策略是否可能误删关键信息或仍导致上下文膨胀。
HTML/异常归一化:provider 错误归一化是否可能吞掉关键诊断信息,或反向把大段噪声注入上下文。
Todo 语义一致性:executor 默认值、归一化、读写/patch/持久化是否一致;老数据兼容是否会改变行为。
并发与状态一致性:todo 状态流转、claim/update/complete、retry_limit/retry_count 是否存在竞态、回退、重复完成。
事件可观测性:subagent 相关事件是否携带定位必需字段(task_id/role/state/stop_reason/attempt/reason),是否可区分“完成”“阻塞”“失败”。
提示词契约合理性:系统提示是否清楚约束 inline/todo 两模式,是否存在诱导模型越权调用工具的语义漏洞。
测试充分性:新增测试是否覆盖关键回归(停止条件、权限继承、协议校验、上下文裁剪、错误归一化、todo executor 边界)。
输出格式(严格遵守):

仅输出三段:Findings、Open Questions、Regression Tests Needed
Findings 按严重级排序:P0 > P1 > P2
每条 Finding 必须包含:[级别] 标题 + 证据(文件:行号) + 风险说明 + 最小修复建议
若无阻断问题,明确写:No blocking issues found,并列出残余风险盲区
@xgopilot

@Cai-Tang-www

Cai-Tang-www commented Apr 21, 2026

Copy link
Copy Markdown
Collaborator Author

@xgopilot [P0] spawn_subagent(inline) capability token 可能绕过既有权限/审批策略。
证据:executeToolCallWithPermission 实际使用传入 capability(internal/runtime/subagent_tool_executor.go:80-87);子代理执行器在无父 token 时会新签发 token(internal/runtime/subagent_tool_executor.go:140-186),并固定写入 NetworkPolicy: AllowAll(internal/runtime/subagent_tool_executor.go:179);而 inline 能力收敛仅处理 tools/paths,不保留父网络策略(internal/runtime/subagent_tool_invoker.go:109-138)。
风险:当模型在 spawn_subagent 里声明 allowed_tools/allowed_paths 时,会触发新 token 分支,可能把子代理调用从“走常规权限策略+审批”变成“由 capability 直接放行”,与 PR 目标“权限检查、审批与 sandbox 不绕过”冲突。
最小修复建议:仅在存在父 capability token 时签发子 token,并通过 ValidateChildAgainstParent 约束;无父 token 场景不要签发 capability(让调用继续走现有策略引擎与审批流)。同时禁止默认 AllowAll,改为继承/收敛父网络策略。

[P1] mode=todo 写入了 executor=subagent,但主链路未看到生产代码接入调度执行,存在“残留 DAG 语义但不可执行”风险。
证据:spawn_subagent 在 todo 模式只写 todo(internal/tools/spawnsubagent/tool.go:231-278,含 Executor: subagent 在 :255);TodoExecutorSubAgent 生产引用仅见于 scheduler 判定(internal/subagent/scheduler.go:909-912);仓库内 NewScheduler(...) 的调用仅在测试文件,未见 runtime/app 生产路径调用(全局检索结果)。
风险:mode=todo 创建的子代理待办可能长期停留在 pending/blocked,与提示词“由 runtime/todo flow 驱动状态流转”不一致,形成静默任务堆积。
最小修复建议:二选一并落实到代码与提示词:A) 在 runtime 主循环显式接入一次性/顺序 dispatch;B) 明确下线 mode=todo(schema+prompt+文档)避免误用。
直接下线mode
spawn_subagent schema 删除 mode=todo 与 items 分支,只保留 inline 即时执行。
spawn_subagent 解析逻辑移除 todo 模式判断与写 Todo 的代码路径。
Prompt/文档删掉 “mode=todo / runtime todo flow 驱动” 表述,改成“仅 inline”。
测试删除/改写 todo 模式用例,新增“传 mode=todo 必须报错”的回归测试。
权限继承回归:父 capability 为 deny_all network + inline allowed_tools=[webfetch],子代理应被拒绝而不是放行。
无父 capability 场景:inline 指定 allowed_tools 时,仍应触发既有权限策略/审批(验证 ask/deny 事件与决策链路)。
mode=todo 端到端:创建 executor=subagent todo 后,验证是否存在生产调度推进;若无,应测试工具返回中明确告知“仅创建,不会自动执行”。
空转保护:构造重复工具调用流,验证达到阈值后能稳定终止并产生可观测 stop reason。
修复这些问题@xgopilot

@fennoai

fennoai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

修复结果

已按你触发评论中的两项问题完成修复并推送到当前 PR 分支。

本次提交:ec14486

关键改动:

  • spawn_subagent 下线 mode=todo,仅保留 inline
    • 移除 items 写 Todo 路径与相关解析分支。
    • schema 仅保留 mode=inline
    • 传入 mode=todoitems 现在会明确报错。
  • 收紧 inline 子代理 capability 继承链路:
    • 无父 CapabilityToken 场景:不再签发子 token,回到既有权限策略/审批链路。
    • 有父 token 场景:按父能力收敛子能力并签发子 token,强制 security.EnsureCapabilitySubset 校验,网络策略继承父 token,不再默认 AllowAll
  • 子代理执行链路透传父 token(通过 capability 结构透传到工具执行阶段),确保继承策略在执行时生效。
  • 提示词/契约同步:
    • tool_usage.md 改为仅说明 spawn_subagent inline 模式。
    • 移除子代理系统提示中的 mode=todo 表述。

测试与回归:

  • 新增/改写了 spawn_subagent inline-only、mode=todo 报错、权限继承与无父 token 权限链路回归测试。
  • 增加 父 token deny_all network + webfetch 被拒绝的回归测试。
  • 执行:go test ./... -count=1(通过)。

推送与 fork 同步:

未做项:

  • 按你的说明,未修改“最大熔断/空转保护”策略。

View job run

xgopilot and others added 2 commits April 21, 2026 08:55
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
fix: inline-only spawn_subagent mode and capability inheritance hardening
@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

@xgopilot 提高测试覆盖率到100

@fennoai

fennoai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

结果同步

已按你这条指令补充测试并推送到当前 PR 分支 feat/subagent-auto-dispatch(commit: 0dde932)。

本次主要补齐了 internal/provider/openaicompat/chatcompletions/request_test.go

  • 新增 ParseError 全分支测试(nil 响应、读 body 失败、JSON 错误、空 body 回退、HTML 头/HTML 内容识别、纯文本回退)
  • 新增 HTML 错误归一化 helper 测试(normalizeErrorContentType / isLikelyHTMLError / formatHTMLErrorMessage / extractErrorSnippet / stripHTMLTags
  • 新增 ToOpenAIMessageWithBudget 导出入口与补充分支测试(远程图片、负预算归一化、session asset 读取失败、非法 part)

验证结果

已执行:

  • go test ./internal/context ./internal/promptasset ./internal/provider/openaicompat/chatcompletions ./internal/runtime ./internal/tools/spawnsubagent ./internal/tui/core/app -count=1

覆盖率变化(关键包):

  • internal/provider/openaicompat/chatcompletions60.7% -> 83.9%

未完成项说明

你要求“提高测试覆盖率到 100%”。
当前仓库与本 PR 涉及范围较大,仍有大量新增行分布在 runtime/subagent/tools/session/todo 等多处,未在本次提交内全部补齐到 100%。本次先完成了一块核心新增逻辑(错误归一化链路)的覆盖率显著提升,并保证相关包测试通过。

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
@Cai-Tang-www

Cai-Tang-www commented Apr 21, 2026

Copy link
Copy Markdown
Collaborator Author

review @xgopilot

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本次 review 重点发现 2 个需要修正的风险点:runtime 主循环缺少硬熔断,以及 inline subagent 轮次上限被移除。具体见下方 inline comments。

Comment thread internal/runtime/run.go

// Run 执行一次完整的 ReAct 闭环:保存用户输入、驱动模型、执行工具并发出事件。
// 已有会话会先加锁再加载/更新,确保同一会话并发 Run 不会出现状态覆盖;
// 新会话在创建后再绑定会话锁,不同会话可并行执行。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里对应的实现已经移除了 NoProgressStreak/RepeatCycle 硬停;当前 run 只依赖“模型自行停止或外部取消”。如果模型持续返回重复/无进展的 tool calls,run 会无限继续并长期持有 session 锁。建议恢复至少一个 fail-safe(max turn 或 no-progress hard cap)避免会话卡死。

if maxSteps > subAgentMaxStepTurnsLimit {
return subAgentMaxStepTurnsLimit
}
return maxSteps

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxSteps 现在不再有上限截断,而 spawn_subagent 入参校验只要求 max_steps >= 0。这会让单次 inline 子代理轮次可被无界放大,带来高成本/高延迟和限流风险。建议恢复统一 hard cap(如 12/20)并在参数解析阶段做 clamp。

@phantom5099 phantom5099 merged commit db1b34e into 1024XEngineer:main Apr 21, 2026
2 checks passed
This was referenced Apr 21, 2026
@Cai-Tang-www Cai-Tang-www deleted the feat/subagent-auto-dispatch branch April 22, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 切换为顺序 Todo + inline SubAgent 执行闭环(非 DAG)

3 participants