Skip to content

buzz-acp: resume agent sessions via session/load (SessionStore keyed by channel + thread root) #6

Closed

Description

@spiritabsolute

TL;DR: buzz-acp never restores an agent session: after the pool sleeps (15 min), Stop/Start, Restart or a Desktop restart, the agent gets a new session and loses all accumulated context. The adapters (claude-agent-acp, codex-acp) support session/load, and the transcripts are on disk. We propose porting upstream PR block#6088 and extending the session key to the thread.

Problem

buzz-acp only ever creates sessions: the single ACP session call is session/new (crates/buzz-acp/src/acp.rs:758). The map of live sessions sessions: HashMap<SessionScope, String> lives inside the AgentPool (crates/buzz-acp/src/pool.rs:133) and is wiped by SessionState::invalidate_all (pool.rs:219) whenever the pool is torn down. That happens on:

The next mention opens a fresh session ([session/query] … resume=none in the agent log) and the harness injects only the thread root plus the last BUZZ_ACP_CONTEXT_MESSAGE_LIMIT (12) replies as <thread-context>. Everything the model had reasoned about, intermediate decisions, file paths it discovered, subagent results — gone.

Evidence

  • 2026-09-29, one agent (session policy thread), harness log agents/logs/<agent>__<session>.log: turn dispatched 07:11:01, last message 07:25:13, idle pool sleep bound reached — tearing pool back to lazy state at 07:26:16, new session 59aac60b… with resume=none at 07:44:54 on the next mention. Old transcript ~/.claude/projects/<workspace>/<session>.jsonl (2.4 MB) was intact on disk.
  • The owner's expectation (2026-09-29): "I set each thread to start its own session with the agent and expected it to persist until I close Buzz." Since then the team runs a manual ritual in every long thread: "let's pause, we'll continue in the next session", "write a prompt to start the next session" — handoff files and restart prompts written by hand because the harness cannot resume.

What already exists

  • @agentclientprotocol/claude-agent-acp ≥ 0.79 implements loadSession → createSession(..., { resume: sessionId }), i.e. native Claude Code resume from the on-disk transcript. codex-acp also advertises loadSession: true in its initialize response.
  • Upstream PR buzz-acp: resume channel sessions across a restart, and name the channel on session/new block/buzz#6088 ("buzz-acp: resume channel sessions across a restart, and name the channel on session/new", head 313d5fd4, +1753/−52, files acp.rs, config.rs, lib.rs, pool.rs, new session_store.rs): a SessionStore at <state-dir>/sessions-<pubkey>.json, session/load when there is no live session, fallback to session/new on JSON-RPC error, flags BUZZ_ACP_STATE_DIR / BUZZ_ACP_NO_RESUME_SESSIONS. Maintainer confirmed the basic scenario and requested changes (2026-08-18); author replied 2026-08-23; no activity since, mergeable_state=dirty. Still OPEN as of 2026-10-09.

Proposal

  1. Port buzz-acp: resume channel sessions across a restart, and name the channel on session/new block/buzz#6088 onto fork/main as a registered fork patch (scripts/fork/patches.json, per docs/fork/MAINTENANCE.md).
  2. Extend the store key from channel_id to the full SessionScope (crates/buzz-acp/src/scope.rs:71): Conversation { channel_id } and Thread { channel_id, root_event_id }. Thread sessions landed in upstream main on 2026-09-18, after the PR was written.
  3. Cover the teardown path explicitly: lazy-pool sleep → empty AgentPool::from_slots → next dispatch must call session/load with the stored id, not session/new. Add a test for it.
  4. Gate on the runtime capability from initialize (loadSession); runtimes without it keep today's behaviour.
  5. On successful load, skip the full <thread-context> re-injection and deliver only the delta (the delivered_event_ids bookkeeping would also need to be persisted, or the harness re-sends the window once and accepts the duplication).
  6. Document the limitation: resume restores conversation history, not in-flight turn state (background subagents, scheduled wakeups do not come back).

Benefit

  • Agents survive the 15-minute idle teardown, Desktop restarts and Restart buttons with their context intact; no more hand-written handoff prompts between "sessions" of the same thread.
  • Fewer tokens: a resumed session does not re-read the thread, the repo and the feature directory from scratch.
  • Thread-scoped sessions (the policy the owner relies on) finally mean what the UI promises.

References

Activity

  1. spiritabsolute commented on Oct 20, 2026

    @spiritabsolute
    CollaboratorAuthor

    Implemented and accepted in #15, now squash-merged into main as 258fba8eb89a67451806b4ff4e984981d0432d13. This completes session continuity and the scoped visibility/context controls. The owner rebuilt and accepted the app; candidate CI passed. Detailed evidence and retained limitations are recorded in the merged PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions