fix(openai-responses): emit reasoning summary as delta.reasoning_content (#2159)

Integrated into release/v3.8.0 — emit reasoning summary as delta.reasoning_content for Chat Completions clients
This commit is contained in:
Gioxa
2026-05-11 20:22:07 +07:00
committed by GitHub
parent e4c8c14fb3
commit 2880155772
3 changed files with 9 additions and 4 deletions

View File

@@ -823,13 +823,18 @@ export function openaiResponsesToOpenAIResponse(chunk, state) {
};
}
// Handle true reasoning summary ("Thought for 15s")
// Handle true reasoning summary ("Thought for 15s").
// Emit as `delta.reasoning_content` — matches the shape used by the
// `reasoning_content_text.delta` branch above and is what Chat clients
// (OpenCode, Claude Code, Cursor, etc.) actually render in their thinking
// panel. A nested `delta.reasoning.summary` object is swallowed by most
// stream mergers and never reaches the user.
if (eventType === "response.reasoning_summary_text.delta") {
const reasoningDelta = data.delta || "";
if (!reasoningDelta) return null;
const reasoningDeltaShape = state.copilotCompatibleReasoning
? { reasoning_text: reasoningDelta }
: { reasoning: { summary: reasoningDelta } };
: { reasoning_content: reasoningDelta };
return {
id: state.chatId,
object: "chat.completion.chunk",

View File

@@ -406,7 +406,7 @@ test("Responses→Chat streaming: reasoning delta emits reasoning_content in Cha
};
const result = openaiResponsesToOpenAIResponse(chunk, state);
assert.ok(result, "should return a chunk");
assert.equal(result.choices[0].delta.reasoning.summary, "thinking step...");
assert.equal(result.choices[0].delta.reasoning_content, "thinking step...");
});
test("Responses→Chat streaming: Copilot mode emits reasoning_text for summary deltas", () => {

View File

@@ -289,7 +289,7 @@ test("Responses -> OpenAI: tool-call delta, reasoning delta and completed usage
assert.equal(added.choices[0].delta.tool_calls[0].function.name, "weather");
assert.equal(args.choices[0].delta.tool_calls[0].function.arguments, '{"city":"SP"}');
assert.equal(reasoning.choices[0].delta.reasoning.summary, "Need weather info.");
assert.equal(reasoning.choices[0].delta.reasoning_content, "Need weather info.");
assert.equal(completed.choices[0].finish_reason, "tool_calls");
assert.equal((completed as any).usage.prompt_tokens, 8);
assert.equal((completed as any).usage.completion_tokens, 2);