ironflow_core/lib.rs
1//! # ironflow-core
2//!
3//! Core building blocks for the **ironflow** workflow engine. This crate
4//! provides composable, async operations that can be chained via plain Rust
5//! variables to build headless CI/CD, DevOps, and AI-powered workflows.
6//!
7//! # Operations
8//!
9//! | Operation | Description |
10//! |-----------|-------------|
11//! | [`Shell`](operations::shell::Shell) | Execute a shell command with timeout, env control, and `kill_on_drop`. |
12//! | [`Agent`](operations::agent::Agent) | Invoke an AI agent (Claude Code by default) with structured output support. |
13//! | [`Http`](operations::http::Http) | Perform HTTP requests via [`reqwest`] with builder-pattern ergonomics. |
14//!
15//! # Provider trait
16//!
17//! The [`AgentProvider`](provider::AgentProvider) trait abstracts the AI
18//! backend. The built-in [`ClaudeCodeProvider`](providers::claude::ClaudeCodeProvider)
19//! shells out to the `claude` CLI; swap it for
20//! [`RecordReplayProvider`](providers::record_replay::RecordReplayProvider)
21//! in tests for deterministic, zero-cost replay.
22//!
23//! # Known limitations: Structured output
24//!
25//! When using [`AgentConfig::output::<T>()`](provider::AgentConfig::output) to request
26//! structured (typed) output from the Claude CLI, be aware of these upstream bugs:
27//!
28//! | Issue | Impact |
29//! |-------|--------|
30//! | [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). |
31//! | [claude-code#9058] | The CLI does not validate output against the provided JSON schema -- non-conforming JSON may be returned. |
32//! | [claude-agent-sdk-python#502] | Wrapper objects with a single array field may be flattened to a bare array (e.g. `[...]` instead of `{"items": [...]}`). |
33//! | [claude-agent-sdk-python#374] | The wrapping behavior is non-deterministic: the same prompt can produce differently shaped output across runs. |
34//!
35//! **Recommended workarounds:**
36//!
37//! 1. **Two-step pattern**: use one agent with tools to gather data, then a second
38//! agent with `.output::<T>()` (no tools) to structure the result.
39//! 2. **Defensive deserialization**: when deserializing structured output, handle
40//! both the expected wrapper object and a bare array/value as fallback.
41//! 3. **`max_turns >= 2`**: structured output requires at least 2 turns; setting
42//! `max_turns(1)` with a schema will fail with `error_max_turns`.
43//!
44//! [claude-code#18536]: https://github.com/anthropics/claude-code/issues/18536
45//! [claude-code#9058]: https://github.com/anthropics/claude-code/issues/9058
46//! [claude-agent-sdk-python#502]: https://github.com/anthropics/claude-agent-sdk-python/issues/502
47//! [claude-agent-sdk-python#374]: https://github.com/anthropics/claude-agent-sdk-python/issues/374
48//!
49//! # Quick start
50//!
51//! ```no_run
52//! use ironflow_core::prelude::*;
53//!
54//! # async fn example() -> Result<(), OperationError> {
55//! let files = Shell::new("ls -la").await?;
56//!
57//! let provider = ClaudeCodeProvider::new();
58//! let review = Agent::new()
59//! .prompt(&format!("Summarise:\n{}", files.stdout()))
60//! .model(Model::HAIKU)
61//! .max_budget_usd(0.10)
62//! .run(&provider)
63//! .await?;
64//!
65//! println!("{}", review.text());
66//! # Ok(())
67//! # }
68//! ```
69
70pub mod dry_run;
71pub mod error;
72pub mod metric_names;
73pub mod parallel;
74pub mod provider;
75pub mod providers;
76pub mod retry;
77pub mod tracker;
78pub mod utils;
79
80/// Workflow operations (shell commands, agent calls, HTTP requests).
81pub mod operations {
82 pub mod agent;
83 pub mod http;
84 pub mod shell;
85}
86
87/// Re-exports of the most commonly used types.
88pub mod prelude {
89 pub use crate::dry_run::{DryRunGuard, is_dry_run, set_dry_run};
90 pub use crate::error::{AgentError, OperationError};
91 pub use crate::operations::agent::{Agent, AgentResult, Model, PermissionMode};
92 pub use crate::operations::http::{Http, HttpOutput};
93 pub use crate::operations::shell::{Shell, ShellOutput};
94 pub use crate::parallel::{try_join_all, try_join_all_limited};
95 pub use crate::provider::{AgentConfig, AgentProvider, DebugMessage, DebugToolCall};
96 pub use crate::providers::claude::ClaudeCodeProvider;
97 pub use crate::providers::record_replay::RecordReplayProvider;
98 pub use crate::retry::RetryPolicy;
99 pub use crate::tracker::WorkflowTracker;
100 pub use schemars::JsonSchema;
101 pub use serde::{Deserialize, Serialize};
102}