A first workflow
Add a workflows map to agent.json. Each key names a workflow; each value
has a trigger and activities.
{
"workflows": {
"morning-summary": {
"trigger": { "type": "schedule", "cron": "0 8 * * 1-5" },
"description": "Summarize yesterday's open conversations every weekday morning.",
"activities": [
{ "id": "summarize", "intent": "Summarize yesterday's open customer conversations and what each one is waiting on." }
]
}
}
} This workflow runs at 08:00 on weekdays, in the bot's local time. The employee carries out the activity with its own persona, skills and connections.
Workflow fields
| Field | Meaning |
|---|---|
trigger | Required. When the workflow runs. See Triggers. |
description | What the workflow is for. |
activities | The steps. See Activities. |
connections | Edges {from, to, label} that make the activities a graph. __trigger__ is the start and __emit__ the end. |
emit | Events this workflow announces when it finishes: a list, or one comma-separated string. See Events. |
inputs | Values passed to every run. |
budget | {total_per_run, cost_estimate}. In a graph run, total_per_run caps output tokens; otherwise both are estimates. |
case | Makes the workflow one long-running case per person or thing. See Cases. |
A workflow with a trigger and no activities is valid. A watch without activities only relays its events to other workflows.
How a run executes
Without connections, activities run in order and the employee performs each one. Each
activity's result is passed to the next. An activity with no output ends the run.
With connections, the activities form a graph. Branches run in parallel, and six
activity types run without the model: condition, loop, wait, http, command and decide. Use a graph
when routing must be exact.
{
"trigger": { "type": "watch", "plugin": "mail", "event": "email.new" },
"activities": [
{ "id": "classify", "type": "decide",
"params": {
"questions": {
"kind": {
"type": "choice",
"instructions": "What kind of message is this?",
"criteria": { "invoice": "A bill from a vendor", "other": "Anything else" }
}
},
"default": { "kind": "other" }
} },
{ "id": "is-invoice", "type": "condition", "params": { "expression": "nodes.classify.kind.choice == invoice" } },
{ "id": "record", "intent": "Record the invoice in _watch_payload as a bill and note the due date." }
],
"connections": [
{ "from": "__trigger__", "to": "classify" },
{ "from": "classify", "to": "is-invoice" },
{ "from": "is-invoice", "to": "record", "label": "True" },
{ "from": "record", "to": "__emit__" }
],
"emit": ["invoice.recorded"]
} What a run receives
The employee always has its persona and the owner's answers to its inputs questions.
A run also receives these values, depending on its trigger.
| Input | Present when |
|---|---|
_event_source, _event_payload, _event_origin | An event trigger fired. Payloads of 8 KB or more are shortened to their scalar fields, with email headers and attachment references kept. |
_watch_payload | A watch or folder trigger fired. One line of the watcher’s output, or {files} for a folder. |
inputs | Always. The workflow’s own inputs values. |
Cases
Some work spans days: a lead that needs follow-ups, a request waiting on documents. Add case and the workflow keeps one open case per person or thing instead of starting fresh
each time.
| Field | Meaning |
|---|---|
key | Required. Comma-separated dotted paths into the trigger data that identify the subject, such as contactEmail,email,phone. |
type | The kind of case, such as lead. Workflows with the same type share cases. Defaults to the workflow name. |
default_wait | How long to wait when a turn names no wait: 3d, 12h, 45m. Default three days. |
Each turn of a case must end with one JSON object and nothing after it. result is the
business state; next tells the engine to wait or close. A
deadline is RFC 3339 or a relative span. Anything else is an invalid turn.
{"result": {"status": "awaiting_documents", "summary": "Requested two bank statements"},
"next": {"action": "wait", "on": "signal", "deadline": "3d", "reason": "documents"}} Limits and recovery
- Each activity can take up to 50 model turns, unless
params.maxIterationssays otherwise. - In a graph, one activity can run at most 10,000 times in a run.
- The owner's spending cap for the employee stops a run when reached. An activity's
token_budgetis an estimate. - A run interrupted by a restart is marked interrupted and resumed once.
- The employee can end a run early with the
exittool.
Run and manage workflows
The owner can run any workflow by hand. Employees manage workflows with run_workflow, workflow_status, list_workflow_runs, set_workflow_enabled and the other workflow tools listed on Helpers and Teams.