Omni

Deep Dive

Architecture

How Omni is built — the crate structure, data flow, and key design decisions.

Crate Map

Omni is a Rust workspace split into focused crates. Each crate has a single responsibility and clearly defined boundaries.

01
omni-coreFoundation

Configuration parsing, database (SQLite + SQLCipher encryption), event bus, logging, and shared types. Every other crate depends on this.

02
omni-permissionsPermission Gating

Capability-based permission system with 20 capability types. PolicyEngine for decision caching, AuditLogger for trail recording, and scope validation.

03
omni-guardianSecurity Scanning

4-layer anti-injection pipeline — signature scanning, heuristic analysis, ML classification, and output policy validation. Scans at 5 points in the agent loop.

04
omni-extensionsExtension Framework

Extension host, WASM sandbox (Wasmtime), manifest parsing, extension discovery and installation, host functions (FFI bridge), and storage.

05
omni-sdkDeveloper SDK

Published crate for extension developers. Typed clients for HTTP, filesystem, process, storage, LLM, channels, and config. The omni_main! macro and prelude.

06
omni-llmLLM Bridge

Provider abstraction layer with 6 adapters. SSE streaming, token counting, provider rotation with exponential backoff. Also contains the agent loop, native tools, and hook system.

07
omni-channelsChannel Plugins

21 messaging platform adapters, channel manager, multi-instance support, binding registry, message router, and webhook server.

08
ui/src-tauriDesktop Application

Tauri v2 shell that wires everything together. 26+ IPC commands, event bridging, and application state management. Excluded from the Cargo workspace.

Agent Loop

The agent loop is the core orchestration engine. It manages multi-turn conversations between the user, the LLM, and tools. Each iteration can invoke one or more tools, then feed the results back to the LLM.

Loop Steps (per turn)

01

Receive user message → Guardian SP-1 scan → MessageReceived hook

02

Assemble full prompt (system + history + message) → Guardian SP-2 scan → LlmInput hook

03

Stream response from LLM provider → Guardian SP-3 scan → LlmOutput hook

04

Parse tool calls from response → Guardian SP-4 scan → BeforeToolCall hook

05

Execute tools (native or extension) → Permission check → AfterToolCall hook → Guardian SP-5 scan

06

If tools were called, append results and go to step 2 (up to max_iterations)

07

Return final text response to user

Tool Resolution

When the LLM requests a tool call, Omni resolves the tool name in this order:

1. Native Tools

29 built-in tools (exec, read_file, web_fetch, git, debugger, etc.). Checked first.

2. Flowchart Tools

Tools from enabled flowcharts. Visual no-code workflows with 19 node types.

3. Extension Tools

Tools from activated extensions. Resolved by reverse-domain ID (e.g., com.example.weather.get_forecast).

Event Bus

The event bus is a broadcast channel that distributes system events to all subscribers. It uses tokio::sync::broadcast for lock-free, multi-consumer event delivery.

Event Types

Event
Description
MessageReceived
A new message was received from a user or channel.
PermissionPrompt
An extension is requesting a permission that needs user approval.
GuardianAlert
The Guardian detected a potential threat.
ExtensionActivated
An extension sandbox was started.
ExtensionDeactivated
An extension sandbox was stopped.
ChannelInstanceCreated
A new channel instance was registered.
ChannelInstanceRemoved
A channel instance was removed.
ChannelBindingAdded
A new channel binding was created.
ChannelBindingRemoved
A channel binding was deleted.

In the Tauri desktop app, events are bridged to the frontend via Tauri's event system, allowing React components to react to backend state changes in real time.

Database

Omni uses SQLite with SQLCipher encryption for all persistent storage. The database is accessed through Arc<Mutex<Database>> with Tokio's spawn_blocking to avoid blocking the async runtime.

Encryption Key Resolution

01

OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)

02

OMNI_DB_KEY environment variable

03

Key file at ~/.data/Omni/db.key

04

Auto-generate and store a new key

Tables

Table
Purpose
sessions
Chat sessions with metadata and timestamps.
messages
All messages (user, assistant, tool) with role, content, and tool call data.
permissions
Persisted permission decisions (Allow/Deny) with duration and use counts.
audit_logs
Complete audit trail of all permission requests and decisions.
extensions
Installed extensions with version, author, and enabled state.
extension_storage
Key-value storage scoped per extension.
channel_instances
Configured channel instances with type, display name, and auto-connect.
channel_bindings
Message routing rules mapping channels to extensions.

Data Flow

A simplified view of how data flows through the system when a user sends a message.

data flow

User Input

Tauri IPC (send_message command)

Guardian Scan (SP-1: user input)

Hook: MessageReceived

Agent Loop

LLM Bridge → Provider Adapter → SSE Stream

Guardian Scan (SP-3: LLM output)

Tool Call? → Permission Check → Native/Extension Tool

Guardian Scan (SP-5: tool output)

Response → Tauri Event (omni:llm-chunk) → React UI

Extension Lifecycle

An extension goes through several states from installation to active use.

01
InstallThe .omni package is extracted, its manifest validated (ID format, version, entrypoint existence), and files copied to the extensions directory. Symlinks are rejected to prevent directory traversal.
02
RegisterThe extension is registered in the database and in-memory registry. If a previous version exists, SemVer comparison determines whether to upgrade.
03
EnableThe extension is marked as enabled in the database. Enabling an extension auto-activates it.
04
ActivateA Wasmtime WASM sandbox is created with resource limits from the manifest. Host functions are linked, callbacks (LLM, channel) are wired, and a concurrency semaphore is allocated.
05
InvokeWhen a tool call is received, the sandbox's handle_tool export is called with the tool name and JSON parameters. The call is bounded by the CPU timeout and concurrency semaphore.
06
DeactivateThe sandbox is torn down, the concurrency semaphore is dropped, and an ExtensionDeactivated event is emitted.
07
UninstallThe extension's files are deleted, its database record is removed, and all associated permissions are revoked.
Architecture — System Design & Data Flow | Omni AI Agent Builder