@openclaw/memory-lancedb 2026.5.28-beta.1 → 2026.5.28-beta.2

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/config.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
+ import { parseFiniteNumber } from "openclaw/plugin-sdk/number-runtime";
4
5
  //#region extensions/memory-lancedb/config.ts
5
6
  const MEMORY_CATEGORIES = [
6
7
  "preference",
@@ -56,11 +57,27 @@ function resolveEnvVars(value) {
56
57
  return envValue;
57
58
  });
58
59
  }
59
- function resolveEmbeddingModel(embedding) {
60
+ function resolveEmbeddingModel(embedding, dimensions) {
60
61
  const model = typeof embedding.model === "string" ? embedding.model : DEFAULT_MODEL;
61
- if (typeof embedding.dimensions !== "number") vectorDimsForModel(model);
62
+ if (dimensions === void 0) vectorDimsForModel(model);
62
63
  return model;
63
64
  }
65
+ function resolveFiniteIntegerConfig(value) {
66
+ if (typeof value !== "number") return;
67
+ const parsed = parseFiniteNumber(value);
68
+ return parsed === void 0 ? void 0 : Math.floor(parsed);
69
+ }
70
+ function resolveBoundedIntegerConfig(params) {
71
+ const resolved = resolveFiniteIntegerConfig(params.value) ?? params.fallback;
72
+ if (resolved < params.min || resolved > params.max) throw new Error(`${params.label} must be between ${params.min} and ${params.max}`);
73
+ return resolved;
74
+ }
75
+ function resolveEmbeddingDimensions(embedding) {
76
+ if (embedding.dimensions === void 0) return;
77
+ const dimensions = typeof embedding.dimensions === "number" ? parseFiniteNumber(embedding.dimensions) : void 0;
78
+ if (dimensions === void 0 || !Number.isInteger(dimensions) || dimensions < 1) throw new Error("embedding.dimensions must be a positive integer");
79
+ return dimensions;
80
+ }
64
81
  const memoryConfigSchema = {
65
82
  parse(value) {
66
83
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("memory config required");
@@ -80,13 +97,24 @@ const memoryConfigSchema = {
80
97
  if (!embedding || typeof embedding !== "object" || Array.isArray(embedding)) throw new Error("embedding config required");
81
98
  assertAllowedKeys(embedding, [...EMBEDDING_CONFIG_KEYS], "embedding config");
82
99
  if (Object.keys(embedding).length === 0) throw new Error("embedding config must include at least one setting");
83
- const model = resolveEmbeddingModel(embedding);
100
+ const dimensions = resolveEmbeddingDimensions(embedding);
101
+ const model = resolveEmbeddingModel(embedding, dimensions);
84
102
  const provider = typeof embedding.provider === "string" ? embedding.provider.trim() : "openai";
85
103
  if (!provider) throw new Error("embedding.provider must not be empty");
86
- const captureMaxChars = typeof cfg.captureMaxChars === "number" ? Math.floor(cfg.captureMaxChars) : void 0;
87
- const recallMaxChars = typeof cfg.recallMaxChars === "number" ? Math.floor(cfg.recallMaxChars) : void 0;
88
- if (typeof captureMaxChars === "number" && (captureMaxChars < 100 || captureMaxChars > 1e4)) throw new Error("captureMaxChars must be between 100 and 10000");
89
- if (typeof recallMaxChars === "number" && (recallMaxChars < 100 || recallMaxChars > 1e4)) throw new Error("recallMaxChars must be between 100 and 10000");
104
+ const captureMaxChars = resolveBoundedIntegerConfig({
105
+ value: cfg.captureMaxChars,
106
+ fallback: 500,
107
+ min: 100,
108
+ max: 1e4,
109
+ label: "captureMaxChars"
110
+ });
111
+ const recallMaxChars = resolveBoundedIntegerConfig({
112
+ value: cfg.recallMaxChars,
113
+ fallback: DEFAULT_RECALL_MAX_CHARS,
114
+ min: 100,
115
+ max: 1e4,
116
+ label: "recallMaxChars"
117
+ });
90
118
  let customTriggers;
91
119
  if (cfg.customTriggers !== void 0) {
92
120
  if (!Array.isArray(cfg.customTriggers)) throw new Error("customTriggers must be an array of strings");
@@ -118,15 +146,15 @@ const memoryConfigSchema = {
118
146
  model,
119
147
  apiKey: typeof embedding.apiKey === "string" ? resolveEnvVars(embedding.apiKey) : void 0,
120
148
  baseUrl: typeof embedding.baseUrl === "string" ? resolveEnvVars(embedding.baseUrl) : void 0,
121
- dimensions: typeof embedding.dimensions === "number" ? embedding.dimensions : void 0
149
+ dimensions
122
150
  },
123
151
  dreaming,
124
152
  dbPath: typeof cfg.dbPath === "string" ? cfg.dbPath : DEFAULT_DB_PATH,
125
153
  autoCapture: cfg.autoCapture === true,
126
154
  autoRecall: cfg.autoRecall !== false,
127
- captureMaxChars: captureMaxChars ?? 500,
155
+ captureMaxChars,
128
156
  ...customTriggers ? { customTriggers } : {},
129
- recallMaxChars: recallMaxChars ?? 1e3,
157
+ recallMaxChars,
130
158
  ...storageOptions ? { storageOptions } : {}
131
159
  };
132
160
  },
package/dist/index.js CHANGED
@@ -54,9 +54,12 @@ function extractLatestUserText(messages) {
54
54
  }
55
55
  function normalizeRecallQuery(text, maxChars = DEFAULT_RECALL_MAX_CHARS) {
56
56
  const normalized = text.replace(/\s+/g, " ").trim();
57
- const limit = Math.max(0, Math.floor(maxChars));
57
+ const limit = normalizeMaxChars(maxChars, DEFAULT_RECALL_MAX_CHARS);
58
58
  return normalized.length > limit ? truncateUtf16Safe(normalized, limit).trimEnd() : normalized;
59
59
  }
60
+ function normalizeMaxChars(value, fallback) {
61
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : fallback;
62
+ }
60
63
  function messageFingerprint(message) {
61
64
  const msgObj = asOptionalRecord(message);
62
65
  if (!msgObj) return `${typeof message}:${String(message)}`;
@@ -336,7 +339,7 @@ function matchesCustomTrigger(text, customTriggers) {
336
339
  return customTriggers.some((trigger) => lower.includes(trigger.toLocaleLowerCase()));
337
340
  }
338
341
  function shouldCapture(text, options) {
339
- const maxChars = options?.maxChars ?? 500;
342
+ const maxChars = normalizeMaxChars(options?.maxChars, 500);
340
343
  if (text.length > maxChars) return false;
341
344
  if (text.includes("<relevant-memories>")) return false;
342
345
  if (text.startsWith("<") && text.includes("</")) return false;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/memory-lancedb",
3
- "version": "2026.5.28-beta.1",
3
+ "version": "2026.5.28-beta.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/memory-lancedb",
9
- "version": "2026.5.28-beta.1",
9
+ "version": "2026.5.28-beta.2",
10
10
  "dependencies": {
11
11
  "@lancedb/lancedb": "0.29.0",
12
12
  "apache-arrow": "18.1.0",
@@ -103,7 +103,8 @@
103
103
  "type": "string"
104
104
  },
105
105
  "dimensions": {
106
- "type": "number"
106
+ "type": "integer",
107
+ "minimum": 1
107
108
  }
108
109
  }
109
110
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/memory-lancedb",
3
- "version": "2026.5.28-beta.1",
3
+ "version": "2026.5.28-beta.2",
4
4
  "description": "OpenClaw LanceDB-backed long-term memory plugin with auto-recall, auto-capture, and vector search.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,10 +26,10 @@
26
26
  "minHostVersion": ">=2026.4.10"
27
27
  },
28
28
  "compat": {
29
- "pluginApi": ">=2026.5.28-beta.1"
29
+ "pluginApi": ">=2026.5.28-beta.2"
30
30
  },
31
31
  "build": {
32
- "openclawVersion": "2026.5.28-beta.1"
32
+ "openclawVersion": "2026.5.28-beta.2"
33
33
  },
34
34
  "release": {
35
35
  "bundleRuntimeDependencies": false,
@@ -46,7 +46,7 @@
46
46
  "npm-shrinkwrap.json"
47
47
  ],
48
48
  "peerDependencies": {
49
- "openclaw": ">=2026.5.28-beta.1"
49
+ "openclaw": ">=2026.5.28-beta.2"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "openclaw": {