Skip to content

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).

  1. Go to Agents in the sidebar and click New agent.

  2. Fill in name, description, and system prompt. The system prompt is the agent’s instructions and personality.

  3. Set the Access Level (Public, Authenticated, or Role-based) and assign roles if applicable.

  4. Pick Tools (workflows tagged is_tool=True and any system tools).

  5. Optionally add Knowledge Sources for RAG, and Delegated Agents for multi-agent workflows.

  6. Save. The agent is immediately available for chat and autonomous runs.

LevelWho can chat / run
PublicAnyone, no auth
AuthenticatedAny logged-in user
Role-basedUsers with at least one assigned role

Mark a workflow as a tool by setting is_tool=True (or using the @tool alias):

from bifrost import workflow
@workflow(
is_tool=True,
tool_description="Look up a customer by email address",
)
async def lookup_customer(email: str):
# ...
return {"name": "John Doe", "account": "12345"}

The tool_description is what the LLM reads to decide when to call the tool. Be specific.

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.

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 message
requests.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?" }));

Switch agents mid-conversation using @mentions:

User: @support-agent I need help with billing
AI: (responds as support-agent)
User: @tech-agent Can you check my server status?
AI: (switches to tech-agent)

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.

Agent runs execute without a chat session. The agent receives input, runs a tool-calling loop, and returns structured output.

  1. A run is created with input data and (optionally) an output schema.
  2. The agent loads its prompt, tools, and knowledge.
  3. The LLM picks a tool, the tool runs, the result feeds back into the LLM.
  4. The loop continues until the agent answers or hits a budget limit.
FieldDefaultMaxPurpose
max_iterations50200Cap on LLM call cycles
max_token_budget100,0001,000,000Cap on total tokens
max_run_timeoutunsetOptional hard time limit

If either iterations or token budget is hit, the run finishes with status budget_exceeded.

from bifrost import workflow, agents
@workflow
async 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"},
},
},
)
  1. Go to Events and open your event source.

  2. Click Add Subscription and set Target Type to Agent.

  3. Pick the agent. The event payload becomes the agent’s input.

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}"},
)

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.

LimitValue
Max depth5
Per-delegation timeout600s

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.

  • Cancel: stops a running agent. Status transitions runningcancellingcancelled. 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.

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.
  • Statusqueuedrunningcompleted | failed | budget_exceeded | cancelled.
  • Triggermanual, webhook, schedule, workflow, rerun, or delegation.

View runs from the agent detail page’s Runs tab, the global History → Agents page, or via GET /api/agent-runs.

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.

ToolPurpose
list_contentList files by entity (app_file, workflow, module)
search_contentRegex search with context lines
read_content_linesRead a specific line range
patch_contentSurgical string replacement
replace_contentFull content replacement / create new file
delete_contentDelete a file

Combined with execute_workflow, validate_workflow, list_executions, etc., these power a search → read → patch loop suited to LLM editing.