mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-20 22:02:19 +03:00
* fix(open-sse): promote reasoning_details text to reasoning_content even when reasoning present (#12665) OpenRouter thinking models return both a "reasoning" string and a "reasoning_details[].text" array for the same thinking trace. OmniRoute's reasoning promotion gated on "is any readable value present" (which includes the "reasoning" alias), so reasoning_content was never populated and clients like opencode that only read reasoning_content lost all thinking traces. Encrypted-only reasoning_details items are left intact (not flattened). Fixes all three promotion gates: - non-streaming: copyOpenAICompatibleReasoningFields now mirrors reasoning_details[].text into reasoning_content unless reasoning_content itself is present - streaming mirror block: same gate fix on getReadableReasoningValue - streaming passthrough: force re-serialization when sanitize added a reasoning_content the upstream delta did not carry (needsReserialization was false because hasUnsupportedReasoningSignal requires !readable) Tests: non-streaming + streaming unit regressions and an integration E2E that drives the full handleChat path against a mock OpenRouter provider. Also closes the same latent gate in the JSON-to-SSE rehydrator (jsonToSse.ts buildReasoningDelta): a populated reasoning string used to short-circuit the unsupported-alias mirror, so reasoning_details[].text was dropped when synthesizing an SSE stream from a non-streaming JSON body. Adds a #12665 regression test for that path, fixes an over-indented brace in stream.ts (lint), and restores the missing trailing newline in the E2E. * docs(changelog): add fragment for #12688 — fix(open-sse): promote reasoning_details text to reasoning_content even when reasoning present * fix(tests): replace any with typed casts in #12665 regressions to satisfy no-explicit-any gate