apps/backend/src/agent/). It is built on DeepAgents, which extends LangGraph with a hierarchical sub-agent model. There is no separate agent service to start — the agent activates when a user sends a chat message.
Architecture
Sub-agents
Sub-agents share the same authentication context (org ID, user ID) as the root agent and always operate within the active organization.
Tool reference
CRM tools
These call/api/agents/* endpoints on the backend and write audit log entries with source AI.
Contacts
Companies
Deals
Context
Filesystem tools
These run inside the chat’s sandbox — an isolated execution environment. In production, sandboxes are remote Sprites machines; in development they run locally.Web tool
Interactive tools
Tool approval (human-in-the-loop)
Tools can declare aneedsApproval function. When it returns true, the tool returns { pending: true } instead of executing, and the frontend surfaces an approval prompt to the user. Execution continues only after the user approves.
Approval is currently required for:
bashcommands that includerm -rfbashcommands orreadcalls that reference.envfiles
Persistent context
Context entities (contacts, companies, deals) attached to a chat thread are stored in LangGraph checkpoint state and persist across turns. Theget_conversation_context tool always returns the current set, even after a page reload.
This is handled by PersistentContextMiddleware (apps/backend/src/agent/middleware/persistent-context.middleware.ts), which merges context entity arrays via a LangGraph state reducer.
Model selection
The model is selected via theAGENT_MODEL environment variable using the format provider/model:
openai, anthropic. An invalid format throws at startup.
Streaming
The backend streams agent output to the frontend as SSE. The response includes:X-Thread-Id— LangGraph thread ID for this runX-Chat-Id— Zuko chat ID
values + messages) is converted to the AI SDK UIMessageStream format via @ai-sdk/langchain, then piped to the browser.
To stop a running agent turn, call POST /api/v1/chat/stop. The backend signals cancellation via AbortSignal, which is passed through to all tool execute calls.