fix(conversation): resume participant sessions#560
Conversation
tangletools
left a comment
There was a problem hiding this comment.
✅ 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
left a comment
There was a problem hiding this comment.
🟢 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/runConversationStreamare the public conversation entry points (src/index.ts:91-92, conversation/index.ts:54) and have live callers:run-persona.ts:172(persona roleplay) andconversation-backend.ts:64(the recursion primitive that nests a Conversation as a participant). The session lifecycle routes through the samestartOrResumeRuntimeSessionhelper (ses - Fit with existing patterns: Matches the established grain exactly. The
resumemethod onAgentExecutionBackend(types.ts:515-519) is a pre-existing, documented part of the interface;createSandboxPromptBackendalready implements it (backends.ts:62). TheRuntimeSessionStoreoption (types.ts:210) mirrors the same pluggable-store pattern already onRunAgentTaskStreamOptions. 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
startbut noresume, backends.ts:250-365) always take the full-transcript-reconstruction path viafullConversationInput, 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.
Summary
runAgentTaskStreamVerification
pnpm run lintpnpm run typecheckpnpm run buildpnpm test(1,595 passed, 2 skipped)pnpm run verify:packagepnpm run docs:checkgit merge-tree --write-tree origin/main HEAD