memory-mimir 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -0
- package/dist/formatter.d.ts +18 -0
- package/dist/formatter.js +129 -0
- package/dist/formatter.js.map +1 -0
- package/dist/index.d.ts +104 -0
- package/dist/index.js +905 -0
- package/dist/index.js.map +1 -0
- package/dist/integration-test.d.ts +5 -0
- package/dist/integration-test.js +163 -0
- package/dist/integration-test.js.map +1 -0
- package/dist/migration-helpers.d.ts +5 -0
- package/dist/migration-helpers.js +20 -0
- package/dist/migration-helpers.js.map +1 -0
- package/dist/migration.d.ts +38 -0
- package/dist/migration.js +189 -0
- package/dist/migration.js.map +1 -0
- package/dist/mimir-client.d.ts +174 -0
- package/dist/mimir-client.js +225 -0
- package/dist/mimir-client.js.map +1 -0
- package/dist/test.d.ts +5 -0
- package/dist/test.js +224 -0
- package/dist/test.js.map +1 -0
- package/openclaw.plugin.json +54 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# memory-mimir
|
|
2
|
+
|
|
3
|
+
OpenClaw plugin that connects to [Mimir](https://github.com/TripleWhite/Mimir-Go) — a unified long-term memory engine. Gives your OpenClaw agent persistent, searchable memory across sessions.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
User message → auto-recall (search Mimir) → inject <memories> → Agent runs → auto-capture (ingest new messages)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Auto-recall**: Before each agent turn, extracts keywords from the user message (supports English + CJK), searches Mimir with agentic retrieval, and injects the most relevant memories into the LLM context.
|
|
12
|
+
|
|
13
|
+
**Auto-capture**: After each agent turn, incrementally captures new conversation messages and sends them to Mimir for extraction (episodes, entities, relations, events).
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- Agentic search with query classification and strategy routing
|
|
18
|
+
- CJK (Chinese/Japanese/Korean) keyword extraction
|
|
19
|
+
- Time range extraction from natural language ("last week", "昨天")
|
|
20
|
+
- Score-ordered compact memory formatting (2000 char budget)
|
|
21
|
+
- Incremental capture — no duplicate ingestion across agent turns
|
|
22
|
+
- Two tool definitions: `mimir_search` and `mimir_ingest` for manual use
|
|
23
|
+
|
|
24
|
+
## Setup
|
|
25
|
+
|
|
26
|
+
### Prerequisites
|
|
27
|
+
|
|
28
|
+
A running [Mimir](https://github.com/TripleWhite/Mimir-Go) server.
|
|
29
|
+
|
|
30
|
+
### Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install
|
|
34
|
+
npm run build
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Configure
|
|
38
|
+
|
|
39
|
+
In your OpenClaw plugin config:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"mimirUrl": "http://localhost:8766",
|
|
44
|
+
"userId": "your-user-id",
|
|
45
|
+
"groupId": "your-group-id",
|
|
46
|
+
"autoRecall": true,
|
|
47
|
+
"autoCapture": true,
|
|
48
|
+
"maxRecallItems": 8,
|
|
49
|
+
"maxRecallTokens": 2000
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
| Option | Type | Default | Description |
|
|
54
|
+
|--------|------|---------|-------------|
|
|
55
|
+
| `mimirUrl` | string | — | Mimir server URL |
|
|
56
|
+
| `userId` | string | — | User ID for memory isolation |
|
|
57
|
+
| `groupId` | string | — | Group ID for memory scoping |
|
|
58
|
+
| `autoRecall` | boolean | `true` | Inject memories before each turn |
|
|
59
|
+
| `autoCapture` | boolean | `true` | Capture conversations after each turn |
|
|
60
|
+
| `maxRecallItems` | number | `8` | Max memory items per recall |
|
|
61
|
+
| `maxRecallTokens` | number | `2000` | Max chars for memory context |
|
|
62
|
+
|
|
63
|
+
## Architecture
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
memory-mimir (this plugin) Mimir-Go (engine)
|
|
67
|
+
┌─────────────────────┐ ┌──────────────────────┐
|
|
68
|
+
│ extractKeywords() │ │ Agentic Search │
|
|
69
|
+
│ extractTimeRange() │──search──→ │ ├─ Query Analyzer │
|
|
70
|
+
│ formatResults() │←─results── │ ├─ BM25 + Vector │
|
|
71
|
+
│ │ │ └─ Graph Traverse │
|
|
72
|
+
│ auto-capture │──ingest──→ │ Pipeline │
|
|
73
|
+
│ (incremental) │ │ ├─ Narrative Extract │
|
|
74
|
+
│ │ │ └─ Graph Extract │
|
|
75
|
+
└─────────────────────┘ └──────────────────────┘
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Run tests
|
|
82
|
+
npm test
|
|
83
|
+
|
|
84
|
+
# Build
|
|
85
|
+
npm run build
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Mimir search results into compact, agent-friendly text.
|
|
3
|
+
* Items are rendered in server-computed score order (no grouping by type).
|
|
4
|
+
* Token budget: ~500 tokens max for auto-recall context.
|
|
5
|
+
*/
|
|
6
|
+
import type { SearchResponse, GraphTraverseResult } from "./mimir-client.js";
|
|
7
|
+
export interface FormatterOptions {
|
|
8
|
+
/** Max characters for the entire formatted block. ~500 tokens ≈ 2000 chars. */
|
|
9
|
+
readonly maxChars: number;
|
|
10
|
+
/** Max individual memory items to show. */
|
|
11
|
+
readonly maxItems: number;
|
|
12
|
+
}
|
|
13
|
+
/** Format search results as a compact memory context block.
|
|
14
|
+
* Items are rendered in score order (as returned by server), not grouped by type.
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatSearchResults(response: SearchResponse, options?: Partial<FormatterOptions>): string;
|
|
17
|
+
/** Format graph traverse results as a relationship summary. */
|
|
18
|
+
export declare function formatGraphResults(result: GraphTraverseResult): string;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Mimir search results into compact, agent-friendly text.
|
|
3
|
+
* Items are rendered in server-computed score order (no grouping by type).
|
|
4
|
+
* Token budget: ~500 tokens max for auto-recall context.
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_OPTIONS = {
|
|
7
|
+
maxChars: 2000,
|
|
8
|
+
maxItems: 8,
|
|
9
|
+
};
|
|
10
|
+
// ─── Main Formatter ──────────────────────────────────────────
|
|
11
|
+
/** Format search results as a compact memory context block.
|
|
12
|
+
* Items are rendered in score order (as returned by server), not grouped by type.
|
|
13
|
+
*/
|
|
14
|
+
export function formatSearchResults(response, options) {
|
|
15
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
16
|
+
const { results } = response;
|
|
17
|
+
if (results.length === 0) {
|
|
18
|
+
return "";
|
|
19
|
+
}
|
|
20
|
+
const lines = [];
|
|
21
|
+
let charCount = 0;
|
|
22
|
+
let itemCount = 0;
|
|
23
|
+
for (const item of results) {
|
|
24
|
+
if (itemCount >= opts.maxItems)
|
|
25
|
+
break;
|
|
26
|
+
const line = formatItem(item);
|
|
27
|
+
if (!line)
|
|
28
|
+
continue;
|
|
29
|
+
// Check char budget before adding (account for newline)
|
|
30
|
+
if (charCount + line.length + 1 > opts.maxChars)
|
|
31
|
+
break;
|
|
32
|
+
lines.push(line);
|
|
33
|
+
charCount += line.length + 1;
|
|
34
|
+
itemCount++;
|
|
35
|
+
}
|
|
36
|
+
// Append foresight_context if present
|
|
37
|
+
if (response.foresight_context) {
|
|
38
|
+
const fLine = `> ${response.foresight_context}`;
|
|
39
|
+
if (charCount + fLine.length + 1 <= opts.maxChars) {
|
|
40
|
+
lines.push(fLine);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return lines.join("\n");
|
|
44
|
+
}
|
|
45
|
+
/** Format graph traverse results as a relationship summary. */
|
|
46
|
+
export function formatGraphResults(result) {
|
|
47
|
+
if (result.entities.length === 0) {
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
const lines = ["## Entity Relationships"];
|
|
51
|
+
// Format entities with their summaries
|
|
52
|
+
for (const entity of result.entities.slice(0, 5)) {
|
|
53
|
+
const aliases = entity.aliases?.length ? ` (aka ${entity.aliases.join(", ")})` : "";
|
|
54
|
+
lines.push(`- **${entity.name}**${aliases}: ${entity.summary || entity.entity_type}`);
|
|
55
|
+
}
|
|
56
|
+
// Format relations as "A → relation → B"
|
|
57
|
+
if (result.relations.length > 0) {
|
|
58
|
+
lines.push("");
|
|
59
|
+
const entityById = new Map();
|
|
60
|
+
for (const e of result.entities) {
|
|
61
|
+
entityById.set(e.id, e);
|
|
62
|
+
}
|
|
63
|
+
for (const rel of result.relations.slice(0, 5)) {
|
|
64
|
+
const source = entityById.get(rel.source_entity_id)?.name ?? "?";
|
|
65
|
+
const target = entityById.get(rel.target_entity_id)?.name ?? "?";
|
|
66
|
+
lines.push(`- ${source} → ${rel.relation_type} → ${target}: ${rel.fact}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return lines.join("\n");
|
|
70
|
+
}
|
|
71
|
+
// ─── Item Dispatcher ─────────────────────────────────────────
|
|
72
|
+
/** Format a single result item with a type-specific prefix. */
|
|
73
|
+
function formatItem(item) {
|
|
74
|
+
const data = item.data;
|
|
75
|
+
switch (item.type) {
|
|
76
|
+
case "episode":
|
|
77
|
+
case "raw_doc": {
|
|
78
|
+
const date = formatDate(data.occurred_at);
|
|
79
|
+
const title = data.title || "";
|
|
80
|
+
const content = data.content || "";
|
|
81
|
+
const summary = title || firstLine(content);
|
|
82
|
+
return `- [${date}] ${truncate(summary, 150)}`;
|
|
83
|
+
}
|
|
84
|
+
case "event_log": {
|
|
85
|
+
const date = formatDate(data.timestamp);
|
|
86
|
+
const fact = data.fact || "";
|
|
87
|
+
return `- [${date}] ${truncate(fact, 150)}`;
|
|
88
|
+
}
|
|
89
|
+
case "entity": {
|
|
90
|
+
const name = data.name || "";
|
|
91
|
+
const entityType = data.entity_type || "";
|
|
92
|
+
const summary = data.summary || "";
|
|
93
|
+
return `- [entity] ${name} (${entityType}): ${truncate(summary, 150)}`;
|
|
94
|
+
}
|
|
95
|
+
case "relation": {
|
|
96
|
+
const fact = data.fact || "";
|
|
97
|
+
const relType = data.relation_type || "";
|
|
98
|
+
return `- [relation] ${relType}: ${truncate(fact, 150)}`;
|
|
99
|
+
}
|
|
100
|
+
case "foresight": {
|
|
101
|
+
const content = data.content || "";
|
|
102
|
+
return `- [upcoming] ${truncate(content, 150)}`;
|
|
103
|
+
}
|
|
104
|
+
default:
|
|
105
|
+
return "";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// ─── Helpers ─────────────────────────────────────────────────
|
|
109
|
+
function formatDate(isoDate) {
|
|
110
|
+
if (!isoDate)
|
|
111
|
+
return "unknown";
|
|
112
|
+
try {
|
|
113
|
+
const d = new Date(isoDate);
|
|
114
|
+
return d.toISOString().slice(0, 10); // "2023-07-15"
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return "unknown";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function truncate(s, maxLen) {
|
|
121
|
+
if (s.length <= maxLen)
|
|
122
|
+
return s;
|
|
123
|
+
return s.slice(0, maxLen - 3) + "...";
|
|
124
|
+
}
|
|
125
|
+
function firstLine(s) {
|
|
126
|
+
const idx = s.indexOf("\n");
|
|
127
|
+
return idx >= 0 ? s.slice(0, idx) : s;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory-mimir: OpenClaw plugin entry point.
|
|
3
|
+
*
|
|
4
|
+
* Replaces OpenClaw's built-in file-backed memory with Mimir
|
|
5
|
+
* as a full long-term memory backend (graph + vector + BM25).
|
|
6
|
+
*/
|
|
7
|
+
interface OpenClawPluginApi {
|
|
8
|
+
pluginConfig: Record<string, unknown>;
|
|
9
|
+
logger: {
|
|
10
|
+
info: (msg: string) => void;
|
|
11
|
+
warn: (msg: string) => void;
|
|
12
|
+
error: (msg: string) => void;
|
|
13
|
+
};
|
|
14
|
+
resolvePath: (path: string) => string;
|
|
15
|
+
on: (event: string, handler: (event: Record<string, unknown>) => Promise<Record<string, unknown> | void>) => void;
|
|
16
|
+
registerTool: (definition: Record<string, unknown>, options: {
|
|
17
|
+
name: string;
|
|
18
|
+
}) => void;
|
|
19
|
+
registerCli: (factory: (ctx: {
|
|
20
|
+
program: CommanderProgram;
|
|
21
|
+
}) => void, options: {
|
|
22
|
+
commands: string[];
|
|
23
|
+
}) => void;
|
|
24
|
+
registerService: (definition: {
|
|
25
|
+
id: string;
|
|
26
|
+
start: () => void;
|
|
27
|
+
stop: () => void;
|
|
28
|
+
}) => void;
|
|
29
|
+
}
|
|
30
|
+
interface CommanderProgram {
|
|
31
|
+
command: (name: string) => CommanderCommand;
|
|
32
|
+
}
|
|
33
|
+
interface CommanderCommand {
|
|
34
|
+
description: (desc: string) => CommanderCommand;
|
|
35
|
+
argument: (name: string, desc: string) => CommanderCommand;
|
|
36
|
+
option: (flags: string, desc: string, defaultVal?: string) => CommanderCommand;
|
|
37
|
+
action: (fn: (...args: unknown[]) => Promise<void>) => CommanderCommand;
|
|
38
|
+
command: (name: string) => CommanderCommand;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Extract plain text from a message content block (string or array).
|
|
42
|
+
* Handles mixed content: text, tool_use, tool_result, image, document.
|
|
43
|
+
* - text blocks: included as-is
|
|
44
|
+
* - tool_use: "[工具: name(args)]" so we know what was invoked
|
|
45
|
+
* - tool_result: recursively extract text (web fetch results, file reads, etc.)
|
|
46
|
+
* - image: "[图片]" placeholder — OpenClaw's reply will describe it
|
|
47
|
+
* - document: "[文档]" placeholder
|
|
48
|
+
*/
|
|
49
|
+
export declare function extractMessageText(content: unknown): string;
|
|
50
|
+
/** Extract searchable topics from user message — pure heuristic, no LLM.
|
|
51
|
+
* For CJK text: pass first 200 chars directly (server has LLMTranslator + RuleAnalyzer).
|
|
52
|
+
* For English: extract up to 8 non-stop-word tokens.
|
|
53
|
+
*/
|
|
54
|
+
export declare function extractKeywords(message: string): string;
|
|
55
|
+
interface TimeRangeResult {
|
|
56
|
+
readonly start: string;
|
|
57
|
+
readonly end: string;
|
|
58
|
+
}
|
|
59
|
+
/** Extract time range from user message using keyword matching.
|
|
60
|
+
* Returns undefined if no temporal reference is found.
|
|
61
|
+
*/
|
|
62
|
+
export declare function extractTimeRange(message: string): TimeRangeResult | undefined;
|
|
63
|
+
declare const memoryMimirPlugin: {
|
|
64
|
+
id: string;
|
|
65
|
+
name: string;
|
|
66
|
+
description: string;
|
|
67
|
+
kind: "memory";
|
|
68
|
+
configSchema: {
|
|
69
|
+
type: string;
|
|
70
|
+
additionalProperties: boolean;
|
|
71
|
+
properties: {
|
|
72
|
+
mimirUrl: {
|
|
73
|
+
type: string;
|
|
74
|
+
description: string;
|
|
75
|
+
};
|
|
76
|
+
userId: {
|
|
77
|
+
type: string;
|
|
78
|
+
description: string;
|
|
79
|
+
};
|
|
80
|
+
groupId: {
|
|
81
|
+
type: string;
|
|
82
|
+
description: string;
|
|
83
|
+
};
|
|
84
|
+
autoRecall: {
|
|
85
|
+
type: string;
|
|
86
|
+
description: string;
|
|
87
|
+
};
|
|
88
|
+
autoCapture: {
|
|
89
|
+
type: string;
|
|
90
|
+
description: string;
|
|
91
|
+
};
|
|
92
|
+
maxRecallItems: {
|
|
93
|
+
type: string;
|
|
94
|
+
description: string;
|
|
95
|
+
};
|
|
96
|
+
maxRecallTokens: {
|
|
97
|
+
type: string;
|
|
98
|
+
description: string;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
register(api: OpenClawPluginApi): void;
|
|
103
|
+
};
|
|
104
|
+
export default memoryMimirPlugin;
|