mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-05 04:48:17 +00:00
fix(openrouter): skip reasoning effort injection for 'auto' routing model
The 'auto' model on OpenRouter dynamically routes to any underlying model
OpenRouter selects, including reasoning-required endpoints. Previously,
OpenClaw would unconditionally inject `reasoning.effort: "none"` into
every request when the thinking level was "off", which causes a 400 error
on models where reasoning is mandatory and cannot be disabled.
Root cause:
- openrouter/auto has reasoning: false in the built-in catalog
- With thinking level "off", createOpenRouterWrapper injects
`reasoning: { effort: "none" }` via mapThinkingLevelToOpenRouterReasoningEffort
- For any OpenRouter-routed model that requires reasoning this results in:
"400 Reasoning is mandatory for this endpoint and cannot be disabled"
- The reasoning: false is then persisted back to models.json on every
ensureOpenClawModelsJson call, so manually removing it has no lasting effect
Fix:
- In applyExtraParamsToAgent, when provider is "openrouter" and the model
id is "auto", pass undefined as thinkingLevel to createOpenRouterWrapper
so no reasoning.effort is injected at all, letting OpenRouter's upstream
model handle it natively
- Add an explanatory comment in buildOpenrouterProvider clarifying that the
reasoning: false catalog value does NOT cause effort injection for "auto"
Users who need explicit reasoning control should target a specific model
id (e.g. openrouter/deepseek/deepseek-r1) rather than the auto router.
Fixes #24851
(cherry picked from commit aa55439798)
This commit is contained in:
committed by
Peter Steinberger
parent
eae13d9367
commit
bc52d4a459
@@ -685,6 +685,12 @@ function buildOpenrouterProvider(): ProviderConfig {
|
|||||||
{
|
{
|
||||||
id: OPENROUTER_DEFAULT_MODEL_ID,
|
id: OPENROUTER_DEFAULT_MODEL_ID,
|
||||||
name: "OpenRouter Auto",
|
name: "OpenRouter Auto",
|
||||||
|
// reasoning: false here is a catalog default only; it does NOT cause
|
||||||
|
// `reasoning.effort: "none"` to be sent for the "auto" routing model.
|
||||||
|
// applyExtraParamsToAgent skips the reasoning effort injection for
|
||||||
|
// model id "auto" because it dynamically routes to any OpenRouter model
|
||||||
|
// (including ones where reasoning is mandatory and cannot be disabled).
|
||||||
|
// See: openclaw/openclaw#24851
|
||||||
reasoning: false,
|
reasoning: false,
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
cost: OPENROUTER_DEFAULT_COST,
|
cost: OPENROUTER_DEFAULT_COST,
|
||||||
|
|||||||
@@ -546,7 +546,14 @@ export function applyExtraParamsToAgent(
|
|||||||
|
|
||||||
if (provider === "openrouter") {
|
if (provider === "openrouter") {
|
||||||
log.debug(`applying OpenRouter app attribution headers for ${provider}/${modelId}`);
|
log.debug(`applying OpenRouter app attribution headers for ${provider}/${modelId}`);
|
||||||
agent.streamFn = createOpenRouterWrapper(agent.streamFn, thinkingLevel);
|
// "auto" is a dynamic routing model — we don't know which underlying model
|
||||||
|
// OpenRouter will select, and it may be a reasoning-required endpoint.
|
||||||
|
// Omit the thinkingLevel so we never inject `reasoning.effort: "none"`,
|
||||||
|
// which would cause a 400 on models where reasoning is mandatory.
|
||||||
|
// Users who need reasoning control should target a specific model ID.
|
||||||
|
// See: openclaw/openclaw#24851
|
||||||
|
const openRouterThinkingLevel = modelId === "auto" ? undefined : thinkingLevel;
|
||||||
|
agent.streamFn = createOpenRouterWrapper(agent.streamFn, openRouterThinkingLevel);
|
||||||
agent.streamFn = createOpenRouterSystemCacheWrapper(agent.streamFn);
|
agent.streamFn = createOpenRouterSystemCacheWrapper(agent.streamFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user