From 66f43baf8f938e439e9b9c6de694f6b27c574438 Mon Sep 17 00:00:00 2001 From: Paul Kompfner Date: Mon, 27 Apr 2026 15:31:42 -0400 Subject: [PATCH] fix: resolve pyright errors in Anthropic _from_standard_message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function takes an OpenAI ChatCompletionMessageParam (a union of TypedDicts) and returns an Anthropic MessageParam (a different TypedDict). It does the conversion via dict-level mutations that don't type-check against either side's TypedDict schema. Work with the deepcopied message as a plain dict and cast to MessageParam at the return sites — matching the boundary-cast convention noted in llm_context.py. Drops anthropic_adapter.py from 20 to 2 pyright errors. --- .../adapters/services/anthropic_adapter.py | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/pipecat/adapters/services/anthropic_adapter.py b/src/pipecat/adapters/services/anthropic_adapter.py index cbe870d81..1632662e5 100644 --- a/src/pipecat/adapters/services/anthropic_adapter.py +++ b/src/pipecat/adapters/services/anthropic_adapter.py @@ -289,20 +289,26 @@ class AnthropicLLMAdapter(BaseLLMAdapter[AnthropicLLMInvocationParams]): ] } """ - message = copy.deepcopy(message) - if message["role"] == "tool": - return { - "role": "user", - "content": [ - { - "type": "tool_result", - "tool_use_id": message["tool_call_id"], - "content": message["content"], - }, - ], - } - if message.get("tool_calls"): - tc = message["tool_calls"] + # ChatCompletionMessageParam (input) and MessageParam (output) are + # different TypedDicts — work with the message as a plain dict for the + # transformations below and cast back to MessageParam at return sites. + msg = cast(dict[str, Any], copy.deepcopy(message)) + if msg["role"] == "tool": + return cast( + MessageParam, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": msg["tool_call_id"], + "content": msg["content"], + }, + ], + }, + ) + if msg.get("tool_calls"): + tc = msg["tool_calls"] ret = {"role": "assistant", "content": []} for tool_call in tc: function = tool_call["function"] @@ -314,8 +320,8 @@ class AnthropicLLMAdapter(BaseLLMAdapter[AnthropicLLMInvocationParams]): "input": arguments, } ret["content"].append(new_tool_use) - return ret - content = message.get("content") + return cast(MessageParam, ret) + content = msg.get("content") if isinstance(content, str): # fix empty text if content == "": @@ -363,7 +369,7 @@ class AnthropicLLMAdapter(BaseLLMAdapter[AnthropicLLMInvocationParams]): image_item = content.pop(img_idx) content.insert(first_txt_idx, image_item) - return message + return cast(MessageParam, msg) def _with_cache_control_markers(self, messages: list[MessageParam]) -> list[MessageParam]: """Add cache control markers to messages for prompt caching.