@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 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;
@@ -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;IA6B/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;CAuBL;;;;;;kBAUiB,GAAG,iBAAiB,YAAY,GAAG,IAAI;;AANzD,wBAoZE;AAEF,OAAO,EAAE,aAAa,EAAE,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: false,
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
- api.on("assistant_response", async (event, ctx) => {
542
- const { content } = event;
543
- if (content && plugin) {
544
- await plugin.onMessage("assistant", content);
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
- // 使用 systemPrompt 而不是 prependContext
562
- // systemPrompt 不会显示在用户聊天内容中
563
- let context = "[MemoryX] Relevant memories from past conversations:\n";
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
- context += result.memories.map(m => `- ${m.content}`).join("\n");
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
- context += "\n";
570
- context += result.relatedMemories.map(m => `- ${m.content}`).join("\n");
660
+ lines.push("");
661
+ lines.push("[Related]");
662
+ lines.push(...result.relatedMemories.map(m => `- ${m.content}`));
571
663
  }
572
- api.logger.info(`[MemoryX] Injected ${result.memories.length} direct + ${result.relatedMemories.length} related memories into system prompt`);
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
- systemPrompt: context
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
- api.on("conversation_end", async (event, ctx) => {
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.11",
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.1"
38
+ "@t0ken.ai/memoryx-sdk": "^1.4.3"
39
39
  }
40
40
  }