@oh-my-pi/pi-mnemopi 16.0.5 → 16.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.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [16.0.6] - 2026-06-18
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Forced the on-demand fastembed runtime install to override fastembed's archived `onnxruntime-node@1.21.0` transitive pin with Mnemopi's `onnxruntime-node@1.26.0` pin, fixing local embedding startup on macOS ARM64. ([#2920](https://github.com/can1357/oh-my-pi/issues/2920))
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Updated OpenRouter request headers to use standard shared headers from the pi-ai package
|
|
14
|
+
|
|
5
15
|
## [16.0.5] - 2026-06-17
|
|
6
16
|
|
|
7
17
|
### Fixed
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
+
import { type RuntimeInstallSpec } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type * as Fastembed from "fastembed";
|
|
2
3
|
type FastembedModule = typeof Fastembed;
|
|
4
|
+
/** Runtime install inputs for the optional fastembed embedding stack. */
|
|
5
|
+
export interface FastembedRuntimeInstallPlan {
|
|
6
|
+
/** Cache directory key; changes when runtime resolution policy changes. */
|
|
7
|
+
versionKey: string;
|
|
8
|
+
/** Dependency graph written to the runtime cache package manifest. */
|
|
9
|
+
install: RuntimeInstallSpec;
|
|
10
|
+
}
|
|
11
|
+
/** Build the deterministic fastembed runtime install plan used by local embeddings. */
|
|
12
|
+
export declare function fastembedRuntimeInstallPlan(): FastembedRuntimeInstallPlan;
|
|
3
13
|
export declare function loadFastembed(): Promise<FastembedModule>;
|
|
4
14
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-mnemopi",
|
|
4
|
-
"version": "16.0.
|
|
4
|
+
"version": "16.0.6",
|
|
5
5
|
"description": "Local SQLite memory engine for Oh My Pi agents",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"fmt": "biome format --write ."
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@oh-my-pi/pi-ai": "16.0.
|
|
43
|
-
"@oh-my-pi/pi-catalog": "16.0.
|
|
44
|
-
"@oh-my-pi/pi-utils": "16.0.
|
|
42
|
+
"@oh-my-pi/pi-ai": "16.0.6",
|
|
43
|
+
"@oh-my-pi/pi-catalog": "16.0.6",
|
|
44
|
+
"@oh-my-pi/pi-utils": "16.0.6",
|
|
45
45
|
"lru-cache": "11.5.1"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
package/src/core/embeddings.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mkdirSync } from "node:fs";
|
|
2
|
-
import { type ApiKey, ProviderHttpError, withAuth } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import { type ApiKey, getOpenRouterHeaders, ProviderHttpError, withAuth } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { hostMatchesUrl } from "@oh-my-pi/pi-catalog/hosts";
|
|
4
4
|
import {
|
|
5
5
|
$env,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
} from "@oh-my-pi/pi-utils";
|
|
12
12
|
import type { EmbeddingModel } from "fastembed";
|
|
13
13
|
import { LRUCache } from "lru-cache/raw";
|
|
14
|
-
import packageJson from "../../package.json" with { type: "json" };
|
|
15
14
|
import { loadFastembed } from "./fastembed-runtime";
|
|
16
15
|
import {
|
|
17
16
|
type EmbeddingOutput,
|
|
@@ -268,10 +267,7 @@ async function embedApi(texts: readonly string[]): Promise<EmbeddingMatrix | nul
|
|
|
268
267
|
const response = await withAuth(apiKey, async key => {
|
|
269
268
|
const headers: Record<string, string> = {
|
|
270
269
|
"Content-Type": "application/json",
|
|
271
|
-
|
|
272
|
-
"HTTP-Referer": "https://omp.sh/",
|
|
273
|
-
"X-OpenRouter-Title": "Oh-My-Pi",
|
|
274
|
-
"X-OpenRouter-Categories": "cli-agent",
|
|
270
|
+
...getOpenRouterHeaders(),
|
|
275
271
|
};
|
|
276
272
|
if (key !== "") {
|
|
277
273
|
headers.Authorization = `Bearer ${key}`;
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
getFastembedRuntimeDir,
|
|
6
6
|
installRuntimeModuleResolver,
|
|
7
7
|
logger,
|
|
8
|
+
type RuntimeInstallSpec,
|
|
8
9
|
resolveRuntimeModule,
|
|
9
10
|
} from "@oh-my-pi/pi-utils";
|
|
10
11
|
import type * as Fastembed from "fastembed";
|
|
@@ -12,13 +13,21 @@ import packageManifest from "../../package.json" with { type: "json" };
|
|
|
12
13
|
|
|
13
14
|
type FastembedModule = typeof Fastembed;
|
|
14
15
|
|
|
16
|
+
/** Runtime install inputs for the optional fastembed embedding stack. */
|
|
17
|
+
export interface FastembedRuntimeInstallPlan {
|
|
18
|
+
/** Cache directory key; changes when runtime resolution policy changes. */
|
|
19
|
+
versionKey: string;
|
|
20
|
+
/** Dependency graph written to the runtime cache package manifest. */
|
|
21
|
+
install: RuntimeInstallSpec;
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
/**
|
|
16
25
|
* `fastembed` and `onnxruntime-node` are optional peers (~270MB of native
|
|
17
26
|
* assets across platforms), never bundled and never installed eagerly. When
|
|
18
27
|
* the direct import cannot resolve — bundled `dist/cli.js`, compiled binary,
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* from there (#2389).
|
|
28
|
+
* a consumer that skipped the optional peers, or a native loader failure from
|
|
29
|
+
* fastembed's nested ORT — the pinned pair is `bun install`ed into a
|
|
30
|
+
* per-version runtime cache on first use and loaded from there (#2389, #2920).
|
|
22
31
|
*
|
|
23
32
|
* The pins live in `peerDependencies` as exact versions (not `catalog:`) so
|
|
24
33
|
* this module reads concrete specs even when the workspace manifest is
|
|
@@ -27,6 +36,16 @@ type FastembedModule = typeof Fastembed;
|
|
|
27
36
|
const FASTEMBED_SPEC = packageManifest.peerDependencies.fastembed;
|
|
28
37
|
const ORT_SPEC = packageManifest.peerDependencies["onnxruntime-node"];
|
|
29
38
|
|
|
39
|
+
/** Build the deterministic fastembed runtime install plan used by local embeddings. */
|
|
40
|
+
export function fastembedRuntimeInstallPlan(): FastembedRuntimeInstallPlan {
|
|
41
|
+
return {
|
|
42
|
+
versionKey: `fastembed-${FASTEMBED_SPEC}_ort-${ORT_SPEC}_forced-ort`.replace(/[^A-Za-z0-9._-]/g, "_"),
|
|
43
|
+
install: {
|
|
44
|
+
dependencies: { fastembed: FASTEMBED_SPEC, "onnxruntime-node": ORT_SPEC },
|
|
45
|
+
overrides: { "onnxruntime-common": ORT_SPEC, "onnxruntime-node": ORT_SPEC },
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
30
49
|
let fastembedLoad: Promise<FastembedModule> | null = null;
|
|
31
50
|
|
|
32
51
|
export function loadFastembed(): Promise<FastembedModule> {
|
|
@@ -42,15 +61,15 @@ async function loadFastembedOnce(): Promise<FastembedModule> {
|
|
|
42
61
|
// native addons and may be absent at runtime — a static import would load
|
|
43
62
|
// the addon at module-init and crash every consumer without the peers.
|
|
44
63
|
try {
|
|
45
|
-
// Preload ORT
|
|
64
|
+
// Preload the pinned ORT before fastembed's nested ORT — only on Windows,
|
|
46
65
|
// where loading the older binding first triggers a DLL-reuse crash.
|
|
47
66
|
if (process.platform === "win32") {
|
|
48
67
|
await import("onnxruntime-node");
|
|
49
68
|
}
|
|
50
69
|
return await import("fastembed");
|
|
51
70
|
} catch (error) {
|
|
52
|
-
if (!
|
|
53
|
-
logger.debug("mnemopi: fastembed not
|
|
71
|
+
if (!isRecoverableFastembedLoadError(error)) throw error;
|
|
72
|
+
logger.debug("mnemopi: fastembed not loadable, using on-demand runtime install", {
|
|
54
73
|
error: String(error),
|
|
55
74
|
});
|
|
56
75
|
return loadFromRuntimeInstall();
|
|
@@ -58,10 +77,10 @@ async function loadFastembedOnce(): Promise<FastembedModule> {
|
|
|
58
77
|
}
|
|
59
78
|
|
|
60
79
|
async function loadFromRuntimeInstall(): Promise<FastembedModule> {
|
|
61
|
-
const
|
|
80
|
+
const plan = fastembedRuntimeInstallPlan();
|
|
62
81
|
const runtimeDir = await ensureRuntimeInstalled({
|
|
63
|
-
runtimeDir: path.join(getFastembedRuntimeDir(), versionKey),
|
|
64
|
-
install:
|
|
82
|
+
runtimeDir: path.join(getFastembedRuntimeDir(), plan.versionKey),
|
|
83
|
+
install: plan.install,
|
|
65
84
|
probePackage: "fastembed",
|
|
66
85
|
});
|
|
67
86
|
const nodeModules = path.join(runtimeDir, "node_modules");
|
|
@@ -80,10 +99,10 @@ async function loadFromRuntimeInstall(): Promise<FastembedModule> {
|
|
|
80
99
|
return requireRuntime(entry) as FastembedModule;
|
|
81
100
|
}
|
|
82
101
|
|
|
83
|
-
function
|
|
102
|
+
function isRecoverableFastembedLoadError(error: unknown): boolean {
|
|
84
103
|
if (typeof error !== "object" || error === null) return false;
|
|
85
104
|
const { name, code, message } = error as { name?: unknown; code?: unknown; message?: unknown };
|
|
86
105
|
if (name === "ResolveMessage") return true;
|
|
87
|
-
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
|
|
106
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND" || code === "ERR_DLOPEN_FAILED") return true;
|
|
88
107
|
return typeof message === "string" && /cannot find (module|package)/i.test(message);
|
|
89
108
|
}
|