@axiom-lattice/pg-stores 3.1.20 → 3.2.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +71 -0
- package/dist/index.d.mts +125 -2
- package/dist/index.d.ts +125 -2
- package/dist/index.js +630 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +629 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/scripts/check-migration-versions.mjs +6 -1
- package/src/createPgStoreConfig.ts +12 -0
- package/src/index.ts +2 -0
- package/src/migrations/model_provider_migrations.ts +157 -0
- package/src/stores/PostgreSQLModelProviderStore.ts +731 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiom-lattice/pg-stores",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
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": "
|
|
29
|
-
"@axiom-lattice/protocols": "4.
|
|
28
|
+
"@axiom-lattice/core": "6.1.0",
|
|
29
|
+
"@axiom-lattice/protocols": "4.6.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/jest": "^29.5.14",
|
|
@@ -25,8 +25,13 @@ for (const file of files) {
|
|
|
25
25
|
// Extract name and version from migration definitions
|
|
26
26
|
// Matches patterns like:
|
|
27
27
|
// name: "create_threads_table",
|
|
28
|
+
// name: 'create_model_providers_table',
|
|
28
29
|
// version: 1,
|
|
29
|
-
|
|
30
|
+
//
|
|
31
|
+
// Both quote styles are accepted. Migrations written with single quotes were
|
|
32
|
+
// invisible to this check, so their names were never compared and a duplicate
|
|
33
|
+
// could only surface at runtime, where MigrationManager.register throws.
|
|
34
|
+
const nameMatches = content.matchAll(/^\s*name:\s*["']([^"']+)["']/gm);
|
|
30
35
|
const versionMatches = content.matchAll(/^\s*version:\s*(\d+)/gm);
|
|
31
36
|
|
|
32
37
|
const names = [...nameMatches].map(m => m[1]);
|
|
@@ -90,6 +90,12 @@ import { createCapabilityBundlesTable } from "./migrations/capability_bundle_mig
|
|
|
90
90
|
import { createProjectRoomReadStates, createProjectRoomTables } from "./migrations/project_room_migration";
|
|
91
91
|
import { addProjectRoomMessageRetentionIndex } from "./migrations/project_room_message_retention_migration";
|
|
92
92
|
import { createUserPushSubscriptions } from "./migrations/user_push_subscription_migration";
|
|
93
|
+
import {
|
|
94
|
+
createModelProvidersTable,
|
|
95
|
+
createModelProviderModelsTable,
|
|
96
|
+
addModelProviderApiStyle,
|
|
97
|
+
addModelProviderModelStale,
|
|
98
|
+
} from "./migrations/model_provider_migrations";
|
|
93
99
|
import { PostgreSQLCapabilityBundleStore } from "./stores/PostgreSQLCapabilityBundleStore";
|
|
94
100
|
import { PostgreSQLProjectRoomStore } from "./stores/PostgreSQLProjectRoomStore";
|
|
95
101
|
import { PostgreSQLProjectMembershipStore } from "./stores/PostgreSQLProjectMembershipStore";
|
|
@@ -97,6 +103,7 @@ import { PostgreSQLProjectBotMembershipStore } from "./stores/PostgreSQLProjectB
|
|
|
97
103
|
import { PostgreSQLProjectRoomMessageStore } from "./stores/PostgreSQLProjectRoomMessageStore";
|
|
98
104
|
import { PostgreSQLProjectRoomReadStateStore } from "./stores/PostgreSQLProjectRoomReadStateStore";
|
|
99
105
|
import { PostgreSQLUserPushSubscriptionStore } from "./stores/PostgreSQLUserPushSubscriptionStore";
|
|
106
|
+
import { PostgreSQLModelProviderStore } from "./stores/PostgreSQLModelProviderStore";
|
|
100
107
|
|
|
101
108
|
export async function createPgStoreConfig(connectionString: string) {
|
|
102
109
|
const pool = new Pool({ connectionString });
|
|
@@ -171,6 +178,10 @@ export async function createPgStoreConfig(connectionString: string) {
|
|
|
171
178
|
mm.register(createProjectRoomReadStates); // v177
|
|
172
179
|
mm.register(createUserPushSubscriptions); // v178
|
|
173
180
|
mm.register(addProjectRoomMessageRetentionIndex); // v179
|
|
181
|
+
mm.register(createModelProvidersTable); // v181
|
|
182
|
+
mm.register(createModelProviderModelsTable); // v182
|
|
183
|
+
mm.register(addModelProviderApiStyle); // v183
|
|
184
|
+
mm.register(addModelProviderModelStale); // v184
|
|
174
185
|
|
|
175
186
|
await mm.migrate();
|
|
176
187
|
|
|
@@ -197,6 +208,7 @@ export async function createPgStoreConfig(connectionString: string) {
|
|
|
197
208
|
connection: new PostgreSQLConnectionStore(pool),
|
|
198
209
|
metrics: new PostgreSQLMetricsServerConfigStore(opts),
|
|
199
210
|
mcp: new PostgreSQLMcpServerConfigStore(opts),
|
|
211
|
+
modelProvider: new PostgreSQLModelProviderStore(opts),
|
|
200
212
|
assistant: new PostgreSQLAssistantStore(opts),
|
|
201
213
|
workflowTracking: new PostgreSQLWorkflowTrackingStore(opts),
|
|
202
214
|
threadMessageQueue: new ThreadMessageQueueStore(opts),
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ export * from "./stores/PostgreSQLDatabaseConfigStore";
|
|
|
18
18
|
export * from "./stores/PostgreSQLConnectionStore";
|
|
19
19
|
export * from "./stores/PostgreSQLMetricsServerConfigStore";
|
|
20
20
|
export * from "./stores/PostgreSQLMcpServerConfigStore";
|
|
21
|
+
export * from "./stores/PostgreSQLModelProviderStore";
|
|
21
22
|
export * from "./stores/PostgreSQLWorkspaceStore";
|
|
22
23
|
export * from "./stores/PostgreSQLProjectStore";
|
|
23
24
|
export * from "./stores/PostgreSQLUserStore";
|
|
@@ -91,6 +92,7 @@ export { PostgreSQLDatabaseConfigStore } from "./stores/PostgreSQLDatabaseConfig
|
|
|
91
92
|
export { PostgreSQLConnectionStore } from "./stores/PostgreSQLConnectionStore";
|
|
92
93
|
export { PostgreSQLMetricsServerConfigStore } from "./stores/PostgreSQLMetricsServerConfigStore";
|
|
93
94
|
export { PostgreSQLMcpServerConfigStore } from "./stores/PostgreSQLMcpServerConfigStore";
|
|
95
|
+
export { PostgreSQLModelProviderStore } from "./stores/PostgreSQLModelProviderStore";
|
|
94
96
|
export { PostgreSQLWorkspaceStore } from "./stores/PostgreSQLWorkspaceStore";
|
|
95
97
|
export { PostgreSQLProjectStore } from "./stores/PostgreSQLProjectStore";
|
|
96
98
|
export { PostgreSQLUserStore } from "./stores/PostgreSQLUserStore";
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model provider table migrations
|
|
3
|
+
*
|
|
4
|
+
* Tenants configure an upstream provider (baseURL + apiKey) and the gateway
|
|
5
|
+
* records the models discovered from it as a snapshot.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { PoolClient } from 'pg';
|
|
9
|
+
import { Migration } from './migration';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create model provider configuration table
|
|
13
|
+
*/
|
|
14
|
+
export const createModelProvidersTable: Migration = {
|
|
15
|
+
version: 181,
|
|
16
|
+
name: 'create_model_providers_table',
|
|
17
|
+
up: async (client: PoolClient) => {
|
|
18
|
+
await client.query(`
|
|
19
|
+
CREATE TABLE IF NOT EXISTS lattice_model_providers (
|
|
20
|
+
id VARCHAR(255) NOT NULL,
|
|
21
|
+
tenant_id VARCHAR(255) NOT NULL,
|
|
22
|
+
name VARCHAR(255) NOT NULL,
|
|
23
|
+
display_name VARCHAR(255),
|
|
24
|
+
protocol VARCHAR(64) NOT NULL,
|
|
25
|
+
api_style VARCHAR(32) NOT NULL DEFAULT 'chat-completions',
|
|
26
|
+
llm_provider VARCHAR(64) NOT NULL,
|
|
27
|
+
base_url TEXT NOT NULL,
|
|
28
|
+
api_key_enc TEXT,
|
|
29
|
+
api_key_hint VARCHAR(16),
|
|
30
|
+
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
|
31
|
+
status VARCHAR(32) NOT NULL DEFAULT 'unknown',
|
|
32
|
+
last_error VARCHAR(255),
|
|
33
|
+
last_discovered_at TIMESTAMP,
|
|
34
|
+
created_by VARCHAR(255),
|
|
35
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
36
|
+
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
37
|
+
|
|
38
|
+
PRIMARY KEY (tenant_id, id),
|
|
39
|
+
CONSTRAINT uk_lattice_model_providers_tenant_name UNIQUE (tenant_id, name)
|
|
40
|
+
)
|
|
41
|
+
`);
|
|
42
|
+
|
|
43
|
+
await client.query(`
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_lattice_model_providers_tenant_id
|
|
45
|
+
ON lattice_model_providers(tenant_id)
|
|
46
|
+
`);
|
|
47
|
+
},
|
|
48
|
+
down: async (client: PoolClient) => {
|
|
49
|
+
await client.query('DROP INDEX IF EXISTS idx_lattice_model_providers_tenant_id');
|
|
50
|
+
await client.query('DROP TABLE IF EXISTS lattice_model_providers');
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Create model provider snapshot table
|
|
56
|
+
*
|
|
57
|
+
* `model_id` is the upstream model id and `provider_id` scopes it, so the same
|
|
58
|
+
* upstream id may appear under several providers in one tenant — each is an
|
|
59
|
+
* independent model addressed by `${providerId}/${modelId}`.
|
|
60
|
+
*/
|
|
61
|
+
export const createModelProviderModelsTable: Migration = {
|
|
62
|
+
version: 182,
|
|
63
|
+
name: 'create_model_provider_models_table',
|
|
64
|
+
up: async (client: PoolClient) => {
|
|
65
|
+
await client.query(`
|
|
66
|
+
CREATE TABLE IF NOT EXISTS lattice_model_provider_models (
|
|
67
|
+
id VARCHAR(255) NOT NULL,
|
|
68
|
+
tenant_id VARCHAR(255) NOT NULL,
|
|
69
|
+
provider_id VARCHAR(255) NOT NULL,
|
|
70
|
+
model_id VARCHAR(512) NOT NULL,
|
|
71
|
+
display_name VARCHAR(255),
|
|
72
|
+
owned_by VARCHAR(255),
|
|
73
|
+
upstream_created TIMESTAMP,
|
|
74
|
+
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
|
75
|
+
raw JSONB,
|
|
76
|
+
discovered_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
77
|
+
|
|
78
|
+
PRIMARY KEY (tenant_id, provider_id, model_id)
|
|
79
|
+
)
|
|
80
|
+
`);
|
|
81
|
+
|
|
82
|
+
await client.query(`
|
|
83
|
+
CREATE INDEX IF NOT EXISTS idx_lattice_model_provider_models_tenant_id
|
|
84
|
+
ON lattice_model_provider_models(tenant_id)
|
|
85
|
+
`);
|
|
86
|
+
|
|
87
|
+
await client.query(`
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_lattice_model_provider_models_tenant_model
|
|
89
|
+
ON lattice_model_provider_models(tenant_id, model_id)
|
|
90
|
+
`);
|
|
91
|
+
|
|
92
|
+
await client.query(`
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_lattice_model_provider_models_tenant_provider
|
|
94
|
+
ON lattice_model_provider_models(tenant_id, provider_id)
|
|
95
|
+
`);
|
|
96
|
+
},
|
|
97
|
+
down: async (client: PoolClient) => {
|
|
98
|
+
await client.query('DROP INDEX IF EXISTS idx_lattice_model_provider_models_tenant_provider');
|
|
99
|
+
await client.query('DROP INDEX IF EXISTS idx_lattice_model_provider_models_tenant_model');
|
|
100
|
+
await client.query('DROP INDEX IF EXISTS idx_lattice_model_provider_models_tenant_id');
|
|
101
|
+
await client.query('DROP TABLE IF EXISTS lattice_model_provider_models');
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Add `api_style` to an already-created providers table.
|
|
107
|
+
*
|
|
108
|
+
* `createModelProvidersTable` (v181) originally shipped without this column and
|
|
109
|
+
* gained it in a later edit. Migrations are recorded by name and never re-run,
|
|
110
|
+
* so any database that had already applied v181 kept a table without the column
|
|
111
|
+
* and every read failed on the missing field. Editing an applied migration does
|
|
112
|
+
* not update the databases that already ran it — this patch is what does.
|
|
113
|
+
*
|
|
114
|
+
* `IF NOT EXISTS` keeps it a no-op for databases created after the column moved
|
|
115
|
+
* into v181.
|
|
116
|
+
*/
|
|
117
|
+
export const addModelProviderApiStyle: Migration = {
|
|
118
|
+
version: 183,
|
|
119
|
+
name: 'add_model_provider_api_style',
|
|
120
|
+
up: async (client: PoolClient) => {
|
|
121
|
+
await client.query(`
|
|
122
|
+
ALTER TABLE lattice_model_providers
|
|
123
|
+
ADD COLUMN IF NOT EXISTS api_style VARCHAR(32) NOT NULL DEFAULT 'chat-completions'
|
|
124
|
+
`);
|
|
125
|
+
},
|
|
126
|
+
down: async (client: PoolClient) => {
|
|
127
|
+
await client.query(`
|
|
128
|
+
ALTER TABLE lattice_model_providers DROP COLUMN IF EXISTS api_style
|
|
129
|
+
`);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Record that an upstream stopped offering a model, without deleting the row.
|
|
135
|
+
*
|
|
136
|
+
* Syncing used to have only two outcomes for a model the upstream dropped:
|
|
137
|
+
* remove it, or leave it looking identical to one the tenant switched off.
|
|
138
|
+
* Removing it silently breaks any agent or eval config that references the key;
|
|
139
|
+
* leaving it makes the two states indistinguishable. This column is the third
|
|
140
|
+
* option — the row stays and says why it is off, and the tenant decides when to
|
|
141
|
+
* delete it.
|
|
142
|
+
*/
|
|
143
|
+
export const addModelProviderModelStale: Migration = {
|
|
144
|
+
version: 184,
|
|
145
|
+
name: 'add_model_provider_model_stale',
|
|
146
|
+
up: async (client: PoolClient) => {
|
|
147
|
+
await client.query(`
|
|
148
|
+
ALTER TABLE lattice_model_provider_models
|
|
149
|
+
ADD COLUMN IF NOT EXISTS stale BOOLEAN NOT NULL DEFAULT FALSE
|
|
150
|
+
`);
|
|
151
|
+
},
|
|
152
|
+
down: async (client: PoolClient) => {
|
|
153
|
+
await client.query(`
|
|
154
|
+
ALTER TABLE lattice_model_provider_models DROP COLUMN IF EXISTS stale
|
|
155
|
+
`);
|
|
156
|
+
},
|
|
157
|
+
};
|