Aim

Struct Aim 

Source
pub struct Aim {}

Implementations§

Source§

impl Aim

Source

pub fn create(path: Arc<PathBuf>) -> Result<Sheet>

Creates a new AIMX workspace at the specified path with default structure.

§Initializes the foundational directory architecture and system workflow nodes required for agentic workflow management. Creates both .aim and .jnl files for persistent storage with MVCC versioning.
§title: Create

Creates a new AIM workspace at the specified path with the default workspace structure.

This function establishes the foundational directory architecture needed for agentic workflow management and initializes the default system workflow nodes required by the AIM ecosystem.

§Arguments
  • path - An absolute Arc<PathBuf> specifying the directory path where the workspace files will be created
§Returns

Returns a Sheet representing the successfully initialized workspace root structure.

§Errors

Returns an error if:

  • The parent directory cannot be created or accessed
  • The workspace files cannot be written to disk
  • The workspace path has already been initialized (workspace already exists)
§Behavior

Internally, create() performs the following operations:

  1. Path Initialization: Sets up the workspace base path and ensures parent directories exist
  2. Default Node Creation: Initializes the core system workflows including context, inference, status, tool, and workflow management nodes
  3. Persistent Storage: Saves the workspace configuration to disk with MVCC versioning
  4. Workspace Binding: Binds the global workspace singleton to the newly created structure
§Side Effects

This function creates the following directory structure and files:

workspace.aim                     # Main workspace configuration file
workspace.jnl                     # Version journal for MVCC operations
workspace/                        # Directory containing workflow files
  ├── context.aim                 # Context management workflow
  ├── context.jnl                 # Context workflow journal
  ├── inference.aim               # Inference tracking workflow
  ├── inference.jnl               # Inference workflow journal
  ├── status.aim                  # System status workflow
  ├── status.jnl                  # Status workflow journal
  ├── tool.aim                    # Tool integration workflow
  ├── tool.jnl                    # Tool workflow journal
  ├── workflow.aim                # Main workflow container
   └── workflow.jnl                # Workflow journal
§MVCC Behavior

When creating a workspace, create() establishes an initial Multi-Version Concurrency Control (MVCC) context. The first version (epoch 1) is created immediately with all default nodes populated.

  • Initial Version: Starts at epoch 1 with minor version 0
  • Node Population: Default nodes are created as immutable facts in the initial version
  • Concurrent Visibility: Readers see the complete initialized structure immediately after creation
§File Operations

The function creates both the main .aim files and their corresponding .jnl journal files. These files are essential for:

  • Workspace Recovery: Persisting workspace state across application restarts
  • MVCC Tracking: Maintaining version history for concurrent access
  • Cross-Reference Integrity: Ensuring workflow nodes can locate each other correctly
§Usage Pattern
use aimx::{Aim, Sheet};
use std::{path::PathBuf, sync::Arc};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Specify the workspace location
    let workspace_path = Arc::new(PathBuf::from("/path/to/my_workspace"));

    // Create the workspace
    let sheet = Aim::create(workspace_path.clone())?;

    // Use the returned Sheet to inspect workspace metadata
    println!("Created workspace at: {}", sheet.path);
    println!("Workspace locator: {}", sheet.locator);
    println!("Initial version: {}, minor: {}", sheet.version, sheet.minor_version);

    // The workspace is now ready for use with other AIM API functions
    Ok(())
}
§Performance Considerations
  • First-Time Setup: Initial workspace creation involves disk I/O and may take longer than subsequent operations
  • Memory Usage: The global workspace singleton consumes memory proportional to the number of default nodes
  • File System: Creates multiple small files; consider SSD storage for optimal performance
§See Also
Source

pub fn open(path: &Path) -> Result<Sheet>

§Opens an existing AIMX workspace at the specified path.
§title: Open

Opens an existing AIMX workspace at the specified path and returns the workspace metadata as a Sheet.

This function establishes the global workspace singleton and prepares the workspace for subsequent API operations. It should typically be called first when working with an existing AIMX workspace that was previously created with Aim::create.

§Arguments
  • path - A reference to the Path where the workspace file is located. This should point to the main workspace file (typically workspace.aim).
§Returns

Returns a Sheet containing metadata about the workspace structure, including:

  • Workflow locator reference
  • File system path
  • Version information (current, minor, first, latest)
  • Creation timestamp
  • Inference model and pattern configuration
  • Workflow row count
§Errors

Returns an error if:

  • The workspace path has already been initialized by another process running in the same address space
  • File system operations fail when creating parent directories
  • The workspace structure is corrupted or invalid
§Behavior

Internally, open() performs the following operations:

  1. Initializes the workspace base path for file operations
  2. Acquires a write lock on the global workspace singleton
  3. Converts the workspace node to a Sheet using Sheet::convert
  4. Returns the metadata sheet for inspection

The function does not load individual workflow files until they are specifically accessed via other API calls. It only initializes the workspace structure and makes it available for subsequent operations.

§Side Effects
  • Initializes the global workspace singleton
  • Establishes the base path for subsequent file operations
  • Makes the workspace available for all subsequent API calls
  • Creates parent directories if they don’t exist
§Usage Pattern
use aimx::{Aim, Sheet};
use std::path::Path;

fn main() -> anyhow::Result<()> {
    // Open an existing workspace
    let workspace_path = Path::new("/path/to/existing/workspace.aim");
    let sheet = Aim::open(workspace_path)?;

    // Use the sheet metadata
    println!("Workspace version: {}", sheet.version);
    println!("Workflow count: {}", sheet.length);
    Ok(())
}
§See Also
Source

pub fn save() -> Result<()>

§Saves all pending changes to the current workspace.
§title: Save

This function commits all modifications made to the workspace since the last save operation, persisting the changes to disk and making them visible to other processes or future sessions.

The save operation uses Multi-Version Concurrency Control (MVCC) to ensure that concurrent readers can continue accessing previous versions while the save operation completes. Only workspace-level changes are saved; individual workflow instances require Aim::snapshot to persist their changes.

§Returns

Returns Ok(()) if the save operation completes successfully.

§Errors

Returns an error if:

  • The workspace has not been initialized via Aim::create or Aim::open
  • The workspace path is not accessible or writable
  • File system permissions prevent writing to the workspace directory
  • The workspace workflow is in an invalid state
  • I/O errors occur during file writing operations
§Side Effects
  • Writes the main workspace file (workspace.aim) to disk
  • Creates a new journal entry (workspace.jnl) for the save transaction
  • Updates the workspace’s internal version tracking (epoch and partial counters)
  • Makes workspace-level changes visible to concurrent readers via MVCC
  • Acquires exclusive write locks during the save process
§MVCC Behavior

The save operation creates a new version snapshot using Multi-Version Concurrency Control:

  1. Read Consistency: Previous versions remain accessible for concurrent readers during the save
  2. Write Locking: Writers acquire exclusive locks to prevent concurrent modifications
  3. Version Visibility: The new version becomes the current readable state after successful save
  4. Reader Isolation: Existing readers continue to see the version they started with until they refresh
§Usage Pattern
use aimx::{Aim, Cell};
use std::sync::Arc;

// Create or open a workspace
let path = Arc::new(std::path::PathBuf::from("workspace.aim"));
let _sheet = Aim::create(path).unwrap();

// Make some workspace-level changes
let foo_ref = Aim::add("foo", "evaluation").unwrap();
let bar_ref = Aim::add("bar", "inference").unwrap();

// Save workspace changes
Aim::save().unwrap();

// Changes are now persistent and visible to other processes
§Implementation Details

Internally, save() performs the following operations:

  1. Acquires a write lock on the global workspace singleton
  2. Retrieves a mutable copy of the workspace workflow
  3. Calls the workflow’s save() method to persist changes:
    • If changes require a new version, increments the epoch counter
    • If changes are partial, increments the partial counter
    • Writes version headers and rule data to the AIM file
    • Updates the journal file with position information for fast lookup
  4. Updates the workspace node with the saved workflow
  5. Releases the write lock, making changes available to other readers
§Important Notes
  • Scope: This function only saves workspace-level changes. Individual workflow instances must use Aim::snapshot to persist their modifications
  • Atomicity: Save operations are atomic - either the entire save succeeds or fails
  • Durability: Once saved, changes are durable and will persist across application restarts
  • Concurrency: The function is thread-safe and uses internal locking to handle concurrent access
  • Versioning: Each save operation creates a new version entry in the journal file for audit trail and rollback capabilities
§See Also
Source

pub fn save_all() -> Result<()>

§Saves all workflows within the workspace hierarchy.
§title: Save All

This function saves all workflows within the workspace hierarchy, ensuring that all pending changes across the entire workspace tree are persisted to disk. Unlike Aim::save which only saves the root workspace workflow, save_all() traverses the entire workspace tree and saves all modified workflows.

The function uses Multi-Version Concurrency Control (MVCC) to ensure that concurrent readers can continue accessing previous versions while save operations complete. All workflow instances that have been modified must be saved using Aim::snapshot before calling save_all() to ensure their changes are included.

§Returns

Returns Ok(()) if all save operations complete successfully.

§Errors

Returns an error if:

  • The workspace has not been initialized via Aim::create or Aim::open
  • Any workflow in the workspace tree has an inaccessible or unwritable path
  • File system permissions prevent writing to any workflow directory
  • Any workflow is in an invalid state
  • I/O errors occur during file writing operations for any workflow
  • A workflow instance has unsaved changes that need to be snapshotted first
§Side Effects
  • Writes all modified workflow files (.aim) to disk
  • Creates new journal entries (.jnl) for each workflow that required saving
  • Updates version tracking (epoch and partial counters) for all modified workflows
  • Makes all workflow changes visible to concurrent readers via MVCC
  • Acquires exclusive write locks for each workflow during its save process
  • Traverses the entire workspace directory tree, potentially accessing many files
§MVCC Behavior

The save_all operation creates new version snapshots for all modified workflows using Multi-Version Concurrency Control:

  1. Read Consistency: Previous versions remain accessible for concurrent readers during each workflow’s save
  2. Write Locking: Each workflow acquires exclusive locks to prevent concurrent modifications during its individual save
  3. Version Visibility: New versions become the current readable state after each workflow’s successful save
  4. Reader Isolation: Existing readers continue to see the versions they started with until they refresh
  5. Atomic Per-Workflow: Each workflow’s save is atomic, but the overall operation may save workflows incrementally
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Create or open a workspace
let path = Arc::new(std::path::PathBuf::from("workspace.aim"));
let _sheet = Aim::create(path).unwrap();

// Make some changes to various workflows
let foo_ref = Aim::add("foo", "evaluation").unwrap();
let bar_ref = Aim::add("bar", "inference").unwrap();

// Acquire contexts for nested workflows
let foo_instance = Aim::acquire(foo_ref.clone()).unwrap();
let baz_ref = Aim::add_node(foo_ref.clone(), Arc::from("baz"), "search").unwrap();

// Make changes to nested workflows
let cell = Cell::new("result", "Number", "42", "");
Aim::append_or_update_cell(&foo_instance, cell).unwrap();

// Snapshot individual workflow changes
Aim::snapshot(&foo_instance).unwrap();
Aim::release(&foo_instance).unwrap();

// Save all workflows in the workspace hierarchy
Aim::save_all().unwrap();

// All changes are now persistent and visible to other processes
§Implementation Details

Internally, save_all() performs the following operations:

  1. Acquires a read lock on the global workspace singleton
  2. Retrieves the workspace workflow and saves it using the standard save process
  3. Traverses all child nodes in the workspace workflow
  4. For each child node that represents a workflow:
    • Loads the workflow if not already in memory
    • Checks if the workflow has pending changes (is_touched())
    • If changes exist, saves the workflow:
      • Acquires exclusive write lock for the workflow
      • Calls the workflow’s save() method to persist changes
      • Updates the workflow’s version tracking and journal
      • Releases the write lock
  5. Recursively processes nested workflows in subdirectories
  6. Returns success only after all workflows have been successfully saved
§Important Notes
  • Scope: This function saves ALL workflows in the workspace tree, not just the root workspace
  • Performance: This operation can be expensive for large workspace hierarchies as it may need to save many workflows
  • Atomicity: While each individual workflow save is atomic, the overall operation saves workflows incrementally. If interrupted, some workflows may be saved while others are not
  • Concurrency: The function is thread-safe and uses internal locking, but concurrent modifications during the save process may cause some workflows to be saved with stale data
  • Instance Requirements: All workflow instances with pending changes must be snapshotted before calling save_all() to ensure their changes are included
  • Error Handling: If any workflow fails to save, the operation stops and returns an error. Some workflows may have been saved before the failure occurred
§Comparison with save()
  • Aim::save(): Saves only the root workspace workflow. Faster, but doesn’t save nested workflows
  • Aim::save_all(): Saves the root workspace workflow AND all nested workflows. Comprehensive but potentially slower
§See Also
Source

pub fn compact() -> Result<()>

§Prunes open read-only nodes from memory to free resources and optimize memory usage.
§title: Compact

This function prunes open read-only nodes from memory to free resources and optimize memory usage.

The compact operation traverses all loaded workflow nodes and instances in the workspace, identifying those that have not been modified since they were loaded. These unmodified workflows are converted from their loaded state back to an unloaded state, releasing the memory used to hold their content while preserving the ability to reload them on demand.

§Returns

Returns a Result<()> containing:

  • Ok(()) if compaction completed successfully
  • Err(anyhow::Error) if an error occurred during the compaction process
§Errors

Returns an error if:

  • A poisoned lock is encountered during traversal
  • An unexpected internal state is found during compaction
§Behavior

Internally, compact() performs the following operations:

  1. Acquires a read lock on the global workspace
  2. Traverses all loaded nodes and instances in the workspace workflow
  3. For each loaded workflow, checks if it has been modified using is_touched()
  4. If a workflow hasn’t been touched, converts it from Loaded state back to Unloaded state
  5. Releases memory associated with the workflow content while preserving the reference
§Side Effects
  • Reduces memory usage by unloading read-only workflows that haven’t been modified
  • Converts NodeState::Loaded to NodeState::Unloaded for untouched workflows
  • No persistent changes to disk - workflows can be reloaded on next access
§Usage Pattern

The compact function is typically called periodically to optimize memory usage, especially after batch operations that may have loaded many workflows:

use aimx::Aim;

// Perform batch operations that load many workflows
// ... (various API operations that access workflows)

// Compact memory usage
match Aim::compact() {
    Ok(()) => println!("Memory compaction completed successfully"),
    Err(e) => println!("Memory compaction failed: {}", e),
}
§See Also
Source

pub fn root() -> Arc<Reference>

§Returns the global singleton reference to the workspace root.
§title: Root

Returns the global singleton reference to the workspace root identifier (_).

This function provides access to the shared workspace reference (_), which serves as the foundation for navigating the entire AIMX workspace hierarchy. The root reference acts as the entry point for tree traversal and workflow discovery operations, and is used internally by several API functions for workspace-level operations.

§Returns

Returns an Arc<Reference> pointing to the workspace root identifier (_). This reference is shared across all API instances and maintains thread-safe access to the global workspace context using OnceCell for lazy initialization.

§Behavior

Internally, root() delegates to Reference::workspace(), which performs the following operations:

  1. Uses a static OnceCell<Arc<Reference>> to ensure the reference is created only once
  2. Creates a new single-part reference with the identifier "_"
  3. Returns a clone of the cached reference for thread-safe sharing

This implementation ensures that:

  • The workspace root reference is consistent across the entire application
  • Multiple calls to root() return equivalent references
  • Thread-safe access is maintained through Arc and OnceCell
§MVCC Considerations

The root reference operates within the Multi-Version Concurrency Control (MVCC) context for the workspace. Initially this will be the version that opened via Aim::open. Concurrent changes being made to this workflow by other processes will not be visible until either Aim::snapshot or Aim::release are called.

§Usage Pattern

The root reference is typically used as the starting point for workspace operations:

use aimx::{Aim, Reference};
use aimx::expressions::ExpressionLike;

// Get the workspace root reference
let root_reference = Aim::root();

// Use it with API functions for workspace operations
let catalog = Aim::catalog(root_reference.clone()).unwrap();
for node in catalog {
    println!("Node: {}", node.to_formula());
}

// Get workspace metadata
let sheet = Aim::sheet(root_reference.clone()).unwrap();
println!("Workspace has {} rules", sheet.length);

// List all rules at the workspace level
let rules = Aim::list(root_reference.clone()).unwrap();
for cell in rules {
    if cell.is_node() {
        if let Some(identifier) = cell.identifier() {
            println!("Node: {}", identifier);
        }
    }
}
§Integration with API

The root reference is used internally by several API functions for workspace-level operations:

  • Aim::catalog - Lists all nodes in the workspace when passed the root reference
  • Aim::sheet - Gets workspace-level metadata when passed the root reference
  • Aim::list - Enumerates rules at the workspace level when passed the root reference
  • Aim::contains - Checks for the existence of nodes at the workspace level
  • Aim::cell - Retrieves specific cells from the workspace workflow
§See Also
  • Aim::catalog - Browse workspace hierarchy using the root reference
  • Aim::sheet - Get workspace metadata using the root reference
  • Aim::list - List rules at root level using the root reference
  • [Reference::child] - Create child references for navigation from the root
  • Reference::workspace - The underlying function that creates the root reference
  • Aim::open - Establish MVCC workspace context that the root reference operates within
Source

pub fn catalog(locator: Arc<Reference>) -> Result<Vec<Arc<Sheet>>>

§Retrieves a catalog of child node references for the specified workflow locator.
§title: Catalog

This function provides hierarchical navigation through the AIMX workspace by listing all direct child nodes contained within a given workflow. It supports both workspace root (_) and nested workflow contexts.

§Arguments
  • locator - An Arc<Reference> pointing to the workflow whose children should be listed. Use Aim::root() for workspace-level cataloging, or any valid workflow reference.
§Returns

Returns a Result<Vec<Arc<Sheet>>> containing sheet metadata for all direct child nodes. Each sheet represents a navigable child workflow with its metadata. If the locator points to the workspace root (_), returns all top-level nodes in the workspace. If the locator points to a specific workflow, returns all nodes defined within that workflow.

§Errors

Returns an error if:

  • The locator references a non-existent workflow
  • The workflow file cannot be read or is corrupted
  • The node structure is incompatible with current API version
§Behavior

Internally, catalog() performs the following operations:

  1. Special Case Handling: If the locator is "_" (workspace root), calls [Workspace::list()] to enumerate all top-level nodes in the workspace workflow.

  2. Node Resolution: For non-root locators, resolves the target node using Workspace::locate_node().

  3. Workflow Access: Retrieves the workflow from the located node using Node::get_workflow().

  4. Rule Iteration: Iterates through all rules in the workflow using WorkflowLike::iter_rules().

  5. Node Filtering: For each rule, checks if it represents a node using Rule::is_node().

  6. Reference Construction: For each node rule found, constructs a child reference using [Reference::child()] and the rule’s identifier.

  7. Result Compilation: Collects all child references into a vector and returns it.

§Side Effects
  • Reads workflow data from disk if not already cached in memory
  • No modifications are made to the workspace or workflow files
  • May trigger lazy loading of workflow content into memory
§Usage Pattern
use aimx::{Aim, Reference, expressions::ExpressionLike};

// Catalog workspace root
let root_reference = Aim::root();
let workspace_nodes = Aim::catalog(root_reference).unwrap();
for node_ref in workspace_nodes {
    println!("Found node: {}", node_ref.to_formula());
}

// Catalog a specific workflow
let workflow_reference = Reference::parse("parent").unwrap();
let child_nodes = Aim::catalog(workflow_reference).unwrap();
for child_ref in child_nodes {
    println!("Found child: {}", child_ref.to_formula());
}
§See Also
  • Aim::root() - Get workspace root reference for cataloging
  • Aim::sheet() - Get workflow metadata for discovered nodes
  • Aim::list() - List rules within a workflow (different from cataloging nodes)
  • Aim::contains() - Check if specific node exists
  • [Reference::child()] - Construct child references for navigation
§File Operations

The function performs read-only access to workflow files. When cataloging a workflow that is not currently loaded in memory, the system will read the .aim file from disk and parse its contents. Subsequent catalog operations on the same workflow will use the cached in-memory representation.

§MVCC Considerations

The catalog reflects the current version of the workflow state in the workspace. Initially this will be the version that opened via Aim::open. Concurrent changes being made to this workflow by other processes will not be visible until either Aim::snapshot or Aim::release are called.

§Performance Considerations
  • Workspace root cataloging is typically fast as it only reads the main workspace workflow
  • Deeply nested workflow cataloging may require loading multiple workflow files
  • Results are not cached between calls, so frequent cataloging of the same workflow should be done judiciously
  • The function scales linearly with the number of rules in the target workflow
Source

pub fn add(identifier: &str, parameters: &str) -> Result<Arc<Reference>>

§Adds a new workflow node to the workspace root with the specified inference configuration.
§title: Add

This function creates a new top-level workflow node in the workspace with the specified inference configuration. The node becomes immediately available for navigation and subsequent operations within the workspace hierarchy.

§Arguments
  • identifier - A unique identifier for the new workflow node. Must be a valid AIMX identifier (alphanumeric characters and underscores, starting with a letter). Cannot be empty or “_” (reserved for workspace root).

  • parameters - A string specifying the inference configuration for the workflow. Uses AIMX inference syntax to define the orchestration pattern and optional model.

§Returns

Returns an Arc<Reference> pointing to the newly created workflow node. This reference can be used for subsequent operations on the workflow.

§Errors

Returns an error if:

  • The identifier is empty or invalid
  • The identifier “_” is used (reserved for workspace root)
  • A node with the same identifier already exists
  • The workspace has not been initialized (no call to Aim::create() or Aim::open())
§Side Effects
  • Creates a new workflow file ({identifier}.aim) and corresponding journal file ({identifier}.jnl) in the workspace directory
  • Updates the workspace workflow with the new node reference
  • Creates corresponding journal entries for MVCC tracking
  • The new workflow node becomes immediately visible to concurrent readers
§Behavior

Internally, add() performs the following operations:

  1. Validates the identifier using parse_identifier() to ensure it follows AIMX naming conventions
  2. Parses the parameters string using Node::parse() to determine the inference configuration
  3. Checks if a node with the same identifier already exists in the workspace
  4. Creates a new Node with the specified inference characteristics
  5. Adds the node to the workspace workflow using workspace.add_node()
  6. Saves the workspace changes to disk
§MVCC Considerations

The new node becomes visible to concurrent readers immediately after this function successfully returns. The operation is atomic - either the node is fully created or no changes are made to the workspace.

§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Create or open a workspace first
let path = Arc::new(std::env::current_dir().unwrap().join("workspace.aim"));
let _sheet = Aim::create(path).unwrap();

// Add a new workflow node with evaluation pattern (default)
let foo_reference = Aim::add("foo", "evaluation").unwrap();
println!("Created node: {}", foo_reference);

// Add another node with inference pattern and thinking model
let bar_reference = Aim::add("bar", "inference thinking").unwrap();
println!("Created node: {}", bar_reference);

// Verify the nodes exist
assert!(Aim::contains(Aim::root(), "foo").unwrap());
assert!(Aim::contains(Aim::root(), "bar").unwrap());

// Add a node with search pattern and extraction model
let search_reference = Aim::add("searcher", "search extract").unwrap();
println!("Created search node: {}", search_reference);
§See Also
Source

pub fn copy(from: &str, to: &str) -> Result<()>

§Copies an existing workflow node to create a new node with a different identifier.
§title: Copy

This function creates a deep copy of an existing workflow node, including all its associated files, directory structure, and child nodes. The copy operation preserves the original node’s inference configuration, rules, and internal structure while assigning it a new identifier in the workspace hierarchy.

§Arguments
  • from - The identifier of the source workflow node to copy. Must be a valid AIMX identifier that exists in the workspace.

  • to - The identifier for the new workflow node. Must be a valid AIMX identifier that does not already exist in the workspace.

§Returns

Returns Ok(()) if the copy operation completes successfully.

§Errors

Returns an error if:

  • The source node (from) does not exist
  • The target identifier (to) already exists
  • Either identifier is invalid or empty
  • File system operations fail during the copy process
  • The workspace cannot be written to
§Side Effects

Creates a complete copy of the source node including:

  • Main workflow file ({to}.aim)
  • Journal file ({to}.jnl) if it exists
  • Directory structure for child nodes
  • All child workflow files recursively
  • Updates the workspace workflow with the new node reference
§MVCC Considerations

The new top level node becomes visible to concurrent readers immediately after this function successfully returns.

§File Operations

The copy operation performs the following file system operations:

workspace/
  ├── {from}.aim      → workspace/{to}.aim      (copied)
  ├── {from}.jnl       → workspace/{to}.jnl       (copied if exists)
  └── {from}/          → workspace/{to}/          (recursively copied)
      ├── child1.aim → workspace/{to}/child1.aim
      └── child2.aim → workspace/{to}/child2.aim
§Usage Pattern
use aimx::Aim;
use std::sync::Arc;

// Copy an existing workflow node
let result = Aim::copy("existing_node", "new_node_copy");

match result {
    Ok(()) => println!("Successfully copied existing_node to new_node_copy"),
    Err(e) => println!("Failed to copy node: {}", e),
}
§Example
use aimx::{Aim, expressions::ExpressionLike};

// Copy an existing workflow node to a new identifier
Aim::copy("existing_workflow", "copied_workflow").unwrap();

// Verify the copy was created
let catalog = Aim::catalog(Aim::root()).unwrap();
let node_names: Vec<String> = catalog
    .iter()
    .map(|reference| reference.to_formula())
    .collect();
    
assert!(node_names.contains(&"existing_workflow".to_string()));
assert!(node_names.contains(&"copied_workflow".to_string()));
§Implementation Details

Internally, copy() performs the following operations:

  1. Validates both source and target identifiers
  2. Checks that the source node exists and target node doesn’t exist
  3. Creates a new Node with the same inference configuration as the source
  4. Copies all associated files (.aim, .jnl) using file system operations
  5. Recursively copies child node directories if they exist
  6. Adds the new node reference to the workspace workflow
  7. Updates the workspace structure
§See Also
Source

pub fn rename(from: &str, to: &str) -> Result<()>

§Renames an existing workflow node in the workspace.
§title: Rename

This function changes the identifier of an existing workflow node, updating all associated files and references while preserving the node’s content, structure, and inference configuration. The rename operation is atomic and maintains the integrity of the workspace hierarchy.

§Arguments
  • from - The current identifier of the workflow node to rename. Must be a valid AIMX identifier that exists in the workspace.

  • to - The new identifier for the workflow node. Must be a valid AIMX identifier that does not already exist in the workspace.

§Returns

Returns Ok(()) if the rename operation completes successfully.

§Errors

Returns an error if:

  • The source node (from) does not exist
  • The target identifier (to) already exists
  • Either identifier is invalid or empty
  • The identifier “_” is used (reserved for workspace root)
  • File system operations fail during the rename process
  • The workspace cannot be written to
§Side Effects

Performs comprehensive file system operations to rename all associated files:

  • Renames the main workflow file ({from}.aim{to}.aim)
  • Renames the journal file ({from}.jnl{to}.jnl) if it exists
  • Renames the directory ({from}/{to}/) if it exists (for child nodes)
  • Updates the workspace workflow with the new node reference
  • Creates corresponding journal entries for MVCC tracking
§MVCC Considerations

The new top level node becomes visible to concurrent readers immediately after this function successfully returns.

§File Operations

The rename operation performs the following file system operations:

workspace/
  ├── {from}.aim       → workspace/{to}.aim  (renamed)
  ├── {from}.jnl       → workspace/{to}.jnl  (renamed if exists)
  └── {from}/          → workspace/{to}/     (renamed if exists)
        ├── child1.aim → workspace/{to}/child1.aim
        └── child2.aim → workspace/{to}/child2.aim
§Behavior

Internally, rename() performs the following operations:

  1. Validates both source and target identifiers using parse_identifier()
  2. Checks that the source node exists in the workspace workflow
  3. Verifies that the target identifier doesn’t already exist
  4. Acquires a write lock on the global workspace singleton
  5. Updates the node reference in the workspace workflow by calling rename_node() on the rule
  6. Renames all associated files (.aim, .jnl) using file system operations
  7. Recursively renames child node directories if they exist
  8. Saves the updated workspace workflow and updates the workspace structure

The operation preserves all content and structure:

  • All rules and their values remain unchanged
  • Inference configuration is preserved
  • Child nodes become accessible via the new reference path
  • Existing references within the workspace are automatically updated
§Usage Pattern
use aimx::{Aim, Reference};
use aimx::expressions::ExpressionLike;
use std::sync::Arc;

// Ensure the workspace exists and contains the node to rename
let root_reference = Aim::root();
let catalog = Aim::catalog(root_reference.clone()).unwrap();
let nodes: Vec<String> = catalog
    .iter()
    .filter_map(|reference| Some(reference.to_formula()))
    .collect();

// Verify the source node exists before renaming
assert!(nodes.contains(&"old_name".to_string()));

// Rename the workflow node
match Aim::rename("old_name", "new_name") {
    Ok(()) => {
        println!("Successfully renamed 'old_name' to 'new_name'");
        
        // Verify the rename was successful
        let updated_catalog = Aim::catalog(root_reference).unwrap();
        let updated_nodes: Vec<String> = updated_catalog
            .iter()
            .filter_map(|reference| Some(reference.to_formula()))
            .collect();
        
        assert!(updated_nodes.contains(&"new_name".to_string()));
        assert!(!updated_nodes.contains(&"old_name".to_string()));
    }
    Err(e) => {
        eprintln!("Failed to rename node: {}", e);
    }
}

// The renamed node is immediately available for use
let new_reference = Reference::parse("new_name").unwrap();
§Integration with Workflow Operations

After renaming, the node remains fully functional with:

  • All rules and content preserved
  • Inference configuration unchanged
  • Child nodes accessible via the new reference path
  • Existing references automatically updated within the workspace
§See Also
Source

pub fn remove(identifier: &str) -> Result<()>

Removes a workflow node from the workspace along with all associated files.

§This function permanently deletes a workflow node and all its associated resources, including the workflow file, journal file, and any child directories or files. The removal operation is irreversible and comprehensive.
§title: Remove

This function permanently deletes a workflow node and all its associated resources, including the workflow file, journal file, and any child directories or files. The removal operation is irreversible and comprehensive, ensuring no orphaned files remain in the workspace.

§Arguments
  • identifier - The identifier of the workflow node to remove. Must be a valid AIMX identifier that exists in the workspace. Cannot be “_” (reserved for workspace root) or “workflow” (reserved for workspace itself).
§Returns

Returns Ok(()) if the removal operation completes successfully.

§Errors

Returns an error if:

  • The specified node does not exist
  • The identifier is “_” or “workflow” (reserved identifiers)
  • The workspace cannot be modified (e.g., read-only permissions)
  • File system operations fail during the removal process
  • The workspace is in an invalid state
§Side Effects

Performs comprehensive file system operations to remove all associated files:

  • Deletes the main workflow file ({identifier}.aim)
  • Deletes the journal file ({identifier}.jnl) if it exists
  • Deletes the directory ({identifier}/) if it exists, including all child workflows recursively
  • Removes the node reference from the workspace workflow
  • Creates corresponding journal entries for MVCC tracking
§Safety Considerations

This operation is irreversible. Once a node is removed, all its data, rules, child workflows, and inference history are permanently deleted. Applications should implement confirmation dialogs or undo mechanisms when calling this function interactively.

§MVCC Considerations

The removed node becomes invisible to concurrent readers immediately after this function successfully returns.

§File Operations

The removal operation performs the following file system operations:

workspace/
  ├── {identifier}.aim (deleted)
  ├── {identifier}.jnl (deleted if exists)
  └── {identifier}/    (recursively deleted if exists)
      ├── child1.aim → (deleted)
      └── child2.aim → (deleted)
§Behavior

Internally, remove() performs the following operations:

  1. Validates the identifier is not reserved (“_” or “workflow”)
  2. Checks that the node exists in the workspace
  3. Acquires a write lock on the global workspace singleton
  4. Removes the node reference from the workspace workflow
  5. Deletes all associated files (.aim, .jnl) using file system operations
  6. Recursively deletes child node directories if they exist
  7. Updates the workspace structure
§Integration with Context Operations

If the workflow being removed has an active context instance (via Aim::acquire), the removal operation will still proceed but may leave orphaned context entries. Consider calling Aim::release on any active handle before removal.

§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Create or open a workspace first
let path = Arc::new(std::env::current_dir().unwrap().join("workspace.aim"));
let _sheet = Aim::create(path).unwrap();

// Add a workflow node to remove
let test_reference = Aim::add("test_node", "evaluation").unwrap();
assert!(Aim::contains(Aim::root(), "test_node").unwrap());

// Remove the workflow node
Aim::remove("test_node").unwrap();

// Verify the node is gone
assert!(!Aim::contains(Aim::root(), "test_node").unwrap());

// Try to remove a non-existent node (will return error)
let result = Aim::remove("nonexistent");
assert!(result.is_err());
§See Also
Source

pub fn sheet(locator: Arc<Reference>) -> Result<Sheet>

§Retrieves metadata and structural information about a workflow as a Sheet.
§title: Sheet

Retrieves comprehensive metadata about a workflow, providing structural information, versioning details, inference configuration, and file system characteristics. This function serves as the primary mechanism for inspecting workflow properties without accessing individual rules or cells.

§Arguments
  • locator - An Arc<Reference> pointing to the workflow to inspect. Use Aim::root() for workspace-level metadata, or any valid workflow reference such as "foo", "foo.bar", or "foo.bar.baz".
§Returns

Returns a Sheet containing comprehensive metadata about the specified workflow. The Sheet structure includes:

  • locator: The workflow’s unique reference path within the workspace
  • path: Absolute file system path to the workflow .aim file
  • date: Creation/modification timestamp (DateTime)
  • version: Current major version (epoch) number
  • minor_version: Current minor version (partial) number
  • first_version: Initial version when workflow was created
  • latest_version: Most recent version available in the journal
  • model: Inference model configuration (e.g., “thinking”, “standard”, “fast”)
  • pattern: Inference pattern (e.g., “evaluation”, “inference”, “search”)
  • length: Number of rules/cells currently in the workflow
§Errors

Returns an error if:

  • The locator references a non-existent workflow
  • The workflow file cannot be read or is corrupted
  • The node structure is incompatible with current API version
§Behavior

Internally, sheet() performs the following operations:

  1. Checks if the locator is the workspace root (_)
  2. For workspace root: Calls Workspace::sheet() to get workspace-level metadata
  3. For specific workflows: Locates the node using Workspace::locate_node()
  4. Converts the node to a Sheet using Sheet::convert()
  5. Returns the populated Sheet structure
§MVCC Considerations

The sheet reflects the current version of the workflow state in the workspace:

  • Initially shows the version that opened via Aim::open or Aim::create
  • Concurrent changes being made by other processes will not be visible until Aim::snapshot or Aim::release are called
  • Does not require write locks (read-only operation)
  • Safe for concurrent access with other readers
§Usage Examples
§Basic Usage
use aimx::{Aim, Reference};
use std::sync::Arc;

// Get workspace metadata
let root_reference = Aim::root();
let workspace_sheet = Aim::sheet(root_reference).unwrap();
println!("Workspace path: {}", workspace_sheet.path);
println!("Version: {}.{}", workspace_sheet.version, workspace_sheet.minor_version);
§Inspect Specific Workflow
use aimx::{Aim, Reference};
use std::sync::Arc;

// Parse a workflow reference
let reference = Reference::parse("foo.bar").unwrap();

// Get sheet information
let sheet = Aim::sheet(reference).unwrap();
println!("Workflow: {}", sheet.locator);
println!("Rules count: {}", sheet.length);
println!("Model: {}", sheet.model);
println!("Pattern: {}", sheet.pattern);
§Check Version Information
use aimx::{Aim, Reference};
use std::sync::Arc;

let reference = Reference::parse("project").unwrap();
let sheet = Aim::sheet(reference).unwrap();

println!("Current version: {}.{}", sheet.version, sheet.minor_version);
println!("First version: {}", sheet.first_version);
println!("Latest version: {}", sheet.latest_version);
println!("Last modified: {}", sheet.date);
§Integration with Workflow Operations

The returned Sheet is particularly useful for:

  • User Interfaces: Displaying workflow properties and metadata
  • Debugging: Understanding workflow structure and configuration
  • Monitoring: Tracking workflow health, version history, and size
  • Management Tools: Integration with workflow orchestration systems
  • Audit Trail: Understanding when workflows were created/modified
  • Version Control: Tracking major/minor version changes over time
§Performance Considerations
  • Fast Operation: Sheet retrieval is read-only and does not load workflow rules
  • Lazy Loading: Node metadata is loaded on-demand
  • Caching: Workspace nodes maintain cached metadata for efficiency
  • No File I/O: Only reads metadata, not full workflow content
§See Also
  • Aim::root() - Get workspace root reference for sheet operations
  • Aim::catalog() - Browse workflow hierarchy before inspection
  • Aim::list() - List rules within a workflow (more detailed than sheet)
  • Aim::cell() - Access individual rules within a workflow
  • Aim::contains() - Check if a workflow contains a specific rule
  • Sheet - Structure containing workflow metadata
  • Reference - Workflow locator and reference system
Source

pub fn list(locator: Arc<Reference>) -> Result<Vec<Cell>>

§Lists all rules within a workflow as Cell objects.
§title: List

Lists all rules within a workflow as Cell objects, providing a complete view of the workflow’s structure and content. This function converts internal rule representations to user-facing Cell objects that can be inspected, modified, or used for analysis.

§Arguments
  • locator - An Arc<Reference> pointing to the workflow whose rules should be listed. Use Aim::root() for workspace-level rules, or any valid workflow reference such as "foo", "foo.bar", or "foo.bar.baz".
§Returns

Returns a Result<Vec<Cell>> containing all rules within the specified workflow in their original order. Each Cell represents a different type of workflow element:

  • Formula Cells: Standard rules with type definitions, formulas, and values
  • Node Cells: References to nested workflow nodes
  • Format Cells: Template and formatting instructions
  • Branch Cells: Conditional workflow branching logic
  • Retry Cells: Retry logic with conditions and limits
  • Comment Cells: Documentation and explanatory text
  • Error Cells: Rules that failed to parse or evaluate
  • Empty Cells: Placeholder or deleted rule positions
§Errors

Returns an error if:

  • The locator references a non-existent workflow
  • The workflow file cannot be read or is corrupted
  • The node structure is incompatible with current API version
§Behavior

Internally, list() performs the following operations:

  1. Checks if the locator is the workspace root (_)
  2. For workspace root: Accesses the workspace workflow via Workspace::get_node("workflow")
  3. For specific workflows: Locates the node using Workspace::locate_node()
  4. Iterates through all rows using the workflow’s iter_rows() method
  5. Converts each row to a Cell using Cell::convert_row()
  6. Returns the vector of Cell objects in their original order
§MVCC Considerations

The list reflects the current committed version of the workflow state:

  • Shows the version that was opened via Aim::open or Aim::create
  • Changes made in other processes are not visible until they are committed via Aim::snapshot or Aim::release
  • Safe for concurrent read access with other processes
  • Does not require write locks (read-only operation)
§Usage Examples
§Basic Usage
use aimx::{Aim, Reference};
use std::sync::Arc;

// List rules in a specific workflow
let reference = Reference::parse("project.tasks").unwrap();
let cells = Aim::list(reference).unwrap();

for cell in cells {
    if let Some(identifier) = cell.identifier() {
        println!("Rule: {}", identifier);
    }
    if cell.is_formula() {
        if let Some(formula) = cell.formula() {
            println!("  Formula: {}", formula);
        }
        if let Some(value) = cell.value() {
            println!("  Value: {}", value);
        }
    }
}
§Inspect Workspace Structure
use aimx::{Aim, Cell};
use std::sync::Arc;

// List all workspace-level rules
let root_reference = Aim::root();
let cells = Aim::list(root_reference).unwrap();

println!("Workspace contains {} rules:", cells.len());
for cell in cells {
    match cell {
        Cell::Node { identifier, value } => {
            println!("  Node: {} -> {}", identifier, value);
        }
        Cell::Comment { comment } => {
            println!("  Comment: {}", comment);
        }
        _ => {
            if let Some(identifier) = cell.identifier() {
                println!("  Rule: {}", identifier);
            }
        }
    }
}
§Filter and Analyze Rules
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

let reference = Reference::parse("analysis").unwrap();
let cells = Aim::list(reference).unwrap();

// Count different types of rules
let mut formula_count = 0;
let mut node_count = 0;
let mut error_count = 0;

for cell in &cells {
    match cell {
        Cell::Formula { .. } => formula_count += 1,
        Cell::Node { .. } => node_count += 1,
        Cell::Errata { .. } => error_count += 1,
        _ => {}
    }
}

println!("Analysis workflow contains:");
println!("  {} formula rules", formula_count);
println!("  {} node references", node_count);
println!("  {} error rules", error_count);

// Find all error details
let errors: Vec<_> = cells.iter()
    .filter_map(|cell| match cell {
        Cell::Errata { identifier, reason, .. } => Some((identifier, reason)),
        _ => None,
    })
    .collect();

for (id, reason) in errors {
    println!("Error in {}: {}", id, reason);
}
§Integration with Context Operations
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

let workflow_ref = Reference::parse("process").unwrap();

// First, examine the current state
let current_cells = Aim::list(workflow_ref.clone()).unwrap();
println!("Current rules: {}", current_cells.len());

// Acquire write context for modifications
let handle = Aim::acquire(workflow_ref.clone()).unwrap();

// Add a new rule
let new_cell = Cell::new("result", "Number", "input * 2", "");
Aim::append_or_update_cell(&handle, new_cell).unwrap();

// The list function will still show the old state
let still_old = Aim::list(workflow_ref.clone()).unwrap();
assert_eq!(still_old.len(), current_cells.len());

// Commit changes to make them visible
Aim::snapshot(&handle).unwrap();

// Now list shows the updated state
let updated_cells = Aim::list(workflow_ref).unwrap();
assert_eq!(updated_cells.len(), current_cells.len() + 1);

Aim::release(&handle).unwrap();
§Cell Type Details

Each Cell type provides different information:

  • Formula: identifier, typedef, formula, value
  • Node: identifier, value (workflow reference)
  • Format: identifier, instruction, template, examples
  • Branch: identifier, condition, target
  • Retry: identifier, count, condition, target
  • Comment: comment
  • Errata: identifier, typedef, reason, formula, location
  • Empty: No content (placeholder)
§Performance Considerations
  • Memory Usage: Loads all rules into memory at once
  • File I/O: Reads the complete workflow file
  • Conversion Overhead: Converts all internal representations to Cell objects
  • For Large Workflows: Consider using Aim::cell() for individual rule access
  • Caching: Results are not cached; each call reads from disk
§Integration with Other Functions
  • Preceding Operations: Use Aim::sheet() to get workflow metadata before listing
  • Navigation: Use Aim::catalog() to find child workflows to list
  • Individual Access: Use Aim::cell() to access specific rules by identifier
  • Existence Check: Use Aim::contains() to verify rule existence
  • Modification: Use context operations (Aim::acquire(), etc.) to modify rules
§See Also
  • Aim::sheet() - Get workflow metadata without loading all rules
  • Aim::catalog() - List child workflow nodes (different from rule listing)
  • Aim::cell() - Access individual rules by identifier
  • Aim::contains() - Check if a workflow contains a specific rule
  • Aim::acquire() - Acquire write context for rule modifications
  • Cell - Structure containing rule metadata and content
  • Reference - Workflow locator and reference system
Source

pub fn exists(locator: Arc<Reference>) -> Result<bool>

Source

pub fn contains(locator: Arc<Reference>, identifier: &str) -> Result<bool>

§Checks if a workflow contains a rule with the specified identifier.
§title: Contains

This function performs a fast existence check for rules within a workflow or nodes within the workspace. It’s optimized for quick lookups and is particularly useful for validation, duplicate checking, and conditional workflow operations.

§Arguments
  • locator - An Arc<Reference> pointing to the workflow to search. Use Aim::root() to check for node existence in the workspace.

  • identifier - The identifier to search for within the workflow. Must be a valid AIMX identifier (alphanumeric, starting with letter).

§Returns

Returns Ok(true) if the identifier exists in the specified workflow, Ok(false) if it does not exist, or an error if the workflow cannot be accessed.

§Errors

Returns an error if:

  • The locator references a non-existent workflow
  • The workflow file cannot be read or is corrupted
  • The workspace is not properly initialized
§MVCC Considerations

The lookup reflects the current version of the workflow state in the workspace. Initially this will be the version that opened via Aim::open. Concurrent changes being made to this workflow by other processes will not be visible until either Aim::snapshot or Aim::release are called.

§Behavior by Locator Type

When locator is the workspace root (_):

  • Checks if a node with the identifier exists in the workspace hierarchy
  • Uses Workspace::contains_node() for workspace-level node lookup
  • Returns true for top-level workflow nodes like “foo”, “bar”, etc.

When locator is a specific workflow reference:

  • Checks if a rule with the identifier exists within that workflow
  • Uses the workflow’s contains() method for rule lookup
  • Returns true for rules like “baz”, “index”, “identifier” within the workflow
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Check if rule exists before adding
if !Aim::contains(reference.clone(), "new_rule").unwrap() {
    // Rule doesn't exist, safe to add
    let cell = aimx::Cell::new("new_rule", "Number", "42", "");
    Aim::append_or_update_cell(&handle, cell).unwrap();
}

// Make changes visible
Aim::release(&handle).unwrap();
§Performance Considerations
  • Optimized: Uses efficient lookup mechanisms without loading unnecessary data
  • Cached: Leverages workspace caching for repeated lookups
  • Lightweight: Minimal overhead compared to full rule loading with Aim::list
§See Also
Source

pub fn import(_locator: Arc<Reference>, _target_path: &Path) -> Result<()>

§Imports workflow data from a CSV file into an existing workflow.
§title: Import

This function imports workflow data from a CSV file into an existing workflow. The import process reads the CSV file and creates or updates cells (rules) in the workflow based on the imported data. This is useful for bulk data entry, migration from spreadsheets, or initializing workflows with existing datasets.

§Arguments
  • locator - An Arc<Reference> pointing to the target workflow where data will be imported. The reference must point to an existing workflow in the workspace.
  • target_path - A Path specifying the file system path to the CSV file to import. The file must exist and be readable.
§Returns

Returns a Result<()> indicating success or failure of the import operation. On success, the workflow will contain the imported data. On failure, the workflow remains unchanged.

§Errors

Returns an error if:

  • The workflow locator references a non-existent workflow
  • The CSV file does not exist or cannot be read
  • The CSV file has invalid format or encoding
  • The CSV data contains invalid cell identifiers or formulas
  • The workspace is not properly initialized
  • Insufficient permissions to read the CSV file
§Behavior

Internally, import() performs the following operations:

  1. Validation: Verifies the workflow locator points to an existing workflow
  2. File Access: Opens and validates the CSV file format
  3. Data Parsing: Parses CSV rows into cell data structures
  4. Validation: Validates cell identifiers, types, and formulas
  5. Import: Creates or updates cells in the target workflow
  6. Commit: Saves changes to make them permanent
§Usage Pattern
use aimx::{Aim, Reference};
use std::{sync::Arc, path::Path};

// Acquire workflow context
let reference = Reference::parse("data.import_target").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Import CSV data
let csv_path = Path::new("/path/to/data.csv");
match Aim::import(reference.clone(), csv_path) {
    Ok(()) => println!("Data imported successfully"),
    Err(e) => println!("Import failed: {}", e),
}

// Make changes visible
Aim::release(&handle).unwrap();
§CSV Format

The CSV file should follow this format:

identifier,typedef,formula,value
user_count,Number,,1000
user_revenue,Number,"user_count * 50",
growth_rate,Number,"(current_revenue / previous_revenue) - 1",0.15

Column Requirements:

  • identifier: Unique cell identifier (required)
  • typedef: Type definition (Number, Text, Bool, etc.) (required)
  • formula: AIMX expression formula (optional)
  • value: Static value (optional)
§Side Effects
  • Creates new cells in the target workflow
  • Updates existing cells if identifiers match
  • Modifies workflow structure permanently
  • Generates new version in the workflow journal
  • Triggers evaluation of affected formulas
§File Operations

The import function performs the following file operations:

  • Reads the CSV file from the specified path
  • Parses CSV content in memory
  • Writes changes to the workflow file
  • Updates the workflow journal with version information
  • No temporary files are created
§MVCC Considerations

The import operation is subject to MVCC (Multi-Version Concurrency Control):

  • Isolation: Import runs within an acquired write context
  • Atomicity: Changes become visible only after successful completion
  • Consistency: Invalid data prevents any changes from being applied
  • Conflict Prevention: Workflow must be acquired before import
  • Rollback: On error, no changes are applied to the workflow
§Performance Considerations
  • Batch Processing: Large CSV files are processed efficiently
  • Memory Usage: CSV data is loaded incrementally to manage memory
  • Disk I/O: Minimizes file operations through batch writes
  • Validation: Comprehensive validation prevents invalid data entry
  • Error Handling: Stops on first validation error to prevent partial imports
§See Also
Source

pub fn export(_locator: Arc<Reference>, _target_path: &Path) -> Result<()>

§Exports workflow data to a CSV file from an existing workflow.
§title: Export

This function exports workflow data to a CSV file from an existing workflow. The export process reads the workflow cells (rules) and writes them to a CSV file in a format that can be imported back into AIMX or used with external spreadsheet applications. This is useful for data backup, migration to spreadsheets, or analysis with external tools.

§Arguments
  • locator - An Arc<Reference> pointing to the source workflow to export. The reference must point to an existing workflow in the workspace.
  • target_path - A Path specifying the file system path where the CSV file will be created. The file will be created or overwritten if it already exists.
§Returns

Returns a Result<()> indicating success or failure of the export operation. On success, a CSV file will be created at the specified path containing the workflow data. On failure, no file is created or modified.

§Errors

Returns an error if:

  • The workflow locator references a non-existent workflow
  • The target path is invalid or cannot be written to
  • The parent directory does not exist and cannot be created
  • Insufficient permissions to create or write the file
  • The workspace is not properly initialized
  • The workflow cannot be read due to concurrent access issues
§Behavior

Internally, export() performs the following operations:

  1. Validation: Verifies the workflow locator points to an existing workflow
  2. Workflow Access: Opens the workflow for reading
  3. Data Collection: Gathers all cells (rules) from the workflow
  4. CSV Generation: Converts cell data to CSV format
  5. File Creation: Creates the target CSV file and writes the data
  6. Completion: Ensures the file is properly written and closed
§Usage Pattern
use aimx::{Aim, Reference};
use std::{sync::Arc, path::Path};

// Acquire workflow context (optional for export)
let reference = Reference::parse("data.export_source").unwrap();

// Export workflow to CSV
let csv_path = Path::new("/path/to/exported_data.csv");
match Aim::export(reference.clone(), csv_path) {
    Ok(()) => println!("Data exported successfully"),
    Err(e) => println!("Export failed: {}", e),
}
§CSV Format

The exported CSV file follows this format:

identifier,typedef,formula,value
user_count,Number,,1000
user_revenue,Number,"user_count * 50",
growth_rate,Number,"(current_revenue / previous_revenue) - 1",0.15
status,Text,,"active"
is_valid,Bool,,true

Column Structure:

  • identifier: Cell identifier (unique within workflow)
  • typedef: Type definition (Number, Text, Bool, Date, etc.)
  • formula: AIMX expression formula (empty if static value)
  • value: Current evaluated value (empty if formula-based)
§Side Effects
  • Creates or overwrites a CSV file at the target path
  • No modifications are made to the source workflow
  • Generates file system I/O operations
  • No changes to workflow versioning or journaling
  • No impact on concurrent readers or writers
§File Operations

The export function performs the following file operations:

  • Creates the target CSV file (overwrites if exists)
  • Writes CSV header row with column names
  • Writes one row per workflow cell
  • Uses comma-separated values with proper escaping
  • Handles text values with quotes when necessary
  • No temporary files are created
§MVCC Considerations

The export operation respects MVCC (Multi-Version Concurrency Control):

  • Read-Only: Export operates on the current committed state of the workflow
  • Consistency: Sees a consistent snapshot of the workflow at export time
  • No Locking: Does not acquire write locks or block other operations
  • Visibility: Exports data that is visible to all concurrent readers
  • Non-Blocking: Does not interfere with ongoing write operations
  • Snapshot Isolation: Exports the latest committed version, not pending changes
§Performance Considerations
  • Memory Usage: Loads workflow data incrementally for large workflows
  • Disk I/O: Single sequential write operation for the CSV file
  • Encoding: Uses UTF-8 encoding for text data
  • Escaping: Properly escapes CSV special characters (commas, quotes, newlines)
  • Batch Processing: Efficiently handles workflows with many cells
  • Minimal Overhead: No additional validation or transformation overhead
§Compatibility

The exported CSV format is compatible with:

  • AIMX import functionality (Aim::import())
  • Microsoft Excel and other spreadsheet applications
  • Database import tools
  • Data analysis software (Python pandas, R, etc.)
  • Custom data processing scripts
§See Also
Source

pub fn print(_locator: Arc<Reference>) -> Result<Arc<str>>

§title: Print

This function generates a markdown string representation of a workflow for display, documentation, or debugging purposes. The print operation reads the workflow structure and content, formatting it as human-readable markdown that can be displayed in applications, included in documentation, or used for debugging workflow structure and content.

§Arguments
  • locator - An Arc<Reference> pointing to the workflow to print. The reference must point to an existing workflow in the workspace.
§Returns

Returns a Result<Arc<str>> containing a markdown string representation of the workflow. On success, the string contains structured markdown with workflow metadata, cell listings, and formatting suitable for display in markdown viewers or documentation systems. On failure, returns an error describing what went wrong.

§Errors

Returns an error if:

  • The workflow locator references a non-existent workflow
  • The workspace is not properly initialized
  • The workflow cannot be read due to concurrent access issues
  • Insufficient permissions to access the workflow
§Behavior

Internally, print() performs the following operations:

  1. Validation: Verifies the workflow locator points to an existing workflow
  2. Workflow Access: Opens the workflow for reading
  3. Metadata Collection: Gathers workflow metadata (sheet information)
  4. Cell Collection: Retrieves all cells (rules) from the workflow
  5. Markdown Generation: Formats the data into structured markdown
  6. String Construction: Creates an efficient string representation
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Get a reference to the workflow to print
let reference = Reference::parse("project.workplan").unwrap();

// Generate markdown representation
match Aim::print(reference.clone()) {
    Ok(markdown) => {
        println!("Workflow documentation:");
        println!("{}", markdown);
        
        // Could also save to file for documentation
        std::fs::write("workplan.md", &*markdown).unwrap();
    },
    Err(e) => println!("Print failed: {}", e),
}
§Markdown Format

The generated markdown follows this structured format:

# Project Workplan

## Workflow Metadata

- **Path**: workspace/project/workplan.aim
- **Model**: evaluation
- **Pattern**: standard
- **Version**: 3 (latest: 3, first: 1)
- **Cells**: 12 total

## Workflow Cells

### Formula Cells

**task_count**: Number = 5
**completed_tasks**: Number = "task_count - pending_tasks" $5
**progress**: Number = "completed_tasks / task_count * 100" $100

### Node Cells

**subproject**: Node = "subproject_details"

### Branch Cells

**decision_point**: Branch = "task_count > 10" -> "complex_workflow"

### Format Cells

**report_template**: Format = "Generate weekly report" <report.md> "weekly", "summary"

### Comment Cells

> This workflow manages project task tracking and reporting

### Error Cells

**invalid_rule**: Error = "division_by_zero" # Cannot divide by zero (at line 12)

Section Structure:

  • Title: Workflow name based on reference
  • Metadata: Sheet information (path, model, version, cell count)
  • Cell Categories: Organized by cell type (Formula, Node, Branch, etc.)
  • Cell Details: Identifier, type, formula, and current value
  • Comments: Workflow documentation and notes
  • Errors: Any evaluation or parsing errors
§Side Effects
  • No modifications are made to the source workflow
  • No file system changes are made
  • Generates minimal memory usage for large workflows
  • No changes to workflow versioning or journaling
  • No impact on concurrent readers or writers
  • Pure read operation with no state changes
§Performance Considerations
  • Memory Usage: Efficiently builds string representation without intermediate copies
  • Lazy Evaluation: Only loads workflow data needed for display
  • String Optimization: Uses Arc<str> for efficient string sharing
  • Incremental Processing: Handles large workflows without excessive memory usage
  • No Caching: Each call reads fresh data from the workflow
  • Minimal Overhead: Direct formatting without intermediate data structures
§Display Integration

The markdown output is designed for integration with various display systems:

  • Documentation Tools: Compatible with markdown processors (GitHub, GitLab, etc.)
  • IDE Integration: Can be displayed in IDE markdown preview panels
  • Web Applications: Suitable for rendering in web-based markdown viewers
  • CLI Tools: Can be printed to terminals with markdown support
  • Documentation Generation: Integrates with static site generators
§Comparison with Other Functions

Compared to related functions:

  • vs export(): print() generates markdown for display, export() creates CSV for data exchange
  • vs list(): print() formats for human consumption, list() returns structured Cell objects
  • vs sheet(): print() includes cell content, sheet() returns only metadata
§See Also
  • Reference - References a workflow location
  • Aim::export() - Export workflow data to CSV
  • Aim::list() - List all cells in a workflow
  • Aim::sheet() - Get workflow metadata and structure
  • Cell - Represents a single cell/rule in a workflow
  • Sheet - Contains workflow metadata and structure information
Source

pub fn cell(locator: Arc<Reference>, identifier: Arc<str>) -> Result<Cell>

§Retrieves a specific cell (rule) from a workflow by its identifier.
§title: Cell

This function retrieves a specific cell (rule) from a workflow by its identifier, providing direct access to the current state of that rule. It supports reading cells from any workflow in the workspace hierarchy and converts internal rule representations into high-level Cell objects that can be easily consumed by applications.

§Arguments
  • locator - An Arc<Reference> pointing to the workflow containing the cell. This can reference any workflow in the workspace hierarchy using dot notation (e.g., "foo", "foo.bar", "foo.bar.baz").
  • identifier - An Arc<str> specifying the unique identifier of the cell to retrieve. Must exactly match the rule’s identifier in the workflow.
§Returns

Returns a Result<Cell> containing:

  • Cell::Empty - If no cell with the specified identifier exists in the workflow
  • Cell::Comment - For comment cells containing documentation text
  • Cell::Errata - For error cells with detailed error information including reason, formula, and location
  • Cell::Node - For workflow node references with their configuration values
  • Cell::Format - For formatting instruction cells with instruction, template, and examples
  • Cell::Branch - For conditional branch cells with condition and target workflow
  • Cell::Retry - For retryable operation cells with count, condition, and target
  • Cell::Formula - For formula-based rule cells with type definition, formula, and current value
  • Cell::Result - For inference result cells (when used with Aim::results)
§Errors

Returns an error if:

  • The locator references a non-existent workflow node
  • The reference path contains invalid syntax
  • File system access fails when reading workflow files
§Behavior

Internally, cell() performs the following operations:

  1. Reference Construction: Creates a child reference by appending the identifier to the locator using locator.child(identifier)
  2. Rule Resolution: Uses Workspace::locate_rule() to find the rule at the specified reference path
  3. Cell Conversion: If a rule is found, converts it to a Cell using Cell::convert_rule() which handles all rule types and error states
  4. Empty Handling: If no rule is found, returns Cell::Empty rather than an error for graceful handling of missing cells
§MVCC Visibility

This function provides read-only access to the current MVCC version of the workflow:

  • Initially reflects the version loaded when the workspace was opened
  • Changes made by other processes become visible after Aim::snapshot or Aim::release are called
  • Concurrent modifications within the same process are only visible after being committed to the workflow
§Usage Pattern
use aimx::{Aim, Reference, Cell};
use std::sync::Arc;

// Open an existing workspace
let workspace_path = std::path::Path::new("workspace.aim");
let _sheet = Aim::open(workspace_path).unwrap();

// Get a reference to a specific workflow
let workflow_ref = Reference::parse("my_workflow").unwrap();

// Retrieve a specific cell from the workflow
let cell = Aim::cell(workflow_ref, Arc::from("my_rule")).unwrap();

// Check the cell type and extract information
match cell {
    Cell::Formula { identifier, typedef, formula, value } => {
        println!("Formula cell: {} : {} = {}", identifier, typedef, formula);
        println!("Current value: {}", value);
    }
    Cell::Node { identifier, value } => {
        println!("Node cell: {} = {}", identifier, value);
    }
    Cell::Empty => {
        println!("No cell found with that identifier");
    }
    _ => {
        println!("Other cell type: {:?}", cell);
    }
}
§Side Effects
  • Read-only: This function does not modify any workflow state
  • File Access: May trigger lazy loading of workflow files from disk
  • Caching: Leverages workspace caching for improved performance on repeated access
§Performance Considerations
  • Efficient Lookup: Uses direct reference-based lookup without loading unnecessary data
  • Lazy Loading: Workflow files are only loaded when first accessed
  • Cached Access: Subsequent calls to the same workflow benefit from in-memory caching
  • Reference Resolution: Minimal overhead for constructing and resolving references
§Differences from Context-Based Operations

This function provides read-only MVCC access to committed workflow state:

  • Use Aim::get_cell for reading cells within an active write context
  • Use Aim::has_cell for checking cell existence without retrieving content
  • Use Aim::list for retrieving all cells in a workflow at once
  • Use Aim::acquire to begin a write context for modifications
§Error Handling

The function gracefully handles missing cells by returning Cell::Empty rather than an error. This allows applications to check for cell existence without exception handling:

use aimx::{Aim, Reference, Cell};
use std::sync::Arc;

let workflow_ref = Reference::parse("my_workflow").unwrap();
let cell = Aim::cell(workflow_ref, Arc::from("optional_rule")).unwrap();

if !cell.is_empty() {
    // Process the cell
    if let Some(identifier) = cell.identifier() {
        println!("Found cell: {}", identifier);
    }
 }
§See Also
  • Aim::list - Retrieve all cells in a workflow
  • Aim::contains - Check if a cell exists without retrieving it
  • Aim::get_cell - Read cells within an active write context
  • Aim::sheet - Get workflow metadata and structural information
  • Aim::acquire - Acquire write context for workflow modifications
  • Cell - Complete documentation for cell types and methods
  • Reference - Documentation for reference construction and parsing
Source

pub fn acquire(locator: Arc<Reference>) -> Result<Arc<str>>

§Acquires exclusive write access to a workflow for modifications.
§title: Acquire

Acquires exclusive write access to a workflow for modifications.

This function establishes a write context for a workflow, enabling modifications to its rules, structure, and inference configuration. It implements Multi-Version Concurrency Control (MVCC) by creating a mutable copy of the workflow that can be modified independently of concurrent readers.

§Arguments
  • locator - An Arc<Reference> pointing to the workflow to acquire for writing. The reference must point to an existing workflow in the workspace.
§Returns

Returns an Arc<str> containing a unique instance handle that identifies the active write context. This handle must be used for all subsequent write operations and must be released with Aim::release() to free the workflow for other writers.

§Errors

Returns an error if:

  • The workflow locator references a non-existent workflow
  • The workflow is already acquired by another process (concurrent write conflict)
  • The context workflow cannot be accessed or modified
  • The workspace is not properly initialized
§Behavior

Internally, acquire() performs the following operations:

  1. Context Workflow Access: Locates the global context workflow (context.aim)
  2. Handle Generation: Converts the reference to a handle string using underscore separators
  3. Conflict Check: Verifies the workflow is not already in use by checking if the handle exists
  4. Write Lock Acquisition: Acquires exclusive access to the context workflow
  5. Instance Registration: Adds the instance handle to the context workflow as an instance mapping
§Side Effects
  • Creates or modifies the global context.aim workflow to track active instances
  • Acquires an exclusive write lock on the context workflow
  • Registers the workflow instance for MVCC isolation
  • Makes the workflow unavailable for concurrent writers
§Usage Pattern

Always use acquire() in conjunction with release() to prevent resource leaks:

use aimx::{Aim, Reference, Cell};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Make changes to the workflow
let cell = Cell::new("meaning_of_life", "Number", "", "42");
Aim::append_or_update_cell(&handle, cell).unwrap();

// Make changes visible
Aim::snapshot(&handle).unwrap();

// Release the workflow
Aim::release(&handle).unwrap();
§See Also
§MVCC Considerations

The acquire function implements Multi-Version Concurrency Control:

  • Isolation: Writers work on a private copy of the workflow
  • Consistency: Readers continue to see the previous version
  • Atomicity: Changes become visible only after Aim::snapshot() or Aim::release()
  • Conflict Prevention: Only one writer can acquire a workflow at a time
  • Conflict Detection: Attempting to acquire an already-acquired workflow returns an error
§MVCC Visibility Timeline
Time         | Writer Operations           | Reader Operations
-------------|------------------------------|------------------------
 T0          | acquire()                    | cell(), list(), contains()
 T1          | append_or_update_cell()      | (changes not visible yet)
 T2          | snapshot()                   | (changes now visible)
 T3          | update_cell()                | (additional changes not visible yet)
 T4          | release()                    | (final state permanent)
§Performance Considerations
  • Low Overhead: Handle acquisition is lightweight
  • File System: Minimal I/O operations during acquisition
  • Memory Usage: Creates a copy of workflow data in memory
  • Lock Duration: Keep acquisition periods short for better concurrency
  • Handle Format: Generated handles use underscore-separated format for uniqueness
Source

pub fn snapshot(handle: &str) -> Result<()>

§Saves the current state of a workflow instance to disk, making changes permanently visible.
§title: Snapshot

This function creates a durable snapshot of all pending changes made within a workflow context, persisting them to the workflow’s .aim file and updating the MVCC version history. Unlike Aim::save() which operates at the workspace level, snapshot() focuses on instance-specific changes and is typically called after completing a set of related modifications.

§Arguments
  • handle - The unique instance handle obtained from Aim::acquire() that identifies the active workflow context to snapshot.
§Returns

Returns Ok(()) if the snapshot operation completes successfully.

§Errors

Returns an error if:

  • The instance handle is invalid or expired
  • The workflow file cannot be written (permissions, disk full)
  • The workflow is in an invalid state (corrupted structure)
  • Concurrent modifications conflict with the snapshot operation
§MVCC Behavior

The snapshot operation operates within the Multi-Version Concurrency Control system:

  • Creates a new version entry in the workflow’s journal file (.jnl)
  • Marks the snapshot version as the new readable state for concurrent readers
  • Previous versions remain accessible for existing readers
  • Writers acquire exclusive locks during the snapshot process
§Side Effects
  • Writes the workflow file ({identifier}.aim) with all current changes
  • Creates a journal entry in the workflow’s journal file ({identifier}.jnl)
  • Updates the workflow’s version metadata (version, latest_version)
  • Makes all context changes visible through the Aim::cell() and Aim::list() APIs
§MVCC Visibility Timeline
Time         | Context Operations           | MVCC Read Operations
-------------|------------------------------|------------------------
 T0          | acquire()                    | cell(), list(), contains()
 T1          | append_or_update_cell()      | (changes not visible yet)
 T2          | snapshot()                   | (changes now visible)
 T3          | update_cell()                | (additional changes not visible yet)
 T4          | release()                    | (final state permanent)
§Usage Pattern

snapshot() should be called after completing a logical group of changes:

use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Make related changes
let input_cell = Cell::new("input_data", "Text", r#""processed""#, "");
Aim::append_or_update_cell(&handle, input_cell).unwrap();

let result_cell = Cell::new("analysed", "Bool", "true", "");
Aim::append_or_update_cell(&handle, result_cell).unwrap();

// Snapshot the logical unit of work
Aim::snapshot(&handle).unwrap();

// Changes are now visible to other processes
assert!(Aim::contains(reference.clone(), "input_data").unwrap());
assert!(Aim::contains(reference.clone(), "analysed").unwrap());

Aim::release(&handle).unwrap();
§Performance Considerations
  • Atomicity: The snapshot operation is atomic - either all changes are saved or none are
  • Efficiency: Consider batching related changes before calling snapshot()
  • Frequency: Balance between frequent snapshots (safety) vs. performance overhead
§Implementation Details

Internally, snapshot() performs:

  1. Locates the instance context using the provided handle
  2. Acquires a write lock on the instance
  3. Calls the instance’s save() method to persist changes
  4. Updates the workflow’s version tracking
  5. Releases the write lock
§Error Handling Strategy

In case of failure:

  • The workflow remains in its previous consistent state
  • The instance handle remains valid for retry attempts
  • Detailed error information is available for debugging
§See Also
Source

pub fn release(handle: &str) -> Result<()>

§Releases a workflow context handle and finalizes all pending changes.
§title: Release

This function releases a workflow context handle and finalizes all pending changes. It performs the final cleanup of a workflow modification session by saving any remaining changes and removing the instance from the global context workflow.

§Arguments
  • handle - A string slice containing the unique instance handle obtained from Aim::acquire() that identifies the active workflow context to release.
§Returns

Returns Result<()> which is:

  • Ok(()) if the release operation completes successfully
  • Err(anyhow::Error) if any step fails
§Errors

Returns an error if:

  • The instance handle is invalid or cannot be located
  • The instance cannot be locked for writing (e.g., concurrent access)
  • The workflow save operation fails (e.g., file system errors)
  • The context workflow cannot be located or accessed
  • The instance entry cannot be found in the context workflow
  • The context workflow operations fail (e.g., save errors)
§Behavior

Internally, release() performs a two-phase cleanup operation:

Phase 1: Final Save

  1. Locates the instance context using the provided handle via Instance::locate()
  2. Acquires a write lock on the instance context
  3. Calls save() on the instance to persist any remaining changes
  4. Releases the instance write lock

Phase 2: Context Cleanup

  1. Locates the global context workflow using Reference::context()
  2. Acquires a write lock on the context workflow via LockManager
  3. Searches for the instance handle in the context workflow using the workflow’s get_index method
  4. Removes the instance row from the context workflow via the workflow’s remove_row method
  5. Saves the updated context workflow via the workflow’s save method
  6. Updates the context node with the modified workflow
  7. Releases the context workflow write lock
§Side Effects
  • Final Persistence: Saves any unsaved changes to the target workflow
  • Context Cleanup: Removes the instance entry from the global context workflow
  • Lock Release: Releases write locks on both the instance and context workflow
  • Resource Cleanup: Makes the workflow available for future Aim::acquire() calls
  • MVCC Update: Finalizes the version state for concurrent readers
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Make changes to the workflow using the handle
// ... workflow modifications ...

// Make changes visible and release
Aim::release(&handle).unwrap();
§Error Handling

The function uses a strict error handling approach:

  • If the instance cannot be located or saved, the function returns an error
  • If the context cleanup fails, the function returns an error indicating that the instance may still be locked and require manual cleanup
  • If the instance is not found in the context workflow, returns a specific error message indicating a missing instance
§MVCC Considerations

The release operation finalizes the Multi-Version Concurrency Control cycle:

  • Creates a final version of all accumulated changes
  • Makes the final state permanently visible to concurrent readers
  • Removes the exclusive write lock, allowing other processes to acquire the workflow
  • Updates the workflow’s version tracking in the journal
§Differences from Aim::snapshot()
FunctionTimingLock BehaviorContext StatePurpose
snapshot()During sessionKeeps context activeContext remains acquiredIntermediate checkpoint
release()End of sessionReleases all locksContext is releasedFinal cleanup and persistence

Use snapshot() for intermediate saves during long-running operations, and release() when the modification session is complete and the context should be cleaned up.

§See Also
Source

pub fn add_node( locator: Arc<Reference>, identifier: Arc<str>, parameters: &str, ) -> Result<Arc<Reference>>

§Adds a new child workflow node within an existing workflow using an active write context.
§title: Add node

This function creates a nested workflow node within a parent workflow that has an active write context (Aim::acquire()). This enables hierarchical workflow structures where workflows can contain sub-workflows, supporting complex agentic workflow compositions.

§Arguments
  • handle - The unique instance handle obtained from Aim::acquire() that identifies the active write context for the parent workflow.

  • identifier - An Arc<str> specifying the unique identifier for the new child node. Must be a valid AIMX identifier (alphanumeric, starting with letter, no underscores). The identifier should be unique within the parent workflow.

  • parameters - A string specifying the inference configuration for the child workflow. Uses the same AIMX inference syntax as Aim::add():

    • Patterns: “evaluation”, “inference”, “search”, “summarize”, “compose”, “debate”
    • Models: “fast”, “standard”, “thinking”, “extract”, “instruct”, “coder” Examples: “evaluation”, “inference thinking”, “search extract”
§Returns

Returns an Arc<Reference> pointing to the newly created child workflow node. The reference path will be {parent_workflow}.{identifier} (e.g., foo.baz).

§Errors

Returns an error if:

  • The instance handle is invalid or expired
  • The identifier is empty, contains invalid characters, or is “_”
  • A node with the same identifier already exists within the parent workflow
  • The parameters string contains invalid inference syntax
  • The parent workflow file cannot be written to
  • The workspace is in an invalid state
§Behavior

Internally, add_node() performs the following operations:

  1. Locates the active instance context using the provided handle
  2. Acquires a write lock on the workflow instance
  3. Parses the inference parameters into a Node structure
  4. Calls the workflow’s add_node() method to create the child workflow
  5. Creates the child workflow file with default structure
  6. Returns a reference to the newly created child node
§File Operations

This function creates the following file system structure:

workspace/
  ├── {parent}.aim        # Parent workflow file (updated with node rule)
  └── {parent}/           # Parent workflow directory (created if needed)
      └── {identifier}.aim  # New child workflow file with default header

The child workflow is initialized as an unloaded node and will be created on first access.

§Usage Pattern

Basic usage with hierarchical workflows:

use aimx::{Aim, Reference};
use std::sync::Arc;

// Create top-level workflow
let foo_ref = Aim::add("foo", "evaluation").unwrap();

// Acquire write context for the parent workflow
let handle = Aim::acquire(foo_ref.clone()).unwrap();

// Add child workflow optimized for complex reasoning
let child_ref = Aim::add_node(foo_ref.clone(), Arc::from("analysis"), "inference thinking").unwrap();
println!("Created child workflow: {}", child_ref);

// Make changes visible to other readers
Aim::snapshot(&handle).unwrap();

// Child workflow is now accessible via MVCC
let child_sheet = Aim::sheet(child_ref).unwrap();
println!("Child workflow model: {}", child_sheet.model);

// Release the write context
Aim::release(&handle).unwrap();
§MVCC Considerations

The new child node becomes visible to concurrent readers only after calling Aim::snapshot() or Aim::release(). Within the write context, the node is immediately available for subsequent operations. The child workflow file is created lazily when first accessed.

§Performance Considerations
  • Atomicity: The node creation is atomic within the write transaction
  • File System: Creates node rule in parent workflow (child file created on demand)
  • Caching: Leverages workspace caching for subsequent operations
  • Context Efficiency: Batch multiple node creations before calling Aim::snapshot
§See Also
Source

pub fn copy_node( locator: Arc<Reference>, from: Arc<Reference>, to: Arc<str>, ) -> Result<()>

§Copies an existing workflow node within a parent workflow to create a replica with a different identifier.
§title: Copy Node

This function copies an existing workflow node within a parent workflow to create a replica with a different identifier. The copy operation includes all associated files (.aim, .jnl) and recursively copies any child directory structure and contents.

§Arguments
  • handle - A &str representing the workflow instance handle obtained from Aim::acquire(). This handle provides exclusive write access to the workflow context where the node will be copied.
  • from - An Arc<Reference> pointing to the existing node that should be copied. This reference identifies the source node within the workspace hierarchy.
  • to - An Arc<str> containing the new identifier for the copied node. This must be a valid, unique identifier within the target workflow.
§Returns

Returns a Result<()> which is:

  • Ok(()) if the node was successfully copied
  • Err(anyhow::Error) if the operation failed
§Errors

Returns an error if:

  • The handle is invalid or doesn’t correspond to an active workflow instance
  • The from reference points to a non-existent node
  • The to identifier already exists in the target workflow
  • The to identifier is invalid (empty, contains invalid characters, or is the reserved _ identifier)
  • File system operations fail (copying files, creating directories, etc.)
  • The target workflow cannot be modified due to access restrictions
§Behavior

Internally, copy_node() performs the following operations:

  1. Validation: Verifies that the from node exists and the to identifier is unique and valid
  2. File System Copy: Recursively copies all associated files and directories:
    • Copies the .aim workflow file from source to target
    • Copies the .jnl journal file if it exists
    • Recursively copies the entire child directory structure if it exists
  3. Node Creation: Creates a new Node with the same inference configuration as the source
  4. Workflow Update: Adds the new node to the target workflow using Aim::add_node()
§Side Effects
  • Creates a new workflow node file at the target location
  • Creates or updates journal files for version tracking
  • Creates directory structures for nested nodes
  • Modifies the target workflow to include the new node reference
  • File system changes are immediately visible and persistent
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Acquire workflow context
let parent_reference = Reference::parse("parent").unwrap();
let handle = Aim::acquire(parent_reference.clone()).unwrap();

// Copy an existing node to a new identifier
let source_reference = Reference::parse("existing.child").unwrap();
let new_identifier = Arc::from("copied_child");
Aim::copy_node(parent_reference.clone(), source_reference, new_identifier).unwrap();

// Make changes visible
Aim::release(&handle).unwrap();
§See Also
§File Operations

The copy operation performs the following file system operations:

  • Copies source.aim to target.aim
  • Copies source.jnl to target.jnl (if exists)
  • Recursively copies source/ directory to target/ (if exists)
  • Creates parent directories as needed
  • All file operations use standard OS file copying mechanisms
§MVCC Considerations
  • The copy operation is performed within an active write context
  • Changes are only visible within the workflow instance until Aim::release() is called
  • The operation maintains version consistency through the journaling system
  • Concurrent read access to the original node remains available during the copy operation
§Performance Considerations
  • File copying performance depends on the size of the workflow files and directory structure
  • Large workflows with extensive journal history may take longer to copy
  • The operation is atomic at the workflow level - either the entire copy succeeds or fails
  • Consider using Aim::snapshot() if you need to make the copy visible before releasing the handle
Source

pub fn rename_node( locator: Arc<Reference>, from: &str, to: Arc<str>, ) -> Result<()>

§Renames a workflow node within a parent workflow using an active write context.
§title: Rename Node

This function renames an existing workflow node within a parent workflow that has an active write context. The rename operation preserves the node’s inference configuration, rules, and internal structure while updating its identifier within the parent workflow hierarchy.

§Arguments
  • handle - The unique instance handle obtained from Aim::acquire() that identifies the active write context for the parent workflow.

  • from - The current identifier of the workflow node to rename. Must be a valid AIMX identifier that exists within the parent workflow.

  • to - An Arc<str> specifying the new identifier for the workflow node. Must be a valid AIMX identifier that does not already exist within the parent workflow.

§Returns

Returns Ok(()) if the rename operation completes successfully.

§Errors

Returns an error if:

  • The instance handle is invalid or expired
  • The source node identifier (from) does not exist within the parent workflow
  • The target identifier (to) already exists within the parent workflow
  • Either identifier is invalid (contains invalid characters or is empty)
  • File system operations fail during the rename process
  • The parent workflow cannot be written to
§Behavior

Internally, rename_node() performs the following operations:

  1. Locates the active instance context using the provided handle
  2. Acquires a write lock on the workflow instance
  3. Validates that the target identifier is unique within the parent workflow
  4. Retrieves the source node rule and its associated node
  5. Renames the node rule within the parent workflow
  6. Performs comprehensive file system operations to rename associated files:
    • Renames the .aim workflow file
    • Renames the .jnl journal file (if it exists)
    • Renames the associated directory structure (if it exists)
§Side Effects
  • File System Changes: Renames all associated files and directories
  • Workflow Modification: Updates the parent workflow with the new node reference
  • MVCC Visibility: Changes become visible only after Aim::snapshot() or Aim::release()
§File Operations

The rename operation performs comprehensive file system operations:

workspace/
    └── {parent}/       # Parent workflow directory
        ├── {from}.aim  # Source workflow file (renamed)
        ├── {from}.jnl  # Source journal file (renamed if exists)
        └── {from}/     # Source directory structure (renamed)
          ↓ renamed to ↓
        ├── {to}.aim    # Target workflow file
        ├── {to}.jnl    # Target journal file (if source had one)
        └── {to}/       # Target directory structure
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Acquire workflow context
let parent_reference = Reference::parse("foo").unwrap();
let handle = Aim::acquire(parent_reference.clone()).unwrap();

// Rename a node within the workflow
let result = Aim::rename_node(parent_reference.clone(), "old_name", Arc::from("new_name"));
assert!(result.is_ok());

// Make changes visible
Aim::release(&handle).unwrap();
§Differences from Aim::rename()
AspectAim::rename()Aim::rename_node()
ScopeWorkspace levelWithin existing workflow context
ContextDirect workspace accessRequires active write context
ReferenceTop-level (e.g., “foo” → “bar”)Nested (e.g., “foo.baz” → “foo.qux”)
File Locationworkspace/foo.aim → workspace/bar.aimworkspace/foo/baz.aim → workspace/foo/qux.aim
§MVCC Considerations

The renamed node becomes visible to concurrent readers only after calling Aim::snapshot() or Aim::release(). Within the write context, the renamed node is immediately available for subsequent operations using the new identifier.

§Performance Considerations
  • Recursive Rename: Renames entire directory structure recursively
  • File Operations: Performs multiple file system operations for each file
  • Atomicity: The operation is atomic - either all files are renamed or none are
  • Error Recovery: If renaming fails partway, created files are rolled back
§Safety Considerations

The rename operation is atomic and reversible until the context is released:

  • If the operation fails, the workflow remains in its original state
  • Until Aim::snapshot() or Aim::release() are called, the original node remains accessible via its old identifier
  • Applications can implement undo mechanisms by calling rename_node() again with the reversed identifiers before committing changes
§See Also
Source

pub fn remove_node(locator: Arc<Reference>, identifier: &str) -> Result<()>

§Removes a workflow node from within a parent workflow using an active write context.
§title: Remove node

This function permanently deletes a child workflow node and all its associated resources (including child workflows, files, and journal entries) from within a parent workflow that has an active write context. The removal operation is comprehensive and irreversible, ensuring no orphaned files remain in the workspace.

§Arguments
  • handle - The unique instance handle obtained from Aim::acquire() that identifies the active write context for the parent workflow.

  • identifier - The identifier of the child workflow node to remove. Must be a valid AIMX identifier that exists within the parent workflow. Cannot be empty or “_” (reserved for workspace root).

§Returns

Returns Ok(()) if the removal operation completes successfully.

§Errors

Returns an error if:

  • The instance handle is invalid or expired
  • The specified child node does not exist within the parent workflow
  • The identifier is empty or invalid (contains invalid characters)
  • File system operations fail during the removal process
  • The parent workflow cannot be written to
§Side Effects

Performs comprehensive file system operations to remove all associated files:

  • Deletes the child workflow file ({parent}/{identifier}.aim)
  • Deletes the child journal file ({parent}/{identifier}.jnl) if it exists
  • Deletes the child directory ({parent}/{identifier}/) if it exists, including all nested child workflows recursively
  • Removes the node reference from the parent workflow
  • Creates corresponding journal entries for MVCC tracking
§Safety Considerations

This operation is irreversible. Once a child node is removed, all its data, rules, nested workflows, and inference history are permanently deleted. Applications should implement confirmation dialogs or undo mechanisms when calling this function interactively.

§MVCC Considerations

The removed child node becomes invisible to concurrent readers only after calling Aim::snapshot() or Aim::release(). Within the write context, the removal is immediately effective for subsequent operations.

§File Operations

The removal operation performs the following file system operations:

workspace/
  └── {parent}/             # Parent workflow directory
      ├── {identifier}.aim  # Child workflow file (deleted)
      ├── {identifier}.jnl  # Child journal file (deleted if exists)
      └── {identifier}/     # Child directory structure (recursively deleted)
          ├── nested1.aim → (deleted)
          └── nested2.aim → (deleted)
§Behavior

Internally, remove_node() performs the following operations:

  1. Locates the active instance context using the provided handle
  2. Acquires a write lock on the workflow instance
  3. Calls the workflow’s delete_node() method to perform the actual removal
  4. Executes file system operations to delete all associated files
  5. Updates the parent workflow by removing the node reference
§Performance Considerations
  • Recursive Deletion: Deletes entire directory structure recursively
  • File Operations: Performs multiple file system operations for each file
  • Atomicity: The operation is atomic - either all files are deleted or none are
  • Error Recovery: If deletion fails partway, created files are rolled back
§Differences from Aim::remove()
AspectAim::remove()Aim::remove_node()
ScopeWorkspace levelWithin existing workflow context
ContextDirect workspace accessRequires active write context
ReferenceTop-level (e.g., “foo”)Nested (e.g., “foo.baz”)
File Locationworkspace/foo.aimworkspace/foo/baz.aim
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Create top-level workflow and child node
let parent_ref = Aim::add("parent", "evaluation").unwrap();
let handle = Aim::acquire(parent_ref.clone()).unwrap();
let child_ref = Aim::add_node(parent_ref.clone(), Arc::from("child"), "inference").unwrap();

// Verify child exists
let child_sheets = Aim::catalog(parent_ref.clone()).unwrap();
assert!(child_sheets.iter().any(|sheet| sheet.path().contains("child")));

// Remove the child node
Aim::remove_node(parent_ref.clone(), "child").unwrap();

// Make removal visible to other readers
Aim::snapshot(&handle).unwrap();

// Verify child is gone
let remaining_children = Aim::catalog(parent_ref).unwrap();
assert!(!remaining_children.iter().any(|sheet| sheet.path().contains("child")));

// Release the write context
Aim::release(&handle).unwrap();
§Integration with Context Operations

If the child workflow being removed has an active context instance (via Aim::acquire), the removal operation will still proceed but may leave orphaned context entries. Consider calling Aim::release on any active child workflow handles before removal.

§See Also
Source

pub fn get_index(handle: &str, identifier: &str) -> Result<Option<usize>>

§Retrieves the index position of a cell within a workflow using an active write context.
§title: Get Index

This function retrieves the zero-based row index position of a rule within a workflow using an active write context. It provides fast lookup of rule positions for operations that need to work with rules by their index rather than their identifier.

§Arguments
  • handle - A string slice containing the context handle that was returned by Aim::acquire(). This provides exclusive write access to the workflow.
  • identifier - A string slice containing the rule identifier to find the index for.
§Returns

Returns a Result<Option<usize>> where:

  • Ok(Some(usize)) - The zero-based index position of the rule if it exists
  • Ok(None) - If no rule with the given identifier exists in the workflow
  • Err(anyhow::Error) - If the context handle is invalid or the workflow cannot be accessed
§Errors

Returns an error if:

  • The provided handle is not a valid context handle
  • The workflow associated with the handle cannot be accessed
  • The instance context has been corrupted or is no longer valid
§Behavior

Internally, get_index() performs the following operations:

  1. Locates the instance context using the provided handle
  2. Acquires a write lock on the context to ensure thread-safe access
  3. Calls the underlying workflow’s get_index() method which performs a hash map lookup
  4. Returns the index position if the rule exists, or None if it doesn’t

The function uses the workflow’s internal lookup table (a HashMap<Arc<str>, usize>) to provide O(1) average-case lookup performance for rule positions.

§Side Effects
  • Acquires a write lock on the instance context (but doesn’t modify the workflow)
  • No persistent changes are made to the workflow or its files
§Usage Pattern
use aimx::{Aim, Cell};
use std::sync::Arc;

// Acquire workflow context
let reference = aimx::Reference::parse("example.workflow").unwrap();
let handle = Aim::acquire(reference).unwrap();

// Add some cells to the workflow
let cell1 = Cell::new("rule1", "Number", "42", "");
let cell2 = Cell::new("rule2", "Text", "\"hello\"", "");
let cell3 = Cell::new("rule3", "Bool", "true", "");

Aim::append_or_update_cell(&handle, cell1).unwrap();
Aim::append_or_update_cell(&handle, cell2).unwrap();
Aim::append_or_update_cell(&handle, cell3).unwrap();

// Get index positions of rules
if let Some(index) = Aim::get_index(&handle, "rule2").unwrap() {
    println!("rule2 is at index: {}", index);
    // index will be 1 (zero-based)
}

// Check for non-existent rule
let none_index = Aim::get_index(&handle, "nonexistent").unwrap();
assert!(none_index.is_none());

// Make changes visible
Aim::release(&handle).unwrap();
§See Also
Source

pub fn get_row(handle: &str, index: usize) -> Result<Cell>

§Retrieves a specific cell (rule) from a workflow by its zero-based index position within an active write context.
§title: Get Row

This function retrieves a specific rule from a workflow by its zero-based index position within an active write context, returning a Cell representation of the rule’s content.

§Arguments
  • handle - A string slice that references the unique instance handle obtained from Aim::acquire(). This handle identifies the active write context for the workflow where the rule should be retrieved.
  • index - The zero-based index position of the rule to retrieve. Must be a valid index within the current bounds of the workflow rule collection.
§Returns

Returns a Cell enum variant representing the rule’s current state at the specified index position. The cell type depends on the rule’s content:

  • Cell::Formula - For standard formula-based rules with expression and value
  • Cell::Node - For workflow node references that point to child workflows
  • Cell::Branch - For conditional branch logic with condition and target
  • Cell::Format - For formatting instructions with templates and examples
  • Cell::Retry - For retryable operations with count, condition, and target
  • Cell::Errata - For error states containing error information
  • Cell::Comment - For comment rows in the workflow
  • Cell::Empty - For cleared or non-existent rules at the specified index
§Errors

Returns an error if:

  • The instance handle is invalid, expired, or cannot be located
  • The workflow context operations fail due to concurrent access issues
  • The instance has been released or is no longer active

The function performs bounds checking internally and returns Cell::Empty for out-of-bounds indices rather than failing.

§Behavior

Internally, get_row() performs the following operations:

  1. Context Resolution: Locates the active instance context using the provided handle via Instance::locate()
  2. Lock Acquisition: Acquires a write lock on the workflow instance to ensure thread safety
  3. Row Retrieval: Calls the workflow’s internal get_row() method to retrieve the rule data at the specified index
  4. Conversion: Converts the internal Row representation to a Cell using Cell::convert_row()
  5. Bounds Handling: Returns Row::Empty for out-of-bounds access, which converts to Cell::Empty
§Side Effects
  • Read Operation: This is a read-only operation that does not modify the workflow
  • Lock Acquisition: Temporarily acquires a write lock for thread safety, but does not modify the workflow content
  • No Persistence: Changes to the returned cell do not affect the workflow until explicitly saved using Aim::snapshot() or Aim::release()
§Usage Pattern
use aimx::{Aim, Cell};

// Acquire workflow context for modifications
let locator = aimx::Reference::parse("workflow.subworkflow").unwrap();
let handle = Aim::acquire(locator).unwrap();

// Add some rules to the workflow
let cell1 = Cell::new("rule1", "Number", "10 + 5", "");
let cell2 = Cell::new("rule2", "Text", "\"hello world\"", "");
let cell3 = Cell::new("rule3", "Bool", "true", "");

Aim::append_or_update_cell(&handle, cell1).unwrap();
Aim::append_or_update_cell(&handle, cell2).unwrap();
Aim::append_or_update_cell(&handle, cell3).unwrap();
Aim::snapshot(&handle).unwrap();

// Retrieve rules by index
let first_rule = Aim::get_row(&handle, 0).unwrap();
let second_rule = Aim::get_row(&handle, 1).unwrap();
let third_rule = Aim::get_row(&handle, 2).unwrap();

println!("First rule: {}", first_rule.identifier().unwrap_or_default());
println!("Second rule: {}", second_rule.identifier().unwrap_or_default());
println!("Third rule: {}", third_rule.identifier().unwrap_or_default());

// Handle out-of-bounds access (returns Empty)
let empty_rule = Aim::get_row(&handle, 99).unwrap();
assert!(empty_rule.is_empty());

// Clean up
Aim::release(&handle).unwrap();
§Integration with Other Index-Based Operations

The retrieved cell can be used in conjunction with other positional operations:

§Comparison with Identifier-Based Access
AspectIndex-Based (get_row)Identifier-Based (get_cell)
Lookup MethodArray index positionHash-based identifier lookup
Use CasePosition-aware operations, bulk processingDirect rule content access, rule updates
PerformanceO(1) direct array accessO(1) hash lookup
StabilityMay change during reordering operationsStable across workflow modifications
API Familyget_row, set_row, insert_row, reposition_rowget_cell, update_cell, delete_cell
Bounds HandlingReturns Cell::Empty for out-of-boundsReturns None for missing identifiers
§MVCC Considerations

The cell reflects the current state of the workflow within the write context, including any uncommitted changes. Changes made through index-based operations are not visible to concurrent readers until Aim::snapshot() or Aim::release() are called to commit the changes.

§Performance Characteristics
  • Direct Access: O(1) array-based lookup for efficient positional access
  • Context Required: Requires active write context handle for thread safety
  • Index Stability: Indices remain stable within atomic operations but may change during batch modifications
  • Memory Efficient: Minimal overhead compared to loading entire workflow

For comprehensive workflow management, consider these related functions:

§See Also
Source

pub fn set_row(handle: &str, index: usize, cell: Cell) -> Result<()>

§Updates a specific row within a workflow using an active write context.
§title: Set row

This function updates a specific row within a workflow using an active write context. It replaces the content at the specified zero-based index with a new cell, or creates the row if it doesn’t exist.

§Arguments
  • handle - A &str reference to an active workflow context handle obtained from Aim::acquire()
  • index - A usize representing the zero-based row index where the cell should be placed
  • cell - A Cell containing the new cell data to set at the specified index
§Returns

Returns Ok(()) if the operation succeeds, or an error if the handle is invalid or the operation fails.

§Errors

Returns an error if:

  • The handle does not correspond to an active workflow context
  • The cell contains an identifier that conflicts with an existing rule at a different index
  • The cell contains an invalid identifier format
§Behavior

Internally, set_row() performs the following operations:

  1. Locates the workflow instance using the provided handle
  2. Acquires a write lock on the workflow
  3. Converts the Cell to a Row using Row::convert()
  4. Calls the workflow’s set_row() method to update the specified index
  5. The workflow performs validation and updates its internal state

The workflow’s set_row() method:

  • Validates the cell identifier format
  • Checks for identifier conflicts with existing rules
  • Expands the workflow’s row vector if the index is beyond current bounds
  • Updates the rule lookup index to maintain identifier-to-index mapping
  • Marks the workflow as having changes that need to be saved
§Side Effects
  • Modifies the workflow’s internal row structure
  • Updates the rule lookup index for fast identifier-based access
  • Marks the workflow as having pending changes (requires Aim::snapshot() or Aim::release() to persist)
  • May expand the workflow’s row vector to accommodate the specified index
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Create a new cell
let cell = Cell::new("updated_rule", "Number", "42", "");

// Update the row at index 0
Aim::set_row(&handle, 0, cell).unwrap();

// Make changes visible
Aim::snapshot(&handle).unwrap();
Aim::release(&handle).unwrap();
§See Also
  • Aim::acquire() - Acquires exclusive write access to a workflow
  • Aim::get_row() - Retrieves a specific row from a workflow
  • Aim::insert_row() - Inserts a new row at a specified index
  • Aim::snapshot() - Saves the current state to make changes visible
  • Aim::release() - Releases a workflow context and finalizes changes
  • Cell - Cell data structure for workflow rules
  • Row - Internal row representation in workflows
§MVCC Considerations

This function operates on a private workspace context that is not visible to other readers until Aim::snapshot() or Aim::release() is called. Multiple writers can operate on different workflow contexts simultaneously without interference.

§Performance Considerations
  • Row index lookup is O(1) for existing rows
  • Identifier validation occurs on each call
  • Large index values may cause vector expansion with O(n) memory allocation
  • The workflow maintains an internal hash map for O(1) identifier-to-index lookups
Source

pub fn insert_row(handle: &str, index: usize, cell: Cell) -> Result<()>

Inserts a new row at the specified index within a workflow using an active write context. This function inserts a new row at a specified index within a workflow using an active write context. It shifts existing rows to higher indices and maintains workflow integrity through identifier uniqueness checks.

§Arguments
  • handle - The unique instance handle obtained from Aim::acquire() that identifies the active write context for the workflow being modified.

  • index - The zero-based row index where the new cell should be inserted. If the index exceeds the current workflow size, the workflow will be expanded with empty rows to accommodate the position before insertion.

  • cell - A Cell object containing the new rule definition to insert. The cell must contain a valid rule with a unique identifier within the workflow.

§Returns

Returns Ok(()) on successful insertion, indicating the row was placed correctly.

§Errors

Returns an error if:

  • The instance handle is invalid or expired
  • The cell contains an invalid rule identifier
  • A rule with the same identifier already exists in the workflow
  • The workflow file cannot be written to
  • The workspace is in an invalid state
§Behavior

Internally, insert_row() performs the following operations:

  1. Locates the active instance context using the provided handle
  2. Acquires a write lock on the workflow instance
  3. Converts the Cell to a Row using Row::convert()
  4. Validates the rule identifier for uniqueness across the entire workflow
  5. Inserts the row at the specified index, shifting existing rows
  6. Rebuilds the internal identifier-to-index lookup mapping
  7. Triggers version-level change tracking (always requires version change)
§MVCC Considerations

The row insertion becomes visible to concurrent readers only after calling Aim::snapshot() or Aim::release(). Within the write context, the inserted row is immediately available for subsequent operations.

§Index Behavior

The function handles various index scenarios:

  • Valid Index: Inserts at position, shifting existing rows to higher indices
  • Index Equals Size: Appends to end of workflow (equivalent to append)
  • Index Beyond Size: Expands workflow with empty rows, then inserts at position
  • Empty Workflow: Creates workflow with single row at index 0
§Identifier Uniqueness

Unlike Aim::set_row(), this function enforces strict identifier uniqueness:

  • New Identifier: Must not exist anywhere in the workflow
  • Duplicate Detection: Checks entire workflow before insertion
  • Error Prevention: Fails early if identifier conflict detected
§Performance Characteristics
  • Insertion Complexity: O(n) due to row shifting and reindexing
  • Lookup Updates: Internal identifier-to-index mapping is rebuilt
  • Version Tracking: Always triggers version-level change tracking
  • Memory Usage: Workflow size increases by one row
FunctionPurposeIndex BehaviorIdentifier HandlingChange Level
insert_row()Insert at indexShifts existing rowsMust be new identifierVersion
set_row()Update specific indexExpands if neededEnforces uniquenessPartial/Version
append_or_update_cell()Add/update by identifierAppends to endUpdates if existsPartial
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Create a new cell to insert
let new_cell = Cell::new("new_rule", "Number", "42", "");

// Insert at index 1 (shifting existing rows)
Aim::insert_row(&handle, 1, new_cell).unwrap();

// Make changes visible
Aim::snapshot(&handle).unwrap();

// Clean up
Aim::release(&handle).unwrap();
§See Also
Source

pub fn reposition_row(handle: &str, from: usize, to: usize) -> Result<()>

§Moves a rule from one row position to another within a workflow.
§title: Reposition Row

Moves a rule from one row position to another within a workflow, reordering the workflow structure.

This function repositions a rule within a workflow by moving it from its current zero-based index position to a new target position. The operation shifts other rules as needed to accommodate the move and maintains the workflow’s internal indexing for efficient rule lookups.

§Arguments
  • handle - An active write context handle obtained from Aim::acquire. Must be a valid handle pointing to a workflow that has been acquired for writing.

  • from - The current zero-based row index of the rule to move. If the index exceeds the current workflow size, the workflow will be expanded with empty rows as needed.

  • to - The target zero-based row index where the rule should be placed. Can be any valid index, including positions beyond the current workflow size. The workflow will be expanded with empty rows if necessary.

§Returns

Returns Ok(()) if the reposition operation was successful.

§Errors

Returns an error if:

  • The handle is invalid or points to a non-existent workflow context
  • The underlying workflow operation fails
§Side Effects
  • Changes the order of rules within the workflow
  • Expands the workflow’s row vector if from or to indices exceed current bounds
  • Triggers a partial change flag on the workflow (requires Aim::snapshot to persist)
  • Rebuilds the internal identifier-to-index lookup mapping
  • The repositioning is immediately visible within the active write context
§Behavior

Internally, reposition_row() performs the following operations:

  1. Early Return: If from equals to, the function returns immediately as no operation is needed
  2. Vector Expansion: Expands the workflow’s rows vector if either from or to exceeds current bounds
  3. Change Tracking: Marks the workflow with a partial change flag
  4. Empty Row Optimization: If both source and destination are empty, returns early
  5. Row Movement: Removes the row from the from index and inserts it at the to index
  6. Index Rebuilding: Rebuilds the internal lookup table that maps rule identifiers to row indices
§MVCC Considerations

The reposition operation is performed within the active write context and is not visible to concurrent readers until Aim::snapshot is called to persist the changes. The operation only sets a partial change flag, making it efficient for frequent reordering operations.

§Performance Characteristics
  • Time Complexity: O(n) where n is the number of rules in the workflow
  • Space Complexity: O(1) additional space, but may expand the row vector
  • Index Rebuilding: Requires rebuilding the identifier-to-index lookup table in O(n) time
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let locator = Reference::parse("example.workflow").unwrap();
let handle = Aim::acquire(locator).unwrap();

// Add some initial rules
let cell1 = Cell::new("first", "Number", "1", "");
let cell2 = Cell::new("second", "Text", "\"hello\"", "");
let cell3 = Cell::new("third", "Bool", "true", "");

Aim::append_or_update_cell(&handle, cell1).unwrap();
Aim::append_or_update_cell(&handle, cell2).unwrap();
Aim::append_or_update_cell(&handle, cell3).unwrap();

// Reposition: move rule from index 0 to index 2
Aim::reposition_row(&handle, 0, 2).unwrap();

// The rule originally at index 0 is now at index 2
let moved_cell = Aim::get_row(&handle, 2).unwrap();
assert_eq!(moved_cell.identifier(), Some(Arc::from("first")));

// Make changes visible
Aim::snapshot(&handle).unwrap();
Aim::release(&handle).unwrap();
§Integration with Other Operations

The repositioned rule maintains its identifier and all associated metadata. Other operations that rely on row indices will see the new ordering:

§See Also
Source

pub fn clear_row(handle: &str, index: usize) -> Result<Cell>

§Clears the content of a cell at the specified index while preserving its position.
§title: Clear Row

Clears the content of a cell at the specified index while preserving its position within the workflow. This operation removes the rule from the specified index but maintains the row structure, allowing the position to be reused later.

§Arguments
  • handle - A reference to the instance handle obtained from Aim::acquire() that identifies the active write context for the workflow.
  • index - The zero-based index position of the row to clear.
§Returns

Returns a Cell containing the rule that was cleared from the specified index. If the index was out of bounds or the row was already empty, returns Cell::Empty.

§Errors

This function does not return errors for invalid operations. Instead:

  • If the handle is invalid, it returns an error when trying to locate the instance
  • If the index is out of bounds, it returns Cell::Empty
  • If the row at the specified index is already empty, it returns Cell::Empty
§Behavior

Internally, clear_row() performs the following operations:

  1. Locates the active instance context using the provided handle
  2. Acquires a write lock on the workflow instance to ensure thread safety
  3. Calls the workflow’s internal clear_row() method
  4. Converts the cleared row to a Cell using Cell::convert_row()
  5. Returns the cell containing the cleared rule (or Cell::Empty if no rule was present)

The underlying workflow implementation ensures that:

  • The row at the specified index becomes empty
  • The row count remains unchanged
  • The rule is removed from the internal lookup table
  • The operation is marked as a version change
§Side Effects
  • Removes the rule from the workflow’s internal identifier lookup table
  • Marks the workflow as having version changes (requiring a save)
  • Decreases the rule count by one (if a rule was present)
  • Preserves the total row count
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Clear a row at index 2 and capture the cleared content
let cleared_cell = Aim::clear_row(&handle, 2).unwrap();

// Check what was cleared
match cleared_cell {
    Cell::Empty => println!("Row was already empty"),
    cell => if let Some(identifier) = cell.identifier() {
    println!("Cleared rule: {}", identifier)
},
}

// Make changes visible
Aim::snapshot(&handle).unwrap();
Aim::release(&handle).unwrap();
§Clear vs Remove Semantics

clear_row() maintains the workflow structure by keeping the row position:

OperationRow CountIndex PreservationContent Recovery
ClearUnchanged✅ Preserved✅ Return value
RemoveDecremented❌ Shifts down✅ Return value

Use clear_row() when:

  • You want to temporarily disable a rule without affecting other row positions
  • You need to preserve the exact workflow structure for later operations
  • You want to capture the cleared rule for potential restoration

Use remove_row() when:

  • You want to permanently delete a rule and compact the workflow
  • Other rows should shift to fill the gap
  • You don’t need to preserve the exact row structure
§MVCC Considerations

The cleared row state is managed within the write context and becomes visible to concurrent readers only after calling Aim::snapshot() or Aim::release(). The cleared row will appear as Cell::Empty when retrieved using Aim::get_row().

§Performance Characteristics
  • Index Access: O(1) array-based operation for row access
  • Lookup Update: O(1) hash table removal for identifier lookup
  • Memory Impact: Minimal - the cleared row slot remains allocated
  • Thread Safety: Requires active write context and internal locking
§See Also
Source

pub fn remove_row(handle: &str, index: usize) -> Result<Cell>

§Removes a specific row from a workflow permanently and returns the removed content.
§title: Remove Row

This function permanently removes a row from a workflow at the specified zero-based index and returns the removed content as a cell.

§Arguments
  • handle - An active write context handle obtained from Aim::acquire. The workflow must be acquired for writing before calling this function.
  • index - Zero-based index specifying which row to remove. Must be within the bounds of the workflow.
§Returns

Returns a Cell containing the removed row’s data. The cell type depends on what was removed:

§Errors

This function does not return errors for invalid operations. Instead:

  • If the handle is invalid or refers to a released context, the function will panic
  • If the index is out of bounds, it returns Cell::Empty
§Behavior

Internally, remove_row() performs the following operations:

  1. Locates the instance using the provided handle
  2. Acquires a write lock on the workflow
  3. Calls target().remove_row(index) on the underlying workflow
  4. Converts the removed row to a Cell using Cell::convert_row()
  5. Returns the cell result

The underlying workflow method handles the actual removal and reindexing operations.

§Side Effects
  • Version Change: Flags the workflow for a version change since this is a structural modification
  • Row Removal: Removes the row entirely from the workflow, shrinking the row vector
  • Index Shifting: Subsequent rows are shifted to lower indices to fill the gap
  • Lookup Update: Rebuilds the internal identifier-to-index mapping via reindex()
  • Change Tracking: Marks the workflow as having pending changes
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Remove a row by index
let removed_cell: Cell = Aim::remove_row(&handle, 0).unwrap();

// Make changes visible
Aim::snapshot(&handle).unwrap();

// Release the handle
Aim::release(&handle).unwrap();
§See Also
  • clear_row - Clears row content without removing the row
  • insert_row - Inserts a new row at a specific index
  • get_row - Retrieves a row at a specific index
  • set_row - Sets/replaces a row at a specific index
  • reposition_row - Moves a row to a different position
  • delete_cell - Removes a rule by identifier instead of index
Source

pub fn has_cell(handle: &str, identifier: &str) -> Result<bool>

§Checks if a specific cell exists within a workflow using an active write context.
§title: Has Cell

Checks if a specific cell (rule) exists within a workflow using an active write context.

This function provides write-context-aware existence checking during workflow modifications, allowing you to conditionally add or update cells based on their current presence in the in-memory workflow state.

§Arguments
  • handle - A string handle representing an active write context acquired via Aim::acquire.
  • identifier - The unique identifier of the cell (rule) to check for existence.
§Returns

Returns a Result containing:

  • Ok(true) if the cell exists within the workflow under the active write context
  • Ok(false) if the cell does not exist in the workflow
  • Err if the handle is invalid or the workflow cannot be accessed
§Errors

Returns an error if:

  • The handle does not correspond to an active write context (instance not found)
  • The workflow context cannot be accessed due to internal errors
  • The underlying storage system encounters an error
§Behavior

Internally, has_cell() performs the following operations:

  1. Context Lookup: Uses Instance::locate() to find the active write context associated with the handle
  2. Lock Acquisition: Acquires a write lock on the workflow context to ensure thread-safe access
  3. Identifier Check: Calls the workflow’s contains() method to check if the identifier exists
  4. Result Return: Returns the boolean result wrapped in a Result type
§Context-Aware Semantics

Unlike Aim::contains, which provides a read-only MVCC view of the last committed state, has_cell() operates within a write context and reflects the current in-memory state:

§MVCC vs Context-Aware Differences
AspectAim::containshas_cell()
Context RequiredNoYes (via Aim::acquire
State ViewedLast committed (disk)Current in-memory modifications
ConcurrencyRead-only, safe for concurrent accessWrite context, exclusive access
Unsaved ChangesNot visibleVisible and included
§Use Cases

has_cell() is essential for:

  • Conditional Logic: Checking if a cell exists before adding or updating it
  • Workflow Validation: Ensuring required cells are present before proceeding
  • Modification Workflows: Building complex modification sequences that depend on cell existence
  • Error Prevention: Avoiding duplicate cell creation or updating non-existent cells
§Side Effects
  • None: This function only reads the current state and does not modify the workflow
  • Thread Safety: Acquires internal locks but releases them before returning
  • Performance: Efficient O(1) lookup using the workflow’s internal hash map
§Usage Pattern
use aimx::{Aim, Cell};
use std::sync::Arc;

// Acquire workflow context
let reference = aimx::Reference::parse("my_workflow").unwrap();
let handle = Aim::acquire(reference).unwrap();

// Check if cell exists before adding
if !Aim::has_cell(&handle, "important_metric").unwrap() {
    let cell = Cell::new("important_metric", "Number", "42", "");
    Aim::append_or_update_cell(&handle, cell).unwrap();
}

// Make changes visible
Aim::release(&handle).unwrap();
§Integration with Other Functions

has_cell() works closely with several other API functions:

§Performance Considerations
  • Efficient Lookup: Uses the underlying workflow’s hash map for O(1) identifier lookup
  • In-Memory Operation: No disk I/O required since the workflow is loaded in the context
  • Lock Overhead: Minimal lock acquisition time due to fine-grained locking
  • Context Bound: Performance depends on workflow size but is generally very fast
§See Also
Source

pub fn get_cell(handle: &str, identifier: &str) -> Result<Option<Cell>>

§Retrieves a specific cell (rule) from a workflow using an active write context by its identifier.
§title: Get Cell

This function retrieves a specific cell (rule) from a workflow using an active write context by its identifier. It returns Some(Cell) if the cell exists, or None if no cell with the given identifier is found.

Unlike Aim::cell() which reads from the globally visible MVCC state, get_cell() reads from the write context’s current state, which may include uncommitted changes that haven’t been made globally visible yet.

§Arguments
  • handle - A &str context handle obtained from Aim::acquire() that provides exclusive write access to the workflow
  • identifier - A &str unique identifier of the cell (rule) to retrieve within the workflow
§Returns

Returns a Result<Option<Cell>> containing:

  • Some(Cell) if a cell with the specified identifier exists in the workflow
  • None if no cell with the specified identifier exists
  • Err(anyhow::Error) if there’s an error locating the context or accessing the workflow
§Errors

Returns an error if:

  • The context handle is invalid or cannot be located in the workspace
  • There’s an issue accessing the workflow data structure
  • The workspace context is corrupted or unavailable
§Behavior

Internally, get_cell() performs the following operations:

  1. Locates the Instance using the provided handle via Instance::locate()
  2. Acquires a write lock on the instance to ensure thread-safe access
  3. Calls WorkflowLike::get_rule() to retrieve the rule by identifier
  4. Converts the rule to a Cell representation using Cell::convert_rule()
  5. Returns Some(Cell) if found, or None if the rule doesn’t exist
§Side Effects
  • None. This function only reads data and does not modify the workflow state
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Acquire workflow context for modification
let reference = Reference::parse("my_workflow").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Retrieve a cell by identifier
if let Some(cell) = Aim::get_cell(&handle, "my_cell").unwrap() {
    // Use the cell data
    if let Some(identifier) = cell.identifier() {
        println!("Cell identifier: {}", identifier);
    }
    if let Some(typedef) = cell.typedef() {
        println!("Cell type: {}", typedef);
    }
    if let Some(value) = cell.value() {
        println!("Cell value: {}", value);
    }
}

// Release the workflow context
Aim::release(&handle).unwrap();
§See Also
  • Aim::cell() - Retrieves a cell from the globally visible MVCC state
  • Aim::has_cell() - Checks if a cell exists without retrieving it
  • Aim::get_row() - Retrieves a cell by index position instead of identifier
  • Aim::acquire() - Acquires exclusive write access to a workflow
  • Aim::snapshot() - Makes changes visible globally
  • Cell - The cell data structure and its methods
§MVCC Considerations

This function operates on the write context’s current state, which includes:

  • All previously committed changes from snapshots
  • All uncommitted changes made in this write context
  • Changes are isolated from other concurrent write contexts until snapshot() is called

For reading from the globally visible state (after snapshots), use Aim::cell() instead.

§Performance Considerations
  • Time complexity: O(log n) for rule lookup in the workflow’s internal data structure
  • Memory overhead: Minimal - only the cell data is returned
  • Lock contention: Uses a write lock internally, but only for read access, so it doesn’t block other readers
  • For frequent identifier lookups, consider caching the result or using batch operations
Source

pub fn append_or_update_cell(handle: &str, cell: Cell) -> Result<()>

§Appends a new rule to or updates an existing rule within a workflow using an active write context.
§title: Append or Update Cell

This function appends a new cell (rule) to a workflow or updates an existing cell with the same identifier using an active write context.

§Arguments
  • handle - A string slice referencing an active workflow context handle obtained from Aim::acquire()
  • cell - A Cell containing the rule data to append or update
§Returns

Returns Ok(()) on success, or an error if the operation fails.

§Errors

Returns an error if:

  • The handle is not a valid active workflow context
  • The cell identifier is invalid (empty or contains reserved characters)
  • The workflow is not accessible for writing
§Behavior

Internally, append_or_update_cell() performs the following operations:

  1. Locates the instance context using the provided handle
  2. Converts the Cell to a Row using Row::convert()
  3. Calls the workflow’s append_or_update method on the target workflow:
    • If a rule with the same identifier already exists, it updates the existing rule
    • If no rule with that identifier exists, it appends the new rule to the end of the workflow
  4. Marks the workflow as having pending changes for eventual saving
§Side Effects
  • Creates or updates a rule in the specified workflow
  • Marks the workflow as having pending changes that will be saved on the next snapshot or release
  • If updating an existing rule, preserves the rule’s position in the workflow
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Create and append/update a cell
let cell = Cell::new("my_rule", "Number", "42", "");
Aim::append_or_update_cell(&handle, cell).unwrap();

// Make changes visible
Aim::snapshot(&handle).unwrap();

// Release the context
Aim::release(&handle).unwrap();
§See Also
Source

pub fn update_cell( handle: &str, identifier: Arc<str>, typedef: Arc<str>, formula: Arc<str>, value: Arc<str>, ) -> Result<()>

§Updates a specific cell (rule) within a workflow using an active write context.
§title: Update Cell

Updates an existing cell (rule) within a workflow using an active write context, replacing all aspects of the rule including identifier, type definition, formula, and value.

Unlike Aim::append_or_update_cell(), this function only updates existing cells and will fail if the cell does not exist.

§Arguments
  • handle - An active write context handle obtained from Aim::acquire(). This handle provides exclusive write access to the workflow.
  • identifier - The new identifier for the cell. This can be the same as the current identifier or a different one for renaming. Must be unique within the workflow.
  • typedef - The type definition for the cell (e.g., "Number", "Text", "Bool", "Node", "Format"). This determines how the cell’s value is interpreted and validated.
  • formula - The AIMX expression formula that computes the cell’s value. Can be empty "" for static cells or cells that derive their value from other sources.
  • value - The current value of the cell. For computed cells, this is typically empty "" and will be populated when the formula is evaluated.
§Returns

Returns Ok(()) on successful update, or an anyhow::Result error if the operation fails.

§Errors

Returns an error if:

  • The workflow handle is invalid or expired
  • The target cell does not exist in the workflow
  • The new identifier conflicts with an existing cell (when renaming)
  • The type definition is invalid or unsupported
  • The formula contains syntax errors (parsing failures)
  • Insufficient permissions or I/O errors occur during the update
§Behavior

The update_cell function performs a complete replacement of an existing cell’s properties:

  1. Validation: Validates that the target cell exists and the new identifier won’t cause conflicts
  2. Rule Construction: Creates a new Rule from the provided parameters, performing static evaluation of constant expressions
  3. Atomic Update: Replaces the entire rule atomically - either all changes succeed or none are applied
  4. Immediate Effect: Changes are visible immediately within the current write context
  5. MVCC Protection: Changes remain private to the write context until Aim::snapshot() is called
§Side Effects
  • Workflow Modification: Updates the specified rule in the workflow’s internal rule table
  • Change Tracking: Marks the workflow as changed for subsequent saving
  • MVCC State: Creates a private version of the workflow visible only to the current write context
  • Identifier Updates: If the identifier changes, updates internal lookup tables for efficient rule access
§Usage Pattern

Update an existing cell’s formula and type while optionally renaming it:

use aimx::{Aim, Reference, Cell};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("project.budget").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// First, check if the cell exists and get its current state
if Aim::has_cell(&handle, "total_cost").unwrap() {
    // Update the cell's formula and type
    Aim::update_cell(
        &handle,
        Arc::from("total_cost"),  // Keep same identifier
        Arc::from("Number"),      // Change to Number type
        Arc::from("materials + labor + overhead"), // New formula
        Arc::from("")             // Empty value (computed)
    ).unwrap();
    
    // Make changes visible to other contexts
    Aim::snapshot(&handle).unwrap();
} else {
    println!("Cell 'total_cost' does not exist");
}

// Clean up and persist changes
Aim::release(&handle).unwrap();

Rename a cell while updating its content:

use aimx::{Aim, Reference};
use std::sync::Arc;

let reference = Reference::parse("project.schedule").unwrap();
let handle = Aim::acquire(reference).unwrap();

// Rename 'old_deadline' to 'project_deadline' and update its value
Aim::update_cell(
    &handle,
    Arc::from("project_deadline"),  // New identifier
    Arc::from("Date"),              // Type
    Arc::from(""),                  // No formula (static value)
    Arc::from("\"2024-12-31\"")     // New value
).unwrap();

Aim::snapshot(&handle).unwrap();
Aim::release(&handle).unwrap();
§MVCC Considerations
  • Private Updates: Changes are only visible within the write context that made them
  • Reader Isolation: Other read contexts continue to see the previous version of the workflow
  • Snapshot Requirement: Call Aim::snapshot() to make changes globally visible to new readers
  • Conflict Prevention: Update operations are atomic and isolated within each write context
§Performance Considerations
  • Formula Parsing: Formulas are parsed immediately during the update operation
  • Static Evaluation: Constant expressions are evaluated at update time for performance
  • Validation: Type and syntax validation occurs synchronously during the update
  • Memory Usage: Only the modified cell is updated in memory; the entire workflow is not copied
  • Lookup Efficiency: Cell identifier changes update internal hash tables for O(1) access
§Common Use Cases
  1. Formula Correction: Fix syntax errors or logic issues in existing formulas
  2. Type Migration: Change data types as requirements evolve (e.g., Text to Number)
  3. Identifier Refactoring: Rename cells for better organization and clarity
  4. Value Updates: Update static values (though Aim::update_cell_value() is more efficient for this)
  5. Rule Enhancement: Add error handling, validation, or optimization to formulas
  6. Data Model Evolution: Modify the structure of workflow data as business rules change
§Error Handling

When update_cell fails, the error typically indicates one of these issues:

use aimx::{Aim, Reference};
use std::sync::Arc;

let reference = Reference::parse("project.data").unwrap();
let handle = Aim::acquire(reference).unwrap();

match Aim::update_cell(
    &handle,
    Arc::from("nonexistent_cell"),  // This will fail
    Arc::from("Number"),
    Arc::from("1 + 1"),
    Arc::from("")
) {
    Ok(()) => println!("Cell updated successfully"),
    Err(e) => {
        if e.to_string().contains("does not exist") {
            println!("Cell not found - use append_or_update_cell for new cells");
        } else {
            println!("Update failed: {}", e);
        }
    }
}

Aim::release(&handle).unwrap();
§Integration with Other APIs
§See Also
  • Cell - The API representation of a workflow cell
  • Rule - The internal representation of a workflow rule
  • Reference - Identifies a specific workflow in the workspace
  • Value - Runtime value representation with type information
  • crate::expressions::ExpressionLike - Parsed AIMX expression for formula evaluation
Source

pub fn update_cell_value( handle: &str, identifier: Arc<str>, value: Arc<str>, ) -> Result<()>

§Updates only the value of an existing cell within a workflow using an active write context.
§title: Update Cell Value

This function updates only the value of an existing cell (rule) within a workflow using an active write context. Unlike update_cell(), this function only modifies the cell’s value while preserving its type definition and formula.

§Arguments
  • handle - A &str representing the workflow instance handle obtained from Aim::acquire(). This provides exclusive write access to the workflow.
  • identifier - An Arc<str> containing the unique identifier of the cell to update. The cell must already exist in the workflow.
  • value - An Arc<str> containing the new value to set. This will be converted to an appropriate Value type internally.
§Returns

Returns a Result<()> indicating success or failure. The operation succeeds if the cell exists and the value is successfully updated.

§Errors

Returns an error if:

  • The workflow instance handle is invalid
  • The cell with the specified identifier does not exist in the workflow
  • The workflow cannot be accessed for writing (e.g., not properly acquired)
§Behavior

Internally, update_cell_value() performs the following operations:

  1. Locates the workflow instance using the provided handle
  2. Acquires a write lock on the workflow
  3. Finds the existing rule by its identifier
  4. Updates only the rule’s value field with the new value
  5. Marks the workflow as having partial changes for persistence

This function only updates the value portion of a cell, leaving the type definition and formula unchanged. If you need to modify the type or formula as well, use Aim::update_cell() instead.

§Side Effects
  • Updates the value of an existing rule in the workflow
  • Marks the workflow as having pending changes that need to be saved
  • Changes are only visible within the current write context until Aim::snapshot() or Aim::release() is called
§Usage Pattern
use aimx::{Aim, Cell, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("my_workflow").unwrap();
let handle = Aim::acquire(reference).unwrap();

// Update a cell's value
Aim::update_cell_value(&handle, Arc::from("my_cell"), Arc::from("new_value")).unwrap();

// Make changes visible
Aim::snapshot(&handle).unwrap();

// Release the workflow
Aim::release(&handle).unwrap();
§See Also
Source

pub fn delete_cell(handle: &str, identifier: Arc<str>) -> Result<Cell>

§Permanently removes a cell (rule) from a workflow by its identifier and returns the removed cell.
§title: Delete Cell

This function permanently removes a cell (rule) from a workflow by its identifier and returns the removed cell.

§Arguments
  • handle - A &str reference to an active write context handle obtained from Aim::acquire. The workflow must be acquired for writing before calling this function.
  • identifier - An Arc<str> containing the identifier of the rule to delete. Must exactly match an existing rule identifier in the workflow.
§Returns

Returns a Result<Cell> containing:

  • Success: Returns Ok(Cell) with the removed rule’s data
  • Non-existent Rule: Returns Ok(Cell::Empty) if the identifier does not exist (no error thrown)
  • Execution Error: Returns Err(anyhow::Error) if the handle is invalid or refers to a released context
§Errors

Returns an error if:

  • The handle is invalid or refers to a released context
  • The workflow cannot be modified
§Behavior

Internally, delete_cell() performs the following operations:

  1. Locates the instance using the provided handle
  2. Acquires a write lock on the workflow context
  3. Calls target().delete_rule(&identifier) on the underlying workflow
  4. Converts the deleted row to a Cell using Cell::convert_row()
  5. Returns the cell (or Cell::Empty if the rule didn’t exist)

The underlying delete_rule method:

  • Removes the rule from the workflow’s internal storage
  • Updates the identifier-to-index mapping by removing the entry
  • Sets the change status to Version to indicate structural changes
  • Leaves an empty row at the original position to maintain index stability
§Side Effects
  • Removes the rule from the workflow’s internal storage
  • Updates the identifier-to-index mapping by removing the entry for the deleted rule
  • Flags the workflow for a version change on next save
  • Maintains row structure by leaving an empty row at the deleted position
  • May affect subsequent rule lookups and index-based operations
§Usage Pattern
use aimx::{Aim, Cell};
use std::sync::Arc;

// Acquire workflow context
let reference = aimx::Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Delete a specific cell
let deleted_cell = Aim::delete_cell(&handle, Arc::from("target_rule")).unwrap();
if !deleted_cell.is_empty() {
    if let Some(identifier) = deleted_cell.identifier() {
        println!("Deleted cell: {}", identifier);
    }
 }

// Make changes visible
Aim::snapshot(&handle).unwrap();
Aim::release(&handle).unwrap();
§See Also
  • remove_row: Remove a row by index position
  • clear_row: Clear row content without deleting the rule
  • update_cell: Replace rule content
  • has_cell: Check if a rule exists before deletion
  • get_cell: Retrieve rule metadata before deletion
§MVCC Considerations

The deleted rule becomes invisible to concurrent readers immediately after Aim::snapshot is called, following the workspace’s MVCC model. Until then, the deletion is only visible within the current write context.

§Performance Considerations
  • Identifier lookups are O(1) due to internal hash map storage
  • Row structure is preserved to maintain index stability for existing operations
  • Change tracking automatically flags the workflow for version-based persistence
  • No file system operations are performed until the next save operation
Source

pub fn start( _source: Arc<Reference>, _target: Option<Arc<Reference>>, ) -> Result<Arc<str>>

§Starts a new workflow inference instance by creating a context instance that binds a source workflow template to an inference target.
§title: Start

This function initiates a new workflow inference instance by creating a context instance that binds a source workflow template to an inference target. It generates a unique handle identifier and sets up the necessary infrastructure for running agentic workflows with inference capabilities.

§Arguments
  • source - An Arc<Reference> pointing to the source workflow that serves as the template for inference. This workflow contains the rules and structure that will be executed during inference.
  • target - An optional Option<Arc<Reference>> pointing to the target workflow where inference results will be stored. If None, a new target workflow is automatically created.
§Returns

Returns a Result<Arc<str>> containing a unique handle identifier that can be used to:

  • Reference the inference instance in subsequent API calls
  • Access the inference context for evaluation
  • Monitor and control the inference workflow execution
§Errors

Returns an error if:

  • The source workflow cannot be located or accessed
  • The target workflow cannot be created or accessed (if specified)
  • There are insufficient permissions to create inference instances
  • The workspace is in an invalid state
§Behavior

Internally, start() performs the following operations:

  1. Generate identifiers: Creates a unique date-stamped identifier for tracking and a random handle identifier for API access
  2. Create inference node: Adds a new node to the inference workflow to track this inference instance
  3. Create context instance: Adds a new context instance to the context workflow that binds the source and target workflows
  4. Bind workflows: Establishes the relationship between the source template and target workflow for inference execution
  5. Return handle: Provides the unique handle for subsequent API interactions
§Side Effects
  • Creates or modifies the inference workflow to track the new inference instance
  • Creates or modifies the context workflow to establish the source-target binding
  • Allocates resources for the inference instance that must be cleaned up with Aim::cancel() or completion
  • May create a new target workflow if none is specified
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Parse the source workflow reference
let source_reference = Reference::parse("my_workflow").unwrap();

// Start a new inference instance
let handle = Aim::start(source_reference.clone(), None).unwrap();
println!("Started inference with handle: {}", handle);

/* Run inference steps using the handle */

// When done, cancel the inference to clean up resources
Aim::cancel(&handle).unwrap();
§See Also
§MVCC Considerations

The start() function operates on the inference and context workflows which are part of the workspace’s MVCC system. The created instances are visible to concurrent readers once committed, but the actual inference execution maintains isolation through the context system.

§Performance Considerations
  • Instance creation involves file I/O operations to update the inference and context workflows
  • Each active inference instance consumes memory for its context and maintains file locks
  • Consider cleaning up completed or cancelled instances to free resources
  • The function uses workspace-level locks during instance creation, which may block other operations
Source

pub fn next(_handle: &str) -> Result<()>

§Executes the next step in a workflow inference instance.
§title: Next

This function executes the next step in a workflow inference instance. It advances the workflow evaluation by one step, processing the current rule and potentially branching to the next rule based on the evaluation result. This enables step-by-step execution of agentic workflows for fine-grained control and debugging.

§Arguments
  • handle - A string slice referencing the workflow inference instance handle obtained from Aim::start(). This handle uniquely identifies the active inference session and provides access to the workflow context.
§Returns

Returns a Result<()> indicating the success or failure of the step execution:

  • Ok(()) - The step executed successfully, which may include:
    • Normal rule evaluation completion
    • Successful branching to another rule
    • Workflow completion
  • Err(anyhow::Error) - The step failed to execute due to:
    • Invalid or expired handle
    • Workflow evaluation errors
    • Resource constraints
    • State corruption
§Errors

Returns an error if:

  • The provided handle does not correspond to an active inference instance
  • The inference instance context cannot be accessed or loaded
  • The workflow evaluation encounters a critical error
  • The step exceeds the maximum evaluation limit (10,000 steps)
  • The workflow contains invalid rule references or syntax errors
§Behavior

Internally, next() performs the following operations:

  1. Instance Resolution: Locates the inference instance using the provided handle
  2. Context Loading: Acquires the evaluation context for the workflow
  3. Rule Evaluation: Executes the current rule in the workflow using the context
  4. Control Flow Processing: Handles branching logic from Value::Branch results
  5. State Advancement: Moves the evaluation pointer to the next rule or target
  6. Error Handling: Captures and reports any evaluation failures

The function implements a step-wise interpreter that:

  • Evaluates rules by row index in order
  • Respects control-flow constructs like Branch and Retry expressions
  • Prevents infinite loops with a maximum step limit
  • Maintains workflow state between calls
  • Supports resumption from suspended states
§Side Effects
  • Advances the internal evaluation state of the workflow instance
  • May modify rule values through Context::set_value()
  • Can trigger branching to different rule paths
  • May cause inference calls to nested workflows
  • Updates the workflow’s change tracking status
  • Persists changes to disk when evaluation completes or fails
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Start a new inference instance
let source_reference = Reference::parse("my_workflow").unwrap();
let handle = Aim::start(source_reference.clone(), None).unwrap();

// Execute workflow step by step
loop {
    match Aim::next(&handle) {
        Ok(()) => {
            // Check if workflow completed or continue
            // Additional logic here...
        }
        Err(e) => {
            println!("Workflow step failed: {}", e);
            break;
        }
    }
}

// Clean up when done
Aim::cancel(&handle).unwrap();
§See Also
§MVCC Considerations

The next() function operates on workflow instances that participate in the MVCC system:

  • Each step may create new version entries in the workflow journal
  • Concurrent readers see consistent snapshots of the workflow state
  • Write locks are acquired during inference calls to nested workflows
  • Changes become visible to other readers only after successful completion
  • Failed steps may leave the workflow in an inconsistent state requiring cleanup
§Performance Considerations
  • Each call involves context lookup and lock acquisition overhead
  • Complex rule expressions or inference calls may take significant time
  • Branching operations require additional rule lookups
  • Memory usage grows with workflow complexity and nesting depth
  • Consider using batch evaluation for simple workflows without branching
  • The 10,000 step limit prevents runaway evaluations but may impact very large workflows
§Error Recovery

When next() returns an error:

  1. The workflow instance remains in its current state
  2. Use Aim::results() to examine the current rule values
  3. Consider calling Aim::cancel() to clean up the instance
  4. Restart with a new instance if the workflow needs to be re-executed
  5. Check the error details to understand the root cause
§Workflow Control Flow

The function supports AIMX’s control flow constructs:

  • Branch expressions: (condition) -> target_rule - jumps to target on true
  • Retry expressions: count, condition -> target_rule - decrements counter and branches
  • Conditional evaluation: Rules are skipped when previous branches redirect flow
  • Error propagation: Critical errors halt evaluation and return failure status
Source

pub fn undo(_handle: &str) -> Result<()>

§Moves the workflow instance to the previous version in its journal history.
§title: Undo

Moves the workflow instance to the previous version in its journal history.

This function implements version rollback by navigating to the previous version stored in the workflow’s journal file. It allows reverting workflow changes by moving the active instance context to an earlier point in time.

§Arguments
  • handle - A string slice containing the unique instance handle obtained from Aim::acquire() that identifies the active workflow context to undo.
§Returns

Returns Result<()> which is:

  • Ok(()) if the undo operation completes successfully
  • Err(anyhow::Error) if any step fails
§Errors

Returns an error if:

  • The instance handle is invalid or cannot be located
  • The workflow has no previous versions in its journal (already at first version)
  • The previous version cannot be loaded (e.g., corrupted journal or missing data)
  • The workflow save operation fails after loading the previous version
  • The journal file is missing or cannot be parsed
  • The target version is not found in the journal
§Behavior

Internally, undo() performs the following operations:

  1. Instance Validation: Locates the instance context using the provided handle via Instance::locate()
  2. Write Lock Acquisition: Acquires a write lock on the instance context
  3. Journal Check: Verifies that a previous version exists in the workflow’s journal
  4. Version Navigation: Identifies the previous version number from the journal entries
  5. Previous Version Loading: Loads the identified previous version using the workflow’s load_version() method
  6. State Update: Updates the workflow instance to reflect the previous version’s state
  7. Persistence: Saves the instance state to make the rollback permanent
§Side Effects
  • Version Rollback: Changes the workflow’s active version to the previous one
  • Data Reversion: Restores all rules and values to their state in the previous version
  • Version Tracking: Updates the workflow’s version metadata to reflect the rollback
  • Journal Preservation: Maintains the journal history (does not delete versions)
  • Instance State: Updates the instance context to work with the rolled-back workflow
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Make some changes
// ... workflow modifications ...

// Save the changes
Aim::snapshot(&handle).unwrap();

// Make more changes
// ... additional modifications ...

// Save again
Aim::snapshot(&handle).unwrap();

// Undo to previous version
match Aim::undo(&handle) {
    Ok(()) => println!("Successfully rolled back to previous version"),
    Err(e) => println!("Failed to undo: {}", e),
}

// Release the workflow
Aim::release(&handle).unwrap();
§Version History Navigation

The undo() function enables time-travel through workflow versions:

Version Timeline:
[1] Initial version
[2] First modification  ← undo() from here
[3] Second modification ← current active version

After undo():
[1] Initial version
[2] First modification  ← current active version
[3] Second modification ← still exists in journal
§MVCC Considerations

The undo operation works within the Multi-Version Concurrency Control framework:

  • Isolation: Only affects the current write context, not other concurrent readers
  • Atomicity: Either completely rolls back to the previous version or fails entirely
  • Consistency: Maintains workflow integrity by loading complete previous states
  • Durability: Changes are persisted to disk after successful rollback
§Relationship to Other Version Functions
FunctionDirectionTargetPurpose
undo()BackwardPrevious versionRollback recent changes
redo()ForwardNext versionRe-apply undone changes
proceed()ForwardNext versionMove to newer version
snapshot()CurrentCurrent versionSave current state
§Error Recovery

If undo() fails, the workflow instance remains in its current state:

  • No partial rollbacks occur
  • The original version remains active
  • Subsequent operations can retry the undo or take alternative actions
  • Journal integrity is preserved regardless of operation success
§See Also
§Performance Considerations
  • I/O Operations: Requires reading the target version from disk
  • Memory Usage: Loads the entire previous version into memory
  • Lock Duration: Holds write locks during the entire operation
  • Journal Size: Performance may degrade with very large journal files
  • Version Distance: Time complexity is generally constant regardless of version distance
§Implementation Notes

The function is currently implemented as a TODO placeholder. When implemented, it should:

  1. Integrate with the existing journal system in crate::aim::journal
  2. Use the workflow’s load_version() method for version navigation
  3. Follow the same error handling patterns as other API functions
  4. Maintain consistency with the MVCC architecture
  5. Include comprehensive tests for edge cases and error conditions
Source

pub fn proceed(_handle: &str) -> Result<()>

§Makes a previous version (currently loaded by undo) the current workflow instance.
§title: Proceed

This function advances a workflow inference instance to the next version in its journal history, effectively moving forward through the workflow’s version timeline after a reverse operation like undo().

When called on an inference instance handle, proceed() locates the associated workflow, reads its journal to find the next available version, loads that version, and makes it the current active version for the inference instance. This function is typically used in conjunction with undo() to provide forward navigation through workflow state history.

§Arguments
  • handle - A string reference to the workflow inference instance handle obtained from Aim::start() or other inference management functions. The handle uniquely identifies the active inference instance within the workspace context.
§Returns

Returns a Result<()> containing:

  • Ok(()) if the workflow was successfully advanced to the next version
  • Err(anyhow::Error) if the operation failed due to invalid handle, missing journal entries, or file system errors
§Errors

Returns an error if:

  • The provided handle does not correspond to an active inference instance
  • The workflow associated with the handle has no journal entries
  • The workflow is already at the latest version (no forward versions available)
  • The journal file cannot be read or parsed
  • The target version cannot be loaded from the workflow file
  • File system access is denied or the workflow file is corrupted
§Behavior

Internally, proceed() performs the following operations:

  1. Instance Resolution: Locates the inference instance using the provided handle
  2. Workflow Access: Acquires read access to the workflow associated with the instance
  3. Journal Analysis: Reads the workflow’s journal file to determine available versions
  4. Version Validation: Checks if there is a next version available to proceed to
  5. Version Loading: Loads the target version from the workflow file
  6. State Update: Updates the workflow instance to use the new version as current
  7. MVCC Coordination: Ensures the version change is properly coordinated with the MVCC system
§Side Effects
  • Updates the current version of the specified workflow inference instance
  • May load different rule sets and workflow state from the target version
  • Changes the evaluation context for subsequent Aim::next() calls on the same instance
  • Maintains audit trail through the journal system for version transitions
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Start a workflow inference instance
let source: Arc<Reference> = Arc::from(Reference::parse("my_workflow").unwrap());
let handle = Aim::start(source, None).unwrap();

// Perform some inference steps
Aim::next(&handle).unwrap();

// Undo to a previous version
Aim::undo(&handle).unwrap();

// Proceed forward to the next version (undo the undo)
Aim::proceed(&handle).unwrap();

// Continue with inference
Aim::next(&handle).unwrap();

// Clean up
Aim::cancel(&handle).unwrap();
§See Also
  • Aim::start() - Creates new workflow inference instances
  • Aim::next() - Executes the next step in workflow inference
  • Aim::undo() - Moves workflow to previous version in journal
  • Aim::redo() - Alternative name for proceeding forward in version history
  • Aim::cancel() - Terminates and removes workflow inference instances
  • Instance - Internal type managing workflow inference state
  • WorkflowLike - Trait providing version and journal access
  • crate::aim::Journal - Version history management system
§MVCC Considerations

The proceed() function operates within the MVCC (Multi-Version Concurrency Control) framework:

  • Version transitions are atomic operations that maintain consistency
  • Multiple inference instances can exist simultaneously with different versions
  • The journal provides immutable version history for rollback/forward operations
  • Workflow locks are acquired during version transitions to prevent conflicts
§Performance Considerations
  • Journal reading is cached and efficient for subsequent operations
  • Version loading involves parsing workflow content, which has O(n) complexity where n is the number of rules
  • Frequent version switching may impact performance; consider caching frequently accessed versions
  • Large workflow files with extensive journal history may require more memory for version management
Source

pub fn redo(_handle: &str) -> Result<()>

§Re-applies changes that were previously undone using Aim::undo(), effectively moving forward through the workflow’s version history to restore previously rolled-back changes.
§title: Redo

Re-applies changes that were previously undone using Aim::undo(), effectively moving forward through the workflow’s version history to restore previously rolled-back changes.

This function implements forward navigation in the workflow version timeline, allowing users to re-apply changes that were undone. It is particularly useful when an undo operation was performed in error or when exploring different versions of a workflow during development.

§Arguments
  • handle - A string slice containing the unique instance handle obtained from Aim::acquire() that identifies the active workflow context to redo.
§Returns

Returns Result<()> which is:

  • Ok(()) if the redo operation completes successfully
  • Err(anyhow::Error) if any step fails
§Errors

Returns an error if:

  • The instance handle is invalid or cannot be located
  • No previous undo operation has been performed (no changes to redo)
  • The next version in the redo sequence cannot be loaded (e.g., corrupted journal or missing data)
  • The workflow save operation fails after loading the target version
  • The journal file is missing or cannot be parsed
  • The target version is not found in the journal
  • The workflow has reached the latest version (no forward versions available for redo)
§Behavior

Internally, redo() performs the following operations:

  1. Instance Validation: Locates the instance context using the provided handle via Instance::locate()
  2. Write Lock Acquisition: Acquires a write lock on the instance context
  3. Undo History Check: Verifies that a previous undo operation has been performed and identifies the target version to redo
  4. Version Validation: Ensures the target version exists and is accessible
  5. Version Loading: Loads the identified version using the workflow’s load_version() method
  6. State Restoration: Updates the workflow instance to reflect the target version’s state
  7. Persistence: Saves the instance state to make the redo permanent
  8. Undo History Update: Advances the undo/redo position pointer for future operations
§Side Effects
  • Change Restoration: Re-applies workflow changes that were previously undone
  • Version Navigation: Moves the workflow’s active version forward in the version timeline
  • State Update: Restores all rules and values to their state in the target version
  • Version Tracking: Updates the workflow’s version metadata to reflect the redo operation
  • Undo History Management: Advances the position in the undo/redo history chain
  • Instance State: Updates the instance context to work with the restored workflow
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Acquire workflow context
let reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::acquire(reference.clone()).unwrap();

// Make some changes and save
// ... workflow modifications ...
Aim::snapshot(&handle).unwrap();

// Undo the changes
match Aim::undo(&handle) {
    Ok(()) => println!("Successfully undid changes"),
    Err(e) => println!("Failed to undo: {}", e),
}

// Redo to restore the changes
match Aim::redo(&handle) {
    Ok(()) => println!("Successfully redid changes"),
    Err(e) => println!("Failed to redo: {}", e),
}

// Release the workflow
Aim::release(&handle).unwrap();
§Version History Navigation

The redo() function enables forward navigation through workflow versions:

Version Timeline:
[1] Initial version
[2] First modification  ← undo() was performed from here to version 1
[3] Second modification ← current active version after redo()

After undo():
[1] Initial version      ← active version
[2] First modification  
[3] Second modification  

After redo():
[1] Initial version
[2] First modification  ← restored to this version
[3] Second modification 
§Relationship to Other Version Functions
FunctionDirectionTargetPurpose
undo()BackwardPrevious versionRollback recent changes
redo()ForwardNext undone versionRe-apply previously undone changes
proceed()ForwardNext versionMove to newer version regardless of undo state
snapshot()CurrentCurrent versionSave current state to create a new version

Key differences:

  • redo() specifically re-applies changes that were undone via undo()
  • proceed() moves forward to any next version, regardless of undo history
  • redo() maintains undo/redo history state, while proceed() does not
§MVCC Considerations

The redo operation works within the Multi-Version Concurrency Control framework:

  • Isolation: Only affects the current write context, not other concurrent readers
  • Atomicity: Either completely restores the target version or fails entirely
  • Consistency: Maintains workflow integrity by loading complete target states
  • Durability: Changes are persisted to disk after successful restoration
  • Undo/Redo Chain: Maintains the undo/redo history for potential future operations
§Error Recovery

If redo() fails, the workflow instance remains in its current state:

  • No partial restorations occur
  • The original version remains active
  • Subsequent operations can retry the redo or take alternative actions
  • Undo/redo history is preserved regardless of operation success
  • The workflow can still use other version navigation functions
§See Also
§Performance Considerations
  • I/O Operations: Requires reading the target version from disk
  • Memory Usage: Loads the entire target version into memory
  • Lock Duration: Holds write locks during the entire operation
  • Journal Size: Performance may degrade with very large journal files
  • Undo History: Maintains additional metadata for undo/redo chain management
  • Version Distance: Time complexity is generally constant regardless of version distance
§Implementation Notes

The function is currently implemented as a TODO placeholder. When implemented, it should:

  1. Integrate with the existing journal system in crate::aim::journal
  2. Track undo/redo position state to determine the correct target version
  3. Use the workflow’s load_version() method for version navigation
  4. Follow the same error handling patterns as other API functions
  5. Maintain consistency with the MVCC architecture
  6. Include comprehensive tests for edge cases and error conditions
  7. Ensure undo/redo operations are inverses of each other
  8. Handle cases where versions have been pruned or journal entries are missing
§Typical Workflow Patterns
use aimx::{Aim, Reference};
use std::sync::Arc;

let reference = Reference::parse("my_workflow").unwrap();
let handle = Aim::acquire(reference).unwrap();

// Pattern 1: Save, undo, then redo
Aim::snapshot(&handle).unwrap();
Aim::undo(&handle).unwrap();
Aim::redo(&handle).unwrap();

// Pattern 2: Multiple undo/redo cycles
Aim::snapshot(&handle).unwrap();
Aim::snapshot(&handle).unwrap();
Aim::undo(&handle).unwrap();  // Back to snapshot 1
Aim::undo(&handle).unwrap();  // Back to initial version
Aim::redo(&handle).unwrap();  // Forward to snapshot 1
Aim::redo(&handle).unwrap();  // Forward to snapshot 2

// Pattern 3: Error handling
match Aim::redo(&handle) {
    Ok(()) => println!("Redo successful"),
    Err(e) => {
        println!("Redo failed: {}", e);
        // Handle the error appropriately
    }
}

Aim::release(&handle).unwrap();
Source

pub fn cancel(_handle: &str) -> Result<()>

§Terminates and cleans up a workflow inference instance, removing all associated resources without saving changes.
§title: Cancel

This function terminates and cleans up a workflow inference instance, removing all associated resources and releasing any locks. Unlike Aim::release() which saves changes before cleanup, cancel() discards any unsaved changes and performs a clean termination of the inference session.

§Arguments
  • handle - A string slice containing the unique instance handle obtained from Aim::start() that identifies the active workflow inference instance to cancel.
§Returns

Returns Result<()> which is:

  • Ok(()) if the cancellation operation completes successfully
  • Err(anyhow::Error) if any step fails
§Errors

Returns an error if:

  • The instance handle is invalid or cannot be located
  • The instance cannot be locked for writing (e.g., concurrent access)
  • The context workflow cannot be located or accessed
  • The context workflow operations fail (e.g., save errors)
  • The instance entry cannot be found in the context workflow
§Behavior

Internally, cancel() performs a clean termination operation that removes the inference instance without preserving any changes:

Phase 1: Instance Cleanup

  1. Locates the instance context using the provided handle via Instance::locate()
  2. Acquires a write lock on the instance context
  3. Discards any unsaved changes - unlike release(), no save operation is performed
  4. Releases the instance write lock

Phase 2: Context Cleanup

  1. Locates the global context workflow using Reference::context()
  2. Acquires a write lock on the context workflow via LockManager
  3. Searches for the instance handle in the context workflow using the workflow’s get_index method
  4. Removes the instance row from the context workflow via the workflow’s remove_row method
  5. Saves the updated context workflow via the workflow’s save method
  6. Updates the context node with the modified workflow
  7. Releases the context workflow write lock
§Side Effects
  • No Persistence: Does not save any unsaved changes to the target workflow
  • Context Cleanup: Removes the instance entry from the global context workflow
  • Lock Release: Releases write locks on both the instance and context workflow
  • Resource Cleanup: Makes the workflow available for future access
  • Instance Termination: Permanently terminates the inference session
§Usage Pattern
use aimx::{Aim, Reference};
use std::sync::Arc;

// Start a workflow inference
let source_reference = Reference::parse("foo.bar").unwrap();
let handle = Aim::start(source_reference.clone(), None).unwrap();

// Run some inference steps
// ... inference operations ...

// Cancel the inference if needed (e.g., on error or user request)
Aim::cancel(&handle).unwrap();
§Error Handling

The function uses a strict error handling approach:

  • If the instance cannot be located, the function returns an error
  • If the context cleanup fails, the function returns an error indicating that the instance may still be locked and require manual cleanup
  • If the instance is not found in the context workflow, returns a specific error message indicating a missing instance
§When to Use cancel() vs release()
FunctionUse CasePersistenceResource Cleanup
cancel()Error conditions, user abort, cleanup without savingNo - discards changesYes - removes instance
release()Normal completion of modificationsYes - saves all changesYes - removes instance
§Workflow Inference Lifecycle

The cancel() function is part of the workflow inference lifecycle:

  1. Start: Aim::start() creates a new inference instance
  2. Execute: Aim::next() runs inference steps
  3. Cancel: Aim::cancel() terminates without saving (this function)
  4. Release: Aim::release() terminates with saving (for modifications)
§Error Recovery

When using cancel() for error recovery:

  1. Call cancel() to clean up the failed inference instance
  2. The original workflow state is preserved (no changes from the failed inference)
  3. Start a new inference instance if needed
  4. Consider using Aim::results() to examine the current workflow state
§MVCC Considerations

The cancellation operation affects Multi-Version Concurrency Control:

  • No new version is created for the target workflow (changes are discarded)
  • The source workflow remains unchanged and available for concurrent readers
  • The context workflow is updated to remove the instance, making it available for new instances
  • Released locks allow other processes to access the workflow immediately
§See Also
  • Aim::start() - Initialize a new workflow inference instance
  • Aim::next() - Execute the next step in workflow inference
  • Aim::release() - Release and save changes from a workflow modification session
  • Aim::acquire() - Acquire exclusive write access for direct modifications
  • Instance::locate() - Locate an instance by handle
  • Workflow inference error handling best practices
Source

pub fn results(locator: Arc<Reference>) -> Result<Vec<Cell>>

§Retrieves all inference results from a workflow as result cells optimized for output display.
§title: Results

Retrieves all inference results from a workflow as result cells optimized for output display.

This function provides access to the evaluated results of a workflow, converting each row into a Cell::Result representation that shows the final computed values rather than the source formulas. It’s designed for reading workflow output after inference execution.

§Arguments
  • locator - An Arc<Reference> that identifies the workflow to retrieve results from
§Returns

Returns a Result<Vec<Cell>> containing:

§Errors

Returns an error if:

  • The locator references a non-existent workflow node
  • The workflow file cannot be read or parsed
  • The workspace is in an invalid state
§Behavior

Internally, results() performs the following operations:

  1. Node Location: Uses Workspace::locate_node() to find the workflow node
  2. Workflow Access: Retrieves the workflow from the located node
  3. Row Iteration: Iterates through all rows in the workflow using workflow.iter_rows()
  4. Result Conversion: Converts each row to a result cell using Cell::convert_result()
  5. Collection: Returns all converted cells as a vector
§Key Differences from list()
Featurelist()results()
PurposeSource template viewing/editingInference output display
Cell TypeFormula cells with sourceResult cells with values
Error DisplayShows formula errorsShows evaluation errors
Value ContentMay show computed valuesAlways shows final values
§Usage Pattern
use aimx::{Aim, Reference, Cell};
use std::sync::Arc;

// Create or acquire a workflow reference
let locator = Reference::parse("my_workflow").unwrap();

// Retrieve results (typically after inference execution)
let results = Aim::results(locator).unwrap();

// Process results
for cell in results {
    match cell {
        Cell::Result { identifier, typedef, value } => {
            println!("{}: {} = {}", identifier, typedef, value);
        },
        Cell::Errata { identifier, reason, .. } => {
            println!("Error in {}: {}", identifier, reason);
        },
        Cell::Comment { comment } => {
            println!("Comment: {}", comment);
        },
        _ => {
            // Handle other cell types (Node, Format, Branch, Retry, Formula, Empty)
        }
    }
}
§Integration with Inference Workflow

This function is typically used in the following inference scenarios:

  1. After inference execution: Retrieve results from completed inference steps
  2. Batch processing: Get all results from a workflow that has been fully evaluated
  3. Result monitoring: Monitor inference progress by checking result values
  4. Error tracking: Identify which rules produced errors during inference
§Example: Basic Results Retrieval
use aimx::{Aim, Reference, Cell};
use std::sync::Arc;

// Create or acquire a workflow reference
let locator = Reference::parse("my_workflow").unwrap();

// Retrieve results (after inference has been executed)
let results = Aim::results(locator).unwrap();

// Process and display results
for cell in results {
    match cell {
        Cell::Result { identifier, typedef, value } => {
            println!("Result: {} ({}): {}", identifier, typedef, value);
        },
        Cell::Errata { identifier, reason, .. } => {
            println!("Error in {}: {}", identifier, reason);
        },
        Cell::Comment { comment } => {
            println!("Comment: {}", comment);
        },
        _ => {
            // Handle other cell types (Node, Format, Branch, Retry, Formula, Empty)
        }
    }
}
§Performance Considerations
  • Memory Usage: Loads entire workflow into memory for row iteration
  • Conversion Overhead: Each row undergoes result conversion which may involve value formatting
  • Error Processing: Error state checking adds minimal overhead per row
  • Best Practice: Use for result retrieval rather than frequent polling during inference
§Error Handling Strategy

The function follows AIMX’s error propagation model:

  • Node location errors are propagated as workspace errors
  • Workflow parsing errors are returned as IO errors
  • Individual rule errors are captured in Cell::Errata results
  • This allows comprehensive error tracking from source to final results
§See Also

Aim::list() - Retrieves source template cells for editing
Aim::start() - Starts a new inference instance
Aim::next() - Executes next inference step
Cell::convert_result() - Converts rows to result cells
Reference - Workflow locator reference type
Workspace::locate_node() - Node location function

Source

pub fn check_identifier(input: &str) -> Result<()>

Source

pub fn function_categories() -> Result<Vec<Arc<str>>>

Get all available function categories.

Returns a list of all function categories in the standard library. Categories include: text, math, business, date, collection, statistical, functional, set, task, and utility.

Source

pub fn function_list(category: &str) -> Result<Vec<Arc<str>>>

Get all functions in a specific category.

Returns a list of function identifiers for the specified category. Returns an empty list if the category doesn’t exist.

Source

pub fn function_card(identifier: &str) -> Result<FunctionCard>

Get complete documentation for a specific function.

Returns a FunctionCard containing the function’s signature, description, examples, and other documentation. Returns an error if the function is not found.

Search functions by partial name or description.

Performs a case-insensitive search across function identifiers, brief descriptions, and detailed descriptions. Returns matching functions sorted by relevance.

Source

pub fn function_signatures( identifier_list: Vec<Arc<str>>, ) -> Result<Vec<Arc<str>>>

Get signatures for multiple function identifiers.

Returns the function signatures for the provided list of identifiers. Only functions that exist in the registry are included in the result.

Auto Trait Implementations§

§

impl Freeze for Aim

§

impl RefUnwindSafe for Aim

§

impl Send for Aim

§

impl Sync for Aim

§

impl Unpin for Aim

§

impl UnwindSafe for Aim

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,