suna/backend/agentpress/processor/xml/xml_results_adder.py

124 lines
5.0 KiB
Python
Raw Normal View History

2024-11-18 06:36:37 +08:00
import logging
from typing import Dict, Any, List, Optional
2025-03-30 14:48:57 +08:00
from agentpress.processor.base_processors import ResultsAdderBase
2024-11-18 06:36:37 +08:00
class XMLResultsAdder(ResultsAdderBase):
"""XML-specific implementation for handling tool results and message processing.
2024-11-18 13:54:26 +08:00
This implementation combines tool calls and their results into XML-formatted
messages, maintaining proper XML structure and relationships between calls
and results.
Methods:
add_initial_response: Add initial XML response
update_response: Update existing XML response
add_tool_result: Add XML tool result
2024-11-18 06:36:37 +08:00
"""
def __init__(self, thread_manager):
2024-11-18 13:54:26 +08:00
"""Initialize with ThreadManager instance.
Args:
thread_manager: Instance providing message management capabilities
"""
2024-11-18 06:36:37 +08:00
super().__init__(thread_manager)
self.message_added = False
2024-11-18 06:36:37 +08:00
async def add_initial_response(self, thread_id: str, content: str, tool_calls: Optional[List[Dict[str, Any]]] = None):
2024-11-18 13:54:26 +08:00
"""Add initial XML response without modifications.
Args:
thread_id: ID of the conversation thread
content: XML content of the response
tool_calls: Optional list of tool calls (not used in XML format)
Notes:
- Preserves XML structure in the content
- Sets message_added flag after successful addition
"""
2024-11-18 06:36:37 +08:00
message = {
"role": "assistant",
"content": content
2024-11-18 06:36:37 +08:00
}
await self.add_message(thread_id, message)
self.message_added = True
async def update_response(self, thread_id: str, content: str, tool_calls: Optional[List[Dict[str, Any]]] = None):
2024-11-18 13:54:26 +08:00
"""Update existing XML response.
Args:
thread_id: ID of the conversation thread
content: Updated XML content
tool_calls: Optional list of tool calls (not used in XML format)
Notes:
- Creates initial message if none exists
- Preserves XML structure in updates
"""
2024-11-18 06:36:37 +08:00
message = {
"role": "assistant",
"content": content
2024-11-18 06:36:37 +08:00
}
2025-04-01 11:30:32 +08:00
# Check if an assistant message already exists in the thread
existing_messages = await self.get_messages(thread_id)
assistant_msg = next((msg for msg in reversed(existing_messages)
if msg['role'] == 'assistant'), None)
if assistant_msg:
# Update existing message
await self.update_message(thread_id, message)
else:
# Add new message
await self.add_message(thread_id, message)
self.message_added = True
2024-11-18 06:36:37 +08:00
async def add_tool_result(self, thread_id: str, result: Dict[str, Any]):
2024-11-18 13:54:26 +08:00
"""Add XML tool result with proper referencing.
Args:
thread_id: ID of the conversation thread
result: Tool execution result to add
Notes:
- Links result to original XML tool call
- Formats result as user message for clarity
- Handles cases where original XML tag cannot be found
"""
try:
# Get the original tool call to find the root tag
messages = await self.get_messages(thread_id)
assistant_msg = next((msg for msg in reversed(messages)
if msg['role'] == 'assistant'), None)
if assistant_msg:
content = assistant_msg['content']
# Find the opening XML tag for this tool call
tool_start = content.find(f'<{result["name"]}')
if tool_start >= 0:
tag_end = content.find('>', tool_start)
if tag_end >= 0:
root_tag = content[tool_start:tag_end + 1]
# Create a simple reference message as user role
result_message = {
"role": "user",
2025-03-31 13:27:21 +08:00
"content": f"<tool_result>Result for {root_tag}\n{result['content']}</tool_result>"
}
await self.add_message(thread_id, result_message)
return
# Fallback if we can't find the root tag
result_message = {
"role": "user",
2025-03-31 13:27:21 +08:00
"content": f"<tool_result>>Result for {result['name']}:\n{result['content']}</<tool_result>>"
}
await self.add_message(thread_id, result_message)
except Exception as e:
logging.error(f"Error adding tool result: {e}")
# Ensure the result is still added even if there's an error
result_message = {
"role": "user",
2025-03-31 13:27:21 +08:00
"content": f"<tool_result>Result for {result['name']}:\n{result['content']}</tool_result>"
}
await self.add_message(thread_id, result_message)