pub mod checkpoint_store;
mod graph;
mod node;
pub mod state;
pub use checkpoint_store::{
Checkpoint, CheckpointInfo, CheckpointStore, FileCheckpointStore, InterruptType,
MemoryCheckpointStore,
};
pub use graph::{
Graph, GraphBuilder, GraphResult, InterruptConfig, InterruptState, RunUntilInterruptResult,
};
pub use state::SharedState;
mod concurrent;
mod dag;
mod sequential;
pub use concurrent::{ConcurrentWorkflow, ConcurrentWorkflowBuilder};
pub use dag::{DagEdge, DagNode, DagWorkflow, DagWorkflowBuilder};
pub use sequential::{SequentialWorkflow, SequentialWorkflowBuilder, WorkflowStep};
use echo_core::agent::Agent;
use echo_core::error::Result;
use futures::future::BoxFuture;
use futures::stream::BoxStream;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex as AsyncMutex;
pub type SharedAgent = Arc<AsyncMutex<Box<dyn Agent>>>;
pub fn shared_agent(agent: impl Agent + 'static) -> SharedAgent {
Arc::new(AsyncMutex::new(Box::new(agent)))
}
#[derive(Debug, Clone)]
pub enum WorkflowEvent {
NodeStart {
node_name: String,
step_index: usize,
},
NodeEnd {
node_name: String,
step_index: usize,
elapsed: Duration,
},
Token { node_name: String, token: String },
NodeError { node_name: String, error: String },
Completed {
result: String,
total_steps: usize,
elapsed: Duration,
},
}
pub trait Workflow: Send + Sync {
fn run<'a>(&'a mut self, input: &'a str) -> BoxFuture<'a, Result<WorkflowOutput>>;
fn run_stream<'a>(
&'a mut self,
input: &'a str,
) -> BoxFuture<'a, Result<BoxStream<'a, Result<WorkflowEvent>>>> {
Box::pin(async move {
let output = self.run(input).await?;
let event = WorkflowEvent::Completed {
result: output.result,
total_steps: output.steps.len(),
elapsed: output.elapsed,
};
let stream: BoxStream<'a, Result<WorkflowEvent>> =
Box::pin(futures::stream::once(async { Ok(event) }));
Ok(stream)
})
}
}
#[derive(Debug, Clone)]
pub struct WorkflowOutput {
pub result: String,
pub steps: Vec<StepOutput>,
pub elapsed: Duration,
}
#[derive(Debug, Clone)]
pub struct StepOutput {
pub agent_name: String,
pub input: String,
pub output: String,
pub elapsed: Duration,
}