@t0ken.ai/memoryx-openclaw-plugin 2.2.59 → 2.2.61

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 CHANGED
@@ -168,9 +168,21 @@ Memories are categorized by the server:
168
168
  - Minimum 2 characters per message
169
169
  - Short messages like "ok", "thanks" are skipped
170
170
 
171
- ## How the proxy works (no virtual model)
171
+ ## How the proxy works
172
172
 
173
- The plugin does **not** add a virtual model. It redirects your existing provider's request URL to a local Sidecar (port 3335). You keep using your configured model (e.g. `zai/glm-5`); the request is sent to the Sidecar with a header identifying the real provider, then the Sidecar forwards to the MemoryX server with your credentials. No need to add `memoryx-proxy` to config or auth.
173
+ **Current behavior:** The plugin starts a local Sidecar (port 3335) and tries to redirect your existing providers baseUrl to it (so you keep using e.g. `zai/glm-5`). Whether that works depends on how OpenClaw resolves the model (config vs. registry). See `OPENCLAW-BASEURL-FLOW.md` for details.
174
+
175
+ **SlimClaw-style (recommended, no file changes):** Like SlimClaw, you can use a **virtual provider** so all traffic goes through the Sidecar without the plugin mutating config or files. Add this to `~/.openclaw/openclaw.json` under `models.providers`:
176
+
177
+ ```json
178
+ "memoryx-proxy": {
179
+ "baseUrl": "http://localhost:3335/v1",
180
+ "apiKey": "placeholder",
181
+ "models": [{ "id": "auto" }]
182
+ }
183
+ ```
184
+
185
+ Then add an auth profile for `memoryx-proxy` (e.g. in `~/.openclaw/agents/main/agent/auth-profiles.json` or global auth) with any placeholder key. In the UI, choose model **memoryx-proxy/auto**. Requests will go to the Sidecar, which forwards to the MemoryX server with your real provider credentials (you configure which provider/model to use via the plugin/Sidecar logic). The plugin does not modify your config or `models.json`; it only runs the Sidecar.
174
186
 
175
187
  ## License
176
188
 
@@ -0,0 +1,8 @@
1
+ export declare const PLUGIN_VERSION = "2.2.61";
2
+ export declare const DEFAULT_API_BASE = "https://t0ken.ai/api";
3
+ export declare const PLUGIN_DIR: string;
4
+ /** 真实上游 baseUrl 缓存文件:重启后若配置已被改成 localhost,从此文件恢复各厂商真实地址。 */
5
+ export declare const REAL_UPSTREAM_BASEURL_CACHE_FILE: string;
6
+ /** Sidecar HTTP port — fixed so openclaw.json can point to localhost:37169. Do not use a range. */
7
+ export declare const SIDECAR_PORT = 37169;
8
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AAEvD,eAAO,MAAM,UAAU,QAAgF,CAAC;AAExG,4DAA4D;AAC5D,eAAO,MAAM,gCAAgC,QAAsD,CAAC;AAEpG,mGAAmG;AACnG,eAAO,MAAM,YAAY,QAAQ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Plugin constants. PLUGIN_VERSION is synced from package.json by prebuild script.
3
+ */
4
+ import * as path from "path";
5
+ import * as os from "os";
6
+ // Plugin version - synced from package.json by prebuild script
7
+ export const PLUGIN_VERSION = "2.2.61";
8
+ export const DEFAULT_API_BASE = "https://t0ken.ai/api";
9
+ export const PLUGIN_DIR = path.join(os.homedir(), ".openclaw", "extensions", "memoryx-openclaw-plugin");
10
+ /** 真实上游 baseUrl 缓存文件:重启后若配置已被改成 localhost,从此文件恢复各厂商真实地址。 */
11
+ export const REAL_UPSTREAM_BASEURL_CACHE_FILE = path.join(PLUGIN_DIR, "real-upstream-baseurl.json");
12
+ /** Sidecar HTTP port — fixed so openclaw.json can point to localhost:37169. Do not use a range. */
13
+ export const SIDECAR_PORT = 37169;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * OpenClaw hooks: message_received, llm_input, llm_output, before_agent_start, session_end.
3
+ */
4
+ import type { MemoryXPlugin } from "./plugin-core.js";
5
+ export declare function registerHooks(api: any, plugin: MemoryXPlugin, wrapProvidersWithProxy: () => void, applySidecarRedirect: (opts?: {
6
+ quiet?: boolean;
7
+ }) => void): void;
8
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,wBAAgB,aAAa,CACzB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,aAAa,EACrB,sBAAsB,EAAE,MAAM,IAAI,EAClC,oBAAoB,EAAE,CAAC,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,GAC3D,IAAI,CAyCN"}
package/dist/hooks.js ADDED
@@ -0,0 +1,39 @@
1
+ export function registerHooks(api, plugin, wrapProvidersWithProxy, applySidecarRedirect) {
2
+ let useVirtualProviderInLastRun = false;
3
+ api.on("message_received", async (event) => {
4
+ const { content } = event;
5
+ if (content && plugin)
6
+ await plugin.onMessage("user", content);
7
+ });
8
+ api.on("llm_input", (_event) => {
9
+ useVirtualProviderInLastRun = _event?.provider === "memoryx-proxy";
10
+ });
11
+ api.on("llm_output", async (event) => {
12
+ const { assistantTexts, provider } = event;
13
+ if (assistantTexts && Array.isArray(assistantTexts) && plugin && provider !== "memoryx-proxy") {
14
+ const fullContent = assistantTexts.join("\n");
15
+ if (fullContent && fullContent.length >= 2)
16
+ await plugin.onMessage("assistant", fullContent);
17
+ }
18
+ });
19
+ api.on("before_agent_start", async (event) => {
20
+ wrapProvidersWithProxy();
21
+ applySidecarRedirect({ quiet: true });
22
+ const { prompt } = event;
23
+ if (!prompt || prompt.length < 2 || !plugin)
24
+ return;
25
+ try {
26
+ await plugin.startTimersIfNeeded();
27
+ await plugin.onMessage("user", prompt);
28
+ // 记忆注入改由服务端 llm_proxy 在转发前注入到请求体(system/消息),不在此处用 prependContext,
29
+ // 避免 OpenClaw 把 prependContext 当成单独用户消息写入历史(role=user 的 MemoryX Context 条)。
30
+ }
31
+ catch (error) {
32
+ api.logger.warn(`[MemoryX] before_agent_start failed: ${error}`);
33
+ }
34
+ });
35
+ api.on("session_end", async () => {
36
+ if (plugin)
37
+ await plugin.endConversation();
38
+ });
39
+ }
package/dist/index.d.ts CHANGED
@@ -3,86 +3,18 @@
3
3
  *
4
4
  * ⚠️ CRITICAL: DO NOT execute any synchronous I/O in register() function!
5
5
  *
6
- * OpenClaw calls register() synchronously (see openclaw/src/plugins/loader.ts):
7
- * const result = register(api);
8
- * if (result && typeof result.then === "function") {
9
- * // async registration is ignored
10
- * }
11
- *
12
- * Any sync I/O (fs.existsSync, fs.mkdirSync, fs.readFileSync, etc.)
13
- * will BLOCK the Node.js event loop and cause gateway restart to hang.
14
- *
15
- * SOLUTION:
16
- * 1. register() must return immediately without any I/O
17
- * 2. All initialization (DB, config loading, etc.) must be lazy-loaded
18
- * 3. SDK uses sql.js (async) internally - no blocking issues
19
- * 4. Use setImmediate() for deferred operations
6
+ * OpenClaw calls register() synchronously (see openclaw/src/plugins/loader.ts).
7
+ * Any sync I/O will BLOCK the Node.js event loop and cause gateway restart to hang.
8
+ * - register() must return immediately without any I/O
9
+ * - All initialization (DB, config loading, etc.) must be lazy-loaded
10
+ * - Use setImmediate() for deferred operations
20
11
  *
21
12
  * This version uses @t0ken.ai/memoryx-sdk with conversation preset:
22
13
  * - maxTokens: 30000 (flush when reaching token limit)
23
14
  * - intervalMs: 300000 (flush after 5 minutes idle)
24
15
  */
25
- interface PluginConfig {
26
- apiBaseUrl?: string;
27
- /** 启用调试模式,拦截所有请求并记录到 plugin.log */
28
- debugProvider?: boolean;
29
- }
30
- interface RecallResult {
31
- memories: Array<{
32
- id: string;
33
- content: string;
34
- category: string;
35
- score: number;
36
- }>;
37
- relatedMemories: Array<{
38
- id: string;
39
- content: string;
40
- category: string;
41
- score: number;
42
- }>;
43
- isLimited: boolean;
44
- remainingQuota: number;
45
- upgradeHint?: string;
46
- }
47
- declare class MemoryXPlugin {
48
- private pluginConfig;
49
- private initialized;
50
- private timersStarted;
51
- constructor(pluginConfig?: PluginConfig);
52
- init(): Promise<void>;
53
- startTimersIfNeeded(): Promise<void>;
54
- onMessage(role: string, content: string): Promise<boolean>;
55
- recall(query: string, limit?: number): Promise<RecallResult>;
56
- endConversation(): Promise<void>;
57
- forget(memoryId: string): Promise<boolean>;
58
- store(content: string): Promise<{
59
- success: boolean;
60
- task_id?: string;
61
- }>;
62
- list(limit?: number): Promise<any[]>;
63
- getAccountInfo(): Promise<{
64
- apiKey: string | null;
65
- agentId: string | null;
66
- agentType: string | null;
67
- initialized: boolean;
68
- quota?: any;
69
- }>;
70
- getQueueStatus(): Promise<{
71
- success: boolean;
72
- data?: {
73
- agent_id: string;
74
- tier: string;
75
- queue_name: string;
76
- queue_length: number;
77
- memory_free_queue: number;
78
- memory_pro_queue: number;
79
- estimated_wait_time: string;
80
- status: string;
81
- message: string;
82
- };
83
- error?: string;
84
- }>;
85
- }
16
+ import type { PluginConfig } from "./types.js";
17
+ import { MemoryXPlugin } from "./plugin-core.js";
86
18
  declare const _default: {
87
19
  id: string;
88
20
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAuDH,UAAU,YAAY;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;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;AAqDD,cAAM,aAAa;IACf,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAkB;gBAE3B,YAAY,CAAC,EAAE,YAAY;IAIjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAad,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUpC,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,wBA65BE;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAE,aAAa,EAAU,MAAM,kBAAkB,CAAC;;;;;;kBAyBvC,GAAG,iBAAiB,YAAY,GAAG,IAAI;;AARzD,wBAkGE;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}