AgentOS clones a fresh agent for each POST /api/chat, so concurrent callers never share chat_history and the agent you passed into AgentOS(agents=[…]) is never mutated by request traffic.
Quick Start
1
Serve an Agent
2
Chat With a Session
Supply a
session_id to continue the same conversation across calls. Omit it to make each call a fresh session.session_ids never see each other’s transcripts.
How It Works
Each request resolves a per-request agent, resets its transcript, binds the session, and runs one turn. The/chat handler and the /invoke router share one session-isolation contract: both call _supports_session_isolation → _clone_agent → bind_session(agent, session_id) from praisonai.api.agent_invoke. Any behaviour change to session binding lands in bind_session() and both surfaces pick it up together.
Session Contract
The response model is unchanged:
{response, agent_name, session_id}. Only the internal binding of session_id and the concurrency semantics changed.
If cloning fails,
/api/chat returns HTTP 500 with detail "Failed to isolate agent for session: {reason}". It is retry-safe and typically indicates a non-copyable custom object on the agent (e.g. a live socket).When Cloning Applies
Only realAgent instances that expose the per-session machinery are cloned. Plain mocks and lightweight callables fall back to the shared template.
Best Practices
Send a session_id to continue a conversation
Send a session_id to continue a conversation
Supplying the same
session_id on each turn is how a client continues one conversation. Omitting it starts a fresh session on a fresh clone every time.Don't rely on handoffs for isolation over /chat
Don't rely on handoffs for isolation over /chat
Agents with
handoffs stay on the shared template and are not session-isolated over /chat. Reach for serve_agents([...]) when you need handoffs and per-session isolation together.Retry on a 500 isolation error
Retry on a 500 isolation error
A
500 — Failed to isolate agent for session means the clone step raised, usually from a non-copyable object on the agent. It is safe to retry after removing the offending object.Isolation is in-process only
Isolation is in-process only
This clone model isolates concurrent in-process requests. It does not persist sessions across process restarts — use a session store backend for durable history.
Don't swap in a chat_history whose setter can raise
Don't swap in a chat_history whose setter can raise
bind_session() treats a raised setter as a fatal cross-tenant hazard and refuses the request. If you attach a custom chat_history descriptor (e.g. one that locks a backing store on assignment), make its setter always succeed — either accept [] unconditionally or replace it with a plain attribute.Related
Serve Agents
serve_agents([...]) — per-session isolation with handoff support, useful for comparisonPraisonAI Call
The call server that hosts the n8n agent-invoke router

