memorylake-openclaw 0.0.2 → 0.0.4
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/.github/workflows/release.yml +23 -0
- package/README.md +5 -5
- package/docs/openclaw.mdx +98 -0
- package/index.ts +189 -30
- package/package.json +5 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Publish Package to npmjs
|
|
2
|
+
on:
|
|
3
|
+
# Trigger on tag push
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*'
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
id-token: write
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v5
|
|
15
|
+
# Setup .npmrc file to publish to npm
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: '24.x'
|
|
19
|
+
registry-url: 'https://registry.npmjs.org'
|
|
20
|
+
- run: npm i && npm ci
|
|
21
|
+
- run: npm publish
|
|
22
|
+
env:
|
|
23
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Your agent forgets everything between sessions. This plugin fixes that. It watch
|
|
|
10
10
|
<img src="../docs/images/openclaw-architecture.png" alt="Architecture" width="800" />
|
|
11
11
|
</p> -->
|
|
12
12
|
|
|
13
|
-
**Auto-Recall** — Before the agent responds, the plugin searches MemoryLake for memories that match the current message and injects them into context.
|
|
13
|
+
**Auto-Recall** — Before the agent responds, the plugin searches MemoryLake for memories and relevant document excerpts that match the current message and injects them into context.
|
|
14
14
|
|
|
15
15
|
**Auto-Capture** — After the agent responds, the plugin sends the exchange to MemoryLake. MemoryLake decides what's worth keeping — new facts get stored, stale ones updated, duplicates merged.
|
|
16
16
|
|
|
@@ -29,16 +29,15 @@ Get an API key from [app.memorylake.ai](https://app.memorylake.ai), then add to
|
|
|
29
29
|
"memorylake-openclaw": {
|
|
30
30
|
"enabled": true,
|
|
31
31
|
"config": {
|
|
32
|
-
"apiKey": "
|
|
33
|
-
"projectId": "proj-..."
|
|
34
|
-
"userId": "your-user-id"
|
|
32
|
+
"apiKey": "sk-...",
|
|
33
|
+
"projectId": "proj-..."
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
36
|
```
|
|
38
37
|
|
|
39
38
|
## Agent tools
|
|
40
39
|
|
|
41
|
-
The agent gets
|
|
40
|
+
The agent gets six tools it can call during conversations:
|
|
42
41
|
|
|
43
42
|
| Tool | Description |
|
|
44
43
|
|------|-------------|
|
|
@@ -47,6 +46,7 @@ The agent gets five tools it can call during conversations:
|
|
|
47
46
|
| `memory_store` | Explicitly save a fact |
|
|
48
47
|
| `memory_get` | Retrieve a memory by ID |
|
|
49
48
|
| `memory_forget` | Delete a memory by ID |
|
|
49
|
+
| `document_search` | Search project documents for relevant paragraphs, tables, and figures |
|
|
50
50
|
|
|
51
51
|
## CLI
|
|
52
52
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: OpenClaw
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Add long-term memory to [OpenClaw](https://github.com/openclaw/openclaw) agents with the `memorylake-openclaw` plugin. Your agent forgets everything between sessions — this plugin fixes that by automatically watching conversations, extracting what matters, and bringing it back when relevant.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
{/*<Frame>
|
|
10
|
+
<img src="/images/openclaw-architecture.png" alt="OpenClaw MemoryLake Architecture" />
|
|
11
|
+
</Frame>*/}
|
|
12
|
+
|
|
13
|
+
The plugin provides:
|
|
14
|
+
1. **Auto-Recall** — Before the agent responds, memories and relevant document excerpts matching the current message are injected into context
|
|
15
|
+
2. **Auto-Capture** — After the agent responds, the exchange is sent to MemoryLake which decides what's worth keeping
|
|
16
|
+
3. **Agent Tools** — Six tools for memory and document operations during conversations
|
|
17
|
+
|
|
18
|
+
Both auto-recall and auto-capture run silently with no manual configuration required.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
openclaw plugins install memorylake-openclaw
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Setup and Configuration
|
|
27
|
+
|
|
28
|
+
<Note>Get your API key and project ID from [app.memorylake.ai](https://app.memorylake.ai).</Note>
|
|
29
|
+
|
|
30
|
+
Add to your `openclaw.json`:
|
|
31
|
+
|
|
32
|
+
```json5
|
|
33
|
+
// plugins.entries
|
|
34
|
+
"memorylake-openclaw": {
|
|
35
|
+
"enabled": true,
|
|
36
|
+
"config": {
|
|
37
|
+
"apiKey": "sk-...",
|
|
38
|
+
"projectId": "proj-..."
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Agent Tools
|
|
44
|
+
|
|
45
|
+
The agent gets six tools it can call during conversations:
|
|
46
|
+
|
|
47
|
+
| Tool | Description |
|
|
48
|
+
|------|-------------|
|
|
49
|
+
| `memory_search` | Search memories by natural language |
|
|
50
|
+
| `memory_list` | List all stored memories for a user |
|
|
51
|
+
| `memory_store` | Explicitly save a fact |
|
|
52
|
+
| `memory_get` | Retrieve a memory by ID |
|
|
53
|
+
| `memory_forget` | Delete a memory by ID |
|
|
54
|
+
| `document_search` | Search project documents for relevant paragraphs, tables, and figures |
|
|
55
|
+
|
|
56
|
+
## CLI Commands
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Search memories
|
|
60
|
+
openclaw memorylake search "what languages does the user know"
|
|
61
|
+
|
|
62
|
+
# View stats
|
|
63
|
+
openclaw memorylake stats
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Configuration Options
|
|
67
|
+
|
|
68
|
+
| Key | Type | Default | Description |
|
|
69
|
+
|-----|------|---------|-------------|
|
|
70
|
+
| `apiKey` | `string` | — | **Required.** MemoryLake API key (supports `${MEMORYLAKE_API_KEY}`) |
|
|
71
|
+
| `projectId` | `string` | — | **Required.** MemoryLake project ID |
|
|
72
|
+
| `host` | `string` | `https://app.memorylake.ai` | MemoryLake server endpoint URL |
|
|
73
|
+
| `userId` | `string` | `"default"` | Scope memories per user |
|
|
74
|
+
| `autoRecall` | `boolean` | `true` | Inject memories before each turn |
|
|
75
|
+
| `autoCapture` | `boolean` | `true` | Store facts after each turn |
|
|
76
|
+
| `topK` | `number` | `5` | Max memories per recall |
|
|
77
|
+
| `searchThreshold` | `number` | `0.3` | Min similarity (0–1) |
|
|
78
|
+
| `rerank` | `boolean` | `true` | Rerank search results for better relevance |
|
|
79
|
+
|
|
80
|
+
## Key Features
|
|
81
|
+
|
|
82
|
+
1. **Zero Configuration** — Auto-recall and auto-capture work out of the box with no prompting required
|
|
83
|
+
2. **Async Processing** — Memory extraction runs asynchronously via MemoryLake's API
|
|
84
|
+
3. **Session Tracking** — Conversations are tagged with `chat_session_id` for traceability
|
|
85
|
+
4. **Rich Tool Suite** — Six agent tools for memory and document operations when needed
|
|
86
|
+
|
|
87
|
+
## Conclusion
|
|
88
|
+
|
|
89
|
+
The `memorylake-openclaw` plugin gives OpenClaw agents persistent memory with minimal setup. Your agents can remember user preferences, facts, and context across sessions automatically.
|
|
90
|
+
|
|
91
|
+
{/*<CardGroup cols={2}>
|
|
92
|
+
<Card title="MemoryLake" icon="brain" href="https://app.memorylake.ai">
|
|
93
|
+
MemoryLake platform
|
|
94
|
+
</Card>
|
|
95
|
+
<Card title="OpenClaw" icon="robot" href="https://github.com/openclaw/openclaw">
|
|
96
|
+
OpenClaw agent framework
|
|
97
|
+
</Card>
|
|
98
|
+
</CardGroup>*/}
|
package/index.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Long-term memory via MemoryLake platform.
|
|
5
5
|
*
|
|
6
6
|
* Features:
|
|
7
|
-
* -
|
|
8
|
-
* - Auto-recall: injects relevant memories
|
|
7
|
+
* - 6 tools: memory_search, memory_list, memory_store, memory_get, memory_forget, document_search
|
|
8
|
+
* - Auto-recall: injects relevant memories and document excerpts before each agent turn
|
|
9
9
|
* - Auto-capture: stores key facts scoped to the current session after each agent turn
|
|
10
10
|
* - CLI: openclaw memorylake search, openclaw memorylake stats
|
|
11
11
|
*/
|
|
@@ -69,6 +69,35 @@ interface AddResult {
|
|
|
69
69
|
results: AddResultItem[];
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
interface DocumentSearchResult {
|
|
73
|
+
type: "table" | "paragraph" | "figure";
|
|
74
|
+
document_id?: string;
|
|
75
|
+
document_name?: string;
|
|
76
|
+
source_document?: { file_name?: string };
|
|
77
|
+
highlight?: {
|
|
78
|
+
chunks?: Array<{ text?: string; range?: string }>;
|
|
79
|
+
inner_tables?: Array<{
|
|
80
|
+
id?: string;
|
|
81
|
+
columns?: Array<{ name?: string; data_type?: string }>;
|
|
82
|
+
num_rows?: number;
|
|
83
|
+
}>;
|
|
84
|
+
figure?: {
|
|
85
|
+
text?: string;
|
|
86
|
+
caption?: string;
|
|
87
|
+
summary_text?: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
title?: string;
|
|
91
|
+
footnote?: string;
|
|
92
|
+
sheet_name?: string;
|
|
93
|
+
figure_id?: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface DocumentSearchResponse {
|
|
97
|
+
count: number;
|
|
98
|
+
results: DocumentSearchResult[];
|
|
99
|
+
}
|
|
100
|
+
|
|
72
101
|
// ============================================================================
|
|
73
102
|
// Unified Provider Interface
|
|
74
103
|
// ============================================================================
|
|
@@ -82,6 +111,7 @@ interface MemoryLakeProvider {
|
|
|
82
111
|
get(memoryId: string): Promise<MemoryItem>;
|
|
83
112
|
getAll(options: ListOptions): Promise<MemoryItem[]>;
|
|
84
113
|
delete(memoryId: string): Promise<void>;
|
|
114
|
+
searchDocuments(query: string, topN: number): Promise<DocumentSearchResponse>;
|
|
85
115
|
}
|
|
86
116
|
|
|
87
117
|
// ============================================================================
|
|
@@ -98,9 +128,11 @@ interface ApiResponse<T = unknown> {
|
|
|
98
128
|
class PlatformProvider implements MemoryLakeProvider {
|
|
99
129
|
private readonly http: ReturnType<typeof got.extend>;
|
|
100
130
|
private readonly basePath: string;
|
|
131
|
+
private readonly docSearchPath: string;
|
|
101
132
|
|
|
102
133
|
constructor(host: string, apiKey: string, projectId: string) {
|
|
103
134
|
this.basePath = `openapi/memorylake/api/v2/projects/${projectId}/memories`;
|
|
135
|
+
this.docSearchPath = `openapi/memorylake/api/v1/projects/${projectId}/documents/search`;
|
|
104
136
|
this.http = got.extend({
|
|
105
137
|
prefixUrl: host,
|
|
106
138
|
headers: {
|
|
@@ -175,6 +207,18 @@ class PlatformProvider implements MemoryLakeProvider {
|
|
|
175
207
|
.json<ApiResponse>();
|
|
176
208
|
if (!resp.success) throw new Error(resp.message ?? "delete failed");
|
|
177
209
|
}
|
|
210
|
+
|
|
211
|
+
async searchDocuments(query: string, topN: number): Promise<DocumentSearchResponse> {
|
|
212
|
+
const resp = await this.http
|
|
213
|
+
.post(this.docSearchPath, { json: { query, topN } })
|
|
214
|
+
.json<ApiResponse>();
|
|
215
|
+
if (!resp.success) throw new Error(resp.message ?? "document search failed");
|
|
216
|
+
const data = resp.data as any;
|
|
217
|
+
return {
|
|
218
|
+
count: data?.count ?? 0,
|
|
219
|
+
results: Array.isArray(data?.results) ? data.results : [],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
178
222
|
}
|
|
179
223
|
|
|
180
224
|
// ============================================================================
|
|
@@ -210,19 +254,57 @@ function normalizeAddResult(raw: any): AddResult {
|
|
|
210
254
|
}
|
|
211
255
|
|
|
212
256
|
// ============================================================================
|
|
213
|
-
//
|
|
257
|
+
// Document Context Builder
|
|
214
258
|
// ============================================================================
|
|
215
259
|
|
|
216
|
-
function
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
260
|
+
function buildDocumentContext(
|
|
261
|
+
results: DocumentSearchResult[],
|
|
262
|
+
maxChunkLength = 10000,
|
|
263
|
+
): string {
|
|
264
|
+
const parts: string[] = [];
|
|
265
|
+
|
|
266
|
+
for (const result of results) {
|
|
267
|
+
const source = result.document_name ?? result.source_document?.file_name ?? "unknown";
|
|
268
|
+
const highlight = result.highlight;
|
|
269
|
+
|
|
270
|
+
if (result.type === "table") {
|
|
271
|
+
const title = result.title || "Untitled Table";
|
|
272
|
+
parts.push(`### Table: ${title} (from ${source})`);
|
|
273
|
+
if (result.footnote) parts.push(`Note: ${result.footnote}`);
|
|
274
|
+
|
|
275
|
+
for (const innerTable of highlight?.inner_tables ?? []) {
|
|
276
|
+
const colDesc = (innerTable.columns ?? [])
|
|
277
|
+
.map((c) => `${c.name}(${c.data_type})`)
|
|
278
|
+
.join(", ");
|
|
279
|
+
if (colDesc) parts.push(`Columns: ${colDesc}`);
|
|
280
|
+
if (innerTable.num_rows != null) parts.push(`Rows: ${innerTable.num_rows}`);
|
|
281
|
+
}
|
|
282
|
+
for (const chunk of highlight?.chunks ?? []) {
|
|
283
|
+
if (chunk.text) parts.push(chunk.text.slice(0, maxChunkLength));
|
|
284
|
+
}
|
|
285
|
+
} else if (result.type === "paragraph") {
|
|
286
|
+
parts.push(`### Paragraph (from ${source}):`);
|
|
287
|
+
for (const chunk of highlight?.chunks ?? []) {
|
|
288
|
+
if (chunk.text) parts.push(chunk.text.slice(0, maxChunkLength));
|
|
289
|
+
}
|
|
290
|
+
} else if (result.type === "figure") {
|
|
291
|
+
const figure = highlight?.figure;
|
|
292
|
+
if (figure) {
|
|
293
|
+
parts.push(`### Figure (from ${source}):`);
|
|
294
|
+
if (figure.caption) parts.push(`Caption: ${figure.caption}`);
|
|
295
|
+
const text = figure.text || figure.summary_text || "";
|
|
296
|
+
if (text) parts.push(text);
|
|
297
|
+
}
|
|
221
298
|
}
|
|
222
|
-
|
|
223
|
-
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return parts.join("\n\n");
|
|
224
302
|
}
|
|
225
303
|
|
|
304
|
+
// ============================================================================
|
|
305
|
+
// Config Parser
|
|
306
|
+
// ============================================================================
|
|
307
|
+
|
|
226
308
|
// ============================================================================
|
|
227
309
|
// Config Schema
|
|
228
310
|
// ============================================================================
|
|
@@ -267,10 +349,10 @@ const memoryLakeConfigSchema = {
|
|
|
267
349
|
return {
|
|
268
350
|
host:
|
|
269
351
|
typeof cfg.host === "string" && cfg.host
|
|
270
|
-
?
|
|
352
|
+
? cfg.host
|
|
271
353
|
: "https://app.memorylake.ai",
|
|
272
|
-
apiKey:
|
|
273
|
-
projectId:
|
|
354
|
+
apiKey: cfg.apiKey as string,
|
|
355
|
+
projectId: cfg.projectId as string,
|
|
274
356
|
userId:
|
|
275
357
|
typeof cfg.userId === "string" && cfg.userId ? cfg.userId : "default",
|
|
276
358
|
autoCapture: cfg.autoCapture !== false,
|
|
@@ -641,6 +723,66 @@ const memoryPlugin = {
|
|
|
641
723
|
{ name: "memory_forget" },
|
|
642
724
|
);
|
|
643
725
|
|
|
726
|
+
api.registerTool(
|
|
727
|
+
{
|
|
728
|
+
name: "document_search",
|
|
729
|
+
label: "Document Search",
|
|
730
|
+
description:
|
|
731
|
+
"Search through documents stored in MemoryLake project. Returns relevant paragraphs, tables, and figures from uploaded documents.",
|
|
732
|
+
parameters: Type.Object({
|
|
733
|
+
query: Type.String({ description: "Search query" }),
|
|
734
|
+
topN: Type.Optional(
|
|
735
|
+
Type.Number({
|
|
736
|
+
description: `Max results (default: ${cfg.topK})`,
|
|
737
|
+
minimum: 1,
|
|
738
|
+
}),
|
|
739
|
+
),
|
|
740
|
+
}),
|
|
741
|
+
async execute(_toolCallId, params) {
|
|
742
|
+
const { query, topN } = params as { query: string; topN?: number };
|
|
743
|
+
|
|
744
|
+
try {
|
|
745
|
+
const response = await provider.searchDocuments(
|
|
746
|
+
query,
|
|
747
|
+
topN ?? cfg.topK,
|
|
748
|
+
);
|
|
749
|
+
|
|
750
|
+
if (!response.results || response.results.length === 0) {
|
|
751
|
+
return {
|
|
752
|
+
content: [
|
|
753
|
+
{ type: "text", text: "No relevant documents found." },
|
|
754
|
+
],
|
|
755
|
+
details: { count: 0 },
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const context = buildDocumentContext(response.results);
|
|
760
|
+
|
|
761
|
+
return {
|
|
762
|
+
content: [
|
|
763
|
+
{
|
|
764
|
+
type: "text",
|
|
765
|
+
text: `Found ${response.results.length} document results:\n\n${context}`,
|
|
766
|
+
},
|
|
767
|
+
],
|
|
768
|
+
details: { count: response.results.length },
|
|
769
|
+
};
|
|
770
|
+
} catch (err) {
|
|
771
|
+
return {
|
|
772
|
+
content: [
|
|
773
|
+
{
|
|
774
|
+
type: "text",
|
|
775
|
+
text: `Document search failed: ${String(err)}`,
|
|
776
|
+
},
|
|
777
|
+
],
|
|
778
|
+
details: { error: String(err) },
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
{ name: "document_search" },
|
|
784
|
+
);
|
|
785
|
+
|
|
644
786
|
// ========================================================================
|
|
645
787
|
// CLI Commands
|
|
646
788
|
// ========================================================================
|
|
@@ -708,7 +850,7 @@ const memoryPlugin = {
|
|
|
708
850
|
// Lifecycle Hooks
|
|
709
851
|
// ========================================================================
|
|
710
852
|
|
|
711
|
-
// Auto-recall: inject relevant memories before agent starts
|
|
853
|
+
// Auto-recall: inject relevant memories and documents before agent starts
|
|
712
854
|
if (cfg.autoRecall) {
|
|
713
855
|
api.on("before_agent_start", async (event, ctx) => {
|
|
714
856
|
if (!event.prompt || event.prompt.length < 5) return;
|
|
@@ -717,28 +859,42 @@ const memoryPlugin = {
|
|
|
717
859
|
const sessionId = (ctx as any)?.sessionKey ?? undefined;
|
|
718
860
|
if (sessionId) currentSessionId = sessionId;
|
|
719
861
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
);
|
|
862
|
+
const [memoryResult, docResult] = await Promise.allSettled([
|
|
863
|
+
provider.search(event.prompt, buildSearchOptions()),
|
|
864
|
+
provider.searchDocuments(event.prompt, cfg.topK),
|
|
865
|
+
]);
|
|
725
866
|
|
|
726
|
-
|
|
867
|
+
const contextParts: string[] = [];
|
|
727
868
|
|
|
728
|
-
|
|
869
|
+
if (memoryResult.status === "fulfilled" && memoryResult.value.length > 0) {
|
|
870
|
+
const memoryContext = memoryResult.value
|
|
729
871
|
.map((r) => `- ${r.content}`)
|
|
730
872
|
.join("\n");
|
|
731
|
-
|
|
873
|
+
contextParts.push(
|
|
874
|
+
`<relevant-memories>\nThe following memories may be relevant to this conversation:\n${memoryContext}\n</relevant-memories>`,
|
|
875
|
+
);
|
|
732
876
|
api.logger.info(
|
|
733
|
-
`memorylake-openclaw: injecting ${
|
|
877
|
+
`memorylake-openclaw: injecting ${memoryResult.value.length} memories into context`,
|
|
734
878
|
);
|
|
879
|
+
} else if (memoryResult.status === "rejected") {
|
|
880
|
+
api.logger.warn(`memorylake-openclaw: memory recall failed: ${String(memoryResult.reason)}`);
|
|
881
|
+
}
|
|
735
882
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
883
|
+
if (docResult.status === "fulfilled" && docResult.value.results.length > 0) {
|
|
884
|
+
const docContext = buildDocumentContext(docResult.value.results);
|
|
885
|
+
contextParts.push(
|
|
886
|
+
`<relevant-documents>\nThe following document excerpts may be relevant to this conversation:\n${docContext}\n</relevant-documents>`,
|
|
887
|
+
);
|
|
888
|
+
api.logger.info(
|
|
889
|
+
`memorylake-openclaw: injecting ${docResult.value.results.length} document results into context`,
|
|
890
|
+
);
|
|
891
|
+
} else if (docResult.status === "rejected") {
|
|
892
|
+
api.logger.warn(`memorylake-openclaw: document search failed: ${String(docResult.reason)}`);
|
|
741
893
|
}
|
|
894
|
+
|
|
895
|
+
if (contextParts.length === 0) return;
|
|
896
|
+
|
|
897
|
+
return { prependContext: contextParts.join("\n\n") };
|
|
742
898
|
});
|
|
743
899
|
}
|
|
744
900
|
|
|
@@ -789,11 +945,14 @@ const memoryPlugin = {
|
|
|
789
945
|
}
|
|
790
946
|
|
|
791
947
|
if (!textContent) continue;
|
|
792
|
-
// Strip injected
|
|
948
|
+
// Strip injected context, keep the actual user text
|
|
793
949
|
if (textContent.includes("<relevant-memories>")) {
|
|
794
950
|
textContent = textContent.replace(/<relevant-memories>[\s\S]*?<\/relevant-memories>\s*/g, "").trim();
|
|
795
|
-
if (!textContent) continue;
|
|
796
951
|
}
|
|
952
|
+
if (textContent.includes("<relevant-documents>")) {
|
|
953
|
+
textContent = textContent.replace(/<relevant-documents>[\s\S]*?<\/relevant-documents>\s*/g, "").trim();
|
|
954
|
+
}
|
|
955
|
+
if (!textContent) continue;
|
|
797
956
|
|
|
798
957
|
formattedMessages.push({
|
|
799
958
|
role: role as string,
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memorylake-openclaw",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MemoryLake memory backend for OpenClaw",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/memorylake-ai/memorylake-openclaw.git"
|
|
10
|
+
},
|
|
7
11
|
"keywords": [
|
|
8
12
|
"openclaw",
|
|
9
13
|
"plugin",
|