Python port of the pi agent harness (reference: ../pi).
- Skills guide
- Prompt templates guide
- Extensions guide
- Providers guide
- Sessions guide
- RPC protocol
- SDK guide
- App template (
templates/my-app)
# 1) Create local resources
mkdir -p .pi/{skills/demo-skill,prompts,extensions}
cat > .pi/skills/demo-skill/SKILL.md <<'EOF'
---
name: demo-skill
description: Demo skill that asks for concise output.
---
Always answer in 3 bullets max.
EOF
cat > .pi/prompts/review.md <<'EOF'
---
description: Quick review template
argument-hint: "<path>"
---
Review $1 for bugs and missing tests.
EOF
cat > .pi/extensions/demo.py <<'EOF'
def register(pi):
def on_discover(event, ctx):
return {"promptPaths": [f"{ctx.cwd}/.pi/prompts"]}
def on_tool_call(event, ctx):
if event.get("toolName") == "bash":
cmd = event.get("input", {}).get("command", "")
if isinstance(cmd, str) and "rm -rf" in cmd:
return {"block": True, "reason": "blocked by demo extension"}
return None
pi.on("resources_discover", on_discover)
pi.on("tool_call", on_tool_call)
EOF# 2) Run interactive mode and try expansions
./pipy-test.sh --provider faux --model faux/test
# In REPL:
# /review README.md
# /skill:demo-skill tighten output
# /reload# 3) Inspect resources via RPC
pipy --mode rpc --no-session --provider faux --model faux/test
# Send lines:
# {"id":"1","type":"get_commands"}
# {"id":"2","type":"get_resource_diagnostics"}
# {"id":"3","type":"reload"}| Package | Role |
|---|---|
pi_ai |
LLM API + models.json registry |
pi_agent |
Agent loop, tool execution, events |
pi_coding_agent |
CLI print mode, read + bash tools |
uv sync
uv run pytest
./pipy-test.sh --help- Interactive auth commands:
/login <provider> <key>,/logout <provider> - RPC auth commands:
{"type":"login","provider":"...","key":"..."},{"type":"logout","provider":"..."} - Session navigation commands:
/tree,/clone [entryId] - Session utility commands:
/new,/name <name>,/resume - Provider runtime support:
openai,anthropic,google,faux
azure-openai-responsesandamazon-bedrockare registered for model discovery and parity tracking, but runtime adapters are explicit placeholders (they return a not-implemented stream error)- Interactive mode is terminal REPL only (no pi TUI/theme/keybindings)
- Full runtime support for placeholder providers (
azure-openai-responses,amazon-bedrock) - Wider provider coverage beyond the current subset
- TUI/theme/keybindings parity and additional UX commands such as sharing flows
piPy reads ~/.pi/agent/models.json — the same file as pi. You can copy
docs/models.json.example or share your existing pi config.
Config directory override (same env as pi):
export PI_CODING_AGENT_DIR=~/.pi/agent # optional; default is ~/.pi/agentFeatures aligned with pi MVP:
- JSON with
//comments and trailing commas - Custom providers (
baseUrl,api,apiKey,models) - Built-in provider overrides (
baseUrl,compat,modelOverrides) apiKeyas env var name, literal, or!shell commandcompat.thinkingFormat: "qwen"for DashScope- APIs:
openai-completions,anthropic-messages
Built-in models (without models.json): openai/gpt-4o-mini, anthropic/claude-sonnet-4-5, anthropic/claude-haiku-4-5.
export ANTHROPIC_API_KEY=sk-ant-...
./pipy-test.sh --model anthropic/claude-sonnet-4-5 -p "List files here"mkdir -p ~/.pi/agent
cp docs/models.json.example ~/.pi/agent/models.json
export DASHSCOPE_API_KEY=sk-...
./pipy-test.sh --model dashscope/qwen-plus -p "List files here"./pipy-test.sh --provider faux --model faux/test -p "hello"Matches pi MVP acceptance: agent_start → turn_start → message_* → tool_execution_*:
./pipy-test.sh -v -p "List files" --provider faux --model faux/test| Feature | Usage |
|---|---|
Tools edit, write, grep |
--tools read,edit,write,grep,bash |
| Session JSONL | auto per cwd; -c continue; --session path.jsonl |
auth.json |
~/.pi/agent/auth.json (same format as pi) |
--mode json |
JSONL events on stdout (JSON mode) |
--list-models |
List built-in + models.json models |
# Edit a file
./pipy-test.sh -p "Add a header comment to README.md" --tools read,edit
# Continue last session in this directory
./pipy-test.sh -c -p "What did we discuss?"
# JSON event stream
./pipy-test.sh --mode json -p "hi" --provider faux --model faux/testCompaction, .pi/project context injection, steer/follow-up queues, and
bounded auto-retries mirror core pi agent-session behavior.
| Area | Notes |
|---|---|
| Compaction | Auto when tokens exceed contextWindow - reserveTokens; manual CLI/RPC/SDK |
| Context files | AGENTS.md, CLAUDE.md, .pi/SYSTEM.md; --no-context-files skips |
| Queues | steer / follow_up (+ streaming prompt with streamingBehavior) |
| Retry | Overload/rate-limit/5xx-ish errors; backoff via settings.retry |
{
"retry": {"enabled": true, "maxRetries": 3, "baseDelayMs": 2000},
"compaction": {
"enabled": true,
"reserveTokens": 16384,
"keepRecentTokens": 20000
}
}Demonstrate faux retry wiring (JSON lines include auto_retry_*):
./pipy-test.sh --mode json -p "hi" \
--provider faux --model faux/retry-testPlan: docs/superpowers/plans/2026-05-24-pipy-p3a.md.
from pi_coding_agent import CreateAgentSessionOptions, create_agent_session
result = await create_agent_session(
CreateAgentSessionOptions(model="anthropic/claude-sonnet-4-5", tools=["read", "bash"])
)
await result.session.prompt("Summarize this repo")See docs/sdk.md and examples/sdk/minimal.py.
pipy --mode rpc --no-session
# JSONL commands on stdin, events + responses on stdoutSee docs/rpc.md. Python helper: pi_coding_agent.rpc_client.RpcClient.
Resources docs: skills, prompt templates, extensions.
Further work: extensions, fuller RPC parity — see pi docs.
Skills, prompt templates, and Python extensions now load with pi-style locations and can be enabled/disabled via CLI flags.
| Resource | Default locations |
|---|---|
| Skills | ~/.pi/agent/skills, ~/.agents/skills, .pi/skills, ancestor .agents/skills |
| Prompts | ~/.pi/agent/prompts, .pi/prompts |
| Extensions | ~/.pi/agent/extensions, .pi/extensions |
Key flags:
./pipy-test.sh --no-skills --no-prompt-templates --no-extensions
./pipy-test.sh --skill ./skills --prompt-template ./prompts --extension ./ext.pySupported command expansion:
- Prompt templates:
/template-name ... - Skills:
/skill:skill-name ...(controlled byenableSkillCommands) - Extensions: custom slash commands registered by Python extension modules
Shipped example extension: examples/extensions/demo_extension.py
无参数启动 REPL(无 TUI,对标 pi「Start here」最小交互):
./pipy-test.sh| 命令 | 说明 |
|---|---|
/help |
帮助 |
/exit |
退出 |
/model [pattern] |
查看或切换模型(支持 provider/model:high) |
/tools |
当前工具列表 |
/session |
会话文件路径 |
单行 prompt 也可直接运行(等同 -p):
./pipy-test.sh "hello"与 pi 相同路径:全局 ~/.pi/agent/settings.json,项目 .pi/settings.json(后者覆盖前者)。
{
"defaultProvider": "anthropic",
"defaultModel": "claude-sonnet-4-5",
"defaultThinkingLevel": "medium"
}CLI:--model、--thinking 优先于 settings;模型 pattern 支持 anthropic/claude-sonnet-4-5:high。
默认:read,bash。全部内置:read, edit, write, grep, find, ls, bash。
./pipy-test.sh --tools read,find,ls -p "list python files"对 openai-completions 网关可设置:
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false,
"thinkingFormat": "qwen"
}supportsDeveloperRole: false 时 system prompt 使用 system 角色而非 developer。
- 交互为终端 REPL,无 pi TUI / 主题 / 快捷键
azure-openai-responses、amazon-bedrock当前仅为占位 provider(已注册,运行时未实现)
| Provider | Env var(s) |
|---|---|
| Claude | ANTHROPIC_API_KEY, ANTHROPIC_OAUTH_TOKEN |
| OpenAI | OPENAI_API_KEY |
| Custom (e.g. DashScope) | Set in models.json apiKey (e.g. DASHSCOPE_API_KEY) |
与 curl 等价:POST …/private/llm/v1/messages,Authorization: Bearer <token>。
- 复制示例配置(勿把 token 提交进 git):
cp docs/models.json.example ~/.pi/agent/models.json- 设置 token(任选其一):
export ANTA_AI_TOKEN='你的 Bearer token'或写入 ~/.pi/agent/auth.json(与 pi 相同格式):
{
"anthropic": {
"type": "api_key",
"key": "你的 Bearer token"
}
}- 运行:
./pipy-test.sh --model anthropic/claude-sonnet-4-6 -p "你是什么模型?"baseUrl 在示例里为 https://ai.anta.com/aimodels-server/private/llm(piPy 会请求 {baseUrl}/v1/messages)。authHeader: true 表示使用 Bearer,而不是官方 x-api-key。