Repository navigation
feat(ai): preserve streamed refusals as text - #43343
Merged
Merged
Conversation
rekram1-node
force-pushed
the
refusal-streams
branch
from
August 20, 2026 03:42
2254e5b to
0c1b60e
Compare
rekram1-node
force-pushed
the
refusal-streams
branch
from
August 20, 2026 03:50
0c1b60e to
e593f00
Compare
24 of 30 tasks
teknium1
added a commit
to NousResearch/hermes-agent
that referenced
this pull request
Sep 15, 2026
…ncode#43343) A model that declines mid-stream delivers the explanation on the structured refusal channel (chat_completions delta.refusal; Responses response.refusal.delta / refusal content parts) and leaves content empty. The streaming accumulators dropped that channel entirely, so a streamed refusal assembled into an empty message and fell into the empty/invalid-response retry loops - burning paid retries reproducing a deterministic refusal - while the non-streaming path had already fixed this class in #46013. - chat_completions streaming: accumulate delta.refusal (incl. model_extra), expose message.refusal on the assembled mock response so ChatCompletionsTransport.normalize_response applies the existing sole-payload -> content_filter promotion; count refusal deltas in the zero-chunk guard; carry refusal in the Relay final-response dict. - Codex Responses stream consumer: collect response.refusal.delta as answer text so a refusal-only stream no longer raises 'did not emit a terminal response' with zero usable content. - Responses normalizer: read type=refusal content parts in _extract_responses_message_text (attr and dict shapes). Sabotage-verified: each new test fails with its wiring line disabled. E2E: refusal-only stream -> terminal content_filter with explanation; refusal-alongside-content stays a normal usable turn; plain-text streams unchanged.
teknium1
added a commit
to NousResearch/hermes-agent
that referenced
this pull request
Sep 15, 2026
…ncode#43343) A model that declines mid-stream delivers the explanation on the structured refusal channel (chat_completions delta.refusal; Responses response.refusal.delta / refusal content parts) and leaves content empty. The streaming accumulators dropped that channel entirely, so a streamed refusal assembled into an empty message and fell into the empty/invalid-response retry loops - burning paid retries reproducing a deterministic refusal - while the non-streaming path had already fixed this class in #46013. - chat_completions streaming: accumulate delta.refusal (incl. model_extra), expose message.refusal on the assembled mock response so ChatCompletionsTransport.normalize_response applies the existing sole-payload -> content_filter promotion; count refusal deltas in the zero-chunk guard; carry refusal in the Relay final-response dict. - Codex Responses stream consumer: collect response.refusal.delta as answer text so a refusal-only stream no longer raises 'did not emit a terminal response' with zero usable content. - Responses normalizer: read type=refusal content parts in _extract_responses_message_text (attr and dict shapes). Sabotage-verified: each new test fails with its wiring line disabled. E2E: refusal-only stream -> terminal content_filter with explanation; refusal-alongside-content stays a normal usable turn; plain-text streams unchanged.
QuixThe2nd
pushed a commit
to QuixThe2nd/hermes-ide
that referenced
this pull request
Sep 15, 2026
jinhuang712
pushed a commit
to jinhuang712/opencode
that referenced
this pull request
Sep 26, 2026
kanekoshoyu
pushed a commit
to kanekoshoyu/hermes-agent-1
that referenced
this pull request
Oct 15, 2026
kanekoshoyu
pushed a commit
to kanekoshoyu/hermes-agent-1
that referenced
this pull request
Oct 29, 2026
kanekoshoyu
pushed a commit
to kanekoshoyu/hermes-agent-1
that referenced
this pull request
Nov 13, 2026
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.
Summary
delta.refusalas visible ordinary assistant textresponse.refusal.delta/response.refusal.doneas visible ordinary assistant textstopremains a successful assistant answercontentor Responsesoutput_text, never as native refusal stateFollow-up to #43332. Part of #41932.
Testing
bun typecheckandbun run buildinpackages/aiThe complete AI suite previously had unrelated failures on
v2: an Azure Chat URL expectation, stale OpenRouter recorded requests, and existing OpenRouter reasoning-lowering expectations.