Merge pull request #1561 from segmentationf4u1t/fix/windows-segfault-minimal
fix: prevent Windows ORT preload crash
This commit is contained in:
@@ -103,6 +103,7 @@
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-ai": "catalog:",
|
||||
"fastembed": "catalog:",
|
||||
"onnxruntime-node": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
@@ -278,6 +279,7 @@
|
||||
"lucide-react": "^1.16.0",
|
||||
"marked": "^18.0.4",
|
||||
"markit-ai": "0.5.3",
|
||||
"onnxruntime-node": "1.24.3",
|
||||
"openai": "^6.39.0",
|
||||
"partial-json": "^0.1.7",
|
||||
"postcss": "^8.5.15",
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
"lucide-react": "^1.16.0",
|
||||
"marked": "^18.0.4",
|
||||
"markit-ai": "0.5.3",
|
||||
"onnxruntime-node": "1.24.3",
|
||||
"openai": "^6.39.0",
|
||||
"partial-json": "^0.1.7",
|
||||
"postcss": "^8.5.15",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed Windows startup crashes by keeping fastembed's older ONNX Runtime binding lazy until local embeddings are used.
|
||||
- Fixed a segfault at startup from eagerly loading fastembed: importing the embeddings module pulled in `fastembed`, which eagerly loads the `onnxruntime-node` native addon. The import is now deferred until a local fastembed model is actually initialized, so API-model, disabled-embeddings, and test runtimes never load the native addon.
|
||||
|
||||
## [15.6.0] - 2026-05-30
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-ai": "catalog:",
|
||||
"fastembed": "catalog:"
|
||||
"fastembed": "catalog:",
|
||||
"onnxruntime-node": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { mkdirSync } from "node:fs";
|
||||
import type { EmbeddingModel } from "fastembed";
|
||||
import { createRequire } from "node:module";
|
||||
import type { EmbeddingModel, FlagEmbedding } from "fastembed";
|
||||
import { getMnemosyneRuntimeOptions, resolveEmbeddingProvider } from "./runtime-options";
|
||||
|
||||
export type Vector = number[];
|
||||
@@ -24,8 +25,14 @@ type LocalModelInitOptions = {
|
||||
};
|
||||
type LocalModelInitializer = (options: LocalModelInitOptions) => Promise<LocalEmbeddingModel>;
|
||||
|
||||
interface FastembedRuntime {
|
||||
EmbeddingModel: typeof EmbeddingModel;
|
||||
FlagEmbedding: typeof FlagEmbedding;
|
||||
}
|
||||
|
||||
const FASTEMBED_CACHE_DIR = `${process.env.HOME ?? ""}/.hermes/cache/fastembed`;
|
||||
const QUERY_CACHE_MAX = 512;
|
||||
const sourceRequire = createRequire(import.meta.url);
|
||||
|
||||
let providerOverride: EmbeddingProvider | null = null;
|
||||
let localModelPromise: Promise<LocalEmbeddingModel> | null = null;
|
||||
@@ -33,12 +40,14 @@ let localModelInitializer: LocalModelInitializer = defaultLocalModelInitializer;
|
||||
let apiCallCount = 0;
|
||||
const queryCache = new Map<string, Vector>();
|
||||
|
||||
async function defaultLocalModelInitializer(options: LocalModelInitOptions): Promise<LocalEmbeddingModel> {
|
||||
// Lazily pull in fastembed here — its module eagerly imports `onnxruntime-node`,
|
||||
// whose native addon load segfaults in some runtimes. Deferring to the actual
|
||||
// model init keeps API-model, disabled, and test runtimes from ever loading it.
|
||||
const { FlagEmbedding } = await import("fastembed");
|
||||
return FlagEmbedding.init(options) as Promise<LocalEmbeddingModel>;
|
||||
function loadFastembedRuntime(): FastembedRuntime {
|
||||
// Preload ORT 1.24 before fastembed's ORT 1.21 binding to avoid Windows DLL reuse crashes.
|
||||
sourceRequire("onnxruntime-node");
|
||||
return sourceRequire("fastembed") as FastembedRuntime;
|
||||
}
|
||||
|
||||
function defaultLocalModelInitializer(options: LocalModelInitOptions): Promise<LocalEmbeddingModel> {
|
||||
return loadFastembedRuntime().FlagEmbedding.init(options);
|
||||
}
|
||||
|
||||
function activeEmbeddingOptions() {
|
||||
|
||||
Reference in New Issue
Block a user