Merge pull request #1451 from pipecat-ai/set-tool-choice-from-context-aggregator

Set tool choice from context aggregator
This commit is contained in:
Filipi da Silva Fuchter
2025-03-26 09:12:26 -03:00
committed by GitHub
3 changed files with 24 additions and 1 deletions

View File

@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added a new frame, `LLMSetToolChoiceFrame`, which provides a mechanism
for modifying the `tool_choice` in the context.
- Added support in `DailyTransport` for updating remote participants'
`canReceive` permission via the `update_remote_participants()` method, by
bumping the daily-python dependency to >= 0.16.0.

View File

@@ -363,6 +363,13 @@ class LLMSetToolsFrame(DataFrame):
tools: List[dict]
@dataclass
class LLMSetToolChoiceFrame(DataFrame):
"""A frame containing a tool choice for an LLM to use for function calling."""
tool_choice: Literal["none", "auto", "required"] | dict
@dataclass
class LLMEnablePromptCachingFrame(DataFrame):
"""A frame to enable/disable prompt caching in certain LLMs."""

View File

@@ -6,7 +6,7 @@
import asyncio
from abc import abstractmethod
from typing import Dict, List, Set
from typing import Dict, List, Literal, Set
from loguru import logger
@@ -26,6 +26,7 @@ from pipecat.frames.frames import (
LLMMessagesAppendFrame,
LLMMessagesFrame,
LLMMessagesUpdateFrame,
LLMSetToolChoiceFrame,
LLMSetToolsFrame,
LLMTextFrame,
OpenAILLMContextAssistantTimestampFrame,
@@ -140,6 +141,11 @@ class BaseLLMResponseAggregator(FrameProcessor):
"""Set LLM tools to be used in the current conversation."""
pass
@abstractmethod
def set_tool_choice(self, tool_choice):
"""Set the tool choice. This should modify the LLM context."""
pass
@abstractmethod
def reset(self):
"""Reset the internals of this aggregator. This should not modify the
@@ -204,6 +210,9 @@ class LLMContextResponseAggregator(BaseLLMResponseAggregator):
def set_tools(self, tools: List):
self._context.set_tools(tools)
def set_tool_choice(self, tool_choice: Literal["none", "auto", "required"] | dict):
self._context.set_tool_choice(tool_choice)
def reset(self):
self._aggregation = ""
@@ -274,6 +283,8 @@ class LLMUserContextAggregator(LLMContextResponseAggregator):
self.set_messages(frame.messages)
elif isinstance(frame, LLMSetToolsFrame):
self.set_tools(frame.tools)
elif isinstance(frame, LLMSetToolChoiceFrame):
self.set_tool_choice(frame.tool_choice)
else:
await self.push_frame(frame, direction)
@@ -415,6 +426,8 @@ class LLMAssistantContextAggregator(LLMContextResponseAggregator):
self.set_messages(frame.messages)
elif isinstance(frame, LLMSetToolsFrame):
self.set_tools(frame.tools)
elif isinstance(frame, LLMSetToolChoiceFrame):
self.set_tool_choice(frame.tool_choice)
elif isinstance(frame, FunctionCallInProgressFrame):
await self._handle_function_call_in_progress(frame)
elif isinstance(frame, FunctionCallResultFrame):