Agents and Chat
Build conversational and autonomous AI agents that call workflows as tools
Agents combine a system prompt, a set of workflows exposed as tools, optional knowledge sources, and a budget. They can run interactively (Chat) or autonomously (event-driven, scheduled, or SDK-invoked).
What you can build
Section titled “What you can build”Creating an agent
Section titled “Creating an agent”-
Go to Agents in the sidebar and click New agent.
-
Fill in name, description, and system prompt. The system prompt is the agent’s instructions and personality.
-
Set the Access Level (Public, Authenticated, or Role-based) and assign roles if applicable.
-
Pick Tools (workflows tagged
is_tool=Trueand any system tools). -
Optionally add Knowledge Sources for RAG, and Delegated Agents for multi-agent workflows.
-
Save. The agent is immediately available for chat and autonomous runs.
Access levels
Section titled “Access levels”| Level | Who can chat / run |
|---|---|
| Public | Anyone, no auth |
| Authenticated | Any logged-in user |
| Role-based | Users with at least one assigned role |
Exposing workflows as tools
Section titled “Exposing workflows as tools”Mark a workflow as a tool by setting is_tool=True (or using the @tool alias):
from bifrost import workflow
@workflow( is_tool=True, description="Look up a customer by email address",)async def lookup_customer(email: str): # ... return {"name": "John Doe", "account": "12345"}The workflow description is what the LLM reads to decide when to call the tool. Be specific. If you need to tune the agent-facing phrasing after discovery, edit it in the workflow record rather than the decorator.
Knowledge sources
Section titled “Knowledge sources”Attach a knowledge namespace to give the agent retrieval-augmented answers. The agent searches the namespace automatically when it needs background context. See Knowledge Bases for namespace setup.
Chat API
Section titled “Chat API”Start conversations programmatically:
import requests
# Create a conversation (optionally pinned to an agent)response = requests.post( f"{api_url}/api/chat/conversations", json={"agent_id": "agent-123"}, headers={"Authorization": f"Bearer {token}"},)conversation_id = response.json()["id"]
# Send a messagerequests.post( f"{api_url}/api/chat/conversations/{conversation_id}/messages", json={"content": "Hello, I need help with my account."}, headers={"Authorization": f"Bearer {token}"},)For real-time tokens, connect a WebSocket:
const ws = new WebSocket( `wss://your-instance.com/api/chat/conversations/${conversationId}/stream`);ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === "delta") console.log(data.content);};ws.send(JSON.stringify({ content: "How do I reset my password?" }));@Mentions
Section titled “@Mentions”Switch agents mid-conversation using @mentions:
User: @support-agent I need help with billingAI: (responds as support-agent)
User: @tech-agent Can you check my server status?AI: (switches to tech-agent)Agentless chat
Section titled “Agentless chat”Posting to /api/chat/conversations without an agent_id uses AI-based routing to pick an appropriate agent or fall back to a system default.
Autonomous agent runs
Section titled “Autonomous agent runs”Agent runs execute without a chat session. The agent receives input, runs a tool-calling loop, and returns structured output.
Lifecycle
Section titled “Lifecycle”- A run is created with input data and (optionally) an output schema.
- The agent loads its prompt, tools, and knowledge.
- The LLM picks a tool, the tool runs, the result feeds back into the LLM.
- The loop continues until the agent answers or hits a budget limit.
Budgets
Section titled “Budgets”| Field | Default | Max | Purpose |
|---|---|---|---|
max_iterations |
50 | 200 | Cap on LLM call cycles |
max_token_budget |
100,000 | 1,000,000 | Cap on total tokens |
max_run_timeout |
unset | — | Optional hard time limit |
If either iterations or token budget is hit, the run finishes with status budget_exceeded.
Triggering a run from a workflow
Section titled “Triggering a run from a workflow”Use agents.run() when the workflow needs the agent’s output before it can continue.
from bifrost import workflow, agents
@workflowasync def triage_ticket(ticket_id: str): return await agents.run( "ticket-triage-agent", input={"ticket_id": ticket_id}, output_schema={ "type": "object", "properties": { "priority": {"type": "string"}, "category": {"type": "string"}, }, }, )Queueing a run without waiting
Section titled “Queueing a run without waiting”Use agents.enqueue() when the workflow only needs to submit the work. Awaiting it waits for the short HTTP 202 acceptance response, not for the agent to finish.
from bifrost import workflow, agents
@workflowasync def queue_ticket_triage(ticket_id: str): handle = await agents.enqueue( "ticket-triage-agent", input={"ticket_id": ticket_id}, output_schema={ "type": "object", "properties": { "priority": {"type": "string"}, "category": {"type": "string"}, }, }, ) return {"run_id": handle.run_id, "status": handle.status}The returned run has already been written with status queued, so it can be read immediately:
run = await agents.get_run(run_id)
if run.status == "completed": return run.outputif run.status in {"failed", "timeout", "cancelled", "budget_exceeded"}: raise RuntimeError(run.error or f"Agent run ended with {run.status}")Poll with a delay when the caller needs to wait later. Avoid a tight loop; one request per second is usually sufficient.
Triggering from an event subscription
Section titled “Triggering from an event subscription”-
Go to Events and open your event source.
-
Click Add Subscription and set Target Type to Agent.
-
Pick the agent. The event payload becomes the agent’s input.
Triggering from the API
Section titled “Triggering from the API”response = requests.post( f"{api_url}/api/agent-runs/execute", json={ "agent_name": "ticket-triage-agent", "input": {"ticket_id": "T-123"}, "output_schema": {"type": "object", "properties": {"priority": {"type": "string"}}}, "timeout": 300, }, headers={"Authorization": f"Bearer {token}"},)Delegation
Section titled “Delegation”Agents can delegate to other agents. When you add a delegated agent, the parent automatically receives a delegate_to_<agent_name> tool. The LLM decides when to call it.
| Limit | Value |
|---|---|
| Max depth | 5 |
| Per-delegation timeout | 600s |
Delegation creates child AgentRun rows linked via parent_run_id. Child runs are filtered out of the top-level run list and rolled up under the parent in the run detail view.
Cancellation and rerun
Section titled “Cancellation and rerun”- Cancel: stops a running agent. Status transitions
running→cancelling→cancelled. Cancellation is checked before each iteration, during tool execution, and via a background watcher. - Rerun: re-executes a finished run with the same input. Creates a new run with
trigger_type="rerun".
Both are exposed in the run detail UI and via POST /api/agent-runs/{run_id}/cancel / POST /api/agent-runs/{run_id}/rerun.
Run observability
Section titled “Run observability”Every autonomous run records:
- Steps — every LLM call and tool execution, including delegation steps with expandable child detail.
- AI usage — input/output tokens and cost grouped by model.
- Status —
queued→running→completed|failed|budget_exceeded|cancelled. - Trigger —
manual,webhook,schedule,workflow,rerun, ordelegation.
View runs from the agent detail page’s Runs tab, the global History → Agents page, or via GET /api/agent-runs.
The Coding Agent
Section titled “The Coding Agent”The Coding Agent is a built-in platform agent for creating and editing Bifrost workflows. It runs in your workspace context and uses precision editing tools rather than full-file replacements.
| Tool | Purpose |
|---|---|
list_content |
List files by entity (app_file, workflow, module) |
search_content |
Regex search with context lines |
read_content_lines |
Read a specific line range |
patch_content |
Surgical string replacement |
replace_content |
Full content replacement / create new file |
delete_content |
Delete a file |
Combined with the Coding Agent’s workflow execution, validation, and execution-history tools, these power a search → read → patch loop suited to LLM editing. A client connected to the root /mcp endpoint reaches this catalog through the four gateway tools; a client connected to the Coding Agent’s /mcp/{agent_id} endpoint sees its approved native tools directly.
Next steps
Section titled “Next steps”- Using AI in workflows — direct LLM completions
- Knowledge bases — RAG setup
- MCP Server setup — expose Bifrost to Claude / Copilot / Cursor
- Publishing agents as MCP — turn an agent’s tool surface into an external MCP endpoint