Skip to content

feat(): 实现 SubAgent WorkerRuntime 与角色策略(#274)#295

Merged
phantom5099 merged 11 commits into
1024XEngineer:mainfrom
Cai-Tang-www:feat(subagent)
Apr 15, 2026
Merged

feat(): 实现 SubAgent WorkerRuntime 与角色策略(#274)#295
phantom5099 merged 11 commits into
1024XEngineer:mainfrom
Cai-Tang-www:feat(subagent)

Conversation

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator

背景

实现 #274:引入可复用的 SubAgent WorkerRuntime 内核,建立角色策略模型,并完成 Runtime 侧工厂注册与执行入口。

本 PR 不改动现有主会话单代理 Run 主链路,仅新增可独立调用的子代理能力。

本次改动

1) 新增 internal/subagent 核心模块

  • 定义领域模型与接口:RoleTaskBudgetCapabilityOutputWorkerRuntimeFactory
  • 新增 RolePolicy 与默认角色策略:researcher / coder / reviewer
  • 新增 WorkerRuntime 默认实现:Start / Step / Stop / Result / State / Policy
  • 新增默认引擎与工厂实现:defaultEngine + WorkerFactory
  • 新增输出契约校验:required sections + summary 必填

2) Runtime 接入

  • Service 增加 subAgentFactory 字段与默认注入
  • 新增工厂注册方法:SetSubAgentFactorySubAgentFactory
  • 新增独立执行入口:RunSubAgentTask
  • 新增子代理生命周期事件:
    • subagent_started
    • subagent_progress
    • subagent_completed
    • subagent_failed
    • subagent_canceled

3) 测试

  • internal/subagent:角色策略、生命周期、错误分支、输出契约
  • internal/runtime:工厂注册与 RunSubAgentTask 事件流
  • 全量测试通过:go test ./... -count=1

设计边界

Closes #274
Refs #273

@codecov

codecov Bot commented Apr 14, 2026

Copy link
Copy Markdown

fennoai[bot]

This comment was marked as outdated.

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

/code 解决你说的review,帮我解决冲突,然后补齐测试率

@fennoai

fennoai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

结果

已按你这条指令完成:处理 review 冲突点、补测试并推送到当前 PR 分支 feat(subagent)

已完成内容

  1. 修复 review 提到的核心问题
  • internal/runtime/subagent_run.go
    • context.Canceled / context.DeadlineExceeded 分流为取消语义,终态事件改为 subagent_canceled,并保证 Result.StopReason 与事件一致。
    • subagent_progress 改为非阻塞发射,避免慢消费者反压执行路径。
  • internal/subagent/worker.go
    • Start 阶段新增 capability 与 policy.AllowedTools 的 fail-closed 约束(越权工具直接报错;未指定工具时回落到策略允许集)。
    • Step 在引擎返回上下文取消错误时映射为 StateCanceled / StopReasonCanceled
    • StepInput.Trace 改为仅复制最近窗口,避免每步全量拷贝导致复杂度放大。
  • internal/subagent/output_contract.go
    • RequiredSections 从“仅校验 summary”修正为“所有声明 required 的 section 均需有内容”。
    • 抽出 section 名称归一化与合法性校验,供策略校验复用。
  • internal/subagent/policy.go
    • RolePolicy.Validate 调整为只校验 required section 名称合法性(避免把内容校验提前到策略定义阶段)。
  1. 补齐测试
  • 新增:
    • internal/subagent/engine_test.go
    • internal/subagent/output_contract_test.go
  • 扩展:
    • internal/subagent/worker_test.go
    • internal/runtime/subagent_run_test.go
    • internal/runtime/subagent_factory_test.go
  • 新增覆盖点包括:取消态事件流、start 阶段 capability 越权失败、输出契约各 required section 校验、trace 窗口限制、nil/边界分支等。
  1. 验证
  • 已执行:go test ./... -count=1(通过)
  • 覆盖率关键结果(局部):
    • internal/subagent/engine.go 100%
    • internal/runtime/subagent_factory.go 100%
    • internal/runtime/subagent/subagent_runinternal/subagent/worker 相关分支覆盖已明显提升

提交信息

  • Commit: 9384e80
  • 已推送到:Cai-Tang-www/neo-code 分支 feat(subagent)(即当前 PR head)

未执行项

  • 未执行额外 CI 平台侧操作(如手动触发外部流水线);仅完成本地构建/测试与代码推送。

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

@xgopilot 解决当前合并冲突点

@fennoai

fennoai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

处理结果

已完成“解决当前合并冲突点”,并已推送到当前 PR 分支 feat(subagent)

已完成内容

  • 识别并处理与 origin/main 的冲突根因文件:
    • internal/runtime/events.go
    • internal/runtime/runtime.go
  • events.go 对齐到 main 的事件 envelope 结构,并新增兼容层文件:
    • internal/runtime/events_subagent.go(保留 subagent 生命周期事件与旧事件名兼容常量)
  • 引入 internal/runtime/controlplane(与 main 对齐)以承载事件负载类型依赖。
  • defaultMaxLoops 拆分到 internal/runtime/runtime_limits.go,减少与 runtime.go 主干冲突。
  • 重构 subagent_factory 存储方式,避免在 Service 结构体上持续冲突:
    • internal/runtime/subagent_factory.go
    • internal/runtime/subagent_factory_test.go

验证结果

  • 本地测试通过:go test ./... -count=1
  • 三方合并验证通过:git merge-tree --write-tree --name-only --messages origin/main HEAD(无冲突)
  • GitHub PR 状态已恢复:
    • mergeStateStatus: CLEAN
    • mergeable: MERGEABLE

提交与推送

  • 已推送提交:
    • cc74bd4
    • 730a61b
    • a5bf778
  • 远端分支:Cai-Tang-www/neo-code:feat(subagent)

未执行项

  • 未执行额外的 CI 平台外操作(如手工触发外部流水线),仅完成代码修复、测试与推送。

View job run

xgopilot and others added 3 commits April 14, 2026 16:18
Generated with [codeagent](https://github.com/qbox/codeagent)

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

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

Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
@wynxing

wynxing commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

/review

fennoai[bot]

This comment was marked as outdated.

fennoai[bot]

This comment was marked as outdated.

fennoai[bot]

This comment was marked as outdated.

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

/code 修复review

@fennoai

fennoai Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

处理结果

已按“修复review”完成代码修复并推送到当前 PR 分支 feat(subagent)

已完成项

  1. 修复 subagent_factory 生命周期泄漏风险
  • 文件:internal/runtime/subagent_factory.gointernal/runtime/runtime.go
  • 调整为 Service 实例字段持有 subAgentFactory,移除全局 sync.Map[*Service]
  • 新增读写锁保护并在 NewWithFactory 注入默认工厂,避免全局强引用导致的 GC 泄漏风险。
  1. 修复默认引擎输出契约不一致
  • 文件:internal/subagent/engine.go
  • 默认引擎完成态输出补齐 summary/findings/patches/risks/next_actions/artifacts,与默认角色策略 required sections 对齐。
  1. 补充测试覆盖
  • 文件:internal/runtime/subagent_factory_test.go
    • 新增 TestServiceSubAgentFactoryIsolationAcrossInstances,验证工厂按实例隔离。
  • 文件:internal/subagent/engine_test.go
    • 新增默认引擎 required sections 非空校验。
    • 新增默认引擎输出满足三种默认角色策略契约校验。

验证

  • 已执行:go test ./... -count=1(通过)

提交与推送

  • Commit: e43f70c
  • Push: Cai-Tang-www/neo-code:feat(subagent)

未执行项

  • 未执行 GitHub 平台侧 CI 操作(仅完成本地测试与推送)。

View job run

…t output contract

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

@xgopilot 解决冲突

@fennoai

fennoai Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

处理结果

已完成本次“解决冲突”,并已把修复推送到当前 PR 分支 feat(subagent)

已完成内容

  • 对齐 main 的 runtime 拆分结构,消除 internal/runtime/runtime.go 结构冲突来源:
    • 新增并对齐:internal/runtime/event_emitter.gointernal/runtime/session_scheduler.go
    • runtime.go 回归与 main 同构(保留本 PR 所需能力通过其它文件承载)
  • 调整 subagent 工厂持有方式,避免依赖 Service 结构体字段导致的冲突热点:
    • 更新 internal/runtime/subagent_factory.go
  • 对齐 state 与事件 envelope 依赖,修复受影响调用与测试:
    • 更新 internal/runtime/state.go
    • 更新 internal/runtime/run.go
    • 更新 internal/runtime/session_mutation.go
    • 更新 internal/runtime/runtime_test.go
    • 对齐 internal/runtime/runtime_internal_helpers_test.gomain,消除测试文件冲突

验证

  • go test ./... -count=1 通过
  • git merge-tree --write-tree --name-only --messages origin/main HEAD 无冲突(exit code 0)

提交与推送

  • 新增提交:
    • 062846d
    • 631d8ab
    • 1afecba
  • 已推送到:Cai-Tang-www/neo-code:feat(subagent)

未执行项

  • 未执行平台侧 CI/CD 人工操作(仅完成本地测试与冲突校验)。

View job run

xgopilot and others added 3 commits April 15, 2026 02:41
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
@phantom5099

Copy link
Copy Markdown
Collaborator

/review

@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.

Focused review on runtime/subagent integration. I found a few correctness and safety gaps worth addressing before merge.

Comment thread internal/runtime/subagent_run.go Outdated
Error: errorText(stepErr),
}
select {
case s.events <- RuntimeEvent{

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.

emitSubAgentProgress writes directly to s.events with a partially-filled RuntimeEvent, so envelope metadata (Timestamp, PayloadVersion, and run-scoped fields like Turn/Phase) stays zero-value for progress events. Since this PR introduces a richer event envelope, this creates inconsistent event contracts across event types. Please route this through the same envelope path (emitWithEnvelope / run-scoped emitter) so metadata is consistently populated.

Comment thread internal/runtime/subagent_run.go Outdated
if result.State == subagent.StateSucceeded {
return result, nil
}
return result, errors.New(result.Error)

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.

return result, errors.New(result.Error) can return an empty-string error when result.Error is blank (possible for custom WorkerRuntime implementations). Please add a fallback error message that includes at least state/stop_reason to keep failures diagnosable.

Comment thread internal/subagent/worker.go Outdated
w.stepCount++
delta := strings.TrimSpace(stepOutput.Delta)
if delta != "" {
w.trace = append(w.trace, delta)

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.

w.trace appends every step but only the last traceWindowSize entries are ever consumed (cloneRecentTrace). With larger MaxSteps, this grows memory and allocation cost unnecessarily in the hot loop. Consider trimming in place (or using a ring buffer) when appending, so internal trace storage remains bounded.

}, nil
}

// bindCapabilityToPolicy 将 capability 约束在角色策略允许的工具集合内。

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.

Capability.AllowedPaths is accepted and normalized, but never enforced in Start/bindCapabilityToPolicy (only tools are filtered). This creates a policy gap: callers can provide path boundaries that are silently ignored. Either enforce path constraints here (or at the engine boundary) or remove the field until it is enforced to avoid a false sense of confinement.

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

/code 修复review

@fennoai

fennoai Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

处理结果

已按“修复review”完成修复并推送到当前 PR 分支 feat(subagent)

已完成内容

  1. 修复 subagent_progress 事件 envelope 不一致
  • 文件:internal/runtime/subagent_run.go
  • 调整为进度事件也写入完整 envelope 元数据(TimestampPayloadVersionTurn),同时保持非阻塞投递。
  1. 修复子代理终态空错误文本问题
  • 文件:internal/runtime/subagent_run.go
  • 新增 subAgentResultError 兜底:当 result.Error 为空时,返回包含 statestop_reason 的可诊断错误。
  1. 修复 trace 热路径内存增长问题
  • 文件:internal/subagent/worker.go
  • 新增有界追加逻辑 appendTraceBounded,在每次追加 delta 时将内部 trace 存储限制在 traceWindowSize
  1. 修复 Capability.AllowedPaths 被静默忽略问题
  • 文件:internal/subagent/worker.go
  • bindCapabilityToPolicy 中改为 fail-closed:若传入 AllowedPaths,立即返回错误,避免产生“已受限”假象。
  1. 补充/更新测试
  • 文件:internal/runtime/subagent_run_test.go
    • 校验 subagent_progress 事件包含 envelope 元数据。
    • 新增自定义 worker 失败且空错误文本时的 fallback 错误断言。
  • 文件:internal/subagent/worker_test.go
    • 新增 AllowedPaths fail-closed 测试。
    • 新增 trace 内部存储上限测试。

验证结果

  • go test ./internal/runtime -run TestServiceRunSubAgentTask -count=1 通过
  • go test ./internal/subagent -run 'TestWorker(StartCapabilityPolicyGuard|TraceStorageBounded|TraceWindow)' -count=1 通过
  • go test ./... -count=1 通过

提交与推送

  • Commit: 727ed3f
  • Push: Cai-Tang-www/neo-code:feat(subagent)

未执行项

  • 未执行平台侧 CI/CD 人工操作(仅完成本地测试与代码推送)。

View job run

xgopilot and others added 2 commits April 15, 2026 03:26
…y bounds

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: Cai-Tang-www <106404101+Cai-Tang-www@users.noreply.github.com>
@phantom5099 phantom5099 merged commit 5c44480 into 1024XEngineer:main Apr 15, 2026
2 checks passed
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(subagent): 引入 WorkerRuntime 抽象与角色策略(researcher/coder/reviewer)

4 participants