Skip to content

feat: 完成SubAgent DAG调度器并修复infra稳定性#317

Merged
phantom5099 merged 5 commits into
1024XEngineer:mainfrom
Cai-Tang-www:feat(todo)
Apr 16, 2026
Merged

feat: 完成SubAgent DAG调度器并修复infra稳定性#317
phantom5099 merged 5 commits into
1024XEngineer:mainfrom
Cai-Tang-www:feat(todo)

Conversation

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator

关联

Closes #275

本次改动

1) SubAgent 调度器落地(issue #275

  • 新增 Task DAG 调度器:依赖阻塞/解锁、并发上限、预算超时、失败重试与放弃。
  • 支持 Todo 领取与回写:claim -> in_progress -> completed/failed/canceled。
  • 增加调度可观测事件(queued/claimed/running/completed/retry_scheduled/failed/canceled/blocked/finished)。
  • 新增调度相关测试矩阵:DAG 校验、依赖解锁、并发限制、重试策略、revision 冲突与取消回写。

2) Todo 模型增强(服务调度器回写)

  • 扩展 Todo 字段:retry_count、retry_limit、next_retry_at。
  • 补齐 Session Todo 更新逻辑与测试覆盖。

3) Infra 稳定性修复(顺带修复全量测试失败)

  • 统一跨平台剪贴板图片不支持错误常量,修复编译失败。
  • 修复 image MIME 识别分支:保留扩展名 MIME,同时避免 application/octet-stream 抢占魔数识别。
  • SaveImageToTempFile 支持 TMPDIR,补齐对应失败路径。

验证

  • 已执行:go test ./...
  • 结果:通过

@codecov

codecov Bot commented Apr 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.77049% with 99 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/subagent/scheduler.go 78.28% 62 Missing and 34 partials ⚠️
internal/subagent/scheduler_graph.go 96.29% 1 Missing and 1 partial ⚠️
internal/tui/infra/image.go 83.33% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

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

I found 3 issues worth fixing before merge (2 high, 1 medium): role trust boundary/role drift, missing cancellation on scheduler error exits, and retry failure reason being wiped during blocked state.

Comment thread internal/subagent/scheduler_types.go Outdated
// defaultRoleSelector 生成默认角色选择器:优先读取 owner_id 中的合法角色,否则回退默认角色。
func defaultRoleSelector(defaultRole Role) RoleSelector {
return func(todo agentsession.TodoItem) Role {
candidate := Role(todo.OwnerID)

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.

defaultRoleSelector treats todo.OwnerID as trusted role input. OwnerID is task data and mutable, so this allows role injection (security boundary issue). It also conflicts with ClaimTodo writing runtime worker IDs into OwnerID, causing retry attempts to silently change role selection. Role should come from trusted scheduler policy/config, not persisted task owner metadata.

s.sortReadyTasks(ready, state.readySince)

started, err := s.startReadyTasks(ctx, ready, state)
if err != nil {

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.

On non-context errors from collectReadyTasks/startReadyTasks, Run returns immediately without canceling already-running tasks (state.running). That can leave todos stuck in in_progress and drop outcome writeback. Consider canceling/marking running tasks before returning on these error paths, same as the ctx.Err()/handleOneOutcome branches.

Comment thread internal/session/todo.go Outdated
}

if item.Status != TodoStatusFailed {
if item.Status != TodoStatusFailed && item.Status != TodoStatusPending {

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.

This normalization clears FailureReason for blocked todos, but scheduler retry logic writes FailureReason while setting status=blocked (handleTaskFailure). The reason is erased immediately, so retry state loses failure context. Either preserve reason for blocked or store retry reason separately.

@Cai-Tang-www

Copy link
Copy Markdown
Collaborator Author

/code 帮我修复review,然后解决test覆盖率问题

@fennoai

fennoai Bot commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

完成情况

已按你的要求修复 review 问题并处理覆盖率缺口,变更已推送到当前 PR 分支 feat(todo)

已修复问题

  1. internal/subagent/scheduler_types.go
  • 修复默认角色选择信任边界:defaultRoleSelector 不再读取 todo.OwnerID,仅使用调度器可信默认角色。
  1. internal/subagent/scheduler.go
  • 修复调度循环异常路径:当 collectReadyTasks / startReadyTasks 返回非上下文错误时,先执行 cancelRunningTodos,避免运行中任务遗留为 in_progress
  1. internal/session/todo.go
  • 修复失败原因丢失:blocked 状态不再清空 FailureReason,保留重试失败上下文。

测试与覆盖率

  • 新增/调整测试文件:
    • internal/subagent/scheduler_test.go
    • internal/session/todo_test.go
  • 本地验证:go test ./... 通过。
  • 关键覆盖率提升(本地 go test -coverprofile):
    • internal/subagent/scheduler.go: 79.5% -> 85.4%
    • internal/subagent/scheduler_executor.go: 85.7% -> 100.0%
    • internal/subagent/scheduler_graph.go: 95.0% -> 100.0%
    • internal/subagent/scheduler_types.go: 96.3% -> 100.0%
    • internal/session/todo.go: 82.8% -> 89.7%

提交信息

  • Commit: b74c29d
  • 已推送到:Cai-Tang-www/neo-code:feat(todo)

未执行项:未直接访问 Codecov 平台复核 patch 百分比(本地已完成覆盖率回归验证)。

View job run

- remove default role derivation from todo owner metadata
- cancel running tasks when scheduler loop exits on internal errors
- preserve blocked todo failure reason for retry diagnostics
- add coverage for scheduler/session error and edge branches

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 16, 2026

Copy link
Copy Markdown
Contributor

处理结果

已按“解决冲突”完成修复并推送到当前 PR 分支 feat(todo)

本次修改

  • 对齐并合并 origin/main 与当前分支在以下冲突代码块的语义:
  • internal/tui/infra/clipboard_common.go
  • internal/tui/infra/image.go
  • internal/tui/infra/infra_test.go
  • 关键处理点:
  • TMPDIR 使用 strings.TrimSpace 后再传入 os.CreateTemp
  • 图片 MIME 识别优先 image/* 扩展名,魔数判断保持 gif/webp 分支完整,兜底返回 detected
  • 剪贴板回退测试兼容 nilerrClipboardImageUnsupported 两种合法结果

验证

  • 已执行:go test ./...
  • 结果:全部通过

提交与推送

  • Commit: dd2cc37
  • Push: HEAD:feat(todo)

未执行项:未进行额外功能改动(仅处理冲突相关代码与测试对齐)。

View job run

… detection

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

/code 继续解决冲突

@fennoai

fennoai Bot commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

处理结果

已继续完成冲突修复,并推送到当前 PR 分支 feat(todo)

本次修改

  • 修复冲突文件:internal/tui/infra/clipboard_common.go
  • 调整 SaveImageToTempFilepattern 分支后的空行布局,使其与 origin/main 同段改动可自动合并,消除三方合并冲突。

验证

  • 已执行:go test ./...
  • 结果:通过
  • 额外校验:基于 origin/main 的三方合并模拟已无冲突标记

提交与推送

  • Commit: 867dfda
  • Push: HEAD -> feat(todo)

未执行项

  • 未做额外功能改动(仅处理冲突消解)。

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 self-assigned this Apr 16, 2026
@phantom5099 phantom5099 merged commit 24ec17c into 1024XEngineer:main Apr 16, 2026
2 checks passed
@Cai-Tang-www Cai-Tang-www deleted the feat(todo) branch April 19, 2026 17:01
@fennoai fennoai Bot mentioned this pull request Apr 24, 2026
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): 实现 Task DAG 调度器(依赖、并发、预算、重试)

3 participants