Skip to content

fix(responses): accumulate response.refusal.delta in ResponseStream#1932

Open
yen0304 wants to merge 1 commit into
openai:mainfrom
yen0304:fix/response-refusal-delta-accumulation
Open

fix(responses): accumulate response.refusal.delta in ResponseStream#1932
yen0304 wants to merge 1 commit into
openai:mainfrom
yen0304:fix/response-refusal-delta-accumulation

Conversation

@yen0304

@yen0304 yen0304 commented Jun 10, 2026

Copy link
Copy Markdown

Summary

ResponseStream#accumulateResponse has explicit cases for accumulating streaming deltas into the response snapshot — but response.refusal.delta was never handled. This means:

  • response.refusal.delta events are emitted to subscribers correctly (via the default maybeEmit path in #addEvent), but
  • The in-memory snapshot's content[n].refusal is never updated — it stays "" for the entire stream.

Any code that reads finalResponse().output[0].content[0].refusal after streaming gets an empty string instead of the model's actual refusal text.

Root cause: The switch in #accumulateResponse handles output_text.delta, function_call_arguments.delta, and reasoning_text.delta, but has no case for refusal.delta.

Changes

  • src/lib/responses/ResponseStream.ts: Added response.refusal.delta case to #accumulateResponse — appends event.delta to content.refusal, matching the exact pattern used by the other delta handlers.
  • tests/lib/ResponseStream.test.ts: New test 'refusal accumulates correctly' — sends three refusal deltas and asserts both that the response.refusal.delta events fire with the right values and that finalResponse() contains the fully concatenated refusal string.
  • tests/lib/__snapshots__/ResponseStream.test.ts.snap: Snapshot for the new test.

Test plan

  • New test added covering the fix ('refusal accumulates correctly')
  • All existing tests pass (standard text works, reasoning works)
  • Verified manually with a standalone driver: without the fix, content.refusal stays "" after 3 deltas; with the fix it reads "I cannot help with that."

ResponseStream#accumulateResponse handled output_text, function_call_arguments,
and reasoning_text deltas but silently dropped response.refusal.delta events.
Refusal content would always remain empty string after streaming.

Added the missing case to append each delta to content.refusal, matching the
pattern used by all other delta event handlers.
@yen0304 yen0304 requested a review from a team as a code owner June 10, 2026 12:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4734910f3b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +13 to +16
import {
type ResponseFunctionCallArgumentsDeltaEvent,
type ResponseRefusalDeltaEvent,
type ResponseTextDeltaEvent,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Import refusal delta from an exported module

In builds that type-check this file, this import fails because ResponseRefusalDeltaEvent is only a local import inside ./EventTypes and is not exported from that module; the newly added binding is also unused. Import it from ../../resources/responses/responses, export an augmented type from EventTypes, or remove it if no special event typing is needed.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant