import os
from smallestai.atoms.crew.nodes import OutputCrewNode
from smallestai.atoms.crew.clients.openai import OpenAIClient
from smallestai.atoms.crew.tools import ToolRegistry, function_tool
from smallestai.atoms.crew.events import SDKAgentEndCallEvent
class SupportAgent(OutputCrewNode):
def __init__(self):
super().__init__(name="support-agent")
self.llm = OpenAIClient(model="gpt-4o-mini")
self.tool_registry = ToolRegistry()
self.tool_registry.discover(self)
self.context.add_message({
"role": "system",
"content": "You are a support agent. Help users with their questions. "
"Use end_call when they're done."
})
@function_tool()
def get_order_status(self, order_id: str):
"""Look up an order's status.
Args:
order_id: Order ID like "ORD-12345"
"""
# Your implementation
return {"status": "shipped", "eta": "Tomorrow"}
@function_tool()
async def end_call(self):
"""End the call when the user says goodbye."""
await self.send_event(SDKAgentEndCallEvent())
return None
async def generate_response(self):
response = await self.llm.chat(
messages=self.context.messages,
stream=True,
tools=self.tool_registry.get_schemas()
)
tool_calls = []
async for chunk in response:
if chunk.content:
yield chunk.content
if chunk.tool_calls:
tool_calls.extend(chunk.tool_calls)
if tool_calls:
results = await self.tool_registry.execute(tool_calls=tool_calls, parallel=True)
self.context.add_messages([
{
"role": "assistant",
"content": "",
"tool_calls": [
{"id": tc.id, "type": "function", "function": {"name": tc.name, "arguments": str(tc.arguments)}}
for tc in tool_calls
]
},
*[{"role": "tool", "tool_call_id": tc.id, "content": result.content}
for tc, result in zip(tool_calls, results)]
])
final = await self.llm.chat(messages=self.context.messages, stream=True)
async for chunk in final:
if chunk.content:
yield chunk.content