a4fc26eed360357640501540f0059014ecab58ea
19
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e1fc71a9b9 |
chore(release): 3.7.0
Bump package, plugins, lock, and README badge to 3.7.0. Promote the post-3.6.0 integrity spine into CHANGELOG: single-writer ownership, HNSW write defaults and preflight, safer repair/re-mine, MCP/daemon lifecycle hardening, entity ReDoS guard, and hook write-routing. Also ruff-format two test files that drifted during conflict merges. Local validation: ruff check/format clean; 3497 passed, 31 skipped. |
||
|
|
c76208507e |
fix(mcp): preserve agent attribution in mempalace_checkpoint (#2023)
mempalace_checkpoint hard-coded added_by="checkpoint" for every drawer, dropping the filing agent's identity even though it arrives in the same call via diary.agent_name. Add an optional top-level added_by parameter and resolve attribution as explicit > diary agent_name > "checkpoint"; blank/whitespace/non-string values defer to the next source. The value is declared in the tool schema so tools/call admits it on both stdio and HTTP transports. Fixes #2023 Co-Authored-By: epinethrone <172391900+epinethrone@users.noreply.github.com> |
||
|
|
9ecdf83c08 | docs: address 3.6.0 release review | ||
|
|
dbfeb82e68 | chore(release): 3.6.0 | ||
|
|
da5a48caf5 |
Merge pull request #1719 from raman325/feat/openclaw-tool-catchup
docs(openclaw): catch up SKILL.md with 8 newer MCP tools |
||
|
|
e096701333 | docs(openclaw): document full MCP tool surface | ||
|
|
d7e182a272 |
docs: add Windows backup alternative to corrupt-index recovery (#1843)
Gemini review on PR #1849: the optional palace backup step used the Unix-only `cp -a`, which fails on Windows. MemPalace ships on win32, so add a PowerShell `Copy-Item` alternative alongside the macOS/Linux form and note that `--archive-existing` already moves the old palace aside. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
65d07045bd |
fix: point diverged-index recovery at from-sqlite, not re-mine (#1843)
A diverged HNSW index (for example after a failed chromadb compaction) leaves the drawer rows intact in chroma.sqlite3 but the vector index out of sync. Re-mining to recover silently drops drawers added through the MCP server and diary entries, which have no source file. - repair-status now recommends `mempalace repair --mode from-sqlite --archive-existing` when DIVERGED, instead of the generic `mempalace repair`, and explains why re-mining loses data. - The shared recall protocol and the recall skills (Cursor + Claude plugin) document the compactor / "Not connected" recovery path: stop the server, rebuild from SQLite, verify, restart — never repair in-process from the agent. Complements #1847 (legacy repair error messages); does not duplicate it. Does not close #1843 — MCP reconnect resilience and honest add_drawer write signalling remain open. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
8e19e815cc | merge: resolve recall-protocol conflict with develop | ||
|
|
fc89a1b67e |
feat(antigravity): add recall skill, optional rule, shared protocol
Adds the recall layer to the Antigravity plugin, mirroring the three- layer wiring from feat/cursor-hooks-support, adapted for Antigravity's native plugin and hook surfaces. The wake hook (PreInvocation, invocationNum==1) was already the eager layer — it injects verbatim palace content via injectSteps[]. ephemeralMessage before the first model call, which is strictly better than Cursor's static directive. This commit adds the on-demand layers: - integrations/shared/recall-protocol.md: single canonical source of truth for "search before answering", shared across Cursor, Antigravity, Claude Code, Codex, OpenClaw. Ported from feat/cursor-hooks-support with the wake-up step de-coupled from any IDE-specific hook name. - .antigravity-plugin/skills/mempalace-recall/SKILL.md: recall-only skill with Protocol, Tool selection, Unhappy paths, and Anti-patterns sections. Tailored to Antigravity: references injectSteps injection, not Cursor's additional_context; links to shared protocol via GitHub URL (relative file paths break in the installed copy at ~/.gemini/config/plugins/mempalace/). - .antigravity-plugin/rules/mempalace-recall.md: plain .md recall rule (no .mdc extension, no YAML frontmatter — per Antigravity's plugin docs which specify rules/<name>.md). Body mirrors Cursor's rule; references the shared protocol via absolute GitHub URL. - hooks/antigravity/install.sh: creates skills/mempalace-recall/ and rules/ in the install dir, copies both new files (cmp-gated, idempotent). Verified: first run writes both, second run is silent. - .antigravity-plugin/README.md: updated layout tree + "Three recall layers" section documenting wake hook (eager), recall skill (on-demand), and optional rule. - 11 new tests in tests/test_antigravity_plugin_manifest.py covering: shared protocol presence, recall skill structure (frontmatter, required sections, GitHub URL reference), rule format (plain .md, no frontmatter), and installer (mkdir + copy_file lines present). Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
24ad98df8c |
feat: add mempalace-recall skill and optional Cursor recall rule
Ports the OpenClaw "search before answering" protocol to the Cursor and Claude plugin surfaces so the agent reads the palace before answering about past work, people, projects, or prior decisions instead of guessing from model memory. - integrations/shared/recall-protocol.md: single source of truth for the recall protocol, referenced by the skill and the rule so they cannot drift. - skills/mempalace-recall/SKILL.md: recall-only skill (the mempalace skill keeps setup/mine/status); cross-linked from the ops skill. - rules/mempalace-recall.mdc: plugin recall rule, alwaysApply: false so it only fires on recall-relevant turns and never adds MCP latency to greenfield work. - examples/cursor/rules/: opt-in copies for non-plugin users, including an aggressive alwaysApply: true variant documented with its latency tradeoff. - .claude-plugin/skills/mempalace-recall/SKILL.md: Claude plugin parity. - tests: assert the recall skill and rules/ discovery layout; the shipped rule must be alwaysApply: false. - docs: .cursor-plugin/README.md and the cursor-hooks guide now describe the three layers of recall (hook + skill + rule). The Antigravity plugin mirror lands as a follow-up on the antigravity branch, where .antigravity-plugin/ exists. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
ca38ae899d |
docs(openclaw): address review round 1
- Fix mempalace_find_tunnels params: (required) -> optional. The MCP handler defaults both wing_a and wing_b to None (mempalace/mcp_server.py:1277), so the prior docs were factually wrong. Caught by gemini-code-assist on PR #1719. - Clarify implicit-vs-explicit tunnel distinction with consistent casing and a brief in-line definition (implicit = discovered from drawer content overlap; explicit = user/agent-declared link). Suggested by copilot-pull-request-reviewer. - Split the mempalace_memories_filed_away one-liner into a short description plus 'Returns' and 'When to call' sub-bullets for readability. Suggested by copilot-pull-request-reviewer. |
||
|
|
29d7e1edcf |
docs(openclaw): catch up SKILL.md with 8 newer MCP tools
The openclaw skill was last updated when mempalace exposed 19 MCP tools. Since then 13 more agent-facing tools have landed; this PR documents the 8 that openclaw should expose so agents can call them natively instead of falling back to `npx mcporter call ...`: Search & Browse: - mempalace_list_drawers (paginated drawer listing) - mempalace_get_drawer (fetch a single drawer by id) Palace Graph: - mempalace_create_tunnel (explicit cross-wing link) - mempalace_list_tunnels (enumerate explicit tunnels) - mempalace_delete_tunnel (remove an explicit tunnel) - mempalace_follow_tunnels (walk explicit tunnels from a room) Write / Session: - mempalace_update_drawer (mutate content or relocate a drawer) - mempalace_memories_filed_away (ack the silent auto-save hook) The 3 admin-only tools (mempalace_sync, mempalace_hook_settings, mempalace_reconnect) are intentionally left out — they're host/admin operations, not agent-facing memory operations. The Hermes MemoryProvider plugin landing in MemPalace/mempalace#1684 makes the same call. Version bumped 3.3.0 -> 3.4.0 (additive tool surface, no breaking changes to existing tool docs). |
||
|
|
c35686c9e1 |
docs(install): recommend uv as the package manager
End-user installs now lead with `uv tool install mempalace`, with `pip install mempalace` kept as a fallback. Dev/contributor docs lead with `uv sync --extra dev` and `uv run` for tests/benchmarks/lint, with the equivalent pip recipe kept inline. The shipped `/mempalace:init` skill instructions (mempalace/instructions/init.md) try `uv tool install` first when uv is on PATH, then fall back through the pip variants. Adds a .python-version pin at 3.12 because the lockfile's onnxruntime==1.24.3 only ships wheels for Python >=3.11; without the pin, `uv sync` on a host where uv prefers 3.10 fails with no source distribution available, which would make the documented command a footgun. pyproject's `requires-python = ">=3.9"` is unchanged — pip users on 3.9/3.10 are unaffected. Files updated: README.md, CONTRIBUTING.md, CLAUDE.md, the gemini-cli guide and example, the .claude-plugin / .codex-plugin READMEs, the mempalace SKILL, the openclaw SKILL, tools/save.md, the three benchmarks docs, and the corresponding website mirrors. |
||
|
|
4aa7e1eebd |
release: v3.3.0 (#839)
* fix: add file-level locking to prevent multi-agent duplicate drawers
Root cause: when multiple agents mine simultaneously, both pass
file_already_mined() check, both delete+insert the same file's
drawers, creating duplicates or losing data.
Fix: mine_lock() in palace.py — cross-platform file lock (fcntl on
Unix, msvcrt on Windows). Both miner.py and convo_miner.py now lock
per-file during the delete+insert cycle and re-check after acquiring
the lock.
Tested:
- Lock acquires and releases correctly
- Second agent blocks until first releases (0.25s wait)
- 33/33 existing tests pass
- Cross-platform: fcntl (macOS/Linux), msvcrt (Windows)
Based on v3.2.0 tag.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: strip system tags, hook output, and Claude UI chrome from drawers
normalize.py now strips before filing:
- <system-reminder>, <command-message>, <command-name> tags
- <task-notification>, <user-prompt-submit-hook>, <hook_output> tags
- Hook status messages (CURRENT TIME, Checking verified facts, etc.)
- Claude Code UI chrome (ctrl+o to expand, progress bars, etc.)
- Collapsed runs of blank lines
This noise was going straight into drawers, wasting storage space
and polluting search results. strip_noise() runs on all normalized
output regardless of input format (JSONL, JSON, plain text).
689/689 tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add closet layer — searchable index pointing to drawers
The closet architecture was always part of MemPalace's design but
never shipped in the public codebase. This adds it.
Palace now has TWO collections:
- mempalace_drawers — full verbatim content (unchanged)
- mempalace_closets — compact AAAK-style index entries
How it works:
- When mining, each file gets a closet alongside its drawers
- Closet contains extracted topics, entities, quotes as pointers
- Closets pack up to 1500 chars, topics never split mid-entry
- Search hits closets first (fast, small), then hydrates the
full drawer content for matching files
- Falls back to direct drawer search if no closets exist yet
Files changed:
- palace.py: get_closets_collection(), build_closet_text(),
upsert_closet(), CLOSET_CHAR_LIMIT
- miner.py: process_file() now creates closets after drawers
- searcher.py: search_memories() tries closet-first search,
hydrates drawers, falls back to direct search
Backwards compatible — existing palaces without closets continue
to work via the fallback path. Closets are created on next mine.
689/689 tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: enforce atomic topics in closets, extract richer pointers
- upsert_closet replaced by upsert_closet_lines: checks each topic
line individually against CLOSET_CHAR_LIMIT. If adding one line
WHOLE would exceed the limit, starts a new closet. Never splits
mid-topic.
- build_closet_lines returns a list of atomic lines (not joined text)
- Richer extraction: section headers, more action verbs, up to 3
quotes, up to 12 topics per file
- Each line is complete: topic|entities|→drawer_refs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: add CLOSETS.md — closet layer overview
Cherry-picked the docs portion of 67e4ac6 to accompany the closet
feature. Test coverage for closets is omnibus with tests for entity
metadata and BM25 (see PR targeting those features) and will land
together in a follow-up.
Co-Authored-By: MSL <232237854+milla-jovovich@users.noreply.github.com>
* feat: entity metadata + diary ingest + BM25 hybrid search
Three features that close the gap between the architecture docs
and the actual codebase:
1. Entity metadata on drawers and closets
- _extract_entities_for_metadata() pulls names from known_entities.json
+ proper nouns appearing 2+ times
- Stamped as "entities" field in ChromaDB metadata
- Enables filterable search by person/project name
2. Day-based diary ingest (diary_ingest.py)
- ONE drawer per day, upserted as the day grows
- Closets pack topics atomically, never split mid-topic
- Tracks entry count in state file, only processes new entries
- Usage: python -m mempalace.diary_ingest --dir ~/summaries
3. BM25 hybrid search in searcher.py
- _bm25_score() keyword matching complements vector similarity
- _hybrid_rank() combines both signals (60% vector, 40% BM25)
- Catches exact name/term matches that embeddings miss
- Applied to both closet-first and direct drawer search paths
689/689 tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add tests for mine_lock, closets, entity metadata, BM25, diary
Trimmed version of Milla's omnibus test_closets.py to only cover
features present in this PR stack (#784 lock, #788 closets, this
PR's entity/BM25/diary). Strip-noise tests will land with #785;
tunnel tests will land with the tunnels PR.
16/16 pass.
Co-Authored-By: MSL <232237854+milla-jovovich@users.noreply.github.com>
* feat: explicit cross-wing tunnels for multi-project agents
Adds active tunnel creation alongside passive tunnel discovery.
Passive tunnels (existing): rooms with the same name across wings.
Explicit tunnels (new): agent-created links between specific
locations. "This API design in project_api relates to the database
schema in project_database."
New functions in palace_graph.py:
- create_tunnel() — link two wing/room pairs with a label
- list_tunnels() — list all explicit tunnels, filter by wing
- delete_tunnel() — remove a tunnel by ID
- follow_tunnels() — from a room, find all connected rooms in
other wings with drawer content previews
New MCP tools:
- mempalace_create_tunnel
- mempalace_list_tunnels
- mempalace_delete_tunnel
- mempalace_follow_tunnels
Tunnels stored in ~/.mempalace/tunnels.json (persists across
palace rebuilds). Deduplicated by endpoint pair.
689/689 tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add TestTunnels for cross-wing tunnel operations
Appended from Milla's omnibus test_closets.py — covers create,
list, delete, dedup, and follow_tunnels behavior. 21/21 pass.
Co-Authored-By: MSL <232237854+milla-jovovich@users.noreply.github.com>
* feat(search): drawer-grep returns best-matching chunk + neighbors
When a closet hit leads to a source file with many drawers, grep each
chunk for query terms and return the BEST-MATCHING chunk + 1 neighbor
on each side, instead of dumping the whole file truncated at
MAX_HYDRATION_CHARS. Result now includes drawer_index and
total_drawers so callers can request adjacent drawers explicitly.
Extracted from Milla's commit 935f657 which bundled drawer-grep with
closet_llm (deferred pending LLM_ENDPOINT refactor) and fact_checker
(separate PR). Ported only the searcher.py change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: offline fact checker against entity registry + knowledge graph
fact_checker.py verifies text for contradictions against locally stored
entities and KG facts. Catches similar-name confusion (Bob vs Bobby),
relationship mismatches (KG says husband, text says brother), and
stale facts (KG valid_from/valid_to).
No hardcoded facts. No network calls. Reads:
- ~/.mempalace/known_entities.json
- KnowledgeGraph SQLite
Usage:
from mempalace.fact_checker import check_text
issues = check_text("Bob is Alice's brother", palace_path)
# CLI
python -m mempalace.fact_checker "text" --palace ~/.mempalace/palace
Extracted from Milla's commit 935f657 which bundled this with
closet_llm (deferred) and drawer-grep (PR #791). Ported only
fact_checker.py — verified no network / API imports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: optional LLM-based closet regeneration — bring-your-own endpoint
Adds mempalace/closet_llm.py as an OPTIONAL path for richer closet
generation. Regex closets remain the default and cover the local-first
promise; users who want LLM-quality topics can bring their own endpoint.
Configuration (env or CLI flag):
LLM_ENDPOINT — OpenAI-compatible base URL (required)
LLM_KEY — bearer token (optional; local inference skips this)
LLM_MODEL — model name (required)
Works with Ollama, vLLM, llama.cpp servers, OpenAI, OpenRouter, and any
other provider that speaks OpenAI-compatible /chat/completions. Zero new
dependencies — uses stdlib urllib.
Replaces the original Anthropic-SDK-hardcoded version of this module
from Milla's branch (commit 935f657). Same prompt, same parsing, same
regenerate_closets flow; only the transport was generalised so the
feature doesn't lock users into a specific vendor or require API keys
for core memory operations (CLAUDE.md, "Local-first, zero API").
Includes 13 unit tests covering config resolution, request shape,
auth-header omission when no key is set, code-fence stripping, and
missing-config error path. All mocked — zero network calls in tests.
Co-Authored-By: MSL <232237854+milla-jovovich@users.noreply.github.com>
* fix(search): hybrid closet+drawer retrieval — closets boost, never gate (#795)
* Fix: set cosine distance metadata on all collection creation sites
ChromaDB defaults HNSW index to L2 (Euclidean) distance, but
MemPalace scoring uses 1-distance which requires cosine (range 0-2).
Add metadata={"hnsw:space": "cosine"} to the 4 production and 3 test
call sites that were missing it.
Closes #218
* fix: sync version.py to 3.2.0
Commit
|
||
|
|
81dc977bbf |
release: finalize v3.2.0 — version consistency + CHANGELOG
PR #761 bumped pyproject.toml to 3.2.0 but missed three other version strings, causing test_version_consistency to fail on develop CI (macos, linux 3.11, windows). - mempalace/version.py: 3.1.0 → 3.2.0 (unblocks test_version_consistency) - README.md: version badge shield 3.1.0 → 3.2.0 - integrations/openclaw/SKILL.md: 3.1.0 → 3.2.0 - CHANGELOG.md: rename [Unreleased] → [3.2.0] — 2026-04-13, add entries for #685, #690, #707, #716, #734, #755, #757, #761 Verified locally: 689/689 tests pass, ruff clean. |
||
|
|
f56e67b516 |
docs: fix stale milla-jovovich org refs and branch target in contributor docs (#679)
The repo moved to the MemPalace org but several docs still point at the old milla-jovovich URLs. Also, CONTRIBUTING.md tells people to PR against main while the actual workflow (per ROADMAP.md) targets develop. Files touched: - CONTRIBUTING.md: clone URL, issues URL, PR target branch - examples/gemini_cli_setup.md: clone URL - integrations/openclaw/SKILL.md: homepage and license URLs |
||
|
|
3a0f782646 | docs: note lower dedup threshold (0.85-0.87) per community feedback | ||
|
|
46520d2154 |
feat: add OpenClaw/ClawHub skill for MemPalace
Complete OpenClaw skill exposing all MCP tools with session protocol, auto-install spec, and setup instructions for OpenClaw + other MCP hosts. Covers all 20 tools: search, check_duplicate, status, list_wings, list_rooms, get_taxonomy, get_aaak_spec, kg_query, kg_add, kg_invalidate, kg_timeline, kg_stats, traverse, find_tunnels, graph_stats, add_drawer, delete_drawer, diary_write, diary_read. Based on PR #207 by @wanikua — updated to v3.1.0, added missing tools (check_duplicate, get_aaak_spec), expanded parameter docs, added OpenClaw CLI setup command. Co-Authored-By: wanikua <wanikua@users.noreply.github.com> |