Skip to content

Sparse per-task probes and optional Parallel Emission #62

Description

@Elsen823

Sparse per-task probes and optional Parallel Emission

Vocabulary follows CONTEXT.md. Do not merge PR #48 as-is.

Test seams

Prefer two existing seams. Do not add a new polling service or a per-task status tool.

  1. Team scheduler — kickTeam / kickMember, Attempt Start (beginTaskAttempt), and the existing agent/status idle edge. Next Probe At, Silent Kick, Captain Wake, and Mailbox Wake all hang off this seam. Inject a clock in tests.
  2. Protocol policy — captain usage section (assembled live), member persona (spawn snapshot), assignment prompt, Status Probe / create-task tool copy, and the AgentTeams settings section that only flips Parallel Emission.

If these seams are wrong, say so before implementation. The Activity View stays a consumer of snapshots; it is not a probe clock.

Problem Statement

Running a team burns a large share of tokens on repeated Status Probes. The captain protocol currently tells the model to poll until every task is terminal. Members often split claim, in_progress, completed, and the captain report across extra ReAct steps. After work is done, models still emit recap turns.

Users watching the Activity View already see Task Records and Member Liveness. Ending a Captain Turn does not stop the team or freeze the panel, but the protocol does not say that, so captains keep polling. If the captain instead goes idle and never Probes, a member that stays running on an open task, or a completion report that only reached the mailbox, can sit unnoticed by the captain model even though the human can see it.

A related GitHub change tried to fix the waste with prompt bans, sleep, and relaxed dependency checks. Those bans did not hold, and they removed the Status Probe recovery kick that idle members still need.

Separately, some models can put several AgentTeams tool calls in one assistant message (Parallel Emission). That saves steps even when exclusive tools still run in order. The agent-loop execution pool is a different knob and must not be overloaded. Parallel Emission should be opt-in, default off, and visible in plugin configuration.

Solution

Keep three pictures of progress: Task Record and Member Liveness are real; the Activity View is the human projection and may lag. Captains may end a Captain Turn after dispatch and wait for Wake. They must not poll Status Probe in a loop or sleep-wait.

Each open attempt carries Next Probe At on the Task Record. Attempt Start arms it (ten minutes, not a user setting). A successful task update or a completion report for that task clears it. When due, runtime performs Silent Kick first. Captain Wake happens only if the task is still non-terminal and the assignee is still running or gone. Idle members that still own open work stay on the existing scheduler retry. After a Wake, re-arm; do not Wake in a tight loop.

Mailbox Wake is independent: if the captain is idle and the captain mailbox has unread reports, Wake soon. Do not wait for Next Probe At.

Parallel Emission is a boolean in the AgentTeams settings namespace, default false, shown as a checkbox on the Plugins configuration card for this plugin. When on, captain usage, new member personas, and assignment prompts may allow several AgentTeams tool calls in one response. Existing member personas stay as spawned. Dependency ids must still exist; same-response creates rely on exclusive in-order execution.

User Stories

  1. As a user, I want the Activity View to keep showing live members after the captain stops calling tools, so that ending a Captain Turn does not look like the team died.
  2. As a user, I want the Activity View to stay independent of whether the create card is on screen, so that I can watch work in a long transcript.
  3. As a user, I want Task Record progress and Member Liveness composed into the Activity View, so that I can tell “queued” from “actually running”.
  4. As a user, I want to leave the captain idle without the panel freezing, so that I can read the DAG while members work.
  5. As a captain, I want to end a Captain Turn after tasks exist, so that I do not burn cache_read waiting.
  6. As a captain, I want member completion messages to Wake me, so that I can present results without polling.
  7. As a captain, I want to stay in the turn and send guidance when I choose, so that ending the turn is allowed rather than required.
  8. As a captain, I want protocol text that does not tell me to poll Status Probe until every task is terminal, so that I stop empty status loops.
  9. As a captain, I want protocol text that forbids bash sleep as a wait, so that I do not add sleep+status cycles.
  10. As a captain, I want to call Status Probe at most as a diagnostic, so that one snapshot can still kick recovery.
  11. As a captain, I want create-task results to say the assignee was notified, so that I do not send_message only to dispatch.
  12. As a captain, I want to omit a recap after delete, so that the last turn is not a polite summary.
  13. As a member, I want assignment messages to include the attempt id, so that I can update the current generation.
  14. As a member, I want not to poll Status Probe for new work, so that I wait for assignment Wakes instead.
  15. As a member, I want a one-shot Status Probe only if I am blocked, so that I still have a diagnostic.
  16. As a member, I want prerequisite outputs inline on assignment when dependencies completed, so that I do not read team.json to start a review.
  17. As a user, I want idle members who still own open work to be retried without a Captain Turn, so that Silent Kick covers the common stall.
  18. As a user, I want a member that stays running on a non-terminal task to eventually produce a Captain Wake, so that the captain can reassign or interrupt.
  19. As a user, I want that Wake to happen only after Silent Kick, so that the scheduler gets the first chance.
  20. As a user, I want a missing or unknown assignee treated like a running hang after Silent Kick, so that a vanished member is not ignored.
  21. As a user, I want Next Probe At stored on each Task Record, so that two tasks do not share one countdown.
  22. As a captain, I do not want to keep Next Probe At in the prompt, so that the clock survives model non-compliance.
  23. As a user, I want Attempt Start to arm Next Probe At, so that claimed work gets a due time.
  24. As a user, I want a successful update_task on that attempt to clear Next Probe At, so that healthy progress does not Wake the captain.
  25. As a user, I want a completion report for that task to clear Next Probe At, so that finished work is not probed.
  26. As a user, I want the default arm interval to be ten minutes and not a settings field, so that plugin configuration stays one Parallel Emission checkbox.
  27. As a user, I want a Captain Wake to re-arm Next Probe At, so that a still-stuck task is not woken every scheduler tick.
  28. As a user, I want no Captain Wake loop, so that a hanging member cannot burn cache_read every few seconds.
  29. As a captain, I want Mailbox Wake when I am idle and have unread captain mail, so that a failed live steer still delivers the report.
  30. As a captain, I want Mailbox Wake without waiting for Next Probe At, so that a finished report is not hidden for ten minutes.
  31. As a user, I want Status Probe to remain a whole-team snapshot plus kick, so that we do not invent a per-task status tool.
  32. As a user, I want the Activity View poll unchanged, so that human display is not the probe clock.
  33. As a user, I want Parallel Emission off by default, so that models that only emit one tool call keep the serial protocol.
  34. As a user, I want a Plugins configuration checkbox labelled for Parallel Emission on the AgentTeams card, so that I can opt in without opening Agent Loop settings.
  35. As a user, I want that checkbox not to write maxParallelToolCalls, so that the execution pool stays on the Agent Loop card.
  36. As a captain, I want usage text to allow several create_task calls in one response when Parallel Emission is on, so that one step can build the graph.
  37. As a captain, I want later create_task calls in that same response to depend on earlier ids in that response, so that exclusive in-order execution satisfies existence checks.
  38. As a captain, I want a missing dependency to still fail loud, so that a failed sibling create cannot leave a child pending forever.
  39. As a member, I want claim and in_progress in the same response when Parallel Emission is on, so that I do not spend a step on the ritual.
  40. As a member, I want completed and send_message in the same response when Parallel Emission is on, so that the captain is Woken once.
  41. As a member already spawned, I want my persona unchanged when the checkbox flips, so that a mid-turn system prompt does not rewrite itself.
  42. As a captain, I want the next assembled usage section to read the live checkbox, so that new turns pick up the opt-in without restart.
  43. As a newly spawned member, I want my persona to match the checkbox at spawn, so that new workers and the captain agree.
  44. As an assignment, I want Parallel Emission lines to match the live checkbox, so that the three protocol surfaces do not contradict.
  45. As a user, I want serial protocol text when the checkbox is off, so that we do not MUST-parallel models that cannot emit multiple tools.
  46. As a user, I want PR 通过消除 status 轮询和启用并行工具调用减少 token 浪费 #48’s empty dependency branch rejected, so that tasks cannot hang on ids that never existed.
  47. As a user, I want PR 通过消除 status 轮询和启用并行工具调用减少 token 浪费 #48’s “never call status” rejected, so that Silent Kick and a diagnostic Probe remain available.
  48. As a user, I want PR 通过消除 status 轮询和启用并行工具调用减少 token 浪费 #48’s mandatory end-turn rejected, so that the captain can still guide.
  49. As a user, I want no sleep-5-then-status protocol, so that we do not replace cache_read waste with wall-clock waste.
  50. As a developer, I want lifecycle tests to drive due Next Probe At with a fake clock, so that ten minutes is not a real wait.
  51. As a developer, I want offline verification to pin protocol strings for poll bans, panel independence, and Parallel Emission on/off, so that usage text cannot drift back to “Poll status until terminal”.
  52. As a user, I want reduced-motion and hidden-page Activity View behaviour unchanged, so that probe work does not regress Issue Feature: Add pluggable visual status indicators for all agents #58 visuals.

Implementation Decisions

  • Extend the existing team scheduler rather than adding a watcher, HTTP route, or 1s scan of all teams. Fold due Next Probe At handling into Silent Kick (the current kick entry). Arm a single timer for the nearest due Next Probe At; cancel/recompute on Task Record writes.
  • Store Next Probe At on the Task Record as an optional epoch-ms field. Absent means not armed. Attempt Start sets it to now + 10 minutes. Successful update_task for that attempt, terminal status, or a completion-shaped captain-bound message for that task id clears it. Captain Wake re-arms the same way as Attempt Start.
  • Silent Kick is the current shared-task kick with no Captain Turn. After it, Captain Wake only if the Task Record is non-terminal and Member Liveness of the assignee is running, missing, or unknown. Idle + open work is left to the kick/retry already implemented on agent/status idle.
  • Captain Wake and Mailbox Wake reuse the existing captain steer helper. If steer fails, leave the mailbox durable; do not tight-loop.
  • Mailbox Wake: captain Agent Liveness idle/ready and unread captain mailbox. Independent of Next Probe At. Perform on kick paths and when mail is appended to the captain mailbox.
  • Do not add a per-task Status Probe tool. Status Probe copy changes to: diagnostic snapshot and recovery kick; do not loop; Activity View already shows progress.
  • create-task result copy notes that the scheduler notifies the assignee; do not send_message merely to dispatch.
  • Protocol builders take Parallel Emission as a boolean. Captain usage section text is a function evaluated at assemble time. Member persona receives the flag only at spawn. Assignment prompt reads the live flag at dispatch.
  • Settings namespace agent-teams with parallelToolCalls: boolean default false. Host registers the section when settings exist. Browser registers a Plugins-tab card keyed by that namespace (type-only slot contract; do not value-import another plugin’s card chrome). Checkbox label is product Chinese: 支持工具并行. Hint that this is Parallel Emission, that Agent Loop’s parallel cap is separate, and that cap 1 still runs exclusive tools in order in one step.
  • Dependency existence checks stay. Same-response create_task relies on exclusive in-order execution.
  • Inject a clock into the scheduler for tests. Do not use real 10-minute sleeps.
  • Do not change Activity View polling cadence, visual status mapping, or maxParallelToolCalls.

Task Record shape addition (decision, not a file map):

interface TeamTask {
  // existing fields
  nextProbeAt?: number // epoch ms; absent = not armed
}

Due action (decision):

if due(task):
  Silent Kick
  if task non-terminal and assignee liveness in {running, missing, unknown}:
    Captain Wake
    re-arm nextProbeAt
  else:
    clear or leave to retry kick

Testing Decisions

Good tests assert externally visible behaviour: Task Record fields after Attempt Start / update / complete; whether kick ran; whether captain steer ran; protocol strings for Parallel Emission on vs off; create_task still rejecting unknown dependency ids; settings default false.

  • Scheduler / lifecycle harness (existing fake agents, tool execute, agent/status idle): arm, clear, Silent Kick without Wake for idle+open, Wake for running+open after due, re-arm after Wake, Mailbox Wake on unread + idle captain, fake clock.
  • Offline verify string/contract checks: usage forbids “Poll status until terminal”; mentions Activity View independence; Parallel Emission on/off branches; create_task still throws on missing dependency.
  • Settings: schema default false; card registers under the agent-teams namespace key when the Host serves that namespace.
  • Do not require a full LLM e2e to prove prompt compliance; runtime clocks and string contracts are the seam. Optional later: one recorded team run with Parallel Emission off.

Prior art: scripts/lifecycle-verify.mjs (kick, idle retry, mailbox fallback), scripts/verify.mjs (pure protocol/source contracts), scripts/stress-verify.mjs (do not weaken).

Out of Scope

  • Merging or cherry-picking PR 通过消除 status 轮询和启用并行工具调用减少 token 浪费 #48 as written.
  • Changing Agent Loop maxParallelToolCalls or auto-detecting model multi-tool support.
  • Rewriting personas of members already spawned.
  • A per-task status tool, transcript scanning, or Activity View-driven probe clock.
  • Making end-of-turn mandatory.
  • Forward references to task ids that do not exist yet.
  • User-configurable probe interval.
  • Cold-restore of members while the captain Agent is offline (existing limitation), except Mailbox Wake when the captain Agent is present and idle.
  • Visual/avatar/HMR work from Issue Feature: Add pluggable visual status indicators for all agents #58 except “do not regress”.

Further Notes

Grilling settled this in-session (Q1–Q12, all recommended options). Glossary: CONTEXT.md. Upstream GitHub issues on NanmiCoder/dsh-agent-teams cannot be labelled by this checkout’s identity (read-only); keep this spec file as the source of record until someone with write access files it and applies ready-for-agent.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions