fix(models): ruled retryability for synthetic stream markers; ChatGPT OAuth stream honesty - #56
Merged
Merged
Conversation
…y above the provider dispatch max_retries and incomplete_stream are the adapters' own synthetic markers, not provider vocabulary, so they now classify in one provider-independent arm: exhausting the quick in-call retry budget is SERVICE_UNAVAILABLE/retryable (the provider was already saying retry), and a truncated stream is NETWORK_ERROR/retryable (a transport fault, not a verdict). Code-less faults unify: a bare response.failed, a message-only flat error, and the bare-event fallback are all the provider aborting without naming a request-shaped cause — request-shaped faults always carry codes — so all take the retryable provider-side disposition. The ChatGPT OAuth backend joins the openai/azure dispatch (same Responses wire contract).
An in-stream error event was packaged as a plain dict that flowed into harmonization and surfaced as an EMPTY SUCCESSFUL response — the provider's verdict (and its code) never reached classification. response.failed was ignored outright, and a stream that died before its terminal event returned partial output as a completed answer. Both readers now raise the REAL provider error through the shared stream_error_payload seam (flat grammar read correctly, partial length annotated, text never leaked), treat response.incomplete as the usable terminal it is, and refuse to present a truncated stream as success (incomplete_stream marker).
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.
Two policy flips ruled after the stream-fault classification fix (#55), plus the OAuth twin's variant of the same dishonesty class.
Retryability rulings. The adapters' synthetic
max_retriesandincomplete_streammarkers were deliberately pinned UNKNOWN/non-retryable in #55 pending a policy decision. Ruled: both flip to retryable. They are our own markers, not provider vocabulary, so they now classify in one provider-independent arm above the provider dispatch — exhausting the adapter's quick in-call retry budget isSERVICE_UNAVAILABLE(the provider was already saying retry; recovery hands to the caller's slower ladder), and a truncated stream isNETWORK_ERROR(a transport fault, not a provider verdict). Code-less faults unify: a bareresponse.failed, a message-only flaterrorevent, and the bare-event fallback all take the retryable provider-side disposition — request-shaped faults always carry codes.openai-oauthjoins the openai/azure dispatch (same Responses wire contract).OAuth stream honesty. The ChatGPT-backend adapter packaged an in-stream
errorevent as a plain dict that flowed into harmonization and surfaced as an EMPTY SUCCESSFUL response — the provider's verdict never reached classification.response.failedwas ignored outright; a stream that died before its terminal event returned partial output as a completed answer. Both readers now raise the real provider error through the sharedstream_error_payloadseam, treatresponse.incompleteas the usable terminal it is, and refuse to present a truncated stream as success.Tests: 7 new oauth stream-honesty tests (MockTransport, both sync and async readers); the harmonize matrix flips its pinned rows and adds rows for provider-independence of the marker arm, code-less unification, and the openai-oauth family membership. Full suite: 1670 passed; the 5 remaining failures are the known Windows-box environment set (readline collection, cwd-sensitive path test, live-key smoke), reproduced identically on main.