Repository navigation
Adapt reasoning history automatically for routed upstreams - #396
Merged
Merged
Conversation
fylorn
marked this pull request as ready for review
November 10, 2026 17:11
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.
Problem and behavior
Chat-compatible APIs do not share a reasoning-history request schema. A later conversation turn can fail with
422 extra_forbiddenformessages[n].assistant.reasoning_contenteven when earlier responses and tool calls worked.History conversion preserves native thinking blocks, ordering, signatures and source identity, and encodes separately for the actual routed upstream and model. Existing advanced provider/model capabilities and exact endpoint profiles select the request encoding. Signed history is rejected before contacting an incompatible upstream.
Automatic mode also negotiates from precise structured HTTP 400/422 field-validation errors on unknown Chat-compatible endpoints. The reported message must actually be an assistant message containing that field. Only the explicitly rejected unsigned field is omitted; rejection does not imply support for another encoding. The request is rebuilt from the original history and passes through outbound redaction again. One logical request has one schema-repair budget shared across providers and existing effort, cache-breakpoint and sealed-history repairs. The resend is a separately accounted attempt.
Automatic runtime behavior
Only accepted adjustments are remembered. The internal cache is bounded to 1,024 entries, expires after 24 hours and resets on configuration reload/restart. It isolates actual upstream credentials/headers, model, API path and tool/thinking mode. Configuration reload replaces the runtime, so requests using an older runtime cannot populate the new cache.
There are no new settings screens, menu entries or compatibility-management endpoints. Existing advanced overrides remain authoritative and survive ordinary provider/model edits. Core is prepared as 0.92.0. The control protocol remains 58 and request-store schema remains 28.
Validation and scope
Regression tests cover actual multi-turn exchanges, exact validation locations, explicit-override precedence, bounded retries across failover, unsuccessful trials, cache isolation/expiry/reload, signed native history, tool-call/result IDs and outbound redaction on every attempt. SSE errors never start negotiation or confirm a trial. Ambiguous errors and required reasoning profiles do not trigger omission.
Refs ThinkWatchProject/ThinkWatch-Lite#407. This fixes the reproduced multi-turn field rejection. The original streaming-delay report remains open for reporter confirmation or a complete capture. No installed application, live database or client configuration is changed. Lite will receive the matching tagged Core dependency on dev; its release remains deferred.
Validation passed: gateway unit/conversion/negotiation suites (872 tests), API/control/configuration suites (832 passed, 1 ignored), generated documentation and message-code manifests, and workspace all-target Clippy with warnings denied. Final platform CI passed on macOS (4,397 tests), Linux (4,394) and Windows (4,376), including real-binary/control-plane smoke checks. Regression coverage also confirms that a plugin changing the retry body cannot make an unapplied repair populate the cache.