agent_servers: Drain ACP output before reporting agent exit (#64603)
Fix a race where an external agent's process exit can be reported before
its final session updates have been applied. Builds on the now-merged
stdio extraction in #64598.
A scripted-agent regression reproduced this with a successful final
prompt response: at the `LoadError::Exited` event, the transcript
contained only the user prompt; after the foreground queue settled, the
final assistant answer appeared.
- Keep child-process status separate from exit-error construction.
- After exit, wait for clean SDK inbound closure and an acknowledgment
behind queued foreground updates, concurrently with stderr completion.
- Bound the drain to 250ms so inherited open pipes or transport errors
cannot indefinitely delay exit reporting.
- Preserve the separate initialization-error grace period and existing
explicit-drop cancellation behavior.
The source change is confined to `crates/agent_servers/src/acp.rs`. No
SDK changes, protocol negotiation, restart policy, or general session
coordinator are introduced.
### Behavior boundaries
- The deadline bounds exit reporting, not descendant lifetime while a
caller retains the connection. Timeout is best effort and cannot
guarantee complete final traffic.
- Existing trailing-stderr selection is unchanged, but the diagnostic is
sampled after draining. Independent pipe reads can place protocol
messages after stderr in the debug log, so captured stderr is not
necessarily included in `LoadError.stderr`.
- The mixed-stream regressions assert transcript contents, inbound-close
state, and diagnostic capture at exit-event delivery. The stderr-only
startup regression retains an exact error-text assertion.
Release Notes:
- acp: Fixed external-agent exit errors appearing before the agent's
final response updates were applied.
d3600d664aBen Brandt committed on 9/22/2026, 2:13:53 PM· committed by GitHubparent674dd79