@mneme-ai/embeddings 0.18.0 → 0.18.2
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/ollama.d.ts +11 -0
- package/dist/ollama.d.ts.map +1 -1
- package/dist/ollama.js +88 -14
- package/dist/ollama.js.map +1 -1
- package/package.json +6 -3
package/dist/ollama.d.ts
CHANGED
|
@@ -3,14 +3,25 @@ export interface OllamaOptions {
|
|
|
3
3
|
model?: string;
|
|
4
4
|
baseUrl?: string;
|
|
5
5
|
dimensions?: number;
|
|
6
|
+
/** Per-request timeout in ms. Default 180000 (3 min — first call may load model into memory). */
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
/** Hook called as each text completes in fallback (singular) mode — useful for fine-grained progress. */
|
|
9
|
+
onItemDone?: (done: number, total: number) => void;
|
|
6
10
|
}
|
|
7
11
|
export declare class OllamaEmbedder implements EmbeddingProvider {
|
|
8
12
|
readonly name: string;
|
|
9
13
|
readonly dimensions: number;
|
|
10
14
|
private readonly baseUrl;
|
|
11
15
|
private readonly model;
|
|
16
|
+
private readonly timeoutMs;
|
|
17
|
+
private readonly onItemDone?;
|
|
18
|
+
/** Once we learn the server lacks /api/embed (404), skip it on every later batch. */
|
|
19
|
+
private batchEndpointBroken;
|
|
12
20
|
constructor(opts?: OllamaOptions);
|
|
13
21
|
embed(texts: string[]): Promise<Float32Array[]>;
|
|
22
|
+
private embedBatch;
|
|
23
|
+
private embedOne;
|
|
24
|
+
private fetchWithTimeout;
|
|
14
25
|
ping(): Promise<boolean>;
|
|
15
26
|
}
|
|
16
27
|
//# sourceMappingURL=ollama.d.ts.map
|
package/dist/ollama.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../src/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../src/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yGAAyG;IACzG,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAeD,qBAAa,cAAe,YAAW,iBAAiB;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAwC;IACpE,qFAAqF;IACrF,OAAO,CAAC,mBAAmB,CAAS;gBAExB,IAAI,GAAE,aAAkB;IAS9B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;YA4BvC,UAAU;YAwBV,QAAQ;YAcR,gBAAgB;IAkBxB,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;CAQ/B"}
|
package/dist/ollama.js
CHANGED
|
@@ -1,38 +1,109 @@
|
|
|
1
1
|
const DEFAULT_MODEL = "nomic-embed-text";
|
|
2
2
|
const DEFAULT_DIMS = 768;
|
|
3
3
|
const DEFAULT_URL = "http://localhost:11434";
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 180_000;
|
|
4
5
|
export class OllamaEmbedder {
|
|
5
6
|
name;
|
|
6
7
|
dimensions;
|
|
7
8
|
baseUrl;
|
|
8
9
|
model;
|
|
10
|
+
timeoutMs;
|
|
11
|
+
onItemDone;
|
|
12
|
+
/** Once we learn the server lacks /api/embed (404), skip it on every later batch. */
|
|
13
|
+
batchEndpointBroken = false;
|
|
9
14
|
constructor(opts = {}) {
|
|
10
15
|
this.model = opts.model ?? DEFAULT_MODEL;
|
|
11
16
|
this.baseUrl = (opts.baseUrl ?? DEFAULT_URL).replace(/\/$/, "");
|
|
12
17
|
this.dimensions = opts.dimensions ?? DEFAULT_DIMS;
|
|
18
|
+
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
19
|
+
this.onItemDone = opts.onItemDone;
|
|
13
20
|
this.name = `ollama:${this.model}`;
|
|
14
21
|
}
|
|
15
22
|
async embed(texts) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
if (texts.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
// Fast path: Ollama's batch endpoint (Ollama >= 0.3) — one HTTP round-trip
|
|
26
|
+
// for the whole batch. Falls back to singular if server returns 404.
|
|
27
|
+
if (!this.batchEndpointBroken) {
|
|
28
|
+
try {
|
|
29
|
+
const vecs = await this.embedBatch(texts);
|
|
30
|
+
if (this.onItemDone)
|
|
31
|
+
this.onItemDone(texts.length, texts.length);
|
|
32
|
+
return vecs;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
// 404 → server is older Ollama without /api/embed; switch to singular.
|
|
36
|
+
// Other errors propagate immediately so the user sees them.
|
|
37
|
+
if (!(err instanceof OllamaNotFoundError))
|
|
38
|
+
throw err;
|
|
39
|
+
this.batchEndpointBroken = true;
|
|
25
40
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
}
|
|
42
|
+
// Fallback: singular endpoint with per-item progress so the user never
|
|
43
|
+
// sees a frozen progress bar while a batch crunches.
|
|
44
|
+
const out = [];
|
|
45
|
+
for (let i = 0; i < texts.length; i++) {
|
|
46
|
+
out.push(await this.embedOne(texts[i]));
|
|
47
|
+
if (this.onItemDone)
|
|
48
|
+
this.onItemDone(i + 1, texts.length);
|
|
30
49
|
}
|
|
31
50
|
return out;
|
|
32
51
|
}
|
|
52
|
+
async embedBatch(texts) {
|
|
53
|
+
const res = await this.fetchWithTimeout(`${this.baseUrl}/api/embed`, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: { "content-type": "application/json" },
|
|
56
|
+
body: JSON.stringify({ model: this.model, input: texts }),
|
|
57
|
+
});
|
|
58
|
+
if (res.status === 404) {
|
|
59
|
+
throw new OllamaNotFoundError("/api/embed not available on this Ollama version");
|
|
60
|
+
}
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
throw new Error(`Ollama embed failed (${res.status}): ${await res.text()}`);
|
|
63
|
+
}
|
|
64
|
+
const json = (await res.json());
|
|
65
|
+
if (!json.embeddings || !Array.isArray(json.embeddings)) {
|
|
66
|
+
throw new Error("Ollama batch endpoint returned no embeddings");
|
|
67
|
+
}
|
|
68
|
+
if (json.embeddings.length !== texts.length) {
|
|
69
|
+
throw new Error(`Ollama returned ${json.embeddings.length} embeddings for ${texts.length} inputs`);
|
|
70
|
+
}
|
|
71
|
+
return json.embeddings.map((v) => Float32Array.from(v));
|
|
72
|
+
}
|
|
73
|
+
async embedOne(text) {
|
|
74
|
+
const res = await this.fetchWithTimeout(`${this.baseUrl}/api/embeddings`, {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: { "content-type": "application/json" },
|
|
77
|
+
body: JSON.stringify({ model: this.model, prompt: text }),
|
|
78
|
+
});
|
|
79
|
+
if (!res.ok) {
|
|
80
|
+
throw new Error(`Ollama embed failed (${res.status}): ${await res.text()}`);
|
|
81
|
+
}
|
|
82
|
+
const json = (await res.json());
|
|
83
|
+
if (!json.embedding)
|
|
84
|
+
throw new Error("Ollama returned no embedding");
|
|
85
|
+
return Float32Array.from(json.embedding);
|
|
86
|
+
}
|
|
87
|
+
async fetchWithTimeout(url, init) {
|
|
88
|
+
const ctrl = new AbortController();
|
|
89
|
+
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
90
|
+
try {
|
|
91
|
+
return await fetch(url, { ...init, signal: ctrl.signal });
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
// Surface a clearer message than "AbortError: This operation was aborted"
|
|
95
|
+
if (err?.name === "AbortError") {
|
|
96
|
+
throw new Error(`Ollama did not respond within ${this.timeoutMs}ms — check that \`ollama serve\` is running and the model is loaded (\`ollama list\`). First request after a fresh pull can take longer; consider re-running.`);
|
|
97
|
+
}
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
clearTimeout(timer);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
33
104
|
async ping() {
|
|
34
105
|
try {
|
|
35
|
-
const res = await
|
|
106
|
+
const res = await this.fetchWithTimeout(`${this.baseUrl}/api/tags`, { method: "GET" });
|
|
36
107
|
return res.ok;
|
|
37
108
|
}
|
|
38
109
|
catch {
|
|
@@ -40,4 +111,7 @@ export class OllamaEmbedder {
|
|
|
40
111
|
}
|
|
41
112
|
}
|
|
42
113
|
}
|
|
114
|
+
/** Internal sentinel for "server doesn't support /api/embed yet". */
|
|
115
|
+
class OllamaNotFoundError extends Error {
|
|
116
|
+
}
|
|
43
117
|
//# sourceMappingURL=ollama.js.map
|
package/dist/ollama.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../src/ollama.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../src/ollama.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mneme-ai/embeddings",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.2",
|
|
4
4
|
"description": "Embedding providers (Ollama, OpenAI, hash-fallback) for Mneme",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,12 +21,15 @@
|
|
|
21
21
|
"url": "https://github.com/patsa2561-art/mneme-ai/issues"
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
|
-
"files": [
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
25
28
|
"scripts": {
|
|
26
29
|
"build": "tsc -b",
|
|
27
30
|
"clean": "tsc -b --clean"
|
|
28
31
|
},
|
|
29
32
|
"dependencies": {
|
|
30
|
-
"@mneme-ai/core": "0.18.
|
|
33
|
+
"@mneme-ai/core": "0.18.2"
|
|
31
34
|
}
|
|
32
35
|
}
|