Skip to content

Commit 69a9a55

Browse files
zanetworkerfranciscojavierarceomattf
authored
fix(openai): translate max_tokens to max_completion_tokens for reasoning models (#5847)
## What does this PR do? OpenAI is deprecating `max_tokens` in favor of `max_completion_tokens`. Reasoning models (o1, o3, o4-mini) and gpt-5+ already reject `max_tokens` outright with: ``` Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead. ``` This PR translates `max_tokens` to `max_completion_tokens` unconditionally for all OpenAI models, since all current models accept `max_completion_tokens`. This avoids maintaining a hardcoded prefix list that would need updating with every new model family. A `DeprecationWarning` is emitted when the translation occurs, so users are informed that their code should migrate to `max_completion_tokens`. Code using `max_tokens` through OGX will continue to work, but the same code run directly against OpenAI will fail for newer models. The translation runs before the existing clamping logic and only applies when `max_completion_tokens` is not already set by the caller. Closes #5845 ## Test Plan Unit tests in `tests/unit/providers/inference/test_remote_openai.py`: ```bash uv run pytest tests/unit/providers/inference/test_remote_openai.py -x --tb=short ``` ``` tests/unit/providers/inference/test_remote_openai.py ...................... [100%] 22 passed in 0.29s ``` Tests cover: - Translation applies to all models (gpt-4o-mini, gpt-4.1, o3, gpt-5, dated variants) - No translation when `max_completion_tokens` is already set by the caller - Original params object is not mutated - Existing clamping logic still works after translation Manually verified with a multi-model test script against a live OGX server with `OPENAI_API_KEY`: - Before fix: gpt-5, o1, o3, o3-mini, o4-mini all return 400 - After fix: all pass via `/v1/chat/completions` with deprecation warning logged --------- Signed-off-by: Adel Zaalouk <azaalouk@redhat.com> Co-authored-by: Francisco Javier Arceo <arceofrancisco@gmail.com> Co-authored-by: Matthew Farrellee <matt@cs.wisc.edu>
1 parent 9e63b84 commit 69a9a55

22 files changed

Lines changed: 3534 additions & 7 deletions

File tree

src/ogx/providers/remote/inference/openai/openai.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# This source code is licensed under the terms described in the LICENSE file in
55
# the root directory of this source tree.
66

7+
import warnings
78
from collections.abc import AsyncIterator, Iterable
89

910
from ogx.log import get_logger
@@ -113,6 +114,20 @@ async def openai_chat_completion(
113114
self,
114115
params: OpenAIChatCompletionRequestWithExtraBody,
115116
) -> OpenAIChatCompletion | AsyncIterator[OpenAIChatCompletionChunk]:
117+
# OpenAI is deprecating max_tokens in favor of max_completion_tokens.
118+
# Reasoning models (o1/o3/o4) and gpt-5+ reject max_tokens outright.
119+
# Translate unconditionally since all OpenAI models accept max_completion_tokens.
120+
if params.max_tokens is not None and params.max_completion_tokens is None:
121+
warnings.warn(
122+
"max_tokens is deprecated by OpenAI and will be removed in a future release. "
123+
"Use max_completion_tokens instead.",
124+
DeprecationWarning,
125+
stacklevel=2,
126+
)
127+
params = params.model_copy()
128+
params.max_completion_tokens = params.max_tokens
129+
params.max_tokens = None
130+
116131
max_output_tokens = self._get_max_output_tokens(params.model)
117132
if max_output_tokens is not None:
118133
updated_params = params

tests/integration/common/recordings/cb6c1a8ea90e50fc5a2a2419b7c6d9799b8f6dd62cc27e185b41d3e2fbfb7641.json

Lines changed: 1085 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/integration/common/recordings/d8c6f841cb0cc1b67a3425918049e4cbd6138dcf187e153c9629c90a1fd2b669.json

Lines changed: 358 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)