microsoft / microsoft/agent-host-protocol

summaryStatus reports Idle while queued messages are pending, causing status flicker

Open
#426 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
344
Forks
122
Avg merge
14h 12m
Merged PRs (30d)
22

Description

Summary

summaryStatus reports SessionStatus.Idle as soon as a turn ends, even when the chat still has queuedMessages that the host is about to drain into a new turn. Clients therefore observe a spurious InProgress -> Idle -> InProgress flicker on every queued turn.

Where

types/channels-chat/reducer.ts:144:

} else if (state.activeTurn) {
    activity = SessionStatus.InProgress;
} else {
    activity = SessionStatus.Idle;
}

There is no consideration of state.queuedMessages, so the gap between one turn completing and the next queued turn starting is reported as an idle session.

Impact

In VS Code this surfaces as a spurious "session finished" OS notification while the user still has messages queued. It is most visible when a session is open in one window but only listed in another (e.g. the editor window vs. the Agents window).

Clients cannot work around this on their own for unsubscribed sessions, because the queue is not visible at summary level:

  • queuedMessages / steeringMessage exist only on the full ChatState (types/channels-chat/state.ts).
  • ChatSummary carries only status — no queue fields.
  • SessionState.chats contains summaries only.

So a client that has not subscribed to a chat has no signal at all that work is queued. VS Code is shipping a time-based debounce as a stopgap, which is a heuristic and can still leak a notification when a drain is slow.

Suggested fix

Report InProgress when there is no active turn but a drainable queued message exists.

"Drainable" must mirror the host's actual admission conditions, otherwise a session can get stuck reporting InProgress for a queue that will never drain. In the VS Code host implementation those conditions are: no active turn, queuedMessages non-empty, no steeringMessage, and the latest turn is not an Error with resumable: true.

Two edge cases worth deciding explicitly:

  1. Cancellation. The VS Code host does not auto-drain on cancel (its turn-end hook only drains on success), but a later queue action does drain. A naive predicate reports InProgress for a queue nothing is currently going to drain.
  2. Truncation. Drainability derived from turns.at(-1) becomes unknowable once turns are truncated, since the history the predicate depends on is gone.

Both suggest the queue's drainability may deserve to be explicit state rather than something re-derived from turn history.

An alternative (or complement) is to expose minimal queue information on ChatSummary — e.g. a queued-message count — so clients can reason about it without subscribing.

Context

Found while fixing spurious agent-session notifications in microsoft/vscode. The reducer is vendored into that repo via scripts/sync-agent-host-protocol.ts, so the fix has to land here first and then be re-synced.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the status calculation at types/channels-chat/reducer.ts:144, then read types/channels-chat/state.ts and the ChatSummary shape to understand which queue state is available. Compare the reducer behavior with the VS Code host's drain conditions, including cancellation and truncated turns. Done means queued work no longer produces a spurious Idle status, and the protocol change can be resynced through scripts/sync-agent-host-protocol.ts.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.