> ## Documentation Index
> Fetch the complete documentation index at: https://sidenet.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Giving an agent a workflow

> Attach a workflow to an agent and it becomes a tool — always running the active version, streaming its progress into the chat.

Agents are good at judgement and bad at bookkeeping; workflows are the
opposite. Attaching a workflow to an agent gives you both in one turn: the
agent decides *whether* and *with what*, the workflow does the fixed sequence
exactly, and the result comes back for the agent to explain.

## Attaching

A workflow is attached on the agent's draft under `workflows`, separately
from `agentTools`:

```bash theme={null}
curl -X PATCH https://api.sidenet.ai/v1/agents/AGENT_ID/draft \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "workflows": [ { "workflow_id": "WORKFLOW_ID" } ] }'
```

In the Studio, the agent page has a **Workflows** section with a picker over
the organization's workflows. Each attached workflow shows the version that
will run, and clicking one opens the workflow editor in a drawer.

Publish and activate the agent as usual for the attachment to reach users.

<Note>
  Attaching a workflow to a **network** (`POST /v1/copilots/{id}/workflows`)
  is different: it lists the workflow on the network's read but does not
  make it callable, and a chat turn cannot be routed to a workflow. To have
  a network run a workflow, attach it to one of the network's agents.
</Note>

## What the agent sees

The workflow becomes a tool named `workflow-<name>`, where `<name>` is the
workflow's own name with anything outside letters, digits, `_` and `-`
replaced by `_`. Its description is the **workflow's description**, and its
arguments are the workflow's `input_schema`, nested under `inputData`.

That makes the workflow's name and description the text the model reads
when deciding to call it. Name workflows the way you would name a tool —
`refund_triage`, not "Refund triage v2 (new)" — and describe what they do and
when to use them in the same terms your agent's instructions use. A platform
guidance block teaches the agent the calling convention; you do not need to
explain `inputData` in your prompt.

## Always the active version

An agent runs the workflow's **active** version, resolved on every turn.
Publishing and activating a new workflow version therefore reaches every
agent that references it on the next turn, with no republish of the agent.
This is the one configuration path that skips the agent's own lifecycle,
and it is deliberate: the workflow's contract to the agent is its input
schema and description, and a new version that keeps those is a drop-in.

Drafts are unreachable by construction. A workflow that has **no active
version** contributes no tool at all — the agent builds and answers without
it rather than failing the turn — and the Studio flags the attachment with a
**No active version** badge so the gap is visible before a user notices the
agent "can't do that".

## What the user sees

While the workflow runs, its progress streams into the chat ahead of the tool
result:

* `data-tool-workflow` — an accumulating snapshot of the whole run under a
  stable id: overall `status` and, per step, `name`, `status`, `input` and
  `output`. Clients replace it in place rather than append.
* `data-tool-workflow-step` — one chunk per finished step with that step's
  output.

Then the ordinary tool result arrives with the workflow's final `result`, and
the agent writes its answer. If a rich-UI step ran inside the workflow, its
component is part of that result and the agent can anchor it in the answer.

A client that reconnects to the stream mid-run replays the buffered chunks
from the start; because the snapshots share an id, the replay collapses to
the same final state.

<Note>
  The snapshot's `name` is the workflow version's id, not its display name.
  A client rendering progress maps it back through the agent's attached
  workflows.
</Note>

## Failure

A failed run comes back to the agent as an error in the tool result — the
step that failed and why — rather than ending the stream. That is the
contract the platform's guidance gives the agent, so it can recover in the
same turn: explain, try different arguments, or fall back to its other
tools. A workflow step that fails inside the run fails the run; there is no
partial success to reason about.

## Design guidance

* **Keep the input schema small and named for humans.** The agent fills it
  from the conversation, so `guest_email` and `check_in_date` beat opaque ids
  when the user has said the words.
* **Let the workflow own the side effects.** If the workflow sends the
  email, the agent should not also have an email tool for the same purpose,
  or it will sometimes pick the wrong one.
* **A workflow runs to completion once invoked.** There is no approval pause
  inside it, and the attachment itself cannot be gated. If a step needs the
  user's consent, keep that write on the agent as a tool with
  `require_approval` and let the workflow do the reading and computing — see
  [Approvals](/docs/approvals).
