Skip to content
akku1139Public

Repository files navigation

teapot πŸ«–

A lightweight harness for running multiple autonomous AI coding agents in parallel, from your browser.

Try it in 5 minutes β†’ Quick start Β· Details live in the Reference section

Ask DeepWiki


πŸš€ Quick start

1. Install

Requires Node.js 24+.

npm install -g teapot-coding-agent

2. Run it

teapot

β†’ Open http://localhost:7788. A setup wizard walks you through provider β†’ API key β†’ model β†’ first agent (it writes the config file for you) β€” no hand-editing required.

Prefer writing the config yourself?
{
  "providers": {
    "openrouter": {
      "baseUrl": "https://openrouter.ai/api/v1",
      "apiKey": "sk-or-your-key",
      "model": "anthropic/claude-sonnet-4"
    }
  },
  "defaultProvider": "openrouter",
  "agents": [
    { "id": "main", "workspace": "/home/you/my-project" }
  ]
}

Save it at ~/.config/teapot-coding-agent/config.json (or pass a path as the first CLI arg / $TEAPOT_CONFIG). A full template lives in teapot.config.example.json. With a config present the wizard is skipped and your agents start immediately.

3. Use it

  • Click #main in the left panel (created by the wizard)
  • Type an instruction in the composer (e.g. "Fix this bug and make the tests pass")
  • The agent reads/writes files, runs bash, and works on its own

Handy keys: t terminal Β· d right panel Β· / commands Β· Esc interrupt


πŸ€” What is this?

One line: a server that hosts several autonomous coding agents over any OpenAI-compatible API, operated from a browser.

β”œβ”€ agent: android  ── ~/projects/android-app
β”œβ”€ agent: kernel   ── ~/projects/kernel
└─ agent: web      ── ~/projects/film-sims-web

Each agent owns its own workspace and runs in parallel as a channel in a Discord-style UI. teapot is not a wrapper around Claude Code or Codex CLI β€” it implements its own agent loop (read_file / edit_file / apply_patch / bash / read_url / memory / skills).

When would I use it?

  • Long-running self-directed tasks like "triage every bug in this repo and fix them until tests pass"
  • Different models per project β€” heavy work on Sonnet, code review on a local Qwen
  • Watch progress, goals and task lists in the browser while you do something else

How does it compare to CLI tools?

teapot Claude Code & similar CLIs
Form resident server + web UI interactive terminal
Multiple agents βœ… parallel usually one session
Mixed models βœ… per agent fixed
Long-running work βœ… auto-restores from JSONL logs manual session juggling
Scheduled tasks (cron) βœ… 15-second tick ❌

πŸ”§ Features

Goals & autonomous loop

Set a goal and auto-continue keeps deciding whether to keep working after each round. Optionally attach a verification contract β€” when the agent calls finish, an independent auditor LLM checks the contract before "done" counts:

goal:    "Add account deletion to the auth module"
verify:  "npm test passes with zero failures / README documents the endpoint"
              ↓ on finish
independent audit β†’ approved β‡’ done Β· changes-required β‡’ gaps queued back to the worker
Sub-agents

Spawn sub-agents with @persona <task> mentions. Children can fork the parent conversation by reference, so provider prefix caches stay warm. wait_children parks the parent until a child settles; its report lands in the parent's timeline. Nesting cap via maxSpawnDepth (default 3).

Memory / task list / skills
  • memory.md β€” durable notes per session (set_memory / get_memory)
  • todo.md β€” checklist shared with the operator; supports surgical per-item updates
  • skills β€” reusable playbooks stored globally (~/.config/teapot-coding-agent/skills/) or per workspace; workspace versions shadow global ones
Scheduled tasks (cron)
{ "tasks": [{ "id": "nightly", "agent": "main",
              "schedule": "0 3 * * *", "prompt": "Check git status and test results, report anything broken" }] }
Integrated terminal

Press t for an interactive shell inside the selected agent's workspace (xterm.js over WebSocket). The PTY comes from util-linux script when available, with a plain-pipe fallback β€” zero native dependencies.

File tree with previews & editing

Browse the workspace from πŸ—‚ files in the right panel: shiki syntax highlighting for code, rendered preview for Markdown, inline playback for images/video/audio, and in-place text editing that saves back to disk (409 on write conflicts).

Context management

Past a token budget (default: 75% of the model's window, or 96k if unknown), older turns are summarized by the LLM so work continues. Goals, memory and skills live in separate files, so context survives restarts and next-day resumes.


⚠️ Security (please read)

Agents can run bash and rewrite files β€” including rm and npm install.

  • Designed to run under a dedicated Linux user
  • git commit before handing over a repo you care about
  • File operations outside the workspace are rejected (safeJoin), but agents can use bash outside of the worktree
  • teapot listens on localhost only by default. If you expose it, set both --host 0.0.0.0 and an API token (TEAPOT_API_TOKEN env or config password):
TEAPOT_API_TOKEN=mysecret teapot --host 0.0.0.0 --port 7788

πŸ“– Reference

Config reference
Key Default Meaning
port 7788 listen port (env TEAPOT_PORT, CLI --port/-p)
host 127.0.0.1 bind address (env TEAPOT_HOST, CLI --host; 0.0.0.0 exposes to LAN)
dataDir ~/.local/share/teapot-coding-agent session logs etc. (env TEAPOT_DATA_DIR)
providers.<name> β€” { baseUrl, apiKey, model? } OpenAI-compatible endpoint
defaultProvider β€” used when an agent doesn't specify one
agents[].id required URL key / display name
agents[].workspace required working directory
agents[].provider / model inherited per-agent overrides
agents[].contextWindowTokens auto-inferred model's real window (drives gauge + compaction)
agents[].readOnly false true blocks mutating tools
agents[].autoContinue true keep looping toward an active goal
contextTokenBudget derived compaction threshold in raw tokens; null/unset = 75% derivation (recommended)
maxSpawnDepth 3 sub-agent nesting limit
password β€” API auth (env TEAPOT_API_TOKEN wins)
tasks[] β€” cron tasks { id, agent, schedule, prompt }
onError retry round-fatal errors (API outages, runaway trips): retry waits retryDelayMs (doubling, ≀10 min) then starts a fresh round; stop ends with status=error
retryDelayMs 60000 base backoff for onError: retry

Lookup order: CLI arg β†’ $TEAPOT_CONFIG β†’ ~/.config/teapot-coding-agent/config.json β†’ ./teapot.config.json

Several model presets on one API key

A provider entry is just { baseUrl, apiKey, model }, so "one key, many models" is one entry per model β€” repeat the same baseUrl/apiKey and vary model. Each agent then names the preset it wants:

{
  "providers": {
    "or-sonnet": { "baseUrl": "https://openrouter.ai/api/v1", "apiKey": "sk-or-...", "model": "anthropic/claude-sonnet-4" },
    "or-opus":   { "baseUrl": "https://openrouter.ai/api/v1", "apiKey": "sk-or-...", "model": "anthropic/claude-opus-4" },
    "or-haiku":  { "baseUrl": "https://openrouter.ai/api/v1", "apiKey": "sk-or-...", "model": "anthropic/claude-haiku-4" }
  },
  "defaultProvider": "or-sonnet",
  "agents": [
    { "id": "main", "workspace": "~/proj", "provider": "or-sonnet" },
    { "id": "deep", "workspace": "~/proj", "provider": "or-opus" }
  ]
}

Switching an agent's model in the right panel never disturbs the others, and an agent may still pin its own model to override the preset's.

Mixing providers
{
  "providers": {
    "openrouter": { "baseUrl": "https://openrouter.ai/api/v1", "apiKey": "sk-or-..." },
    "local":      { "baseUrl": "http://localhost:8080/v1", "apiKey": "llama.cpp" }
  },
  "defaultProvider": "openrouter",
  "agents": [
    { "id": "coder",    "workspace": "~/proj", "model": "anthropic/claude-sonnet-4" },
    { "id": "reviewer", "workspace": "~/proj", "provider": "local" }
  ]
}

Anything OpenAI-compatible works: OpenRouter / OpenAI / OpenCode Go / Ollama / vLLM / llama.cpp. Requests to openrouter.ai automatically carry app-attribution headers; requests to opencode.ai carry a stable x-opencode-session, which OpenCode Go refuses to route a conversation without.

Model context windows are inferred from /v1/models at startup and drive the runtime gauge plus the derived compaction budget (manual override supported).

HTTP API
GET  /api/agents                        list
POST /api/agents                        create { workspace, id?, provider?, model?, start? }
GET  /api/agents/:id/events?limit=300   events ( ?before=<id> pages upward )
GET  /api/agents/:id/branches           branch list
GET  /api/agents/:id/file?path=         fetch text file
PUT  /api/agents/:id/file?path=         save { content, baseContent? } (409 on conflict)
GET  /api/agents/:id/raw?path=          raw media bytes
GET  /api/agents/:id/tree               file tree
POST /api/agents/:id/prompt             send { text, start?, images?: [{url}] } β†’ { promptId }
POST /api/agents/:id/prompt/cancel      withdraw { promptId } (409 once delivered)
POST /api/agents/:id/goal               { text?, status?, verify? }
POST /api/agents/:id/start|stop|fork|load
DELETE /api/agents/:id                  remove (logs kept)
GET  /api/metrics                       RSS / heap / loadavg
WS   /api/ws                            live event stream

All API routes honor optional bearer auth.

Session log (JSONL) format

Append-only JSONL you can read with cat/jq:

{"v":1,"id":"e1","type":"prompt","data":{"source":"user","text":"..."}}
{"v":1,"id":"e2","type":"tool_call","data":{"callId":"…","name":"bash","argsRaw":"…"}}
{"v":1,"id":"e3","type":"tool_result","data":{"callId":"…","ok":true,"durationMs":117}}
{"v":1,"id":"e4","type":"message","data":{"role":"assistant","content":"…"}}

Each event links to its parent, forks share the branch point, and goal.md / memory.md / todo.md live beside chat.jsonl under sessions/<agent>-<uuid>/.

Development (from a checkout)
pnpm install
pnpm dev            # run TypeScript natively
pnpm dev-web        # Vite HMR (separate terminal)
pnpm test           # node --test
pnpm build          # tsc + vite build β†’ dist/ + public/

Layout: src/master.ts (boot/cron/config) Β· src/agent/ (loop/tools) Β· src/server/api.ts (Hono REST+WS) Β· frontend/ (SolidJS) Β· test/ (node:test)


License

AGPL-3.0-or-later β€” LICENSE

Releases

Packages

Contributors

Languages