@pattern-js/mod-vectors 0.4.0-main.c8eb671

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/dist/admin.d.ts +20 -0
  4. package/dist/admin.d.ts.map +1 -0
  5. package/dist/admin.js +249 -0
  6. package/dist/admin.js.map +1 -0
  7. package/dist/chunk.d.ts +28 -0
  8. package/dist/chunk.d.ts.map +1 -0
  9. package/dist/chunk.js +74 -0
  10. package/dist/chunk.js.map +1 -0
  11. package/dist/engine-local.d.ts +62 -0
  12. package/dist/engine-local.d.ts.map +1 -0
  13. package/dist/engine-local.js +418 -0
  14. package/dist/engine-local.js.map +1 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +9 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/mod.d.ts +21 -0
  20. package/dist/mod.d.ts.map +1 -0
  21. package/dist/mod.js +49 -0
  22. package/dist/mod.js.map +1 -0
  23. package/dist/ops.d.ts +12 -0
  24. package/dist/ops.d.ts.map +1 -0
  25. package/dist/ops.js +138 -0
  26. package/dist/ops.js.map +1 -0
  27. package/dist/service.d.ts +72 -0
  28. package/dist/service.d.ts.map +1 -0
  29. package/dist/service.js +166 -0
  30. package/dist/service.js.map +1 -0
  31. package/dist/types.d.ts +104 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +33 -0
  34. package/dist/types.js.map +1 -0
  35. package/docs/index.md +94 -0
  36. package/docs/ops/vectors.chunk.md +8 -0
  37. package/docs/ops/vectors.collection.ensure.md +7 -0
  38. package/docs/ops/vectors.collections.ingest.md +10 -0
  39. package/docs/ops/vectors.collections.list.md +3 -0
  40. package/docs/ops/vectors.collections.search.md +7 -0
  41. package/docs/ops/vectors.delete.md +5 -0
  42. package/docs/ops/vectors.index.md +7 -0
  43. package/docs/ops/vectors.query.md +13 -0
  44. package/docs/ops/vectors.upsert.md +8 -0
  45. package/package.json +53 -0
package/dist/ops.js ADDED
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @pattern-js/mod-vectors — the `vectors.*` op catalog.
3
+ *
4
+ * Pure domain ops over the VectorsService: declare a collection, chunk text,
5
+ * upsert (text is embedded through the collection's declared alias), query
6
+ * (vector / keyword / hybrid, filterable), delete — plus `vectors.index`,
7
+ * the chunk→embed→upsert convenience that makes on-canvas RAG ingestion a
8
+ * single node.
9
+ */
10
+ import { value, z } from "@pattern-js/core";
11
+ import { chunkDoc } from "./chunk.js";
12
+ import { VECTORS_SERVICE } from "./service.js";
13
+ import { collectionSpecSchema, filterSchema, queryModeSchema, vectorItemSchema } from "./types.js";
14
+ function service(ctx) {
15
+ const svc = ctx.services[VECTORS_SERVICE];
16
+ if (!svc)
17
+ throw new Error("vectors: service not available — is @pattern-js/mod-vectors listed in pattern.config.json mods?");
18
+ return svc;
19
+ }
20
+ const chunkConfig = {
21
+ maxChars: z.number().int().positive().default(1200),
22
+ overlap: z.number().int().min(0).default(150),
23
+ separators: z.array(z.string()).default(["\n\n", "\n", ". "]),
24
+ };
25
+ const docSchema = z.object({
26
+ id: z.string().optional(),
27
+ text: z.string(),
28
+ meta: z.record(z.string(), z.unknown()).optional(),
29
+ });
30
+ const collectionEnsure = {
31
+ type: "vectors.collection.ensure",
32
+ title: "vectors.collection.ensure",
33
+ description: "Declare (idempotently) an embedding collection: name + embedding alias + filterable meta fields. " +
34
+ "Dims lock on first write; only declared filterables can be filtered on.",
35
+ config: collectionSpecSchema,
36
+ inputs: {},
37
+ outputs: { collection: value(z.string()) },
38
+ execute: async (ctx) => {
39
+ const spec = collectionSpecSchema.parse(ctx.config);
40
+ await service(ctx).ensureCollection(spec);
41
+ return { collection: spec.name };
42
+ },
43
+ };
44
+ const upsert = {
45
+ type: "vectors.upsert",
46
+ title: "vectors.upsert",
47
+ description: "Write items into a collection: { items: [{ id?, text, meta? } | { id, vector, meta? }] } → { count, embedded }. " +
48
+ "Text embeds through the collection's declared alias; unchanged items (same id + content hash) are skipped.",
49
+ config: z.object({ collection: z.string().min(1) }),
50
+ inputs: { items: value(z.array(vectorItemSchema)) },
51
+ outputs: { count: value(z.number()), embedded: value(z.number()) },
52
+ execute: async (ctx) => {
53
+ const { collection } = ctx.config;
54
+ const items = z.array(vectorItemSchema).parse((await ctx.input.value("items")) ?? []);
55
+ const res = await service(ctx).upsert(collection, items, ctx);
56
+ return { count: res.count, embedded: res.embedded };
57
+ },
58
+ };
59
+ const query = {
60
+ type: "vectors.query",
61
+ title: "vectors.query",
62
+ description: "Search a collection: text (embedded via the collection's alias) or a raw vector → { matches: [{ id, score, text, meta }] }. " +
63
+ "mode: vector | keyword | hybrid (RRF fusion); filter: { field: value | values[] } over DECLARED filterables, pruned before scoring.",
64
+ config: z.object({
65
+ collection: z.string().min(1),
66
+ k: z.number().int().positive().max(100).default(8),
67
+ mode: queryModeSchema.default("vector"),
68
+ filter: filterSchema.optional(),
69
+ }),
70
+ inputs: {
71
+ text: value(z.string().optional()),
72
+ vector: value(z.array(z.number()).optional()),
73
+ filter: value(filterSchema.optional()),
74
+ },
75
+ outputs: { matches: value() },
76
+ execute: async (ctx) => {
77
+ const cfg = ctx.config;
78
+ const [text, vector, filterIn] = await Promise.all([
79
+ ctx.input.has("text") ? ctx.input.value("text") : undefined,
80
+ ctx.input.has("vector") ? ctx.input.value("vector") : undefined,
81
+ ctx.input.has("filter") ? ctx.input.value("filter") : undefined,
82
+ ]);
83
+ const matches = await service(ctx).query(cfg.collection, { text: text ?? undefined, vector: vector ?? undefined, k: cfg.k, mode: cfg.mode, filter: filterIn ?? cfg.filter }, ctx);
84
+ return { matches };
85
+ },
86
+ };
87
+ const del = {
88
+ type: "vectors.delete",
89
+ title: "vectors.delete",
90
+ description: "Delete rows by id from a collection: { ids } → { count }.",
91
+ config: z.object({ collection: z.string().min(1) }),
92
+ inputs: { ids: value(z.array(z.string())) },
93
+ outputs: { count: value(z.number()) },
94
+ execute: async (ctx) => {
95
+ const { collection } = ctx.config;
96
+ const ids = (await ctx.input.value("ids")) ?? [];
97
+ return { count: await service(ctx).delete(collection, ids) };
98
+ },
99
+ };
100
+ const chunk = {
101
+ type: "vectors.chunk",
102
+ title: "vectors.chunk",
103
+ description: "Split text for indexing (recursive character splitter, overlap carried across boundaries). " +
104
+ "Input `text` (one string) or `docs` ([{ id?, text, meta? }]) → { chunks: [{ id, text, meta? }] } with ids `${docId}#${i}`.",
105
+ config: z.object(chunkConfig),
106
+ inputs: { text: value(z.string().optional()), docs: value(z.array(docSchema).optional()) },
107
+ outputs: { chunks: value() },
108
+ execute: async (ctx) => {
109
+ const cfg = ctx.config;
110
+ const [text, docs] = await Promise.all([
111
+ ctx.input.has("text") ? ctx.input.value("text") : undefined,
112
+ ctx.input.has("docs") ? ctx.input.value("docs") : undefined,
113
+ ]);
114
+ const inputDocs = docs?.length ? docs : text !== undefined && text !== null ? [{ text }] : [];
115
+ if (!inputDocs.length)
116
+ throw new Error("vectors.chunk: wire `text` (one string) or `docs` (an array of { id?, text, meta? })");
117
+ const chunks = inputDocs.flatMap((d) => chunkDoc(d, cfg));
118
+ return { chunks };
119
+ },
120
+ };
121
+ const index = {
122
+ type: "vectors.index",
123
+ title: "vectors.index",
124
+ description: "Chunk → embed → upsert in one node (the RAG ingestion convenience). Input `docs` ([{ id?, text, meta? }]); " +
125
+ "chunk ids are `${docId}#${i}`, each chunk carries its doc's meta. Unchanged chunks are skipped (content hash).",
126
+ config: z.object({ collection: z.string().min(1), ...chunkConfig }),
127
+ inputs: { docs: value(z.array(docSchema)) },
128
+ outputs: { count: value(z.number()), chunks: value(z.number()) },
129
+ execute: async (ctx) => {
130
+ const cfg = ctx.config;
131
+ const docs = z.array(docSchema).parse((await ctx.input.value("docs")) ?? []);
132
+ const chunks = docs.flatMap((d) => chunkDoc(d, cfg));
133
+ const res = await service(ctx).upsert(cfg.collection, chunks.map((c) => ({ id: c.id, text: c.text, meta: c.meta })), ctx);
134
+ return { count: res.count, chunks: chunks.length };
135
+ },
136
+ };
137
+ export const vectorsOps = [collectionEnsure, upsert, query, del, chunk, index];
138
+ //# sourceMappingURL=ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.js","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @pattern-js/mod-vectors — the VectorsService (key "vectorsService").
3
+ *
4
+ * The contract surface between ops/sibling mods and whichever engine is
5
+ * registered (mod-email's driver pattern: the default "local" engine ships
6
+ * here; sqlite-vec/pgvector drivers register in their `ready`). Embedding
7
+ * happens HERE, always through the collection's declared alias, via the
8
+ * duck-typed "aiProviderService" — mod-ai is never imported.
9
+ */
10
+ import type { OpContext } from "@pattern-js/core";
11
+ import type { CollectionInfo, CollectionSpec, Filter, ListedRow, Match, QueryMode, VectorItem, VectorsEngine } from "./types.js";
12
+ export declare const VECTORS_SERVICE = "vectorsService";
13
+ export interface VectorsService {
14
+ registerEngine(engine: VectorsEngine): void;
15
+ /** The active engine's id ("local" unless a driver replaced it). */
16
+ engineId(): string;
17
+ ensureCollection(spec: CollectionSpec): Promise<void>;
18
+ listCollections(): Promise<CollectionInfo[]>;
19
+ /** Embed-and-write. Items may carry raw vectors (embedding skipped) or text. */
20
+ upsert(collection: string, items: VectorItem[], ctx: OpContext): Promise<{
21
+ count: number;
22
+ embedded: number;
23
+ }>;
24
+ query(collection: string, input: {
25
+ text?: string;
26
+ vector?: number[];
27
+ k?: number;
28
+ filter?: Filter;
29
+ mode?: QueryMode;
30
+ }, ctx: OpContext): Promise<Match[]>;
31
+ /** Enumerate rows newest-first (admin browsers, memory managers) — no scoring, that's `query`. */
32
+ list(collection: string, q?: {
33
+ filter?: Filter;
34
+ limit?: number;
35
+ offset?: number;
36
+ }): Promise<ListedRow[]>;
37
+ delete(collection: string, ids: string[]): Promise<number>;
38
+ }
39
+ export declare class DefaultVectorsService implements VectorsService {
40
+ private readonly engines;
41
+ private active;
42
+ constructor(local: VectorsEngine);
43
+ registerEngine(engine: VectorsEngine): void;
44
+ engineId(): string;
45
+ private engine;
46
+ ensureCollection(spec: CollectionSpec): Promise<void>;
47
+ listCollections(): Promise<CollectionInfo[]>;
48
+ private spec;
49
+ /** The collection's embedding model, via its declared alias — the ONE path to a vector. */
50
+ private model;
51
+ private embed;
52
+ upsert(collection: string, items: VectorItem[], ctx: OpContext): Promise<{
53
+ count: number;
54
+ embedded: number;
55
+ }>;
56
+ query(collection: string, input: {
57
+ text?: string;
58
+ vector?: number[];
59
+ k?: number;
60
+ filter?: Filter;
61
+ mode?: QueryMode;
62
+ }, ctx: OpContext): Promise<Match[]>;
63
+ list(collection: string, q?: {
64
+ filter?: Filter;
65
+ limit?: number;
66
+ offset?: number;
67
+ }): Promise<ListedRow[]>;
68
+ delete(collection: string, ids: string[]): Promise<number>;
69
+ /** Undeclared filter field = a located error naming the field AND the fix. */
70
+ private assertFilterable;
71
+ }
72
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEd,MAAM,EAEN,SAAS,EACT,KAAK,EACL,SAAS,EACT,UAAU,EACV,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAehD,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,IAAI,MAAM,CAAC;IACnB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,eAAe,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7C,gFAAgF;IAChF,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9G,KAAK,CACH,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,EAC1F,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACpB,kGAAkG;IAClG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACzG,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5D;AAmBD,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,MAAM,CAAS;gBAEX,KAAK,EAAE,aAAa;IAKhC,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAO3C,QAAQ,IAAI,MAAM;IAIlB,OAAO,CAAC,MAAM;IAIR,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAU3D,eAAe,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAI9B,IAAI;IAQlB,2FAA2F;YAC7E,KAAK;YAWL,KAAK;IAcb,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAsC7G,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,EAC1F,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,KAAK,EAAE,CAAC;IAsBb,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQlH,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1D,8EAA8E;IAC9E,OAAO,CAAC,gBAAgB;CAWzB"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * @pattern-js/mod-vectors — the VectorsService (key "vectorsService").
3
+ *
4
+ * The contract surface between ops/sibling mods and whichever engine is
5
+ * registered (mod-email's driver pattern: the default "local" engine ships
6
+ * here; sqlite-vec/pgvector drivers register in their `ready`). Embedding
7
+ * happens HERE, always through the collection's declared alias, via the
8
+ * duck-typed "aiProviderService" — mod-ai is never imported.
9
+ */
10
+ import { createHash } from "node:crypto";
11
+ import { normalize } from "./engine-local.js";
12
+ export const VECTORS_SERVICE = "vectorsService";
13
+ /* ── duck-typed views of mod-ai (never imported) ─────────────────────────── */
14
+ const AI_PROVIDER_SERVICE = "aiProviderService";
15
+ const sha256 = (s) => createHash("sha256").update(s).digest("hex");
16
+ /** Meta values for the DECLARED filterable fields (arrays flatten to any-of). */
17
+ function extractFilterables(meta, declared) {
18
+ const out = {};
19
+ if (!meta)
20
+ return out;
21
+ for (const field of declared) {
22
+ const raw = meta[field];
23
+ if (raw === undefined || raw === null)
24
+ continue;
25
+ const values = (Array.isArray(raw) ? raw : [raw]).filter((v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean");
26
+ if (values.length)
27
+ out[field] = values;
28
+ }
29
+ return out;
30
+ }
31
+ export class DefaultVectorsService {
32
+ engines = new Map();
33
+ active;
34
+ constructor(local) {
35
+ this.engines.set(local.id, local);
36
+ this.active = local.id;
37
+ }
38
+ registerEngine(engine) {
39
+ this.engines.set(engine.id, engine);
40
+ // Last registered driver wins (there is at most one real driver installed);
41
+ // the local engine stays available as "local".
42
+ this.active = engine.id;
43
+ }
44
+ engineId() {
45
+ return this.active;
46
+ }
47
+ engine() {
48
+ return this.engines.get(this.active);
49
+ }
50
+ async ensureCollection(spec) {
51
+ if (!spec.alias) {
52
+ throw new Error(`vectors: collection "${spec.name}" must declare its embedding alias — that declaration is what makes ` +
53
+ "index-with-one-model-query-with-another unrepresentable.");
54
+ }
55
+ await this.engine().ensureCollection(spec);
56
+ }
57
+ listCollections() {
58
+ return this.engine().listCollections();
59
+ }
60
+ async spec(collection) {
61
+ const spec = await this.engine().getCollection(collection);
62
+ if (!spec) {
63
+ throw new Error(`vectors: unknown collection "${collection}" — declare it first with vectors.collection.ensure`);
64
+ }
65
+ return spec;
66
+ }
67
+ /** The collection's embedding model, via its declared alias — the ONE path to a vector. */
68
+ async model(spec, ctx) {
69
+ const provider = ctx.services[AI_PROVIDER_SERVICE];
70
+ if (!provider || typeof provider.textEmbeddingModel !== "function") {
71
+ throw new Error(`vectors: embedding text for collection "${spec.name}" needs @pattern-js/mod-ai installed ` +
72
+ `(it provides the "${spec.alias}" embedding alias). Raw-vector upsert/query works without it.`);
73
+ }
74
+ return provider.textEmbeddingModel({ alias: spec.alias }, ctx);
75
+ }
76
+ async embed(spec, values, ctx) {
77
+ if (!values.length)
78
+ return [];
79
+ const model = await this.model(spec, ctx);
80
+ const perCallRaw = typeof model.maxEmbeddingsPerCall === "function" ? await model.maxEmbeddingsPerCall() : model.maxEmbeddingsPerCall;
81
+ const perCall = Math.max(1, Math.min(Number(perCallRaw) || 64, 64));
82
+ const out = [];
83
+ for (let i = 0; i < values.length; i += perCall) {
84
+ const batch = values.slice(i, i + perCall);
85
+ const { embeddings } = await model.doEmbed({ values: batch, abortSignal: ctx.signal });
86
+ for (const e of embeddings)
87
+ out.push(normalize(e));
88
+ }
89
+ return out;
90
+ }
91
+ async upsert(collection, items, ctx) {
92
+ const spec = await this.spec(collection);
93
+ const rows = [];
94
+ const toEmbed = [];
95
+ for (const item of items) {
96
+ if (item.vector === undefined && !item.text?.trim()) {
97
+ throw new Error(`vectors: an upsert item needs \`text\` (embedded via alias "${spec.alias}") or a raw \`vector\``);
98
+ }
99
+ const id = item.id ?? sha256(item.text ?? JSON.stringify(item.vector)).slice(0, 24);
100
+ const hash = sha256(JSON.stringify({ t: item.text ?? null, v: item.vector ?? null, m: item.meta ?? null }));
101
+ rows.push({
102
+ id,
103
+ vector: item.vector ? normalize(item.vector) : null,
104
+ text: item.text ?? null,
105
+ meta: item.meta ?? null,
106
+ filterValues: extractFilterables(item.meta, spec.filterables),
107
+ hash,
108
+ });
109
+ if (item.vector === undefined)
110
+ toEmbed.push({ index: rows.length - 1, text: item.text });
111
+ }
112
+ // Content-hash diffing: unchanged rows (same id + hash) skip re-embedding
113
+ // AND re-writing — the boot indexer leans on this after every upgrade.
114
+ const existing = await this.engine().hashes(collection, rows.map((r) => r.id));
115
+ const changed = new Set(rows.filter((r) => existing.get(r.id) !== r.hash).map((r) => r.id));
116
+ const pendingEmbeds = toEmbed.filter(({ index }) => changed.has(rows[index].id));
117
+ const embeddings = await this.embed(spec, pendingEmbeds.map((p) => p.text), ctx);
118
+ pendingEmbeds.forEach(({ index }, i) => {
119
+ rows[index].vector = embeddings[i];
120
+ });
121
+ const writes = rows.filter((r) => changed.has(r.id));
122
+ await this.engine().upsert(collection, writes);
123
+ return { count: writes.length, embedded: embeddings.length };
124
+ }
125
+ async query(collection, input, ctx) {
126
+ const spec = await this.spec(collection);
127
+ const mode = input.mode ?? "vector";
128
+ const k = Math.max(1, Math.min(input.k ?? 8, 100));
129
+ if (input.filter)
130
+ this.assertFilterable(spec, input.filter, collection);
131
+ if (!input.text?.trim() && input.vector === undefined) {
132
+ throw new Error("vectors: query needs `text` (embedded via the collection's alias) or a raw `vector`");
133
+ }
134
+ if (mode !== "vector" && !input.text?.trim()) {
135
+ throw new Error(`vectors: mode "${mode}" ranks by keywords — it needs a \`text\` query`);
136
+ }
137
+ let vector;
138
+ if (mode !== "keyword") {
139
+ vector = input.vector ? normalize(input.vector) : (await this.embed(spec, [input.text], ctx))[0];
140
+ }
141
+ return this.engine().query(collection, { vector, text: input.text, k, filter: input.filter, mode });
142
+ }
143
+ async list(collection, q = {}) {
144
+ const spec = await this.spec(collection);
145
+ if (q.filter)
146
+ this.assertFilterable(spec, q.filter, collection);
147
+ const eng = this.engine();
148
+ if (!eng.list)
149
+ throw new Error(`vectors: engine "${eng.id}" does not support listing rows`);
150
+ return eng.list(collection, q);
151
+ }
152
+ delete(collection, ids) {
153
+ return this.engine().delete(collection, ids);
154
+ }
155
+ /** Undeclared filter field = a located error naming the field AND the fix. */
156
+ assertFilterable(spec, filter, collection) {
157
+ const declared = new Set(spec.filterables);
158
+ for (const field of Object.keys(filter)) {
159
+ if (!declared.has(field)) {
160
+ throw new Error(`vectors: "${field}" is not a filterable field of collection "${collection}" — declared: ` +
161
+ `[${spec.filterables.join(", ") || "none"}]. Add it to \`filterables\` in vectors.collection.ensure and re-upsert.`);
162
+ }
163
+ }
164
+ }
165
+ }
166
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @pattern-js/mod-vectors — value shapes + the engine SPI.
3
+ *
4
+ * The load-bearing idea: a collection DECLARES its embedding alias (and, once
5
+ * written, its dimensions), so "indexed with one model, queried with another"
6
+ * — the classic silent RAG bug — is unrepresentable. Filterable metadata is
7
+ * declared the same way (mod-store's declared-index philosophy): only
8
+ * declared fields are indexed and only declared fields may be filtered on,
9
+ * so a typo'd filter is a located error, not an empty result.
10
+ */
11
+ import { z } from "@pattern-js/core";
12
+ export declare const filterValueSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
13
+ /** AND of equality/any-of — deliberately minimal so every driver can push it down. */
14
+ export declare const filterSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>]>>;
15
+ export type Filter = z.infer<typeof filterSchema>;
16
+ export type FilterValue = z.infer<typeof filterValueSchema>;
17
+ export declare const queryModeSchema: z.ZodEnum<{
18
+ vector: "vector";
19
+ keyword: "keyword";
20
+ hybrid: "hybrid";
21
+ }>;
22
+ export type QueryMode = z.infer<typeof queryModeSchema>;
23
+ export declare const collectionSpecSchema: z.ZodObject<{
24
+ name: z.ZodString;
25
+ alias: z.ZodString;
26
+ dims: z.ZodOptional<z.ZodNumber>;
27
+ metric: z.ZodDefault<z.ZodLiteral<"cosine">>;
28
+ filterables: z.ZodDefault<z.ZodArray<z.ZodString>>;
29
+ }, z.core.$strip>;
30
+ export type CollectionSpec = z.infer<typeof collectionSpecSchema>;
31
+ /** One upsert item: text to embed (id defaults to a hash) or a raw vector. */
32
+ export declare const vectorItemSchema: z.ZodObject<{
33
+ id: z.ZodOptional<z.ZodString>;
34
+ text: z.ZodOptional<z.ZodString>;
35
+ vector: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
36
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
37
+ }, z.core.$strip>;
38
+ export type VectorItem = z.infer<typeof vectorItemSchema>;
39
+ export interface Match {
40
+ id: string;
41
+ score: number;
42
+ text: string | null;
43
+ meta: Record<string, unknown> | null;
44
+ }
45
+ export interface CollectionInfo extends CollectionSpec {
46
+ rows: number;
47
+ }
48
+ /** A fully-prepared row the service hands the engine (embedding already done). */
49
+ export interface EngineRow {
50
+ id: string;
51
+ /** L2-normalized (cosine = dot); null for keyword-only rows. */
52
+ vector: Float32Array | null;
53
+ text: string | null;
54
+ meta: Record<string, unknown> | null;
55
+ /** Values for the DECLARED filterable fields, pre-extracted from meta. */
56
+ filterValues: Record<string, FilterValue[]>;
57
+ /** Content hash — lets indexers skip re-embedding unchanged text. */
58
+ hash: string;
59
+ }
60
+ export interface EngineQuery {
61
+ /** L2-normalized query vector (vector/hybrid modes). */
62
+ vector?: Float32Array;
63
+ /** The raw text query (keyword/hybrid modes). */
64
+ text?: string;
65
+ k: number;
66
+ filter?: Filter;
67
+ mode: QueryMode;
68
+ }
69
+ /**
70
+ * The driver SPI (mod-email's registerDriver pattern). The default "local"
71
+ * engine is sqlite-backed brute force; sqlite-vec / pgvector drivers register
72
+ * the same shape and receive `{ filter, mode }` to push down.
73
+ */
74
+ /** One stored row, as enumeration (no scores — that's `query`'s job). */
75
+ export interface ListedRow {
76
+ id: string;
77
+ text: string | null;
78
+ meta: Record<string, unknown> | null;
79
+ updatedAt: number;
80
+ }
81
+ export interface VectorsEngine {
82
+ id: string;
83
+ ensureCollection(spec: CollectionSpec): Promise<void>;
84
+ getCollection(name: string): Promise<CollectionSpec | null>;
85
+ listCollections(): Promise<CollectionInfo[]>;
86
+ /** Existing content hashes for these ids (indexers diff against this). */
87
+ hashes(collection: string, ids: string[]): Promise<Map<string, string>>;
88
+ upsert(collection: string, rows: EngineRow[]): Promise<void>;
89
+ query(collection: string, q: EngineQuery): Promise<Match[]>;
90
+ delete(collection: string, ids: string[]): Promise<number>;
91
+ /**
92
+ * Enumerate rows, newest-first, optionally pruned by a declared-filterable
93
+ * filter (admin browsers, memory managers). OPTIONAL — a driver that can't
94
+ * scan cheaply may omit it; the service reports that honestly.
95
+ */
96
+ list?(collection: string, q: {
97
+ filter?: Filter;
98
+ limit?: number;
99
+ offset?: number;
100
+ }): Promise<ListedRow[]>;
101
+ /** Lock dims on first write; throws (naming the alias) on mismatch. */
102
+ close(): Promise<void>;
103
+ }
104
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @pattern-js/mod-vectors — value shapes + the engine SPI.
3
+ *
4
+ * The load-bearing idea: a collection DECLARES its embedding alias (and, once
5
+ * written, its dimensions), so "indexed with one model, queried with another"
6
+ * — the classic silent RAG bug — is unrepresentable. Filterable metadata is
7
+ * declared the same way (mod-store's declared-index philosophy): only
8
+ * declared fields are indexed and only declared fields may be filtered on,
9
+ * so a typo'd filter is a located error, not an empty result.
10
+ */
11
+ import { z } from "@pattern-js/core";
12
+ export const filterValueSchema = z.union([z.string(), z.number(), z.boolean()]);
13
+ /** AND of equality/any-of — deliberately minimal so every driver can push it down. */
14
+ export const filterSchema = z.record(z.string(), z.union([filterValueSchema, z.array(filterValueSchema)]));
15
+ export const queryModeSchema = z.enum(["vector", "keyword", "hybrid"]);
16
+ export const collectionSpecSchema = z.object({
17
+ name: z.string().min(1),
18
+ /** The embedding alias this collection indexes AND queries with. */
19
+ alias: z.string().min(1),
20
+ /** Locked on first write when omitted; a later mismatch is a hard, located error. */
21
+ dims: z.number().int().positive().optional(),
22
+ metric: z.literal("cosine").default("cosine"),
23
+ /** Meta fields extracted into the indexed side table — the ONLY filterable fields. */
24
+ filterables: z.array(z.string()).default([]),
25
+ });
26
+ /** One upsert item: text to embed (id defaults to a hash) or a raw vector. */
27
+ export const vectorItemSchema = z.object({
28
+ id: z.string().optional(),
29
+ text: z.string().optional(),
30
+ vector: z.array(z.number()).optional(),
31
+ meta: z.record(z.string(), z.unknown()).optional(),
32
+ });
33
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAC;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAChF,sFAAsF;AACtF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAI3G,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,oEAAoE;IACpE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,qFAAqF;IACrF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC7C,sFAAsF;IACtF,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC7C,CAAC,CAAC;AAGH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC"}