Skip to content

omoios/agent-coordinator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

357 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agent-coordinator

Control plane for a hosted coding-agent SDK. Authenticate a user, spin up a per-session Cloudflare Durable Object, spawn a sandboxed dev box on Modal running OpenCode, and stream the agent’s work back over WebSocket — multi-tenant, bring-your-own-key, with durable run history.

Live demo — Chat UI · https://app.omoios.dev   API · https://agents.omoios.dev (/health{"status":"ok"})


What it does

The full pipeline is proven end-to-end against the deployed stack:

chat → control plane → Modal sandbox → opencode → model → streamed reply

The sandbox is a real dev box, not a file editor — it clones a repo, installs dependencies, and runs code. In one end-to-end run it cloned expressjs/express, ran npm install, and executed the project’s full 1249-test suite inside the spawned sandbox, streaming the result back to the UI.

Verified live (2026-06-14)npm run e2e:prod:journey drives one real session against the deployed control plane + a Modal sandbox on GLM-5.2 (1M-context), fully headless — 6/6 checks pass:

  • sandbox ready — session created, Modal sandbox spawned, dialed back over WSS, token-hash authenticated
  • single-turn reply — prompt → streamed tokens → execution_complete
  • multi-turn, same session — a second prompt re-dispatched through the FIFO queue (session persistence)
  • tool executed in the sandbox — a real bash exec (tool_call frame); the command's output round-tripped back through the stream
  • environment autodiscovery — server-side detect of omoios/agent-coordinatorpm=npm, 25 files, install=[npm install]

Architecture

flowchart LR
  U["Chat SPA\napp.omoios.dev"] -- "HTTPS + WS" --> W["Cloudflare Worker\nHono router\nagents.omoios.dev"]
  W -- "requireAuth / resolveContext" --> A[("Better Auth + app data\nPostgres via Hyperdrive / Neon")]
  W -- "DO id = org:session" --> DO["SessionDO\nprivate SQLite · WS hub\nFIFO queue · alarm watchdog"]
  DO -- "HMAC-signed spawn" --> M["Modal sandbox\nOpenCode + bridge"]
  M -- "WSS dial-back (token-hash auth)" --> DO
  M -- "model calls (BYOK / gateway)" --> L["LLM provider"]
  DO -- "durable flush on every terminal transition" --> R[("agent_runs / agent_run_events\nPostgres")]
Loading
  • Request → DO routing (src/index.ts): one Hono entry; each session resolves to a Durable Object whose id is ${organizationId}:${sessionId} — tenant isolation by construction (one org cannot name another’s DO).
  • SessionDO (src/do/session-do.ts): a single actor per session that hibernates when idle and survives it — private SQLite (sessions, messages, events, artifacts), a hibernation-safe WebSocket hub, a FIFO message queue, ACK’d critical events (re-sent until acknowledged), and an alarm-driven watchdog.
  • Modal data plane (packages/modal-infra): HMAC-authenticated sandbox lifecycle, GitHub-App installation tokens for clone/push, pre-built composite images.

Engineering highlights

  • Hexagonal ports & adapters. 15 ports across 5 planes (src/lib/ports/registry.ts). Each port is a bundle, not just an interface: (interface, ≥1 real adapter, 1 in-memory fake, 1 contract test, 1 fault catalog). A walking-skeleton test runs the entire run lifecycle in-memory with zero infrastructure; a disruption suite breaks each seam and asserts fail-closed; a conformance-registry tripwire turns “rename a fake / add a port without its bundle” into a red build.
  • Multi-tenant by construction. A single org resolver (resolveContext), DO-id namespacing, and per-tenant AES-GCM encryption (HKDF of a master key + organization_id — cross-tenant decrypt is impossible).
  • Provider-neutral. No default provider/model anywhere; provider = model.split("/")[0]. BYOK by default, with a pluggable model-gateway seam (direct / LiteLLM / Bifrost).
  • Durable run history. Every terminal session transition flushes an attributed run record (tenant, api key, cost, ordered events) to Postgres, non-blocking.
  • 1,424 tests across 128 files, run inside a real Cloudflare Workers isolate (miniflare) backed by an isolated Postgres database — not mocks.

Tech stack

Cloudflare Workers · Durable Objects · Hono · Better Auth · Postgres (Hyperdrive / Neon) · Drizzle · Modal · OpenCode · TypeScript · Vitest · Vite + Void (chat SPA).

Quickstart

npm run setup        # one-time: install deps, verify .dev.vars, start local Postgres, run migrations
npm run dev:local    # control plane (:8789) + chat UI (:5174) together
npm test             # full suite — Workers pool + Postgres
npm run doctor       # read-only health check (Node, ports, migration drift, stale procs)

Secrets go in .dev.vars for local dev (wrangler secret put … in prod). See AGENTS.md for the full operator guide and CODEBASE_MAP.md for the layout map.

Design & decisions

This project was built to exercise a clean hexagonal cutover off a Modal-hardwired prototype toward swappable ports & adapters. The reasoning is documented, not just the code:

Repository layout

src/            control-plane worker: index.ts (Hono entry), do/ (SessionDO, OrgEventsDO),
                lib/ (15 ports + adapters + fakes), routes/, db/pg/ (Drizzle schema)
routes/         additive Void file-route handlers mounted into the Hono app
packages/       chat/ (Void SSR SPA), modal-infra/ + sandbox-runtime/ (vendored Python data plane)
test/           1,424 tests: integration, ports (conformance + fault), node, transport, e2e scripts
docs/           decisions/ (ADRs), design/ (target pack), references/, runbooks/

Known limitations & roadmap

Honest scope boundaries — the core pipeline works; these are deliberate v1 cuts:

  • BYOK key-stripping (LITELLM_STRIP_BYOK) is off by default; production runs BYOK-direct. Flipping it on requires the model gateway to serve every model first.
  • Modal is still the inline sandbox path. The ports/fakes/conformance harness proves the seam is swappable; formally demoting Modal to one adapter (and adding a second provider) is future work.
  • ACP agent adapters (OpenCodeAgent, AcpAgent) are Node-runtime reference adapters proven by the scripts/opencode-acp-* end-to-end loops; the live worker path uses the lower-level ACP client. Wiring the wrapper classes into the worker is future work.
  • A few platform event types (environment.changed, audit.event) are forward-declared with no producer yet.

Single-author project by Kevin Hill. Built as a deep exploration of agent-orchestrated development on Cloudflare’s edge platform.

About

Multi-tenant control plane for a hosted coding-agent SDK — Cloudflare Workers + Durable Objects + Hono + Postgres + Modal, with hexagonal ports & adapters. Live: app.omoios.dev

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors