# How the TinyFlows Workflow Engine Drives OpenHuman's Visual Automation Canvas

> Discover how the TinyFlows workflow engine powers OpenHuman's visual automation canvas by compiling nodes and orchestrating execution with LLM and memory subsystems.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: internals
- Published: 2026-08-28

---

**The TinyFlows workflow engine executes user-drawn automation graphs by compiling visual canvas nodes into a runtime representation and orchestrating execution through capability adapters that bridge the engine to OpenHuman's LLM, memory, and telemetry subsystems.**

OpenHuman's visual automation canvas provides a node-based interface for constructing complex workflows. At the runtime layer, the **TinyFlows** engine serves as the execution core that interprets these persisted graphs, orchestrating every step from initial compilation through final state persistence.

## Architecture Overview: Three Integration Layers

The integration between the visual canvas and the execution engine operates through three distinct architectural layers, each defined by specific responsibilities in the OpenHuman source code.

### Canvas to Graph Translation

When users draw workflows in the visual interface, the frontend serializes node positions, edge connections, and configuration data into a JSON representation. This data maps directly to the `tinyflows::model::WorkflowGraph` struct. In [`src/openhuman/flows/types.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/types.rs), OpenHuman defines wrapper types that extend the core TinyFlows graph with application-specific metadata such as workflow names, descriptions, and timestamps. The RPC controllers exposed in [`src/openhuman/flows/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/bus.rs)—including `openhuman.flows_import`, `openhuman.flows_run`, and `openhuman.flows_resume`—handle the transfer of these graph definitions between the UI and the backend storage layer.

### Engine Invocation and Compilation

The runtime entry point resides in [`src/openhuman/flows/tinyflows/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/mod.rs). When a run request arrives, the controller retrieves the stored graph and invokes `tinyflows::compiler::compile` to validate the node graph and produce a compiled runtime representation. The engine then executes via `tinyflows::engine::run(&compiled, seed, caps)`, where `seed` represents the initial input data and `caps` represents the capability adapters that provide external system access.

### Capability Adapter Pattern

TinyFlows expects a standard set of capabilities (LLM, HTTP, Memory, State, Tier, and ToolInvoker) that the host application must implement. OpenHuman supplies these adapters in the `src/openhuman/flows/tinyflows/caps/` package:

- **[`src/openhuman/flows/tinyflows/caps/state.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/caps/state.rs)** implements the `StateStore` capability, persisting step-wise execution state across asynchronous operations.
- **[`src/openhuman/flows/tinyflows/caps/memory_adapter.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/caps/memory_adapter.rs)** wires the TinyFlows `MemoryProvider` interface to OpenHuman's memory subsystem, enabling vector search and context retrieval within workflow nodes.
- **[`src/openhuman/flows/tinyflows/caps/llm.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/caps/llm.rs)** provides the LLM capability that forwards generation requests to OpenHuman's model provider infrastructure.

## Execution Pipeline Step-by-Step

The complete execution flow follows six distinct phases that transform a visual design into operational automation.

1. **Graph Construction**: Users build workflows in the canvas, which serializes the graph to JSON and transmits it via the `openhuman.flows_import` RPC endpoint.

2. **Persistence**: The controller in [`src/openhuman/flows/store.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/store.rs) persists the **WorkflowGraph** alongside metadata, enabling versioned workflow storage and retrieval.

3. **Run Initialization**: The UI issues `openhuman.flows_run` (or `flows_resume` for interrupted flows). The backend resolves the stored graph, compiles it using `tinyflows::compiler::compile`, and constructs a `Caps` struct bundling all capability adapters.

4. **Engine Execution**: `tinyflows::engine::run` traverses the compiled graph, invoking the appropriate capability for each node type—whether LLM inference calls, HTTP requests, memory reads, or custom tool invocations.

5. **Observability Streaming**: After each node execution, TinyFlows emits events to the **RunObserver** implementation defined in [`src/openhuman/flows/tinyflows/observability.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/observability.rs). This handler forwards step status, timestamps, and optional trace data to Langfuse or other telemetry backends.

6. **Result Delivery**: The final output or partial execution state returns via RPC to the UI, where the canvas updates node visualizations to reflect completion status, errors, or intermediate results.

## Implementation Examples

The following code demonstrates how OpenHuman invokes the TinyFlows engine from Rust and how the frontend initiates execution via RPC.

### Running a Flow from the Backend

This Rust example from [`src/openhuman/flows/tinyflows/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/mod.rs) demonstrates graph compilation and engine invocation:

```rust
use tinyflows::engine::{self, GraphObservation};
use tinyflows::compiler;
use tinyflows::model::WorkflowGraph;
use openhuman::flows::tinyflows::caps::{self, Capabilities};

// Retrieve stored graph JSON
let graph: WorkflowGraph = serde_json::from_str(&graph_json)?;

// Compile validates node connections and produces optimized runtime graph
let compiled = compiler::compile(&graph).expect("invalid workflow");

// Initialize capabilities bridging to OpenHuman subsystems
let caps = caps::Capabilities::new(/* LLM, HTTP, Memory, State, etc. */);

// Execute with seed input
let outcome = engine::run(&compiled, json!({ "seed": 1 }), &caps);
match outcome {
    Ok(run) => println!("Flow succeeded: {:?}", run.state()),
    Err(e) => eprintln!("Execution failed: {}", e),
}

```

### Initiating Execution from the Frontend

The React frontend communicates with the engine through the RPC bridge defined in [`src/openhuman/flows/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/bus.rs):

```typescript
import { coreRpcClient } from '@/services/coreRpcClient';

// Trigger workflow execution
await coreRpcClient.call('openhuman.flows_run', {
  workflow_id: 'abc123',
  input: { seed: 1, query: "analyze sentiment" },
});

// Subscribe to real-time execution events
coreRpcClient.on('flows.run', (event) => {
  updateCanvasNode(event.node_id, event.status, event.output);
});

```

## Summary

- The **TinyFlows workflow engine** serves as the runtime interpreter for OpenHuman's visual automation canvas, executing compiled graphs through capability adapters.
- **WorkflowGraph** definitions transit from UI to storage via RPC endpoints in [`src/openhuman/flows/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/bus.rs), with persistence handled by [`src/openhuman/flows/store.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/store.rs).
- The engine requires six capability implementations—LLM, HTTP, Memory, State, Tier, and ToolInvoker—provided in `src/openhuman/flows/tinyflows/caps/` to interface with OpenHuman infrastructure.
- **RunObserver** events in [`src/openhuman/flows/tinyflows/observability.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/observability.rs) enable real-time telemetry streaming to external monitoring systems.
- Execution flows through compilation (`tinyflows::compiler::compile`), runtime invocation (`tinyflows::engine::run`), and RPC result delivery back to the visual canvas.

## Frequently Asked Questions

### What is the TinyFlows workflow engine?

TinyFlows is a Rust-based workflow execution engine that interprets node-based automation graphs. It operates independently of the visual interface, expecting only a compiled graph and a set of capability adapters to execute business logic, making it suitable for embedding in applications like OpenHuman that require robust, observable automation backends.

### How does OpenHuman persist workflow graphs created in the visual canvas?

OpenHuman persists workflows through the `openhuman.flows_import` RPC endpoint, which stores the graph definition in [`src/openhuman/flows/store.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/store.rs). The storage layer maintains the JSON representation of the `tinyflows::model::WorkflowGraph` alongside metadata such as creation timestamps and workflow descriptions, enabling versioned retrieval when runs are initiated.

### What capabilities must the host application provide to TinyFlows?

TinyFlows requires six capability interfaces: **StateStore** for persistence across steps, **MemoryProvider** for context retrieval, **LLM** for model inference, **HTTP** for external requests, **Tier** for execution environment management, and **ToolInvoker** for custom tool execution. OpenHuman implements these in the `src/openhuman/flows/tinyflows/caps/` directory, bridging the engine to the host's existing subsystems.

### How is execution telemetry handled during workflow runs?

During execution, TinyFlows emits step-level events to the **RunObserver** trait implemented in [`src/openhuman/flows/tinyflows/observability.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/observability.rs). This implementation captures node execution status, timing data, and outputs, forwarding the telemetry to Langfuse or other observability platforms, providing full traceability of automation execution from the visual canvas through to completion.