gitnexus 1.6.10-rc.150 → 1.6.10-rc.151
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/_shared/index.d.ts +1 -1
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts +16 -0
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js +19 -7
- package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
- package/dist/core/embedding-checkpoint.d.ts +143 -0
- package/dist/core/embedding-checkpoint.js +221 -0
- package/dist/core/embedding-count.d.ts +61 -0
- package/dist/core/embedding-count.js +69 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +8 -0
- package/dist/core/embeddings/embedding-pipeline.js +253 -14
- package/dist/core/embeddings/http-client.js +126 -18
- package/dist/core/index-freshness.d.ts +1 -1
- package/dist/core/index-freshness.js +13 -2
- package/dist/core/run-analyze.js +227 -73
- package/dist/server/analyze-job.d.ts +37 -2
- package/dist/server/analyze-job.js +13 -2
- package/dist/server/analyze-launch.d.ts +1 -1
- package/dist/server/analyze-launch.js +4 -3
- package/dist/server/api.d.ts +0 -11
- package/dist/server/api.js +114 -115
- package/dist/server/embed-run-outcome.d.ts +89 -0
- package/dist/server/embed-run-outcome.js +88 -0
- package/dist/server/sse-progress.d.ts +41 -0
- package/dist/server/sse-progress.js +125 -0
- package/dist/storage/repo-manager.d.ts +40 -9
- package/package.json +1 -1
- package/web/assets/{index-BsB9kQ9C.js → index-N45yA6IV.js} +49 -49
- package/web/index.html +1 -1
package/dist/_shared/index.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ export { withRetry, computeBackoffMs } from './integrations/retry.js';
|
|
|
55
55
|
export type { RetryOptions, RetryDecision } from './integrations/retry.js';
|
|
56
56
|
export { CircuitBreaker, CircuitOpenError, getBreaker } from './integrations/circuit-breaker.js';
|
|
57
57
|
export type { CircuitBreakerOptions } from './integrations/circuit-breaker.js';
|
|
58
|
-
export { resilientFetch, ResilientFetchExhaustedError, RETRY_AFTER_CAP_MS, parseRetryAfter, } from './integrations/resilient-fetch.js';
|
|
58
|
+
export { resilientFetch, ResilientFetchExhaustedError, RETRY_AFTER_CAP_MS, parseRetryAfter, isTerminalNetworkError, } from './integrations/resilient-fetch.js';
|
|
59
59
|
export type { ResilientFetchOptions } from './integrations/resilient-fetch.js';
|
|
60
60
|
export { UNDERSTAND_QUICKLY_DISPATCH_URL, UNDERSTAND_QUICKLY_EVENT_TYPE, UNDERSTAND_QUICKLY_TOKEN_ENV, buildUqDispatchPayload, isValidOwnerRepo, parseOwnerRepoFromRemote, stripGitSuffix, } from './integrations/understand-quickly.js';
|
|
61
61
|
export type { UqDispatchPayload } from './integrations/understand-quickly.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/_shared/index.js
CHANGED
|
@@ -40,7 +40,7 @@ export { buildPositionIndex } from './scope-resolution/position-index.js';
|
|
|
40
40
|
// NOT add them here. Production consumers must not call them.
|
|
41
41
|
export { withRetry, computeBackoffMs } from './integrations/retry.js';
|
|
42
42
|
export { CircuitBreaker, CircuitOpenError, getBreaker } from './integrations/circuit-breaker.js';
|
|
43
|
-
export { resilientFetch, ResilientFetchExhaustedError, RETRY_AFTER_CAP_MS, parseRetryAfter, } from './integrations/resilient-fetch.js';
|
|
43
|
+
export { resilientFetch, ResilientFetchExhaustedError, RETRY_AFTER_CAP_MS, parseRetryAfter, isTerminalNetworkError, } from './integrations/resilient-fetch.js';
|
|
44
44
|
// Understand-Quickly registry integration (opt-in)
|
|
45
45
|
export { UNDERSTAND_QUICKLY_DISPATCH_URL, UNDERSTAND_QUICKLY_EVENT_TYPE, UNDERSTAND_QUICKLY_TOKEN_ENV, buildUqDispatchPayload, isValidOwnerRepo, parseOwnerRepoFromRemote, stripGitSuffix, } from './integrations/understand-quickly.js';
|
|
46
46
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAiCjC,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AAGvD,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAGrF,gEAAgE;AAChE,yEAAyE;AACzE,2DAA2D;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AA4BxE,oFAAoF;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAMvF,uEAAuE;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAUpE,sEAAsE;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AAKvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAKrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAEpG,OAAO,EACL,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,GACZ,MAAM,0CAA0C,CAAC;AAUlD,2EAA2E;AAC3E,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAErF,OAAO,EACL,cAAc,EACd,cAAc,EACd,uBAAuB,GACxB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAG1E,8EAA8E;AAC9E,wEAAwE;AACxE,wEAAwE;AACxE,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAEjG,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,kBAAkB,EAClB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAiCjC,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AAGvD,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAGrF,gEAAgE;AAChE,yEAAyE;AACzE,2DAA2D;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AA4BxE,oFAAoF;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAMvF,uEAAuE;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAUpE,sEAAsE;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AAKvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAKrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAEpG,OAAO,EACL,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,GACZ,MAAM,0CAA0C,CAAC;AAUlD,2EAA2E;AAC3E,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAErF,OAAO,EACL,cAAc,EACd,cAAc,EACd,uBAAuB,GACxB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAG1E,8EAA8E;AAC9E,wEAAwE;AACxE,wEAAwE;AACxE,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAEjG,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,kBAAkB,EAClB,eAAe,EACf,sBAAsB,GACvB,MAAM,mCAAmC,CAAC;AAG3C,mDAAmD;AACnD,OAAO,EACL,+BAA+B,EAC/B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,GACf,MAAM,sCAAsC,CAAC"}
|
|
@@ -59,6 +59,22 @@ type Outcome = {
|
|
|
59
59
|
kind: 'retryable-network';
|
|
60
60
|
err: unknown;
|
|
61
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* The network errors `resilientFetch` treats as terminal — never retried, and
|
|
64
|
+
* routed through the breaker's neutral path.
|
|
65
|
+
*
|
|
66
|
+
* Both timer-fired aborts (`AbortSignal.timeout()` → `TimeoutError`) and
|
|
67
|
+
* caller-driven aborts (`AbortController.abort()` → `AbortError`) qualify:
|
|
68
|
+
* retrying against an already-aborted signal would fail again immediately, and
|
|
69
|
+
* neither outcome reflects backend health.
|
|
70
|
+
*
|
|
71
|
+
* Exported because callers that hook into the retry loop (a `fetchImpl` that
|
|
72
|
+
* inspects or re-wraps its own throws) have to agree with {@link
|
|
73
|
+
* classifyOutcome} about which errors are terminal. Sharing this predicate is
|
|
74
|
+
* what makes that agreement structural instead of a hand-copied condition that
|
|
75
|
+
* can drift.
|
|
76
|
+
*/
|
|
77
|
+
export declare function isTerminalNetworkError(err: unknown): err is DOMException;
|
|
62
78
|
/** Exported for unit tests. */
|
|
63
79
|
export declare function classifyOutcome(result: {
|
|
64
80
|
kind: 'error';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resilient-fetch.d.ts","sourceRoot":"","sources":["../../src/integrations/resilient-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,cAAc,EACd,gBAAgB,EAEhB,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,kEAAkE;IAClE,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC,GAAG;QAClF,gFAAgF;QAChF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;KACjC,CAAC;IACF,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAQzC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,GAAE,MAAM,MAAiB,GAAG,MAAM,GAAG,IAAI,CAejG;AAED,wEAAwE;AACxE,KAAK,OAAO,GACR;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhD,+BAA+B;AAC/B,wBAAgB,eAAe,CAC7B,MAAM,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,EAC9E,GAAG,EAAE,MAAM,MAAM,EACjB,eAAe,SAAqB,GACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"resilient-fetch.d.ts","sourceRoot":"","sources":["../../src/integrations/resilient-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,cAAc,EACd,gBAAgB,EAEhB,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,kEAAkE;IAClE,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC,GAAG;QAClF,gFAAgF;QAChF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;KACjC,CAAC;IACF,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAQzC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,GAAE,MAAM,MAAiB,GAAG,MAAM,GAAG,IAAI,CAejG;AAED,wEAAwE;AACxE,KAAK,OAAO,GACR;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY,CAExE;AAED,+BAA+B;AAC/B,wBAAgB,eAAe,CAC7B,MAAM,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,EAC9E,GAAG,EAAE,MAAM,MAAM,EACjB,eAAe,SAAqB,GACnC,OAAO,CAyBT;AAcD,oEAAoE;AACpE,qBAAa,4BAA6B,SAAQ,KAAK;aAEzB,QAAQ,EAAE,QAAQ;IAD9C,SAAkB,IAAI,kCAAkC;gBAC5B,QAAQ,EAAE,QAAQ;CAG/C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,GAAG,GAAG,EACnB,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,QAAQ,CAAC,CA+GnB"}
|
|
@@ -40,16 +40,28 @@ export function parseRetryAfter(value, now = Date.now) {
|
|
|
40
40
|
const delta = target - now();
|
|
41
41
|
return delta >= 0 ? delta : 0;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* The network errors `resilientFetch` treats as terminal — never retried, and
|
|
45
|
+
* routed through the breaker's neutral path.
|
|
46
|
+
*
|
|
47
|
+
* Both timer-fired aborts (`AbortSignal.timeout()` → `TimeoutError`) and
|
|
48
|
+
* caller-driven aborts (`AbortController.abort()` → `AbortError`) qualify:
|
|
49
|
+
* retrying against an already-aborted signal would fail again immediately, and
|
|
50
|
+
* neither outcome reflects backend health.
|
|
51
|
+
*
|
|
52
|
+
* Exported because callers that hook into the retry loop (a `fetchImpl` that
|
|
53
|
+
* inspects or re-wraps its own throws) have to agree with {@link
|
|
54
|
+
* classifyOutcome} about which errors are terminal. Sharing this predicate is
|
|
55
|
+
* what makes that agreement structural instead of a hand-copied condition that
|
|
56
|
+
* can drift.
|
|
57
|
+
*/
|
|
58
|
+
export function isTerminalNetworkError(err) {
|
|
59
|
+
return err instanceof DOMException && (err.name === 'TimeoutError' || err.name === 'AbortError');
|
|
60
|
+
}
|
|
43
61
|
/** Exported for unit tests. */
|
|
44
62
|
export function classifyOutcome(result, now, retryAfterCapMs = RETRY_AFTER_CAP_MS) {
|
|
45
63
|
if (result.kind === 'error') {
|
|
46
|
-
|
|
47
|
-
// and caller-driven aborts (`AbortController.abort()` → `AbortError`)
|
|
48
|
-
// are terminal: retrying against an already-aborted signal would
|
|
49
|
-
// fail again immediately, and neither outcome reflects backend
|
|
50
|
-
// health. They route through the breaker's neutral path.
|
|
51
|
-
if (result.err instanceof DOMException &&
|
|
52
|
-
(result.err.name === 'TimeoutError' || result.err.name === 'AbortError')) {
|
|
64
|
+
if (isTerminalNetworkError(result.err)) {
|
|
53
65
|
return { kind: 'terminal-network', err: result.err };
|
|
54
66
|
}
|
|
55
67
|
return { kind: 'retryable-network', err: result.err };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resilient-fetch.js","sourceRoot":"","sources":["../../src/integrations/resilient-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,gBAAgB,EAChB,UAAU,GAEX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAqB,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AA0B5B,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,MAAM,aAAa,GAAG;IACpB,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAoB,EAAE,MAAoB,IAAI,CAAC,GAAG;IAChF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAEhC,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACtD,OAAO,OAAO,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC;IAC7B,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAUD
|
|
1
|
+
{"version":3,"file":"resilient-fetch.js","sourceRoot":"","sources":["../../src/integrations/resilient-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single owner of `RepoMeta.embeddingCheckpoint` — how it is minted, and
|
|
3
|
+
* how a run decides what to do with one it finds.
|
|
4
|
+
*
|
|
5
|
+
* This module exists for the reason `embedding-count.ts` next door exists, and
|
|
6
|
+
* for a sharper one. A review of #2790 found that two hand-copied bodies of
|
|
7
|
+
* "measure the embedding count" had drifted inside a single change; the fix for
|
|
8
|
+
* that then created a SECOND pair of hand-copied publishers — of this record —
|
|
9
|
+
* and they had already drifted too: the CLI armed the attempt counter only
|
|
10
|
+
* after clearing its identity gate, the server derived it from the resumed
|
|
11
|
+
* marker alone. Worse, only one of the two READERS implemented `kind` at all,
|
|
12
|
+
* so a `'partial'` marker written by `gitnexus analyze` and resumed through
|
|
13
|
+
* `POST /api/embed` hit exactly the permanent wedge `kind` was introduced to
|
|
14
|
+
* remove. Prose promising two sites stay in step is not a mechanism. This is.
|
|
15
|
+
*
|
|
16
|
+
* Same tier as {@link ./embedding-count.ts} and {@link ./embedding-mode.ts}:
|
|
17
|
+
* type-only imports, no native dependencies, so `run-analyze.ts` can import it
|
|
18
|
+
* statically without dragging an embeddings module in (#2370) and `server/`
|
|
19
|
+
* can import it too.
|
|
20
|
+
*/
|
|
21
|
+
import type { RepoMeta } from '../storage/repo-manager.js';
|
|
22
|
+
export type EmbeddingCheckpoint = NonNullable<RepoMeta['embeddingCheckpoint']>;
|
|
23
|
+
export type EmbeddingCheckpointKind = NonNullable<EmbeddingCheckpoint['kind']>;
|
|
24
|
+
export interface EmbeddingRunIdentity {
|
|
25
|
+
model: string;
|
|
26
|
+
dimensions: number;
|
|
27
|
+
provider: string;
|
|
28
|
+
}
|
|
29
|
+
export interface EmbeddingCheckpointProgress {
|
|
30
|
+
nodesProcessed: number;
|
|
31
|
+
totalNodes: number;
|
|
32
|
+
chunksProcessed: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* How many consecutive resume attempts may fail to clear a `'partial'` pending
|
|
36
|
+
* set before it is abandoned.
|
|
37
|
+
*
|
|
38
|
+
* Not a fresh guess: it is this repo's existing per-operation retry budget —
|
|
39
|
+
* the HTTP embedder spends `HTTP_MAX_RETRIES + 1 === 3` per request and the WAL
|
|
40
|
+
* driver `CHECKPOINT_RETRY_ATTEMPTS === 3` per flush. Each attempt here is a
|
|
41
|
+
* whole analyze invocation with those budgets nested underneath, so 3 is
|
|
42
|
+
* already generous while still converging within a day of ordinary committing.
|
|
43
|
+
*/
|
|
44
|
+
export declare const EMBEDDING_RESUME_MAX_ATTEMPTS = 3;
|
|
45
|
+
/**
|
|
46
|
+
* The one home for the back-compat default. Markers written before #2790's
|
|
47
|
+
* follow-up carry no `kind`, and they must keep the stricter behavior — an
|
|
48
|
+
* implicit default scattered across read sites is precisely how the two
|
|
49
|
+
* readers came to disagree.
|
|
50
|
+
*/
|
|
51
|
+
export declare const checkpointKind: (checkpoint: EmbeddingCheckpoint) => EmbeddingCheckpointKind;
|
|
52
|
+
/** Pending-node count, tolerating the field's optionality. */
|
|
53
|
+
export declare const pendingNodeCount: (checkpoint: EmbeddingCheckpoint) => number;
|
|
54
|
+
/**
|
|
55
|
+
* The attempt-chain rule, which is the subtlest thing here and was the part
|
|
56
|
+
* that had already diverged.
|
|
57
|
+
*
|
|
58
|
+
* The counter advances only when this run resumed a `'partial'` marker AND at
|
|
59
|
+
* least one node it was handed failed AGAIN. A resume that cleared its set but
|
|
60
|
+
* lost *different* nodes is a FRESH partial, so the budget resets — otherwise a
|
|
61
|
+
* steadily-flaky endpoint would exhaust the budget on nodes that were never the
|
|
62
|
+
* problem. `undefined` rather than `0` when the streak breaks, so a clean
|
|
63
|
+
* marker serializes without the field.
|
|
64
|
+
*/
|
|
65
|
+
export declare const nextAttemptCount: (resumedFrom: EmbeddingCheckpoint | undefined, failedNodeIds: readonly string[]) => number | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Mint the marker written BEFORE a bounded write window opens.
|
|
68
|
+
*
|
|
69
|
+
* `'interrupted'`: if the process dies inside the window these nodes may hold a
|
|
70
|
+
* subset of their chunks, which is what forces resume to delete and regenerate
|
|
71
|
+
* them even when a persisted row carries the current content hash — and what
|
|
72
|
+
* makes an identity mismatch fail closed rather than mix vector spaces. No
|
|
73
|
+
* `attempts`: the retry bound belongs to `'partial'`, whose pending set
|
|
74
|
+
* provably holds zero rows and can therefore be abandoned safely.
|
|
75
|
+
*/
|
|
76
|
+
export declare const mintInterruptedCheckpoint: (identity: EmbeddingRunIdentity, progress: EmbeddingCheckpointProgress, pendingNodeIds: string[], at?: string) => EmbeddingCheckpoint;
|
|
77
|
+
/**
|
|
78
|
+
* Mint the marker written AFTER a run that completed while dropping nodes.
|
|
79
|
+
*
|
|
80
|
+
* `totalNodes` is reconstructed as complete + dropped, because `nodesProcessed`
|
|
81
|
+
* counts only the nodes that finished with a full row set. It feeds the resume
|
|
82
|
+
* log line and nothing else.
|
|
83
|
+
*/
|
|
84
|
+
export declare const mintPartialCheckpoint: (identity: EmbeddingRunIdentity, result: {
|
|
85
|
+
nodesProcessed: number;
|
|
86
|
+
chunksProcessed: number;
|
|
87
|
+
failedNodeIds: string[];
|
|
88
|
+
}, resumedFrom: EmbeddingCheckpoint | undefined, at?: string) => EmbeddingCheckpoint;
|
|
89
|
+
/**
|
|
90
|
+
* Mint the marker written when a run finished but its embedding count could not
|
|
91
|
+
* be verified.
|
|
92
|
+
*
|
|
93
|
+
* A third state, and it needs its own `kind` rather than borrowing `'partial'`:
|
|
94
|
+
* its pending set is EMPTY. Nothing was dropped and nothing needs re-embedding
|
|
95
|
+
* — the marker exists only to defeat the same-commit fast return so the next
|
|
96
|
+
* run re-derives a count, because clearing it while `stats.embeddings` still
|
|
97
|
+
* reads a stale zero is what arms a later `--force` to wipe live embeddings.
|
|
98
|
+
* Stamping it `'partial'` made `gitnexus status` tell the operator that N nodes
|
|
99
|
+
* had lost their embeddings, where N is zero.
|
|
100
|
+
*/
|
|
101
|
+
export declare const mintUnverifiedCountCheckpoint: (identity: EmbeddingRunIdentity, progress: EmbeddingCheckpointProgress, at?: string) => EmbeddingCheckpoint;
|
|
102
|
+
export type EmbeddingResumeDecision =
|
|
103
|
+
/** An explicit flag cleared it; nothing to resume. */
|
|
104
|
+
{
|
|
105
|
+
readonly action: 'discard';
|
|
106
|
+
readonly log: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Keep running, but abandon the pending set — either the retry budget is
|
|
110
|
+
* spent, or the marker was written by a different embedding identity whose
|
|
111
|
+
* nodes provably hold zero rows so nothing is at risk.
|
|
112
|
+
*/
|
|
113
|
+
| {
|
|
114
|
+
readonly action: 'abandon';
|
|
115
|
+
readonly log: string;
|
|
116
|
+
}
|
|
117
|
+
/** Resume: regenerate `pendingNodeIds` under the matching identity. */
|
|
118
|
+
| {
|
|
119
|
+
readonly action: 'resume';
|
|
120
|
+
readonly log: string;
|
|
121
|
+
readonly pendingNodeIds: ReadonlySet<string>;
|
|
122
|
+
readonly resumedFrom: EmbeddingCheckpoint;
|
|
123
|
+
}
|
|
124
|
+
/** Fail closed: a half-written window under a foreign identity. */
|
|
125
|
+
| {
|
|
126
|
+
readonly action: 'abort';
|
|
127
|
+
readonly error: string;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* The one implementation of "what should this run do with the checkpoint it
|
|
131
|
+
* found", shared by the CLI resume gate and `POST /api/embed`.
|
|
132
|
+
*
|
|
133
|
+
* Callers resolve the embedding identity lazily and pass it only when they need
|
|
134
|
+
* a verdict beyond the flag checks — resolving it is not free, and the flag
|
|
135
|
+
* paths short-circuit before it is needed. Pass `identity: undefined` to get
|
|
136
|
+
* just those; a decision that requires an identity returns `'resume'` only when
|
|
137
|
+
* one was supplied and matched.
|
|
138
|
+
*/
|
|
139
|
+
export declare const decideEmbeddingResume: (checkpoint: EmbeddingCheckpoint, identity: EmbeddingRunIdentity | undefined, options?: {
|
|
140
|
+
force?: boolean;
|
|
141
|
+
dropEmbeddings?: boolean;
|
|
142
|
+
maxAttempts?: number;
|
|
143
|
+
}) => EmbeddingResumeDecision;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single owner of `RepoMeta.embeddingCheckpoint` — how it is minted, and
|
|
3
|
+
* how a run decides what to do with one it finds.
|
|
4
|
+
*
|
|
5
|
+
* This module exists for the reason `embedding-count.ts` next door exists, and
|
|
6
|
+
* for a sharper one. A review of #2790 found that two hand-copied bodies of
|
|
7
|
+
* "measure the embedding count" had drifted inside a single change; the fix for
|
|
8
|
+
* that then created a SECOND pair of hand-copied publishers — of this record —
|
|
9
|
+
* and they had already drifted too: the CLI armed the attempt counter only
|
|
10
|
+
* after clearing its identity gate, the server derived it from the resumed
|
|
11
|
+
* marker alone. Worse, only one of the two READERS implemented `kind` at all,
|
|
12
|
+
* so a `'partial'` marker written by `gitnexus analyze` and resumed through
|
|
13
|
+
* `POST /api/embed` hit exactly the permanent wedge `kind` was introduced to
|
|
14
|
+
* remove. Prose promising two sites stay in step is not a mechanism. This is.
|
|
15
|
+
*
|
|
16
|
+
* Same tier as {@link ./embedding-count.ts} and {@link ./embedding-mode.ts}:
|
|
17
|
+
* type-only imports, no native dependencies, so `run-analyze.ts` can import it
|
|
18
|
+
* statically without dragging an embeddings module in (#2370) and `server/`
|
|
19
|
+
* can import it too.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* How many consecutive resume attempts may fail to clear a `'partial'` pending
|
|
23
|
+
* set before it is abandoned.
|
|
24
|
+
*
|
|
25
|
+
* Not a fresh guess: it is this repo's existing per-operation retry budget —
|
|
26
|
+
* the HTTP embedder spends `HTTP_MAX_RETRIES + 1 === 3` per request and the WAL
|
|
27
|
+
* driver `CHECKPOINT_RETRY_ATTEMPTS === 3` per flush. Each attempt here is a
|
|
28
|
+
* whole analyze invocation with those budgets nested underneath, so 3 is
|
|
29
|
+
* already generous while still converging within a day of ordinary committing.
|
|
30
|
+
*/
|
|
31
|
+
export const EMBEDDING_RESUME_MAX_ATTEMPTS = 3;
|
|
32
|
+
/**
|
|
33
|
+
* The one home for the back-compat default. Markers written before #2790's
|
|
34
|
+
* follow-up carry no `kind`, and they must keep the stricter behavior — an
|
|
35
|
+
* implicit default scattered across read sites is precisely how the two
|
|
36
|
+
* readers came to disagree.
|
|
37
|
+
*/
|
|
38
|
+
export const checkpointKind = (checkpoint) => checkpoint.kind ?? 'interrupted';
|
|
39
|
+
/** Pending-node count, tolerating the field's optionality. */
|
|
40
|
+
export const pendingNodeCount = (checkpoint) => checkpoint.pendingNodeIds?.length ?? 0;
|
|
41
|
+
/**
|
|
42
|
+
* The attempt-chain rule, which is the subtlest thing here and was the part
|
|
43
|
+
* that had already diverged.
|
|
44
|
+
*
|
|
45
|
+
* The counter advances only when this run resumed a `'partial'` marker AND at
|
|
46
|
+
* least one node it was handed failed AGAIN. A resume that cleared its set but
|
|
47
|
+
* lost *different* nodes is a FRESH partial, so the budget resets — otherwise a
|
|
48
|
+
* steadily-flaky endpoint would exhaust the budget on nodes that were never the
|
|
49
|
+
* problem. `undefined` rather than `0` when the streak breaks, so a clean
|
|
50
|
+
* marker serializes without the field.
|
|
51
|
+
*/
|
|
52
|
+
export const nextAttemptCount = (resumedFrom, failedNodeIds) => {
|
|
53
|
+
if (resumedFrom === undefined || checkpointKind(resumedFrom) !== 'partial')
|
|
54
|
+
return undefined;
|
|
55
|
+
const resumedPending = new Set(resumedFrom.pendingNodeIds ?? []);
|
|
56
|
+
const failedAgain = failedNodeIds.some((id) => resumedPending.has(id));
|
|
57
|
+
return failedAgain ? (resumedFrom.attempts ?? 0) + 1 : undefined;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Mint the marker written BEFORE a bounded write window opens.
|
|
61
|
+
*
|
|
62
|
+
* `'interrupted'`: if the process dies inside the window these nodes may hold a
|
|
63
|
+
* subset of their chunks, which is what forces resume to delete and regenerate
|
|
64
|
+
* them even when a persisted row carries the current content hash — and what
|
|
65
|
+
* makes an identity mismatch fail closed rather than mix vector spaces. No
|
|
66
|
+
* `attempts`: the retry bound belongs to `'partial'`, whose pending set
|
|
67
|
+
* provably holds zero rows and can therefore be abandoned safely.
|
|
68
|
+
*/
|
|
69
|
+
export const mintInterruptedCheckpoint = (identity, progress, pendingNodeIds, at = new Date().toISOString()) => ({
|
|
70
|
+
at,
|
|
71
|
+
...progress,
|
|
72
|
+
model: identity.model,
|
|
73
|
+
dimensions: identity.dimensions,
|
|
74
|
+
provider: identity.provider,
|
|
75
|
+
kind: 'interrupted',
|
|
76
|
+
pendingNodeIds,
|
|
77
|
+
});
|
|
78
|
+
/**
|
|
79
|
+
* Mint the marker written AFTER a run that completed while dropping nodes.
|
|
80
|
+
*
|
|
81
|
+
* `totalNodes` is reconstructed as complete + dropped, because `nodesProcessed`
|
|
82
|
+
* counts only the nodes that finished with a full row set. It feeds the resume
|
|
83
|
+
* log line and nothing else.
|
|
84
|
+
*/
|
|
85
|
+
export const mintPartialCheckpoint = (identity, result, resumedFrom, at = new Date().toISOString()) => ({
|
|
86
|
+
at,
|
|
87
|
+
nodesProcessed: result.nodesProcessed,
|
|
88
|
+
totalNodes: result.nodesProcessed + result.failedNodeIds.length,
|
|
89
|
+
chunksProcessed: result.chunksProcessed,
|
|
90
|
+
model: identity.model,
|
|
91
|
+
dimensions: identity.dimensions,
|
|
92
|
+
provider: identity.provider,
|
|
93
|
+
kind: 'partial',
|
|
94
|
+
attempts: nextAttemptCount(resumedFrom, result.failedNodeIds),
|
|
95
|
+
pendingNodeIds: result.failedNodeIds,
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* Mint the marker written when a run finished but its embedding count could not
|
|
99
|
+
* be verified.
|
|
100
|
+
*
|
|
101
|
+
* A third state, and it needs its own `kind` rather than borrowing `'partial'`:
|
|
102
|
+
* its pending set is EMPTY. Nothing was dropped and nothing needs re-embedding
|
|
103
|
+
* — the marker exists only to defeat the same-commit fast return so the next
|
|
104
|
+
* run re-derives a count, because clearing it while `stats.embeddings` still
|
|
105
|
+
* reads a stale zero is what arms a later `--force` to wipe live embeddings.
|
|
106
|
+
* Stamping it `'partial'` made `gitnexus status` tell the operator that N nodes
|
|
107
|
+
* had lost their embeddings, where N is zero.
|
|
108
|
+
*/
|
|
109
|
+
export const mintUnverifiedCountCheckpoint = (identity, progress, at = new Date().toISOString()) => ({
|
|
110
|
+
at,
|
|
111
|
+
...progress,
|
|
112
|
+
model: identity.model,
|
|
113
|
+
dimensions: identity.dimensions,
|
|
114
|
+
provider: identity.provider,
|
|
115
|
+
kind: 'unverified-count',
|
|
116
|
+
pendingNodeIds: [],
|
|
117
|
+
});
|
|
118
|
+
/**
|
|
119
|
+
* The one implementation of "what should this run do with the checkpoint it
|
|
120
|
+
* found", shared by the CLI resume gate and `POST /api/embed`.
|
|
121
|
+
*
|
|
122
|
+
* Callers resolve the embedding identity lazily and pass it only when they need
|
|
123
|
+
* a verdict beyond the flag checks — resolving it is not free, and the flag
|
|
124
|
+
* paths short-circuit before it is needed. Pass `identity: undefined` to get
|
|
125
|
+
* just those; a decision that requires an identity returns `'resume'` only when
|
|
126
|
+
* one was supplied and matched.
|
|
127
|
+
*/
|
|
128
|
+
export const decideEmbeddingResume = (checkpoint, identity, options = {}) => {
|
|
129
|
+
const kind = checkpointKind(checkpoint);
|
|
130
|
+
const pending = pendingNodeCount(checkpoint);
|
|
131
|
+
const maxAttempts = options.maxAttempts ?? EMBEDDING_RESUME_MAX_ATTEMPTS;
|
|
132
|
+
if (options.dropEmbeddings) {
|
|
133
|
+
return { action: 'discard', log: 'Discarding the embedding checkpoint (--drop-embeddings).' };
|
|
134
|
+
}
|
|
135
|
+
if (options.force) {
|
|
136
|
+
return {
|
|
137
|
+
action: 'discard',
|
|
138
|
+
log: 'Discarding the embedding checkpoint (--force)' +
|
|
139
|
+
`${pending > 0 ? ` and its ${pending} pending node(s)` : ''}; this run rebuilds from ` +
|
|
140
|
+
'scratch. Pass --embeddings to regenerate them explicitly.',
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Only the 'unverified-count' marker may skip the identity gate. Its pending
|
|
144
|
+
// set is empty BY DEFINITION and it exists purely to force a fresh count, so
|
|
145
|
+
// there is nothing a foreign embedding identity could corrupt.
|
|
146
|
+
//
|
|
147
|
+
// An empty pending set alone must NOT take this path. `onCheckpoint` mints an
|
|
148
|
+
// 'interrupted' marker with `pendingNodeIds: []` after every post-window
|
|
149
|
+
// save, and legacy markers may omit the field entirely — so keying on
|
|
150
|
+
// emptiness would silently clear an interrupted marker under a foreign
|
|
151
|
+
// provider instead of failing closed, which is exactly the vector-space
|
|
152
|
+
// mixing the 'interrupted' kind exists to prevent.
|
|
153
|
+
if (kind === 'unverified-count') {
|
|
154
|
+
return {
|
|
155
|
+
action: 'abandon',
|
|
156
|
+
log: 'Re-deriving the embedding count left unverified by the previous run.',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (kind === 'partial' && (checkpoint.attempts ?? 0) >= maxAttempts) {
|
|
160
|
+
return {
|
|
161
|
+
action: 'abandon',
|
|
162
|
+
log: `Warning: ${pending} node(s) failed to embed on ${checkpoint.attempts} consecutive ` +
|
|
163
|
+
'resume attempts and are being abandoned (#2790). The index is registered without ' +
|
|
164
|
+
'them; `gitnexus status` stops reporting it as incomplete. Re-run ' +
|
|
165
|
+
'`gitnexus analyze --embeddings --force` once the embedding endpoint accepts them.',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (identity === undefined) {
|
|
169
|
+
return {
|
|
170
|
+
action: 'abort',
|
|
171
|
+
error: 'Cannot resume embedding checkpoint: no embedding identity was resolved.',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const providerDiffers = checkpoint.provider !== identity.provider;
|
|
175
|
+
const identityDiffers = providerDiffers ||
|
|
176
|
+
checkpoint.model !== identity.model ||
|
|
177
|
+
checkpoint.dimensions !== identity.dimensions;
|
|
178
|
+
if (identityDiffers && kind !== 'interrupted') {
|
|
179
|
+
// Those nodes hold zero rows, so there is no vector space to mix. Throwing
|
|
180
|
+
// here is what turned an exit-0 partial run into a permanent wedge: a hook
|
|
181
|
+
// or CI job without the endpoint's env vars resolves `provider: 'local'`,
|
|
182
|
+
// mismatches, and dies before any phase runs.
|
|
183
|
+
return {
|
|
184
|
+
action: 'abandon',
|
|
185
|
+
log: `Warning: dropping ${pending} pending node(s) from a ${kind} embedding checkpoint: it ` +
|
|
186
|
+
`was written by a different embedding configuration (${checkpoint.model} at ` +
|
|
187
|
+
`${checkpoint.dimensions} dimensions) than this run resolves (${identity.model} at ` +
|
|
188
|
+
`${identity.dimensions}). Those nodes hold no embedding rows, so nothing is lost that ` +
|
|
189
|
+
'a later `--embeddings` run cannot regenerate.',
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (providerDiffers) {
|
|
193
|
+
return {
|
|
194
|
+
action: 'abort',
|
|
195
|
+
error: 'Cannot resume embedding checkpoint: the embedding provider configuration differs. ' +
|
|
196
|
+
'Restore the matching endpoint configuration or pass --drop-embeddings to rebuild without it.',
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
if (identityDiffers) {
|
|
200
|
+
return {
|
|
201
|
+
action: 'abort',
|
|
202
|
+
error: `Cannot resume embedding checkpoint: it uses ${checkpoint.model} at ` +
|
|
203
|
+
`${checkpoint.dimensions} dimensions, but this run resolves ${identity.model} at ` +
|
|
204
|
+
`${identity.dimensions}. Restore the matching embedding configuration or pass ` +
|
|
205
|
+
'--drop-embeddings to rebuild without it.',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// Reached with an EMPTY pending set too — an 'interrupted' marker written by
|
|
209
|
+
// a post-window save names none. That still resumes rather than clearing:
|
|
210
|
+
// the marker's presence is what forces embedding generation on a run that
|
|
211
|
+
// would otherwise derive `shouldGenerateEmbeddings: false`, and it has now
|
|
212
|
+
// cleared the identity gate, so resuming is safe.
|
|
213
|
+
return {
|
|
214
|
+
action: 'resume',
|
|
215
|
+
log: `Previous analyze ended at an embedding checkpoint (${checkpoint.nodesProcessed}/` +
|
|
216
|
+
`${checkpoint.totalNodes} nodes); resuming from persisted hashes` +
|
|
217
|
+
`${pending > 0 ? ` and regenerating ${pending} pending node(s)` : ''}.`,
|
|
218
|
+
pendingNodeIds: new Set(checkpoint.pendingNodeIds ?? []),
|
|
219
|
+
resumedFrom: checkpoint,
|
|
220
|
+
};
|
|
221
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single implementation of "how many embedding rows are actually persisted".
|
|
3
|
+
*
|
|
4
|
+
* Lives in its own module — beside {@link ./embedding-mode.ts} and with the same
|
|
5
|
+
* no-native-imports property — because the CLI (`run-analyze.ts`) and the server
|
|
6
|
+
* (`server/api.ts`) both publish `RepoMeta.stats.embeddings`, and a review of
|
|
7
|
+
* #2790 found the two hand-copied bodies had already drifted inside a single
|
|
8
|
+
* change: one used `?? Number.NaN`, the other `?? 0`, under a comment asserting
|
|
9
|
+
* they measured the field "the same way". Two publishers of one field must not
|
|
10
|
+
* be able to disagree, so there is now one function and three call sites.
|
|
11
|
+
*
|
|
12
|
+
* Keeping it out of `core/embeddings/` is deliberate: `run-analyze.ts` may only
|
|
13
|
+
* reach embedding modules through `await import(...)` (#2370 — no embeddings
|
|
14
|
+
* module loads unless a run actually needs one), and this counter runs on the
|
|
15
|
+
* ordinary finalization path of every analyze.
|
|
16
|
+
*
|
|
17
|
+
* TRI-STATE, and the asymmetry is the whole point. `unknown` means COULD NOT
|
|
18
|
+
* ASK — the query throws for reasons that have nothing to do with how many rows
|
|
19
|
+
* were written (table missing, connection closed, DB busy or read-only, the
|
|
20
|
+
* VECTOR-extension DML lock #2623) — and a fabricated count is never returned in
|
|
21
|
+
* its place. A wrong-LOW value is the dangerous direction: `stats.embeddings` is
|
|
22
|
+
* the sole input to the next run's `existingEmbeddingCount` → `deriveEmbeddingMode`
|
|
23
|
+
* → `shouldLoadCache`, so a false `0` is exactly what makes a later `--force`
|
|
24
|
+
* wipe live embeddings without loading the cache.
|
|
25
|
+
*/
|
|
26
|
+
/** Callback shape both callers already satisfy with their `executeQuery`. */
|
|
27
|
+
export type EmbeddingCountQuery = (cypher: string) => Promise<Array<Record<string, unknown>> | undefined>;
|
|
28
|
+
export type PersistedEmbeddingCount = {
|
|
29
|
+
readonly kind: 'measured';
|
|
30
|
+
readonly count: number;
|
|
31
|
+
}
|
|
32
|
+
/** `reason` is operator-facing: each caller phrases its own warning around it. */
|
|
33
|
+
| {
|
|
34
|
+
readonly kind: 'unknown';
|
|
35
|
+
readonly reason: string;
|
|
36
|
+
};
|
|
37
|
+
export declare const EMBEDDING_COUNT_CYPHER = "MATCH (e:CodeEmbedding) RETURN count(e) AS cnt";
|
|
38
|
+
/**
|
|
39
|
+
* Count the persisted embedding rows, or report that the answer never arrived.
|
|
40
|
+
*
|
|
41
|
+
* A MISSING row or cell counts as unknown, NOT as zero: an empty table still
|
|
42
|
+
* answers with one row holding `0`, so no row / no cell means the query did not
|
|
43
|
+
* really answer. That distinction is what `?? Number.NaN` buys — with `?? 0`,
|
|
44
|
+
* `Number.isFinite(0)` is true and the unknown branch becomes unreachable for
|
|
45
|
+
* exactly the case it exists to catch.
|
|
46
|
+
*/
|
|
47
|
+
export declare const measurePersistedEmbeddingCount: (runQuery: EmbeddingCountQuery) => Promise<PersistedEmbeddingCount>;
|
|
48
|
+
/** `undefined` ≡ unknown, for the call sites that only need the optional number. */
|
|
49
|
+
export declare const persistedEmbeddingCountOrUndefined: (result: PersistedEmbeddingCount) => number | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Fold a measurement into the `RepoMeta.stats.embeddings` a run publishes.
|
|
52
|
+
*
|
|
53
|
+
* The measurement was already shared; this fold was not, and it is the half
|
|
54
|
+
* that decides what actually lands on disk — the CLI's finalization and the
|
|
55
|
+
* server's `withMeasuredEmbeddingCount` each carried their own copy of the same
|
|
56
|
+
* two lines. NEVER a fabricated `0`: `unknown` carries `priorCount` forward
|
|
57
|
+
* (see this file's header for the chain a false zero arms), and `undefined` in
|
|
58
|
+
* means `undefined` out, so a repo that never had a count keeps the field
|
|
59
|
+
* absent rather than gaining an invented one.
|
|
60
|
+
*/
|
|
61
|
+
export declare const resolvePersistedEmbeddingCount: (measured: PersistedEmbeddingCount, priorCount: number | undefined) => number | undefined;
|