fix(responses): accumulate response.refusal.delta in ResponseStream#1932
fix(responses): accumulate response.refusal.delta in ResponseStream#1932yen0304 wants to merge 1 commit into
Conversation
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.
There was a problem hiding this comment.
💡 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".
| import { | ||
| type ResponseFunctionCallArgumentsDeltaEvent, | ||
| type ResponseRefusalDeltaEvent, | ||
| type ResponseTextDeltaEvent, |
There was a problem hiding this comment.
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 👍 / 👎.
Summary
ResponseStream#accumulateResponsehas explicit cases for accumulating streaming deltas into the response snapshot — butresponse.refusal.deltawas never handled. This means:response.refusal.deltaevents are emitted to subscribers correctly (via the defaultmaybeEmitpath in#addEvent), butcontent[n].refusalis never updated — it stays""for the entire stream.Any code that reads
finalResponse().output[0].content[0].refusalafter streaming gets an empty string instead of the model's actual refusal text.Root cause: The switch in
#accumulateResponsehandlesoutput_text.delta,function_call_arguments.delta, andreasoning_text.delta, but has no case forrefusal.delta.Changes
src/lib/responses/ResponseStream.ts: Addedresponse.refusal.deltacase to#accumulateResponse— appendsevent.deltatocontent.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 theresponse.refusal.deltaevents fire with the right values and thatfinalResponse()contains the fully concatenated refusal string.tests/lib/__snapshots__/ResponseStream.test.ts.snap: Snapshot for the new test.Test plan
'refusal accumulates correctly')standard text works,reasoning works)content.refusalstays""after 3 deltas; with the fix it reads"I cannot help with that."