feat(router,inference,config): pin narration to a configured model_id

[router.narration] model_id selects which provider handles narration turns
instead of generic capability routing — lets a small/fast model own narration
while the main model keeps CHAT/STEERING.

- NarrationSettings.modelId parsed from TOML, threaded via RouterConfig
  .narrationModelId into DefaultRouterFacade.narrate (3-arg route)
- DefaultInferenceRouter: exact-id match against healthy providers, with a
  post-select health check; any miss logs WARN and falls back to capability
  routing (never fails the narration turn)
- onUserInput unchanged — only narrate uses the pinned model (tested)
This commit is contained in:
2026-06-10 20:53:28 +04:00
parent cc6b402a23
commit 883e23dec7
10 changed files with 192 additions and 1 deletions
@@ -175,7 +175,7 @@ class DefaultRouterFacade(
val contextPack = routerContextBuilder.buildNarrationContext(state, trigger, config.tokenBudget)
val provider = inferenceRouter.route(effectiveStageId, setOf(ModelCapability.General))
val provider = inferenceRouter.route(effectiveStageId, setOf(ModelCapability.General), config.narrationModelId)
val inferenceRequest = InferenceRequest(
requestId = InferenceRequestId(UUID.randomUUID().toString()),
sessionId = sessionId,
@@ -24,4 +24,5 @@ data class RouterConfig(
topP = 0.9,
maxTokens = 4096,
),
val narrationModelId: String? = null,
)