Files
vscode/extensions
3eb10e18b3 chat: true mid-turn steering for cloud sessions (#325368)
* chat: flush queued/steering messages when a streamed session turn completes

Contributed chat sessions whose in-progress turn is streamed via
activeResponseCallback (progressObs) — e.g. Copilot cloud sessions —
register a synthetic pending request while streaming. A message sent
mid-turn is therefore queued as a steering/queued message. The
streaming-completion branch in loadRemoteSession deleted that pending
request without flushing the queue, so the queued message was stranded
in the model forever and never sent (steering 'limbo').

Mirror the normal request-completion path by calling
processPendingRequests when the streamed turn completes. It is a no-op
while another request is in flight and returns early for server-managed
(agent-host) queues, so it is safe on every completion tick.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chat: true mid-turn steering for cloud sessions

Builds on the queued-message flush fix to inject a steer into a live
cloud turn instead of only sending it after the turn settles, matching
github.com/copilot/agents.

Core (chatServiceImpl): for non-server-managed streamed
(activeResponseCallback) sessions, dispatch a queued Steering message
immediately when the in-flight pending request is the synthetic
streamed-turn tracker (no requestId) — never over a real in-flight
request. Re-establish tracking on the next progress tick so the turn
stays in-progress.

Extension (copilotCloudSessionsProvider):
- Track live TaskTurnStreamer taskIds; when a stream is already active,
  handleTaskFollowUp only POSTs /steer and lets the running stream
  render the injected result (no second streamer).
- Make the follow-up stream yield-aware (mirrors the Copilot CLI
  provider): poll context.yieldRequested and return on yield so the
  chat service flushes the next steer immediately.
- Choose the render mode from the pre-steer task state: a steer into an
  active turn renders mode:'current' (the injection has no new
  task.sessions[] row, so mode:'next' would time out); a steer onto a
  settled task renders mode:'next'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chat: address review — fix synthetic-tracker race, tracking restore, stale task state

- Identify the synthetic streamed-turn pending request via an explicit
  WeakSet instead of `requestId === undefined`: real requests are inserted
  into _pendingRequests before their requestId is assigned, so the old guard
  could delete a live request and start a concurrent invocation.
- Restore in-progress tracking deterministically when the immediate-steer
  dispatch settles (hook responseCompletePromise) instead of relying on a
  future progress tick that may never fire.
- Cloud provider: treat a follow-up as mid-turn (render mode:'current')
  only when BOTH the task and its latest turn are active, so a terminal
  task with a stale in_progress latest turn doesn't pick a streamer that
  exits before the steered turn appears.
- Rework the regression tests: the steering test now asserts immediate
  dispatch, no duplicate dispatch on completion, and preserved in-progress
  tracking; a separate test covers completion-flush of a non-steering
  queued message.
- Condense multi-line inline comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-14 06:04:38 +00:00
..
2026-07-10 12:59:32 +00:00
2026-07-08 19:02:49 +00:00