Skip to content

Runtime

The aeqi runtime is a Rust process that orchestrates a single Company. It runs the agents, executes Quests, fires Events, holds Ideas, manages Sessions, bridges Channels.

One binary. Per-tenant. Self-hostable.

Topology

aeqi-platform                          aeqi (runtime)
  ↑ HTTPS                                 :8401–8599 per tenant
  | proxy                                  ↑
  | by entity_id  ─────────────►  one runtime per Company
  ↑                                       │
external client                            ├── orchestrator
(dashboard, MCP, API caller)               ├── REST API
                                           ├── IPC server
                                           ├── scheduler
                                           ├── channel gateway
                                           └── workers

A runtime hosts ONE Company's data and agents. The platform spawns and manages tenant runtimes; clients hit the platform proxy and get routed to the right runtime by the per-request Company selector (X-Company, internally an entity_id).

What lives in the runtime

Component Responsibility
Orchestrator Picks up events, routes to detectors, dispatches tool calls, runs agent turns.
REST API HTTP surface for the dashboard, CLI, MCP server. Sandbox tenants bind :8401–8500, host tenants :8501–8599.
IPC server Internal verbs callable from in-process subsystems and the platform's IPC bus.
Scheduler Walks the active scheduled events every minute; fires due cron ticks.
Channel gateway Long-poll / webhook bridges for Telegram, WhatsApp, etc. Bridges inbound to sessions.
Workers Per-Quest execution. Worktree-isolated when running code.
Embedded UI rust-embed static assets — the dashboard SPA.

All in one process. No separate services to wire.

Storage

Two SQLite databases per tenant:

DB Contents
sessions.db Quests, sessions, transcripts. The execution substrate.
aeqi.db Ideas, agents, events, roles, role_edges, channels, credentials. The state substrate.

No Postgres, no Redis, no message queue. Two SQLite files per tenant; backups are file copies.

Quest execution

A Quest in pending is picked up by the assigned agent's worker:

  1. Worker creates an isolated git worktree for the Quest.
  2. Worker opens a session for the Quest (linked via idea_id).
  3. Worker loads the agent's injection_mode=always Ideas plus any explicit idea_ids on the Quest.
  4. Worker dispatches turns: LLM call → tool calls → state updates → repeat.
  5. Each turn's state is committed to the worktree (per-turn commits — replayable, auditable).
  6. On completion, worker records an outcome, closes the session's awaiting, marks Quest done.

Tool permissions are enforced per-agent via bwrap sandbox. Network, filesystem, and contract-write access are gated.

Multi-tenant isolation

Per-tenant runtimes (aeqi-host-<entity_id>.service) isolate by:

  • Process — each tenant is a separate systemd unit on a separate port.
  • Filesystem — each tenant has its own data directory under /var/lib/aeqi/<entity_id>/.
  • Network — bound to 127.0.0.1:<port>, fronted by the platform proxy.
  • Credentials — per-tenant encrypted credentials substrate; platform never sees plaintext.

This is the canonical deploy topology: one systemd unit per tenant, no shared runtime process.

Self-host

Self-host runs a single-tenant runtime (no platform proxy, no per-tenant spawn). The same binary, same APIs, same UI — just bound to localhost.

aeqi setup
aeqi start  # binds 8400, dashboard at http://127.0.0.1:8400

See Quickstart for the full local dev path.

IPC verbs

Internal verbs callable from the platform's IPC bus or by other runtime subsystems:

  • agents.spawn, agents.list, agents.update, agents.delete
  • roles.create, roles.update, roles.assign, roles.unassign
  • quests.create, quests.assign, quests.close
  • events.subscribe, events.fire
  • ideas.store, ideas.search, ideas.update
  • message_to, add_participant
  • channels.upsert, channels.delete
  • credentials.ingest, credentials.lookup

See IPC verbs for the full catalog.

Model providers

Model-agnostic. Configure via:

aeqi secrets set OPENROUTER_API_KEY sk-or-...
aeqi secrets set ANTHROPIC_API_KEY sk-ant-...
aeqi secrets set OLLAMA_HOST http://localhost:11434

Per-agent model field picks which provider to use; defaults inheritable from parent role/entity.

The aeqi-platform's hosted runtime exposes aeqi-inference — an OpenAI-compatible endpoint that routes through DeepInfra for open-weights models. Self-host runtimes hit upstream providers directly.

Embed

The dashboard SPA is rust-embed'd into the binary. No separate npm install on the deploy host. aeqi start serves UI + API from the same port.

For UI-only iteration, rebuild the SPA (npm run build in apps/ui) and redeploy the static bundle — no Rust rebuild needed when only TS/CSS changed. See /docs/guides/claude-code for hosted dev tips.

Observability

Signal Where
Logs systemd journal (journalctl -u aeqi-host-<id>.service).
Metrics Prometheus endpoint at :8400/metrics (when feature-enabled).
Traces OpenTelemetry export (configurable).
Events All internal events queryable via GET /api/events.

Cookies for sign-in and analytics. No third-party tracking.