a1673f7428
RTK was documented as delivering "60-90% token savings", which reads as a cost reduction. What RTK actually reduces is bash output bytes. Those are one contributor to input tokens, which are themselves only part of a bill that also counts output tokens, so the reduction dilutes at every step. - add docs/guide/resources/savings-explained.md as the canonical explainer: the savings chain, both estimators, and what RTK does not reduce - rescope the headline claim across README (7 languages), the guide, hook rules, agent definitions and module READMEs - relabel per-command tables as bash output reduction, keeping every figure - document that reported tokens are estimates: rtk gain uses bytes/4 (src/core/tracking.rs), filter tests use split_whitespace().count(). Neither is a real tokenizer, so ratios hold but absolute counts do not Remove figures that had no source: the $3/Mtok constant and its $36 example, the +/-10% tokenization accuracy claim, the 99.5% hook-install figure, the invented session tables in README and INSTALL, and the 30-50% parser range. CHANGELOG is untouched. Shipped release notes stay as a historical record.
Pi Hooks
Part of
hooks/— see alsosrc/hooks/for installation code
Design Intent
RTK's Pi extension is a rewrite-only token optimizer. It mutates bash commands to their
rtk-prefixed equivalents, cutting up to 90% of the bash output that reaches the context.
Permission gating is intentionally out of scope. RTK does not block, confirm, or audit
commands — that concern belongs to a dedicated permission extension (e.g. one that gates
rm -rf, sudo, etc.). This separation keeps RTK's hook fast, predictable, and composable
with other Pi extensions.
Specifics
- TypeScript extension using Pi's
ExtensionAPI(not a shell hook, nozxdependency) - Subscribes to
tool_callevent, narrows tobashtool viaisToolCallEventType - Calls
rtk rewriteviapi.exec; mutatesevent.input.commandin-place if rewrite differs - All error paths return
undefined(pass through); RTK never blocks execution - Version guard at load time: checks
rtk >= 0.23.0; warns and registers no-op if too old or missing - Installed to
.pi/extensions/rtk.tsbyrtk init --agent pi(project-local) or~/.pi/agent/extensions/rtk.tsbyrtk init --agent pi --global
Uninstall
# Remove project-local install (run from the project root)
rtk init --uninstall --agent pi
# → removes .pi/extensions/rtk.ts
# Remove global install
rtk init --uninstall --agent pi --global
# → removes ~/.pi/agent/extensions/rtk.ts
Uninstall is idempotent — re-running when nothing is installed is a no-op. Only the extension file is managed by install/uninstall.
Testing
# Load the extension directly without installing
pi -e ./hooks/pi/rtk.ts
# Verify rewrites are active — ask the agent to run a command, then check history
rtk gain --history # should show rtk-prefixed commands with savings %
# Test RTK_DISABLED passthrough
RTK_DISABLED=1 pi -e ./hooks/pi/rtk.ts
# → commands pass through unchanged; no rewrites in rtk gain --history
# Test version guard — temporarily shadow rtk with a stub that prints "rtk 0.22.0"
# → extension logs a warning at startup and registers a no-op; pi starts normally
Design Notes
- All filtering logic lives in
rtk rewrite(the Rust registry), not in this file - Exit codes 0 and 3 both mean "rewrite and allow"; they are handled identically
- Uses
pi.execfor subprocess management — consistent with Pi's extension API