Summary
When a client resumes or reconnects after missing the live event stream, there does not appear to be a documented way in the CLI/SDK to query whether the previous turn already completed successfully.
session.idle appears to be the canonical live "turn is done / session is now idle" signal, but because it is ephemeral and not persisted to events.jsonl, a reconnecting client that missed it has to infer completion from persisted artifacts and coarse session metadata.
Current situation
A resumed client can currently combine:
- live events, if it was attached when they arrived,
- session metadata such as
ModifiedTime, and
- persisted artifacts such as
~/.copilot/session-state/<session-id>/events.jsonl.
However, none of the documented SDK APIs seem to provide a direct answer to: did the previous turn already finish, or is it still in progress?
For example:
GetStatusAsync() exposes CLI/protocol status, not per-session turn state
ListSessionsAsync() / GetSessionMetadataAsync() expose metadata, not turn completion state
assistant.turn_end is persisted, but is not a reliable terminal signal because it can occur between tool rounds
Why this matters
For restart/reconnect flows, clients need an authoritative answer to whether the last turn finished cleanly.
Without that, they have to resort to heuristics such as:
- scanning the tail of
events.jsonl,
- checking file mtime / file growth, and
- waiting on timeout/watchdog logic.
Those heuristics are inherently unreliable for long-running or tool-heavy turns and can produce both false positives and false negatives.
Requested improvement
Any of the following would solve the underlying problem:
- Persist a durable completion marker to
events.jsonl — either by persisting the final session.idle, or by emitting a dedicated persisted event such as session.turn_complete
- Expose a documented session/turn status API that a reconnecting client can call after resume
- Persist a final session status snapshot that can be read after reconnect
The important point is not the exact mechanism; it is that resumed clients need some authoritative, durable completion signal instead of having to guess.
Scope
- Affects the CLI event log under
~/.copilot/session-state/<session-id>/events.jsonl
- Affects SDK/app clients that restore or reconnect sessions after restart, reconnect, or crash recovery
Related downstream tracking issue: PureWeen/PolyPilot#538
Summary
When a client resumes or reconnects after missing the live event stream, there does not appear to be a documented way in the CLI/SDK to query whether the previous turn already completed successfully.
session.idleappears to be the canonical live "turn is done / session is now idle" signal, but because it is ephemeral and not persisted toevents.jsonl, a reconnecting client that missed it has to infer completion from persisted artifacts and coarse session metadata.Current situation
A resumed client can currently combine:
ModifiedTime, and~/.copilot/session-state/<session-id>/events.jsonl.However, none of the documented SDK APIs seem to provide a direct answer to: did the previous turn already finish, or is it still in progress?
For example:
GetStatusAsync()exposes CLI/protocol status, not per-session turn stateListSessionsAsync()/GetSessionMetadataAsync()expose metadata, not turn completion stateassistant.turn_endis persisted, but is not a reliable terminal signal because it can occur between tool roundsWhy this matters
For restart/reconnect flows, clients need an authoritative answer to whether the last turn finished cleanly.
Without that, they have to resort to heuristics such as:
events.jsonl,Those heuristics are inherently unreliable for long-running or tool-heavy turns and can produce both false positives and false negatives.
Requested improvement
Any of the following would solve the underlying problem:
events.jsonl— either by persisting the finalsession.idle, or by emitting a dedicated persisted event such assession.turn_completeThe important point is not the exact mechanism; it is that resumed clients need some authoritative, durable completion signal instead of having to guess.
Scope
~/.copilot/session-state/<session-id>/events.jsonlRelated downstream tracking issue: PureWeen/PolyPilot#538