Thinking / Reasoning Compatibility
May 14, 2026 ยท View on GitHub
This document describes the current thinking / reasoning compatibility layer in aiproxy, including:
- how different request protocols express reasoning parameters
- how the proxy normalizes those parameters internally
- how they are converted when forwarding to different upstream vendors
- known vendor- and model-specific limitations, fallbacks, and downgrade behavior
This document focuses on parameter compatibility and conversion behavior, not the full upstream API surface of each vendor.
1. Goals
The purpose of this feature is to:
- let callers use the native reasoning format of the current request mode whenever possible
- automatically convert reasoning parameters when transforming from request format A to upstream format B
- reduce upstream validation errors caused by model capability differences or schema mismatches
The implementation follows these rules:
- it only parses the native thinking / reasoning fields of the current request mode
- OpenAI Chat / Completions only parse
reasoning_effort - OpenAI Responses as a target format only writes
reasoning.effort - Gemini only parses
generationConfig.thinkingConfig - Claude / Anthropic only parse
thinkingandoutput_config
- OpenAI Chat / Completions only parse
- it no longer supports reverse compatibility for the old generic
thinkingstructure - only converted request bodies are normalized or constrained for upstream validity
- native requests are not automatically migrated into another thinking dialect
- for example, a native Claude request is not rewritten into OpenAI
reasoning_effort - existing protocol-level cleanup may still apply, for example when an upstream forbids
temperaturetogether with thinking
- for example, a native Claude request is not rewritten into OpenAI
- adaptor-specific native fields may still be preserved when the upstream itself
accepts them, for example Qianfan native
thinking - every model-name-based capability branch uses:
OriginModelfirstActualModelas fallback when origin does not match
2. Internal normalization model
Internally, the proxy first normalizes different protocol-specific reasoning parameters into one unified structure. Conceptually it contains:
Specified: whether reasoning was explicitly configuredDisabled: whether reasoning was explicitly turned offEffort: normalized effort levelBudgetTokens: token budget if the original protocol provided one
2.1 Supported normalized effort values
The normalized effort enum is:
noneminimallowmediumhighxhigh
The parser also accepts several aliases:
off/disabled->nonemed->mediummax/maximum->xhigh
2.2 Default effort <-> budget mapping
When an upstream only supports token budgets instead of discrete labels such as high or medium, the proxy uses this mapping:
| effort | budget |
|---|---|
none | 0 |
minimal | 1024 |
low | 2048 |
medium | 8192 |
high | 16384 |
xhigh | 32768 |
When converting budget back into effort, the proxy uses these ranges:
| budget range | normalized effort |
|---|---|
<= 0 | none |
1 ~ 1024 | minimal |
1025 ~ 4096 | low |
4097 ~ 12288 | medium |
12289 ~ 24576 | high |
> 24576 | xhigh |
3. Supported input formats by request mode
3.1 OpenAI Chat / Completions
The compatibility layer currently only parses:
{
"reasoning_effort": "none|minimal|low|medium|high|xhigh"
}
Notes:
- this is the only reasoning field currently consumed in OpenAI Chat / Completions mode
- the old generic
thinkingstructure is no longer parsed here
3.2 OpenAI Responses
When the proxy needs to build an OpenAI Responses request body, reasoning is written as:
{
"reasoning": {
"effort": "none|minimal|low|medium|high|xhigh"
}
}
Notes:
- in the current implementation, Responses is mostly used as a target format
- for example, Chat / Claude / Gemini requests converted into Responses will write
reasoning.effort
3.3 Gemini
The proxy currently parses:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true,
"thinkingLevel": "minimal|low|medium|high"
}
}
}
Parsing priority:
thinkingLevelthinkingBudgetincludeThoughts
Interpretation:
thinkingLevelmaps directly to normalized effortthinkingBudgetis converted into effort through the budget rangesincludeThoughts=truewith no other recognized fields is treated asmediumthinkingBudget<=0is treated asnone- if
thinkingConfigis explicitly present but contains no recognized reasoning fields, it is treated as disabled
3.4 Claude / Anthropic
The proxy currently parses:
{
"thinking": {
"type": "disabled|enabled|adaptive",
"budget_tokens": 2048
},
"output_config": {
"effort": "low|medium|high|max"
}
}
Rules:
thinking.type=disabled->nonethinking.type=enabledoradaptive-> reasoning enabled- if
budget_tokensis provided, the budget is preserved in normalized form - if
output_config.effortis provided, it takes precedence for effort selection - if only
thinking.type=enabledis present without budget or effort, the normalized default ismedium
4. How normalized reasoning is written to each target format
4.1 OpenAI Chat / Completions output
Output field:
{
"reasoning_effort": "..."
}
Typical use cases:
- Gemini -> OpenAI
- Claude -> OpenAI
- any other request normalized first, then emitted as OpenAI-compatible reasoning
Effort mapping:
| normalized effort | OpenAI Chat / Completions field |
|---|---|
none | reasoning_effort: "none" |
minimal | reasoning_effort: "minimal" |
low | reasoning_effort: "low" |
medium | reasoning_effort: "medium" |
high | reasoning_effort: "high" |
xhigh | reasoning_effort: "xhigh" |
4.2 OpenAI Responses output
Output field:
{
"reasoning": {
"effort": "..."
}
}
Typical use cases:
- Chat -> Responses
- Claude -> Responses
- Gemini -> Responses
Effort mapping:
| normalized effort | OpenAI Responses field |
|---|---|
none | reasoning.effort: "none" |
minimal | reasoning.effort: "minimal" |
low | reasoning.effort: "low" |
medium | reasoning.effort: "medium" |
high | reasoning.effort: "high" |
xhigh | reasoning.effort: "xhigh" |
4.3 Gemini output
Output location:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true,
"thinkingLevel": "low|medium|high"
}
}
}
There are two main branches.
A. Gemini 3 / 4 / 5 families: use thinkingLevel
If the model name matches one of these families, the proxy prefers thinkingLevel:
gemini-3*gemini-4*gemini-5*
Mapping rules:
- Pro models:
high/xhigh->high- all other enabled states ->
low
- non-Pro models:
none->minimallow->lowmedium->mediumhigh/xhigh->high- everything else ->
minimal
Disable behavior:
- these models generally do not use
thinkingBudget=0as the disable path - when the caller explicitly sends
none, the proxy degrades to the minimum valid level for that model instead of forcing an invalid disable payload
Exact level mapping:
| normalized effort | Gemini 3+ Pro thinkingLevel | Gemini 3+ non-Pro thinkingLevel |
|---|---|---|
none | low | minimal |
minimal | low | minimal |
low | low | low |
medium | low | medium |
high | high | high |
xhigh | high | high |
B. Gemini 2.5 family: use thinkingBudget
Model limits:
| model | budget range | disable supported |
|---|---|---|
gemini-2.5-pro | 128 ~ 32768 | no |
gemini-2.5-flash | 1 ~ 24576 | yes |
gemini-2.5-flash-lite | 512 ~ 24576 | yes |
Write rules:
- when reasoning is enabled:
- first derive a default budget from effort
- then clamp it to the model-specific allowed range
- when reasoning is disabled:
- models that support disabling receive
thinkingBudget=0 - models that do not support disabling receive the minimum allowed budget
- models that support disabling receive
includeThoughts:truewhen reasoning is enabledfalsewhen reasoning is disabled
Important note:
- Gemini thinking budgets are not additionally clamped by
max_tokens/maxOutputTokens - this is intentional, to avoid incorrectly shrinking an otherwise valid Gemini reasoning configuration
Exact budget mapping after Gemini model-range clamping:
| normalized effort | gemini-2.5-pro | gemini-2.5-flash | gemini-2.5-flash-lite |
|---|---|---|---|
none | 128 | 0 | 0 |
minimal | 1024 | 1024 | 1024 |
low | 2048 | 2048 | 2048 |
medium | 8192 | 8192 | 8192 |
high | 16384 | 16384 | 16384 |
xhigh | 32768 | 24576 | 24576 |
includeThoughts is true for enabled rows and false for the none row.
4.4 Claude / Anthropic output
The proxy may emit two shapes.
A. Legacy / budget mode
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
}
B. Adaptive mode
{
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "low|medium|high|max"
}
}
Mapping details:
xhigh-> Claudeoutput_config.effort=maxhigh->highmedium->mediumlow,minimal, andnonemap tolowwhen adaptive output is used
Exact output mapping:
| normalized effort | legacy / budget Claude output | adaptive Claude output |
|---|---|---|
none | thinking.type=disabled | thinking.type=disabled; may be removed for adaptive-only / Mythos models |
minimal | thinking.type=enabled, budget_tokens=1024 | thinking.type=adaptive, output_config.effort=low |
low | thinking.type=enabled, budget_tokens=2048 | thinking.type=adaptive, output_config.effort=low |
medium | thinking.type=enabled, budget_tokens=8192 | thinking.type=adaptive, output_config.effort=medium |
high | thinking.type=enabled, budget_tokens=16384 | thinking.type=adaptive, output_config.effort=high |
xhigh | thinking.type=enabled, budget_tokens=32768 | thinking.type=adaptive, output_config.effort=max |
Budget-mode constraints:
- minimum
budget_tokens=1024 - any explicit budget below
1024is raised to1024 - when
max_tokensexists, the proxy guarantees:max_tokens >= max(budget_tokens + 1, 2048)budget_tokens < max_tokens
- invalid budgets are adjusted into an upstream-valid value
Adaptive capability behavior:
- older models continue to use
enabled + budget_tokens - models that support adaptive thinking are emitted as
thinking.type=adaptive + output_config.effort - Claude capability detection uses
OriginModelfirst, thenActualModel
4.5 Ali DashScope-compatible output
Output fields:
{
"enable_thinking": true,
"thinking_budget": 2048
}
Rules:
none->enable_thinking=false, andthinking_budgetis removed- enabled reasoning ->
enable_thinking=true - if the model supports budgets,
thinking_budgetis written and clamped to the Qianfan documented range[100, 16384]
Exact mapping:
| normalized effort | Ali output for models supporting thinking_budget | Ali output for models without budget support |
|---|---|---|
none | enable_thinking=false; no thinking_budget | enable_thinking=false; no thinking_budget |
minimal | enable_thinking=true, thinking_budget=1024 | enable_thinking=true; no thinking_budget |
low | enable_thinking=true, thinking_budget=2048 | enable_thinking=true; no thinking_budget |
medium | enable_thinking=true, thinking_budget=8192 | enable_thinking=true; no thinking_budget |
high | enable_thinking=true, thinking_budget=16384 | enable_thinking=true; no thinking_budget |
xhigh | enable_thinking=true, thinking_budget=16384 | enable_thinking=true; no thinking_budget |
Models currently considered to support thinking_budget include:
qwen3-*qwq-*- models containing
glm - models containing
kimi
Ali-specific behavior:
thinking_budgetis not clamped bymax_tokensqwen3-*: non-streaming requests are forced toenable_thinking=falseqwq-*: requests are forced tostream=true
4.6 Zhipu / DeepSeek / Doubao thinking output
These vendors currently use a simplified thinking object:
{
"thinking": {
"type": "enabled|disabled"
}
}
Rules:
none->thinking.type=disabled- every other enabled state ->
thinking.type=enabled - these vendors currently preserve only the on/off meaning, not detailed budget information
That means:
minimal,low,medium,high, andxhigh- all collapse into the same upstream
enabledstate
Exact mapping:
| normalized effort | Zhipu / DeepSeek / Doubao output |
|---|---|
none | thinking.type=disabled |
minimal | thinking.type=enabled |
low | thinking.type=enabled |
medium | thinking.type=enabled |
high | thinking.type=enabled |
xhigh | thinking.type=enabled |
4.7 Qianfan output
Qianfan supports multiple upstream reasoning shapes, and different models accept different fields:
{
"thinking": {
"type": "enabled|disabled"
},
"enable_thinking": true,
"thinking_budget": 2048,
"reasoning_effort": "high|max"
}
Rules:
- native
thinkinghas priority and is preserved as provided - when
thinkingis present, conflictingreasoning_effort,enable_thinking, andthinking_budgetare removed - when native
thinkingis absent, the adaptor selects a field family based on model capability:- models that support
reasoning_effort: enabled states emitreasoning_effort=high|max; disabled states emit no reasoning field - models that support
enable_thinking: emitenable_thinking=true|false; enabled states also emitthinking_budgetwhen supported - models that support
thinking: emitthinking.type=enabled|disabled; enabled states also emitthinking_budgetwhen supported - models that only support
thinking_budget: enabled states emit onlythinking_budget; disabled states emit no reasoning field
- models that support
- model capability detection first checks exact documented model names, then falls back to family / keyword matches such as
qwen3-*,deepseek-v4-*,*think*/*thinking*, and*vl* - models that do not match any Qianfan reasoning capability have normalized reasoning controls removed to avoid sending unsupported fields
Exact mapping by field family when the input does not already contain native thinking:
| normalized effort | reasoning_effort models | enable_thinking models | thinking models | budget-only models |
|---|---|---|---|---|
none | no reasoning field | enable_thinking=false | thinking.type=disabled | no reasoning field |
minimal | reasoning_effort=high | enable_thinking=true; thinking_budget=1024 when supported | thinking.type=enabled; thinking_budget=1024 when supported | thinking_budget=1024 |
low | reasoning_effort=high | enable_thinking=true; thinking_budget=2048 when supported | thinking.type=enabled; thinking_budget=2048 when supported | thinking_budget=2048 |
medium | reasoning_effort=high | enable_thinking=true; thinking_budget=8192 when supported | thinking.type=enabled; thinking_budget=8192 when supported | thinking_budget=8192 |
high | reasoning_effort=high | enable_thinking=true; thinking_budget=16384 when supported | thinking.type=enabled; thinking_budget=16384 when supported | thinking_budget=16384 |
xhigh | reasoning_effort=max | enable_thinking=true; thinking_budget=16384 when supported | thinking.type=enabled; thinking_budget=16384 when supported | thinking_budget=16384 |
For OpenAI Responses input, Qianfan also normalizes reasoning.effort into
the same upstream Qianfan fields.
4.8 Moonshot / Kimi output
Moonshot / Kimi uses Kimi's thinking object only for upstream models that
support thinking toggling:
{
"thinking": {
"type": "enabled|disabled"
}
}
Exact mapping for toggle-capable Kimi models:
| normalized effort | Kimi output |
|---|---|
none | thinking.type=disabled |
minimal | thinking.type=enabled |
low | thinking.type=enabled |
medium | thinking.type=enabled |
high | thinking.type=enabled |
xhigh | thinking.type=enabled |
For non-toggle Kimi models, the adaptor removes reasoning_effort and does not
send thinking. Kimi output currently preserves only on/off semantics, not
budget or fine-grained effort.
5. Vendor / adaptor support matrix
This section focuses on the major adaptors that currently participate in the reasoning compatibility layer. The tables describe what happens after the source request has been parsed into the normalized reasoning model.
5.1 OpenAI / Azure / OpenAI-compatible upstreams
Native fields:
| mode | native source field | emitted upstream field | exact effort mapping |
|---|---|---|---|
| Chat Completions | reasoning_effort | reasoning_effort | unchanged unless a known GPT model family does not support the requested value |
| Completions | reasoning_effort | reasoning_effort | unchanged unless a known GPT model family does not support the requested value |
| Responses | reasoning.effort | reasoning.effort | unchanged unless a known GPT model family does not support the requested value |
Cross-protocol conversions:
| source request mode | target OpenAI mode | conversion |
|---|---|---|
| Gemini -> Chat / Completions | OpenAI-compatible chat payload | generationConfig.thinkingConfig -> normalized effort -> reasoning_effort |
| Claude / Anthropic -> Chat / Completions | OpenAI-compatible chat payload | thinking / output_config -> normalized effort -> reasoning_effort |
| OpenAI Chat -> Responses | OpenAI Responses payload | reasoning_effort -> normalized effort -> reasoning.effort |
| Gemini -> Responses | OpenAI Responses payload | thinkingConfig -> normalized effort -> reasoning.effort |
| Claude / Anthropic -> Responses | OpenAI Responses payload | thinking / output_config -> OpenAI chat request -> reasoning.effort |
Notes:
- OpenAI Chat / Completions only parse
reasoning_effort. - OpenAI Chat / Completions do not parse Gemini-style
thinkingConfig, Claude-stylethinking, Alienable_thinking, or Alithinking_budgetin this mode. - GPT reasoning effort compatibility is an OpenAI-adaptor-specific rule. It applies to native OpenAI Chat / Completions / Responses payloads and to Gemini / Claude / Chat requests converted into OpenAI Chat or Responses payloads.
- The compatibility check uses
OriginModelfirst and falls back toActualModel. Matching recognizes only explicit known GPT model IDs / families, while allowing provider prefixes and official-style suffixes such as dated snapshots. - If neither model name matches a known GPT reasoning-effort family, including unknown GPT-like model names, the adaptor leaves the requested effort unchanged.
- For known GPT families, unsupported efforts are migrated to the nearest supported effort. Ties prefer the higher enabled effort, so
minimalon a model that supportsnoneandlowbecomeslow.
Known GPT effort support used by the adaptor:
| model match | supported reasoning_effort / reasoning.effort values | migration examples |
|---|---|---|
gpt-5.5* | none, low, medium, high, xhigh | minimal -> low |
gpt-5.4*, gpt-5.2* | none, low, medium, high, xhigh | minimal -> low |
gpt-5.4-pro*, gpt-5.2-pro* | medium, high, xhigh | none / minimal / low -> medium |
gpt-5.1* | none, low, medium, high | minimal -> low; xhigh -> high |
gpt-5-pro* | high | any unsupported value -> high |
gpt-5* | minimal, low, medium, high | none -> minimal; xhigh -> high |
5.2 Google Gemini
Supported reasoning conversion modes:
| source request mode | Gemini adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | generationConfig.thinkingConfig |
| Claude / Anthropic | parses thinking / output_config through the Claude converter | generationConfig.thinkingConfig |
| Gemini native | uses generationConfig.thinkingConfig as the native request field | generationConfig.thinkingConfig |
| OpenAI Responses | not a Gemini adaptor input mode | N/A |
| OpenAI Completions | not a Gemini adaptor input mode | N/A |
Exact output depends on the target Gemini model family:
| normalized effort | Gemini 3+ Pro | Gemini 3+ non-Pro | gemini-2.5-pro | gemini-2.5-flash | gemini-2.5-flash-lite |
|---|---|---|---|---|---|
none | thinkingLevel=low | thinkingLevel=minimal | thinkingBudget=128, includeThoughts=false | thinkingBudget=0, includeThoughts=false | thinkingBudget=0, includeThoughts=false |
minimal | thinkingLevel=low | thinkingLevel=minimal | thinkingBudget=1024, includeThoughts=true | thinkingBudget=1024, includeThoughts=true | thinkingBudget=1024, includeThoughts=true |
low | thinkingLevel=low | thinkingLevel=low | thinkingBudget=2048, includeThoughts=true | thinkingBudget=2048, includeThoughts=true | thinkingBudget=2048, includeThoughts=true |
medium | thinkingLevel=low | thinkingLevel=medium | thinkingBudget=8192, includeThoughts=true | thinkingBudget=8192, includeThoughts=true | thinkingBudget=8192, includeThoughts=true |
high | thinkingLevel=high | thinkingLevel=high | thinkingBudget=16384, includeThoughts=true | thinkingBudget=16384, includeThoughts=true | thinkingBudget=16384, includeThoughts=true |
xhigh | thinkingLevel=high | thinkingLevel=high | thinkingBudget=32768, includeThoughts=true | thinkingBudget=24576, includeThoughts=true | thinkingBudget=24576, includeThoughts=true |
Notes:
- The exact mapping table applies when the adaptor is converting from OpenAI Chat or Claude / Anthropic into Gemini.
- Native Gemini requests keep their own
generationConfig.thinkingConfig; the adaptor does not rewrite a native Gemini thinking dialect into another Gemini thinking dialect. - Gemini 2.5 uses budget-based output with model-specific range enforcement.
- Gemini 3 / 4 / 5 use
thinkingLevel. - Some models cannot truly disable thinking, so
nonedegrades to the minimum valid level or budget.
5.3 Anthropic official
Supported reasoning conversion modes:
| source request mode | Anthropic adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | thinking and optionally output_config |
| Gemini native | parses generationConfig.thinkingConfig | thinking and optionally output_config |
| Anthropic native | preserves native Anthropic fields | thinking and output_config as provided, with native cleanup |
| OpenAI Responses | not an Anthropic adaptor input mode | N/A |
| OpenAI Completions | not an Anthropic adaptor input mode | N/A |
Exact output by Claude capability:
| normalized effort | legacy / budget Claude output | adaptive Claude output |
|---|---|---|
none | thinking.type=disabled | thinking.type=disabled; may be removed for adaptive-only / Mythos models |
minimal | thinking.type=enabled, budget_tokens=1024 | thinking.type=adaptive, output_config.effort=low |
low | thinking.type=enabled, budget_tokens=2048 | thinking.type=adaptive, output_config.effort=low |
medium | thinking.type=enabled, budget_tokens=8192 | thinking.type=adaptive, output_config.effort=medium |
high | thinking.type=enabled, budget_tokens=16384 | thinking.type=adaptive, output_config.effort=high |
xhigh | thinking.type=enabled, budget_tokens=32768 | thinking.type=adaptive, output_config.effort=max |
Notes:
- The exact mapping table applies when the adaptor is converting from OpenAI Chat or Gemini into Claude.
- Native Anthropic requests keep native
thinking/output_configfields, apart from native cleanup required by the adaptor. - Budget mode enforces
budget_tokens < max_tokens. - Older models use
enabled + budget_tokens. - Adaptive-capable models use
adaptive + output_config.effort.
5.4 AWS Bedrock Claude
Supported reasoning conversion modes:
| source request mode | Bedrock Claude behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | Claude thinking after Bedrock wrapping |
| Gemini native | parses generationConfig.thinkingConfig | Claude thinking after Bedrock wrapping |
| Anthropic native | preserves native Anthropic fields | Claude thinking after Bedrock wrapping |
| OpenAI Responses | not a Bedrock Claude input mode | N/A |
| OpenAI Completions | not a Bedrock Claude input mode | N/A |
The effort mapping is the same as Anthropic official: legacy models use enabled + budget_tokens; adaptive-capable models use adaptive + output_config.effort.
Bedrock then wraps the Claude request for the Bedrock runtime.
5.5 Vertex AI Claude
Supported reasoning conversion modes:
| source request mode | Vertex Claude behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | Claude thinking after Vertex wrapping |
| Gemini native | parses generationConfig.thinkingConfig | Claude thinking after Vertex wrapping |
| Anthropic native | preserves native Anthropic fields | Claude thinking after Vertex wrapping |
| OpenAI Responses | not a Vertex Claude input mode | N/A |
| OpenAI Completions | not a Vertex Claude input mode | N/A |
The effort mapping is the same as Anthropic official: legacy models use enabled + budget_tokens; adaptive-capable models use adaptive + output_config.effort.
Vertex then wraps the Claude request for Vertex AI.
5.6 Ali DashScope
Supported reasoning conversion modes:
| source request mode | Ali adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | enable_thinking; optional thinking_budget |
| OpenAI Completions | parses reasoning_effort | enable_thinking; optional thinking_budget |
| Gemini native | parses generationConfig.thinkingConfig through OpenAI-compatible conversion | enable_thinking; optional thinking_budget |
| Anthropic native | uses Ali Claude Code Proxy native request format | no cross-dialect reasoning migration |
| OpenAI Responses | passed through OpenAI-compatible Responses conversion | no Ali-specific reasoning hook |
Ali exact effort mapping:
| normalized effort | output on budget-capable Ali models | output on non-budget Ali models |
|---|---|---|
none | enable_thinking=false; thinking_budget removed | enable_thinking=false; thinking_budget removed |
minimal | enable_thinking=true; thinking_budget=1024 | enable_thinking=true; no thinking_budget |
low | enable_thinking=true; thinking_budget=2048 | enable_thinking=true; no thinking_budget |
medium | enable_thinking=true; thinking_budget=8192 | enable_thinking=true; no thinking_budget |
high | enable_thinking=true; thinking_budget=16384 | enable_thinking=true; no thinking_budget |
xhigh | enable_thinking=true; thinking_budget=16384 | enable_thinking=true; no thinking_budget |
Ali budget-capable model detection:
| model rule | writes thinking_budget |
|---|---|
model starts with qwen3- | yes |
model starts with qwq- | yes |
model name contains glm | yes |
model name contains kimi | yes |
| other Ali-compatible models | no; only enable_thinking is written |
Ali-specific behavior:
thinking_budgetis not clamped bymax_tokens.qwen3-*non-streaming Chat / Completions requests forceenable_thinking=falseafter the reasoning hook.qwen3-*non-streaming Gemini-mode requests forceenable_thinking=falseand removethinking_budget.qwq-*requests forcestream=true.
5.7 Doubao
Supported reasoning conversion modes:
| source request mode | Doubao adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | thinking.type |
| Gemini native | parses generationConfig.thinkingConfig through OpenAI-compatible conversion | thinking.type |
| Anthropic native | parses thinking / output_config through OpenAI-compatible conversion | thinking.type |
| OpenAI Responses | passed through native OpenAI-compatible Responses conversion | no Doubao-specific reasoning hook |
| OpenAI Completions | not supported by Doubao adaptor | N/A |
Exact effort mapping:
| normalized effort | Doubao output |
|---|---|
none | thinking.type=disabled |
minimal | thinking.type=enabled |
low | thinking.type=enabled |
medium | thinking.type=enabled |
high | thinking.type=enabled |
xhigh | thinking.type=enabled |
Notes:
- Only on/off semantics are preserved; budget and fine-grained effort are dropped.
deepseek-reasoneralso injects a system prompt, using the same origin-first, actual-fallback model match strategy.
5.8 DeepSeek
Supported reasoning conversion modes:
| source request mode | DeepSeek adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | thinking.type |
| Gemini native | parses generationConfig.thinkingConfig through OpenAI-compatible conversion | thinking.type |
| Anthropic native | uses DeepSeek /anthropic/v1/messages | no cross-dialect reasoning migration |
| OpenAI Responses | unsupported by the DeepSeek adaptor | N/A |
| OpenAI Completions | OpenAI-compatible pass-through | no DeepSeek-specific reasoning hook |
Exact effort mapping for the hooked Chat / Gemini paths:
| normalized effort | DeepSeek output |
|---|---|
none | thinking.type=disabled |
minimal | thinking.type=enabled |
low | thinking.type=enabled |
medium | thinking.type=enabled |
high | thinking.type=enabled |
xhigh | thinking.type=enabled |
DeepSeek currently preserves only enabled / disabled for the hooked OpenAI Chat and Gemini paths.
5.9 Zhipu
Supported reasoning conversion modes:
| source request mode | Zhipu adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | thinking.type |
| Gemini native | parses generationConfig.thinkingConfig through OpenAI-compatible conversion | thinking.type |
| Anthropic native | parses thinking / output_config through OpenAI-compatible conversion | thinking.type |
| OpenAI Responses | unsupported by this adaptor | N/A |
| OpenAI Completions | OpenAI-compatible pass-through | no Zhipu-specific reasoning hook |
Exact effort mapping for the hooked Chat / Gemini / Anthropic paths:
| normalized effort | Zhipu output |
|---|---|
none | thinking.type=disabled |
minimal | thinking.type=enabled |
low | thinking.type=enabled |
medium | thinking.type=enabled |
high | thinking.type=enabled |
xhigh | thinking.type=enabled |
Zhipu currently preserves only enabled / disabled for the hooked paths.
5.10 Qianfan
Supported reasoning conversion modes:
| source request mode | Qianfan adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | preserves native thinking; otherwise parses reasoning_effort | model-dependent thinking.type / enable_thinking / thinking_budget / reasoning_effort |
| OpenAI Completions | preserves native thinking; otherwise parses reasoning_effort | model-dependent thinking.type / enable_thinking / thinking_budget / reasoning_effort |
| Gemini native | parses generationConfig.thinkingConfig through OpenAI-compatible conversion | model-dependent thinking.type / enable_thinking / thinking_budget / reasoning_effort |
| Anthropic native | parses thinking / output_config through OpenAI-compatible conversion | model-dependent thinking.type / enable_thinking / thinking_budget / reasoning_effort |
| OpenAI Responses | preserves native thinking; otherwise parses reasoning.effort | model-dependent thinking.type / enable_thinking / thinking_budget / reasoning_effort |
Exact effort mapping by field family when native thinking is not already present:
| normalized effort | reasoning_effort models | enable_thinking models | thinking models | budget-only models |
|---|---|---|---|---|
none | no reasoning field | enable_thinking=false | thinking.type=disabled | no reasoning field |
minimal | reasoning_effort=high | enable_thinking=true; thinking_budget=1024 when supported | thinking.type=enabled; thinking_budget=1024 when supported | thinking_budget=1024 |
low | reasoning_effort=high | enable_thinking=true; thinking_budget=2048 when supported | thinking.type=enabled; thinking_budget=2048 when supported | thinking_budget=2048 |
medium | reasoning_effort=high | enable_thinking=true; thinking_budget=8192 when supported | thinking.type=enabled; thinking_budget=8192 when supported | thinking_budget=8192 |
high | reasoning_effort=high | enable_thinking=true; thinking_budget=16384 when supported | thinking.type=enabled; thinking_budget=16384 when supported | thinking_budget=16384 |
xhigh | reasoning_effort=max | enable_thinking=true; thinking_budget=16384 when supported | thinking.type=enabled; thinking_budget=16384 when supported | thinking_budget=16384 |
Notes:
- Qianfan native
thinkingwins overreasoning_effort/reasoning.effort. - When native
thinkingis present in Chat / Completions, the adaptor removesreasoning_effort,enable_thinking, andthinking_budget. - When native
thinkingis present in Responses, the adaptor removesreasoning. - Qianfan accepts only
highandmaxforreasoning_effort, so lower enabled efforts are upgraded tohigh. - disabled states are expressed according to the model's field family; models that cannot disable thinking or do not match a reasoning capability are not forced to receive
thinking.type=disabled. - model capability detection is origin-first, actual-fallback, and falls back to family / keyword matching when exact model names do not match.
5.11 Moonshot / Kimi
Supported reasoning conversion modes:
| source request mode | Moonshot adaptor behavior | emitted upstream field |
|---|---|---|
| OpenAI Chat | parses reasoning_effort | Kimi thinking.type for toggle-capable models |
| Gemini native | parses generationConfig.thinkingConfig through OpenAI-compatible conversion | Kimi thinking.type for toggle-capable models |
| Anthropic native | parses thinking / output_config through OpenAI-compatible conversion | Kimi thinking.type for toggle-capable models |
| OpenAI Completions | OpenAI-compatible payload is passed through | no Moonshot-specific reasoning hook |
| OpenAI Responses | unsupported by the Moonshot adaptor | N/A |
The Moonshot adaptor currently treats these actual upstream model names as thinking-toggle capable:
| actual upstream model rule | supports emitted Kimi thinking.type |
|---|---|
kimi-k2.5* | yes |
kimi-k2.6* | yes |
| other Kimi model names | no; reasoning_effort is removed and thinking is omitted |
Exact effort mapping for toggle-capable Kimi models:
| normalized effort | Kimi output |
|---|---|
none | thinking.type=disabled; reasoning_effort removed |
minimal | thinking.type=enabled; reasoning_effort removed |
low | thinking.type=enabled; reasoning_effort removed |
medium | thinking.type=enabled; reasoning_effort removed |
high | thinking.type=enabled; reasoning_effort removed |
xhigh | thinking.type=enabled; reasoning_effort removed |
For non-toggle Kimi models, such as dedicated thinking models, the adaptor removes reasoning_effort and omits thinking.
It does not send thinking.type=disabled to a model that cannot be disabled.
Notes:
- Only on/off semantics are preserved; budget and fine-grained effort are dropped.
- Model support is checked against
ActualModel, because the upstream Kimi model name after channel mapping determines whetherthinkingis valid.
6. Model matching strategy
Most model-capability branches follow the same rule:
- use
OriginModelfirst - if
OriginModeldoes not match, fall back toActualModel
Why this exists:
- callers may use a business-facing original model name
- channel mapping may rewrite to the real upstream model name in
ActualModel - some capability checks only match one of those names
This strategy is already used in:
- Claude adaptive capability detection
- Gemini thinking-level vs thinking-budget path selection
- Ali budget support detection
- Doubao bot / vision / deepseek-reasoner special routing
- other model-name-based reasoning capability branches
Exception:
- Moonshot / Kimi thinking-toggle detection uses
ActualModelfirst, becausethinkingvalidity depends on the final upstream Kimi model after channel mapping.
7. Complete conversion examples
This section is intentionally broad. It tries to cover every reasoning-related conversion path currently implemented in code.
7.1 OpenAI Chat / Completions as the source format
7.1.1 OpenAI Chat -> OpenAI Responses
Input:
{
"model": "gpt-4o",
"reasoning_effort": "high",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"model": "gpt-4o",
"input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "hello"}]}],
"reasoning": {
"effort": "high"
}
}
Notes:
- the same reasoning payload shape is used when Chat is converted to Responses for OpenAI-compatible upstreams
- the same principle also applies to Azure when the request is routed to Responses
7.1.2 OpenAI Chat -> Gemini 2.5 Pro
Input:
{
"model": "gemini-2.5-pro",
"reasoning_effort": "high",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 16384,
"includeThoughts": true
}
}
}
7.1.3 OpenAI Chat -> Gemini 2.5 Flash with explicit disable
Input:
{
"model": "gemini-2.5-flash",
"reasoning_effort": "none",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 0,
"includeThoughts": false
}
}
}
7.1.4 OpenAI Chat -> Gemini 3 Pro with explicit disable
Input:
{
"model": "gemini-3-pro",
"reasoning_effort": "none",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"generationConfig": {
"thinkingConfig": {
"thinkingLevel": "low",
"includeThoughts": false
}
}
}
Notes:
- the proxy does not force an invalid disable payload here
- it degrades to the minimum valid level for the model
7.1.5 OpenAI Chat -> Anthropic Claude Sonnet 4.5
Input:
{
"model": "claude-sonnet-4-5",
"reasoning_effort": "low",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
}
7.1.6 OpenAI Chat -> Anthropic Claude 3.7 Sonnet
Input:
{
"model": "claude-3-7-sonnet-20250219",
"reasoning_effort": "medium",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "enabled",
"budget_tokens": 8192
}
}
7.1.7 OpenAI Chat -> Anthropic Claude Opus 4.7
Input:
{
"model": "claude-opus-4-7",
"reasoning_effort": "high",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "high"
}
}
7.1.8 OpenAI Chat -> AWS Bedrock Claude
Input:
{
"model": "claude-opus-4-7",
"reasoning_effort": "high",
"messages": [{"role": "user", "content": "hello"}]
}
Representative output body:
{
"anthropic_version": "bedrock-2023-05-31",
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "high"
}
}
Notes:
- AWS wraps the Claude request with Bedrock-specific fields
- the inner Claude thinking shape still follows the Anthropic conversion rules
7.1.9 OpenAI Chat -> Vertex AI Claude
Input:
{
"model": "claude-sonnet-4-5",
"reasoning_effort": "low",
"messages": [{"role": "user", "content": "hello"}]
}
Representative output body:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
}
Notes:
- Vertex AI uses a different transport path such as
rawPredict/streamRawPredict - the request body still follows the Claude reasoning schema
7.1.10 OpenAI Chat -> Ali compatible chat
Input:
{
"model": "glm-4.5",
"reasoning_effort": "high",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"reasoning_effort": "high"
}
7.1.11 OpenAI Chat -> Ali qwen3-* non-stream request
Input:
{
"model": "qwen3-32b",
"reasoning_effort": "high",
"stream": false,
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"enable_thinking": false,
"thinking_budget": 16384
}
Notes:
- the model-specific qwen3 patch forces
enable_thinking=falsefor non-streaming requests - the budget field may still remain in the converted body because the override only changes the enable flag
7.1.12 OpenAI Chat -> Ali qwq-*
Input:
{
"model": "qwq-plus",
"reasoning_effort": "low",
"stream": false,
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"enable_thinking": true,
"thinking_budget": 2048,
"stream": true
}
7.1.13 OpenAI Chat -> Zhipu
Input:
{
"model": "glm-5.1",
"reasoning_effort": "none",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "disabled"
}
}
7.1.14 OpenAI Chat -> DeepSeek
Input:
{
"model": "deepseek-chat",
"reasoning_effort": "high",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "enabled"
}
}
7.1.15 OpenAI Chat -> Doubao
Input:
{
"model": "doubao-seed-1-6",
"reasoning_effort": "none",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "disabled"
}
}
7.1.16 OpenAI Chat -> Doubao with deepseek-reasoner
Input:
{
"model": "deepseek-reasoner",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"messages": [
{
"role": "system",
"content": "ๅ็ญๅ๏ผ้ฝๅ
็จ <think></think> ่พๅบไฝ ็ๆ่่ฟ็จใ"
},
{
"role": "user",
"content": "hello"
}
]
}
Notes:
- this is not an effort conversion example
- it is still part of the implemented reasoning-related behavior in the Doubao adaptor
7.1.17 OpenAI Chat -> Moonshot / Kimi K2.6
Input:
{
"model": "kimi-k2.6",
"reasoning_effort": "none",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "disabled"
}
}
Notes:
reasoning_effortis removed- enabled efforts become
thinking.type=enabled - budget and fine-grained effort are not preserved
7.1.18 OpenAI Chat -> Moonshot / Kimi non-toggle model
Input:
{
"model": "kimi-k2-thinking",
"reasoning_effort": "none",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"messages": [{"role": "user", "content": "hello"}]
}
Notes:
reasoning_effortis removedthinkingis omitted because this model family does not support toggling via request parameter
7.1.19 OpenAI Completions -> Ali
Input:
{
"model": "glm-4.5",
"reasoning_effort": "low",
"prompt": "hello"
}
Output:
{
"enable_thinking": true,
"thinking_budget": 2048
}
7.1.20 OpenAI Chat -> Qianfan, disabling reasoning on an enable_thinking model
Input:
{
"model": "qwen3-14b",
"reasoning_effort": "none",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"enable_thinking": false
}
Notes:
reasoning_effort:noneis removed- the Qianfan adaptor expresses disabled reasoning according to the target model's field family;
qwen3-*usesenable_thinking=false
7.1.21 OpenAI Chat -> Qianfan DeepSeek v4 with enabled reasoning
Input:
{
"model": "deepseek-v4-pro",
"reasoning_effort": "xhigh",
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "enabled"
},
"thinking_budget": 16384
}
Notes:
- DeepSeek models use Qianfan
thinking.type. - DeepSeek v4 also supports
thinking_budget, so enabled reasoning includes the budget derived from effort and clamped to[100, 16384]. reasoning_effortis removed after conversion.
7.1.22 OpenAI Chat -> Qianfan with native thinking
Input:
{
"model": "deepseek-v3.2",
"reasoning_effort": "none",
"thinking": {
"type": "enabled"
},
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "enabled"
}
}
Notes:
- native
thinkingwins - conflicting
reasoning_effort,enable_thinking, andthinking_budgetare removed
7.1.23 OpenAI Completions -> Qianfan
Input:
{
"model": "qwen3-14b",
"reasoning_effort": "low",
"prompt": "hello"
}
Output:
{
"enable_thinking": true,
"thinking_budget": 2048
}
7.2 Gemini native requests as the source format
7.2.1 Gemini -> OpenAI Chat / Completions
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true
}
},
"contents": [{"role": "user", "parts": [{"text": "hello"}]}]
}
Output:
{
"reasoning_effort": "low",
"messages": [{"role": "user", "content": "hello"}]
}
7.2.2 Gemini -> OpenAI Responses
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingLevel": "high"
}
},
"contents": [{"role": "user", "parts": [{"text": "hello"}]}]
}
Output:
{
"reasoning": {
"effort": "high"
}
}
7.2.3 Gemini -> Anthropic official
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true
}
},
"contents": [{"role": "user", "parts": [{"text": "hello"}]}]
}
Output for an older Claude model:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
}
7.2.4 Gemini -> Anthropic adaptive Claude
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true
}
},
"contents": [{"role": "user", "parts": [{"text": "hello"}]}]
}
Output for claude-opus-4-7:
{
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "low"
}
}
7.2.5 Gemini -> AWS Bedrock Claude
Representative output body:
{
"anthropic_version": "bedrock-2023-05-31",
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
}
7.2.6 Gemini -> Vertex AI Claude
Representative output body:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
}
7.2.7 Gemini -> Ali
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true
}
},
"contents": [{"role": "user", "parts": [{"text": "hello"}]}]
}
Output:
{
"enable_thinking": true,
"thinking_budget": 2048
}
7.2.8 Gemini -> Zhipu / DeepSeek / Doubao
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true
}
}
}
Output:
{
"thinking": {
"type": "enabled"
}
}
Notes:
- budget details are not preserved
- the payload degrades to pure on/off semantics
7.2.9 Gemini -> Moonshot / Kimi K2.6
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 2048,
"includeThoughts": true
}
}
}
Output:
{
"thinking": {
"type": "enabled"
}
}
Notes:
- Gemini
thinkingConfigis first normalized through the OpenAI-compatiblereasoning_effortpath, then the Moonshot hook writes Kimithinking - budget details are not preserved
7.2.10 Gemini -> Qianfan
Input:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 0
}
},
"contents": [{"role": "user", "parts": [{"text": "hello"}]}]
}
Output:
{
"enable_thinking": false
}
Notes:
- Gemini
thinkingBudget<=0is normalized tonone - Qianfan writes disabled states according to the model field family:
enable_thinking=false,thinking.type=disabled, or no reasoning field - enabled Gemini budgets first become normalized effort, then Qianfan emits the field family supported by the target model
7.3 Claude / Anthropic requests as the source format
7.3.1 Claude -> OpenAI Chat / Completions
Input:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
},
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"reasoning_effort": "low",
"messages": [{"role": "user", "content": "hello"}]
}
7.3.2 Claude adaptive -> OpenAI Chat / Completions
Input:
{
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "high"
},
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"reasoning_effort": "high"
}
7.3.3 Claude -> OpenAI Responses
Input:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
},
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"reasoning": {
"effort": "low"
}
}
7.3.4 Claude -> Gemini
Input:
{
"thinking": {
"type": "enabled",
"budget_tokens": 16384
},
"messages": [{"role": "user", "content": "hello"}]
}
Output for gemini-2.5-pro:
{
"generationConfig": {
"thinkingConfig": {
"thinkingBudget": 16384,
"includeThoughts": true
}
}
}
7.3.5 Native Anthropic -> Anthropic official
Input:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
},
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
}
Notes:
- this path preserves native Claude thinking fields
- it does not rewrite them into another thinking dialect
7.3.6 Native Anthropic -> AWS / Vertex Claude wrappers
Input:
{
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "low"
},
"messages": [{"role": "user", "content": "hello"}]
}
Representative AWS wrapper:
{
"anthropic_version": "bedrock-2023-05-31",
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "low"
}
}
Representative Vertex body:
{
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "low"
}
}
7.3.7 Claude -> Moonshot / Kimi K2.6
Input:
{
"thinking": {
"type": "disabled"
},
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"thinking": {
"type": "disabled"
}
}
Notes:
- Claude
thinkingis first normalized through the OpenAI-compatiblereasoning_effortpath, then the Moonshot hook writes Kimithinking - budget and adaptive effort details are not preserved by the Kimi target
7.3.8 Claude -> Qianfan
Input:
{
"thinking": {
"type": "adaptive"
},
"output_config": {
"effort": "high"
},
"messages": [{"role": "user", "content": "hello"}]
}
Output:
{
"enable_thinking": true,
"thinking_budget": 16384
}
Notes:
- Claude
thinking/output_configare first normalized through the OpenAI-compatible path - Qianfan then writes according to the target model's field family; the example
qwen3-*target usesenable_thinkingandthinking_budget - disabled Claude thinking is expressed according to the target model's field family, or omitted when the model cannot disable reasoning
7.4 OpenAI Responses requests as the source format
7.4.1 OpenAI Responses -> Qianfan
Input:
{
"model": "deepseek-v3.2",
"input": "hello",
"reasoning": {
"effort": "none"
}
}
Output:
{
"model": "deepseek-v3.2",
"input": "hello",
"thinking": {
"type": "disabled"
}
}
Notes:
reasoning.effort:noneis removed- the example target model supports
thinking, so Qianfan receivesthinking.type=disabled - if a Responses request already contains native
thinking, that nativethinkingwins andreasoningis removed
8. What this feature does not do
This feature intentionally does not do the following:
- it does not parse thinking dialects that do not belong to the current request mode
- for example, OpenAI Chat mode does not parse Gemini
thinkingConfig - Gemini mode does not parse Claude
thinking
- for example, OpenAI Chat mode does not parse Gemini
- it does not migrate every native request into a different thinking dialect
- it does not guarantee that every upstream preserves detailed budget and effort semantics
- especially for Zhipu / Doubao / DeepSeek, which currently preserve only enabled / disabled
- it does not automatically add reasoning compatibility to adaptors that do not yet install the required hooks
9. Maintenance guidance
If a new vendor or request format needs thinking compatibility in the future, the recommended workflow is:
- define the native parsing entry for that request mode
- normalize it into
NormalizedReasoning - write it back using the actual upstream-supported schema
- only apply constraints and validity fixes to the converted request body
- document the model-name matching order for capability checks; use
origin-first / actual-fallback by default, but use
ActualModelwhen the final upstream model name determines parameter validity - add tests for at least:
- explicit disable
- old-model vs new-model behavior
- budget minimum and maximum limits
max_tokens/maxOutputTokensinteractionsOriginModelmatch andActualModelfallback match