Files
correx/docs/modules/core/core-router.adoc
T
kami 9734eec63c docs: add module documentation in AsciiDoc with PlantUML diagrams
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.
2026-05-26 16:59:21 +04:00

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?