mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-10-19 05:20:05 +00:00
fix(claude): stop downgrading adaptive thinking on claude-haiku-5-5 (#15841)
⚠️ base-red inherited: #15306 Validated in local merge-train _artifacts/merge-wave-13/train2.log on devbox-vm-06-dev002 @ 59b137edc8bd23f9c95db60d65fa6dbc5ef00743 (FAST). All 13 boarded. Static gates green except inherited translation drift of docs/reference/ENVIRONMENT.md, the same violations on origin/release/v3.8.52. Changed node:test files passed 90/90 on rerun. The RTL sidebar test passed 19/19. Vitest 5s timeouts in autoCombo (#8601, #8603) reproduced on the pure origin/release/v3.8.52 tip; those files are not in this train's diff.
This commit is contained in:
parent
4b04b0f6b9
commit
52efa6f7bd
4 changed files with 50 additions and 3 deletions
1
changelog.d/fixes/15841-haiku-5-5-adaptive-thinking.md
Normal file
1
changelog.d/fixes/15841-haiku-5-5-adaptive-thinking.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
- **fix(claude):** `claude-haiku-5-5` requests keep `thinking.type: "adaptive"` instead of being downgraded to `"enabled"`, which Anthropic rejected with HTTP 400 ([#15841](https://github.com/diegosouzapw/OmniRoute/pull/15841)) — thanks @aldoeliacim
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
import { isAdaptiveThinkingOnly } from "../../src/shared/constants/modelSpecs.ts";
|
||||
|
||||
type JsonRecord = Record<string, unknown>;
|
||||
|
||||
// Models that reject `thinking.type:"adaptive"` and `output_config.effort` —
|
||||
// today, all Claude Haiku-tier models (4.5 / 3.5 / dated and aliased). Adaptive
|
||||
// thinking + the effort knob landed on Sonnet 4.6 / Opus 4.5+ only; sending
|
||||
// either on Haiku is a hard 400 from the Messages API.
|
||||
// Claude Haiku-tier models that predate adaptive thinking (4.5 / 3.5 / dated and
|
||||
// aliased). Haiku 5.5+ is adaptive-only (spec `adaptiveThinkingOnly`), so it
|
||||
// must NOT be rewritten here: the family regex alone wrongly downgrades it.
|
||||
// Adaptive thinking + the effort knob landed on Sonnet 4.6 / Opus 4.5+ and
|
||||
// Haiku 5.5; sending `enabled` to those is a hard 400 from the Messages API.
|
||||
const HAIKU_CONSTRAINT_PATTERN = /haiku/i;
|
||||
|
||||
// Default budget when collapsing `thinking.type:"adaptive"` to a manual shape
|
||||
|
|
@ -18,6 +22,9 @@ function asRecord(value: unknown): JsonRecord | null {
|
|||
|
||||
function modelRejectsAdaptiveAndEffort(modelId: string | null | undefined): boolean {
|
||||
if (typeof modelId !== "string" || modelId.length === 0) return false;
|
||||
// Spec is authoritative: an adaptive-only model accepts adaptive+effort, so
|
||||
// it is never rejected here regardless of its family name.
|
||||
if (isAdaptiveThinkingOnly(modelId)) return false;
|
||||
return HAIKU_CONSTRAINT_PATTERN.test(modelId);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -417,6 +417,21 @@ export const MODEL_SPECS: Record<string, ModelSpec> = {
|
|||
aliases: BEDROCK_CLAUDE_ALIASES("claude-sonnet-5"),
|
||||
},
|
||||
|
||||
// ── Claude Haiku 5.5 ────────────────────────────────────────────
|
||||
// Adaptive-thinking-only, like Sonnet 5.5: `thinking.type:"enabled"` returns
|
||||
// 400 ("use thinking.type.adaptive and output_config.effort"). Haiku 4.5 and
|
||||
// earlier still accept manual budgets, so this spec must NOT be widened to
|
||||
// the /haiku/ family. Limits from the gateway catalog (context 1M, output 128K).
|
||||
"claude-haiku-5-5": {
|
||||
maxOutputTokens: 128000,
|
||||
contextWindow: 1000000,
|
||||
supportsThinking: true,
|
||||
supportsTools: true,
|
||||
supportsVision: true,
|
||||
adaptiveThinkingOnly: true,
|
||||
aliases: BEDROCK_CLAUDE_ALIASES("claude-haiku-5-5"),
|
||||
},
|
||||
|
||||
// ── Claude Sonnet 5.5 ───────────────────────────────────────────
|
||||
"claude-sonnet-5-5": {
|
||||
// Same shape as Sonnet 5, but it rejects thinking.type:"disabled"
|
||||
|
|
|
|||
|
|
@ -72,6 +72,30 @@ describe("normalizeClaudeHaikuConstraints", () => {
|
|||
assert.strictEqual(out, input);
|
||||
});
|
||||
|
||||
// Regression: Haiku 5.5 is adaptive-only (spec adaptiveThinkingOnly). The
|
||||
// family regex used to rewrite its adaptive+effort to manual `enabled`, which
|
||||
// Anthropic rejects with a 400 ("use thinking.type.adaptive ...").
|
||||
it("leaves claude-haiku-5-5 adaptive thinking + effort untouched", () => {
|
||||
const input = {
|
||||
model: "claude-haiku-5-5",
|
||||
thinking: { type: "adaptive" },
|
||||
output_config: { effort: "high" },
|
||||
};
|
||||
const out = normalizeClaudeHaikuConstraints(input, input.model);
|
||||
assert.strictEqual(out, input);
|
||||
assert.deepEqual(out.thinking, { type: "adaptive" });
|
||||
assert.deepEqual(out.output_config, { effort: "high" });
|
||||
});
|
||||
|
||||
it("still downgrades adaptive on pre-5 Haiku (4.5 keeps the manual-only contract)", () => {
|
||||
const input = {
|
||||
model: "claude-haiku-4-5-20251001",
|
||||
thinking: { type: "adaptive" },
|
||||
};
|
||||
const out = normalizeClaudeHaikuConstraints(input, input.model);
|
||||
assert.deepEqual(out.thinking, { type: "enabled", budget_tokens: 10000 });
|
||||
});
|
||||
|
||||
it("leaves haiku bodies that have no adaptive thinking or effort untouched", () => {
|
||||
const input = {
|
||||
model: "claude-haiku-4-5-20251001",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue