Expand description
§ironflow-core
Core building blocks for the ironflow workflow engine. This crate provides composable, async operations that can be chained via plain Rust variables to build headless CI/CD, DevOps, and AI-powered workflows.
§Operations
| Operation | Description |
|---|---|
Shell | Execute a shell command with timeout, env control, and kill_on_drop. |
Agent | Invoke an AI agent (Claude Code by default) with structured output support. |
Http | Perform HTTP requests via reqwest with builder-pattern ergonomics. |
§Provider trait
The AgentProvider trait abstracts the AI
backend. The built-in ClaudeCodeProvider
shells out to the claude CLI; swap it for
RecordReplayProvider
in tests for deterministic, zero-cost replay.
§Known limitations: Structured output
When using AgentConfig::output::<T>() to request
structured (typed) output from the Claude CLI, be aware of these upstream bugs:
| Issue | Impact |
|---|---|
| claude-code#18536 | structured_output is always null when tools are used alongside --json-schema. ironflow prevents this at compile time via typestate (tools and schema are mutually exclusive). |
| claude-code#9058 | The CLI does not validate output against the provided JSON schema – non-conforming JSON may be returned. |
| claude-agent-sdk-python#502 | Wrapper objects with a single array field may be flattened to a bare array (e.g. [...] instead of {"items": [...]}). |
| claude-agent-sdk-python#374 | The wrapping behavior is non-deterministic: the same prompt can produce differently shaped output across runs. |
Recommended workarounds:
- Two-step pattern: use one agent with tools to gather data, then a second
agent with
.output::<T>()(no tools) to structure the result. - Defensive deserialization: when deserializing structured output, handle both the expected wrapper object and a bare array/value as fallback.
max_turns >= 2: structured output requires at least 2 turns; settingmax_turns(1)with a schema will fail witherror_max_turns.
§Quick start
use ironflow_core::prelude::*;
let files = Shell::new("ls -la").await?;
let provider = ClaudeCodeProvider::new();
let review = Agent::new()
.prompt(&format!("Summarise:\n{}", files.stdout()))
.model(Model::HAIKU)
.max_budget_usd(0.10)
.run(&provider)
.await?;
println!("{}", review.text());Modules§
- dry_run
- Global dry-run mode control.
- error
- Error types for ironflow operations.
- metric_
names - Centralised metric name constants for Prometheus instrumentation.
- operations
- Workflow operations (shell commands, agent calls, HTTP requests).
- parallel
- Parallel step execution utilities.
- prelude
- Re-exports of the most commonly used types.
- provider
- Provider trait and configuration types for agent invocations.
- providers
- Built-in
AgentProviderimplementations. - retry
- Retry policy for transient failures with exponential backoff.
- tracker
- Workflow-level cost, token, and duration tracking.
- utils
- Utility functions for output handling and OOM protection.