@brianmichel/pi-noodle
Long-term memory for Pi — local libSQL database with vector search.
Package details
Install @brianmichel/pi-noodle from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@brianmichel/pi-noodle- Package
@brianmichel/pi-noodle- Version
0.1.0- Published
- Jun 2, 2026
- Downloads
- 119/mo · 119/wk
- Author
- brianmichel
- License
- MIT
- Types
- extension
- Size
- 250.8 KB
- Dependencies
- 1 dependency · 2 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-noodle
Long-term memory for Pi.
This repo is building a small, opinionated memory system that tries to be:
- useful — retrieve facts that actually help future turns
- safe — avoid saving temporary or sensitive content
- automatic — capture durable signals from normal conversation
- inspectable — review what was saved, pending, or discarded
Under the hood it uses libSQL for storage and vector similarity search for retrieval.

Quick start
# Install as a Pi extension
pi install @brianmichel/pi-noodle
# In Pi, configure interactively
/noodle settings
The setup screen shows the full config on one page:
- Database mode — local file or Turso Cloud
- Embedding provider — OpenAI, LM Studio, Ollama, or custom
- Relevant fields update in place as you switch modes/providers
- Required fields are validated before save
Settings are saved to ~/.pi/noodle/config.json — memories travel with you across all projects.
/noodle command
/noodle Show current config (paths, endpoint, masked API key)
/noodle remember <text> Save a memory directly
/noodle forget <query> Find and delete a memory
/noodle edit <query> Find and update a memory
/noodle review Review recent auto-saved memories
/noodle settings Interactive single-screen configuration editor with validation
/noodle setup Alias for /noodle settings
/noodle init Create a default config file for manual editing
/noodle web Start the Memory Explorer (auto-stops when all tabs close)
/noodle web stop Stop the explorer immediately
/noodle web dev Dev mode — hot reload on save, use web stop when done
/noodle web 8080 Start on a custom port
For UI development outside Pi, run npm run web:dev from the repo — it connects to your configured database and reloads the browser whenever you edit src/web/index.html.
Memory Explorer Web UI
Launch a dark-themed web interface to browse, search, and visualize your memories:
- Live stats — total memories, categories, scopes
- Category filter — dropdown of all stored categories
- Text search — substring matching on memory text
- Dark mode — GitHub-inspired color scheme
Run /noodle web in Pi to open the explorer in your browser. The server runs in a background process and shuts down automatically ~2 seconds after you close all tabs. Use /noodle web stop to kill it manually.
Config file
~/.pi/noodle/config.json:
{
"db": {
"mode": "local",
"path": "/Users/you/.pi/noodle/memories.db"
},
"embedding": {
"provider": "openai",
"apiKey": "sk-...",
"baseUrl": "https://api.openai.com/v1",
"model": "text-embedding-3-small"
}
}
Cloud mode (Turso)
{
"db": {
"mode": "cloud",
"url": "libsql://my-db-org.turso.io",
"authToken": "eyJ..."
},
"embedding": {
"provider": "openai",
"apiKey": "sk-...",
"baseUrl": "https://api.openai.com/v1",
"model": "text-embedding-3-small"
},
"extractor": {
"mode": "balanced",
"model": "deepseek/deepseek-v4-flash:free",
"triggerEvery": 10
}
}
Memory modes
When memory mode is not off, capture uses a unified capture pipeline with policy-gated persistence:
conservative- fewer extraction runs
- higher bar for auto-save
- softer inferences are usually discarded until reinforced
balanced(recommended default)- durable facts can auto-save
- medium-confidence preferences go to
/noodle review
proactive- more frequent extraction
- more candidate discovery
- pending review queue grows faster, but saved-memory safety rules stay the same
The extractor model is configurable too, so you can tune quality/speed/cost separately from behavior mode.
Environment variable overrides
Env vars take priority over the config file:
| Variable | Overrides |
|---|---|
NOODLE_CONFIG_PATH |
Config file location |
NOODLE_DB_PATH |
Local DB path |
NOODLE_DB_URL |
Cloud DB URL |
NOODLE_DB_TOKEN |
Cloud DB auth token |
OPENAI_API_KEY |
Embedding API key |
EMBEDDING_BASE_URL |
Embedding endpoint URL |
EMBEDDING_MODEL |
Embedding model name |
NOODLE_EXTRACTOR_MODE |
Memory mode: off / conservative / balanced / proactive |
NOODLE_EXTRACTOR_MODEL |
Extractor model ID |
NOODLE_EXTRACTOR_TRIGGER_EVERY |
Automatic extraction cadence in user turns |
NOODLE_EXTRACTOR_DEBUG |
Show the extractor debug widget: true / false |
Architecture
Pi lifecycle events
└─► MemoryService.capture(event)
├─► heuristic capture
├─► optional LLM extraction
├─► candidate promotion policy
└─► conversation capture / consolidation when needed
│
▼
MemoryBackend
│
TursoBackend
├─► libSQL (local or cloud)
└─► Embedder
Capture pipeline
input / compact / switch / shutdown
│
└─► MemoryService.capture(event)
│
├─► heuristic prefilter
│ ├─ blocks sensitive / temporary content
│ └─ catches explicit memory asks
│
├─► optional LLM extraction
│ └─ turns conversation context into memory candidates
│
├─► local promotion policy
│ ├─ save → durable memory DB
│ ├─ pending → /noodle review only
│ └─ discard → dropped
│
└─► retrieval injects only saved memories
Why it is shaped this way
- Pi only tells the memory system what event happened
MemoryServicedecides which capture stages should run- heuristic and LLM candidates share the same promotion path
- pending memories stay out of retrieval until reviewed or reinforced
What gets stored
Every memory is a row in SQLite with text, embedding (F32_BLOB), category, categories, scope (userId/assistantId/sessionId), and arbitrary metadata.
Search
Vector similarity via vector_distance_cos() in libSQL, ranked by cosine distance, post-filtered by category and threshold.
Policy and review
The system intentionally separates:
- detection — heuristics and LLM extraction find memory candidates
- promotion — local policy decides save / pending / discard
- retrieval — only saved memories are injected into prompts
That keeps the system proactive without letting low-confidence guesses pollute retrieval. Pending candidates stay visible in /noodle review but are not injected until promoted.
File layout
src/
├── config.ts # Config resolution (~/.pi/noodle/config.json + env vars)
├── config-screen.ts # Flat single-screen config editor for /noodle settings
├── constants.ts # DEFAULT_AGENT_ID
├── types.ts # NoodleConfig, JsonObject, NotificationTarget, etc.
├── utils.ts # maskSecret, describeError, formatJson, extractTextContent
├── commands.ts # /noodle command + interactive setup entrypoint
├── extension.ts # Pi extension lifecycle hooks
├── tools.ts # memory_add / search / list / get / update / delete
├── session.ts # Session message collection
├── queue.ts # Sequential async write queue
├── notifications.ts # UI notification helpers
└── memory/
├── backend.ts # MemoryBackend interface
├── types.ts # MemoryRecord, MemoryScope, etc.
├── turso-backend.ts # TursoBackend (libSQL + vector search)
├── embedder.ts # Embedder type
├── embedders/ # openai.ts, lm-studio.ts
├── service.ts # MemoryService (event-driven capture pipeline + promotion)
├── policy.ts # Heuristics (classification, repetition, retrieval)
└── runtime.ts # Wiring (config + TursoBackend + MemoryService)