Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
pnpm typecheck
pnpm build
pnpm verify
pnpm verify:browser
- name: Pack the actual candidate once
id: artifact
run: |
Expand Down Expand Up @@ -94,6 +95,7 @@ jobs:
pnpm typecheck
pnpm build
pnpm verify
pnpm verify:browser

harness:
name: Real Harness (${{ matrix.host }})
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,19 @@ Defaults work without extra setup. A trusted profile can override member behavio
memberModel: deepseek-v4
memberMaxDepth: 1
maxMembers: 8
captainAvatar: '' # Empty keeps the packaged captain whale
roleAvatars: # Optional role/category overrides
researcher: https://example.com/researcher.webp
engineer: https://example.com/engineer.png
avatarMaxBytes: 2097152 # Default/hard maximum: 2 MiB; may be reduced
```

`memberProvider` is the sub-agent runtime backend (`spawn` / `fork`), not an LLM provider. Cross-LLM-provider routing uses the optional `provider` + `model` fields of `agent_teams_add_member`; `memberModel` is only a model default for all members. A member on the captain's current provider/model inherits the captain's reasoning effort, while a changed provider or model automatically uses the target model's default. To request a particular effort, pass the optional `reasoning_effort` field — one of the target model's supported effort ids, or `"default"` to force the model's own default.

`slashCommand: false` disables the deterministic `/agent-teams` activation surfaces (slash command and gesture boundary), leaving the natural-language trigger as the only entry point.

The **Avatar** action beside a live team's title lets the captain paste an HTTP(S) URL, upload PNG/JPEG/WebP for the captain or any member, or restore the default. Per-team/member choices outrank `roleAvatars`, which outrank packaged role whales; unmatched members still use the initial-letter fallback. Uploads live under the team's `avatars/` directory and `team.json` stores only a short reference. Remote images load through the same-origin Host proxy for Desktop CSP compatibility.

## Boundaries

- One captain leads one active team at a time.
Expand Down
7 changes: 7 additions & 0 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,19 @@ dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.16-rc.
memberModel: deepseek-v4
memberMaxDepth: 1
maxMembers: 8
captainAvatar: '' # 空值保留默认队长鲸鱼
roleAvatars: # 可选:覆盖角色分类头像
researcher: https://example.com/researcher.webp
engineer: https://example.com/engineer.png
avatarMaxBytes: 2097152 # 默认/最大 2 MiB,可调小
```

这里的 `memberProvider` 指子 Agent 的运行后端(`spawn` / `fork`),不是 LLM provider。跨 LLM provider 由 `agent_teams_add_member` 的可选 `provider` + `model` 参数表达;`memberModel` 只是所有成员的模型默认覆盖。成员沿用队长当前 provider/model 时会继承队长的思考强度;provider 或 model 任一改变时会自动使用目标模型的默认档。需要指定特定强度时,可传入可选的 `reasoning_effort` 参数(目标模型支持的档位 id,或 `"default"` 表示强制使用模型自身默认档)。

`slashCommand: false` 可关闭确定性的 `/agent-teams` 激活面(slash 命令与手势边界),仅保留自然语言触发。

活动面板团队标题旁的“头像”入口可以为当前队长或任一成员粘贴 HTTP(S) URL、上传 PNG/JPEG/WebP,或恢复默认。会话级设置优先于 `roleAvatars`,后者再优先于内置角色鲸鱼;无匹配成员仍显示首字母。上传文件保存在团队目录的 `avatars/` 下,`team.json` 只记录短引用。外链由 Host 同源代理加载,以兼容 Desktop CSP。

## 使用边界

- 一个队长同一时间只能带一个活动团队。
Expand Down
6 changes: 6 additions & 0 deletions cordis.patch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@
stateDir: .agent-teams
# Provider used to spawn member subagents ('spawn' or 'fork').
memberProvider: spawn
# Optional default captain image. Empty keeps the packaged lead whale.
captainAvatar: ''
# Optional role/category -> HTTP(S) or same-origin image URL overrides.
roleAvatars: {}
# Upload and remote-proxy limit (default and hard maximum: 2 MiB).
avatarMaxBytes: 2097152
9 changes: 8 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,17 @@
fallback: # 主模型不可用时的第二选择
provider: openai
model: gpt-5.5
captainAvatar: '' # 默认队长头像;空值保留内置鲸鱼
roleAvatars: # 可选:角色分类 -> 图片 URL
researcher: https://example.com/researcher.webp
engineer: https://example.com/engineer.png
avatarMaxBytes: 2097152 # 上传/外链代理限制,最大 2 MiB
```

最终优先级为:成员显式 `provider` + `model` / `model` → `memberModel` → 队长当前路由。成员沿用队长当前 provider/model 时继承队长的思考强度;provider 或 model 任一改变时自动使用目标模型的默认档。显式 `reasoning_effort`(目标模型支持的档位 id,或 `"default"`)优先,并在目标 provider/model 上创建前校验;不兼容时成员创建会明确失败。最终生效的 provider/model/思考强度会写入 `team.json`,供状态查询和成员冷恢复使用。

头像优先级为:队长/成员的会话级自定义头像 → `roleAvatars` 分类覆盖 → 内置角色鲸鱼 → 首字母圆形。活动面板团队标题旁的“头像”入口可选择队长或成员,使用 HTTP(S) URL、上传 PNG/JPEG/WebP,或恢复默认。上传文件写入 `<stateDir>/<teamId>/avatars/`,`team.json` 只保存 URL 或 `managed:` 短引用;Host 会校验大小、MIME、文件签名和文件名,并通过同源代理输出远程图片以兼容 Electron CSP。

## 使用协议

插件提示段会指导模型按两阶段协议执行:创建 staged 团队 → 写入可编辑成员占位 → 拆任务并声明依赖 → 等待用户审查 → **Approve & Run** 后原子创建成员并启动调度 → 队长监控/引导 → 汇报后 `agent_teams_delete`。staged 阶段没有子会话、不会领取任务。只有用户明确要求跳过审查时才使用 `approval: automatic`。成员之间可以直接互发消息,无需队长中转。驻留成员在中断或正常结束一轮后若仍持有 `claimed/in_progress` 任务,该 attempt 会停驻;只有显式重试/转派/接管才会撤销它。本进程已经观察过的停驻 attempt 在 Harness 回收其 AgentHandle 后仍保持原 attempt,Captain 轮询 `agent_teams_status` 不会因此重铸。只有冷启动或从未被本进程观察过的开放任务,才会自动恢复一次;恢复投递失败会回到原来的 capability,而不会变成可无限重派的 `pending`。
Expand Down Expand Up @@ -154,6 +161,6 @@ profiles:

## 验证

- 离线与生命周期:`pnpm build && pnpm typecheck && pnpm verify`。除基础检查外,还包含 8 成员、31 节点多层 DAG(运行中扩展至 38 任务)的故障矩阵:并发接管/移除、50 次迟到写入、4 个开放任务冷重启、7 路认领竞争、40 次终态覆盖、42 条消息突发和最终归档;组合验证 `dsh --profile agent-teams-check --dump-config`
- 离线与生命周期:`pnpm build && pnpm typecheck && pnpm verify`。除基础检查外,还包含头像 MIME/签名/大小/路径穿越/CSRF/旧状态兼容测试,以及 8 成员、31 节点多层 DAG(运行中扩展至 38 任务)的故障矩阵:并发接管/移除、50 次迟到写入、4 个开放任务冷重启、7 路认领竞争、40 次终态覆盖、42 条消息突发和最终归档;组合验证 `dsh --profile agent-teams-check --dump-config`
- 真实 e2e:`dsh plugin --profile headless add <path>` 后 `dsh --profile headless "用 AgentTeams …"`,核对 `.agent-teams/` 状态文件与会话日志事件流
- GUI:独立实例 + ego-browser(详见 `verification-guide.md`)
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit",
"sync:skill": "node scripts/sync-skill.mjs",
"verify:skill": "node scripts/sync-skill.mjs --check",
"verify": "node scripts/verify.mjs && node scripts/fallback-tdd.mjs && node scripts/member-failure-tdd.mjs && node scripts/quality-gates-tdd.mjs && node scripts/lifecycle-verify.mjs && node scripts/stress-verify.mjs && pnpm verify:web-routes && pnpm verify:release && pnpm verify:skill && pnpm verify:harness-contract && pnpm verify:http-body && pnpm verify:compatibility",
"verify": "node scripts/verify.mjs && node scripts/avatar-verify.mjs && node scripts/fallback-tdd.mjs && node scripts/member-failure-tdd.mjs && node scripts/quality-gates-tdd.mjs && node scripts/lifecycle-verify.mjs && node scripts/stress-verify.mjs && pnpm verify:web-routes && pnpm verify:release && pnpm verify:skill && pnpm verify:harness-contract && pnpm verify:http-body && pnpm verify:compatibility",
"prepublishOnly": "pnpm build && pnpm verify",
"verify:avatar": "node scripts/avatar-verify.mjs",
"verify:browser": "node scripts/avatar-browser-verify.mjs",
"verify:web-routes": "node scripts/web-routes-verify.mjs",
"verify:release": "node --test scripts/release-metadata.test.mjs",
"verify:harness-contract": "node scripts/harness-compat-tdd.mjs && node scripts/lifecycle-verify.mjs --modern-harness && node scripts/member-failure-tdd.mjs --modern-harness",
Expand Down Expand Up @@ -224,6 +226,7 @@
"@types/react": "~18.3.1",
"@types/react-dom": "^18.3.7",
"lightningcss": "^1.33.0",
"playwright-core": "^1.63.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tsdown": "0.22.2",
Expand Down
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading