fix(failover): send remote targets their own upstream model

A chain request reached a cloud-proxy target with the client's model,
the chain name, whenever the target set no upstream_model: passthrough
forwards the body's model and translate falls back to it. The upstream
answered 404, which neither retries nor trips, while the liveness
probe, which checks the target's own name, kept passing.

PrepareTarget now sets the upstream model of a remote target to
proxy.upstream_model or the target name, the same name the probe uses.
The request pipeline and realtime chain stages both call it.

Assisted-by: Claude:claude-opus-5-5
This commit is contained in:
Ettore Di Giacinto committed 2026-09-26 19:26:13 +00:00
1 parent d1a59aae41
commit e183ea11d1
8 files changed
+98 -7

No files matched your search

+13 -7
View File
@@ -1032,6 +1032,14 @@ func newModel(pipeline *config.Pipeline, cl *config.ModelConfigLoader, ml *model
// takes the chain's active target, so everything that inspects stage
// configs at session start (voice, reasoning, templates) sees a real model.
stageChains := map[string]string{}
loadTarget := func(name string) (*config.ModelConfig, error) {
cfg, err := cl.LoadResolvedModelConfig(name, ml.ModelPath, appConfig.ToConfigLoaderOptions()...)
if err != nil {
return nil, err
}
failover.PrepareTarget(cfg)
return cfg, nil
}
resolveStage := func(stage string, cfg *config.ModelConfig) (*config.ModelConfig, error) {
if cfg == nil || !cfg.IsFailover() {
return cfg, nil
@@ -1044,7 +1052,7 @@ func newModel(pipeline *config.Pipeline, cl *config.ModelConfigLoader, ml *model
return nil, fmt.Errorf("failover chain %q not found", cfg.Name)
}
stageChains[stage] = cfg.Name
return cl.LoadResolvedModelConfig(st.Active, ml.ModelPath, appConfig.ToConfigLoaderOptions()...)
return loadTarget(st.Active)
}
cfgVAD, err := cl.LoadResolvedModelConfig(pipeline.VAD, ml.ModelPath, appConfig.ToConfigLoaderOptions()...)
@@ -1185,12 +1193,10 @@ func newModel(pipeline *config.Pipeline, cl *config.ModelConfigLoader, ml *model
appConfig: appConfig,
evaluator: evaluator,
stageChains: stageChains,
stageTargetConfig: func(name string) (*config.ModelConfig, error) {
return cl.LoadResolvedModelConfig(name, ml.ModelPath, appConfig.ToConfigLoaderOptions()...)
},
tuneLLM: tuneLLM,
appTracing: appConfig.EnableTracing,
stageChains: stageChains,
stageTargetConfig: loadTarget,
tuneLLM: tuneLLM,
appTracing: appConfig.EnableTracing,
}
if routing != nil {
wm.routerDeps = routing.Deps