Skip to main content
Execution graphs let you describe a multi-step workflow as a picture: each box is a task an agent will perform, and arrows show which task depends on which. Comis runs the graph for you, fanning tasks out in parallel where possible and stitching the results back together. You can also ask an agent in plain English (for example, “have four analysts research NVDA in parallel, then a trader give a verdict”) — the agent translates that description into a graph and runs it. Under the hood, an execution graph is a directed acyclic graph (DAG). Each node in the graph is a sub-agent task. Nodes can run in parallel when they have no dependencies, or wait for upstream nodes to finish before starting. The graph coordinator handles scheduling, result forwarding, timeouts, budget enforcement, and failure cascading automatically.

When to use execution graphs

Execution graphs are the right tool when your workflow has multiple steps that need to coordinate:
  • Research pipelines — search for information, analyze results, write a summary (sequential chain)
  • Fan-out/fan-in — analyze 5 repositories in parallel, then synthesize findings into a single report
  • Adversarial debate — have bull and bear analysts argue before a synthesizer makes a final call (debate node type)
  • Consensus voting — have multiple agents vote independently in parallel (vote node type)
  • Editorial refinement — draft, review, and polish through sequential agents (refine node type)
  • Human-in-the-loop — pause for user approval before executing a high-stakes action (approval-gate node type)
  • Budget-controlled batch processing — process multiple items with a total cost ceiling
If you just need one agent to call another, use sub-agent sessions instead. Execution graphs are for workflows with multiple coordinated steps.

Quick example

Here is a 3-node graph that researches a topic, analyzes the findings, and writes a report:
tool: pipeline
action: execute
nodes:
  - node_id: research
    task: "Search the web for recent developments in quantum computing"
  - node_id: analyze
    task: "Analyze the research findings and identify key trends: {{research.result}}"
    depends_on: [research]
  - node_id: write
    task: "Write a 500-word summary of quantum computing trends based on: {{analyze.result}}"
    depends_on: [analyze]
label: "Quantum Computing Research"
The research node runs first (no dependencies). When it finishes, analyze starts with the research output injected into its task text via {{research.result}}. Finally, write produces the report.

Key concepts

Nodes

Each node represents a sub-agent task. A graph can have between 1 and 20 nodes. Every node requires a node_id (unique within the graph) and a task (the instruction for the sub-agent). Optional node settings:
SettingDescription
depends_onArray of upstream node IDs that must complete first
agentAgent ID to run this node (defaults to the calling agent)
modelModel override for this node
timeout_msPer-node timeout in milliseconds
max_stepsMaximum agentic steps for the sub-agent
barrier_modeWhen to proceed if dependencies fail: all, majority, or best-effort
retriesNumber of automatic retries on failure (0-3, default 1). Uses exponential backoff: 1s, 2s, 4s, 8s, capped at 30s
type_idBuilt-in node type: agent, debate, vote, refine, collaborate, approval-gate, or map-reduce
type_configType-specific configuration (required when type_id is set). See Node Types
context_modeControls upstream output verbosity: full (default), summary (500 chars + shared dir reference), refs (file path references only), or none (no upstream outputs)

Node types

By default, each node spawns a single sub-agent to execute its task. For multi-agent orchestration patterns, set type_id and type_config to use a built-in node type:
TypePatternExample
debateAdversarial rounds between agentsBull vs bear analysis
voteIndependent parallel votingAnalyst consensus
refineSequential improvement chainDraft -> edit -> polish
collaborateSequential additive contributionsTeam brainstorming
approval-gateHuman checkpoint via chat”Approve before trading”
map-reduceParallel work + reducerMulti-source research
See Node Types for configuration details and examples.

Dependencies

Nodes declare their dependencies using depends_on arrays. The graph coordinator validates the dependency structure at define time — it detects cycles, missing references, duplicate node IDs, and self-dependencies. Nodes with no dependencies are root nodes and start immediately.

Barrier modes

Barrier modes control when a fan-in node (a node with multiple dependencies) should proceed:
ModeBehavior
all (default)Every dependency must complete successfully
majorityMore than 50% of dependencies must complete, and all must reach a terminal state
best-effortAt least one dependency must complete, and all must reach a terminal state
All barrier modes wait for every dependency to reach a terminal state (completed, failed, or skipped) before evaluating. A best-effort node does not fire as soon as one dependency completes — it waits until all dependencies have finished, then checks that at least one succeeded.

Failure policies

The graph-level on_failure setting controls what happens when a node fails:
PolicyBehavior
fail-fast (default)A failed node immediately cascades: all downstream dependents are skipped
continueDownstream nodes are only skipped if their barrier can never be satisfied. Nodes whose barrier is still satisfiable keep running

Data flow

Nodes consume outputs from upstream nodes using {{nodeId.result}} templates directly in the task text. The nodeId in the template must appear in the consuming node’s depends_on array.
- node_id: summarize
  task: "Summarize the analysis: {{analyze.result}}"
  depends_on: [analyze]
When analyze completes, its output text replaces {{analyze.result}} in the summarize node’s task description. User-provided variables: Use ${VARIABLE_NAME} syntax for values the user provides before execution. Variables are resolved at graph.execute time via the variables parameter. See the Developer Guide for details.
Nodes can only reference outputs from nodes listed in their depends_on array. The graph coordinator validates this at execution time and rejects invalid references.

Shared data folder

Each graph execution gets a temporary shared directory at ~/.comis/graph-runs/{graphId}/. All nodes in the graph can read and write files in this folder, making it useful for exchanging large payloads (reports, data files, images) that do not fit in text-based template passing. The folder persists after graph completion so output files remain accessible.

Budget and timeouts

Graphs support resource limits at both the node and graph level:
  • Per-node timeout (timeout_ms on the node) — kills the node’s sub-agent if it runs too long
  • Graph-level timeout (timeout_ms on the graph) — cancels all remaining nodes if the entire graph exceeds the time limit
  • Budget limits (budget.max_tokens, budget.max_cost) — cancels the graph if cumulative token usage or cost across all nodes exceeds the limit

Graph lifecycle

Every graph follows the same lifecycle:
  1. Define — validate the graph structure (DAG check, dependency resolution) without executing
  2. Execute — start the graph; root nodes run immediately, others wait for dependencies
  3. Monitor — check status of running and completed nodes
  4. Complete or cancel — the graph reaches a terminal state when all nodes finish, or it can be manually cancelled
Node status transitions: pending -> ready -> running -> completed / failed / skipped Graph status values: running, completed, failed, cancelled

Worked example: four-analyst NVDA research team

A common request: “Have four analysts research NVDA in parallel, then have a trader read every analysis and give a final verdict.” This is a classic fan-out / fan-in pattern. Here is the complete graph:
tool: pipeline
action: execute
label: "NVDA Research Team"
on_failure: continue
budget:
  max_tokens: 2000000
  max_cost: 5.00
nodes:
  # Fan-out: four analysts run in parallel (no depends_on)
  - node_id: fundamental
    task: "Analyze NVDA fundamentals: revenue growth, margins, P/E, balance sheet, key product lines. Cite sources."
    agent: equity-analyst
  - node_id: technical
    task: "Analyze NVDA technicals: 50/200 DMA, RSI, MACD, recent breakouts, volume profile."
    agent: technical-analyst
  - node_id: macro
    task: "Analyze macro context for NVDA: AI capex cycle, GPU demand, geopolitical risks, semi supply chain."
    agent: macro-analyst
  - node_id: sentiment
    task: "Analyze NVDA sentiment: institutional flows, analyst targets, options skew, social mentions."
    agent: sentiment-analyst

  # Fan-in: the trader waits for all four (barrier_mode: all is the default)
  - node_id: verdict
    task: |
      You are a senior trader. Read four analyses and issue a final verdict
      (BUY / HOLD / SELL) with reasoning, key risks, and a price target.

      Fundamental analysis:
      {{fundamental.result}}

      Technical analysis:
      {{technical.result}}

      Macro context:
      {{macro.result}}

      Sentiment:
      {{sentiment.result}}
    agent: senior-trader
    depends_on: [fundamental, technical, macro, sentiment]
    barrier_mode: all
The DAG looks like this:
        fundamental ─┐

        technical ───┤
                     ├──► verdict
        macro ───────┤

        sentiment ───┘
The four analysts run concurrently. Once all four reach a terminal state and all succeeded (barrier_mode: all), the verdict node fires with their outputs templated into its task. If you set barrier_mode: majority on verdict, it would fire when any three of the four analysts succeed — useful when you want resilience to a single flaky tool. With best-effort, it fires as long as one succeeds. The graph-level on_failure: continue means a single analyst failing does not cancel the others — the verdict node decides what to do with whichever analyses completed. You can build this same graph in the Visual Builder by dragging four nodes, connecting them all to a fifth node, and pasting the task templates.

The pipeline tool

Agents create and manage execution graphs using the pipeline built-in tool. It supports 9 actions: define, execute, status, outputs, cancel, save, load, list, and delete. See the Pipeline Tool Guide for the complete action reference with examples.

Visual builder

The web dashboard includes a visual graph builder where you can design execution graphs by dragging and connecting nodes, then save and execute them directly. See the Visual Builder Guide for details.

Configuration

Execution graphs require agent-to-agent communication to be enabled:
security:
  agentToAgent:
    enabled: true
Without this setting, the pipeline tool will not be available to agents. See Configuration Reference for all security settings.

Events

The graph coordinator emits three events during execution:
EventWhenKey fields
graph:startedGraph execution beginsgraphId, label, nodeCount
graph:node_updatedA node transitions to a new statusgraphId, nodeId, status, durationMs, error
graph:completedGraph reaches terminal stategraphId, status, durationMs, nodesCompleted, nodesFailed, nodesSkipped, cancelReason
See Event Bus for the full event reference.

Pipeline Tool Guide

Complete reference for the pipeline tool’s 9 actions

Visual Builder

Design and run graphs from the web dashboard

Developer API

API reference for building graph integrations

Sub-Agent Sessions

How each graph node runs as a sub-agent