Core Concepts
Dispatcher
Route incoming messages to the right agent instance.
A Dispatcher determines which agent instance handles each incoming message. This is how Zgent manages multiple concurrent sessions with a single agent definition.
How dispatching works
When a message arrives, the dispatcher returns a DispatchResult containing:
- key — a session identifier (e.g., a chat ID or user ID)
- action — what to do with the message
| Action | Behavior |
|---|---|
ROUTE | Route to the agent instance for this key. If no instance exists, create one. |
CREATE_AGENT | Explicitly create a new agent instance |
DROP | Ignore this message |
ERROR | Report an error |
Basic dispatcher
Route every message to a single shared instance:
from zgent import Dispatcher, DispatchResult, DispatchAction
dispatcher = Dispatcher(
lambda msg: DispatchResult(key="shared", action=DispatchAction.ROUTE)
)Session-per-user dispatcher
Route messages by session ID so each user gets their own agent instance:
dispatcher = Dispatcher(
lambda msg: DispatchResult(key=msg.session_id, action=DispatchAction.ROUTE)
)Conditional dispatcher
Drop messages that don't match a filter:
def route_or_drop(msg):
if msg.session_id.startswith("vip-"):
return DispatchResult(key=msg.session_id, action=DispatchAction.ROUTE)
return DispatchResult(key="", action=DispatchAction.DROP)
dispatcher = Dispatcher(route_or_drop)Async dispatcher
The dispatcher function can be async for lookups that require I/O:
async def lookup_dispatcher(msg):
user = await db.get_user(msg.session_id)
if user and user.is_active:
return DispatchResult(key=user.id, action=DispatchAction.ROUTE)
return DispatchResult(key="", action=DispatchAction.DROP)
dispatcher = Dispatcher(lookup_dispatcher)Attaching to a definition
Pass the dispatcher when creating an AgentDefinition:
from zgent import AgentDefinition, AgentEngine
definition = AgentDefinition(
system_prompt="You are a helpful assistant.",
engine_type=AgentEngine.CLAUDE,
dispatcher=Dispatcher(
lambda msg: DispatchResult(key=msg.session_id, action=DispatchAction.ROUTE)
),
)If no dispatcher is provided, Zgent routes by message.session_id. Messages without a session ID fall back to a shared empty-key instance.