Skip to content

fix(conversation): resume participant sessions#560

Merged
drewstone merged 1 commit into
mainfrom
fix/conversation-session-resume
Jul 17, 2026
Merged

fix(conversation): resume participant sessions#560
drewstone merged 1 commit into
mainfrom
fix/conversation-session-resume

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

Summary

  • keep one backend session per conversation participant and resume it across turns
  • send only unseen turns to resumable backends while reconstructing one exact transcript for stateless backends
  • persist participant session IDs with committed turns so a shared journal and session store can continue after driver restart
  • reject cross-participant session collisions before writing shared state
  • reuse the runtime session lifecycle already used by runAgentTaskStream

Verification

  • pnpm run lint
  • pnpm run typecheck
  • pnpm run build
  • pnpm test (1,595 passed, 2 skipped)
  • pnpm run verify:package
  • pnpm run docs:check
  • compiled package scenario: 4 turns, 2 starts, 2 resumes, exact unseen-turn inputs
  • git merge-tree --write-tree origin/main HEAD

@tangletools tangletools 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.

✅ Auto-approved drewstone PR — 4aa3494d

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-07-17T01:18:03Z

@tangletools tangletools 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.

🟢 Value Audit — sound

Verdict sound
Concerns 0 (none)
Heuristic 0.0s
Duplication 0.0s
Interrogation 156.2s (2 bridge agents)
Total 156.2s

💰 Value — sound

Gives each conversation participant one persistent, resumable backend session across turns by extracting and reusing the session-lifecycle primitive that runAgentTaskStream already had — reduces duplication, adds a real capability, no better approach found.

  • What it does: Before this PR, runConversationStream created a brand-new backend session for every single turn of every participant (run-conversation.ts old code: backend.start or newRuntimeSession with no requested ID, no resume). After, each participant gets one backend session that is resumed across its turns: resumable backends (those implementing backend.resume) receive only the unseen turns since their las
  • Goals it achieves: (1) Cost/token efficiency for stateful backends (OpenAI Assistants, stateful sandboxes) — they no longer receive the full transcript re-sent every turn, only the delta since their last turn. (2) Correctness for stateful participants — a participant that builds up state across its turns (e.g. a coding agent in a sandbox) now actually keeps that state, instead of starting fresh each turn. (3) Crash
  • Assessment: Sound and well-architected. The change identifies that runAgentTaskStream already had start/resume session logic as private functions, extracts it into a reusable primitive (startOrResumeRuntimeSession in sessions.ts), extends it minimally with exactly the seams the conversation driver needs (continuationInput for delta-only resume input, validateSession for cross-participant collision rejection,
  • Better / existing approach: none — this is the right approach. I checked for an existing equivalent (grep startOrResumeRuntimeSession across src/: only sessions.ts definition + two consumers, run.ts:249 and run-conversation.ts:436 — no other session-resumption path exists to reuse). I checked whether conversation-backend.ts (the nesting primitive that wraps a Conversation as a participant) had its own session handling worth
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 2
  • Bridge warning: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content

🎯 Usefulness — sound

Adds per-participant backend session continuity to the conversation driver by reusing the codebase's existing shared session-lifecycle primitive, correctly handling both resumable and stateless backends, with clean durability across driver restarts.

  • Integration: Fully reachable. runConversation/runConversationStream are the public conversation entry points (src/index.ts:91-92, conversation/index.ts:54) and have live callers: run-persona.ts:172 (persona roleplay) and conversation-backend.ts:64 (the recursion primitive that nests a Conversation as a participant). The session lifecycle routes through the same startOrResumeRuntimeSession helper (ses
  • Fit with existing patterns: Matches the established grain exactly. The resume method on AgentExecutionBackend (types.ts:515-519) is a pre-existing, documented part of the interface; createSandboxPromptBackend already implements it (backends.ts:62). The RuntimeSessionStore option (types.ts:210) mirrors the same pluggable-store pattern already on RunAgentTaskStreamOptions. Participant-session IDs reuse `slugifySpeake
  • Real-world viability: Holds up across both backend shapes and all error paths. Stateless backends (OpenAI-compatible — the most common production backend — has start but no resume, backends.ts:250-365) always take the full-transcript-reconstruction path via fullConversationInput, with no duplication: the old code appended currentInput as a trailing user message which echoed the previous response twice; the new co
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 1

No concerns — sound change, no better or existing approach found. ✅


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260717T012225Z

@drewstone
drewstone merged commit dfb5656 into main Jul 17, 2026
2 checks passed
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.

2 participants