@axiom-lattice/pg-stores 3.0.2 → 3.1.1

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.js CHANGED
@@ -35,10 +35,11 @@ __export(index_exports, {
35
35
  MenuStore: () => MenuStore,
36
36
  MigrationManager: () => MigrationManager,
37
37
  PGVectorStoreProvider: () => PGVectorStoreProvider,
38
- Pool: () => import_pg27.Pool,
38
+ Pool: () => import_pg28.Pool,
39
39
  PostgreSQLA2AApiKeyStore: () => PostgreSQLA2AApiKeyStore,
40
40
  PostgreSQLAgentWebAppStore: () => PostgreSQLAgentWebAppStore,
41
41
  PostgreSQLAssistantStore: () => PostgreSQLAssistantStore,
42
+ PostgreSQLCapabilityBundleStore: () => PostgreSQLCapabilityBundleStore,
42
43
  PostgreSQLChannelInstallationStore: () => PostgreSQLChannelInstallationStore,
43
44
  PostgreSQLCollectionStore: () => PostgreSQLCollectionStore,
44
45
  PostgreSQLConnectionStore: () => PostgreSQLConnectionStore,
@@ -77,6 +78,7 @@ __export(index_exports, {
77
78
  createA2AApiKeysTable: () => createA2AApiKeysTable,
78
79
  createAgentWebAppsTable: () => createAgentWebAppsTable,
79
80
  createAssistantsTable: () => createAssistantsTable,
81
+ createCapabilityBundlesTable: () => createCapabilityBundlesTable,
80
82
  createChannelBindingsTable: () => createChannelBindingsTable,
81
83
  createChannelIdentityMappingTables: () => createChannelIdentityMappingTables,
82
84
  createChannelInstallationsTable: () => createChannelInstallationsTable,
@@ -109,10 +111,10 @@ __export(index_exports, {
109
111
  safeParse: () => safeParse
110
112
  });
111
113
  module.exports = __toCommonJS(index_exports);
112
- var import_pg27 = require("pg");
114
+ var import_pg28 = require("pg");
113
115
 
114
116
  // src/createPgStoreConfig.ts
115
- var import_pg24 = require("pg");
117
+ var import_pg25 = require("pg");
116
118
 
117
119
  // src/migrations/migration.ts
118
120
  var MigrationManager = class {
@@ -2382,6 +2384,7 @@ var PostgreSQLWorkspaceStore = class {
2382
2384
 
2383
2385
  // src/stores/PostgreSQLProjectStore.ts
2384
2386
  var import_pg7 = require("pg");
2387
+ var import_protocols = require("@axiom-lattice/protocols");
2385
2388
 
2386
2389
  // src/migrations/project_migrations.ts
2387
2390
  var createProjectsTable = {
@@ -2597,34 +2600,62 @@ var PostgreSQLProjectStore = class {
2597
2600
  * Create a new project
2598
2601
  */
2599
2602
  async createProject(tenantId, workspaceId, id, data) {
2603
+ (0, import_protocols.assertGenericProjectConfig)(data.config);
2600
2604
  await this.ensureInitialized();
2601
2605
  const now = /* @__PURE__ */ new Date();
2602
2606
  const kind = data.kind || "business";
2603
- await this.pool.query(
2604
- `
2605
- INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at)
2607
+ const client = await this.pool.connect();
2608
+ try {
2609
+ await client.query("BEGIN");
2610
+ await client.query(
2611
+ "SELECT pg_advisory_xact_lock(hashtextextended($1 || ':project-mutations', 0))",
2612
+ [tenantId]
2613
+ );
2614
+ await client.query(
2615
+ "SELECT pg_advisory_xact_lock(hashtextextended($2 || ':project:' || $1, 0))",
2616
+ [id, tenantId]
2617
+ );
2618
+ const existing = await client.query(
2619
+ "SELECT config FROM lattice_projects WHERE id = $1 AND tenant_id = $2 FOR UPDATE",
2620
+ [id, tenantId]
2621
+ );
2622
+ const ids = existing.rows[0]?.config?.capabilityBundleIds;
2623
+ const bundleIds = Array.isArray(ids) && ids.every((bundleId) => typeof bundleId === "string") ? [...ids].sort() : [];
2624
+ if (bundleIds.length > 0) {
2625
+ await client.query(
2626
+ `SELECT pg_advisory_xact_lock(hashtextextended($1 || ':' || bundle_id, 0))
2627
+ FROM unnest($2::text[]) AS bundle_id
2628
+ ORDER BY bundle_id`,
2629
+ [tenantId, bundleIds]
2630
+ );
2631
+ }
2632
+ const result = await client.query(
2633
+ `INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at)
2606
2634
  VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
2607
2635
  ON CONFLICT (id, tenant_id) DO UPDATE SET
2608
2636
  workspace_id = EXCLUDED.workspace_id,
2609
2637
  name = EXCLUDED.name,
2610
2638
  description = EXCLUDED.description,
2611
- config = EXCLUDED.config,
2639
+ config = CASE
2640
+ WHEN lattice_projects.config ? 'capabilityBundleIds'
2641
+ THEN COALESCE(EXCLUDED.config, '{}'::jsonb)
2642
+ || jsonb_build_object('capabilityBundleIds', lattice_projects.config->'capabilityBundleIds')
2643
+ ELSE EXCLUDED.config
2644
+ END,
2612
2645
  kind = EXCLUDED.kind,
2613
2646
  updated_at = EXCLUDED.updated_at
2647
+ RETURNING id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at
2614
2648
  `,
2615
- [id, tenantId, workspaceId, data.name, data.description || null, data.config || null, kind, now, now]
2616
- );
2617
- return {
2618
- id,
2619
- tenantId,
2620
- workspaceId,
2621
- name: data.name,
2622
- description: data.description,
2623
- config: data.config,
2624
- kind,
2625
- createdAt: now,
2626
- updatedAt: now
2627
- };
2649
+ [id, tenantId, workspaceId, data.name, data.description || null, data.config || null, kind, now, now]
2650
+ );
2651
+ await client.query("COMMIT");
2652
+ return this.mapRowToProject(result.rows[0]);
2653
+ } catch (error) {
2654
+ await client.query("ROLLBACK");
2655
+ throw error;
2656
+ } finally {
2657
+ client.release();
2658
+ }
2628
2659
  }
2629
2660
  /**
2630
2661
  * Update an existing project
@@ -2634,11 +2665,8 @@ var PostgreSQLProjectStore = class {
2634
2665
  * overwrites the existing config. To preserve the current config, omit this field.
2635
2666
  */
2636
2667
  async updateProject(tenantId, id, updates) {
2668
+ (0, import_protocols.assertGenericProjectConfig)(updates.config);
2637
2669
  await this.ensureInitialized();
2638
- const existing = await this.getProjectById(tenantId, id);
2639
- if (!existing) {
2640
- return null;
2641
- }
2642
2670
  const updateFields = [];
2643
2671
  const updateValues = [];
2644
2672
  let paramIndex = 1;
@@ -2651,43 +2679,190 @@ var PostgreSQLProjectStore = class {
2651
2679
  updateValues.push(updates.description || null);
2652
2680
  }
2653
2681
  if (updates.config !== void 0) {
2654
- updateFields.push(`config = $${paramIndex++}`);
2655
- updateValues.push(updates.config || null);
2682
+ const configParam = `$${paramIndex++}`;
2683
+ updateFields.push(`config = CASE
2684
+ WHEN config ? 'capabilityBundleIds'
2685
+ THEN COALESCE(${configParam}::jsonb, '{}'::jsonb)
2686
+ || jsonb_build_object('capabilityBundleIds', config->'capabilityBundleIds')
2687
+ ELSE ${configParam}::jsonb
2688
+ END`);
2689
+ updateValues.push(updates.config);
2656
2690
  }
2657
2691
  if (updates.kind !== void 0) {
2658
2692
  updateFields.push(`kind = $${paramIndex++}`);
2659
2693
  updateValues.push(updates.kind);
2660
2694
  }
2661
2695
  if (updateFields.length === 0) {
2662
- return existing;
2696
+ return await this.getProjectById(tenantId, id);
2663
2697
  }
2664
2698
  updateFields.push(`updated_at = $${paramIndex++}`);
2665
2699
  updateValues.push(/* @__PURE__ */ new Date());
2666
- updateValues.push(id);
2667
- updateValues.push(tenantId);
2668
- await this.pool.query(
2669
- `
2670
- UPDATE lattice_projects
2671
- SET ${updateFields.join(", ")}
2672
- WHERE id = $${paramIndex} AND tenant_id = $${paramIndex + 1}
2673
- `,
2674
- updateValues
2675
- );
2676
- return await this.getProjectById(tenantId, id);
2700
+ updateValues.push(id, tenantId);
2701
+ const client = await this.pool.connect();
2702
+ try {
2703
+ await client.query("BEGIN");
2704
+ await client.query(
2705
+ "SELECT pg_advisory_xact_lock(hashtextextended($1 || ':project-mutations', 0))",
2706
+ [tenantId]
2707
+ );
2708
+ await client.query(
2709
+ "SELECT pg_advisory_xact_lock(hashtextextended($2 || ':project:' || $1, 0))",
2710
+ [id, tenantId]
2711
+ );
2712
+ const existing = await client.query(
2713
+ "SELECT config FROM lattice_projects WHERE id = $1 AND tenant_id = $2 FOR UPDATE",
2714
+ [id, tenantId]
2715
+ );
2716
+ if (!existing.rows[0]) {
2717
+ await client.query("COMMIT");
2718
+ return null;
2719
+ }
2720
+ const ids = existing.rows[0].config?.capabilityBundleIds;
2721
+ const bundleIds = Array.isArray(ids) && ids.every((bundleId) => typeof bundleId === "string") ? [...ids].sort() : [];
2722
+ if (bundleIds.length > 0) {
2723
+ await client.query(
2724
+ `SELECT pg_advisory_xact_lock(hashtextextended($1 || ':' || bundle_id, 0))
2725
+ FROM unnest($2::text[]) AS bundle_id
2726
+ ORDER BY bundle_id`,
2727
+ [tenantId, bundleIds]
2728
+ );
2729
+ }
2730
+ const result = await client.query(
2731
+ `UPDATE lattice_projects SET ${updateFields.join(", ")}
2732
+ WHERE id = $${paramIndex} AND tenant_id = $${paramIndex + 1}
2733
+ RETURNING id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at`,
2734
+ updateValues
2735
+ );
2736
+ await client.query("COMMIT");
2737
+ return this.mapRowToProject(result.rows[0]);
2738
+ } catch (error) {
2739
+ await client.query("ROLLBACK");
2740
+ throw error;
2741
+ } finally {
2742
+ client.release();
2743
+ }
2677
2744
  }
2678
2745
  /**
2679
2746
  * Delete a project by ID
2680
2747
  */
2681
2748
  async deleteProject(tenantId, id) {
2749
+ await this.ensureInitialized();
2750
+ const client = await this.pool.connect();
2751
+ try {
2752
+ await client.query("BEGIN");
2753
+ await client.query(
2754
+ "SELECT pg_advisory_xact_lock(hashtextextended($1 || ':project-mutations', 0))",
2755
+ [tenantId]
2756
+ );
2757
+ await client.query(
2758
+ "SELECT pg_advisory_xact_lock(hashtextextended($2 || ':project:' || $1, 0))",
2759
+ [id, tenantId]
2760
+ );
2761
+ const selected = await client.query(
2762
+ "SELECT config FROM lattice_projects WHERE id = $1 AND tenant_id = $2 FOR UPDATE",
2763
+ [id, tenantId]
2764
+ );
2765
+ if (!selected.rows[0]) {
2766
+ await client.query("COMMIT");
2767
+ return false;
2768
+ }
2769
+ const ids = selected.rows[0].config?.capabilityBundleIds;
2770
+ const bundleIds = Array.isArray(ids) && ids.every((bundleId) => typeof bundleId === "string") ? [...ids].sort() : [];
2771
+ if (bundleIds.length > 0) {
2772
+ await client.query(
2773
+ `SELECT pg_advisory_xact_lock(hashtextextended($1 || ':' || bundle_id, 0))
2774
+ FROM unnest($2::text[]) AS bundle_id
2775
+ ORDER BY bundle_id`,
2776
+ [tenantId, bundleIds]
2777
+ );
2778
+ }
2779
+ const result = await client.query(
2780
+ "DELETE FROM lattice_projects WHERE id = $1 AND tenant_id = $2",
2781
+ [id, tenantId]
2782
+ );
2783
+ await client.query("COMMIT");
2784
+ return result.rowCount !== null && result.rowCount > 0;
2785
+ } catch (error) {
2786
+ await client.query("ROLLBACK");
2787
+ throw error;
2788
+ } finally {
2789
+ client.release();
2790
+ }
2791
+ }
2792
+ async updateCapabilityBundleIds(tenantId, projectId, bundleIds, expectedRevisions = {}) {
2793
+ await this.ensureInitialized();
2794
+ const client = await this.pool.connect();
2795
+ try {
2796
+ await client.query("BEGIN");
2797
+ await client.query(
2798
+ "SELECT pg_advisory_xact_lock(hashtextextended($1 || ':project-mutations', 0))",
2799
+ [tenantId]
2800
+ );
2801
+ await client.query(
2802
+ "SELECT pg_advisory_xact_lock(hashtextextended($2 || ':project:' || $1, 0))",
2803
+ [projectId, tenantId]
2804
+ );
2805
+ await client.query(
2806
+ "SELECT id FROM lattice_projects WHERE id = $1 AND tenant_id = $2 FOR UPDATE",
2807
+ [projectId, tenantId]
2808
+ );
2809
+ if (bundleIds.length > 0) {
2810
+ await client.query(
2811
+ `SELECT pg_advisory_xact_lock(hashtextextended($1 || ':' || bundle_id, 0))
2812
+ FROM unnest($2::text[]) AS bundle_id
2813
+ ORDER BY bundle_id`,
2814
+ [tenantId, [...bundleIds].sort()]
2815
+ );
2816
+ if (Object.keys(expectedRevisions).length > 0) {
2817
+ const revisions = await client.query("SELECT id, updated_at::text AS updated_at FROM lattice_capability_bundles WHERE tenant_id = $1 AND id = ANY($2::uuid[]) FOR UPDATE", [tenantId, bundleIds]);
2818
+ if (revisions.rows.some((bundle) => expectedRevisions[bundle.id] !== void 0 && expectedRevisions[bundle.id] !== bundle.updated_at)) {
2819
+ await client.query("ROLLBACK");
2820
+ return { status: "bundle_conflict" };
2821
+ }
2822
+ }
2823
+ }
2824
+ const result = await client.query(
2825
+ `UPDATE lattice_projects
2826
+ SET config = COALESCE(config, '{}'::jsonb) || jsonb_build_object('capabilityBundleIds', $3::jsonb), updated_at = NOW()
2827
+ WHERE id = $1 AND tenant_id = $2
2828
+ AND NOT EXISTS (
2829
+ SELECT 1 FROM unnest($4::uuid[]) AS bundle_id
2830
+ WHERE NOT EXISTS (
2831
+ SELECT 1 FROM lattice_capability_bundles
2832
+ WHERE tenant_id = $2 AND id = bundle_id
2833
+ )
2834
+ )
2835
+ RETURNING id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at`,
2836
+ [projectId, tenantId, JSON.stringify(bundleIds), bundleIds]
2837
+ );
2838
+ if (result.rows[0]) {
2839
+ await client.query("COMMIT");
2840
+ return { status: "updated", project: this.mapRowToProject(result.rows[0]) };
2841
+ }
2842
+ const project = await client.query(
2843
+ "SELECT id FROM lattice_projects WHERE id = $1 AND tenant_id = $2",
2844
+ [projectId, tenantId]
2845
+ );
2846
+ await client.query("COMMIT");
2847
+ return project.rows.length > 0 ? { status: "bundle_not_found" } : { status: "project_not_found" };
2848
+ } catch (error) {
2849
+ await client.query("ROLLBACK");
2850
+ throw error;
2851
+ } finally {
2852
+ client.release();
2853
+ }
2854
+ }
2855
+ async isCapabilityBundleReferenced(tenantId, bundleId) {
2682
2856
  await this.ensureInitialized();
2683
2857
  const result = await this.pool.query(
2684
- `
2685
- DELETE FROM lattice_projects
2686
- WHERE id = $1 AND tenant_id = $2
2687
- `,
2688
- [id, tenantId]
2858
+ `SELECT 1 AS exists FROM lattice_projects
2859
+ WHERE tenant_id = $1
2860
+ AND jsonb_typeof(config->'capabilityBundleIds') = 'array'
2861
+ AND COALESCE(config->'capabilityBundleIds', '[]'::jsonb) ? $2
2862
+ LIMIT 1`,
2863
+ [tenantId, bundleId]
2689
2864
  );
2690
- return result.rowCount !== null && result.rowCount > 0;
2865
+ return result.rows.length > 0;
2691
2866
  }
2692
2867
  };
2693
2868
 
@@ -5170,10 +5345,48 @@ var ThreadMessageQueueStore = class {
5170
5345
  (id, thread_id, tenant_id, assistant_id, workspace_id, project_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
5171
5346
  VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
5172
5347
  RETURNING *`,
5173
- [id || import_crypto.default.randomUUID(), threadId, tenantId, assistantId, workspaceId || null, projectId || null, JSON.stringify(content), type, nextSeq, priority, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]
5348
+ [id || import_crypto.default.randomUUID(), threadId, tenantId, assistantId, workspaceId ?? null, projectId ?? null, JSON.stringify(content), type, nextSeq, priority, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]
5174
5349
  );
5175
5350
  return this.rowToMessage(result.rows[0]);
5176
5351
  }
5352
+ async addMessageIfCapacity(params, maxSize) {
5353
+ if (maxSize === Infinity) {
5354
+ await this.addMessage(params);
5355
+ return true;
5356
+ }
5357
+ const client = await this.pool.connect();
5358
+ try {
5359
+ await client.query("BEGIN");
5360
+ const scope = { tenantId: params.tenantId, assistantId: params.assistantId, workspaceId: params.workspaceId, projectId: params.projectId };
5361
+ const lockKey = `${params.tenantId}:${params.assistantId}:${params.threadId}:${params.workspaceId ?? ""}:${params.projectId ?? ""}`;
5362
+ await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [lockKey]);
5363
+ const filter = scopeClause(scope, 2);
5364
+ const count = await client.query(
5365
+ `SELECT COUNT(*) as count FROM lattice_thread_message_queue WHERE thread_id = $1 AND status = 'pending'${filter.sql}`,
5366
+ [params.threadId, ...filter.params]
5367
+ );
5368
+ if (parseInt(count.rows[0].count, 10) >= maxSize) {
5369
+ await client.query("ROLLBACK");
5370
+ return false;
5371
+ }
5372
+ const seq = await client.query(
5373
+ `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq FROM lattice_thread_message_queue WHERE thread_id = $1`,
5374
+ [params.threadId]
5375
+ );
5376
+ const result = await client.query(
5377
+ `INSERT INTO lattice_thread_message_queue (id, thread_id, tenant_id, assistant_id, workspace_id, project_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
5378
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING *`,
5379
+ [params.id || import_crypto.default.randomUUID(), params.threadId, params.tenantId, params.assistantId, params.workspaceId ?? null, params.projectId ?? null, JSON.stringify(params.content), params.type || "human", seq.rows[0].next_seq, params.priority ?? 0, params.command ? JSON.stringify(params.command) : null, params.custom_run_config ? JSON.stringify(params.custom_run_config) : null]
5380
+ );
5381
+ await client.query("COMMIT");
5382
+ return Boolean(result.rows[0]);
5383
+ } catch (error) {
5384
+ await client.query("ROLLBACK");
5385
+ throw error;
5386
+ } finally {
5387
+ client.release();
5388
+ }
5389
+ }
5177
5390
  /**
5178
5391
  * Add message at head of queue (high priority, e.g., STEER/Command messages)
5179
5392
  * Uses priority=100 to ensure message is processed first
@@ -5194,42 +5407,45 @@ var ThreadMessageQueueStore = class {
5194
5407
  (id, thread_id, tenant_id, assistant_id, workspace_id, project_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
5195
5408
  VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, 100, $10, $11)
5196
5409
  RETURNING *`,
5197
- [id || import_crypto.default.randomUUID(), threadId, resolvedTenantId, resolvedAssistantId, workspaceId || null, projectId || null, JSON.stringify(content), type, nextSeq, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]
5410
+ [id || import_crypto.default.randomUUID(), threadId, resolvedTenantId, resolvedAssistantId, workspaceId ?? null, projectId ?? null, JSON.stringify(content), type, nextSeq, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]
5198
5411
  );
5199
5412
  return this.rowToMessage(result.rows[0]);
5200
5413
  }
5201
5414
  /**
5202
5415
  * Get pending messages for thread
5203
5416
  */
5204
- async getPendingMessages(threadId) {
5417
+ async getPendingMessages(threadId, scope) {
5418
+ const filter = scopeClause(scope, 2);
5205
5419
  const result = await this.pool.query(
5206
- `SELECT * FROM lattice_thread_message_queue
5207
- WHERE thread_id = $1 AND status = 'pending'
5420
+ `SELECT * FROM lattice_thread_message_queue
5421
+ WHERE thread_id = $1 AND status = 'pending'${filter.sql}
5208
5422
  ORDER BY priority DESC, sequence_order ASC`,
5209
- [threadId]
5423
+ [threadId, ...filter.params]
5210
5424
  );
5211
5425
  return result.rows.map((row) => this.rowToMessage(row));
5212
5426
  }
5213
5427
  /**
5214
5428
  * Get processing messages for a thread
5215
5429
  */
5216
- async getProcessingMessages(threadId) {
5430
+ async getProcessingMessages(threadId, scope) {
5431
+ const filter = scopeClause(scope, 2);
5217
5432
  const result = await this.pool.query(
5218
5433
  `SELECT * FROM lattice_thread_message_queue
5219
- WHERE thread_id = $1 AND status = 'processing'
5434
+ WHERE thread_id = $1 AND status = 'processing'${filter.sql}
5220
5435
  ORDER BY priority DESC, sequence_order ASC`,
5221
- [threadId]
5436
+ [threadId, ...filter.params]
5222
5437
  );
5223
5438
  return result.rows.map((row) => this.rowToMessage(row));
5224
5439
  }
5225
5440
  /**
5226
5441
  * Get queue size
5227
5442
  */
5228
- async getQueueSize(threadId) {
5443
+ async getQueueSize(threadId, scope) {
5444
+ const filter = scopeClause(scope, 2);
5229
5445
  const result = await this.pool.query(
5230
5446
  `SELECT COUNT(*) as count FROM lattice_thread_message_queue
5231
- WHERE thread_id = $1 AND status = 'pending'`,
5232
- [threadId]
5447
+ WHERE thread_id = $1 AND status = 'pending'${filter.sql}`,
5448
+ [threadId, ...filter.params]
5233
5449
  );
5234
5450
  return parseInt(result.rows[0].count, 10);
5235
5451
  }
@@ -5238,58 +5454,70 @@ var ThreadMessageQueueStore = class {
5238
5454
  */
5239
5455
  async getThreadsWithPendingMessages() {
5240
5456
  const result = await this.pool.query(
5241
- `SELECT DISTINCT ON (thread_id) tenant_id, assistant_id, thread_id, workspace_id, project_id
5457
+ `SELECT DISTINCT ON (tenant_id, assistant_id, workspace_id, project_id, thread_id) tenant_id, assistant_id, thread_id, workspace_id, project_id
5242
5458
  FROM lattice_thread_message_queue
5243
5459
  WHERE status IN ('pending', 'processing')
5244
- ORDER BY thread_id`
5460
+ ORDER BY tenant_id, assistant_id, workspace_id, project_id, thread_id`
5245
5461
  );
5246
5462
  return result.rows.map((row) => ({
5247
5463
  tenantId: row.tenant_id,
5248
5464
  assistantId: row.assistant_id,
5249
5465
  threadId: row.thread_id,
5250
- workspaceId: row.workspace_id || void 0,
5251
- projectId: row.project_id || void 0
5466
+ workspaceId: row.workspace_id,
5467
+ projectId: row.project_id
5252
5468
  }));
5253
5469
  }
5254
5470
  /**
5255
5471
  * Remove message
5256
5472
  */
5257
- async removeMessage(messageId) {
5473
+ async removeMessage(messageId, scope) {
5474
+ const filter = scopeClause(scope, 2);
5258
5475
  const result = await this.pool.query(
5259
- `DELETE FROM lattice_thread_message_queue WHERE id = $1 RETURNING id`,
5260
- [messageId]
5476
+ `DELETE FROM lattice_thread_message_queue WHERE id = $1${filter.sql} RETURNING id`,
5477
+ [messageId, ...filter.params]
5261
5478
  );
5262
5479
  return (result.rowCount ?? 0) > 0;
5263
5480
  }
5264
5481
  /**
5265
5482
  * Clear all messages for thread
5266
5483
  */
5267
- async clearMessages(threadId) {
5484
+ async clearMessages(threadId, scope) {
5485
+ const filter = scopeClause(scope, 2);
5268
5486
  await this.pool.query(
5269
- `DELETE FROM lattice_thread_message_queue WHERE thread_id = $1`,
5270
- [threadId]
5487
+ `DELETE FROM lattice_thread_message_queue WHERE thread_id = $1${filter.sql}`,
5488
+ [threadId, ...filter.params]
5271
5489
  );
5272
5490
  }
5273
5491
  /**
5274
5492
  * Mark message as processing
5275
5493
  */
5276
- async markProcessing(messageId) {
5494
+ async markProcessing(messageId, customRunConfig, scope) {
5495
+ if (customRunConfig !== void 0) {
5496
+ const filter2 = scopeClause(scope, 3);
5497
+ await this.pool.query(
5498
+ `UPDATE lattice_thread_message_queue SET status = 'processing', custom_run_config = $2 WHERE id = $1${filter2.sql}`,
5499
+ [messageId, JSON.stringify(customRunConfig), ...filter2.params]
5500
+ );
5501
+ return;
5502
+ }
5503
+ const filter = scopeClause(scope, 2);
5277
5504
  await this.pool.query(
5278
- `UPDATE lattice_thread_message_queue SET status = 'processing' WHERE id = $1`,
5279
- [messageId]
5505
+ `UPDATE lattice_thread_message_queue SET status = 'processing' WHERE id = $1${filter.sql}`,
5506
+ [messageId, ...filter.params]
5280
5507
  );
5281
5508
  }
5282
5509
  /**
5283
5510
  * Reset all processing messages to pending state for a thread
5284
5511
  * Returns the number of messages reset
5285
5512
  */
5286
- async resetProcessingToPending(threadId) {
5513
+ async resetProcessingToPending(threadId, scope) {
5514
+ const filter = scopeClause(scope, 2);
5287
5515
  const result = await this.pool.query(
5288
5516
  `UPDATE lattice_thread_message_queue
5289
5517
  SET status = 'pending'
5290
- WHERE thread_id = $1 AND status = 'processing'
5518
+ WHERE thread_id = $1 AND status = 'processing'${filter.sql}
5291
5519
  RETURNING id`,
5292
- [threadId]
5520
+ [threadId, ...filter.params]
5293
5521
  );
5294
5522
  return result.rowCount ?? 0;
5295
5523
  }
@@ -5306,6 +5534,18 @@ var ThreadMessageQueueStore = class {
5306
5534
  };
5307
5535
  }
5308
5536
  };
5537
+ function scopeClause(scope, start) {
5538
+ if (!scope) return { sql: "", params: [] };
5539
+ const params = [];
5540
+ const entries = ["tenantId", "assistantId", "workspaceId", "projectId"].map((key) => [key, scope[key]]);
5541
+ const sql = entries.map(([key, value]) => {
5542
+ const column = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
5543
+ if (value == null) return ` AND ${column} IS NULL`;
5544
+ params.push(value);
5545
+ return ` AND ${column} = $${start + params.length - 1}`;
5546
+ }).join("");
5547
+ return { sql, params };
5548
+ }
5309
5549
 
5310
5550
  // src/stores/ChannelBindingStore.ts
5311
5551
  var import_pg14 = require("pg");
@@ -6056,17 +6296,17 @@ var PostgreSQLA2AApiKeyStore = class {
6056
6296
  const result = await this.pool.query(
6057
6297
  `SELECT * FROM lattice_a2a_api_keys WHERE enabled = true`
6058
6298
  );
6059
- const map = /* @__PURE__ */ new Map();
6299
+ const map2 = /* @__PURE__ */ new Map();
6060
6300
  for (const row of result.rows) {
6061
6301
  const key = (0, import_core5.decrypt)(row.key_value);
6062
- map.set(key, {
6302
+ map2.set(key, {
6063
6303
  key,
6064
6304
  tenantId: row.tenant_id,
6065
6305
  projectId: row.project_id,
6066
6306
  assistantIds: row.assistant_ids ?? void 0
6067
6307
  });
6068
6308
  }
6069
- return map;
6309
+ return map2;
6070
6310
  }
6071
6311
  };
6072
6312
 
@@ -6296,7 +6536,7 @@ var PostgreSQLAgentWebAppStore = class {
6296
6536
 
6297
6537
  // src/stores/PostgreSQLScheduleStorage.ts
6298
6538
  var import_pg18 = require("pg");
6299
- var import_protocols = require("@axiom-lattice/protocols");
6539
+ var import_protocols2 = require("@axiom-lattice/protocols");
6300
6540
 
6301
6541
  // src/migrations/schedule_migrations.ts
6302
6542
  var createScheduledTasksTable = {
@@ -6710,7 +6950,7 @@ var PostgreSQLScheduleStorage = class {
6710
6950
  await this.ensureInitialized();
6711
6951
  const result = await this.pool.query(
6712
6952
  `SELECT * FROM lattice_scheduled_tasks WHERE status IN ($1, $2) ORDER BY created_at ASC`,
6713
- [import_protocols.ScheduledTaskStatus.PENDING, import_protocols.ScheduledTaskStatus.PAUSED]
6953
+ [import_protocols2.ScheduledTaskStatus.PENDING, import_protocols2.ScheduledTaskStatus.PAUSED]
6714
6954
  );
6715
6955
  return result.rows.map((row) => this.mapRowToTask(row));
6716
6956
  }
@@ -6869,9 +7109,9 @@ var PostgreSQLScheduleStorage = class {
6869
7109
  AND updated_at < $4
6870
7110
  `,
6871
7111
  [
6872
- import_protocols.ScheduledTaskStatus.COMPLETED,
6873
- import_protocols.ScheduledTaskStatus.CANCELLED,
6874
- import_protocols.ScheduledTaskStatus.FAILED,
7112
+ import_protocols2.ScheduledTaskStatus.COMPLETED,
7113
+ import_protocols2.ScheduledTaskStatus.CANCELLED,
7114
+ import_protocols2.ScheduledTaskStatus.FAILED,
6875
7115
  cutoff
6876
7116
  ]
6877
7117
  );
@@ -7737,6 +7977,7 @@ var PostgreSQLTaskStore = class {
7737
7977
  };
7738
7978
 
7739
7979
  // src/stores/PostgreSQLTaskWorkItemStore.ts
7980
+ var import_protocols3 = require("@axiom-lattice/protocols");
7740
7981
  var import_uuid4 = require("uuid");
7741
7982
  var PostgreSQLTaskWorkItemStore = class {
7742
7983
  constructor(pool) {
@@ -7828,6 +8069,35 @@ var PostgreSQLTaskWorkItemStore = class {
7828
8069
  const result = await this.pool.query(query, params);
7829
8070
  return result.rows.map((row) => this.rowToItem(row));
7830
8071
  }
8072
+ /** List pending execution results using one bounded PostgreSQL anti-join query. */
8073
+ async listPendingExecutionResults(params) {
8074
+ if (!Number.isSafeInteger(params.limit) || params.limit < 0 || params.limit > import_protocols3.MAX_PENDING_EXECUTION_RESULTS_LIMIT) {
8075
+ const error = new RangeError(`limit must be a safe integer between 0 and ${import_protocols3.MAX_PENDING_EXECUTION_RESULTS_LIMIT}`);
8076
+ error.code = "INVALID_LIMIT";
8077
+ throw error;
8078
+ }
8079
+ if (params.limit === 0) return [];
8080
+ const result = await this.pool.query(
8081
+ `SELECT result.*
8082
+ FROM lattice_task_work_items AS result
8083
+ WHERE result.tenant_id = $1
8084
+ AND result.task_id = $2
8085
+ AND result.action = 'execution_result'
8086
+ AND result.event_key COLLATE "C" ~ '^execution-result:[A-Za-z0-9._:-]+$'
8087
+ AND NOT EXISTS (
8088
+ SELECT 1
8089
+ FROM lattice_task_work_items AS reconciled
8090
+ WHERE reconciled.tenant_id = result.tenant_id
8091
+ AND reconciled.task_id = result.task_id
8092
+ AND reconciled.action = 'execution_reconciled'
8093
+ AND reconciled.detail ->> 'executionResultId' = result.event_key
8094
+ )
8095
+ ORDER BY result.created_at DESC, result.id DESC
8096
+ LIMIT $3`,
8097
+ [params.tenantId, params.taskId, params.limit]
8098
+ );
8099
+ return result.rows.map((row) => this.rowToItem(row));
8100
+ }
7831
8101
  rowToItem(row) {
7832
8102
  return {
7833
8103
  id: row.id,
@@ -8855,10 +9125,268 @@ var addTaskWorkItemEventKeyMigration = {
8855
9125
  `);
8856
9126
  }
8857
9127
  };
9128
+ var addTaskWorkItemPendingIndexesMigration = {
9129
+ version: 171,
9130
+ name: "add_task_work_item_pending_indexes",
9131
+ up: async (client) => {
9132
+ await client.query(`
9133
+ CREATE INDEX IF NOT EXISTS idx_task_work_items_pending_order
9134
+ ON lattice_task_work_items (tenant_id, task_id, action, created_at DESC, id DESC)
9135
+ `);
9136
+ await client.query(`
9137
+ CREATE INDEX IF NOT EXISTS idx_task_work_items_reconciled_result
9138
+ ON lattice_task_work_items (tenant_id, task_id, (detail ->> 'executionResultId'))
9139
+ WHERE action = 'execution_reconciled'
9140
+ `);
9141
+ }
9142
+ };
9143
+
9144
+ // src/migrations/capability_bundle_migration.ts
9145
+ var createCapabilityBundlesTable = {
9146
+ version: 170,
9147
+ name: "create_capability_bundles_table",
9148
+ up: async (client) => {
9149
+ await client.query(`CREATE TABLE IF NOT EXISTS lattice_capability_bundles (
9150
+ id UUID PRIMARY KEY, tenant_id VARCHAR(255) NOT NULL, bundle_key VARCHAR(255) NOT NULL,
9151
+ name VARCHAR(255) NOT NULL, description TEXT, capabilities JSONB NOT NULL DEFAULT '[]'::jsonb,
9152
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
9153
+ UNIQUE (tenant_id, bundle_key)
9154
+ )`);
9155
+ await client.query("CREATE INDEX IF NOT EXISTS idx_lattice_capability_bundles_tenant ON lattice_capability_bundles(tenant_id)");
9156
+ },
9157
+ down: async (client) => {
9158
+ await client.query("DROP INDEX IF EXISTS idx_lattice_capability_bundles_tenant");
9159
+ await client.query("DROP TABLE IF EXISTS lattice_capability_bundles");
9160
+ }
9161
+ };
9162
+
9163
+ // src/stores/PostgreSQLCapabilityBundleStore.ts
9164
+ var import_crypto4 = require("crypto");
9165
+ var import_pg24 = require("pg");
9166
+ var duplicateMessage = "Capability bundle key already exists for tenant";
9167
+ function map(row) {
9168
+ return {
9169
+ id: row.id,
9170
+ tenantId: row.tenant_id,
9171
+ key: row.bundle_key,
9172
+ name: row.name,
9173
+ description: row.description ?? void 0,
9174
+ capabilities: row.capabilities,
9175
+ createdAt: row.created_at.toISOString(),
9176
+ updatedAt: typeof row.updated_at === "string" ? row.updated_at : row.updated_at.toISOString()
9177
+ };
9178
+ }
9179
+ function isDuplicate(error) {
9180
+ return typeof error === "object" && error !== null && "code" in error && error.code === "23505";
9181
+ }
9182
+ var PostgreSQLCapabilityBundleStore = class {
9183
+ /**
9184
+ * Creates a PostgreSQL capability bundle store.
9185
+ *
9186
+ * @param options - Pool ownership, connection, and migration options.
9187
+ */
9188
+ constructor(options) {
9189
+ this.initialized = false;
9190
+ this.ownsPool = true;
9191
+ this.initPromise = null;
9192
+ if (options.pool) {
9193
+ this.pool = options.pool;
9194
+ this.ownsPool = false;
9195
+ this.initialized = true;
9196
+ return;
9197
+ }
9198
+ this.pool = typeof options.poolConfig === "string" ? new import_pg24.Pool({ connectionString: options.poolConfig }) : options.poolConfig ? new import_pg24.Pool(options.poolConfig) : (() => {
9199
+ throw new Error("Either pool or poolConfig must be provided");
9200
+ })();
9201
+ this.migrationManager = new MigrationManager(this.pool);
9202
+ this.migrationManager.register(createCapabilityBundlesTable);
9203
+ if (options.autoMigrate !== false) {
9204
+ this.startInitialization();
9205
+ }
9206
+ }
9207
+ /**
9208
+ * Applies pending migrations for an internally managed pool.
9209
+ *
9210
+ * @returns A shared promise that resolves when initialization completes.
9211
+ */
9212
+ async initialize() {
9213
+ if (this.initialized) return;
9214
+ if (this.initPromise) return this.initPromise;
9215
+ return this.startInitialization();
9216
+ }
9217
+ startInitialization() {
9218
+ this.initPromise = this.migrationManager.migrate().then(() => {
9219
+ this.initialized = true;
9220
+ });
9221
+ void this.initPromise.catch(() => void 0);
9222
+ return this.initPromise;
9223
+ }
9224
+ /**
9225
+ * Closes the pool when it was created by this store.
9226
+ *
9227
+ * @returns A promise that resolves after owned resources are released.
9228
+ */
9229
+ async dispose() {
9230
+ if (this.ownsPool) await this.pool.end();
9231
+ }
9232
+ async ready() {
9233
+ if (!this.initialized) await this.initialize();
9234
+ }
9235
+ async listByTenant(tenantId) {
9236
+ await this.ready();
9237
+ const result = await this.pool.query(
9238
+ "SELECT id, tenant_id, bundle_key, name, description, capabilities, created_at, updated_at::text AS updated_at FROM lattice_capability_bundles WHERE tenant_id = $1 ORDER BY created_at",
9239
+ [tenantId]
9240
+ );
9241
+ return result.rows.map(map);
9242
+ }
9243
+ async getById(tenantId, id) {
9244
+ await this.ready();
9245
+ const result = await this.pool.query(
9246
+ "SELECT id, tenant_id, bundle_key, name, description, capabilities, created_at, updated_at::text AS updated_at FROM lattice_capability_bundles WHERE tenant_id = $1 AND id = $2",
9247
+ [tenantId, id]
9248
+ );
9249
+ return result.rows[0] ? map(result.rows[0]) : null;
9250
+ }
9251
+ async getManyByIds(tenantId, ids) {
9252
+ await this.ready();
9253
+ if (ids.length === 0) return [];
9254
+ const result = await this.pool.query(
9255
+ "SELECT id, tenant_id, bundle_key, name, description, capabilities, created_at, updated_at::text AS updated_at FROM lattice_capability_bundles WHERE tenant_id = $1 AND id = ANY($2::uuid[])",
9256
+ [tenantId, ids]
9257
+ );
9258
+ return result.rows.map(map);
9259
+ }
9260
+ async create(tenantId, input) {
9261
+ await this.ready();
9262
+ try {
9263
+ const result = await this.pool.query(
9264
+ `INSERT INTO lattice_capability_bundles
9265
+ (id, tenant_id, bundle_key, name, description, capabilities)
9266
+ VALUES ($1, $2, $3, $4, $5, $6::jsonb)
9267
+ RETURNING id, tenant_id, bundle_key, name, description, capabilities, created_at, updated_at::text AS updated_at`,
9268
+ [
9269
+ (0, import_crypto4.randomUUID)(),
9270
+ tenantId,
9271
+ input.key,
9272
+ input.name,
9273
+ input.description ?? null,
9274
+ JSON.stringify(input.capabilities)
9275
+ ]
9276
+ );
9277
+ return map(result.rows[0]);
9278
+ } catch (error) {
9279
+ if (isDuplicate(error)) throw new Error(duplicateMessage);
9280
+ throw error;
9281
+ }
9282
+ }
9283
+ async update(tenantId, id, input) {
9284
+ await this.ready();
9285
+ const fields = [];
9286
+ const values = [];
9287
+ const add = (field, value) => {
9288
+ values.push(value);
9289
+ fields.push(`${field} = $${values.length}`);
9290
+ };
9291
+ if (input.name !== void 0) add("name", input.name);
9292
+ if (Object.prototype.hasOwnProperty.call(input, "description")) {
9293
+ add("description", input.description ?? null);
9294
+ }
9295
+ if (input.capabilities !== void 0) {
9296
+ add("capabilities", JSON.stringify(input.capabilities));
9297
+ }
9298
+ if (fields.length === 0) {
9299
+ const expectedUpdatedAt2 = input.expectedUpdatedAt;
9300
+ const result = await this.pool.query(
9301
+ `SELECT id, tenant_id, bundle_key, name, description, capabilities, created_at, updated_at::text AS updated_at
9302
+ FROM lattice_capability_bundles
9303
+ WHERE tenant_id = $1 AND id = $2${expectedUpdatedAt2 === void 0 ? "" : " AND updated_at::text = $3"}`,
9304
+ expectedUpdatedAt2 === void 0 ? [tenantId, id] : [tenantId, id, expectedUpdatedAt2]
9305
+ );
9306
+ if (result.rows[0]) return map(result.rows[0]);
9307
+ return expectedUpdatedAt2 === void 0 ? null : { status: "conflict" };
9308
+ }
9309
+ const expectedUpdatedAt = input.expectedUpdatedAt;
9310
+ values.push(tenantId, id);
9311
+ if (expectedUpdatedAt !== void 0) values.push(expectedUpdatedAt);
9312
+ const tenantParam = values.length - (expectedUpdatedAt === void 0 ? 1 : 2);
9313
+ const idParam = tenantParam + 1;
9314
+ const revisionPredicate = expectedUpdatedAt === void 0 ? "" : ` AND updated_at::text = $${values.length}`;
9315
+ try {
9316
+ const result = await this.pool.query(
9317
+ `UPDATE lattice_capability_bundles
9318
+ SET ${fields.join(", ")}, updated_at = GREATEST(updated_at + interval '1 microsecond', clock_timestamp())
9319
+ WHERE tenant_id = $${tenantParam} AND id = $${idParam}${revisionPredicate}
9320
+ RETURNING id, tenant_id, bundle_key, name, description, capabilities, created_at, updated_at::text AS updated_at`,
9321
+ values
9322
+ );
9323
+ if (result.rows[0]) return map(result.rows[0]);
9324
+ return expectedUpdatedAt === void 0 ? null : { status: "conflict" };
9325
+ } catch (error) {
9326
+ if (isDuplicate(error)) throw new Error(duplicateMessage);
9327
+ throw error;
9328
+ }
9329
+ }
9330
+ async deleteIfUnreferenced(tenantId, id) {
9331
+ await this.ready();
9332
+ const client = await this.pool.connect();
9333
+ try {
9334
+ await client.query("BEGIN");
9335
+ await client.query(
9336
+ "SELECT pg_advisory_xact_lock(hashtextextended($1 || ':project-mutations', 0))",
9337
+ [tenantId]
9338
+ );
9339
+ const projectIds = await client.query(
9340
+ `SELECT id FROM lattice_projects
9341
+ WHERE tenant_id = $1
9342
+ ORDER BY id`,
9343
+ [tenantId]
9344
+ );
9345
+ if (projectIds.rows.length > 0) {
9346
+ await client.query(
9347
+ `SELECT pg_advisory_xact_lock(hashtextextended($1 || ':project:' || project_id, 0))
9348
+ FROM unnest($2::text[]) AS project_id
9349
+ ORDER BY project_id`,
9350
+ [tenantId, projectIds.rows.map((project) => project.id)]
9351
+ );
9352
+ }
9353
+ await client.query(
9354
+ `SELECT id FROM lattice_projects
9355
+ WHERE tenant_id = $1
9356
+ FOR UPDATE`,
9357
+ [tenantId]
9358
+ );
9359
+ await client.query("SELECT pg_advisory_xact_lock(hashtextextended($1 || ':' || $2, 0))", [tenantId, id]);
9360
+ const referenced = await client.query(
9361
+ `SELECT 1 FROM lattice_projects
9362
+ WHERE tenant_id = $1
9363
+ AND jsonb_typeof(config->'capabilityBundleIds') = 'array'
9364
+ AND COALESCE(config->'capabilityBundleIds', '[]'::jsonb) ? $2
9365
+ LIMIT 1`,
9366
+ [tenantId, id]
9367
+ );
9368
+ if (referenced.rows.length > 0) {
9369
+ await client.query("COMMIT");
9370
+ return "in_use";
9371
+ }
9372
+ const deleted = await client.query(
9373
+ "DELETE FROM lattice_capability_bundles WHERE tenant_id = $1 AND id = $2 RETURNING id",
9374
+ [tenantId, id]
9375
+ );
9376
+ await client.query("COMMIT");
9377
+ return deleted.rows.length > 0 ? "deleted" : "not_found";
9378
+ } catch (error) {
9379
+ await client.query("ROLLBACK");
9380
+ throw error;
9381
+ } finally {
9382
+ client.release();
9383
+ }
9384
+ }
9385
+ };
8858
9386
 
8859
9387
  // src/createPgStoreConfig.ts
8860
9388
  async function createPgStoreConfig(connectionString) {
8861
- const pool = new import_pg24.Pool({ connectionString });
9389
+ const pool = new import_pg25.Pool({ connectionString });
8862
9390
  const mm = new MigrationManager(pool);
8863
9391
  mm.register(createThreadsTable);
8864
9392
  mm.register(createScheduledTasksTable);
@@ -8913,6 +9441,8 @@ async function createPgStoreConfig(connectionString) {
8913
9441
  mm.register(addA2AKeyAssistantIds);
8914
9442
  mm.register(addTaskWorkItemEventKeyMigration);
8915
9443
  mm.register(createAgentWebAppsTable);
9444
+ mm.register(createCapabilityBundlesTable);
9445
+ mm.register(addTaskWorkItemPendingIndexesMigration);
8916
9446
  await mm.migrate();
8917
9447
  const checkpoint = import_langgraph_checkpoint_postgres.PostgresSaver.fromConnString(connectionString);
8918
9448
  checkpoint.setup().catch((err) => {
@@ -8941,6 +9471,7 @@ async function createPgStoreConfig(connectionString) {
8941
9471
  taskWorkItem: taskWorkItemStore,
8942
9472
  a2aApiKey: new PostgreSQLA2AApiKeyStore(opts),
8943
9473
  agentWebApp: new PostgreSQLAgentWebAppStore(opts),
9474
+ capabilityBundle: new PostgreSQLCapabilityBundleStore(opts),
8944
9475
  schedule: new PostgreSQLScheduleStorage(opts),
8945
9476
  menu: new MenuStore(opts),
8946
9477
  sharedResource: new PostgresSharedResourceStore(opts),
@@ -8951,7 +9482,7 @@ async function createPgStoreConfig(connectionString) {
8951
9482
  }
8952
9483
 
8953
9484
  // src/stores/PostgreSQLSkillStore.ts
8954
- var import_pg25 = require("pg");
9485
+ var import_pg26 = require("pg");
8955
9486
  var PostgreSQLSkillStore = class {
8956
9487
  constructor(options) {
8957
9488
  this.initialized = false;
@@ -8964,9 +9495,9 @@ var PostgreSQLSkillStore = class {
8964
9495
  return;
8965
9496
  }
8966
9497
  if (typeof options.poolConfig === "string") {
8967
- this.pool = new import_pg25.Pool({ connectionString: options.poolConfig });
9498
+ this.pool = new import_pg26.Pool({ connectionString: options.poolConfig });
8968
9499
  } else if (options.poolConfig) {
8969
- this.pool = new import_pg25.Pool(options.poolConfig);
9500
+ this.pool = new import_pg26.Pool(options.poolConfig);
8970
9501
  } else {
8971
9502
  throw new Error("Either pool or poolConfig must be provided");
8972
9503
  }
@@ -9267,7 +9798,7 @@ var PostgreSQLSkillStore = class {
9267
9798
  };
9268
9799
 
9269
9800
  // src/stores/ChannelIdentityMappingStore.ts
9270
- var import_pg26 = require("pg");
9801
+ var import_pg27 = require("pg");
9271
9802
  var ChannelIdentityMappingStore = class {
9272
9803
  constructor(options) {
9273
9804
  this.initialized = false;
@@ -9279,7 +9810,7 @@ var ChannelIdentityMappingStore = class {
9279
9810
  this.initialized = true;
9280
9811
  return;
9281
9812
  }
9282
- this.pool = typeof options.poolConfig === "string" ? new import_pg26.Pool({ connectionString: options.poolConfig }) : options.poolConfig ? new import_pg26.Pool(options.poolConfig) : (() => {
9813
+ this.pool = typeof options.poolConfig === "string" ? new import_pg27.Pool({ connectionString: options.poolConfig }) : options.poolConfig ? new import_pg27.Pool(options.poolConfig) : (() => {
9283
9814
  throw new Error("Either pool or poolConfig must be provided");
9284
9815
  })();
9285
9816
  this.migrationManager = new MigrationManager(this.pool);
@@ -9508,6 +10039,7 @@ function mapRowToChannelIdentityMapping(row) {
9508
10039
  PostgreSQLA2AApiKeyStore,
9509
10040
  PostgreSQLAgentWebAppStore,
9510
10041
  PostgreSQLAssistantStore,
10042
+ PostgreSQLCapabilityBundleStore,
9511
10043
  PostgreSQLChannelInstallationStore,
9512
10044
  PostgreSQLCollectionStore,
9513
10045
  PostgreSQLConnectionStore,
@@ -9546,6 +10078,7 @@ function mapRowToChannelIdentityMapping(row) {
9546
10078
  createA2AApiKeysTable,
9547
10079
  createAgentWebAppsTable,
9548
10080
  createAssistantsTable,
10081
+ createCapabilityBundlesTable,
9549
10082
  createChannelBindingsTable,
9550
10083
  createChannelIdentityMappingTables,
9551
10084
  createChannelInstallationsTable,