mirror of https://github.com/kortix-ai/suna.git
138 lines
4.7 KiB
Python
138 lines
4.7 KiB
Python
import logging
|
|
from typing import Dict, Any, Callable, List, Optional, Set
|
|
from abc import ABC, abstractmethod
|
|
|
|
# --- Tool Parser Base ---
|
|
|
|
class ToolParserBase(ABC):
|
|
"""Abstract base class defining the interface for parsing tool calls from LLM responses.
|
|
|
|
This class provides the foundational interface for parsing both complete and streaming
|
|
responses from Language Models, specifically focusing on tool call extraction and processing.
|
|
|
|
Attributes:
|
|
None
|
|
|
|
Methods:
|
|
parse_response: Processes complete LLM responses
|
|
parse_stream: Handles streaming response chunks
|
|
"""
|
|
|
|
@abstractmethod
|
|
async def parse_response(self, response: Any) -> Dict[str, Any]:
|
|
"""Parse a complete LLM response and extract tool calls.
|
|
|
|
Args:
|
|
response (Any): The complete response from the LLM
|
|
|
|
Returns:
|
|
Dict[str, Any]: A dictionary containing:
|
|
- role: The message role (usually 'assistant')
|
|
- content: The text content of the response
|
|
- tool_calls: List of extracted tool calls (if present)
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def parse_stream(self, response_chunk: Any, tool_calls_buffer: Dict[int, Dict]) -> tuple[Optional[Dict[str, Any]], bool]:
|
|
"""Parse a streaming response chunk and manage tool call accumulation.
|
|
|
|
Args:
|
|
response_chunk (Any): A single chunk from the streaming response
|
|
tool_calls_buffer (Dict[int, Dict]): Buffer storing incomplete tool calls
|
|
|
|
Returns:
|
|
tuple[Optional[Dict[str, Any]], bool]: A tuple containing:
|
|
- The parsed message if complete tool calls are found (or None)
|
|
- Boolean indicating if the stream is complete
|
|
"""
|
|
pass
|
|
|
|
# --- Tool Executor Base ---
|
|
|
|
class ToolExecutorBase(ABC):
|
|
"""Abstract base class defining the interface for tool execution strategies.
|
|
|
|
This class provides the foundation for implementing different tool execution
|
|
approaches, supporting both parallel and sequential execution patterns.
|
|
|
|
Attributes:
|
|
None
|
|
|
|
Methods:
|
|
execute_tool_calls: Main entry point for tool execution
|
|
_execute_parallel: Handles parallel tool execution
|
|
_execute_sequential: Handles sequential tool execution
|
|
"""
|
|
|
|
@abstractmethod
|
|
async def execute_tool_calls(
|
|
self,
|
|
tool_calls: List[Dict[str, Any]],
|
|
available_functions: Dict[str, Callable],
|
|
thread_id: str,
|
|
executed_tool_calls: Optional[Set[str]] = None
|
|
) -> List[Dict[str, Any]]:
|
|
"""Execute a list of tool calls and return their results.
|
|
|
|
Args:
|
|
tool_calls: List of tool calls to execute
|
|
available_functions: Dictionary of available tool functions
|
|
thread_id: ID of the current conversation thread
|
|
executed_tool_calls: Set of already executed tool call IDs
|
|
|
|
Returns:
|
|
List[Dict[str, Any]]: List of tool execution results
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def _execute_parallel(
|
|
self,
|
|
tool_calls: List[Dict[str, Any]],
|
|
available_functions: Dict[str, Callable],
|
|
thread_id: str,
|
|
executed_tool_calls: Set[str]
|
|
) -> List[Dict[str, Any]]:
|
|
"""Execute tool calls in parallel."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def _execute_sequential(
|
|
self,
|
|
tool_calls: List[Dict[str, Any]],
|
|
available_functions: Dict[str, Callable],
|
|
thread_id: str,
|
|
executed_tool_calls: Set[str]
|
|
) -> List[Dict[str, Any]]:
|
|
"""Execute tool calls sequentially."""
|
|
pass
|
|
|
|
# --- Results Adder Base ---
|
|
|
|
class ResultsAdderBase(ABC):
|
|
"""Abstract base class for handling tool results and message processing."""
|
|
|
|
def __init__(self, thread_manager):
|
|
"""Initialize with a ThreadManager instance.
|
|
|
|
Args:
|
|
thread_manager: The ThreadManager instance to use for message operations
|
|
"""
|
|
self.add_message = thread_manager.add_message
|
|
self.update_message = thread_manager._update_message
|
|
self.list_messages = thread_manager.list_messages
|
|
self.message_added = False
|
|
|
|
@abstractmethod
|
|
async def add_initial_response(self, thread_id: str, content: str, tool_calls: Optional[List[Dict[str, Any]]] = None):
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def update_response(self, thread_id: str, content: str, tool_calls: Optional[List[Dict[str, Any]]] = None):
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def add_tool_result(self, thread_id: str, result: Dict[str, Any]):
|
|
pass
|