Architecture & concepts
┌──────────────────────────────────────────────────┐
│ Human interfaces │
│ ─ Web dashboard (React, group chat) │
│ ─ CLI (olympus "...") │
└────────────────────┬───────────────────────────────┘
│
┌──────────▼──────────┐
│ Orchestrator │ LLM router (CLI) /
│ + context bus │ main coordinator (chat)
│ + ticket store │ dispatch / ask_agent
└──────────┬──────────┘
│
┌────────┬───────┼────────┬────────┬────────┐
▼ ▼ ▼ ▼ ▼ ▼
sysadmin programmer terraform ansible hpc (+ terminal
companion)The agent contract
Every agent is a small Python class (AgentSpec) declaring name, domain, tools, destructive_verbs, and a model. It implements one synchronous method, handle(task, ctx) -> AgentResult. The agent is a black box to the orchestrator: same input shape (TaskMessage), same output shape (AgentResult), regardless of domain. Runtime capabilities (approval, audit, rollback, memory, the group-chat seams) are injected per-run through AgentContext — an agent with none wired behaves as the plain v1 black box.
Tool-gating is enforced by the runtime, not by prompting: gate_tools(...) wraps every tool so a call outside the declared set is rejected, and any destructive_verb re-enters through the approval hook before it executes.
Group chat (sub-agents)
The dashboard chat is a ticket — a group chat persisted as a TicketStore of ordered events (human_message, agent_message, agent_thinking, dispatch, agent_result, tool_call, approval_*, mcp_event). The main coordinator builds two tools from context seams:
dispatch(agent, subtask)— run one specialist to completion and get its result summary back.ask_agent(target, question)— ask a participant one direct question; the asked agent answers from its own retained context (per-(ticket,agent) checkpoints), and only the answer crosses back.
Each agent's context is isolated; collaboration is directed Q&A, never a shared context dump. The coordinator streams its reasoning as agent_thinking events that interleave chronologically with the dispatch and tool-call chips. When a ticket is closed, its transcript is summarized into long-term memory and the per-ticket checkpoints are discarded.
Safety
- Tool-gating — declared-tools-only, enforced in Python.
- Approval — destructive verbs route through an
ApprovalHook(ConsoleApprovalHookfor the CLI, an inline approval card in the dashboard). - Self-protection — a
SelfProtectionPolicyhard-denies any call that targets Olympus's own namespace or VM hosts, before approval. A user (even an admin) cannot approve their own self-escalation. - Audit — every tool call is appended pre- and post-execution with the approval decision and result.
See Configuration for the self-protection, approval, and demo-mode knobs.
The intelligence layer
All off by default (Null* stores); a deployment opts in via AgentContext.
- Memory —
JsonlMemoryStore(lexical, dep-free, default for tests/CI) orEmbeddingMemoryStore(OpenAI embeddings + cosine). Retrieved runs are prepended to the prompt as untrusted reference material. - Feedback — 👍/👎/correction; "bad" entries are filtered from future prompts, "good" entries get a score boost, corrections ride into the prompt.
- Rollback — the runtime captures a destructive op's inverse before it fires (programmer write/edit/delete, sysadmin
delete_pod→apply_manifest, terraformtf_apply→tf_restore_state). Undo re-prompts approval. - Telemetry — per-invocation cost on the agent; a coordinator turn aggregates dispatched specialists' cost, with a per-agent breakdown and per-user daily caps.
MCP
A Model Context Protocol server is wired with a target_agent, a transport (stdio or Streamable-HTTP), and an integrator-supplied destructive allowlist — its tools register onto that agent (prefixed) and flow through the same gate + approval + self-protection machinery as native tools. Declared at startup via OLYMPUS_MCP_SERVERS or added at runtime. Production example: NetDB (IPAM/DNS/DHCP, ~32 tools over HTTP) grafted onto sysadmin.
Deployment shape
The dashboard, orchestrator, bus, and all agent runtimes run as a single Deployment in Kubernetes (Helm chart), fronted by a TLS reverse proxy. Self-host it on Proxmox/bare-metal (main repo infra/), or reproduce the public AWS path with the sandbox repo. See Deployment.