Wenlan
Wenlan is a source-backed AI knowledge base and LLM wiki for AI work: organize documents and decisions into pages you can find, inspect, and review.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full 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.