Engines
An engine (your Chi) is the AI backend that drives the workspace. Ikenga is engine-optional: the shell boots and runs the kernel without one, and engines are installed as pkgs alongside everything else. The default engine ships as a pkg precisely so it can update independently of the shell binary.
The chat layer is multi-engine. Any number of engines can be installed side by side, and the frontend sees one wire regardless of which one is running — engine swaps are invisible above the kernel boundary.
The model
Section titled “The model”Each engine adapter wraps a CLI-based AI backend — a binary that speaks a streaming protocol over stdio. Two pieces make up an engine:
- The pkg (in
ikenga-pkgs/packages/engine/<id>/) declares the contract: a stableagentId, a display name, a capability matrix, an onboarding block (which vault keys and auth command the engine needs), and a settings schema. - The runtime adapter (Rust, in the shell) translates between that CLI’s native protocol and the shell’s internal session wire.
The frontend talks to whatever engine is active through one normalized envelope shape on a single channel. Whether the underlying CLI speaks that protocol natively or the Rust adapter translates is something the UI never has to know.
The engine block
Section titled “The engine block”An engine pkg declares an engine block in its manifest:
{ "engine": { "agentId": "myai", "display": "MyAI", "capabilities": { "streaming": true, "toolUse": true, "thinking": false, "modelSwitching": true, "sessionResume": true, "mcp": false }, "onboarding": { "requiredVaultKeys": ["MYAI_API_KEY"], "authCommand": "myai login", "docsUrl": "https://docs.myai.example" } }}capabilitiesis a superset matrix every adapter must answer —streaming,toolUse,thinking,artifacts,fileAttachments,imageInput,slashCommands,modelSwitching,promptCaching,agenticTools,mcp,sessionResume. Set the ones you implement totrue, the rest tofalse. The chat UI reads these to enable or disable features per engine, so a flag you claim but don’t implement will silently break that feature.onboardingis surfaced by the first-run wizard.requiredVaultKeysare looked up in the encrypted vault;authCommandis a copy-to-clipboard hint — the shell does not run it for you.
Available engines
Section titled “Available engines”| Engine | Status | Auth | Resume |
|---|---|---|---|
| Claude Code | Default — fully wired. The shell spawns your local claude CLI and translates its streaming output. | claude login or ANTHROPIC_API_KEY | claude --resume <id> |
| Gemini | Pluggable adapter. Spawns gemini and proxies its protocol bidirectionally. | gemini auth or GEMINI_API_KEY | gemini --resume / --session-id |
| Codex | Pluggable adapter. Stream-parses codex exec --json into the shell’s normalized envelopes. | codex login or OPENAI_API_KEY | codex resume |
| noop | Reference adapter. Returns canned responses — useful for tests and demos and as the minimum viable engine manifest. | — | — |
Every engine requires its CLI on your $PATH.
Per-turn engine and model
Section titled “Per-turn engine and model”A chat thread is created with one engine, and that stays pinned to the thread. But the composer lets you swap the engine and model per turn — a single send can be routed to a different engine without changing the thread. The picker is a two-level Engine → Model popover.
For not-yet-installed engines, onboarding metadata is mirrored on the frontend, so the auth surface can guide you through setting up an engine before you’ve added its pkg.
Where to go next
Section titled “Where to go next”- Pkgs → — the manifest, capabilities, and lifecycle the engine block plugs into.
- Build your first pkg → — the engine-adapter archetype is one of the tracks.