openclaw-amem 1.4.1 → 1.4.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/index.js CHANGED
@@ -56,6 +56,12 @@ var init_config = __esm({
56
56
  function getEmbeddingModel() {
57
57
  return process.env.AMEM_EMBED_MODEL?.trim() || DEFAULT_EMBEDDING_MODEL;
58
58
  }
59
+ function getEmbeddingPooling() {
60
+ const explicit = process.env.AMEM_EMBED_POOLING?.trim().toLowerCase();
61
+ if (explicit === "mean" || explicit === "cls") return explicit;
62
+ const basename2 = getEmbeddingModel().split("/").pop()?.toLowerCase() ?? "";
63
+ return CLS_POOLED_MODELS.has(basename2) ? "cls" : "mean";
64
+ }
59
65
  async function getExtractor() {
60
66
  const wanted = getEmbeddingModel();
61
67
  if (extractor && loadedModelName === wanted) return extractor;
@@ -76,21 +82,25 @@ async function getEmbeddingDim() {
76
82
  cachedDim = probe.length;
77
83
  return cachedDim;
78
84
  }
79
- function meanPoolingNormalize(output, attentionMask) {
85
+ function poolNormalize(output, attentionMask, mode) {
80
86
  const seqLen = output.length;
81
87
  const dim = output[0].length;
82
88
  const pooled = new Array(dim).fill(0);
83
- let maskSum = 0;
84
- for (let i = 0; i < seqLen; i++) {
85
- const m = attentionMask[i];
86
- maskSum += m;
89
+ if (mode === "cls") {
90
+ for (let j = 0; j < dim; j++) pooled[j] = output[0][j];
91
+ } else {
92
+ let maskSum = 0;
93
+ for (let i = 0; i < seqLen; i++) {
94
+ const m = attentionMask[i];
95
+ maskSum += m;
96
+ for (let j = 0; j < dim; j++) {
97
+ pooled[j] += output[i][j] * m;
98
+ }
99
+ }
87
100
  for (let j = 0; j < dim; j++) {
88
- pooled[j] += output[i][j] * m;
101
+ pooled[j] /= Math.max(maskSum, 1e-9);
89
102
  }
90
103
  }
91
- for (let j = 0; j < dim; j++) {
92
- pooled[j] /= Math.max(maskSum, 1e-9);
93
- }
94
104
  let norm = 0;
95
105
  for (const v of pooled) norm += v * v;
96
106
  norm = Math.sqrt(norm);
@@ -98,7 +108,8 @@ function meanPoolingNormalize(output, attentionMask) {
98
108
  }
99
109
  async function encode(text) {
100
110
  const ext = await getExtractor();
101
- const result = await ext(text, { pooling: "mean", normalize: true });
111
+ const pooling = getEmbeddingPooling();
112
+ const result = await ext(text, { pooling, normalize: true });
102
113
  if (result && result.data) {
103
114
  return Array.from(result.data);
104
115
  }
@@ -114,7 +125,7 @@ async function encode(text) {
114
125
  }
115
126
  raw.push(row);
116
127
  }
117
- return meanPoolingNormalize(raw, new Array(seqLen).fill(1));
128
+ return poolNormalize(raw, new Array(seqLen).fill(1), pooling);
118
129
  }
119
130
  throw new Error("Unexpected embedding output shape");
120
131
  }
@@ -129,7 +140,7 @@ function cosineSimilarity(a, b) {
129
140
  for (let i = 0; i < a.length; i++) dot += a[i] * b[i];
130
141
  return dot;
131
142
  }
132
- var pipeline, extractor, loadedModelName, cachedDim, DEFAULT_EMBEDDING_MODEL;
143
+ var pipeline, extractor, loadedModelName, cachedDim, DEFAULT_EMBEDDING_MODEL, CLS_POOLED_MODELS;
133
144
  var init_embedding = __esm({
134
145
  "../amem-core/src/embedding.ts"() {
135
146
  "use strict";
@@ -138,6 +149,19 @@ var init_embedding = __esm({
138
149
  loadedModelName = null;
139
150
  cachedDim = null;
140
151
  DEFAULT_EMBEDDING_MODEL = "Xenova/paraphrase-multilingual-MiniLM-L12-v2";
152
+ CLS_POOLED_MODELS = /* @__PURE__ */ new Set([
153
+ "bge-m3",
154
+ "bge-base-zh-v1.5",
155
+ "bge-small-zh-v1.5",
156
+ "bge-base-en-v1.5",
157
+ "bge-small-en-v1.5",
158
+ "bge-large-en-v1.5",
159
+ "gte-multilingual-base",
160
+ "gte-modernbert-base",
161
+ "gte-large-en-v1.5",
162
+ "snowflake-arctic-embed-m",
163
+ "snowflake-arctic-embed-l"
164
+ ]);
141
165
  }
142
166
  });
143
167
 
@@ -2395,6 +2419,7 @@ __export(src_exports, {
2395
2419
  generateReviewBatch: () => generateReviewBatch,
2396
2420
  getEmbeddingDim: () => getEmbeddingDim,
2397
2421
  getEmbeddingModel: () => getEmbeddingModel,
2422
+ getEmbeddingPooling: () => getEmbeddingPooling,
2398
2423
  getNote: () => getNote,
2399
2424
  invalidateNote: () => invalidateNote,
2400
2425
  isModelLoaded: () => isModelLoaded,
@@ -2,7 +2,7 @@
2
2
  "id": "openclaw-amem",
3
3
  "name": "amem",
4
4
  "description": "Catches memories that contradict each other. Notes rewrite themselves as new ones arrive, link into a graph, and stay separated per agent and per person. Runs on a small model. Requires a local Qdrant. 中文走 jieba 分词,提示词有中文版。",
5
- "version": "1.4.1",
5
+ "version": "1.4.2",
6
6
  "kind": "memory",
7
7
  "openclaw": {
8
8
  "compat": {
@@ -39,6 +39,7 @@
39
39
  "AMEM_LLM_TIMEOUT",
40
40
  "AMEM_CRUD_UPDATE_MIN_SIM",
41
41
  "AMEM_EMBED_MODEL",
42
+ "AMEM_EMBED_POOLING",
42
43
  "AMEM_COLLECTION",
43
44
  "AMEM_DATA_DIR",
44
45
  "AMEM_EVO_COUNTER_PATH",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-amem",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Catches memories that contradict each other. Notes rewrite themselves as new ones arrive, link into a graph, and stay separated per agent and per person. Runs on a small model. Requires a local Qdrant. 中文走 jieba 分词,提示词有中文版。",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -16,7 +16,7 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@anthropic-ai/sdk": "^0.112.1",
19
+ "@anthropic-ai/sdk": "^0.112.5",
20
20
  "@huggingface/transformers": "^4.2.0",
21
21
  "@node-rs/jieba": "^2.0.1",
22
22
  "@qdrant/js-client-rest": "^1.18.0",
@@ -28,7 +28,7 @@
28
28
  "@types/node": "^26.1.1",
29
29
  "@types/uuid": "^11.0.0",
30
30
  "eslint": "^10.7.0",
31
- "prettier": "^3.9.5",
31
+ "prettier": "^3.9.6",
32
32
  "tsup": "^8.4.0",
33
33
  "tsx": "^4.23.1",
34
34
  "typescript": "^6.0.3",