use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq)]
pub enum Token {
Ident(String),
Str(String),
Num(f64),
LBrace,
RBrace,
LBracket,
RBracket,
Arrow,
Comma,
Eof,
}
impl Token {
pub fn describe(&self) -> String {
match self {
Token::Ident(s) => format!("identifier `{s}`"),
Token::Str(_) => "string".to_string(),
Token::Num(_) => "number".to_string(),
Token::LBrace => "`{`".to_string(),
Token::RBrace => "`}`".to_string(),
Token::LBracket => "`[`".to_string(),
Token::RBracket => "`]`".to_string(),
Token::Arrow => "`->`".to_string(),
Token::Comma => "`,`".to_string(),
Token::Eof => "end of input".to_string(),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Span {
pub line: usize,
pub column: usize,
}
impl Span {
pub fn new(line: usize, column: usize) -> Self {
Self { line, column }
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct SpannedToken {
pub token: Token,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
pub enum Literal {
Str(String),
Num(f64),
Ident(String),
}
#[derive(Clone, Debug, PartialEq)]
pub struct Program {
pub graphs: Vec<GraphDecl>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GraphDecl {
pub name: String,
pub span: Span,
pub start: Option<String>,
pub defaults: Vec<(String, Literal)>,
pub channels: Vec<ChannelDecl>,
pub nodes: Vec<NodeDecl>,
pub edges: Vec<EdgeDecl>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct ChannelDecl {
pub name: String,
pub reducer: String,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq)]
pub struct NodeDecl {
pub name: String,
pub kind: Option<String>,
pub model: Option<String>,
pub prompt: Option<String>,
pub tools: Vec<String>,
pub next: Option<String>,
pub routes: Vec<RouteDecl>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq)]
pub struct RouteDecl {
pub label: String,
pub target: String,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq)]
pub struct EdgeDecl {
pub from: String,
pub to: String,
pub span: Span,
}
pub const END: &str = "END";
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Blueprint {
pub graph_id: String,
pub start: String,
pub channels: Vec<ChannelSpec>,
pub nodes: Vec<NodeSpec>,
pub edges: Vec<EdgeSpec>,
pub defaults: Vec<(String, Literal)>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChannelSpec {
pub name: String,
pub reducer: String,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct NodeSpec {
pub name: String,
pub kind: String,
pub model: Option<String>,
pub prompt: Option<String>,
pub tools: Vec<String>,
pub routing: Routing,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
pub enum Routing {
Next(String),
Conditional(Vec<(String, String)>),
Terminal,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct EdgeSpec {
pub from: String,
pub to: String,
}