takeln 0.11.0

Typed Rust runtime for durable DAG-based agent workflows
Documentation
use async_trait::async_trait;
use takeln::{Graph, GraphError, InMemoryCheckpointer, Node, NodeContext, NodeOutput};

#[derive(Clone, serde::Serialize, serde::Deserialize, Default, Debug)]
struct ChainState {
    output: String,
}

struct StepNode {
    text: String,
}

#[async_trait]
impl Node<ChainState> for StepNode {
    async fn call(&self, _ctx: NodeContext, mut state: ChainState) -> Result<NodeOutput<ChainState>, GraphError> {
        state.output.push_str(&self.text);
        state.output.push(' ');
        Ok(NodeOutput::bare(state))
    }
}

#[tokio::main]
async fn main() {
    let mut graph = Graph::new();
    graph.add_node(
        "Node1",
        StepNode {
            text: "hello".to_string(),
        },
    );
    graph.add_node(
        "Node2",
        StepNode {
            text: "from".to_string(),
        },
    );
    graph.add_node(
        "Node3",
        StepNode {
            text: "takeln".to_string(),
        },
    );

    graph.add_edge("Node1", "Node2");
    graph.add_edge("Node2", "Node3");
    graph.add_edge("Node3", "__END__");

    let checkpointer = InMemoryCheckpointer::new();
    let initial_state = ChainState::default();

    println!("Starting simple chain execution...");
    let final_state = graph
        .run("thread_chain", initial_state, "Node1", &checkpointer, None)
        .await
        .unwrap();

    println!("Execution finished. Output: '{}'", final_state.output.trim());
}