Building flows
Scripts, Sentry and tools
Each kind of process has settings of its own: an agent's model, prompt and tools, a script's code, a Sentry query. This page covers them, with tips on getting each right.
Agents
| Setting | What it does |
|---|---|
| Model | Which model the agent runs on. Default uses the worker's default. Different processes can use different providers' models, for example to get independent opinions. |
| Thinking | How much the model reasons before answering: off, minimal, low, medium, high, xhigh, max, or the default. |
| Prompt | What to do, in plain words. |
| MCP servers | Which of the app's MCP servers (Slack, Sentry, Jira…) this agent may use; none by default. A server you haven't connected yet shows Not connected and a Connect button. |
| Repositories | Which of the flow's repositories it works in: Every repository of the flow, or some, or none for an agent that only talks to other systems. |
| Tell it about the flow it works in, in OPL | Adds the flow's OPL to its prompt. |
| Rounds, Timeout (s), Retries | See Review loops and Handling failure. |
Writing a good prompt
- Name inputs and outputs as the board names them: “Fix the exception in Exceptions following the Style guide.”
- Say what good looks like: “the smallest change that is clearly right, with a test that fails without it.”
- Leave out JSON shapes and plumbing. The engine appends the inputs, the output contract and any change request; see What a step sees.
- Put the contract for each field in its attribute's definition, not the prompt.
MCP servers are added by an admin under Settings → MCP servers, and each person connects them for themselves. An agent acts with the connections of whoever its run is for.
Scripts
A script process runs bash in the worker, with curl and jq. Use it for whatever should happen the same way every time: calling an API, running a build, reshaping JSON.
| Name | Holds |
|---|---|
$INPUTS | A directory with one file per object it takes, named after the object with unsafe characters made underscores (Jira Ticket → $INPUTS/Jira_Ticket), holding the object's JSON. |
| stdout | What it prints is its output, in the same contract as an agent's. |
$OUTPUTS | Where it writes files, with their paths in file attributes. |
$WORKSPACE, $BRANCH | The checkouts' directory and the run's branch, when the flow has repositories. |
$SINCE, $LAST_RUN | In a run a schedule started, when the schedule's last run that ended done started, as a Unix timestamp. Empty on its first run and in runs started by hand. See Schedules. |
| exit code | Non-zero fails the step, with stderr as the error. |
key=$(jq -r .data "$INPUTS/Ticket_key")
curl -fsS "https://jira.example.com/rest/api/2/issue/$key" \
-H "Authorization: Bearer $JIRA_TOKEN" |
jq '{key: .key, summary: .fields.summary, priority: .fields.priority.id | tonumber}'Sentry
Drop Sentry from Connectors. It fetches issues from Sentry's API and yields them as a list: the usual first step of a scheduled flow.
| Setting | Holds |
|---|---|
| Organization, Project | Slugs. The organization is required. |
| Query | Sentry search syntax, is:unresolved by default, such as is:unresolved level:error. |
| Environment | Only issues seen in it. |
| Sort by | Last seen, First seen, Events, Users or Trends. |
| Limit | How many issues, 1 to 50. |
Each attribute of the list takes the issue field it is named after: id, shortId, title, culprit, level, status, count, userCount, firstSeen, lastSeen, permalink and project. A dotted name reaches into a field, such as metadata.value for an error's message. A list without attributes gets all of them. The server needs a SENTRY_AUTH_TOKEN.