@vxil/sdk 0.11.1 → 0.13.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.
package/dist/index.d.ts CHANGED
@@ -741,7 +741,14 @@ export interface SearchHit {
741
741
  chunk_id: string;
742
742
  doc_id: string;
743
743
  text: string;
744
+ /** the fused RANK value (reciprocal-rank fusion: ≈ 1/61 for the first hit at
745
+ * the default rrf_k) — it orders the hits; it is NOT a similarity, so never
746
+ * threshold on it. */
744
747
  score: number;
748
+ /** cosine similarity of the hit to the query (−1…1, higher = closer) — the
749
+ * value to threshold on. null when the query used no vector (mode
750
+ * 'keyword', or a bring-your-own-vectors collection queried by text only). */
751
+ similarity: number | null;
745
752
  /** provider relevance score — present only when the hit went through the
746
753
  * configured BYO reranker (`reranked: true` on the result set). */
747
754
  rerank_score?: number;
@@ -1499,6 +1506,9 @@ export interface RagSearchHit {
1499
1506
  text: string;
1500
1507
  /** the raw retrieval score (RRF, or rerank relevance when reranked). */
1501
1508
  score: number;
1509
+ /** cosine similarity of the hit to the query, passed through from
1510
+ * vector-search (−1…1; null when retrieval used no query vector). */
1511
+ similarity?: number | null;
1502
1512
  /** the effective post-boost score results are RANKED by — present only when
1503
1513
  * metadata boosts applied (rag.md §2f). */
1504
1514
  boosted_score?: number;
@@ -1989,6 +1999,12 @@ export interface CmsReindexPage {
1989
1999
  skipped: number;
1990
2000
  next_cursor: string | null;
1991
2001
  complete: boolean;
2002
+ /** Present when this page certified an index (the last page of a pass over
2003
+ * a collection whose equality / owner index was not armed): 'armed',
2004
+ * 'pending' (rows changed during the pass — run another) or 'timeout' (the
2005
+ * check ran out of time — the index stays unarmed; filters stay correct
2006
+ * but unaccelerated). */
2007
+ index_certify?: 'armed' | 'pending' | 'timeout';
1992
2008
  }
1993
2009
  /** The result of a bounded filtered delete (cms.md §20). `matched` counts the
1994
2010
  * rows this page selected (≤ `limit`); `deleted` counts the ones actually
@@ -3559,6 +3575,12 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3559
3575
  * session) still sees every field. Writes are unaffected. ≤16 entries,
3560
3576
  * each `^[a-z0-9][a-z0-9_-]{0,31}$` (the `orgs` role alphabet). */
3561
3577
  read_roles?: string[];
3578
+ /** Equality index for an UNSLOTTED field (cms.md §3 "Indexed
3579
+ * equality"): `=` / `$eq` / `$in` filters on it are index-served
3580
+ * instead of a bounded scan — results are identical either way. ≤4
3581
+ * per collection; not with `index_slot` (a slot already indexes
3582
+ * equality) and not on a computed field. */
3583
+ indexed?: boolean;
3562
3584
  }>;
3563
3585
  /** Per-record action buttons (cms.md §17): `[{ key, label, fn }]` —
3564
3586
  * exactly ONE human-initiated step each; `fn` names a deployed tenant
@@ -3586,6 +3608,18 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3586
3608
  * read unless the session's verified roles intersect `roles`; server-caller
3587
3609
  * reads and ALL writes are unaffected. */
3588
3610
  setFieldReadRoles: (collection: string, field: string, type: "string" | "text" | "int" | "float" | "bool" | "datetime" | "json" | "relation" | "file", roles: string[] | null, rest?: Record<string, unknown>) => Promise<void>;
3611
+ /** Turn a field's EQUALITY INDEX on or off (cms.md §3 "Indexed equality")
3612
+ * — the same-type in-place alter on the fields route; `indexed` is
3613
+ * present-key, so no other attribute moves. Only for UNSLOTTED,
3614
+ * non-computed fields, ≤4 per collection (422 `eq_index_budget`).
3615
+ * `index_ready: false` + `reindex_required: true` on a collection over
3616
+ * 2,000 live items: run `reindexAll` (until then filters stay on the
3617
+ * bounded scan — never wrong, only slower). */
3618
+ setFieldIndexed: (collection: string, field: string, type: "string" | "text" | "int" | "float" | "bool" | "datetime" | "json" | "relation" | "file", indexed: boolean) => Promise<{
3619
+ indexed: boolean;
3620
+ index_ready: boolean;
3621
+ reindex_required: boolean;
3622
+ }>;
3589
3623
  /** Set (or clear, with `null`) the collection's end-user owner-scope flag
3590
3624
  * (design §5.1). Names an existing `string` field that holds the owner id. */
3591
3625
  setOwnerField: (collection: string, ownerField: string | null) => Promise<void>;
@@ -3623,6 +3657,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3623
3657
  updated: number;
3624
3658
  skipped: number;
3625
3659
  pages: number;
3660
+ index_certify?: CmsReindexPage["index_certify"];
3626
3661
  }>;
3627
3662
  /** Replace the collection's per-record ACTION list (cms.md §17) — the
3628
3663
  * `{ actions }` fields-route meta-op; `[]` clears. Each action is ONE
@@ -4031,11 +4066,13 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
4031
4066
  hook_reconcile?: {
4032
4067
  created: number;
4033
4068
  updated: number;
4069
+ unchanged?: number;
4034
4070
  deleted: number;
4035
4071
  failed: number;
4036
4072
  };
4037
4073
  cron_schedules?: {
4038
4074
  created: number;
4075
+ unchanged?: number;
4039
4076
  deleted: number;
4040
4077
  failed: number;
4041
4078
  };
@@ -5149,7 +5186,10 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
5149
5186
  }) => Promise<RagStreamHandle>;
5150
5187
  /** Retrieval-only grounding preview (rag.md §1c): the exact chunks `answer`
5151
5188
  * would ground on, with rerank + metadata boosts applied — no generation,
5152
- * no token spend. `boosts`/`rerank`/`min_score` override the rag config. */
5189
+ * no token spend. `boosts`/`rerank`/`min_score` override the rag config.
5190
+ * `min_score` floors the EFFECTIVE `score`, which is a RANK value (about
5191
+ * 0.016–0.033 at the top): a floor above ~0.033 drops every hit. Judge
5192
+ * relevance by each hit's `similarity` (cosine, -1..1) instead. */
5153
5193
  search: (input: {
5154
5194
  query: string;
5155
5195
  collection?: string;
package/dist/index.js CHANGED
@@ -1088,6 +1088,29 @@ export class Vxil {
1088
1088
  setFieldReadRoles: async (collection, field, type, roles, rest = {}) => {
1089
1089
  await this.call('POST', `/v1/cms/collections/${encodeURIComponent(collection)}/fields`, { ...rest, field, type, read_roles: roles ?? [] });
1090
1090
  },
1091
+ /** Turn a field's EQUALITY INDEX on or off (cms.md §3 "Indexed equality")
1092
+ * — the same-type in-place alter on the fields route; `indexed` is
1093
+ * present-key, so no other attribute moves. Only for UNSLOTTED,
1094
+ * non-computed fields, ≤4 per collection (422 `eq_index_budget`).
1095
+ * `index_ready: false` + `reindex_required: true` on a collection over
1096
+ * 2,000 live items: run `reindexAll` (until then filters stay on the
1097
+ * bounded scan — never wrong, only slower). */
1098
+ setFieldIndexed: async (collection, field, type, indexed) => {
1099
+ try {
1100
+ const d = (await this.call('POST', `/v1/cms/collections/${encodeURIComponent(collection)}/fields`, { field, type, indexed })).data ?? {};
1101
+ return { indexed: d.indexed ?? indexed, index_ready: d.index_ready ?? indexed, reindex_required: d.reindex_required === true };
1102
+ }
1103
+ catch (e) {
1104
+ // 409 already_exists = the field is already in that state (the
1105
+ // idempotent re-POST); read its readiness from the collection list.
1106
+ if (!(e instanceof VxilError) || e.status !== 409)
1107
+ throw e;
1108
+ const colls = (await this.call('GET', '/v1/cms/collections')).data.collections;
1109
+ const f = colls.find((c) => c.collection === collection)?.fields.find((x) => x.field === field);
1110
+ const ready = f?.index_ready === true;
1111
+ return { indexed: f?.indexed === true, index_ready: ready, reindex_required: f?.indexed === true && !ready };
1112
+ }
1113
+ },
1091
1114
  /** Set (or clear, with `null`) the collection's end-user owner-scope flag
1092
1115
  * (design §5.1). Names an existing `string` field that holds the owner id. */
1093
1116
  setOwnerField: async (collection, ownerField) => {
@@ -1126,6 +1149,7 @@ export class Vxil {
1126
1149
  let updated = 0;
1127
1150
  let skipped = 0;
1128
1151
  let pages = 0;
1152
+ let indexCertify;
1129
1153
  for (;;) {
1130
1154
  let page = await this.cms.collections.reindex(collection, {
1131
1155
  ...(opts?.field ? { field: opts.field } : {}),
@@ -1148,11 +1172,13 @@ export class Vxil {
1148
1172
  opts?.onPage?.(page);
1149
1173
  }
1150
1174
  skipped += page.skipped ?? 0;
1175
+ if (page.index_certify)
1176
+ indexCertify = page.index_certify;
1151
1177
  if (page.complete || !page.next_cursor)
1152
1178
  break;
1153
1179
  cursor = page.next_cursor;
1154
1180
  }
1155
- return { scanned, updated, skipped, pages };
1181
+ return { scanned, updated, skipped, pages, ...(indexCertify ? { index_certify: indexCertify } : {}) };
1156
1182
  },
1157
1183
  /** Replace the collection's per-record ACTION list (cms.md §17) — the
1158
1184
  * `{ actions }` fields-route meta-op; `[]` clears. Each action is ONE
@@ -1905,7 +1931,10 @@ export class Vxil {
1905
1931
  stream: async (input) => (await this.call('POST', '/v1/rag/answer', { ...input, stream: true })).data,
1906
1932
  /** Retrieval-only grounding preview (rag.md §1c): the exact chunks `answer`
1907
1933
  * would ground on, with rerank + metadata boosts applied — no generation,
1908
- * no token spend. `boosts`/`rerank`/`min_score` override the rag config. */
1934
+ * no token spend. `boosts`/`rerank`/`min_score` override the rag config.
1935
+ * `min_score` floors the EFFECTIVE `score`, which is a RANK value (about
1936
+ * 0.016–0.033 at the top): a floor above ~0.033 drops every hit. Judge
1937
+ * relevance by each hit's `similarity` (cosine, -1..1) instead. */
1909
1938
  search: async (input) => (await this.call('POST', '/v1/rag/search', input)).data,
1910
1939
  /** Ingest into the backing vector-search collection (chunk → embed → index). */
1911
1940
  ingest: async (collection, input) => (await this.call('POST', `/v1/rag/ingest/${encodeURIComponent(collection)}`, input)).data,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vxil/sdk",
3
- "version": "0.11.1",
3
+ "version": "0.13.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Typed client for the Vxil REST API (notifications, auth, jobs, files, cms, comments, webhooks, realtime, orgs, rate-limits).",