chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* 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}`
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user