fix review findings: whenIdle() is observation, not the teardown await
Codex's confirmation pass found the teardown-framing error went deeper than the three prose spots already fixed: the whenIdle() JSDoc itself (and its mirrors) claimed "the quiescence signal a teardown awaits ... a lifecycle owner disposes the agent through its AgentHandle which ... awaits THIS". The disposer does not call whenIdle() — it does `stop(); await agent.done` directly (packages/core/agent-loop/src/index.ts:271). whenIdle() is the NON-OWNER observation hook; owner teardown awaits the loop-exit promise (done) through AgentHandle.dispose(). Reframe every copy accordingly: - packages/core/agent/src/types.ts: the Agent.whenIdle() contract JSDoc. - packages/core/agent-loop/src/agent.ts: the impl JSDoc. - packages/core/agent/README.md and docs/core-data-structures/core.md (the type-equiv mirror of the types.ts JSDoc — re-copied verbatim). - docs/rfc/proposed/feature/2026-06-14-acp-agent-client-protocol.md:40 and :70: owner teardown via AgentHandle.dispose(); a non-owner observing quiescence uses the interface-level agent.whenIdle(), not hand-rolled agent/status. - Regenerate the cordis catalog (whenIdle source line moved).
This commit is contained in:
@@ -253,12 +253,14 @@ interface Agent {
|
||||
|
||||
/**
|
||||
* Resolve once the agent has reached quiescence after settling out of
|
||||
* `running`, or immediately if it is already idle with no queued work. The
|
||||
* quiescence signal a teardown awaits: a lifecycle owner disposes the agent
|
||||
* through its `AgentHandle` (which aborts in-flight work then awaits this), so
|
||||
* the caller proceeds only after queued/running work has fully stopped (a
|
||||
* closing ACP connection, a disposing UI plugin) rather than returning while
|
||||
* the driver is still streaming or about to start a queued turn.
|
||||
* `running`, or immediately if it is already idle with no queued work. A
|
||||
* non-owner's quiescence-observation hook: a consumer that does NOT own the
|
||||
* agent's lifecycle (a closing ACP connection, a UI plugin) awaits this to
|
||||
* proceed only after queued/running work has fully stopped, rather than
|
||||
* returning while the driver is still streaming or about to start a queued
|
||||
* turn. It does NOT tear the agent down — a lifecycle owner stops and
|
||||
* unregisters the agent through its `AgentHandle.dispose()` (which awaits the
|
||||
* loop-exit promise directly), separate from this.
|
||||
*
|
||||
* "Quiescence", not merely "status changed": a disposed agent emits
|
||||
* `agent/status('disposed')` from inside its disposer, BEFORE the driver loop
|
||||
@@ -266,10 +268,6 @@ interface Agent {
|
||||
* to actually exit (the implementation chains the loop-exit promise), not just
|
||||
* observe the status flip. A mid-step disposal that never reaches `idle` still
|
||||
* unblocks the await this way.
|
||||
*
|
||||
* Distinct from disposal: `whenIdle()` observes the transition WITHOUT tearing
|
||||
* the agent down. A consumer that owns the agent's lifecycle disposes it
|
||||
* separately.
|
||||
*/
|
||||
whenIdle(): Promise<void>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user