From 567fcadba011088cadec538873ae837c65496fb0 Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Tue, 11 Aug 2026 12:38:57 +0800 Subject: [PATCH] fix(subagent): report resumable children as ready MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit list_agents called a storage-only continuable child 'complete', inviting parents to poll it for a result that will never appear there. Rename the status to 'ready' — resumable, not terminal — and rewrite the tool description to say a parent is told when a child finishes, so listing is for recall, not polling. --- ...list-agents-residency-vocabulary.i18n.yaml | 6 +++ ...-08-06-list-agents-residency-vocabulary.md | 40 +++++++++++++++++++ ...-06-list-agents-residency-vocabulary.zh.md | 40 +++++++++++++++++++ ...subagent-catalog-and-list-agents.i18n.yaml | 4 +- ...urable-subagent-catalog-and-list-agents.md | 6 +-- ...ble-subagent-catalog-and-list-agents.zh.md | 6 +-- docs/subsystems/subagent.i18n.yaml | 4 +- docs/subsystems/subagent.md | 2 +- docs/subsystems/subagent.zh.md | 2 +- docs/tool-catalog.i18n.yaml | 4 +- docs/tool-catalog.md | 2 +- docs/tool-catalog.zh.md | 2 +- .../advanced-toolchain/session.1.jsonl | 2 +- .../advanced-toolchain/session.2.jsonl | 2 +- .../system-prompt.expected.md | 4 +- .../tool-schemas.expected.json | 2 +- .../both-mode-turn/tool-schemas.expected.json | 2 +- .../code-mode-turn/system-prompt.expected.md | 4 +- .../lsp-definition/tool-schemas.expected.json | 2 +- .../tool-schemas.expected.json | 2 +- .../tool-schemas.expected.json | 2 +- .../pty-tools/tool-schemas.expected.json | 2 +- .../tool-schemas.expected.json | 2 +- .../tool-schemas.expected.json | 2 +- .../tool-schemas.1.expected.json | 2 +- .../tool-schemas.1.expected.json | 2 +- .../session.1.jsonl | 2 +- .../session.2.jsonl | 2 +- .../subagent-list-agents/session.jsonl | 2 +- .../tool-schemas.1.expected.json | 2 +- .../snapshots/subagent-mixed/session.1.jsonl | 2 +- .../snapshots/subagent-mixed/session.2.jsonl | 2 +- .../snapshots/subagent-multi/session.1.jsonl | 2 +- .../snapshots/subagent-multi/session.2.jsonl | 2 +- .../tool-schemas.1.expected.json | 2 +- .../text-turn/tool-schemas.expected.json | 2 +- .../web-fetch/tool-schemas.expected.json | 2 +- .../advanced-toolchain/session.1.jsonl | 8 ++-- .../advanced-toolchain/session.2.jsonl | 8 ++-- .../advanced-toolchain/session.jsonl | 26 ++++++------ .../compaction-recovery/session.jsonl | 12 +++--- .../tests/snapshots/pty-tools/session.jsonl | 32 +++++++-------- packages/subagent/subagent/README.i18n.yaml | 4 +- packages/subagent/subagent/README.md | 2 +- packages/subagent/subagent/README.zh.md | 2 +- .../tool-subagent-control/README.i18n.yaml | 4 +- .../subagent/tool-subagent-control/README.md | 6 +-- .../tool-subagent-control/README.zh.md | 6 +-- .../tool-subagent-control/src/list-agents.ts | 20 ++++++---- .../tests/list-agents.spec.ts | 22 ++++++++-- 50 files changed, 215 insertions(+), 109 deletions(-) create mode 100644 .agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.i18n.yaml create mode 100644 .agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.md create mode 100644 .agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.zh.md diff --git a/.agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.i18n.yaml new file mode 100644 index 0000000000..5f01146dbe --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.md +2026-08-06-list-agents-residency-vocabulary.md: 01fff958921465909f5cd300dc355fdac6ec0772 +2026-08-06-list-agents-residency-vocabulary.zh.md: d68b9857de23ccb0b68f0bfafba153fde63303a7 diff --git a/.agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.md b/.agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.md new file mode 100644 index 0000000000..01fff95892 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-08-06-list-agents-residency-vocabulary.md @@ -0,0 +1,40 @@ +# Agent Note: `list_agents` uses `ready` for resumable children + +Status: implemented + +English | [中文](2026-08-06-list-agents-residency-vocabulary.zh.md) + +## Problem + +`list_agents` projected a continuable child's process residency as `running | idle | complete`. `complete` reads as a terminal unit of work with a result somewhere, but the underlying fact says only that no Activation is resident: the conversation is intact, `send_message` can continue it, and nothing about the child's outcome is being claimed. A model that reads `complete` reasonably looks for a result to collect or sends replacement work to a conversation it believes has ended. + +The word is especially misleading alongside [manager-owned settlement delivery](../feature/2026-08-06-manager-owned-subagent-settlement-delivery.md). Completion reaches the parent as a notice; listing exists to recall durable conversations, not to poll for that notice. + +## Decision + +The model-facing projection reports `running | idle | ready`: + +- **`running`** means the resident Agent has an active driver. +- **`idle`** means the Agent is resident between turns and may be waiting on agents it started. +- **`ready`** means only the durable conversation remains. `send_message` starts the next turn on the same conversation; the status is resumable rather than terminal and does not mean a result is waiting to be collected. + +The tool description states those distinctions and directs the model away from polling: it says the parent is told when a child finishes and that listing is for recalling which children it started. `send_message` remains the authoritative delivery check because either snapshot may race another process or a later message. + +The service layer is unchanged. `SubagentListEntry.activity` retains `'running' | 'inactive'`, which accurately describes corpus residency for consumers such as a UI. The model-facing adapter maps `inactive` to `ready` because that word communicates the action available to the model without inventing an outcome. + +## Alternatives considered + +**Keep `complete` and qualify it in the description.** A description saying that `complete` does not mean complete fights the rendered status on every read. The line the model scans must carry the correct distinction itself. + +**Use `active | dormant`.** This removes the useful distinction between a resident Agent that is between turns and a storage-only conversation, and makes the storage-only state sound unavailable. `ready` states the useful fact: the same conversation accepts another turn. + +**Drop the status entirely.** Residency remains useful when a parent decides whether to send more work. Removing it trades one misleading status for no signal. + +**Rename the service activity values.** `running | inactive` is correct at the service layer and has non-model consumers. Renaming it would churn a general contract to fix one adapter's presentation; the [durable catalog note](../feature/2026-07-22-durable-subagent-catalog-and-list-agents.md) continues to own that service vocabulary. + +## Consequences + +- The rendered line uses ` [running] —