Core Action Steps
For common fields, string substitutions, metadata filters, caching, and execution order, see the Agent Steps Overview.
Prompt Call Step
Calls an AI model to generate a response. This is the most versatile step type, supporting 90+ models across multiple providers with features like structured JSON output, tool calling, and response formatting.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
model | enum | Yes | — | The AI model to use (see supported models below) |
model_variant | string | No | null | Model variant identifier, if applicable |
auto_upgrade_strategy | enum | No | null (inherit) | Optional per-step model lifecycle strategy. When set, may automatically switch to a configured successor model before execution based on rollout policy. |
auto_rollback_enabled | boolean | No | null (inherit) | Optional per-step override to enable or disable automatic rollback after selected failure signals when an upgraded model is in use. |
auto_rollback_triggers | array | No | null (inherit) | Optional per-step rollback trigger list. Supported values: agent_eval_fail, governance_flag, governance_block, agent_run_failed. |
prompt_template | string or object | No | null | The prompt sent to the model. Supports substitutions. If not set, the step's input is used as the prompt. |
system_template | string | No | null | System instructions for the model. Sets the model's behavior and context. Supports substitutions. |
temperature | float | No | null (model default) | Controls randomness of the response. Range: 0.0 (deterministic) to 1.0 (creative). |
max_tokens | integer | No | null (model default) | Maximum number of tokens in the response |
simple_format | boolean | No | true | Controls the prompt input format. When true, uses a plain text prompt and system prompt (like ChatGPT/Claude). When false, uses an advanced JSON payload that leverages the model's native API features. |
json_template | object | No | null | The JSON payload sent to the model when simple_format is false. Uses the model's native prompt format, allowing access to provider-specific features. Supports substitutions. |
tools | array | No | [] | List of tool IDs the model can call during generation (see Tools) |
extended_caching_days | integer | No | null | Number of days to cache results (must be > 0) |
cache_all_minutes | integer | No | null | Cache all identical requests for N minutes (1–60) |
use_step_input_as_messages | boolean | No | false | Simple mode only. Parses step input as a chat messages array and sends directly to the model. See Input as Messages. |
Model Lifecycle Controls (Prompt Call and Insight)
Both Prompt Call and Insight support optional per-step lifecycle overrides:
auto_upgrade_strategy: one ofnone,early_adopter,middle_of_road,cautious_adopterauto_rollback_enabled:true,false, ornull(inherit)auto_rollback_triggers: subset ofagent_eval_fail,governance_flag,governance_block,agent_run_failed
If a step leaves these fields as null, it inherits the agent-level defaults.
How strategies behave:
- none: never auto-upgrade; always use the configured base model.
- early_adopter: upgrade to the successor as soon as one is configured.
- middle_of_road: upgrade only after a stability window following successor release.
- cautious_adopter: upgrade only after the current model is deprecated and the successor has been stable.
How rollback works:
When auto-rollback is enabled and the step actually ran on an auto-upgraded model, Seclai can automatically roll the branch definition back to a previously successful branch change when a configured trigger occurs.
Supported Models
Seclai supports 90+ models across 12+ providers — including OpenAI, Anthropic, Google, Amazon, DeepSeek, xAI, Meta, Mistral, Moonshot AI, Qwen, NVIDIA, and Cohere. See the Models page for the full, up-to-date list with capabilities and pricing.
Tools (Function Calling)
Prompt call steps can use tools — functions that the AI model can invoke during generation to retrieve additional information. When tools are configured, the model autonomously decides when to call them based on the conversation context. For example, when asked a question, the model might search a knowledge base, load a specific document, and then synthesize an answer.
Four tool groups are available: Web Tools (fetch pages, search the web), Knowledge Base Tools (semantic search, discovery), Content Tools (load documents, inspect content, write metadata and attachments), and Memory Bank Tools (read/write/search persistent memory).
For the full list of tools, parameters, and guidance on when to use tools vs. explicit steps, see the Tools page.
Formatting Cleanup
Apply automatic post-processing to the model's response:
| Value | Description |
|---|---|
convert_markdown_to_html | Converts Markdown output to HTML |
convert_html_to_markdown | Converts HTML output to Markdown |
plain_text_only | Strips all formatting, returning plain text |
Streaming Output
Attaching a Streaming Result step immediately after a prompt call enables token-by-token streaming to the user via Server-Sent Events. The model's output is delivered as it is generated, rather than waiting for the full response.
Other steps can still run in parallel with the streaming result — for example, an Add Memory step to persist the prompt call's output, or a Webhook Call to notify an external system. The streaming result and all parallel siblings receive the same prompt call output and execute concurrently.
Input as Messages (Conversational Mode)
When use_step_input_as_messages is enabled (simple mode only), the step parses its input as a JSON array of chat messages and sends them directly to the model — instead of wrapping a single prompt template in a user message.
Expected input format:
[
{ "role": "user", "content": "Hello, how are you?" },
{ "role": "assistant", "content": "I'm doing well! How can I help you?" },
{ "role": "user", "content": "Can you summarize this document?" }
]
This is the exact format produced by the Load Memory step when configured with content_type: "application/json".
Why use this? Sending each message as a separate element (rather than embedding the entire history in a single prompt string) enables prompt caching on supported providers. The model can cache the stable prefix of earlier messages and only process the new ones, significantly reducing latency and cost for conversational workflows.
Recommended conversational workflow:
- Write Memory (speaker:
user) — save the incoming user message - Load Memory (order:
oldest_first, content type:JSON) — load the full history as a messages array - Prompt Call (
use_step_input_as_messages: true) — send messages to the model with a system prompt - Write Memory (speaker:
assistant) — save the model's response - Streaming Result — stream the response to the user
Important: Use
oldest_firstorder for prompt caching to work. The oldest messages form a stable prefix that the model can cache. Usingnewest_firstwould change the prefix on every turn, defeating the cache.
Adding additional context (RAG, preferences, metadata):
When your conversational agent also uses retrieval results, user preferences, or other contextual data, place that additional context in the system_template rather than in prompt_template (which must be null when using input-as-messages). Note that dynamic content in system_template (e.g. retrieval results that change per turn) will still change the cached prefix and can reduce prompt-caching effectiveness — the main caching benefit comes from keeping the conversation history as a stable message array via oldest_first ordering.
Example system_template with additional context:
You are a helpful assistant. Use the provided context to answer accurately.
Knowledge base results:
{{step.search-kb-retrieval.output}}
User preferences:
{{step.recall-prefs-search_memory.output}}
This keeps the conversation messages clean (each message is sent individually for caching) while still providing the model with all the context it needs via the system prompt.
When use_step_input_as_messages is enabled:
- The
prompt_templatefield is ignored (hidden in the editor) - The
system_templateis still used as the system prompt - The step fails with a clear error if the input is not valid JSON or doesn't match the expected
[{role, content}]schema - Valid roles are:
user,assistant,system
Simple vs Advanced Format
The simple_format field controls how the prompt is sent to the model:
Simple format (simple_format: true, default):
- Uses
prompt_template(string) andsystem_template(string) - Works like interactive chat interfaces (ChatGPT, Claude)
- Portable across model providers with little or no modification
json_templatemust not be provided
Advanced format (simple_format: false):
- Uses
json_template(JSON object) — the model's native prompt payload - Gives access to provider-specific features and fine-grained control
- May require modifications when switching between model providers
prompt_templatemust not be provided
Example advanced format JSON template:
{
"messages": [
{
"role": "system",
"content": "You are an expert analyst for {{organization.name}}."
},
{
"role": "user",
"content": "Analyze this: {{agent.input}}"
}
]
}
String substitutions (e.g., {{agent.input}}, {{metadata.*}}) are supported inside both prompt_template and json_template.
Use Case Examples
Content summarization:
System: You are a concise content summarizer. Output a 2-3 sentence summary.
Prompt: Summarize this article:
{{agent.input}}
Question answering with context (RAG):
System: You are a helpful assistant for {{organization.name}}.
Answer questions using ONLY the provided context.
If the answer is not in the context, say "I don't have that information."
Prompt: Context:
{{step.retrieval.output}}
Question: {{agent.input}}
Structured data extraction:
System: Extract the following information from the text and return as JSON.
Prompt: {{agent.input}}
With json_template:
{
"type": "object",
"properties": {
"company_name": { "type": "string" },
"revenue": { "type": "string" },
"employees": { "type": "integer" },
"headquarters": { "type": "string" }
}
}
Multi-language response:
System: You are a translator. Translate the input to {{metadata.target_language}}.
Maintain the original formatting and tone.
Prompt: {{agent.input}}
AI Assistant
The prompt call step includes an AI assistant that can generate a complete configuration based on a natural-language description of what you want the step to do. Click the AI Assistant button (requires a model to be selected first) to open the assistant modal.
The assistant can set all prompt call fields:
- Model and model variant — selects a cost-effective model that fits the task (e.g. tool use, structured output, long context)
- Mode — chooses between simple mode (prompt + system prompt) and JSON mode (vendor-native payload)
- Prompt template and system template — writes templates using substitution variables like
{{input}}and{{step.<id>.output}} - Temperature and max tokens — tunes generation parameters for the task
- Tools — enables tool use (e.g. web search) when the task requires it
- JSON template — builds vendor-specific payloads when JSON mode is appropriate
- Formatting cleanup — selects post-processing (Markdown → HTML, HTML → Markdown, plain text only)
For Prompt Call steps, the assistant follows these conventions:
- Use
{{agent.input}}when referring to the user's original question/message - Use
{{input}}only for previous-step output/context - Put core instruction logic in System Template
- In System Template, prefer this order: original question (
{{agent.input}}) → instructions → previous-step data ({{input}}/{{step.<id>.output}})
The assistant is aware of the full agent workflow context — all steps, the trigger configuration, and the knowledge bases available — so it can reference outputs from earlier steps and tailor the prompt to the agent's purpose.
Each response also includes a purpose field (a brief description of the step's intent) and a note explaining what was changed or asking a follow-up question.
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.
Transform 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 transform 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
Gate Step
Evaluates conditions against the step's input to decide whether subsequent steps should execute. A gate acts as a conditional branch point — when conditions are met (or not met, depending on configuration), the gate either passes the input through or blocks execution.
Gates support three common branching patterns:
- If/else — Two parallel gates with opposite conditions (e.g.,
intent = questionandintent ≠ question). Exactly one fires per input, routing execution down the matching branch. A join on one branch and a combinator recombine the result. - Switch — A row of parallel gates, each checking one mutually exclusive case. Exactly one gate fires, directing input to a dedicated processing branch. Join steps on n−1 branches feed a combinator that merges the result.
- Parallel non-exclusive — Multiple gates run independently in parallel, each guarding a different branch. Unlike if/else and switch, these gates are not mutually exclusive — any combination of branches can fire depending on which conditions are met.
Related steps: Join and Combinator recombine branches created by gates. Retry pairs with a gate to implement conditional retry logic. Evaluate scores output that a gate can branch on.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
conditions | array | Yes | — | The list of conditions to evaluate |
match | enum | No | all | How to combine condition results: all (AND — every condition must match) or any (OR — at least one must match) |
on_match | enum | No | continue | What to do when conditions are met: continue (pass input through) or stop (block execution, output is empty) |
Each condition has:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
target | string | Yes | — | What to evaluate. Built-in targets: input (step input text), input_length (character count), input_content_type (MIME type). Also supports metadata.<field> for metadata values. |
operator | enum | Yes | — | The comparison operator (see below) |
value | any | No | null | The value to compare against. Supports substitution variables. |
value_type | enum | No | null | How to interpret the value: number, date, datetime, or relative_time |
comment | string | No | null | A description of what this condition checks |
Condition Operators
| Operator | Description | Example |
|---|---|---|
$eq | Equals | target == value |
$ne | Not equals | target != value |
$lt | Less than | target < value |
$lte | Less than or equal | target <= value |
$gt | Greater than | target > value |
$gte | Greater than or equal | target >= value |
$in | In list | target in [value1, value2, ...] |
$nin | Not in list | target not in [value1, value2, ...] |
$regex | Matches regex pattern | re.search(value, target) |
$not_regex | Does not match regex | not re.search(value, target) |
$empty | Is empty or null | target is None or target.strip() == "" |
$not_empty | Is not empty | target is not None and target.strip() != "" |
For $lt, $lte, $gt, $gte: numeric comparison is attempted first; if both values are not numeric, string comparison is used.
Value Types
The value_type field controls how the comparison value is interpreted:
| Value Type | Description | Example Values |
|---|---|---|
number | Treat as a numeric value | 100, 3.14 |
date | Treat as a date | 2026-02-17 |
datetime | Treat as a datetime | 2026-02-17T14:30:00 |
relative_time | Parse as a relative time expression | now, today, yesterday, 3 days ago, 1 week ago, 2 hours ago, 5 days from now |
Relative time expressions are resolved at execution time. Supported expressions include:
now— Current datetimetoday— Start of todayyesterday— Start of yesterdaythis week/last week— Start of current/previous weekN days ago/N hours ago/N minutes agoN days from now/N hours from now
Use Case Examples
Only process non-empty input:
| Condition | Target | Operator | Value |
|---|---|---|---|
| 1 | input | $not_empty | — |
Match: all, On match: continue
Filter by content length (skip short content):
| Condition | Target | Operator | Value | Value Type |
|---|---|---|---|---|
| 1 | input_length | $gt | 100 | number |
Match: all, On match: continue — Only continue if input is longer than 100 characters.
Route by category (only process technology articles):
| Condition | Target | Operator | Value |
|---|---|---|---|
| 1 | metadata.category | $eq | technology |
Block specific content types:
| Condition | Target | Operator | Value |
|---|---|---|---|
| 1 | input_content_type | $in | ["text/html", "application/xml"] |
Match: all, On match: stop — Block HTML and XML content from proceeding.
Time-based gating (only process recent content):
| Condition | Target | Operator | Value | Value Type |
|---|---|---|---|---|
| 1 | metadata.published_date | $gt | 7 days ago | relative_time |
Match: all, On match: continue — Only process content published in the last 7 days.
Complex multi-condition gate:
| Condition | Target | Operator | Value |
|---|---|---|---|
| 1 | input | $not_empty | — |
| 2 | input_length | $gt | 50 |
| 3 | metadata.status | $ne | draft |
| 4 | metadata.language | $in | ["en", "es", "fr"] |
Match: all, On match: continue — All four conditions must be true to proceed.
If/else — two mutually exclusive gates:
Two gates run in parallel with opposite conditions — one checks intent = question, the other checks intent ≠ question. Exactly one gate fires per input, routing execution down the matching branch. A join on one branch and a combinator recombine the result.
Switch — parallel mutually exclusive gates for multi-way routing:
A row of parallel gates, each checking one case (topic = tech, topic = finance, topic = general). The conditions are mutually exclusive so exactly one gate fires per input. Each gate leads to its own processing branch, and join steps on n−1 branches feed a combinator that merges the result.
Parallel non-exclusive gates:
Multiple gates run independently in parallel, each guarding a separate branch. Unlike if/else and switch, these are not mutually exclusive — any combination of branches can fire. A combinator with join steps merges whichever results are produced.
AI Assistant
The AI assistant can generate gate conditions for you. Describe the filtering logic you need (e.g., "only process articles longer than 200 characters about technology"), and it will create the appropriate conditions with the correct operators and match mode.
Combinator Step
Merges outputs from multiple parallel branches into a single output using a template. Combinators work with Join steps to collect results from different processing paths and combine them.
Related steps: Gate creates the parallel branches that feed into a combinator. Join connects each non-main branch to the combinator.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
combinator_mode | string | No | custom | How to generate the output template (see modes below) |
combinator_xml_tag | string | No | output | Custom XML tag name when using xml_custom_tag mode |
output_template | string | No | "" | The template string for custom mode. 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. |
Combinator Modes
| Mode | Description |
|---|---|
custom | You write the output template directly using substitution variables |
exclusive | Passes through the first non-empty parent output |
xml_custom_tag | Wraps each parent output in XML tags using combinator_xml_tag as the tag name |
xml_step_ids | Wraps each parent output in XML tags using the step IDs as tag names |
json_array | Combines parent outputs into a JSON array |
json_object | Combines parent outputs into a JSON object keyed by step IDs |
Using Join Steps with Combinators
A Join step connects a parallel branch to a combinator. The join step's target field specifies which combinator it feeds into. The combinator waits for all connected join steps to complete before executing.
Example: Parallel processing with combinator
Agent Input
├── Step: retrieval (search KB)
│ └── Step: summarize (prompt call)
│ └── Step: join_summary (join → combine)
├── Step: extract_entities (prompt call)
│ └── Step: join_entities (join → combine)
└── Step: combine (combinator)
└── Step: final_output (display result)
In this workflow:
- Two branches run in parallel: one retrieves and summarizes, the other extracts entities
- Both branches have join steps targeting
combine - The combinator waits for both joins to complete
- The combinator merges the results using its output template
Custom output template for the combinator:
Summary: {{step.summarize.output}}
Entities: {{step.extract_entities.output}}
Use Case Examples
Merge analysis results (custom mode):
Output template:
{
"summary": "{{step.summarize.output}}",
"sentiment": "{{step.sentiment.output}}",
"entities": {{step.entities.output}},
"generated_at": "{{datetime UTC}}"
}
Content type: application/json
Wrap outputs in XML (xml_step_ids mode):
Auto-generated output:
<summarize>The article discusses...</summarize>
<entities>["AI", "machine learning"]</entities>
AI Assistant
The AI assistant can generate combinator output templates. Describe the structure you want for your combined output, and it will create a template referencing the appropriate step outputs.
Join Step
Connects a parallel branch to a Combinator step (above). The join step is a transparent relay — its output is identical to its input. Its purpose is to signal to the combinator that a branch has completed.
Related steps: Gate creates the parallel branches that need joining. Combinator receives the joined outputs and merges them.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
target | string | Yes | — | The ID of the combinator step this join feeds into. Must match ^[a-zA-Z0-9_-]+$. |
Join steps cannot have child steps.
Use Case Example
See the Combinator step section for a complete example of how join steps connect parallel branches to a combinator.
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 |
convert_to | string | No | "html", "markdown", or "plain_text" — optional format conversion after extraction |
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.
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.
Insight 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 Insight 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" | "json_object" | "json_array" | No | "text" | Controls the format of the model's response. 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 Insight vs Prompt Call
| Consideration | Prompt Call | Insight |
|---|---|---|
| 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 insight 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 Insight.
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 output content type is determined automatically:
- Text format (
output_format: "text"with nooutput_schema) →text/plain - Structured format (
output_format: "json_object"or"json_array", or anyoutput_schema) →application/json
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 Insight 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 Insight step and will include it when the task involves analyzing large content.
Retry Step
Re-executes the workflow from a specified ancestor step up to a configurable number of times. When the retry step completes, the runner resets the target step and all its descendants back to pending and re-schedules the target. This continues until the maximum retry count is reached, at which point execution proceeds normally past the retry step.
Related steps: Gate makes retries conditional — place a gate before the retry to check output quality and only retry when the result is unsatisfactory. Evaluate scores the output that a gate inspects before triggering a retry.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
target_step_id | string | Yes | — | The id of an ancestor step in the parent chain to re-execute from. Must be alphanumeric (including hyphens and underscores). |
max_retries | integer | Yes | — | Maximum number of times the target will be re-executed (1–10). |
How It Works
- The retry step is a non-composite leaf step — it cannot contain child steps.
- Each time the retry step completes, the runner checks how many times it has already completed.
- If the count is within
max_retries, the target step and all its descendants are reset to pending and the target is re-scheduled. - If the count exceeds
max_retries, execution continues normally — the retry has been exhausted.
Best Practice: Pair with a Gate
Without a gate, a retry step will unconditionally re-run its target up to max_retries times. To make retries conditional, place a gate step between the output-producing step and the retry:
retrieval (target for retry)
└─ prompt_call
└─ gate (evaluates output quality)
└─ retry (target_step_id: retrieval, max_retries: 3)
- If the gate's conditions pass (
on_match: "continue"), child execution proceeds — including the retry step, which will unconditionally re-run the target (up tomax_retriestimes). Useon_match: "stop"with success conditions instead (see below). - If the gate blocks (
on_match: "stop"and conditions match, oron_match: "continue"and conditions fail), child steps including retry are not reached, and execution stops.
To implement conditional retry effectively:
- Use
on_match: "stop"on the gate, with conditions that detect a good result (e.g., output is not empty, contains expected keywords). - When the output is satisfactory, the gate stops — blocking the retry step.
- When the output fails the conditions, the gate passes through, and the retry step triggers re-execution.
Use Case Examples
Retry a failed retrieval up to 3 times:
target_step_id: search-knowledge-base
max_retries: 3
Quality-gated retry for LLM output:
prompt_call (id: generate-report)
└─ gate (conditions: [{target: "input", operator: "$not_empty"}], on_match: "stop")
└─ retry (target_step_id: generate-report, max_retries: 2)
If the prompt call produces non-empty output, the gate stops and the retry is never reached. If the output is empty, the gate passes through and retry re-executes the prompt call.
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.
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 join on the display branch and a combinator recombine 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
Step 5a: Join
Step 3b: Gate (passed = false)
Step 4b: Retry (max: 3, target: generate-report)
Step 6: Combinator — merge final output