Set ErrorCode Refusal on non-streaming Chat Completions refusals to match the Responses path - #654
Conversation
There was a problem hiding this comment.
Pull request overview
Aligns refusal handling in the non-streaming Chat Completions provider with the Responses provider by consistently tagging refusal-derived message.ErrorContent with ErrorCode: "Refusal", enabling uniform downstream classification.
Changes:
- Set
ErrorCode: "Refusal"when mappingchoice.Message.Refusalinto*message.ErrorContenton the non-streaming chat path. - Add a regression test to ensure refusals with
content: nullare parsed intoErrorContentwith bothMessageandErrorCodepopulated.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| provider/openaiprovider/chat.go | Tags non-streaming chat refusal ErrorContent with ErrorCode: "Refusal" to match Responses behavior. |
| provider/openaiprovider/chat_test.go | Adds a test asserting refusal responses produce ErrorContent with ErrorCode == "Refusal". |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This comment has been minimized.
This comment has been minimized.
225b288 to
26703c6
Compare
This comment has been minimized.
This comment has been minimized.
26703c6 to
ff9e3f7
Compare
Parity Review — ✅ ApprovedThis PR sets Cross-repo consistency: The PR description correctly notes that .NET and Python SDKs carry a consistent, well-known code for refusal content across both chat and responses surfaces. The Go change aligns with that convention. Within-repo consistency: Out of scope for this PR: The streaming chat refusal path ( No new exported identifiers were added or changed, so the Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "awmgmcpg"See Network Configuration for more information.
|
The non-streaming Chat Completions path emitted an ErrorContent for a model refusal without setting ErrorCode, while every Responses-path refusal tags ErrorCode "Refusal". Tag the Chat Completions refusal the same way so consumers categorizing by ErrorContent.ErrorCode classify identical refusals consistently across both providers.
ff9e3f7 to
9af49b6
Compare
What
The non-streaming Chat Completions path maps a model refusal to a
message.ErrorContentbut leavesErrorCodeempty:Every Responses-path refusal (three sites in
responses.go) tagsErrorCode: "Refusal". This change adds the same tag on the Chat Completions non-streaming path.Why
Refusals should be categorizable the same way regardless of which OpenAI surface produced them. Today a consumer routing on
ErrorContent.ErrorCodeclassifies Responses refusals but silently drops identical Chat Completions refusals into the empty-code bucket. This mirrors the .NET/Python SDKs, where refusal content carries a consistent, well-known code across the chat and responses clients, and aligns with the existing"Refusal"convention already asserted inresponses_test.go.Not a duplicate of #556, which concerns the streaming chat refusal path.
Testing
Added
TestChatResponseWithRefusalContent_ParsesCorrectlyinchat_test.go(mirroringTestResponsesResponseWithRefusalContent_ParsesCorrectly): it returns a chat completion withcontent: nulland arefusalstring, runs the agent, extracts the*message.ErrorContent, and asserts bothMessageandErrorCode == "Refusal". The test fails before the fix (empty ErrorCode) and passes after.go build ./...,go vet, andgo test ./provider/openaiprovider/...all pass.