Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions packages/agent/src/adapters/codex-app-server/models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
formatCodexModelName,
getReasoningEffortOptions,
modelIdFromConfigOptions,
supportsMaxEffort,
supportsXhighEffort,
} from "./models";

Expand All @@ -30,8 +31,8 @@ describe("getReasoningEffortOptions", () => {
"gpt-5.6-luna",
"openai/gpt-5.6-sol",
"GPT-5.6-SOL",
])("offers Extra High for the gpt-5.6 family (%s)", (modelId) => {
expect(values(modelId)).toEqual(["low", "medium", "high", "xhigh"]);
])("offers Max for the gpt-5.6 family (%s)", (modelId) => {
expect(values(modelId)).toEqual(["low", "medium", "high", "xhigh", "max"]);
});

it.each(["gpt-5.3-codex", "gpt-5.1", "o3"])(
Expand All @@ -57,6 +58,14 @@ describe("supportsXhighEffort", () => {
});
});

describe("supportsMaxEffort", () => {
it("is true only for the gpt-5.6 family", () => {
expect(supportsMaxEffort("gpt-5.6-sol")).toBe(true);
expect(supportsMaxEffort("GPT-5.6-LUNA")).toBe(true);
expect(supportsMaxEffort("gpt-5.5")).toBe(false);
});
});

describe("modelIdFromConfigOptions", () => {
const modelOption = (currentValue: unknown): SessionConfigOption =>
({
Expand Down
13 changes: 10 additions & 3 deletions packages/agent/src/adapters/codex-app-server/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,28 @@ const CODEX_REASONING_EFFORT_OPTIONS: ReasoningEffortOption[] = [
{ value: "high", name: "High" },
];

// OpenAI's `reasoning_effort` exposes an "extra high" tier only on the gpt-5.5
// and gpt-5.6 families, matching what the Codex app offers. Older models top
// out at "high".
// OpenAI's `reasoning_effort` exposes an "extra high" tier on the gpt-5.5 and
// gpt-5.6 families. GPT-5.6 also supports the "max" tier. Older models top out
// at "high".
export function supportsXhighEffort(modelId: string): boolean {
const id = modelId.toLowerCase();
return id.includes("gpt-5.5") || id.includes("gpt-5.6");
}

export function supportsMaxEffort(modelId: string): boolean {
return modelId.toLowerCase().includes("gpt-5.6");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Substring Capability Gate

When a custom or gateway-provided model ID contains gpt-5.6 but is not one of the supported GPT-5.6 Codex variants, this gate still exposes max. Selecting it can send an unsupported effort value to the runtime and fail task startup for that model.

Rule Used: When implementing new features, ensure that the UI... (source)

Learned From
PostHog/posthog#32595
PostHog/posthog#32677

}

export function getReasoningEffortOptions(
modelId: string,
): ReasoningEffortOption[] {
const options = [...CODEX_REASONING_EFFORT_OPTIONS];
if (supportsXhighEffort(modelId)) {
options.push({ value: "xhigh", name: "Extra High" });
}
if (supportsMaxEffort(modelId)) {
options.push({ value: "max", name: "Max" });
}
return options;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/agent/src/adapters/reasoning-effort.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ describe("isSupportedReasoningEffort", () => {
);
});

it("accepts xhigh but not max for the codex gpt-5.6 family", () => {
it("accepts xhigh and max for the codex gpt-5.6 family", () => {
expect(isSupportedReasoningEffort("codex", "gpt-5.6-luna", "xhigh")).toBe(
true,
);
expect(isSupportedReasoningEffort("codex", "gpt-5.6-sol", "max")).toBe(
false,
true,
);
});

Expand Down
Loading