Skip to content

feat: add Parallel Emission opt-in across protocol surfaces - #147

Open
spacexun2 wants to merge 4 commits into
NanmiCoder:mainfrom
spacexun2:feat/parallel-emission
Open

feat: add Parallel Emission opt-in across protocol surfaces#147
spacexun2 wants to merge 4 commits into
NanmiCoder:mainfrom
spacexun2:feat/parallel-emission

Conversation

@spacexun2

Copy link
Copy Markdown
Contributor

Summary

This implements Slice 1 — Parallel Emission of the split described in #62 (refs #62). Slice 2 (per-task probes, Next Probe At, Silent Kick / Captain Wake / Mailbox Wake) follows separately; nothing in that slice is touched here.

Parallel Emission is the opt-in ability for models that can emit several agent_teams_* tool calls in one assistant message. It is a single boolean in the new agent-teams settings namespace, parallelToolCalls, default off, surfaced as a 支持工具并行 checkbox on the plugin's Plugins-configuration card:

  • Host: when the settings service exists, the plugin lazily registers the agent-teams namespace with exactly one field (schema default false). Without the service (headless profiles, older hosts) the registration never happens, the switch reads false, and everything else is unaffected.
  • Protocol surfaces branch on the live value: the captain usage section is evaluated at assemble time, member personas freeze the value at spawn (already-spawned members are never rewritten), and assignment prompts read it at dispatch. When on, the surfaces allow claim + in_progress, completed + report, and several create_task calls in one response; when off, the surfaces keep the serial protocol — member personas and assignment prompts are byte-identical to the previous text, and the usage section adds one explicit serial sentence ("Issue one agent_teams_* tool call per response ..."). Same-response calls still execute in order, so later creates can reference earlier ids from the same response — and dependency ids must still exist: create_task rejects unknown dependencies exactly as before (pinned by a new lifecycle check; PR 通过消除 status 轮询和启用并行工具调用减少 token 浪费 #48's empty-dependency branch stays rejected).
  • Web client: a Plugins-tab card keyed by the agent-teams namespace under the settings.plugin.item type-only slot contract. Both client imports are type-only and all writes go through the cordis settingsScope service, so the bundle purity gate mechanically guarantees no cross-plugin value import. The checkbox is disabled when the namespace is not served or the settings document is read-only (memory mode). It never writes maxParallelToolCalls — the Agent Loop execution pool stays on the Agent Loop card (negative source pins enforce this).

Docs: one sentence in each README's Configuration section and a short section in docs/usage.md.

Validation

  • tsc -p tsconfig.json --noEmit, tsc -p tsconfig.client.json --noEmit, and the full build (clean-build + both tsc passes + tsdown, including the client bundle purity gate) pass.
  • node scripts/verify.mjs: all 184 checks pass, including new pins for the settings schema default ({} resolves parallelToolCalls: false), persona / assignment / usage on-vs-off branches, the type-only Plugins-tab registration keyed by the namespace, and negative guards keeping maxParallelToolCalls out of this plugin's sources.
  • node scripts/lifecycle-verify.mjs drives the real compiled create_task with a never-created dependency id and asserts it fails loud (no forward references).
  • fallback-tdd, member-failure-tdd (both harness modes), quality-gates-tdd, harness-compat-tdd, web-routes-verify, release-metadata, http-body, compatibility, doctor, and stress-verify all pass; node --test scripts/compatibility.test.mjs additionally skips its doctor-bin-symlink case on this machine (EPERM: operation not permitted, symlink — Windows without symlink privilege), reproduced identically on clean main.
  • Known-local flake note: two lifecycle-verify checks (unfinished captain takeover returns to a member when the captain becomes idle, activity refines residency through the live Agent registry) fail intermittently on this machine on clean main as well (reproduced in a pristine worktree, plain and --modern-harness variants) — pre-existing timing flakiness, unrelated to this branch.

Slice 2 follow-up will cover the per-task probe clock and the protocol rewrites around polling, wake, and end-of-turn.

Register the agent-teams settings namespace (parallelToolCalls, default
false) where the host provides the settings service, and branch the three
protocol surfaces on the live value: the captain usage section reads it at
assemble time, member personas freeze it at spawn, and assignment prompts
read it at dispatch. The web client contributes a Plugins-tab checkbox
card keyed by the namespace through type-only slot contracts, writing only
parallelToolCalls and never the Agent Loop maxParallelToolCalls knob.
Hosts without the settings service keep the serial protocol unchanged.
Pin the settings schema default, the persona/assignment/usage on and off
branches, the type-only plugins-tab registration, and negative guards
keeping maxParallelToolCalls out of this plugin. Drive a real create_task
through the lifecycle harness to prove unknown dependency ids still fail
loud, so same-response emission cannot smuggle forward references.
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.

1 participant