Reconcile Claude background task state
This commit is contained in:
1 parent
f0661919bb
commit
9fd21af4e8
6 files changed
+310
-24
No files matched your search
+20
-6
@@ -86,6 +86,20 @@ transcript is still being written to and its process is the session's to stop.
|
||||
status ends it from the update, since the failure to avoid is a subagent
|
||||
nothing ever finishes.
|
||||
|
||||
Since Claude Code 2.1.261, `background_tasks_changed { tasks: [...] }` is
|
||||
the authoritative level beside those edges: its set replaces the previous
|
||||
set, so a missed terminal edge cannot leave a subagent running forever. Its
|
||||
ids are deliberately not correlated with the edge stream; the useful claim
|
||||
here is whether the set is empty. The edges still carry mapping, outcome
|
||||
and closing summary. On adoption the driver sends a repeated `initialize`,
|
||||
which makes a current CLI send the full set; an older CLI accepts it and sends no level,
|
||||
leaving the edge-based path unchanged. A snapshot is reconciled immediately
|
||||
when the persisted parent status proves it is between turns, and otherwise
|
||||
at the next `result` boundary -- while a turn is open, a foreground agent is
|
||||
legitimately absent from the background set. Reconciliation writes
|
||||
`Status Exited`, which is also what makes a formerly stale row deletable;
|
||||
a task notification ordered after the level can still add its summary.
|
||||
|
||||
The two rules this replaces were both wrong, in opposite directions. The
|
||||
parent's `tool_result` is not it: a backgrounded Task's arrives at launch
|
||||
("Async agent launched..."), so ending there truncated a running agent's
|
||||
@@ -117,12 +131,12 @@ transcript is still being written to and its process is the session's to stop.
|
||||
|
||||
**While any task is outstanding the session's turn ends in
|
||||
`Status Waiting` rather than `Idle`.** `Idle` means "waiting for a person",
|
||||
and a session with a backgrounded subagent is not doing that. Two sources:
|
||||
the translator's `open_tasks`, and `Subagents::any_open` -- which is what
|
||||
covers a subagent launched before a backend restart adopted the session,
|
||||
whose `task_started` is behind the offset its stdout is read from. That
|
||||
second lookup is also what lets such a subagent's ending be recognised at
|
||||
all.
|
||||
and a session with a backgrounded subagent is not doing that. The edge
|
||||
fallback has two sources: the translator's `open_tasks`, and
|
||||
`Subagents::any_open` -- which covers a subagent launched before a backend
|
||||
restart adopted the session, whose `task_started` is behind the durable
|
||||
stdout offset. On current Claude versions the replace-semantics level above
|
||||
reconciles both at a safe turn boundary.
|
||||
|
||||
**A limit the account hits inside a subagent is hoisted to the session**
|
||||
as well as recorded here, because `resume.rs` can only schedule against a
|
||||
|
||||
Reference in new issue
Block a user