Merge pull request #701 from pipecat-ai/khk/anthropic-function-calling-fix

fixes for anthropic function calling
This commit is contained in:
Mark Backman
2024-11-09 06:39:34 -05:00
committed by GitHub
3 changed files with 24 additions and 20 deletions

View File

@@ -67,7 +67,8 @@ async def main():
llm = AnthropicLLMService( llm = AnthropicLLMService(
api_key=os.getenv("ANTHROPIC_API_KEY"), api_key=os.getenv("ANTHROPIC_API_KEY"),
model="claude-3-5-sonnet-20240620", # model="claude-3-5-sonnet-20240620",
model="claude-3-5-sonnet-latest",
enable_prompt_caching_beta=True, enable_prompt_caching_beta=True,
) )
llm.register_function("get_weather", get_weather) llm.register_function("get_weather", get_weather)

View File

@@ -98,12 +98,13 @@ async def load_conversation(function_name, tool_call_id, args, llm, context, res
messages = [ messages = [
{ {
"role": "system", "role": "system",
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.", "content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a succinct, creative and helpful way. Prefer responses that are one sentence long unless you are asked for a longer or more detailed response.",
}, },
{"role": "user", "content": ""}, {"role": "user", "content": "Start the call by saying the word 'hello'. Say only that word."},
{"role": "assistant", "content": []}, # {"role": "user", "content": ""},
{"role": "user", "content": "Tell me"}, # {"role": "assistant", "content": []},
{"role": "user", "content": "a joke"}, # {"role": "user", "content": "Tell me"},
# {"role": "user", "content": "a joke"},
] ]
tools = [ tools = [
{ {
@@ -183,7 +184,7 @@ async def main():
) )
llm = AnthropicLLMService( llm = AnthropicLLMService(
api_key=os.getenv("ANTHROPIC_API_KEY"), model="claude-3-5-sonnet-20240620" api_key=os.getenv("ANTHROPIC_API_KEY"), model="claude-3-5-sonnet-latest"
) )
# you can either register a single function for all function calls, or specific functions # you can either register a single function for all function calls, or specific functions

View File

@@ -671,6 +671,7 @@ class AnthropicAssistantContextAggregator(LLMAssistantContextAggregator):
): ):
self._function_call_in_progress = None self._function_call_in_progress = None
self._function_call_result = frame self._function_call_result = frame
await self._push_aggregation()
else: else:
logger.warning( logger.warning(
"FunctionCallResultFrame tool_call_id != InProgressFrame tool_call_id" "FunctionCallResultFrame tool_call_id != InProgressFrame tool_call_id"
@@ -679,9 +680,12 @@ class AnthropicAssistantContextAggregator(LLMAssistantContextAggregator):
self._function_call_result = None self._function_call_result = None
elif isinstance(frame, AnthropicImageMessageFrame): elif isinstance(frame, AnthropicImageMessageFrame):
self._pending_image_frame_message = frame self._pending_image_frame_message = frame
await self._push_aggregation()
async def _push_aggregation(self): async def _push_aggregation(self):
if not self._aggregation: if not (
self._aggregation or self._function_call_result or self._pending_image_frame_message
):
return return
run_llm = False run_llm = False
@@ -694,20 +698,18 @@ class AnthropicAssistantContextAggregator(LLMAssistantContextAggregator):
frame = self._function_call_result frame = self._function_call_result
self._function_call_result = None self._function_call_result = None
if frame.result: if frame.result:
self._context.add_message( assistant_message = {"role": "assistant", "content": []}
if aggregation:
assistant_message["content"].append({"type": "text", "text": aggregation})
assistant_message["content"].append(
{ {
"role": "assistant", "type": "tool_use",
"content": [ "id": frame.tool_call_id,
{"type": "text", "text": aggregation}, "name": frame.function_name,
{ "input": frame.arguments,
"type": "tool_use",
"id": frame.tool_call_id,
"name": frame.function_name,
"input": frame.arguments,
},
],
} }
) )
self._context.add_message(assistant_message)
self._context.add_message( self._context.add_message(
{ {
"role": "user", "role": "user",
@@ -721,7 +723,7 @@ class AnthropicAssistantContextAggregator(LLMAssistantContextAggregator):
} }
) )
run_llm = True run_llm = True
else: elif aggregation:
self._context.add_message({"role": "assistant", "content": aggregation}) self._context.add_message({"role": "assistant", "content": aggregation})
if self._pending_image_frame_message: if self._pending_image_frame_message: