Zgent
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
ActionBehavior
ROUTERoute to the agent instance for this key. If no instance exists, create one.
CREATE_AGENTExplicitly create a new agent instance
DROPIgnore this message
ERRORReport 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.

On this page