Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions agents/how-agents-work.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ attacker actually get there?

## How a run proceeds

1. **The agent receives a task.** In chat that's your message; in a workflow it's a briefing composed by the
orchestrator.
1. **The agent receives a task.** In chat that's your message; in a workflow it's the task Console composes
for that step.
2. **It reasons and calls tools.** Each call returns a result it reads before deciding the next step.
3. **It may load a skill** with `activate_skill` when it hits a task a documented procedure covers.
4. **It may delegate** with `spawn_agent`, handing focused work to a child and waiting for the summary.
Expand Down Expand Up @@ -50,20 +50,14 @@ between agents.

You can watch the tree live — as a nested view in the CLI, and in the web console's chat while a turn runs.

### Forcing sequential delegation

Set [`sequential-spawns: true`](/agents/writing-an-agent#sequential-spawns) when steps depend on each other
and the agent must see one result before starting the next. Console's `workflow-runner` uses exactly this to
guarantee workflow steps run in order.

## Where agents come from

| Source | Description |
| --- | --- |
| **Platform agents** | The library Console ships. See [the agent library](/agents/library). |
| **Organization agents** | Agents your team writes, in the web console or the CLI. |

Both appear together wherever agents are listed, and the workflow orchestrator treats them identically. An
Both appear together wherever agents are listed, and a workflow treats them identically. An
organization agent whose `name` matches a platform agent **shadows** it — the supported way to customize
built-in behavior.

Expand Down
28 changes: 15 additions & 13 deletions agents/library.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,20 @@ defined budget so the results stay reviewable.
These two are the ends of a loop worth understanding: `detection-author` turns a one-time discovery into a
permanent rule, and `detections-runner` is what applies every rule you've accumulated from then on.

## Review
## Patching

| Agent | What it does |
| --- | --- |
| `code-reviewer` | Reviews code for security vulnerabilities, performance issues, and best practices. |
| `security-analyzer` | Deep security analysis with taint tracking and vulnerability assessment. |
| `patch-generator` | Generates a verified patch for one detection's findings in one file: edits the file, re-runs the detection to confirm the fix, captures the diff, and records it. |

Add it as its own step after any agent that produces findings — `detections-runner`, a vulnerability
scanner, or one of your own. It [consumes findings grouped by detection and file](/agents/writing-an-agent#group-by)
by default, so it runs once per (detection, file) pair rather than once per individual match.

<Note>
Patch generation used to be a setting on `detections-runner` itself. It's its own step now — if your
workflow used the old setting, Console already added `patch-generator` as a step for you.
</Note>

## Agents spawned by other agents

Expand All @@ -51,28 +59,22 @@ steps:

| Agent | Spawned by | Role |
| --- | --- | --- |
| `patch-generator` | `detections-runner`, when patch generation is enabled | Generates a verified patch for one detection's findings in one file: edits the file, re-runs the detection to confirm the fix, captures the diff, and records it. |
| `policy-evaluator` | `detections-runner` | Evaluates one policy detection against the repository, bound to that detection so every finding links back to it. |
| `policy-fix-verifier` | `patch-generator` | Independently judges whether a patched file still violates a policy. Deliberately read-only — it returns a verdict and cannot report findings or edit code. |

You *can* name one as a workflow step, but they expect a briefing their usual parent provides, so they work
best left to it.

## The orchestrator

`workflow-runner` is the agent that executes workflows: it reads a workflow's description and steps, spawns
each step's agent in order, and composes each briefing. You don't add it to a chain — it *is* the chain. See
[the agent chain](/workflows/agent-chain) for how it composes briefings.

## Common chains

| Goal | Chain |
| --- | --- |
| Fast pull request check | `vulnerability-scanner-basic` |
| Standard pull request review | `vulnerability-scanner-standard` |
| Fastest signal | `vulnerability-scanner-basic` |
| Balanced scan | `vulnerability-scanner-standard` |
| Deepest audit | `vulnerability-scanner-comprehensive` |
| Turn findings into permanent rules | `vulnerability-scanner-standard` → `detection-author` |
| Apply everything you've already vetted | `detections-runner` |
| Deep audit | `vulnerability-scanner-comprehensive` → `security-analyzer` |
| Apply everything you've already vetted, and patch it | `detections-runner` → `patch-generator` |

## Next steps

Expand Down
5 changes: 3 additions & 2 deletions agents/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ Telling them apart is the most common early stumble:
## Yours are first-class

Console ships a library of agents and skills to start from. Detections are yours to build up — nothing is
prebuilt there. Anything you write sits alongside the built-ins with no second-class status — the orchestrator that runs workflows treats platform and organization agents
identically, briefing both from their stated `description`.
prebuilt there. Anything you write sits alongside the built-ins with no second-class status — a workflow
runs platform and organization agents identically, and both are picked from the same list by their stated
`description`.

An agent you write with the same name as a built-in one **shadows** it. That's the supported way to
customize built-in behavior without breaking workflows that already reference that name.
Expand Down
3 changes: 3 additions & 0 deletions agents/tool-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ See [what agents can read](/data/what-agents-can-read) for what that covers and
| `report_finding` | Records a confirmed vulnerability, with evidence. This is what makes a result durable rather than conversational. |
| `list_findings` | Lists findings already recorded. |
| `report_patch` | Attaches a verified remediation patch (a unified diff) to the finding(s) it fixes. Call it only after editing the file **and** confirming the fix. It stores the patch; it does not verify. |
| `emit_artifact` | Records a result of a kind your agent declares in [`produces:`](/agents/writing-an-agent#contracts-what-a-step-produces-and-consumes) — Console's own kinds or one you've defined yourself. Rejects `amplify:finding`: findings always go through `report_finding` instead. |
| `list_artifacts` | Lists recorded artifacts, optionally filtered by kind. |
| `get_artifact` | Fetches one artifact's full content by id. |

## Detections

Expand Down
150 changes: 136 additions & 14 deletions agents/writing-an-agent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,26 @@ That's the entire contract. No build step, no registration.
| `allowed-tools` | No | string[] | Restricts the agent to these tools. Omit to inherit. |
| `maxIterations` | No | positive int | Budget of reasoning↔tool cycles before the agent is stopped. |
| `timeout` | No | positive int (ms) | Wall-clock limit for one execution. |
| `sequential-spawns` | No | boolean | Rejects concurrent `spawn_agent` calls, forcing one child at a time. |
| `produces` | No | list | The kinds of result this agent's step may record. See [contracts](#contracts-what-a-step-produces-and-consumes) below. |
| `consumes` | No | list | The kinds this agent's step reads, and how. See [contracts](#contracts-what-a-step-produces-and-consumes) below. |
| `mutates-worktree` | No | boolean | Declares that this agent edits files in the repository. See below. |

### The description is read at runtime
### Why the description matters

The description does real work. When a workflow runs your agent, the orchestrator reads the description to
compose that step's briefing and reflects the agent's stated role back at it. Other agents deciding whether
to delegate see only the name and description, so those two lines are the whole interface.
Two audiences read `description`, and neither is your agent itself:

A vague description produces a vague briefing. Write it as a precise statement of what the agent does and
what it produces:
- **You, choosing agents for a workflow** — the [workflow editor](/workflows/create-a-workflow#agents) and
the [agent library](/agents/library) show it as the one-line summary of what an agent does.
- **Other agents, deciding whether to delegate to it** — an agent choosing a sub-agent to spawn sees only its
name and description, so those two lines are the entire interface it has to go on.

Write it as an external, precise statement of the job and its output — not a note to yourself:

```yaml
# Good — states the job and the output
description: Audits third-party dependencies for known-vulnerable versions and unmaintained packages, and reports each one as a finding.

# Too vague to brief against
# Too vague to be useful to anyone deciding whether to use this agent
description: Dependency helper.
```

Expand All @@ -87,14 +91,132 @@ Both are ceilings, not targets. Leave them unset unless the agent is an outlier.
- Raise `timeout` for **orchestrators**, whose wall clock includes every child they spawn. Set it above the
worst-case sum of the children's durations.

### `sequential-spawns`
## Contracts: what a step produces and consumes

When you chain agents into a [workflow](/workflows/create-a-workflow), Console needs to know which step's
output feeds which step's input, so it can run steps that don't depend on each other together, wait for the
ones that do, and skip a step that has nothing to work on. You declare that with `produces` and `consumes`.

### `produces`

The kinds of result this agent's step may record:

```yaml
produces:
- kind: amplify:finding
```

`produces` is a *may*, never a promise — an agent that looked thoroughly and found nothing has still done
its job, and nothing checks that a declared kind was actually emitted.

A kind is either one of Console's own (prefixed `amplify:`, like `amplify:finding` or `amplify:patch`) or one
you define yourself. See [defining your own kind](#defining-your-own-kind) below.

### `consumes`

The kinds this agent's step reads, and how it wants them delivered:

```yaml
consumes:
- kind: amplify:finding
mode: each
```

| Field | Required | What it does |
| --- | --- | --- |
| `kind` | Yes | The kind this step reads. |
| `mode` | No | `each` or `all`. Defaults to `all`. |
| `group-by` | No | Only with `mode: each`. See below. |

**`mode: all`** (the default) runs your agent once, with everything matching that kind from earlier in the
chain — including an empty set. Use this for a step whose job is to summarize or report on the whole run:
"no issues found" is itself a result worth producing, so it needs to run even when there's nothing to say.

**`mode: each`** runs a separate copy of your agent per item (or per group, if you set `group-by`). Zero
items means the step doesn't run at all — it's recorded as [skipped](/workflows/running#run-statuses), not
as having run and found nothing. Use this when your agent's job only makes sense one item at a time, like
generating a fix for a single bug.

<Note>
A step can only consume a kind that an earlier step in the same workflow actually produces. Console checks
this when you save the workflow, not when it runs.
</Note>

### `group-by`

For a `mode: each` step, `group-by` controls what counts as "one item." By default every result is its own
item; naming fields under `group-by` batches results that share the same values into a single item instead.

`patch-generator`, Console's built-in patching agent, is the canonical example — one patch should fix every
match of the same underlying issue in the same file, not one patch per individual match:

```yaml
consumes:
- kind: amplify:finding
mode: each
group-by: [detection_id, properties.filePath]
```

Names in `group-by` come from the kind you're consuming — never from anything about how Console stores it:

- **A field the kind itself declares**, including one nested inside another declared field, like
`properties.filePath` above.
- **A documented attribute of that kind.** `amplify:finding` additionally exposes `detection_id` and
`severity` this way.
- **`id`** — every item is its own group, overriding any default grouping. `amplify:finding` already groups
by detection and file when you set no `group-by` of your own, so write `group-by: [id]` explicitly if you
want one child per finding instead.

An empty `group-by: []` isn't allowed: grouping by nothing means everything is one group, which is what
`mode: all` already means. Console rejects it and suggests `[id]` if that's what you meant.

<Note>
A result your grouping can't place — a finding with no detection behind it, say — is left out of that
step, with the reason recorded on the step. It still reaches any other step consuming the same kind with
`mode: all`.
</Note>

### `mutates-worktree`

Set this to `true` if your agent edits files in the repository:

```yaml
mutates-worktree: true
```

This states a fact, not a scheduling request. Console uses it to make sure two steps that both edit the
checkout never run at the same time and clobber each other's changes. Leave it unset (the default) for an
agent that only reads.

### Defining your own kind

If `produces` names a kind that doesn't already exist in your organization, attach a `schema:` block and
Console registers it the moment you save the agent — no separate setup step:

```yaml
produces:
- kind: scan-report
schema:
fields:
verdict:
type: string
enum: [clean, issues-found]
total_findings:
type: integer
```

Each field has a `type` (`string`, `number`, `integer`, `boolean`, `object`, or `array`) and can be marked
`required`. A `string` field can restrict its values with `enum`; an `object` field declares its own nested
`fields`; an `array` field declares the shape of its `items`.

By default an agent may spawn several sub-agents at once. Setting `sequential-spawns: true` makes a second
concurrent spawn return an error instead of queuing, which forces the agent to observe each child's result
before starting the next.
Saving the identical schema again is a no-op. Changing an already-registered kind's shape is not allowed —
Console rejects the save rather than reinterpreting artifacts you've already recorded under the old shape.
If a kind's shape needs to change, give it a new name.

Use it for orchestrators whose steps depend on each other. It applies only to the agent that declares it —
children are free to fan out.
<Note>
Names starting with `amplify:` are reserved for Console's own kinds. You can *consume* `amplify:finding`
or `amplify:patch` in your own agents, but you can't register a `schema:` under that prefix.
</Note>

## Writing one in the web console

Expand Down
5 changes: 3 additions & 2 deletions quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ Open **Workflows** and click **New workflow**.

Click **Save**.

Console's orchestrator reads the description as the goal and briefs your agent against it, so write it as an
instruction. See [create a workflow](/workflows/create-a-workflow#description).
The description is just a summary for your own reference — the agent you wrote in step 3 already carries
its own instructions, and those are what actually run. See
[create a workflow](/workflows/create-a-workflow#description).

## 5. Run it

Expand Down
Loading