recipes
Cookbook
Small, copy-paste-ready patterns for things people build with minmo.
Each one assumes a VoiceAgent is already created — see the
quickstart if you need that part.
Multiple tools on one agent
Register as many functions as you need — each becomes its own tool with its own JSON schema, inferred from the signature and docstring.
@agent.tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"It's sunny in {city}."
@agent.tool
def get_account_balance(account_id: str) -> str:
"""Look up a customer's account balance by id."""
return "$42.00"
@agent.tool
def book_appointment(date: str, time: str, reason: str) -> str:
"""Book an appointment on a given date and time."""
return f"Booked for {date} at {time}: {reason}"
Mixing server-hosted and client-side tools
A tool that only needs data your frontend already has (auth, session state) doesn't need a round trip to your server — declare it transport="client" and answer it yourself when the provider sends tool.call over the live session.
@agent.tool # hosted by minmo, transport="http" is the default
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"It's sunny in {city}."
@agent.tool(transport="client")
def get_account_balance(account_id: str) -> str:
"""Look up the current user's balance — answered client-side."""
return "$42.00"
Asserting tool-call behavior in CI
simulate() drives your llm directly and checks which tools it picks — no live session, so it's cheap enough to run on every commit.
from minmo.testing import simulate
result = simulate(agent, transcript=["What's the weather in Paris?"])
assert result["tool_calls"][0]["name"] == "get_weather"
assert result["tool_calls"][0]["arguments"]["city"] == "Paris"
Switching to Hume
Hume needs an extra secret_key (its OAuth client secret) alongside the usual api_key, and optionally a specific voice.
from minmo import VoiceAgent
from minmo.providers.hume import HumeProvider
agent = VoiceAgent(
prompt="You are a friendly voice assistant.",
api_key="YOUR_HUME_API_KEY",
provider=HumeProvider(),
provider_options={
"secret_key": "YOUR_HUME_SECRET_KEY",
"voice": {"name": "ITO", "provider": "HUME_AI"},
},
)
result = agent.deploy()
print(result["info"])
token = agent.mint_token() # OAuth access token, start an EVI session with it
Switching to OpenAI Realtime
OpenAI Realtime doesn't host anything on their servers — deploy() just builds the config in memory, so call mint_token() right after, in the same process, to actually get a usable session token.
from minmo import VoiceAgent
from minmo.providers.openai_realtime import OpenAIRealtimeProvider
agent = VoiceAgent(
prompt="You are a friendly voice assistant.",
api_key="YOUR_OPENAI_API_KEY",
provider=OpenAIRealtimeProvider(),
provider_options={"model": "gpt-4o-realtime-preview", "voice": "alloy"},
)
agent.deploy()
token = agent.mint_token() # send this session token to your client
Logging sessions to disk
Pass log_path when creating the agent, then call log_session() after a call ends (e.g. from your provider's webhook or end-of-call handler) to persist transcript + tool calls, and optionally react to it.
agent = VoiceAgent(
prompt="You are a friendly voice assistant.",
api_key="YOUR_ASSEMBLYAI_API_KEY",
log_path="./sessions.jsonl",
on_session_end=lambda record: print("saved:", record["session_id"]),
)
# after a call ends:
agent.log_session(
session_id="sess_123",
transcript=[{"role": "user", "content": "What's the weather in Paris?"}],
tool_calls=[{"name": "get_weather", "arguments": {"city": "Paris"}}],
)
Inspect the latest one anytime with minmo logs on the command line.
Deploying tool hosting yourself
local=True is for development — it spins up a local server and an ngrok tunnel. In production, run minmo's own server factory behind your real domain and point deploy() at it.
from minmo.server import create_tool_server
app = create_tool_server(agent) # a FastAPI app — serve it with uvicorn/gunicorn
# elsewhere, once that server is live at your domain:
agent.deploy(local=False, host_url="https://tools.yourdomain.com")
# or export MINMO_HOST_URL=https://tools.yourdomain.com and drop host_url