CortexPrism is a self-hosted, open-source AI agent operating system — an autonomous agent runtime that turns any LLM into a capable digital agent. It provides persistent memory, a rich tool ecosystem, sandboxed code execution, multi-agent orchestration, a full-featured web UI, and enterprise-grade security.
- License: Apache 2.0
- Version: 0.51.0 (see
deno.json) - Repository:
CortexPrism/cortexon GitHub - CI:
.github/workflows/ci.yml(runs on push tomain)
| Layer | Technology |
|---|---|
| Runtime | Deno 2.x (TypeScript strict mode) |
| Database | libSQL (SQLite-compatible) via @libsql/client |
| Testing | Deno test runner |
| CLI framework | @cliffy/command |
| LLM SDKs | Anthropic, OpenAI, Google Generative AI, AWS Bedrock |
| Frontend | Inline SPA (Tailwind CDN, CodeMirror 6, vanilla JS) |
| Package manager | Deno import maps (deno.json) |
deno task check # Type-check all files
deno task lint # Lint all files
deno task fmt # Format all files (auto-fix)
deno task test # Run all 303 tests (sets --allow-all)
deno run --allow-all src/main.ts <command> # Run CLICI runs deno fmt --check, deno lint, deno check src/main.ts, deno test --allow-all on
ubuntu, macos, and windows.
The codebase is organized into 6 coarse packages under packages/ and a composition root in src/:
packages/
├── core/ — @cortex/core
│ ├── contracts/ — pure interface definitions (ICortexConfig, IDbClient, etc.)
│ └── src/ — config, db, i18n, utils, plugins
├── gate/ — @cortex/gate
│ ├── contracts/
│ └── src/ — security (policy, vault, supervisor), sandbox, vfs
├── ai/ — @cortex/ai
│ ├── contracts/
│ └── src/ — agent, tools, memory, llm, pipeline, skills
├── server/ — @cortex/server
│ ├── contracts/
│ └── src/ — server, hub, channels, a2a, mcp, voice, workspace, codegraph
├── infra/ — @cortex/infra
│ ├── contracts/
│ └── src/ — processes, services, scheduler, ipc, triggers, workflow, observability
└── cli/ — @cortex/cli
├── contracts/
└── src/ — cli commands, tui
src/
├── agent/ — agent loop orchestrator (81 lines)
│ stages/ — 7 pipeline stages (setup, history, assessment, prompt-builder, model-selector, llm-stream, tool-executor)
│ post/ — post-turn modules (response, background, cleanup)
│ helpers/ — shared helpers (preferences, strip-tool-calls, nanoid)
│ pipeline/ — pipeline context
├── server/
│ server.ts — HTTP server entry (composition root for server)
│ new-router.ts — route dispatcher (replaced 6,075-line monolith)
│ routes/ — 62 route modules (one per API area)
│ ui/
│ │ mod.ts — UI assembler (concatenates JS + HTML)
│ │ js/ — 25 concatenated JS modules
│ │ pages/ — 41 page HTML templates
│ │ shared/ — shared utilities
│ │ css.ts — embedded CSS
│ │ shell.ts — sidebar/layout HTML
│ │ providers.ts
├── main.ts — CLI entry point (composition root)
└── tests/ — 30 test files (flat structure)
@cortex/core ← @cortex/gate ← @cortex/ai ← @cortex/server ← @cortex/cli
↖ ↗
@cortex/infra
corehas zero internal dependenciesgatedepends only oncoreaidepends oncore+gateserverdepends oncore+aiinfradepends oncore+aicliis the composition root, depends on all
Each package defines pure TypeScript interfaces in packages/<name>/contracts/. These have zero
runtime dependencies and define the boundaries between packages. Common contracts:
ICortexConfig,IProviderConfig(core/contracts/config.ts)ITool,IToolRegistry,IToolContext(ai/contracts/tools.ts)IAgentLoop,IAgentTurnOptions(ai/contracts/agent.ts)ILLMProvider,ILLMRouter(ai/contracts/llm.ts)IMemoryStore,IEpisodicStore(ai/contracts/memory.ts)IPipelineHook,IPipelineManager(ai/contracts/pipeline.ts)IPolicyEngine,IVault(gate/contracts/policy.ts)ISandboxProvider(gate/contracts/sandbox.ts)IRouteHandler,IRouteTable(server/contracts/router.ts)IWSHub,IWSHandler(server/contracts/websocket.ts)IScheduler,IJobRow(infra/contracts/scheduler.ts)IServiceManager(infra/contracts/services.ts)ICommand,ICommandRegistry(cli/contracts/commands.ts)
The 81-line agentTurn() orchestrator calls pipeline stages sequentially:
Setup → History → Assessment → Prompt Builder → Model Selector → LLM Stream → Tool Executor
→ Post Response → Background (fire-and-forget) → Cleanup
Tool execution runs in a for loop within llm-stream.ts (up to DEFAULT_MAX_TOOL_ROUNDS = 12).
Sub-agent dispatch is parallel via Promise.all.
Routes are defined as RouteHandler[] arrays in 62 files under src/server/routes/. Each handler
is { method: string; pattern: RegExp; handler: (req, path) => Response }. The dispatcher splits
routes into publicRoutes and protectedRoutes, running the auth guard (requireAuth) between
them. Route ORDER matters — handlers are tried in registration order via regex matching.
The SPA is assembled by concatenating 25 JS files and 41 HTML page templates into a single
<script> block. Global variables (ws, sessionId, currentPage, etc.) are shared across all JS
modules since they're concatenated into one scope. The DASHBOARD_JS template literal is injected
at a specific position. serveUi(locale) generates the full HTML response with {LOCALE}
replacement.
5 SQLite databases in WAL mode:
cortex.db— sessions, jobs, policies, services, nodes, workspace, agents, channels, triggers, workflows, projectsmemory.db— episodic_memory, semantic_memory, memory_graph, reflections, skills, glossary, preferenceslens.db— activity audit log (tool calls, LLM calls, policy decisions, approvals)vault.db— AES-256-GCM encrypted credentials (PBKDF2 key derivation)plugins.db— plugin registry
Migrations are in packages/core/src/db/migrations/ (NNN_name.sql format, currently 41 migrations).
Register new migrations in packages/core/src/db/migrate.ts.
24 providers implemented in packages/ai/src/llm/. Each implements LLMProvider with complete()
and stream() methods. The router (llm/router.ts) supports cascade (cheapest-first) and threshold
(prompt-scoring) strategies. Model Quartermaster (model-quartermaster/) uses 6-signal prediction
for intelligent model selection.
Three-layer Parallax model:
- Policy validator — regex allow/deny rules on every tool call
- LLM supervisor — fast model (Gemini Flash/GPT-4o Mini) reviews sensitive access with decision caching
- Human approval — CLI prompts + Web UI modal with 1-hour TTL grants
12 pipeline stages hook into the agent loop via IPipelineHook. Hooks can mutate inputs, abort
execution, or observe results. Registered via IPipelineManager.registerHook().
| Task | Location | Registration |
|---|---|---|
| CLI command | packages/cli/src/cli/<name>.ts |
packages/cli/src/cli/registry.ts or src/main.ts |
| REST endpoint | src/server/routes/<name>.ts |
Add to route table in src/server/new-router.ts |
| DB migration | packages/core/src/db/migrations/NNN_name.sql |
packages/core/src/db/migrate.ts targets array |
| LLM provider | packages/ai/src/llm/<name>.ts |
LLMProvider interface, register in factory |
| Built-in tool | packages/ai/src/tools/builtin/<name>.ts |
Tool interface, register in packages/ai/src/tools/registry.ts |
| Pipeline hook | packages/ai/src/pipeline/builtin.ts |
Register via IPipelineManager |
| Agent stage | src/agent/stages/<name>.ts |
Call from agentTurn() orchestrator |
- TypeScript strict — no implicit
any, no!assertions without justification - Async-first —
async/awaitover raw Promise chains - Fire-and-forget — background tasks use
.catch(() => {}), never block response - Error handling — catch at boundaries, return structured error results
- No hardcoded secrets — use vault via
CORTEX_VAULT_KEYenv var - No hardcoded paths — use
PATHSfrompackages/core/src/config/paths.ts - SQL — use the libsql
Dbwrapper frompackages/core/src/db/client.ts - Subprocess — use
Deno.Command, neverDeno.run - Named exports — avoid default exports except for Deno task entry points
- Conventional commits —
feat:,fix:,docs:,refactor:,chore:,test:,perf:
- Tests in
tests/directory (flat structure, 30 files) - Run:
deno task test(sets--allow-all) - Type-check:
deno task check - UI integrity tests:
deno test --allow-read tests/ui_js_integrity_test.ts(validates generated JS has no syntax errors or missing functions) - Test naming:
Deno.test('descriptive name', async () => { ... })
- Config file:
~/.cortex/config.json(JSON) - Environment variables:
CORTEX_DATA_DIR,CORTEX_CONFIG_DIR,CORTEX_VAULT_KEY,CORTEX_LOG_LEVEL,GITHUB_TOKEN - Provider API keys can be in config or environment variables
- Config schema:
packages/core/contracts/config.ts(ICortexConfig)
| File | Purpose | Lines |
|---|---|---|
src/main.ts |
CLI composition root | ~103 |
src/agent/loop.ts |
Agent turn orchestrator | ~81 |
src/server/server.ts |
HTTP server entry | ~300 |
src/server/new-router.ts |
API route dispatcher | ~200 |
src/server/ui/mod.ts |
UI assembler | ~220 |
packages/ai/src/tools/registry.ts |
Tool registry | ~319 |
packages/ai/src/llm/router.ts |
Model router | ~400 |
packages/gate/src/security/policy.ts |
Policy engine | ~500 |
packages/core/src/db/client.ts |
Database client | ~200 |
packages/core/src/config/config.ts |
Config loading | ~500 |
deno.json |
Workspace config + import map | ~73 |