Repository navigation
fix(openai-completions): keep a refusal instead of returning an empty turn - #484
Open
pcbeingused333 wants to merge 1 commit into
Open
pcbeingused333 wants to merge 1 commit into
pcbeingused333 wants to merge 1 commit into
Conversation
… turn A refused Chat Completions request ends with finish_reason "stop", no content and the text in message.refusal (delta.refusal when streamed). The provider ignored the field, so the turn was empty and reported as a success. Yield the streamed refusal, keep it as the turn's text, and report content_filter so the usual "filtered by the provider" warning (or error, with a data model) applies. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A refused Chat Completions request (for example a refused structured output) ends with
finish_reason: "stop",content: nulland the text inmessage.refusal, or indelta.refusalwhen streamed.OpenAICompletionsProviderignored the field, so the turn came back empty and was reported as"success":chat.chat(...)returned an empty string, a streamed call yielded nothing, and with adata_modelthe failure showed up as a missing JSON payload instead of a refusal.The provider now yields streamed
delta.refusaltext, keeps the refusal as the turn's text when the message has no content, and reportsfinish_reason == "content_filter"for it, which makes the existing "filtered by the provider's content moderation policy" warning (or error, with adata_model) apply. Responses with content are unchanged, and so is a refusal-freestop. Databricks, Cloudflare, Portkey, Perplexity, Hugging Face and the other providers built on this class inherit the change.Tests (
tests/test_provider_openai_completions.py): a refusedChatCompletiongives the refusal text andcontent_filter; the same with adata_modelraises the content-moderation error; and streamed chunks withdelta.refusalfragments are yielded as text, merged, and end in a turn with the full text andcontent_filter. All three fail onmain. The existing tests in the file still pass; the failures intests/test_chat.pyin my environment come from missing optional dependencies and are the same onmain. No request was made to a live server.This change was made with Claude Code; the tests above were run before opening the PR.
🤖 Generated with Claude Code