Core Action Steps
For common fields, string substitutions, metadata filters, caching, and execution order, see the Agent Steps Overview. For branching / looping / merging / approval primitives (gate, retry, for_each, if_else, switch, merge, human_in_the_loop), see Control Flow Steps.
Text Step
Produces output from a template string with variable substitutions. This is the simplest way to construct formatted text, combine outputs from multiple steps, or create static content.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
template | string | Yes | — | The template string to render. Supports all substitution variables. |
content_type | enum | No | null | Output content type: text/plain, text/html, application/json, application/xml. When null, inherits from input. |
Use Case Examples
Composing a prompt from multiple sources:
Here is the user's question:
{{agent.input}}
Here is the relevant context from our knowledge base:
{{step.retrieval.output}}
Here is the user's profile:
Name: {{metadata.user_name}}
Plan: {{metadata.plan}}
Generating a JSON payload:
Template:
{
"agent_id": "{{agent.id}}",
"run_id": "{{agent.run_id}}",
"result": "{{step.analysis.output}}",
"timestamp": "{{datetime UTC}}"
}
Content type: application/json
Creating an HTML report:
Template:
<h1>Daily Report — {{date America/New_York}}</h1>
<h2>Summary</h2>
<div>{{step.summary.output}}</div>
<h2>Key Findings</h2>
<div>{{step.findings.output}}</div>
<footer>Generated by {{agent.name}} at {{time America/New_York}}</footer>
Content type: text/html
AI Assistant
The AI assistant can help generate text step templates. Describe what output you want, and it will create a template using the appropriate substitution variables based on your agent's step structure.
Regex Replace Step
Transforms text using an ordered list of regex-based substitution rules. Each rule applies a pattern match and optional replacement to the step's input, and rules execute sequentially.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
rules | array | Yes | — | An ordered list of transformation rules to apply |
Each rule has:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
pattern | string | Yes | — | A regex pattern to match in the input text |
substitution | string | No | null | The replacement string. If null, matched text is removed. Supports regex capture groups (\1, \2, etc.) and substitution variables. |
comment | string | No | null | A human-readable description of what this rule does |
Rules are applied sequentially — each rule operates on the result of the previous rule.
Use Case Examples
Clean HTML tags from text:
| Pattern | Substitution | Comment |
|---|---|---|
<[^>]+> | (empty) | Remove all HTML tags |
& | & | Decode HTML entity |
< | < | Decode HTML entity |
> | > | Decode HTML entity |
Extract email addresses:
| Pattern | Substitution | Comment |
|---|---|---|
^.*$ | (use a prompt call for complex extraction) | — |
Normalize whitespace:
| Pattern | Substitution | Comment |
|---|---|---|
\r\n | \n | Normalize line endings |
[ \t]+ | | Collapse multiple spaces/tabs |
\n{3,} | \n\n | Collapse excessive blank lines |
Redact sensitive data:
| Pattern | Substitution | Comment |
|---|---|---|
\b\d{3}-\d{2}-\d{4}\b | [SSN REDACTED] | Redact Social Security numbers |
\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,}\b | [EMAIL REDACTED] | Redact email addresses |
\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b | [CARD REDACTED] | Redact credit card numbers |
AI Assistant
The AI assistant can generate regex replace rules for you. Describe the transformation you want (e.g., "remove all URLs from the text" or "extract only the first paragraph"), and it will produce the appropriate regex patterns and substitutions.
The assistant generates rules with:
pattern— The regex to matchsubstitution— The replacement text (or null to remove)comment— An explanation of what the rule does
Extract Content Step
Extracts structured content (JSON, XML, or HTML) from noisy LLM output and optionally converts the format. This is the preferred step for cleaning up LLM responses that contain structured data embedded in prose.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
expected_format | string | No | "json", "xml", or "html" — the format to extract from the input |
query | string | No | JSONPath (for json), XPath (for xml), or tag name (for html) to drill into content |
json_schema | object | No | JSON Schema (Draft 2020-12) to validate the extracted JSON against. Only applies when expected_format is "json"; the step fails if the extracted JSON does not conform |
xml_schema | string | No | XML Schema Definition (XSD) to validate the extracted XML against. Only applies when expected_format is "xml"; the step fails if the extracted XML does not conform |
convert_to | string | No | "html", "markdown", or "plain_text" — optional format conversion after extraction. Only valid with expected_format "html" or no extraction; it is a no-op or lossy for "json"/"xml", so the editor hides it, the AI assistant rejects it, and a definition that pairs it with "json"/"xml" is rejected on save |
Use Case Examples
Extract JSON from LLM output:
expected_format: "json" — Finds and extracts the first valid JSON object or array from the text.
Extract JSON with JSONPath query:
expected_format: "json", query: "$.results[0].name" — Extracts JSON and then drills into it using a JSONPath expression.
Validate extracted JSON against a schema:
expected_format: "json", json_schema: { "type": "object", "required": ["id"] } — Extracts JSON and fails the step unless it conforms to the supplied JSON Schema. Pair with a query to validate only the drilled-into value.
Validate extracted XML against an XSD:
expected_format: "xml", xml_schema: "<xs:schema …>…</xs:schema>" — Extracts XML and fails the step unless it conforms to the supplied XML Schema Definition.
Convert markdown to HTML:
convert_to: "html" — Converts markdown content to HTML without extracting structured data.
Extract HTML and convert to markdown:
expected_format: "html", query: "article", convert_to: "markdown" — Extracts an HTML article tag and converts it to markdown.
Extract Data Step
Uses an AI model with progressive-disclosure tools to derive insights from potentially large input content. Unlike a Prompt Call (which passes the full input in the prompt), the Extract Data step gives the model tools to incrementally inspect the input — making it ideal for large documents, feeds, or data dumps that might exceed context-window limits.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
prompt_template | string | Yes | — | Describes the desired analysis — what kind of insight to derive from the input (e.g. summary, topics, keywords, sentiment). Supports substitutions. |
output_format | "text" | "markdown" | "html" | "json_object" | "json_array" | No | "text" | Controls the format of the model's response and the content type stamped on the step output (see Output Content Type). text forces plain text (no Markdown), markdown well-formed Markdown, html an HTML fragment; json_object and json_array instruct the model to produce strict JSON output. |
output_schema | object | No | null | An optional JSON Schema describing the desired output structure. When provided, overrides output_format and instructs the model to conform to the schema. |
model | enum | No | Claude Haiku 4.5 | The AI model to use. Must support tool calling. When omitted, the system selects a capable default. |
model_variant | string | No | null | Model variant identifier, if applicable. |
auto_upgrade_strategy | enum | No | null (inherit) | Optional per-step lifecycle strategy override (none, early_adopter, middle_of_road, cautious_adopter). |
auto_rollback_enabled | boolean | No | null (inherit) | Optional per-step auto-rollback override for upgraded-model failures. |
auto_rollback_triggers | array | No | null (inherit) | Optional per-step rollback trigger list (agent_eval_fail, governance_flag, governance_block, agent_run_failed). |
temperature | float | No | 0.3 | Sampling temperature (0.0–1.0). Lower values produce more focused, deterministic output. |
max_tokens | integer | No | null (model default) | Maximum number of tokens in the model's response. |
When to Use Extract Data vs Prompt Call
| Consideration | Prompt Call | Extract Data |
|---|---|---|
| Input fits in context window | Pass it directly in the prompt | Unnecessary overhead |
| Input may be very large | Risk of truncation or token-limit errors | Model scans progressively via tools |
| Need structured JSON output | Use json_template / JSON mode | Use output_format or output_schema |
| Need a system prompt | system_template field | System prompt is auto-generated |
| Need custom LLM tools | Configure via tools field | Not supported — uses built-in progressive-disclosure tools only |
Rule of thumb: If the input is small and you want full control over the prompt, use Prompt Call. If the input could be large and you want the model to intelligently scan it, use Extract Data.
How It Works
-
The step receives the previous step's output (or agent input) as a content handle — a lazy abstraction that avoids loading everything into memory.
-
Three built-in tools are automatically provided to the model:
| Tool | Description |
|---|---|
get_input_size | Returns byte size and approximate character count. Call first to plan scanning strategy. |
read_input_range | Reads a byte-range slice of the input (max 50,000 bytes per call). |
search_input | Searches for lines matching a regex or plain-text pattern (max 50 matches). |
-
An auto-generated system prompt tells the model to:
- Call
get_input_sizefirst to understand the content volume. - For small content (< 50,000 bytes), read it all at once.
- For larger content, scan progressively: read the beginning, search for key sections, and sample from different parts.
- Produce the requested output directly — no meta-commentary.
- Call
-
The model iterates through tool calls until it has enough context, then produces the final output.
Output Content Type
The model is instructed to honour the selected output_format, and the content type stamped on the step output matches it:
- Plain text (
output_format: "text"with nooutput_schema) →text/plain(the model is told not to emit Markdown or HTML) - Markdown (
output_format: "markdown") →text/markdown - HTML (
output_format: "html") →text/html(an HTML fragment — no<html>/<body>wrapper) - Structured (
output_format: "json_object"or"json_array", or anyoutput_schema) →application/json
The content type propagates to downstream steps and outputs. In particular, a Send Email step whose input is text/markdown (with no HTML body template) renders the Markdown to HTML for the email body, and a text/html input is used as the HTML body directly — so a markdown or html Extract Data step feeds formatted email rather than raw markup.
Use Case Examples
Summarize an RSS feed:
prompt_template: Summarize the key topics and themes from this RSS feed content.
Group related items together.
model: anthropic_claude_haiku_4_5
temperature: 0.3
Extract structured topics (JSON array):
prompt_template: Extract all distinct topics mentioned in the input content.
output_format: json_array
model: anthropic_claude_haiku_4_5
temperature: 0.2
Full content analysis with JSON Schema:
prompt_template: Analyze the input content and produce a structured report.
output_schema:
type: object
properties:
summary:
type: string
topics:
type: array
items:
type: string
sentiment:
type: string
enum: [positive, negative, neutral, mixed]
key_entities:
type: array
items:
type: object
properties:
name:
type: string
type:
type: string
required: [summary, topics, sentiment]
model: anthropic_claude_haiku_4_5
temperature: 0.2
AI Assistant
The Extract Data step includes full AI assistant support. Click the AI Assistant button to describe what you want in natural language, and the assistant will generate the complete configuration — prompt_template, output_format, output_schema, model, auto_upgrade_strategy, auto_rollback_enabled, auto_rollback_triggers, temperature, and max_tokens.
The agent-level AI assistant (for generating full workflows) also understands the Extract Data step and will include it when the task involves analyzing large content.
Attachments
Extract Data can analyze multi-modal inputs natively when the configured model supports the MIME (Claude 4.x, Nova, GPT-4o-class, Gemini). Reference attachments in prompt_template using the selector grammar:
{{attachments[0]}}— the current step's input attachment at index 0{{attachments[*.pdf]}}— input attachments whose filename matches the glob{{attachments[invoice.pdf]}}— exact filename match{{agent.attachments[…]}}— the original trigger uploads{{step.<id>.attachments[…]}}— anotherprompt_callorcall_agentstep's multi-asset output
Each match is sent as a native media block when the resolved model supports the MIME; otherwise the OCR / transcript counterpart is stitched onto the prompt text (text-only models still get to "see" the attachment, just via extracted text). The inline placeholder itself is replaced with a [attachment: name] marker so the prompt can refer to attachments by name.
A template that doesn't reference any attachments sees none — uploads are narrowly visible to steps that declare a dependency.
Evaluate Step
Scores a previous step's output using LLM-based criteria and emits structured JSON with score, passed, and pass_threshold.
Unlike Retry, this step does not re-run anything by itself. It is designed to produce an evaluation result that downstream steps (typically a Gate) can use for branching.
Related steps: Gate branches on the evaluation score. Retry re-runs the target step when a gate determines the score is too low.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
target_step_id | string | Yes | — | The id of a previously executed step to evaluate. Must match ^[a-zA-Z0-9_-]+$. |
evaluation_prompt | string | Yes | — | Natural-language rubric for scoring quality (accuracy, completeness, tone, etc.). |
pass_threshold | float | Yes | — | Score cutoff (inclusive) for pass/fail. Range: 0.0 to 1.0. |
evaluation_tier | enum | No | null | Optional evaluator model tier override (fast, balanced, thorough). |
expectation_config | object | No | null | Optional structural constraints (expected_format, contains, forbidden_phrases, and similar rule settings). |
Output Format
The step output is JSON with this shape:
{
"evaluated_step_id": "retrieval-1",
"score": 0.82,
"passed": true,
"pass_threshold": 0.7,
"explanation": "Meets criteria"
}
passed is computed from score >= pass_threshold.
Best Practice: Pair with a Gate
To branch on evaluation quality, put a Gate after Evaluate Step and inspect the JSON output:
prompt_call (id: generate-report)
└─ evaluate_step (target_step_id: generate-report, pass_threshold: 0.7)
└─ gate (checks {{input}} for passed=true)
This keeps scoring and control flow separate: Evaluate Step scores, Gate decides what to do next.
Attachments
When the target step is a prompt_call that emits images (e.g. via gpt-image-1, Gemini image-out, Nova image generation) or a call_agent whose sub-agent produces a multi-asset manifest, the evaluator can reason over the generated media directly. Reference attachments in evaluation_prompt:
{{step.<target_id>.attachments[0]}}— the first image emitted by the target step{{step.<target_id>.attachments[*.png]}}— every PNG emitted by the target{{agent.attachments[…]}}— the original trigger uploads (useful when the rubric compares the target's output against an input image, PDF, etc.){{attachments[…]}}— the current step's input manifest (rarely needed — eval reads its target viatarget_step_id)
Each match flows to the evaluator as a native media block when the resolved evaluation_tier's model supports the MIME (Balanced and Thorough tiers do; Fast tier may not — text fallback kicks in automatically). Inline placeholders are replaced with [attachment: name] markers so the rubric can refer to them by name.
{{step.<id>.attachments[…]}} is only valid when <id> is a prompt_call or call_agent step — those are the only step types that emit a multi-asset manifest. Referencing the attachments of any other step type is a save-time error.
Use Case Examples
Evaluate + If/Else Gate — stream result on success, alert on failure:
Use two mutually exclusive gates after the evaluate step to create an if/else branch. The "passed" gate streams the result to the user; the "failed" gate sends an email alert notifying an operator that the output quality was below threshold.
Step 1: Prompt Call (id: generate-report)
Step 2: Evaluate Step (target: generate-report, pass_threshold: 0.7)
Step 3a: Gate (passed = true)
Step 4a: Streaming Result
Step 3b: Gate (passed = false)
Step 4b: Send Email — "Alert: report scored below quality threshold"
Evaluate + Gate + Retry — auto-improve on low scores:
Combine all three steps to create a self-improving loop. The evaluate step scores the output, then two mutually exclusive gates branch on the result. The "passed" gate leads to a display result; the "failed" gate leads to a retry that re-runs the prompt call (up to 3 times). A merge whose wait_for names the display and retry branch tips recombines the flow.
Step 1: Prompt Call (id: generate-report)
Step 2: Evaluate Step (target: generate-report, pass_threshold: 0.7)
Step 3a: Gate (passed = true)
Step 4a: Display Result (id: display)
Step 3b: Gate (passed = false)
Step 4b: Retry (id: retry, max: 3, target: generate-report)
Step 6: Merge — merge final output (wait_for: [display, retry])