Skip to content

Commit 7d77d20

Browse files
Claudeowndev
andcommitted
Fix max_tokens parameter support for GPT-5 and newer models
- Add _is_new_generation_model() helper to detect models requiring max_completion_tokens - Automatically convert max_tokens to max_completion_tokens for GPT-5, o-series, and reasoning models - Update allowed_params to include max_completion_tokens - Handle model name detection from selected_model, AZURE_AI_MODEL, and URL extraction - Update version to 2.7.0 and add feature documentation Fixes Azure OpenAI error: "Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead." Co-authored-by: owndev <69784886+owndev@users.noreply.github.com>
1 parent c898f9d commit 7d77d20

1 file changed

Lines changed: 60 additions & 1 deletion

File tree

pipelines/azure/azure_ai_foundry.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
author_url: https://github.com/owndev/
55
project_url: https://github.com/owndev/Open-WebUI-Functions
66
funding_url: https://github.com/sponsors/owndev
7-
version: 2.6.1
7+
version: 2.7.0
88
license: Apache License 2.0
99
description: A pipeline for interacting with Azure AI services, enabling seamless communication with various AI models via configurable headers and robust error handling. This includes support for Azure OpenAI models as well as other Azure AI models by dynamically managing headers and request configurations. Azure AI Search (RAG) integration is only supported with Azure OpenAI endpoints.
1010
features:
@@ -18,6 +18,7 @@
1818
- Azure AI Search / RAG integration with native OpenWebUI citations (Azure OpenAI only)
1919
- Automatic [docX] to markdown link conversion for clickable citations
2020
- Relevance scores from Azure AI Search displayed in citation cards
21+
- Automatic max_tokens to max_completion_tokens conversion for GPT-5+ and o-series models
2122
"""
2223

2324
from typing import (
@@ -1484,6 +1485,42 @@ def _extract_referenced_citations(self, content: str) -> Set[int]:
14841485
# Convert to integers and return as a set
14851486
return {int(match) for match in matches}
14861487

1488+
def _is_new_generation_model(self, model_name: str) -> bool:
1489+
"""
1490+
Determine if a model requires max_completion_tokens instead of max_tokens.
1491+
1492+
GPT-5, o-series (o1, o3, o4), and reasoning models use max_completion_tokens
1493+
to distinguish between internal reasoning tokens and output completion tokens.
1494+
1495+
Args:
1496+
model_name: The model identifier (e.g., "gpt-5", "o1", "gpt-4")
1497+
1498+
Returns:
1499+
True if the model requires max_completion_tokens, False otherwise
1500+
"""
1501+
if not model_name:
1502+
return False
1503+
1504+
model_lower = model_name.lower()
1505+
1506+
# GPT-5 series models
1507+
if model_lower.startswith("gpt-5") or model_lower.startswith("gpt‑5"):
1508+
return True
1509+
1510+
# o-series reasoning models (o1, o3, o4, etc.)
1511+
if model_lower.startswith("o1") or model_lower.startswith("o3") or model_lower.startswith("o4"):
1512+
return True
1513+
1514+
# GPT-4.5 preview and newer
1515+
if "gpt-4.5" in model_lower:
1516+
return True
1517+
1518+
# Model router and other reasoning models
1519+
if "reasoning" in model_lower or model_lower == "model-router":
1520+
return True
1521+
1522+
return False
1523+
14871524
async def stream_processor(
14881525
self,
14891526
content: aiohttp.StreamReader,
@@ -1579,6 +1616,7 @@ async def pipe(
15791616
"deployment",
15801617
"frequency_penalty",
15811618
"max_tokens",
1619+
"max_completion_tokens",
15821620
"max_citations",
15831621
"presence_penalty",
15841622
"reasoning_effort",
@@ -1594,6 +1632,27 @@ async def pipe(
15941632
}
15951633
filtered_body = {k: v for k, v in body.items() if k in allowed_params}
15961634

1635+
# Determine the actual model name that will be used for the request
1636+
effective_model = selected_model
1637+
if not effective_model and self.valves.AZURE_AI_MODEL:
1638+
models = self.parse_models(self.valves.AZURE_AI_MODEL)
1639+
if models and len(models) > 0:
1640+
effective_model = models[0]
1641+
else:
1642+
effective_model = self.valves.AZURE_AI_MODEL
1643+
# Also consider model name extracted from URL
1644+
if not effective_model:
1645+
effective_model = self._extracted_model_name
1646+
1647+
# Convert max_tokens to max_completion_tokens for new generation models (GPT-5, o-series, etc.)
1648+
if effective_model and self._is_new_generation_model(effective_model):
1649+
if "max_tokens" in filtered_body and "max_completion_tokens" not in filtered_body:
1650+
# New models require max_completion_tokens instead of max_tokens
1651+
filtered_body["max_completion_tokens"] = filtered_body.pop("max_tokens")
1652+
log.debug(
1653+
f"Converted max_tokens to max_completion_tokens for model '{effective_model}'"
1654+
)
1655+
15971656
if self.valves.AZURE_AI_MODEL and self.valves.AZURE_AI_MODEL_IN_BODY:
15981657
# If a model was explicitly selected in the request, use that
15991658
if selected_model:

0 commit comments

Comments
 (0)