@alisio/plugin-semantic 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.es.md +168 -0
- package/README.md +160 -2
- package/THIRD_PARTY_NOTICES.md +42 -0
- package/assets/architecture.svg +1 -0
- package/assets/ask-flow.svg +1 -0
- package/cover.svg +53 -0
- package/dist/apps.d.ts +26 -0
- package/dist/apps.d.ts.map +1 -0
- package/dist/apps.js +141 -0
- package/dist/apps.js.map +1 -0
- package/dist/embedded.html +3043 -0
- package/dist/engine/download.d.ts +77 -0
- package/dist/engine/download.d.ts.map +1 -0
- package/dist/engine/download.js +213 -0
- package/dist/engine/download.js.map +1 -0
- package/dist/engine/embedder.d.ts +55 -0
- package/dist/engine/embedder.d.ts.map +1 -0
- package/dist/engine/embedder.js +182 -0
- package/dist/engine/embedder.js.map +1 -0
- package/dist/engine/infer.d.ts +22 -0
- package/dist/engine/infer.d.ts.map +1 -0
- package/dist/engine/infer.js +53 -0
- package/dist/engine/infer.js.map +1 -0
- package/dist/engine/models.d.ts +45 -0
- package/dist/engine/models.d.ts.map +1 -0
- package/dist/engine/models.js +132 -0
- package/dist/engine/models.js.map +1 -0
- package/dist/engine/runtime.d.ts +46 -0
- package/dist/engine/runtime.d.ts.map +1 -0
- package/dist/engine/runtime.js +172 -0
- package/dist/engine/runtime.js.map +1 -0
- package/dist/engine/setup.d.ts +82 -0
- package/dist/engine/setup.d.ts.map +1 -0
- package/dist/engine/setup.js +183 -0
- package/dist/engine/setup.js.map +1 -0
- package/dist/engine/store.d.ts +46 -0
- package/dist/engine/store.d.ts.map +1 -0
- package/dist/engine/store.js +288 -0
- package/dist/engine/store.js.map +1 -0
- package/dist/engine/tar.d.ts +18 -0
- package/dist/engine/tar.d.ts.map +1 -0
- package/dist/engine/tar.js +198 -0
- package/dist/engine/tar.js.map +1 -0
- package/dist/engine/worker.d.ts +2 -0
- package/dist/engine/worker.d.ts.map +1 -0
- package/dist/engine/worker.js +64 -0
- package/dist/engine/worker.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +269 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +53 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +118 -0
- package/dist/messages.js.map +1 -0
- package/dist/notebook/answer.d.ts +35 -0
- package/dist/notebook/answer.d.ts.map +1 -0
- package/dist/notebook/answer.js +88 -0
- package/dist/notebook/answer.js.map +1 -0
- package/dist/notebook/chunk.d.ts +23 -0
- package/dist/notebook/chunk.d.ts.map +1 -0
- package/dist/notebook/chunk.js +124 -0
- package/dist/notebook/chunk.js.map +1 -0
- package/dist/notebook/db.d.ts +107 -0
- package/dist/notebook/db.d.ts.map +1 -0
- package/dist/notebook/db.js +356 -0
- package/dist/notebook/db.js.map +1 -0
- package/dist/notebook/docx.d.ts +3 -0
- package/dist/notebook/docx.d.ts.map +1 -0
- package/dist/notebook/docx.js +16 -0
- package/dist/notebook/docx.js.map +1 -0
- package/dist/notebook/extract.d.ts +11 -0
- package/dist/notebook/extract.d.ts.map +1 -0
- package/dist/notebook/extract.js +99 -0
- package/dist/notebook/extract.js.map +1 -0
- package/dist/notebook/jobs.d.ts +31 -0
- package/dist/notebook/jobs.d.ts.map +1 -0
- package/dist/notebook/jobs.js +84 -0
- package/dist/notebook/jobs.js.map +1 -0
- package/dist/notebook/ooxml.d.ts +6 -0
- package/dist/notebook/ooxml.d.ts.map +1 -0
- package/dist/notebook/ooxml.js +131 -0
- package/dist/notebook/ooxml.js.map +1 -0
- package/dist/notebook/retrieve.d.ts +14 -0
- package/dist/notebook/retrieve.d.ts.map +1 -0
- package/dist/notebook/retrieve.js +37 -0
- package/dist/notebook/retrieve.js.map +1 -0
- package/dist/notebook/service.d.ts +92 -0
- package/dist/notebook/service.d.ts.map +1 -0
- package/dist/notebook/service.js +752 -0
- package/dist/notebook/service.js.map +1 -0
- package/dist/notebook/workspace.d.ts +17 -0
- package/dist/notebook/workspace.d.ts.map +1 -0
- package/dist/notebook/workspace.js +75 -0
- package/dist/notebook/workspace.js.map +1 -0
- package/dist/notebook/zip.d.ts +33 -0
- package/dist/notebook/zip.d.ts.map +1 -0
- package/dist/notebook/zip.js +154 -0
- package/dist/notebook/zip.js.map +1 -0
- package/dist/paths.d.ts +17 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +28 -0
- package/dist/paths.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/icon.svg +16 -0
- package/package.json +62 -3
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { errorCode, SemanticPluginError } from "../errors.js";
|
|
3
|
+
import { activationMessage, messagesFor } from "../messages.js";
|
|
4
|
+
import { downloadModel, isModelReady, ProgressTracker, } from "./download.js";
|
|
5
|
+
import { totalBytes } from "./models.js";
|
|
6
|
+
import { currentTarget, installRuntime, isRuntimeReady, RUNTIME_PACKAGES, runtimeBytes, runtimeSupported, } from "./runtime.js";
|
|
7
|
+
export const EMBEDDING_ID = "semantic.e5";
|
|
8
|
+
export const STORE_ID = "semantic.lance";
|
|
9
|
+
/**
|
|
10
|
+
* The one setup flow shared by `/semantic:setup` and the app's "Prepare" step (§6.1): show the
|
|
11
|
+
* model, its size and destination; download and verify it as a job with progress; then ask the host
|
|
12
|
+
* to activate this plugin's providers. Never runs on install or on a first query.
|
|
13
|
+
*/
|
|
14
|
+
export class SetupManager {
|
|
15
|
+
options;
|
|
16
|
+
jobs = new Map();
|
|
17
|
+
current;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.options = options;
|
|
20
|
+
}
|
|
21
|
+
async plan() {
|
|
22
|
+
const { spec, cacheRoot } = this.options;
|
|
23
|
+
const target = this.options.target ?? currentTarget();
|
|
24
|
+
const packages = this.options.runtimePackages ?? RUNTIME_PACKAGES;
|
|
25
|
+
const runtimeReady = await isRuntimeReady(cacheRoot, target, packages);
|
|
26
|
+
const modelReady = await isModelReady(cacheRoot, spec);
|
|
27
|
+
const runtime = {
|
|
28
|
+
bytes: runtimeBytes(packages),
|
|
29
|
+
ready: runtimeReady,
|
|
30
|
+
supported: runtimeSupported(target),
|
|
31
|
+
};
|
|
32
|
+
const model = { bytes: totalBytes(spec), ready: modelReady };
|
|
33
|
+
return {
|
|
34
|
+
key: spec.key,
|
|
35
|
+
label: spec.label,
|
|
36
|
+
bytes: (runtimeReady ? 0 : runtime.bytes) + (modelReady ? 0 : model.bytes),
|
|
37
|
+
prepared: runtimeReady && modelReady,
|
|
38
|
+
destination: cacheRoot,
|
|
39
|
+
runtime,
|
|
40
|
+
model,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
running() {
|
|
44
|
+
return this.current?.job.state === "running";
|
|
45
|
+
}
|
|
46
|
+
get(id) {
|
|
47
|
+
const job = this.jobs.get(id);
|
|
48
|
+
return job ? structuredClone(job) : undefined;
|
|
49
|
+
}
|
|
50
|
+
cancel(id) {
|
|
51
|
+
if (this.current?.job.id !== id || this.current.job.state !== "running")
|
|
52
|
+
return false;
|
|
53
|
+
this.current.controller.abort();
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
currentId() {
|
|
57
|
+
return this.current?.job.id;
|
|
58
|
+
}
|
|
59
|
+
cancelRunning() {
|
|
60
|
+
return this.current ? this.cancel(this.current.job.id) : false;
|
|
61
|
+
}
|
|
62
|
+
/** Starts the setup job, or returns the one already running. */
|
|
63
|
+
start() {
|
|
64
|
+
if (this.current && this.current.job.state === "running")
|
|
65
|
+
return this.current.job;
|
|
66
|
+
const job = {
|
|
67
|
+
id: `setup-${randomUUID()}`,
|
|
68
|
+
kind: "setup",
|
|
69
|
+
state: "running",
|
|
70
|
+
progress: 0,
|
|
71
|
+
};
|
|
72
|
+
const controller = new AbortController();
|
|
73
|
+
this.jobs.set(job.id, job);
|
|
74
|
+
const done = this.execute(job, controller.signal);
|
|
75
|
+
this.current = { job, controller, done };
|
|
76
|
+
return job;
|
|
77
|
+
}
|
|
78
|
+
async run() {
|
|
79
|
+
this.start();
|
|
80
|
+
return this.current.done;
|
|
81
|
+
}
|
|
82
|
+
/** Full text of `/semantic:setup`: notice (first time only), progress milestones, outcome. */
|
|
83
|
+
async commandText(locale) {
|
|
84
|
+
const m = messagesFor(locale);
|
|
85
|
+
const plan = await this.plan();
|
|
86
|
+
const lines = [];
|
|
87
|
+
if (!plan.prepared)
|
|
88
|
+
lines.push(m.downloadNotice(plan.bytes));
|
|
89
|
+
lines.push(m.model(plan.label, plan.destination));
|
|
90
|
+
if (plan.prepared)
|
|
91
|
+
lines.push(m.alreadyPrepared);
|
|
92
|
+
const job = this.start();
|
|
93
|
+
let milestone = 25;
|
|
94
|
+
const progressLines = [];
|
|
95
|
+
const watcher = setInterval(() => {
|
|
96
|
+
const detail = this.jobs.get(job.id)?.detail;
|
|
97
|
+
if (!detail || plan.prepared)
|
|
98
|
+
return;
|
|
99
|
+
while (detail.fraction * 100 >= milestone && milestone < 100) {
|
|
100
|
+
progressLines.push(m.progress(milestone, detail.bytes, detail.total));
|
|
101
|
+
milestone += 25;
|
|
102
|
+
}
|
|
103
|
+
}, 100);
|
|
104
|
+
const finished = await this.current.done;
|
|
105
|
+
clearInterval(watcher);
|
|
106
|
+
lines.push(...progressLines);
|
|
107
|
+
if (finished.state === "cancelled")
|
|
108
|
+
lines.push(m.cancelled);
|
|
109
|
+
else if (finished.state === "failed")
|
|
110
|
+
lines.push(m.failed(finished.error ?? "operation_failed"));
|
|
111
|
+
else if (finished.result) {
|
|
112
|
+
if (finished.result.downloaded) {
|
|
113
|
+
lines.push(m.progress(100, plan.bytes, plan.bytes));
|
|
114
|
+
lines.push(m.doneNotice);
|
|
115
|
+
}
|
|
116
|
+
lines.push(activationMessage(locale, finished.result));
|
|
117
|
+
}
|
|
118
|
+
return lines.join("\n");
|
|
119
|
+
}
|
|
120
|
+
/** Cancels a running download (plugin dispose). */
|
|
121
|
+
dispose() {
|
|
122
|
+
this.current?.controller.abort();
|
|
123
|
+
}
|
|
124
|
+
async execute(job, signal) {
|
|
125
|
+
const { spec, cacheRoot, embedder, semantic, fetcher } = this.options;
|
|
126
|
+
embedder.setDownloading(true);
|
|
127
|
+
try {
|
|
128
|
+
// One progress bar for the whole first-time download: runtime tarballs, then model files.
|
|
129
|
+
const plan = await this.plan();
|
|
130
|
+
if (!plan.runtime.supported)
|
|
131
|
+
throw new SemanticPluginError("engine_unavailable");
|
|
132
|
+
const target = this.options.target ?? currentTarget();
|
|
133
|
+
const packages = this.options.runtimePackages ?? RUNTIME_PACKAGES;
|
|
134
|
+
const count = (plan.runtime.ready ? 0 : packages.length) + (plan.model.ready ? 0 : spec.files.length);
|
|
135
|
+
const tracker = new ProgressTracker(plan.bytes, count, (detail) => {
|
|
136
|
+
job.detail = detail;
|
|
137
|
+
job.progress = Math.max(job.progress, detail.fraction);
|
|
138
|
+
});
|
|
139
|
+
const { installed } = await installRuntime(cacheRoot, {
|
|
140
|
+
signal,
|
|
141
|
+
tracker,
|
|
142
|
+
target,
|
|
143
|
+
packages,
|
|
144
|
+
...(fetcher ? { fetcher } : {}),
|
|
145
|
+
});
|
|
146
|
+
const { downloaded } = await downloadModel(cacheRoot, spec, {
|
|
147
|
+
signal,
|
|
148
|
+
tracker,
|
|
149
|
+
...(fetcher ? { fetcher } : {}),
|
|
150
|
+
});
|
|
151
|
+
job.progress = 1;
|
|
152
|
+
job.result = { downloaded: downloaded || installed, ...(await this.activate(semantic)) };
|
|
153
|
+
job.state = "done";
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
const code = errorCode(error);
|
|
157
|
+
job.error = code;
|
|
158
|
+
job.state = code === "cancelled" ? "cancelled" : "failed";
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
embedder.setDownloading(false);
|
|
162
|
+
}
|
|
163
|
+
return job;
|
|
164
|
+
}
|
|
165
|
+
async activate(semantic) {
|
|
166
|
+
if (!semantic)
|
|
167
|
+
return { activation: "no_semantic_api" };
|
|
168
|
+
if (typeof semantic.activate !== "function")
|
|
169
|
+
return { activation: "activate_unsupported" };
|
|
170
|
+
try {
|
|
171
|
+
const result = await semantic.activate({ embedding: EMBEDDING_ID, store: STORE_ID }, { recommend: true });
|
|
172
|
+
return {
|
|
173
|
+
activation: result.status,
|
|
174
|
+
...(result.active ? { active: result.active } : {}),
|
|
175
|
+
...(result.message ? { message: result.message } : {}),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return { activation: "unavailable" };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/engine/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CollectionInfo, SemanticHealth, SemanticMetadata, VectorMatch, VectorRecord, VectorStoreProvider } from "@alisio/sdk";
|
|
2
|
+
export interface LanceStoreOptions {
|
|
3
|
+
/** Database directory (`<state>/lance`). */
|
|
4
|
+
dir: string;
|
|
5
|
+
/** Row count from which an IVF-PQ index is built once (flat search is exact below it). */
|
|
6
|
+
indexThreshold?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* `VectorStoreProvider` on LanceDB (`semantic.lance`). Collection names arrive namespaced by the host
|
|
10
|
+
* (`<plugin>/<collection>`), so each maps to a hashed table name recorded in `collections.json`
|
|
11
|
+
* (written atomically). Tables use the cosine metric and `score = 1 - distance` (D8). Metadata is a
|
|
12
|
+
* JSON column; equality filters are applied to decoded rows, so filter values never become SQL.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LanceStore implements VectorStoreProvider {
|
|
15
|
+
readonly id = "semantic.lance";
|
|
16
|
+
readonly name = "LanceDB (local)";
|
|
17
|
+
private readonly dir;
|
|
18
|
+
private readonly indexThreshold;
|
|
19
|
+
private connection;
|
|
20
|
+
constructor(options: LanceStoreOptions);
|
|
21
|
+
ensureCollection(name: string, spec: {
|
|
22
|
+
modelId: string;
|
|
23
|
+
dimensions: number;
|
|
24
|
+
}, signal: AbortSignal): Promise<CollectionInfo>;
|
|
25
|
+
getCollection(name: string, signal: AbortSignal): Promise<CollectionInfo | null>;
|
|
26
|
+
listCollections(prefix: string, signal: AbortSignal): Promise<CollectionInfo[]>;
|
|
27
|
+
dropCollection(name: string, signal: AbortSignal): Promise<void>;
|
|
28
|
+
upsert(name: string, records: VectorRecord[], signal: AbortSignal): Promise<void>;
|
|
29
|
+
delete(name: string, ids: string[], signal: AbortSignal): Promise<void>;
|
|
30
|
+
query(name: string, vector: Float32Array, options: {
|
|
31
|
+
topK: number;
|
|
32
|
+
filter?: SemanticMetadata;
|
|
33
|
+
signal: AbortSignal;
|
|
34
|
+
}): Promise<VectorMatch[]>;
|
|
35
|
+
health(): Promise<SemanticHealth>;
|
|
36
|
+
/** Writes are serialized per database directory, across every store instance in the process. */
|
|
37
|
+
private serial;
|
|
38
|
+
private entry;
|
|
39
|
+
private info;
|
|
40
|
+
private table;
|
|
41
|
+
private connect;
|
|
42
|
+
/** Always read from disk: another activation (another open workspace) may have written it. */
|
|
43
|
+
private readSidecar;
|
|
44
|
+
private writeSidecar;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/engine/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAkBrB,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,0FAA0F;IAC1F,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiCD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,mBAAmB;IACpD,QAAQ,CAAC,EAAE,oBAAoB;IAC/B,QAAQ,CAAC,IAAI,qBAAqB;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,UAAU,CAAkC;IAEpD,YAAY,OAAO,EAAE,iBAAiB,EAGrC;IAEK,gBAAgB,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAC7C,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,cAAc,CAAC,CAiBzB;IAEK,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAIrF;IAEK,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CASpF;IAEK,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrE;IAEK,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CtF;IAEK,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAc5E;IAEK,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GACxE,OAAO,CAAC,WAAW,EAAE,CAAC,CA8CxB;IAEK,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAQtC;IAED,gGAAgG;IAChG,OAAO,CAAC,MAAM;YAWA,KAAK;YAML,IAAI;YAUJ,KAAK;IAMnB,OAAO,CAAC,OAAO;IAcf,8FAA8F;IAC9F,OAAO,CAAC,WAAW;YAYL,YAAY;CAO3B"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { SemanticPluginError } from "../errors.js";
|
|
5
|
+
const KEY = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/;
|
|
6
|
+
// Host rule for record ids (spec 029 D9). The charset excludes quotes, so a validated id list is a
|
|
7
|
+
// safe SQL literal for `delete`.
|
|
8
|
+
const ID = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
9
|
+
const NAME_MAX = 200;
|
|
10
|
+
const DELETE_BATCH = 500;
|
|
11
|
+
/**
|
|
12
|
+
* Write queue per database directory. Process-wide on purpose: two activations of the plugin (two
|
|
13
|
+
* open workspaces) share one `collections.json`. It holds no data, only pending writes.
|
|
14
|
+
*/
|
|
15
|
+
const QUEUES = new Map();
|
|
16
|
+
function invalid() {
|
|
17
|
+
throw new SemanticPluginError("invalid_input");
|
|
18
|
+
}
|
|
19
|
+
function checkMetadata(metadata) {
|
|
20
|
+
if (metadata === undefined)
|
|
21
|
+
return;
|
|
22
|
+
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata))
|
|
23
|
+
invalid();
|
|
24
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
25
|
+
if (!KEY.test(key))
|
|
26
|
+
invalid();
|
|
27
|
+
const type = typeof value;
|
|
28
|
+
if (type !== "string" && type !== "boolean" && !(type === "number" && Number.isFinite(value)))
|
|
29
|
+
invalid();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function checkName(name) {
|
|
33
|
+
if (typeof name !== "string" || name.length === 0 || name.length > NAME_MAX)
|
|
34
|
+
invalid();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `VectorStoreProvider` on LanceDB (`semantic.lance`). Collection names arrive namespaced by the host
|
|
38
|
+
* (`<plugin>/<collection>`), so each maps to a hashed table name recorded in `collections.json`
|
|
39
|
+
* (written atomically). Tables use the cosine metric and `score = 1 - distance` (D8). Metadata is a
|
|
40
|
+
* JSON column; equality filters are applied to decoded rows, so filter values never become SQL.
|
|
41
|
+
*/
|
|
42
|
+
export class LanceStore {
|
|
43
|
+
id = "semantic.lance";
|
|
44
|
+
name = "LanceDB (local)";
|
|
45
|
+
dir;
|
|
46
|
+
indexThreshold;
|
|
47
|
+
connection;
|
|
48
|
+
constructor(options) {
|
|
49
|
+
this.dir = options.dir;
|
|
50
|
+
this.indexThreshold = options.indexThreshold ?? 50_000;
|
|
51
|
+
}
|
|
52
|
+
async ensureCollection(name, spec, signal) {
|
|
53
|
+
checkName(name);
|
|
54
|
+
if (!Number.isInteger(spec.dimensions) || spec.dimensions < 1 || spec.dimensions > 4096)
|
|
55
|
+
invalid();
|
|
56
|
+
signal.throwIfAborted();
|
|
57
|
+
return this.serial(async () => {
|
|
58
|
+
const sidecar = await this.readSidecar();
|
|
59
|
+
if (!sidecar.collections[name]) {
|
|
60
|
+
sidecar.collections[name] = {
|
|
61
|
+
table: `c_${createHash("sha256").update(name).digest("hex").slice(0, 32)}`,
|
|
62
|
+
modelId: spec.modelId,
|
|
63
|
+
dimensions: spec.dimensions,
|
|
64
|
+
};
|
|
65
|
+
await this.writeSidecar(sidecar);
|
|
66
|
+
}
|
|
67
|
+
return this.info(name, sidecar.collections[name]);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async getCollection(name, signal) {
|
|
71
|
+
signal.throwIfAborted();
|
|
72
|
+
const entry = (await this.readSidecar()).collections[name];
|
|
73
|
+
return entry ? this.info(name, entry) : null;
|
|
74
|
+
}
|
|
75
|
+
async listCollections(prefix, signal) {
|
|
76
|
+
signal.throwIfAborted();
|
|
77
|
+
const sidecar = await this.readSidecar();
|
|
78
|
+
const names = Object.keys(sidecar.collections)
|
|
79
|
+
.filter((name) => name.startsWith(prefix))
|
|
80
|
+
.sort();
|
|
81
|
+
return Promise.all(names.map((name) => this.info(name, sidecar.collections[name])));
|
|
82
|
+
}
|
|
83
|
+
async dropCollection(name, signal) {
|
|
84
|
+
signal.throwIfAborted();
|
|
85
|
+
await this.serial(async () => {
|
|
86
|
+
const sidecar = await this.readSidecar();
|
|
87
|
+
const entry = sidecar.collections[name];
|
|
88
|
+
if (!entry)
|
|
89
|
+
return;
|
|
90
|
+
const db = await this.connect();
|
|
91
|
+
if ((await db.tableNames()).includes(entry.table))
|
|
92
|
+
await db.dropTable(entry.table);
|
|
93
|
+
delete sidecar.collections[name];
|
|
94
|
+
await this.writeSidecar(sidecar);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
async upsert(name, records, signal) {
|
|
98
|
+
signal.throwIfAborted();
|
|
99
|
+
await this.serial(async () => {
|
|
100
|
+
const entry = await this.entry(name);
|
|
101
|
+
for (const record of records) {
|
|
102
|
+
if (!ID.test(record.id))
|
|
103
|
+
invalid();
|
|
104
|
+
if (!(record.vector instanceof Float32Array) || record.vector.length !== entry.dimensions)
|
|
105
|
+
invalid();
|
|
106
|
+
for (const x of record.vector)
|
|
107
|
+
if (!Number.isFinite(x))
|
|
108
|
+
invalid();
|
|
109
|
+
if (record.text !== undefined && typeof record.text !== "string")
|
|
110
|
+
invalid();
|
|
111
|
+
checkMetadata(record.metadata);
|
|
112
|
+
}
|
|
113
|
+
if (records.length === 0)
|
|
114
|
+
return;
|
|
115
|
+
const rows = records.map((r) => ({
|
|
116
|
+
id: r.id,
|
|
117
|
+
vector: Array.from(r.vector),
|
|
118
|
+
text: r.text ?? "",
|
|
119
|
+
has_text: r.text !== undefined,
|
|
120
|
+
metadata: JSON.stringify(r.metadata ?? {}),
|
|
121
|
+
}));
|
|
122
|
+
const db = await this.connect();
|
|
123
|
+
const table = await this.table(entry);
|
|
124
|
+
if (!table)
|
|
125
|
+
await db.createTable(entry.table, rows);
|
|
126
|
+
else
|
|
127
|
+
await table
|
|
128
|
+
.mergeInsert("id")
|
|
129
|
+
.whenMatchedUpdateAll()
|
|
130
|
+
.whenNotMatchedInsertAll()
|
|
131
|
+
.execute(rows);
|
|
132
|
+
signal.throwIfAborted();
|
|
133
|
+
if (!entry.indexed) {
|
|
134
|
+
const current = (await this.table(entry));
|
|
135
|
+
if ((await current.countRows()) >= this.indexThreshold) {
|
|
136
|
+
const { Index } = await import("@lancedb/lancedb");
|
|
137
|
+
await current.createIndex("vector", {
|
|
138
|
+
config: Index.ivfPq({ distanceType: "cosine" }),
|
|
139
|
+
});
|
|
140
|
+
const sidecar = await this.readSidecar();
|
|
141
|
+
const stored = sidecar.collections[name];
|
|
142
|
+
if (stored) {
|
|
143
|
+
stored.indexed = true;
|
|
144
|
+
await this.writeSidecar(sidecar);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
async delete(name, ids, signal) {
|
|
151
|
+
for (const id of ids)
|
|
152
|
+
if (typeof id !== "string" || !ID.test(id))
|
|
153
|
+
invalid();
|
|
154
|
+
signal.throwIfAborted();
|
|
155
|
+
await this.serial(async () => {
|
|
156
|
+
const table = await this.table(await this.entry(name));
|
|
157
|
+
if (!table)
|
|
158
|
+
return;
|
|
159
|
+
for (let i = 0; i < ids.length; i += DELETE_BATCH) {
|
|
160
|
+
const list = ids
|
|
161
|
+
.slice(i, i + DELETE_BATCH)
|
|
162
|
+
.map((id) => `'${id}'`)
|
|
163
|
+
.join(", ");
|
|
164
|
+
await table.delete(`id IN (${list})`);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
async query(name, vector, options) {
|
|
169
|
+
const filter = options.filter;
|
|
170
|
+
if (filter) {
|
|
171
|
+
checkMetadata(filter);
|
|
172
|
+
if (Object.keys(filter).length > 16)
|
|
173
|
+
invalid();
|
|
174
|
+
}
|
|
175
|
+
const topK = Math.max(1, Math.min(100, Math.floor(options.topK)));
|
|
176
|
+
options.signal.throwIfAborted();
|
|
177
|
+
const sidecar = await this.readSidecar();
|
|
178
|
+
const entry = sidecar.collections[name];
|
|
179
|
+
if (!entry)
|
|
180
|
+
return [];
|
|
181
|
+
const table = await this.table(entry);
|
|
182
|
+
if (!table)
|
|
183
|
+
return [];
|
|
184
|
+
// A filter is applied after decoding metadata, so it searches every row (exact, flat).
|
|
185
|
+
let search = table
|
|
186
|
+
.vectorSearch(Array.from(vector))
|
|
187
|
+
.distanceType("cosine")
|
|
188
|
+
.select(["id", "text", "has_text", "metadata", "_distance"])
|
|
189
|
+
.limit(filter ? Math.max(topK, await table.countRows()) : topK);
|
|
190
|
+
if (filter)
|
|
191
|
+
search = search.bypassVectorIndex();
|
|
192
|
+
const rows = (await search.toArray());
|
|
193
|
+
options.signal.throwIfAborted();
|
|
194
|
+
const matches = [];
|
|
195
|
+
for (const row of rows) {
|
|
196
|
+
let metadata = {};
|
|
197
|
+
try {
|
|
198
|
+
metadata = JSON.parse(row.metadata);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
metadata = {};
|
|
202
|
+
}
|
|
203
|
+
if (filter && !Object.entries(filter).every(([k, value]) => metadata[k] === value))
|
|
204
|
+
continue;
|
|
205
|
+
const score = Math.max(-1, Math.min(1, 1 - Number(row._distance)));
|
|
206
|
+
matches.push({
|
|
207
|
+
id: row.id,
|
|
208
|
+
score,
|
|
209
|
+
...(row.has_text ? { text: row.text } : {}),
|
|
210
|
+
...(Object.keys(metadata).length > 0 ? { metadata } : {}),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return matches.sort((a, b) => b.score - a.score).slice(0, topK);
|
|
214
|
+
}
|
|
215
|
+
async health() {
|
|
216
|
+
try {
|
|
217
|
+
await (await this.connect()).tableNames();
|
|
218
|
+
return { status: "ready" };
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
this.connection = undefined;
|
|
222
|
+
return { status: "unavailable", detail: "the vector database cannot be opened" };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/** Writes are serialized per database directory, across every store instance in the process. */
|
|
226
|
+
serial(work) {
|
|
227
|
+
const previous = QUEUES.get(this.dir) ?? Promise.resolve();
|
|
228
|
+
const run = previous.then(work, work);
|
|
229
|
+
const tail = run.catch(() => { });
|
|
230
|
+
QUEUES.set(this.dir, tail);
|
|
231
|
+
void tail.then(() => {
|
|
232
|
+
if (QUEUES.get(this.dir) === tail)
|
|
233
|
+
QUEUES.delete(this.dir);
|
|
234
|
+
});
|
|
235
|
+
return run;
|
|
236
|
+
}
|
|
237
|
+
async entry(name) {
|
|
238
|
+
const entry = (await this.readSidecar()).collections[name];
|
|
239
|
+
if (!entry)
|
|
240
|
+
throw new SemanticPluginError("not_found");
|
|
241
|
+
return entry;
|
|
242
|
+
}
|
|
243
|
+
async info(name, entry) {
|
|
244
|
+
const table = await this.table(entry);
|
|
245
|
+
return {
|
|
246
|
+
name,
|
|
247
|
+
modelId: entry.modelId,
|
|
248
|
+
dimensions: entry.dimensions,
|
|
249
|
+
count: table ? await table.countRows() : 0,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
async table(entry) {
|
|
253
|
+
const db = await this.connect();
|
|
254
|
+
if (!(await db.tableNames()).includes(entry.table))
|
|
255
|
+
return undefined;
|
|
256
|
+
return db.openTable(entry.table);
|
|
257
|
+
}
|
|
258
|
+
connect() {
|
|
259
|
+
if (!this.connection) {
|
|
260
|
+
this.connection = (async () => {
|
|
261
|
+
await mkdir(this.dir, { recursive: true, mode: 0o700 });
|
|
262
|
+
const lancedb = await import("@lancedb/lancedb");
|
|
263
|
+
return lancedb.connect(this.dir);
|
|
264
|
+
})();
|
|
265
|
+
this.connection.catch(() => {
|
|
266
|
+
this.connection = undefined;
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return this.connection;
|
|
270
|
+
}
|
|
271
|
+
/** Always read from disk: another activation (another open workspace) may have written it. */
|
|
272
|
+
readSidecar() {
|
|
273
|
+
return readFile(join(this.dir, "collections.json"), "utf8").then((text) => {
|
|
274
|
+
const parsed = JSON.parse(text);
|
|
275
|
+
return parsed?.version === 1 && parsed.collections
|
|
276
|
+
? parsed
|
|
277
|
+
: { version: 1, collections: {} };
|
|
278
|
+
}, () => ({ version: 1, collections: {} }));
|
|
279
|
+
}
|
|
280
|
+
async writeSidecar(sidecar) {
|
|
281
|
+
await mkdir(this.dir, { recursive: true, mode: 0o700 });
|
|
282
|
+
const target = join(this.dir, "collections.json");
|
|
283
|
+
const temp = `${target}.${process.pid}.${Date.now()}.tmp`;
|
|
284
|
+
await writeFile(temp, JSON.stringify(sidecar), { mode: 0o600 });
|
|
285
|
+
await rename(temp, target);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/engine/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ExtractLimits {
|
|
2
|
+
signal: AbortSignal;
|
|
3
|
+
maxEntries?: number;
|
|
4
|
+
maxFileBytes?: number;
|
|
5
|
+
maxTotalBytes?: number;
|
|
6
|
+
}
|
|
7
|
+
export type Extracted = Record<string, {
|
|
8
|
+
bytes: number;
|
|
9
|
+
sha256: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Archive path checks applied to every entry, selected or not. */
|
|
12
|
+
export declare function safeEntryPath(name: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Extracts `archive` (gzip + ustar/pax) into `dest`. `select` maps an archive path to the path to
|
|
15
|
+
* write under `dest`, or null to skip. Returns size and SHA-256 of every written file.
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractTarGz(archive: string, dest: string, select: (path: string) => string | null, limits: ExtractLimits): Promise<Extracted>;
|
|
18
|
+
//# sourceMappingURL=tar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tar.d.ts","sourceRoot":"","sources":["../../src/engine/tar.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AACD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAM1E,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAmCD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,CAAC,CAoHpB"}
|