mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
feat(pi-hermes-memory): 导入上游 v0.9.10 源码快照
从官方 Git 仓库导入 chandra447/pi-hermes-memory 在 tag v0.9.10 (df624056a2e8c68bc89ba0a81e1c120856ec9665,2026-10-02)的源码快照。 本次仅导入源码,尚未接入组合包:package.json、加载顺序、依赖与权限策略 均未改动。 - 原样导入 src/、tests/、docs/、scripts/、README、CHANGELOG、PLAN、 AGENTS 与 LICENSE;该快照共 156 个上游文件。 - 剔除嵌套 .git、上游 .github 工作流、.ralph/、.claude/、node_modules、 覆盖率与构建产物。 - 新增中文 UPSTREAM.md,记录来源,以及启用前必须完成的待决事项: 在 pi-compaction 之前注册加载顺序、better-sqlite3 版本与根 allowScripts 对齐、strip-ansi 解析确认。 - 说明选择 tag 而非 main 的原因:导入时上游 main 已领先至 24fcd8ad26fc27badb8d7dbaf8034645de07b893(2026-10-11),选 tag 是为 对应一个已发布、可复现的版本。 尚未接线。启用前还需反转 tests/extension-load.test.ts 中"不得加载 Hermes"的断言,并同步 pi-tool-search 分组、权限策略与文档。 验证:快照 156 个上游文件全部导入,目录内仅多出 UPSTREAM.md 一份; 已确认与上游 main 内容存在差异,证明取的是 tag 而非 main。
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# v0.4 Plan: SQLite FTS5 Session Search + Hybrid Memory
|
||||
|
||||
## Problem
|
||||
|
||||
The current memory architecture has two scaling bottlenecks:
|
||||
|
||||
1. **Memory capacity**: MEMORY.md is capped at 2,200 chars. Power users accumulate knowledge faster than consolidation can manage. Important facts get pruned.
|
||||
2. **No session history search**: Past conversations are stored as JSONL files in `~/.pi/agent/sessions/<project>/`, but there's no way to search them. When the agent needs context from a previous session, it's gone forever.
|
||||
|
||||
## Solution: Hybrid Memory Architecture
|
||||
|
||||
### Core memory (always injected, unchanged)
|
||||
- `MEMORY.md` — 5,000 chars (up from 2,200)
|
||||
- `USER.md` — 5,000 chars (up from 1,375)
|
||||
- Still injected into every session via `<memory-context>` tags
|
||||
- Still human-readable, still editable
|
||||
|
||||
### Extended memory (SQLite, searchable on demand)
|
||||
- `~/.pi/agent/memory/sessions.db`
|
||||
- `memories` table — unlimited entries, searchable via FTS5
|
||||
- Agent uses `memory_search` tool to query when it needs context
|
||||
- Not automatically injected — agent must explicitly search
|
||||
|
||||
### Session history (SQLite, searchable on demand)
|
||||
- Same `sessions.db` file
|
||||
- `sessions` + `messages` tables — all past conversations indexed
|
||||
- `session_fts` FTS5 index — full-text search across all sessions
|
||||
- Agent uses `session_search` tool to find relevant past context
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Session starts
|
||||
↓
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ System Prompt (always injected) │
|
||||
│ ┌─────────────────────────────────────────────┐ │
|
||||
│ │ <memory-context> │ │
|
||||
│ │ MEMORY (your personal notes) [5,000 chars] │ │
|
||||
│ │ ═══ END MEMORY ═══ │ │
|
||||
│ │ </memory-context> │ │
|
||||
│ │ <memory-context> │ │
|
||||
│ │ USER PROFILE [5,000 chars] │ │
|
||||
│ │ ═══ END MEMORY ═══ │ │
|
||||
│ │ </memory-context> │ │
|
||||
│ │ <memory-context> │ │
|
||||
│ │ PROJECT MEMORY [5,000 chars] │ │
|
||||
│ │ ═══ END MEMORY ═══ │ │
|
||||
│ │ </memory-context> │ │
|
||||
│ └─────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
|
||||
Agent has access to tools:
|
||||
memory_search("prisma migration")
|
||||
→ Searches memories table (global + project)
|
||||
→ Returns top-10 relevant entries
|
||||
|
||||
session_search("how we fixed the test hang")
|
||||
→ Searches session history via FTS5
|
||||
→ Returns relevant conversation snippets
|
||||
```
|
||||
|
||||
## Data Model
|
||||
|
||||
```sql
|
||||
-- Session metadata
|
||||
CREATE TABLE sessions (
|
||||
id TEXT PRIMARY KEY, -- UUID from JSONL
|
||||
project TEXT NOT NULL, -- decoded cwd path
|
||||
started_at TEXT NOT NULL, -- ISO timestamp
|
||||
ended_at TEXT, -- ISO timestamp (null if still running)
|
||||
message_count INTEGER DEFAULT 0
|
||||
);
|
||||
|
||||
-- All messages from all sessions
|
||||
CREATE TABLE messages (
|
||||
id TEXT PRIMARY KEY, -- message ID from JSONL
|
||||
session_id TEXT NOT NULL REFERENCES sessions(id),
|
||||
role TEXT NOT NULL, -- 'user', 'assistant', 'system'
|
||||
content TEXT NOT NULL, -- extracted text content
|
||||
timestamp TEXT NOT NULL, -- ISO timestamp
|
||||
tool_calls TEXT -- JSON array of tool call names (for assistant messages)
|
||||
);
|
||||
|
||||
-- FTS5 index for full-text search across messages
|
||||
CREATE VIRTUAL TABLE message_fts USING fts5(
|
||||
content,
|
||||
content='messages',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
-- Extended memory entries (beyond MEMORY.md limit)
|
||||
CREATE TABLE memories (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
project TEXT, -- NULL for global, project name for project-specific
|
||||
target TEXT NOT NULL, -- 'memory' or 'user'
|
||||
content TEXT NOT NULL,
|
||||
created DATE NOT NULL,
|
||||
last_referenced DATE NOT NULL
|
||||
);
|
||||
|
||||
-- FTS5 index for memory search
|
||||
CREATE VIRTUAL TABLE memory_fts USING fts5(
|
||||
content,
|
||||
content='memories',
|
||||
content_rowid='id'
|
||||
);
|
||||
```
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
### 1. Session indexing is lazy (on session end)
|
||||
- Don't parse JSONL files on every startup
|
||||
- Index a session when `session_shutdown` fires
|
||||
- Bulk import existing sessions via `/memory-index-sessions` command
|
||||
|
||||
### 2. FTS5 for both memories and sessions
|
||||
- Keyword search is sufficient for v0.4
|
||||
- Embeddings deferred to v0.5+ if search quality isn't enough
|
||||
- `better-sqlite3` includes FTS5 by default
|
||||
|
||||
### 3. Single DB file
|
||||
- `~/.pi/agent/memory/sessions.db` stores everything
|
||||
- Memories + sessions + FTS indices in one file
|
||||
- Simple backup (copy one file), simple cleanup
|
||||
|
||||
### 4. Agent-driven search
|
||||
- `memory_search` and `session_search` are LLM tools
|
||||
- Agent decides when to search (not automatic)
|
||||
- Avoids injecting irrelevant context into every session
|
||||
|
||||
### 5. Char limit increase to 5,000
|
||||
- MEMORY.md: 2,200 → 5,000 chars
|
||||
- USER.md: 1,375 → 5,000 chars
|
||||
- Project MEMORY.md: 2,200 → 5,000 chars
|
||||
- More room for core memories before consolidation kicks in
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Purpose | Size |
|
||||
|---|---|---|
|
||||
| `better-sqlite3` | SQLite with FTS5 | ~1MB native addon |
|
||||
|
||||
## Risks
|
||||
|
||||
| Risk | Mitigation |
|
||||
|---|---|
|
||||
| `better-sqlite3` is a native C++ addon | Standard for dev tools; CI has build tools |
|
||||
| FTS5 search quality | Start with keyword search, add embeddings later if needed |
|
||||
| Session JSONL format changes | Parse defensively, skip unknown message types |
|
||||
| Large session history (1000+ sessions) | FTS5 handles this well; add pagination to results |
|
||||
| DB corruption | Atomic writes, WAL mode, backup before migrations |
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. `session_search("prisma migration")` returns relevant conversation snippets from past sessions
|
||||
2. `memory_search("auth setup")` returns relevant entries from extended memory store
|
||||
3. MEMORY.md limit raised to 5,000 chars without breaking existing functionality
|
||||
4. Existing session files indexed without data loss
|
||||
5. All tests pass, zero regressions
|
||||
Reference in New Issue
Block a user