██████╗ ███╗ ███╗███╗ ██╗██╗
██╔═══██╗████╗ ████║████╗ ██║██║
██║ ██║██╔████╔██║██╔██╗ ██║██║
██║ ██║██║╚██╔╝██║██║╚██╗██║██║
╚██████╔╝██║ ╚═╝ ██║██║ ╚████║██║
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝
Brain, hands, and super legs for any LLM — frontier or local.
Omni gives any language model — frontier or open, big or small — a body to act through, a memory to learn from, and an evolving sense of how to use itself. It was designed for the open-model wave (MiMo, Qwen, GLM, DeepSeek, Kimi, Llama via Ollama) and works just as well with Claude, GPT, and Gemini.
The thesis is simple: weaker models become useful when the harness around them is strong. Instead of asking a 7B model to plan, execute, and reflect on its own, Omni layers in a planner, a critic, and a memory; probes the model on first contact; and adapts its prompts, tools, and loop strategy to fit. The result is an agent that punches above the model's weight class.
┌─ third brain ────────────┐ ┌─ hands ─────────────────┐ ┌─ super legs ────────────┐
│ Planner decomposes │ │ bash, read/write, │ │ Probe capabilities │
│ Critic reviews │ + │ edit (find/replace), │ + │ Adapt prompts to model │
│ Memory recalls │ │ multi_edit, glob, │ │ Trace every session │
│ │ │ grep, web_fetch, MCP │ │ Evolve prompt variants │
└──────────────────────────┘ └─────────────────────────┘ └─────────────────────────┘
│
▼
┌─────────────────────────┐
│ Engine (the loop) │
│ AsyncIterable<Event> │
└─────────────────────────┘
│
┌──────────────────┬──────────────┴──────────────┬─────────────────┐
▼ ▼ ▼ ▼
CLI Server Web VS Code
(readline) (HTTP + WS) (browser) (extension)
Most agent frameworks assume a frontier model. Run them on a local 7B and they crumble — the model hallucinates tool names, drops formatting, goes in circles. The convenient answer is to wait for open models to catch up. Omni takes the other route:
The model is interchangeable. The harness is the agent.
If the harness compensates intelligently for what the model can't do — by probing capabilities, choosing the right system prompt, decomposing tasks, criticising results, and learning across sessions — then a 7B running on your laptop can do real work.
|
|
- Prebuilt subagents —
explore,test,critiqueship in-repo asAGENT.mddefinitions, each a sandboxed child engine with its own model, tool subset, and enforced permission rules (regex allow/deny per tool — e.g.testmay runbun testbut notrm -rf, and write only*.test.ts). Override or add your own in~/.omni/agents/<name>/AGENT.mdor workspace.omni/agents/. - Parallel dispatch — the agent calls a subagent directly as a tool, or fans several out at once with
dispatch_agents(bounded concurrency, partial-failure isolation, abort propagation) and collects every result when they finish. - Plan / Auto / Build modes —
plan= read-only tools + the Planner first;build= all tools + the Critic after + permission prompts;auto= all tools with prompts auto-allowed (unattended — safety guards still apply). Switch with/plan·/auto·/build·/mode; an opt-in classifier can pick the mode per turn, and the agent can request plan→build viarequest_build_mode(human-gated). - Per-role models — the planner, critic, and each subagent may run on a different model than the main agent (e.g. plan on Claude, execute on a local model), defaulting to the main model.
True streaming • abort propagation through model + tools • loop detection by tool-call signature • bounded retries on retryable errors • parallel tool calls with interleaved event streams • session snapshot/restore preserving identity • cost tracking when per-1k rates are known • 22 discriminated EngineEvent variants — the only public observation channel.
One-liner (downloads the prebuilt binary, installs to ~/.omni/bin, wires PATH):
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/hallelx2/omni/main/install.sh | bash# Windows (PowerShell)
irm https://raw.githubusercontent.com/hallelx2/omni/main/install.ps1 | iexThen drop your key in ~/.omni/.env and run omni:
echo 'MIMO_API_KEY=tp-...' >> ~/.omni/.env
omni # full TUI
omni --plain # plain readline REPL (pipes / CI)With MIMO_API_KEY present, Omni auto-selects the MiMo adapter — no
OMNI_ADAPTER needed.
git clone https://github.com/hallelx2/omni.git && cd omni
bun install
bun run setup # build host binary → ~/.omni/bin/omni + wire PATHOr just build without installing:
bun run build # → packages/cli/dist/omni[.exe] (host platform)
bun run build:all # all platforms (win/linux/mac × x64/arm64)bun run dev # interactive TUI
OMNI_ADAPTER=mimo bun run dev
bun run dev --plain # readline REPL
bun test # test suite
bun run typecheck # all packagesGitHub release (binaries for the curl | bash installers):
gh auth login
bun run release v0.1.0 # build:all + create GitHub release with binariesThis uploads assets named omni-<plat>-<arch> so the install one-liners
above can fetch them.
npm release (all platforms, via CI): push a tag and the
Release (npm) workflow builds a native
binary on a runner per OS, then publishes the omni-harness launcher plus
each omni-harness-<plat> package. Cross-compiling can't be done from one
host (opentui ships per-platform native modules), so the matrix is required.
git tag v0.1.0-beta.1 && git push origin v0.1.0-beta.1 # → npm tag "beta"
git tag v0.1.0 && git push origin v0.1.0 # → npm tag "latest"
# or run the workflow manually (Actions → Release (npm) → Run workflow)Testers then install with:
npm i -g omni-harness@beta # or @latest
omniOne-time setup: add an npm automation token as the repo secret
NPM_TOKEN (Settings → Secrets → Actions). The Linux-arm64 leg uses the
ubuntu-24.04-arm runner (GitHub-hosted arm64; available on public repos).
Omni keeps per-user state in ~/.omni/:
~/.omni/
├── config.json # default adapter, model, provider keys, UI prefs
├── db.sqlite # sessions, messages, events, audit, profiles, variants
├── traces/ # one JSONL file per session run
├── agents/ # custom subagent defs (AGENT.md) — override the shipped ones
├── memory.json # long-term memory entries
└── settings.json # surface-specific settings (theme, etc.)
Every path is env-overridable (OMNI_HOME, OMNI_DB, OMNI_TRACES, OMNI_MEMORY, OMNI_CONFIG). The CLI's /paths command shows what resolved.
Example ~/.omni/config.json
{
"adapter": "mimo",
"model": "mimo-v2.5-pro",
"maxIterations": 12,
"enableReActFallback": true,
"providers": {
"mimo": {
"apiKey": "tp-...",
"baseURL": "https://token-plan-sgp.xiaomimimo.com/v1"
},
"anthropic": { "apiKey": "sk-ant-..." }
},
"permissions": {
"mode": "ask",
"denyDestructive": true
},
"ui": { "theme": "dark", "showThinking": true },
"storage": { "tracesEnabled": true },
"modes": { "default": "build" },
"agents": {
"planner": { "model": "anthropic:claude-sonnet-4-5" },
"critic": { "enabled": true, "autoRetry": false }
}
}Precedence for every value: explicit argument > env var > config file > built-in default.
| Adapter | Endpoint | Env var | Notes |
|---|---|---|---|
mimo |
https://token-plan-sgp.xiaomimimo.com/v1 |
MIMO_API_KEY |
Lowercase model ids (mimo-v2.5-pro); reasoning content auto-roundtripped |
mimo-anthropic |
<base>/anthropic/v1 |
MIMO_API_KEY |
Same key, Anthropic protocol |
ollama |
http://localhost:11434/v1 |
(none) | Any tag Ollama serves locally |
anthropic |
api.anthropic.com | ANTHROPIC_API_KEY |
Extended thinking supported |
openai |
api.openai.com | OPENAI_API_KEY |
gpt-4o, gpt-4o-mini, o1, o-series |
google |
generativelanguage.googleapis.com | GOOGLE_API_KEY |
gemini-2.0-flash, 1.5-pro |
mock |
(none) | (none) | Scripted; for tests and offline dev |
All non-mock adapters go through Vercel AI SDK 6. Adding a new provider is roughly 80 lines — see docs/authoring-an-adapter.md.
/help list commands
/paths show resolved ~/.omni/ paths
/usage cumulative token usage and cost
/session current session ID
/model active model
/mode show or switch run mode (/mode plan | auto | build)
/plan switch to plan mode (read-only + planner)
/auto switch to auto mode (full tools, no permission prompts)
/build switch to build mode (full tools + critic)
/skill pin/unpin a skill (/skill <name|off>)
/history compact view of conversation so far
/quit exit (also: /exit)
Three concrete mechanisms, in increasing autonomy:
1. Adaptive prompts. On first contact with a model, Omni runs probeModel — a small battery of cheap prompts (~600 tokens) that classify the model (native tool calls?, instruction-following?, verbosity?). adapt(profile) maps that to a strategy (which system prompt, ReAct fallback, iteration budget). This is wired into startup and cached per model in ~/.omni/db.sqlite.
2. Session traces. Every run writes a JSONL trace to ~/.omni/traces/ plus rows to SQLite. scoreTrace ranks completed sessions; replayTrace + checkTrace re-run a trace against invariants — a library for regression-testing agent behavior.
3. Prompt evolution (experimental). A genetic variant pool (tournamentSelect, mutatePrompt) is built and unit-tested, but not wired into the default loop — it ships as a programmatic API, not a v1 feature.
The engine is a closed-loop controller:
┌─────────────┐ tool call ┌──────────────┐
│ Model │──────────────▶│ Engine │
│ (adapter) │ │ - validate │
│ │◀──────────────│ - permission │
└─────────────┘ result │ - execute │
│ - feed back │
└──────┬───────┘
│ events
▼
┌──────────────────┐
│ EngineEvent │
│ AsyncIterable │
└──────────────────┘
See docs/architecture.md for the full event taxonomy (22 types), lifecycle guarantees, and per-subsystem internals.
| Package | Purpose |
|---|---|
@omni/core |
Engine loop, types, context, permissions, validator, tokenizer, paths/config |
@omni/adapters |
Vercel AI SDK adapters — openai-compatible (MiMo, Ollama…), Anthropic, OpenAI, Google + cost helper |
@omni/tools |
bash, read_file, write_file, edit, multi_edit, glob, grep, web_fetch, MCP client |
@omni/improve |
Planner, Critic, Memory, Probe, Adapt, FileTracer, replay, prompt evolution |
@omni/storage |
bun:sqlite with versioned migrations + 7 repositories |
@omni/cli |
Interactive terminal — slash commands, permission prompts, session persistence |
@omni/server |
HTTP + WebSocket server with WS-bridged permission requests |
@omni/web |
Minimal browser client |
@omni/desktop |
Tauri desktop app — React UI + bundled engine sidecar |
@omni/vscode |
VS Code extension (unfinished — not in this release) |
@omni/cli-driver |
Smoke-test driver |
- Authoring a tool — write a tool the model can use (contract, schemas, progress events, anti-patterns)
- Authoring an adapter — plug in a new model provider (translation utilities, provider-specific gotchas)
- Architecture — engine internals, event taxonomy, lifecycle
- API reference — generated with
bun run --cwd packages/core docs(TypeDoc)
A minimal tool looks like this:
import { z } from "zod"
import type { Tool, ToolContext } from "@omni/core"
export const shout: Tool<{ text: string }, { result: string }> = {
name: "shout",
description: "Return the input in upper case.",
permission: "auto",
schema: z.object({ text: z.string() }),
async execute(args, ctx: ToolContext) {
return { result: args.text.toUpperCase() }
},
}| Tests | 571 passing across 65 files |
| Packages | 11, all typecheck clean |
| Source | ~24,000 lines of TypeScript |
| Verified live | MiMo-V2.5-Pro driven end-to-end on a test project (read → edit → run tests, self-corrected via the verifier loop); prompt caching measured −80% tokens/cost on a repeat task |
| Surfaces | CLI (TUI + plain REPL), HTTP/WS server, web client, Tauri desktop app |
| Not in this release | VS Code extension (kept private); prompt-evolution loop (experimental API) |
What's solid (click to expand)
| Aspect | Done |
|---|---|
| 1. Engine | streaming, abort, loops, retries, parallel tools, snapshot, tracer hook, 4 fuzz-style property tests |
| 2. Types & API | TSDoc on every public symbol, JSONSchema7 for tool params, tiered exports, TypeDoc generates clean docs |
| 3. Adapters | 7 providers via Vercel AI SDK 6, reasoning_content roundtrip, cost computation, fake-fetch e2e tests |
| 4. Tools | 8 built-ins + MCP (in-memory + real stdio tested), cross-platform shell with ANSI strip, path safety |
| 5. Context | tiktoken tokenizer, summarize-by-default compaction (older turns compacted, not dropped), tool-result chunking, prompt-cache token surfacing |
| 6. Permissions | gate types + audit + rule patterns; destructive-bash denied by default, opt-in workspace confinement, mode-aware (auto) gate |
| 7. Third brain | Planner, Critic, keyword + embedding (VectorMemory) memory — all unit-tested and wired |
| 8. Self-improvement | probe + adapt wired into startup; FileTracer on every run; scoreTrace/replay library; variant pool experimental |
| 9. Storage | bun:sqlite, versioned migrations, 8 repos, FK cascades |
| 10. CLI | TUI + plain REPL, slash commands, plan/auto/build modes + intent classifier, long-term memory, session persistence |
| 11. Surfaces | server WS with permission forwarding tested 3 ways; web client with permission UI |
| 12. Testing | typecheck script, CI workflow, trace replay, 4 property tests |
| 13. Documentation | architecture + 2 author guides + .env.example + TypeDoc |
What's still imperfect (the honest list)
- Engine — the executor could be split out of
engine.ts; no property test proving aborted runs never emittool.result - Adapters — rate-limit retry untested live; Google adapter not run end-to-end; Anthropic extended thinking not e2e-verified
- Tools —
grep's ripgrep path is exercised only whenrgis installed;web_fetchmarkdown untested on complex layouts - Permissions — destructive-bash deny + opt-in workspace confinement (
restrictToWorkspace) +allowlistGateship, but the bash path-confinement is heuristic, not a true per-command sandbox - Self-improvement — probe/adapt are wired; the prompt-evolution loop is built + tested but intentionally not wired for v1 (experimental API)
- Storage — no backup/restore command; forward-only migrations
- CLI — slash arg parsing is space-split (no quoted strings); no
/sessionscontinue command yet - Desktop — ships per-OS installers via CI, but no auto-update yet; the VS Code extension is unfinished and excluded from this release
- Prompt caching — surfaced + billed for OpenAI-compatible (incl. MiMo) and Anthropic; cached-token accounting on other providers depends on what their API reports
- Testing — no load test; no chaos/fuzz on the adapter translation layer
- Docs — no
examples/directory; no FAQ yet
Issues and PRs welcome. The workflow is straightforward:
bun install
bun test # ensure baseline is green
# ... make changes
bun run typecheck # all packages
bun testA few conventions: tools belong in @omni/tools and follow the Tool<TArgs, TResult> contract; new model providers belong in @omni/adapters and use the AI SDK translation helpers; never throw from a permission gate (return deny); every public symbol gets a TSDoc comment.
Omni stands on the shoulders of:
- Vercel AI SDK — provider translation, streaming, tool calling
- Bun — runtime, package manager, SQLite, test runner, all of it
- opencode — studied for monorepo structure and the
reasoning_contentroundtrip pattern - Model Context Protocol — the standard for extending agents with external tools
- ripgrep — accelerates
grepwhen present - Xiaomi MiMo — the model that proved this approach on a real open weights stack
MIT © Halleluyah Oludele