gitnexus 1.6.10-rc.2 → 1.6.10-rc.3
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/README.md +22 -0
- package/dist/cli/analyze.js +61 -2
- package/dist/cli/cli-message.d.ts +1 -1
- package/dist/cli/doctor.d.ts +5 -0
- package/dist/cli/doctor.js +21 -1
- package/dist/cli/embeddings.d.ts +12 -0
- package/dist/cli/embeddings.js +49 -0
- package/dist/cli/help-i18n.js +4 -0
- package/dist/cli/i18n/en.d.ts +4 -0
- package/dist/cli/i18n/en.js +4 -0
- package/dist/cli/i18n/resources.d.ts +8 -0
- package/dist/cli/i18n/zh-CN.d.ts +4 -0
- package/dist/cli/i18n/zh-CN.js +4 -0
- package/dist/cli/index.js +11 -0
- package/dist/core/embeddings/embedder.js +16 -2
- package/dist/core/embeddings/node-module-compat.d.ts +23 -0
- package/dist/core/embeddings/node-module-compat.js +23 -0
- package/dist/core/embeddings/onnxruntime-common-resolver.js +6 -3
- package/dist/core/embeddings/onnxruntime-node-resolver.js +31 -5
- package/dist/core/embeddings/runtime-install.d.ts +119 -0
- package/dist/core/embeddings/runtime-install.js +372 -0
- package/dist/core/embeddings/runtime-support.d.ts +48 -17
- package/dist/core/embeddings/runtime-support.js +96 -0
- package/dist/mcp/core/embedder.js +16 -2
- package/dist/mcp/local/local-backend.d.ts +6 -0
- package/dist/mcp/local/local-backend.js +21 -2
- package/package.json +5 -3
- package/scripts/cross-platform-tests.ts +12 -0
package/README.md
CHANGED
|
@@ -220,6 +220,7 @@ gitnexus analyze [path] # Index a repository (or update stale index)
|
|
|
220
220
|
gitnexus analyze --repair-fts # Fast path: rebuild/verify only FTS indexes on existing index data
|
|
221
221
|
gitnexus analyze --force # Full rebuild: re-parse + graph rebuild + FTS rebuild
|
|
222
222
|
gitnexus analyze --embeddings # Enable embedding generation (slower, better search)
|
|
223
|
+
gitnexus embeddings install # Fetch the optional local embedding stack on demand (--cuda, --force)
|
|
223
224
|
gitnexus analyze --skills # Generate repo-specific skill files from detected communities
|
|
224
225
|
gitnexus analyze --skip-agents-md # Preserve custom AGENTS.md/CLAUDE.md gitnexus section edits
|
|
225
226
|
gitnexus analyze --skip-skills # Skip installing .claude/skills/gitnexus/ skill files
|
|
@@ -420,6 +421,27 @@ If `npm install -g gitnexus` fails on native modules:
|
|
|
420
421
|
npm install -g gitnexus
|
|
421
422
|
```
|
|
422
423
|
|
|
424
|
+
### Installation fails behind an HTTP proxy (`onnxruntime-node` postinstall)
|
|
425
|
+
|
|
426
|
+
`onnxruntime-node`'s postinstall downloads optional CUDA GPU binaries from `api.nuget.org` — outside the npm registry, so registry mirrors don't cover it, and its proxy layer (`global-agent`) ignores the standard `HTTP_PROXY`/`HTTPS_PROXY` variables and rejects 302 redirects ([#2370](https://github.com/abhigyanpatwari/GitNexus/issues/2370)).
|
|
427
|
+
|
|
428
|
+
Since the packages are optional dependencies, a failed download no longer breaks `npm install -g gitnexus` — npm skips the embedding stack and everything else works. The stack then **self-heals on demand**: the first `gitnexus analyze --embeddings` (or an explicit `gitnexus embeddings install`) fetches it through your configured npm registry — mirrors and proxies apply, no NuGet download involved — into `~/.gitnexus/embedding-runtime`.
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
# heal a proxy-degraded install manually (CPU embeddings; registry-only)
|
|
432
|
+
gitnexus embeddings install
|
|
433
|
+
|
|
434
|
+
# reinstall into the prefix even when the stack already resolves
|
|
435
|
+
gitnexus embeddings install --force
|
|
436
|
+
|
|
437
|
+
# CUDA GPU hosts: also fetch GPU binaries (NuGet; set the proxy global-agent reads)
|
|
438
|
+
GLOBAL_AGENT_HTTPS_PROXY=<proxy-url> gitnexus embeddings install --cuda
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
The prefix defaults to `~/.gitnexus/embedding-runtime`; set `GITNEXUS_EMBEDDING_RUNTIME_DIR` to install it elsewhere (e.g. a writable path in a container).
|
|
442
|
+
|
|
443
|
+
> **Node requirement for the on-demand prefix:** the self-heal loads the prefixed packages via `module.registerHooks`, available on Node **≥ 22.15** (on the 22.x line) or **≥ 23.5** (on the 23.x line). On an older Node the packages install but can't be loaded from the prefix — reinstall them into the install itself instead (works on every supported Node): `ONNXRUNTIME_NODE_INSTALL=skip npm install -g gitnexus` (Windows: `set ONNXRUNTIME_NODE_INSTALL=skip && npm install -g gitnexus`). Skipping only the CUDA download keeps full CPU embeddings (CPU embeddings don't need it). Check the result any time with `gitnexus doctor` (Embeddings → Support line).
|
|
444
|
+
|
|
423
445
|
### Analyze warns about unavailable FTS or VECTOR extensions
|
|
424
446
|
|
|
425
447
|
GitNexus uses optional DuckDB extensions for BM25 and vector search. The `gitnexus serve` and MCP read paths only ever try to `LOAD` the extensions — they never block on a network install. The `analyze` command, by default, attempts one bounded out-of-process `INSTALL` if `LOAD` fails and proceeds even when that install times out, so the index is always written to disk; BM25/vector search degrade gracefully until the extensions become available.
|
package/dist/cli/analyze.js
CHANGED
|
@@ -27,8 +27,9 @@ import { cliError } from './cli-message.js';
|
|
|
27
27
|
import { EMBEDDING_DIMS_ERROR, normalizeEmbeddingDims } from './embedding-dims.js';
|
|
28
28
|
import { formatElapsed } from './format-elapsed.js';
|
|
29
29
|
import { isHfDownloadFailure } from '../core/embeddings/hf-env.js';
|
|
30
|
-
import { safeUrl } from '../core/embeddings/http-client.js';
|
|
31
|
-
import { isLocalEmbeddingRuntimeBlockerMessage } from '../core/embeddings/runtime-support.js';
|
|
30
|
+
import { isHttpMode, safeUrl } from '../core/embeddings/http-client.js';
|
|
31
|
+
import { isLocalEmbeddingRuntimeBlockerMessage, isMissingLocalEmbeddingStackMessage, localEmbeddingPrefixUnloadableMessage, localEmbeddingStackMissingMessage, } from '../core/embeddings/runtime-support.js';
|
|
32
|
+
import { ANALYZE_EMBEDDING_INSTALL_TIMEOUT_MS, getEmbeddingInstallTimeoutMs, getEmbeddingRuntimeDir, installEmbeddingRuntime, isPrefixRuntimeLoadable, resolveEmbeddingRuntime, } from '../core/embeddings/runtime-install.js';
|
|
32
33
|
import { warnIfNpm11NpxRisk } from './resolve-invocation.js';
|
|
33
34
|
// Capture stderr.write at module load BEFORE anything (LadybugDB native
|
|
34
35
|
// init, progress bar, console redirection) can monkey-patch it. The
|
|
@@ -797,6 +798,52 @@ const analyzeCommandImpl = async (inputPath, cliOptions) => {
|
|
|
797
798
|
console.log(' Note: custom HTTP embeddings require BOTH --embedding-base-url and --embedding-model ' +
|
|
798
799
|
'(or the matching env vars). Falling back to local ONNX embeddings.\n');
|
|
799
800
|
}
|
|
801
|
+
// On-demand embedding runtime (#2370): when the optional stack was pruned at
|
|
802
|
+
// install time (proxy-blocked NuGet download in onnxruntime-node's
|
|
803
|
+
// postinstall), heal it here instead of failing later in the pipeline. The
|
|
804
|
+
// install goes through the user's npm registry config (mirrors/proxies
|
|
805
|
+
// apply) with --ignore-scripts, so no NuGet download is attempted. Runs
|
|
806
|
+
// before bar.start() like the sibling validations above.
|
|
807
|
+
if (embeddingsEnabled && !isHttpMode()) {
|
|
808
|
+
const resolved = resolveEmbeddingRuntime();
|
|
809
|
+
// Resolved-but-unloadable (a populated prefix on a Node with no
|
|
810
|
+
// module.registerHooks), or nothing installed on such a Node: fail fast with
|
|
811
|
+
// capability guidance instead of dying mid-pipeline over an unusable prefix
|
|
812
|
+
// or downloading a runtime the loader can't reach. A package-sourced stack
|
|
813
|
+
// never needs the hook, so it is excluded. --embeddings was explicitly
|
|
814
|
+
// requested and this failure is deterministic, so fail fast rather than
|
|
815
|
+
// silently degrading to BM25 (distinct from a transient install timeout).
|
|
816
|
+
if (!isPrefixRuntimeLoadable() && (resolved === null || resolved.source === 'runtime-prefix')) {
|
|
817
|
+
cliError(` ${localEmbeddingPrefixUnloadableMessage().replace(/\n/g, '\n ')}\n`, {
|
|
818
|
+
recoveryHint: 'local-embedding-stack-missing',
|
|
819
|
+
});
|
|
820
|
+
process.exitCode = 1;
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
// On-demand embedding runtime (#2370): when the optional stack was pruned at
|
|
824
|
+
// install time (proxy-blocked NuGet download in onnxruntime-node's
|
|
825
|
+
// postinstall), heal it here instead of failing later in the pipeline. The
|
|
826
|
+
// install goes through the user's npm registry config (mirrors/proxies
|
|
827
|
+
// apply) with --ignore-scripts, so no NuGet download is attempted.
|
|
828
|
+
if (resolved === null) {
|
|
829
|
+
console.log(` Local embedding runtime is not installed (optional packages were skipped at install time).\n` +
|
|
830
|
+
` Downloading it now from your npm registry into ${getEmbeddingRuntimeDir()} …\n` +
|
|
831
|
+
` (one-time; rerun manually anytime with \`gitnexus embeddings install\`)\n`);
|
|
832
|
+
try {
|
|
833
|
+
// Short deadline (env override still wins): analyze is interactive, so a
|
|
834
|
+
// blackholed proxy must not stall the whole index run for the 10-minute
|
|
835
|
+
// default — fail over to the guidance below instead.
|
|
836
|
+
await installEmbeddingRuntime({}, getEmbeddingInstallTimeoutMs(ANALYZE_EMBEDDING_INSTALL_TIMEOUT_MS));
|
|
837
|
+
console.log(' Embedding runtime installed.\n');
|
|
838
|
+
}
|
|
839
|
+
catch (err) {
|
|
840
|
+
cliError(` Could not install the embedding runtime: ${err instanceof Error ? err.message : String(err)}\n\n` +
|
|
841
|
+
` ${localEmbeddingStackMissingMessage().replace(/\n/g, '\n ')}\n`, { recoveryHint: 'local-embedding-stack-missing' });
|
|
842
|
+
process.exitCode = 1;
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
800
847
|
if (options.repairFts && options.force) {
|
|
801
848
|
cliError(' Cannot combine `--repair-fts` with `--force`. ' +
|
|
802
849
|
'Use `--repair-fts` for fast FTS-only repair, or `--force` for a full rebuild.\n');
|
|
@@ -1203,6 +1250,18 @@ const analyzeCommandImpl = async (inputPath, cliOptions) => {
|
|
|
1203
1250
|
process.exitCode = 1;
|
|
1204
1251
|
return;
|
|
1205
1252
|
}
|
|
1253
|
+
// The optional embedding stack (@huggingface/transformers → onnxruntime-node)
|
|
1254
|
+
// was pruned at install time — usually a proxy-blocked NuGet download during
|
|
1255
|
+
// onnxruntime-node's postinstall (#2370). Checked before the generic
|
|
1256
|
+
// module-not-found "installation may be corrupt" hint below, which would
|
|
1257
|
+
// otherwise misdiagnose a deliberate optional-dependency skip.
|
|
1258
|
+
if (isMissingLocalEmbeddingStackMessage(msg)) {
|
|
1259
|
+
cliError(` ${msg.replace(/\n/g, '\n ')}\n`, {
|
|
1260
|
+
recoveryHint: 'local-embedding-stack-missing',
|
|
1261
|
+
});
|
|
1262
|
+
process.exitCode = 1;
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1206
1265
|
// HF download failure — show clean guidance without the raw stack trace.
|
|
1207
1266
|
// Checked before writeFatalToStderr so the user sees one focused message
|
|
1208
1267
|
// rather than a stack-trace dump followed by a second remediation block.
|
|
@@ -12,7 +12,7 @@ import { type CliMessageKey, type CliMessageVars } from './i18n/index.js';
|
|
|
12
12
|
* Consumers can import this type to narrow log-record `recoveryHint`
|
|
13
13
|
* fields without restating the literal list.
|
|
14
14
|
*/
|
|
15
|
-
export type RecoveryHint = 'wal-corruption' | 'wal-checkpoint-threshold' | 'heap-oom-respawn' | 'native-worker-abort' | 'hf-endpoint-unreachable' | 'local-embedding-unsupported' | 'large-repo' | 'npm-resolution' | 'module-not-found' | 'gitnexusrc-invalid' | 'default-branch-invalid';
|
|
15
|
+
export type RecoveryHint = 'wal-corruption' | 'wal-checkpoint-threshold' | 'heap-oom-respawn' | 'native-worker-abort' | 'hf-endpoint-unreachable' | 'local-embedding-unsupported' | 'local-embedding-stack-missing' | 'large-repo' | 'npm-resolution' | 'module-not-found' | 'gitnexusrc-invalid' | 'default-branch-invalid';
|
|
16
16
|
/**
|
|
17
17
|
* Common shape for the optional structured-field bag passed to
|
|
18
18
|
* `cliError`/`cliWarn`/`cliInfo`. Typed so the `recoveryHint` slot is
|
package/dist/cli/doctor.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type EmbeddingRuntimeResolution } from '../core/embeddings/runtime-install.js';
|
|
1
2
|
export declare function displayWidth(value: string): number;
|
|
2
3
|
export declare function padDisplayEnd(value: string, columns: number): string;
|
|
3
4
|
/**
|
|
@@ -14,6 +15,10 @@ export declare function localEmbeddingDoctorStatus(opts: {
|
|
|
14
15
|
httpMode: boolean;
|
|
15
16
|
platform?: NodeJS.Platform;
|
|
16
17
|
arch?: NodeJS.Architecture;
|
|
18
|
+
/** Injectable for tests; defaults to probing the real install. */
|
|
19
|
+
resolution?: EmbeddingRuntimeResolution | null;
|
|
20
|
+
/** Injectable for tests; defaults to this Node's registerHooks capability. */
|
|
21
|
+
prefixLoadable?: boolean;
|
|
17
22
|
}): {
|
|
18
23
|
status: string;
|
|
19
24
|
detail: string | null;
|
package/dist/cli/doctor.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getRuntimeCapabilities, getRuntimeFingerprint } from '../core/platform/capabilities.js';
|
|
2
2
|
import { resolveEmbeddingConfig } from '../core/embeddings/config.js';
|
|
3
3
|
import { isHttpMode } from '../core/embeddings/http-client.js';
|
|
4
|
-
import { getLocalEmbeddingRuntimeBlocker } from '../core/embeddings/runtime-support.js';
|
|
4
|
+
import { getLocalEmbeddingRuntimeBlocker, localEmbeddingPrefixUnloadableMessage, localEmbeddingStackMissingMessage, } from '../core/embeddings/runtime-support.js';
|
|
5
|
+
import { isPrefixRuntimeLoadable, resolveEmbeddingRuntime, } from '../core/embeddings/runtime-install.js';
|
|
5
6
|
import { cudaRedirectDoctorStatus } from '../core/embeddings/onnxruntime-node-resolver.js';
|
|
6
7
|
import { checkLbugNative } from '../core/lbug/native-check.js';
|
|
7
8
|
import { getExtensionInstallPolicy } from '../core/lbug/extension-loader.js';
|
|
@@ -64,6 +65,25 @@ export function localEmbeddingDoctorStatus(opts) {
|
|
|
64
65
|
if (blocker) {
|
|
65
66
|
return { status: `✗ local embeddings unavailable on ${platform}/${arch}`, detail: blocker };
|
|
66
67
|
}
|
|
68
|
+
// The stack is an optionalDependency — npm prunes it when onnxruntime-node's
|
|
69
|
+
// postinstall can't download its CUDA binaries (proxy/firewall, #2370).
|
|
70
|
+
const resolution = opts.resolution !== undefined ? opts.resolution : resolveEmbeddingRuntime();
|
|
71
|
+
if (resolution === null) {
|
|
72
|
+
return {
|
|
73
|
+
status: '✗ optional embedding stack not installed',
|
|
74
|
+
detail: localEmbeddingStackMissingMessage(),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// A prefix-sourced stack needs module.registerHooks to load; on Node < 22.15 /
|
|
78
|
+
// < 23.5 it is present but unreachable (#2372). Report loadability, not bare
|
|
79
|
+
// presence, so the diagnostic stops claiming a ✓ the loader can't honour.
|
|
80
|
+
const prefixLoadable = opts.prefixLoadable ?? isPrefixRuntimeLoadable();
|
|
81
|
+
if (resolution.source === 'runtime-prefix' && !prefixLoadable) {
|
|
82
|
+
return {
|
|
83
|
+
status: '✗ embedding stack installed in the prefix but not loadable on this Node',
|
|
84
|
+
detail: localEmbeddingPrefixUnloadableMessage(),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
67
87
|
return { status: '✓ local embeddings supported', detail: null };
|
|
68
88
|
}
|
|
69
89
|
export const doctorCommand = async () => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface EmbeddingsInstallOptions {
|
|
2
|
+
cuda?: boolean;
|
|
3
|
+
force?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* `gitnexus embeddings install [--cuda] [--force]` — fetch the optional local
|
|
7
|
+
* embedding stack on demand (#2370). Goes through the user's npm registry
|
|
8
|
+
* config (mirrors/proxies apply); with --cuda it additionally runs
|
|
9
|
+
* onnxruntime-node's postinstall to download the CUDA GPU binaries from NuGet
|
|
10
|
+
* (set GLOBAL_AGENT_HTTPS_PROXY behind a proxy).
|
|
11
|
+
*/
|
|
12
|
+
export declare const embeddingsInstallCommand: (options?: EmbeddingsInstallOptions) => Promise<void>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { cliError, cliInfo, cliWarn } from './cli-message.js';
|
|
2
|
+
import { getEmbeddingRuntimeDir, getEmbeddingStackSpecs, installEmbeddingRuntime, isPrefixRuntimeLoadable, resolveEmbeddingRuntime, } from '../core/embeddings/runtime-install.js';
|
|
3
|
+
import { localEmbeddingPrefixUnloadableMessage } from '../core/embeddings/runtime-support.js';
|
|
4
|
+
/**
|
|
5
|
+
* `gitnexus embeddings install [--cuda] [--force]` — fetch the optional local
|
|
6
|
+
* embedding stack on demand (#2370). Goes through the user's npm registry
|
|
7
|
+
* config (mirrors/proxies apply); with --cuda it additionally runs
|
|
8
|
+
* onnxruntime-node's postinstall to download the CUDA GPU binaries from NuGet
|
|
9
|
+
* (set GLOBAL_AGENT_HTTPS_PROXY behind a proxy).
|
|
10
|
+
*/
|
|
11
|
+
export const embeddingsInstallCommand = async (options = {}) => {
|
|
12
|
+
const resolved = resolveEmbeddingRuntime();
|
|
13
|
+
if (resolved?.source === 'package' && !options.force) {
|
|
14
|
+
cliInfo('The embedding stack is already installed with gitnexus itself — nothing to do.\n' +
|
|
15
|
+
'(Use --force to install a copy into the runtime prefix anyway.)');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const specs = Object.entries(getEmbeddingStackSpecs())
|
|
19
|
+
.map(([name, spec]) => `${name}@${spec}`)
|
|
20
|
+
.join(', ');
|
|
21
|
+
cliInfo(`Installing ${specs} into ${getEmbeddingRuntimeDir()} …`);
|
|
22
|
+
cliInfo(options.cuda
|
|
23
|
+
? 'CUDA mode: onnxruntime-node will download GPU binaries from NuGet ' +
|
|
24
|
+
'(set GLOBAL_AGENT_HTTPS_PROXY=<proxy-url> behind a proxy).'
|
|
25
|
+
: 'CPU mode: install scripts are skipped — only your npm registry is contacted.');
|
|
26
|
+
try {
|
|
27
|
+
await installEmbeddingRuntime({ cuda: options.cuda, onOutput: (line) => cliInfo(` ${line}`) });
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
cliError(`${err instanceof Error ? err.message : String(err)}\n`, {
|
|
31
|
+
recoveryHint: 'local-embedding-stack-missing',
|
|
32
|
+
});
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const postInstall = resolveEmbeddingRuntime();
|
|
37
|
+
if (postInstall === null) {
|
|
38
|
+
cliInfo('✗ Install completed but the stack still does not resolve — check the output above.');
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (postInstall.source === 'runtime-prefix' && !isPrefixRuntimeLoadable()) {
|
|
43
|
+
// The packages are in the prefix, but this Node has no module.registerHooks
|
|
44
|
+
// to load them — don't claim readiness the loader can't honour.
|
|
45
|
+
cliWarn(`${localEmbeddingPrefixUnloadableMessage()}\n`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
cliInfo('✓ Embedding runtime installed. `gitnexus analyze --embeddings` is ready.');
|
|
49
|
+
};
|
package/dist/cli/help-i18n.js
CHANGED
|
@@ -17,6 +17,8 @@ const COMMAND_DESCRIPTION_KEYS = {
|
|
|
17
17
|
list: 'help.command.list.description',
|
|
18
18
|
status: 'help.command.status.description',
|
|
19
19
|
doctor: 'help.command.doctor.description',
|
|
20
|
+
embeddings: 'help.command.embeddings.description',
|
|
21
|
+
'embeddings install': 'help.command.embeddings.install.description',
|
|
20
22
|
clean: 'help.command.clean.description',
|
|
21
23
|
remove: 'help.command.remove.description',
|
|
22
24
|
wiki: 'help.command.wiki.description',
|
|
@@ -143,6 +145,8 @@ const OPTION_DESCRIPTION_KEYS = {
|
|
|
143
145
|
'eval-server|-p, --port <port>': 'help.option.port',
|
|
144
146
|
'eval-server|--host <host>': 'help.option.evalServer.host',
|
|
145
147
|
'eval-server|--idle-timeout <seconds>': 'help.option.evalServer.idleTimeout',
|
|
148
|
+
'embeddings install|--cuda': 'help.option.embeddings.install.cuda',
|
|
149
|
+
'embeddings install|--force': 'help.option.embeddings.install.force',
|
|
146
150
|
'group create|--force': 'help.option.group.create.force',
|
|
147
151
|
'group sync|--skip-embeddings': 'help.option.group.sync.skipEmbeddings',
|
|
148
152
|
'group sync|--exact-only': 'help.option.group.sync.exactOnly',
|
package/dist/cli/i18n/en.d.ts
CHANGED
|
@@ -117,6 +117,8 @@ export declare const en: {
|
|
|
117
117
|
readonly 'help.command.list.description': "List all indexed repositories";
|
|
118
118
|
readonly 'help.command.status.description': "Show index status for current repo";
|
|
119
119
|
readonly 'help.command.doctor.description': "Show runtime platform capabilities and embedding configuration";
|
|
120
|
+
readonly 'help.command.embeddings.description': "Manage the on-demand local embedding runtime";
|
|
121
|
+
readonly 'help.command.embeddings.install.description': "Install the local embedding stack (@huggingface/transformers + onnxruntime-node) on demand. Heals installs where npm skipped the optional packages (e.g. behind an HTTP proxy, #2370). Downloads only from your configured npm registry — mirrors and proxies apply.";
|
|
120
122
|
readonly 'help.command.clean.description': "Delete GitNexus index for current repo";
|
|
121
123
|
readonly 'help.command.remove.description': "Delete the GitNexus index for a registered repo (by alias, name, or absolute path). Unlike `clean`, does not require being inside the repo. Idempotent on unknown targets.";
|
|
122
124
|
readonly 'help.command.wiki.description': "Generate repository wiki from knowledge graph";
|
|
@@ -220,6 +222,8 @@ export declare const en: {
|
|
|
220
222
|
readonly 'help.option.check.cycles': "Detect circular imports and fail when any are found";
|
|
221
223
|
readonly 'help.option.evalServer.host': "Bind address (default: 127.0.0.1, use 0.0.0.0 to expose to all interfaces)";
|
|
222
224
|
readonly 'help.option.evalServer.idleTimeout': "Auto-shutdown after N seconds idle (0 = disabled)";
|
|
225
|
+
readonly 'help.option.embeddings.install.cuda': "Also download the CUDA GPU binaries (runs onnxruntime-node's NuGet postinstall; set GLOBAL_AGENT_HTTPS_PROXY behind a proxy)";
|
|
226
|
+
readonly 'help.option.embeddings.install.force': "Install into the runtime prefix even when the stack already resolves";
|
|
223
227
|
readonly 'help.option.group.create.force': "Overwrite existing group";
|
|
224
228
|
readonly 'help.option.group.sync.skipEmbeddings': "Exact + BM25 only (no embedding fallback)";
|
|
225
229
|
readonly 'help.option.group.sync.exactOnly': "Exact match only";
|
package/dist/cli/i18n/en.js
CHANGED
|
@@ -117,6 +117,8 @@ export const en = {
|
|
|
117
117
|
'help.command.list.description': 'List all indexed repositories',
|
|
118
118
|
'help.command.status.description': 'Show index status for current repo',
|
|
119
119
|
'help.command.doctor.description': 'Show runtime platform capabilities and embedding configuration',
|
|
120
|
+
'help.command.embeddings.description': 'Manage the on-demand local embedding runtime',
|
|
121
|
+
'help.command.embeddings.install.description': 'Install the local embedding stack (@huggingface/transformers + onnxruntime-node) on demand. Heals installs where npm skipped the optional packages (e.g. behind an HTTP proxy, #2370). Downloads only from your configured npm registry — mirrors and proxies apply.',
|
|
120
122
|
'help.command.clean.description': 'Delete GitNexus index for current repo',
|
|
121
123
|
'help.command.remove.description': 'Delete the GitNexus index for a registered repo (by alias, name, or absolute path). Unlike `clean`, does not require being inside the repo. Idempotent on unknown targets.',
|
|
122
124
|
'help.command.wiki.description': 'Generate repository wiki from knowledge graph',
|
|
@@ -220,6 +222,8 @@ export const en = {
|
|
|
220
222
|
'help.option.check.cycles': 'Detect circular imports and fail when any are found',
|
|
221
223
|
'help.option.evalServer.host': 'Bind address (default: 127.0.0.1, use 0.0.0.0 to expose to all interfaces)',
|
|
222
224
|
'help.option.evalServer.idleTimeout': 'Auto-shutdown after N seconds idle (0 = disabled)',
|
|
225
|
+
'help.option.embeddings.install.cuda': "Also download the CUDA GPU binaries (runs onnxruntime-node's NuGet postinstall; set GLOBAL_AGENT_HTTPS_PROXY behind a proxy)",
|
|
226
|
+
'help.option.embeddings.install.force': 'Install into the runtime prefix even when the stack already resolves',
|
|
223
227
|
'help.option.group.create.force': 'Overwrite existing group',
|
|
224
228
|
'help.option.group.sync.skipEmbeddings': 'Exact + BM25 only (no embedding fallback)',
|
|
225
229
|
'help.option.group.sync.exactOnly': 'Exact match only',
|
|
@@ -118,6 +118,8 @@ export declare const cliResources: {
|
|
|
118
118
|
readonly 'help.command.list.description': "List all indexed repositories";
|
|
119
119
|
readonly 'help.command.status.description': "Show index status for current repo";
|
|
120
120
|
readonly 'help.command.doctor.description': "Show runtime platform capabilities and embedding configuration";
|
|
121
|
+
readonly 'help.command.embeddings.description': "Manage the on-demand local embedding runtime";
|
|
122
|
+
readonly 'help.command.embeddings.install.description': "Install the local embedding stack (@huggingface/transformers + onnxruntime-node) on demand. Heals installs where npm skipped the optional packages (e.g. behind an HTTP proxy, #2370). Downloads only from your configured npm registry — mirrors and proxies apply.";
|
|
121
123
|
readonly 'help.command.clean.description': "Delete GitNexus index for current repo";
|
|
122
124
|
readonly 'help.command.remove.description': "Delete the GitNexus index for a registered repo (by alias, name, or absolute path). Unlike `clean`, does not require being inside the repo. Idempotent on unknown targets.";
|
|
123
125
|
readonly 'help.command.wiki.description': "Generate repository wiki from knowledge graph";
|
|
@@ -221,6 +223,8 @@ export declare const cliResources: {
|
|
|
221
223
|
readonly 'help.option.check.cycles': "Detect circular imports and fail when any are found";
|
|
222
224
|
readonly 'help.option.evalServer.host': "Bind address (default: 127.0.0.1, use 0.0.0.0 to expose to all interfaces)";
|
|
223
225
|
readonly 'help.option.evalServer.idleTimeout': "Auto-shutdown after N seconds idle (0 = disabled)";
|
|
226
|
+
readonly 'help.option.embeddings.install.cuda': "Also download the CUDA GPU binaries (runs onnxruntime-node's NuGet postinstall; set GLOBAL_AGENT_HTTPS_PROXY behind a proxy)";
|
|
227
|
+
readonly 'help.option.embeddings.install.force': "Install into the runtime prefix even when the stack already resolves";
|
|
224
228
|
readonly 'help.option.group.create.force': "Overwrite existing group";
|
|
225
229
|
readonly 'help.option.group.sync.skipEmbeddings': "Exact + BM25 only (no embedding fallback)";
|
|
226
230
|
readonly 'help.option.group.sync.exactOnly': "Exact match only";
|
|
@@ -360,6 +364,8 @@ export declare const cliResources: {
|
|
|
360
364
|
'help.command.list.description': string;
|
|
361
365
|
'help.command.status.description': string;
|
|
362
366
|
'help.command.doctor.description': string;
|
|
367
|
+
'help.command.embeddings.description': string;
|
|
368
|
+
'help.command.embeddings.install.description': string;
|
|
363
369
|
'help.command.clean.description': string;
|
|
364
370
|
'help.command.remove.description': string;
|
|
365
371
|
'help.command.wiki.description': string;
|
|
@@ -463,6 +469,8 @@ export declare const cliResources: {
|
|
|
463
469
|
'help.option.check.cycles': string;
|
|
464
470
|
'help.option.evalServer.host': string;
|
|
465
471
|
'help.option.evalServer.idleTimeout': string;
|
|
472
|
+
'help.option.embeddings.install.cuda': string;
|
|
473
|
+
'help.option.embeddings.install.force': string;
|
|
466
474
|
'help.option.group.create.force': string;
|
|
467
475
|
'help.option.group.sync.skipEmbeddings': string;
|
|
468
476
|
'help.option.group.sync.exactOnly': string;
|
package/dist/cli/i18n/zh-CN.d.ts
CHANGED
|
@@ -117,6 +117,8 @@ export declare const zhCN: {
|
|
|
117
117
|
'help.command.list.description': string;
|
|
118
118
|
'help.command.status.description': string;
|
|
119
119
|
'help.command.doctor.description': string;
|
|
120
|
+
'help.command.embeddings.description': string;
|
|
121
|
+
'help.command.embeddings.install.description': string;
|
|
120
122
|
'help.command.clean.description': string;
|
|
121
123
|
'help.command.remove.description': string;
|
|
122
124
|
'help.command.wiki.description': string;
|
|
@@ -220,6 +222,8 @@ export declare const zhCN: {
|
|
|
220
222
|
'help.option.check.cycles': string;
|
|
221
223
|
'help.option.evalServer.host': string;
|
|
222
224
|
'help.option.evalServer.idleTimeout': string;
|
|
225
|
+
'help.option.embeddings.install.cuda': string;
|
|
226
|
+
'help.option.embeddings.install.force': string;
|
|
223
227
|
'help.option.group.create.force': string;
|
|
224
228
|
'help.option.group.sync.skipEmbeddings': string;
|
|
225
229
|
'help.option.group.sync.exactOnly': string;
|
package/dist/cli/i18n/zh-CN.js
CHANGED
|
@@ -117,6 +117,8 @@ export const zhCN = {
|
|
|
117
117
|
'help.command.list.description': '列出所有已索引仓库',
|
|
118
118
|
'help.command.status.description': '显示当前仓库的索引状态',
|
|
119
119
|
'help.command.doctor.description': '显示运行平台能力和嵌入配置',
|
|
120
|
+
'help.command.embeddings.description': '管理按需安装的本地嵌入运行时',
|
|
121
|
+
'help.command.embeddings.install.description': '按需安装本地嵌入组件(@huggingface/transformers + onnxruntime-node)。修复 npm 跳过可选包的安装(例如在 HTTP 代理后,#2370)。仅从你配置的 npm registry 下载 — 镜像和代理均生效。',
|
|
120
122
|
'help.command.clean.description': '删除当前仓库的 GitNexus 索引',
|
|
121
123
|
'help.command.remove.description': '删除已注册仓库的 GitNexus 索引(按别名、名称或绝对路径)。与 `clean` 不同,不要求位于仓库内;未知目标会幂等处理。',
|
|
122
124
|
'help.command.wiki.description': '从知识图谱生成仓库 Wiki',
|
|
@@ -220,6 +222,8 @@ export const zhCN = {
|
|
|
220
222
|
'help.option.check.cycles': '检测循环导入,并在发现循环时失败',
|
|
221
223
|
'help.option.evalServer.host': '绑定地址(默认:127.0.0.1;用 0.0.0.0 暴露到所有网卡)',
|
|
222
224
|
'help.option.evalServer.idleTimeout': '空闲 N 秒后自动关闭(0 = 禁用)',
|
|
225
|
+
'help.option.embeddings.install.cuda': '同时下载 CUDA GPU 二进制文件(运行 onnxruntime-node 的 NuGet postinstall;代理后请设置 GLOBAL_AGENT_HTTPS_PROXY)',
|
|
226
|
+
'help.option.embeddings.install.force': '即使嵌入组件已可解析,也强制安装到运行时目录',
|
|
223
227
|
'help.option.group.create.force': '覆盖现有仓库组',
|
|
224
228
|
'help.option.group.sync.skipEmbeddings': '仅使用 exact + BM25(不使用嵌入回退)',
|
|
225
229
|
'help.option.group.sync.exactOnly': '仅精确匹配',
|
package/dist/cli/index.js
CHANGED
|
@@ -153,6 +153,17 @@ program
|
|
|
153
153
|
.command('doctor')
|
|
154
154
|
.description('Show runtime platform capabilities and embedding configuration')
|
|
155
155
|
.action(createLazyAction(() => import('./doctor.js'), 'doctorCommand'));
|
|
156
|
+
program
|
|
157
|
+
.command('embeddings')
|
|
158
|
+
.description('Manage the on-demand local embedding runtime')
|
|
159
|
+
.command('install')
|
|
160
|
+
.description('Install the local embedding stack (@huggingface/transformers + onnxruntime-node) on demand. ' +
|
|
161
|
+
'Heals installs where npm skipped the optional packages (e.g. behind an HTTP proxy, #2370). ' +
|
|
162
|
+
'Downloads only from your configured npm registry — mirrors and proxies apply.')
|
|
163
|
+
.option('--cuda', "Also download the CUDA GPU binaries (runs onnxruntime-node's NuGet postinstall; " +
|
|
164
|
+
'set GLOBAL_AGENT_HTTPS_PROXY behind a proxy)')
|
|
165
|
+
.option('--force', 'Install into the runtime prefix even when the stack already resolves')
|
|
166
|
+
.action(createLazyAction(() => import('./embeddings.js'), 'embeddingsInstallCommand'));
|
|
156
167
|
program
|
|
157
168
|
.command('clean')
|
|
158
169
|
.description('Delete GitNexus index for current repo')
|
|
@@ -16,8 +16,9 @@ import { DEFAULT_EMBEDDING_CONFIG } from './types.js';
|
|
|
16
16
|
import { isHttpMode, getHttpDimensions, httpEmbed } from './http-client.js';
|
|
17
17
|
import { resolveEmbeddingConfig } from './config.js';
|
|
18
18
|
import { applyHfEnvOverrides, isHfDownloadFailure, withHfDownloadRetry } from './hf-env.js';
|
|
19
|
-
import { getLocalEmbeddingRuntimeBlocker } from './runtime-support.js';
|
|
19
|
+
import { getLocalEmbeddingRuntimeBlocker, getMissingLocalEmbeddingStackMessage, } from './runtime-support.js';
|
|
20
20
|
import { ensureOnnxRuntimeCommonResolvable } from './onnxruntime-common-resolver.js';
|
|
21
|
+
import { ensureEmbeddingStackResolvable } from './runtime-install.js';
|
|
21
22
|
import { ensureOnnxRuntimeNodeMatchesSystem, isEffectiveCudaAvailable, } from './onnxruntime-node-resolver.js';
|
|
22
23
|
import { logger } from '../logger.js';
|
|
23
24
|
// Module-level state for singleton pattern
|
|
@@ -73,6 +74,11 @@ export const initEmbedder = async (onProgress, config = {}, forceDevice) => {
|
|
|
73
74
|
try {
|
|
74
75
|
// Lazy-load transformers.js only after the runtime guard has passed, so
|
|
75
76
|
// unsupported platforms never reach the native ONNX import (#1515).
|
|
77
|
+
// Registered FIRST so it sits last in the hook chain (registerHooks runs
|
|
78
|
+
// the most recent hook first): when the optional stack was pruned at
|
|
79
|
+
// install time (#2370), its bare specifiers fall back to the on-demand
|
|
80
|
+
// runtime prefix.
|
|
81
|
+
ensureEmbeddingStackResolvable();
|
|
76
82
|
// Under pnpm-strict / `pnpm dlx`, transformers' phantom `onnxruntime-common`
|
|
77
83
|
// import is unresolvable; register the fallback resolver first (#307).
|
|
78
84
|
ensureOnnxRuntimeCommonResolvable();
|
|
@@ -82,7 +88,15 @@ export const initEmbedder = async (onProgress, config = {}, forceDevice) => {
|
|
|
82
88
|
// to the CUDA-13 build before transformers imports them. No-op on matching
|
|
83
89
|
// layouts, non-CUDA, Windows/DirectML, and macOS.
|
|
84
90
|
ensureOnnxRuntimeNodeMatchesSystem();
|
|
85
|
-
|
|
91
|
+
// The stack is an optionalDependency: npm prunes it when onnxruntime-node's
|
|
92
|
+
// postinstall can't reach api.nuget.org (#2370). Rethrow with actionable
|
|
93
|
+
// reinstall guidance instead of a raw ERR_MODULE_NOT_FOUND.
|
|
94
|
+
const { pipeline, env } = await import('@huggingface/transformers').catch((err) => {
|
|
95
|
+
const missing = getMissingLocalEmbeddingStackMessage(err);
|
|
96
|
+
if (missing)
|
|
97
|
+
throw new Error(missing);
|
|
98
|
+
throw err;
|
|
99
|
+
});
|
|
86
100
|
// Configure transformers.js environment
|
|
87
101
|
env.allowLocalModels = false;
|
|
88
102
|
// Bridge user-controlled env vars to transformers.js: HF_HOME →
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single access point for `module.registerHooks` (#2372).
|
|
3
|
+
*
|
|
4
|
+
* `module.registerHooks` — the synchronous ESM/CJS resolution-hook API the
|
|
5
|
+
* embedding-stack resolvers rely on — was added in Node 22.15.0 (and 23.5.0 on
|
|
6
|
+
* the 23.x line). The gitnexus engines floor is `>=22.0.0`, which admits Node
|
|
7
|
+
* 22.0–22.14 AND 23.0–23.4, where the export is absent.
|
|
8
|
+
*
|
|
9
|
+
* In this `"type": "module"` package, a *static named* import of a missing
|
|
10
|
+
* builtin export (`import { registerHooks } from 'node:module'`) is a
|
|
11
|
+
* `SyntaxError` at ESM link time — thrown before any `typeof registerHooks`
|
|
12
|
+
* guard in the module body can run, so every module carrying that import fails
|
|
13
|
+
* to load on those Node versions. This module owns the only namespace import of
|
|
14
|
+
* `node:module` and hands callers a value-or-`undefined` they guard at runtime,
|
|
15
|
+
* so the graceful-degradation path is finally reachable.
|
|
16
|
+
*
|
|
17
|
+
* `@types/node` types `registerHooks` as always-present, so `nodeModule.registerHooks`
|
|
18
|
+
* would type as defined while being `undefined` at runtime on older Node. The
|
|
19
|
+
* `Partial` narrow surfaces the real optionality without an `any` cast.
|
|
20
|
+
*/
|
|
21
|
+
import * as nodeModule from 'node:module';
|
|
22
|
+
/** `module.registerHooks` if this Node exposes it (>=22.15 / >=23.5), else `undefined`. */
|
|
23
|
+
export declare const getRegisterHooks: () => typeof nodeModule.registerHooks | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single access point for `module.registerHooks` (#2372).
|
|
3
|
+
*
|
|
4
|
+
* `module.registerHooks` — the synchronous ESM/CJS resolution-hook API the
|
|
5
|
+
* embedding-stack resolvers rely on — was added in Node 22.15.0 (and 23.5.0 on
|
|
6
|
+
* the 23.x line). The gitnexus engines floor is `>=22.0.0`, which admits Node
|
|
7
|
+
* 22.0–22.14 AND 23.0–23.4, where the export is absent.
|
|
8
|
+
*
|
|
9
|
+
* In this `"type": "module"` package, a *static named* import of a missing
|
|
10
|
+
* builtin export (`import { registerHooks } from 'node:module'`) is a
|
|
11
|
+
* `SyntaxError` at ESM link time — thrown before any `typeof registerHooks`
|
|
12
|
+
* guard in the module body can run, so every module carrying that import fails
|
|
13
|
+
* to load on those Node versions. This module owns the only namespace import of
|
|
14
|
+
* `node:module` and hands callers a value-or-`undefined` they guard at runtime,
|
|
15
|
+
* so the graceful-degradation path is finally reachable.
|
|
16
|
+
*
|
|
17
|
+
* `@types/node` types `registerHooks` as always-present, so `nodeModule.registerHooks`
|
|
18
|
+
* would type as defined while being `undefined` at runtime on older Node. The
|
|
19
|
+
* `Partial` narrow surfaces the real optionality without an `any` cast.
|
|
20
|
+
*/
|
|
21
|
+
import * as nodeModule from 'node:module';
|
|
22
|
+
/** `module.registerHooks` if this Node exposes it (>=22.15 / >=23.5), else `undefined`. */
|
|
23
|
+
export const getRegisterHooks = () => nodeModule.registerHooks;
|
|
@@ -57,11 +57,12 @@
|
|
|
57
57
|
* as before — fine on hoisted layouts. Any failure during installation is
|
|
58
58
|
* swallowed.
|
|
59
59
|
*/
|
|
60
|
-
import {
|
|
60
|
+
import { createRequire } from 'node:module';
|
|
61
61
|
import { pathToFileURL } from 'node:url';
|
|
62
62
|
import { join } from 'node:path';
|
|
63
63
|
import { getEffectiveOnnxRuntimeNodeDir } from './onnxruntime-node-resolver.js';
|
|
64
64
|
import { logger } from '../logger.js';
|
|
65
|
+
import { getRegisterHooks } from './node-module-compat.js';
|
|
65
66
|
let attempted = false;
|
|
66
67
|
/**
|
|
67
68
|
* Compute the file: URL the hook redirects `onnxruntime-common` to.
|
|
@@ -98,8 +99,10 @@ export const ensureOnnxRuntimeCommonResolvable = () => {
|
|
|
98
99
|
// initEmbedder() call, and the hook is process-global — once is enough.
|
|
99
100
|
attempted = true;
|
|
100
101
|
try {
|
|
101
|
-
// Node < 22.15 (the gitnexus engines floor is >= 22.0.0): no
|
|
102
|
-
// hooks API. Degrade gracefully — the import still works on
|
|
102
|
+
// Node < 22.15 / < 23.5 (the gitnexus engines floor is >= 22.0.0): no
|
|
103
|
+
// synchronous hooks API. Degrade gracefully — the import still works on
|
|
104
|
+
// hoisted layouts.
|
|
105
|
+
const registerHooks = getRegisterHooks();
|
|
103
106
|
if (typeof registerHooks !== 'function')
|
|
104
107
|
return;
|
|
105
108
|
const redirectUrl = resolveOnnxRuntimeCommonUrl();
|
|
@@ -51,12 +51,14 @@
|
|
|
51
51
|
* loaded (the probe uses CJS `require.resolve`, which an ESM hook does not
|
|
52
52
|
* affect) — keeping probe and runtime consistent.
|
|
53
53
|
*/
|
|
54
|
-
import {
|
|
54
|
+
import { createRequire } from 'node:module';
|
|
55
55
|
import { pathToFileURL } from 'node:url';
|
|
56
56
|
import { existsSync } from 'node:fs';
|
|
57
57
|
import { join, dirname } from 'node:path';
|
|
58
58
|
import { execFileSync } from 'node:child_process';
|
|
59
59
|
import { logger } from '../logger.js';
|
|
60
|
+
import { getEmbeddingRuntimeDir } from './runtime-install.js';
|
|
61
|
+
import { getRegisterHooks } from './node-module-compat.js';
|
|
60
62
|
const require = createRequire(import.meta.url);
|
|
61
63
|
/**
|
|
62
64
|
* Read a shared object's NEEDED entries, tolerating ldd's non-zero exit when a
|
|
@@ -152,7 +154,18 @@ const resolveDefaultOrtNodeDir = () => {
|
|
|
152
154
|
return dirname(createRequire(transformersMain).resolve('onnxruntime-node/package.json'));
|
|
153
155
|
}
|
|
154
156
|
catch {
|
|
155
|
-
|
|
157
|
+
// On-demand runtime prefix (#2370): when the optional stack was pruned at
|
|
158
|
+
// install time and fetched on demand, the copy that actually loads (via
|
|
159
|
+
// ensureEmbeddingStackResolvable's fallback hook) lives in the prefix — so
|
|
160
|
+
// it IS the effective default and must be the one the CUDA probe inspects.
|
|
161
|
+
try {
|
|
162
|
+
const prefixRequire = createRequire(join(getEmbeddingRuntimeDir(), 'noop.js'));
|
|
163
|
+
const transformersMain = prefixRequire.resolve('@huggingface/transformers');
|
|
164
|
+
return dirname(createRequire(transformersMain).resolve('onnxruntime-node/package.json'));
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
156
169
|
}
|
|
157
170
|
};
|
|
158
171
|
/** gitnexus' own direct top-level onnxruntime-node dir. */
|
|
@@ -161,7 +174,19 @@ const resolveOurOrtNodeDir = () => {
|
|
|
161
174
|
return dirname(require.resolve('onnxruntime-node/package.json'));
|
|
162
175
|
}
|
|
163
176
|
catch {
|
|
164
|
-
|
|
177
|
+
// On-demand runtime prefix (#2370): when gitnexus' own onnxruntime-node was
|
|
178
|
+
// pruned at install time and fetched on demand, the prefix copy IS our
|
|
179
|
+
// effective top-level build — so the CUDA-major redirect must be able to
|
|
180
|
+
// target it (mirrors resolveDefaultOrtNodeDir's fallback above). Without
|
|
181
|
+
// this, `embeddings install --cuda` on a pruned install downloads the GPU
|
|
182
|
+
// binaries but the probe still can't see them and embeddings run on CPU.
|
|
183
|
+
try {
|
|
184
|
+
const prefixRequire = createRequire(join(getEmbeddingRuntimeDir(), 'noop.js'));
|
|
185
|
+
return dirname(prefixRequire.resolve('onnxruntime-node/package.json'));
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
165
190
|
}
|
|
166
191
|
};
|
|
167
192
|
let cached = null;
|
|
@@ -176,7 +201,7 @@ const decide = () => {
|
|
|
176
201
|
// major is still probed: a CUDA-12 host on Node 22.0–22.14 whose default
|
|
177
202
|
// build already matches must keep auto-selecting the GPU exactly as it did
|
|
178
203
|
// before this redirect existed.
|
|
179
|
-
const canRedirect = typeof
|
|
204
|
+
const canRedirect = typeof getRegisterHooks() === 'function';
|
|
180
205
|
const systemMajor = detectSystemCudaMajor();
|
|
181
206
|
// `defaultDir` resolving is NOT a precondition for checking `ourDir` below —
|
|
182
207
|
// if transformers' own resolution fails outright (defaultMajor stays null),
|
|
@@ -264,8 +289,9 @@ export const ensureOnnxRuntimeNodeMatchesSystem = () => {
|
|
|
264
289
|
return;
|
|
265
290
|
attempted = true;
|
|
266
291
|
try {
|
|
292
|
+
const registerHooks = getRegisterHooks();
|
|
267
293
|
if (typeof registerHooks !== 'function')
|
|
268
|
-
return; // Node < 22.15: graceful no-op
|
|
294
|
+
return; // Node < 22.15 / < 23.5: graceful no-op
|
|
269
295
|
const d = decide();
|
|
270
296
|
if (!d.redirect || !d.effectiveDir)
|
|
271
297
|
return;
|