AgentOS
An operating system for AI agents
Every winning AI agent team — Claude Code, Cursor, Manus, Devin — has converged on the same architecture: a ReAct loop, a handful of raw tools, and a carefully engineered information flow. Same model, different harness: benchmark scores double. Strip 80% of the tools: the task still completes.
The model is the engine. The harness is the car. The harness is the product.
But harness has a shelf life. MCP fired for a year, then the CLI resurgence hit. Last year’s rigid orchestration, today’s model handles in a single prompt. Hard-coded harness decisions — context strategy, tool selection, communication protocol — become cages as model capability grows.
AgentOS separates kernel from harness the way Unix separates the OS from userland. The kernel manages agent lifecycle, persistence, and extension points — nothing else. Every harness decision lives in a Skill. Context management is a Skill. Multi-agent communication is a Skill. The web UI is a Skill. LLMs eliminated microkernel’s historical configuration overhead: an agent can now discover, load, and configure Skills itself.
AOS Skills build on the open Agent Skills standard — the same SKILL.md format adopted by Claude Code, Cursor, Copilot, and 30+ clients — and extend it with a runtime Service face: a long-running subprocess that registers hooks, calls syscalls, and participates in the kernel lifecycle.
graph LR
A["Agent<br/>(LLM + bash)"]:::react
S["Skills<br/>context · UI · A2A · yours"]:::skill
K["Microkernel<br/>lifecycle · hooks · persistence"]:::kernel
A -->|"bash"| S <-->|"syscall"| K
classDef react fill:#C05621,stroke:#C05621,color:#fff
classDef skill fill:#805AD5,stroke:#6B46C1,color:#fff
classDef kernel fill:#2C3E50,stroke:#2C3E50,color:#fff
Agent only has bash — no kernel access, structurally isolated. Skills are the entire user space: each one has a context face (SKILL.md injected into the agent) and an optional service face (subprocess connected via WS/UDS). Kernel provides mechanisms — syscalls, hooks, persistence — but zero policy. Swap a Skill, swap the harness.
| OS Concept | AOS Equivalent | What it does |
|---|---|---|
| Process / CPU | ReActUnit | Temporary LLM + bash loop; created per dispatch, destroyed on completion |
| Disk | SessionHistory | Append-only fact log; the ground truth |
| RAM | SessionContext | Rebuildable projection in plain LLM wire format |
| User | Agent | Identity, permission boundary, inheritable config |
| Program | Skill | Two faces: context face (SKILL.md + scripts/) and service face (subprocess) |
| Syscall | Syscall | The only legal kernel boundary — every state change crosses it |
| Interrupt | Hook | Extension points across the lifecycle; sync hooks can reject operations |
Every session.dispatch spawns a ReActUnit — one LLM + bash loop. Hooks from Skills gate every step along the way: dispatch.before can reject the request, compute.before rewrites the prompt, tool.before intercepts bash commands, tool.after validates results. All hooks are provided by Skills. None are hard-coded in the kernel.
SessionHistory is append-only disk. SessionContext is ephemeral RAM in LLM wire format. The kernel provides append (O(1)) and assemble (O(n) rebuild via hook). What to keep, what to compress — that’s Skill policy, not kernel business.
A Skill is a directory with a SKILL.md. Add a service field to run a subprocess that hooks into the kernel:
# skills/my-guard/service.py
from aos_sdk import define_service
@define_service
def service():
def guard(input_data, output_data):
cmd = output_data['args'].get('command', '')
for pattern in ['rm -rf /', 'DROP TABLE', ':(){ :|:& };:']:
if pattern in cmd:
return {'verdict': 'reject', 'reason': f'blocked: {pattern}'}
return output_data
return {'hooks': {'tool.before': guard}}# skills/my-guard/SKILL.md
---
name: my-guard
description: Blocks dangerous bash commands before they execute
service: ./service.py
---
This skill intercepts all bash commands and rejects destructive patterns.Drop the directory into skills/. The daemon hot-reloads it. No registry, no package manager, no restart required.
| Tool | Version | Install |
|---|---|---|
| Node.js | ≥ 22 | nvm install (reads .nvmrc) |
| pnpm | ≥ 10 | corepack enable |
| Pixi | latest | curl -fsSL https://pixi.sh/install.sh | bash |
| Docker | latest | Desktop or Engine + Compose |
Pixi manages Python and Node.js environments from a single lockfile (think pyenv + conda-forge combined) — no separate Python install needed.
# 1. Install dependencies
pnpm install && pixi install
# 2. Start Postgres
docker compose -f AgentOS/docker-compose.yml up -d --wait --remove-orphans
# 3. Configure
cp AgentOS/.env.example AgentOS/.env
# Edit .env — set OPENROUTER_API_KEY (get a free key at https://openrouter.ai/keys)
# To use a local model, set OPENROUTER_BASE_URL to your Ollama or LM Studio endpoint
# 4. Start the daemon
pixi run start
# 5. Verify
pixi run status
# 6. Open the UI
open http://localhost:3000The daemon spawns Service subprocesses connected via per-service Unix Domain Sockets. The default aoscb.json starts aos-context, aos-frontend, aos-a2a, and aos-skill automatically. aos-frontend is a Skill whose setup.sh runs pnpm install for the Next.js UI on first launch — no manual frontend install needed.
One required variable:
OPENROUTER_API_KEY. SeeAgentOS/.env.examplefor all options.
| Symptom | Likely cause | Fix |
|---|---|---|
Cannot connect to the Docker daemon |
Docker not running | Start Docker Desktop (or sudo systemctl start docker on Linux) |
Bind: address already in use on port 5432 |
Another Postgres instance | Stop it (brew services stop postgresql) or change AOS_DB_URL |
Bind: address already in use on port 3000 |
Another app on 3000 | Stop the other app or change the port in skills/aos-frontend/package.json |
pixi: command not found |
Pixi not installed | Run curl -fsSL https://pixi.sh/install.sh | bash and restart your shell |
| LLM calls fail / 401 errors | Invalid API key | Confirm OPENROUTER_API_KEY in AgentOS/.env; get a new key at openrouter.ai/keys |
| Daemon silently exits | Missing .env or bad DB URL |
Check AgentOS/aos.log; ensure AgentOS/.env exists and Postgres is healthy |
| Skill | What it does |
|---|---|
| aos-context | Context engine — projects SessionHistory → SessionContext on every dispatch. Provides the required session.assemble hook. Replaceable. |
| aos-frontend | Next.js web UI at :3000. Humans interact here; agents use bash. Deletable without affecting the kernel. |
| aos-a2a | Agent-to-Agent messaging with three send modes: --silent (FYI), --notify (no reply expected), --wake (reply required). |
| aos-skill | skill list and skill load <name> CLI so agents can discover and pull in Skills on demand. |
AgentOS/
├── AgentOS/ # Python kernel + daemon
│ ├── src/aos/ # runtime, session, agent, skill, hook, service, react
│ └── docker-compose.yml # PostgreSQL
├── packages/
│ ├── sdk-py/ # Python SDK (aos-sdk)
│ └── sdk-ts/ # TypeScript SDK (@evop/sdk)
├── skills/ # Built-in Skills (the default harness)
│ ├── aos-context/
│ ├── aos-frontend/
│ ├── aos-a2a/
│ └── aos-skill/
├── docs/ # Single source of truth
│ ├── aos-charter.md # Design philosophy
│ └── specs/ # 7 specification documents
└── aoscb.json # System config (default skills, model)
The docs/ directory is the single source of truth. Code faithfully reflects specs.
| Spec | What it covers |
|---|---|
| aos-charter.md | Design philosophy — why an OS, what AOS is and isn’t |
| aos-syscall.md | Syscalls — signatures, semantics, authorization model |
| aos-hooks.md | Hooks — delivery, verdicts, registration and dispatch rules |
| aos-lifecycle.md | Daemon startup, dispatch, recovery, archival |
| aos-data-model.md | ControlBlocks, SessionHistory, RuntimeLog |
| aos-service.md | WS/UDS protocol — any language, full examples |
| aos-deployment.md | Configuration, daemon management, skillRoot conventions |
pnpm quality # Full gate — JS/TS lint + format + typecheck + Python lint + format + typecheck
pixi run test # Python tests
pixi run start # Start daemon
pixi run stop # Stop daemonStack: pnpm workspaces · Pixi/conda-forge · ESLint + Prettier · Ruff + Pyright · Husky + commitlint (Conventional Commits)
CI: GitHub Actions on every push and PR — see .github/workflows/quality.yml.