@mneme-ai/embeddings 0.18.3 → 0.19.1
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/bundled.d.ts +40 -0
- package/dist/bundled.d.ts.map +1 -0
- package/dist/bundled.js +108 -0
- package/dist/bundled.js.map +1 -0
- package/dist/bundled.test.d.ts +2 -0
- package/dist/bundled.test.d.ts.map +1 -0
- package/dist/bundled.test.js +45 -0
- package/dist/bundled.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/resolve.d.ts +18 -7
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +48 -13
- package/dist/resolve.js.map +1 -1
- package/dist/resolve.test.d.ts +2 -0
- package/dist/resolve.test.d.ts.map +1 -0
- package/dist/resolve.test.js +70 -0
- package/dist/resolve.test.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { EmbeddingProvider } from "@mneme-ai/core";
|
|
2
|
+
export interface BundledOptions {
|
|
3
|
+
/** HuggingFace repo id. all-MiniLM-L6-v2 = 25MB / 384-dim — best size/quality. */
|
|
4
|
+
model?: string;
|
|
5
|
+
/** Override cache dir. Default: ~/.cache/mneme/models. */
|
|
6
|
+
cacheDir?: string;
|
|
7
|
+
/** Hook for download/load progress (lazy load can take ~5–60s on cold start). */
|
|
8
|
+
onProgress?: (info: {
|
|
9
|
+
status: string;
|
|
10
|
+
loaded?: number;
|
|
11
|
+
total?: number;
|
|
12
|
+
file?: string;
|
|
13
|
+
}) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare class BundledEmbedder implements EmbeddingProvider {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly dimensions: number;
|
|
18
|
+
private readonly model;
|
|
19
|
+
private readonly cacheDir;
|
|
20
|
+
private readonly onProgress?;
|
|
21
|
+
private extractor;
|
|
22
|
+
private loadPromise;
|
|
23
|
+
constructor(opts?: BundledOptions);
|
|
24
|
+
/** Cheap pre-flight — instantiates the pipeline (downloads if needed) and
|
|
25
|
+
* runs a 1-token sanity embed. Use BEFORE the long indexer loop. */
|
|
26
|
+
verify(): Promise<{
|
|
27
|
+
ok: true;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
reason: string;
|
|
31
|
+
remedy: string;
|
|
32
|
+
}>;
|
|
33
|
+
embed(texts: string[]): Promise<Float32Array[]>;
|
|
34
|
+
/** Lazy load — done at most once, even under concurrent embed() calls. */
|
|
35
|
+
private load;
|
|
36
|
+
private bootPipeline;
|
|
37
|
+
}
|
|
38
|
+
/** Default cache dir: ~/.cache/mneme/models. User can `rm -rf` to reset. */
|
|
39
|
+
export declare function defaultCacheDir(): string;
|
|
40
|
+
//# sourceMappingURL=bundled.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundled.d.ts","sourceRoot":"","sources":["../src/bundled.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACjG;AAeD,qBAAa,eAAgB,YAAW,iBAAiB;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAA+B;IAC3D,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,WAAW,CAA0C;gBAEjD,IAAI,GAAE,cAAmB;IAQrC;yEACqE;IAC/D,MAAM,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB/E,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAiBrD,0EAA0E;YAC5D,IAAI;YAQJ,YAAY;CAmC3B;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
|
package/dist/bundled.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BundledEmbedder — zero-install WASM embeddings.
|
|
3
|
+
*
|
|
4
|
+
* Uses @xenova/transformers (pure JS + ONNX-WASM, no native deps) so the
|
|
5
|
+
* tool runs on Windows / Mac / Linux out of the box. The model file is
|
|
6
|
+
* lazy-downloaded on first use (~25MB to a local cache), giving users a
|
|
7
|
+
* "★★★ semantic quality" path without installing Ollama.
|
|
8
|
+
*
|
|
9
|
+
* Fallback order in resolveEmbedder():
|
|
10
|
+
* OpenAI (★★★★★ paid) → Ollama (★★★★ free local)
|
|
11
|
+
* → Bundled WASM (★★★ free, no install) → Hash (★★ deterministic)
|
|
12
|
+
*/
|
|
13
|
+
import { homedir } from "node:os";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { mkdirSync } from "node:fs";
|
|
16
|
+
const DEFAULT_MODEL = "Xenova/all-MiniLM-L6-v2";
|
|
17
|
+
const DEFAULT_DIMS = 384;
|
|
18
|
+
export class BundledEmbedder {
|
|
19
|
+
name;
|
|
20
|
+
dimensions;
|
|
21
|
+
model;
|
|
22
|
+
cacheDir;
|
|
23
|
+
onProgress;
|
|
24
|
+
extractor = null;
|
|
25
|
+
loadPromise = null;
|
|
26
|
+
constructor(opts = {}) {
|
|
27
|
+
this.model = opts.model ?? DEFAULT_MODEL;
|
|
28
|
+
this.dimensions = DEFAULT_DIMS;
|
|
29
|
+
this.cacheDir = opts.cacheDir ?? defaultCacheDir();
|
|
30
|
+
this.onProgress = opts.onProgress;
|
|
31
|
+
this.name = `bundled:${this.model}`;
|
|
32
|
+
}
|
|
33
|
+
/** Cheap pre-flight — instantiates the pipeline (downloads if needed) and
|
|
34
|
+
* runs a 1-token sanity embed. Use BEFORE the long indexer loop. */
|
|
35
|
+
async verify() {
|
|
36
|
+
try {
|
|
37
|
+
await this.load();
|
|
38
|
+
await this.embed(["ok"]);
|
|
39
|
+
return { ok: true };
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const msg = err.message ?? String(err);
|
|
43
|
+
return {
|
|
44
|
+
ok: false,
|
|
45
|
+
reason: `Bundled WASM model failed: ${msg}`,
|
|
46
|
+
remedy: "First run requires internet to download ~25MB. " +
|
|
47
|
+
"If you're offline, set --embedder hash to use the deterministic fallback.",
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async embed(texts) {
|
|
52
|
+
// Fast path: empty input never triggers the lazy load — keeps tests
|
|
53
|
+
// and trivial calls free of the 25MB model download.
|
|
54
|
+
if (texts.length === 0)
|
|
55
|
+
return [];
|
|
56
|
+
const ext = await this.load();
|
|
57
|
+
const out = new Array(texts.length);
|
|
58
|
+
// Sequential: the WASM pipeline isn't designed for concurrency; one at a
|
|
59
|
+
// time is the predictable, memory-safe path. For 1000 chunks this takes
|
|
60
|
+
// ~10–20s on consumer laptops — acceptable for a one-time index.
|
|
61
|
+
for (let i = 0; i < texts.length; i++) {
|
|
62
|
+
const result = await ext(texts[i], { pooling: "mean", normalize: true });
|
|
63
|
+
// result.data is Float32Array-like — copy into a fresh typed array.
|
|
64
|
+
out[i] = Float32Array.from(result.data);
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/** Lazy load — done at most once, even under concurrent embed() calls. */
|
|
69
|
+
async load() {
|
|
70
|
+
if (this.extractor)
|
|
71
|
+
return this.extractor;
|
|
72
|
+
if (this.loadPromise)
|
|
73
|
+
return this.loadPromise;
|
|
74
|
+
this.loadPromise = this.bootPipeline();
|
|
75
|
+
this.extractor = await this.loadPromise;
|
|
76
|
+
return this.extractor;
|
|
77
|
+
}
|
|
78
|
+
async bootPipeline() {
|
|
79
|
+
// Ensure cache dir exists so transformers.js can write the ONNX model.
|
|
80
|
+
try {
|
|
81
|
+
mkdirSync(this.cacheDir, { recursive: true });
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
/* permission errors surface later via the pipeline */
|
|
85
|
+
}
|
|
86
|
+
// Dynamic import — keeps the heavy WASM init out of cold-start path
|
|
87
|
+
// for users who never touch this provider.
|
|
88
|
+
const transformers = (await import("@xenova/transformers"));
|
|
89
|
+
transformers.env.cacheDir = this.cacheDir;
|
|
90
|
+
transformers.env.allowRemoteModels = true;
|
|
91
|
+
const onProgress = this.onProgress;
|
|
92
|
+
return await transformers.pipeline("feature-extraction", this.model, {
|
|
93
|
+
progress_callback: onProgress
|
|
94
|
+
? (info) => onProgress({
|
|
95
|
+
status: String(info["status"] ?? ""),
|
|
96
|
+
loaded: typeof info["loaded"] === "number" ? info["loaded"] : undefined,
|
|
97
|
+
total: typeof info["total"] === "number" ? info["total"] : undefined,
|
|
98
|
+
file: typeof info["file"] === "string" ? info["file"] : undefined,
|
|
99
|
+
})
|
|
100
|
+
: undefined,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Default cache dir: ~/.cache/mneme/models. User can `rm -rf` to reset. */
|
|
105
|
+
export function defaultCacheDir() {
|
|
106
|
+
return join(homedir(), ".cache", "mneme", "models");
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=bundled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundled.js","sourceRoot":"","sources":["../src/bundled.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundled.test.d.ts","sourceRoot":"","sources":["../src/bundled.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for BundledEmbedder.
|
|
3
|
+
*
|
|
4
|
+
* Strategy: avoid downloading the model in CI by NOT calling embed()/verify()
|
|
5
|
+
* (which would trigger the lazy load + ~25MB download). Test only the
|
|
6
|
+
* synchronous shape — constructor, name, dimensions, defaults — plus that the
|
|
7
|
+
* EmbeddingProvider contract is satisfied. Real-world end-to-end is covered by
|
|
8
|
+
* the smoke test in CHANGELOG and was verified at v0.19.0 ship.
|
|
9
|
+
*/
|
|
10
|
+
import { describe, it, expect } from "vitest";
|
|
11
|
+
import { BundledEmbedder, defaultCacheDir } from "./bundled.js";
|
|
12
|
+
describe("BundledEmbedder — shape + defaults (no network)", () => {
|
|
13
|
+
it("uses Xenova/all-MiniLM-L6-v2 with 384 dims by default", () => {
|
|
14
|
+
const e = new BundledEmbedder();
|
|
15
|
+
expect(e.name).toBe("bundled:Xenova/all-MiniLM-L6-v2");
|
|
16
|
+
expect(e.dimensions).toBe(384);
|
|
17
|
+
});
|
|
18
|
+
it("accepts a custom model and reflects it in the name", () => {
|
|
19
|
+
const e = new BundledEmbedder({ model: "Xenova/bge-small-en" });
|
|
20
|
+
expect(e.name).toBe("bundled:Xenova/bge-small-en");
|
|
21
|
+
});
|
|
22
|
+
it("name uses the bundled: prefix so resolveEmbedder can route it", () => {
|
|
23
|
+
const e = new BundledEmbedder();
|
|
24
|
+
expect(e.name.startsWith("bundled:")).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it("defaultCacheDir lives under the user home — predictable + clearable", () => {
|
|
27
|
+
const dir = defaultCacheDir();
|
|
28
|
+
expect(dir).toContain("mneme");
|
|
29
|
+
expect(dir).toContain("models");
|
|
30
|
+
// Not absolute equality (per-OS) but should be an absolute path
|
|
31
|
+
expect(dir.length).toBeGreaterThan(5);
|
|
32
|
+
});
|
|
33
|
+
it("constructor never throws even if @xenova/transformers can't be loaded", () => {
|
|
34
|
+
// The lazy-import is in load(), not the constructor — so creating the
|
|
35
|
+
// instance is always safe (a deliberate design choice for resolveEmbedder).
|
|
36
|
+
expect(() => new BundledEmbedder()).not.toThrow();
|
|
37
|
+
expect(() => new BundledEmbedder({ cacheDir: "/tmp/x" })).not.toThrow();
|
|
38
|
+
});
|
|
39
|
+
it("embed([]) returns [] without loading the pipeline (cheap fast-path)", async () => {
|
|
40
|
+
const e = new BundledEmbedder();
|
|
41
|
+
const out = await e.embed([]);
|
|
42
|
+
expect(out).toEqual([]);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=bundled.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundled.test.js","sourceRoot":"","sources":["../src/bundled.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEhE,QAAQ,CAAC,iDAAiD,EAAE,GAAG,EAAE;IAC/D,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACvD,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAChC,gEAAgE;QAChE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,sEAAsE;QACtE,4EAA4E;QAC5E,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
package/dist/resolve.d.ts
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import type { EmbeddingProvider } from "@mneme-ai/core";
|
|
2
|
+
import { BundledEmbedder } from "./bundled.js";
|
|
2
3
|
export interface ResolveOptions {
|
|
3
|
-
|
|
4
|
+
/**
|
|
5
|
+
* `auto` (default) walks the fallback ladder so the user gets the highest
|
|
6
|
+
* quality embedder that's actually available, with hash always reachable
|
|
7
|
+
* as the last resort:
|
|
8
|
+
*
|
|
9
|
+
* 1. OpenAI (★★★★★ paid) — if OPENAI_API_KEY is set
|
|
10
|
+
* 2. Ollama (★★★★ free) — if /api/tags responds + model pulled
|
|
11
|
+
* 3. Bundled (★★★ free) — WASM model, ~25MB lazy download
|
|
12
|
+
* 4. Hash (★★) — deterministic, zero deps, always works
|
|
13
|
+
*
|
|
14
|
+
* Pass an explicit value to skip the ladder.
|
|
15
|
+
*/
|
|
16
|
+
provider?: "auto" | "ollama" | "openai" | "bundled" | "hash";
|
|
4
17
|
model?: string;
|
|
5
18
|
apiKey?: string;
|
|
6
19
|
baseUrl?: string;
|
|
20
|
+
/** Optional callback for bundled-model download progress. */
|
|
21
|
+
onBundledProgress?: NonNullable<ConstructorParameters<typeof BundledEmbedder>[0]>["onProgress"];
|
|
7
22
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Auto-select an embedder.
|
|
10
|
-
*
|
|
11
|
-
* auto: prefer Ollama → OpenAI (if key) → hash fallback
|
|
12
|
-
* ollama / openai / hash: explicit
|
|
13
|
-
*/
|
|
14
23
|
export declare function resolveEmbedder(opts?: ResolveOptions): Promise<EmbeddingProvider>;
|
|
24
|
+
/** Helper for callers that explicitly want the deterministic offline path. */
|
|
25
|
+
export declare function hashEmbedder(): EmbeddingProvider;
|
|
15
26
|
//# sourceMappingURL=resolve.d.ts.map
|
package/dist/resolve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,WAAW,CAC7B,qBAAqB,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,CACjD,CAAC,YAAY,CAAC,CAAC;CACjB;AAED,wBAAsB,eAAe,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgE3F;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,IAAI,iBAAiB,CAEhD"}
|
package/dist/resolve.js
CHANGED
|
@@ -1,29 +1,64 @@
|
|
|
1
1
|
import { OllamaEmbedder } from "./ollama.js";
|
|
2
2
|
import { OpenAIEmbedder } from "./openai.js";
|
|
3
|
+
import { BundledEmbedder } from "./bundled.js";
|
|
3
4
|
import { HashEmbedder } from "./hash.js";
|
|
4
|
-
/**
|
|
5
|
-
* Auto-select an embedder.
|
|
6
|
-
*
|
|
7
|
-
* auto: prefer Ollama → OpenAI (if key) → hash fallback
|
|
8
|
-
* ollama / openai / hash: explicit
|
|
9
|
-
*/
|
|
10
5
|
export async function resolveEmbedder(opts = {}) {
|
|
11
6
|
const provider = opts.provider ?? "auto";
|
|
12
|
-
|
|
7
|
+
// ── Explicit picks ──────────────────────────────────────────────────
|
|
8
|
+
if (provider === "openai") {
|
|
9
|
+
const apiKey = opts.apiKey ?? process.env["OPENAI_API_KEY"];
|
|
10
|
+
if (!apiKey) {
|
|
11
|
+
throw new Error("No OpenAI API key. Set OPENAI_API_KEY or pass --api-key.");
|
|
12
|
+
}
|
|
13
|
+
return new OpenAIEmbedder({ apiKey, model: opts.model, baseUrl: opts.baseUrl });
|
|
14
|
+
}
|
|
15
|
+
if (provider === "ollama") {
|
|
13
16
|
const ollama = new OllamaEmbedder({ model: opts.model, baseUrl: opts.baseUrl });
|
|
14
17
|
if (await ollama.ping())
|
|
15
18
|
return ollama;
|
|
16
|
-
|
|
17
|
-
throw new Error(`Ollama not reachable at ${opts.baseUrl ?? "http://127.0.0.1:11434"}. Start it with: ollama serve`);
|
|
18
|
-
}
|
|
19
|
+
throw new Error(`Ollama not reachable at ${opts.baseUrl ?? "http://127.0.0.1:11434"}. Start it with: ollama serve`);
|
|
19
20
|
}
|
|
21
|
+
if (provider === "bundled") {
|
|
22
|
+
return new BundledEmbedder({ model: opts.model, onProgress: opts.onBundledProgress });
|
|
23
|
+
}
|
|
24
|
+
if (provider === "hash") {
|
|
25
|
+
return new HashEmbedder();
|
|
26
|
+
}
|
|
27
|
+
// ── auto: walk the ladder, NEVER block the user ────────────────────
|
|
28
|
+
// Each step is health-checked. A failing step quietly falls to the next.
|
|
29
|
+
// The user always ends up with a working embedder (worst case = hash).
|
|
30
|
+
// 1. OpenAI key wins — best quality, no install.
|
|
20
31
|
const apiKey = opts.apiKey ?? process.env["OPENAI_API_KEY"];
|
|
21
|
-
if (
|
|
32
|
+
if (apiKey) {
|
|
22
33
|
return new OpenAIEmbedder({ apiKey, model: opts.model, baseUrl: opts.baseUrl });
|
|
23
34
|
}
|
|
24
|
-
if
|
|
25
|
-
|
|
35
|
+
// 2. Ollama — only if a SHORT sanity embed succeeds. We had real users
|
|
36
|
+
// where /api/tags responded but /api/embeddings hung for minutes; that
|
|
37
|
+
// used to surface as a hard error. Now we just fall through silently.
|
|
38
|
+
const ollama = new OllamaEmbedder({
|
|
39
|
+
model: opts.model,
|
|
40
|
+
baseUrl: opts.baseUrl,
|
|
41
|
+
timeoutMs: 10_000, // short for the auto-detect probe — full timeout used after
|
|
42
|
+
});
|
|
43
|
+
if (await ollama.ping()) {
|
|
44
|
+
const ver = await ollama.verify();
|
|
45
|
+
if (ver.ok) {
|
|
46
|
+
// Reset to the normal long timeout for the real workload.
|
|
47
|
+
return new OllamaEmbedder({ model: opts.model, baseUrl: opts.baseUrl });
|
|
48
|
+
}
|
|
49
|
+
// Ollama is reachable but unhealthy — explicitly skip and try the next step.
|
|
50
|
+
// We swallow the reason: the user picked auto, they want it to JUST WORK.
|
|
26
51
|
}
|
|
52
|
+
// 3. Bundled WASM — ★★★, ~25MB auto-download. Doesn't need a "ping" — the
|
|
53
|
+
// module is in the npm install. We instantiate eagerly; the actual model
|
|
54
|
+
// download happens lazily on first embed (or via verify()).
|
|
55
|
+
return new BundledEmbedder({ model: opts.model, onProgress: opts.onBundledProgress });
|
|
56
|
+
// 4. Hash is the FINAL escape hatch — only chosen by explicit `--embedder hash`
|
|
57
|
+
// or by callers that don't want network/download. Auto-detect prefers
|
|
58
|
+
// bundled because it returns true semantic vectors with no setup.
|
|
59
|
+
}
|
|
60
|
+
/** Helper for callers that explicitly want the deterministic offline path. */
|
|
61
|
+
export function hashEmbedder() {
|
|
27
62
|
return new HashEmbedder();
|
|
28
63
|
}
|
|
29
64
|
//# sourceMappingURL=resolve.js.map
|
package/dist/resolve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.test.d.ts","sourceRoot":"","sources":["../src/resolve.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the resolveEmbedder() fallback ladder.
|
|
3
|
+
*
|
|
4
|
+
* Strategy: stub network-touching methods (Ollama.ping, Ollama.verify) so
|
|
5
|
+
* tests run offline + deterministically. We're NOT validating real Ollama
|
|
6
|
+
* or model downloads here — the ladder logic is what matters.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
9
|
+
import { resolveEmbedder } from "./resolve.js";
|
|
10
|
+
import { OllamaEmbedder } from "./ollama.js";
|
|
11
|
+
describe("resolveEmbedder — auto fallback ladder (never blocks user)", () => {
|
|
12
|
+
const origKey = process.env["OPENAI_API_KEY"];
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
delete process.env["OPENAI_API_KEY"];
|
|
15
|
+
vi.spyOn(OllamaEmbedder.prototype, "ping").mockResolvedValue(false);
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
if (origKey !== undefined)
|
|
19
|
+
process.env["OPENAI_API_KEY"] = origKey;
|
|
20
|
+
else
|
|
21
|
+
delete process.env["OPENAI_API_KEY"];
|
|
22
|
+
vi.restoreAllMocks();
|
|
23
|
+
});
|
|
24
|
+
it("auto picks OpenAI when OPENAI_API_KEY is set", async () => {
|
|
25
|
+
process.env["OPENAI_API_KEY"] = "sk-test-key";
|
|
26
|
+
const e = await resolveEmbedder({ provider: "auto" });
|
|
27
|
+
expect(e.name.startsWith("openai:")).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
it("auto picks Ollama when ping AND verify both succeed", async () => {
|
|
30
|
+
vi.spyOn(OllamaEmbedder.prototype, "ping").mockResolvedValue(true);
|
|
31
|
+
vi.spyOn(OllamaEmbedder.prototype, "verify").mockResolvedValue({ ok: true });
|
|
32
|
+
const e = await resolveEmbedder({ provider: "auto" });
|
|
33
|
+
expect(e.name.startsWith("ollama:")).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
it("auto SKIPS Ollama when ping succeeds but verify fails (the v0.19 fix)", async () => {
|
|
36
|
+
vi.spyOn(OllamaEmbedder.prototype, "ping").mockResolvedValue(true);
|
|
37
|
+
vi.spyOn(OllamaEmbedder.prototype, "verify").mockResolvedValue({
|
|
38
|
+
ok: false,
|
|
39
|
+
reason: "embed timed out",
|
|
40
|
+
remedy: "warm up model",
|
|
41
|
+
});
|
|
42
|
+
const e = await resolveEmbedder({ provider: "auto" });
|
|
43
|
+
// Falls through to bundled — the user's pre-v0.19 hang is GONE.
|
|
44
|
+
expect(e.name.startsWith("bundled:")).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
it("auto picks bundled WASM when nothing else is available", async () => {
|
|
47
|
+
// ping defaults to false in beforeEach; no OPENAI_API_KEY.
|
|
48
|
+
const e = await resolveEmbedder({ provider: "auto" });
|
|
49
|
+
expect(e.name.startsWith("bundled:")).toBe(true);
|
|
50
|
+
expect(e.dimensions).toBe(384);
|
|
51
|
+
});
|
|
52
|
+
it("explicit provider:hash bypasses the ladder and returns hash", async () => {
|
|
53
|
+
const e = await resolveEmbedder({ provider: "hash" });
|
|
54
|
+
expect(e.name.startsWith("hash:")).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
it("explicit provider:bundled returns bundled with the requested model", async () => {
|
|
57
|
+
const e = await resolveEmbedder({
|
|
58
|
+
provider: "bundled",
|
|
59
|
+
model: "Xenova/bge-small-en",
|
|
60
|
+
});
|
|
61
|
+
expect(e.name).toBe("bundled:Xenova/bge-small-en");
|
|
62
|
+
});
|
|
63
|
+
it("explicit provider:ollama throws when Ollama isn't reachable (helpful error)", async () => {
|
|
64
|
+
await expect(resolveEmbedder({ provider: "ollama" })).rejects.toThrow(/Ollama not reachable/);
|
|
65
|
+
});
|
|
66
|
+
it("explicit provider:openai without a key throws a clear error", async () => {
|
|
67
|
+
await expect(resolveEmbedder({ provider: "openai" })).rejects.toThrow(/OpenAI API key/);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=resolve.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.test.js","sourceRoot":"","sources":["../src/resolve.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mneme-ai/embeddings",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Embedding providers (Ollama,
|
|
3
|
+
"version": "0.19.1",
|
|
4
|
+
"description": "Embedding providers (OpenAI, Ollama, bundled-WASM, hash-fallback) for Mneme",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"clean": "tsc -b --clean"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@mneme-ai/core": "0.
|
|
33
|
+
"@mneme-ai/core": "0.19.1",
|
|
34
|
+
"@xenova/transformers": "^2.17.2"
|
|
34
35
|
}
|
|
35
36
|
}
|