114 lines
3.8 KiB
TypeScript
114 lines
3.8 KiB
TypeScript
/**
|
|
* Issue #2331 — Codex model alias effort suffixes
|
|
* (`gpt-5.5-xhigh`, `-high`, `-medium`, `-low`) are the user's explicit
|
|
* routing choice and must override a client-injected `reasoning.effort`
|
|
* default. OpenCode auto-injects `reasoning.effort=medium` for GPT-5-family
|
|
* requests, which used to silently mask the suffix.
|
|
*
|
|
* The fix is in `open-sse/executors/codex.ts`: priority is
|
|
* modelEffort > explicitReasoning > requestReasoningEffort > fallback.
|
|
*
|
|
* These tests exercise the effort-resolution priority directly via a
|
|
* small re-implementation of the resolution chain so we don't have to
|
|
* spin up the full Codex executor (which talks to upstream).
|
|
*/
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
// Replicate the priority chain that lives in
|
|
// open-sse/executors/codex.ts:1382-1402 so tests fail loudly if someone
|
|
// reverts the order.
|
|
type Inputs = {
|
|
modelEffort: string | null;
|
|
explicitReasoning: string | undefined;
|
|
requestReasoningEffort: string | undefined;
|
|
fallbackReasoningEffort: string | undefined;
|
|
};
|
|
|
|
function resolveEffort(i: Inputs): string | undefined {
|
|
return (
|
|
i.modelEffort ||
|
|
i.explicitReasoning ||
|
|
i.requestReasoningEffort ||
|
|
i.fallbackReasoningEffort ||
|
|
undefined
|
|
);
|
|
}
|
|
|
|
test("#2331 model suffix wins over client reasoning.effort default", () => {
|
|
const out = resolveEffort({
|
|
modelEffort: "xhigh",
|
|
explicitReasoning: "medium", // OpenCode default
|
|
requestReasoningEffort: undefined,
|
|
fallbackReasoningEffort: undefined,
|
|
});
|
|
assert.equal(out, "xhigh");
|
|
});
|
|
|
|
test("#2331 model suffix wins over body.reasoning_effort field too", () => {
|
|
const out = resolveEffort({
|
|
modelEffort: "low",
|
|
explicitReasoning: undefined,
|
|
requestReasoningEffort: "high",
|
|
fallbackReasoningEffort: undefined,
|
|
});
|
|
assert.equal(out, "low");
|
|
});
|
|
|
|
test("#2331 without suffix, explicit client effort still works (backward compat)", () => {
|
|
const out = resolveEffort({
|
|
modelEffort: null,
|
|
explicitReasoning: "high",
|
|
requestReasoningEffort: undefined,
|
|
fallbackReasoningEffort: "medium",
|
|
});
|
|
assert.equal(out, "high");
|
|
});
|
|
|
|
test("#2331 without suffix or client value, connection fallback applies", () => {
|
|
const out = resolveEffort({
|
|
modelEffort: null,
|
|
explicitReasoning: undefined,
|
|
requestReasoningEffort: undefined,
|
|
fallbackReasoningEffort: "medium",
|
|
});
|
|
assert.equal(out, "medium");
|
|
});
|
|
|
|
test("#2331 no input anywhere → undefined (caller will skip body.reasoning)", () => {
|
|
const out = resolveEffort({
|
|
modelEffort: null,
|
|
explicitReasoning: undefined,
|
|
requestReasoningEffort: undefined,
|
|
fallbackReasoningEffort: undefined,
|
|
});
|
|
assert.equal(out, undefined);
|
|
});
|
|
|
|
// ─── Regression check on the actual source ─────────────────────────────
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const CODEX_SRC = path.resolve(__dirname, "../../open-sse/executors/codex.ts");
|
|
|
|
test("#2331 codex.ts still prioritizes modelEffort first in rawEffort chain", () => {
|
|
const src = fs.readFileSync(CODEX_SRC, "utf8");
|
|
|
|
// The chain we expect: rawEffort = modelEffort || explicitReasoning || ...
|
|
// Anchor on the assignment so a future refactor that flips priority back
|
|
// (the bug we just fixed) trips this guard.
|
|
const ASSIGNMENT_RE = /const\s+rawEffort\s*=\s*([\s\S]{0,400}?);/;
|
|
const match = src.match(ASSIGNMENT_RE);
|
|
assert.ok(match, "rawEffort assignment not found in codex.ts");
|
|
|
|
const chain = match![1].replace(/\s+/g, " ").trim();
|
|
const firstToken = chain.split("||")[0].trim();
|
|
assert.equal(
|
|
firstToken,
|
|
"modelEffort",
|
|
`rawEffort priority chain must start with modelEffort, got: ${chain}`
|
|
);
|
|
});
|