Skip to content

Claude agent: Phase 13 — session restoration#316343

Merged
TylerLeonhardt merged 3 commits into
mainfrom
tyleonha/claude-phase13
May 14, 2026
Merged

Claude agent: Phase 13 — session restoration#316343
TylerLeonhardt merged 3 commits into
mainfrom
tyleonha/claude-phase13

Conversation

@TylerLeonhardt
Copy link
Copy Markdown
Member

Implements IAgent.getSessionMessages for the Claude provider so the workbench can reload an existing Claude session's full transcript across agent-host restarts. Unblocks self-hosting.

Full plan + decisions + drift notes live in phase13-plan.md.

What changed

File Change
claudeAgentSdkService.ts Add getSessionMessages to interface + bindings + impl
claudeReplayMapper.ts (new) SessionMessage[]readonly Turn[] per CONTEXT M7. Pure function; splits SDK shape detection (parseSessionMessage adapter) from the stateful reducer (ReplayBuilder).
claudeAgent.ts Replace getSessionMessages stub with subagent-URI dispatch + provisional check + SDK fetch + replay, all wrapped in listSessions-style warn-log-and-return-[] resilience
claudeReplayMapper.test.ts (new) 10 fixtures covering M7 grouping rules (text/tool_result/system, tail-Turn state, subagent markers, CLI-echo synthetic-message drop)
claudeAgent.test.ts 4 Phase 13 integration tests (happy path, subagent URI throws TODO: Phase 12, provisional session returns [], SDK throw → [])
CONTEXT.md Relax M7 notification gate to admit notification at all priorities pending real-world data on priority: 'low' content
phase13-plan.md (new), roadmap.md Plan, decisions, drift, council-review fixes; Phase 13 marked ✅ DONE

Tests

  • 101 tests green (mapper fixtures + agent integration suites)
  • compile-check-ts-native clean
  • Live restart-and-restore E2E deferred — fixture coverage of M7 grouping rules is enough for the read path; launch + log skills documented for future bug-driven runs

Out of scope (intentional)

  • Any (turnId, assistantEnvelopeUuid) mapping. Originally planned as live ingest + replay backfill, then as a mapper return-value by-product. Both reverted: fork (Phase 6.5) is the only consumer, fork is rare, and walking JSONL on demand at fork time is cheaper than threading state forever to optimize a cold path. Phase 6.5, if/when it lands, reads SessionMessage.uuid itself.
  • Subagent transcript fetch — owned by Phase 12. Subagent URIs throw TODO: Phase 12.
  • IAgent.truncateSession — explicitly not implemented; clients fork instead.

Implement IAgent.getSessionMessages for the Claude provider so the
workbench can reload an existing Claude session's full transcript
across agent-host restarts. Unblocks self-hosting.

- claudeAgentSdkService.ts: add getSessionMessages binding
- claudeReplayMapper.ts (NEW): SessionMessage[] -> readonly Turn[]
  per CONTEXT M7. Pure function; no by-products, no persistence.
  Splits SDK shape detection (parseSessionMessage adapter) from
  the stateful reducer (ReplayBuilder).
- claudeAgent.ts: replace getSessionMessages stub with subagent
  URI dispatch + provisional check + SDK fetch + replay, all wrapped
  with the listSessions-style warn-log-and-return-[] resilience.
- claudeReplayMapper.test.ts: 10 fixtures covering M7 grouping rules
  (text/tool_result/system, tail-Turn state, subagent markers,
  CLI-echo synthetic-message drop).
- claudeAgent.test.ts: 4 Phase 13 integration tests (happy path,
  subagent URI, provisional session, SDK throw resilience).
- CONTEXT.md: relax M7 notification gate to admit all priorities
  pending real-world data on priority: 'low' content.
- phase13-plan.md (NEW) + roadmap.md: capture decisions, drift,
  council-review fixes, and mark Phase 13 done.
Copilot AI review requested due to automatic review settings May 14, 2026 01:03
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

Screenshot Changes

Base: a7f6d3e3 Current: ba33efe8

Changed (4)

agentSessionsViewer/FailedWithDuration/Dark
Before After
before after
agentSessionsViewer/FailedWithDuration/Light
Before After
before after
agentSessionsViewer/WithDiffChanges/Dark
Before After
before after
agentSessionsViewer/WithDiffChanges/Light
Before After
before after

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements Claude session restoration by adding SDK transcript fetching and replaying Claude SessionMessage[] into agent-host Turn[], allowing restored Claude sessions to reload transcript history after agent-host restarts.

Changes:

  • Adds IClaudeAgentSdkService.getSessionMessages and wires ClaudeAgent.getSessionMessages.
  • Introduces claudeReplayMapper.ts plus fixture coverage for text, tool calls, system notifications, subagent markers, and CLI echo filtering.
  • Updates Phase 13 planning/context docs and related test fakes for the widened SDK interface.
Show a summary per file
File Description
src/vs/platform/agentHost/node/claude/claudeAgent.ts Fetches SDK transcripts and maps them to restored turns.
src/vs/platform/agentHost/node/claude/claudeAgentSdkService.ts Adds the SDK binding for session transcript reads.
src/vs/platform/agentHost/node/claude/claudeReplayMapper.ts New replay mapper from Claude transcript messages to protocol turns.
src/vs/platform/agentHost/node/claude/CONTEXT.md Updates system notification replay guidance.
src/vs/platform/agentHost/node/claude/phase13-plan.md Documents Phase 13 scope, decisions, tests, and deferred work.
src/vs/platform/agentHost/node/claude/roadmap.md Marks Phase 13 complete and updates related roadmap decisions.
src/vs/platform/agentHost/test/node/claudeAgent.test.ts Adds agent-level restoration tests and fake SDK support.
src/vs/platform/agentHost/test/node/claudeAgent.integrationTest.ts Updates integration fake to satisfy the new SDK service interface.
src/vs/platform/agentHost/test/node/claudeReplayMapper.test.ts Adds replay mapper fixture tests.

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 1

Comment thread src/vs/platform/agentHost/node/claude/claudeReplayMapper.ts
Copilot review caught that on-disk JSONL system entries put `subtype`
(and `content` for compact_boundary, `text` for notification) at the
top level of the envelope alongside `type`, NOT nested inside
`message`. The SDK's `SessionMessage` type only declares
`{ type, uuid, session_id, message, parent_tool_use_id }` so the
extra envelope fields aren't typed — but the production session
parser fixtures (extensions/copilot/.../claudeSessionParser.spec.ts)
confirm the on-disk shape.

Net effect of the bug: real `compact_boundary` and `notification`
entries were silently dropped even with `includeSystemMessages: true`,
defeating the whole point of asking for them.

- claudeReplayMapper.ts: parseSystemMessage now reads from the
  envelope via a single narrow cast; new readSystemEnvelopeText
  prefers `text` (notification) then `content` (compact_boundary).
- claudeReplayMapper.test.ts: makeSystem helper now builds
  envelope-shaped fixtures; Fixture 4 asserts the actual text
  surfaces.
This reverts f77f3f0.

Listening to the SDK contract over the production parser's raw-JSONL
fixtures: the SDK's `SessionMessage` type declares
`{ type, uuid, session_id, message: unknown, parent_tool_use_id }`
for ALL three discriminants. For user/assistant we already read the
discriminant-specific payload (role, content, blocks) from
`message.*`; doing the same for system (`message.subtype`,
`message.text`) is the consistent pattern.

The production session parser fixtures parse raw on-disk JSONL — a
lower layer than `getSessionMessages()`, which normalizes those
entries into the documented `SessionMessage` shape with payload
inside `message`. The original implementation was correct.
@TylerLeonhardt TylerLeonhardt marked this pull request as ready for review May 14, 2026 01:21
@TylerLeonhardt TylerLeonhardt enabled auto-merge (squash) May 14, 2026 01:21
@TylerLeonhardt TylerLeonhardt merged commit 1007508 into main May 14, 2026
25 checks passed
@TylerLeonhardt TylerLeonhardt deleted the tyleonha/claude-phase13 branch May 14, 2026 01:37
@vs-code-engineering vs-code-engineering Bot added this to the 1.121.0 milestone May 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.

3 participants