pub struct WorkflowContext { /* private fields */ }Expand description
Execution context for a single workflow run.
Tracks the current step position and provides convenience methods for executing operations with automatic persistence.
§Examples
use ironflow_engine::context::WorkflowContext;
use ironflow_engine::config::ShellConfig;
use ironflow_engine::error::EngineError;
let result = ctx.shell("greet", ShellConfig::new("echo hello")).await?;
assert!(result.output["stdout"].as_str().unwrap().contains("hello"));Implementations§
Source§impl WorkflowContext
impl WorkflowContext
Sourcepub fn new(
run_id: Uuid,
store: Arc<dyn RunStore>,
provider: Arc<dyn AgentProvider>,
) -> Self
pub fn new( run_id: Uuid, store: Arc<dyn RunStore>, provider: Arc<dyn AgentProvider>, ) -> Self
Create a new context for a run.
Not typically called directly — the Engine
creates this when executing a WorkflowHandler.
Sourcepub fn total_cost_usd(&self) -> Decimal
pub fn total_cost_usd(&self) -> Decimal
Accumulated cost across all executed steps so far.
Sourcepub fn total_duration_ms(&self) -> u64
pub fn total_duration_ms(&self) -> u64
Accumulated duration across all executed steps so far.
Sourcepub async fn parallel(
&mut self,
steps: Vec<(&str, StepConfig)>,
fail_fast: bool,
) -> Result<Vec<ParallelStepResult>, EngineError>
pub async fn parallel( &mut self, steps: Vec<(&str, StepConfig)>, fail_fast: bool, ) -> Result<Vec<ParallelStepResult>, EngineError>
Execute multiple steps concurrently (wait-all model).
All steps in the batch execute in parallel via tokio::JoinSet.
Each step is recorded with the same position (execution wave).
Dependencies on previous steps are recorded automatically.
When fail_fast is true, remaining steps are aborted on the first
failure. When false, all steps run to completion and the first
error is returned.
§Errors
Returns EngineError if any step fails.
§Examples
use ironflow_engine::context::WorkflowContext;
use ironflow_engine::config::{StepConfig, ShellConfig};
use ironflow_engine::error::EngineError;
let results = ctx.parallel(
vec![
("test-unit", StepConfig::Shell(ShellConfig::new("cargo test --lib"))),
("lint", StepConfig::Shell(ShellConfig::new("cargo clippy"))),
],
true,
).await?;
for r in &results {
println!("{}: {:?}", r.name, r.output.output);
}Sourcepub async fn shell(
&mut self,
name: &str,
config: ShellConfig,
) -> Result<StepOutput, EngineError>
pub async fn shell( &mut self, name: &str, config: ShellConfig, ) -> Result<StepOutput, EngineError>
Execute a shell step.
Creates the step record, runs the command, persists the result, and returns the output for use in subsequent steps.
§Errors
Returns EngineError if the command fails or the store errors.
§Examples
use ironflow_engine::context::WorkflowContext;
use ironflow_engine::config::ShellConfig;
use ironflow_engine::error::EngineError;
let files = ctx.shell("list", ShellConfig::new("ls -la")).await?;
println!("stdout: {}", files.output["stdout"]);Sourcepub async fn http(
&mut self,
name: &str,
config: HttpConfig,
) -> Result<StepOutput, EngineError>
pub async fn http( &mut self, name: &str, config: HttpConfig, ) -> Result<StepOutput, EngineError>
Execute an HTTP step.
§Errors
Returns EngineError if the request fails or the store errors.
§Examples
use ironflow_engine::context::WorkflowContext;
use ironflow_engine::config::HttpConfig;
use ironflow_engine::error::EngineError;
let resp = ctx.http("health", HttpConfig::get("https://api.example.com/health")).await?;
println!("status: {}", resp.output["status"]);Sourcepub async fn agent(
&mut self,
name: &str,
config: AgentStepConfig,
) -> Result<StepOutput, EngineError>
pub async fn agent( &mut self, name: &str, config: AgentStepConfig, ) -> Result<StepOutput, EngineError>
Execute an agent step.
§Errors
Returns EngineError if the agent invocation fails or the store errors.
§Examples
use ironflow_engine::context::WorkflowContext;
use ironflow_engine::config::AgentStepConfig;
use ironflow_engine::error::EngineError;
let review = ctx.agent("review", AgentStepConfig::new("Review the code")).await?;
println!("review: {}", review.output["value"]);Sourcepub async fn operation(
&mut self,
name: &str,
op: &dyn Operation,
) -> Result<StepOutput, EngineError>
pub async fn operation( &mut self, name: &str, op: &dyn Operation, ) -> Result<StepOutput, EngineError>
Execute a custom operation step.
Runs a user-defined Operation with full step lifecycle management:
creates the step record, transitions to Running, executes the operation,
persists the output and duration, and marks the step Completed or Failed.
The operation’s kind() is stored as
StepKind::Custom.
§Errors
Returns EngineError if the operation fails or the store errors.
§Examples
use ironflow_engine::context::WorkflowContext;
use ironflow_engine::operation::Operation;
use ironflow_engine::error::EngineError;
use serde_json::{Value, json};
use std::pin::Pin;
use std::future::Future;
struct MyOp;
impl Operation for MyOp {
fn kind(&self) -> &str { "my-service" }
fn execute(&self) -> Pin<Box<dyn Future<Output = Result<Value, EngineError>> + Send + '_>> {
Box::pin(async { Ok(json!({"ok": true})) })
}
}
let result = ctx.operation("call-service", &MyOp).await?;
println!("output: {}", result.output);Sourcepub async fn workflow(
&mut self,
handler: &dyn WorkflowHandler,
payload: Value,
) -> Result<StepOutput, EngineError>
pub async fn workflow( &mut self, handler: &dyn WorkflowHandler, payload: Value, ) -> Result<StepOutput, EngineError>
Execute a sub-workflow step.
Creates a child run for the named workflow handler, executes it with
its own steps and lifecycle, and returns a StepOutput containing
the child run ID and aggregated metrics.
Requires the context to be created with
with_handler_resolver.
§Errors
Returns EngineError::InvalidWorkflow if no handler is registered
with the given name, or if no handler resolver is available.
§Examples
use ironflow_engine::context::WorkflowContext;
use ironflow_engine::error::EngineError;
use serde_json::json;
// let result = ctx.workflow(&MySubWorkflow, json!({})).await?;Sourcepub async fn payload(&self) -> Result<Value, EngineError>
pub async fn payload(&self) -> Result<Value, EngineError>
Access the payload that triggered this run.
Fetches the run from the store and returns its payload.
§Errors
Returns EngineError::Store if the run is not found.