High-performance AI coding agent CLI written in Rust with zero unsafe code
High-performance AI coding agent CLI written in Rust with zero unsafe code
pi_agent_rust - Native AI coding agent CLI written in Rust
Why Should You Care? • TL;DR • Methodology • Quick Start • Features • Installation • Commands • Configuration
```bash # Install latest release curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/pi_agent_rust/main/install.sh?$(date +%s)" | bash ``` --- ## The Problem You want an AI coding assistant in your terminal, but existing tools are: - **Slow to start**: Managed runtimes can add noticeable startup overhead - **Resource intensive**: Electron apps or heavy runtimes can add substantial overhead - **Unreliable**: Streaming breaks, sessions corrupt, tools fail silently - **Hard to extend**: Closed ecosystems or complex plugin systems ## The Solution **pi_agent_rust** is a from-scratch Rust port of [Pi Agent](https://github.com/badlogic/pi) by [Mario Zechner](https://github.com/badlogic) (made with his blessing!). Official release archives install the single end-user binary `pi`, with streaming responses and 36 built-in tools (19 in the default `--tools` list; 14 always in the model's schema, the rest reachable through the `xdev` dispatcher or enabled in settings). ### Current product direction This project is no longer trying to be a strict drop-in replacement for the legacy TypeScript Pi. That target became both impractical and undesirable as the legacy implementation evolved. Legacy Pi remains useful historical context, but it is not our compatibility authority or definition of completeness. OMP is the closer reference for where the product is going: feature surface, agent workflows, look and feel, and overall UI/UX. Pi Rust still chooses Rust-native architecture and may intentionally differ from both projects when that produces a simpler, safer, or better coding agent. Historical drop-in and parity artifacts remain in the repository as records; they do not gate product work, releases, or user-facing claims. All repository quality checks, builds, and releases run through Doodlestein Self-Releaser (DSR). Contributors must not invoke Cargo or RCH directly, and GitHub Actions is never an execution or evidence authority for this project. Use `dsr quality --tool pi_agent_rust` for the registered quality recipe and the canonical DSR build/release commands documented in [docs/releasing.md](docs/releasing.md). Rather than a direct line-by-line translation, this port builds on two purpose-built Rust libraries: - **[asupersync](https://github.com/Dicklesworthstone/asupersync)**: A structured concurrency async runtime with built-in HTTP, TLS, and SQLite - **[rich_rust](https://github.com/Dicklesworthstone/rich_rust)**: A Rust port of [Rich](https://github.com/Textualize/rich) by [Will McGugan](https://github.com/willmcgugan), providing beautiful terminal output with markup syntax ```bash # Start a session pi "Help me refactor this function to use async/await" # Continue a previous session pi --continue # Single-shot mode (no session) pi -p "What does this error mean?" < error.log ``` ## Why Should You Care? If you already use Pi Agent, especially through OpenClaw, this project keeps the core workflow while upgrading the engine under the hood: - **A native single-binary design** intended to minimize startup and runtime overhead - **A bounded-resource architecture** for long-running sessions - **A capability-gated security model** for extension/tool execution, including command-level blocking of dangerous extension shell patterns Security is a first-class design goal here, not a bolt-on: - Capability-gated hostcalls (`tool`/`exec`/`http`/`session`/`ui`/`events`) - Two-stage extension `exec` enforcement: capability gate first, then command mediation that blocks critical shell classes by default (for example recursive delete, disk/device writes, reverse shell) and can tighten to block high-tier classes in strict/safe policy - Policy + runtime risk + quota enforcement on the execution path - Per-extension trust lifecycle (`pending` -> `acknowledged` -> `trusted` -> `killed`) with kill-switch audit logs and explicit operator provenance - Hostcall-lane emergency controls that can force compatibility-lane execution globally or for one extension when fast-lane behavior needs immediate containment - Structured concurrency via `asupersync` for more predictable cancellation/lifecycle behavior - Auditable runtime signals/ledgers and redacted security alerts for extension behavior ## TL;DR (Pi/OpenClaw Users) The Rust port is designed around large-session, multi-agent, and extension-heavy workloads. Release-facing performance numbers are published only when the checked-in evidence artifacts are current, have matching run provenance, and show data and a passing result for every declared budget, with no data-contract failures. Historical benchmark snapshots are retained in planning/evidence artifacts, but they are not treated as current README claims until the performance evidence gate is regenerated cleanly. Extension runtime guarantees are also concrete: | Extension assurance signal | Why you should care | |---|---| | Two-stage `exec` guard (`exec` capability policy + command-level mediation + DCG/heredoc AST signals) | Dangerous shell intent is caught before spawn, including destructive payloads hidden in multiline wrappers | | Trust lifecycle + kill switch (`pending/acknowledged/trusted/killed`) | You can quarantine an extension instantly, log who pulled the switch and why, and require explicit re-acknowledgement before restoring access | | Hostcall lane kill-switch controls (`forced_compat_global_kill_switch`, `forced_compat_extension_kill_switch`) | Fast-path regressions can be contained immediately by forcing compatibility-lane execution without disabling the extension system | | Deterministic hostcall reactor mesh (shard affinity, bounded SPSC lanes, backpressure telemetry, optional NUMA slab tracking) | Runtime behavior stays predictable under contention; queue pressure and routing decisions are observable instead of opaque | | Cold owner-isolated JS realms + persistent transpile cache | Every reload gets a fresh realm while versioned disk-cached transpilation avoids treating mutable JavaScript state as safely reusable | | Tamper-evident runtime risk ledger (`verify` / `replay` / `calibrate`) | Security decisions are hash-linked and can be replayed or threshold-tuned from real runtime traces | Bottom line: Pi's architecture targets lower latency, lower memory use, and stronger extension runtime safety under real workload pressure; current numeric claims must come from fresh, provenance-matched evidence artifacts. Data source: `docs/planning/BENCHMARK_COMPARISON_BETWEEN_RUST_VERSION_AND_ORIGINAL__GPT.md` (latest secure-path + full orchestrator checkpoints, 2026-04-23). ### README Citation Convention Release-facing numeric performance claims in this README include inline citations with format: `*(from [artifact-path], run [correlation-id])*` Example: `*(from [artifact-path], run [correlation-id])*` Two additional machine-recognized citation forms exist: - `*(from [artifact-path])*` — path-only citation. The cited artifact must exist and parse; freshness is enforced by the same 14-day rule as release-facing claims. - `*(from [artifact-path]; historical snapshot)*` — explicit historical contract. The citation itself declares the obligation a retained snapshot: existence and validity are still checked, but staleness is not enforced because such claims never satisfy current release-facing requirements. `scripts/check_readme_evidence_freshness.py` (a pre-release check listed in [docs/releasing.md](docs/releasing.md), not part of the code quality recipe) checks file freshness and artifact content so stale, no-data, or correlation-mismatched evidence cannot back user-facing performance claims; for release-facing citations of `budget_summary.json` it validates the full `pi.perf.budget_summary.v2` contract, including that the header counts equal the per-budget rows. It reports line-numbered proof obligations for cited claims and extracts claim-gated performance phrases for reviewer audit. Historical snapshot citations are mapped separately and do not satisfy current release-facing claims. ## Performance-Oriented Architecture In this README, `we` means the project owner and collaborating coding agents. The design concentrates performance work in several runtime layers rather than assuming one optimization proves an end-to-end result. | Technique | What we do | Runtime intent | |---|---|---| | Cold-start minimization | Single native binary, no Node/Bun runtime bootstrap, no JIT warmup, startup prewarm for extension runtime paths | Reduce time-to-first-interaction | | Less copying on hot paths | `Arc`/`Cow` message flow, zero-copy hostcall/tool payload handling, reduced clone-heavy provider/session paths | Reduce CPU and allocation pressure | | Deterministic dispatch core | Typed hostcall opcodes, fast-lane/compat-lane routing, bounded shard queues with reactor-mesh telemetry | Reduce tail latency under concurrent extension load | | Efficient long-session storage | SQLite session index + v2 sidecar (segmented log + offset index) with O(index+tail) reopen path | Avoid full-history work on eligible resumes | | Streaming parser tuned for real networks | SSE parser tracks scanned bytes, handles UTF-8 tails, normalizes chunk boundaries, interns event-type strings | Reduce repeated scanning and parser stalls | | Safe fast-path controls | Shadow dual execution sampling, automatic backoff on divergence/overhead, compatibility-lane kill switches for containment | Bound optimization risk and preserve fallback behavior | | DSR performance governance | Scenario matrices, strict artifact contracts, fail-closed perf gates | Detect regressions before release | If you want the full implementation inventory, see [Performance Engineering](#performance-engineering). ## Benchmark Methodology and Claim Integrity The benchmark evidence policy is designed to keep results realistic, reproducible, and hard to game. What we measured: - **Matched-state workloads**: resume a large session and append the same 10 messages. - **Realistic E2E workloads**: resume + append + extension activity + slash-style state changes + forks + exports + compactions. - **Scale levels**: from `100k` up to `5M` token-class session states. - **Startup/readiness**: command-level readiness (`--help`, `--version`) separately from long-session workflows. How we kept comparisons fair: - **Two scopes** in the benchmark report: - apples-to-apples (`pi_agent_rust` vs legacy `coding-agent`) - apples-to-oranges (legacy stack components included where legacy behavior is outsourced) - **Release-mode binaries** and repeated runs per matrix cell. - **No paid-provider noise** in core latency/footprint tables (provider-call costs are excluded from these core comparisons). How we kept claims honest: - **Security controls stayed on** during secure-path measurements (no policy/risk/quota bypasses for speed claims). - **Raw artifacts are preserved** (JSON/trace/time outputs) and called out in the benchmark report. - **Blockers are explicitly disclosed**: when direct legacy reruns were blocked by missing workspace deps, we state that and compare against prior validated legacy artifacts instead of pretending reruns succeeded. - **Interpretation notes are explicit**: the report distinguishes baseline sections vs fresh reruns so readers can see exactly which values came from which run set. - **Re
install.sh source build fails when CARGO_TARGET_DIR is set: "Source build succeeded but binary was not found"
`read` tool returns an empty string for every file on Windows (reports "0 lines")
classic tui: can not reply to 'ask' tool
ftui: can not scroll model list
[Feature request] Windows native support
Heading colors mismatch; tables misaligned with truncated cells
"Running ask ..." hangs ~3 minutes, then times out; the question card appears ~5 minutes later
Suggestion — Strengthen system robustness
FTUI does not match the original pi's interactive TUI in appearance or performance — propose iterating against recorded captures of the original
Loading a local extension (`-e <file>.js`) triggers `npm install -g pi-extmgr` at startup; extension host fails either way