Skip to content

Preserve sandbox history when live hydration fails - #340815

Merged
Osvaldo Ortega (osortega) merged 3 commits into
mainfrom
copilot/sandbox-live-hydration-recovery
Oct 14, 2026
Merged

Osvaldo Ortega (osortega) merged 3 commits into
mainfrom
copilot/sandbox-live-hydration-recovery

Conversation

@osortega

@osortega Osvaldo Ortega (osortega) commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #340354, addressing the live-hydration review finding. No separate tracking issue was supplied.

AgentHostSessionHandler can fulfill its content request with an error transcript or an empty root-session fallback after a subscription failure. The sandbox facade previously treated either result as a successful live snapshot, replacing recorded messages, invalidating their cache, cancelling the recorded refresh, and disabling its recovery paths.

  • Expose an optional, explicit initial-history failure outcome rather than inferring failure from empty history or historical error responses. Other consumers keep their existing error rendering.
  • Reject failed live promotion while retaining the recorded transcript, cache, ongoing history refresh, and existing live Retry action. Release the rejected session and its subscriptions, including failures before a chat URI was resolved.
  • Preserve genuinely new sessions, successfully hydrated empty chats, and conversations containing failed historical turns. A missing root session can still initialize lazily, but only after the already-running recorded read successfully confirms there is no conversation to preserve.
  • A truncated replay that omits the requested root reports incomplete history, not an empty conversation. Partial transcripts containing the requested root remain readable with their existing warning.

No new setting, protocol field, storage key, telemetry event, or banner is introduced. Recorded-history recovery still does not reconnect or submit input.

Validation

Truncated-root follow-up (d9b11a29af2), using Node 24.18.0:

  • npm run build-fast -- --client-only — passed.
  • node build/hygiene.ts src/vs/workbench/contrib/chat/browser/remoteAgentHost/cloudSandboxReadOnlySessionHandler.ts src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts — passed.
  • npm run eslint -- src/vs/workbench/contrib/chat/browser/remoteAgentHost/cloudSandboxReadOnlySessionHandler.ts src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts — passed.
  • git diff --check — passed.
  • The following selection passed 86 tests, including both new missing-root truncation regressions and the existing readable-partial-history case. Both new cases failed before the one-line validation fix.
xvfb-run -a ./scripts/test.sh --no-sandbox --disable-dev-shm-usage --reporter dot \
  --run src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts \
  --run src/vs/workbench/contrib/chat/test/browser/remoteAgentHost/cloudSandboxSessionHandler.test.ts \
  --run src/vs/workbench/contrib/chat/test/browser/remoteAgentHost/cloudSandboxHistoryCache.test.ts \
  --grep 'history loading cloud sandbox promotion|CloudSandboxSessionHandler|CloudSandboxHistoryCache'

Initial fix (e5ac639c4b8), using Node 24.18.0:

  • npm run install-fast — passed after the new main branch's SDK/runtime version check identified stale dependencies. No dependency manifests changed.
  • npm run build-fast -- --client-only — passed.
  • npm run typecheck-client — passed, including the final cancellation/subscription-release assertions.
  • node build/hygiene.ts src/vs/workbench/contrib/chat/common/chatSessionsService.ts src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts src/vs/workbench/contrib/chat/browser/remoteAgentHost/cloudSandboxSessionHandler.ts src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts — passed. After adding cancellation/subscription-release coverage, node build/hygiene.ts src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts also passed.
  • npm run eslint -- src/vs/workbench/contrib/chat/common/chatSessionsService.ts src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts src/vs/workbench/contrib/chat/browser/remoteAgentHost/cloudSandboxSessionHandler.ts src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts — passed, all four changed files.
  • git diff --check — passed.

The following focused selection passed 130 tests, including 12 real-provider sandbox promotion cases:

xvfb-run -a ./scripts/test.sh --no-sandbox --disable-dev-shm-usage --reporter dot \
  --run src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts \
  --run src/vs/workbench/contrib/chat/test/browser/remoteAgentHost/cloudSandboxSessionHandler.test.ts \
  --run src/vs/workbench/contrib/chat/test/browser/remoteAgentHost/cloudSandboxHistoryCache.test.ts \
  --grep 'history loading|history with tool events|disposal|does not render a load failure|still renders a load failure|CloudSandboxSessionHandler|CloudSandboxHistoryCache'

The real-provider regression cases reproduced eight failures on the unfixed implementation, including cache invalidation, transcript replacement, cancelled recorded reads, and lost retry. One intermediate Electron launch crashed during module loading (exit code 5), before executing tests; the final identical selection completed successfully.

Live cloud end-to-end flows were not exercised.

How to Test

  1. Open a sandbox with cached or recorded messages and make its live session/default-chat/peer-chat subscription fail. Confirm messages and the cache remain intact, the recorded API refresh continues, and the existing live Retry action remains available.
  2. Let the recorded refresh succeed, then recover the live subscription and invoke Retry. Confirm the same chat promotes successfully without dropping the draft.
  3. Repeat with a root-session NotFound response. Existing recorded messages must remain readable; a successful empty recorded result must still allow lazy session initialization. An unavailable API or a truncated replay missing the requested root must not be mistaken for an empty conversation, including when the replay contains a different session.
  4. Check a new session, an empty but successfully hydrated chat, and a transcript containing a failed turn. All must still load normally. Close a chat while a missing-root result is waiting for recorded history and confirm its pending work is cancelled and released.

Distinguish failed live history from authoritative snapshots so recorded messages, cached history, and recovery remain available. Keep lazy session initialization conditional on a successful empty recorded read.

Co-authored-by: Copilot <[email protected]>
Copilot AI balanced review requested due to automatic review settings October 9, 2026 22:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A truncated recorded response can still be mistaken for authoritative empty history, allowing unsafe session initialization.

1 open finding
What changed in this PR

Preserves recorded cloud sandbox transcripts when live Agent Host hydration fails.

Changes:

  • Exposes explicit initial-history failures.
  • Rejects failed live promotion while retaining recovery state.
  • Adds real-provider regression coverage.
File Description
chatSessionsService.ts Defines the history-load failure result.
agentHostSessionHandler.ts Reports hydration failures and releases subscriptions.
cloudSandboxSessionHandler.ts Validates live snapshots before promotion.
agentHostChatContribution.test.ts Covers promotion, retry, and cancellation paths.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@connor4312 Connor Peet (connor4312) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full diff and relevant session hydration, history fallback, and subscription cleanup context. No actionable P1 or P2 security or correctness findings.

Written by Connor's agent running GPT-6.1 Sol

@github-actions

Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: 50559e74 Current: 129e0086

Changed (1)

sessions/chatCompositeBar/OverflowingTabs/Light
Before After
before after

@osortega
Osvaldo Ortega (osortega) merged commit ca37fb3 into main Oct 14, 2026
35 checks passed
@osortega
Osvaldo Ortega (osortega) deleted the copilot/sandbox-live-hydration-recovery branch October 14, 2026 03:46
@vs-code-engineering vs-code-engineering Bot added this to the 1.143.0 milestone Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants