From f4d3f955959f7c76311be13c050a0995da9c2101 Mon Sep 17 00:00:00 2001 From: Yum-wu <1172989563@qq.com> Date: Tue, 22 Sep 2026 13:59:47 +0800 Subject: [PATCH] fix(responses): preserve visible reasoning when summary mode is omitted --- scripts/test-layout/layout.json | 1 + src/combos/request.ts | 8 ++- src/responses/parser.ts | 3 +- tests/fixtures/test-layout-expected.json | 1 + .../reasoning-effort-summary-default.test.ts | 53 +++++++++++++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 tests/responses/reasoning-effort-summary-default.test.ts diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 2e31c8b2431..99a71424d89 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1211,6 +1211,7 @@ "rate-limit-retry.test.ts": "providers", "raycast-client.test.ts": "clients", "raycast-detect.test.ts": "clients", + "reasoning-effort-summary-default.test.ts": "responses", "reasoning-effort.test.ts": "codex-integration", "reasoning-envelope.test.ts": "responses", "reasoning-metadata.test.ts": "codex-integration", diff --git a/src/combos/request.ts b/src/combos/request.ts index e0fa6426087..0d0b0123732 100644 --- a/src/combos/request.ts +++ b/src/combos/request.ts @@ -110,9 +110,13 @@ export function concreteComboRequestBody( return clone; } if (reasoning === undefined) { - clone.reasoning = { effort: resolvedEffort }; + clone.reasoning = { effort: resolvedEffort, summary: "auto" }; } else { - clone.reasoning = { ...(reasoning as Record), effort: resolvedEffort }; + clone.reasoning = { + ...(reasoning as Record), + effort: resolvedEffort, + ...((reasoning as Record).summary === undefined ? { summary: "auto" } : {}), + }; } return clone; } diff --git a/src/responses/parser.ts b/src/responses/parser.ts index 51bb36f5245..3d63480be0b 100644 --- a/src/responses/parser.ts +++ b/src/responses/parser.ts @@ -542,7 +542,8 @@ export function parseRequest( options.reasoning = requestedEffort; } const summaryMode = data.reasoning?.summary; - if (!summaryMode || summaryMode === "none") options.hideThinkingSummary = true; + const reasoningActive = Boolean(requestedEffort && requestedEffort !== "none" && requestedEffort !== "off"); + if (summaryMode === "none" || (!summaryMode && !reasoningActive)) options.hideThinkingSummary = true; if (data.presence_penalty !== undefined) options.presencePenalty = data.presence_penalty; if (data.frequency_penalty !== undefined) options.frequencyPenalty = data.frequency_penalty; if (data.service_tier !== undefined) options.serviceTier = data.service_tier; diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 25bf5372234..33bd8f5418e 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1037,6 +1037,7 @@ "rate-limit-retry.test.ts": "providers", "raycast-client.test.ts": "clients", "raycast-detect.test.ts": "clients", + "reasoning-effort-summary-default.test.ts": "responses", "reasoning-effort.test.ts": "codex-integration", "reasoning-envelope.test.ts": "responses", "reasoning-metadata.test.ts": "codex-integration", diff --git a/tests/responses/reasoning-effort-summary-default.test.ts b/tests/responses/reasoning-effort-summary-default.test.ts new file mode 100644 index 00000000000..9dcad9a1c1c --- /dev/null +++ b/tests/responses/reasoning-effort-summary-default.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, test } from "bun:test"; +import { parseRequest } from "../../src/responses/parser"; +import { concreteComboRequestBody } from "../../src/combos/request"; +import type { OcxComboTarget } from "../../src/types"; + +describe("reasoning effort preserves visible thinking when summary is omitted", () => { + test("reasoning with active effort does not default to hideThinkingSummary", () => { + const parsed = parseRequest({ + model: "test-model", + reasoning: { effort: "high" }, + input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "hi" }] }], + }); + expect(parsed.options.reasoning).toBe("high"); + expect(parsed.options.hideThinkingSummary).toBeUndefined(); + }); + + test("explicit summary of none still hides thinking summary", () => { + const parsed = parseRequest({ + model: "test-model", + reasoning: { effort: "high", summary: "none" }, + input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "hi" }] }], + }); + expect(parsed.options.reasoning).toBe("high"); + expect(parsed.options.hideThinkingSummary).toBe(true); + }); + + test("omitted reasoning and omitted effort still default to hideThinkingSummary", () => { + const parsed = parseRequest({ + model: "test-model", + input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "hi" }] }], + }); + expect(parsed.options.hideThinkingSummary).toBe(true); + }); + + test("reasoning effort of none defaults to hideThinkingSummary", () => { + const parsed = parseRequest({ + model: "test-model", + reasoning: { effort: "none" }, + input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "hi" }] }], + }); + expect(parsed.options.hideThinkingSummary).toBe(true); + }); + + test("combo injected effort defaults summary to auto", () => { + const target: Pick = { + provider: "test-provider", + model: "test-model", + }; + const body = { model: "combo/test", input: [] }; + const child = concreteComboRequestBody(body, target, "high", ["high"]); + expect(child.reasoning).toEqual({ effort: "high", summary: "auto" }); + }); +});