Skip to content

Kakezh/openclaw-memoryplus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8,810 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@kakezh/memory-x

npm version License: MIT GitHub Packages

Framework-agnostic hierarchical memory system for AI agents

Based on xMemory and Memory Taxonomy research papers.


📋 Features

Feature Description
Framework-Agnostic Works with OpenClaw, LangChain, or standalone
Hierarchical Storage 4-level memory hierarchy (Original → Episode → Semantic → Theme)
3D Taxonomy Form × Function × Dynamics classification
Knowledge Graph Entity-relationship management with path finding
Multi-Hop Reasoning Complex inference across memory hierarchy
Forgetting Mechanism Ebbinghaus curve-based memory lifecycle
Conflict Detection Automatic detection and resolution of memory conflicts
Zero Config Works out of the box, no setup required
Cross-Platform Pure JavaScript, no native dependencies
Type-Safe Full TypeScript support

📦 Installation

From GitHub Packages

# Create .npmrc file (one-time setup)
echo "@kakezh:registry=https://npm.pkg.github.com" > ~/.npmrc

# Install
npm install @kakezh/memory-x

From Source

git clone https://github.com/Kakezh/openclaw-memoryplus.git
cd openclaw-memoryplus/extensions/memory-x
pnpm install && pnpm build

🚀 Quick Start

Standalone Usage

import { MemoryEngine } from '@kakezh/memory-x';

// Create engine (zero config)
const memory = new MemoryEngine();
await memory.init();

// Store a memory
await memory.remember("User prefers dark mode", {
  type: "preference",
  confidence: 0.9,
  entities: ["User"]
});

// Recall memories
const result = await memory.recall("user preferences");
console.log(result.evidence);

// Get statistics
const stats = memory.stats();
console.log(stats);

Using Tools Interface

import { createMemoryX } from '@kakezh/memory-x';

const adapter = await createMemoryX();

// Get all tools
const tools = adapter.getTools();

// Execute a tool
const result = await adapter.execute('memory_remember', {
  content: "User likes TypeScript",
  type: "preference"
});

With OpenClaw

import { createOpenClawPlugin } from '@kakezh/memory-x/adapters/openclaw';

export default createOpenClawPlugin({
  workspacePath: "./data"
});

🏗️ Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                           Memory-X System Architecture                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                     Framework-Agnostic Core                          │    │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                  │    │
│  │  │   Memory    │  │   Vector    │  │   Dynamics  │                  │    │
│  │  │   Engine    │  │   Index     │  │  (Forget)   │                  │    │
│  │  └─────────────┘  └─────────────┘  └─────────────┘                  │    │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                  │    │
│  │  │  Knowledge  │  │  Multi-Hop  │  │  Conflict   │                  │    │
│  │  │   Graph     │  │  Reasoning  │  │  Detector   │                  │    │
│  │  └─────────────┘  └─────────────┘  └─────────────┘                  │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│  ┌─────────────────────────────────┼───────────────────────────────────┐    │
│  │                          Adapters Layer                              │    │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                  │    │
│  │  │  Generic    │  │  OpenClaw   │  │  LangChain  │                  │    │
│  │  │  Adapter    │  │  Adapter    │  │  Adapter    │                  │    │
│  │  └─────────────┘  └─────────────┘  └─────────────┘                  │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│  ┌─────────────────────────────────┼───────────────────────────────────┐    │
│  │                         Storage Layer                                │    │
│  │  ┌─────────────────────────────────────────────────────────────┐   │    │
│  │  │  SQLite (sql.js / better-sqlite3) - Auto-select backend     │   │    │
│  │  └─────────────────────────────────────────────────────────────┘   │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Directory Structure

memory-x/
├── core/                      # Framework-agnostic core
│   ├── engine.ts              # MemoryEngine class
│   ├── types.ts               # Type definitions
│   └── index.ts               # Core exports
│
├── adapters/                  # Framework adapters
│   ├── generic.ts             # Generic adapter (any project)
│   ├── openclaw.ts            # OpenClaw adapter
│   └── index.ts               # Adapter exports
│
├── store/                     # Storage implementations
│   ├── sqlite-store.ts        # Native SQLite (better-sqlite3)
│   ├── sqljs-store.ts         # Pure JS SQLite (sql.js)
│   └── vector-index.ts        # Vector similarity search
│
├── dynamics/                  # Memory lifecycle
│   ├── forgetting.ts          # Ebbinghaus forgetting curve
│   └── conflict.ts            # Conflict detection & resolution
│
└── reasoning/                 # Advanced reasoning
    ├── knowledge-graph.ts     # Entity-relationship graph
    └── multi-hop.ts           # Multi-hop inference engine

🧠 Core Concepts

1. Four-Level Hierarchy (xMemory)

Memory-X implements a hierarchical memory structure inspired by human cognition:

┌─────────────────────────────────────────────────────────────────────────────┐
│ Level 4: Theme (主题)                                                        │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ High-level concepts: User preferences, projects, domain knowledge       │ │
│ │ Example: { name: "编程偏好", semanticIds: ["sem-1", "sem-2"] }          │ │
│ │ Auto-created from entity references in semantic memories                │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│                                    ▲                                         │
│                                    │ contains                                │
│ Level 3: Semantic (语义)                                                     │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Reusable facts: preferences, goals, constraints, events                 │ │
│ │ Example: { content: "User prefers TypeScript", type: "preference" }     │ │
│ │ Extracted from episodes, can be searched semantically                   │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│                                    ▲                                         │
│                                    │ extracted from                         │
│ Level 2: Episode (片段)                                                      │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Contiguous message blocks: conversation segments, task context          │ │
│ │ Example: { summary: "讨论项目架构...", originalIds: ["orig-1"] }         │ │
│ │ Grouped by topic or time boundaries                                     │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│                                    ▲                                         │
│                                    │ contains                                │
│ Level 1: Original (原始)                                                     │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Raw messages: User input, Agent responses                               │ │
│ │ Example: { content: "请帮我写一个函数", speaker: "user" }                │ │
│ │ Immutable record of all interactions                                    │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘

Data Flow:

User Input → Original → Episode → Semantic → Theme
                ↓          ↓          ↓         ↓
            Raw Log   Summarize  Extract   Organize

2. 3D Taxonomy (Memory Classification)

Memory-X classifies memories across three dimensions:

                    Form
                     │
         ┌───────────┼───────────┐
         │           │           │
      token     parametric     latent
    (context)  (weights)    (hidden)
         │           │           │
         └───────────┼───────────┘
                     │
    ┌────────────────┼────────────────┐
    │                │                │
Function          Function         Function
    │                │                │
factual        experiential      working
(objective)     (personal)      (temporal)
    │                │                │
    └────────────────┼────────────────┘
                     │
         ┌───────────┼───────────┐
         │           │           │
    Forgetting   Conflict    Reconstruction
      Curve      Resolution     (future)
         │           │           │
         └───────────┼───────────┘
                     │
                 Dynamics
Dimension Values Description
Form token, parametric, latent Where memory exists
Function factual, experiential, working What memory is used for
Dynamics forgetting, conflict, reconstruction How memory evolves

3. Memory Types

type MemoryType = 
  | 'fact'        // Objective truth: "Paris is the capital of France"
  | 'preference'  // User preferences: "User prefers dark mode"
  | 'goal'        // Goals and objectives: "Complete the project by Friday"
  | 'constraint'  // Rules and limits: "API rate limit is 1000/hour"
  | 'event';      // Time-based events: "Meeting scheduled for 3pm"

4. Knowledge Graph

Memory-X automatically builds a knowledge graph from entity references:

// Entity Types
type EntityType = 
  | 'person'         // People
  | 'organization'   // Companies, teams
  | 'location'       // Places
  | 'concept'        // Abstract concepts
  | 'event'          // Events
  | 'object'         // Physical objects
  | 'topic';         // Topics/subjects

// Relation Types
type RelationType = 
  | 'related_to'     // Generic relation
  | 'part_of'        // Composition
  | 'has_property'   // Property
  | 'prefers'        // Preference
  | 'dislikes'       // Dislike
  | 'works_at'       // Employment
  | 'located_in'     // Location
  | 'occurred_at'    // Event location
  | 'caused_by'      // Causation
  | 'follows'        // Sequence
  | 'contradicts';   // Conflict

Example Graph:

┌─────────┐    prefers    ┌─────────┐
│  User   │──────────────▶│Dark Mode│
└─────────┘               └─────────┘
     │
     │ works_at
     ▼
┌─────────┐    located_in ┌─────────┐
│Acme Corp│──────────────▶│New York │
└─────────┘               └─────────┘

5. Forgetting Mechanism

Based on the Ebbinghaus forgetting curve:

Retention
    │
1.0 ┤●
    │  ╲
0.8 ┤    ●
    │      ╲
0.6 ┤        ●
    │          ╲
0.4 ┤            ●
    │              ╲
0.2 ┤                ●●●
    │
0.0 ┤──────────────────────▶ Time (days)
    0   1   2   5   10  30

Formula: R = e^(-t/S) where:

  • R = Retention score
  • t = Time elapsed (days)
  • S = Stability (increases with access count)

Importance Score considers:

  • Confidence level
  • Memory type weight
  • Entity connections
  • Theme membership

6. Conflict Detection

Automatically detects and resolves conflicts:

Conflict Type Example Resolution
Factual "User is 25" vs "User is 30" Keep highest confidence
Preference "User likes X" vs "User dislikes X" Ask user or keep newest
Temporal Overlapping validity periods Merge or split

🛠️ API Reference

MemoryEngine

class MemoryEngine {
  constructor(config?: MemoryConfig);
  
  // Lifecycle
  init(): Promise<void>;
  close(): void;
  
  // Core methods
  remember(content: string, options?: RememberOptions): Promise<RememberResult>;
  recall(query: string, options?: RecallOptions): Promise<RecallResult>;
  reflect(): Promise<ReflectResult>;
  stats(): MemoryStats;
  
  // Tool interface
  getTools(): MemoryTool[];
  executeTool(name: string, params: any): Promise<MemoryToolResult>;
  
  // Events
  on(event: string, handler: MemoryEventHandler): void;
}

Core Methods

remember()

Store a memory with automatic hierarchy classification:

await memory.remember("User prefers dark mode", {
  type: "preference",      // Memory type
  confidence: 0.9,         // Confidence score (0-1)
  entities: ["User"]       // Entity references for knowledge graph
});

// Returns:
// {
//   success: true,
//   ids: {
//     original: "orig-...",
//     episode: "ep-...",
//     semantic: "sem-...",
//     theme: "theme-..."
//   }
// }

recall()

Retrieve memories using semantic search:

const result = await memory.recall("user preferences", {
  maxTokens: 4000  // Maximum tokens to return
});

// Returns:
// {
//   evidence: {
//     themes: [{ id, name }],
//     semantics: [{ id, content, score }],
//     episodes: [{ id, summary }]
//   },
//   metrics: {
//     totalTokens: 1234,
//     evidenceDensity: 0.85
//   }
// }

reflect()

Discover patterns from memory themes:

const patterns = await memory.reflect();

// Returns:
// {
//   patterns: [{
//     themeId: "theme-...",
//     themeName: "编程偏好",
//     occurrenceCount: 5,
//     suggestedSkill: "SOP for 编程偏好"
//   }],
//   evolutionSuggestions: [...]
// }

Tools API

Tool Parameters Description
memory_remember content, type?, confidence?, entities? Store memory
memory_recall query, maxTokens? Retrieve memories
memory_reflect - Discover patterns
memory_status - Get statistics

Types

interface MemoryConfig {
  workspacePath?: string;           // Storage path (default: "./memory-data")
  storage?: "sqlite" | "memory";    // Storage backend (default: "sqlite")
  hierarchy?: {
    maxThemeSize?: number;          // Max memories per theme (default: 50)
    minThemeCoherence?: number;     // Min coherence score (default: 0.7)
    autoReorganize?: boolean;       // Auto-reorganize themes (default: true)
  };
  retrieval?: {
    themeTopK?: number;             // Top themes to retrieve (default: 3)
    semanticTopK?: number;          // Top semantics to retrieve (default: 5)
    maxTokens?: number;             // Max tokens in response (default: 4000)
  };
}

interface RememberOptions {
  type?: "fact" | "preference" | "goal" | "constraint" | "event";
  confidence?: number;    // 0-1, default: 0.5
  entities?: string[];    // Entity references
}

interface RecallOptions {
  maxTokens?: number;     // Default: 4000
}

⚙️ Configuration

Basic Configuration

const memory = new MemoryEngine({
  workspacePath: "./my-memory-data"
});
await memory.init();

Full Configuration

const memory = new MemoryEngine({
  workspacePath: "./data",
  storage: "sqlite",
  hierarchy: {
    maxThemeSize: 50,
    minThemeCoherence: 0.7,
    autoReorganize: true
  },
  retrieval: {
    themeTopK: 3,
    semanticTopK: 5,
    maxTokens: 4000
  }
});
await memory.init();

🔧 Storage Backends

Memory-X automatically selects the best available storage backend:

Backend Performance Portability Dependencies
better-sqlite3 ⚡ Fastest Platform-specific Native compilation
sql.js 🔄 Good Cross-platform Pure JavaScript

No configuration needed - the system auto-detects and uses the best available option.


📊 Performance

Theoretical Benefits (from xMemory Paper)

The following metrics are based on the xMemory research paper:

Metric Value Description
Token Efficiency -30% Reduction vs flat retrieval through hierarchical filtering
QA Accuracy +10% Improvement vs RAG baseline with evidence density scoring
Evidence Density Higher relevance vs simple top-k retrieval

Measured Performance (Benchmark Results)

The following metrics are from actual benchmark tests run on:

Environment Value
Platform Linux x64
Node.js v22.22.0
CPU Cores 16
Total RAM 6.70 GB

Storage Performance

Operation Mean P50 P95 P99
Single Write 49.02 µs 14.55 µs 103.38 µs 1.50 ms
Batch Write (100) 1.14 ms 635.42 µs 3.24 ms 3.24 ms
Search (100 memories) 6.25 µs 2.64 µs 9.99 µs 131.48 µs
Search (500 memories) 3.86 µs 3.09 µs 8.14 µs 10.87 µs
Search (1000 memories) 9.46 µs 7.61 µs 13.82 µs 49.75 µs
Search (5000 memories) 57.19 µs 38.83 µs 79.34 µs 803.95 µs

Hierarchy Operations

Operation Mean P50 P95 Grade
Remember (4-level) 7.13 µs 6.58 µs 11.41 µs 🟢 Excellent
Recall (500 memories) 5.26 µs 4.63 µs 8.46 µs 🟢 Excellent
Reflect (100 memories) 30.60 µs 1.98 µs 341.47 µs 🟢 Excellent
Stats (1000 memories) 3.14 µs 3.02 µs 3.42 µs 🟢 Excellent

Memory Overhead

Metric Value
Per Memory Overhead ~882 B
1000 Memories ~861 KB

Implementation Characteristics

Aspect Description
Storage SQLite with auto-select backend (sql.js / better-sqlite3)
Search Keyword-based with vector similarity (when embedding provider configured)
Memory Model 4-level hierarchy with automatic classification

Running Benchmarks

cd extensions/memory-x
pnpm bench

Results are saved to bench/results.json.


📚 Advanced Usage

Event Handling

memory.on('memory:created', (event) => {
  console.log('New memory:', event.payload);
});

memory.on('memory:conflict', (event) => {
  console.log('Conflict detected:', event.payload);
});

Custom Embedding Provider

import { IEmbeddingProvider } from '@kakezh/memory-x';

class MyEmbeddingProvider implements IEmbeddingProvider {
  async embed(text: string): Promise<number[]> {
    // Your embedding logic
    return [/* vector */];
  }

  async embedBatch(texts: string[]): Promise<number[][]> {
    return Promise.all(texts.map(t => this.embed(t)));
  }
}

memory.setEmbeddingProvider(new MyEmbeddingProvider());

Best Practices

// 1. Use appropriate memory types
await memory.remember("Paris is the capital of France", { type: "fact" });
await memory.remember("User prefers dark mode", { type: "preference" });
await memory.remember("Complete project by Friday", { type: "goal" });
await memory.remember("API rate limit is 1000/hour", { type: "constraint" });
await memory.remember("Meeting at 3pm", { type: "event" });

// 2. Provide entity references for knowledge graph
await memory.remember("John works at Acme Corp", {
  type: "fact",
  entities: ["John", "Acme Corp"]
});

// 3. Set confidence for uncertain information
await memory.remember("User might be interested in Python", {
  type: "preference",
  confidence: 0.6
});

// 4. Always close the engine when done
process.on('SIGTERM', () => memory.close());

📖 References

  1. xMemory: Beyond RAG for Agent Memory - Four-level hierarchy concept
  2. Memory Taxonomy: Memory in the Age of AI Agents - 3D classification system
  3. AMemGym: Interactive Memory Benchmarking - Evaluation framework

📝 Changelog

v1.0.0 (Current)

  • ✅ Framework-agnostic architecture (Core + Adapters)
  • ✅ Published to GitHub Packages
  • ✅ Zero configuration setup
  • ✅ Cross-platform support (sql.js)
  • ✅ Full TypeScript support
  • ✅ Knowledge graph with path finding
  • ✅ Multi-hop reasoning engine
  • ✅ Ebbinghaus forgetting mechanism
  • ✅ Conflict detection & resolution

📄 License

MIT © Kakezh


Author: Kakezh
Repository: github.com/Kakezh/openclaw-memoryplus
Package: @kakezh/memory-x
Documentation: INTEGRATION.md | ARCHITECTURE.md

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors