diff --git a/src/fastmcp/client/sampling/handlers/openai.py b/src/fastmcp/client/sampling/handlers/openai.py index 3ddcadaca..362e05905 100644 --- a/src/fastmcp/client/sampling/handlers/openai.py +++ b/src/fastmcp/client/sampling/handlers/openai.py @@ -84,7 +84,7 @@ class OpenAISamplingHandler: kwargs: dict[str, Any] = { "model": model, "messages": openai_messages, - "max_tokens": params.maxTokens, + "max_completion_tokens": params.maxTokens, } if params.temperature is not None: kwargs["temperature"] = params.temperature diff --git a/tests/client/sampling/handlers/test_openai_handler.py b/tests/client/sampling/handlers/test_openai_handler.py index d5b263a81..29f12d749 100644 --- a/tests/client/sampling/handlers/test_openai_handler.py +++ b/tests/client/sampling/handlers/test_openai_handler.py @@ -1,7 +1,8 @@ -from unittest.mock import MagicMock +from unittest.mock import AsyncMock, MagicMock import pytest from mcp.types import ( + CreateMessageRequestParams, CreateMessageResult, ModelHint, ModelPreferences, @@ -72,6 +73,39 @@ def test_select_model_from_preferences(prefs, expected): assert handler._select_model_from_preferences(prefs) == expected +async def test_handler_passes_max_completion_tokens(): + """Verify the handler uses max_completion_tokens (not max_tokens).""" + mock_client = MagicMock(spec=AsyncOpenAI) + mock_client.chat = MagicMock() + mock_client.chat.completions = MagicMock() + mock_client.chat.completions.create = AsyncMock( + return_value=ChatCompletion( + id="123", + created=123, + model="gpt-4o-mini", + object="chat.completion", + choices=[ + Choice( + message=ChatCompletionMessage(content="hi", role="assistant"), + finish_reason="stop", + index=0, + ) + ], + ) + ) + handler = OpenAISamplingHandler(default_model="gpt-4o-mini", client=mock_client) + messages = [ + SamplingMessage(role="user", content=TextContent(type="text", text="hello")) + ] + params = CreateMessageRequestParams(messages=messages, maxTokens=300) + await handler(messages, params, context=None) # type: ignore[arg-type] + + call_kwargs = mock_client.chat.completions.create.call_args + assert "max_completion_tokens" in call_kwargs.kwargs + assert call_kwargs.kwargs["max_completion_tokens"] == 300 + assert "max_tokens" not in call_kwargs.kwargs + + async def test_chat_completion_to_create_message_result(): mock_client = MagicMock(spec=AsyncOpenAI) handler = OpenAISamplingHandler(default_model="fallback-model", client=mock_client) # type: ignore[arg-type]