Create your agent
xpander agent new --name "stateful-agent" --framework agno --folder .
This creates a serverless backend instance with base template files:
Dockerfile
- Container configuration
requirements.txt
- Python dependencies
xpander_handler.py
- Agent Event Listener
.env
- API key and agent ID configuration
The serverless agent is immediately available for testing:
xpander agent invoke "stateful-agent" "hi"
Or use the Web UI at https://app.xpander.ai/agents/agent-id
Write the agent code
The default serverless agent uses a basic template. Create myAgent.py
to customize behavior:
from dotenv import load_dotenv
load_dotenv()
from agno.agent import Agent
from xpander_sdk import Backend
class MyAgent(Agent):
def __init__(self, **kwargs):
agent_backend = Backend()
super().__init__(**agent_backend.get_args(), **kwargs)
def local_test(self):
self.print_response("How many people live in Canada?")
self.print_response("And what's their favorite food?")
myAgent = MyAgent()
myAgent.local_test()
The Backend instance includes a PostgreSQL database with read/write permissions, system prompt, model settings, and Tools/MCP integrations. When loaded into Agno, it automatically creates the database schema. All settings can be overridden in code using the override
parameter:# Override model example
backend = Backend()
agent = Agent(**backend.get_args(override={
'model': Ollama(id="gpt-oss:20b")
}))
Create a virtual environment, install dependencies, export your API key and run the Agent.
Setup environment
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export OPENAI_API_KEY="your-key"
Output
The agent remembers the conversation context between questions:
Access your PostgreSQL database with myAgent.storage.db_url
or view all messages using get_messages_for_session()
.
Deploy Updates
After testing, update xpander_handler.py
to use your MyAgent
instance instead of the default agno_agent
object.
Example:
from myAgent import MyAgent
@on_task
async def my_agent_handler(task: Task):
backend = Backend(configuration=task.configuration)
agno_args = await backend.aget_args(task=task)
my_agent = MyAgent(**agno_args)
result = await my_agent.arun(message=task.to_message())
task.result = result.content
return task
And deploy your custom version:
This replaces the serverless agent with your dedicated container. Traffic routes through xpander_handler.py
.