@icex-labs/openclaw-memory-engine 5.0.0 → 5.0.1

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.
Files changed (2) hide show
  1. package/lib/classifier.js +43 -2
  2. package/package.json +1 -1
package/lib/classifier.js CHANGED
@@ -158,16 +158,57 @@ export async function classifyImportance(contentEmbedding, ws) {
158
158
  return IMPORTANCE_SCORES[bestLevel] || 5;
159
159
  }
160
160
 
161
+ /**
162
+ * Lightweight fallback classifier — no embedding API needed.
163
+ * Uses format/symbol signals that work across languages:
164
+ * - $ amounts → finance
165
+ * - URLs → technology
166
+ * - dates → general (but higher importance)
167
+ * - very short messages → low importance
168
+ */
169
+ function fallbackClassify(content) {
170
+ let entity = "general";
171
+ let importance = 5;
172
+
173
+ // Finance: currency symbols, large numbers
174
+ if (/[\$€£¥₹]\s*[\d,.]+|\b\d{4,}[\d,.]*\b/.test(content)) {
175
+ entity = "finance";
176
+ importance = 7;
177
+ }
178
+ // Technology: URLs, code patterns, file paths
179
+ else if (/https?:\/\/|```|\/\w+\/\w+|\.(js|py|ts|json|yaml|md)\b/i.test(content)) {
180
+ entity = "technology";
181
+ }
182
+ // Dates with context → likely scheduling/planning
183
+ else if (/\b\d{4}-\d{2}-\d{2}\b|\b\d{1,2}:\d{2}\b/.test(content)) {
184
+ importance = 6;
185
+ }
186
+
187
+ // Short messages are less important
188
+ if (content.length < 30) importance = Math.min(importance, 3);
189
+ // Long detailed messages are more important
190
+ if (content.length > 200) importance = Math.max(importance, 6);
191
+
192
+ return { entity, importance };
193
+ }
194
+
161
195
  /**
162
196
  * Full classification: entity + importance in one call.
163
- * Reuses the same content embedding for both.
197
+ * Uses embedding similarity when available, falls back to format-based heuristics.
164
198
  * @param {string} content - text to classify
165
199
  * @param {string} ws - workspace path
166
200
  * @param {float[]} [existingEmbedding] - reuse if already computed
167
- * @returns {Promise<{ entity: string, importance: number }>}
201
+ * @returns {Promise<{ entity: string, importance: number, embedding: float[]|null }>}
168
202
  */
169
203
  export async function classify(content, ws, existingEmbedding = null) {
170
204
  const emb = existingEmbedding || await getEmbedding(content);
205
+
206
+ // If no embedding available (no API key), use fallback
207
+ if (!emb) {
208
+ const fb = fallbackClassify(content);
209
+ return { entity: fb.entity, importance: fb.importance, embedding: null };
210
+ }
211
+
171
212
  const [entity, importance] = await Promise.all([
172
213
  classifyEntity(emb, ws),
173
214
  classifyImportance(emb, ws),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icex-labs/openclaw-memory-engine",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "description": "MemGPT-style hierarchical memory plugin for OpenClaw — core memory block + archival storage with semantic search",
5
5
  "type": "module",
6
6
  "main": "index.js",