aimx/lib.rs
1//! # AIM Expressions (AIMX)
2//!
3//! Agentic Inference Markup Expressions (AIMX) is a high-performance, C-like declarative language
4//! for writing formulas to control inference in agentic workflows.
5//!
6//! This rust library provides an entry point to the entire Aim workspace. It is can be used by
7//! server daemons for workflow deployment, integrated development tools for hand coding agentic
8//! workflows, web, desktop and mobile application front ends for both visual design tools and
9//! agentic inference applications.
10//!
11//! The language was created to improve upon the familiar declarative syntax of spreadsheet formulas
12//! by replacing error-prone cell referencing (e.g., `A1`) with a robust, C-style variable naming
13//! convention. This enables powerful, readable patterns like multi-part reference chaining
14//! (`employee.salary`), array indexing (`matrix[index]`), method calling (`sales.average().round_to(2)`)
15//! and functional programming with closures `plan.perform(task => $tool.write_paragraph(task, context))`.
16//! By using a subset of C-like syntax, AIMX is immediately familiar to developers who know
17//! Javascript, TypeScript, C#, or similar languages. It strikes a balance between simplicity and
18//! expressive power, making it effective for a wide range of tasks—from automating business
19//! processes to orchestrating complex AI agent pipelines.
20//!
21//! ## Key Features
22//!
23//! - **C-like Syntax**: Familiar operators and expressions with simplified syntax
24//! - **Rich Type System**: Strong typing with automatic type promotion and casting
25//! - **Built-in Functions**: Comprehensive standard library with mathematical, text, date, and collection functions
26//! - **Agentic Workflow Integration**: Native support for AI inference calls and task management
27//! - **Concurrent Architecture**: Thread-safe evaluation with multi-version concurrency control
28//! - **Extensible**: Custom function registration and modular design
29//!
30//! # Quick Start
31//!
32//! ```rust
33//! use aimx::{aimx_parse, ExpressionLike, Context, Literal, Value};
34//!
35//! // Parse and evaluate a simple expression
36//! let expression = aimx_parse("2 + 3 * 4");
37//! let mut context = Context::new();
38//! let result = expression.evaluate(&mut context).unwrap();
39//! assert_eq!(result.to_string(), "14");
40//!
41//! // Work with variables and functions
42//! let mut context = Context::new()
43//! .with_value("base_price", Value::Literal(Literal::Number(100.0)))
44//! .with_value("tax_rate", Value::Literal(Literal::Number(0.08)));
45//!
46//! let expression = aimx_parse("base_price * (1 + tax_rate)");
47//! let result = expression.evaluate(&mut context).unwrap();
48//! assert_eq!(result.to_string(), "108");
49//! ```
50//!
51//! # Core Concepts
52//!
53//! ## Expressions and Evaluation
54//!
55//! AIMX expressions are parsed into an abstract syntax tree (AST) that can be evaluated
56//! within a context. The context provides variable values, function implementations, and
57//! manages the runtime environment.
58//!
59//! ```rust
60//! use aimx::{aimx_parse, ExpressionLike, Context};
61//!
62//! // Parse expressions
63//! let expr1 = aimx_parse("5 > 3 ? \"yes\" : \"no\"");
64//! let expr2 = aimx_parse("sqrt(16) + abs(-5)");
65//!
66//! // Evaluate in context
67//! let mut context = Context::new();
68//! let result1 = expr1.evaluate(&mut context).unwrap();
69//! let result2 = expr2.evaluate(&mut context).unwrap();
70//!
71//! assert_eq!(result1.to_string(), "yes");
72//! assert_eq!(result2.to_string(), "9");
73//! ```
74//!
75//! ## Type System
76//!
77//! AIMX is a strongly typed language with automatic type promotion. The left operand's type
78//! generally dictates the conversion for the right operand.
79//!
80//! ```rust
81//! use aimx::{aimx_parse, ExpressionLike, Context};
82//!
83//! let mut context = Context::new();
84//!
85//! // Type promotion examples
86//! let expr1 = aimx_parse("\"Total: \" + 42"); // String promotion → "Total: 42"
87//! let expr2 = aimx_parse("2 + \"40\""); // Number promotion → 42
88//! let expr3 = aimx_parse("(Text)96"); // Explicit casting → "96"
89//!
90//! // Boolean conversion (any type can be converted to bool)
91//! let expr4 = aimx_parse("value ? value : \"default\"");
92//! ```
93//!
94//! ## Grammar Reference
95//!
96//! ### Operators (in order of precedence, highest to lowest)
97//!
98//! | Operators | Description | Associativity |
99//! |-----------|-------------|---------------|
100//! | `()` | Parentheses | Left to right |
101//! | `_` | Empty placeholder | Singular |
102//! | `=>` | Closure | Left to right |
103//! | `.` `()` `[]` `$` | Postfix operations | Left to right |
104//! | `!` `+` `-` `(type)` | Unary operators | Right to left |
105//! | `*` `/` `%` | Multiplicative | Left to right |
106//! | `+` `-` | Additive | Left to right |
107//! | `<` `<=` `>` `>=` | Relational | Left to right |
108//! | `=` `!=` | Equality | Left to right |
109//! | `&` `&&` | Logical AND | Left to right |
110//! | `|` `||` | Logical OR | Left to right |
111//! | `?` `:` | Conditional (ternary) | Right to left |
112//! | `,` | Array separator | Left to right |
113//! | `;` | Procedure separator (closures only) | Left to right |
114//!
115//! ### Data Types
116//!
117//! - **`Bool`**: Boolean values (`true` or `false`)
118//! - **`Number`**: 64-bit floating point numbers
119//! - **`Text`**: UTF-8 string values
120//! - **`Date`**: Date and time values
121//! - **`Task`**: Task primitives with status and description
122//! - **`Array`**: Collections of values (homogeneous or heterogeneous)
123//! - **`Closure`**: First-class anonymous functions
124//! - **`Node`**: References to workflow files
125//!
126//! ### Special Syntax
127//!
128//! **Tasks**: AIMX has dedicated syntax for creating tasks that consumes the `[]` prefix:
129//!
130//! ```text
131//! [x] "A completed task" // → Boolean true
132//! [-] "A failed task" // → Number -1.0
133//! [ ] "A pending task" // → Text value
134//! ```
135//!
136//! **Arrays**: Because `[]` is used for tasks, arrays use parentheses like argument lists in C:
137//!
138//! ```rust
139//! use aimx::{aimx_parse, ExpressionLike, Context};
140//!
141//! let mut context = Context::new();
142//!
143//! // Array expressions
144//! let expr = aimx_parse("(1, 2, 3).sum()");
145//! let result = expr.evaluate(&mut context).unwrap();
146//! assert_eq!(result.to_string(), "6");
147//! ```
148//!
149//! ## Agentic Workflow Integration
150//!
151//! AIMX is designed for agentic workflow applications with special conventions for AI inference:
152//!
153//! - **Assignment Rules** (`_` prefix): Rules prefixed with underscore are meant to be populated by AI inference
154//! - **Modifier Rules** (UPPERCASE): All-uppercase identifiers construct prompts for language models
155//! - **Inference Calls** (`$` prefix): References starting with `$` trigger inference calls to workflow nodes
156//!
157//! ```rust
158//! # // Note: This example shows the pattern, actual inference integration requires workflow setup
159//! # use aimx::{aimx_parse, ExpressionLike, Context};
160//! #
161//! # let mut context = Context::new();
162//! # let expr = aimx_parse("$tool.summarize_email(message_body)");
163//! # // The above would trigger inference on the 'summarize_email' workflow node
164//! ```
165//!
166//! # Examples
167//!
168//! ```rust
169//! use aimx::{aimx_parse, ExpressionLike, Context};
170//!
171//! let mut context = Context::new();
172//!
173//! // Mathematical expressions
174//! let expr = aimx_parse("(2 + 3) * 4 / 2");
175//! assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "10");
176//!
177//! // Boolean logic
178//! let expr = aimx_parse("true & false | !false");
179//! assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "true");
180//!
181//! // String operations
182//! let expr = aimx_parse("\"hello\".upper() + \" \" + \"WORLD\".lower()");
183//! assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "HELLO world");
184//!
185//! // Array operations
186//! let expr = aimx_parse("(1, 5, 3).max()");
187//! assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "5");
188//!
189//! // Function composition
190//! let expr = aimx_parse("sqrt(pow(2, 2) + max((1, 3))).round_to(5)");
191//! assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "2.64575");
192//!
193//! // Or simpler:
194//! let expr = aimx_parse("sqrt(16)");
195//! assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "4");
196//! ```
197//!
198//! # Architecture
199//!
200//! The crate is organized into several modules that handle different aspects of parsing and evaluation:
201//!
202//! ## Core Modules
203//!
204//! - [`parser`] - Main parsing interface [`aimx_parse`]
205//! - [`expression`] - Top-level [`Expression`] AST and parsing
206//! - [`evaluate`] - Core evaluation traits [`ExpressionLike`], [`ContextLike`]
207//! - [`value`] - Runtime [`Value`] representation
208//! - [`context`] - Default [`Context`] implementation
209//! - [`literal`] - [`Literal`] value parsing and representation
210//!
211//! ## Workflow Management
212//!
213//! - [`workflow`] - [`Workflow`] struct and [`WorkflowLike`] trait
214//! - [`workspace`] - Global workspace management
215//! - [`rule`] - Workflow [`Rule`] definitions
216//! - [`aim`] - Agentic Inference Markup file format handling
217//!
218//! ## Function System
219//!
220//! - [`function_registry`] - Function registration and calling
221//! - [`functions`] - Built-in function libraries
222//! - Mathematical, text, date, business, statistical, and collection functions - Comprehensive standard library
223//!
224//! ## Expression Grammar
225//!
226//! - [`expressions`] - Operator-specific expression parsing
227//! - [`expressions::primary`], [`expressions::closure`], [`expressions::conditional`], etc.
228//! - [`literals`] - Literal value parsing modules
229//! - [`values`] - Special value types and utilities
230//!
231//! ## Inference Integration
232//!
233//! - [`inference`] - AI provider integration and inference handling
234//! - [`inference::provider`], [`inference::prompt`], [`inference::request`], etc.
235//!
236//! # Concurrency Model
237//!
238//! AIMX uses a sophisticated multi-version concurrency control (MVCC) model:
239//!
240//! - **Non-blocking Reads**: Unlimited concurrent readers access consistent snapshots
241//! - **Atomic Writes**: Writers operate on isolated copies before publishing changes
242//! - **Fine-grained Locking**: Per-workflow locking instead of global workspace locking
243//! - **Lazy Loading**: Workflows are loaded on-demand when first accessed
244//!
245//! This architecture ensures high performance for agentic workflows where many tasks
246//! may need to evaluate expressions simultaneously without blocking.
247//!
248//! # Error Handling
249//!
250//! The parser and evaluator provide comprehensive error handling:
251//!
252//! ```rust
253//! use aimx::{aimx_parse, ExpressionLike, Context};
254//!
255//! let mut context = Context::new();
256//!
257//! // Parsing errors are captured in the Expression result
258//! let expr = aimx_parse("2 + * 3"); // Invalid syntax
259//! if expr.has_error() {
260//! println!("Parsing failed: {}", expr);
261//! }
262//!
263//! // Evaluation errors are returned as Result types
264//! let expr = aimx_parse("10 / 0");
265//! match expr.evaluate(&mut context) {
266//! Ok(value) => println!("Result: {}", value),
267//! Err(e) => println!("Evaluation error: {}", e),
268//! }
269//! ```
270//!
271//! # Performance Considerations
272//!
273//! - **Static Evaluation**: Use [`statically_evaluate`] for expressions without external dependencies
274//! - **Function Registry**: The singleton function registry is thread-safe and efficient
275//! - **AST Optimization**: Expressions are flattened for optimal evaluation performance
276//! - **Lazy Resolution**: Variable references and function calls are resolved on-demand
277//!
278//! # Getting Started
279//!
280//! Add AIMX to your `Cargo.toml`:
281//!
282//! ```toml
283//! [dependencies]
284//! aimx = "0.9.1"
285//! ```
286//!
287//! Then start parsing and evaluating expressions:
288//!
289//! ```rust
290//! use aimx::{aimx_parse, ExpressionLike, Context, Literal, Value};
291//!
292//! fn main() -> anyhow::Result<()> {
293//! let expression = aimx_parse("(temperature - 32) * 5/9");
294//! let mut context = Context::new()
295//! .with_value("temperature", Value::Literal(Literal::Number(68.0)));
296//!
297//! let result = expression.evaluate(&mut context)?;
298//! println!("Celsius: {}", result);
299//!
300//! Ok(())
301//! }
302//! ```
303
304// Core parsing and evaluation modules
305pub mod context;
306pub mod evaluate;
307pub mod expression;
308pub mod function_registry;
309pub mod literal;
310pub mod macros;
311pub mod parser;
312pub mod rule;
313pub mod typedef;
314pub mod value;
315pub mod workflow;
316pub mod workspace;
317pub mod writer;
318
319// Agentic Inference Markup (AIM) modules
320pub mod aim;
321// Expression modules
322pub mod expressions;
323// Function registry and built-in functions
324pub mod functions;
325// Inference modules
326pub mod inference;
327// Literal modules
328pub mod literals;
329// Special value modules
330pub mod values;
331
332// Re-export key types for easier access
333pub use aim::{AppName, get_config, get_config_mut, get_lock_manager};
334pub use context::{ContextLike, Context};
335pub use evaluate::{ExpressionLike, evaluate_and_promote, statically_evaluate};
336pub use expression::{Expression, parse_argument_list, parse_expression};
337pub use expressions::{Primary, Reference};
338pub use function_registry::FunctionRegistry;
339pub use inference::{Api, Model, Capability, Provider, generate_prompt, send_request, parse_response, validate_responses};
340pub use literal::{Literal, parse_bool, parse_literal, parse_task};
341pub use parser::aimx_parse;
342pub use rule::{Rule, parse_rule};
343pub use typedef::{Typedef, parse_literal_type, parse_typedef};
344pub use value::{Value, parse_value};
345pub use values::Node;
346pub use workflow::{WorkflowLike, Workflow};
347pub use workspace::{get_workspace, load_workspace, create_path, add_node_rule, rename_node_rule, delete_node_rule};
348pub use writer::{Prefix, PrintMode, Writer};