code-graph-context 3.0.5 → 3.0.6

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.
@@ -128,7 +128,11 @@ export class EmbeddingSidecar {
128
128
  });
129
129
  this.process.on('exit', (code, signal) => {
130
130
  if (!this.stopping) {
131
- console.error(`[embedding-sidecar] Process exited unexpectedly (code=${code}, signal=${signal})`);
131
+ console.error(`[embedding-sidecar] Process exited unexpectedly (pid=${childPid}, code=${code}, signal=${signal}, ` +
132
+ `inflight=${this.inflight}, queued=${this.waitQueue.length})`);
133
+ }
134
+ else {
135
+ console.error(`[embedding-sidecar] Process stopped (pid=${childPid})`);
132
136
  }
133
137
  this.cleanup();
134
138
  });
@@ -322,6 +326,13 @@ export class EmbeddingSidecar {
322
326
  process.removeListener('exit', this._exitHandler);
323
327
  this._exitHandler = null;
324
328
  }
329
+ // Drain the wait queue — reject all queued callers so they don't hang forever
330
+ while (this.waitQueue.length > 0) {
331
+ const waiter = this.waitQueue.shift();
332
+ if (waiter)
333
+ waiter(); // unblock; they'll fail on the dead connection and can retry
334
+ }
335
+ this.inflight = 0;
325
336
  this.process = null;
326
337
  this.readyPromise = null;
327
338
  }
@@ -43,18 +43,38 @@ export class LocalEmbeddingsService {
43
43
  for (let i = 0; i < texts.length; i += httpLimit) {
44
44
  const batch = texts.slice(i, i + httpLimit);
45
45
  const batchNum = Math.floor(i / httpLimit) + 1;
46
- try {
47
- const results = await sidecar.embed(batch, gpuBatchSize);
46
+ let results;
47
+ let lastError;
48
+ // Retry once on transient failures (sidecar crash, connection refused)
49
+ for (let attempt = 0; attempt < 2; attempt++) {
50
+ try {
51
+ results = await sidecar.embed(batch, gpuBatchSize);
52
+ break;
53
+ }
54
+ catch (error) {
55
+ lastError = error instanceof Error ? error : new Error(String(error));
56
+ const isTransient = lastError.message.includes('ECONNREFUSED') ||
57
+ lastError.message.includes('ECONNRESET') ||
58
+ lastError.message.includes('timed out') ||
59
+ lastError.message.includes('fetch failed');
60
+ if (isTransient && attempt === 0) {
61
+ console.error(`[embedding] Transient failure on batch ${batchNum}/${httpBatches} (${lastError.message}), restarting sidecar and retrying...`);
62
+ await sidecar.stop();
63
+ await sidecar.start();
64
+ continue;
65
+ }
66
+ const textLengths = batch.map((t) => t.length);
67
+ console.error(`[embedding] FAILED HTTP batch ${batchNum}/${httpBatches} (${batch.length} texts, gpuBatchSize=${gpuBatchSize}, ` +
68
+ `textLengths=[min=${Math.min(...textLengths)}, max=${Math.max(...textLengths)}, total=${textLengths.reduce((a, b) => a + b, 0)}]): ${lastError.message}`);
69
+ throw lastError;
70
+ }
71
+ }
72
+ if (results) {
48
73
  allResults.push(...results);
49
74
  if (httpBatches > 1) {
50
75
  console.error(`[embedding] HTTP batch ${batchNum}/${httpBatches}: ${batch.length} texts embedded`);
51
76
  }
52
77
  }
53
- catch (error) {
54
- const msg = error instanceof Error ? error.message : String(error);
55
- console.error(`[embedding] FAILED HTTP batch ${batchNum}/${httpBatches} (${batch.length} texts, gpuBatchSize=${gpuBatchSize}): ${msg}`);
56
- throw error;
57
- }
58
78
  }
59
79
  return allResults;
60
80
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-graph-context",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "description": "MCP server that builds code graphs to provide rich context to LLMs",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/andrew-hernandez-paragon/code-graph-context#readme",