fix(providers): mark groq compound and allam-2-7b as non-reasoning models (#12379)

groq/compound and allam-2-7b were absent from the curated Groq registry, so the capability heuristic defaulted them to reasoning-capable and forwarded reasoning_effort verbatim — Groq answers HTTP 400. Declaring supportsReasoning: false makes applyThinkingBudget() strip reasoning_effort, output_config.effort and thinking, same class as #3258. The gpt-oss reasoning models keep the field.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
This commit is contained in:
Paco Cartones
2026-09-02 08:12:18 +02:00
committed by GitHub
parent 090ae83e12
commit 8e474914ea
3 changed files with 66 additions and 0 deletions

View File

@@ -0,0 +1 @@
- **fix(providers):** declare `groq/compound` and `allam-2-7b` as non-reasoning models in the curated Groq registry so `reasoning_effort` / `output_config.effort` / `thinking` from Claude Code are stripped instead of forwarded, which Groq rejected with HTTP 400 ([#12134](https://github.com/diegosouzapw/OmniRoute/issues/12134))

View File

@@ -16,6 +16,10 @@ export const groqProvider: RegistryEntry = {
supportsReasoning: false,
},
{ id: "llama-3.3-70b-versatile", name: "Llama 3.3 70B", supportsReasoning: false },
// Same class (#12134): compound and ALLaM are not reasoning models on Groq either, so
// declare it here — undeclared models default to reasoning-capable via the heuristic.
{ id: "groq/compound", name: "Groq Compound", supportsReasoning: false },
{ id: "allam-2-7b", name: "ALLaM 2 7B", supportsReasoning: false },
{ id: "openai/gpt-oss-120b", name: "GPT-OSS 120B" },
{ id: "openai/gpt-oss-20b", name: "GPT-OSS 20B" },
{ id: "qwen/qwen3-32b", name: "Qwen3 32B" },

View File

@@ -0,0 +1,61 @@
import test from "node:test";
import assert from "node:assert/strict";
const { applyThinkingBudget, setThinkingBudgetConfig, ThinkingMode, DEFAULT_THINKING_CONFIG } =
await import("../../open-sse/services/thinkingBudget.ts");
// Regression coverage for #12134 (same class as #3258): Claude Code → Groq failed with
// `reasoning_effort` HTTP 400 for `groq/compound` and `allam-2-7b`. Neither model was in the
// curated Groq registry, so the capability heuristic defaulted them to reasoning-capable and
// `reasoning_effort` (derived from Claude Code's `output_config.effort`) was forwarded verbatim.
// Both must now be declared `supportsReasoning: false` so the field is stripped, while reasoning
// models (gpt-oss) keep it.
test("#12134 groq/groq/compound strips reasoning_effort", () => {
setThinkingBudgetConfig({ mode: ThinkingMode.PASSTHROUGH });
const out = applyThinkingBudget({
model: "groq/groq/compound",
messages: [{ role: "user", content: "hi" }],
reasoning_effort: "medium",
}) as Record<string, unknown>;
assert.equal(out.reasoning_effort, undefined, "reasoning_effort must be stripped for compound");
setThinkingBudgetConfig(DEFAULT_THINKING_CONFIG);
});
test("#12134 groq/groq/compound strips output_config.effort and thinking", () => {
setThinkingBudgetConfig({ mode: ThinkingMode.PASSTHROUGH });
const out = applyThinkingBudget({
model: "groq/groq/compound",
messages: [{ role: "user", content: "hi" }],
output_config: { effort: "high" },
thinking: { type: "enabled", budget_tokens: 10240 },
}) as Record<string, { effort?: unknown } | undefined>;
assert.equal(out.thinking, undefined, "thinking must be stripped");
assert.ok(
!out.output_config || out.output_config.effort === undefined,
"output_config.effort must be stripped (else claude→openai re-injects reasoning_effort)"
);
setThinkingBudgetConfig(DEFAULT_THINKING_CONFIG);
});
test("#12134 groq/allam-2-7b strips reasoning_effort", () => {
setThinkingBudgetConfig({ mode: ThinkingMode.PASSTHROUGH });
const out = applyThinkingBudget({
model: "groq/allam-2-7b",
messages: [{ role: "user", content: "hi" }],
reasoning_effort: "low",
}) as Record<string, unknown>;
assert.equal(out.reasoning_effort, undefined, "reasoning_effort must be stripped for allam");
setThinkingBudgetConfig(DEFAULT_THINKING_CONFIG);
});
test("#12134 groq/openai/gpt-oss-20b KEEPS reasoning_effort (reasoning model — no regression)", () => {
setThinkingBudgetConfig({ mode: ThinkingMode.PASSTHROUGH });
const out = applyThinkingBudget({
model: "groq/openai/gpt-oss-20b",
messages: [{ role: "user", content: "hi" }],
reasoning_effort: "high",
}) as Record<string, unknown>;
assert.equal(out.reasoning_effort, "high", "gpt-oss is a reasoning model — must keep the field");
setThinkingBudgetConfig(DEFAULT_THINKING_CONFIG);
});