Repository navigation
fix(translate): preserve upstream error details - #712
Merged
Merged
Conversation
Replace fluent protocol subpaths with named root translators returning plain trips or input failures. Keep request builders and event adapters intact while containing expected input exceptions at public operations. Consume translation failures at gateway attempt and payload boundaries, and encode rewritten JSON errors at the transport boundary. Preserve the current model context and remote-image loader requirements for the pairwise request backend. Validate named translation and gateway suites, owning TypeScript projects, and changed lint targets.
Restate recognized upstream errors through source-owned converters before and during streams. Preserve independent error classifications, nullable code and param values, envelope metadata, and one merged provider extension container. Use the same recognized context-overflow decision for Gemini HTTP and body codes. Keep unknown response bytes untouched and propagate unexpected parser failures with their original error and cause. Validate 322 tests in 19 named files, changed-file ESLint, and the translate and gateway TypeScript projects.
Normalize HTTP and streaming error envelopes through the same metadata merge. Preserve outer request identifiers and trace fields in the existing extension container while retaining error-level collision priority. Distinguish event transport fields from native error payloads so canonical payloads retain their original reference and classification when no envelope data remains. Validate 324 tests in 19 named files, ESLint on all four changed files, and the translate and gateway TypeScript projects.
Move each source protocol's error converters into as-source/error.ts so HTTP error restatement and SSE output share the focused error owner. Preserve the extracted implementation byte for byte. Align six existing error expectations in three test files with retained upstream details and independent classifications. Validate 376 tests in 22 named files, all 17 changed TypeScript lint targets, and the translate and gateway TypeScript projects.
Preserve the param and code supplied by raw translation input failures in Messages and GenerateContent error envelopes. Omit absent details and keep the rejecting candidate performance context intact. Keep protocol error results precise and validate both detail envelopes, the named translation boundary suites, and gateway TypeScript checks.
Port the reviewed capture, error telemetry, and Responses attempt explanations to their public-boundary owners. Remove redundant dispatcher and assertion narration and update the dashboard capture reference.
Move reviewed error-format explanations to dedicated protocol error owners and HTTP wrappers. Clarify diagnostic field projection, unknown-body passthrough, and replacement headers while preserving the existing status policy and envelope metadata behavior.
Keep the reviewed Struct Any explanation beside the public-boundary field-preservation matrix.
2 tasks done
Move Responses canonicalization and Gemini Part classification into their protocol modules. Protocol errors are ordinary native data, adapted at translation entrypoints. Share HTTP/RPC status facts while preserving gateway status policy.
Share the native HTTP/RPC mapping while retaining this boundary's UNKNOWN classification for 502 and unrecognized codes.
Keep expected token-counting input failures as gateway API errors so final response rendering records the selected candidate's zero-output error. Preserve fallback across candidates and verify final failure attribution and successful fallback through real HTTP requests and performance records.
Preserve every distinct same-named upstream error value beneath the first available numeric suffix while reserving original keys. Keep container and inner-error precedence, and coalesce equal JSON structures without rewriting raw number tokens. Merge HTTP and SSE namespaces before projection, keeping loose fields and canonical values from being duplicated during source rendering. Verified 91 scoped tests, the translate TypeScript project, and ESLint for all changed files.
Remove the translated-error exception that turned HTTP 502 into UNKNOWN. Reuse the protocol mapping to UNAVAILABLE while preserving HTTP 502, the unknown-status fallback and context-overflow classification.
Carry standard Responses error bodies through the hosted-tool event lifecycle, drain the following response.failed resource, and reconstruct non-streaming errors without retaining an HTTP-result side channel. Preserve accumulated usage telemetry while allowing stateful, affinity, HTTP, and WebSocket consumers to observe the complete failure lifecycle.
Choose the non-streaming HTTP status from the standard Responses error code or type after the internal error-to-failed lifecycle completes. Preserve 502 only for unknown classifications and keep the reconstructed JSON body unchanged.
Menci
changed the base branch from
refactor/translate-public-boundary
to
main
November 12, 2026 14:07
…ields # Conflicts: # packages/protocols/src/openai-responses/index.ts # packages/translate/AGENTS.md # packages/translate/__tests__/protocols/anthropic-messages/as-source/context-window-error_test.ts # packages/translate/__tests__/protocols/chat-legacy-round-trip_test.ts # packages/translate/__tests__/protocols/chat-reasoning-round-trip_test.ts # packages/translate/__tests__/protocols/openai-chat-completions/as-source/continuous-usage_test.ts # packages/translate/__tests__/protocols/round-trip-receive_test.ts # packages/translate/__tests__/protocols/routes_test.ts # packages/translate/src/index.ts # packages/translate/src/ir/output/types.ts # packages/translate/src/protocols/anthropic-messages/as-source/context-window-error.ts # packages/translate/src/protocols/anthropic-messages/as-source/events.ts # packages/translate/src/protocols/anthropic-messages/via-openai-chat-completions/request.ts # packages/translate/src/protocols/anthropic-messages/via-openai-chat-completions/translate.ts # packages/translate/src/protocols/anthropic-messages/via-openai-responses/request.ts # packages/translate/src/protocols/anthropic-messages/via-openai-responses/translate.ts # packages/translate/src/protocols/gemini-generate-content/as-source/events.ts # packages/translate/src/protocols/gemini-generate-content/via-anthropic-messages/request.ts # packages/translate/src/protocols/gemini-generate-content/via-anthropic-messages/translate.ts # packages/translate/src/protocols/gemini-generate-content/via-openai-chat-completions/request.ts # packages/translate/src/protocols/gemini-generate-content/via-openai-chat-completions/translate.ts # packages/translate/src/protocols/gemini-generate-content/via-openai-responses/request.ts # packages/translate/src/protocols/gemini-generate-content/via-openai-responses/translate.ts # packages/translate/src/protocols/openai-chat-completions/as-source/events.ts # packages/translate/src/protocols/openai-chat-completions/via-anthropic-messages/request.ts # packages/translate/src/protocols/openai-chat-completions/via-anthropic-messages/translate.ts # packages/translate/src/protocols/openai-chat-completions/via-openai-responses/content.ts # packages/translate/src/protocols/openai-chat-completions/via-openai-responses/request.ts # packages/translate/src/protocols/openai-chat-completions/via-openai-responses/translate.ts # packages/translate/src/protocols/openai-responses/as-target/events.ts # packages/translate/src/protocols/openai-responses/via-anthropic-messages/request.ts # packages/translate/src/protocols/openai-responses/via-anthropic-messages/translate.ts # packages/translate/src/protocols/openai-responses/via-openai-chat-completions/content.ts # packages/translate/src/protocols/openai-responses/via-openai-chat-completions/request.ts # packages/translate/src/protocols/openai-responses/via-openai-chat-completions/translate.ts
Menci
marked this pull request as ready for review
November 12, 2026 14:17
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.
Restate recognized structured upstream errors into the client's protocol before and during streams. Preserve nullable named fields, unconsumed aliases, envelope metadata and protocol-specific diagnostics while retaining semantic response headers. Unexpected parser failures preserve their error chain, and unrecognized bodies pass through.
Preserve distinct colliding metadata values under the first unused
_1,_2, ... suffix. Existing container/inner-error values retain their original key; equal values at the same original key coalesce. Reserve every explicitly stated key before allocating suffixes, and merge namespaces once so source projection cannot duplicate metadata.Carry Responses continuation failures through the normal event lifecycle. A structured non-streaming error body becomes the corresponding
errorevent, followed by the aggregateresponse.failedresource. Streaming clients receive both events; non-streaming collection drains the failed resource and renders the original standard error fields as JSON. The original HTTP status and headers are not retained across this event boundary; the downstream HTTP status is reconstructed from the standard errorcodeor classificationtype, with 502 reserved for unknown classifications. Accumulated output usage is still recorded once.Protocol errors are JSON; this change adds no plaintext interpretation or status-derived fallback error code. Gemini HTTP 502 errors use the shared protocol mapping and therefore report RPC status
UNAVAILABLE.Depends on #709's prepared-trip contract and local gateway error handling. Focused validation covers flat and nested Responses errors, nullable codes, HTTP classification, extension fields, raw numeric tokens, error-to-failed lifecycle consumers, accumulated usage telemetry, Gemini status mapping, metadata collisions and explicit suffix names. The latest local verification passed 442 named gateway/protocol tests, both owning TypeScript projects and exact changed-file lint.