[heartstone] Phase 11 — Session Management + Reconnection#8670
Open
kevinpschaaf wants to merge 4 commits into
Open
[heartstone] Phase 11 — Session Management + Reconnection#8670kevinpschaaf wants to merge 4 commits into
kevinpschaaf wants to merge 4 commits into
Conversation
…arker
Backend changes for session management:
- GraphSessionStore: added SessionSummary, graph_id tracking, list_sessions(), delete_session()
- InMemoryGraphSessionStore: graph index, optional EventBus for status publishing
- Router: GET / monitor SSE (uniform sessionStatus events), DELETE /{id},
replayComplete marker in per-session stream, graphId dual-purpose (Drive
loading vs. session scoping)
- Tests: 17 new tests covering store and router changes
- PROJECT.md: Phase 11 expanded with full design and decisions
Service layer: - GraphRunEvent: added replayComplete, graphCancelled event types - SessionStatusEvent: new type for monitor stream - GraphRunService: createSession now requires graphId, added connectSession, monitorSessions, deleteSession methods Controller layer: - SessionHistoryController: reactive session map (deep signal), activeSessionId, monitor/connection abort controllers - DevToolsController: wired sessionHistory subcontroller Action layer: - session-actions: startSessionMonitor (SSE → controller bridge), stopSessionMonitor, deleteSession - backend-run-action: passes graphId to createSession, handles replayComplete and graphCancelled events UI layer: - bb-devtools-sessions-panel: session list with status dots, timestamps, connect-on-click, delete buttons - devtools.ts: Sessions tab gated behind enableBackendGraphRunner flag - Monitor auto-starts on tab connect, stops on disconnect
backend-run-action: - EventMode type: 'live' (interactive) vs 'replay' (non-blocking) - processEvent: mode-aware; inputRequired returns 'continue' in replay - createBridge: mode-aware; shows prompt text but skips input UI in replay - connectToSession: two-phase stream processing (replay → replayComplete → live) - startBackendRun: sets activeSessionId after creating session sessions-panel: - Session click calls connectToSession directly
- Unified handleSuspend for inputNode/waitForInput/waitForChoice events - Fixed waitForChoice rendering using ChoicePresenter + A2UIInteraction - Extracted consumeSessionEvents and initRunState to deduplicate the event loop between startBackendRun and connectToSession (~150 lines) - Made graph_id required in GraphSessionStore.create (protocol + impl) - Added date display in devtools sessions list - Added handleSuspend test suite (8 tests covering all branches) - Exported handleSuspend for testability - Fixed graph_runner access_token forwarding through resume flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a "Sessions" devtools tab for per-graph session management, session reconnection with event replay, and a unified suspend/resume flow for all input types (inputNode, waitForInput, waitForChoice).
Why
Previously, running a graph created a session with no way to reconnect if the browser tab was closed or the user navigated away. Completed and suspended sessions were invisible. This phase makes sessions first-class: users can view session history, reconnect to running/suspended sessions, and delete old ones — all through the existing devtools panel.
Changes
Backend (opal-backend)
GET /v1beta1/graphSessions?graphId=X): streams the current session list plus live status changes as sessions progressDELETE /v1beta1/graphSessions/{id}): removes a session and its graph index entryreplayCompletemarker: emitted after replaying historical events so the frontend knows when to switch from replay to live modegraph_idmade required inGraphSessionStore.create(protocol + impl) — every session must be associated with a graphFrontend (visual-editor)
SessionHistoryController: signal-backed controller undereditor.devtoolstracking the active session, connection state, and session listsession-actions.ts: SCA actions for connect/disconnect/delete/monitor —connectToSessionuseshandleInputRequestedfor the input lifecyclesessions-panel.ts: devtools "Sessions" tab UI showing per-graph session history with status dots, timestamps (now with date), and connect/delete controlsGraphRunServiceextensions:connectSession(),monitorSessions(),deleteSession(), andcancelSession()methods for session lifecycle managementhandleSuspend: single handler forinputNode,waitForInput, andwaitForChoicesuspend events, replacing scattered suspend logicconsumeSessionEventsextraction: deduplicated the event loop betweenstartBackendRunandconnectToSession(~150 lines removed), with sharedinitRunStatesetup helperwaitForChoicerendering: usesChoicePresenter+A2UIInteractionto render proper choice buttons instead of falling back to a text inputTests
handleSuspendtests: covers all three suspend types, early-return guards (no suspendEvent, no console entry, unknown type), schema behavior verification, and abort handlinggraph_idnow required in allstore.createcalls acrosstest_graph_session_store.py,test_agent_integration.py,test_headless_mode.pytest_graph_session_router.py: integration tests for session creation, SSE streaming, replay, and the monitor endpointTesting
Manual verification: