@t0ken.ai/memoryx-openclaw-plugin 1.1.15 → 1.1.17
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 +35 -2
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +321 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,11 +4,44 @@ Official MemoryX plugin for OpenClaw. Enables long-term memory for agents by rec
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Recall**: `before_agent_start` → semantic search for relevant memories
|
|
8
|
-
- **
|
|
7
|
+
- **Auto Recall**: `before_agent_start` → semantic search for relevant memories
|
|
8
|
+
- **Auto Capture**: `message_received` + `assistant_response` → buffer and flush to MemoryX API
|
|
9
|
+
- **Function Calling**: LLM can actively search, list, and delete memories
|
|
9
10
|
- **Auto Registration**: Agents auto-register with machine fingerprint
|
|
10
11
|
- **Conversation Buffer**: Smart buffering with token counting and round-based flushing
|
|
11
12
|
|
|
13
|
+
## Function Calling Tools
|
|
14
|
+
|
|
15
|
+
The plugin registers three tools that LLM can call during conversations:
|
|
16
|
+
|
|
17
|
+
| Tool | Description | When to Use |
|
|
18
|
+
|------|-------------|-------------|
|
|
19
|
+
| `memoryx_recall` | Search through long-term memories | User asks "do you remember X?" or needs context |
|
|
20
|
+
| `memoryx_store` | Save important information to memory | User says "remember this" or you identify important info |
|
|
21
|
+
| `memoryx_list` | List all stored memories | User asks "what do you remember about me?" |
|
|
22
|
+
| `memoryx_forget` | Delete a specific memory | User asks to forget/remove something |
|
|
23
|
+
|
|
24
|
+
### memoryx_store Parameters
|
|
25
|
+
|
|
26
|
+
| Parameter | Type | Required | Description |
|
|
27
|
+
|-----------|------|----------|-------------|
|
|
28
|
+
| `content` | string | Yes | The information to remember (e.g., "User prefers dark mode") |
|
|
29
|
+
| `category` | enum | No | `preference`, `fact`, `plan`, `experience`, `opinion`, `other` |
|
|
30
|
+
|
|
31
|
+
### Example Usage
|
|
32
|
+
|
|
33
|
+
**User**: "What do you remember about my preferences?"
|
|
34
|
+
**LLM**: *calls `memoryx_list`* → Returns list of stored memories
|
|
35
|
+
|
|
36
|
+
**User**: "Did I ever mention my favorite color?"
|
|
37
|
+
**LLM**: *calls `memoryx_recall` with query="favorite color"* → Searches and returns relevant memories
|
|
38
|
+
|
|
39
|
+
**User**: "Please forget about my old address"
|
|
40
|
+
**LLM**: *calls `memoryx_forget` with memory_id* → Deletes the memory
|
|
41
|
+
|
|
42
|
+
**User**: "Remember that my favorite color is blue"
|
|
43
|
+
**LLM**: *calls `memoryx_store` with content="User's favorite color is blue" category="preference"* → Stores the memory
|
|
44
|
+
|
|
12
45
|
## Install
|
|
13
46
|
|
|
14
47
|
```bash
|
package/dist/index.d.ts
CHANGED
|
@@ -81,6 +81,14 @@ declare class MemoryXPlugin {
|
|
|
81
81
|
onMessage(role: string, content: string): Promise<boolean>;
|
|
82
82
|
recall(query: string, limit?: number): Promise<RecallResult>;
|
|
83
83
|
endConversation(): Promise<void>;
|
|
84
|
+
forget(memoryId: string): Promise<boolean>;
|
|
85
|
+
store(content: string, category?: string): Promise<{
|
|
86
|
+
success: boolean;
|
|
87
|
+
task_id?: string;
|
|
88
|
+
duplicate?: boolean;
|
|
89
|
+
existing?: string;
|
|
90
|
+
}>;
|
|
91
|
+
list(limit?: number): Promise<any[]>;
|
|
84
92
|
getStatus(): Promise<{
|
|
85
93
|
initialized: boolean;
|
|
86
94
|
hasApiKey: boolean;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAqDH,UAAU,YAAY;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAiBD,UAAU,YAAY;IAClB,QAAQ,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,eAAe,EAAE,KAAK,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AA0JD,cAAM,mBAAmB;IACrB,OAAO,CAAC,qBAAqB,CAAc;IAC3C,OAAO,CAAC,qBAAqB,CAAyC;IACtE,OAAO,CAAC,cAAc,CAAsB;IAE5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAK;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;;IAM7C,OAAO,CAAC,UAAU;IAIlB,iBAAiB,IAAI,MAAM;IAIrB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB3D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBrC,oBAAoB,IAAI,IAAI;IAMtB,SAAS,IAAI,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAQ/F;AAED,cAAM,aAAa;IACf,OAAO,CAAC,MAAM,CAMZ;IAEF,OAAO,CAAC,mBAAmB,CAAkD;IAC7E,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAK;IACrC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAkB;gBAEzB,YAAY,CAAC,EAAE,YAAY;IAQvC,IAAI,IAAI,IAAI;IAmBZ,OAAO,KAAK,OAAO,GAElB;YAEa,UAAU;YAWV,UAAU;YAIV,YAAY;IA+B1B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,mBAAmB;YAMb,gBAAgB;IAiEjB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2B1D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IA6D/D,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAKhC,SAAS,IAAI,OAAO,CAAC;QAC9B,WAAW,EAAE,OAAO,CAAC;QACrB,SAAS,EAAE,OAAO,CAAC;QACnB,kBAAkB,EAAE;YAAE,YAAY,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KACvF,CAAC;CAQL;;;;;;kBAUiB,GAAG,iBAAiB,YAAY,GAAG,IAAI;;AANzD,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -491,6 +491,99 @@ class MemoryXPlugin {
|
|
|
491
491
|
this.conversationManager.startNewConversation();
|
|
492
492
|
log("Conversation ended, starting new conversation");
|
|
493
493
|
}
|
|
494
|
+
async forget(memoryId) {
|
|
495
|
+
this.init();
|
|
496
|
+
if (!this.config.apiKey) {
|
|
497
|
+
log("Forget failed: no API key");
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
try {
|
|
501
|
+
const response = await fetch(`${this.apiBase}/v1/memories/${memoryId}`, {
|
|
502
|
+
method: "DELETE",
|
|
503
|
+
headers: {
|
|
504
|
+
"X-API-Key": this.config.apiKey
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
if (response.ok) {
|
|
508
|
+
log(`Forgot memory ${memoryId}`);
|
|
509
|
+
return true;
|
|
510
|
+
}
|
|
511
|
+
log(`Forget failed: ${response.status}`);
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
catch (e) {
|
|
515
|
+
log(`Forget failed: ${e}`);
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
async store(content, category = "other") {
|
|
520
|
+
this.init();
|
|
521
|
+
if (!this.config.apiKey) {
|
|
522
|
+
log("Store failed: no API key");
|
|
523
|
+
return { success: false };
|
|
524
|
+
}
|
|
525
|
+
try {
|
|
526
|
+
const response = await fetch(`${this.apiBase}/v1/memories`, {
|
|
527
|
+
method: "POST",
|
|
528
|
+
headers: {
|
|
529
|
+
"Content-Type": "application/json",
|
|
530
|
+
"X-API-Key": this.config.apiKey
|
|
531
|
+
},
|
|
532
|
+
body: JSON.stringify({
|
|
533
|
+
content,
|
|
534
|
+
project_id: this.config.projectId,
|
|
535
|
+
metadata: { category, source: "function_call" }
|
|
536
|
+
})
|
|
537
|
+
});
|
|
538
|
+
if (!response.ok) {
|
|
539
|
+
const errorData = await response.json().catch(() => ({}));
|
|
540
|
+
log(`Store failed: ${response.status} ${JSON.stringify(errorData)}`);
|
|
541
|
+
return { success: false };
|
|
542
|
+
}
|
|
543
|
+
const data = await response.json();
|
|
544
|
+
log(`Stored memory, task_id: ${data.task_id}`);
|
|
545
|
+
return { success: true, task_id: data.task_id };
|
|
546
|
+
}
|
|
547
|
+
catch (e) {
|
|
548
|
+
log(`Store failed: ${e}`);
|
|
549
|
+
return { success: false };
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async list(limit = 10) {
|
|
553
|
+
this.init();
|
|
554
|
+
if (!this.config.apiKey) {
|
|
555
|
+
log("List failed: no API key");
|
|
556
|
+
return [];
|
|
557
|
+
}
|
|
558
|
+
try {
|
|
559
|
+
const response = await fetch(`${this.apiBase}/v1/memories/search`, {
|
|
560
|
+
method: "POST",
|
|
561
|
+
headers: {
|
|
562
|
+
"Content-Type": "application/json",
|
|
563
|
+
"X-API-Key": this.config.apiKey
|
|
564
|
+
},
|
|
565
|
+
body: JSON.stringify({
|
|
566
|
+
query: "*",
|
|
567
|
+
project_id: this.config.projectId,
|
|
568
|
+
limit
|
|
569
|
+
})
|
|
570
|
+
});
|
|
571
|
+
if (!response.ok) {
|
|
572
|
+
log(`List failed: ${response.status}`);
|
|
573
|
+
return [];
|
|
574
|
+
}
|
|
575
|
+
const data = await response.json();
|
|
576
|
+
return (data.data || []).map((m) => ({
|
|
577
|
+
id: m.id,
|
|
578
|
+
content: m.memory || m.content,
|
|
579
|
+
category: m.category || "other"
|
|
580
|
+
}));
|
|
581
|
+
}
|
|
582
|
+
catch (e) {
|
|
583
|
+
log(`List failed: ${e}`);
|
|
584
|
+
return [];
|
|
585
|
+
}
|
|
586
|
+
}
|
|
494
587
|
async getStatus() {
|
|
495
588
|
const status = await this.conversationManager.getStatus();
|
|
496
589
|
return {
|
|
@@ -504,7 +597,7 @@ let plugin;
|
|
|
504
597
|
export default {
|
|
505
598
|
id: "memoryx-openclaw-plugin",
|
|
506
599
|
name: "MemoryX Realtime Plugin",
|
|
507
|
-
version: "1.
|
|
600
|
+
version: "1.1.17",
|
|
508
601
|
description: "Real-time memory capture and recall for OpenClaw",
|
|
509
602
|
register(api, pluginConfig) {
|
|
510
603
|
api.logger.info("[MemoryX] Plugin registering...");
|
|
@@ -512,6 +605,233 @@ export default {
|
|
|
512
605
|
api.logger.info(`[MemoryX] API Base: \`${pluginConfig.apiBaseUrl}\``);
|
|
513
606
|
}
|
|
514
607
|
plugin = new MemoryXPlugin(pluginConfig);
|
|
608
|
+
api.registerTool({
|
|
609
|
+
name: "memoryx_recall",
|
|
610
|
+
label: "MemoryX Recall",
|
|
611
|
+
description: "Search through long-term memories. Use when you need context about user preferences, past decisions, or previously discussed topics.",
|
|
612
|
+
parameters: {
|
|
613
|
+
type: "object",
|
|
614
|
+
properties: {
|
|
615
|
+
query: {
|
|
616
|
+
type: "string",
|
|
617
|
+
description: "Search query to find relevant memories"
|
|
618
|
+
},
|
|
619
|
+
limit: {
|
|
620
|
+
type: "number",
|
|
621
|
+
description: "Maximum number of results to return (default: 5)"
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
required: ["query"]
|
|
625
|
+
},
|
|
626
|
+
async execute(_toolCallId, params) {
|
|
627
|
+
const { query, limit = 5 } = params;
|
|
628
|
+
if (!plugin) {
|
|
629
|
+
return {
|
|
630
|
+
content: [{ type: "text", text: "MemoryX plugin not initialized." }],
|
|
631
|
+
details: { error: "not_initialized" }
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
try {
|
|
635
|
+
const result = await plugin.recall(query, limit);
|
|
636
|
+
if (result.isLimited) {
|
|
637
|
+
return {
|
|
638
|
+
content: [{ type: "text", text: result.upgradeHint || "Quota exceeded" }],
|
|
639
|
+
details: { error: "quota_exceeded", hint: result.upgradeHint }
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
if (result.memories.length === 0 && result.relatedMemories.length === 0) {
|
|
643
|
+
return {
|
|
644
|
+
content: [{ type: "text", text: "No relevant memories found." }],
|
|
645
|
+
details: { count: 0 }
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
const lines = [];
|
|
649
|
+
const total = result.memories.length + result.relatedMemories.length;
|
|
650
|
+
if (result.memories.length > 0) {
|
|
651
|
+
lines.push(`Found ${result.memories.length} direct memories:`);
|
|
652
|
+
result.memories.forEach((m, i) => {
|
|
653
|
+
lines.push(`${i + 1}. [${m.category}] ${m.content} (${Math.round(m.score * 100)}%)`);
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
if (result.relatedMemories.length > 0) {
|
|
657
|
+
if (lines.length > 0)
|
|
658
|
+
lines.push("");
|
|
659
|
+
lines.push(`Found ${result.relatedMemories.length} related memories:`);
|
|
660
|
+
result.relatedMemories.forEach((m, i) => {
|
|
661
|
+
lines.push(`${i + 1}. [${m.category}] ${m.content}`);
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
return {
|
|
665
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
666
|
+
details: {
|
|
667
|
+
count: total,
|
|
668
|
+
direct_count: result.memories.length,
|
|
669
|
+
related_count: result.relatedMemories.length,
|
|
670
|
+
remaining_quota: result.remainingQuota
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
catch (error) {
|
|
675
|
+
return {
|
|
676
|
+
content: [{ type: "text", text: `Memory search failed: ${error.message}` }],
|
|
677
|
+
details: { error: error.message }
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}, { name: "memoryx_recall" });
|
|
682
|
+
api.registerTool({
|
|
683
|
+
name: "memoryx_forget",
|
|
684
|
+
label: "MemoryX Forget",
|
|
685
|
+
description: "Delete specific memories. Use when user explicitly asks to forget or remove something from memory.",
|
|
686
|
+
parameters: {
|
|
687
|
+
type: "object",
|
|
688
|
+
properties: {
|
|
689
|
+
memory_id: {
|
|
690
|
+
type: "string",
|
|
691
|
+
description: "The ID of the memory to delete"
|
|
692
|
+
}
|
|
693
|
+
},
|
|
694
|
+
required: ["memory_id"]
|
|
695
|
+
},
|
|
696
|
+
async execute(_toolCallId, params) {
|
|
697
|
+
const { memory_id } = params;
|
|
698
|
+
if (!plugin) {
|
|
699
|
+
return {
|
|
700
|
+
content: [{ type: "text", text: "MemoryX plugin not initialized." }],
|
|
701
|
+
details: { error: "not_initialized" }
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
try {
|
|
705
|
+
const success = await plugin.forget(memory_id);
|
|
706
|
+
if (success) {
|
|
707
|
+
return {
|
|
708
|
+
content: [{ type: "text", text: `Memory ${memory_id} has been forgotten.` }],
|
|
709
|
+
details: { action: "deleted", id: memory_id }
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
return {
|
|
714
|
+
content: [{ type: "text", text: `Memory ${memory_id} not found or could not be deleted.` }],
|
|
715
|
+
details: { action: "failed", id: memory_id }
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
catch (error) {
|
|
720
|
+
return {
|
|
721
|
+
content: [{ type: "text", text: `Failed to forget memory: ${error.message}` }],
|
|
722
|
+
details: { error: error.message }
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}, { name: "memoryx_forget" });
|
|
727
|
+
api.registerTool({
|
|
728
|
+
name: "memoryx_store",
|
|
729
|
+
label: "MemoryX Store",
|
|
730
|
+
description: "Save important information to long-term memory. Use when user explicitly asks to remember something, or when you identify important user preferences, facts, or decisions that should be persisted.",
|
|
731
|
+
parameters: {
|
|
732
|
+
type: "object",
|
|
733
|
+
properties: {
|
|
734
|
+
content: {
|
|
735
|
+
type: "string",
|
|
736
|
+
description: "The information to remember. Should be a clear, concise statement. Examples: 'User prefers dark mode in all applications', 'User birthday is January 15th', 'User works as a software engineer at Acme Corp'"
|
|
737
|
+
},
|
|
738
|
+
category: {
|
|
739
|
+
type: "string",
|
|
740
|
+
enum: ["preference", "fact", "plan", "experience", "opinion", "other"],
|
|
741
|
+
description: "Category of the memory: preference (user likes/dislikes), fact (objective info), plan (future goals), experience (past events), opinion (user's views), other"
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
required: ["content"]
|
|
745
|
+
},
|
|
746
|
+
async execute(_toolCallId, params) {
|
|
747
|
+
const { content, category = "other" } = params;
|
|
748
|
+
if (!plugin) {
|
|
749
|
+
return {
|
|
750
|
+
content: [{ type: "text", text: "MemoryX plugin not initialized." }],
|
|
751
|
+
details: { error: "not_initialized" }
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
if (!content || content.trim().length < 5) {
|
|
755
|
+
return {
|
|
756
|
+
content: [{ type: "text", text: "Content too short. Please provide more meaningful information to remember." }],
|
|
757
|
+
details: { error: "content_too_short" }
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
try {
|
|
761
|
+
const result = await plugin.store(content.trim(), category);
|
|
762
|
+
if (result.success) {
|
|
763
|
+
return {
|
|
764
|
+
content: [{ type: "text", text: `Stored: "${content.slice(0, 100)}${content.length > 100 ? '...' : ''}"` }],
|
|
765
|
+
details: { action: "stored", task_id: result.task_id }
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
else if (result.duplicate) {
|
|
769
|
+
return {
|
|
770
|
+
content: [{ type: "text", text: `Similar memory already exists: "${result.existing}"` }],
|
|
771
|
+
details: { action: "duplicate" }
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
return {
|
|
776
|
+
content: [{ type: "text", text: "Failed to store memory. Please try again." }],
|
|
777
|
+
details: { error: "store_failed" }
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
catch (error) {
|
|
782
|
+
return {
|
|
783
|
+
content: [{ type: "text", text: `Failed to store memory: ${error.message}` }],
|
|
784
|
+
details: { error: error.message }
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}, { name: "memoryx_store" });
|
|
789
|
+
api.registerTool({
|
|
790
|
+
name: "memoryx_list",
|
|
791
|
+
label: "MemoryX List",
|
|
792
|
+
description: "List all stored memories. Use when user asks what you remember about them.",
|
|
793
|
+
parameters: {
|
|
794
|
+
type: "object",
|
|
795
|
+
properties: {
|
|
796
|
+
limit: {
|
|
797
|
+
type: "number",
|
|
798
|
+
description: "Maximum number of memories to list (default: 10)"
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
async execute(_toolCallId, params) {
|
|
803
|
+
const { limit = 10 } = params;
|
|
804
|
+
if (!plugin) {
|
|
805
|
+
return {
|
|
806
|
+
content: [{ type: "text", text: "MemoryX plugin not initialized." }],
|
|
807
|
+
details: { error: "not_initialized" }
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
try {
|
|
811
|
+
const memories = await plugin.list(limit);
|
|
812
|
+
if (memories.length === 0) {
|
|
813
|
+
return {
|
|
814
|
+
content: [{ type: "text", text: "No memories stored yet." }],
|
|
815
|
+
details: { count: 0 }
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
const lines = [`Here are the ${memories.length} most recent memories:`];
|
|
819
|
+
memories.forEach((m, i) => {
|
|
820
|
+
lines.push(`${i + 1}. [${m.category || 'general'}] ${m.content || m.memory}`);
|
|
821
|
+
});
|
|
822
|
+
return {
|
|
823
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
824
|
+
details: { count: memories.length }
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
catch (error) {
|
|
828
|
+
return {
|
|
829
|
+
content: [{ type: "text", text: `Failed to list memories: ${error.message}` }],
|
|
830
|
+
details: { error: error.message }
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}, { name: "memoryx_list" });
|
|
515
835
|
api.on("message_received", async (event, ctx) => {
|
|
516
836
|
const { content } = event;
|
|
517
837
|
if (content && plugin) {
|
package/openclaw.plugin.json
CHANGED