Get Started

Workflows

Multi-agent pipelines with DAG execution. Define a graph of steps once, run it many times with different inputs. Independent branches execute in parallel automatically. Steps can fan out, branch on conditions, wait for humans, call webhooks, transform data, and dynamically splice new steps into a running DAG.

Workflows require primitivesEnabled: true on your platform config. Available on Pro and Enterprise plans.

Creating a workflow

Use the typed builder API to construct a workflow. Call .build() at the end to produce a WorkflowCreateOpts object you pass to theazo.workflows.create().

workflow.ts
import { Theazo, workflow } from 'theazo'

const theazo = new Theazo({ apiKey: 'th_live_...' })

const wf = await theazo.workflows.create(
  workflow('lead-enrichment')
    .step('scrape', {
      agent: 'web-researcher',        // what the agent does comes from its definition
      input: { website: '$.input.website' },  // input feeds it data (JSONPath)
    })
    .step('enrich', {
      agent: 'data-enricher',
      dependsOn: ['scrape'],
      input: {
        companyData: '$.scrape.output.company',
        rawHtml:     '$.scrape.output.html',
      },
    })
    .condition('check-fit', {
      if:   '$.enrich.output.icp_score >= 70',
      then: 'send-to-crm',            // step id (or { agent: 'closer' })
      else: 'archive',
      dependsOn: ['enrich'],
    })
    .build()
)

console.log(wf.id)       // 'wf_a1b2c3'
console.log(wf.version)  // 1

Input and output schemas

Attach JSON Schema validators to inputSchema and outputSchema. Theazo validates the run input at trigger time and the final output before marking the run complete. Invalid inputs are rejected with a 422 before any agents start.

schema.ts
const wf = await theazo.workflows.create(
  workflow('lead-enrichment')
    .input({
      type: 'object',
      required: ['website', 'userId'],
      properties: {
        website: { type: 'string', format: 'uri' },
        userId:  { type: 'string' },
        priority: { type: 'string', enum: ['low', 'high'] },
      },
    })
    .output({
      type: 'object',
      required: ['score', 'enrichedLead'],
      properties: {
        score:        { type: 'number', minimum: 0, maximum: 100 },
        enrichedLead: { type: 'object' },
      },
    })
    // ... steps ...
    .build()
)

Step types

Each step has a type that controls how it executes. All step types share id, dependsOn, inputMap, and onStepFailure. There are 10 step types.

agentdefault

Runs an agent definition in its own sandbox and model loop. What the agent does comes from its definition; inputMap feeds it data via JSONPath.

{
  id: 'scrape',
  type: 'agent',
  agent: 'web-researcher',
  inputMap: { website: '$.input.website' },
}
parallel

Fans out to multiple sub-steps simultaneously. All sub-steps must complete (or fail per policy) before downstream dependents proceed.

{
  id: 'research-all',
  type: 'parallel',
  branches: [
    { id: 'twitter',  type: 'agent', agent: 'social-agent', inputMap: { company: '$.input.company' } },
    { id: 'linkedin', type: 'agent', agent: 'social-agent', inputMap: { company: '$.input.company' } },
    { id: 'news',     type: 'agent', agent: 'news-agent',   inputMap: { company: '$.input.company' } },
  ],
}
condition

Branches execution based on a JSONPath expression in if, evaluated against the current run state. Resolves to the then or else target — a step id, or an inline { agent } target.

{
  id: 'check-score',
  type: 'condition',
  dependsOn: ['score'],
  if: '$.score.output.score >= 70',
  then: 'send-to-crm',   // step id (or { agent: 'closer' })
  else: 'archive',
}
delay

Pauses execution for a fixed duration before proceeding. The agent sandbox is released during the wait — no compute cost accrues.

{
  id: 'wait-24h',
  type: 'delay',
  duration: '24h',    // duration string: ms | s | m | h | d
  dependsOn: ['send-intro-email'],
}
approval

Pauses the run and waits for a human approval decision via the Approvals API or dashboard. On timeout, the defaultAction applies.

{
  id: 'approve-send',
  type: 'approval',
  action: 'send_email',
  timeout: '4h',
  defaultAction: 'deny',
  dependsOn: ['draft-email'],
}
webhook

POSTs a payload to an external URL and waits for a callback (or fires-and-forgets). Body is constructed from inputMap values.

{
  id: 'notify-crm',
  type: 'webhook',
  url: 'https://hooks.yourapp.com/lead-created',
  method: 'POST',
  waitForCallback: false,
  inputMap: { lead: '$.enrich.output.lead' },
  headers: { 'X-Source': 'theazo' },
}
transform

Runs a pure JSONPath reshaping operation — no agent, no sandbox. Use to restructure data between steps without paying for compute. Transform expressions are serializable JSONB; never use JS functions here.

{
  id: 'reshape',
  type: 'transform',
  dependsOn: ['research-all'],
  expression: {
    twitterHandle: '$.twitter.output.handle',
    linkedinUrl:   '$.linkedin.output.url',
    latestHeadline: '$.news.output.articles[0].title',
    company:        '$.input.company',
  },
}
map

Iterates an array from a previous step and runs a sub-step for each element. Controlled concurrency via concurrency. Produces an array output in the same order as the input.

{
  id: 'score-each',
  type: 'map',
  dependsOn: ['scrape'],
  over: '$.scrape.output.leads',      // JSONPath to the array
  concurrency: 5,
  step: {                              // each array item is passed as this agent's input
    id: 'score-lead',
    type: 'agent',
    agent: 'scorer',
  },
}
planner

Dynamic DAG expansion. Runs an agent whose output is a list of new step definitions. Theazo splices those steps into the running DAG at runtime. Useful when the number or shape of tasks is not known at workflow-definition time.

{
  id: 'plan',
  type: 'planner',
  agent: 'task-planner',
  description: 'Given the input leads, produce a list of research tasks',
  // Agent must output: { steps: WorkflowStep[] }
  // Theazo validates the schema and splices them into the DAG
  dependsOn: ['pre-filter'],
}
wait

Suspends the run until a named external event is delivered via POST /v1/workflow-runs/:runId/resume (or workflows.resumeRun()). The event payload becomes the step's output, so downstream steps can read it via JSONPath. If timeout elapses before the event arrives, a background sweep fires automatically: the run continues from onTimeout (the wait resolves with output.timedOut = true), or fails if no onTimeout is set — so a run never hangs forever. Use for long-running async integrations. Unlike delay (fixed duration) and approval (human decision), wait blocks on an arbitrary external signal.

{
  id: 'wait-payment',
  type: 'wait',
  event: 'payment.confirmed',   // resumeRun({ event: 'payment.confirmed', payload }) continues the run
  timeout: '48h',               // optional
  onTimeout: 'send-reminder',   // optional: step id to continue from on timeout
  dependsOn: ['send-invoice'],
}

Data passing with JSONPath

Steps pass data forward using inputMap. Keys become named variables available to the step. Values are JSONPath strings evaluated against the full run state. All values are serializable to JSONB — never use JavaScript functions in step definitions.

// JSONPath reference patterns
inputMap: {
  leads:       '$.scrape.output.leads',           // array from prior step
  companyName: '$.scrape.output.company.name',    // nested field
  rawInput:    '$.input.website',                 // original workflow input
  firstItem:   '$.scrape.output.leads[0]',        // array index
}

Shared state

Steps can declare which keys they read and write from a shared state bag. The state bag persists across the entire run and survives hibernation. Declare stateReads and stateWrites per step so Theazo can detect conflicts and serialize concurrent writers.

shared-state.ts
const wf = await theazo.workflows.create(
  workflow('pipeline')
    .step('writer', {
      agent: 'data-agent',
      stateWrites: ['company', 'metadata'],   // keys this step writes
    })
    .step('reader', {
      agent: 'scorer',
      dependsOn: ['writer'],
      stateReads: ['company'],               // keys this step reads
    })
    .build()
)

// Shared state is written/read by steps (stateWrites/stateReads above);
// it starts empty on each run.
const run = await theazo.workflows.run(wf.id, {
  userId: 'user_123',
  sessionId: 'ses_abc123',   // the end-user's session
  input: { website: 'https://acme.com' },
})

Workflow policy

Attach a WorkflowPolicy to enforce tool restrictions, cost budgets, and approval gates across all steps. Policy applies to every agent launched by the workflow — individual step overrides are not supported.

policy.ts
const wf = await theazo.workflows.create(
  workflow('secure-pipeline')
    .withPolicy({
      allowTools: ['exec_code', 'read_file', 'list_files'],
      denyTools:  ['shell_exec', 'write_file'],
      requireApprovalFor: ['send_email', 'update_crm'],
      maxCostPerStep: { amount: 50, currency: 'usd' },  // $0.50 per step
      maxTotalCost:   { amount: 500, currency: 'usd' }, // $5.00 per run
    })
    // ... steps ...
    .build()
)

If a step exceeds maxCostPerStep, it is paused and a workflow.step.cost_exceeded webhook fires. If the run total exceeds maxTotalCost, the entire run is cancelled.

Per-step error routing

By default a failing step stops the run (respecting the top-level onFailure policy). Override per step with onStepFailure to route to a recovery step instead.

{
  id: 'enrich',
  type: 'agent',
  agent: 'data-enricher',
  dependsOn: ['scrape'],
  inputMap: { company: '$.scrape.output.company' },
  onStepFailure: { action: 'goto', target: 'enrich-fallback' },
},
{
  id: 'enrich-fallback',
  type: 'agent',
  agent: 'data-enricher-lite',
  inputMap: { company: '$.scrape.output.company' },
}

Running a workflow

run.ts
const run = await theazo.workflows.run(wf.id, {
  userId: 'user_123',
  sessionId: 'ses_abc123',   // the end-user's session
  input: {
    website:  'https://acme.com',
    priority: 'high',
  },
  idempotencyKey: 'lead-acme-2026-06-05',  // safe to retry — won't double-run
})

console.log(run.id)      // 'wfrun_abc123'
console.log(run.status)  // 'running'
idempotencyKey is scoped per platform. Submitting the same key within 24 hours returns the existing run rather than starting a new one. Use it to safely retry on network errors.

Checking run status

const run = await theazo.workflows.getRun('wfrun_abc123')

console.log(run.status)          // 'completed' | 'running' | 'failed' | 'partial' | 'cancelled'
console.log(run.steps)           // per-step: { id, status, cost, output, startedAt, completedAt }
console.log(run.cost)            // { amount: 2340, currency: 'usd' }
console.log(run.duration)        // 184 (seconds)
console.log(run.canRetryFrom)    // 'enrich' — resume from this step on partial failure

Partial results

When a non-critical step fails and the run continues, the run status becomes partial. The canRetryFrom field names the first failed step. retryRun() resets failed steps and re-runs — already-completed steps are skipped, not re-executed.

if (run.status === 'partial') {
  // Retry — failed steps are reset; completed steps are not re-run
  await theazo.workflows.retryRun(run.id)
}

Cancelling a run

await theazo.workflows.cancelRun('wfrun_abc123')
// In-progress agents are paused; partial results preserved

SSE streaming

Subscribe to a run's live event stream using theazo.workflows.streamRun(runId). Events are Server-Sent Events delivered as an AsyncIterable<StreamEvent>.

stream.ts
for await (const event of theazo.workflows.streamRun('wfrun_abc123')) {
  switch (event.type) {
    case 'step.started':
      console.log('Started:', event.stepId)
      break
    case 'step.completed':
      console.log('Done:', event.stepId, '— cost', event.cost)
      break
    case 'step.failed':
      console.error('Failed:', event.stepId, event.error)
      break
    case 'run.completed':
      console.log('Workflow done. Total cost:', event.totalCost)
      break
    case 'run.partial':
      console.warn('Partial result. Retry from:', event.canRetryFrom)
      break
    case 'approval.pending':
      console.log('Waiting for approval on:', event.action)
      break
  }
}

Cost estimation

Before running an expensive workflow, call theazo.workflows.estimate() with a sample input. Theazo runs a dry-pass — resolving the DAG, counting expected steps and agent calls — and returns a cost estimate without executing any agents.

estimate.ts
const estimate = await theazo.workflows.estimate('wf_a1b2c3', {
  input: { website: 'https://acme.com', priority: 'high' },
})

console.log(estimate.minCost)  // { amount: 80,  currency: 'usd' }
console.log(estimate.maxCost)  // { amount: 420, currency: 'usd' }
console.log(estimate.steps)    // per-step estimate breakdown

Versioning

Every call to theazo.workflows.update() increments the version integer. In-flight runs continue on the version they started on; new runs pick up the latest version automatically.

// Update the workflow definition — version increments atomically
const updated = await theazo.workflows.update('wf_a1b2c3', {
  steps: [ /* new step list */ ],
})
console.log(updated.version)  // 2

// New runs use the latest version; the run records which one it ran on
const run = await theazo.workflows.run(updated.id, {
  userId: 'user_123',
  sessionId: 'ses_abc123',
  input: { website: 'https://acme.com' },
})
console.log(run.workflowVersion)  // 2

Complete example

A full lead pipeline: parallel research, data transform, map-score each lead, conditional routing, and approval gate before CRM push.

lead-pipeline.ts
import { Theazo, workflow } from 'theazo'

const theazo = new Theazo({ apiKey: 'th_live_...' })

const wf = await theazo.workflows.create(
  workflow('lead-pipeline')
    .input({
      type: 'object',
      required: ['company', 'website'],
      properties: {
        company: { type: 'string' },
        website: { type: 'string', format: 'uri' },
      },
    })
    .withPolicy({
      allowTools: ['exec_code', 'read_file'],
      requireApprovalFor: ['update_crm'],
      maxTotalCost: { amount: 1000, currency: 'usd' },
    })

    // Step 1 — parallel social + news research
    .parallel('research', [
      { id: 'twitter',  type: 'agent', agent: 'social-agent', inputMap: { company: '$.input.company' } },
      { id: 'linkedin', type: 'agent', agent: 'social-agent', inputMap: { company: '$.input.company' } },
      { id: 'news',     type: 'agent', agent: 'news-agent',   inputMap: { company: '$.input.company' } },
    ])

    // Step 2 — transform into a clean shape (no agent, no cost)
    .transform('reshape', {
      twitter:  '$.twitter.output',
      linkedin: '$.linkedin.output',
      news:     '$.news.output.articles',
      company:  '$.input.company',
    }, { dependsOn: ['research'] })

    // Step 3 — score each news article (concurrency=3); each array item is the agent input
    .map('score-news', {
      over: '$.reshape.output.news',
      agent: 'relevance-scorer',
      concurrency: 3,
      dependsOn: ['reshape'],
    })

    // Step 4 — final scoring with all signals
    .step('score', {
      agent: 'lead-scorer',
      dependsOn: ['score-news'],
      input: {
        twitter:    '$.reshape.output.twitter',
        linkedin:   '$.reshape.output.linkedin',
        newsScores: '$.score-news.output',
        company:    '$.input.company',
      },
    })

    // Step 5 — conditional routing on the score
    .condition('route', {
      if:   '$.score.output.score >= 70',
      then: 'approve-crm',   // step id
      else: 'archive',
      dependsOn: ['score'],
    })

    // Step 6a — high score → approval gate before CRM
    .approval('approve-crm', 'update_crm', { timeout: '4h', defaultAction: 'deny' })

    // Step 6b — low score → archive
    .step('archive', {
      agent: 'archiver',
      input: { lead: '$.reshape.output', score: '$.score.output' },
    })

    .build()
)

// Estimate cost before running
const estimate = await theazo.workflows.estimate(wf.id, {
  input: { company: 'Stripe', website: 'https://stripe.com' },
})
console.log('Estimated cost:', estimate.maxCost)  // { amount: 420, currency: 'usd' }

// Run it
const run = await theazo.workflows.run(wf.id, {
  userId: 'user_456',
  sessionId: 'ses_abc123',
  input: { company: 'Stripe', website: 'https://stripe.com' },
  idempotencyKey: 'lead-stripe-2026-06-05',
})

// Stream live events
for await (const event of theazo.workflows.streamRun(run.id)) {
  if (event.type === 'step.completed') {
    console.log(event.stepId, 'done — cost:', event.cost)
  }
  if (event.type === 'run.completed') {
    console.log('Total cost:', event.totalCost)
    break
  }
}

API reference

POST/v1/workflows

Create a workflow definition. Returns the workflow with version=1.

Parameters

namestringHuman-readable workflow name.
descriptionstringWhat the workflow does.
stepsobject | object | object | object | object | object | object | object | object | object[]requiredThe workflow’s steps — a DAG. See the step-type catalog.
inputSchemaRecord<string, unknown>JSON Schema for the run input, validated on each run.
outputSchemaRecord<string, unknown>JSON Schema describing the run output.
policyobjectTool / cost / concurrency guardrails applied to every step.
onFailure'pause' | 'retry' | 'skip' | 'abort'What to do when a step fails. Default: pause.
retriesobjectAutomatic step-retry policy.
timeoutstringMax wall-clock for the whole run, e.g. "1h".
concurrencynumberMax steps run in parallel. Default: unbounded.
plannerPolicyRecord<string, unknown>Configuration for planner steps (dynamic step generation).

Response

Workflow

Example

bash
curl -X POST https://api.theazo.com/v1/workflows \
  -H "Authorization: Bearer th_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "lead-enrichment",
    "steps": [{ "id": "scrape", "type": "agent", "agent": "web-researcher", "inputMap": { "website": "$.input.website" } }]
  }'
GET/v1/workflows

List all workflow definitions for this platform. Ordered by createdAt descending.

Response

Workflow[]

Example

bash
curl https://api.theazo.com/v1/workflows \
  -H "Authorization: Bearer th_live_..."
GET/v1/workflows/:id

Fetch a single workflow definition by ID.

Response

Workflow

Example

bash
curl https://api.theazo.com/v1/workflows/wf_a1b2c3 \
  -H "Authorization: Bearer th_live_..."
PUT/v1/workflows/:id

Update a workflow definition (all fields optional; omitted fields keep their stored value). Increments version atomically. In-flight runs are unaffected.

Parameters

namestringHuman-readable workflow name.
descriptionstringWhat the workflow does.
stepsobject | object | object | object | object | object | object | object | object | object[]requiredThe workflow’s steps — a DAG. See the step-type catalog.
inputSchemaRecord<string, unknown>JSON Schema for the run input, validated on each run.
outputSchemaRecord<string, unknown>JSON Schema describing the run output.
policyobjectTool / cost / concurrency guardrails applied to every step.
onFailure'pause' | 'retry' | 'skip' | 'abort'What to do when a step fails. Default: pause.
retriesobjectAutomatic step-retry policy.
timeoutstringMax wall-clock for the whole run, e.g. "1h".
concurrencynumberMax steps run in parallel. Default: unbounded.
plannerPolicyRecord<string, unknown>Configuration for planner steps (dynamic step generation).

Response

Workflow

Example

bash
curl -X PUT https://api.theazo.com/v1/workflows/wf_a1b2c3 \
  -H "Authorization: Bearer th_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "lead-enrichment-v2" }'
DELETE/v1/workflows/:id

Delete a workflow definition. Does not cancel in-progress runs.

Response

void

Example

bash
curl -X DELETE https://api.theazo.com/v1/workflows/wf_a1b2c3 \
  -H "Authorization: Bearer th_live_..."
POST/v1/workflows/:id/runs

Start a new run of a workflow. Returns 202 with the run object. Execution is async.

Parameters

userIdstringrequiredUser the run is attributed to.
sessionIdstringrequiredSession the run executes under — its environment is inherited.
inputRecord<string, unknown>Input payload passed to the workflow.
idempotencyKeystringDedupe key — a repeat with the same key returns the existing run instead of starting a new one.

Response

WorkflowRun

Example

bash
curl -X POST https://api.theazo.com/v1/workflows/wf_a1b2c3/runs \
  -H "Authorization: Bearer th_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_123",
    "sessionId": "ses_abc123",
    "input": { "website": "https://acme.com" },
    "idempotencyKey": "lead-acme-2026-06-05"
  }'
GET/v1/workflows/:id/runs

List all runs for a workflow. Ordered by createdAt descending.

Parameters

statusstringFilter by status: running | completed | failed | partial | cancelled.
limitnumberMax results to return. Default 50.

Response

WorkflowRun[]

Example

bash
curl "https://api.theazo.com/v1/workflows/wf_a1b2c3/runs?status=completed&limit=20" \
  -H "Authorization: Bearer th_live_..."
GET/v1/workflow-runs/:runId

Fetch current status, per-step results, and cost for a run.

Response

WorkflowRun

Example

bash
curl https://api.theazo.com/v1/workflow-runs/wfrun_abc123 \
  -H "Authorization: Bearer th_live_..."
GET/v1/workflow-runs/:runId/stream

SSE stream of run events. Returns text/event-stream. Events: step.started, step.completed, step.failed, approval.pending, run.completed, run.partial.

Response

text/event-stream

Example

bash
curl https://api.theazo.com/v1/workflow-runs/wfrun_abc123/stream \
  -H "Authorization: Bearer th_live_..." \
  -H "Accept: text/event-stream"
POST/v1/workflow-runs/:runId/cancel

Cancel an in-progress run. In-flight agents are paused, partial results preserved.

Response

WorkflowRun

Example

bash
curl -X POST https://api.theazo.com/v1/workflow-runs/wfrun_abc123/cancel \
  -H "Authorization: Bearer th_live_..."
POST/v1/workflow-runs/:runId/resume

Resume a run paused on a wait step. Supply the event name (must match the step's event field) and an optional payload, which becomes the step's output. Returns 409 if the run is not paused.

Parameters

eventstringrequiredName of the awaited event being delivered to a paused `wait` step.
payloadRecord<string, unknown>Event payload made available to the resumed workflow.

Response

WorkflowRun

Example

bash
curl -X POST https://api.theazo.com/v1/workflow-runs/wfrun_abc123/resume \
  -H "Authorization: Bearer th_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "event": "payment.confirmed", "payload": { "txId": "txn_999" } }'
POST/v1/workflows/:id/estimate

Dry-run cost estimation. No agents are executed. Returns min/max cost and per-step breakdown.

Parameters

inputobjectrequiredSample input used to resolve the DAG shape.

Response

WorkflowEstimate

Example

bash
curl -X POST https://api.theazo.com/v1/workflows/wf_a1b2c3/estimate \
  -H "Authorization: Bearer th_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "input": { "website": "https://acme.com" } }'

SDK method reference

workflow(name)WorkflowBuilderCreate a typed builder. Chain .step(id, opts), .condition(id, opts), .parallel(id, branches), .transform(id, expr), .map(id, opts), .delay(id, dur), .approval(id, action), .wait(id, opts), .input(schema), .output(schema), .withPolicy(policy), then .build().
theazo.workflows.create(opts)Promise<Workflow>Create a workflow definition. Accepts the output of workflow().build() or a raw WorkflowCreateOpts.
theazo.workflows.list()Promise<Workflow[]>List all workflow definitions for this platform.
theazo.workflows.get(workflowId)Promise<Workflow>Fetch a workflow definition by ID.
theazo.workflows.update(workflowId, opts)Promise<Workflow>Update steps, policy, or name. Version increments atomically.
theazo.workflows.delete(workflowId)Promise<void>Delete a workflow definition. Does not cancel in-progress runs.
theazo.workflows.estimate(workflowId, { input })Promise<WorkflowEstimate>Dry-run cost estimate. No agents are executed.
theazo.workflows.run(workflowId, { userId, sessionId, input?, idempotencyKey? })Promise<WorkflowRun>Start a new run in the user's session. Async — returns 202 immediately.
theazo.workflows.getRun(runId)Promise<WorkflowRun>Fetch current status, per-step results, and total cost.
theazo.workflows.listRuns(workflowId, opts?)Promise<WorkflowRun[]>List runs for a workflow, newest first. Filterable by status.
theazo.workflows.cancelRun(runId)Promise<void>Cancel an in-progress run. In-flight agents are paused.
theazo.workflows.retryRun(runId)Promise<void>Retry a failed/partial run. Failed steps are reset; completed steps are not re-run.
theazo.workflows.resumeRun(runId, { event, payload? })Promise<void>Resume a run paused on a wait step by delivering the awaited event. The payload becomes the step's output.
theazo.workflows.streamRun(runId)AsyncIterable<StreamEvent>SSE stream of run events: step.started, step.completed, step.failed, approval.pending, run.completed, run.partial.

Roadmap

The following capabilities are planned but not yet available. They're documented here so you know what's coming — the current engine and step types above are the complete shipped surface today.

Sub-workflowsplanned

A workflow step type that invokes another workflow and passes its output downstream — for composing pipelines out of reusable workflows.

Natural-language authoringplanned

Generate a workflow definition from a plain-language description, then refine it as config.

Embeddable UI componentsplanned

Drop-in workflow builder and run-progress widgets AgentCos can embed directly in their own product.

Template libraryplanned

Pre-built, parameterized workflow templates for common patterns (research, enrichment, triage).

Local dry-run & mocksplanned

Execute a workflow against mocked agent outputs to test branching and data flow without live compute. (Cost estimation via workflows.estimate() is available today.)

Artifact storeplanned

First-class handling of large intermediate outputs (files, blobs) passed between steps without inlining them into run state.

Pinned-version runsplanned

Run against a specific historical workflow version for reproducibility. Requires version snapshots — today runs always use the latest version (and record it as run.workflowVersion); update() increments the version.

Seeded shared state on runplanned

Pass an initial shared-state bag into run() that steps read via stateReads. Today shared state is written/read between steps and starts empty each run.

Was this page helpful?