@axiom-lattice/pg-stores 3.3.12 → 3.3.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiom-lattice/pg-stores",
3
- "version": "3.3.12",
3
+ "version": "3.3.13",
4
4
  "description": "PG stores implementation for Axiom Lattice framework",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -25,8 +25,8 @@
25
25
  "@langchain/core": "1.1.30",
26
26
  "pg": "^8.16.3",
27
27
  "uuid": "^9.0.1",
28
- "@axiom-lattice/core": "8.0.2",
29
- "@axiom-lattice/protocols": "4.10.0"
28
+ "@axiom-lattice/core": "8.1.0",
29
+ "@axiom-lattice/protocols": "4.11.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/jest": "^29.5.14",
@@ -30,20 +30,26 @@ export class PGVectorStoreProvider implements VectorStoreProvider {
30
30
 
31
31
  async create(params: VectorStoreCreateParams): Promise<any> {
32
32
  const { tableName, embeddingKey } = params;
33
+ const tenantId = params.tenantId ?? "default";
33
34
 
34
- let embeddings;
35
- try {
36
- embeddings = embeddingsLatticeManager.getEmbeddingsClient(embeddingKey);
37
- } catch {
38
- try {
39
- embeddings = embeddingsLatticeManager.getEmbeddingsClient("default");
40
- } catch {
41
- throw new Error(
42
- `No embedding model registered. Register one first:\n` +
43
- ` import { registerEmbeddingsLattice } from "@axiom-lattice/core";\n` +
44
- ` registerEmbeddingsLattice("default", new SomeEmbeddings(...));`
45
- );
46
- }
35
+ // Tenant first, deployment second — the same order every model resolver
36
+ // uses. A tenant model key is `${providerId}/${modelId}` and only resolves
37
+ // in that tenant's namespace.
38
+ const embeddings =
39
+ (await embeddingsLatticeManager.getEmbeddingsClientWithTenant(
40
+ tenantId,
41
+ embeddingKey
42
+ )) ??
43
+ (await embeddingsLatticeManager.getEmbeddingsClientWithTenant(
44
+ tenantId,
45
+ "default"
46
+ ));
47
+
48
+ if (!embeddings) {
49
+ throw new Error(
50
+ `No embedding model "${embeddingKey}" registered for tenant "${tenantId}", ` +
51
+ `and no deployment default. Configure one in the model provider panel.`
52
+ );
47
53
  }
48
54
 
49
55
  return PGVectorStore.initialize(embeddings, {
@@ -98,6 +98,7 @@ import {
98
98
  addModelProviderModelStale,
99
99
  addModelProviderModelExtra,
100
100
  addModelProviderModelDefault,
101
+ addModelProviderModelKind,
101
102
  } from "./migrations/model_provider_migrations";
102
103
  import { PostgreSQLCapabilityBundleStore } from "./stores/PostgreSQLCapabilityBundleStore";
103
104
  import { PostgreSQLProjectRoomStore } from "./stores/PostgreSQLProjectRoomStore";
@@ -191,6 +192,7 @@ export async function createPgStoreConfig(connectionString: string) {
191
192
  mm.register(dropPluginDeploymentAuthToken); // v190
192
193
  mm.register(addModelProviderModelExtra); // v191
193
194
  mm.register(addModelProviderModelDefault); // v192
195
+ mm.register(addModelProviderModelKind); // v193
194
196
 
195
197
  await mm.migrate();
196
198
 
@@ -229,3 +229,30 @@ export const addModelProviderModelDefault: Migration = {
229
229
  `);
230
230
  },
231
231
  };
232
+
233
+ /**
234
+ * What a model does: chat, embedding or speech-to-text.
235
+ *
236
+ * A column on the model row rather than a convention on the provider, because
237
+ * one provider is one credential and one base URL — a DashScope-compatible
238
+ * endpoint serves all three at once. Keeping it off the provider row is what
239
+ * lets a tenant configure one endpoint and still mark individual models by kind.
240
+ *
241
+ * `NOT NULL DEFAULT 'chat'` backfills every existing row, which is exactly
242
+ * right: before this column existed, every tenant model was a chat model.
243
+ */
244
+ export const addModelProviderModelKind: Migration = {
245
+ version: 193,
246
+ name: 'add_model_provider_model_kind',
247
+ up: async (client: PoolClient) => {
248
+ await client.query(`
249
+ ALTER TABLE lattice_model_provider_models
250
+ ADD COLUMN IF NOT EXISTS kind VARCHAR(16) NOT NULL DEFAULT 'chat'
251
+ `);
252
+ },
253
+ down: async (client: PoolClient) => {
254
+ await client.query(`
255
+ ALTER TABLE lattice_model_provider_models DROP COLUMN IF EXISTS kind
256
+ `);
257
+ },
258
+ };
@@ -12,6 +12,7 @@ import {
12
12
  ModelProviderWireProtocol,
13
13
  ModelProviderApiStyle,
14
14
  ModelProviderLlmProvider,
15
+ ModelKind,
15
16
  CreateModelProviderRequest,
16
17
  UpdateModelProviderRequest,
17
18
  ProviderModelInput,
@@ -24,6 +25,7 @@ import {
24
25
  addModelProviderModelStale,
25
26
  addModelProviderModelExtra,
26
27
  addModelProviderModelDefault,
28
+ addModelProviderModelKind,
27
29
  } from '../migrations/model_provider_migrations';
28
30
  import { encrypt, safeDecrypt } from '@axiom-lattice/core';
29
31
 
@@ -81,6 +83,7 @@ interface ModelRow {
81
83
  enabled: boolean;
82
84
  stale: boolean;
83
85
  extra: Record<string, unknown> | null;
86
+ kind: string;
84
87
  is_default: boolean;
85
88
  discovered_at: Date;
86
89
  }
@@ -144,6 +147,7 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
144
147
  this.migrationManager.register(addModelProviderModelStale); // v184
145
148
  this.migrationManager.register(addModelProviderModelExtra); // v191
146
149
  this.migrationManager.register(addModelProviderModelDefault); // v192
150
+ this.migrationManager.register(addModelProviderModelKind); // v193
147
151
 
148
152
  // Auto-migrate by default
149
153
  if (options.autoMigrate !== false) {
@@ -469,7 +473,7 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
469
473
  ? await this.pool.query<ModelRow>(
470
474
  `
471
475
  SELECT id, tenant_id, provider_id, model_id, display_name, owned_by,
472
- upstream_created, enabled, stale, extra, is_default, discovered_at
476
+ upstream_created, enabled, stale, extra, kind, is_default, discovered_at
473
477
  FROM lattice_model_provider_models
474
478
  WHERE tenant_id = $1 AND provider_id = $2
475
479
  ORDER BY model_id ASC
@@ -479,7 +483,7 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
479
483
  : await this.pool.query<ModelRow>(
480
484
  `
481
485
  SELECT id, tenant_id, provider_id, model_id, display_name, owned_by,
482
- upstream_created, enabled, stale, extra, is_default, discovered_at
486
+ upstream_created, enabled, stale, extra, kind, is_default, discovered_at
483
487
  FROM lattice_model_provider_models
484
488
  WHERE tenant_id = $1
485
489
  ORDER BY model_id ASC
@@ -505,7 +509,7 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
505
509
  const result = await this.pool.query<ModelRow>(
506
510
  `
507
511
  SELECT id, tenant_id, provider_id, model_id, display_name, owned_by,
508
- upstream_created, enabled, stale, extra, is_default, discovered_at
512
+ upstream_created, enabled, stale, extra, kind, is_default, discovered_at
509
513
  FROM lattice_model_provider_models
510
514
  WHERE tenant_id = $1 AND provider_id = $2 AND model_id = $3
511
515
  `,
@@ -553,10 +557,11 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
553
557
  model_id: string;
554
558
  enabled: boolean;
555
559
  extra: Record<string, unknown> | null;
560
+ kind: string;
556
561
  is_default: boolean;
557
562
  }>(
558
563
  `
559
- SELECT model_id, enabled, extra, is_default FROM lattice_model_provider_models
564
+ SELECT model_id, enabled, extra, kind, is_default FROM lattice_model_provider_models
560
565
  WHERE tenant_id = $1 AND provider_id = $2
561
566
  `,
562
567
  [tenantId, providerId]
@@ -567,6 +572,9 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
567
572
  const currentExtra = new Map(
568
573
  current.rows.map((row) => [row.model_id, row.extra])
569
574
  );
575
+ const currentKind = new Map(
576
+ current.rows.map((row) => [row.model_id, row.kind])
577
+ );
570
578
  const currentIsDefault = new Map(
571
579
  current.rows.map((row) => [row.model_id, row.is_default])
572
580
  );
@@ -595,6 +603,13 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
595
603
  (model) => model.extra ?? currentExtra.get(model.id) ?? {}
596
604
  );
597
605
 
606
+ // Same rule as `extra`: an omitted `kind` keeps the row's stored value,
607
+ // and a row created by discovery — which carries no kind at all — starts
608
+ // as chat. Nothing here can silently reclassify a model the tenant set.
609
+ const effectiveKind = rows.map(
610
+ (model) => model.kind ?? currentKind.get(model.id) ?? "chat"
611
+ );
612
+
598
613
  // Whether this write is naming a default at all.
599
614
  //
600
615
  // The unique index spans the *tenant*, while this method writes one
@@ -661,15 +676,15 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
661
676
  `
662
677
  INSERT INTO lattice_model_provider_models (
663
678
  id, tenant_id, provider_id, model_id, display_name, owned_by,
664
- upstream_created, raw, enabled, stale, extra, is_default, discovered_at
679
+ upstream_created, raw, enabled, stale, extra, kind, is_default, discovered_at
665
680
  )
666
681
  SELECT * FROM unnest(
667
682
  $1::text[], $2::text[], $3::text[], $4::text[], $5::text[],
668
683
  $6::text[], $7::timestamp[], $8::jsonb[], $9::boolean[], $10::boolean[],
669
- $11::jsonb[], $12::boolean[], $13::timestamp[]
684
+ $11::jsonb[], $12::text[], $13::boolean[], $14::timestamp[]
670
685
  ) AS t(
671
686
  id, tenant_id, provider_id, model_id, display_name, owned_by,
672
- upstream_created, raw, enabled, stale, extra, is_default, discovered_at
687
+ upstream_created, raw, enabled, stale, extra, kind, is_default, discovered_at
673
688
  )
674
689
  ON CONFLICT (tenant_id, provider_id, model_id) DO UPDATE SET
675
690
  display_name = EXCLUDED.display_name,
@@ -679,6 +694,7 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
679
694
  enabled = EXCLUDED.enabled,
680
695
  stale = EXCLUDED.stale,
681
696
  extra = EXCLUDED.extra,
697
+ kind = EXCLUDED.kind,
682
698
  is_default = EXCLUDED.is_default,
683
699
  discovered_at = EXCLUDED.discovered_at
684
700
  `,
@@ -698,6 +714,7 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
698
714
  effectiveEnabled,
699
715
  rows.map((model) => model.stale ?? false),
700
716
  effectiveExtra.map((extra) => JSON.stringify(extra)),
717
+ effectiveKind,
701
718
  effectiveIsDefault,
702
719
  rows.map(() => new Date().toISOString()),
703
720
  ]
@@ -827,6 +844,7 @@ export class PostgreSQLModelProviderStore implements ModelProviderStore {
827
844
  enabled: row.enabled,
828
845
  stale: row.stale,
829
846
  extra: extraOrUndefined(row.extra),
847
+ kind: (row.kind as ModelKind) || "chat",
830
848
  isDefault: row.is_default,
831
849
  discoveredAt: row.discovered_at,
832
850
  };