9734eec63c
Generated by per-group subagents covering all 52 modules across: core (18), infrastructure (10), apps (5), interfaces (3), plugins (7), testing (9) Documentation format: - AsciiDoc (.adoc) files in docs/modules/<group>/ - PlantUML (.puml) files in docs/diagrams/ - .adoc files reference diagrams via include:: directives Each doc covers: purpose, responsibilities, non-responsibilities, key types, event flow, integration points, invariants, PlantUML diagram, known issues, and open questions.
145 lines
6.0 KiB
Plaintext
145 lines
6.0 KiB
Plaintext
= core-router
|
|
|
|
== purpose
|
|
|
|
Provides a chat/steering interface for users to interact with a running workflow. Maintains its own event-sourced state (workflow status, L2 stage memory, conversation history) and builds a tailored context pack for routing inferences that decide the next workflow action.
|
|
|
|
== responsibilities
|
|
|
|
* Accepting user input via chat or steering mode
|
|
* Maintaining conversation history per session (in-memory, scoped to facade lifecycle)
|
|
* Tracking workflow lifecycle (idle, running, paused, completed, failed) from orchestration events
|
|
* Recording L2 stage memory entries (summaries of completed/failed stages)
|
|
* Building a `ContextPack` for routing decisions that includes system prompt, workflow status, conversation turns, and stage summaries
|
|
* Routing user inputs as steering notes when in STEERING mode (emitting `SteeringNoteAddedEvent`)
|
|
* Dispatching inference requests to a provider for router responses
|
|
|
|
== non-responsibilities
|
|
|
|
* Does not orchestrate workflows — only tracks state and provides an interface
|
|
* Does not produce L2 summaries — they are generated from event metadata
|
|
* Does not manage the full context assembly pipeline — only builds the router-specific subset
|
|
* Does not persist conversation history — it is held in-memory in the facade
|
|
|
|
== key types
|
|
|
|
=== RouterFacade
|
|
* **kind**: interface
|
|
* **purpose**: Entry point for user input. Returns a `RouterResponse`.
|
|
|
|
=== DefaultRouterFacade
|
|
* **kind**: class
|
|
* **purpose**: Coordinates repository, context builder, inference router, and event store to process user input. Supports `CHAT` and `STEERING` modes.
|
|
|
|
=== RouterRepository
|
|
* **kind**: interface
|
|
* **purpose**: Rebuilds `RouterState` for a session.
|
|
|
|
=== DefaultRouterRepository
|
|
* **kind**: class
|
|
* **purpose**: Rebuilds `RouterState` via `EventReplayer`.
|
|
|
|
=== RouterContextBuilder
|
|
* **kind**: interface
|
|
* **purpose**: Builds a router-specific `ContextPack` from `RouterState` and a token budget.
|
|
|
|
=== DefaultRouterContextBuilder
|
|
* **kind**: class
|
|
* **purpose**: Assembles L0 entries (system prompt, workflow status) and L1 entries (conversation history, stage summaries). Uses token budget with oldest-first eviction.
|
|
|
|
=== RouterReducer / DefaultRouterReducer
|
|
* **kind**: interface / class
|
|
* **purpose**: Transforms `RouterState` given stored events. Handles `WorkflowStartedEvent`, `WorkflowCompletedEvent`, `WorkflowFailedEvent`, `OrchestrationPausedEvent`, `OrchestrationResumedEvent`, `StageCompletedEvent`, `StageFailedEvent`.
|
|
|
|
=== RouterProjector
|
|
* **kind**: class
|
|
* **purpose**: Wraps `RouterReducer` as a `Projection<RouterState>`.
|
|
|
|
=== RouterState
|
|
* **kind**: data class
|
|
* **purpose**: Event-sourced state for the router.
|
|
* **fields**: `sessionId`, `workflowStatus`, `currentStageId`, `l2Memory` (list of `RouterL2Entry`), `conversationHistory` (list of `RouterTurn`)
|
|
|
|
=== RouterConfig
|
|
* **kind**: data class
|
|
* **purpose**: Configuration for the router.
|
|
* **fields**: `conversationKeepLast` (default 6), `tokenBudget` (default 4096)
|
|
|
|
=== RouterResponse
|
|
* **kind**: data class
|
|
* **purpose**: Response from the router to the user.
|
|
* **fields**: `content`, `steeringEmitted`
|
|
|
|
=== WorkflowStatus
|
|
* **kind**: enum
|
|
* **variants**: `IDLE`, `RUNNING`, `PAUSED`, `COMPLETED`, `FAILED`
|
|
|
|
=== StageOutcomeKind
|
|
* **kind**: enum
|
|
* **variants**: `SUCCESS`, `FAILURE`, `CANCELLED`
|
|
|
|
=== RouterL2Entry
|
|
* **kind**: data class
|
|
* **purpose**: A summary of a completed/failed stage for L2 memory.
|
|
* **fields**: `stageId`, `summary`, `outcome`, `timestamp`
|
|
|
|
=== RouterTurn
|
|
* **kind**: data class
|
|
* **purpose**: A single turn in the conversation history.
|
|
* **fields**: `role` (TurnRole), `content`, `timestamp`
|
|
|
|
=== TurnRole
|
|
* **kind**: enum
|
|
* **variants**: `USER`, `ROUTER`
|
|
|
|
=== ChatMode
|
|
* **kind**: enum
|
|
* **variants**: `CHAT`, `STEERING`
|
|
|
|
== event flow
|
|
|
|
*inbound:*
|
|
* `WorkflowStartedEvent` → sets session ID, status to `RUNNING`, current stage
|
|
* `WorkflowCompletedEvent` → sets status to `COMPLETED`, clears current stage
|
|
* `WorkflowFailedEvent` → sets status to `FAILED`, clears current stage
|
|
* `OrchestrationPausedEvent` → sets status to `PAUSED`
|
|
* `OrchestrationResumedEvent` → sets status to `RUNNING`
|
|
* `StageCompletedEvent` → appends L2 entry with outcome SUCCESS
|
|
* `StageFailedEvent` → appends L2 entry with outcome FAILURE, clears current stage
|
|
|
|
*outbound:*
|
|
* `SteeringNoteAddedEvent` → emitted by `DefaultRouterFacade` when mode is `STEERING` and user submits input
|
|
|
|
== integration points
|
|
|
|
* `:core:events` — `StoredEvent`, `SteeringNoteAddedEvent`, orchestration lifecycle event types, `EventStore`, `EventMetadata`, `EventId`, `SessionId`, `StageId`
|
|
* `:core:context` — `ContextPack`, `ContextEntry`, `ContextLayer`, `CompressionMetadata`, `TokenBudget`, `ContextEntryId`, `ContextPackId`
|
|
* `:core:inference` — `InferenceRouter`, `InferenceRequest`, `InferenceProvider`, `GenerationConfig`, `ModelCapability`, `ResponseFormat`
|
|
* `:core:sessions` — `Projection`, `EventReplayer`
|
|
|
|
== invariants
|
|
|
|
* Conversation history is held in-memory in `DefaultRouterFacade` — it is not rebuilt from events. On restart, conversation history is empty.
|
|
* `RouterTurn` is separate from the event-sourced conversation log — the reducer does not track individual turns, only L2 stage entries.
|
|
* L2 entries are created by the reducer from `StageCompletedEvent` and `StageFailedEvent` metadata, not from actual LLM-generated summaries.
|
|
* `RouterContextBuilder.L0` entries (system prompt, workflow status) are never dropped. L1 and L2 entries are evicted oldest-first under budget pressure.
|
|
|
|
== PlantUML diagram
|
|
|
|
[plantuml, core-router, "png"]
|
|
----
|
|
include::../../diagrams/core-router.puml[]
|
|
----
|
|
|
|
|
|
|
|
|
|
== known issues
|
|
|
|
* Conversation history is held in a `ConcurrentHashMap` in `DefaultRouterFacade` and is not event-sourced. This means router conversation context is lost on process restart. The reducer tracks event-derived L2 entries but not individual conversation turns.
|
|
|
|
== open questions
|
|
|
|
* Should conversation turns be event-sourced so the full conversation survives restarts?
|
|
* The `RouterTurn` timestamp is generated by `Clock.System.now()` on the facade side — should it be derived from event metadata instead?
|