@axiom-lattice/pg-stores 1.0.70 → 1.0.72

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
@@ -32,8 +32,9 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ChannelBindingStore: () => ChannelBindingStore,
34
34
  ChannelIdentityMappingStore: () => ChannelIdentityMappingStore,
35
+ MenuStore: () => MenuStore,
35
36
  MigrationManager: () => MigrationManager,
36
- Pool: () => import_pg20.Pool,
37
+ Pool: () => import_pg22.Pool,
37
38
  PostgreSQLA2AApiKeyStore: () => PostgreSQLA2AApiKeyStore,
38
39
  PostgreSQLAssistantStore: () => PostgreSQLAssistantStore,
39
40
  PostgreSQLChannelInstallationStore: () => PostgreSQLChannelInstallationStore,
@@ -55,6 +56,7 @@ __export(index_exports, {
55
56
  addProjectConfigColumn: () => addProjectConfigColumn,
56
57
  addScheduleTenantId: () => addScheduleTenantId,
57
58
  addSkillTenantId: () => addSkillTenantId,
59
+ addStepThreadId: () => addStepThreadId,
58
60
  addThreadTenantId: () => addThreadTenantId,
59
61
  alterChannelInstallationsTable: () => alterChannelInstallationsTable,
60
62
  changeAssistantPrimaryKey: () => changeAssistantPrimaryKey,
@@ -72,6 +74,7 @@ __export(index_exports, {
72
74
  createEvalRunsTable: () => createEvalRunsTable,
73
75
  createEvalSuitesTable: () => createEvalSuitesTable,
74
76
  createMcpServerConfigsTable: () => createMcpServerConfigsTable,
77
+ createMenuItemsTable: () => createMenuItemsTable,
75
78
  createMetricsConfigsTable: () => createMetricsConfigsTable,
76
79
  createPgStoreConfig: () => createPgStoreConfig,
77
80
  createProjectsTable: () => createProjectsTable,
@@ -86,7 +89,7 @@ __export(index_exports, {
86
89
  evalMigrations: () => evalMigrations
87
90
  });
88
91
  module.exports = __toCommonJS(index_exports);
89
- var import_pg20 = require("pg");
92
+ var import_pg22 = require("pg");
90
93
 
91
94
  // src/stores/PostgreSQLThreadStore.ts
92
95
  var import_pg = require("pg");
@@ -690,6 +693,30 @@ var changeAssistantPrimaryKey = {
690
693
  }
691
694
  };
692
695
 
696
+ // src/migrations/assistant_owner_user_migration.ts
697
+ var addAssistantOwnerUserId = {
698
+ version: 132,
699
+ name: "add_assistant_owner_user_id",
700
+ up: async (client) => {
701
+ await client.query(`
702
+ ALTER TABLE lattice_assistants
703
+ ADD COLUMN IF NOT EXISTS owner_user_id VARCHAR(255)
704
+ `);
705
+ await client.query(`
706
+ CREATE INDEX IF NOT EXISTS idx_lattice_assistants_owner_user_id
707
+ ON lattice_assistants(owner_user_id)
708
+ `);
709
+ },
710
+ down: async (client) => {
711
+ await client.query(
712
+ "DROP INDEX IF EXISTS idx_lattice_assistants_owner_user_id"
713
+ );
714
+ await client.query(
715
+ "ALTER TABLE lattice_assistants DROP COLUMN IF EXISTS owner_user_id"
716
+ );
717
+ }
718
+ };
719
+
693
720
  // src/stores/PostgreSQLAssistantStore.ts
694
721
  var PostgreSQLAssistantStore = class {
695
722
  constructor(options) {
@@ -705,6 +732,7 @@ var PostgreSQLAssistantStore = class {
705
732
  this.migrationManager.register(createAssistantsTable);
706
733
  this.migrationManager.register(addAssistantTenantId);
707
734
  this.migrationManager.register(changeAssistantPrimaryKey);
735
+ this.migrationManager.register(addAssistantOwnerUserId);
708
736
  if (options.autoMigrate !== false) {
709
737
  this.initialize().catch((error) => {
710
738
  console.error("Failed to initialize PostgreSQLAssistantStore:", error);
@@ -740,7 +768,7 @@ var PostgreSQLAssistantStore = class {
740
768
  await this.ensureInitialized();
741
769
  const result = await this.pool.query(
742
770
  `
743
- SELECT id, tenant_id, name, description, graph_definition, created_at, updated_at
771
+ SELECT id, tenant_id, name, description, graph_definition, owner_user_id, created_at, updated_at
744
772
  FROM lattice_assistants
745
773
  WHERE tenant_id = $1
746
774
  ORDER BY created_at DESC
@@ -756,7 +784,7 @@ var PostgreSQLAssistantStore = class {
756
784
  await this.ensureInitialized();
757
785
  const result = await this.pool.query(
758
786
  `
759
- SELECT id, tenant_id, name, description, graph_definition, created_at, updated_at
787
+ SELECT id, tenant_id, name, description, graph_definition, owner_user_id, created_at, updated_at
760
788
  FROM lattice_assistants
761
789
  WHERE tenant_id = $1 AND id = $2
762
790
  `,
@@ -775,12 +803,13 @@ var PostgreSQLAssistantStore = class {
775
803
  const now = /* @__PURE__ */ new Date();
776
804
  await this.pool.query(
777
805
  `
778
- INSERT INTO lattice_assistants (id, tenant_id, name, description, graph_definition, created_at, updated_at)
779
- VALUES ($1, $2, $3, $4, $5, $6, $7)
806
+ INSERT INTO lattice_assistants (id, tenant_id, name, description, graph_definition, owner_user_id, created_at, updated_at)
807
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
780
808
  ON CONFLICT (id, tenant_id) DO UPDATE SET
781
809
  name = EXCLUDED.name,
782
810
  description = EXCLUDED.description,
783
811
  graph_definition = EXCLUDED.graph_definition,
812
+ owner_user_id = EXCLUDED.owner_user_id,
784
813
  updated_at = EXCLUDED.updated_at
785
814
  `,
786
815
  [
@@ -789,6 +818,7 @@ var PostgreSQLAssistantStore = class {
789
818
  data.name,
790
819
  data.description || null,
791
820
  JSON.stringify(data.graphDefinition),
821
+ data.ownerUserId || null,
792
822
  now,
793
823
  now
794
824
  ]
@@ -799,6 +829,7 @@ var PostgreSQLAssistantStore = class {
799
829
  name: data.name,
800
830
  description: data.description,
801
831
  graphDefinition: data.graphDefinition,
832
+ ownerUserId: data.ownerUserId,
802
833
  createdAt: now,
803
834
  updatedAt: now
804
835
  };
@@ -827,6 +858,10 @@ var PostgreSQLAssistantStore = class {
827
858
  updateFields.push(`graph_definition = $${paramIndex++}`);
828
859
  updateValues.push(JSON.stringify(updates.graphDefinition));
829
860
  }
861
+ if (updates.ownerUserId !== void 0) {
862
+ updateFields.push(`owner_user_id = $${paramIndex++}`);
863
+ updateValues.push(updates.ownerUserId || null);
864
+ }
830
865
  if (updateFields.length === 0) {
831
866
  return existing;
832
867
  }
@@ -873,6 +908,23 @@ var PostgreSQLAssistantStore = class {
873
908
  );
874
909
  return result.rows.length > 0;
875
910
  }
911
+ /**
912
+ * Get assistant by owner user ID
913
+ */
914
+ async getByOwner(tenantId, userId) {
915
+ await this.ensureInitialized();
916
+ const result = await this.pool.query(
917
+ `
918
+ SELECT id, tenant_id, name, description, graph_definition, owner_user_id, created_at, updated_at
919
+ FROM lattice_assistants
920
+ WHERE tenant_id = $1 AND owner_user_id = $2
921
+ LIMIT 1
922
+ `,
923
+ [tenantId, userId]
924
+ );
925
+ if (result.rows.length === 0) return null;
926
+ return this.mapRowToAssistant(result.rows[0]);
927
+ }
876
928
  /**
877
929
  * Dispose resources and close the connection pool
878
930
  * Should be called when the store is no longer needed
@@ -900,6 +952,7 @@ var PostgreSQLAssistantStore = class {
900
952
  name: row.name,
901
953
  description: row.description || void 0,
902
954
  graphDefinition: typeof row.graph_definition === "string" ? JSON.parse(row.graph_definition) : row.graph_definition,
955
+ ownerUserId: row.owner_user_id || void 0,
903
956
  createdAt: row.created_at,
904
957
  updatedAt: row.updated_at
905
958
  };
@@ -3096,6 +3149,22 @@ var createWorkflowTrackingTables = {
3096
3149
  `);
3097
3150
  }
3098
3151
  };
3152
+ var addStepThreadId = {
3153
+ name: "add_step_thread_id",
3154
+ version: 113,
3155
+ up: async (client) => {
3156
+ await client.query(`
3157
+ ALTER TABLE lattice_workflow_steps
3158
+ ADD COLUMN IF NOT EXISTS thread_id VARCHAR(255);
3159
+ `);
3160
+ },
3161
+ down: async (client) => {
3162
+ await client.query(`
3163
+ ALTER TABLE lattice_workflow_steps
3164
+ DROP COLUMN IF EXISTS thread_id;
3165
+ `);
3166
+ }
3167
+ };
3099
3168
 
3100
3169
  // src/stores/PostgreSQLWorkflowTrackingStore.ts
3101
3170
  var PostgreSQLWorkflowTrackingStore = class {
@@ -3109,6 +3178,7 @@ var PostgreSQLWorkflowTrackingStore = class {
3109
3178
  }
3110
3179
  this.migrationManager = new MigrationManager(this.pool);
3111
3180
  this.migrationManager.register(createWorkflowTrackingTables);
3181
+ this.migrationManager.register(addStepThreadId);
3112
3182
  if (options.autoMigrate !== false) {
3113
3183
  this.initialize().catch((error) => {
3114
3184
  console.error("Failed to initialize PostgreSQLWorkflowTrackingStore:", error);
@@ -3241,8 +3311,8 @@ var PostgreSQLWorkflowTrackingStore = class {
3241
3311
  const now = /* @__PURE__ */ new Date();
3242
3312
  const id = `step_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
3243
3313
  await this.pool.query(
3244
- `INSERT INTO lattice_workflow_steps (id, run_id, tenant_id, step_type, step_name, edge_from, edge_to, edge_purpose, input, status, started_at, created_at, updated_at)
3245
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`,
3314
+ `INSERT INTO lattice_workflow_steps (id, run_id, tenant_id, step_type, step_name, edge_from, edge_to, edge_purpose, input, thread_id, status, started_at, created_at, updated_at)
3315
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`,
3246
3316
  [
3247
3317
  id,
3248
3318
  request.runId,
@@ -3253,6 +3323,7 @@ var PostgreSQLWorkflowTrackingStore = class {
3253
3323
  request.edgeTo || null,
3254
3324
  request.edgePurpose || null,
3255
3325
  request.input ? JSON.stringify(request.input) : null,
3326
+ request.threadId || null,
3256
3327
  "running",
3257
3328
  now,
3258
3329
  now,
@@ -3265,6 +3336,7 @@ var PostgreSQLWorkflowTrackingStore = class {
3265
3336
  tenantId: request.tenantId,
3266
3337
  stepType: request.stepType,
3267
3338
  stepName: request.stepName,
3339
+ threadId: request.threadId,
3268
3340
  edgeFrom: request.edgeFrom,
3269
3341
  edgeTo: request.edgeTo,
3270
3342
  edgePurpose: request.edgePurpose,
@@ -3275,6 +3347,25 @@ var PostgreSQLWorkflowTrackingStore = class {
3275
3347
  updatedAt: now
3276
3348
  };
3277
3349
  }
3350
+ async upsertRunStep(request) {
3351
+ await this.ensureInitialized();
3352
+ const result = await this.pool.query(
3353
+ `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND step_type = $2 AND step_name = $3`,
3354
+ [request.runId, request.stepType, request.stepName]
3355
+ );
3356
+ if (result.rows.length > 0) {
3357
+ const existing = this.mapRowToRunStep(result.rows[0]);
3358
+ if (!existing.threadId && request.threadId) {
3359
+ await this.pool.query(
3360
+ `UPDATE lattice_workflow_steps SET thread_id = $1, updated_at = $2 WHERE run_id = $3 AND id = $4`,
3361
+ [request.threadId, /* @__PURE__ */ new Date(), request.runId, existing.id]
3362
+ );
3363
+ existing.threadId = request.threadId;
3364
+ }
3365
+ return existing;
3366
+ }
3367
+ return this.createRunStep(request);
3368
+ }
3278
3369
  async updateRunStep(runId, stepId, updates) {
3279
3370
  await this.ensureInitialized();
3280
3371
  const now = /* @__PURE__ */ new Date();
@@ -3359,6 +3450,7 @@ var PostgreSQLWorkflowTrackingStore = class {
3359
3450
  tenantId: row.tenant_id,
3360
3451
  stepType: row.step_type,
3361
3452
  stepName: row.step_name,
3453
+ threadId: row.thread_id,
3362
3454
  edgeFrom: row.edge_from,
3363
3455
  edgeTo: row.edge_to,
3364
3456
  edgePurpose: row.edge_purpose,
@@ -4411,6 +4503,30 @@ var alterMessageQueueIdColumn = {
4411
4503
  }
4412
4504
  };
4413
4505
 
4506
+ // src/migrations/add_workspace_project_to_queue.ts
4507
+ var addWorkspaceProjectToQueue = {
4508
+ version: 131,
4509
+ name: "add_workspace_project_to_queue",
4510
+ up: async (client) => {
4511
+ await client.query(`
4512
+ ALTER TABLE lattice_thread_message_queue
4513
+ ADD COLUMN IF NOT EXISTS workspace_id VARCHAR(255)
4514
+ `);
4515
+ await client.query(`
4516
+ ALTER TABLE lattice_thread_message_queue
4517
+ ADD COLUMN IF NOT EXISTS project_id VARCHAR(255)
4518
+ `);
4519
+ },
4520
+ down: async (client) => {
4521
+ await client.query(
4522
+ "ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS workspace_id"
4523
+ );
4524
+ await client.query(
4525
+ "ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS project_id"
4526
+ );
4527
+ }
4528
+ };
4529
+
4414
4530
  // src/stores/ThreadMessageQueueStore.ts
4415
4531
  var ThreadMessageQueueStore = class {
4416
4532
  constructor(options) {
@@ -4427,6 +4543,7 @@ var ThreadMessageQueueStore = class {
4427
4543
  this.migrationManager.register(addPriorityAndCommandColumns);
4428
4544
  this.migrationManager.register(addCustomRunConfigColumn);
4429
4545
  this.migrationManager.register(alterMessageQueueIdColumn);
4546
+ this.migrationManager.register(addWorkspaceProjectToQueue);
4430
4547
  if (options.autoMigrate !== false) {
4431
4548
  this.initialize().catch((error) => {
4432
4549
  console.error("Failed to initialize ThreadMessageQueueStore:", error);
@@ -4456,7 +4573,7 @@ var ThreadMessageQueueStore = class {
4456
4573
  * Add message to queue
4457
4574
  */
4458
4575
  async addMessage(params) {
4459
- const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
4576
+ const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
4460
4577
  const seqResult = await this.pool.query(
4461
4578
  `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq
4462
4579
  FROM lattice_thread_message_queue
@@ -4466,10 +4583,10 @@ var ThreadMessageQueueStore = class {
4466
4583
  const nextSeq = seqResult.rows[0].next_seq;
4467
4584
  const result = await this.pool.query(
4468
4585
  `INSERT INTO lattice_thread_message_queue
4469
- (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
4470
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
4586
+ (id, thread_id, tenant_id, assistant_id, workspace_id, project_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
4587
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
4471
4588
  RETURNING *`,
4472
- [id || import_crypto.default.randomUUID(), threadId, tenantId, assistantId, JSON.stringify(content), type, nextSeq, priority, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]
4589
+ [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]
4473
4590
  );
4474
4591
  return this.rowToMessage(result.rows[0]);
4475
4592
  }
@@ -4478,7 +4595,7 @@ var ThreadMessageQueueStore = class {
4478
4595
  * Uses priority=100 to ensure message is processed first
4479
4596
  */
4480
4597
  async addMessageAtHead(params) {
4481
- const { threadId, tenantId, assistantId, content, type = "human", command, custom_run_config, id } = params;
4598
+ const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "human", command, custom_run_config, id } = params;
4482
4599
  const resolvedTenantId = tenantId;
4483
4600
  const resolvedAssistantId = assistantId;
4484
4601
  const seqResult = await this.pool.query(
@@ -4490,10 +4607,10 @@ var ThreadMessageQueueStore = class {
4490
4607
  const nextSeq = seqResult.rows[0].next_seq;
4491
4608
  const result = await this.pool.query(
4492
4609
  `INSERT INTO lattice_thread_message_queue
4493
- (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
4494
- VALUES ($1, $2, $3, $4, $5, $6, $7, 100, $8, $9)
4610
+ (id, thread_id, tenant_id, assistant_id, workspace_id, project_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
4611
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, 100, $10, $11)
4495
4612
  RETURNING *`,
4496
- [id || import_crypto.default.randomUUID(), threadId, resolvedTenantId, resolvedAssistantId, JSON.stringify(content), type, nextSeq, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]
4613
+ [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]
4497
4614
  );
4498
4615
  return this.rowToMessage(result.rows[0]);
4499
4616
  }
@@ -4537,7 +4654,7 @@ var ThreadMessageQueueStore = class {
4537
4654
  */
4538
4655
  async getThreadsWithPendingMessages() {
4539
4656
  const result = await this.pool.query(
4540
- `SELECT DISTINCT tenant_id, assistant_id, thread_id
4657
+ `SELECT DISTINCT ON (thread_id) tenant_id, assistant_id, thread_id, workspace_id, project_id
4541
4658
  FROM lattice_thread_message_queue
4542
4659
  WHERE status IN ('pending', 'processing')
4543
4660
  ORDER BY thread_id`
@@ -4545,7 +4662,9 @@ var ThreadMessageQueueStore = class {
4545
4662
  return result.rows.map((row) => ({
4546
4663
  tenantId: row.tenant_id,
4547
4664
  assistantId: row.assistant_id,
4548
- threadId: row.thread_id
4665
+ threadId: row.thread_id,
4666
+ workspaceId: row.workspace_id || void 0,
4667
+ projectId: row.project_id || void 0
4549
4668
  }));
4550
4669
  }
4551
4670
  /**
@@ -4972,6 +5091,25 @@ var PostgreSQLChannelInstallationStore = class {
4972
5091
  );
4973
5092
  return result.rows.map((row) => this.mapRowToInstallation(row));
4974
5093
  }
5094
+ async getAllInstallations(channel) {
5095
+ await this.ensureInitialized();
5096
+ const result = channel ? await this.pool.query(
5097
+ `
5098
+ SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at
5099
+ FROM lattice_channel_installations
5100
+ WHERE channel = $1
5101
+ ORDER BY created_at DESC
5102
+ `,
5103
+ [channel]
5104
+ ) : await this.pool.query(
5105
+ `
5106
+ SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at
5107
+ FROM lattice_channel_installations
5108
+ ORDER BY created_at DESC
5109
+ `
5110
+ );
5111
+ return result.rows.map((row) => this.mapRowToInstallation(row));
5112
+ }
4975
5113
  async createInstallation(tenantId, installationId, data) {
4976
5114
  await this.ensureInitialized();
4977
5115
  const now = /* @__PURE__ */ new Date();
@@ -5885,33 +6023,501 @@ var PostgreSQLScheduleStorage = class {
5885
6023
  }
5886
6024
  };
5887
6025
 
6026
+ // src/stores/PostgreSQLTaskStore.ts
6027
+ var import_pg18 = require("pg");
6028
+
6029
+ // src/migrations/task_migration.ts
6030
+ var createTasksTable = {
6031
+ version: 133,
6032
+ name: "create_lattice_tasks_table",
6033
+ up: async (client) => {
6034
+ await client.query(`
6035
+ CREATE TABLE IF NOT EXISTS lattice_tasks (
6036
+ id VARCHAR(255) PRIMARY KEY,
6037
+ tenant_id VARCHAR(255) NOT NULL,
6038
+ owner_type VARCHAR(10) NOT NULL DEFAULT 'user',
6039
+ owner_id VARCHAR(255) NOT NULL,
6040
+ title VARCHAR(500) NOT NULL,
6041
+ description TEXT,
6042
+ status VARCHAR(20) NOT NULL DEFAULT 'pending',
6043
+ priority VARCHAR(10) NOT NULL DEFAULT 'medium',
6044
+ due_date VARCHAR(50),
6045
+ metadata JSONB,
6046
+ parent_id VARCHAR(255),
6047
+ source_id VARCHAR(255),
6048
+ context JSONB,
6049
+ created_at VARCHAR(50) NOT NULL,
6050
+ updated_at VARCHAR(50) NOT NULL
6051
+ )
6052
+ `);
6053
+ await client.query(`
6054
+ CREATE INDEX IF NOT EXISTS idx_lattice_tasks_tenant_id
6055
+ ON lattice_tasks(tenant_id)
6056
+ `);
6057
+ await client.query(`
6058
+ CREATE INDEX IF NOT EXISTS idx_lattice_tasks_owner
6059
+ ON lattice_tasks(tenant_id, owner_type, owner_id)
6060
+ `);
6061
+ await client.query(`
6062
+ CREATE INDEX IF NOT EXISTS idx_lattice_tasks_status
6063
+ ON lattice_tasks(tenant_id, status)
6064
+ `);
6065
+ await client.query(`
6066
+ CREATE INDEX IF NOT EXISTS idx_lattice_tasks_parent_id
6067
+ ON lattice_tasks(tenant_id, parent_id)
6068
+ `);
6069
+ },
6070
+ down: async (client) => {
6071
+ await client.query("DROP TABLE IF EXISTS lattice_tasks");
6072
+ }
6073
+ };
6074
+
6075
+ // src/stores/PostgreSQLTaskStore.ts
6076
+ var import_uuid2 = require("uuid");
6077
+ function mapRowToTask(row) {
6078
+ return {
6079
+ id: row.id,
6080
+ tenantId: row.tenant_id,
6081
+ ownerType: row.owner_type,
6082
+ ownerId: row.owner_id,
6083
+ title: row.title,
6084
+ description: row.description ?? void 0,
6085
+ status: row.status,
6086
+ priority: row.priority,
6087
+ dueDate: row.due_date ?? void 0,
6088
+ metadata: row.metadata ?? void 0,
6089
+ parentId: row.parent_id ?? void 0,
6090
+ sourceId: row.source_id ?? void 0,
6091
+ context: row.context ?? void 0,
6092
+ createdAt: new Date(row.created_at),
6093
+ updatedAt: new Date(row.updated_at)
6094
+ };
6095
+ }
6096
+ var PostgreSQLTaskStore = class {
6097
+ constructor(options) {
6098
+ this.initialized = false;
6099
+ this.ownsPool = true;
6100
+ this.initPromise = null;
6101
+ if (typeof options.poolConfig === "string") {
6102
+ this.pool = new import_pg18.Pool({ connectionString: options.poolConfig });
6103
+ } else {
6104
+ this.pool = new import_pg18.Pool(options.poolConfig);
6105
+ }
6106
+ this.migrationManager = new MigrationManager(this.pool);
6107
+ this.migrationManager.register(createTasksTable);
6108
+ if (options.autoMigrate !== false) {
6109
+ this.initialize().catch((error) => {
6110
+ console.error("Failed to initialize PostgreSQLTaskStore:", error);
6111
+ throw error;
6112
+ });
6113
+ }
6114
+ }
6115
+ async initialize() {
6116
+ if (this.initialized) {
6117
+ return;
6118
+ }
6119
+ if (this.initPromise) {
6120
+ return this.initPromise;
6121
+ }
6122
+ this.initPromise = (async () => {
6123
+ try {
6124
+ await this.migrationManager.migrate();
6125
+ this.initialized = true;
6126
+ } finally {
6127
+ this.initPromise = null;
6128
+ }
6129
+ })();
6130
+ return this.initPromise;
6131
+ }
6132
+ async create(params) {
6133
+ await this.ensureInitialized();
6134
+ const id = (0, import_uuid2.v4)();
6135
+ const now = (/* @__PURE__ */ new Date()).toISOString();
6136
+ await this.pool.query(
6137
+ `INSERT INTO lattice_tasks (id, tenant_id, owner_type, owner_id, title, description, status, priority, due_date, metadata, parent_id, source_id, context, created_at, updated_at)
6138
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)`,
6139
+ [
6140
+ id,
6141
+ params.tenantId,
6142
+ params.ownerType,
6143
+ params.ownerId,
6144
+ params.title,
6145
+ params.description || null,
6146
+ params.status || "pending",
6147
+ params.priority || "medium",
6148
+ params.dueDate || null,
6149
+ params.metadata ? JSON.stringify(params.metadata) : null,
6150
+ params.parentId || null,
6151
+ params.sourceId || null,
6152
+ params.context ? JSON.stringify(params.context) : null,
6153
+ now,
6154
+ now
6155
+ ]
6156
+ );
6157
+ return await this.getById(params.tenantId, id);
6158
+ }
6159
+ async getById(tenantId, id) {
6160
+ await this.ensureInitialized();
6161
+ const result = await this.pool.query(
6162
+ `SELECT * FROM lattice_tasks WHERE tenant_id = $1 AND id = $2`,
6163
+ [tenantId, id]
6164
+ );
6165
+ if (result.rows.length === 0) return null;
6166
+ return mapRowToTask(result.rows[0]);
6167
+ }
6168
+ async list(filter) {
6169
+ await this.ensureInitialized();
6170
+ const conditions = [`tenant_id = $1`];
6171
+ const params = [filter.tenantId];
6172
+ let paramIndex = 2;
6173
+ if (filter.ownerType) {
6174
+ conditions.push(`owner_type = $${paramIndex++}`);
6175
+ params.push(filter.ownerType);
6176
+ }
6177
+ if (filter.ownerId) {
6178
+ conditions.push(`owner_id = $${paramIndex++}`);
6179
+ params.push(filter.ownerId);
6180
+ }
6181
+ if (filter.status) {
6182
+ conditions.push(`status = $${paramIndex++}`);
6183
+ params.push(filter.status);
6184
+ }
6185
+ if (filter.priority) {
6186
+ conditions.push(`priority = $${paramIndex++}`);
6187
+ params.push(filter.priority);
6188
+ }
6189
+ if (filter.parentId) {
6190
+ conditions.push(`parent_id = $${paramIndex++}`);
6191
+ params.push(filter.parentId);
6192
+ }
6193
+ if (filter.sourceId) {
6194
+ conditions.push(`source_id = $${paramIndex++}`);
6195
+ params.push(filter.sourceId);
6196
+ }
6197
+ if (filter.metadata) {
6198
+ for (const [key, value] of Object.entries(filter.metadata)) {
6199
+ const safeKey = key.replace(/[^a-zA-Z0-9_]/g, "");
6200
+ if (safeKey) {
6201
+ conditions.push(`metadata->>'${safeKey}' = $${paramIndex++}`);
6202
+ params.push(String(value));
6203
+ }
6204
+ }
6205
+ }
6206
+ const where = conditions.join(" AND ");
6207
+ const limit = filter.limit || 100;
6208
+ const offset = filter.offset || 0;
6209
+ const result = await this.pool.query(
6210
+ `SELECT * FROM lattice_tasks WHERE ${where} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`,
6211
+ [...params, limit, offset]
6212
+ );
6213
+ return result.rows.map((r) => mapRowToTask(r));
6214
+ }
6215
+ async update(tenantId, id, updates) {
6216
+ await this.ensureInitialized();
6217
+ const existing = await this.getById(tenantId, id);
6218
+ if (!existing) return null;
6219
+ const setClauses = [];
6220
+ const params = [];
6221
+ let paramIndex = 1;
6222
+ if (updates.title !== void 0) {
6223
+ setClauses.push(`title = $${paramIndex++}`);
6224
+ params.push(updates.title);
6225
+ }
6226
+ if (updates.description !== void 0) {
6227
+ setClauses.push(`description = $${paramIndex++}`);
6228
+ params.push(updates.description);
6229
+ }
6230
+ if (updates.status !== void 0) {
6231
+ setClauses.push(`status = $${paramIndex++}`);
6232
+ params.push(updates.status);
6233
+ }
6234
+ if (updates.priority !== void 0) {
6235
+ setClauses.push(`priority = $${paramIndex++}`);
6236
+ params.push(updates.priority);
6237
+ }
6238
+ if (updates.dueDate !== void 0) {
6239
+ setClauses.push(`due_date = $${paramIndex++}`);
6240
+ params.push(updates.dueDate);
6241
+ }
6242
+ if (updates.metadata !== void 0) {
6243
+ setClauses.push(`metadata = $${paramIndex++}`);
6244
+ params.push(JSON.stringify(updates.metadata));
6245
+ }
6246
+ if (updates.parentId !== void 0) {
6247
+ setClauses.push(`parent_id = $${paramIndex++}`);
6248
+ params.push(updates.parentId);
6249
+ }
6250
+ if (updates.sourceId !== void 0) {
6251
+ setClauses.push(`source_id = $${paramIndex++}`);
6252
+ params.push(updates.sourceId);
6253
+ }
6254
+ if (updates.context !== void 0) {
6255
+ setClauses.push(`context = $${paramIndex++}`);
6256
+ params.push(JSON.stringify(updates.context));
6257
+ }
6258
+ if (updates.ownerType !== void 0) {
6259
+ setClauses.push(`owner_type = $${paramIndex++}`);
6260
+ params.push(updates.ownerType);
6261
+ }
6262
+ if (updates.ownerId !== void 0) {
6263
+ setClauses.push(`owner_id = $${paramIndex++}`);
6264
+ params.push(updates.ownerId);
6265
+ }
6266
+ if (setClauses.length === 0) {
6267
+ return existing;
6268
+ }
6269
+ setClauses.push(`updated_at = $${paramIndex++}`);
6270
+ params.push((/* @__PURE__ */ new Date()).toISOString());
6271
+ params.push(tenantId, id);
6272
+ await this.pool.query(
6273
+ `UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex++}`,
6274
+ params
6275
+ );
6276
+ return this.getById(tenantId, id);
6277
+ }
6278
+ async delete(tenantId, id) {
6279
+ await this.ensureInitialized();
6280
+ const result = await this.pool.query(
6281
+ `DELETE FROM lattice_tasks WHERE tenant_id = $1 AND id = $2`,
6282
+ [tenantId, id]
6283
+ );
6284
+ return (result.rowCount ?? 0) > 0;
6285
+ }
6286
+ async dispose() {
6287
+ if (this.ownsPool && this.pool) {
6288
+ await this.pool.end();
6289
+ }
6290
+ }
6291
+ async ensureInitialized() {
6292
+ if (!this.initialized) {
6293
+ await this.initialize();
6294
+ }
6295
+ }
6296
+ };
6297
+
6298
+ // src/stores/MenuStore.ts
6299
+ var import_pg19 = require("pg");
6300
+
6301
+ // src/migrations/menu_items_migration.ts
6302
+ var createMenuItemsTable = {
6303
+ version: 134,
6304
+ name: "create_menu_items_table",
6305
+ up: async (client) => {
6306
+ await client.query(`
6307
+ CREATE TABLE IF NOT EXISTS lattice_menu_items (
6308
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
6309
+ tenant_id VARCHAR(255) NOT NULL,
6310
+ menu_target VARCHAR(20) NOT NULL CHECK (menu_target IN ('sidebar', 'workspace')),
6311
+ "group" VARCHAR(100),
6312
+ name VARCHAR(255) NOT NULL,
6313
+ icon VARCHAR(50),
6314
+ sort_order INT NOT NULL DEFAULT 0,
6315
+ content_type VARCHAR(20) NOT NULL CHECK (content_type IN ('agent', 'html', 'custom')),
6316
+ content_config JSONB NOT NULL DEFAULT '{}',
6317
+ enabled BOOLEAN NOT NULL DEFAULT true,
6318
+ created_at TIMESTAMP NOT NULL DEFAULT NOW(),
6319
+ updated_at TIMESTAMP NOT NULL DEFAULT NOW()
6320
+ )
6321
+ `);
6322
+ await client.query(`
6323
+ CREATE INDEX IF NOT EXISTS idx_menu_items_tenant_target
6324
+ ON lattice_menu_items(tenant_id, menu_target)
6325
+ `);
6326
+ await client.query(`
6327
+ CREATE INDEX IF NOT EXISTS idx_menu_items_sort
6328
+ ON lattice_menu_items(tenant_id, menu_target, sort_order)
6329
+ `);
6330
+ },
6331
+ down: async (client) => {
6332
+ await client.query("DROP TABLE IF EXISTS lattice_menu_items");
6333
+ }
6334
+ };
6335
+
6336
+ // src/stores/MenuStore.ts
6337
+ var MenuStore = class {
6338
+ constructor(options) {
6339
+ this.initialized = false;
6340
+ this.initPromise = null;
6341
+ this.pool = typeof options.poolConfig === "string" ? new import_pg19.Pool({ connectionString: options.poolConfig }) : new import_pg19.Pool(options.poolConfig);
6342
+ this.migrationManager = new MigrationManager(this.pool);
6343
+ this.migrationManager.register(createMenuItemsTable);
6344
+ if (options.autoMigrate !== false) {
6345
+ this.initialize().catch((error) => {
6346
+ console.error("Failed to initialize MenuStore:", error);
6347
+ throw error;
6348
+ });
6349
+ }
6350
+ }
6351
+ async initialize() {
6352
+ if (this.initialized) return;
6353
+ if (this.initPromise) return this.initPromise;
6354
+ this.initPromise = (async () => {
6355
+ try {
6356
+ await this.migrationManager.migrate();
6357
+ this.initialized = true;
6358
+ } finally {
6359
+ this.initPromise = null;
6360
+ }
6361
+ })();
6362
+ return this.initPromise;
6363
+ }
6364
+ async list(params) {
6365
+ await this.ensureInitialized();
6366
+ const conditions = ["tenant_id = $1"];
6367
+ const values = [params.tenantId];
6368
+ let idx = 2;
6369
+ if (params.menuTarget) {
6370
+ conditions.push(`menu_target = $${idx++}`);
6371
+ values.push(params.menuTarget);
6372
+ }
6373
+ const result = await this.pool.query(
6374
+ `SELECT * FROM lattice_menu_items
6375
+ WHERE ${conditions.join(" AND ")}
6376
+ AND enabled = true
6377
+ ORDER BY sort_order ASC`,
6378
+ values
6379
+ );
6380
+ return result.rows.map((r) => this.mapRowToMenuItem(r));
6381
+ }
6382
+ async getById(id) {
6383
+ await this.ensureInitialized();
6384
+ const result = await this.pool.query(
6385
+ `SELECT * FROM lattice_menu_items WHERE id = $1`,
6386
+ [id]
6387
+ );
6388
+ if (result.rows.length === 0) return null;
6389
+ return this.mapRowToMenuItem(result.rows[0]);
6390
+ }
6391
+ async create(input) {
6392
+ await this.ensureInitialized();
6393
+ const result = await this.pool.query(
6394
+ `INSERT INTO lattice_menu_items
6395
+ (tenant_id, menu_target, "group", name, icon, sort_order, content_type, content_config)
6396
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
6397
+ RETURNING *`,
6398
+ [
6399
+ input.tenantId,
6400
+ input.menuTarget,
6401
+ input.group || null,
6402
+ input.name,
6403
+ input.icon || null,
6404
+ input.sortOrder ?? 0,
6405
+ input.contentType,
6406
+ JSON.stringify(input.contentConfig)
6407
+ ]
6408
+ );
6409
+ return this.mapRowToMenuItem(result.rows[0]);
6410
+ }
6411
+ async update(id, patch) {
6412
+ await this.ensureInitialized();
6413
+ const existing = await this.pool.query(
6414
+ `SELECT * FROM lattice_menu_items WHERE id = $1`,
6415
+ [id]
6416
+ );
6417
+ if (existing.rows.length === 0) {
6418
+ throw new Error(`MenuItem ${id} not found`);
6419
+ }
6420
+ const row = existing.rows[0];
6421
+ const setClauses = [];
6422
+ const values = [];
6423
+ let idx = 1;
6424
+ if (patch.group !== void 0) {
6425
+ setClauses.push(`"group" = $${idx++}`);
6426
+ values.push(patch.group);
6427
+ }
6428
+ if (patch.name !== void 0) {
6429
+ setClauses.push(`name = $${idx++}`);
6430
+ values.push(patch.name);
6431
+ }
6432
+ if (patch.icon !== void 0) {
6433
+ setClauses.push(`icon = $${idx++}`);
6434
+ values.push(patch.icon);
6435
+ }
6436
+ if (patch.sortOrder !== void 0) {
6437
+ setClauses.push(`sort_order = $${idx++}`);
6438
+ values.push(patch.sortOrder);
6439
+ }
6440
+ if (patch.contentConfig !== void 0) {
6441
+ setClauses.push(`content_config = $${idx++}`);
6442
+ values.push(JSON.stringify(patch.contentConfig));
6443
+ }
6444
+ if (patch.enabled !== void 0) {
6445
+ setClauses.push(`enabled = $${idx++}`);
6446
+ values.push(patch.enabled);
6447
+ }
6448
+ if (setClauses.length === 0) {
6449
+ return this.mapRowToMenuItem(row);
6450
+ }
6451
+ setClauses.push(`updated_at = NOW()`);
6452
+ values.push(id);
6453
+ const result = await this.pool.query(
6454
+ `UPDATE lattice_menu_items SET ${setClauses.join(", ")} WHERE id = $${idx}
6455
+ RETURNING *`,
6456
+ values
6457
+ );
6458
+ return this.mapRowToMenuItem(result.rows[0]);
6459
+ }
6460
+ async delete(id) {
6461
+ await this.ensureInitialized();
6462
+ await this.pool.query(`DELETE FROM lattice_menu_items WHERE id = $1`, [id]);
6463
+ }
6464
+ async ensureInitialized() {
6465
+ if (!this.initialized) {
6466
+ await this.initialize();
6467
+ }
6468
+ }
6469
+ mapRowToMenuItem(row) {
6470
+ return {
6471
+ id: row.id,
6472
+ tenantId: row.tenant_id,
6473
+ menuTarget: row.menu_target,
6474
+ group: row.group || void 0,
6475
+ name: row.name,
6476
+ icon: row.icon || void 0,
6477
+ sortOrder: row.sort_order,
6478
+ contentType: row.content_type,
6479
+ contentConfig: row.content_config,
6480
+ enabled: row.enabled,
6481
+ createdAt: row.created_at,
6482
+ updatedAt: row.updated_at
6483
+ };
6484
+ }
6485
+ };
6486
+
5888
6487
  // src/createPgStoreConfig.ts
6488
+ var import_langgraph_checkpoint_postgres = require("@langchain/langgraph-checkpoint-postgres");
5889
6489
  function createPgStoreConfig(connectionString) {
5890
- const opts = { poolConfig: connectionString, autoMigrate: false };
5891
- const optsAuto = { poolConfig: connectionString, autoMigrate: true };
6490
+ const opts = { poolConfig: connectionString, autoMigrate: true };
6491
+ const checkpoint = import_langgraph_checkpoint_postgres.PostgresSaver.fromConnString(connectionString);
6492
+ checkpoint.setup().catch((err) => {
6493
+ console.error("[pg-stores] Failed to setup checkpoint table:", err.message || err);
6494
+ });
5892
6495
  return {
5893
6496
  workspace: new PostgreSQLWorkspaceStore(opts),
5894
6497
  project: new PostgreSQLProjectStore(opts),
5895
- eval: new PostgreSQLEvalStore(optsAuto),
6498
+ eval: new PostgreSQLEvalStore(opts),
5896
6499
  user: new PostgreSQLUserStore(opts),
5897
6500
  tenant: new PostgreSQLTenantStore(opts),
5898
6501
  userTenantLink: new PostgreSQLUserTenantLinkStore(opts),
5899
- channelBinding: new ChannelBindingStore(optsAuto),
5900
- channelInstallation: new PostgreSQLChannelInstallationStore(optsAuto),
6502
+ channelBinding: new ChannelBindingStore(opts),
6503
+ channelInstallation: new PostgreSQLChannelInstallationStore(opts),
5901
6504
  thread: new PostgreSQLThreadStore(opts),
5902
6505
  database: new PostgreSQLDatabaseConfigStore(opts),
5903
6506
  metrics: new PostgreSQLMetricsServerConfigStore(opts),
5904
6507
  mcp: new PostgreSQLMcpServerConfigStore(opts),
5905
6508
  assistant: new PostgreSQLAssistantStore(opts),
5906
- workflowTracking: new PostgreSQLWorkflowTrackingStore(optsAuto),
5907
- threadMessageQueue: new ThreadMessageQueueStore(optsAuto),
5908
- a2aApiKey: new PostgreSQLA2AApiKeyStore(optsAuto),
5909
- schedule: new PostgreSQLScheduleStorage(opts)
6509
+ workflowTracking: new PostgreSQLWorkflowTrackingStore(opts),
6510
+ threadMessageQueue: new ThreadMessageQueueStore(opts),
6511
+ task: new PostgreSQLTaskStore(opts),
6512
+ a2aApiKey: new PostgreSQLA2AApiKeyStore(opts),
6513
+ schedule: new PostgreSQLScheduleStorage(opts),
6514
+ menu: new MenuStore(opts),
6515
+ checkpoint
5910
6516
  };
5911
6517
  }
5912
6518
 
5913
6519
  // src/stores/PostgreSQLSkillStore.ts
5914
- var import_pg18 = require("pg");
6520
+ var import_pg20 = require("pg");
5915
6521
 
5916
6522
  // src/migrations/skill_migrations.ts
5917
6523
  var createSkillsTable = {
@@ -6073,9 +6679,9 @@ var PostgreSQLSkillStore = class {
6073
6679
  this.ownsPool = true;
6074
6680
  this.initPromise = null;
6075
6681
  if (typeof options.poolConfig === "string") {
6076
- this.pool = new import_pg18.Pool({ connectionString: options.poolConfig });
6682
+ this.pool = new import_pg20.Pool({ connectionString: options.poolConfig });
6077
6683
  } else {
6078
- this.pool = new import_pg18.Pool(options.poolConfig);
6684
+ this.pool = new import_pg20.Pool(options.poolConfig);
6079
6685
  }
6080
6686
  this.migrationManager = new MigrationManager(this.pool);
6081
6687
  this.migrationManager.register(createSkillsTable);
@@ -6429,12 +7035,12 @@ var createChannelIdentityMappingTables = {
6429
7035
  };
6430
7036
 
6431
7037
  // src/stores/ChannelIdentityMappingStore.ts
6432
- var import_pg19 = require("pg");
7038
+ var import_pg21 = require("pg");
6433
7039
  var ChannelIdentityMappingStore = class {
6434
7040
  constructor(options) {
6435
7041
  this.initialized = false;
6436
7042
  this.initPromise = null;
6437
- this.pool = typeof options.poolConfig === "string" ? new import_pg19.Pool({ connectionString: options.poolConfig }) : new import_pg19.Pool(options.poolConfig);
7043
+ this.pool = typeof options.poolConfig === "string" ? new import_pg21.Pool({ connectionString: options.poolConfig }) : new import_pg21.Pool(options.poolConfig);
6438
7044
  this.migrationManager = new MigrationManager(this.pool);
6439
7045
  this.migrationManager.register(createChannelIdentityMappingTables);
6440
7046
  if (options.autoMigrate !== false) {
@@ -6649,6 +7255,7 @@ function mapRowToChannelIdentityMapping(row) {
6649
7255
  0 && (module.exports = {
6650
7256
  ChannelBindingStore,
6651
7257
  ChannelIdentityMappingStore,
7258
+ MenuStore,
6652
7259
  MigrationManager,
6653
7260
  Pool,
6654
7261
  PostgreSQLA2AApiKeyStore,
@@ -6672,6 +7279,7 @@ function mapRowToChannelIdentityMapping(row) {
6672
7279
  addProjectConfigColumn,
6673
7280
  addScheduleTenantId,
6674
7281
  addSkillTenantId,
7282
+ addStepThreadId,
6675
7283
  addThreadTenantId,
6676
7284
  alterChannelInstallationsTable,
6677
7285
  changeAssistantPrimaryKey,
@@ -6689,6 +7297,7 @@ function mapRowToChannelIdentityMapping(row) {
6689
7297
  createEvalRunsTable,
6690
7298
  createEvalSuitesTable,
6691
7299
  createMcpServerConfigsTable,
7300
+ createMenuItemsTable,
6692
7301
  createMetricsConfigsTable,
6693
7302
  createPgStoreConfig,
6694
7303
  createProjectsTable,