Skip to content

fix(azure): use max_completion_tokens and omit temperature for reasoning deployments - #2807

Merged
esokullu merged 3 commits into
webbrain-one:mainfrom
alectimison-maker:fix/azure-reasoning-model-contract
Aug 16, 2026
Merged

fix(azure): use max_completion_tokens and omit temperature for reasoning deployments#2807
esokullu merged 3 commits into
webbrain-one:mainfrom
alectimison-maker:fix/azure-reasoning-model-contract

Conversation

@alectimison-maker

Copy link
Copy Markdown
Contributor

Summary

  • Azure OpenAI deployments of reasoning models (o1, o1-mini, o3-mini, o4-mini, gpt-5, gpt-4.1) now use max_completion_tokens and omit temperature, matching the new OpenAI wire contract these models require.
  • Legacy deployments (gpt-4o, gpt-35-turbo) keep max_tokens and temperature: 0.7 unchanged.
  • config.omitTemperature is now honored on any deployment.

Fixes #2806.

Motivation

Azure rejects max_tokens and any non-default temperature for reasoning-model deployments, so every chat, Ask, and connection-test request 400s and the provider is unusable with those models. The OpenAI-compatible provider already migrated via _isNewOpenAIContract() (src/chrome/src/providers/openai.js:170); the Azure class (src/chrome/src/providers/azure-openai.js:64) still hard-codes the legacy contract, and its temperature could not even be suppressed via extraBody (it is not in RESERVED_EXTRA_BODY_KEYS).

Design

Mirrored the OpenAI-compatible provider's contract detection: a regex over the deployment name (which commonly mirrors the model id) with the same anchored pattern ^(gpt-5|gpt-4\.1|o1|o3|o4). Deployment names that do not match the pattern keep the legacy contract, and custom reasoning deployments can still opt out via config.omitTemperature — both paths are tested. Changes are mirrored to the Firefox tree per the repo's parity convention.

Testing

  • node test/run.js — 1766 passed, 0 failed (3 new tests cover both Chrome and Firefox providers)
  • npm run test:security — 60/60 passed
  • npm run test:toolbar-guard — 33 passed

New tests assert the wire body directly (_buildRequestBody) for reasoning deployments (max_completion_tokens set, max_tokens and temperature absent), legacy deployments (max_tokens and temperature 0.7 preserved), and the omitTemperature escape hatch. No network access needed.

Compatibility and risks

  • Legacy Azure deployments keep byte-identical request bodies.
  • Reasoning deployments detected by deployment name: a deployment named after the model (the common case) is fixed automatically; custom names fall back to the legacy contract, and the issue/PR notes the omitTemperature escape hatch.
  • Requires an api-version that supports max_completion_tokens for reasoning models — this was already a requirement for those deployments to work at all.

Scope

  • Deferred: router-prefixed reasoning model ids in the OpenAI-compatible provider (openai.js _isNewOpenAIContract cannot see openai/o1-style ids) — noted as a follow-up, not addressed here.

…ing deployments

Azure OpenAI deployments of reasoning models (o1, o3, o4, gpt-5, gpt-4.1)
reject the legacy max_tokens parameter and any temperature override, so
every chat, Ask, and connection-test request 400s. Mirror the
_isNewOpenAIContract detection from the OpenAI-compatible provider and
switch to max_completion_tokens with the API's default temperature.
Legacy deployments (gpt-4o, gpt-35-turbo) keep max_tokens and 0.7
temperature; config.omitTemperature is now honored on any deployment.
Deployment names do not reveal the model behind them (prod-chat may back
o3-mini, o365-assistant may back gpt-35-turbo), so name-guessing both
misses reasoning deployments and misfires on look-alike names. Drop the
heuristic; the Compatibility panel's max tokens field is now the explicit
per-deployment switch. Setting it to max_completion_tokens also omits
temperature, since a reasoning deployment rejects any non-default
temperature. The panel and the wire contract stay consistent.
@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

@alectimison-maker is attempting to deploy a commit to the esokullu's projects Team on Vercel.

A member of the Team first needs to authorize it.

@alectimison-maker

Copy link
Copy Markdown
Contributor Author

Thanks — you're right that deployment names don't reveal the model, and the guess misfired in both directions. I've reworked the approach to drop name-guessing entirely:

  • azure-openai.js no longer inspects the deployment name. The default wire contract is the legacy one (max_tokens + temperature), exactly as before this PR.
  • The Compatibility panel's "max tokens field" is now the explicit per-deployment switch (it already flowed through configuredMaxTokensField; _addMaxTokens just stops hard-coding max_tokens). Setting it to max_completion_tokens also omits temperature, because a reasoning deployment rejects any non-default temperature — so one knob does both, and the panel's own summary (automaticTokenField) stays consistent with what is actually sent.
  • omitTemperature still works independently.

This also resolves the untrimmed-read and the settings-panel-drift concerns: there is no name probe to trim, and auto mode always shows/sends max_tokens.

New tests: o1/o3/o4/gpt-5/o365-assistant/prod-chat names all stay legacy by default; compat.maxTokensField: 'max_completion_tokens' flips a prod-chat deployment to the new contract and drops temperature.

@esokullu
esokullu merged commit a01c9d5 into webbrain-one:main Aug 16, 2026
1 of 2 checks passed
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.

Azure OpenAI reasoning deployments (o1/o3/o4/gpt-5/gpt-4.1) fail with 400 on every request

2 participants