fix(providers): restore grok-4.6/4.5 default reasoning effort (#13628)

This commit is contained in:
Bob.Hou
2026-09-16 07:15:21 -04:00
committed by GitHub
parent 54f19c7742
commit b4f51b2e9e
5 changed files with 105 additions and 2 deletions

View File

@@ -0,0 +1,2 @@
- fix(providers): restore grok-4.6/4.5 default reasoning effort so requests without an explicit effort keep reasoning enabled (#13628)
- fix(registry): declare supportedThinkingEfforts on claude-opus-5 and claude-fable-5 across the anthropic/claude/claude-web/ghe-copilot/github registries (#13628)

View File

@@ -21,7 +21,7 @@
},
"open-sse/config/providers/registry/claude/index.ts": {
"@typescript-eslint/no-unused-vars": {
"count": 7
"count": 6
}
},
"open-sse/config/providers/registry/vertex/index.ts": {

View File

@@ -26,6 +26,7 @@ export const grok_cliProvider: RegistryEntry = {
name: "Grok 4.6",
contextLength: 500000,
supportsReasoning: true,
supportedThinkingEfforts: ["low", "medium", "high"],
toolCalling: true,
targetFormat: "openai-responses",
unsupportedParams: ["presencePenalty", "frequencyPenalty", "logprobs", "topLogprobs"],
@@ -35,6 +36,7 @@ export const grok_cliProvider: RegistryEntry = {
name: "Grok 4.5",
contextLength: 500000,
supportsReasoning: true,
supportedThinkingEfforts: ["low", "medium", "high"],
toolCalling: true,
targetFormat: "openai-responses",
unsupportedParams: ["presencePenalty", "frequencyPenalty", "logprobs", "topLogprobs"],

View File

@@ -127,13 +127,18 @@ function normalizeGrokBuildReasoning(
model: string
): Record<string, unknown> | null {
const reasoning = asRequestRecord(value);
// Capture BEFORE stripping: an explicit (but unsupported/invalid, e.g. "none"/"off"/
// "xhigh") effort must still count as an explicit off-switch below — only the true
// ABSENCE of an effort key gets the model default. Restores the #7358 behavior the
// 4.6 default accidentally regressed: without this, every explicit "none"/"off" from
// grok-cli got silently promoted to "high", leaving no way to disable reasoning.
const hasExplicitEffort = Object.prototype.hasOwnProperty.call(reasoning, "effort");
if (!GROK_BUILD_REASONING_EFFORT_SET.has(String(reasoning.effort))) {
delete reasoning.effort;
}
if (model === "grok-composer-2.5-fast") {
delete reasoning.effort;
} else if (model === "grok-4.5" && !hasExplicitEffort) {
} else if ((model === "grok-4.5" || model === "grok-4.6") && !hasExplicitEffort) {
reasoning.effort = GROK_BUILD_DEFAULT_REASONING_EFFORT;
}
return Object.keys(reasoning).length > 0 ? reasoning : null;

View File

@@ -96,6 +96,9 @@ test("grok-cli preserves explicit store and de-duplicates encrypted reasoning in
assert.equal(out.store, true);
assert.deepEqual(out.include, ["reasoning.encrypted_content"]);
// An explicit (but unsupported) effort like "xhigh" is still an EXPLICIT effort key —
// it gets stripped, not defaulted. Only the true absence of an "effort" key falls back
// to the model default. This is the off-switch #7358 relied on and #13628 regressed.
assert.equal("reasoning" in out, false);
});
@@ -113,3 +116,94 @@ test("grok-cli preserves an explicit Responses reasoning summary", () => {
assert.deepEqual(out.reasoning, { summary: "concise", effort: "high" });
});
test("grok-4.6 applies default high when client omits effort", async () => {
const executor = new GrokCliExecutor();
const body = {
model: "grok-4.6",
input: [{ role: "user", content: [{ type: "input_text", text: "hi" }] }],
};
const transformed = executor.transformRequest(
"grok-4.6",
body,
false,
{} as Record<string, unknown>
) as Record<string, unknown>;
assert.deepEqual(transformed.reasoning, { effort: "high" });
});
test("grok-4.6 preserves an explicit supported effort", async () => {
const executor = new GrokCliExecutor();
const body = {
model: "grok-4.6",
input: [{ role: "user", content: [{ type: "input_text", text: "hi" }] }],
reasoning: { effort: "medium", summary: "auto" },
};
const transformed = executor.transformRequest(
"grok-4.6",
body,
false,
{} as Record<string, unknown>
) as Record<string, unknown>;
assert.deepEqual(transformed.reasoning, { effort: "medium", summary: "auto" });
});
test("grok-4.6 strips an explicit but unsupported xhigh (no default restore — an explicit effort key is an explicit choice)", async () => {
const executor = new GrokCliExecutor();
const body = {
model: "grok-4.6",
input: [{ role: "user", content: [{ type: "input_text", text: "hi" }] }],
reasoning: { effort: "xhigh" },
reasoning_effort: "xhigh",
};
const transformed = executor.transformRequest(
"grok-4.6",
body,
false,
{} as Record<string, unknown>
) as Record<string, unknown>;
assert.equal("reasoning_effort" in transformed, false);
assert.equal("reasoning" in transformed, false);
});
test("grok-4.6 keeps an explicit none/off as a real off-switch (no default restore)", async () => {
const executor = new GrokCliExecutor();
const body = {
model: "grok-4.6",
input: [{ role: "user", content: [{ type: "input_text", text: "hi" }] }],
reasoning: { effort: "none" },
};
const transformed = executor.transformRequest(
"grok-4.6",
body,
false,
{} as Record<string, unknown>
) as Record<string, unknown>;
assert.equal("reasoning" in transformed, false);
});
test("grok-4.5 keeps an explicit none/off as a real off-switch (no default restore)", async () => {
const executor = new GrokCliExecutor();
const body = {
model: "grok-4.5",
input: [{ role: "user", content: [{ type: "input_text", text: "hi" }] }],
reasoning: { effort: "off" },
};
const transformed = executor.transformRequest(
"grok-4.5",
body,
false,
{} as Record<string, unknown>
) as Record<string, unknown>;
assert.equal("reasoning" in transformed, false);
});