@t0ken.ai/memoryx-openclaw-plugin 2.2.11 → 2.2.13
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/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +113 -18
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -63,6 +63,21 @@ declare class MemoryXPlugin {
|
|
|
63
63
|
initialized: boolean;
|
|
64
64
|
quota?: any;
|
|
65
65
|
}>;
|
|
66
|
+
getQueueStatus(): Promise<{
|
|
67
|
+
success: boolean;
|
|
68
|
+
data?: {
|
|
69
|
+
agent_id: string;
|
|
70
|
+
tier: string;
|
|
71
|
+
queue_name: string;
|
|
72
|
+
queue_length: number;
|
|
73
|
+
memory_free_queue: number;
|
|
74
|
+
memory_pro_queue: number;
|
|
75
|
+
estimated_wait_time: string;
|
|
76
|
+
status: string;
|
|
77
|
+
message: string;
|
|
78
|
+
};
|
|
79
|
+
error?: string;
|
|
80
|
+
}>;
|
|
66
81
|
}
|
|
67
82
|
declare const _default: {
|
|
68
83
|
id: string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA4CH,UAAU,YAAY;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,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;AA4CD,cAAM,aAAa;IACf,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,WAAW,CAAkB;gBAEzB,YAAY,CAAC,EAAE,YAAY;IAIjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAad,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA6B1D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA4CH,UAAU,YAAY;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,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;AA4CD,cAAM,aAAa;IACf,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,WAAW,CAAkB;gBAEzB,YAAY,CAAC,EAAE,YAAY;IAIjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAad,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA6B1D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IAyC/D,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAYhC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc1C,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAcvE,IAAI,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAiBxC,cAAc,IAAI,OAAO,CAAC;QACnC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,WAAW,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;IAwBW,cAAc,IAAI,OAAO,CAAC;QACnC,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE;YACH,QAAQ,EAAE,MAAM,CAAC;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,MAAM,CAAC;YACnB,YAAY,EAAE,MAAM,CAAC;YACrB,iBAAiB,EAAE,MAAM,CAAC;YAC1B,gBAAgB,EAAE,MAAM,CAAC;YACzB,mBAAmB,EAAE,MAAM,CAAC;YAC5B,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;SACnB,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CAcL;;;;;;kBAUiB,GAAG,iBAAiB,YAAY,GAAG,IAAI;;AANzD,wBAoeE;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -143,6 +143,15 @@ class MemoryXPlugin {
|
|
|
143
143
|
try {
|
|
144
144
|
const sdk = await getSDK(this.pluginConfig);
|
|
145
145
|
const result = await sdk.search(query, limit);
|
|
146
|
+
// Check if quota is limited (search_count >= search_limit for free tier)
|
|
147
|
+
const isLimited = result.is_limited ??
|
|
148
|
+
(result.search_count !== undefined &&
|
|
149
|
+
result.search_limit !== undefined &&
|
|
150
|
+
result.search_count >= result.search_limit);
|
|
151
|
+
// Build upgrade hint if limited
|
|
152
|
+
const upgradeHint = isLimited
|
|
153
|
+
? `Search quota exceeded (${result.search_count}/${result.search_limit}). Upgrade to Pro for unlimited searches.`
|
|
154
|
+
: undefined;
|
|
146
155
|
return {
|
|
147
156
|
memories: (result.data || []).map((m) => ({
|
|
148
157
|
id: m.id,
|
|
@@ -156,8 +165,9 @@ class MemoryXPlugin {
|
|
|
156
165
|
category: m.category || "other",
|
|
157
166
|
score: m.score || 0
|
|
158
167
|
})),
|
|
159
|
-
isLimited
|
|
160
|
-
remainingQuota: result.remaining_quota ?? -1
|
|
168
|
+
isLimited,
|
|
169
|
+
remainingQuota: result.remaining_quota ?? -1,
|
|
170
|
+
upgradeHint
|
|
161
171
|
};
|
|
162
172
|
}
|
|
163
173
|
catch (e) {
|
|
@@ -242,6 +252,20 @@ class MemoryXPlugin {
|
|
|
242
252
|
};
|
|
243
253
|
}
|
|
244
254
|
}
|
|
255
|
+
async getQueueStatus() {
|
|
256
|
+
await this.init();
|
|
257
|
+
try {
|
|
258
|
+
const sdk = await getSDK(this.pluginConfig);
|
|
259
|
+
return await sdk.getQueueStatus();
|
|
260
|
+
}
|
|
261
|
+
catch (e) {
|
|
262
|
+
log(`GetQueueStatus failed: ${e}`);
|
|
263
|
+
return {
|
|
264
|
+
success: false,
|
|
265
|
+
error: String(e)
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
245
269
|
}
|
|
246
270
|
let plugin;
|
|
247
271
|
export default {
|
|
@@ -532,18 +556,86 @@ export default {
|
|
|
532
556
|
}
|
|
533
557
|
}
|
|
534
558
|
}, { name: "memoryx_account_info" });
|
|
559
|
+
api.registerTool({
|
|
560
|
+
name: "memoryx_queue_status",
|
|
561
|
+
label: "MemoryX Queue Status",
|
|
562
|
+
description: "获取 Celery 队列状态,显示当前积压任务数量和预计等待时间。用于诊断记忆处理延迟问题。当用户问为什么记忆还没处理、记忆处理状态、队列状态时使用。",
|
|
563
|
+
parameters: {
|
|
564
|
+
type: "object",
|
|
565
|
+
properties: {}
|
|
566
|
+
},
|
|
567
|
+
async execute(_toolCallId, params) {
|
|
568
|
+
if (!plugin) {
|
|
569
|
+
return {
|
|
570
|
+
content: [{ type: "text", text: "MemoryX plugin not initialized." }],
|
|
571
|
+
details: { error: "not_initialized" }
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
try {
|
|
575
|
+
const result = await plugin.getQueueStatus();
|
|
576
|
+
if (!result.success) {
|
|
577
|
+
return {
|
|
578
|
+
content: [{ type: "text", text: `获取队列状态失败: ${result.error || '未知错误'}` }],
|
|
579
|
+
details: { error: result.error }
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
const data = result.data;
|
|
583
|
+
const statusEmoji = {
|
|
584
|
+
"normal": "✅",
|
|
585
|
+
"backlogged": "⚠️",
|
|
586
|
+
"severely_backlogged": "🔴"
|
|
587
|
+
}[data.status] || "❓";
|
|
588
|
+
const lines = [
|
|
589
|
+
`${statusEmoji} MemoryX 队列状态:`,
|
|
590
|
+
`队列名称: ${data.queue_name}`,
|
|
591
|
+
`当前层级: ${data.tier}`,
|
|
592
|
+
`积压任务: ${data.queue_length} 个`,
|
|
593
|
+
`Free 队列: ${data.memory_free_queue} 个`,
|
|
594
|
+
`Pro 队列: ${data.memory_pro_queue} 个`,
|
|
595
|
+
`预计等待: ${data.estimated_wait_time}`,
|
|
596
|
+
`状态: ${data.message}`
|
|
597
|
+
];
|
|
598
|
+
return {
|
|
599
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
600
|
+
details: {
|
|
601
|
+
queue_name: data.queue_name,
|
|
602
|
+
queue_length: data.queue_length,
|
|
603
|
+
status: data.status,
|
|
604
|
+
estimated_wait_time: data.estimated_wait_time
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
catch (error) {
|
|
609
|
+
return {
|
|
610
|
+
content: [{ type: "text", text: `获取队列状态失败: ${error.message}` }],
|
|
611
|
+
details: { error: error.message }
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}, { name: "memoryx_queue_status" });
|
|
616
|
+
// User message capture via message_received hook
|
|
617
|
+
// Event structure: { from: string, content: string, timestamp?: number }
|
|
535
618
|
api.on("message_received", async (event, ctx) => {
|
|
536
619
|
const { content } = event;
|
|
537
620
|
if (content && plugin) {
|
|
538
621
|
await plugin.onMessage("user", content);
|
|
539
622
|
}
|
|
540
623
|
});
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
624
|
+
// Assistant response capture via llm_output hook
|
|
625
|
+
// Event structure: { assistantTexts: string[], lastAssistant?: unknown, usage?: {...} }
|
|
626
|
+
api.on("llm_output", async (event, ctx) => {
|
|
627
|
+
const { assistantTexts } = event;
|
|
628
|
+
if (assistantTexts && Array.isArray(assistantTexts) && plugin) {
|
|
629
|
+
// Join all assistant text segments
|
|
630
|
+
const fullContent = assistantTexts.join("\n");
|
|
631
|
+
if (fullContent && fullContent.length >= 2) {
|
|
632
|
+
await plugin.onMessage("assistant", fullContent);
|
|
633
|
+
}
|
|
545
634
|
}
|
|
546
635
|
});
|
|
636
|
+
// Auto-inject memories via prependContext
|
|
637
|
+
// Note: OpenClaw's systemPrompt field is extracted but NEVER USED (bug in attempt.ts:918-928)
|
|
638
|
+
// We use prependContext which works, but the context will be visible in the user's prompt
|
|
547
639
|
api.on("before_agent_start", async (event, ctx) => {
|
|
548
640
|
const { prompt } = event;
|
|
549
641
|
if (!prompt || prompt.length < 2 || !plugin)
|
|
@@ -551,34 +643,37 @@ export default {
|
|
|
551
643
|
try {
|
|
552
644
|
const result = await plugin.recall(prompt, 5);
|
|
553
645
|
if (result.isLimited) {
|
|
646
|
+
// Don't inject upgrade hints into prompt - just log
|
|
554
647
|
api.logger.warn(`[MemoryX] ${result.upgradeHint}`);
|
|
555
|
-
return
|
|
556
|
-
systemPrompt: `[MemoryX] ${result.upgradeHint}`
|
|
557
|
-
};
|
|
648
|
+
return;
|
|
558
649
|
}
|
|
559
650
|
if (result.memories.length === 0 && result.relatedMemories.length === 0)
|
|
560
651
|
return;
|
|
561
|
-
//
|
|
562
|
-
//
|
|
563
|
-
|
|
652
|
+
// Build a concise memory context
|
|
653
|
+
// Format: [Memory Context]\n- memory 1\n- memory 2
|
|
654
|
+
const lines = ["[Memory Context]"];
|
|
564
655
|
if (result.memories.length > 0) {
|
|
565
|
-
|
|
656
|
+
lines.push(...result.memories.map(m => `- ${m.content}`));
|
|
566
657
|
}
|
|
567
658
|
if (result.relatedMemories.length > 0) {
|
|
568
659
|
if (result.memories.length > 0)
|
|
569
|
-
|
|
570
|
-
|
|
660
|
+
lines.push("");
|
|
661
|
+
lines.push("[Related]");
|
|
662
|
+
lines.push(...result.relatedMemories.map(m => `- ${m.content}`));
|
|
571
663
|
}
|
|
572
|
-
|
|
664
|
+
const context = lines.join("\n");
|
|
665
|
+
api.logger.info(`[MemoryX] Injected ${result.memories.length} direct + ${result.relatedMemories.length} related memories`);
|
|
573
666
|
return {
|
|
574
|
-
|
|
667
|
+
prependContext: context
|
|
575
668
|
};
|
|
576
669
|
}
|
|
577
670
|
catch (error) {
|
|
578
671
|
api.logger.warn(`[MemoryX] Recall failed: ${error}`);
|
|
579
672
|
}
|
|
580
673
|
});
|
|
581
|
-
|
|
674
|
+
// Session end hook - flush memories when session ends
|
|
675
|
+
// Event structure: { sessionId: string, messageCount: number, durationMs?: number }
|
|
676
|
+
api.on("session_end", async (event, ctx) => {
|
|
582
677
|
if (plugin) {
|
|
583
678
|
await plugin.endConversation();
|
|
584
679
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t0ken.ai/memoryx-openclaw-plugin",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.13",
|
|
4
4
|
"description": "MemoryX real-time memory capture and recall plugin for OpenClaw (powered by @t0ken.ai/memoryx-sdk)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "MemoryX Team",
|
|
@@ -35,6 +35,6 @@
|
|
|
35
35
|
"typescript": "^5.0.0"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@t0ken.ai/memoryx-sdk": "^1.4.
|
|
38
|
+
"@t0ken.ai/memoryx-sdk": "^1.4.3"
|
|
39
39
|
}
|
|
40
40
|
}
|