mod accessors;
mod artifacts;
mod error_handlers;
mod failure;
mod guard;
mod lifecycle;
mod steps;
#[cfg(test)]
mod tests;
use std::collections::HashMap;
use std::fmt;
use std::sync::Arc;
use rust_decimal::Decimal;
use uuid::Uuid;
use ironflow_core::decision::DecisionProvider;
use ironflow_core::provider::AgentProvider;
use ironflow_core::trace_context::WorkflowTraceContext;
use ironflow_store::models::Step;
use ironflow_store::store::Store;
use crate::artifact::ArtifactSink;
use crate::config::StepConfig;
use crate::executor::StepResult;
use crate::guard::{SharedGuardState, WorkflowGuardConfig};
use crate::handler::WorkflowHandler;
use crate::log_sender::LogSender;
use crate::notify::WorkflowEventBus;
use crate::operation::OperationContext;
use crate::plan::SharedPlanRecorder;
pub(crate) type HandlerResolver =
Arc<dyn Fn(&str) -> Option<Arc<dyn WorkflowHandler>> + Send + Sync>;
pub struct WorkflowContext {
run_id: Uuid,
workflow_name: String,
store: Arc<dyn Store>,
provider: Arc<dyn AgentProvider>,
decision_provider: Option<Arc<dyn DecisionProvider>>,
handler_resolver: Option<HandlerResolver>,
position: u32,
last_step_ids: Vec<Uuid>,
total_cost_usd: Decimal,
total_duration_ms: u64,
max_cost_usd: Option<Decimal>,
inherited_cost_usd: Decimal,
replay_steps: HashMap<u32, Step>,
granted_approvals: HashMap<u32, u32>,
attempt: u32,
carried_duration_ms: u64,
log_sender: Option<LogSender>,
artifact_sink: Option<Arc<dyn ArtifactSink>>,
has_allowed_failure: bool,
error_handlers: Vec<OnErrorHandler>,
guard_state: Option<SharedGuardState>,
guard_config: Option<WorkflowGuardConfig>,
step_results: Vec<StepResult>,
event_bus: Option<WorkflowEventBus>,
trace_context: WorkflowTraceContext,
operation_ctx: Option<OperationContext>,
plan: Option<SharedPlanRecorder>,
}
struct OnErrorHandler {
name: String,
config: StepConfig,
}
impl fmt::Debug for WorkflowContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WorkflowContext")
.field("run_id", &self.run_id)
.field("position", &self.position)
.field("total_cost_usd", &self.total_cost_usd)
.field("inherited_cost_usd", &self.inherited_cost_usd)
.field("max_cost_usd", &self.max_cost_usd)
.field("planning", &self.plan.is_some())
.finish_non_exhaustive()
}
}