Skip to content
This repository was archived by the owner on Feb 27, 2026. It is now read-only.
This repository was archived by the owner on Feb 27, 2026. It is now read-only.

feat: hook memory_search tool to query nova_memory database instead of filesystem #144

Description

@NOVA-Openclaw

Problem

The memory_search tool (built into OpenClaw) searches MEMORY.md and memory/*.md files using a local SQLite QMD index. Our actual memory system lives in PostgreSQL (nova_memory database) with vector embeddings in memory_embeddings table — entity facts, daily logs, lessons, events, processed chats, etc. (3,600+ embeddings).

This creates a split: the tool searches the filesystem while our real memories are in the database. The filesystem files are mostly session notes that get embedded into the database anyway. We should hook the tool to query the database directly.

Proposed Solution

Create a new hook: memory-recall

  • Fires on before_tool_call (OpenClaw supports this — see pi-tools.before-tool-call.ts)
  • Intercepts calls to memory_search tool
  • Instead of letting the default filesystem search run, queries memory_embeddings in PostgreSQL using the same OpenAI text-embedding-3-small embeddings we already have
  • Returns results in the same format the tool expects (path, snippet, score, startLine, endLine)
  • Falls back to default filesystem search if database is unavailable

Query flow:

  1. Embed the query using OpenAI text-embedding-3-small (same model as our embeddings)
  2. Query memory_embeddings with cosine similarity (`<=>\ operator via pgvector)
  3. Apply memory_type_priorities weighting
  4. Return top N results formatted as MemorySearchResult

Hook structure:

hooks/memory-recall/
  handler.ts    # before_tool_call hook
  package.json  # {"type": "module"}
  HOOK.md       # metadata: {"openclaw":{"events":["before_tool_call"]}}

Existing infrastructure to leverage

  • memory_embeddings table with pgvector — already has 3,600+ embedded records
  • memory_type_priorities table — weights different source types
  • text-embedding-3-small (1536 dims) — same model, same embeddings
  • proactive-recall.py — existing Python script that does this exact query (can reference for SQL patterns)
  • loadPgEnv() from ~/.openclaw/lib/pg-env.ts — standard PG connection pattern

Files to create/modify

  1. hooks/memory-recall/handler.ts — new hook
  2. hooks/memory-recall/package.json{"type": "module"}
  3. hooks/memory-recall/HOOK.md — hook metadata for before_tool_call
  4. agent-install.sh — sync new hook to ~/.openclaw/hooks/

Constraints

  • Must return results in OpenClaw's expected MemorySearchResult format
  • Must respect maxResults and minScore parameters from the tool call
  • Fail silently and fall through to default filesystem search on any error
  • Latency budget: < 2s for the full embed + query cycle
  • Use loadPgEnv() for database credentials (standard pattern)

Related

  • semantic-recall hook — automatic per-turn injection (different: that's push, this is pull)
  • proactive-recall.py — Python script with the exact pgvector query pattern
  • memory_embeddings table — the actual data source
  • nova-memory feat: agent_turn_context table and per-turn injection hook #143agent_turn_context (complementary feature)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions