rpi-cli
The terminal coding-agent CLI — the rpi binary — built on the rpi-* library
crates. It is the ready-to-run surface of the
rpi project: an interactive TUI, a
one-shot -p mode, a JSON event mode, durable sessions, and Rust cdylib
plugin loading.
Install
Requires Rust 1.88 or newer. Then point it at a provider and start it:
# or OPENAI_API_KEY, or ~/.rpi/agent/models.json
One-shot, and machine-readable output:
Authentication
Credentials are resolved in priority order:
--api-keyon the command line~/.rpi/auth.json, written byrpi auth login(mode0o600on Unix)- the
apiKeyfield of a provider in~/.rpi/agent/models.json - provider environment variables:
OPENAI_API_KEY,ANTHROPIC_AUTH_TOKEN,ANTHROPIC_API_KEY
~/.rpi/ can be relocated with RPI_CODING_AGENT_DIR.
Custom providers and gateways
Any Anthropic-Messages or OpenAI-compatible endpoint can be declared in
~/.rpi/agent/models.json:
{
"providers": {
"gateway": {
"api": "anthropic-messages",
"baseUrl": "https://gateway.example.com",
"apiKey": "sk-gateway-secret",
"authHeader": true,
"headers": { "x-portkey-key": "…" },
"models": [{ "id": "custom-claude", "name": "Custom Claude" }]
}
}
}
Use "api": "openai-completions" for an OpenAI-compatible endpoint. Anthropic
endpoint overrides also honour ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN.
Sessions and resources
- Sessions are JSONL v4 files under the session directory, with branching and context compaction.
- Project resources are discovered from
.rpi/(skills, prompts, themes, andSYSTEM.md), with~/.rpi/agent/as the global layer. When both define the same skill or prompt name, the project copy wins. - Plugins are loaded from project
.rpi/extensions, global~/.rpi/agent/extensions, and--extensions-dir.
Plugins
rpi install defaults to the versioned rpi-extension.json prebuilt protocol: it resolves a non-yanked stable package version and repository through crates.io, loads the <package>-v<version> Release manifest, and verifies the archive and declared library before transactionally installing it into ~/.rpi/agent/extensions. Explicit --github owner/repo installs use package-specific tags and also support unpublished extensions. Both repository forms consume the same protocol; they never infer library filenames or use repository-wide latest bundles. Missing prebuilt releases fail with an actionable error; --build and --path explicitly select Cargo compilation. Installed provenance preserves the source for update discovery, reinstalls and uninstall. Actual plugin ABI/API-size validation still happens when loading the library.
rpi install <name> installs or upgrades an extension without --force. An already installed version is skipped; use --force to reinstall the same version or allow a downgrade. These rules also apply to explicit Cargo builds and local installs.
rpi extension update updates all project-linked extensions and globally installed registry/prebuilt extensions; rpi extension update <name> selects one extension by name. Updates retain the original Cargo build backend or explicit GitHub source. Global development installs made with --path are excluded. The old rpi package update [name] remains compatible, but rpi extension update [name] is recommended for extension updates. Project linking commands remain rpi package link, rpi package list, and rpi package unlink.
Remote mode
The client holds no local provider, tools, extensions or session files; all agent work happens on the server. See docs/remote/user-guide.md.
Default tools
The CLI loads the Pi-compatible read, write, edit and bash tools.
Additional implementations (grep, find, ls, docs, powershell) remain
available in the rpi-tools library and
through the default_tools setting.
Library usage
The crate also exposes its internals, so the CLI surface can be embedded:
[]
= "0.3"
For building your own agent, depend on
rpi-agent and
rpi-harness directly instead — see
docs/agent/project-structure.md.
RPC message identity, images and client text files
rpi --mode rpc exposes additive, explicitly negotiated native contracts for
optional durable message identity, ordered inline PNG/JPEG prompt input, and
client-authoritative text I/O through the existing built-in read/write/edit
tools. Legacy text/local operation remains the default; client terminal support
and an OS filesystem sandbox are not implied. See the
native protocol contract for gates,
wire shapes, limits, authority combinations and validation scope. Consumers must
check ready capabilities rather than infer support from a crate version.
Custom-entry branch queries (RPC and runtime actions)
get_session_branch is a filtered custom-entry query, not an unfiltered
transcript export. RPC example:
customTypes is required and must be a non-empty array of non-blank strings.
Type identifiers match exactly as written by append_entry: whitespace and
case are preserved, and only exact duplicate identifiers are deduplicated.
Only afterSeq (non-negative integer), limit (positive integer), and order
(oldestFirst, the default, or newestFirst) are optional query arguments.
The cursor is exclusive in the selected order: seq > afterSeq for
oldestFirst, seq < afterSeq for newestFirst. Type filtering and
branch ancestry apply before global ordering and limit across all requested
types. Results are {"entries":[...],"count":N,"filtered":true}.
Runtime action GetSessionBranch accepts the same query, without RPC's type
and id envelope. Both surfaces reject {}, unknown fields, and the retired
query keys customType, custom_type, custom_types, and after_seq, even
when mixed with valid modern keys. This canonical contract has no alias fallback.
append_entry / AppendEntry still use singular customType for writes.
Migration from unfiltered hosts
This is a breaking query-contract change: replace unfiltered {} or legacy
arguments with an explicit customTypes list. Upgrade the host and consumers
together. Older hosts may accept the new arguments but ignore them; clients
requiring filtering must require filtered == true in the reply and reject
unsupported hosts rather than treating an unfiltered branch as filtered data.
Plugin ABI compatibility alone does not establish this query capability.
get_messages, get_history, and the append/write protocol are unchanged.
Documentation
- User guide: https://rpi.bigfisharc.cn/docs.html
- Architecture: docs/architecture/overview.md
- Extension authoring: docs/extensions/authoring.md
- Changelog: CHANGELOG.md
License
This crate is part of a Rust port of the MIT-licensed TypeScript pi SDK
(© Mario Zechner).
CLI self-update
rpi update downloads the matching GitHub prebuilt CLI using the versioned rpi-release.json distribution protocol. It verifies target, archive size, both SHA-256 hashes, and the executable version before using the existing atomic replacement and Windows staging helper. Version discovery uses crates.io. Only rpi update --build selects local Cargo compilation; missing manifests and failed checks preserve the installed executable. --force reinstalls and --offline reports cached information without downloads or builds.