enact-core 0.0.2

Core agent runtime for Enact - Graph-Native AI agents
Documentation
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GraphDefinition {
    pub name: String,
    #[serde(default = "default_version")]
    pub version: String,
    pub description: Option<String>,
    #[serde(default)]
    pub model: Option<String>, // default model for all LLM nodes in this graph
    #[serde(default)]
    pub triggers: Vec<String>, // "manual", "cron:...", etc.
    #[serde(default)]
    pub inputs: HashMap<String, String>, // name -> description or type
    pub nodes: HashMap<String, NodeDefinition>,
}

fn default_version() -> String {
    "1.0".to_string()
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum NodeDefinition {
    /// LLM-based agent node
    Llm {
        #[serde(default)]
        model: Option<String>, // e.g., "gpt-4o"
        system_prompt: String,
        #[serde(default)]
        tools: Vec<String>, // tool names
        #[serde(default)]
        edges: HashMap<String, String>, // output matching -> target node
    },
    /// Function execution node (e.g., shell command, script)
    Function {
        action: String, // e.g., "scripts/check_style.sh"
        #[serde(default)]
        edges: HashMap<String, String>,
    },
    /// Conditional branching node (no LLM, just logic)
    Condition {
        expr: String,                   // e.g. "input.contains('error')"
        edges: HashMap<String, String>, // "true" -> nodeA, "false" -> nodeB
    },
    /// Sub-graph execution
    Graph {
        graph_name: String,
        #[serde(default)]
        edges: HashMap<String, String>,
    },
}

impl NodeDefinition {
    pub fn edges(&self) -> &HashMap<String, String> {
        match self {
            NodeDefinition::Llm { edges, .. } => edges,
            NodeDefinition::Function { edges, .. } => edges,
            NodeDefinition::Condition { edges, .. } => edges,
            NodeDefinition::Graph { edges, .. } => edges,
        }
    }
}