suna/backend/agentpress/example/agent.py

187 lines
6.6 KiB
Python
Raw Normal View History

2025-07-28 17:53:10 +08:00
import asyncio
from agentpress.thread_manager import ThreadManager
2025-07-28 20:08:56 +08:00
from agentpress.tool import Tool, ToolResult, openapi_schema, usage_example
2025-07-29 20:45:21 +08:00
from agentpress.response_processor import ProcessorConfig
2025-07-28 17:53:10 +08:00
class CalculatorTool(Tool):
@openapi_schema({
"type": "function",
"function": {
"name": "calculate",
"description": "Perform basic mathematical calculations (addition, subtraction, multiplication, division)",
"parameters": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": ["add", "subtract", "multiply", "divide"],
"description": "The mathematical operation to perform"
},
"a": {
"type": "number",
"description": "First number for the calculation"
},
"b": {
"type": "number",
"description": "Second number for the calculation"
}
},
"required": ["operation", "a", "b"]
}
}
})
2025-07-28 20:08:56 +08:00
@usage_example("""
<function_calls>
<invoke name="calculate">
<parameter name="operation">add</parameter>
<parameter name="a">15</parameter>
<parameter name="b">27</parameter>
</invoke>
</function_calls>
This will add 15 and 27 to get 42.""")
2025-07-28 17:53:10 +08:00
async def calculate(self, operation: str, a: float, b: float) -> ToolResult:
2025-07-29 20:45:21 +08:00
if operation == "add":
result = a + b
elif operation == "subtract":
result = a - b
elif operation == "multiply":
result = a * b
elif operation == "divide":
if b == 0:
return self.fail_response("Cannot divide by zero")
result = a / b
else:
return self.fail_response(f"Unknown operation: {operation}")
2025-07-28 17:53:10 +08:00
2025-07-29 20:45:21 +08:00
return self.success_response({"result": result})
2025-07-28 17:53:10 +08:00
class SimpleAgent:
def __init__(self):
self.thread_manager = ThreadManager()
self.thread_manager.add_tool(CalculatorTool)
self.system_prompt = {
"role": "system",
"content": """You are a helpful mathematical assistant agent. You can:
1. Perform basic mathematical calculations (addition, subtraction, multiplication, division)
2. Provide help information about available operations
3. Explain mathematical concepts in simple terms
When a user asks for calculations, use the calculator tool to ensure accuracy.
Always be friendly and explain your reasoning when solving problems.
Available tools:
- calculate: Perform mathematical operations
2025-07-28 18:53:36 +08:00
2025-07-28 17:53:10 +08:00
"""
}
2025-07-29 20:45:21 +08:00
async def chat(self, thread_id: str, user_message: str, stream: bool = True):
2025-07-28 17:53:10 +08:00
await self.thread_manager.add_message(
thread_id=thread_id,
type="user",
2025-07-29 20:45:21 +08:00
content={"role": "user", "content": user_message},
2025-07-28 17:53:10 +08:00
is_llm_message=True
)
2025-07-28 18:53:36 +08:00
processor_config = ProcessorConfig(
xml_tool_calling=True,
execute_tools=True,
2025-07-29 20:45:21 +08:00
tool_execution_strategy="sequential"
2025-07-28 18:53:36 +08:00
)
2025-07-28 17:53:10 +08:00
return await self.thread_manager.run_thread(
thread_id=thread_id,
system_prompt=self.system_prompt,
2025-07-29 20:45:21 +08:00
temporary_message={"role": "user", "content": user_message},
2025-07-28 17:53:10 +08:00
stream=stream,
2025-07-29 20:45:21 +08:00
llm_model="gpt-4o",
2025-07-28 18:53:36 +08:00
processor_config=processor_config,
2025-07-29 20:45:21 +08:00
include_xml_examples=True
2025-07-28 17:53:10 +08:00
)
2025-07-29 20:45:21 +08:00
def render_conversation(self, messages):
2025-07-28 17:53:10 +08:00
print("\n" + "="*60)
print("📜 CONVERSATION HISTORY")
print("="*60)
for i, message in enumerate(messages, 1):
role = message.get('role', 'unknown')
content = message.get('content', '')
if role == 'user':
role_display = "👤 USER"
2025-07-29 20:45:21 +08:00
color = '\033[94m'
2025-07-28 17:53:10 +08:00
elif role == 'assistant':
role_display = "🤖 ASSISTANT"
2025-07-29 20:45:21 +08:00
color = '\033[92m'
2025-07-28 17:53:10 +08:00
elif role == 'system':
role_display = "⚙️ SYSTEM"
2025-07-29 20:45:21 +08:00
color = '\033[93m'
2025-07-28 17:53:10 +08:00
else:
role_display = f"📝 {role.upper()}"
2025-07-29 20:45:21 +08:00
color = '\033[96m'
2025-07-28 17:53:10 +08:00
reset = '\033[0m'
print(f"\n{color}{role_display} (Message {i}){reset}")
print("-" * 40)
if isinstance(content, str):
print(content)
elif isinstance(content, list):
for item in content:
if isinstance(item, dict):
if item.get('type') == 'text':
print(item.get('text', ''))
elif item.get('type') == 'tool_use':
tool_name = item.get('name', 'unknown_tool')
tool_input = item.get('input', {})
print(f"🔧 Tool Call: {tool_name}")
print(f" Input: {tool_input}")
else:
print(f" {item}")
else:
print(f" {item}")
elif isinstance(content, dict):
if 'tool_calls' in content:
for tool_call in content['tool_calls']:
function = tool_call.get('function', {})
print(f"🔧 Tool Call: {function.get('name', 'unknown')}")
print(f" Arguments: {function.get('arguments', {})}")
else:
print(content)
else:
print(f"[{type(content).__name__}]: {content}")
print("\n" + "="*60)
2025-07-29 20:45:21 +08:00
async def main():
2025-07-28 17:53:10 +08:00
agent = SimpleAgent()
2025-07-29 20:33:32 +08:00
thread_id = await agent.thread_manager.create_thread()
2025-07-28 17:53:10 +08:00
2025-07-29 20:45:21 +08:00
messages = [
2025-07-28 17:53:10 +08:00
"What's 15 + 27?",
"Can you multiply 8.5 by 4?",
2025-07-29 20:45:21 +08:00
"What's 100 divided by 7?"
2025-07-28 17:53:10 +08:00
]
2025-07-29 20:45:21 +08:00
for message in messages:
print(f"User: {message}")
print("Agent: ", end="", flush=True)
2025-07-28 17:53:10 +08:00
2025-07-29 20:45:21 +08:00
response_stream = await agent.chat(thread_id, message, stream=True)
async for chunk in response_stream:
if isinstance(chunk, dict) and chunk.get('type') == 'content':
print(chunk.get('content', ''), end='', flush=True)
print()
2025-07-28 17:53:10 +08:00
try:
2025-07-29 20:33:32 +08:00
conversation_history = await agent.thread_manager.get_llm_messages(thread_id)
2025-07-28 17:53:10 +08:00
agent.render_conversation(conversation_history)
except Exception as e:
2025-07-29 20:45:21 +08:00
print(f"Failed to fetch conversation history: {e}")
2025-07-28 17:53:10 +08:00
if __name__ == "__main__":
2025-07-29 20:45:21 +08:00
asyncio.run(main())