Skip to main content
The agent invoke registry maps an agent id to a template agent, so a request handler can resolve and invoke the right agent by id.

Quick Start

1

Default (single-tenant)

Use the module-level functions — no registry= kwarg needed. This is what almost every user wants.
2

Scoped (multi-tenant / multi-embedding)

Construct an AgentRegistry() per tenant and pass it via the registry= kwarg. Two AgentOS gateways in the same interpreter can now hold isolated agent sets.
3

Bind a per-tenant registry to a mounted FastAPI app

Passing registry= to register_agent(...) scopes the free functions, but the mounted router’s route handlers resolve their registry through Depends(_registry_dependency). Override that dependency so /agents, /agents/{id}, and /agents/{id}/invoke serve your registry instead of the process-global one.
The override is per FastAPI app instance, so two AgentOS gateways in the same interpreter now serve their own agent set through /agents, /agents/{id}, and /agents/{id}/invoke — not a shared list.

How It Works

Every invocation resolves through resolve_session_agent(agent_id, session_id, *, registry=None), which clones the registered template per request so concurrent callers never share mutable conversation state. The invoke handler passes in whatever Depends(_registry_dependency) resolved to, so a per-app override reaches the resolver. unregister pops the id atomically under a lock (dict.pop), so a concurrent unregister can’t race between the membership check and the delete — the previous split check-then-delete returned uncaught 500s on concurrent deletes, which is the reason the class exists. Per-request clones are closed for you. The invoke handler wraps every clone in try/finally and closes it (preferring aclose(), falling back to sync close() in a worker thread) after every request. Only real clones are closed; when the resolved agent is the shared registered template (plain mocks / non-isolatable objects), it is left untouched. Deriving ownership from the resolved object itself — rather than a second, independently-timed registry lookup — is race-free even when the registry entry is concurrently replaced. See Agent Lifecycle Cleanup.

Configuration Options

AgentRegistry methods: Module-level functions (backward-compatible):

Best Practices

The module-global is already thread-safe, and the registry= kwarg is the escape hatch, not the default path. Use plain register_agent(agent_id, agent) / get_agent(agent_id) for single-tenant setups.
Two AgentOS gateways sharing the module global will step on each other’s agent ids. Construct one AgentRegistry() per gateway and thread it through your register_agent(...) calls.
Just calling register_agent(..., registry=my_reg) isn’t enough — the router’s route handlers resolve their registry via Depends(_registry_dependency). To serve your registry through the API, add:
_registry_dependency is an override key, not a helper you call from user code — its name starts with _ on purpose.
Every invocation goes through resolve_session_agent, which clones the template per request via clone_for_channel. Do not stash mutable state on the registered agent expecting it to survive across calls.
The registry holds a template; every invoke resolves a per-request clone via clone_for_channel(). Live resources (open sockets, connection pools, subprocesses) put on the template survive across requests but are also not released by the invoke wrapper’s per-request cleanup — the wrapper deliberately skips the shared template. Attach resources to the clone through Agent’s standard fields so aclose() on the clone cleans them up.

Registering Agents

Agents are registered in-process with register_agent(...) — this is the only supported path.
POST /api/v1/agents/{agent_id}/register is not a registration surface. It returns 501 Not Implemented:
Previously this endpoint returned 200 with a placeholder payload that implied success, but nothing was registered. Client code that relied on 200 OK to confirm registration should call register_agent(...) in the server process instead.

AgentOS Chat Session Isolation

Session isolation cloning path

Serve Agents Auth

Surface where this registry is invoked

Agent Lifecycle Cleanup

How the per-request clone releases its resources on teardown

n8n API

Per-request clone cleanup in the HTTP invoke endpoint