Skip to content

fix(providers/openai): blank line between reasoning summary parts - #67

Draft
mafredri wants to merge 1 commit into
coder_2_33from
mafredri/responses-reasoning-summary-paragraphs
Draft

mafredri wants to merge 1 commit into
coder_2_33from
mafredri/responses-reasoning-summary-paragraphs

Conversation

@mafredri

@mafredri mafredri commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Problem

Each OpenAI reasoning summary part has the form **Title**\n\nBody. Stream sent a single "\n" before each part, and Generate joined the parts with "\n". Markdown treats a single newline as a soft break, so in the Coder chat UI each title after the first one shows inline at the end of the previous paragraph.

Fix

  • Stream sends "\n\n" before every summary part, including the first one. Stream deltas do not mark where one reasoning item ends. The Coder chat UI joins adjacent reasoning parts into one block, including across provider-executed web_search calls. Without the leading blank line, the title of the next item would join the previous sentence with no space.
  • Generate joins the parts with "\n\n". It still adds no blank line before the first part, as before. Generate returns each reasoning item as a separate ReasoningContent.

Replay is unaffected. responsesReasoningInputItem rebuilds each item from ResponsesReasoningMetadata.Summary, not from the text.

Not changed: the OpenRouter and Vercel providers use the same single newline for openai-responses reasoning details (providers/openrouter/language_model_hooks.go:157,356 and providers/vercel/language_model_hooks.go:196,403). Their first part has no leading separator, and I have not checked their data.

Validation

  • responses_reasoning_summary_test.go covers Stream (an item with two parts, then an item with one part) and Generate. Both tests fail with the old separator.
  • go test ./..., go build ./..., and golangci-lint run ./providers/openai/... pass, and go mod tidy leaves no diff. A full golangci-lint run (local v2.0.2) reports one prealloc issue in providers/kronk/language_model.go:624, a file this PR does not change.
  • CI: build (Linux, macOS, Windows) and lint pass. govulncheck fails with the same 11 IDs as the run for fix: replay OpenAI Responses reasoning from encrypted content聽#63 (dependency and standard library findings). This PR does not change go.mod.
  • I did not run these tests against the live OpenAI API.

coder/coder will update its fantasy pin after this merges.

Dogfood data behind the leading separator

I queried 7 days of dogfood chat_messages for OpenAI Responses models (openai, and Bedrock openai.*):

  • In every completed reasoning part, the stored text is exactly "\n" + summary[0] + "\n" + summary[1] .... Only this provider adds the separator.
  • All 4,044 summary parts start with **Title**\n\n. No part starts or ends with whitespace.
  • 884 summary parts come after another part of the same item. A blank line between parts fixes these, with or without a leading one.
  • 355 boundaries in 262 of 2,802 messages are between reasoning items that the UI joins into one block, either because they are adjacent or because only a web_search call is between them. Without a blank line before the first part, these would show as sentence.**Title**.
  • Interrupted turns store each delta as a separate part (2 OpenAI messages in 45 days). They show whatever this provider streams.

馃 This PR was created with the help of Coder Agents, and will be reviewed by a human. 馃弬馃徎

OpenAI reasoning summary parts each open with a bold title line.
Streaming separated them with a single newline, which Markdown treats as
a soft break, so every title after the first rendered at the end of the
previous paragraph. A blank line now precedes each part.

The first part gets one too. Consumers that join consecutive reasoning
items, such as the Coder chat UI, would otherwise glue the next item's
title onto the previous sentence. Generate joins the parts with a blank
line to match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant