Repository navigation
Route a conversation's encrypted history back to the provider that holds it - #120
Merged
Merged
Conversation
…lds it OpenAI Responses with store: false (Codex always sends it) hands the client encrypted state it sends back every turn: reasoning, remote compactions, agent messages, encrypted tool output. Only the account that encrypted it can read it, so a conversation that moved to another provider (affinity expiry, a tripped breaker, failover) was refused with invalid_encrypted_content on every turn from then on. The gateway now remembers, per conversation (authenticated user plus x-session-id, or the client's own session header such as Codex's session_id), the provider that last answered it, in Redis for 30 days, independent of the affinity settings. A Responses request carrying sealed content (tw_dialect::sealed) goes only to that provider: no strategy pick, no failover, its open breaker does not stop it; when the provider has no route for the model any more the request is refused up front with 409. A request carrying only sealed reasoning prefers that provider and still fails over. An upstream's refusal of sealed history, as a 4xx or as the error event of a stream, becomes SealedHistoryRefused with a plain explanation and the upstream's words, and no longer counts against the route. The log row records pinned_by: encrypted_history. Core crates point at the core branch fix/encrypted-history-pin until it is tagged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Enterprise side of ThinkWatchProject/ThinkWatch-Core#368.
OpenAI Responses with
store: false(how Codex always sends) hands the client encrypted state to send back every turn: reasoning, remote compactions, Codex sub-agent messages, encrypted tool output. Only the account that encrypted it can read it. A conversation that moved to another provider (affinity expiry, a tripped breaker, failover) was refused withinvalid_encrypted_contenton every turn from then on.What changes
x-session-id, or the client's own session header such as Codex'ssession_id), the provider that last answered it: Redis, 30 days, independent of the affinity settings.tw_dialect::sealed) goes back to that provider:SealedHistoryUnavailable(409);SealedHistoryRefused, which explains what happened and what to do, followed by the upstream's words. It no longer counts against the route.pinned_by: encrypted_history.Before the next release
The core crates point at core
mainat the merge of ThinkWatchProject/ThinkWatch-Core#368 (rev, set on the dependency lines so core's CI can still append its[patch]). Replace with the next core tag before the next enterprise release.Tests
crates/test-support/tests/gateway_sealed_history.rs(5 integration tests) plus one ingateway_responses_ws.rs; unit tests for the decision, narrowing, failure classification and refusal mapping. Full integration suite and workspace unit tests pass locally; fmt and clippy clean.🤖 Generated with Claude Code