把自然语言描述转为结构化 JSON,并由 mcp-diagram-generator MCP 服务生成 Draw.io、Mermaid 或 Excalidraw 图表文件。
集成
pibox
试用Install, configure, or run pi-coding-agent through the pibox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.
它能做什么
pi-coding-agent inside an aicodebox container. One image, seven ways in: interactive shell, one-shot exec, HTTP REST API, OpenAI-compatible endpoint, MCP server, Telegram bot, cron scheduler.
技能文档
pibox
pi-coding-agent inside an aicodebox container. One image, seven ways in: interactive shell, one-shot exec, HTTP REST API, OpenAI-compatible endpoint, MCP server, Telegram bot, cron scheduler.
You talk to pibox, pibox talks to pi, pi talks to whatever Anthropic-compatible LLM you point it at (ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN).
For installation and configuration, see references/setup.md.
Security & safety
- No auth when
PIBOX_API_MODE_TOKENis unset. With it empty the REST/OpenAI-compatible API surface is UNAUTHENTICATED — anyone who can reach it gets full agent-execution and workspace file-read/write/delete access. NEVER expose such an instance on a network or to untrusted agents; set the token and bind to loopback / behind an authenticating proxy. - No auth when
PIBOX_MCP_MODE_TOKENis unset. Same story for the MCP surface (/mcpor the sidecar) — empty token means unauthenticatedrun_prompt/file-tool access, and it does not fall back toPIBOX_API_MODE_TOKEN. Set it explicitly. - Destructive & irreversible.
DELETE /run/{id},DELETE /files/{path}, and the MCPdelete_filetool remove state with no undo (canceled runs can't be resumed; deleted files are gone). An agent must NEVER call these unless the user explicitly asked for that exact action; confirm the specific target first, scope it to the current task, and never enumerate-then-bulk-delete. On a shared/multi-tenant instance a deletion can destroy another caller's in-flight run or workspace file — treat these routes as admin-only.
When To Use
- Drive pi-coding-agent from a script/service instead of an interactive terminal (
/run,/openai/v1/chat/completions, or MCP tools). - Wire pi into an OpenAI-SDK-compatible client (LangChain, openai-python) via the
/openai/v1/*surface. - Give an MCP-aware agent (Claude, Cursor, OpenClaw) remote tool access to a pi-driven workspace.
- Chat with pi from Telegram, with per-chat model/effort overrides and file transfer.
- Schedule recurring pi runs (standups, digests, periodic maintenance) via cron mode.
- One-off container run for a single prompt (CI step, quick script) via one-shot exec.
When NOT To Use
- Don't run two foreground modes together except Telegram+Cron (cron runs in-thread inside telegram) — API set alongside anything else wins and the others don't start.
- Don't expect
/openai/v1/chat/completionsto stream token-by-token whentoolsor a JSON schema is in play — those modes compute the full answer first and replay it as a single-shot SSE stream (still a valid stream, just not incremental). Plain chat streams incrementally. - Don't rely on
PIBOX_MCP_MODE_TOKENfalling back toPIBOX_API_MODE_TOKEN— MCP has its own bearer, no fallback. - Don't point multiple concurrent runs at the same workspace — the API/OAI layer returns 409 "workspace busy" while a run is in flight in that workspace.
Interactive shell mode
No mode env var set, no args passed to docker run. Falls through to pi's own CLI, invoked directly — a normal interactive pi session inside the container.
docker run -it --rm \
-e ANTHROPIC_AUTH_TOKEN=your-token \
-e ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
-e ANTHROPIC_MODEL=glm-4.6 \
-v "$PWD/workspace:/workspace" \
psyb0t/pibox:latest
Auth: none at the container boundary — you're inside it. pi itself uses the ANTHROPIC_* env vars.
One-shot exec mode
No mode env var set, args passed after the image name are forwarded verbatim to the pi binary (passthrough). -p "" runs pi non-interactively and prints the result to stdout, then exits.
docker run --rm \
-e ANTHROPIC_AUTH_TOKEN=your-token \
-e ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
-e ANTHROPIC_MODEL=glm-4.6 \
-v "$PWD/workspace:/workspace" \
psyb0t/pibox:latest \
-p "list the files in /workspace"
Any pi CLI flag works here (--model, --thinking, --session, etc.) — the entrypoint just execs pi "$@". Auth: none at the container boundary; pi uses ANTHROPIC_*.
REST API mode
PIBOX_API_MODE=1. FastAPI server on :8080 (override PIBOX_API_MODE_PORT). Requires PIBOX_AVAILABLE_MODELS= — the server refuses to boot without it (no sensible default; pi can drive any provider's models).
docker run -d --network host \
-e PIBOX_API_MODE=1 \
-e PIBOX_API_MODE_TOKEN=your-secret \
-e PIBOX_AVAILABLE_MODELS=glm-4.6,glm-4.5-air \
-e ANTHROPIC_AUTH_TOKEN=your-token \
-e ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
-e ANTHROPIC_MODEL=glm-4.6 \
-v "$PWD/workspace:/workspace" \
psyb0t/pibox:latest
| Method | Path | What it does |
|---|---|---|
GET | /healthz | liveness — {ok, adapter}, unauthenticated |
GET | /status | in-flight runs + busy workspaces |
POST | /run | run the agent — sync by default; body async or fireAndForget makes it fire-and-poll |
GET | /run/result?runId= | poll a run started with async/fireAndForget |
DELETE | /run/{id} | cancel an in-flight run (kills the subprocess) |
GET | /files | list the workspace root — {entries: [{name, type, size?}, ...]} |
GET | /files/{path} | list a sub-directory, or stream a file's bytes |
PUT | /files/{path} | upload — raw request body becomes the file contents; parent dirs auto-created |
DELETE | /files/{path} | delete a file (refuses directories — 400) |
POST | /openai/v1/chat/completions | OpenAI-compatible chat (see below) |
GET | /openai/v1/models | model list, from PIBOX_AVAILABLE_MODELS |
POST | /mcp | MCP server (streamable HTTP) — mounted only when PIBOX_MCP_MODE=1 |
All /files/* paths resolve against the workspace root with traversal checking — .. segments that escape the root return 400. Every route except /healthz is gated by Authorization: Bearer when that var is set; empty/unset token = no auth.
No auth when PIBOX_API_MODE_TOKEN is unset. With it empty the API is UNAUTHENTICATED — anyone who can reach it gets run-the-agent and workspace file-read/write/delete access. NEVER expose such an instance on a network or to untrusted agents; set the token and bind to loopback / behind an authenticating proxy.
Destructive & irreversible. DELETE /run/{id} kills the in-flight subprocess with no undo, and DELETE /files/{path} deletes a workspace file with no undo. An agent must NEVER call either unless the user explicitly asked for that exact action; confirm the specific target first; scope it to the current task; never enumerate-then-bulk-delete. On a shared/multi-tenant instance this can disrupt or destroy another caller's run or data — treat these routes as admin-only.
# sync run
curl -s http://localhost:8080/run \
-H "Authorization: Bearer your-secret" \
-H "Content-Type: application/json" \
-d '{"prompt": "say HELLO", "workspace": "/workspace"}'
# async run, then poll
RUN_ID=$(curl -s http://localhost:8080/run \
-H "Authorization: Bearer your-secret" -H "Content-Type: application/json" \
-d '{"prompt": "long task", "async": true}' | jq -r .runId)
curl -s "http://localhost:8080/run/result?runId=$RUN_ID" \
-H "Authorization: Bearer your-secret"
# cancel it
curl -s -X DELETE "http://localhost:8080/run/$RUN_ID" \
-H "Authorization: Bearer your-secret"
# upload / download / list / delete a workspace file
curl -sS -X PUT -H "Authorization: Bearer your-secret" \
--data-binary @local.txt http://localhost:8080/files/notes/hello.txt
curl -sS -H "Authorization: Bearer your-secret" \
http://localhost:8080/files/notes/hello.txt
curl -sS -H "Authorization: Bearer your-secret" \
http://localhost:8080/files/notes | jq
curl -sS -X DELETE -H "Authorization: Bearer your-secret" \
http://localhost:8080/files/notes/hello.txt
POST /run body fields: prompt (required), workspace, model, systemPrompt, appendSystemPrompt, jsonSchema, noContinue, resume, timeoutSeconds, thinking, noTools, toolsAllowlist, extraArgs, async, fireAndForget, includeRaw. With jsonSchema set the response is verbose: text, json (schema-validated), events, sessionId, usage, attempts (per-retry breakdown, up to 3 self-correction retries on parse/validation failure). Without jsonSchema the response is lean: {runId, workspace, exitCode, text}.
OpenAI-compatible endpoint mode
Same PIBOX_API_MODE=1 server, POST /openai/v1/chat/completions and GET /openai/v1/models. Drop-in for any OpenAI-SDK client — point the base URL at http://host:8080/openai/v1 and set the model to one of PIBOX_AVAILABLE_MODELS.
curl -s http://localhost:8080/openai/v1/chat/completions \
-H "Authorization: Bearer your-secret" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-4.6",
"messages": [{"role": "user", "content": "say HELLO"}]
}'
Streaming ("stream": true): plain chat streams incrementally, one SSE chunk per token delta. Requests carrying tools or a JSON-schema constraint can't stream token-by-token (the answer only exists once fully computed) — they're buffered: the whole response is computed, then replayed as a single-shot SSE stream (role chunk → one content/tool_calls delta → finish chunk → [DONE]). The client's streaming parser is satisfied either way.
Tools / tool_choice (OpenAI client-executed tool calling): send tools (OpenAI function-schema array) and optionally tool_choice (auto/none/required/{"type":"function","function":{"name":...}}). pibox's own internal tools (bash, file edits) default OFF while in tool mode so the model behaves as a pure function-calling LLM — override with header x-aicodebox-no-tools: 0 to re-enable the hybrid. The response comes back as tool_calls + finish_reason: "tool_calls", exactly like OpenAI; you execute the tool client-side and send the result back in the next message round.
response_format / JSON-schema: standard OpenAI response_format body field —{"type": "text"} (default), {"type": "json_object"} (force parseable JSON, no shape constraint), or {"type": "json_schema", "json_schema": {"name": ..., "schema": {...}}} (schema-validated, with up to 3 self-correction retries on failure → 422 if still invalid). tools and response_format compose in one request: a tool-call turn returns tool_calls (not schema-checked); the model's final answer (no more tool calls) is what gets schema-validated.
Extra x-aicodebox-* headers (workspace pinning, session continuation, extra args, timeout, tools allowlist) are documented in references/setup.md. Upstream provider errors (auth failure, rate limit, content-safety rejection) surface as HTTP 400, not a silent empty response.
MCP server mode
PIBOX_MCP_MODE=1. Exposes an MCP (streamable HTTP) surface with 5 tools: run_prompt, list_files, read_file, write_file, delete_file. Coexists with any foreground mode:
| Foreground | MCP placement |
|---|---|
API mode (PIBOX_API_MODE=1) | mounted at /mcp on the API port — no extra process |
| Telegram / Cron / passthrough / none | sidecar uvicorn on its own port, PIBOX_MCP_MODE_PORT (default 8081), mounted at the port root |
claude mcp add --transport http pibox http://localhost:8080/mcp \
--header "Authorization: Bearer your-mcp-token"
Raw JSON-RPC (debugging, non-MCP-aware callers):
curl -s http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer your-mcp-token" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
run_prompt(prompt, workspace?, model?, system_prompt?, append_system_prompt?, no_continue=true, resume?, thinking?, json_schema?) invokes the agent and returns its text. list_files/read_file/write_file/delete_file operate on workspace-relative paths with the same traversal guard as the REST /files endpoints.
Destructive & irreversible. delete_file removes a workspace file with no undo. An agent must NEVER call it unless the user explicitly asked for that exact action; confirm the specific target first; scope it to the current task; never enumerate-then-bulk-delete. On a shared/multi-tenant instance this can destroy another caller's workspace data — treat it as admin-only.
Auth: PIBOX_MCP_MODE_TOKEN= — bearer via Authorization: Bearer …, or ?apiToken=… query param for clients that can't set headers. Empty = no auth. No fallback to PIBOX_API_MODE_TOKEN.
No auth when PIBOX_MCP_MODE_TOKEN is unset. With it empty the MCP surface is UNAUTHENTICATED — anyone who can reach it gets run_prompt (arbitrary agent execution) and workspace file read/write/delete access. NEVER expose such an instance on a network or to untrusted agents; set the token and bind to loopback / behind an authenticating proxy.
Telegram bot mode
PIBOX_TELEGRAM_MODE=1 + PIBOX_TELEGRAM_MODE_TOKEN=.
- Text in → pi runs → Markdown→HTML rendered response back.
- File uploads land in the chat's workspace.
[SEND_FILE: path]in pi's output delivers workspace files as Telegram attachments. - Per-chat overrides:
/model,/effort(maps to pi's--thinkinglevels),/system_prompt,/append_system_prompt. Persisted across restarts. /cancelkills the in-flight run./reloadre-reads config./configdumps merged settings./statusshows in-flight state./fetchdownloads a file./start,/helpfor basics.- Replies to cron messages inject the job's instruction + result so pi has full context for follow-ups.
Config at $HOME/.aicodebox/telegram.yml (override via PIBOX_TELEGRAM_MODE_CONFIG):
allowed_chats: [-100123, 42]
default:
model: glm-4.6
workspace: shared
chats:
-100123:
workspace: alpha
allowed_users: [10, 20]
Auth: chat/user allowlisting via the config yaml (allowed_chats, per-chat allowed_users) — no separate bearer token, the bot token itself gates who can even message it.
Cron scheduler mode
PIBOX_CRON_MODE=1 + PIBOX_CRON_MODE_FILE=/path/to/cron.yaml. 6-field cron schedules via croniter. Each job fires pi with the given instruction on schedule.
jobs:
- name: morning-standup
schedule: "0 0 9 * * 1-5"
instruction: |
Summarize what changed in /workspace since yesterday.
Be brief. One paragraph max.
workspace: myproject
telegram_chat_id: -100123
model: glm-4.6
thinking: low
Each run gets a history dir at $HOME/.aicodebox/cron/history//-/ (override root via PIBOX_CRON_MODE_HISTORY_DIR) with meta.json, stdout.log, stderr.log, result.txt. If telegram is also configured, telegram.json lands there too and the next run's prompt gets a "prior run" hint so pi can reference its own history without you wiring it up. Running alongside Telegram mode (PIBOX_TELEGRAM_MODE=1 + PIBOX_CRON_MODE=1) runs cron in-thread inside the telegram process — the only foreground-mode pairing allowed.
Auth: none — this is a scheduled background job, not a request-driven surface. telegram_chat_id on a job routes its result through the (already-authenticated) Telegram bot if set.
Auth (LLM upstream)
pi speaks the Anthropic wire protocol. Point it at any Anthropic-compatible endpoint via env vars, forwarded into every mode:
| Var | Purpose |
|---|---|
ANTHROPIC_AUTH_TOKEN | Bearer token (Z.AI, direct Anthropic, etc.) |
ANTHROPIC_API_KEY | Same thing — pi reads both |
ANTHROPIC_BASE_URL | Endpoint override (default https://api.anthropic.com) |
ANTHROPIC_MODEL | Default model when the caller doesn't specify one |
Z.AI's GLM models are a fast/cheap default: ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic + ANTHROPIC_MODEL=glm-4.6.
pi's thinking levels (--thinking): off, minimal, low, medium, high, xhigh. Exposed as /effort in Telegram mode and thinking in API/OAI requests.
Surface-level auth (separate from the LLM upstream) is per-mode: PIBOX_API_MODE_TOKEN gates the REST + OAI routes, PIBOX_MCP_MODE_TOKEN gates MCP (no fallback between the two), Telegram gates by bot-token possession + chat/user allowlist, cron and interactive/exec modes have no surface auth (container-boundary trust). Both PIBOX_API_MODE_TOKEN and PIBOX_MCP_MODE_TOKEN default to empty, which means no auth — see Security & safety above before exposing either surface beyond localhost.
Typical Workflows
One-off task from a script, no server:
docker run --rm -e ANTHROPIC_AUTH_TOKEN=$TOKEN -e ANTHROPIC_BASE_URL=$BASE_URL \
-e ANTHROPIC_MODEL=glm-4.6 -v "$PWD:/workspace" \
psyb0t/pibox:latest -p "summarize the diff in /workspace"
Long-running server, drive it with curl:
docker run -d --network host -e PIBOX_API_MODE=1 -e PIBOX_API_MODE_TOKEN=$SECRET \
-e PIBOX_AVAILABLE_MODELS=glm-4.6 -e ANTHROPIC_AUTH_TOKEN=$TOKEN \
-e ANTHROPIC_BASE_URL=$BASE_URL -v "$PWD/workspace:/workspace" psyb0t/pibox:latest
curl -s http://localhost:8080/run -H "Authorization: Bearer $SECRET" \
-H "Content-Type: application/json" -d '{"prompt": "run the tests and report failures"}'
Structured extraction via JSON schema:
curl -s http://localhost:8080/run -H "Authorization: Bearer $SECRET" \
-H "Content-Type: application/json" \
-d '{"prompt": "extract TODOs from /workspace", "jsonSchema": {"type":"object","properties":{"todos":{"type":"array","items":{"type":"string"}}},"required":["todos"]}}'
Wire an MCP-aware agent (Claude Code, OpenClaw) to a running pibox:
claude mcp add --transport http pibox http://localhost:8080/mcp \
--header "Authorization: Bearer $MCP_TOKEN"
Chat + Telegram + scheduled digest, all on one box:
docker run -d --network host \
-e PIBOX_TELEGRAM_MODE=1 -e PIBOX_TELEGRAM_MODE_TOKEN=$BOT_TOKEN \
-e PIBOX_CRON_MODE=1 -e PIBOX_CRON_MODE_FILE=/config/cron.yaml \
-e ANTHROPIC_AUTH_TOKEN=$TOKEN -e ANTHROPIC_BASE_URL=$BASE_URL \
-v "$PWD/workspace:/workspace" -v "$PWD/cron.yaml:/config/cron.yaml:ro" \
psyb0t/pibox:latest
相关技能
在本地磁盘以分类纯 Markdown 文件保存需要长期留存的事实,与智能体内置记忆并存。
以 AI 机器人身份加入视频会议,提供语音、虚拟形象与屏幕共享四种模式。
诊断生产力系统反复失效的根因,给出最小干预——容量测算、瓶颈定位、可靠的本地记录。
通过一次 REST API 调用,向 10 个社交平台发布视频、图片、文字与文档。
通过一个命令行工具完成多链加密货币交易、钱包管理与 AI 市场分析。
psyb0t 的更多技能
浏览全部技能对接用户自部署的 mt5-httpapi MetaTrader 5 网关,每次涉及真实资金的写操作都必须逐笔确认后再执行。
面向反爬检测栈 QA 与授权测试场景的 Docker 浏览器自动化工具。
自托管、OpenAI 兼容的语音服务,一个容器搞定转写、翻译与合成。
在固定白名单的 SSH 沙箱里跑 ffmpeg、sox、ImageMagick 处理音视频和图片。
通过 SSH 调用 Qwen3-TTS 生成语音,支持预设音色、声音克隆与声音设计。
一个端点统一管控多个 IMAP/SMTP 邮箱,跨账号并行完成读取、检索、发送、标记与删除。