route a subagent by its model, not by the default
Both arms took default_provider(), so `model` renamed the request without rerouting it: kimi-k3 went to Anthropic and came back 404 (2026-08-14). That was loud by luck — a name the default provider recognises would have run the wrong model in silence. The inherit arm was wrong the same way and quietly. An unroutable override is now refused rather than guessed at, per for_model's own contract.
This commit is contained in:
parent
63ef8e5b55
commit
1ef8a20a6b
1 changed files with 34 additions and 12 deletions
|
|
@ -44,7 +44,35 @@ impl SubagentRunner for ServerSubagentRunner {
|
|||
)
|
||||
})?;
|
||||
|
||||
let model = params.model.unwrap_or(agent.llm_config.model.clone());
|
||||
// A model must carry its wire with it. Both arms used to take
|
||||
// `default_provider()`, so an override was a name change and not a
|
||||
// route change: `kimi-k3` was sent to Anthropic, which answered
|
||||
// `404 model: kimi-k3` (2026-08-14). That failure was loud only by
|
||||
// luck — a name the default provider happens to recognise would have
|
||||
// run the wrong model in silence. The inherit arm was wrong the same
|
||||
// way, and quietly: a fork of an agent whose provider is not the
|
||||
// default went to the wrong wire with a model that provider does not
|
||||
// serve.
|
||||
//
|
||||
// An unroutable override is refused rather than guessed at, which is
|
||||
// `for_model`'s own instruction — "no entry" and "wrong entry" both
|
||||
// mean don't guess a wire for this model.
|
||||
let (model, llm) = match params.model {
|
||||
Some(m) => {
|
||||
let provider = self.server.providers.for_model(&m).ok_or_else(|| {
|
||||
crate::core::tools::defs::ToolError::invalid_input(&format!(
|
||||
"No provider is configured for model `{m}`. Add a \
|
||||
[models.\"{m}\"] entry naming its provider, or omit \
|
||||
`model` to inherit the parent's."
|
||||
))
|
||||
})?;
|
||||
(m, provider)
|
||||
}
|
||||
None => (
|
||||
agent.llm_config.model.clone(),
|
||||
self.server.providers.for_agent(&agent),
|
||||
),
|
||||
};
|
||||
let temperature = agent.llm_config.temperature;
|
||||
|
||||
// Resolve limits from config or params
|
||||
|
|
@ -151,17 +179,11 @@ impl SubagentRunner for ServerSubagentRunner {
|
|||
tools: Some(bifrost_tools.clone()),
|
||||
};
|
||||
|
||||
let response = self
|
||||
.server
|
||||
.providers
|
||||
.default_provider()
|
||||
.chat_completion(req)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
crate::core::tools::defs::ToolError::invalid_input(&format!(
|
||||
"Subagent LLM call failed: {e}"
|
||||
))
|
||||
})?;
|
||||
let response = llm.chat_completion(req).await.map_err(|e| {
|
||||
crate::core::tools::defs::ToolError::invalid_input(&format!(
|
||||
"Subagent LLM call failed: {e}"
|
||||
))
|
||||
})?;
|
||||
|
||||
if response.tool_calls.is_empty() {
|
||||
final_content = response.content.clone();
|
||||
|
|
|
|||
Loading…
Reference in a new issue