Skip to main content

Workflows

What workflows are

A workflow is a sequence of steps, each handled by a specialized agent, that together accomplish a complex task. Instead of one agent doing everything, workflows assign the right specialist to each step.

Example — Research & Report workflow:

Step 1 → Web Researcher agent — find sources on the topic
Step 2 → Fact Checker agent — verify the top claims
Step 3 → Summarizer agent — distill to key points
Step 4 → Report Generator agent — format as a structured document

Each step runs one after the other. If you want steps 1 and 2 to run in parallel, you configure execution_mode: parallel.


Built-in workflow templates

AI Partner ships with 9 pre-built templates ready to use immediately:

Research & Report

Web research → structured analysis → document. Best for market research, topic briefings, and deep dives.

Code & Document

Read a codebase → generate inline docs, README, and architecture notes. Best for onboarding and code handoff.

YouTube Content Pipeline

Topic research → script → thumbnails brief → SEO metadata. End-to-end video content in one run.

LinkedIn Thought Leadership

Research a trend → write a high-engagement LinkedIn post with hook, insight, and CTA.

Instagram Batch Content

Input a theme → generate 5–10 caption + visual-brief pairs ready for scheduling.

Consulting Discovery

Client brief → competitive landscape → gap analysis → slide-ready findings report.

Dynamic Investigation

Planner-driven: the engine discovers and injects steps at runtime based on what it finds. Good for open-ended research.

Foreach Summarizer

Feed a JSON array (companies, URLs, topics) → one parallel research step per item → unified summary.

Validation Loop

Writer → validator → loop back if rejected → final approved output. Demonstrates the on_validation_fail contract.


Starting a workflow

From the chat input

Type / in the chat input to open the Workflow Command Palette:

/ → shows workflow list
Research & Report
Code Review
Data Analysis
Content Creation
Competitive Analysis
Due Diligence
[+ Custom]

Select a template, describe your intent, optionally attach a document, and click Start. A live progress card appears in the conversation.

From the Workflows panel

Go to sidebar → Workflows:

  1. Pick a template
  2. Describe what you want
  3. (Optional) attach input files — documents, PDFs, spreadsheets, images
  4. Preview the step breakdown
  5. Click Run

The Workflows panel shows per-step agent status, live log lines, and output file previews as the pipeline runs.

Attaching input files

Click Attach files in the run form to upload one or more input documents. Files are saved as real binary files to the run's input/ workspace directory — not injected as text. Every agent in the pipeline can read them with read_file using the full workspace path that is automatically appended to each step's task.

Supported formats: .txt, .md, .csv, .pdf, .docx, .xlsx, .json, .zip, .png, .jpg, and more. Up to 10 files, 25 MB each.

Example: attach a competitor_brief.pdf before running a Due Diligence workflow. The researcher agent reads the PDF directly — no manual copy-paste.

Re-using parameters (presets)

Every time you successfully start a run, AI Partner saves the parameter values to browser storage (up to 3 per template). Next time you open the run form, click Load previous… in the header dropdown to pre-fill all fields instantly.

The Run Again button on a completed run's status banner also pre-fills the form with that run's exact parameters.


Choosing the delivery format

The run form has a Delivery format dropdown. Pick how the final deliverable is rendered:

FormatBest for
HTML (default)A polished, self-contained web page — opens anywhere, no dependencies
PDFPrint-ready A4 documents
PowerPoint (.pptx)Slide decks — one slide per ## heading
Word (.docx)Editable documents with real headings, bullets, and tables
Excel (.xlsx)Tabular/data deliverables — one sheet per table

How it works — content first, format second

Agents never generate binary files directly. Every step produces grounded markdown/json source (validated for content quality). When the run finishes, the engine runs a deterministic render step that converts the primary deliverable into the format you chose:

agent writes → output/report.md (the source — always kept)
↓ render
delivery_format = pptx → output/report.pptx (downloadable alongside the source)

This separation is deliberate: the model focuses on getting the content right, and a reliable renderer handles presentation. The markdown/json source is always kept and downloadable next to the rendered file.

Notes

  • HTML, PDF, Word render from any markdown deliverable (headings, bullets, tables, paragraphs are preserved — no literal ** or #).
  • PowerPoint turns each ## section into a slide.
  • Excel needs tabular data — markdown tables or a JSON array. If the source has no tables, it gracefully falls back to HTML (a warning is included in the completion event).
  • Rendering never fails a run. If a render step errors (e.g. a missing dependency), the run still completes and the markdown source is delivered, with a render_warning in the workflow:completed event.

The format is chosen per run — the same template can produce a PPTX one day and a PDF the next without editing the template.


Watching a workflow run

Text progress view

The Workflows panel (and the in-chat progress card) shows:

Workflow: Competitive Analysis
Topic: B2B project management tools
Status: Running • Step 2 of 4

Step 1: Web Researcher ✅ Complete (47s) → found 12 sources
Step 2: Fact Checker 🔄 Running → verifying pricing claims
Step 3: Summarizer ⏳ Waiting
Step 4: Report Generator ⏳ Waiting

Output files: (none yet)

When complete:

Step 4: Report Generator ✅ Complete (28s)

Output files:
→ competitive_analysis_2026_05_13.docx [Download]
→ competitive_analysis_2026_05_13.xlsx [Download]

Visual canvas view

Switch to the Canvas tab in the Workflows panel to see a live node graph of the workflow:

┌─────────────────────────────────────────────────────────┐
│ [Web Researcher]──────→[Fact Checker] │
│ ✅ 47s 🔄 running │
│ │ │
│ └──────────────→[Summarizer] │
│ ⏳ waiting │
│ │ │
│ ↓ │
│ [Report Generator] │
│ ⏳ waiting │
└─────────────────────────────────────────────────────────┘

Each node shows:

  • Agent profile name and avatar color
  • Status — running (spinner), complete (✅), waiting (⏳), or failed (❌)
  • Duration once finished
  • Files produced — click any node to see files that step generated

Arrows between nodes show data dependencies. File handoff arrows (with the file icon) indicate that one step's output is passed as input to the next.

The canvas updates in real time via Socket.IO events. Click any step node to open its detailed log in a side panel.


Saving a workflow from a conversation

After any strategy discussion, analysis session, or process walkthrough in chat, you can tell the agent to save the process as a reusable template — no JSON editing or form filling needed.

Examples of what to say:

  • "Save this as a workflow"
  • "Create a workflow from our trading strategy discussion"
  • "Make this repeatable"
  • "Add this to my workflows"

The agent will:

  1. Summarise the repeatable process from the conversation
  2. Call the create_workflow_from_context tool — which uses the same production template generator as the built-in templates (live agent slugs from the database, connected integration status, per-role tool rules)
  3. Validate the generated template — if validation fails, the agent refines its summary and retries once
  4. Save the template under your account
  5. Confirm with the step count and parameter names: "Workflow 'EMA Crossover Strategy' saved — 4 steps. Parameters: ticker, timeframe."

The Workflows panel refreshes automatically — the new template appears in the gallery and command palette (/) without any manual navigation.

What makes a good workflow candidate

Use this for repeatable processes — tasks you'll run again with different inputs each time:

Good candidateNot a workflow
Analyse a YouTube video → extract hooks → produce recreation brief"What's the best hook for this specific video?"
Fetch NSE tickers → apply EMA filter → backtest → produce report"What's the current market outlook?"
Scrape job postings → extract required skills → weekly skills-gap report"Find me some Python jobs"

The agent requires a repeatable process with variable inputs. One-shot analysis and single questions are handled by the standard chat / goal-execution path — they don't need to be workflows.

If validation fails

The agent will return the validation errors and what to fix. Refining your instructions helps:

  • Be specific about steps in order — what does each phase do?
  • Name the variable inputs that change per run (these become template parameters)
  • Describe the output files each step should produce

Then say: "Try saving this as a workflow again." The agent retries with the improved context.

Template ownership

Templates you save from chat are yours — not visible to other users in a shared deployment. Built-in system templates are visible to everyone and cannot be deleted via the API.


Creating a custom workflow

Go to Workflows → + New Template:

  1. 1
    Name and describe the workflow

    Give it a name and a description that appears in the command palette.

  2. 2
    Add steps

    For each step, specify:

    • Step name — e.g., "Gather competitor pricing"
    • Agent profile — which specialist handles this step
    • Instructions — what this agent should do with its input
    • Tool whitelist — limit which tools this step can use (optional)
    • Required integrations — fail early if a key is missing (optional)
  3. 3
    Set dependencies and execution mode

    Use depends_on to declare which prior steps must complete before this step starts. Steps that share no dependencies run in parallel automatically — no mode field needed.

    PatternHow to configure
    SequentialStep B lists Step A in depends_on
    ParallelSteps A and B both list the same prior step (or nothing) — they run concurrently
    Fan-out (foreach)Add a foreach config object to the step — one parallel execution per item in a JSON array
    Validation loopAdd on_validation_fail to the validator step — loops back to a prior step on rejection

    There is no execution_mode field. Parallelism is derived from the depends_on graph.

  4. 4
    Save and use

    Save the template. It appears immediately in the command palette (/) and Workflows panel.


Example: custom due diligence workflow

Templates are JSON. Parallelism comes from depends_on — steps A and B with no shared dependency run concurrently; step C that depends on both waits for both.

{
"id": "vendor-due-diligence",
"name": "Vendor Due Diligence",
"description": "Research a vendor before signing a contract",
"parameters": [
{ "name": "company", "type": "string", "description": "Vendor company name", "required": true }
],
"steps": [
{
"id": "background",
"name": "Company Background",
"agent": "researcher",
"task": "Research {{company}}: history, founders, investors, and public revenue signals. Write findings to handoff/background.md",
"produces": ["handoff/background.md"]
},
{
"id": "news",
"name": "News & Reputation Check",
"agent": "researcher",
"task": "Find recent news, G2/Trustpilot/Glassdoor reviews, and controversy for {{company}}. Write to handoff/news.md",
"produces": ["handoff/news.md"]
},
{
"id": "financials",
"name": "Financial Health Check",
"agent": "analyst",
"task": "Find funding history, last valuation, and profitability signals for {{company}}. Write to handoff/financials.md",
"produces": ["handoff/financials.md"]
},
{
"id": "summary",
"name": "Risk Summary",
"agent": "writer",
"task": "Read handoff/background.md, handoff/news.md, handoff/financials.md. Write a 1-page risk summary with a Go/No-Go recommendation to output/risk-summary.md",
"depends_on": ["background", "news", "financials"],
"consumes": ["handoff/background.md", "handoff/news.md", "handoff/financials.md"],
"produces": ["output/risk-summary.md"]
}
],
"output_files": ["output/risk-summary.md"]
}

background, news, and financials have no shared dependency so they run in parallel. summary waits for all three.


Foreach mode example

Use foreach to run the same analysis across multiple items in parallel:

Run the Competitive Analysis workflow for these companies:
Asana, Monday.com, ClickUp, Notion, Linear

With foreach mode on the research step:

  • 5 parallel Web Researcher agents run simultaneously
  • Each handles one company
  • The Summarizer step waits for all 5 to finish
  • The Report Generator produces one unified comparison document

Workflow vs. single goal

Single goalWorkflow
Best forAd-hoc, one-off tasksRepeatable, structured processes
Agent count1 main + up to 5 sub-agentsDefined specialist per step
OutputWhatever the goal producesStructured per-step outputs
ReuseLearned as a skillReused as a template
ControlGoal-level pause/cancelPer-step visibility and control

Use a single goal for "research NVIDIA earnings". Use a workflow for "every Friday, research our top 5 competitors and produce a weekly brief".


Determinism + intelligence — what makes workflows different

AI Partner workflows are a deterministic pipeline of intelligent agents. Two ideas matter:

  1. The pipeline shape is your contract. You author the DAG: which steps run, in what order, with what dependencies. The engine never re-orders or invents steps. n8n / Zapier work the same way at this layer.
  2. Each node is an agent, not a deterministic API call. Inside the step's tool_whitelist, the agent picks tools, retries on its own, decides which prompt structure to write, and adapts to what the data actually looks like. n8n nodes can't do this.

The result: predictable orchestration, intelligent execution.

A few specific engine behaviours follow from this contract:

Steps run autonomously

Workflow steps run with approvalMode='none'. The engine does NOT pause for human approval when the agent calls run_command, write_file, or any tool inside its scoped whitelist. Declaring the step in the template IS the authorization.

What still surfaces to you:

  • Tools in the engine's alwaysDeny list (payments, table drops, etc.) are blocked regardless.
  • Browser CAPTCHA / login walls trigger HITL via the partner-mode browser control state machine — these are genuinely machine-impossible blockers.

If a step needs a human gate, have the agent call request_user_approval explicitly as part of its task.

Tools are scoped per step

Every step in a built-in template declares a tool_whitelist listing exactly the tools that step's agent can call. A researcher step can't accidentally send_email; a writer step can't delete_file. This is the contract layer between "what the step is supposed to do" and "what it can actually do."

When you author your own templates, start from the default tool set for the agent's role and loosen it only when a specific step genuinely needs a tool that isn't included.

Retries don't double-fire side-effects

The engine keeps a per-step ledger. If a workflow is paused and resumed, or on_failure: "retry" triggers, it checks the ledger first — a "completed" step returns its cached result instead of relaunching the agent, so a step that sent an email or posted to Slack will NOT re-send on retry.

Side-effect-heavy steps are therefore safe to mark on_failure: "retry".

Integration calls produce audit receipts

Any step that calls a known integration tool (messaging_send, slack_send_message, twitter_post, gmail_send, create_pr, etc.) automatically gets a receipt captured on its StepResult:

{
"tool": "slack_send_message",
"result_id": "1734522345.000100",
"recipient": "#announcements",
"content_hash": "9c4f81a3b…",
"timestamp": "2026-05-19T14:22:10.123Z"
}

Receipts appear in the run-detail UI under each step's panel. They give you the channel's returned id (message_id, post_url, etc.), recipient, and a content hash for verification.

Step execution

Each workflow step is dispatched as a single scoped task to a sub-agent. There is no goal-decomposition pass — the step's task description is passed directly to the agent without an additional planning call.

This keeps steps deterministic and cheap:

PropertyValue
Agent instances per step1
LLM calls before first tool1 (the agent's first ReAct reason call)
Re-decompositionNone — the template IS the decomposition
Workspace path<workspace>/runs/<runId>/ — no cascading
Sub-delegationDisabled (noSubDelegate: true)

The workspaceRoot from run.workspace_root flows directly into the step's stepContract. Every file path the agent writes lands at <workspace>/runs/<runId>/handoff/<file> (or wherever the step task says), never at the global /workspace/handoff/.

Produces gates — how steps are validated

When a step declares produces[], the engine converts each path into a StepGate:

{ "path": "handoff/trend-analysis.md", "minBytes": 1, "maxAgeMs": 3600000 }

After the agent finishes, verifyProducesGates() checks each gate: file must exist, meet the minimum size, and have been written within the step's time window. A gate failure marks the step as failed and triggers the step's on_failure handler.

Because the agent is blocked from returning until it produces the required files (via the stepContract.gates list), produces verification and agent-level completion are guaranteed to agree.

For quality gating beyond existence/size checks, use a dedicated validator step and declare on_validation_fail on it — this loops back to a specified prior step (e.g., a writer) when the validator rejects output. See Validation Loop below.

Validation loop pattern

Add on_validation_fail to a validator step to loop back to a prior step when it rejects output:

{
"id": "validate",
"name": "Validate Report",
"agent": "validator",
"task": "Read output/report.md. If it meets the quality bar write APPROVED on line 1. Otherwise write REJECTED and your reason.",
"depends_on": ["write"],
"consumes": ["output/report.md"],
"produces": ["handoff/validation.md"],
"on_validation_fail": {
"goto": "write",
"max_loops": 3,
"inject_feedback": true
}
}
FieldDescription
gotoStep ID to jump back to when validation fails
max_loopsMaximum retry iterations before the workflow fails
inject_feedbackIf true, the validator's rejection reason is injected into the retry agent's context

Structured handoff contracts

Plain string consumes / produces entries do a basic existence check. For stricter contracts use ProducesGate objects and ConsumeRef objects — they add schema validation, resolved path injection, and hard-fail attribution when a contract is broken.

ProducesGate — typed output declaration

"produces": [{
"path": "handoff/data.json",
"alias": "market_data",
"format": "json",
"json_keys": ["title", "summary", "key_findings"],
"min_size": 50
}]
FieldDescription
pathWorkspace-relative path (required)
aliasLogical name referenceable by downstream ConsumeRef entries
formatjson | csv | markdown | text — informs schema gates and agent context
json_keysTop-level JSON keys that must exist — fails the step if any are missing
csv_columnsCSV header column names that must exist — fails the step if any are missing
min_sizeMinimum file size in bytes (default: 1)
must_containRegex (gims) that file content must match
must_be_freshFile mtime must be after step start — rejects stale files (default: true)

ConsumeRef — typed input reference

"consumes": [{
"from_step": "produce_data",
"alias": "market_data",
"inject_as": "market_data_path"
}]
FieldDescription
from_stepID of the step that declared the alias in its produces gate
aliasMatches ProducesGate.alias on the producing step
inject_asOptional: {{inject_as}} is substituted in the step's task with the resolved absolute path

Unlike plain string consumes (which auto-skip when a file is missing), a ConsumeRef that can't be resolved causes the step to hard-fail with attribution — a missing typed alias is a contract violation, not a transient condition.

The agent's task context also includes a schema hint:

- /workspace/runs/abc/handoff/data.json [file from "produce_data" (alias: market_data), format: json, JSON keys: [title, summary, key_findings]] (substituted as {{market_data_path}} above)

Full 2-step example

{
"steps": [
{
"id": "research",
"name": "Research",
"agent": "researcher",
"task": "Research {{topic}}. Write a JSON file to handoff/data.json with keys: title, summary, key_findings.",
"produces": [{
"path": "handoff/data.json",
"alias": "research_data",
"format": "json",
"json_keys": ["title", "summary", "key_findings"],
"min_size": 50
}]
},
{
"id": "write",
"name": "Write Report",
"agent": "writer",
"task": "Read the research from {{research_data_path}} and write a report to output/report.md.",
"depends_on": ["research"],
"consumes": [{ "from_step": "research", "alias": "research_data", "inject_as": "research_data_path" }],
"produces": ["output/report.md"]
}
]
}

Plain string consumes / produces remain fully supported — no changes needed for existing templates.

Live feed — workflow:step:log

While a step is running, the server emits a workflow:step:log Socket.IO event after every tool call:

{
"runId": "abc123",
"stepId": "trend_research",
"tool": "write_file",
"summary": "Wrote 3 KB to handoff/trend-analysis.md",
"success": true,
"iteration": 4
}

The Workflows panel subscribes to these events and renders a per-tool log line in the Live Action Feed panel. No polling — updates are pushed in real time.

Reasoning-notes handoff between steps

After each step finishes, its agent leaves a brief reasoning summary at handoff/.<step_id>_notes.md. When the next step launches, that note is injected into the agent's task as context. So each step doesn't start cold — it inherits what the previous specialist found, what it decided, and what to pay attention to.

You don't configure this. It's enabled for every workflow step automatically.


The publisher agent — multi-channel delivery

For workflows that end in "send a message" / "post to Slack" / "tweet this" / "email the team", use the publisher agent profile. It:

  • Reads pre-approved content from a file (never edits it)
  • Picks the right channel tool based on the step's task instructions (slack_send_message, twitter_post, gmail_send, or messaging_send for Telegram/Discord/WhatsApp/Signal)
  • Writes a receipt JSON to output/<step-id>-receipt.json for audit and retry safety

Example step:

{
"id": "notify_team",
"name": "Notify Team",
"agent": "publisher",
"tool_whitelist": ["read_file", "write_file", "create_directory",
"messaging_send", "slack_send_message"],
"required_integrations": ["slack"],
"depends_on": ["write_report"],
"consumes": ["output/report.md"],
"task": "Read output/report.md. Post a 2-line summary with the report link to the #announcements Slack channel.",
"produces": ["output/notify-receipt.json"]
}

For Telegram-only workflows the legacy telegram-reporter profile still works, but prefer publisher for new templates — it handles all channels uniformly.


Scheduling recurring workflow runs

Every template card in the Workflows gallery has a calendar icon (hover to reveal). Clicking it opens the Schedule modal:

  1. Choose a frequency: Daily at 9 AM, Weekdays at 9 AM, Monday at 9 AM, Every hour, or Custom (enter any valid cron expression)
  2. Fill in the template's parameters — these are fixed for every scheduled run
  3. Give the scheduled task a name
  4. Click Schedule

The task is registered in the Task Scheduler with mode: workflow. It fires at each cron tick exactly like a manually started run — a new run is created, the workspace is initialized, and agents execute step by step.

You can view, edit, pause, or delete scheduled workflow tasks in sidebar → Task Scheduler.

Example: schedule the Competitive Analysis workflow every Monday at 9 AM with niche: SaaS project management tools so a fresh brief is ready every week without any manual action.


Cost visibility

After each step completes, the engine queries the LLM usage log and attaches the cost to the step result. The Workflows panel shows:

  • Per step: $0.003 label next to the step duration in the step list
  • Run total: total cost in the green completion banner (e.g., $0.04)

Cost tracking works for any LLM provider — OpenAI, Groq, DeepSeek, Anthropic, local Ollama (where cost is $0.00). The values come from estimated_cost in the llm_usage table.


Completion callbacks

If you want to be notified when a run completes without keeping the browser open, expand POST callback on completion in the run form footer and enter a URL. When the run finishes (success or failure), AI Partner sends a JSON POST:

{
"runId": "wf_run_1748123456_a1b2c3d4",
"status": "completed",
"templateId": "competitive-analysis",
"completedAt": "2026-05-21T09:14:22.000Z",
"error": null
}

Use this to chain into Zapier, Make, or any webhook endpoint. The POST is fire-and-forget — a delivery failure does not affect the run.


Concurrent run limit

By default, a maximum of 3 workflow runs can be active simultaneously. Starting a 4th returns:

Concurrency limit reached (3 active runs). Try again shortly.

Your administrator can change this limit in the server configuration.


Deleting old runs

The Workflows gallery shows past runs in the History tab. Each run in a terminal state (completed / failed / cancelled) has a trash icon: clicking it removes the DB record and the workspace directory under runs/<runId>/. Active or paused runs don't show delete — cancel them first.