From e553bb010f223dfae47f99eec196e22ed0abaca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Fri, 10 Apr 2026 17:37:49 -0700 Subject: [PATCH] tests: migrate LLM tests to Settings-based constructor API Replace the old `model=` / `params=InputParams(...)` style with the new `settings=.Settings(...)` form across LLM service tests. --- tests/test_novita_llm.py | 4 +- tests/test_openai_llm_timeout.py | 10 ++-- tests/test_run_inference.py | 79 +++++++++++++++++++++++--------- tests/test_sambanova_llm.py | 4 +- 4 files changed, 68 insertions(+), 29 deletions(-) diff --git a/tests/test_novita_llm.py b/tests/test_novita_llm.py index 9aab54cab..aacb8c25c 100644 --- a/tests/test_novita_llm.py +++ b/tests/test_novita_llm.py @@ -22,7 +22,9 @@ async def test_novita_llm_stream_closed_on_cancellation(): This prevents socket leaks when the pipeline is interrupted (e.g., user interruption). """ with patch.object(NovitaLLMService, "create_client"): - service = NovitaLLMService(api_key="test-key", model="test-model") + service = NovitaLLMService( + api_key="test-key", settings=NovitaLLMService.Settings(model="test-model") + ) service._client = AsyncMock() stream_closed = False diff --git a/tests/test_openai_llm_timeout.py b/tests/test_openai_llm_timeout.py index 61264cbf5..b077146da 100644 --- a/tests/test_openai_llm_timeout.py +++ b/tests/test_openai_llm_timeout.py @@ -29,7 +29,7 @@ async def test_openai_llm_emits_error_frame_on_timeout(): primary LLM times out. """ with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() # Track pushed frames and errors @@ -96,7 +96,7 @@ async def test_openai_llm_timeout_still_pushes_end_frame(): The finally block should ensure proper cleanup regardless of timeout. """ with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() pushed_frames = [] @@ -137,7 +137,7 @@ async def test_openai_llm_stream_closed_on_cancellation(): import asyncio with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() # Track if close was called @@ -195,7 +195,7 @@ async def test_openai_llm_emits_error_frame_on_exception(): This enables proper error handling for API errors, rate limits, and other failures. """ with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() pushed_errors = [] @@ -233,7 +233,7 @@ async def test_openai_llm_async_iterator_closed_on_stream_end(): See MagicStack/uvloop#699. """ with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() # Track if the iterator's aclose was called diff --git a/tests/test_run_inference.py b/tests/test_run_inference.py index e182fba18..755560ec9 100644 --- a/tests/test_run_inference.py +++ b/tests/test_run_inference.py @@ -30,12 +30,15 @@ async def test_openai_run_inference_with_llm_context(): """Test run_inference with LLMContext returns expected response.""" # Create service with mocked client and specific parameters with patch.object(OpenAILLMService, "create_client"): - from pipecat.services.openai.base_llm import BaseOpenAILLMService - - params = BaseOpenAILLMService.InputParams( - temperature=0.7, max_tokens=100, frequency_penalty=0.5, seed=42 + service = OpenAILLMService( + settings=OpenAILLMService.Settings( + model="gpt-4", + temperature=0.7, + max_tokens=100, + frequency_penalty=0.5, + seed=42, + ) ) - service = OpenAILLMService(model="gpt-4", params=params) service._client = AsyncMock() # Setup mocks @@ -87,7 +90,7 @@ async def test_openai_run_inference_with_llm_context(): async def test_openai_run_inference_client_exception(): """Test that exceptions from the client are propagated.""" with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -108,9 +111,15 @@ async def test_anthropic_run_inference_with_llm_context(): # Create service with mocked client and specific parameters from pipecat.services.anthropic.llm import AnthropicLLMService - params = AnthropicLLMService.InputParams(max_tokens=2048, temperature=0.6, top_k=50, top_p=0.95) service = AnthropicLLMService( - api_key="test-key", model="claude-3-sonnet-20240229", params=params + api_key="test-key", + settings=AnthropicLLMService.Settings( + model="claude-3-sonnet-20240229", + max_tokens=2048, + temperature=0.6, + top_k=50, + top_p=0.95, + ), ) service._client = AsyncMock() @@ -156,7 +165,9 @@ async def test_anthropic_run_inference_with_llm_context(): @pytest.mark.asyncio async def test_anthropic_run_inference_client_exception(): """Test that exceptions from the Anthropic client are propagated.""" - service = AnthropicLLMService(api_key="test-key", model="claude-3-sonnet-20240229") + service = AnthropicLLMService( + api_key="test-key", settings=AnthropicLLMService.Settings(model="claude-3-sonnet-20240229") + ) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -175,7 +186,9 @@ async def test_anthropic_run_inference_client_exception(): async def test_google_run_inference_with_llm_context(): """Test run_inference with LLMContext returns expected response for Google.""" # Create service with mocked client - service = GoogleLLMService(api_key="test-key", model="gemini-2.0-flash") + service = GoogleLLMService( + api_key="test-key", settings=GoogleLLMService.Settings(model="gemini-2.0-flash") + ) service._client = AsyncMock() # Setup mocks @@ -213,7 +226,9 @@ async def test_google_run_inference_with_llm_context(): @pytest.mark.asyncio async def test_google_run_inference_client_exception(): """Test that exceptions from the Google client are propagated.""" - service = GoogleLLMService(api_key="test-key", model="gemini-2.0-flash") + service = GoogleLLMService( + api_key="test-key", settings=GoogleLLMService.Settings(model="gemini-2.0-flash") + ) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -238,8 +253,14 @@ async def test_aws_bedrock_run_inference_with_llm_context(): # Create service with specific parameters from pipecat.services.aws.llm import AWSBedrockLLMService - params = AWSBedrockLLMService.InputParams(max_tokens=1024, temperature=0.5, top_p=0.85) - service = AWSBedrockLLMService(model="anthropic.claude-3-sonnet-20240229-v1:0", params=params) + service = AWSBedrockLLMService( + settings=AWSBedrockLLMService.Settings( + model="anthropic.claude-3-sonnet-20240229-v1:0", + max_tokens=1024, + temperature=0.5, + top_p=0.85, + ) + ) # Setup mocks mock_context = MagicMock(spec=LLMContext) @@ -289,7 +310,9 @@ async def test_aws_bedrock_run_inference_with_llm_context(): @pytest.mark.asyncio async def test_aws_bedrock_run_inference_client_exception(): """Test that exceptions from the AWS Bedrock client are propagated.""" - service = AWSBedrockLLMService(model="anthropic.claude-3-sonnet-20240229-v1:0") + service = AWSBedrockLLMService( + settings=AWSBedrockLLMService.Settings(model="anthropic.claude-3-sonnet-20240229-v1:0") + ) mock_context = MagicMock(spec=LLMContext) mock_adapter = MagicMock() @@ -319,7 +342,7 @@ async def test_aws_bedrock_run_inference_client_exception(): async def test_openai_run_inference_system_instruction_overrides_context(): """Test that system_instruction overrides the system message from context.""" with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -356,7 +379,7 @@ async def test_openai_run_inference_system_instruction_overrides_context(): async def test_openai_run_inference_system_instruction_none_unchanged(): """Test that when system_instruction is None, behavior is unchanged.""" with patch.object(OpenAILLMService, "create_client"): - service = OpenAILLMService(model="gpt-4") + service = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-4")) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -387,7 +410,9 @@ async def test_openai_run_inference_system_instruction_none_unchanged(): @pytest.mark.asyncio async def test_anthropic_run_inference_system_instruction_overrides_context(): """Test that system_instruction overrides the system message for Anthropic.""" - service = AnthropicLLMService(api_key="test-key", model="claude-3-sonnet-20240229") + service = AnthropicLLMService( + api_key="test-key", settings=AnthropicLLMService.Settings(model="claude-3-sonnet-20240229") + ) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -417,7 +442,9 @@ async def test_anthropic_run_inference_system_instruction_overrides_context(): @pytest.mark.asyncio async def test_anthropic_run_inference_system_instruction_none_unchanged(): """Test that when system_instruction is None, Anthropic behavior is unchanged.""" - service = AnthropicLLMService(api_key="test-key", model="claude-3-sonnet-20240229") + service = AnthropicLLMService( + api_key="test-key", settings=AnthropicLLMService.Settings(model="claude-3-sonnet-20240229") + ) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -443,7 +470,9 @@ async def test_anthropic_run_inference_system_instruction_none_unchanged(): @pytest.mark.asyncio async def test_google_run_inference_system_instruction_overrides_context(): """Test that system_instruction overrides the system message for Google.""" - service = GoogleLLMService(api_key="test-key", model="gemini-2.0-flash") + service = GoogleLLMService( + api_key="test-key", settings=GoogleLLMService.Settings(model="gemini-2.0-flash") + ) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -475,7 +504,9 @@ async def test_google_run_inference_system_instruction_overrides_context(): @pytest.mark.asyncio async def test_google_run_inference_system_instruction_none_unchanged(): """Test that when system_instruction is None, Google behavior is unchanged.""" - service = GoogleLLMService(api_key="test-key", model="gemini-2.0-flash") + service = GoogleLLMService( + api_key="test-key", settings=GoogleLLMService.Settings(model="gemini-2.0-flash") + ) service._client = AsyncMock() mock_context = MagicMock(spec=LLMContext) @@ -506,7 +537,9 @@ async def test_google_run_inference_system_instruction_none_unchanged(): @pytest.mark.asyncio async def test_aws_bedrock_run_inference_system_instruction_overrides_context(): """Test that system_instruction overrides the system message for AWS Bedrock.""" - service = AWSBedrockLLMService(model="anthropic.claude-3-sonnet-20240229-v1:0") + service = AWSBedrockLLMService( + settings=AWSBedrockLLMService.Settings(model="anthropic.claude-3-sonnet-20240229-v1:0") + ) mock_context = MagicMock(spec=LLMContext) mock_adapter = MagicMock() @@ -542,7 +575,9 @@ async def test_aws_bedrock_run_inference_system_instruction_overrides_context(): @pytest.mark.asyncio async def test_aws_bedrock_run_inference_system_instruction_none_unchanged(): """Test that when system_instruction is None, AWS Bedrock behavior is unchanged.""" - service = AWSBedrockLLMService(model="anthropic.claude-3-sonnet-20240229-v1:0") + service = AWSBedrockLLMService( + settings=AWSBedrockLLMService.Settings(model="anthropic.claude-3-sonnet-20240229-v1:0") + ) mock_context = MagicMock(spec=LLMContext) mock_adapter = MagicMock() diff --git a/tests/test_sambanova_llm.py b/tests/test_sambanova_llm.py index 57e2e8c50..d74d96583 100644 --- a/tests/test_sambanova_llm.py +++ b/tests/test_sambanova_llm.py @@ -23,7 +23,9 @@ async def test_sambanova_llm_stream_closed_on_cancellation(): See issue #3639. """ with patch.object(SambaNovaLLMService, "create_client"): - service = SambaNovaLLMService(api_key="test-key", model="test-model") + service = SambaNovaLLMService( + api_key="test-key", settings=SambaNovaLLMService.Settings(model="test-model") + ) service._client = AsyncMock() stream_closed = False