@t0ken.ai/memoryx-openclaw-plugin 2.2.12 → 2.2.15

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.
@@ -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;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,wBAqdE;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA+CH,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,wBAqeE;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -25,15 +25,17 @@
25
25
  import * as fs from "fs";
26
26
  import * as path from "path";
27
27
  import * as os from "os";
28
- // Read version from package.json at module load time
28
+ // Lazy-load version to avoid blocking I/O at module load time
29
+ // OpenClaw loads plugins synchronously, so top-level sync I/O will block status command
29
30
  const PACKAGE_JSON_PATH = path.join(__dirname, "..", "package.json");
30
- let VERSION = "unknown";
31
- try {
32
- const packageJson = JSON.parse(fs.readFileSync(PACKAGE_JSON_PATH, "utf-8"));
33
- VERSION = packageJson.version || "unknown";
34
- }
35
- catch {
36
- // Ignore if package.json not found
31
+ function getVersion() {
32
+ try {
33
+ const packageJson = JSON.parse(fs.readFileSync(PACKAGE_JSON_PATH, "utf-8"));
34
+ return packageJson.version || "unknown";
35
+ }
36
+ catch {
37
+ return "unknown";
38
+ }
37
39
  }
38
40
  const DEFAULT_API_BASE = "https://t0ken.ai/api";
39
41
  const PLUGIN_DIR = path.join(os.homedir(), ".openclaw", "extensions", "memoryx-openclaw-plugin");
@@ -143,6 +145,15 @@ class MemoryXPlugin {
143
145
  try {
144
146
  const sdk = await getSDK(this.pluginConfig);
145
147
  const result = await sdk.search(query, limit);
148
+ // Check if quota is limited (search_count >= search_limit for free tier)
149
+ const isLimited = result.is_limited ??
150
+ (result.search_count !== undefined &&
151
+ result.search_limit !== undefined &&
152
+ result.search_count >= result.search_limit);
153
+ // Build upgrade hint if limited
154
+ const upgradeHint = isLimited
155
+ ? `Search quota exceeded (${result.search_count}/${result.search_limit}). Upgrade to Pro for unlimited searches.`
156
+ : undefined;
146
157
  return {
147
158
  memories: (result.data || []).map((m) => ({
148
159
  id: m.id,
@@ -156,8 +167,9 @@ class MemoryXPlugin {
156
167
  category: m.category || "other",
157
168
  score: m.score || 0
158
169
  })),
159
- isLimited: false,
160
- remainingQuota: result.remaining_quota ?? -1
170
+ isLimited,
171
+ remainingQuota: result.remaining_quota ?? -1,
172
+ upgradeHint
161
173
  };
162
174
  }
163
175
  catch (e) {
@@ -261,7 +273,7 @@ let plugin;
261
273
  export default {
262
274
  id: "memoryx-openclaw-plugin",
263
275
  name: "MemoryX Realtime Plugin",
264
- get version() { return VERSION; },
276
+ get version() { return getVersion(); },
265
277
  description: "Real-time memory capture and recall for OpenClaw (powered by @t0ken.ai/memoryx-sdk)",
266
278
  register(api, pluginConfig) {
267
279
  api.logger.info("[MemoryX] Plugin registering...");
@@ -603,18 +615,30 @@ export default {
603
615
  }
604
616
  }
605
617
  }, { name: "memoryx_queue_status" });
618
+ // User message capture via message_received hook
619
+ // Event structure: { from: string, content: string, timestamp?: number }
606
620
  api.on("message_received", async (event, ctx) => {
607
621
  const { content } = event;
608
622
  if (content && plugin) {
609
623
  await plugin.onMessage("user", content);
610
624
  }
611
625
  });
612
- api.on("assistant_response", async (event, ctx) => {
613
- const { content } = event;
614
- if (content && plugin) {
615
- await plugin.onMessage("assistant", content);
626
+ // Assistant response capture via llm_output hook
627
+ // AI responses are saved to conversation history (for rounds/maxTokens counting)
628
+ // But they do NOT trigger memory search - only user messages do that
629
+ api.on("llm_output", async (event, ctx) => {
630
+ const { assistantTexts } = event;
631
+ if (assistantTexts && Array.isArray(assistantTexts) && plugin) {
632
+ // Join all assistant text segments
633
+ const fullContent = assistantTexts.join("\n");
634
+ if (fullContent && fullContent.length >= 2) {
635
+ await plugin.onMessage("assistant", fullContent);
636
+ }
616
637
  }
617
638
  });
639
+ // Auto-inject memories via prependContext
640
+ // Note: OpenClaw's systemPrompt field is extracted but NEVER USED (bug in attempt.ts:918-928)
641
+ // We use prependContext which works, but the context will be visible in the user's prompt
618
642
  api.on("before_agent_start", async (event, ctx) => {
619
643
  const { prompt } = event;
620
644
  if (!prompt || prompt.length < 2 || !plugin)
@@ -622,39 +646,42 @@ export default {
622
646
  try {
623
647
  const result = await plugin.recall(prompt, 5);
624
648
  if (result.isLimited) {
649
+ // Don't inject upgrade hints into prompt - just log
625
650
  api.logger.warn(`[MemoryX] ${result.upgradeHint}`);
626
- return {
627
- systemPrompt: `[MemoryX] ${result.upgradeHint}`
628
- };
651
+ return;
629
652
  }
630
653
  if (result.memories.length === 0 && result.relatedMemories.length === 0)
631
654
  return;
632
- // 使用 systemPrompt 而不是 prependContext
633
- // systemPrompt 不会显示在用户聊天内容中
634
- let context = "[MemoryX] Relevant memories from past conversations:\n";
655
+ // Build a concise memory context
656
+ // Format: [Memory Context]\n- memory 1\n- memory 2
657
+ const lines = ["[Memory Context]"];
635
658
  if (result.memories.length > 0) {
636
- context += result.memories.map(m => `- ${m.content}`).join("\n");
659
+ lines.push(...result.memories.map(m => `- ${m.content}`));
637
660
  }
638
661
  if (result.relatedMemories.length > 0) {
639
662
  if (result.memories.length > 0)
640
- context += "\n";
641
- context += result.relatedMemories.map(m => `- ${m.content}`).join("\n");
663
+ lines.push("");
664
+ lines.push("[Related]");
665
+ lines.push(...result.relatedMemories.map(m => `- ${m.content}`));
642
666
  }
643
- api.logger.info(`[MemoryX] Injected ${result.memories.length} direct + ${result.relatedMemories.length} related memories into system prompt`);
667
+ const context = lines.join("\n");
668
+ api.logger.info(`[MemoryX] Injected ${result.memories.length} direct + ${result.relatedMemories.length} related memories`);
644
669
  return {
645
- systemPrompt: context
670
+ prependContext: context
646
671
  };
647
672
  }
648
673
  catch (error) {
649
674
  api.logger.warn(`[MemoryX] Recall failed: ${error}`);
650
675
  }
651
676
  });
652
- api.on("conversation_end", async (event, ctx) => {
677
+ // Session end hook - flush memories when session ends
678
+ // Event structure: { sessionId: string, messageCount: number, durationMs?: number }
679
+ api.on("session_end", async (event, ctx) => {
653
680
  if (plugin) {
654
681
  await plugin.endConversation();
655
682
  }
656
683
  });
657
- api.logger.info(`[MemoryX] ✅ Plugin v${VERSION} ready! Your conversations will be remembered automatically.`);
684
+ api.logger.info(`[MemoryX] ✅ Plugin v${getVersion()} ready! Your conversations will be remembered automatically.`);
658
685
  // Async check and show portal link after SDK initializes
659
686
  setImmediate(async () => {
660
687
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t0ken.ai/memoryx-openclaw-plugin",
3
- "version": "2.2.12",
3
+ "version": "2.2.15",
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.2"
38
+ "@t0ken.ai/memoryx-sdk": "^1.4.3"
39
39
  }
40
40
  }