← Back to Plugins
Tools

Plugin Graph

CoderofTheWest By CoderofTheWest 👁 285 views ▲ 0 votes

Knowledge graph plugin for OpenClaw — entity extraction, triple storage, and graph-based retrieval

GitHub

Install

npm install
```

Configuration Example

{
  "plugins": {
    "load": {
      "paths": [
        "/path/to/openclaw-plugin-graph"
      ]
    },
    "entries": {
      "openclaw-plugin-graph": {
        "enabled": true,
        "config": {}
      }
    }
  }
}

README

# openclaw-plugin-graph

**Memory Graph** — a knowledge graph that learns the relationships in your conversations.

Extracts entities and relationships from every conversation, stores them as triples in a graph database, and uses that graph to surface contextually relevant connections the agent wouldn't otherwise recall. When a user mentions "Chris," the agent doesn't just search for exchanges containing that name — it traverses the graph to find what Chris created, who Chris knows, and what those people work on.

## What it does

- **Entity extraction**: Pulls people, places, organizations, dates, URLs, and concepts from conversation text using compromise.js NLP + regex patterns. Builds a gazetteer of known entities that improves extraction over time.
- **Relationship triples**: Stores `subject → predicate → object` triples with confidence scores, exchange provenance, and mention counts. 12 canonical predicates: `knows`, `created`, `uses`, `works_on`, `interested_in`, `located_in`, `part_of`, `prefers`, `related_to`, `has_property`, `occurred_at`, `causes`.
- **Multi-hop traversal**: Recursive CTE walks the graph up to N hops (default 2), finding indirect connections with score decay per hop. "Chris knows Dan, Dan created the analytics dashboard" surfaces in a query about Chris even though Chris never mentioned that dashboard.
- **Meta-path patterns**: Predicate-sequence patterns like `[knows, works_on]` or `[created, part_of]` find structurally meaningful paths. Ships with 5 static defaults; more are discovered automatically.
- **Pattern discovery**: During nightshift, the plugin evaluates candidate predicate sequences against the actual graph data. Filters by fanout cap, structural viability (minimum yield), and novelty (overlap with single-hop results). Only patterns that surface genuinely new connections survive.
- **Graph-aware context injection**: Before each conversation, injects a `[GRAPH CONTEXT]` block with natural-language relationship summaries — "Chris created the analytics dashboard, uses React, and knows Dan" — so the agent has relational awareness without being told.
- **LLM enrichment**: Queues exchanges for deeper extraction via LLM during nightshift. Produces cleaner, more nuanced triples than the fast-path NLP extractor.
- **Conversational entity resolution**: When the graph encounters ambiguous entities ("is this the same Bob?"), it uses a 3-tier approach — high confidence matches are assumed, low confidence ones prompt the agent to ask the user naturally, medium confidence ones are deferred for later resolution.
- **Archive backfill**: On first run, scans existing continuity archives and builds the graph retroactively. No conversations are lost just because the plugin was installed later.
- **RRF fusion with continuity**: Graph search results feed into continuity's Reciprocal Rank Fusion as a third ranked list alongside semantic and keyword search. Exchanges connected by graph relationships get boosted in recall.

## How it works

### Data flow

```
User message arrives
        │
        ▼
before_agent_start (priority 8)
        │
        ├── Extract entities from user message
        │     └── compromise.js NER + gazetteer matching
        │
        ├── Graph search (multi-hop + meta-path)
        │     ├── Recursive CTE traversal (bidirectional, N hops)
        │     ├── Meta-path pattern matching (static + discovered)
        │     └── Merge: max(hopScore, metaScore) per exchange
        │
        ├── Build [GRAPH CONTEXT] block
        │     └── Predicate-to-language templates → compound sentences
        │
        ├── Build [GRAPH NOTE] (entity resolution hints)
        │
        └── Publish results to global bus → continuity RRF
              └── global.__ocGraph.lastResults[agentId]

Model processes message + generates response

agent_end
        │
        ├── Fast-path extraction (compromise.js)
        │     ├── Entity extraction + triple generation
        │     └── Co-occurrence detection
        │
        ├── Queue for LLM enrichment (if enabled)
        │     └── Nightshift picks up queue → deeper extraction
        │
        └── Entity resolution (3-tier)
              ├── Assume (confidence > 0.8)
              ├── Ask (confidence < 0.4) → [GRAPH NOTE] next turn
              └── Defer (0.4–0.8) → pending_resolution

nightshift (graph-enrichment task, priority 35)
        │
        ├── LLM extraction on queued exchanges
        ├── Entity resolution on pending merges
        ├── Pattern discovery (every 24h)
        │     └── Candidate generation → fanout filter → viability → novelty
        └── Gap detection (under-connected entities)
```

### Storage

| Component | Location | Format |
|-----------|----------|--------|
| Graph database | `data/agents/{agentId}/graph.db` | SQLite (entities, triples, co-occurrences, meta-patterns) |
| Entity gazetteer | In-memory, built from DB | Maps normalized names → entity records |

Each agent gets its own isolated graph database. The plugin supports multiple agents on the same gateway without data mixing.

## Installation

### Prerequisites

- OpenClaw installed and running (gateway active)
- Node.js >= 18

### Install dependencies

```bash
cd /path/to/openclaw-plugin-graph
npm install
```

This installs:
- `better-sqlite3` — synchronous SQLite driver
- `compromise` — NLP library for entity extraction

### Configure OpenClaw

Add the plugin to your `~/.openclaw/openclaw.json`:

```json
{
  "plugins": {
    "load": {
      "paths": [
        "/path/to/openclaw-plugin-graph"
      ]
    },
    "entries": {
      "openclaw-plugin-graph": {
        "enabled": true,
        "config": {}
      }
    }
  }
}
```

### Restart the gateway

```bash
openclaw gateway restart
```

Verify the plugin loaded:

```bash
openclaw logs | grep "Graph plugin"
```

You should see:
```
Graph plugin registered — Phases 1-5: extraction + multi-hop traversal + meta-paths + context injection active
```

## Architecture

### Modules

```
index.js                     Main plugin — hook registration, orchestration
├── lib/
│   ├── extractor.js         compromise.js NER + regex + heuristic relationships
│   ├── graph-store.js       SQLite schema, prepared statements, CRUD
│   ├── graph-searcher.js    Single-hop, multi-hop CTE, meta-path queries
│   ├── context-builder.js   [GRAPH CONTEXT] natural-language generation
│   ├── pattern-discovery.js Nightshift pattern candidate evaluation
│   ├── entity-resolver.js   3-tier conversational resolution + merge
│   ├── llm-extractor.js     Ollama LLM extraction for deeper triples
│   └── backfill.js          Retroactive extraction from continuity archives
└── config.default.json      Default configuration
```

### Hooks registered

| Hook | Priority | Purpose |
|------|----------|---------|
| `before_agent_start` | 8 | Entity extraction, graph search, context injection, RRF publishing |
| `agent_end` | — | Fast-path extraction, enrichment queuing, entity resolution |
| `session_end` | — | Log session graph stats |

### Gateway methods

| Method | Purpose |
|--------|---------|
| `graph.getState` | Entity count, triple count, active patterns, last backfill |
| `graph.search` | Execute graph search (params: text, limit) |
| `graph.getEntity` | Look up a specific entity by name |
| `graph.getTriples` | Get triples for a subject or object |
| `graph.listAgents` | List all agents with graph data |
| `graph.detectGaps` | Find under-connected or stale entities |
| `graph.resolveEntity` | Manually resolve a pending entity |
| `graph.mergeEntities` | Merge two entities into one |
| `graph.backfillStatus` | Check archive backfill progress |
| `graph.rebuild` | Rebuild graph from scratch (destructive) |
| `graph.getPatterns` | List all active meta-path patterns (static + discovered) |
| `graph.discoverPatterns` | Trigger pattern discovery manually |

### Integration with other plugins

The graph plugin communicates with sibling plugins via the global bus pattern — no npm dependencies, just runtime wiring through `global` objects:

- **→ continuity**: Publishes search results to `global.__ocGraph.lastResults[agentId]`. Continuity's searcher picks these up for 3-way RRF fusion (semantic + keyword + graph).
- **→ nightshift**: Registers a `graph-enrichment` task runner and queues enrichment tasks for off-hours processing.
- **→ metabolism**: Subscribes to `global.__ocMetabolism.gapListeners` to receive knowledge gaps for enrichment, and fires discovered gaps back to metabolism listeners.

All integrations degrade gracefully — if a sibling plugin isn't loaded, the graph plugin continues without it.

## Configuration

All configuration is optional. The plugin ships with sensible defaults in `config.default.json`.

```json
{
  "extraction": {
    "minExchangeLength": 20,
    "skipHeartbeats": true,
    "maxEntitiesPerExchange": 15,
    "confidenceThreshold": 0.5,
    "canonicalPredicates": [
      "knows", "created", "uses", "located_in", "part_of",
      "interested_in", "prefers", "works_on", "related_to",
      "has_property", "occurred_at", "causes"
    ]
  },

  "retrieval": {
    "maxHops": 2,
    "maxResults": 20,
    "hopDecay": 0.7,
    "minTraversalConfidence": 0.6,
    "metaPathWeight": 0.8
  },

  "metaPaths": {
    "static": [
      { "predicates": ["interested_in", "interested_in"], "weight": 0.8 },
      { "predicates": ["created", "part_of"], "weight": 0.9 },
      { "predicates": ["knows", "works_on"], "weight": 0.85 },
      { "predicates": ["uses", "created"], "weight": 0.7 },
      { "predicates": ["works_on", "part_of"], "weight": 0.75 }
    ]
  },

  "patternDiscovery": {
    "enabled": true,
    "maxActivePatterns": 12,
    "minYield": 3,
    "maxOverlapRatio": 0.9,
    "maxFanoutPerStep": 50

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...