{
  "slug": "agent-workflows",
  "title": "Agent Workflows",
  "description": "Chain multiple agents into a single pipeline. One prompt in, one curation queue item out — even though several agents touched it.",
  "category": "concepts",
  "order": 7,
  "locale": "en",
  "translationGroup": "91eab3a1-176b-4b51-9465-e9076e0be813",
  "helpCardId": null,
  "content": "## What's a workflow?\n\nA workflow is an **ordered chain of agents** that runs as a single pipeline. Each step is a reference to an existing agent on your site. The first step receives the user prompt; every subsequent step receives the previous step's output and applies its own role on top.\n\nThe canonical example: **Writer → SEO Optimizer → Translator**.\n\n1. Writer takes \"Write an article about TypeScript generics\" → produces a draft\n2. SEO Optimizer takes that draft → returns the same draft restructured for search\n3. Translator takes the optimised draft → returns it in another language\n\nOnly the **final** step's output lands in the curation queue. Curators see one item per workflow run, not one per step. Every step's cost is summed and charged to the Cockpit budget once at the end. One `agent.completed` webhook fires.\n\n## How content flows between steps\n\nThe runner passes a synthesized Markdown prompt from one step to the next. For step 2 onwards, the user prompt looks like:\n\n```\nYou are processing existing content as part of a multi-step workflow. Apply\nyour role to the draft below and return the improved version using the same\nJSON schema.\n\n## Current draft\nTitle: <previous step's title>\nExcerpt: <previous step's excerpt>\nTags: <previous step's tags>\n\nBody:\n<previous step's content>\n```\n\nThis means each agent in the chain sees the *whole* draft as it currently stands, not just a diff. Agents are stateless across runs anyway — this just gives the next one enough context to do its job.\n\n## Creating a workflow\n\n1. Open `/admin/agents` and switch to the **Workflows** tab.\n2. Click **New workflow**.\n3. Give it a name (e.g. \"Writer → SEO → Translator\").\n4. Click the agent buttons in the order you want them to run. Each click adds a step.\n5. Drag the grip handles (⋮⋮) to reorder. Click the × on a row to remove a step.\n6. (Optional) Tick **Run on a schedule** and set frequency, time, max-per-run, and a default prompt to send to step 1 on each scheduled run.\n7. Click **Create**.\n\nEditing works the same way — click the pencil icon on an existing workflow card to reopen the form pre-populated with its current state. Save changes and the workflow is updated in place (its stats and createdAt are preserved).\n\n## Running a workflow\n\nEach workflow card has a prompt textarea and a **Run** button. Type a prompt, click Run, wait. The runner iterates the steps in order, each calling its agent's LLM through `executeAgentRaw` (the same code path as `runAgent` but without intermediate side effects). When the last step finishes:\n\n- One queue item is created with the final `contentData`\n- The Cockpit budget is charged the sum of all step costs\n- One `recordRun` analytics row is written, with `model: \"<step1> → <step2> → <step3>\"`\n- One `agent.completed` webhook fires with `agentName: \"Workflow: <name>\"`\n\nA single 3-step workflow takes roughly the same wall time as 3 separate agent runs. The savings are in cleanup, not throughput.\n\n## Scheduling\n\nWorkflows have the same `schedule` shape as individual agents — `enabled`, `frequency` (`daily` / `weekly` / `manual`), `time`, `maxPerRun`. The scheduler iterates workflows alongside agents in the same 5-minute tick.\n\nWorkflow lastRun keys are namespaced under `wf:<id>` in `_data/scheduler-state.json` so they don't collide with agent ids.\n\nScheduled workflow runs use the workflow's `defaultPrompt` field as the input to step 1. Manual runs always use whatever the curator types into the per-card textarea.\n\n## Per-step budget guards\n\nThere's no separate workflow-level budget. Instead, each step's agent is independently checked against its own per-agent cost guards (Phase 4) before its LLM call. If any step's agent is over its budget, the workflow halts at that step and throws.\n\nThis is generally what you want — it means a runaway agent in a chain still gets stopped by its own budget without you having to set workflow-specific caps.\n\n## JSON mode\n\nThe workflow create/edit form has a **JSON / UI** mode toggle in its header (the same `ModeToggle` component used by the structured array editor in collections). Switch to JSON to see the entire workflow body as formatted JSON. Edit it directly if you need a structure the visual editor doesn't expose. Switch back and the form re-validates from your edits.\n\nThe Save button works from either mode — it parses the JSON body before submission.\n\n## See also\n\n- [Agents overview](/docs/ai-agents) — what an agent is.\n- [Per-agent cost guards](/docs/agent-cost-guards) — how step-level budgets work.\n- [Agent templates](/docs/agent-templates) — start each step from a template instead of a one-off agent.",
  "excerpt": "What's a workflow?\n\nA workflow is an ordered chain of agents that runs as a single pipeline. Each step is a reference to an existing agent on your site. The first step receives the user prompt; every subsequent step receives the previous step's output and applies its own role on top.\n\nThe canonical ",
  "seo": {
    "metaTitle": "Agent Workflows — webhouse.app Docs",
    "metaDescription": "Chain multiple agents into a single pipeline. One prompt in, one curation queue item out, even though several agents touched it.",
    "keywords": [
      "webhouse",
      "cms",
      "ai",
      "workflows",
      "pipelines",
      "agents"
    ]
  },
  "createdAt": "2026-04-08T00:00:00.000Z",
  "updatedAt": "2026-04-08T00:00:00.000Z"
}