refactor(types): name the LLMContext/OpenAI boundary with explicit cast helpers
LLMContext's NotGiven, LLMContextToolChoice, and LLMStandardMessage are currently aliased to their OpenAI equivalents, so passing values between the two sides type-checks implicitly. That works today but obscures the fact that these are meant to be conceptually distinct — if LLMContext ever diverges from OpenAI's types, every implicit crossing would silently break. Introduce two module-private cast helpers in open_ai_adapter.py: - _openai_from_llm_context_tool_choice(tool_choice) - _openai_from_llm_standard_message(message) Both are typed no-ops today (implemented with typing.cast) but each carries a docstring explaining why the cast is present, and every boundary crossing now routes through a named function. Future readers (and future greps) can find the crossings; a later divergence becomes a mechanical find-and-update rather than hunting through adapter code. No behavior change, no pyright error delta.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
"""OpenAI LLM adapter for Pipecat."""
|
||||
|
||||
from typing import Any, TypedDict, TypeGuard, TypeVar
|
||||
from typing import Any, TypedDict, TypeGuard, TypeVar, cast
|
||||
|
||||
from openai._types import NotGiven as OpenAINotGiven
|
||||
from openai.types.chat import (
|
||||
@@ -22,12 +22,39 @@ from pipecat.processors.aggregators.llm_context import (
|
||||
LLMContextMessage,
|
||||
LLMContextToolChoice,
|
||||
LLMSpecificMessage,
|
||||
LLMStandardMessage,
|
||||
NotGiven,
|
||||
)
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
def _openai_from_llm_context_tool_choice(
|
||||
tool_choice: LLMContextToolChoice | NotGiven,
|
||||
) -> ChatCompletionToolChoiceOptionParam | OpenAINotGiven:
|
||||
"""Reinterpret an LLMContext ``tool_choice`` as OpenAI's type.
|
||||
|
||||
The underlying types are currently aliased — ``LLMContextToolChoice`` is
|
||||
``ChatCompletionToolChoiceOptionParam`` and LLMContext's ``NotGiven`` is
|
||||
OpenAI's — so this is a typed no-op today. It's kept as a named boundary
|
||||
so that if the LLMContext side ever diverges from OpenAI's types, every
|
||||
crossing is visible and easy to update.
|
||||
"""
|
||||
return cast("ChatCompletionToolChoiceOptionParam | OpenAINotGiven", tool_choice)
|
||||
|
||||
|
||||
def _openai_from_llm_standard_message(
|
||||
message: LLMStandardMessage,
|
||||
) -> ChatCompletionMessageParam:
|
||||
"""Reinterpret an LLMContext standard message as OpenAI's type.
|
||||
|
||||
Same rationale as :func:`_openai_from_llm_context_tool_choice`: the
|
||||
aliased types make this a no-op today, but the boundary is preserved
|
||||
for future divergence.
|
||||
"""
|
||||
return cast("ChatCompletionMessageParam", message)
|
||||
|
||||
|
||||
def is_given(value: _T | OpenAINotGiven) -> TypeGuard[_T]:
|
||||
"""Check whether a value was explicitly provided.
|
||||
|
||||
@@ -117,7 +144,7 @@ class OpenAILLMAdapter(BaseLLMAdapter[OpenAILLMInvocationParams]):
|
||||
"messages": messages,
|
||||
# NOTE; LLMContext's tools are guaranteed to be a ToolsSchema (or NOT_GIVEN)
|
||||
"tools": self.from_standard_tools(context.tools),
|
||||
"tool_choice": context.tool_choice,
|
||||
"tool_choice": _openai_from_llm_context_tool_choice(context.tool_choice),
|
||||
}
|
||||
|
||||
def to_provider_tools_format(self, tools_schema: ToolsSchema) -> list[ChatCompletionToolParam]:
|
||||
@@ -166,7 +193,7 @@ class OpenAILLMAdapter(BaseLLMAdapter[OpenAILLMInvocationParams]):
|
||||
result.append(message.message)
|
||||
else:
|
||||
# Standard message, pass through unchanged
|
||||
result.append(message)
|
||||
result.append(_openai_from_llm_standard_message(message))
|
||||
|
||||
if convert_developer_to_user:
|
||||
for msg in result:
|
||||
@@ -178,5 +205,4 @@ class OpenAILLMAdapter(BaseLLMAdapter[OpenAILLMInvocationParams]):
|
||||
def _from_standard_tool_choice(
|
||||
self, tool_choice: LLMContextToolChoice | NotGiven
|
||||
) -> ChatCompletionToolChoiceOptionParam | OpenAINotGiven:
|
||||
# Just a pass-through: tool_choice is already the right type
|
||||
return tool_choice
|
||||
return _openai_from_llm_context_tool_choice(tool_choice)
|
||||
|
||||
Reference in New Issue
Block a user