pi-taste
Local, transparent Taste learning for the Pi coding agent
Package details
Install pi-taste from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-taste- Package
pi-taste- Version
0.5.6- Published
- Aug 31, 2026
- Downloads
- 147/mo · 6/wk
- Author
- lycanw
- License
- MIT
- Types
- extension
- Size
- 105.8 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
Pi Taste
English | 简体中文
Pi Taste is a local Taste-learning extension for the Pi coding agent. Its learning pipeline follows the same approach as Command Code Taste (without cloud sync), so it stays local and works with any model, including your ChatGPT/Codex account.
It does not train or modify model weights. Learned preferences land in a single readable taste.md file.
Pi Taste is an independent open-source project inspired by Command Code's Taste workflow.
1. Quick start
Install from the Pi package gallery / npm:
pi install npm:pi-taste@0.5.6
Try it for one run without installing:
pi -e npm:pi-taste@0.5.6
This release is tested with Pi 0.84.4 and requires Node.js 22.19 or newer, matching Pi's runtime requirement.
After installation or an update, reload Pi:
/reload
Check the current state:
/taste status
Default behavior:
- Taste is on: automatic learning and Taste injection are both enabled;
- the Learner follows the current main Pi model (use
/taste modelto set a separate one); - automatic learning starts after the foreground Agent fully settles and may continue in the background alongside later turns.
Useful first commands:
/taste list
/taste remember -g Always keep responses concise unless I request detail.
/taste model status
2. How learning works
When /taste on is active, an ordinary user turn follows this pipeline:
your visible message + assistant's visible text
→ current foreground Agent fully settles
→ background Learner (tool-calling model agent)
→ the model reads/writes taste.md itself
read_taste_file / write_taste_file / edit_taste_file
→ automatic category reorganization (>5 learnings → {category}/taste.md)
→ full taste.md injected on a future turn via <taste>
The Learner gets the same kind of context Command Code uses:
- NEW messages: the visible user/assistant text from the current turn (thinking, tool results, and metadata are stripped);
- Previously analyzed window: recent surrounding context, provided only to resolve references, never re-learned;
- Current taste structure: a tree of your taste files and their learning counts.
The model decides semantically whether a durable, generalizable preference was revealed: coding style, tooling, workflow, communication. It records each one as:
- Prefers tabs over spaces. Confidence: 0.9
There is no state machine. Anything the model writes is injected — exactly like Command Code, including low-confidence entries. Silent feedback, one-off constraints, and factual corrections are filtered by the model's judgment, not by keyword rules.
User steering and follow-up messages inserted while the Agent is streaming are also captured, evaluated against the assistant text visible at the insertion point.
The injection snapshot is created before the current feedback is held for learning, so a newly learned preference can affect only a later turn.
Pi processes launched with --no-session, and pi-subagents children marked by PI_SUBAGENT_CHILD=1, receive Taste injection but do not generate learning events. PI_TASTE_ALLOW_NO_SESSION=1 is intended only for isolated testing and never overrides the subagent-child guard.
3. Conversation activity cards
Taste transcripts appear as activity cards in the conversation, so you can see what was learned. Cards show contents and paths; they are TUI-only and never enter the model context.
✓ Taste Updated — 1 learned: Prefer tabs over spaces. (90%) → taste.md
State [global]: /home/user/.pi/agent/taste/taste.md
Cards cover:
- a learned preference (write/edit);
- a category reorganization;
- a Learner failure.
Press Ctrl+O to expand. Expanded details include model, event ID, and paths.
4. Safety
- Learning happens after
agent_settled; later turns never wait for or cancel a running Learner (single-concurrency queue). - Paths are contained: the model can only touch
taste.mdor{category}/taste.mdinside the taste directory..., absolute paths, and other names are rejected. - Feedback and assistant text are length-capped and redacted (tokens/secrets) before being sent to the Learner.
- Provider credentials are never copied into Taste configuration or source code.
5. Footer status
When Taste is active, the model footer shows:
Taste:onorTaste:off;·N: N Learner jobs queued or running;!: the most recent Learner operation failed.
6. Taste model configuration
The default mode is inherit: the Learner uses the current main Pi model. Changing /model changes the model used for later learning.
/taste model status # show mode and active model
/taste model inherit # follow the current main model
/taste model select # open Pi's model picker (TUI)
/taste model set provider/model
/taste model only provider/model
/taste model add provider/model
/taste model remove provider/model
/taste model list [query]
7. Managing preferences
Taste state is a single editable taste.md. You can also manage it with commands:
/taste list [id|all] # show all learnings
/taste remember [-g] <preference> # record manually (explicit user action)
/taste move <id> [global|project] # move between scopes
/taste forget <id> # remove a learning
/taste import <file> [-g] [--yes] # import bullets from a markdown file
- Default scope is
project;-gtargets the global store. importdeduplicates and skips lines that look like credentials; it does not call a model.forgetdeletes the line.
8. Taste and Global controls
/taste on | off
/taste onenables both automatic learning and injection;/taste offdisables automatic learning and all Taste injection; stored state is preserved.
There is no independent injection switch and no per-project global switch: like Command Code, the Learner writes to the project store (and the global store is available for explicit -g management). The [pending] marker from earlier versions no longer exists.
9. Storage
Global:
~/.pi/agent/taste/taste.md
Project (nearest Git root, else Pi's working directory):
<project-root>/.pi/taste/
├── .gitignore # prevents accidental publication of private state
└── taste.md # single authoritative preference file
taste.md format:
- Prefers tabs over spaces. Confidence: 0.9
- Avoid worktrees. Confidence: 0.4
Categories (>5 learnings) automatically become:
<project-root>/.pi/taste/<category>/taste.md
with the root taste.md holding See [<category>/taste.md](<category>/taste.md).
Writes use atomic replacement and a cross-process lock. Store files are created with private permissions where supported.
10. Command Code compatibility
Pi Taste reads your existing Command Code Taste files as read-only input for injection:
~/.commandcode/taste/taste.md
<project-root>/.commandcode/taste/taste.md
<project-root>/.commandcode/taste/<category>/taste.md
It never modifies them and deduplicates against Pi Taste. Since v0.5.0, the format and learning behavior follow Command Code, so you can point both tools at compatible files.
11. Configuration
Default ~/.pi/agent/taste/config.json:
{
"version": 3,
"learningEnabled": true,
"observer": {
"modelMode": "inherit",
"models": [],
"reasoning": "low",
"maxOutputTokens": 6000,
"timeoutMs": 90000,
"maxInputChars": 30000
},
"injection": {
"maxChars": 16000
}
}
learningEnabled is the master switch controlling both automatic learning and injection.
For isolated tests, PI_TASTE_DIR=/tmp/pi-taste-test redirects only the global Taste store. It does not move or copy provider credentials.
12. Privacy and security
- Common token and secret patterns are redacted before interaction excerpts are sent to the Learner.
- User messages and assistant text are length-capped.
- Redaction is defense in depth, not a complete secret scanner.
taste.mdcan contain preference text; treat it as private.- Activity cards contain preference text and absolute file paths, but they are not sent to the model.
- Provider credentials are never copied into Taste configuration or source code.
13. Backup and reuse on another device
The extension source can be reinstalled from GitHub. To preserve learned behavior, back up the private Taste state:
~/.pi/agent/taste/
<project-root>/.pi/taste/
A private encrypted backup of global state can be created with:
tar -C ~/.pi/agent -czf - taste \
| gpg --symmetric --cipher-algo AES256 \
-o ~/pi-taste-backup.tar.gz.gpg
14. Troubleshooting
Nothing is learned.
- Check
/taste status—Taste: onand no!in the footer. - The Learner must have a working Token/API for the current model.
/taste model statusshows the active model. - Feedback must contain an actual preference; silent acknowledgements are ignored by the model's judgment.
Learner failed (! in footer).
- Run
/taste statusto see the last error. - Common causes: model overload, timeout, or unavailable auth.
Learned something unexpected.
- Edit
taste.mddirectly (it is human-readable) or/taste forget <id>.
License
MIT