Crate aimx

Source
Expand description

§AIM Expressions (AIMX)

Agentic Inference Markup Expressions (AIMX) is a high-performance, C-like declarative language for writing formulas to control inference in agentic workflows.

This rust library provides an entry point to the entire Aim workspace. It is can be used by server daemons for workflow deployment, integrated development tools for hand coding agentic workflows, web, desktop and mobile application front ends for both visual design tools and agentic inference applications.

The language was created to improve upon the familiar declarative syntax of spreadsheet formulas by replacing error-prone cell referencing (e.g., A1) with a robust, C-style variable naming convention. This enables powerful, readable patterns like multi-part reference chaining (employee.salary), array indexing (matrix[index]), method calling (sales.average().round_to(2)) and functional programming with closures plan.perform(task => $tool.write_paragraph(task, context)). By using a subset of C-like syntax, AIMX is immediately familiar to developers who know Javascript, TypeScript, C#, or similar languages. It strikes a balance between simplicity and expressive power, making it effective for a wide range of tasks—from automating business processes to orchestrating complex AI agent pipelines.

§Key Features

  • C-like Syntax: Familiar operators and expressions with simplified syntax
  • Rich Type System: Strong typing with automatic type promotion and casting
  • Built-in Functions: Comprehensive standard library with mathematical, text, date, and collection functions
  • Agentic Workflow Integration: Native support for AI inference calls and task management
  • Concurrent Architecture: Thread-safe evaluation with multi-version concurrency control
  • Extensible: Custom function registration and modular design

§Quick Start

use aimx::{aimx_parse, ExpressionLike, Context, Literal, Value};

// Parse and evaluate a simple expression
let expression = aimx_parse("2 + 3 * 4");
let mut context = Context::new();
let result = expression.evaluate(&mut context).unwrap();
assert_eq!(result.to_string(), "14");

// Work with variables and functions
let mut context = Context::new()
    .with_value("base_price", Value::Literal(Literal::Number(100.0)))
    .with_value("tax_rate", Value::Literal(Literal::Number(0.08)));
 
let expression = aimx_parse("base_price * (1 + tax_rate)");
let result = expression.evaluate(&mut context).unwrap();
assert_eq!(result.to_string(), "108");

§Core Concepts

§Expressions and Evaluation

AIMX expressions are parsed into an abstract syntax tree (AST) that can be evaluated within a context. The context provides variable values, function implementations, and manages the runtime environment.

use aimx::{aimx_parse, ExpressionLike, Context};

// Parse expressions
let expr1 = aimx_parse("5 > 3 ? \"yes\" : \"no\"");
let expr2 = aimx_parse("sqrt(16) + abs(-5)");
 
// Evaluate in context
let mut context = Context::new();
let result1 = expr1.evaluate(&mut context).unwrap();
let result2 = expr2.evaluate(&mut context).unwrap();
 
assert_eq!(result1.to_string(), "yes");
assert_eq!(result2.to_string(), "9");

§Type System

AIMX is a strongly typed language with automatic type promotion. The left operand’s type generally dictates the conversion for the right operand.

use aimx::{aimx_parse, ExpressionLike, Context};

let mut context = Context::new();
 
// Type promotion examples
let expr1 = aimx_parse("\"Total: \" + 42");     // String promotion → "Total: 42"
let expr2 = aimx_parse("2 + \"40\"");           // Number promotion → 42
let expr3 = aimx_parse("(Text)96");            // Explicit casting → "96"
 
// Boolean conversion (any type can be converted to bool)
let expr4 = aimx_parse("value ? value : \"default\"");

§Grammar Reference

§Operators (in order of precedence, highest to lowest)

OperatorsDescriptionAssociativity
()ParenthesesLeft to right
_Empty placeholderSingular
=>ClosureLeft to right
. () [] $Postfix operationsLeft to right
! + - (type)Unary operatorsRight to left
* / %MultiplicativeLeft to right
+ -AdditiveLeft to right
< <= > >=RelationalLeft to right
= !=EqualityLeft to right
& &&Logical ANDLeft to right
`
? :Conditional (ternary)Right to left
,Array separatorLeft to right
;Procedure separator (closures only)Left to right

§Data Types

  • Bool: Boolean values (true or false)
  • Number: 64-bit floating point numbers
  • Text: UTF-8 string values
  • Date: Date and time values
  • Task: Task primitives with status and description
  • Array: Collections of values (homogeneous or heterogeneous)
  • Closure: First-class anonymous functions
  • Node: References to workflow files

§Special Syntax

Tasks: AIMX has dedicated syntax for creating tasks that consumes the [] prefix:

[x] "A completed task"      // → Boolean true
[-] "A failed task"        // → Number -1.0
[ ] "A pending task"       // → Text value

Arrays: Because [] is used for tasks, arrays use parentheses like argument lists in C:

use aimx::{aimx_parse, ExpressionLike, Context};

let mut context = Context::new();
 
// Array expressions
let expr = aimx_parse("(1, 2, 3).sum()");
let result = expr.evaluate(&mut context).unwrap();
assert_eq!(result.to_string(), "6");

§Agentic Workflow Integration

AIMX is designed for agentic workflow applications with special conventions for AI inference:

  • Assignment Rules (_ prefix): Rules prefixed with underscore are meant to be populated by AI inference
  • Modifier Rules (UPPERCASE): All-uppercase identifiers construct prompts for language models
  • Inference Calls ($ prefix): References starting with $ trigger inference calls to workflow nodes

§Examples

use aimx::{aimx_parse, ExpressionLike, Context};
 
let mut context = Context::new();
 
// Mathematical expressions
let expr = aimx_parse("(2 + 3) * 4 / 2");
assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "10");
 
// Boolean logic
let expr = aimx_parse("true & false | !false");
assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "true");
 
// String operations
let expr = aimx_parse("\"hello\".upper() + \" \" + \"WORLD\".lower()");
assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "HELLO world");
 
// Array operations
let expr = aimx_parse("(1, 5, 3).max()");
assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "5");
 
// Function composition
let expr = aimx_parse("sqrt(pow(2, 2) + max((1, 3))).round_to(5)");
assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "2.64575");

// Or simpler:
let expr = aimx_parse("sqrt(16)");
assert_eq!(expr.evaluate(&mut context).unwrap().to_string(), "4");

§Architecture

The crate is organized into several modules that handle different aspects of parsing and evaluation:

§Core Modules

§Workflow Management

§Function System

  • function_registry - Function registration and calling
  • functions - Built-in function libraries
  • Mathematical, text, date, business, statistical, and collection functions - Comprehensive standard library

§Expression Grammar

§Inference Integration

§Concurrency Model

AIMX uses a sophisticated multi-version concurrency control (MVCC) model:

  • Non-blocking Reads: Unlimited concurrent readers access consistent snapshots
  • Atomic Writes: Writers operate on isolated copies before publishing changes
  • Fine-grained Locking: Per-workflow locking instead of global workspace locking
  • Lazy Loading: Workflows are loaded on-demand when first accessed

This architecture ensures high performance for agentic workflows where many tasks may need to evaluate expressions simultaneously without blocking.

§Error Handling

The parser and evaluator provide comprehensive error handling:

use aimx::{aimx_parse, ExpressionLike, Context};

let mut context = Context::new();
 
// Parsing errors are captured in the Expression result
let expr = aimx_parse("2 + * 3"); // Invalid syntax
if expr.has_error() {
    println!("Parsing failed: {}", expr);
}
 
// Evaluation errors are returned as Result types
let expr = aimx_parse("10 / 0");
match expr.evaluate(&mut context) {
    Ok(value) => println!("Result: {}", value),
    Err(e) => println!("Evaluation error: {}", e),
}

§Performance Considerations

  • Static Evaluation: Use statically_evaluate for expressions without external dependencies
  • Function Registry: The singleton function registry is thread-safe and efficient
  • AST Optimization: Expressions are flattened for optimal evaluation performance
  • Lazy Resolution: Variable references and function calls are resolved on-demand

§Getting Started

Add AIMX to your Cargo.toml:

[dependencies]
aimx = "0.9.1"

Then start parsing and evaluating expressions:

use aimx::{aimx_parse, ExpressionLike, Context, Literal, Value};

fn main() -> anyhow::Result<()> {
    let expression = aimx_parse("(temperature - 32) * 5/9");
    let mut context = Context::new()
        .with_value("temperature", Value::Literal(Literal::Number(68.0)));
     
    let result = expression.evaluate(&mut context)?;
    println!("Celsius: {}", result);
     
    Ok(())
}

Re-exports§

pub use aim::AppName;
pub use aim::get_config;
pub use aim::get_config_mut;
pub use aim::get_lock_manager;
pub use context::ContextLike;
pub use context::Context;
pub use evaluate::ExpressionLike;
pub use evaluate::evaluate_and_promote;
pub use evaluate::statically_evaluate;
pub use expression::Expression;
pub use expression::parse_argument_list;
pub use expression::parse_expression;
pub use expressions::Primary;
pub use expressions::Reference;
pub use function_registry::FunctionRegistry;
pub use inference::Api;
pub use inference::Model;
pub use inference::Capability;
pub use inference::Provider;
pub use inference::generate_prompt;
pub use inference::send_request;
pub use inference::parse_response;
pub use inference::validate_responses;
pub use literal::Literal;
pub use literal::parse_bool;
pub use literal::parse_literal;
pub use literal::parse_task;
pub use parser::aimx_parse;
pub use rule::Rule;
pub use rule::parse_rule;
pub use typedef::Typedef;
pub use typedef::parse_literal_type;
pub use typedef::parse_typedef;
pub use value::Value;
pub use value::parse_value;
pub use values::Node;
pub use workflow::WorkflowLike;
pub use workflow::Workflow;
pub use workspace::get_workspace;
pub use workspace::load_workspace;
pub use workspace::create_path;
pub use workspace::add_node_rule;
pub use workspace::rename_node_rule;
pub use workspace::delete_node_rule;
pub use writer::Prefix;
pub use writer::PrintMode;
pub use writer::Writer;

Modules§

aim
Agentic Inference Markup (AIM) file format support
context
Evaluation context for expression evaluation within AIM workflows.
evaluate
Core evaluation traits and utilities for AIMX expressions.
expression
Top-level expression parsing and evaluation for the AIMX language.
expressions
Expression parsing and evaluation modules for the AIMX language.
function_registry
Function registry and calling interface.
functions
Built-in function library for AIM expressions.
inference
AIMX Inference Module
literal
Literal value parsing and representation for the AIM expression grammar.
literals
Literal parsing modules for the AIM expression grammar.
macros
Macros for defining AIMX functions with type safety.
parser
Main parsing interface for AIMX expressions.
rule
Agentic Inference Markup (AIM) Rules
typedef
Type definitions for the AIM expression grammar.
value
Runtime value representation for AIM Expressions (AIMX).
values
Special value types for AIMX expressions.
workflow
Workflow Management
workspace
Workspace Management
writer
Buffered writer for serializing AIM data structures.

Macros§

define_direct_function
Macro for functions that return direct values (not Result<T, E>) Uses convert_result_to_value() for direct value types
define_function
Two-macro solution for better type safety and clarity
define_implicit_function
Macro for defining implicit functions that work with specific value types.