todo-28-session-turns.md 1.5 KB

Todo 28: Session Turns

Status

done

Goal

Separate session and turn behavior. A WebSocket session is the ongoing conversation. A turn starts with one user message and finishes after ChatAgent has produced the visible reply, including any EventAgent handoff and final ChatAgent response.

Root Cause

The UI currently closes and recreates the WebSocket for every submit. The backend runtime also treats done as the end of the whole run after one user message. round_index is a ChatAgent call counter, so the post-event ChatAgent call appears as a second round with events_enabled=[], which is expected for a one-event-loop turn but confusing without turn boundaries.

Scope

  • Add a persistent runtime session entrypoint for WebSocket use.
  • Emit turn_started and turn_completed events.
  • Reset EventAgent event-loop budget for each new user turn.
  • Keep post-event final ChatAgent calls inside the same turn.
  • Keep existing one-shot runtime.run() behavior for tests and smoke helpers.
  • Reuse an open WebSocket from the frontend instead of closing it on every submit.

Verification

  • Runtime test proves a second user turn gets enabled events again.
  • WebSocket test proves one connection can process two user messages.
  • Static UI test proves the browser sends user_message on an open socket and handles turn_completed.
  • uv run pytest tests/test_debug_runtime.py tests/test_websocket_api.py -q passes: 45 tests.
  • uv run pytest passes: 56 tests.