尚未检测到更新。GitHub 发布版本后会显示在这里。
制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Persistent AI teammates with their own sandbox computers. You create a bot, give it a job, and it keeps working on that job across restarts — on your machine or on a remote sandbox, with you approving the actions that matter.
Modeled on Cursor's Grok Bot. A bot calls
whatever provider you configure — Anthropic, OpenAI, or any OpenAI-compatible
endpoint — and that choice is stored in the app, not hard-wired in .env.
bash, read, write, edit, ls) run inside
a sandbox, either a Docker container or — for development only — your own
machine. Switching a bot between sandbox targets is a config change; the
workspace on each target is separate and does not follow.read / write /
external and held for approval according to the bot's mode. Rules may only
tighten what a mode allows, never loosen it.--internal
network behind a bridging proxy, so only an allowlist gets out. MCP servers
are a separate egress path and are only covered when applyToMcp is set.@name.Needs Node 22 or newer (node:sqlite), and Docker if you want real isolation.
pnpm install
cp .env.example .env # optional: seed a provider on first run
pnpm dev # http://localhost:4000
The API is behind a bearer token. One is generated into .env on first run if
AUTH_TOKEN is empty; the web UI picks it up automatically on localhost.
Open the sidebar and choose 模型. Add a provider (a preset fills the base
URL, the API style, and a couple of model ids), paste an API key, and use
测试连接 before saving. Pick a default model there. Each bot can override
it from its own settings sheet. Keys are stored in sqlite and only ever shown
back masked (sk-a…wxyz); they are not written into logs or into the
models.json PI reads (that file holds a $ENV reference).
On a database that has no providers yet, the first launch imports one from the environment so an existing install keeps working:
ADA_TOKEN + ADA_BASE_URL (+ optional PI_MODEL) — the previous
Anthropic-messages gateway. This stays the default when both seeds are set.ANTHROPIC_API_KEY (+ optional MODEL_ID) — Anthropic directly.After that, .env is not consulted again. Edit providers in the UI.
In 模型 → 添加提供商 the DeepSeek preset is the one the form opens on. It fills:
| Field | Value |
|---|---|
| 接口 | openai-chat-completions |
| Base URL | https://api.deepseek.com |
| 模型 | deepseek-chat (and deepseek-reasoner, which you can remove) |
Create a key at platform.deepseek.com, paste it,
hit 测试连接, save, and set deepseek-chat as the default. deepseek-chat
is the one that tool-calls. A single bot can be pointed at a different model
from 设置 → 模型 without changing the default.
Desktop app:
pnpm app # run from source
pnpm dmg # signed DMG (needs an Apple Developer ID)
| Path | What lives there |
|---|---|
src/pi/ | The agent loop: PI session per bot, approval gate, tools |
src/agent/ | Store, permission policy, bash classification, routines |
src/sandbox/ | Local and Docker drivers, egress proxy, target resolution |
src/server/ | HTTP + WebSocket, run lifecycle, scheduler, group chat |
src/web/ | The UI, one file |
desktop/ | Electron wrapper |
scripts/ | Tests (see below) |
website/ | Product site, static. See website/README.md |
docs/ | Architecture notes. See docs/architecture.md |
想看整体结构,读 docs/architecture.md:16 张 Mermaid 图,
按仓库里的实现画的 —— 总览、一次对话回合、审批门怎么判、模型提供商怎么存
key、沙箱与出网白名单、sqlite 里的实体关系,以及 website/ 为什么不参与
pnpm build。代码和 README 对不上的地方,文档里标了「待核实」。
pnpm test # offline: typecheck, store, policy, routines, egress, providers
pnpm test:live # needs ADA_TOKEN; drives a real model and a real browser
pnpm test:live includes pnpm intent (does the model actually reach for
ask_choice and schedule_routine?), pnpm budget (does a hung turn get cut
off, and does a slow human decision avoid counting as a stall?), and
pnpm browser (54 checks through a real Chrome).
local sandbox driver provides no isolation at all and needs
SANDBOX_ALLOW_LOCAL=1 to start. It's for development.Sandbox.exec takes a timeout but no AbortSignal, so a running command
can't be interrupted — only waited out or timed out. The turn budget works
around this by abandoning the session rather than blocking on it.