enact-core 0.0.2

Core agent runtime for Enact - Graph-Native AI agents
Documentation
//! Function node - wraps an async function as a node

use super::{Node, NodeState};
use async_trait::async_trait;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

/// Type alias for async node functions
pub type NodeFn = Arc<
    dyn Fn(NodeState) -> Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
        + Send
        + Sync,
>;

/// Function node - wraps an async closure
pub struct FunctionNode {
    name: String,
    func: NodeFn,
}

impl FunctionNode {
    pub fn new<F, Fut>(name: impl Into<String>, func: F) -> Self
    where
        F: Fn(NodeState) -> Fut + Send + Sync + 'static,
        Fut: Future<Output = anyhow::Result<NodeState>> + Send + 'static,
    {
        let func = Arc::new(move |state: NodeState| {
            let fut = func(state);
            Box::pin(fut) as Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
        });

        Self {
            name: name.into(),
            func,
        }
    }
}

#[async_trait]
impl Node for FunctionNode {
    fn name(&self) -> &str {
        &self.name
    }

    async fn execute(&self, state: NodeState) -> anyhow::Result<NodeState> {
        (self.func)(state).await
    }
}