← Back to Plugins
Tools

Noesis

blaspat By blaspat 👁 152 views ▲ 0 votes

Memory plugin for OpenClaw agents

GitHub

Install

npm install @blaspat/openclaw-noesis

Configuration Example

{
  "plugins": {
    "entries": {
      "noesis": {
        "enabled": true,
        "config": {
          "ollamaEndpoint": "http://localhost:11434",
          "embeddingModel": "nomic-embed-text",
          "topK": 6,
          "indexQmdSessions": true
        }
      }
    },
    "slots": {
      "memory": "noesis"
    }
  }
}

README

# Noesis — Local-First Semantic Memory for OpenClaw

Local-first semantic memory for OpenClaw. No API keys. No cloud. Just your data, on your machine.

Noesis gives your OpenClaw agents a persistent, searchable memory layer backed by [LanceDB](https://lancedb.com) and [Ollama](https://ollama.ai). It slots directly into OpenClaw's memory system so the auto-recall loop just works — your agents remember things across sessions, across restarts, and across each other.

---

## Table of Contents

- [Why Noesis?](#why-noesis)
- [Stack](#stack)
- [Installation](#installation)
  - [1. Install the plugin](#1-install-the-plugin)
  - [2. Set the memory slot](#2-set-the-memory-slot)
  - [3. Start Ollama](#3-start-ollama)
  - [4. Restart the gateway](#4-restart-the-gateway)
- [How It Works](#how-it-works)
  - [Hybrid Search Pipeline](#hybrid-search-pipeline)
  - [Memory Types](#memory-types)
  - [When Agents Write to Noesis](#when-agents-write-to-noesis)
  - [Multi-Agent Isolation](#multi-agent-isolation)
  - [ANN Index](#ann-index)
- [Tools](#tools)
  - [Agent tools](#agent-tools-use-these-in-your-prompts)
  - [Memory slot tools](#memory-slot-tools-used-by-openclaw-auto-recall)
- [Data Model](#data-model)
- [Migrating Existing Memory Files](#migrating-existing-memory-files)
- [Configuration](#configuration)
  - [Embedding Model Choice](#embedding-model-choice)
- [Performance](#performance)
- [Git LFS Persistence](#git-lfs-persistence)
- [Requirements](#requirements)
- [Python CLI Dependencies](#python-cli-dependencies)
- [Architecture Notes](#architecture-notes)
- [License](#license)

---

## Why Noesis?

The pain points it solves:

- **"My agent forgets everything between sessions"** — Noesis persists memory to disk in LanceDB. It survives restarts.
- **"I want semantic search, not just keyword matching"** — Hybrid pipeline: vector ANN + BM25 keyword + MMR reranking.
- **"I don't want to pay API costs for memory"** — Ollama embeddings, fully local. Zero external calls.
- **"I have multiple agents and want shared memory"** — Multi-agent support with `agentId` isolation and opt-in cross-agent search.
- **"Built-in memory search is too slow for large datasets"** — LanceDB IVF-PQ ANN index: sub-30ms queries at scale.

---

## Stack

| Layer | Technology |
|-------|-----------|
| Vector store | LanceDB (disk-based, ARM64 native) |
| Embeddings | Ollama (local, no API key) |
| Default model | `nomic-embed-text` (768d, fast, ~274MB) |
| Alt model | `mxbai-embed-large` (1024d, higher accuracy) |
| Search | Vector ANN + BM25 FTS + MMR rerank |
| Session indexing | QMD session watcher |
| Plugin type | Memory slot (`plugins.slots.memory: "noesis"`) |

---

## Installation

### 1. Install the plugin

```bash
# Via npm (if published as `@blaspat/openclaw-noesis`)
npm install @blaspat/openclaw-noesis

# Or via ClawHub
openclaw plugins install clawhub:@blaspat/openclaw-noesis
```

### 2. Set the memory slot

```bash
openclaw config set plugins.slots.memory noesis
```

Or edit your OpenClaw config:

```json
{
  "plugins": {
    "entries": {
      "noesis": {
        "enabled": true,
        "config": {
          "ollamaEndpoint": "http://localhost:11434",
          "embeddingModel": "nomic-embed-text",
          "topK": 6,
          "indexQmdSessions": true
        }
      }
    },
    "slots": {
      "memory": "noesis"
    }
  }
}
```

### 3. Start Ollama

```bash
ollama serve
```

Noesis auto-detects Ollama on startup and pulls the embedding model if it's not already downloaded. No manual steps needed.

### 4. Restart the gateway

```bash
openclaw gateway restart
```

That's it. Your agents now have persistent semantic memory.

---

## How It Works

### Hybrid Search Pipeline

Every `memory_search` call runs through this pipeline:

```
Query text
   ↓
Ollama embeddings (~20ms, local)
   ↓
LanceDB IVF-PQ vector search (topK × 2 candidates)
   ↓
BM25 full-text search (keyword fallback/supplement)
   ↓
Hybrid merge (vector 60% + BM25 40%)
   ↓
MMR rerank (λ=0.7, balances relevance + diversity)
   ↓
Top-K results with full content (lossless)
```

### Memory Types

| Type | Used for |
|------|---------|
| `fact` | Objective info (names, settings, world knowledge) |
| `decision` | Things that were decided, logged for recall |
| `preference` | How things should be done |
| `context` | Project or session context |
| `session` | Auto-indexed from QMD session transcripts |

### When Agents Write to Noesis

Noesis auto-indexes without needing explicit agent calls. Memory flows in through these paths:

**1. Session transcripts (automatic)**

When `indexQmdSessions: true`, a background watcher picks up new QMD session files in `~/.openclaw/sessions/`. Session content is chunked and stored as `memoryType: session` entries under the agent's session ID.

**2. Agent memory dirs (automatic)**

When `watchMemoryDirs: true`, Noesis watches `~/.openclaw/agents/*/workspace/memory/*.md`. Any `.md` file in an agent's memory directory is checksummed, chunked, and indexed — deduplicated by content hash. This includes `MEMORY.md`, daily notes, and anything else an agent writes to disk.

**3. Manual via `noesis_index`**

Agents can call `noesis_index` directly with text, tags, `memoryType`, `priority`, and `ttlDays`. Used for explicitly important entries — a decision the agent wants to guarantee will be remembered.

### Multi-Agent Isolation

Each entry stores an `agentId`. By default, search only returns entries from the querying agent. Pass `crossAgent: true` to search across all agents (read-only — agents can't write each other's memories).

### ANN Index

After enough data is loaded, Noesis creates an IVF-PQ index on the embedding column:

- **nprobe = 16** — 16 partition probes per query. >90% recall at ~20ms on HDD.
- **num_sub_vectors = 96** — PQ compression for 768-dim vectors.
- Index is persistent on disk and survives restarts.

---

## Tools

### Agent tools (use these in your prompts)

| Tool | Description |
|------|-------------|
| `noesis_index` | Store a memory entry (text + metadata + priority + TTL) |
| `noesis_search` | Semantic search with filters |
| `noesis_recall` | List recent entries by agent or session |
| `noesis_import` | Trigger MD → LanceDB migration |
| `noesis_stats` | Entry counts, breakdown by agent/type/priority, expired count |
| `noesis_delete` | Delete entry by ID |
| `noesis_cleanup` | Apply 20% score penalty to all currently expired entries (stay in DB) |
| `noesis_export` | Bulk export all entries as JSON (with optional filters) |
| `noesis_set_priority` | Update priority and/or TTL on an existing entry |

### Memory slot tools (used by OpenClaw auto-recall)

| Tool | Description |
|------|-------------|
| `memory_search` | Auto-recall entry point |
| `memory_get` | Retrieve by ID |
| `memory_index` | Auto-index new content |
| `memory_recall` | Cross-session recall |

---

## Data Model

```
memories table:
  id           string    UUID v4
  agentId      string    "assistantAgent", "tradeAgent", etc.
  sessionId    string    OpenClaw session ID
  content      string    Full original text (lossless)
  chunk        string    Embedded chunk (for reference)
  embedding    float32[] 768-dim or 1024-dim vector
  memoryType   string    fact/decision/preference/context/session
  priority     int64     Priority 0–100 (high ≥75 always surfaces)
  expiresAt    int64     Unix ms. 0 = never. Penalized at 20% score after expiry.
  createdAt    int64     Unix timestamp (ms)
  sourcePath   string    Origin .md or QMD file path
  checksum     string    SHA-256(content+agentId) for dedup
  tags         string[]  Custom tags
```

---

## Migrating Existing Memory Files

If you have existing markdown memory files (`MEMORY.md`, `memory/*.md`), import them:

```bash
# Import one agent
noesis_import agentId=<agentId>

# Import all agents
noesis_import
```

Or use the standalone Python CLI:

**Standalone Python CLI:**
```bash
pip install lancedb requests

python3 scripts/import_memory.py --agent <agentId>
python3 scripts/import_memory.py --all
python3 scripts/import_memory.py --agent <agentId> --chunk-size 256 --model mxbai-embed-large
```

---

## Configuration

| Key | Default | Description |
|-----|---------|-------------|
| `lanceDbPath` | `~/.openclaw/noesis/db` | LanceDB storage directory |
| `ollamaEndpoint` | `http://localhost:11434` | Ollama API endpoint |
| `embeddingModel` | `nomic-embed-text` | Embedding model (see below) |
| `chunkSize` | `512` | Chunk size in words |
| `chunkOverlap` | `64` | Overlap between chunks |
| `topK` | `6` | Default search result count |
| `autoMigrate` | `false` | Auto-import markdown files on startup |
| `indexQmdSessions` | `true` | Watch + auto-index QMD sessions |
| `watchMemoryDirs` | `false` | Watch agent memory dirs for changes and auto-index .md files |
| `defaultTtlDays` | `90` | Default TTL in days for new entries. `0` = never expire. |
| `autoCleanup` | `true` | On startup, penalize expired entries (20% score). Entries stay in DB. |
| `gitLfsEnabled` | `false` | Enable Git LFS persistence for LanceDB backups |
| `gitLfsRepo` | `blaspat/openclaw-noesis-data` | GitHub repo for Git LFS snapshots |
| `annNprobe` | `16` | IVF-PQ search probes (higher = more accurate, slower) |
| `annNumSubvectors` | `96` | IVF-PQ compression granularity |

### Embedding Model Choice

**`nomic-embed-text` (default, 768d, ~274MB)**
- Faster inference (~20ms on CPU)
- Excellent for short queries and agent memory recall
- Recommended for most setups

**`mxbai-embed-large` (alternative, 1024d, ~834MB)**
- Higher accuracy on longer contexts
- Better MTEB scores overall
- Use when retrieval accuracy matters more than speed

Switch model:
```json
{ "plugins": { "entries": { "noesis": { "config": { "embeddingModel": "mxbai-embed-large" } } } } }
```

---

## Performance

| Setup | Query latency | Notes |
|-------|--------------|-------|
| No index, small dataset | ~50–200ms | Fine for <1K entries |
| IVF-PQ index, HDD | ~2

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...