Skip to content

[AISAGE-706] fix(ai-gateway): drop legacy reasoning fields for reasoning-details mapped providers - #7751

Merged
chrarnoldus merged 1 commit into
mainfrom
fix/ai-gateway-drop-legacy-reasoning
Oct 16, 2026
Merged

chrarnoldus merged 1 commit into
mainfrom
fix/ai-gateway-drop-legacy-reasoning

Conversation

@chrarnoldus

Copy link
Copy Markdown
Contributor

Summary

Some OpenCode Go BYOK requests fail with:

[BYOK] Upstream request failed: [unknown_parameter] invalid request body: json: unknown field "reasoning"

Since #7586 moved direct BYOK providers to the OpenRouter client default, clients send OpenRouter-style reasoning fields that strict upstreams reject. There are two separate reasoning fields:

  • Message-level reasoning (legacy string next to reasoning_details on assistant messages). The reasoning-details request transforms (ReasoningContent and GeminiThought) now drop it. When a message has no reasoning_details, ReasoningContent folds the legacy string into reasoning_content instead of losing it, unless reasoning_content is already set.
  • Top-level reasoning config ({ effort, enabled, ... }). This is the field behind the exact error above. OpenCode Go now maps reasoning.effort to reasoning_effort (an explicit reasoning_effort takes precedence) and removes reasoning. This follows the existing EdenAI and NVIDIA providers.

Upstream probe

These are direct requests to opencode.ai/zen/go/v1/chat/completions with the same three-message history. Only the noted field changes:

Model baseline message reasoning top-level reasoning
omen-alpha 200 200 400 [unknown_parameter] ... unknown field "reasoning"
glm-5.3-flash 200 200 400 [unknown_parameter] ... unknown field "reasoning"
cat-jam-free 200 400 [unsupported_parameter] messages[1].reasoning 400 [unsupported_parameter] reasoning
glm-5.3, kimi-k3, mimo-v2.6-pro, qwen3.7-plus, minimax-m3, others 200 200 200

reasoning_effort: "high" is accepted (for example omen-alpha returns 200 with reasoning_content).

Verification

  • pnpm --filter @kilocode/web-shared typecheck: passes
  • Jest: apply-provider-specific-logic, direct-byok/opencode-go, providers/openrouter/*, build-direct-provider and rewriteModelResponse suites: 11 suites, 339 tests pass
  • oxlint on the changed files: clean; oxfmt and git diff --check: clean
  • An end-to-end run through a local gateway with an OpenCode Go BYOK key follows in a PR comment.

@chrarnoldus chrarnoldus self-assigned this Oct 16, 2026
@kilo-code-bot

kilo-code-bot Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The reasoning-field fixes in the OpenCode Go BYOK path and the shared reasoning-details transforms are logically sound and covered by new tests; no bugs, security issues, or regressions were found in the changed lines.

Files Reviewed (5 files)
  • packages/web-shared/src/lib/ai-gateway/providers/apply-provider-specific-logic.ts
  • packages/web-shared/src/lib/ai-gateway/providers/apply-provider-specific-logic.test.ts
  • packages/web-shared/src/lib/ai-gateway/providers/direct-byok/opencode-go.ts
  • packages/web-shared/src/lib/ai-gateway/providers/direct-byok/opencode-go.test.ts
  • packages/web-shared/src/lib/ai-gateway/providers/openrouter/request-helpers.ts

Notes

  • opencode-go.ts maps reasoning.effort to reasoning_effort with ??=, so an explicit reasoning_effort wins, then drops reasoning. This matches the sibling EdenAI/NVIDIA pattern and the documented probe results.
  • mapReasoningDetailsToReasoningContent deletes the legacy message-level reasoning and only folds it into reasoning_content when there are no reasoning_details and reasoning_content is unset; the new tests cover the drop and fold paths.
  • mapGeminiReasoningDetails now also drops the legacy reasoning field.

Reviewed by deepseek-v4.1-flash · Input: 73.7K · Output: 15.7K · Cached: 571.9K

Review guidance: REVIEW.md from base branch main

@chrarnoldus

Copy link
Copy Markdown
Contributor Author

E2E verification with an OpenCode Go BYOK key

Setup: I ran ai-gateway locally from this branch. A seeded test user had a real OpenCode Go key stored as their opencode-go BYOK key. I tested two kinds of requests through POST /api/v1/chat/completions:

  • Raw: requests with the failing shapes. These are an assistant message with both reasoning and reasoning_details, top-level reasoning: {enabled: true}, and top-level reasoning: {effort: "high"}.
  • SDK: @openrouter/ai-sdk-provider 3.1.0 with ai 7, running a two-step tool-calling conversation through generateText and streamText, with reasoning: {enabled: true} and reasoning: {effort: "high"}.

For the baseline, I restored the three source files to the branch parent commit and restarted the gateway. Each model had 7 cases (3 raw, 4 SDK):

Model Before (branch parent) After (this PR)
omen-alpha 6/7 fail: 400 [BYOK] Upstream request failed: [unknown_parameter] invalid request body: json: unknown field "reasoning" 7/7 pass
glm-5.3-flash 4/7 fail with the same unknown field "reasoning" error 7/7 pass
cat-jam-free 7/7 fail: [unsupported_parameter] Unrecognized request argument supplied: reasoning. / messages[1].reasoning. 7/7 pass
glm-5.3 (control, accepts both fields) 7/7 pass 7/7 pass

The "before" column reproduces the reported error exactly. In the SDK runs, follow-up turns that carry the previous step's reasoning now succeed, and reasoning still reaches the client as reasoning_details.

Effort mapping: upstream honors reasoning_effort. On a harder prompt, low gave 16 reasoning tokens and high gave 103 for omen-alpha; for glm-5.3, low gave 73 and high gave 136.

Some SDK tool-call steps with effort: high show no reasoning text. Direct calls to OpenCode Go give the same result for that prompt (reasoning_tokens: 0), so the gateway is not dropping it.

@chrarnoldus
chrarnoldus added this pull request to the merge queue Oct 16, 2026
Merged via the queue into main with commit 24b427c Oct 16, 2026
29 checks passed
@chrarnoldus
chrarnoldus deleted the fix/ai-gateway-drop-legacy-reasoning branch October 16, 2026 11:57
@chrarnoldus chrarnoldus changed the title fix(ai-gateway): drop legacy reasoning fields for reasoning-details mapped providers [AISAGE-706] fix(ai-gateway): drop legacy reasoning fields for reasoning-details mapped providers Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants