Sinks
Sinks define where agent output goes after a run completes. They are most useful in daemon mode and compose pipelines, where agents run unattended and their results need to be routed somewhere — a webhook, a file, a custom function, or another agent.
Sinks are configured in the spec.sinks list.
Quick Example
spec:
sinks:
- type: webhook
url: https://hooks.slack.com/services/T.../B.../xxx
headers:
Content-Type: application/json
- type: file
path: ./output/results.jsonl
format: jsonlSink Types
| Type | Description |
|---|---|
webhook | HTTP POST to a URL |
file | Write to a local file |
custom | Call a Python function |
delegate | Route output to another agent |
Webhook
Sends a JSON payload to a URL via HTTP POST. Useful for Slack, Discord, PagerDuty, or any HTTP endpoint.
sinks:
- type: webhook
url: https://hooks.slack.com/services/T.../B.../xxx
headers:
Content-Type: application/json
Authorization: Bearer ${WEBHOOK_TOKEN}
timeout_seconds: 10
retry: true
max_retries: 3| Field | Type | Default | Description |
|---|---|---|---|
url | str | (required) | Destination URL |
headers | dict | {} | HTTP headers (supports ${VAR} substitution) |
timeout_seconds | int | 10 | Request timeout |
retry | bool | true | Retry on failure |
max_retries | int | 3 | Maximum retry attempts (exponential backoff) |
Payload Format
The webhook POST body is a JSON object:
{
"agent_name": "monitor-agent",
"run_id": "a1b2c3d4e5f6",
"trigger_type": "cron",
"status": "success",
"output": "All 3 services healthy. Response times: api=120ms, web=85ms, db=45ms.",
"timestamp": "2025-01-15T09:00:05Z",
"tokens_used": 1250,
"duration_ms": 4200
}File
Writes agent output to a local file. Supports JSON, JSONL (JSON Lines), and plain text formats.
sinks:
- type: file
path: ./output/results.jsonl
format: jsonl
mode: append| Field | Type | Default | Description |
|---|---|---|---|
path | str | (required) | Output file path |
format | str | "jsonl" | Output format: "json", "jsonl", or "text" |
mode | str | "append" | Write mode: "append" or "overwrite" |
json— writes a single JSON object per run (overwrites by default)jsonl— appends one JSON line per run (same schema as webhook payload)text— writes the raw output string
Custom
Calls a Python function with the run result. Use this for custom integrations — database writes, email, message queues, or anything else.
sinks:
- type: custom
module: my_sinks
function: send_to_database
config:
db_url: postgres://localhost/mydb
table: agent_results| Field | Type | Default | Description |
|---|---|---|---|
module | str | (required) | Python module path (must be importable) |
function | str | (required) | Function name to call |
config | dict | {} | Config dict passed to the function |
The function signature:
def send_to_database(result: dict, config: dict) -> None:
"""Called by InitRunner after each agent run.
Args:
result: Run result dict (same schema as webhook payload).
config: Config dict from the sink YAML.
"""
import psycopg2
conn = psycopg2.connect(config["db_url"])
# ... insert result into databaseDelegate
Routes agent output as input to another agent. This is primarily used in compose pipelines to chain agents together.
sinks:
- type: delegate
agent: summarizer
role_file: ./roles/summarizer.yaml
prompt_template: "Summarize the following agent output:\n\n{output}"| Field | Type | Default | Description |
|---|---|---|---|
agent | str | (required) | Target agent name |
role_file | str | (required) | Path to the target agent's role YAML |
prompt_template | str | "{output}" | Template with {output} placeholder for the source agent's output |
Multiple Sinks
An agent can have multiple sinks. All sinks fire after each run completes:
spec:
sinks:
# Log to file
- type: file
path: ./logs/runs.jsonl
format: jsonl
# Notify Slack
- type: webhook
url: ${SLACK_WEBHOOK_URL}
# Store in database
- type: custom
module: my_sinks
function: store_resultSinks with Daemon Mode
Sinks are most commonly used with triggers and daemon mode. When a trigger fires and an agent run completes, all configured sinks receive the result:
spec:
triggers:
- type: cron
schedule: "0 */6 * * *"
prompt: "Check system health and report status."
sinks:
- type: webhook
url: ${SLACK_WEBHOOK_URL}
- type: file
path: ./logs/health-checks.jsonl
format: jsonlinitrunner daemon role.yamlEvery 6 hours, the agent runs, and the output is sent to both Slack and the log file.
Sinks with Compose
In compose pipelines, delegate sinks route output between agents. See the compose documentation for multi-agent pipeline examples.