Skip to content

Streaming Chat Executor Architecture

Project-graph analysis (Feb 2025) showed that _stream_chat_impl inside the
old coordinator path still orchestrated every phase of streaming chat. The
orchestration first moved into a dedicated pipeline module. The live runtime
has since been consolidated again: the canonical entry point is now the
service-owned streaming runtime backed by
victor.agent.services.chat_stream_executor.StreamingChatExecutor, not
ChatCoordinator.stream_chat().

1. Responsibilities

Phase Responsibilities formerly inside _stream_chat_impl Extracted component
Session bootstrap Create StreamingChatContext, emit requirement events, reset dedup state victor.agent.streaming.context
Iteration loop Enforce limits, request provider responses, feed tool calls StreamingChatHandler, ToolExecutionHandler
Intent handling Run classifier, apply continuation overrides IntentClassificationHandler, ContinuationHandler
Recovery & fallbacks Delegate to RecoveryCoordinator, response_completer victor.agent.recovery_coordinator, response_completer
Metrics & observability Emit streaming metrics, cumulative token usage StreamingController, StreamingCoordinator

The original pipeline extraction removed streaming fan-out from the old
coordinator facade. The current runtime keeps that same fan-out inside the
canonical executor rather than inside a deprecated coordinator or a parallel
pipeline surface.

2. Canonical Architecture

ChatService.stream_chat()
└── ServiceStreamingRuntime.stream_chat()
    └── StreamingChatExecutor(runtime_owner=ServiceStreamingRuntime)
        ├── setup() -> StreamingChatContext + requirement extraction
        ├── iterate() async generator
        │     • delegates provider streaming + tool execution
        │     • consults continuation + intent handlers
        └── finalize() -> completion fallback + metrics aggregation

StreamingChatExecutor.run(user_message) is the canonical streaming-session
entry point. ServiceStreamingRuntime owns executor creation and binding.
ChatCoordinator.stream_chat() survives only as a compatibility shim around
the service/runtime path.

3. Implemented Changes

  1. Executor landing
    victor/agent/services/chat_stream_executor.py now contains the live
    streaming implementation and reuses dedicated helper modules for intent,
    continuation, tool execution, and recovery.
  2. Service-owned runtime
    victor.agent.services.chat_stream_runtime.ServiceStreamingRuntime is the
    canonical owner of executor construction and invocation.
  3. Factory exposure – orchestrator/runtime builders expose
    create_streaming_chat_executor(...) and
    create_service_streaming_runtime(...) so canonical wiring stays out of the
    deprecated coordinator shims.
  4. Compatibility shim retentionChatCoordinator.stream_chat() no longer
    owns streaming orchestration. It forwards to the service/runtime surfaces
    and only falls back to the legacy hook for older integrations.

4. Testing Strategy

  1. Executor unit tests
    - Mock/spy runtime-owner helpers to prove the executor exercises the
    expected phases (pre-checks, continuation, tool execution, recovery).
    - Simulate error and cancellation paths to guard the retry logic.
  2. Compatibility tests
    - Keep explicit coverage that deprecated shims prefer ChatService, then
    ServiceStreamingRuntime, and only then the legacy hook.
  3. Integration coverage
    - Maintain tests/unit/agent/test_orchestrator_core.py and service
    delegation suites so the service-owned runtime remains the canonical path.
    - Maintain the streaming CLI integration tests to ensure real providers
    and tool executions still behave identically.

5. Follow-up Checklist

  • Extract streaming orchestration out of _stream_chat_impl.
  • Move canonical streaming ownership to ServiceStreamingRuntime.
  • Consolidate the live path onto StreamingChatExecutor.
  • Reduce ChatCoordinator.stream_chat to a compatibility forwarding layer.
  • Remove _stream_chat_impl.
  • Add dedicated unit tests for executor-level behaviours beyond current service/runtime suites.
  • Add CI checks that fail when streaming fan-out exceeds agreed thresholds.