@axiom-lattice/pg-stores 3.3.4 → 3.3.6
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +20 -0
- package/dist/index.d.mts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +153 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +160 -78
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/scripts/verify-model-provider-migrations.ts +214 -0
- package/scripts/verify-store.ts +232 -0
- package/src/__tests__/PostgreSQLA2AApiKeyStore.test.ts +41 -4
- package/src/__tests__/PostgreSQLChannelInstallationStore.test.ts +48 -4
- package/src/__tests__/PostgreSQLConnectionStore.integration.test.ts +60 -1
- package/src/__tests__/PostgreSQLDatabaseConfigStore.test.ts +53 -0
- package/src/__tests__/PostgreSQLMcpServerConfigStore.test.ts +43 -0
- package/src/__tests__/PostgreSQLMetricsServerConfigStore.test.ts +59 -0
- package/src/__tests__/PostgreSQLModelProviderStore.test.ts +58 -0
- package/src/__tests__/PostgreSQLProjectRoomMessageStore.correlatedInterrupt.integration.test.ts +74 -0
- package/src/__tests__/PostgreSQLProjectRoomMessageStore.test.ts +23 -0
- package/src/createPgStoreConfig.ts +6 -1
- package/src/migrations/connection_config_migrations.ts +56 -0
- package/src/migrations/model_provider_migrations.ts +74 -0
- package/src/stores/PostgreSQLA2AApiKeyStore.ts +4 -17
- package/src/stores/PostgreSQLChannelInstallationStore.ts +4 -4
- package/src/stores/PostgreSQLDatabaseConfigStore.ts +2 -7
- package/src/stores/PostgreSQLMcpServerConfigStore.ts +9 -19
- package/src/stores/PostgreSQLMetricsServerConfigStore.ts +3 -13
- package/src/stores/PostgreSQLModelProviderStore.ts +128 -25
package/dist/index.mjs
CHANGED
|
@@ -963,7 +963,7 @@ var createDatabaseConfigsTable = {
|
|
|
963
963
|
};
|
|
964
964
|
|
|
965
965
|
// src/stores/PostgreSQLDatabaseConfigStore.ts
|
|
966
|
-
import { encrypt,
|
|
966
|
+
import { encrypt, safeDecrypt } from "@axiom-lattice/core";
|
|
967
967
|
var PostgreSQLDatabaseConfigStore = class {
|
|
968
968
|
constructor(options) {
|
|
969
969
|
this.initialized = false;
|
|
@@ -1218,12 +1218,7 @@ var PostgreSQLDatabaseConfigStore = class {
|
|
|
1218
1218
|
mapRowToEntry(row) {
|
|
1219
1219
|
const config = typeof row.config === "string" ? JSON.parse(row.config) : row.config;
|
|
1220
1220
|
if (config.password) {
|
|
1221
|
-
|
|
1222
|
-
config.password = decrypt(config.password);
|
|
1223
|
-
} catch (error) {
|
|
1224
|
-
console.error("Failed to decrypt database password:", error);
|
|
1225
|
-
throw new Error("Failed to decrypt database configuration");
|
|
1226
|
-
}
|
|
1221
|
+
config.password = safeDecrypt(config.password);
|
|
1227
1222
|
}
|
|
1228
1223
|
return {
|
|
1229
1224
|
id: row.id,
|
|
@@ -1400,7 +1395,7 @@ var createMetricsConfigsTable = {
|
|
|
1400
1395
|
};
|
|
1401
1396
|
|
|
1402
1397
|
// src/stores/PostgreSQLMetricsServerConfigStore.ts
|
|
1403
|
-
import { encrypt as encrypt2,
|
|
1398
|
+
import { encrypt as encrypt2, safeDecrypt as safeDecrypt2 } from "@axiom-lattice/core";
|
|
1404
1399
|
var PostgreSQLMetricsServerConfigStore = class {
|
|
1405
1400
|
constructor(options) {
|
|
1406
1401
|
this.initialized = false;
|
|
@@ -1655,20 +1650,10 @@ var PostgreSQLMetricsServerConfigStore = class {
|
|
|
1655
1650
|
mapRowToEntry(row) {
|
|
1656
1651
|
const config = typeof row.config === "string" ? JSON.parse(row.config) : row.config;
|
|
1657
1652
|
if (config.apiKey) {
|
|
1658
|
-
|
|
1659
|
-
config.apiKey = decrypt2(config.apiKey);
|
|
1660
|
-
} catch (error) {
|
|
1661
|
-
console.error("Failed to decrypt apiKey:", error);
|
|
1662
|
-
throw new Error("Failed to decrypt metrics server configuration");
|
|
1663
|
-
}
|
|
1653
|
+
config.apiKey = safeDecrypt2(config.apiKey);
|
|
1664
1654
|
}
|
|
1665
1655
|
if (config.password) {
|
|
1666
|
-
|
|
1667
|
-
config.password = decrypt2(config.password);
|
|
1668
|
-
} catch (error) {
|
|
1669
|
-
console.error("Failed to decrypt password:", error);
|
|
1670
|
-
throw new Error("Failed to decrypt metrics server configuration");
|
|
1671
|
-
}
|
|
1656
|
+
config.password = safeDecrypt2(config.password);
|
|
1672
1657
|
}
|
|
1673
1658
|
return {
|
|
1674
1659
|
id: row.id,
|
|
@@ -1744,7 +1729,7 @@ var createMcpServerConfigsTable = {
|
|
|
1744
1729
|
};
|
|
1745
1730
|
|
|
1746
1731
|
// src/stores/PostgreSQLMcpServerConfigStore.ts
|
|
1747
|
-
import { encrypt as encrypt3,
|
|
1732
|
+
import { encrypt as encrypt3, safeDecrypt as safeDecrypt3 } from "@axiom-lattice/core";
|
|
1748
1733
|
var PostgreSQLMcpServerConfigStore = class {
|
|
1749
1734
|
constructor(options) {
|
|
1750
1735
|
this.initialized = false;
|
|
@@ -2015,28 +2000,18 @@ var PostgreSQLMcpServerConfigStore = class {
|
|
|
2015
2000
|
mapRowToEntry(row) {
|
|
2016
2001
|
const config = typeof row.config === "string" ? JSON.parse(row.config) : row.config;
|
|
2017
2002
|
if (config.env && row.is_env_encrypted) {
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
decryptedEnv[key] = decrypt3(value);
|
|
2022
|
-
}
|
|
2023
|
-
config.env = decryptedEnv;
|
|
2024
|
-
} catch (error) {
|
|
2025
|
-
console.error("Failed to decrypt MCP server env:", error);
|
|
2026
|
-
throw new Error("Failed to decrypt MCP server configuration");
|
|
2003
|
+
const decryptedEnv = {};
|
|
2004
|
+
for (const [key, value] of Object.entries(config.env)) {
|
|
2005
|
+
decryptedEnv[key] = safeDecrypt3(value);
|
|
2027
2006
|
}
|
|
2007
|
+
config.env = decryptedEnv;
|
|
2028
2008
|
}
|
|
2029
2009
|
if (config.headers && row.is_env_encrypted) {
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
decryptedHeaders[key] = decrypt3(value);
|
|
2034
|
-
}
|
|
2035
|
-
config.headers = decryptedHeaders;
|
|
2036
|
-
} catch (error) {
|
|
2037
|
-
console.error("Failed to decrypt MCP server headers:", error);
|
|
2038
|
-
throw new Error("Failed to decrypt MCP server configuration");
|
|
2010
|
+
const decryptedHeaders = {};
|
|
2011
|
+
for (const [key, value] of Object.entries(config.headers)) {
|
|
2012
|
+
decryptedHeaders[key] = safeDecrypt3(value);
|
|
2039
2013
|
}
|
|
2014
|
+
config.headers = decryptedHeaders;
|
|
2040
2015
|
}
|
|
2041
2016
|
return {
|
|
2042
2017
|
id: row.id,
|
|
@@ -5927,7 +5902,7 @@ var alterChannelInstallationsTable = {
|
|
|
5927
5902
|
};
|
|
5928
5903
|
|
|
5929
5904
|
// src/stores/PostgreSQLChannelInstallationStore.ts
|
|
5930
|
-
import {
|
|
5905
|
+
import { safeDecrypt as safeDecrypt4, encrypt as encrypt4 } from "@axiom-lattice/core";
|
|
5931
5906
|
var PostgreSQLChannelInstallationStore = class {
|
|
5932
5907
|
constructor(options) {
|
|
5933
5908
|
this.initialized = false;
|
|
@@ -6157,9 +6132,9 @@ var PostgreSQLChannelInstallationStore = class {
|
|
|
6157
6132
|
decryptSecrets(config) {
|
|
6158
6133
|
return {
|
|
6159
6134
|
...config,
|
|
6160
|
-
...typeof config.appSecret === "string" ? { appSecret:
|
|
6161
|
-
...typeof config.verificationToken === "string" ? { verificationToken:
|
|
6162
|
-
...typeof config.encryptKey === "string" ? { encryptKey:
|
|
6135
|
+
...typeof config.appSecret === "string" ? { appSecret: safeDecrypt4(config.appSecret) } : {},
|
|
6136
|
+
...typeof config.verificationToken === "string" ? { verificationToken: safeDecrypt4(config.verificationToken) } : {},
|
|
6137
|
+
...typeof config.encryptKey === "string" ? { encryptKey: safeDecrypt4(config.encryptKey) } : {}
|
|
6163
6138
|
};
|
|
6164
6139
|
}
|
|
6165
6140
|
};
|
|
@@ -6237,7 +6212,7 @@ var addApiKeyGrants = {
|
|
|
6237
6212
|
};
|
|
6238
6213
|
|
|
6239
6214
|
// src/stores/PostgreSQLA2AApiKeyStore.ts
|
|
6240
|
-
import { encrypt as encrypt5, decrypt as
|
|
6215
|
+
import { encrypt as encrypt5, decrypt, safeDecrypt as safeDecrypt5 } from "@axiom-lattice/core";
|
|
6241
6216
|
import { randomUUID } from "crypto";
|
|
6242
6217
|
function generateApiKey() {
|
|
6243
6218
|
return `a2a_${randomUUID().replace(/-/g, "")}`;
|
|
@@ -6245,7 +6220,7 @@ function generateApiKey() {
|
|
|
6245
6220
|
function mapRowToRecord(row) {
|
|
6246
6221
|
return {
|
|
6247
6222
|
id: row.id,
|
|
6248
|
-
key:
|
|
6223
|
+
key: safeDecrypt5(row.key_value),
|
|
6249
6224
|
tenantId: row.tenant_id,
|
|
6250
6225
|
projectId: row.project_id,
|
|
6251
6226
|
assistantIds: row.assistant_ids ?? void 0,
|
|
@@ -6302,17 +6277,6 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
6302
6277
|
async ensureInitialized() {
|
|
6303
6278
|
if (!this.initialized) await this.initialize();
|
|
6304
6279
|
}
|
|
6305
|
-
/** Map rows that decrypt cleanly; skip rows under an unknown key. */
|
|
6306
|
-
safeMap(rows) {
|
|
6307
|
-
const out = [];
|
|
6308
|
-
for (const row of rows) {
|
|
6309
|
-
try {
|
|
6310
|
-
out.push(mapRowToRecord(row));
|
|
6311
|
-
} catch {
|
|
6312
|
-
}
|
|
6313
|
-
}
|
|
6314
|
-
return out;
|
|
6315
|
-
}
|
|
6316
6280
|
async findByKey(key) {
|
|
6317
6281
|
await this.ensureInitialized();
|
|
6318
6282
|
const all = await this.pool.query(
|
|
@@ -6320,7 +6284,7 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
6320
6284
|
);
|
|
6321
6285
|
for (const row of all.rows) {
|
|
6322
6286
|
try {
|
|
6323
|
-
if (
|
|
6287
|
+
if (decrypt(row.key_value) === key) return mapRowToRecord(row);
|
|
6324
6288
|
} catch {
|
|
6325
6289
|
continue;
|
|
6326
6290
|
}
|
|
@@ -6349,13 +6313,13 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
6349
6313
|
`SELECT * FROM lattice_a2a_api_keys WHERE tenant_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`,
|
|
6350
6314
|
[params.tenantId, limit, offset]
|
|
6351
6315
|
);
|
|
6352
|
-
return
|
|
6316
|
+
return result2.rows.map((row) => mapRowToRecord(row));
|
|
6353
6317
|
}
|
|
6354
6318
|
const result = await this.pool.query(
|
|
6355
6319
|
`SELECT * FROM lattice_a2a_api_keys ORDER BY created_at DESC LIMIT $1 OFFSET $2`,
|
|
6356
6320
|
[limit, offset]
|
|
6357
6321
|
);
|
|
6358
|
-
return
|
|
6322
|
+
return result.rows.map((row) => mapRowToRecord(row));
|
|
6359
6323
|
}
|
|
6360
6324
|
async create(input) {
|
|
6361
6325
|
await this.ensureInitialized();
|
|
@@ -6452,7 +6416,7 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
6452
6416
|
const map2 = /* @__PURE__ */ new Map();
|
|
6453
6417
|
for (const row of result.rows) {
|
|
6454
6418
|
try {
|
|
6455
|
-
const key =
|
|
6419
|
+
const key = decrypt(row.key_value);
|
|
6456
6420
|
map2.set(key, {
|
|
6457
6421
|
key,
|
|
6458
6422
|
tenantId: row.tenant_id,
|
|
@@ -9787,6 +9751,7 @@ var createChannelIdentityMappingTables = {
|
|
|
9787
9751
|
};
|
|
9788
9752
|
|
|
9789
9753
|
// src/migrations/connection_config_migrations.ts
|
|
9754
|
+
import { encrypt as encrypt6, isEncryptedValue } from "@axiom-lattice/core";
|
|
9790
9755
|
var createConnectionConfigsTable = {
|
|
9791
9756
|
version: 160,
|
|
9792
9757
|
name: "create_connection_configs_table",
|
|
@@ -9841,6 +9806,38 @@ var addConnectionSecretFields = {
|
|
|
9841
9806
|
`);
|
|
9842
9807
|
}
|
|
9843
9808
|
};
|
|
9809
|
+
var reencryptLegacyConnectionSecrets = {
|
|
9810
|
+
version: 191,
|
|
9811
|
+
name: "reencrypt_legacy_connection_secrets",
|
|
9812
|
+
up: async (client) => {
|
|
9813
|
+
const result = await client.query(
|
|
9814
|
+
`SELECT id, tenant_id, config, secret_fields
|
|
9815
|
+
FROM lattice_connection_configs
|
|
9816
|
+
WHERE secret_fields IS NOT NULL`
|
|
9817
|
+
);
|
|
9818
|
+
for (const row of result.rows) {
|
|
9819
|
+
const secretFields = Array.isArray(row.secret_fields) ? row.secret_fields.filter((field) => typeof field === "string") : [];
|
|
9820
|
+
if (secretFields.length === 0) continue;
|
|
9821
|
+
const config = row.config && typeof row.config === "object" ? { ...row.config } : {};
|
|
9822
|
+
let changed = false;
|
|
9823
|
+
for (const field of secretFields) {
|
|
9824
|
+
const value = config[field];
|
|
9825
|
+
if (typeof value === "string" && value.length > 0 && !isEncryptedValue(value)) {
|
|
9826
|
+
config[field] = encrypt6(value);
|
|
9827
|
+
changed = true;
|
|
9828
|
+
}
|
|
9829
|
+
}
|
|
9830
|
+
if (changed) {
|
|
9831
|
+
await client.query(
|
|
9832
|
+
`UPDATE lattice_connection_configs
|
|
9833
|
+
SET config = $1::jsonb, updated_at = CURRENT_TIMESTAMP
|
|
9834
|
+
WHERE tenant_id = $2 AND id = $3`,
|
|
9835
|
+
[JSON.stringify(config), row.tenant_id, row.id]
|
|
9836
|
+
);
|
|
9837
|
+
}
|
|
9838
|
+
}
|
|
9839
|
+
}
|
|
9840
|
+
};
|
|
9844
9841
|
|
|
9845
9842
|
// src/migrations/add_share_open_grants.ts
|
|
9846
9843
|
var addShareOpenGrants = {
|
|
@@ -10315,6 +10312,44 @@ var addModelProviderModelStale = {
|
|
|
10315
10312
|
`);
|
|
10316
10313
|
}
|
|
10317
10314
|
};
|
|
10315
|
+
var addModelProviderModelExtra = {
|
|
10316
|
+
version: 191,
|
|
10317
|
+
name: "add_model_provider_model_extra",
|
|
10318
|
+
up: async (client) => {
|
|
10319
|
+
await client.query(`
|
|
10320
|
+
ALTER TABLE lattice_model_provider_models
|
|
10321
|
+
ADD COLUMN IF NOT EXISTS extra JSONB NOT NULL DEFAULT '{}'::jsonb
|
|
10322
|
+
`);
|
|
10323
|
+
},
|
|
10324
|
+
down: async (client) => {
|
|
10325
|
+
await client.query(`
|
|
10326
|
+
ALTER TABLE lattice_model_provider_models DROP COLUMN IF EXISTS extra
|
|
10327
|
+
`);
|
|
10328
|
+
}
|
|
10329
|
+
};
|
|
10330
|
+
var addModelProviderModelDefault = {
|
|
10331
|
+
version: 192,
|
|
10332
|
+
name: "add_model_provider_model_default",
|
|
10333
|
+
up: async (client) => {
|
|
10334
|
+
await client.query(`
|
|
10335
|
+
ALTER TABLE lattice_model_provider_models
|
|
10336
|
+
ADD COLUMN IF NOT EXISTS is_default BOOLEAN NOT NULL DEFAULT FALSE
|
|
10337
|
+
`);
|
|
10338
|
+
await client.query(`
|
|
10339
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uk_lattice_model_provider_models_tenant_default
|
|
10340
|
+
ON lattice_model_provider_models (tenant_id)
|
|
10341
|
+
WHERE is_default
|
|
10342
|
+
`);
|
|
10343
|
+
},
|
|
10344
|
+
down: async (client) => {
|
|
10345
|
+
await client.query(`
|
|
10346
|
+
DROP INDEX IF EXISTS uk_lattice_model_provider_models_tenant_default
|
|
10347
|
+
`);
|
|
10348
|
+
await client.query(`
|
|
10349
|
+
ALTER TABLE lattice_model_provider_models DROP COLUMN IF EXISTS is_default
|
|
10350
|
+
`);
|
|
10351
|
+
}
|
|
10352
|
+
};
|
|
10318
10353
|
|
|
10319
10354
|
// src/stores/PostgreSQLCapabilityBundleStore.ts
|
|
10320
10355
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
@@ -11279,7 +11314,10 @@ var PostgreSQLUserPushSubscriptionStore = class {
|
|
|
11279
11314
|
|
|
11280
11315
|
// src/stores/PostgreSQLModelProviderStore.ts
|
|
11281
11316
|
import { Pool as Pool27 } from "pg";
|
|
11282
|
-
import { encrypt as
|
|
11317
|
+
import { encrypt as encrypt7, safeDecrypt as safeDecrypt6 } from "@axiom-lattice/core";
|
|
11318
|
+
function extraOrUndefined(value) {
|
|
11319
|
+
return value && Object.keys(value).length > 0 ? value : void 0;
|
|
11320
|
+
}
|
|
11283
11321
|
var PostgreSQLModelProviderStore = class {
|
|
11284
11322
|
constructor(options) {
|
|
11285
11323
|
this.initialized = false;
|
|
@@ -11301,6 +11339,10 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11301
11339
|
this.migrationManager = new MigrationManager(this.pool);
|
|
11302
11340
|
this.migrationManager.register(createModelProvidersTable);
|
|
11303
11341
|
this.migrationManager.register(createModelProviderModelsTable);
|
|
11342
|
+
this.migrationManager.register(addModelProviderApiStyle);
|
|
11343
|
+
this.migrationManager.register(addModelProviderModelStale);
|
|
11344
|
+
this.migrationManager.register(addModelProviderModelExtra);
|
|
11345
|
+
this.migrationManager.register(addModelProviderModelDefault);
|
|
11304
11346
|
if (options.autoMigrate !== false) {
|
|
11305
11347
|
this.initialize().catch((error) => {
|
|
11306
11348
|
console.error("Failed to initialize PostgreSQLModelProviderStore:", error);
|
|
@@ -11394,7 +11436,7 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11394
11436
|
await this.ensureInitialized();
|
|
11395
11437
|
const now = /* @__PURE__ */ new Date();
|
|
11396
11438
|
const nowString = now.toISOString();
|
|
11397
|
-
const apiKeyEnc = data.apiKey ?
|
|
11439
|
+
const apiKeyEnc = data.apiKey ? encrypt7(data.apiKey) : null;
|
|
11398
11440
|
const apiKeyHint = data.apiKey ? data.apiKey.slice(-4) : null;
|
|
11399
11441
|
await this.pool.query(
|
|
11400
11442
|
`
|
|
@@ -11470,7 +11512,7 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11470
11512
|
updateData.api_key_enc = null;
|
|
11471
11513
|
updateData.api_key_hint = null;
|
|
11472
11514
|
} else if (updates.apiKey) {
|
|
11473
|
-
updateData.api_key_enc =
|
|
11515
|
+
updateData.api_key_enc = encrypt7(updates.apiKey);
|
|
11474
11516
|
updateData.api_key_hint = updates.apiKey.slice(-4);
|
|
11475
11517
|
}
|
|
11476
11518
|
if (updates.enabled !== void 0) {
|
|
@@ -11547,7 +11589,7 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11547
11589
|
const result = providerId ? await this.pool.query(
|
|
11548
11590
|
`
|
|
11549
11591
|
SELECT id, tenant_id, provider_id, model_id, display_name, owned_by,
|
|
11550
|
-
upstream_created, enabled, stale, discovered_at
|
|
11592
|
+
upstream_created, enabled, stale, extra, is_default, discovered_at
|
|
11551
11593
|
FROM lattice_model_provider_models
|
|
11552
11594
|
WHERE tenant_id = $1 AND provider_id = $2
|
|
11553
11595
|
ORDER BY model_id ASC
|
|
@@ -11556,7 +11598,7 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11556
11598
|
) : await this.pool.query(
|
|
11557
11599
|
`
|
|
11558
11600
|
SELECT id, tenant_id, provider_id, model_id, display_name, owned_by,
|
|
11559
|
-
upstream_created, enabled, discovered_at
|
|
11601
|
+
upstream_created, enabled, stale, extra, is_default, discovered_at
|
|
11560
11602
|
FROM lattice_model_provider_models
|
|
11561
11603
|
WHERE tenant_id = $1
|
|
11562
11604
|
ORDER BY model_id ASC
|
|
@@ -11575,7 +11617,7 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11575
11617
|
const result = await this.pool.query(
|
|
11576
11618
|
`
|
|
11577
11619
|
SELECT id, tenant_id, provider_id, model_id, display_name, owned_by,
|
|
11578
|
-
upstream_created, enabled, discovered_at
|
|
11620
|
+
upstream_created, enabled, stale, extra, is_default, discovered_at
|
|
11579
11621
|
FROM lattice_model_provider_models
|
|
11580
11622
|
WHERE tenant_id = $1 AND provider_id = $2 AND model_id = $3
|
|
11581
11623
|
`,
|
|
@@ -11594,8 +11636,12 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11594
11636
|
* is an independent model.
|
|
11595
11637
|
*
|
|
11596
11638
|
* Models the upstream no longer offers are deleted; models that survive are
|
|
11597
|
-
* upserted *without* touching `enabled`, so the tenant's
|
|
11598
|
-
*
|
|
11639
|
+
* upserted *without* touching `enabled` or `extra`, so the tenant's choices
|
|
11640
|
+
* survive a re-discovery. New rows take the column defaults.
|
|
11641
|
+
*
|
|
11642
|
+
* The default model is the exception to the delete: it is kept and flagged
|
|
11643
|
+
* `stale` instead, because deleting it would take the tenant's default away
|
|
11644
|
+
* with no confirmation.
|
|
11599
11645
|
*/
|
|
11600
11646
|
async replaceProviderModels(tenantId, providerId, models) {
|
|
11601
11647
|
await this.ensureInitialized();
|
|
@@ -11604,7 +11650,7 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11604
11650
|
await client.query("BEGIN");
|
|
11605
11651
|
const current = await client.query(
|
|
11606
11652
|
`
|
|
11607
|
-
SELECT model_id, enabled FROM lattice_model_provider_models
|
|
11653
|
+
SELECT model_id, enabled, extra, is_default FROM lattice_model_provider_models
|
|
11608
11654
|
WHERE tenant_id = $1 AND provider_id = $2
|
|
11609
11655
|
`,
|
|
11610
11656
|
[tenantId, providerId]
|
|
@@ -11612,6 +11658,12 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11612
11658
|
const currentEnabled = new Map(
|
|
11613
11659
|
current.rows.map((row) => [row.model_id, row.enabled])
|
|
11614
11660
|
);
|
|
11661
|
+
const currentExtra = new Map(
|
|
11662
|
+
current.rows.map((row) => [row.model_id, row.extra])
|
|
11663
|
+
);
|
|
11664
|
+
const currentIsDefault = new Map(
|
|
11665
|
+
current.rows.map((row) => [row.model_id, row.is_default])
|
|
11666
|
+
);
|
|
11615
11667
|
const deduped = /* @__PURE__ */ new Map();
|
|
11616
11668
|
for (const model of models) {
|
|
11617
11669
|
deduped.set(model.id, model);
|
|
@@ -11620,12 +11672,37 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11620
11672
|
const effectiveEnabled = rows.map(
|
|
11621
11673
|
(model) => model.enabled ?? currentEnabled.get(model.id) ?? true
|
|
11622
11674
|
);
|
|
11675
|
+
const effectiveExtra = rows.map(
|
|
11676
|
+
(model) => model.extra ?? currentExtra.get(model.id) ?? {}
|
|
11677
|
+
);
|
|
11678
|
+
const namesDefault = rows.some((model) => model.isDefault === true);
|
|
11679
|
+
if (namesDefault) {
|
|
11680
|
+
await client.query(
|
|
11681
|
+
`UPDATE lattice_model_provider_models SET is_default = FALSE WHERE tenant_id = $1`,
|
|
11682
|
+
[tenantId]
|
|
11683
|
+
);
|
|
11684
|
+
}
|
|
11685
|
+
const effectiveIsDefault = rows.map(
|
|
11686
|
+
(model) => model.isDefault ?? (namesDefault ? false : currentIsDefault.get(model.id)) ?? false
|
|
11687
|
+
);
|
|
11688
|
+
await client.query(
|
|
11689
|
+
`
|
|
11690
|
+
UPDATE lattice_model_provider_models
|
|
11691
|
+
SET stale = TRUE
|
|
11692
|
+
WHERE tenant_id = $1
|
|
11693
|
+
AND provider_id = $2
|
|
11694
|
+
AND model_id <> ALL($3::text[])
|
|
11695
|
+
AND is_default
|
|
11696
|
+
`,
|
|
11697
|
+
[tenantId, providerId, rows.map((model) => model.id)]
|
|
11698
|
+
);
|
|
11623
11699
|
await client.query(
|
|
11624
11700
|
`
|
|
11625
11701
|
DELETE FROM lattice_model_provider_models
|
|
11626
11702
|
WHERE tenant_id = $1
|
|
11627
11703
|
AND provider_id = $2
|
|
11628
11704
|
AND model_id <> ALL($3::text[])
|
|
11705
|
+
AND NOT is_default
|
|
11629
11706
|
`,
|
|
11630
11707
|
[tenantId, providerId, rows.map((model) => model.id)]
|
|
11631
11708
|
);
|
|
@@ -11634,14 +11711,15 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11634
11711
|
`
|
|
11635
11712
|
INSERT INTO lattice_model_provider_models (
|
|
11636
11713
|
id, tenant_id, provider_id, model_id, display_name, owned_by,
|
|
11637
|
-
upstream_created, raw, enabled, stale, discovered_at
|
|
11714
|
+
upstream_created, raw, enabled, stale, extra, is_default, discovered_at
|
|
11638
11715
|
)
|
|
11639
11716
|
SELECT * FROM unnest(
|
|
11640
11717
|
$1::text[], $2::text[], $3::text[], $4::text[], $5::text[],
|
|
11641
|
-
$6::text[], $7::timestamp[], $8::jsonb[], $9::boolean[], $10::boolean[],
|
|
11718
|
+
$6::text[], $7::timestamp[], $8::jsonb[], $9::boolean[], $10::boolean[],
|
|
11719
|
+
$11::jsonb[], $12::boolean[], $13::timestamp[]
|
|
11642
11720
|
) AS t(
|
|
11643
11721
|
id, tenant_id, provider_id, model_id, display_name, owned_by,
|
|
11644
|
-
upstream_created, raw, enabled, stale, discovered_at
|
|
11722
|
+
upstream_created, raw, enabled, stale, extra, is_default, discovered_at
|
|
11645
11723
|
)
|
|
11646
11724
|
ON CONFLICT (tenant_id, provider_id, model_id) DO UPDATE SET
|
|
11647
11725
|
display_name = EXCLUDED.display_name,
|
|
@@ -11650,6 +11728,8 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11650
11728
|
raw = EXCLUDED.raw,
|
|
11651
11729
|
enabled = EXCLUDED.enabled,
|
|
11652
11730
|
stale = EXCLUDED.stale,
|
|
11731
|
+
extra = EXCLUDED.extra,
|
|
11732
|
+
is_default = EXCLUDED.is_default,
|
|
11653
11733
|
discovered_at = EXCLUDED.discovered_at
|
|
11654
11734
|
`,
|
|
11655
11735
|
[
|
|
@@ -11667,6 +11747,8 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11667
11747
|
),
|
|
11668
11748
|
effectiveEnabled,
|
|
11669
11749
|
rows.map((model) => model.stale ?? false),
|
|
11750
|
+
effectiveExtra.map((extra) => JSON.stringify(extra)),
|
|
11751
|
+
effectiveIsDefault,
|
|
11670
11752
|
rows.map(() => (/* @__PURE__ */ new Date()).toISOString())
|
|
11671
11753
|
]
|
|
11672
11754
|
);
|
|
@@ -11735,12 +11817,7 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11735
11817
|
mapRowToEntry(row) {
|
|
11736
11818
|
let apiKey;
|
|
11737
11819
|
if (row.api_key_enc) {
|
|
11738
|
-
|
|
11739
|
-
apiKey = decrypt6(row.api_key_enc);
|
|
11740
|
-
} catch (error) {
|
|
11741
|
-
console.error("Failed to decrypt model provider API key:", error);
|
|
11742
|
-
throw new Error("Failed to decrypt model provider API key");
|
|
11743
|
-
}
|
|
11820
|
+
apiKey = safeDecrypt6(row.api_key_enc);
|
|
11744
11821
|
}
|
|
11745
11822
|
return {
|
|
11746
11823
|
id: row.id,
|
|
@@ -11776,6 +11853,8 @@ var PostgreSQLModelProviderStore = class {
|
|
|
11776
11853
|
upstreamCreatedAt: row.upstream_created || void 0,
|
|
11777
11854
|
enabled: row.enabled,
|
|
11778
11855
|
stale: row.stale,
|
|
11856
|
+
extra: extraOrUndefined(row.extra),
|
|
11857
|
+
isDefault: row.is_default,
|
|
11779
11858
|
discoveredAt: row.discovered_at
|
|
11780
11859
|
};
|
|
11781
11860
|
}
|
|
@@ -12200,8 +12279,11 @@ async function createPgStoreConfig(connectionString) {
|
|
|
12200
12279
|
mm.register(createDistributedLeases);
|
|
12201
12280
|
mm.register(createOutboxTable);
|
|
12202
12281
|
mm.register(addConnectionSecretFields);
|
|
12282
|
+
mm.register(reencryptLegacyConnectionSecrets);
|
|
12203
12283
|
mm.register(createPluginDeployments);
|
|
12204
12284
|
mm.register(dropPluginDeploymentAuthToken);
|
|
12285
|
+
mm.register(addModelProviderModelExtra);
|
|
12286
|
+
mm.register(addModelProviderModelDefault);
|
|
12205
12287
|
await mm.migrate();
|
|
12206
12288
|
const checkpoint = PostgresSaver.fromConnString(connectionString);
|
|
12207
12289
|
checkpoint.setup().catch((err) => {
|