test, refactor: follow-ups to LLMService generic refactor
Two follow-ups now that LLMService is generic over its adapter: - Add an explicit backward-compat test verifying that an LLMService subclass with no generic parameter (the third-party-provider pattern) instantiates and returns a usable adapter. The existing MockLLMService (declared without brackets) already exercised this implicitly, but it's worth a named assertion. - Drop the now-redundant `params: SomeLLMInvocationParams = ...` variable annotations on `adapter.get_llm_invocation_params()` results. Since `get_llm_adapter()` now returns the precise adapter type, and `BaseLLMAdapter` is generic in its invocation-params type, the call already infers the right TypedDict.
This commit is contained in:
@@ -329,7 +329,7 @@ class AnthropicLLMService(LLMService[AnthropicLLMAdapter]):
|
||||
|
||||
def _get_llm_invocation_params(self, context: LLMContext) -> AnthropicLLMInvocationParams:
|
||||
adapter = self.get_llm_adapter()
|
||||
params: AnthropicLLMInvocationParams = adapter.get_llm_invocation_params(
|
||||
params = adapter.get_llm_invocation_params(
|
||||
context,
|
||||
enable_prompt_caching=assert_given(self._settings.enable_prompt_caching),
|
||||
system_instruction=assert_given(self._settings.system_instruction),
|
||||
|
||||
@@ -283,7 +283,7 @@ class AWSBedrockLLMService(LLMService[AWSBedrockLLMAdapter]):
|
||||
self._settings.system_instruction
|
||||
)
|
||||
adapter = self.get_llm_adapter()
|
||||
params: AWSBedrockLLMInvocationParams = adapter.get_llm_invocation_params(
|
||||
params = adapter.get_llm_invocation_params(
|
||||
context, system_instruction=effective_instruction
|
||||
)
|
||||
messages = params["messages"]
|
||||
@@ -372,7 +372,7 @@ class AWSBedrockLLMService(LLMService[AWSBedrockLLMAdapter]):
|
||||
|
||||
def _get_llm_invocation_params(self, context: LLMContext) -> AWSBedrockLLMInvocationParams:
|
||||
adapter = self.get_llm_adapter()
|
||||
params: AWSBedrockLLMInvocationParams = adapter.get_llm_invocation_params(
|
||||
params = adapter.get_llm_invocation_params(
|
||||
context, system_instruction=assert_given(self._settings.system_instruction)
|
||||
)
|
||||
return params
|
||||
|
||||
@@ -21,7 +21,7 @@ from loguru import logger
|
||||
from PIL import Image
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from pipecat.adapters.services.gemini_adapter import GeminiLLMAdapter, GeminiLLMInvocationParams
|
||||
from pipecat.adapters.services.gemini_adapter import GeminiLLMAdapter
|
||||
from pipecat.frames.frames import (
|
||||
AssistantImageRawFrame,
|
||||
Frame,
|
||||
@@ -292,7 +292,7 @@ class GoogleLLMService(LLMService[GeminiLLMAdapter]):
|
||||
tools = []
|
||||
effective_instruction = system_instruction or self._settings.system_instruction
|
||||
adapter = self.get_llm_adapter()
|
||||
params: GeminiLLMInvocationParams = adapter.get_llm_invocation_params(
|
||||
params = adapter.get_llm_invocation_params(
|
||||
context, system_instruction=effective_instruction
|
||||
)
|
||||
messages = params["messages"]
|
||||
@@ -387,7 +387,7 @@ class GoogleLLMService(LLMService[GeminiLLMAdapter]):
|
||||
|
||||
async def _stream_content(self, context: LLMContext) -> AsyncIterator[GenerateContentResponse]:
|
||||
adapter = self.get_llm_adapter()
|
||||
params: GeminiLLMInvocationParams = adapter.get_llm_invocation_params(
|
||||
params = adapter.get_llm_invocation_params(
|
||||
context, system_instruction=assert_given(self._settings.system_instruction)
|
||||
)
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ class BaseOpenAILLMService(LLMService[OpenAILLMAdapter]):
|
||||
f"{self}: Generating chat from context {adapter.get_messages_for_logging(context)}"
|
||||
)
|
||||
|
||||
params_from_context: OpenAILLMInvocationParams = adapter.get_llm_invocation_params(
|
||||
params_from_context = adapter.get_llm_invocation_params(
|
||||
context,
|
||||
system_instruction=self._settings.system_instruction,
|
||||
convert_developer_to_user=not self.supports_developer_role,
|
||||
@@ -374,7 +374,7 @@ class BaseOpenAILLMService(LLMService[OpenAILLMAdapter]):
|
||||
"""
|
||||
effective_instruction = system_instruction or self._settings.system_instruction
|
||||
adapter = self.get_llm_adapter()
|
||||
invocation_params: OpenAILLMInvocationParams = adapter.get_llm_invocation_params(
|
||||
invocation_params = adapter.get_llm_invocation_params(
|
||||
context,
|
||||
system_instruction=effective_instruction,
|
||||
convert_developer_to_user=not self.supports_developer_role,
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
import unittest
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from pipecat.adapters.base_llm_adapter import BaseLLMAdapter
|
||||
from pipecat.adapters.services.open_ai_adapter import OpenAILLMAdapter
|
||||
from pipecat.frames.frames import (
|
||||
FunctionCallFromLLM,
|
||||
FunctionCallInProgressFrame,
|
||||
@@ -39,6 +41,25 @@ class MockLLMService(LLMService):
|
||||
super().__init__(settings=settings, **kwargs)
|
||||
|
||||
|
||||
class TestUnparameterizedSubclass(unittest.TestCase):
|
||||
"""Backward-compat coverage: third-party providers subclass LLMService
|
||||
without specifying a generic adapter parameter. That should keep working
|
||||
after LLMService became `Generic[TAdapter]`.
|
||||
"""
|
||||
|
||||
def test_unparameterized_subclass_instantiates(self):
|
||||
# MockLLMService is declared as `class MockLLMService(LLMService):`
|
||||
# — no generic bracket. The TypeVar's `bound=BaseLLMAdapter` should
|
||||
# resolve TAdapter to BaseLLMAdapter for callers that don't opt in.
|
||||
service = MockLLMService()
|
||||
adapter = service.get_llm_adapter()
|
||||
|
||||
# Default adapter_class is OpenAILLMAdapter; the runtime instance
|
||||
# should reflect that, regardless of how generics are erased.
|
||||
self.assertIsInstance(adapter, OpenAILLMAdapter)
|
||||
self.assertIsInstance(adapter, BaseLLMAdapter)
|
||||
|
||||
|
||||
class TestLLMService(unittest.IsolatedAsyncioTestCase):
|
||||
async def _run_function_calls_inline(self, service: MockLLMService):
|
||||
async def run_inline(runner_items):
|
||||
|
||||
Reference in New Issue
Block a user