@cortexkit/pi-magic-context 0.49.18 → 0.49.20

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 (59) hide show
  1. package/dist/auto-search-worker.js +53 -10
  2. package/dist/chunk-embedding-write-worker.js +29 -22
  3. package/dist/{compaction-marker-candidates-wjzqbspm.js → compaction-marker-candidates-fnm47jat.js} +3 -3
  4. package/dist/compaction-marker-candidates-worker.js +2 -2
  5. package/dist/compartment-chunk-embedding-81qesfjs.js +64 -0
  6. package/dist/embedding-backfill-56e871c6.js +24 -0
  7. package/dist/embedding-worker-process.js +2 -2
  8. package/dist/embedding-worker.js +5 -5
  9. package/dist/historian-calibration-extension.js +1 -1
  10. package/dist/index-54wmg4rj.js +82 -0
  11. package/dist/{index-xnch62s6.js → index-5n5zxs8e.js} +314 -127
  12. package/dist/{index-gdjv1nnd.js → index-5vgt1zeh.js} +6 -7
  13. package/dist/{index-qpq6w67c.js → index-6kb2xpw7.js} +2 -2
  14. package/dist/{index-d43hmn31.js → index-af9t637y.js} +68 -16
  15. package/dist/{index-z2rkv0mb.js → index-b8am7tns.js} +4 -4
  16. package/dist/{index-rhprywn6.js → index-bttctq07.js} +23 -5
  17. package/dist/{index-e1rza8gp.js → index-dzem6gn9.js} +1 -1
  18. package/dist/{index-2mmy81qt.js → index-e19qtjj0.js} +468 -18
  19. package/dist/{index-7bqrfyny.js → index-fgs78jyd.js} +12 -15
  20. package/dist/{index-d4dt19md.js → index-hqw0rt9k.js} +1 -1
  21. package/dist/{index-rrwv9y2k.js → index-hws5f0z9.js} +1 -1
  22. package/dist/{index-f18ec69t.js → index-jn44h81p.js} +1 -1
  23. package/dist/{index-xxn1tpnv.js → index-jt0g3hn0.js} +45 -28
  24. package/dist/{index-d8gc0112.js → index-jxjr7kz9.js} +3 -3
  25. package/dist/{index-4bv5bttd.js → index-kqb3d8bs.js} +9 -5
  26. package/dist/{index-gp928w10.js → index-mtvvhcw4.js} +10 -10
  27. package/dist/{index-1kcfwk9c.js → index-my0dn413.js} +1 -1
  28. package/dist/{index-apgwdby5.js → index-n4wyxcgr.js} +1 -1
  29. package/dist/{index-g7p75667.js → index-p63nwn5v.js} +2 -2
  30. package/dist/{index-svgkv4g2.js → index-qerzchrs.js} +2 -2
  31. package/dist/{index-vktahpdj.js → index-rfyvax95.js} +9 -3
  32. package/dist/{index-yygsh681.js → index-rgfb753z.js} +3 -3
  33. package/dist/{index-d21pdr8v.js → index-tb3d9trm.js} +2 -2
  34. package/dist/{index-vmcgew7x.js → index-v2epyzbm.js} +75 -57
  35. package/dist/{index-fvjthct0.js → index-vdy273xw.js} +107 -20
  36. package/dist/{index-jrap43gc.js → index-w1avzkdt.js} +1 -1
  37. package/dist/{index-r9f4f6s1.js → index-zhwwp8zz.js} +64 -8
  38. package/dist/index.js +1119 -247
  39. package/dist/{logger-dygt96rn.js → logger-shetp43v.js} +1 -1
  40. package/dist/{message-fts-rowid-map-cvpy2dmb.js → message-fts-rowid-map-bpexnsdj.js} +6 -5
  41. package/dist/{message-index-bounded-g9hgresf.js → message-index-bounded-d4r3weh0.js} +14 -13
  42. package/dist/{message-index-74qdqmq7.js → message-index-mvag9crh.js} +14 -13
  43. package/dist/{message-time-backfill-ssshbdy8.js → message-time-backfill-kc10yrcj.js} +3 -3
  44. package/dist/migration-worker.js +12 -11
  45. package/dist/{project-embedding-registry-vf1ncptn.js → project-embedding-registry-cfrg952x.js} +13 -12
  46. package/dist/raw-ordinal-warmup-worker.js +136 -101
  47. package/dist/{read-session-chunk-chepqmw5.js → read-session-chunk-7g4zvpd8.js} +9 -8
  48. package/dist/{read-session-raw-9s3xn7fc.js → read-session-raw-0fsjh10f.js} +4 -3
  49. package/dist/{safe-notification-target-2rkvkmw8.js → safe-notification-target-zcpchea6.js} +2 -2
  50. package/dist/search-archive-qbhp7e89.js +21 -0
  51. package/dist/{search-6ztbx25v.js → search-hp4g3g9v.js} +22 -21
  52. package/dist/{sqlite-fsp0sf3r.js → sqlite-d67n6dtr.js} +1 -1
  53. package/dist/{storage-memory-yxxc5v4n.js → storage-memory-9g882j7a.js} +2 -2
  54. package/dist/{storage-tags-1kets0q8.js → storage-tags-m2qcp1g2.js} +7 -5
  55. package/dist/subagent-entry.js +26 -25
  56. package/dist/tag-snapshot-worker-pi.js +66 -55
  57. package/package.json +1 -1
  58. package/dist/embedding-backfill-vwag34t0.js +0 -23
  59. package/dist/search-archive-jg4a1kcx.js +0 -20
@@ -3,7 +3,7 @@ import {
3
3
  } from "./index-bxmf4dhr.js";
4
4
  import {
5
5
  getSynapseLaneIdentity
6
- } from "./index-d8gc0112.js";
6
+ } from "./index-jxjr7kz9.js";
7
7
  import {
8
8
  getHarness2
9
9
  } from "./index-0h2mkab2.js";
@@ -11,10 +11,10 @@ import {
11
11
  getMagicContextStorageDir,
12
12
  importPluginModule,
13
13
  log2
14
- } from "./index-7bqrfyny.js";
14
+ } from "./index-fgs78jyd.js";
15
15
  import {
16
16
  inRootAsyncContext2
17
- } from "./index-rrwv9y2k.js";
17
+ } from "./index-hws5f0z9.js";
18
18
  import {
19
19
  computeNormalizedHash
20
20
  } from "./index-9x1f96r8.js";
@@ -98,6 +98,432 @@ function resolveEmbeddingTextPrefixes(model, queryInstruction, documentPrefix) {
98
98
  };
99
99
  }
100
100
 
101
+ // ../plugin/src/features/magic-context/memory/local-embedding-pooling.ts
102
+ import { createHash } from "node:crypto";
103
+ import { existsSync, readFileSync, statSync } from "node:fs";
104
+ import { join } from "node:path";
105
+ var decisionLogged = new Set;
106
+ var unavailableLogged = new Set;
107
+ var metadataByCache = new Map;
108
+ var testMetadataByModel = new Map;
109
+ var testMetadataFallback;
110
+ var UNRESOLVED_LOCAL_EMBEDDING_POOLING = {
111
+ status: "unresolved",
112
+ pooling: "mean",
113
+ normalize: true,
114
+ declared: false,
115
+ reason: "pooling metadata is unavailable; preserving legacy mean pooling and normalization"
116
+ };
117
+ var LEGACY_MEAN_POOLING = {
118
+ status: "ready",
119
+ pooling: "mean",
120
+ normalize: true,
121
+ declared: false,
122
+ reason: "no sentence-transformers Pooling module is declared; preserving legacy mean pooling and normalization"
123
+ };
124
+ function defaultModelCacheDir() {
125
+ return join(getMagicContextStorageDir(), "models");
126
+ }
127
+ function metadataDirectory(model, modelCacheDir) {
128
+ const digest = createHash("sha256").update(model).digest("hex");
129
+ return join(modelCacheDir, ".pooling-metadata", digest);
130
+ }
131
+ function parseJson(text, label) {
132
+ try {
133
+ return JSON.parse(text);
134
+ } catch (error) {
135
+ throw new Error(`${label} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
136
+ }
137
+ }
138
+ function isRecord(value) {
139
+ return typeof value === "object" && value !== null && !Array.isArray(value);
140
+ }
141
+ function isModelDirectory(model) {
142
+ try {
143
+ return statSync(model).isDirectory();
144
+ } catch {
145
+ return false;
146
+ }
147
+ }
148
+ function isPoolingModule(value) {
149
+ if (!isRecord(value))
150
+ return false;
151
+ return typeof value.type === "string" && /(?:^|\.)Pooling$/.test(value.type) || typeof value.name === "string" && value.name.toLowerCase() === "pooling";
152
+ }
153
+ function isNormalizeModule(value) {
154
+ if (!isRecord(value))
155
+ return false;
156
+ return typeof value.type === "string" && /(?:^|\.)Normalize$/.test(value.type) || typeof value.name === "string" && value.name.toLowerCase() === "normalize";
157
+ }
158
+ function safeModulePath(value) {
159
+ if (typeof value !== "string" || !value.trim())
160
+ return null;
161
+ const pieces = value.replaceAll("\\", "/").split("/");
162
+ if (pieces.some((piece) => piece === ".." || piece === "."))
163
+ return null;
164
+ return pieces.filter(Boolean).join("/");
165
+ }
166
+ function poolingFromFiles(modulesText, configText, label) {
167
+ if (modulesText === null)
168
+ return LEGACY_MEAN_POOLING;
169
+ const modulesValue = parseJson(modulesText, `${label}/modules.json`);
170
+ if (!Array.isArray(modulesValue)) {
171
+ return {
172
+ status: "unsupported",
173
+ normalize: false,
174
+ declared: true,
175
+ reason: "modules.json is not a module list"
176
+ };
177
+ }
178
+ const poolingModule = modulesValue.find(isPoolingModule);
179
+ if (!poolingModule)
180
+ return LEGACY_MEAN_POOLING;
181
+ const modulePath = safeModulePath(poolingModule.path);
182
+ if (modulePath === null || configText === null) {
183
+ return {
184
+ status: "unsupported",
185
+ normalize: modulesValue.some(isNormalizeModule),
186
+ declared: true,
187
+ reason: `Pooling module at ${String(poolingModule.path ?? "<missing path>")} has no readable config.json`
188
+ };
189
+ }
190
+ const config = parseJson(configText, `${label}/${modulePath}/config.json`);
191
+ if (!isRecord(config)) {
192
+ return {
193
+ status: "unsupported",
194
+ normalize: modulesValue.some(isNormalizeModule),
195
+ declared: true,
196
+ reason: `Pooling config at ${modulePath}/config.json is not an object`
197
+ };
198
+ }
199
+ const enabledModes = [
200
+ ["pooling_mode_cls_token", "cls"],
201
+ ["pooling_mode_mean_tokens", "mean"],
202
+ ["pooling_mode_lasttoken", "last_token"],
203
+ ["pooling_mode_max_tokens", undefined],
204
+ ["pooling_mode_mean_sqrt_len_tokens", undefined],
205
+ ["pooling_mode_weightedmean_tokens", undefined],
206
+ ["pooling_mode_mean_last_token", undefined]
207
+ ].filter(([key]) => config[key] === true);
208
+ const normalize = modulesValue.some(isNormalizeModule);
209
+ if (enabledModes.length !== 1) {
210
+ return {
211
+ status: "unsupported",
212
+ normalize,
213
+ declared: true,
214
+ reason: enabledModes.length === 0 ? `Pooling config at ${modulePath}/config.json enables no pooling mode` : `Pooling config enables multiple modes: ${enabledModes.map(([key]) => key).join(", ")}`
215
+ };
216
+ }
217
+ const [flag, method] = enabledModes[0];
218
+ if (!method) {
219
+ return {
220
+ status: "unsupported",
221
+ normalize,
222
+ declared: true,
223
+ reason: `unsupported declared pooling mode ${flag}`
224
+ };
225
+ }
226
+ return {
227
+ status: "ready",
228
+ pooling: method,
229
+ normalize,
230
+ declared: true,
231
+ reason: `modules.json declares ${flag}; ${normalize ? "a Normalize module is present" : "no Normalize module is declared"}`
232
+ };
233
+ }
234
+ function poolingMetadataCacheKey(model, modelCacheDir) {
235
+ return JSON.stringify([model, modelCacheDir]);
236
+ }
237
+ function cachedMetadataPath(model, modelCacheDir) {
238
+ return join(metadataDirectory(model, modelCacheDir), "resolution.json");
239
+ }
240
+ function parseCachedMetadata(text) {
241
+ try {
242
+ const value = JSON.parse(text);
243
+ if (!isRecord(value) || value.status !== "ready" && value.status !== "unsupported")
244
+ return null;
245
+ if (typeof value.normalize !== "boolean" || typeof value.declared !== "boolean" || typeof value.reason !== "string")
246
+ return null;
247
+ if (value.status === "ready" && value.pooling !== "mean" && value.pooling !== "cls" && value.pooling !== "last_token")
248
+ return null;
249
+ return value;
250
+ } catch {
251
+ return null;
252
+ }
253
+ }
254
+ function readDirectoryMetadata(model) {
255
+ const modulesPath = join(model, "modules.json");
256
+ if (!existsSync(modulesPath))
257
+ return LEGACY_MEAN_POOLING;
258
+ const modulesText = readFileSync(modulesPath, "utf8");
259
+ const moduleList = parseJson(modulesText, `${model}/modules.json`);
260
+ if (!Array.isArray(moduleList)) {
261
+ return {
262
+ status: "unsupported",
263
+ normalize: false,
264
+ declared: true,
265
+ reason: "modules.json is not a module list"
266
+ };
267
+ }
268
+ const poolingModule = moduleList.find(isPoolingModule);
269
+ const modulePath = poolingModule ? safeModulePath(poolingModule.path) : null;
270
+ const configText = modulePath ? readFileSync(join(model, modulePath, "config.json"), "utf8") : null;
271
+ return poolingFromFiles(modulesText, configText, model);
272
+ }
273
+ function getCachedLocalEmbeddingPooling(model, modelCacheDir = defaultModelCacheDir()) {
274
+ if (testMetadataByModel.has(model))
275
+ return testMetadataByModel.get(model) ?? null;
276
+ const cacheKey = poolingMetadataCacheKey(model, modelCacheDir);
277
+ const cachedInMemory = metadataByCache.get(cacheKey);
278
+ if (cachedInMemory)
279
+ return cachedInMemory;
280
+ if (isModelDirectory(model)) {
281
+ try {
282
+ const metadata = readDirectoryMetadata(model);
283
+ metadataByCache.set(cacheKey, metadata);
284
+ return metadata;
285
+ } catch (error) {
286
+ const metadata = {
287
+ status: "unsupported",
288
+ normalize: false,
289
+ declared: true,
290
+ reason: error instanceof Error ? error.message : String(error)
291
+ };
292
+ metadataByCache.set(cacheKey, metadata);
293
+ return metadata;
294
+ }
295
+ }
296
+ try {
297
+ const cached = parseCachedMetadata(readFileSync(cachedMetadataPath(model, modelCacheDir), "utf8"));
298
+ if (cached) {
299
+ metadataByCache.set(cacheKey, cached);
300
+ return cached;
301
+ }
302
+ } catch {}
303
+ if (testMetadataFallback) {
304
+ metadataByCache.set(cacheKey, testMetadataFallback);
305
+ return testMetadataFallback;
306
+ }
307
+ metadataByCache.set(cacheKey, UNRESOLVED_LOCAL_EMBEDDING_POOLING);
308
+ return UNRESOLVED_LOCAL_EMBEDDING_POOLING;
309
+ }
310
+ function logLocalEmbeddingPoolingDecisionOnce(model, metadata, logger = log2) {
311
+ const decisionKey = `${model}:${metadata.status}:${metadata.pooling ?? "none"}:${metadata.normalize}`;
312
+ if (decisionLogged.has(decisionKey))
313
+ return;
314
+ decisionLogged.add(decisionKey);
315
+ if (metadata.status === "unsupported") {
316
+ logger(`[magic-context] local embedding pooling for ${model} is unsupported: ${metadata.reason}`);
317
+ } else {
318
+ logger(`[magic-context] local embedding pooling for ${model}: ${metadata.pooling} pooling, normalization ${metadata.normalize ? "enabled" : "disabled"} (${metadata.reason})`);
319
+ }
320
+ }
321
+ function logUnavailableOnce(model, reason, logger) {
322
+ if (unavailableLogged.has(model))
323
+ return;
324
+ unavailableLogged.add(model);
325
+ logger(`[magic-context] local embedding pooling metadata for ${model} is not available: ${reason}; using legacy mean pooling and retrying during a later background bootstrap`);
326
+ }
327
+ function remoteHost() {
328
+ const configured = process.env.HF_ENDPOINT?.trim().replace(/\/+$/, "");
329
+ return configured || "https://huggingface.co";
330
+ }
331
+ function safeRepoId(repo) {
332
+ return repo.length > 0 && repo.split("/").every((part) => part && part !== "." && part !== "..");
333
+ }
334
+ function modelFileUrl(host, repo, file) {
335
+ const path = repo.split("/").map(encodeURIComponent).join("/");
336
+ const filePath = file.split("/").map(encodeURIComponent).join("/");
337
+ return `${host}/${path}/resolve/main/${filePath}`;
338
+ }
339
+ async function fetchModelFile(host, repo, file, fetcher) {
340
+ const response = await fetcher(modelFileUrl(host, repo, file));
341
+ if (response.status === 404)
342
+ return { kind: "missing" };
343
+ if (!response.ok)
344
+ throw new Error(`HTTP ${response.status} fetching ${repo}/${file}`);
345
+ return { kind: "found", text: await response.text() };
346
+ }
347
+ async function filesForRepo(host, repo, fetcher) {
348
+ const modules = await fetchModelFile(host, repo, "modules.json", fetcher);
349
+ if (modules.kind === "missing") {
350
+ const rootConfigResult = await fetchModelFile(host, repo, "config.json", fetcher);
351
+ if (rootConfigResult.kind === "missing") {
352
+ return {
353
+ modulesText: null,
354
+ configText: null,
355
+ configPath: null,
356
+ rootConfig: null,
357
+ rootModules: null
358
+ };
359
+ }
360
+ const rootConfigValue = parseJson(rootConfigResult.text, `${repo}/config.json`);
361
+ const origin = isRecord(rootConfigValue) && typeof rootConfigValue._name_or_path === "string" ? rootConfigValue._name_or_path.trim() : "";
362
+ if (!origin || origin === repo || !safeRepoId(origin)) {
363
+ return {
364
+ modulesText: null,
365
+ configText: null,
366
+ configPath: null,
367
+ rootConfig: rootConfigResult.text,
368
+ rootModules: null
369
+ };
370
+ }
371
+ const originModules = await fetchModelFile(host, origin, "modules.json", fetcher);
372
+ if (originModules.kind === "missing") {
373
+ return {
374
+ modulesText: null,
375
+ configText: null,
376
+ configPath: null,
377
+ rootConfig: rootConfigResult.text,
378
+ rootModules: null
379
+ };
380
+ }
381
+ const originModuleList = parseJson(originModules.text, `${origin}/modules.json`);
382
+ if (!Array.isArray(originModuleList)) {
383
+ return {
384
+ modulesText: originModules.text,
385
+ configText: null,
386
+ configPath: null,
387
+ rootConfig: rootConfigResult.text,
388
+ rootModules: originModules.text
389
+ };
390
+ }
391
+ const poolingModule = originModuleList.find(isPoolingModule);
392
+ const modulePath = poolingModule ? safeModulePath(poolingModule.path) : null;
393
+ if (!modulePath) {
394
+ return {
395
+ modulesText: originModules.text,
396
+ configText: null,
397
+ configPath: null,
398
+ rootConfig: rootConfigResult.text,
399
+ rootModules: originModules.text
400
+ };
401
+ }
402
+ const poolingConfig = await fetchModelFile(host, origin, `${modulePath}/config.json`, fetcher);
403
+ if (poolingConfig.kind === "missing") {
404
+ return {
405
+ modulesText: originModules.text,
406
+ configText: null,
407
+ configPath: `${origin}/${modulePath}/config.json`,
408
+ rootConfig: rootConfigResult.text,
409
+ rootModules: originModules.text
410
+ };
411
+ }
412
+ return {
413
+ modulesText: originModules.text,
414
+ configText: poolingConfig.text,
415
+ configPath: `${origin}/${modulePath}/config.json`,
416
+ rootConfig: rootConfigResult.text,
417
+ rootModules: originModules.text
418
+ };
419
+ }
420
+ const modulesValue = parseJson(modules.text, `${repo}/modules.json`);
421
+ if (!Array.isArray(modulesValue)) {
422
+ return {
423
+ modulesText: modules.text,
424
+ configText: null,
425
+ configPath: null,
426
+ rootConfig: null,
427
+ rootModules: modules.text
428
+ };
429
+ }
430
+ const poolingModule = modulesValue.find(isPoolingModule);
431
+ const modulePath = poolingModule ? safeModulePath(poolingModule.path) : null;
432
+ if (!modulePath) {
433
+ return {
434
+ modulesText: modules.text,
435
+ configText: null,
436
+ configPath: null,
437
+ rootConfig: null,
438
+ rootModules: modules.text
439
+ };
440
+ }
441
+ const poolingConfig = await fetchModelFile(host, repo, `${modulePath}/config.json`, fetcher);
442
+ return {
443
+ modulesText: modules.text,
444
+ configText: poolingConfig.kind === "found" ? poolingConfig.text : null,
445
+ configPath: `${repo}/${modulePath}/config.json`,
446
+ rootConfig: null,
447
+ rootModules: modules.text
448
+ };
449
+ }
450
+ async function cacheRemoteFiles(model, modelCacheDir, files) {
451
+ const root = metadataDirectory(model, modelCacheDir);
452
+ const writes = [];
453
+ if (files.rootConfig !== null)
454
+ writes.push(writeStorageFileAsync(join(root, "config.json"), files.rootConfig, true));
455
+ if (files.rootModules !== null)
456
+ writes.push(writeStorageFileAsync(join(root, "modules.json"), files.rootModules, true));
457
+ if (files.configText !== null && files.configPath !== null) {
458
+ const slash = files.configPath.indexOf("/");
459
+ const repo = files.configPath.slice(0, slash);
460
+ const relative = files.configPath.slice(slash + 1);
461
+ writes.push(writeStorageFileAsync(join(root, "source", repo, relative), files.configText, true));
462
+ }
463
+ await Promise.all(writes);
464
+ }
465
+ async function preflightLocalEmbeddingPooling(model, options = {}) {
466
+ const cacheDir = options.modelCacheDir ?? defaultModelCacheDir();
467
+ const logger = options.logger ?? log2;
468
+ const cacheKey = poolingMetadataCacheKey(model, cacheDir);
469
+ const cached = getCachedLocalEmbeddingPooling(model, cacheDir);
470
+ if (cached && cached.status !== "unresolved") {
471
+ logLocalEmbeddingPoolingDecisionOnce(model, cached, logger);
472
+ return cached;
473
+ }
474
+ if (isModelDirectory(model)) {
475
+ try {
476
+ const metadata = readDirectoryMetadata(model);
477
+ metadataByCache.set(cacheKey, metadata);
478
+ testMetadataByModel.delete(model);
479
+ logLocalEmbeddingPoolingDecisionOnce(model, metadata, logger);
480
+ return metadata;
481
+ } catch (error) {
482
+ const reason = error instanceof Error ? error.message : String(error);
483
+ const metadata = {
484
+ status: "unsupported",
485
+ normalize: false,
486
+ declared: true,
487
+ reason
488
+ };
489
+ metadataByCache.set(cacheKey, metadata);
490
+ testMetadataByModel.delete(model);
491
+ logLocalEmbeddingPoolingDecisionOnce(model, metadata, logger);
492
+ return metadata;
493
+ }
494
+ }
495
+ try {
496
+ const fetcher = options.fetcher ?? ((url) => fetch(url, { signal: AbortSignal.timeout(20000) }));
497
+ const files = await filesForRepo(remoteHost(), model, fetcher);
498
+ let metadata;
499
+ try {
500
+ metadata = poolingFromFiles(files.modulesText, files.configText, model);
501
+ } catch (error) {
502
+ metadata = {
503
+ status: "unsupported",
504
+ normalize: false,
505
+ declared: true,
506
+ reason: error instanceof Error ? error.message : String(error)
507
+ };
508
+ }
509
+ await cacheRemoteFiles(model, cacheDir, files);
510
+ await writeStorageFileAsync(cachedMetadataPath(model, cacheDir), JSON.stringify(metadata), true);
511
+ metadataByCache.set(cacheKey, metadata);
512
+ testMetadataByModel.delete(model);
513
+ logLocalEmbeddingPoolingDecisionOnce(model, metadata, logger);
514
+ return metadata;
515
+ } catch (error) {
516
+ const reason = error instanceof Error ? error.message : String(error);
517
+ metadataByCache.set(cacheKey, UNRESOLVED_LOCAL_EMBEDDING_POOLING);
518
+ testMetadataByModel.delete(model);
519
+ logUnavailableOnce(model, reason, logger);
520
+ return UNRESOLVED_LOCAL_EMBEDDING_POOLING;
521
+ }
522
+ }
523
+ function logLocalEmbeddingPoolingUnavailableOnce(model, reason, logger = log2) {
524
+ logUnavailableOnce(model, reason, logger);
525
+ }
526
+
101
527
  // ../plugin/src/features/magic-context/memory/embedding-identity.ts
102
528
  function normalizeEndpoint(endpoint) {
103
529
  return endpoint?.trim().replace(/\/+$/, "") ?? "";
@@ -119,6 +545,8 @@ function getEmbeddingProviderIdentity(config) {
119
545
  const truncate = config.provider === "openai-compatible" ? config.truncate?.trim() : undefined;
120
546
  const documentPrefix = config.provider === "openai-compatible" ? resolveEmbeddingTextPrefixes(config.model, config.query_instruction, config.document_prefix).documentPrefix : "";
121
547
  const localDtype = config.provider === "local" && config.local_dtype && config.local_dtype !== "fp32" ? config.local_dtype : undefined;
548
+ const localPooling = config.provider === "local" ? getCachedLocalEmbeddingPooling(config.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL) : null;
549
+ const localPoolingFingerprint = localPooling?.status === "ready" && (localPooling.pooling !== "mean" || !localPooling.normalize) ? `${localPooling.pooling};normalize=${localPooling.normalize}` : undefined;
122
550
  const identityInput = config.provider === "openai-compatible" ? {
123
551
  provider: "openai-compatible",
124
552
  model: config.model.trim(),
@@ -133,15 +561,16 @@ function getEmbeddingProviderIdentity(config) {
133
561
  endpoint: "",
134
562
  apiKeyPresent: false,
135
563
  runtimeFingerprint: LOCAL_EMBEDDING_RUNTIME_FINGERPRINT,
136
- ...localDtype ? { localDtype } : {}
564
+ ...localDtype ? { localDtype } : {},
565
+ ...localPoolingFingerprint ? { localPooling: localPoolingFingerprint } : {}
137
566
  };
138
567
  return `embedding-provider:${computeNormalizedHash(JSON.stringify(identityInput))}`;
139
568
  }
140
569
 
141
570
  // ../plugin/src/features/magic-context/memory/embedding-local.ts
142
- import { readdirSync, statSync } from "node:fs";
571
+ import { readdirSync, statSync as statSync2 } from "node:fs";
143
572
  import { stat, unlink } from "node:fs/promises";
144
- import { dirname, join } from "node:path";
573
+ import { dirname, join as join2 } from "node:path";
145
574
  import { pathToFileURL } from "node:url";
146
575
  import { workerData } from "node:worker_threads";
147
576
 
@@ -603,7 +1032,7 @@ var importTransformersNodeWasmFallbackForRuntime = async () => {
603
1032
  const nodeWasmEntry = new URL(new URL(import.meta.url).pathname.endsWith(".ts") ? "../../../../dist/transformers-node-wasm.js" : "./transformers-node-wasm.js", import.meta.url).href;
604
1033
  return await importPluginModule(() => import(nodeWasmEntry));
605
1034
  };
606
- var modelCacheDirForRuntime = () => workerData?.magicContextEmbeddingWorker && typeof workerData.modelCacheDir === "string" ? workerData.modelCacheDir : join(getMagicContextStorageDir(), "models");
1035
+ var modelCacheDirForRuntime = () => workerData?.magicContextEmbeddingWorker && typeof workerData.modelCacheDir === "string" ? workerData.modelCacheDir : join2(getMagicContextStorageDir(), "models");
607
1036
  var logForRuntime = log2;
608
1037
  var injectWasmOrtForRuntime = injectWasmOrt;
609
1038
  var loadedLocalEmbeddingRuntimes = new Map;
@@ -612,14 +1041,14 @@ function directoryBytes(path) {
612
1041
  let total = 0;
613
1042
  try {
614
1043
  for (const entry of readdirSync(path, { withFileTypes: true })) {
615
- const entryPath = join(path, entry.name);
1044
+ const entryPath = join2(path, entry.name);
616
1045
  if (entry.isDirectory()) {
617
1046
  const childBytes = directoryBytes(entryPath);
618
1047
  if (childBytes === null)
619
1048
  return null;
620
1049
  total += childBytes;
621
1050
  } else if (entry.isFile()) {
622
- total += statSync(entryPath).size;
1051
+ total += statSync2(entryPath).size;
623
1052
  }
624
1053
  }
625
1054
  return total;
@@ -845,6 +1274,7 @@ class LocalEmbeddingProvider {
845
1274
  dtype;
846
1275
  runtimePreference;
847
1276
  pipeline = null;
1277
+ poolingMetadata = null;
848
1278
  workerClient;
849
1279
  workerLoaded = false;
850
1280
  initPromise = null;
@@ -922,6 +1352,18 @@ class LocalEmbeddingProvider {
922
1352
  throw new LocalEmbeddingFsUnavailableError;
923
1353
  }
924
1354
  const modelCacheDir = modelCacheDirForRuntime();
1355
+ const cachedPoolingMetadata = getCachedLocalEmbeddingPooling(this.model, modelCacheDir);
1356
+ const poolingMetadata = cachedPoolingMetadata?.status === "unresolved" || !cachedPoolingMetadata ? UNRESOLVED_LOCAL_EMBEDDING_POOLING : cachedPoolingMetadata;
1357
+ if (poolingMetadata.status === "unsupported" || !poolingMetadata.pooling) {
1358
+ throw new Error(`unsupported pooling for local model '${this.model}': ${poolingMetadata.reason}`);
1359
+ }
1360
+ if (poolingMetadata.status === "unresolved") {
1361
+ logLocalEmbeddingPoolingUnavailableOnce(this.model, poolingMetadata.reason, logForRuntime);
1362
+ }
1363
+ this.poolingMetadata = poolingMetadata;
1364
+ if (!workerData?.magicContextEmbeddingWorker) {
1365
+ logLocalEmbeddingPoolingDecisionOnce(this.model, poolingMetadata, logForRuntime);
1366
+ }
925
1367
  try {
926
1368
  ensureStorageDirectorySync(modelCacheDir);
927
1369
  env.cacheDir = modelCacheDir;
@@ -929,7 +1371,7 @@ class LocalEmbeddingProvider {
929
1371
  log2("[magic-context] could not create model cache dir, using library default");
930
1372
  }
931
1373
  const createPipeline = transformersModule.pipeline;
932
- const lockPath = join(modelCacheDir, ".load.lock");
1374
+ const lockPath = join2(modelCacheDir, ".load.lock");
933
1375
  const releaseLock = await acquireModelLoadLock(lockPath);
934
1376
  const stopHeartbeat = startLockHeartbeat(lockPath);
935
1377
  try {
@@ -1036,8 +1478,8 @@ class LocalEmbeddingProvider {
1036
1478
  return null;
1037
1479
  }
1038
1480
  const result = await withQuietConsole(() => pipeline(text, {
1039
- pooling: "mean",
1040
- normalize: true
1481
+ pooling: this.poolingMetadata?.pooling ?? "mean",
1482
+ normalize: this.poolingMetadata?.normalize ?? true
1041
1483
  }));
1042
1484
  const embedding = extractBatchEmbeddings(result, 1)[0] ?? null;
1043
1485
  if (!embedding) {
@@ -1088,11 +1530,19 @@ class LocalEmbeddingProvider {
1088
1530
  if (!pipeline) {
1089
1531
  return Array.from({ length: texts.length }, () => null);
1090
1532
  }
1091
- const result = await withQuietConsole(() => pipeline(texts, {
1092
- pooling: "mean",
1093
- normalize: true
1094
- }));
1095
- const embeddings = extractBatchEmbeddings(result, texts.length);
1533
+ const pooling = this.poolingMetadata?.pooling ?? "mean";
1534
+ const normalize = this.poolingMetadata?.normalize ?? true;
1535
+ let embeddings;
1536
+ if (pooling === "last_token" && texts.length > 1) {
1537
+ embeddings = [];
1538
+ for (const text of texts) {
1539
+ const result = await withQuietConsole(() => pipeline(text, { pooling, normalize }));
1540
+ embeddings.push(extractBatchEmbeddings(result, 1)[0] ?? null);
1541
+ }
1542
+ } else {
1543
+ const result = await withQuietConsole(() => pipeline(texts, { pooling, normalize }));
1544
+ embeddings = extractBatchEmbeddings(result, texts.length);
1545
+ }
1096
1546
  if (embeddings.every((embedding) => embedding === null)) {
1097
1547
  this.lastFailureReason = classifyLocalEmbeddingFailure(new Error("local embedding pipeline returned no vectors"), { usesWasm: this.usesWasm });
1098
1548
  } else {
@@ -1168,4 +1618,4 @@ class LocalEmbeddingProvider {
1168
1618
  }
1169
1619
  }
1170
1620
 
1171
- export { embeddingModelsMatch, resolveEmbeddingTextPrefixes, getEmbeddingProviderIdentity, dominantEmbeddingFailure, resolveLocalEmbeddingWorkerRuntime, getLocalEmbeddingNativeMemoryStats, LocalEmbeddingProvider };
1621
+ export { embeddingModelsMatch, resolveEmbeddingTextPrefixes, getCachedLocalEmbeddingPooling, logLocalEmbeddingPoolingDecisionOnce, preflightLocalEmbeddingPooling, logLocalEmbeddingPoolingUnavailableOnce, getEmbeddingProviderIdentity, dominantEmbeddingFailure, resolveLocalEmbeddingWorkerRuntime, getLocalEmbeddingNativeMemoryStats, LocalEmbeddingProvider };
@@ -486,6 +486,7 @@ async function importPluginModule(load) {
486
486
 
487
487
  // ../plugin/src/shared/logger.ts
488
488
  var isTestEnv = false;
489
+ var syncLogWrites = process.env.MAGIC_CONTEXT_LOG_SYNC === "1";
489
490
  var buffer = [];
490
491
  var flushTimer = null;
491
492
  var FLUSH_INTERVAL_MS = 500;
@@ -630,6 +631,15 @@ function scheduleFlush() {
630
631
  flush();
631
632
  }, FLUSH_INTERVAL_MS);
632
633
  }
634
+ function appendLine(line) {
635
+ buffer.push(line);
636
+ bufferedBytes += Buffer.byteLength(line);
637
+ boundBuffer();
638
+ if (syncLogWrites || buffer.length >= BUFFER_SIZE_LIMIT)
639
+ flush();
640
+ else
641
+ scheduleFlush();
642
+ }
633
643
  var lineForwarder = null;
634
644
  function setLogLineForwarder2(forward) {
635
645
  lineForwarder = forward;
@@ -638,13 +648,7 @@ function writeForwardedLogLine2(line) {
638
648
  if (isTestEnv)
639
649
  return;
640
650
  try {
641
- buffer.push(line);
642
- bufferedBytes += Buffer.byteLength(line);
643
- boundBuffer();
644
- if (buffer.length >= BUFFER_SIZE_LIMIT)
645
- flush();
646
- else
647
- scheduleFlush();
651
+ appendLine(line);
648
652
  } catch {}
649
653
  }
650
654
  function log2(message, data) {
@@ -669,14 +673,7 @@ ${data.stack}` : ""}`)}` : ` ${JSON.stringify(sanitizeConfigValue(data))}`;
669
673
  lineForwarder(line);
670
674
  return;
671
675
  }
672
- buffer.push(line);
673
- bufferedBytes += Buffer.byteLength(line);
674
- boundBuffer();
675
- if (buffer.length >= BUFFER_SIZE_LIMIT) {
676
- flush();
677
- } else {
678
- scheduleFlush();
679
- }
676
+ appendLine(line);
680
677
  } catch {}
681
678
  }
682
679
  function sessionLog2(sessionId, message, data) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  log2
3
- } from "./index-7bqrfyny.js";
3
+ } from "./index-fgs78jyd.js";
4
4
 
5
5
  // ../plugin/src/shared/write-transaction-timing.ts
6
6
  var SLOW_WRITE_TRANSACTION_THRESHOLD_MS = 1000;
@@ -691,7 +691,7 @@ async function withAsyncPrivilegedWriter2(db, operation, options = {}) {
691
691
  } catch (error) {
692
692
  if (entered || !(error instanceof SqliteAcquisitionBusyError))
693
693
  throw error;
694
- options.beforeRetry?.(error);
694
+ await options.beforeRetry?.(error);
695
695
  const elapsed = performance.now() - started;
696
696
  if (elapsed >= budgetMs) {
697
697
  reportSqliteDiagnostic(`sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  log2
3
- } from "./index-7bqrfyny.js";
3
+ } from "./index-fgs78jyd.js";
4
4
 
5
5
  // ../plugin/src/shared/safe-notification-target.ts
6
6
  var DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;