-
Notifications
You must be signed in to change notification settings - Fork 2
Step Types
OCC supports 11 step types. Each has specific fields and behavior.
The workhorse. Sends a prompt to Claude and returns the response.
- id: analyze
type: agent # Optional — "agent" is the default
model: claude-sonnet-4-6
tools: [Read, Grep, Glob] # Claude tools available to this step
prompt: |
Analyze this code: {code}
Focus on performance issues.
output_var: analysis
timeout_ms: 180000Key fields: prompt, model, tools, cwd, timeout_ms
Classifies input and routes to different step groups based on the result.
- id: classify
type: router
prompt: |
Classify this project: {input.path}
Return one of: frontend, backend, fullstack
routes:
frontend: [review_ui, review_a11y]
backend: [review_api, review_db]
fullstack: [review_ui, review_api, review_db]
default_route: fullstack
output_var: project_typeHow it works:
- Claude responds with a classification (e.g., "frontend")
- OCC matches the response to a route key
- Only the steps listed in that route are executed
- Steps not in the selected route are skipped
Key fields: routes, default_route
Scores or validates output from another step. Can trigger retries.
- id: quality_check
type: evaluator
input_var: draft # Variable to evaluate
criteria: |
Score this draft on:
- Accuracy (1-10)
- Completeness (1-10)
- Clarity (1-10)
PASS if average >= 7.
eval_scoring: true # Numeric scoring mode (1-10)
eval_threshold: 7 # Minimum score to pass
on_fail: retry # "retry", "skip", or "error"
max_retries: 2
retry_target: write_draft # Which step to re-run on failure
prompt: "Evaluate the draft"
output_var: eval_resultModes:
-
eval_scoring: false(default) — PASS/FAIL evaluation -
eval_scoring: true— numeric 1-10 score, compared againsteval_threshold
On failure:
-
retry— re-runsretry_targetstep, then re-evaluates -
skip— marks step as skipped, continues chain -
error— stops the chain
Key fields: input_var, criteria, eval_scoring, eval_threshold, on_fail, max_retries, retry_target
Pauses execution until a human approves or rejects via the API.
- id: approval
type: gate
prompt: "Review the report before publishing. Approve or reject."
timeout_hours: 24
on_timeout: skip # "skip", "error", or "approve"
gate_actions: ["approve", "reject", "escalate"]
gate_rejection_reason: true # Collect reason on reject
gate_auto_approve_if: '{score} > "9"' # Auto-approve condition
output_var: approval_resultApproval API:
# List pending gates
curl http://localhost:4242/approvals
# Approve
curl -X POST http://localhost:4242/executions/{id}/approve/{stepId} \
-H "Content-Type: application/json" \
-d '{"approved": true}'Key fields: timeout_hours, on_timeout, gate_actions, gate_auto_approve_if
Manipulate data between steps without using LLM tokens.
- id: extract
type: transform
operation: json_extract
input_var: research_json
json_path: "findings"
prompt: "extract findings"
output_var: findingsOperations:
| Operation | Description | Key fields |
|---|---|---|
json_extract |
Extract a key from JSON |
json_path, input_var
|
regex_match |
Extract regex matches |
regex, input_var
|
template |
String template | template_str |
split |
Split string into array | input_var |
merge |
Merge multiple inputs | inputs |
truncate |
Truncate to N chars |
truncate_limit, input_var
|
replace |
String replacement | input_var |
filter |
Filter array items | input_var |
map |
Transform array items | input_var |
join |
Join array to string | input_var |
to_json |
Convert to JSON string | input_var |
from_json |
Parse JSON string | input_var |
Cost: Zero LLM tokens. Runs in-process.
Iterate over items, running a step template for each.
- id: analyze_each
type: loop
items_var: input.competitors # Comma-separated or JSON array
max_parallel: 3 # Max concurrent iterations
loop_until: '{item} == "STOP"' # Optional break condition
loop_on_error: continue # "continue" or "abort"
step_template:
type: agent
model: claude-sonnet-4-6
prompt: "Analyze competitor: {item}"
tools: []
prompt: "Loop over competitors"
output_var: competitor_analysesHow it works:
- Splits
items_varinto individual items - Runs
step_templatefor each item, with{item}available - Results collected into output_var as concatenated text
-
max_parallelcontrols concurrency
Key fields: items_var, max_parallel, step_template, loop_until, loop_on_error
Combine outputs from multiple parallel steps.
- id: combine
type: merge
inputs: [analysis_a, analysis_b, analysis_c]
strategy: llm_summarize
prompt: "Synthesize these analyses into a unified report."
output_var: combinedStrategies:
| Strategy | Description | Uses LLM? |
|---|---|---|
concatenate |
Join all inputs with separator | No |
json_array |
Wrap inputs in a JSON array | No |
llm_summarize |
Claude summarizes all inputs | Yes |
pick_best |
Claude picks the best input | Yes |
Key fields: inputs, strategy
Web automation via Playwright — navigate, click, extract, screenshot.
- id: scrape
type: browser
browser_url: "https://example.com/data"
browser_task: "Extract the pricing table from this page"
browser_max_steps: 10
browser_headless: true
browser_output_format: markdown
browser_wait_ms: 3000
prompt: "Scrape pricing data"
output_var: pricing_dataRequires: Playwright installed (npx playwright install chromium)
Key fields: browser_url, browser_task, browser_max_steps, browser_headless, browser_output_format, browser_viewport, browser_wait_ms, browser_page_name, browser_scroll_strategy
Execute another chain as a step, mapping inputs and outputs.
- id: research
type: subchain
subchain: deep-researcher # Name of the chain to execute
subchain_input_map:
topic: "{input.subject}" # Map parent vars → subchain inputs
depth: "deep"
prompt: "Run research subchain"
output_var: research_resultThe subchain runs in its own isolated context. Its internal steps don't pollute the parent chain's variables.
Key fields: subchain, subchain_input_map
Multiple AI agents discuss a topic, then reach consensus.
- id: brainstorm
type: debate
debate_agents:
- prompt: "Argue FOR this approach: {proposal}"
model: claude-sonnet-4-6
- prompt: "Argue AGAINST this approach: {proposal}"
model: claude-sonnet-4-6
- prompt: "Be a neutral moderator. Weigh both sides."
model: claude-opus-4-6
debate_rounds: 2
debate_decision: consensus # "voting", "consensus", or "last_round"
prompt: "Debate the proposal"
output_var: debate_resultKey fields: debate_agents, debate_rounds, debate_decision
Send HTTP callbacks on step completion. (Currently executes as agent step — full webhook support planned.)
- id: notify
type: webhook
prompt: "Notify external system"
output_var: webhook_result- Chain Format — Full YAML reference
- Pre-Tools — Data injection before steps
- Cookbook — Practical examples using different step types