@memberjunction/ai-vectors-sqlserver 0.0.1 → 5.39.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/README.md CHANGED
@@ -1,45 +1,88 @@
1
1
  # @memberjunction/ai-vectors-sqlserver
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/ai-vectors-sqlserver`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
3
+ A **colocated** MemberJunction vector-database provider backed by **SQL Server 2025 native vectors**
4
+ (the `VECTOR(N)` type and the `VECTOR_SEARCH` DiskANN table-valued function). It stores and queries
5
+ embeddings inside the application's own SQL Server database — borrowing the active data provider's
6
+ connection rather than opening a separate pool — so vectors live alongside the entity rows they
7
+ describe and can be searched with the database's native ANN index.
8
+
9
+ Registered with the MJ class factory as **`SQLServerVectorDatabase`** (`@RegisterClass(VectorDBBase, 'SQLServerVectorDatabase')`).
10
+
11
+ > **Status:** validated end-to-end against a live **SQL Server 2025 RTM** container (17.0.4050)
12
+ > in `sibling` storage mode — index create, upsert, exact query, metadata (`JSON_VALUE`) filtering,
13
+ > and result mapping all confirmed working. The `entityColumn` mode and the approximate
14
+ > (`VECTOR_SEARCH`) path on Azure SQL Database remain unexercised; treat those as untested.
15
+
16
+ ## How it works
17
+
18
+ This is a [colocated](../../Database/README.md) provider: it implements no connection logic of its
19
+ own. Instead it receives the active relational connection through MemberJunction's
20
+ `IColocatedVectorHost` adapter (implemented by `SQLServerDataProvider`) and runs all DDL/DML through
21
+ it. When a transaction is open on that connection, vector writes participate in it.
22
+
23
+ ### Query path
24
+
25
+ The provider prefers the DiskANN-aware **`VECTOR_SEARCH`** TVF (`SELECT TOP (N) WITH APPROXIMATE`),
26
+ which engages the vector index and is dramatically faster than a brute-force scan at scale. But that
27
+ surface is **not present in every SQL Server 2025 build** — verified live, **boxed SQL Server 2025 RTM
28
+ (17.0.4050) does not have `VECTOR_SEARCH`/`WITH APPROXIMATE` or `CREATE VECTOR INDEX … DiskANN`**; only
29
+ the `VECTOR(n)` type and the exact `VECTOR_DISTANCE` function ship there. (The approximate surface is
30
+ currently Azure SQL Database, and likely a later boxed CU.)
31
+
32
+ So the provider **detects support lazily and falls back**: it attempts the `VECTOR_SEARCH` query once;
33
+ if the server rejects it, it caches that fact process-wide and routes all subsequent queries through an
34
+ exact **`VECTOR_DISTANCE`** scan. Where the TVF *is* available, filtered queries additionally dispatch
35
+ on cardinality — below a configurable threshold (default 50,000 matching rows) they use the exact path
36
+ anyway, because DiskANN's graph walk fails to converge when a filter's row cluster is disjoint from the
37
+ query vector's neighborhood. Net: correct results everywhere, accelerated where the index exists.
38
+
39
+ ### Storage modes
40
+
41
+ Configured per index via `MJVectorIndex.ProviderConfig` (which flows to `CreateIndexParams.additionalParams`):
42
+
43
+ | Mode | Where vectors live | Filters resolve against | Use it for |
44
+ |---|---|---|---|
45
+ | `sibling` (default) | an MJ-managed sibling table (`id`/`embedding`/`metadata`/`content`) | the JSON `metadata` column | generic, entity-agnostic, multi-model indexes |
46
+ | `entityColumn` | an existing `VECTOR` column on an entity table | **live entity columns** | adopting embeddings already stored on a table — no re-vectorization |
47
+
48
+ #### `entityColumn` configuration
49
+
50
+ ```json
51
+ {
52
+ "storageMode": "entityColumn",
53
+ "sourceTable": "Recommendation.Content",
54
+ "vectorColumn": "Embedding",
55
+ "keyColumn": "ID",
56
+ "entityName": "Content",
57
+ "selectColumns": ["Title", "URL", "Source", "ContentType", "Date"],
58
+ "iterativeFilterThreshold": 50000
59
+ }
60
+ ```
61
+
62
+ The provider projects the listed columns into each result's metadata and synthesizes the MJ
63
+ `RecordID`/`Entity` fields so the `SearchEngine` renders these results identically to sibling/external
64
+ indexes. `entityColumn` upsert/delete operate by a single scalar key (`keyColumn`); composite-PK
65
+ entities are not supported in this mode.
66
+
67
+ ## Enabling
68
+
69
+ 1. Create an `MJ: Vector Databases` row with `ClassKey = 'SQLServerVectorDatabase'` (no `DefaultURL`
70
+ or `CredentialID` — it uses the application's connection).
71
+ 2. Create `MJ: Vector Indexes` rows pointing at it, with the `ProviderConfig` above for `entityColumn`
72
+ mode (or none for `sibling` mode).
73
+ 3. Search flows through `@memberjunction/search-engine`'s `VectorSearchProvider`; sync flows through
74
+ `@memberjunction/ai-vector-sync`'s `EntityVectorSyncer`.
75
+
76
+ ## Limitations
77
+
78
+ - Requires **SQL Server 2025** (major version ≥ 17); the provider fails loud on older servers.
79
+ - **Approximate / DiskANN search** depends on the `VECTOR_SEARCH` TVF, which is absent on boxed
80
+ SQL Server 2025 RTM (the provider transparently falls back to exact `VECTOR_DISTANCE` — correct,
81
+ but O(rows) per query, so large corpora on the boxed product will be slow until a CU adds the TVF).
82
+ - **Hybrid keyword search** (full-text `CONTAINS` + vector) is not yet implemented — queries are
83
+ vector-only. (The pgvector colocated provider does RRF hybrid today.)
84
+ - `entityColumn` mode supports **single-column keys** only.
85
+
86
+ ## License
87
+
88
+ ISC
@@ -0,0 +1,3 @@
1
+ export * from './models/SQLServerVectorDatabase.js';
2
+ export * from './models/sqlserverColocatedSQL.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './models/SQLServerVectorDatabase.js';
2
+ export * from './models/sqlserverColocatedSQL.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { BaseRequestParams, BaseResponse, ColocatedQueryOptions, ColocatedQueryResult, CreateIndexParams, EditIndexParams, IndexList, ListVectorIDsParams, ListVectorIDsResult, QueryOptions, SharedIndexFilterOptions, UpdateOptions, VectorDBBase, VectorRecord } from '@memberjunction/ai-vectordb';
2
+ import { UserInfo } from '@memberjunction/core';
3
+ /**
4
+ * Colocated MemberJunction vector provider backed by **SQL Server 2025 native vectors**
5
+ * (`VECTOR(N)` + the `VECTOR_SEARCH` DiskANN table-valued function), stored in the application's
6
+ * own database. Borrows the active data provider's connection via {@link IColocatedVectorHost}.
7
+ *
8
+ * **Two storage modes** (per index, via `MJVectorIndex.ProviderConfig` → `CreateIndexParams.additionalParams`):
9
+ * - `sibling` (default): MJ creates and owns a sibling table (`id`/`embedding`/`metadata`/`content`).
10
+ * Generic, entity-agnostic, multi-model. Filters resolve against the JSON `metadata` column.
11
+ * - `entityColumn`: vectors live on an existing entity table's `VECTOR` column. Filters resolve
12
+ * against **live entity columns**, and results project real entity fields. This is the migration
13
+ * target for systems that already store embeddings on their own tables (e.g. a `Content.Embedding`
14
+ * column) — point MJ at the column instead of re-vectorizing.
15
+ *
16
+ * **Query path** prefers the DiskANN-aware `VECTOR_SEARCH` TVF (never `ORDER BY VECTOR_DISTANCE`,
17
+ * which doesn't engage the index). But that surface isn't in every 2025 build — verified live, boxed
18
+ * SQL Server 2025 RTM lacks it — so the provider lazily detects (per host) whether `VECTOR_SEARCH`
19
+ * works and **falls back to an exact `VECTOR_DISTANCE` scan** when it doesn't. Where the TVF exists,
20
+ * filtered queries dispatch on cardinality: small filtered sets use the exact path (DiskANN doesn't
21
+ * converge when the filter cluster is disjoint from the query neighborhood), large sets use DiskANN.
22
+ * See {@link sqlserverColocatedSQL} for the production-verified SQL shapes and the reasoning behind each.
23
+ *
24
+ * Validated end-to-end against a live SQL Server 2025 RTM container in sibling and entityColumn modes
25
+ * (exact fallback path). The approximate path on Azure SQL Database remains untested.
26
+ *
27
+ * Registered with the MJ class factory as `'SQLServerVectorDatabase'`.
28
+ */
29
+ export declare class SQLServerVectorDatabase extends VectorDBBase {
30
+ constructor(apiKey: string);
31
+ get SupportsColocatedQuery(): boolean;
32
+ get SupportsHybridSearch(): boolean;
33
+ private get Host();
34
+ private get Schema();
35
+ private Qualify;
36
+ private Run;
37
+ private AssertVectorCapable;
38
+ private EnsureInfrastructure;
39
+ private GetResolvedIndex;
40
+ /** Validate & narrow the untyped `CreateIndexParams.additionalParams` bag into a typed config,
41
+ * throwing on malformed shapes rather than asserting (`as`) a shape that may not hold. */
42
+ private NormalizeIndexConfig;
43
+ private ParseSelectColumns;
44
+ /** Resolve the schema-qualified table string for an entityColumn source spec, validating each
45
+ * identifier segment (accepts `[schema].[table]`, `schema.table`, or bare `table`). */
46
+ private QualifyEntityTable;
47
+ ListIndexes(): Promise<IndexList>;
48
+ GetIndex(params: BaseRequestParams): Promise<BaseResponse>;
49
+ CreateIndex(params: CreateIndexParams): Promise<BaseResponse>;
50
+ private CreateSiblingIndex;
51
+ private RegisterEntityColumnIndex;
52
+ /** Attempt to create a DiskANN vector index; tolerate failure (preview surface / pre-existing). */
53
+ private TryCreateVectorIndex;
54
+ private UpsertRegistry;
55
+ DeleteIndex(params: BaseRequestParams): Promise<BaseResponse>;
56
+ EditIndex(_params: EditIndexParams): Promise<BaseResponse>;
57
+ /**
58
+ * Whether a given host server supports the `VECTOR_SEARCH` DiskANN TVF
59
+ * (`SELECT TOP (N) WITH APPROXIMATE`). Verified live: boxed **SQL Server 2025 RTM does NOT** —
60
+ * only `VECTOR_DISTANCE` (exact) ships there; the approximate/DiskANN surface is currently Azure
61
+ * SQL Database (and likely a later boxed CU). Detected lazily on first query.
62
+ *
63
+ * Keyed **per host**, not process-wide: one MJ process can hold connections to multiple SQL
64
+ * Servers (parallel client-to-many-servers, or mixed 2022/2025 backends), and capability differs
65
+ * per server — a process-global flag would let one server's probe poison another's path.
66
+ */
67
+ private static ApproximateSearchSupportedByHost;
68
+ ColocatedQuery(params: ColocatedQueryOptions, _contextUser?: UserInfo): Promise<ColocatedQueryResult>;
69
+ /**
70
+ * Execute the vector search, choosing the exact vs. approximate path and transparently falling
71
+ * back to exact `VECTOR_DISTANCE` when this server lacks the `VECTOR_SEARCH` TVF.
72
+ *
73
+ * Path selection:
74
+ * - If the approximate surface is known-absent → always exact.
75
+ * - Else for filtered queries, count the filter cardinality and use exact below the threshold
76
+ * (DiskANN doesn't converge when the filter cluster is disjoint from the query neighborhood).
77
+ * - Else attempt approximate; if it errors with a "feature not supported" signature, cache that
78
+ * fact and retry exact.
79
+ */
80
+ private RunVectorQuery;
81
+ /** Best-effort heuristic: does this error indicate the VECTOR_SEARCH/DiskANN surface is absent on
82
+ * this server? Matches on message text (brittle across CUs/locales), but only gates a fallback to
83
+ * an equally-correct exact query, so a false negative just rethrows and a false positive is slow,
84
+ * not wrong. */
85
+ private IsApproximateUnsupportedError;
86
+ /** Map a query result row to a ColocatedMatch, synthesizing metadata per storage mode. */
87
+ private RowToMatch;
88
+ private ToMetadataValue;
89
+ QueryIndex(params: QueryOptions, contextUser?: UserInfo): Promise<BaseResponse>;
90
+ CreateRecord(record: VectorRecord, indexName?: string): Promise<BaseResponse>;
91
+ CreateRecords(records: VectorRecord[], indexName?: string): Promise<BaseResponse>;
92
+ private UpsertRecords;
93
+ /** Extract the scalar key value from a vector record id (CompositeKey URL `Field|Value`). */
94
+ private ExtractKeyValue;
95
+ UpdateRecord(record: UpdateOptions): Promise<BaseResponse>;
96
+ UpdateRecords(records: UpdateOptions): Promise<BaseResponse>;
97
+ DeleteRecord(record: VectorRecord, indexName?: string): Promise<BaseResponse>;
98
+ DeleteRecords(records: VectorRecord[], indexName?: string): Promise<BaseResponse>;
99
+ private DeleteByKeys;
100
+ DeleteAllRecords(indexName: string, _namespace?: string): Promise<BaseResponse>;
101
+ GetRecord(params: BaseRequestParams): Promise<BaseResponse>;
102
+ GetRecords(params: BaseRequestParams): Promise<BaseResponse>;
103
+ ListVectorIDs(params: ListVectorIDsParams): Promise<ListVectorIDsResult>;
104
+ BuildMetadataFilter(options: SharedIndexFilterOptions): object | undefined;
105
+ private ParseMetadata;
106
+ private Success;
107
+ private Failure;
108
+ }
109
+ //# sourceMappingURL=SQLServerVectorDatabase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SQLServerVectorDatabase.d.ts","sourceRoot":"","sources":["../../src/models/SQLServerVectorDatabase.ts"],"names":[],"mappings":"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"}