qaml-ai/camelAI

camelAI — an AI coding assistant platform built on Cloudflare Workers and Durable Objects

TypeScript

389

3,230 commits

updated Oct 19, 2026

See the code

README

camelAI

An AI coding assistant for persistent workspaces, connected data, and deployable applications.

Website · Open camelAI · CI · MIT License

What camelAI does

camelAI gives teams persistent AI coding workspaces backed by Cloudflare. Each chat thread runs its own coding agent in a Durable Object. Users can connect external services and data, build applications, and publish them to managed app hosts.

The platform includes:

  • persistent chat threads and project files
  • AI coding agents with workspace-aware tools
  • integrations for APIs, databases, email, Slack, Discord, and other services
  • isolated application builds, notebook analysis, and SQL execution
  • previews and production publishing through Workers for Platforms
  • organization, authentication, billing, usage, and administrative controls

Quick start

Prerequisites

  • Node.js 22 or newer
  • Bun
  • a Cloudflare account with access to the development resources
  • Docker for sandbox-backed features and agent evals

Install the project and create a local secrets file:

git clone https://github.com/qaml-ai/camelAI.git
cd camelAI
bun install --frozen-lockfile
cp .dev.vars.example .dev.vars

Replace the placeholder signing and encryption secrets in .dev.vars. For hosted model access, also add a development Cloudflare AI Gateway token. You can instead configure an Anthropic, OpenAI, OpenRouter, Bedrock, or custom provider from the organization settings after the app starts.

Start the app with local authentication:

bun run dev:local-auth

Open http://localhost:3001. The local-auth command is restricted to the Vite development server and seeds a Local Dev user, organization, and workspace.

To exercise the normal OAuth flow, use:

bun run dev

The port defaults to 3001 and can be changed with VITE_DEV_PORT.

Architecture

React Router SSR + browser HTTP/SSE
                  |
                  v
       Cloudflare main Worker
                  |
                  v
       ChatThreadDO (coding agent)
       custom harness built on pi
                  |
       +----------+-----------+----------------+
       |                      |                |
       v                      v                v
Code Mode dynamic     WorkspaceFilesystemDO   Short-lived Cloudflare
Worker / V8 isolate     SQLite + R2 files      sandbox containers
JavaScript tools,       Artifacts history      build / notebook / SQL
data connections

deploy_project: project files -> build sandbox -> Workers for Platforms
                                                   |
                                                   v
                                        Dispatcher Worker -> live app

The agent is camelAI's own harness, built from pi's lower-level agent loop and state-management libraries. It is not Claude Code or Codex. Anthropic, OpenAI, OpenRouter, Bedrock, and custom endpoints can provide the underlying model, but they do not provide the agent harness.

ChatThreadDO owns the agent loop and persistent chat state. The agent uses native file tools and writes JavaScript instead of bash; Code Mode runs that JavaScript in fresh V8 isolates with explicit platform and connection methods. Credentials remain outside the execution sandbox.

Project files live in WorkspaceFilesystemDO, with small files in Durable Object SQLite and larger files in R2. Cloudflare Artifacts provides git history. Linux is reserved for short-lived jobs that need it: application builds, notebook analysis, and database queries run in dedicated Cloudflare sandbox containers. The dispatcher routes requests to published user applications.

Read Our coding agent runs in a Cloudflare Durable Object, not a VM for the design progression and tradeoffs behind this architecture.

For deeper implementation details and repository conventions, see AGENTS.md.

Repository structure

PathPurpose
src/React Router application, routes, UI, and shared libraries
workers/main/Main Worker, Durable Objects, HTTP/SSE transports, MCP, and sandbox services
workers/dispatcher/Routing for published user applications
workers/app-usage-guard/Usage monitoring and reversible app quarantine
workers/discord-bridge/Discord Gateway connection and control Worker
sandbox/Agent skills and project scaffold templates
scripts/Development, deployment, eval, and maintenance tooling
tests/Application and shared-library unit tests
workers/main/tests/Worker, Durable Object, Miniflare, and agent eval tests
e2e/Playwright end-to-end tests
infra/Self-hosting and database egress infrastructure

Development commands

Use Bun for JavaScript and TypeScript commands.

CommandPurpose
bun run devStart React Router development with Cloudflare bindings
bun run dev:local-authStart development with a seeded local identity
bun run buildCreate a production build
bun run typecheckGenerate route types and run TypeScript checks
bun run lintRun source and import checks
bun run testRun Vitest in watch mode
bun run test:runRun application and shared-library tests once
bun run test:workersRun Worker and Durable Object tests
bun run test:allRun application and Worker test suites
bun run test:e2eRun Playwright end-to-end tests

When changing UI routes or components, run typecheck and the most relevant unit tests. For Worker or Durable Object behavior, prefer a focused worker test:

bun run test:workers -- <test-file>

Agent evals require Docker and additional credentials. Run a committed eval by manifest ID:

bun run test:eval <eval-id>

The client and worker CI shards use the shared Azure azure-ci runner pool for trusted main/production branch runs when CI_RUNNER_LABELS is ["self-hosted","Linux","X64","azure-ci"]. PRs use GitHub-hosted runners. Docker smoke jobs and browser E2E retain hosted runners because they use shared container names or fixed ports. The organization runner group also enforces the trusted workflow/branch allowlist; changing a PR's runs-on cannot grant access. This trusts branch pushes and does not itself require code review. Delete CI_RUNNER_LABELS to return all new jobs to hosted runners. The Azure pool has four slots shared with run and camel-bots, capped at 8 vCPUs and 24 GiB with CPU priority over DST but no reserved cores. Each test shard uses two Vitest workers.

Self-hosting

camelAI has a supported single-machine Docker Compose target for private networks and on-premises evaluation:

bun run selfhost:init
bun run selfhost:doctor
bun run selfhost:up

The self-hosted target supports the web application, authentication, model providers, durable state, project source files and local history, project builds and deployments, notebooks, SQL execution, and browser rendering. Outbound email and password-email verification are intentionally unavailable, as is multi-node failover.

See SELF_HOSTING.md for the release-image and source-build modes, capability contract, authentication, outbound-email policy, and operator validation. Detailed requirements, Compose and provider configuration, backup, and upgrade procedures are in infra/selfhost/README.md.

Deployment

Deployment commands are intended for maintainers with access to the relevant Cloudflare account and environment secrets.

# Main application
bun run deploy:main:staging
bun run deploy:main:prod

# Published-app dispatcher
bun run deploy:dispatcher:staging
bun run deploy:dispatcher:prod

Other Workers have dedicated deploy:* scripts in package.json. Environment-specific bindings live in the corresponding wrangler*.jsonc files.

Re-applying user-app cost controls

Every app deploy (and rollback) wraps the app's Durable Object classes in an alarm throttle and sets a per-script CPU limit (USER_APP_ALARM_MIN_INTERVAL_MS, USER_APP_ALARM_DAILY_BUDGET, USER_APP_CPU_MS on the main worker; see workers/main/src/user-app-cost-controls-policy.ts). The CPU limit defaults to 15000 ms (Cloudflare's own default is 30 s). USER_APP_CPU_MS_OVERRIDES sets it per app: a comma- or whitespace-separated list of <dispatchScriptName>=<ms>, for example freight-analyzer--gmie6a=30000 other-app--acme=0, where 0 leaves that app without a cpu_ms limit. Malformed entries are ignored with a warning. The backfill script reads both from the target's wrangler.<env>.jsonc vars, so set overrides there for "already applied" to match what an upload produces. Apps deployed before a change only pick it up on their next deploy. To backfill them, replay each live app's latest cached deploy artifact:

# Dry run (default): read-only Cloudflare API calls, lists what would be redeployed
CLOUDFLARE_API_TOKEN=... bun run backfill:user-app-cost-controls --env prod --order alarm-spend --limit 20

# Redeploy, top alarm spenders first, one app at a time
CLOUDFLARE_API_TOKEN=... ADMIN_API_KEY=... bun run backfill:user-app-cost-controls \
  --env prod --apply --order alarm-spend --limit 20
  • --scripts a,b,c limits the run to those dispatch script names; --limit N stops after N redeploys; --delay-ms N sets the pause between them (default 2000).
  • Replaying uploads a new script version, which resets every Durable Object instance of that app (in-memory state and open WebSockets are dropped; storage is kept). Run it off-peak and start with a small --limit.
  • Apps are skipped when they already carry the current controls, have no artifact record in the usage-guard state, are quarantined or suspended by the usage guard, or hold a deploy lease. The summary counts each skip reason, and the script exits non-zero if any redeploy failed.
  • --apply calls POST /api/admin/apps/:dispatchScriptName/cost-controls on the target environment, so the main worker there must already include this code.

Contributing

Before opening a pull request:

bun run typecheck
bun run lint
bun run test:all

Add focused tests for behavior changes, especially around authentication, billing, persistence, file safety, and administrative operations. Follow the architecture and code conventions in AGENTS.md, and keep feature-specific documentation close to the code it describes.

License

camelAI is available under the MIT License.

qaml-ai/camelAI

camelAI — an AI coding assistant platform built on Cloudflare Workers and Durable Objects

TypeScript

389

3,230 commits

updated Oct 19, 2026

See the code

README

camelAI

An AI coding assistant for persistent workspaces, connected data, and deployable applications.

Website · Open camelAI · CI · MIT License

What camelAI does

camelAI gives teams persistent AI coding workspaces backed by Cloudflare. Each chat thread runs its own coding agent in a Durable Object. Users can connect external services and data, build applications, and publish them to managed app hosts.

The platform includes:

  • persistent chat threads and project files
  • AI coding agents with workspace-aware tools
  • integrations for APIs, databases, email, Slack, Discord, and other services
  • isolated application builds, notebook analysis, and SQL execution
  • previews and production publishing through Workers for Platforms
  • organization, authentication, billing, usage, and administrative controls

Quick start

Prerequisites

  • Node.js 22 or newer
  • Bun
  • a Cloudflare account with access to the development resources
  • Docker for sandbox-backed features and agent evals

Install the project and create a local secrets file:

git clone https://github.com/qaml-ai/camelAI.git
cd camelAI
bun install --frozen-lockfile
cp .dev.vars.example .dev.vars

Replace the placeholder signing and encryption secrets in .dev.vars. For hosted model access, also add a development Cloudflare AI Gateway token. You can instead configure an Anthropic, OpenAI, OpenRouter, Bedrock, or custom provider from the organization settings after the app starts.

Start the app with local authentication:

bun run dev:local-auth

Open http://localhost:3001. The local-auth command is restricted to the Vite development server and seeds a Local Dev user, organization, and workspace.

To exercise the normal OAuth flow, use:

bun run dev

The port defaults to 3001 and can be changed with VITE_DEV_PORT.

Architecture

React Router SSR + browser HTTP/SSE
                  |
                  v
       Cloudflare main Worker
                  |
                  v
       ChatThreadDO (coding agent)
       custom harness built on pi
                  |
       +----------+-----------+----------------+
       |                      |                |
       v                      v                v
Code Mode dynamic     WorkspaceFilesystemDO   Short-lived Cloudflare
Worker / V8 isolate     SQLite + R2 files      sandbox containers
JavaScript tools,       Artifacts history      build / notebook / SQL
data connections

deploy_project: project files -> build sandbox -> Workers for Platforms
                                                   |
                                                   v
                                        Dispatcher Worker -> live app

The agent is camelAI's own harness, built from pi's lower-level agent loop and state-management libraries. It is not Claude Code or Codex. Anthropic, OpenAI, OpenRouter, Bedrock, and custom endpoints can provide the underlying model, but they do not provide the agent harness.

ChatThreadDO owns the agent loop and persistent chat state. The agent uses native file tools and writes JavaScript instead of bash; Code Mode runs that JavaScript in fresh V8 isolates with explicit platform and connection methods. Credentials remain outside the execution sandbox.

Project files live in WorkspaceFilesystemDO, with small files in Durable Object SQLite and larger files in R2. Cloudflare Artifacts provides git history. Linux is reserved for short-lived jobs that need it: application builds, notebook analysis, and database queries run in dedicated Cloudflare sandbox containers. The dispatcher routes requests to published user applications.

Read Our coding agent runs in a Cloudflare Durable Object, not a VM for the design progression and tradeoffs behind this architecture.

For deeper implementation details and repository conventions, see AGENTS.md.

Repository structure

PathPurpose
src/React Router application, routes, UI, and shared libraries
workers/main/Main Worker, Durable Objects, HTTP/SSE transports, MCP, and sandbox services
workers/dispatcher/Routing for published user applications
workers/app-usage-guard/Usage monitoring and reversible app quarantine
workers/discord-bridge/Discord Gateway connection and control Worker
sandbox/Agent skills and project scaffold templates
scripts/Development, deployment, eval, and maintenance tooling
tests/Application and shared-library unit tests
workers/main/tests/Worker, Durable Object, Miniflare, and agent eval tests
e2e/Playwright end-to-end tests
infra/Self-hosting and database egress infrastructure

Development commands

Use Bun for JavaScript and TypeScript commands.

CommandPurpose
bun run devStart React Router development with Cloudflare bindings
bun run dev:local-authStart development with a seeded local identity
bun run buildCreate a production build
bun run typecheckGenerate route types and run TypeScript checks
bun run lintRun source and import checks
bun run testRun Vitest in watch mode
bun run test:runRun application and shared-library tests once
bun run test:workersRun Worker and Durable Object tests
bun run test:allRun application and Worker test suites
bun run test:e2eRun Playwright end-to-end tests

When changing UI routes or components, run typecheck and the most relevant unit tests. For Worker or Durable Object behavior, prefer a focused worker test:

bun run test:workers -- <test-file>

Agent evals require Docker and additional credentials. Run a committed eval by manifest ID:

bun run test:eval <eval-id>

The client and worker CI shards use the shared Azure azure-ci runner pool for trusted main/production branch runs when CI_RUNNER_LABELS is ["self-hosted","Linux","X64","azure-ci"]. PRs use GitHub-hosted runners. Docker smoke jobs and browser E2E retain hosted runners because they use shared container names or fixed ports. The organization runner group also enforces the trusted workflow/branch allowlist; changing a PR's runs-on cannot grant access. This trusts branch pushes and does not itself require code review. Delete CI_RUNNER_LABELS to return all new jobs to hosted runners. The Azure pool has four slots shared with run and camel-bots, capped at 8 vCPUs and 24 GiB with CPU priority over DST but no reserved cores. Each test shard uses two Vitest workers.

Self-hosting

camelAI has a supported single-machine Docker Compose target for private networks and on-premises evaluation:

bun run selfhost:init
bun run selfhost:doctor
bun run selfhost:up

The self-hosted target supports the web application, authentication, model providers, durable state, project source files and local history, project builds and deployments, notebooks, SQL execution, and browser rendering. Outbound email and password-email verification are intentionally unavailable, as is multi-node failover.

See SELF_HOSTING.md for the release-image and source-build modes, capability contract, authentication, outbound-email policy, and operator validation. Detailed requirements, Compose and provider configuration, backup, and upgrade procedures are in infra/selfhost/README.md.

Deployment

Deployment commands are intended for maintainers with access to the relevant Cloudflare account and environment secrets.

# Main application
bun run deploy:main:staging
bun run deploy:main:prod

# Published-app dispatcher
bun run deploy:dispatcher:staging
bun run deploy:dispatcher:prod

Other Workers have dedicated deploy:* scripts in package.json. Environment-specific bindings live in the corresponding wrangler*.jsonc files.

Re-applying user-app cost controls

Every app deploy (and rollback) wraps the app's Durable Object classes in an alarm throttle and sets a per-script CPU limit (USER_APP_ALARM_MIN_INTERVAL_MS, USER_APP_ALARM_DAILY_BUDGET, USER_APP_CPU_MS on the main worker; see workers/main/src/user-app-cost-controls-policy.ts). The CPU limit defaults to 15000 ms (Cloudflare's own default is 30 s). USER_APP_CPU_MS_OVERRIDES sets it per app: a comma- or whitespace-separated list of <dispatchScriptName>=<ms>, for example freight-analyzer--gmie6a=30000 other-app--acme=0, where 0 leaves that app without a cpu_ms limit. Malformed entries are ignored with a warning. The backfill script reads both from the target's wrangler.<env>.jsonc vars, so set overrides there for "already applied" to match what an upload produces. Apps deployed before a change only pick it up on their next deploy. To backfill them, replay each live app's latest cached deploy artifact:

# Dry run (default): read-only Cloudflare API calls, lists what would be redeployed
CLOUDFLARE_API_TOKEN=... bun run backfill:user-app-cost-controls --env prod --order alarm-spend --limit 20

# Redeploy, top alarm spenders first, one app at a time
CLOUDFLARE_API_TOKEN=... ADMIN_API_KEY=... bun run backfill:user-app-cost-controls \
  --env prod --apply --order alarm-spend --limit 20
  • --scripts a,b,c limits the run to those dispatch script names; --limit N stops after N redeploys; --delay-ms N sets the pause between them (default 2000).
  • Replaying uploads a new script version, which resets every Durable Object instance of that app (in-memory state and open WebSockets are dropped; storage is kept). Run it off-peak and start with a small --limit.
  • Apps are skipped when they already carry the current controls, have no artifact record in the usage-guard state, are quarantined or suspended by the usage guard, or hold a deploy lease. The summary counts each skip reason, and the script exits non-zero if any redeploy failed.
  • --apply calls POST /api/admin/apps/:dispatchScriptName/cost-controls on the target environment, so the main worker there must already include this code.

Contributing

Before opening a pull request:

bun run typecheck
bun run lint
bun run test:all

Add focused tests for behavior changes, especially around authentication, billing, persistence, file safety, and administrative operations. Follow the architecture and code conventions in AGENTS.md, and keep feature-specific documentation close to the code it describes.

License

camelAI is available under the MIT License.

Significant stargazers

Justin Bennett

383 followers · starred Jul 2026

ahonn

574 followers · starred Jul 2026

IceCodeNew

259 followers · starred Jul 2026

Matt Wonlaw

499 followers · starred Jul 2026