Files
OmniRoute/tests/unit/gemini-3-5-flash-thinking.test.ts
Diego Rodrigues de Sa e Souza b17dfa4a14 fix(sse): mark gemini-3.5-flash as thinking-capable (#10450)
The base gemini-3.5-flash entry spread the shared GEMINI_35_FLASH_MODEL_SPEC
constant, which has supportsThinking:false because it is also spread into
several Antigravity flash-tier aliases that reject client-supplied thinking
params. That made the reasoning-routing policy resolve reasoning_effort as
"unsupported" for the base Google AI Studio model, producing a spurious
pre-provider HTTP 400 even though the model supports reasoning (it has an
effort-tier alias gemini-3.5-flash-high).

Set supportsThinking:true as an explicit override on the base
gemini-3.5-flash entry only, leaving the shared spec and the Antigravity
tier aliases unchanged.

Closes #10286

Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com>
2026-08-17 05:49:16 -03:00

77 lines
2.6 KiB
TypeScript

// Regression test for #10286: gemini-3.5-flash was incorrectly marked
// supportsThinking:false, causing a spurious pre-provider HTTP 400 for any
// request with reasoning_effort set, even though the base Google AI Studio
// model supports reasoning (it has an effort-tier alias gemini-3.5-flash-high).
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-repro-10286-"));
process.env.DATA_DIR = TEST_DATA_DIR;
process.env.API_KEY_SECRET = process.env.API_KEY_SECRET || "test-repro-10286-secret";
const caps = await import("../../src/lib/modelCapabilities.ts");
const core = await import("../../src/lib/db/core.ts");
const rulesDb = await import("../../src/lib/db/reasoningRoutingRules.ts");
const policy = await import("../../src/lib/reasoningRouting/policy.ts");
async function resetStorage() {
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
rulesDb.invalidateReasoningRoutingRuleCache();
}
function ruleInput(patch: Record<string, unknown> = {}) {
return {
name: "Enable thinking on gemini-3.5-flash",
description: "",
scope: "global",
apiKeyId: null,
comboId: null,
connectionId: null,
modelPattern: "gemini-3.5-flash",
sourceEffort: "any",
requestTags: [],
tagMatchMode: "any",
effortMode: "inherit",
targetEffort: null,
targetKind: "keep",
targetModel: null,
targetComboId: null,
budgetAction: "preserve",
budgetTokens: null,
priority: 0,
enabled: true,
...patch,
};
}
test.beforeEach(resetStorage);
test.after(async () => {
await resetStorage();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
});
test("gemini-3.5-flash (AI Studio provider) resolves as thinking-capable", () => {
const resolved = caps.getResolvedModelCapabilities({
provider: "gemini",
model: "gemini-3.5-flash",
});
assert.equal(resolved.supportsThinking, true);
});
test("reasoning_effort 'high' on gemini-3.5-flash is NOT rejected by routing policy", async () => {
await rulesDb.createReasoningRoutingRule(ruleInput());
const decision = await policy.resolveReasoningRoutingRule({
sourceModel: "gemini/gemini-3.5-flash",
sourceModelAliases: ["gemini-3.5-flash"],
sourceEffort: "high",
hasReasoningSignal: true,
});
assert.ok(decision, "a matching rule must produce a decision");
assert.equal(decision.capability, "supported");
});