npm.io
2026.6.291 • Published 2h ago

openclaw-hybrid-memory

Licence
Version
2026.6.291
Deps
6
Size
24.7 MB
Vulns
0
Weekly
3.0K
Stars
4
Install scriptsThis package runs scripts during installation (preinstall/install/postinstall)

OpenClaw memory-hybrid plugin (npm: openclaw-hybrid-memory)

This folder is the published OpenClaw extension: durable agent memory (structured store + semantic recall, auto-capture / auto-recall, configurable decay and maintenance, optional graph and credential vault).

User-facing overview, scenarios, and install: Repository README · Documentation site · Quick start


Install & verify

openclaw plugins install openclaw-hybrid-memory
openclaw hybrid-mem install
# Configure embedding (required) in ~/.openclaw/openclaw.json — see LLM-AND-PROVIDERS.md
openclaw gateway stop && openclaw gateway start
openclaw hybrid-mem verify

Upgrade: openclaw hybrid-mem upgrade (then restart the gateway).

Useful follow-up commands: openclaw hybrid-mem status for a one-screen health summary and openclaw hybrid-mem dashboard for the Mission Control URL.


Requirements (short)

Requirement Notes
Node.js >=22.16.0 (engines in package.json)
OpenClaw ≥2026.5.0 required (peer); ≥2026.6.1 recommended (Skill Workshop, skills hot-reload, Dreaming tab)
Embeddings Required — OpenAI, Ollama, ONNX, or Google; see LLM-AND-PROVIDERS.md
Build toolchain For @lancedb/lancedb: C++ build tools + Python 3 on the install machine

Agent tools

All tools use underscore names (memory_store, memory_recall, …). Dotted aliases are invalid for some providers.


Package layout

Path Role
openclaw.plugin.json Manifest and config schema
index.ts Plugin entry: stores, tools, CLI, lifecycle
config.ts Defaults and config parsing
backends/ SQLite, LanceDB, event bus, etc.
tools/ Tool implementations and dashboard routes
cli/ hybrid-mem commands
skills/hybrid-memory/ Bundled Agent Skill (SKILL.md + references); copied to {workspace}/skills/hybrid-memory/ on first plugin start if absent (or use hybrid-mem install to refresh)

File Description
package.json npm package and OpenClaw extension entry
openclaw.plugin.json Plugin manifest and config schema
config.ts Decay classes, TTL defaults, config parsing (incl. autoRecall, store, etc.)
index.ts Plugin implementation (SQLite+FTS5, LanceDB, tools, CLI, lifecycle)
versionInfo.ts Plugin and memory-manager version metadata
backends/event-bus.ts Event Bus — append-only memory_events SQLite table for sensor → Rumination Engine pipeline
tools/dashboard-routes.ts Dashboard HTTP route registration — registers all /plugins/memory-dashboard/* routes with consistent auth (Issue #279)
tools/public-api-routes.ts Public API surface routes (/plugins/memory-public/*) for health/search/timeline/stats/export/fact (Issue #1027)
services/public-export-bundle.ts Stable export bundle builder used by GET /plugins/memory-public/export (Issue #1027)
Topic Doc
Full config CONFIGURATION.md
CLI CLI-REFERENCE.md
Architecture ARCHITECTURE.md
Event bus API docs/event-bus.md
Retrieval / RRF docs/rrf-retrieval.md, RETRIEVAL-MODES.md
Graph / contacts GRAPH-MEMORY.md
ONNX embeddings README below
Local ONNX embeddings (optional)

Entity layer (contacts, organizations, NER)

When graph.enabled is true, new facts are enriched asynchronously with typed entity mentions (e.g. PERSON, ORG, SERVICE, TOOL, MODEL, PROJECT, AGENT, ROLE) using franc + LLM with quality gating/canonicalization. Before mention rows are written to SQLite (organizations, contacts, fact_entity_mentions, org_fact_links), they are normalized, deduplicated per fact/label, and filtered for short or generic noise. The memory_directory tool exposes list_contacts and org_view for structured lists—use memory_recall for ranked semantic search. Backfill older facts with openclaw hybrid-mem enrich-entities, and audit/repair existing rows with openclaw hybrid-mem entity-mentions audit|cleanup. See GRAPH-MEMORY.md and MULTILINGUAL-SUPPORT.md.

Event Bus

backends/event-bus.ts adds an Event Bus: an append-only memory_events SQLite table that decouples sensor sweeps (producers) from the Rumination Engine (consumer).

Key API:

Method Description
appendEvent(type, source, payload, importance?, fingerprint?) Append a new event; returns its auto-generated id
queryEvents(filter?) Filter by status, event_type, since, limit
updateStatus(id, newStatus) Advance an event through the status lifecycle
dedup(fingerprint, cooldownHours?) Return true if a duplicate exists within the cooldown window
pruneArchived(olderThanDays?) Delete archived events older than N days

Status lifecycle: raw → processed → surfaced → pushed → archived

computeFingerprint(input) is a SHA-256 helper for building stable dedup keys.

See docs/event-bus.md for the full schema, API reference, and integration example.

Dashboard HTTP Routes

tools/dashboard-routes.ts registers two HTTP routes under the /plugins/memory-dashboard/ prefix:

Route Description
GET /plugins/memory-dashboard/ HTML dashboard shell
GET /plugins/memory-dashboard/api/health JSON health report ({ status, generatedAt })

Routes are only registered when health.enabled is true (the default). OpenClaw v2026.3.8 enforces a consistent-auth requirement: every route under the same path prefix must use the same authenticated value. dashboard-routes.ts satisfies this by reading cfg.health.authenticated once and applying it to all routes via a single shared routeOpts object.

Config field: health.authenticated (boolean, default true) — controls whether dashboard routes require an authenticated session. Set to false only if you intentionally want unauthenticated access.

Mission Control — Memory Viewer (Issue #1023)

The Mission Control local dashboard (createDashboardServer) doubles as the Memory Viewer / Mission Control UI for hybrid-memory. It serves a rich HTML dashboard at the root and exposes a comprehensive JSON API under /api/viewer/.

Access: The dashboard runs on 127.0.0.1 only (local-only, no authentication required for local access). The HTTP server port is configured via dashboard.port in the plugin config (default 7700).

Important: The dashboard server is registered separately from the OpenClaw HTTP gateway. It is accessible at http://127.0.0.1:7700/ (or the configured port) — not through the OpenClaw gateway URL. This is intentional: local-only, no auth overhead, safe for operators on the same machine.

Memory Viewer API endpoints

All Memory Viewer routes are served by the local Mission Control server on the dashboard port:

Endpoint Method Description
/api/viewer/stats GET Overview: total facts, verified, edicts, issues, episodes, links, breakdown by category/tier/decay/source
/api/viewer/facts GET Paginated facts list with optional filters: ?category=&entity=&limit=&offset=
/api/viewer/facts/:id GET Single fact detail including verification status, provenance, and decay info
/api/viewer/facts/:id/verify POST Verify a fact ({ "verifiedBy": "agent" | "user" | "system" })
/api/viewer/facts/:id/forget POST Forget (soft-delete) a fact
/api/viewer/entities GET Top entities by fact count with categories and tags
/api/viewer/episodes GET Recent episodic memory events with outcome, duration, and session context
/api/viewer/narratives GET Recent session narratives/summaries
/api/viewer/issues GET All tracked issues with status, severity, and symptoms
/api/viewer/workflows GET Workflow patterns and recent tool-sequence traces
/api/viewer/edicts GET All edicts (verified ground-truth facts)
/api/viewer/verified GET All verified facts with verification metadata
/api/viewer/links GET Memory graph links (source → target with type and strength)
/api/viewer/provenance/:factId GET Provenance chain for a specific fact

All responses include Cache-Control: no-cache. POST endpoints accept JSON body and return { ok: boolean, message: string }.

Public API HTTP Routes

tools/public-api-routes.ts registers a compact, beginner-friendly REST surface under /plugins/memory-public/:

Route Description
GET /plugins/memory-public/health API surface health + version metadata
GET /plugins/memory-public/search?q=<query>&limit=<n> Simple full-text memory search
GET /plugins/memory-public/timeline?limit=<n> Reverse-chronological memory timeline
GET /plugins/memory-public/stats Core memory stats (facts/episodes/procedures/links)
GET /plugins/memory-public/export Stable JSON export bundle (facts, episodes, procedures, narratives, provenance)
GET /plugins/memory-public/fact?id=<uuid> Inspect a single fact plus incoming/outgoing links

Routes use the same health.authenticated setting to keep auth behavior consistent per prefix.

See docs/PUBLIC-API-SURFACE.md for demo flows and payload shape details.

"health": {
  "enabled": true,
  "authenticated": true
}

Lifecycle & Shutdown

The plugin registers SIGUSR1 / SIGUSR2 signal handlers to close all database connections cleanly on process shutdown:

import { closeAllDatabases } from "./backends/base-sqlite-store";

// Called automatically on SIGUSR1/SIGUSR2, or invoke manually:
await closeAllDatabases();

All stores (FactsDB, CredentialsDB, EventBus, etc.) implement a close() method that:

  • Flushes pending writes
  • Closes the SQLite connection
  • Prevents further operations (throws "<StoreName> is closed" if accessed afterward)

The EventBus additionally enters a terminal closed state after close() is called — any subsequent appendEvent() call throws "EventBus is closed".

Dependencies

  • Built-in node:sqlite (ships with supported Node.js versions)
  • @lancedb/lancedb ^0.26.2
  • @sinclair/typebox 0.34.48
  • openai ^6.16.0 — peer dependency (must be directly provided by the host). The openai package is not bundled with this plugin. Your host environment must directly declare and install openai ^6.16.0 — a transitive copy (e.g. one pulled in via a sub-dependency of OpenClaw) is not sufficient under pnpm, Yarn PnP, or other strict package managers. Install it explicitly alongside this plugin: npm i openai.

Build tools required for @lancedb/lancedb: C++ toolchain (e.g. build-essential on Linux, Visual Studio Build Tools on Windows), Python 3.

Local ONNX Embeddings (optional)

For local embedding inference without an API key, install onnxruntime-node into the OpenClaw extensions folder (~/.openclaw/extensions) — one level above the plugin package — so that it survives openclaw hybrid-mem upgrade:

npm install --prefix ~/.openclaw/extensions onnxruntime-node@^1.18.0

Then set embedding.provider: "onnx" in plugin config. See repository TROUBLESHOOTING.md if loading fails.

Recall timing diagnostics

Optional autoRecall.recallTiming (off | basic | verbose) — see INTERACTIVE-RECALL-LATENCY.md and CONFIGURATION.md.


Credits

Design lineage and a full list of extensions in this repo: CREDITS-AND-ATTRIBUTION.md. Based on Give Your Clawdbot Permanent Memory (Clawdboss.ai).

Operator health audit

Run a one-shot store health report with:

openclaw hybrid-mem audit health
openclaw hybrid-mem audit health --json
openclaw hybrid-mem audit health --strict

The JSON output is versioned (schemaVersion: 1) for dashboards and automation. The report surfaces tier sanity, category drift, vectorless active facts, validated-but-unpromoted procedures, implicit-feedback signal noise, and remediation hints. --strict exits 2 when warnings/errors are present; JSON includes exitCode, exitReason, warningCount, and errorCount so cron/automation can treat strict health failures differently from command crashes. The installer also publishes a weekly hybrid-mem:weekly-audit-health cron step that runs openclaw hybrid-mem audit health --strict --json.

For LanceDB/Arrow/native RSS diagnostics, run:

openclaw hybrid-mem vectordb-health
openclaw hybrid-mem vectordb-health --json

Hybrid-memory emits one-time startup-memory-checkpoint log lines for plugin registration, first recall, first active-task projection, and first compaction (recorded on the first before_compaction hook). Each line includes owner, subsystem, operation, RSS bytes/delta, and active handle/request counts for faster attribution during gateway memory pressure incidents.

Vector search and semantic-cache result materialization are bounded at runtime to prevent unbounded Arrow/Lance memory use under heavy recall workloads. The defaults can be tuned via environment variables:

Variable Default Min Max Description
OPENCLAW_HYBRID_MEM_VECTOR_QUERY_MAX_RESULTS 200 10 5000 Hard ceiling for rows fetched per vector search call
OPENCLAW_HYBRID_MEM_SEMANTIC_CACHE_MAX_ROWS_PER_FILTER_KEY 100 10 5000 Per-filter cap for semantic query cache rows
OPENCLAW_HYBRID_MEM_SEMANTIC_CACHE_CANDIDATE_LIMIT_MAX 200 10 5000 Upper bound for candidate vectors loaded per cache lookup

hybrid-mem stats and hybrid-mem health now also surface decay stickiness (stable+permanent) and guidance to run decay reclassify --dry-run --stable-only when legacy ratios are high.

Weekly pending digest (#1197)

Render an at-a-glance backlog of approve/decline/defer actions across persona proposals, procedure promotions, tool proposals, crystallization proposals, and verified facts:

openclaw hybrid-mem digest pending --since 7d --format md
openclaw hybrid-mem digest pending --since 7d --format json --out /tmp/pending.json

The JSON payload is versioned (schemaVersion: 1) and surfaces:

  • personaProposals.pendingEntries[].evidence — top supporting fact ids and total count derived from the proposal's evidenceSessions join against facts.provenance_session.
  • procedures.newThisWeek — count of procedures whose last_validated timestamp falls within the lookback window, alongside the existing validatedNotPromoted backlog.
  • Approve / decline / defer commands per entry so the operator can act without leaving the digest.

The installer registers hybrid-mem:weekly-pending-digest (Mondays 08:00) and respects digest.weekly.delivery.{ mode, chatId } to optionally announce the rendered markdown body to a Telegram channel. Full schema and rationale: docs/pending-digest.md.

Maintenance log format & analyzer

Hybrid-memory maintenance cron jobs write structured run artifacts under:

$HOME/.openclaw/logs/cron-hybrid-mem/YYYYMMDD/
  <job>-<timestamp>-<pid>.log
  <job>-<timestamp>-<pid>.exit.txt

Orchestrator runs may also write {job}-{runId}.summary.json and {job}-{runId}.validation.json (see docs/maintenance-job-runs.md). Per-command JobRun artifacts live under job-runs/{jobRunId}/.

Each .exit.txt file contains one line per step:

2026-05-07T02:10:21Z prune exit=0
2026-05-07T02:11:02Z distill exit=1
2026-05-07T02:12:10Z self-correct exit=0 status=skipped reason=skipped_cooldown

Use the analyzer to classify failures, persist regression history, emit an operator digest, and optionally report plugin/orchestration bugs through the existing GlitchTip path:

openclaw hybrid-mem maintenance analyze-logs --since 24h --digest md
openclaw hybrid-mem maintenance analyze-logs --since 7d --format json --out /tmp/maintenance-findings.json
openclaw hybrid-mem maintenance analyze-logs --since 24h --auto-fix --glitchtip --strict

Rules are data-driven in services/maintenance-rules.json, so operators can inspect or extend classifications without changing analyzer code. Findings are persisted in maintenance-findings.db table maintenance_finding, enabling week-over-week trend output for --since 7d / --trend runs. The digest collapses repeated fingerprints into New vs Still failing, suppresses stale historical fingerprints outside the current window from the primary findings, and avoids re-reporting already GlitchTip-reported fingerprints on every analyzer run. Known benign compatibility notices (for example missing registerContextEngine on older SDKs and Codex project-local config warnings) are collected in noiseWarnings[] and excluded from primary failure counts by default (#1833).

The installer registers hybrid-mem:maintenance-log-analyzer to run after the nightly chain and announce the rendered digest to the operator.

Unified maintenance inventory

Use the maintenance inventory report to see host crontab jobs and gateway ~/.openclaw/cron/jobs.json jobs in one place, including scheduler ownership, timezone, guard/log paths, last-run state, and collision groups:

openclaw hybrid-mem maintenance inventory
openclaw hybrid-mem maintenance inventory --format markdown
openclaw hybrid-mem maintenance inventory --json
Auto-fix whitelist (#1199)

--auto-fix applies only safe, idempotent actions implemented in services/maintenance-auto-fix.ts:

  • Stale scan lock files: when a finding includes a *.lock absolute path and the recorded PID is not running, the lock file is removed.
  • Retry-once marker: for transient LLM / network rules, the finding is annotated (auto-fixed-retry-once) so the next cron tick can retry — no extra shell commands are executed.

Add --auto-fix-all together with --auto-fix to opt into heavier remediation (still scoped to the maintenance analyzer):

  • Vacuum-on-busy: when at least two SQLITE_BUSY / “database is locked” findings fall within the configured persistence window (historical rows in maintenance-findings.db plus the current batch), runs VACUUM + WAL checkpoint on the open facts DB and invokes openclaw hybrid-mem vectordb-optimize.
  • Re-embed vectorless: when an embedding-auth rule matches in the current batch, runs openclaw hybrid-mem reembed-vectorless --limit 200 --apply once (useful after credentials were fixed).

Override the CLI binary with OPENCLAW_BIN if openclaw is not on PATH.

Resolved-issue suppression

services/maintenance-resolved.json maps finding fingerprints to { resolvedInVersion, note }. When the log’s parsed pluginVersion is >= resolvedInVersion (dotted numeric comparison), matching findings are dropped from the analyzer output to cut noise after a release fix.

Keywords