v0.18.7 — Update notifications that actually reach long-running servers
v0.18.7
Changed
- Update notifications now re-check GitHub every 24h (previously: a single
check at server startup — a long-running server never saw releases published
after it booted). The docstring's "cached 24h" promise is now real. - Update nudge repeats every 7 days instead of once per server lifetime:
a user who misses the first notice gets reminded weekly, without spam.
Failure paths unchanged: network errors fail open silently.
v0.18.7 (unreleased)
Removed
- Legacy
webui/graph dashboard deleted (the original DeepSeek-era UI).nexus-memory webuinow starts the current dashboard (dashboard/): connected agents, memory graph with filters, memory inspector. Same command, now on port 9121 — no stale UI left behind.
Changed
- README / AGENTS.md / install scripts point agents to the current dashboard.
pip install nexus-memory[webui]extra removed from pyproject (fastapi/uvicorn needed only when running the dashboard from a checkout).
v0.18.6 — Auto-Scoping Parity: All Three Plugins
Auto-scoping now works identically on every integration path — Hermes native plugin, OpenClaw TS plugin, and Claude Code hooks. v0.18.5 shipped self-organizing memory server-side (auto-tagging in the MCP server worked for all agents) but the client-side pieces (auto-recall gating, auto-capture tagging, store-tool tagging) lived only in the Hermes plugin. Now every plugin infers areas from scoped centroids with the same clear-match rule — no user config anywhere (Nebo law: full automation or useless; no release without plugin parity).
New
plugins/openclaw/lib/scope-auto.ts— TypeScript port ofscope_auto.py: centroid cache with TTL + inflight dedup, conservativeinferScope()(clear-closest only: ≥0.72 absolute AND ≥0.05 margin over runner-up),prefetchFilterScopes()with manual-scope-as-addition semantics. Wired into auto-recall gating, auto-capture tagging, and thenexus_storetool (explicit scope param wins → cfg scope → auto-infer → default).plugins/claude-code/scripts/scope_auto.py— shared lib for the Claude Code hooks (short-lived processes: one scroll per call, fail-open).auto_recall.pynow infers the allowed scope set from the prompt itself;auto_capture.pytags captures via_resolve_capture_scope().- Parity tests: 13 new tests — 12 Python (clear-match, ambiguous fail-open, absolute threshold, manual-scope union, fetch fail-open, capture resolution) + 1 cross-language parity test that runs the actual TypeScript module via node and asserts identical decisions to the Python implementation.
Tests
- 1076 passed (1063 previous + 13 parity tests)
The memory now assigns its own areas — full automation, zero user setup (Nebo law: automate or it's useless). Scope labels exist since v0.18.4, but they required a config value per agent. Now the memory infers the area itself: when a new memory is stored, it compares the content vector against the centroids of existing scoped areas and inherits the matching scope automatically. And at recall time, a question that clearly belongs to one area gets that area's memories plus the shared ones — no configuration anywhere in the loop.
New
scope_auto.py— scope centroids + conservative inference: centroid per scope from canonical scoped points (60s TTL cache, fail-open to "no areas").infer_scope(): only tags a memory when its vector is CLEARLY closest to one area (margin ≥ 0.05 to runner-up AND ≥ 0.72 absolute similarity) — under-tagging is harmless, over-tagging is what we avoid. Zero LLM cost: pure vector math.- Auto-tagging at
remember(): caller leavesscopeatdefault→ server inherits the inferred area automatically. Explicit non-default scopes are never overridden. Fail-open: any inference error → staysdefault. - Query-side auto-filtering (Hermes plugin prefetch): a prompt that clearly belongs to one area surfaces only
default+ that area's memories; ambiguous prompts change nothing (old behavior). NoNEXUS_SCOPEneeded — the query steers itself. - Fully backward compatible: with no scoped memories in the store, centroids are empty →
defaulteverywhere → byte-for-byte old behavior. Users never see the word "scope".
Tests
- 1063 passed (1048 previous + 15 new auto-scoping tests: centroid math, margin logic, dimension-mismatch skip, fail-open paths, remember-integration, prefetch integration)
v0.18.4 — Scopes: Project/Agent Areas (unreleased feature, first implementation)
Scopes answer "which project does this belong to?" — access levels already answer "who may see this?". Every memory can now carry a scope label so multiple agents sharing one memory store get clean, focused auto-recall instead of cross-project noise.
New
- Scope labels (
scope): optional area label on every memory (nexus_remember(..., scope="voice")). Valid:[a-z0-9-], max 40 chars, normalized lowercase. Anything invalid degrades todefault(fail-open) — behaves exactly like pre-scope memories. - Core principle — scopes steer automatic prefetch, never explicit search: auto-prefetch (Hermes plugin
NEXUS_SCOPEenv / OpenClaw pluginscopeconfig) surfaces onlydefaultmemories plus the agent's own scope. Explicitrecall()/nexus_searchis NEVER scope-filtered — a scoped memory is never hidden from a direct question. - OpenClaw plugin parity:
scopeconfig key +NEXUS_SCOPEenv fallback inlib/config.ts, gating in the auto-recall hook, scope inheritance in capture +nexus_storetool (optionalscopeparameter with same normalization). - Claude Code plugin parity: auto-recall hook gates on
NEXUS_SCOPE(same client-side filter contract), auto-capture stores memories with inherited_normalize_scope(NEXUS_SCOPE); graph-boost neighbors intentionally unfiltered (explicit relations). MCP-based Claude Code setups inherit v0.18.4 automatically. - Backward compatible: no
NEXUS_SCOPEset → the agent sees everything (old behavior); memories without a scope field behave asdefault.
Tests
- 1048 passed on the production suite (1034 previous + 14 new scope tests; 21 additional scope/rewrite tests live on the development testbed workspace)
v0.18.0 — Consolidation Daemon + Multi-Station Fuel Chain
Ingestion-time consolidation is live. Raw session dumps are distilled into atomic, self-contained facts (pronouns resolved, relative dates anchored) and contradictions are superseded at write time — the retrieval hebel from the LongMemEval findings, now in production path.
New
- Consolidation daemon (
consolidation.py): in-process background thread in the MCP server (no cron, harness-independent). Distills un-consolidatedsessionpoints intofactpoints, resolves conflicts at write time via embed-similarity (≥0.75) + LLM classify (duplicate/supersede/unrelated). Never deletes — superseded facts keep lifecycle status. Kill-switchNEXUS_CONSOLIDATION=0. IntervalNEXUS_CONSOLIDATION_INTERVAL(default 3600s). - Fuel chain (
fuel_chain.py): the daemon is a hitchhiker on the user's existing LLM config — no setup, no new account. Station order (cheapest first): local Ollama → OpenRouter → OpenAI-compatible keys (OPENAI_API_KEY / NOUS_API_KEY / explicit NEXUS_FUEL_BASE+NEXUS_FUEL_KEY). Cheapest tier model per station, never the user's flagship. All stations closed → daemon sleeps and retries next tick (fail-safe, never crashes, never blocks). - Monthly budget cap:
NEXUS_FUEL_BUDGET_USD(default 1.00). Paid stations pause when the cap is hit; free local Ollama keeps working. Spend tracker in~/.nexus-memory/fuel_spend.json(auto-reset each month).
Tests
- 799 passed (8 new fuel-chain tests + 19 consolidation tests from the 05.09 GO)
Changelog
All notable changes to Nexus Memory are documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.