mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-26 00:52:18 +03:00
Validated on the combined 8-PR board: the declared-vocabulary clamp integrates with #11232's learned-set clamp (both fire in sequence; REASONING_EFFORT_ORDER import added), reasoning quartet 57/57 including the new opencode-go suite 7/7, 88/88 across the board's focused suites, typecheck:core + dashboard-typecheck clean, all static gates within baseline. Retargeted main→release/v3.8.50 and rebased onto the release tip (authorship preserved; the branch carried main history, so only the real commit was carried). The generic explicit-capability clamp closes the Console Go 400 [1210] loop for models with a declared effort vocabulary. Thank you @linhdmn — the live-probe table in the PR body is exactly the evidence standard we want.
121 lines
5.1 KiB
TypeScript
121 lines
5.1 KiB
TypeScript
/**
|
|
* Console Go (opencode.ai/zen/go/v1) reasoning-effort vocabulary clamp.
|
|
*
|
|
* Live-reproduced 2026-08-23 via the Hermes Telegram bot → /v1/chat/completions:
|
|
* `opencode-go/ox-alpha-free` rejects every reasoning_effort except
|
|
* {low, high, max} whenever the request carries tools —
|
|
*
|
|
* [400] Error from provider (Console Go): Upstream request failed: [1210]
|
|
* This model always engages in thinking and cannot be disabled; please use
|
|
* low, high, or max
|
|
*
|
|
* Hermes sends reasoning_effort:"medium" with 24 tools and died on every turn.
|
|
* Two gaps let the bad value reach the upstream verbatim:
|
|
* 1. `ox-alpha-free` is a discovery-synced model with no static registry
|
|
* entry declaring its effort vocabulary.
|
|
* 2. sanitizeReasoningEffortForProvider only consults declared
|
|
* supportedThinkingEfforts in the `max` branch (max fallback); other
|
|
* out-of-vocabulary values pass through untouched.
|
|
*
|
|
* Fix under test: declare ["low","high","max"] on the registry entry and add a
|
|
* generic explicit-capability clamp that remaps any out-of-vocabulary effort to
|
|
* the nearest declared tier (smallest ranked ≥ requested, else the highest).
|
|
* Models without a declaration keep today's pass-through behavior (#8057).
|
|
*/
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
const { sanitizeReasoningEffortForProvider } = await import("../../open-sse/executors/base.ts");
|
|
const { REGISTRY } = await import("../../open-sse/config/providerRegistry.ts");
|
|
|
|
function makeLog() {
|
|
const messages: Array<[string, string]> = [];
|
|
return {
|
|
info: (tag: string, msg: string) => messages.push([tag, msg]),
|
|
messages,
|
|
};
|
|
}
|
|
|
|
const HERMES_BODY = {
|
|
model: "ox-alpha-free",
|
|
max_tokens: 65536,
|
|
stream_options: { include_usage: true },
|
|
messages: [{ role: "user", content: "Start telegram bot" }],
|
|
tools: [
|
|
{
|
|
type: "function",
|
|
function: { name: "clarify", description: "ask", parameters: { type: "object" } },
|
|
},
|
|
],
|
|
};
|
|
|
|
test("registry: opencode-go declares ox-alpha-free with the live-verified Console Go effort set", () => {
|
|
const entry = REGISTRY["opencode-go"];
|
|
assert.ok(entry, "opencode-go registry entry must exist");
|
|
const model = entry.models.find((m) => m.id === "ox-alpha-free");
|
|
assert.ok(model, "ox-alpha-free must be registered on opencode-go");
|
|
assert.deepEqual(model.supportedThinkingEfforts, ["low", "high", "max"]);
|
|
});
|
|
|
|
test("clamp: medium → high for ox-alpha-free (the exact Hermes failure)", () => {
|
|
const log = makeLog();
|
|
const body = { ...HERMES_BODY, reasoning_effort: "medium" };
|
|
const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "ox-alpha-free", log);
|
|
assert.notEqual(result, body, "must return a new object when mutating");
|
|
assert.equal((result as Record<string, unknown>).reasoning_effort, "high");
|
|
assert.ok(
|
|
log.messages.some(([tag, m]) => tag === "REASONING_SANITIZE" && /medium → high/.test(m)),
|
|
"logs the mapping"
|
|
);
|
|
});
|
|
|
|
test("clamp: disable-shaped efforts map to low (upstream refuses to stop thinking)", () => {
|
|
for (const effort of ["none", "minimal"]) {
|
|
const body = { ...HERMES_BODY, reasoning_effort: effort };
|
|
const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "ox-alpha-free", null);
|
|
assert.equal(
|
|
(result as Record<string, unknown>).reasoning_effort,
|
|
"low",
|
|
`${effort} → low`
|
|
);
|
|
}
|
|
});
|
|
|
|
test("clamp: xhigh → max for ox-alpha-free", () => {
|
|
const body = { ...HERMES_BODY, reasoning_effort: "xhigh" };
|
|
const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "ox-alpha-free", null);
|
|
assert.equal((result as Record<string, unknown>).reasoning_effort, "max");
|
|
});
|
|
|
|
test("clamp: in-vocabulary efforts pass through untouched", () => {
|
|
for (const effort of ["low", "high", "max"]) {
|
|
const body = { ...HERMES_BODY, reasoning_effort: effort };
|
|
const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "ox-alpha-free", null);
|
|
assert.equal(result, body, `${effort} must not be rewritten`);
|
|
assert.equal((result as Record<string, unknown>).reasoning_effort, effort);
|
|
}
|
|
});
|
|
|
|
test("clamp writes back to every carrier present (top-level + reasoning.effort + output_config.effort)", () => {
|
|
const body = {
|
|
...HERMES_BODY,
|
|
reasoning_effort: "medium",
|
|
reasoning: { effort: "medium" },
|
|
output_config: { effort: "medium" },
|
|
};
|
|
const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "ox-alpha-free", null) as Record<
|
|
string,
|
|
unknown
|
|
>;
|
|
assert.equal(result.reasoning_effort, "high");
|
|
assert.deepEqual(result.reasoning, { effort: "high" });
|
|
assert.deepEqual(result.output_config, { effort: "high" });
|
|
});
|
|
|
|
test("no declaration → pass-through unchanged (#8057 policy for unlisted models)", () => {
|
|
const body = { ...HERMES_BODY, model: "some-unregistered-model", reasoning_effort: "medium" };
|
|
const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "some-unregistered-model", null);
|
|
assert.equal(result, body, "undeclared models keep today's trust-the-upstream behavior");
|
|
assert.equal((result as Record<string, unknown>).reasoning_effort, "medium");
|
|
});
|