@nacre.work/core 0.0.0 → 0.1.0

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 (72) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +9 -0
  3. package/dist/authz/filter.d.ts +54 -3
  4. package/dist/authz/filter.d.ts.map +1 -1
  5. package/dist/authz/filter.js +45 -9
  6. package/dist/authz/filter.js.map +1 -1
  7. package/dist/authz/index.d.ts +2 -2
  8. package/dist/authz/index.d.ts.map +1 -1
  9. package/dist/authz/index.js +1 -1
  10. package/dist/authz/index.js.map +1 -1
  11. package/dist/config.d.ts +33 -0
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +137 -3
  14. package/dist/config.js.map +1 -1
  15. package/dist/db/client.d.ts +39 -0
  16. package/dist/db/client.d.ts.map +1 -1
  17. package/dist/db/client.js +82 -0
  18. package/dist/db/client.js.map +1 -1
  19. package/dist/db/migrate.d.ts.map +1 -1
  20. package/dist/db/migrate.js +49 -0
  21. package/dist/db/migrate.js.map +1 -1
  22. package/dist/index.d.ts +15 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +9 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/lifecycle.d.ts +57 -0
  27. package/dist/lifecycle.d.ts.map +1 -0
  28. package/dist/lifecycle.js +97 -0
  29. package/dist/lifecycle.js.map +1 -0
  30. package/dist/metadata.d.ts +50 -0
  31. package/dist/metadata.d.ts.map +1 -0
  32. package/dist/metadata.js +127 -0
  33. package/dist/metadata.js.map +1 -0
  34. package/dist/metrics.d.ts +18 -1
  35. package/dist/metrics.d.ts.map +1 -1
  36. package/dist/metrics.js +77 -2
  37. package/dist/metrics.js.map +1 -1
  38. package/dist/migrations/0008_authenticating_lookup.sql +124 -0
  39. package/dist/migrations/0009_refresh_tokens.sql +73 -0
  40. package/dist/migrations/0010_definer_search_path.sql +22 -0
  41. package/dist/migrations/0011_sweep_lease.sql +36 -0
  42. package/dist/migrations/0012_prune.sql +118 -0
  43. package/dist/migrations/0013_reindex.sql +65 -0
  44. package/dist/oauth.d.ts +45 -0
  45. package/dist/oauth.d.ts.map +1 -0
  46. package/dist/oauth.js +53 -0
  47. package/dist/oauth.js.map +1 -0
  48. package/dist/observability.d.ts.map +1 -1
  49. package/dist/observability.js +81 -13
  50. package/dist/observability.js.map +1 -1
  51. package/dist/passwords.d.ts +37 -0
  52. package/dist/passwords.d.ts.map +1 -0
  53. package/dist/passwords.js +234 -0
  54. package/dist/passwords.js.map +1 -0
  55. package/dist/redis.d.ts +46 -0
  56. package/dist/redis.d.ts.map +1 -0
  57. package/dist/redis.js +234 -0
  58. package/dist/redis.js.map +1 -0
  59. package/dist/reindex.d.ts +87 -0
  60. package/dist/reindex.d.ts.map +1 -0
  61. package/dist/reindex.js +97 -0
  62. package/dist/reindex.js.map +1 -0
  63. package/dist/tsconfig.tsbuildinfo +1 -1
  64. package/dist/vector/query.d.ts +49 -4
  65. package/dist/vector/query.d.ts.map +1 -1
  66. package/dist/vector/query.js +43 -10
  67. package/dist/vector/query.js.map +1 -1
  68. package/dist/vector/search.d.ts +109 -4
  69. package/dist/vector/search.d.ts.map +1 -1
  70. package/dist/vector/search.js +166 -7
  71. package/dist/vector/search.js.map +1 -1
  72. package/package.json +26 -8
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../vector/query.ts"],"names":[],"mappings":"AA2DA;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA2B;IAC1D,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,EAAE,EAAE,WAAW,GAAG,IAAI,EAAE,GAAG,OAAO,CAAA;IAEnF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,2EAA2E;QAC3E,yEAAyE;QACzE,+CAA+C;QAC/C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAClC,KAAK,EACH,MAAM,CAAC,IAAI,KAAK,OAAO;gBACrB,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;gBACpB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAChF,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,4EAA4E;YAC5E,MAAM;YACN,KAAK,EAAE,aAAa;SACrB,CAAC,CAAC;QACH,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACxB,KAAK;QACL,YAAY,EAAE,WAAW;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE;IAChD,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE;IAC9C,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE;IAC9C,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE;IAC/C;QACE,UAAU,EAAE,UAAU;QACtB,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;KACpE;CACO,CAAA;AAEV;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAkB,EAAE,IAAY;IAC/D,OAAO;QACL,OAAO,EAAE;YACP,CAAC,UAAU,CAAC,EAAE;gBACZ,IAAI;gBACJ,QAAQ,EAAE,QAAiB;gBAC3B,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE;gBACzC,mBAAmB,EAAE;oBACnB,MAAM,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;iBACpE;aACF;SACF;QACD,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5B,iBAAiB,EAAE,EAAE,sBAAsB,EAAE,CAAC,EAAE;QAChD,eAAe,EAAE,IAAI;KACtB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,UAAkB;IAC1D,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,IAAI,UAAU,EAAE,CAAA;AAC/D,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,EAAE,CAAC,CAAA;IACzE,CAAC;IACD,OAAO,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAA;AAC5C,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../vector/query.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,44 @@
1
- import { type QueryablePlan } from '../authz/filter.js';
1
+ import { type Narrowing, type QueryablePlan } from '../authz/filter.js';
2
2
  import { type Branch } from './query.js';
3
+ /**
4
+ * What Qdrant actually said.
5
+ *
6
+ * The REST client throws `Error: Bad Request` with the reason in a `data`
7
+ * property nobody looks at, so an unhandled one reaches a log as four words
8
+ * that name no collection, no vector and no cause. Both times a query in this
9
+ * repository was malformed, the message alone was useless and the reason was
10
+ * one line inside `data`.
11
+ */
12
+ export declare function explainQdrant(cause: unknown): string;
3
13
  export interface VectorStoreOptions {
4
14
  readonly url: string;
5
15
  readonly apiKey?: string;
6
16
  }
7
17
  export interface SearchRequest {
8
18
  readonly orgId: string;
9
- readonly orgSlug: string;
19
+ /**
20
+ * The organization's collection, read from `organizations.vector_collection`.
21
+ *
22
+ * Not derived from the slug. It was, everywhere, and the column was written
23
+ * once at `init` and read by nothing — so a reindex that moved the pointer
24
+ * moved a pointer no query followed, and the copy it had just finished sat
25
+ * unused while search carried on against the old collection. The name is a
26
+ * value the database owns; deriving it in six places is what let the two
27
+ * disagree silently.
28
+ */
29
+ readonly collection: string;
10
30
  /** What the caller may reach. `none` is not accepted — see buildFilter. */
11
31
  readonly plan: QueryablePlan;
12
32
  readonly branches: readonly Branch[];
13
33
  readonly topK: number;
34
+ /**
35
+ * A restriction the caller asked for, layered on top of the permission one.
36
+ *
37
+ * Still not a filter the caller assembles — it is a list of layer ids that
38
+ * `buildFilter` turns into a `must`, so it can only ever remove results. The
39
+ * distinction is the whole reason this is not `filter?: VectorFilter`.
40
+ */
41
+ readonly narrow?: Narrowing;
14
42
  }
15
43
  export interface Hit {
16
44
  readonly id: string;
@@ -32,7 +60,15 @@ export interface Hit {
32
60
  export declare class VectorStore {
33
61
  #private;
34
62
  constructor(options: VectorStoreOptions);
35
- ensureCollection(orgSlug: string, vectorName: string, size: number): Promise<void>;
63
+ /**
64
+ * Create an organization's first collection, if it is not there.
65
+ *
66
+ * `collectionName(orgSlug)` is the *initial* name and only that. Once a
67
+ * reindex has rebuilt the collection the organization's name no longer
68
+ * derives from its slug, which is why every other method here takes the
69
+ * collection rather than working it out.
70
+ */
71
+ ensureCollection(orgSlug: string, vectorName: string, size: number): Promise<string>;
36
72
  /**
37
73
  * Mark every point of a document deleted.
38
74
  *
@@ -46,7 +82,68 @@ export declare class VectorStore {
46
82
  * is tombstoned in Postgres but not here stays searchable until a background
47
83
  * job gets to it. That window is exactly what invariant I5 forbids.
48
84
  */
49
- tombstone(orgSlug: string, documentId: string): Promise<void>;
85
+ tombstone(collection: string, documentId: string): Promise<void>;
86
+ /**
87
+ * Replace the caller's metadata on every point of a document.
88
+ *
89
+ * `setPayload` under the reserved key, which merges at the top level and so
90
+ * leaves `org_id`, `deleted`, `acl_tags` and the rest exactly as they were —
91
+ * the namespace is what makes that safe rather than a list of fields to
92
+ * preserve.
93
+ *
94
+ * Whole-object replacement inside that key, not a merge: a caller sending
95
+ * `{source: "notion"}` after `{source: "confluence", team: "legal"}` means
96
+ * the document now has one tag, and merging would leave a tag they removed
97
+ * still matching filters. `PATCH` names the resource, not the field.
98
+ *
99
+ * The vectors are untouched. Re-embedding a document because a tag moved
100
+ * would make a bulk retag cost as much as a bulk ingest, which is the same
101
+ * argument the ACL retag path is built on.
102
+ */
103
+ setMetadata(collection: string, documentId: string, metadata: Record<string, unknown>): Promise<void>;
104
+ /**
105
+ * The named vectors a collection has, and their widths.
106
+ *
107
+ * The set is fixed when the collection is created. That is the fact the whole
108
+ * reindex design turns on, and it was worth checking rather than assuming:
109
+ * `update_collection` adjusts the parameters of vectors that already exist and
110
+ * answers `Not existing vector name error` for anything else, so there is no
111
+ * way to add one to a live collection.
112
+ */
113
+ vectorsOf(collection: string): Promise<Record<string, number>>;
114
+ /**
115
+ * Copy an organization's collection into a new one that also has room for a
116
+ * new model.
117
+ *
118
+ * This exists because a named vector cannot be added to a collection after it
119
+ * is created. The way around that is not to add one — it is to create a
120
+ * collection that already has the slot, move the points across as they are,
121
+ * and switch which collection the organization points at.
122
+ *
123
+ * **No embeddings are computed here.** The vectors that come out of the old
124
+ * collection go into the new one unchanged. That is what makes this the cheap
125
+ * half of a model migration: the expensive half — computing vectors with the
126
+ * new model — happens afterwards, one layer at a time, into the slot this
127
+ * created.
128
+ *
129
+ * Idempotent by construction: if the target already exists it is deleted and
130
+ * rebuilt. A half-copied collection is worse than none, and there is no way to
131
+ * tell one from a complete one by looking at it — the source is still live and
132
+ * still authoritative until the pointer moves, so throwing away a partial
133
+ * attempt costs only the time it took.
134
+ */
135
+ copyCollection(input: {
136
+ from: string;
137
+ to: string;
138
+ /** Added alongside everything the source already has. */
139
+ addVector: {
140
+ name: string;
141
+ size: number;
142
+ };
143
+ /** Points per scroll page and per upsert. */
144
+ batch?: number;
145
+ onProgress?: (copied: number) => void;
146
+ }): Promise<void>;
50
147
  search(request: SearchRequest): Promise<readonly Hit[]>;
51
148
  /**
52
149
  * Re-check the tenant on the way out.
@@ -57,6 +154,14 @@ export declare class VectorStore {
57
154
  * and a bug that produces one cross-tenant row will produce more.
58
155
  */
59
156
  static assertTenant(orgId: string, hits: readonly Hit[]): readonly Hit[];
157
+ /**
158
+ * Whether the vector store is answering.
159
+ *
160
+ * `getCollections` rather than a bare TCP connect: Qdrant accepting a socket
161
+ * while refusing queries is the failure a readiness probe exists to catch,
162
+ * and the Compose healthcheck already covers the socket.
163
+ */
164
+ ready(): Promise<boolean>;
60
165
  close(): Promise<void>;
61
166
  }
62
167
  //# sourceMappingURL=search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../vector/search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACpE,OAAO,EAAuE,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AAE7G,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,GAAG;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,WAAW;;gBAGV,OAAO,EAAE,kBAAkB;IAWjC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxF;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7D,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;IAiB7D;;;;;;;OAOG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,EAAE,GAAG,SAAS,GAAG,EAAE;IAYlE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../vector/search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACrG,OAAO,EAAqF,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AAE3H;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGpD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAC5B;AAED,MAAM,WAAW,GAAG;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,WAAW;;gBAGV,OAAO,EAAE,kBAAkB;IAWvC;;;;;;;OAOG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB1F;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE;;;;;;;;;;;;;;;;OAgBG;IACG,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC;IAehB;;;;;;;;OAQG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAQpE;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,cAAc,CAAC,KAAK,EAAE;QAC1B,IAAI,EAAE,MAAM,CAAA;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,yDAAyD;QACzD,SAAS,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;QACzC,6CAA6C;QAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;KACtC,GAAG,OAAO,CAAC,IAAI,CAAC;IA+DX,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;IA4B7D;;;;;;;OAOG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,EAAE,GAAG,SAAS,GAAG,EAAE;IAYxE;;;;;;OAMG;IACG,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAKzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
@@ -1,6 +1,19 @@
1
1
  import { QdrantClient } from '@qdrant/js-client-rest';
2
- import { buildFilter } from '../authz/filter.js';
3
- import { buildHybridQuery, collectionConfig, collectionName, PAYLOAD_INDEXES } from './query.js';
2
+ import { buildFilter, METADATA_PREFIX } from '../authz/filter.js';
3
+ import { buildHybridQuery, collectionConfig, collectionName, PAYLOAD_INDEXES, vectorParams } from './query.js';
4
+ /**
5
+ * What Qdrant actually said.
6
+ *
7
+ * The REST client throws `Error: Bad Request` with the reason in a `data`
8
+ * property nobody looks at, so an unhandled one reaches a log as four words
9
+ * that name no collection, no vector and no cause. Both times a query in this
10
+ * repository was malformed, the message alone was useless and the reason was
11
+ * one line inside `data`.
12
+ */
13
+ export function explainQdrant(cause) {
14
+ const data = cause?.data;
15
+ return data === undefined ? String(cause) : `${String(cause)} — ${JSON.stringify(data)}`;
16
+ }
4
17
  /**
5
18
  * The vector store.
6
19
  *
@@ -23,11 +36,19 @@ export class VectorStore {
23
36
  ? { url: options.url }
24
37
  : { url: options.url, apiKey: options.apiKey });
25
38
  }
39
+ /**
40
+ * Create an organization's first collection, if it is not there.
41
+ *
42
+ * `collectionName(orgSlug)` is the *initial* name and only that. Once a
43
+ * reindex has rebuilt the collection the organization's name no longer
44
+ * derives from its slug, which is why every other method here takes the
45
+ * collection rather than working it out.
46
+ */
26
47
  async ensureCollection(orgSlug, vectorName, size) {
27
48
  const name = collectionName(orgSlug);
28
49
  const existing = await this.#client.getCollections();
29
50
  if (existing.collections.some((c) => c.name === name))
30
- return;
51
+ return name;
31
52
  await this.#client.createCollection(name, collectionConfig(vectorName, size));
32
53
  // Created here rather than left to an operator: a filter that falls back to
33
54
  // a scan is a latency problem that only shows up at a customer's volume.
@@ -38,6 +59,7 @@ export class VectorStore {
38
59
  wait: true,
39
60
  });
40
61
  }
62
+ return name;
41
63
  }
42
64
  /**
43
65
  * Mark every point of a document deleted.
@@ -52,21 +74,147 @@ export class VectorStore {
52
74
  * is tombstoned in Postgres but not here stays searchable until a background
53
75
  * job gets to it. That window is exactly what invariant I5 forbids.
54
76
  */
55
- async tombstone(orgSlug, documentId) {
56
- await this.#client.setPayload(collectionName(orgSlug), {
77
+ async tombstone(collection, documentId) {
78
+ await this.#client.setPayload(collection, {
57
79
  wait: true,
58
80
  payload: { deleted: true },
59
81
  filter: { must: [{ key: 'doc_id', match: { value: documentId } }] },
60
82
  });
61
83
  }
84
+ /**
85
+ * Replace the caller's metadata on every point of a document.
86
+ *
87
+ * `setPayload` under the reserved key, which merges at the top level and so
88
+ * leaves `org_id`, `deleted`, `acl_tags` and the rest exactly as they were —
89
+ * the namespace is what makes that safe rather than a list of fields to
90
+ * preserve.
91
+ *
92
+ * Whole-object replacement inside that key, not a merge: a caller sending
93
+ * `{source: "notion"}` after `{source: "confluence", team: "legal"}` means
94
+ * the document now has one tag, and merging would leave a tag they removed
95
+ * still matching filters. `PATCH` names the resource, not the field.
96
+ *
97
+ * The vectors are untouched. Re-embedding a document because a tag moved
98
+ * would make a bulk retag cost as much as a bulk ingest, which is the same
99
+ * argument the ACL retag path is built on.
100
+ */
101
+ async setMetadata(collection, documentId, metadata) {
102
+ try {
103
+ await this.#client.setPayload(collection, {
104
+ wait: true,
105
+ payload: { [METADATA_PREFIX]: metadata },
106
+ filter: { must: [{ key: 'doc_id', match: { value: documentId } }] },
107
+ });
108
+ }
109
+ catch (cause) {
110
+ throw new Error(`metadata write to ${collection} rejected: ${explainQdrant(cause)}`, { cause });
111
+ }
112
+ }
113
+ /**
114
+ * The named vectors a collection has, and their widths.
115
+ *
116
+ * The set is fixed when the collection is created. That is the fact the whole
117
+ * reindex design turns on, and it was worth checking rather than assuming:
118
+ * `update_collection` adjusts the parameters of vectors that already exist and
119
+ * answers `Not existing vector name error` for anything else, so there is no
120
+ * way to add one to a live collection.
121
+ */
122
+ async vectorsOf(collection) {
123
+ const info = await this.#client.getCollection(collection);
124
+ const vectors = (info.config?.params?.vectors ?? {});
125
+ return Object.fromEntries(Object.entries(vectors).map(([name, v]) => [name, Number(v.size ?? 0)]));
126
+ }
127
+ /**
128
+ * Copy an organization's collection into a new one that also has room for a
129
+ * new model.
130
+ *
131
+ * This exists because a named vector cannot be added to a collection after it
132
+ * is created. The way around that is not to add one — it is to create a
133
+ * collection that already has the slot, move the points across as they are,
134
+ * and switch which collection the organization points at.
135
+ *
136
+ * **No embeddings are computed here.** The vectors that come out of the old
137
+ * collection go into the new one unchanged. That is what makes this the cheap
138
+ * half of a model migration: the expensive half — computing vectors with the
139
+ * new model — happens afterwards, one layer at a time, into the slot this
140
+ * created.
141
+ *
142
+ * Idempotent by construction: if the target already exists it is deleted and
143
+ * rebuilt. A half-copied collection is worse than none, and there is no way to
144
+ * tell one from a complete one by looking at it — the source is still live and
145
+ * still authoritative until the pointer moves, so throwing away a partial
146
+ * attempt costs only the time it took.
147
+ */
148
+ async copyCollection(input) {
149
+ const existing = await this.vectorsOf(input.from);
150
+ if (input.addVector.name in existing) {
151
+ throw new Error(`${input.from} already has a vector called ${input.addVector.name}; nothing to copy for`);
152
+ }
153
+ const vectors = {};
154
+ for (const [name, size] of Object.entries(existing)) {
155
+ vectors[name] = vectorParams(size);
156
+ }
157
+ vectors[input.addVector.name] = vectorParams(input.addVector.size);
158
+ // Rebuilt rather than resumed. See the note above.
159
+ await this.#client.deleteCollection(input.to).catch(() => undefined);
160
+ await this.#client.createCollection(input.to, {
161
+ vectors: vectors,
162
+ sparse_vectors: { bm25: {} },
163
+ optimizers_config: { default_segment_number: 4 },
164
+ on_disk_payload: true,
165
+ });
166
+ for (const index of PAYLOAD_INDEXES) {
167
+ await this.#client.createPayloadIndex(input.to, {
168
+ field_name: index.field_name,
169
+ field_schema: index.field_schema,
170
+ wait: true,
171
+ });
172
+ }
173
+ const batch = input.batch ?? 256;
174
+ let offset = undefined;
175
+ let copied = 0;
176
+ do {
177
+ const page = await this.#client.scroll(input.from, {
178
+ limit: batch,
179
+ with_payload: true,
180
+ with_vector: true,
181
+ ...(offset === undefined || offset === null ? {} : { offset }),
182
+ });
183
+ const points = page.points ?? [];
184
+ if (points.length > 0) {
185
+ await this.#client.upsert(input.to, {
186
+ wait: true,
187
+ points: points.map((p) => ({
188
+ id: p.id,
189
+ // Whatever the source had, unchanged. The new slot stays empty
190
+ // until a layer is reindexed into it.
191
+ vector: p.vector,
192
+ payload: p.payload ?? {},
193
+ })),
194
+ });
195
+ copied += points.length;
196
+ input.onProgress?.(copied);
197
+ }
198
+ offset = page.next_page_offset;
199
+ } while (offset !== undefined && offset !== null);
200
+ }
62
201
  async search(request) {
63
- const filter = buildFilter(request.orgId, request.plan);
202
+ const filter = buildFilter(request.orgId, request.plan, request.narrow);
64
203
  const query = buildHybridQuery({
65
204
  branches: request.branches,
66
205
  filter,
67
206
  limit: request.topK,
68
207
  });
69
- const result = await this.#client.query(collectionName(request.orgSlug), query);
208
+ let result;
209
+ try {
210
+ result = await this.#client.query(request.collection, query);
211
+ }
212
+ catch (cause) {
213
+ // Named, because the query has as many branches as the organization has
214
+ // models and "Bad Request" does not say which one Qdrant objected to.
215
+ throw new Error(`query against ${request.collection} using ` +
216
+ `${query.prefetch.map((b) => b.using).join(', ')} rejected: ${explainQdrant(cause)}`, { cause });
217
+ }
70
218
  return result.points.map((p) => ({
71
219
  id: String(p.id),
72
220
  score: p.score,
@@ -90,6 +238,17 @@ export class VectorStore {
90
238
  }
91
239
  return hits;
92
240
  }
241
+ /**
242
+ * Whether the vector store is answering.
243
+ *
244
+ * `getCollections` rather than a bare TCP connect: Qdrant accepting a socket
245
+ * while refusing queries is the failure a readiness probe exists to catch,
246
+ * and the Compose healthcheck already covers the socket.
247
+ */
248
+ async ready() {
249
+ await this.#client.getCollections();
250
+ return true;
251
+ }
93
252
  async close() {
94
253
  // The REST client holds no pool; this exists so callers have one shape to
95
254
  // depend on when it does.
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../vector/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../vector/search.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nacre.work/core",
3
- "version": "0.0.0",
4
- "description": "Data model, permission resolver, shared types",
3
+ "version": "0.1.0",
4
+ "description": "Nacre core: data model, permission resolver, and shared types",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/nacre-work/nacre.git",
@@ -10,10 +10,6 @@
10
10
  "homepage": "https://nacre.work",
11
11
  "license": "Apache-2.0",
12
12
  "type": "module",
13
- "scripts": {
14
- "build": "tsc -b && node ./scripts/copy-migrations.mjs",
15
- "dev": "tsx watch index.ts"
16
- },
17
13
  "publishConfig": {
18
14
  "access": "public"
19
15
  },
@@ -26,7 +22,9 @@
26
22
  }
27
23
  },
28
24
  "files": [
29
- "dist"
25
+ "dist",
26
+ "LICENSE",
27
+ "NOTICE"
30
28
  ],
31
29
  "dependencies": {
32
30
  "@qdrant/js-client-rest": "^1.18.0",
@@ -35,5 +33,25 @@
35
33
  "devDependencies": {
36
34
  "@types/node": "^26.1.2",
37
35
  "jose": "^6.2.7"
36
+ },
37
+ "keywords": [
38
+ "nacre",
39
+ "rag",
40
+ "permissions",
41
+ "access-control",
42
+ "authorization",
43
+ "vector-search",
44
+ "self-hosted"
45
+ ],
46
+ "bugs": {
47
+ "url": "https://github.com/nacre-work/nacre/issues"
48
+ },
49
+ "author": "Nacre",
50
+ "engines": {
51
+ "node": ">=22"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -b && node ./scripts/copy-migrations.mjs",
55
+ "dev": "tsx watch index.ts"
38
56
  }
39
- }
57
+ }