Agent Host: Add correlated live-session lifecycle and queue diagnostics
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
## Problem
The investigation in #330888 identified the immediate failure that left a Copilot Agent Host chat stuck, but the exported logs could not answer the underlying lifecycle question.
In that incident:
- the durable Agent Host/AHP chat and its persisted history still existed;
- VS Code retained a cached `CopilotAgentSession` wrapper;
- the Copilot runtime had successfully resumed the backing SDK session and completed one turn;
- a later `session.send` RPC accepted another message;
- asynchronous `session.queue.process` then failed because the SDK session ID was not present in the runtime's live-session registry;
- no close, destroy, owner-detach, terminal error, or idle event explained when or why that registry entry disappeared.
The current export therefore proves the proximate failure but not the root cause. We need enough privacy-safe correlation to reconstruct the lifetime of one backing session across VS Code, the SDK wrapper, and the runtime.
## Requested diagnostics
Use a consistent correlation tuple across every layer:
- Agent Host configuration/session ID
- AHP chat URI or opaque chat ID
- Copilot SDK session ID
- turn ID and SDK message ID
- Agent Host client/connection ID
- Copilot client/process generation and process ID
- opaque owner/lease ID where applicable
### Agent Host lifecycle
Log structured start/result records for:
- `CopilotSessionLifetime` creation, acquire, release, close, and reset, including active lease and pending-release counts;
- live-session cache insertion, replacement, lookup, and removal;
- `_registerInitializedSession`, `_registerLiveChat`, `_destroyLiveSession`, `_resumeSession`, and `_doResumeSession`;
- configuration refreshes that destroy and resume the same SDK session ID;
- client replacement/restart and the generation to which each wrapper belongs;
- wrapper state before send: cached, disconnected, active turn, client generation, and backing chat mapping;
- stale-wrapper invalidation and recovery attempts.
Every removal should include a stable reason code such as `configuration-refresh`, `last-owner-detached`, `chat-release`, `client-restart`, `explicit-destroy`, `runtime-shutdown`, or `recovery`.
### SDK and runtime lifecycle
Log structured start/result records for:
- `session.create`, `session.resume`, `session.destroy`, `session.shutdown`, and runtime registry insert/remove;
- owner attach/detach, including the remaining owner count and removal reason;
- whether the SDK's JavaScript `sessions` map and the runtime live-session registry contain the ID at each send;
- queue enqueue, scheduled processing start, retry, success, and abandonment;
- the exact registry lookup that produced `Session not found`, including runtime/client generation and the last known registry mutation for that ID;
- whether `session.send` acknowledged durable enqueueing versus successful processor scheduling.
### Turn terminality
For each send, log:
- send accepted/rejected and returned SDK message ID;
- latency to the first SDK event;
- first event type;
- terminal `idle`, `session.error`, abort, or transport failure;
- any turn that remains pending without a first SDK event;
- which terminal AHP action (`chat/turnComplete`, `chat/turnCancelled`, or `chat/error`) closed the protocol turn.
These records should make it explicit when a request is only durably queued but has no live processor.
## Acceptance criteria
A single exported bundle should let an investigator answer, without additional private state:
1. Was the backing SDK session live immediately before `session.send`?
2. Did the JavaScript SDK map and runtime registry agree?
3. When was the live entry added or removed, by which owner/client generation, and for what reason?
4. Was the message only enqueued, or did queue processing actually start?
5. If queue processing failed, how was that failure surfaced to Agent Host and the AHP turn?
6. Why did a restored chat remain `InProgress`, and which action eventually made it terminal?
For the sequence **configuration refresh → resume → successful turn → idle → second send**, the logs should contain one complete, causally ordered lifecycle chain. A missing runtime session must have a preceding removal reason or an explicit invariant-violation record stating that no removal was observed.
Contributor guide
Assessment
This issue has not been assessed yet.