feat: correx-managed model lifecycle slice 2 — per-stage model selection

StageConfig.modelId; InferenceRouter gains a backward-compatible model-aware
route() overload (default ignores modelId, so static routers and test fakes are
unaffected). New ManagedInferenceRouter (infra commons) resolves a target model
per stage (stage.modelId > capability match > default) and ensureLoaded()s it
before routing, returning the live managed provider — its id changes with the
resident model, so there is no stale health cache to invalidate on swap.
ModelManager.ensureLoaded default delegates to the idempotent load(). Main wires
the managed router on the [[models]] path; the static path keeps DefaultInferenceRouter.

Plan: docs/plans/2026-05-31-model-lifecycle-management.md (slice 2 of 5).
This commit is contained in:
2026-06-01 11:35:51 +04:00
parent e45a626cc4
commit 382194b498
8 changed files with 240 additions and 2 deletions
@@ -753,7 +753,7 @@ abstract class SessionOrchestrator(
timeoutMs: Long,
responseFormat: ResponseFormat = ResponseFormat.Text,
): InferenceResult {
val provider = inferenceRouter.route(stageId, stageConfig.requiredCapabilities)
val provider = inferenceRouter.route(stageId, stageConfig.requiredCapabilities, stageConfig.modelId)
log.debug(
"[Orchestrator] inference session={} stage={} provider={} timeoutMs={}",
sessionId.value, stageId.value, provider.id.value, timeoutMs,