@cortexkit/opencode-magic-context 0.10.0 → 0.10.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.
@@ -1 +1 @@
1
- {"version":3,"file":"embedding-local.d.ts","sourceRoot":"","sources":["../../../../src/features/magic-context/memory/embedding-local.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAyH9D,qBAAa,sBAAuB,YAAW,iBAAiB;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAA8B;gBAErC,KAAK,SAAgC;IAK3C,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAqG9B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAyBjD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC;IA6B7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB9B,QAAQ,IAAI,OAAO;CAGtB"}
1
+ {"version":3,"file":"embedding-local.d.ts","sourceRoot":"","sources":["../../../../src/features/magic-context/memory/embedding-local.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAyN9D,qBAAa,sBAAuB,YAAW,iBAAiB;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAA8B;gBAErC,KAAK,SAAgC;IAK3C,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAoH9B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAyBjD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC;IA6B7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB9B,QAAQ,IAAI,OAAO;CAGtB"}
package/dist/index.js CHANGED
@@ -16165,7 +16165,57 @@ function cosineSimilarity(a, b) {
16165
16165
 
16166
16166
  // src/features/magic-context/memory/embedding-local.ts
16167
16167
  import { mkdirSync } from "fs";
16168
+ import { open, stat, unlink, writeFile } from "fs/promises";
16168
16169
  import { join as join9 } from "path";
16170
+ async function acquireModelLoadLock(lockPath) {
16171
+ const waitStart = Date.now();
16172
+ while (true) {
16173
+ try {
16174
+ const handle = await open(lockPath, "wx");
16175
+ try {
16176
+ await handle.writeFile(`pid=${process.pid} started=${Date.now()}
16177
+ `);
16178
+ } catch {}
16179
+ await handle.close();
16180
+ return async () => {
16181
+ try {
16182
+ await unlink(lockPath);
16183
+ } catch {}
16184
+ };
16185
+ } catch (error48) {
16186
+ const code = error48.code;
16187
+ if (code !== "EEXIST" && code !== "EPERM") {
16188
+ throw error48;
16189
+ }
16190
+ try {
16191
+ const info = await stat(lockPath);
16192
+ if (Date.now() - info.mtimeMs > STALE_LOCK_MS) {
16193
+ log(`[magic-context] embedding-load lock stale (>${STALE_LOCK_MS}ms), taking over`);
16194
+ try {
16195
+ await unlink(lockPath);
16196
+ } catch {}
16197
+ continue;
16198
+ }
16199
+ } catch {
16200
+ continue;
16201
+ }
16202
+ if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
16203
+ log("[magic-context] embedding-load lock wait exceeded, proceeding without lock");
16204
+ return async () => {};
16205
+ }
16206
+ await new Promise((resolve2) => setTimeout(resolve2, LOCK_POLL_MS));
16207
+ }
16208
+ }
16209
+ }
16210
+ function startLockHeartbeat(lockPath) {
16211
+ const HEARTBEAT_MS = Math.floor(STALE_LOCK_MS / 3);
16212
+ const timer = setInterval(() => {
16213
+ writeFile(lockPath, `pid=${process.pid} alive=${Date.now()}
16214
+ `).catch(() => {});
16215
+ }, HEARTBEAT_MS);
16216
+ timer.unref?.();
16217
+ return () => clearInterval(timer);
16218
+ }
16169
16219
  async function withQuietConsole(fn) {
16170
16220
  const origWarn = console.warn;
16171
16221
  const origError = console.error;
@@ -16258,30 +16308,37 @@ class LocalEmbeddingProvider {
16258
16308
  log("[magic-context] could not create model cache dir, using library default");
16259
16309
  }
16260
16310
  const createPipeline = transformersModule.pipeline;
16261
- const MAX_ATTEMPTS = 3;
16262
- let lastError;
16263
- for (let attempt = 1;attempt <= MAX_ATTEMPTS; attempt++) {
16264
- try {
16265
- this.pipeline = await withQuietConsole(() => createPipeline("feature-extraction", this.model, {
16266
- quantized: true,
16267
- dtype: "fp32"
16268
- }));
16269
- lastError = undefined;
16270
- break;
16271
- } catch (error48) {
16272
- lastError = error48;
16273
- if (!isTransientLoadError(error48) || attempt === MAX_ATTEMPTS) {
16311
+ const lockPath = join9(modelCacheDir, ".load.lock");
16312
+ const releaseLock = await acquireModelLoadLock(lockPath);
16313
+ const stopHeartbeat = startLockHeartbeat(lockPath);
16314
+ try {
16315
+ const MAX_ATTEMPTS = 3;
16316
+ let lastError;
16317
+ for (let attempt = 1;attempt <= MAX_ATTEMPTS; attempt++) {
16318
+ try {
16319
+ this.pipeline = await withQuietConsole(() => createPipeline("feature-extraction", this.model, {
16320
+ dtype: "fp32"
16321
+ }));
16322
+ lastError = undefined;
16274
16323
  break;
16324
+ } catch (error48) {
16325
+ lastError = error48;
16326
+ if (!isTransientLoadError(error48) || attempt === MAX_ATTEMPTS) {
16327
+ break;
16328
+ }
16329
+ const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
16330
+ log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
16331
+ await new Promise((resolve2) => setTimeout(resolve2, delayMs));
16275
16332
  }
16276
- const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
16277
- log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
16278
- await new Promise((resolve2) => setTimeout(resolve2, delayMs));
16279
16333
  }
16280
- }
16281
- if (this.pipeline) {
16282
- log(`[magic-context] embedding model loaded: ${this.model}`);
16283
- } else {
16284
- throw lastError ?? new Error("unknown embedding load failure");
16334
+ if (this.pipeline) {
16335
+ log(`[magic-context] embedding model loaded: ${this.model}`);
16336
+ } else {
16337
+ throw lastError ?? new Error("unknown embedding load failure");
16338
+ }
16339
+ } finally {
16340
+ stopHeartbeat();
16341
+ await releaseLock();
16285
16342
  }
16286
16343
  } catch (error48) {
16287
16344
  log("[magic-context] embedding model failed to load:", error48);
@@ -16356,10 +16413,13 @@ class LocalEmbeddingProvider {
16356
16413
  return this.pipeline !== null;
16357
16414
  }
16358
16415
  }
16416
+ var LOCK_POLL_MS = 150, STALE_LOCK_MS, MAX_LOCK_WAIT_MS;
16359
16417
  var init_embedding_local = __esm(() => {
16360
16418
  init_magic_context();
16361
16419
  init_data_path();
16362
16420
  init_logger();
16421
+ STALE_LOCK_MS = 3 * 60000;
16422
+ MAX_LOCK_WAIT_MS = 5 * 60000;
16363
16423
  });
16364
16424
 
16365
16425
  // src/features/magic-context/memory/embedding-openai.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@clack/prompts": "^1.1.0",
47
- "@huggingface/transformers": "~3.7.6",
47
+ "@huggingface/transformers": "^4.1.0",
48
48
  "@opencode-ai/plugin": "^1.2.26",
49
49
  "@opencode-ai/sdk": "^1.2.26",
50
50
  "ai-tokenizer": "^1.0.6",