linting fixes to anthropic.py
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
WARNING: --strip-extras is becoming the default in version 8.0.0. To silence this warning, either use --strip-extras to opt into the new default or use --no-strip-extras to retain the existing behavior.
|
|
||||||
#
|
#
|
||||||
# This file is autogenerated by pip-compile with Python 3.11
|
# This file is autogenerated by pip-compile with Python 3.10
|
||||||
# by the following command:
|
# by the following command:
|
||||||
#
|
#
|
||||||
# pip-compile --all-extras pyproject.toml
|
# pip-compile --all-extras pyproject.toml
|
||||||
@@ -13,7 +12,6 @@ aiohttp==3.9.5
|
|||||||
# langchain
|
# langchain
|
||||||
# langchain-community
|
# langchain-community
|
||||||
# pipecat-ai (pyproject.toml)
|
# pipecat-ai (pyproject.toml)
|
||||||
# together
|
|
||||||
aiosignal==1.3.1
|
aiosignal==1.3.1
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
annotated-types==0.7.0
|
annotated-types==0.7.0
|
||||||
@@ -29,6 +27,10 @@ anyio==4.4.0
|
|||||||
# openai
|
# openai
|
||||||
# starlette
|
# starlette
|
||||||
# watchfiles
|
# watchfiles
|
||||||
|
async-timeout==4.0.3
|
||||||
|
# via
|
||||||
|
# aiohttp
|
||||||
|
# langchain
|
||||||
attrs==23.2.0
|
attrs==23.2.0
|
||||||
# via
|
# via
|
||||||
# aiohttp
|
# aiohttp
|
||||||
@@ -51,7 +53,6 @@ charset-normalizer==3.3.2
|
|||||||
click==8.1.7
|
click==8.1.7
|
||||||
# via
|
# via
|
||||||
# flask
|
# flask
|
||||||
# together
|
|
||||||
# typer
|
# typer
|
||||||
# uvicorn
|
# uvicorn
|
||||||
coloredlogs==15.0.1
|
coloredlogs==15.0.1
|
||||||
@@ -76,8 +77,8 @@ einops==0.8.0
|
|||||||
# via pipecat-ai (pyproject.toml)
|
# via pipecat-ai (pyproject.toml)
|
||||||
email-validator==2.2.0
|
email-validator==2.2.0
|
||||||
# via fastapi
|
# via fastapi
|
||||||
eval-type-backport==0.2.0
|
exceptiongroup==1.2.2
|
||||||
# via together
|
# via anyio
|
||||||
fal-client==0.4.1
|
fal-client==0.4.1
|
||||||
# via pipecat-ai (pyproject.toml)
|
# via pipecat-ai (pyproject.toml)
|
||||||
fastapi==0.111.1
|
fastapi==0.111.1
|
||||||
@@ -90,7 +91,6 @@ filelock==3.15.4
|
|||||||
# via
|
# via
|
||||||
# huggingface-hub
|
# huggingface-hub
|
||||||
# pyht
|
# pyht
|
||||||
# together
|
|
||||||
# torch
|
# torch
|
||||||
# transformers
|
# transformers
|
||||||
flask==3.0.3
|
flask==3.0.3
|
||||||
@@ -192,13 +192,13 @@ jsonpatch==1.33
|
|||||||
# via langchain-core
|
# via langchain-core
|
||||||
jsonpointer==3.0.0
|
jsonpointer==3.0.0
|
||||||
# via jsonpatch
|
# via jsonpatch
|
||||||
langchain==0.2.13
|
langchain==0.2.12
|
||||||
# via
|
# via
|
||||||
# langchain-community
|
# langchain-community
|
||||||
# pipecat-ai (pyproject.toml)
|
# pipecat-ai (pyproject.toml)
|
||||||
langchain-community==0.2.12
|
langchain-community==0.2.11
|
||||||
# via pipecat-ai (pyproject.toml)
|
# via pipecat-ai (pyproject.toml)
|
||||||
langchain-core==0.2.30
|
langchain-core==0.2.29
|
||||||
# via
|
# via
|
||||||
# langchain
|
# langchain
|
||||||
# langchain-community
|
# langchain-community
|
||||||
@@ -208,7 +208,7 @@ langchain-openai==0.1.20
|
|||||||
# via pipecat-ai (pyproject.toml)
|
# via pipecat-ai (pyproject.toml)
|
||||||
langchain-text-splitters==0.2.2
|
langchain-text-splitters==0.2.2
|
||||||
# via langchain
|
# via langchain
|
||||||
langsmith==0.1.99
|
langsmith==0.1.98
|
||||||
# via
|
# via
|
||||||
# langchain
|
# langchain
|
||||||
# langchain-community
|
# langchain-community
|
||||||
@@ -247,11 +247,9 @@ numpy==1.26.4
|
|||||||
# numba
|
# numba
|
||||||
# onnxruntime
|
# onnxruntime
|
||||||
# pipecat-ai (pyproject.toml)
|
# pipecat-ai (pyproject.toml)
|
||||||
# pyarrow
|
|
||||||
# pyloudnorm
|
# pyloudnorm
|
||||||
# resampy
|
# resampy
|
||||||
# scipy
|
# scipy
|
||||||
# together
|
|
||||||
# torchvision
|
# torchvision
|
||||||
# transformers
|
# transformers
|
||||||
onnxruntime==1.18.1
|
onnxruntime==1.18.1
|
||||||
@@ -277,7 +275,6 @@ packaging==24.1
|
|||||||
pillow==10.3.0
|
pillow==10.3.0
|
||||||
# via
|
# via
|
||||||
# pipecat-ai (pyproject.toml)
|
# pipecat-ai (pyproject.toml)
|
||||||
# together
|
|
||||||
# torchvision
|
# torchvision
|
||||||
proto-plus==1.24.0
|
proto-plus==1.24.0
|
||||||
# via
|
# via
|
||||||
@@ -294,8 +291,6 @@ protobuf==4.25.4
|
|||||||
# pipecat-ai (pyproject.toml)
|
# pipecat-ai (pyproject.toml)
|
||||||
# proto-plus
|
# proto-plus
|
||||||
# pyht
|
# pyht
|
||||||
pyarrow==17.0.0
|
|
||||||
# via together
|
|
||||||
pyasn1==0.6.0
|
pyasn1==0.6.0
|
||||||
# via
|
# via
|
||||||
# pyasn1-modules
|
# pyasn1-modules
|
||||||
@@ -313,7 +308,6 @@ pydantic==2.8.2
|
|||||||
# langchain-core
|
# langchain-core
|
||||||
# langsmith
|
# langsmith
|
||||||
# openai
|
# openai
|
||||||
# together
|
|
||||||
pydantic-core==2.20.1
|
pydantic-core==2.20.1
|
||||||
# via pydantic
|
# via pydantic
|
||||||
pygments==2.18.0
|
pygments==2.18.0
|
||||||
@@ -355,7 +349,6 @@ requests==2.32.3
|
|||||||
# langsmith
|
# langsmith
|
||||||
# pyht
|
# pyht
|
||||||
# tiktoken
|
# tiktoken
|
||||||
# together
|
|
||||||
# transformers
|
# transformers
|
||||||
resampy==0.4.3
|
resampy==0.4.3
|
||||||
# via pipecat-ai (pyproject.toml)
|
# via pipecat-ai (pyproject.toml)
|
||||||
@@ -387,12 +380,10 @@ sqlalchemy==2.0.32
|
|||||||
# langchain-community
|
# langchain-community
|
||||||
starlette==0.37.2
|
starlette==0.37.2
|
||||||
# via fastapi
|
# via fastapi
|
||||||
sympy==1.13.2
|
sympy==1.13.1
|
||||||
# via
|
# via
|
||||||
# onnxruntime
|
# onnxruntime
|
||||||
# torch
|
# torch
|
||||||
tabulate==0.9.0
|
|
||||||
# via together
|
|
||||||
tenacity==8.5.0
|
tenacity==8.5.0
|
||||||
# via
|
# via
|
||||||
# langchain
|
# langchain
|
||||||
@@ -402,8 +393,6 @@ tiktoken==0.7.0
|
|||||||
# via langchain-openai
|
# via langchain-openai
|
||||||
timm==0.9.16
|
timm==0.9.16
|
||||||
# via pipecat-ai (pyproject.toml)
|
# via pipecat-ai (pyproject.toml)
|
||||||
together==1.2.7
|
|
||||||
# via pipecat-ai (pyproject.toml)
|
|
||||||
tokenizers==0.19.1
|
tokenizers==0.19.1
|
||||||
# via
|
# via
|
||||||
# anthropic
|
# anthropic
|
||||||
@@ -424,17 +413,15 @@ tqdm==4.66.5
|
|||||||
# google-generativeai
|
# google-generativeai
|
||||||
# huggingface-hub
|
# huggingface-hub
|
||||||
# openai
|
# openai
|
||||||
# together
|
|
||||||
# transformers
|
# transformers
|
||||||
transformers==4.40.2
|
transformers==4.40.2
|
||||||
# via pipecat-ai (pyproject.toml)
|
# via pipecat-ai (pyproject.toml)
|
||||||
typer==0.12.3
|
typer==0.12.3
|
||||||
# via
|
# via fastapi-cli
|
||||||
# fastapi-cli
|
|
||||||
# together
|
|
||||||
typing-extensions==4.12.2
|
typing-extensions==4.12.2
|
||||||
# via
|
# via
|
||||||
# anthropic
|
# anthropic
|
||||||
|
# anyio
|
||||||
# deepgram-sdk
|
# deepgram-sdk
|
||||||
# fastapi
|
# fastapi
|
||||||
# google-generativeai
|
# google-generativeai
|
||||||
@@ -448,13 +435,14 @@ typing-extensions==4.12.2
|
|||||||
# torch
|
# torch
|
||||||
# typer
|
# typer
|
||||||
# typing-inspect
|
# typing-inspect
|
||||||
|
# uvicorn
|
||||||
typing-inspect==0.9.0
|
typing-inspect==0.9.0
|
||||||
# via dataclasses-json
|
# via dataclasses-json
|
||||||
uritemplate==4.1.1
|
uritemplate==4.1.1
|
||||||
# via google-api-python-client
|
# via google-api-python-client
|
||||||
urllib3==2.2.2
|
urllib3==2.2.2
|
||||||
# via requests
|
# via requests
|
||||||
uvicorn[standard]==0.30.6
|
uvicorn[standard]==0.30.5
|
||||||
# via
|
# via
|
||||||
# fastapi
|
# fastapi
|
||||||
# fastapi-cli
|
# fastapi-cli
|
||||||
|
|||||||
@@ -30,8 +30,14 @@ from pipecat.frames.frames import (
|
|||||||
)
|
)
|
||||||
from pipecat.processors.frame_processor import FrameDirection
|
from pipecat.processors.frame_processor import FrameDirection
|
||||||
from pipecat.services.ai_services import LLMService
|
from pipecat.services.ai_services import LLMService
|
||||||
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext, OpenAILLMContextFrame
|
from pipecat.processors.aggregators.openai_llm_context import (
|
||||||
from pipecat.processors.aggregators.llm_response import LLMUserContextAggregator, LLMAssistantContextAggregator
|
OpenAILLMContext,
|
||||||
|
OpenAILLMContextFrame
|
||||||
|
)
|
||||||
|
from pipecat.processors.aggregators.llm_response import (
|
||||||
|
LLMUserContextAggregator,
|
||||||
|
LLMAssistantContextAggregator
|
||||||
|
)
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
@@ -40,7 +46,8 @@ try:
|
|||||||
except ModuleNotFoundError as e:
|
except ModuleNotFoundError as e:
|
||||||
logger.error(f"Exception: {e}")
|
logger.error(f"Exception: {e}")
|
||||||
logger.error(
|
logger.error(
|
||||||
"In order to use Anthropic, you need to `pip install pipecat-ai[anthropic]`. Also, set `ANTHROPIC_API_KEY` environment variable.")
|
"In order to use Anthropic, you need to `pip install pipecat-ai[anthropic]`. " +
|
||||||
|
"Also, set `ANTHROPIC_API_KEY` environment variable.")
|
||||||
raise Exception(f"Missing module: {e}")
|
raise Exception(f"Missing module: {e}")
|
||||||
|
|
||||||
|
|
||||||
@@ -81,7 +88,7 @@ class AnthropicLLMService(LLMService):
|
|||||||
def can_generate_metrics(self) -> bool:
|
def can_generate_metrics(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ staticmethod
|
@staticmethod
|
||||||
def create_context_aggregator(context: OpenAILLMContext) -> AnthropicContextAggregatorPair:
|
def create_context_aggregator(context: OpenAILLMContext) -> AnthropicContextAggregatorPair:
|
||||||
user = AnthropicUserContextAggregator(context)
|
user = AnthropicUserContextAggregator(context)
|
||||||
assistant = AnthropicAssistantContextAggregator(user)
|
assistant = AnthropicAssistantContextAggregator(user)
|
||||||
@@ -140,16 +147,17 @@ class AnthropicLLMService(LLMService):
|
|||||||
if event.content_block.type == "tool_use":
|
if event.content_block.type == "tool_use":
|
||||||
tool_use_block = event.content_block
|
tool_use_block = event.content_block
|
||||||
json_accumulator = ''
|
json_accumulator = ''
|
||||||
elif (event.type == "message_delta" and
|
elif ((event.type == "message_delta" and
|
||||||
hasattr(event.delta, 'stop_reason') and event.delta.stop_reason == 'tool_use'):
|
hasattr(event.delta, 'stop_reason')
|
||||||
|
and event.delta.stop_reason == 'tool_use')):
|
||||||
if tool_use_block:
|
if tool_use_block:
|
||||||
await self.call_function(context=context,
|
await self.call_function(context=context,
|
||||||
tool_call_id=tool_use_block.id,
|
tool_call_id=tool_use_block.id,
|
||||||
function_name=tool_use_block.name,
|
function_name=tool_use_block.name,
|
||||||
arguments=json.loads(json_accumulator))
|
arguments=json.loads(json_accumulator))
|
||||||
|
|
||||||
# Calculate usage. Do this here in its own if statement, because there may be usage data
|
# Calculate usage. Do this here in its own if statement, because there may be usage
|
||||||
# embedded in messages that we do other processing for, above.
|
# data embedded in messages that we do other processing for, above.
|
||||||
if hasattr(event, "usage"):
|
if hasattr(event, "usage"):
|
||||||
prompt_tokens += event.usage.input_tokens if hasattr(
|
prompt_tokens += event.usage.input_tokens if hasattr(
|
||||||
event.usage, "input_tokens") else 0
|
event.usage, "input_tokens") else 0
|
||||||
@@ -161,7 +169,7 @@ class AnthropicLLMService(LLMService):
|
|||||||
completion_tokens += event.message.usage.output_tokens if hasattr(
|
completion_tokens += event.message.usage.output_tokens if hasattr(
|
||||||
event.message.usage, "output_tokens") else 0
|
event.message.usage, "output_tokens") else 0
|
||||||
|
|
||||||
except CancelledError as e:
|
except CancelledError:
|
||||||
# If we're interrupted, we won't get a complete usage report. So set our flag to use the
|
# If we're interrupted, we won't get a complete usage report. So set our flag to use the
|
||||||
# token estimate. The reraise the exception so all the processors running in this task
|
# token estimate. The reraise the exception so all the processors running in this task
|
||||||
# also get cancelled.
|
# also get cancelled.
|
||||||
@@ -174,7 +182,8 @@ class AnthropicLLMService(LLMService):
|
|||||||
await self.push_frame(LLMFullResponseEndFrame())
|
await self.push_frame(LLMFullResponseEndFrame())
|
||||||
await self._report_usage_metrics(
|
await self._report_usage_metrics(
|
||||||
prompt_tokens=prompt_tokens,
|
prompt_tokens=prompt_tokens,
|
||||||
completion_tokens=completion_tokens if not use_completion_tokens_estimate else completion_tokens_estimate)
|
completion_tokens=(completion_tokens if not use_completion_tokens_estimate
|
||||||
|
else completion_tokens_estimate))
|
||||||
|
|
||||||
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
@@ -200,7 +209,8 @@ class AnthropicLLMService(LLMService):
|
|||||||
await self._process_context(context)
|
await self._process_context(context)
|
||||||
|
|
||||||
async def request_image_frame(self, user_id: str, *, text_content: str = None):
|
async def request_image_frame(self, user_id: str, *, text_content: str = None):
|
||||||
await self.push_frame(UserImageRequestFrame(user_id=user_id, context=text_content), FrameDirection.UPSTREAM)
|
await self.push_frame(UserImageRequestFrame(user_id=user_id, context=text_content),
|
||||||
|
FrameDirection.UPSTREAM)
|
||||||
|
|
||||||
def _estimate_tokens(self, text: str) -> int:
|
def _estimate_tokens(self, text: str) -> int:
|
||||||
return int(len(re.split(r'[^\w]+', text)) * 1.3)
|
return int(len(re.split(r'[^\w]+', text)) * 1.3)
|
||||||
@@ -231,7 +241,7 @@ class AnthropicLLMContext(OpenAILLMContext):
|
|||||||
|
|
||||||
self.system_message = system
|
self.system_message = system
|
||||||
|
|
||||||
@ classmethod
|
@classmethod
|
||||||
def from_openai_context(cls, openai_context: OpenAILLMContext):
|
def from_openai_context(cls, openai_context: OpenAILLMContext):
|
||||||
self = cls(
|
self = cls(
|
||||||
messages=openai_context.messages,
|
messages=openai_context.messages,
|
||||||
@@ -252,11 +262,11 @@ class AnthropicLLMContext(OpenAILLMContext):
|
|||||||
self.messages.pop(0)
|
self.messages.pop(0)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ classmethod
|
@classmethod
|
||||||
def from_messages(cls, messages: List[dict]) -> "AnthropicLLMContext":
|
def from_messages(cls, messages: List[dict]) -> "AnthropicLLMContext":
|
||||||
return cls(messages=messages)
|
return cls(messages=messages)
|
||||||
|
|
||||||
@ classmethod
|
@classmethod
|
||||||
def from_image_frame(cls, frame: VisionImageRawFrame) -> "AnthropicLLMContext":
|
def from_image_frame(cls, frame: VisionImageRawFrame) -> "AnthropicLLMContext":
|
||||||
context = cls()
|
context = cls()
|
||||||
context.add_image_frame_message(
|
context.add_image_frame_message(
|
||||||
@@ -389,12 +399,13 @@ class AnthropicAssistantContextAggregator(LLMAssistantContextAggregator):
|
|||||||
elif isinstance(frame, FunctionCallInProgressFrame):
|
elif isinstance(frame, FunctionCallInProgressFrame):
|
||||||
self._function_call_in_progress = frame
|
self._function_call_in_progress = frame
|
||||||
elif isinstance(frame, FunctionCallResultFrame):
|
elif isinstance(frame, FunctionCallResultFrame):
|
||||||
if self._function_call_in_progress and self._function_call_in_progress.tool_call_id == frame.tool_call_id:
|
if (self._function_call_in_progress and self._function_call_in_progress.tool_call_id ==
|
||||||
|
frame.tool_call_id):
|
||||||
self._function_call_in_progress = None
|
self._function_call_in_progress = None
|
||||||
self._function_call_result = frame
|
self._function_call_result = frame
|
||||||
else:
|
else:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"FunctionCallResultFrame tool_call_id does not match FunctionCallInProgressFrame tool_call_id")
|
"FunctionCallResultFrame tool_call_id != InProgressFrame tool_call_id")
|
||||||
self._function_call_in_progress = None
|
self._function_call_in_progress = None
|
||||||
self._function_call_result = None
|
self._function_call_result = None
|
||||||
elif isinstance(frame, AnthropicImageMessageFrame):
|
elif isinstance(frame, AnthropicImageMessageFrame):
|
||||||
|
|||||||
Reference in New Issue
Block a user