@axiom-lattice/pg-stores 1.0.71 → 1.0.73

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,
@@ -3282,7 +3354,15 @@ var PostgreSQLWorkflowTrackingStore = class {
3282
3354
  [request.runId, request.stepType, request.stepName]
3283
3355
  );
3284
3356
  if (result.rows.length > 0) {
3285
- return this.mapRowToRunStep(result.rows[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;
3286
3366
  }
3287
3367
  return this.createRunStep(request);
3288
3368
  }
@@ -3370,6 +3450,7 @@ var PostgreSQLWorkflowTrackingStore = class {
3370
3450
  tenantId: row.tenant_id,
3371
3451
  stepType: row.step_type,
3372
3452
  stepName: row.step_name,
3453
+ threadId: row.thread_id,
3373
3454
  edgeFrom: row.edge_from,
3374
3455
  edgeTo: row.edge_to,
3375
3456
  edgePurpose: row.edge_purpose,
@@ -4422,6 +4503,30 @@ var alterMessageQueueIdColumn = {
4422
4503
  }
4423
4504
  };
4424
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
+
4425
4530
  // src/stores/ThreadMessageQueueStore.ts
4426
4531
  var ThreadMessageQueueStore = class {
4427
4532
  constructor(options) {
@@ -4438,6 +4543,7 @@ var ThreadMessageQueueStore = class {
4438
4543
  this.migrationManager.register(addPriorityAndCommandColumns);
4439
4544
  this.migrationManager.register(addCustomRunConfigColumn);
4440
4545
  this.migrationManager.register(alterMessageQueueIdColumn);
4546
+ this.migrationManager.register(addWorkspaceProjectToQueue);
4441
4547
  if (options.autoMigrate !== false) {
4442
4548
  this.initialize().catch((error) => {
4443
4549
  console.error("Failed to initialize ThreadMessageQueueStore:", error);
@@ -4467,7 +4573,7 @@ var ThreadMessageQueueStore = class {
4467
4573
  * Add message to queue
4468
4574
  */
4469
4575
  async addMessage(params) {
4470
- 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;
4471
4577
  const seqResult = await this.pool.query(
4472
4578
  `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq
4473
4579
  FROM lattice_thread_message_queue
@@ -4477,10 +4583,10 @@ var ThreadMessageQueueStore = class {
4477
4583
  const nextSeq = seqResult.rows[0].next_seq;
4478
4584
  const result = await this.pool.query(
4479
4585
  `INSERT INTO lattice_thread_message_queue
4480
- (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
4481
- 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)
4482
4588
  RETURNING *`,
4483
- [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]
4484
4590
  );
4485
4591
  return this.rowToMessage(result.rows[0]);
4486
4592
  }
@@ -4489,7 +4595,7 @@ var ThreadMessageQueueStore = class {
4489
4595
  * Uses priority=100 to ensure message is processed first
4490
4596
  */
4491
4597
  async addMessageAtHead(params) {
4492
- 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;
4493
4599
  const resolvedTenantId = tenantId;
4494
4600
  const resolvedAssistantId = assistantId;
4495
4601
  const seqResult = await this.pool.query(
@@ -4501,10 +4607,10 @@ var ThreadMessageQueueStore = class {
4501
4607
  const nextSeq = seqResult.rows[0].next_seq;
4502
4608
  const result = await this.pool.query(
4503
4609
  `INSERT INTO lattice_thread_message_queue
4504
- (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)
4505
- 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)
4506
4612
  RETURNING *`,
4507
- [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]
4508
4614
  );
4509
4615
  return this.rowToMessage(result.rows[0]);
4510
4616
  }
@@ -4548,7 +4654,7 @@ var ThreadMessageQueueStore = class {
4548
4654
  */
4549
4655
  async getThreadsWithPendingMessages() {
4550
4656
  const result = await this.pool.query(
4551
- `SELECT DISTINCT tenant_id, assistant_id, thread_id
4657
+ `SELECT DISTINCT ON (thread_id) tenant_id, assistant_id, thread_id, workspace_id, project_id
4552
4658
  FROM lattice_thread_message_queue
4553
4659
  WHERE status IN ('pending', 'processing')
4554
4660
  ORDER BY thread_id`
@@ -4556,7 +4662,9 @@ var ThreadMessageQueueStore = class {
4556
4662
  return result.rows.map((row) => ({
4557
4663
  tenantId: row.tenant_id,
4558
4664
  assistantId: row.assistant_id,
4559
- threadId: row.thread_id
4665
+ threadId: row.thread_id,
4666
+ workspaceId: row.workspace_id || void 0,
4667
+ projectId: row.project_id || void 0
4560
4668
  }));
4561
4669
  }
4562
4670
  /**
@@ -4983,6 +5091,25 @@ var PostgreSQLChannelInstallationStore = class {
4983
5091
  );
4984
5092
  return result.rows.map((row) => this.mapRowToInstallation(row));
4985
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
+ }
4986
5113
  async createInstallation(tenantId, installationId, data) {
4987
5114
  await this.ensureInitialized();
4988
5115
  const now = /* @__PURE__ */ new Date();
@@ -5896,33 +6023,501 @@ var PostgreSQLScheduleStorage = class {
5896
6023
  }
5897
6024
  };
5898
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
+
5899
6487
  // src/createPgStoreConfig.ts
6488
+ var import_langgraph_checkpoint_postgres = require("@langchain/langgraph-checkpoint-postgres");
5900
6489
  function createPgStoreConfig(connectionString) {
5901
- const opts = { poolConfig: connectionString, autoMigrate: false };
5902
- 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
+ });
5903
6495
  return {
5904
6496
  workspace: new PostgreSQLWorkspaceStore(opts),
5905
6497
  project: new PostgreSQLProjectStore(opts),
5906
- eval: new PostgreSQLEvalStore(optsAuto),
6498
+ eval: new PostgreSQLEvalStore(opts),
5907
6499
  user: new PostgreSQLUserStore(opts),
5908
6500
  tenant: new PostgreSQLTenantStore(opts),
5909
6501
  userTenantLink: new PostgreSQLUserTenantLinkStore(opts),
5910
- channelBinding: new ChannelBindingStore(optsAuto),
5911
- channelInstallation: new PostgreSQLChannelInstallationStore(optsAuto),
6502
+ channelBinding: new ChannelBindingStore(opts),
6503
+ channelInstallation: new PostgreSQLChannelInstallationStore(opts),
5912
6504
  thread: new PostgreSQLThreadStore(opts),
5913
6505
  database: new PostgreSQLDatabaseConfigStore(opts),
5914
6506
  metrics: new PostgreSQLMetricsServerConfigStore(opts),
5915
6507
  mcp: new PostgreSQLMcpServerConfigStore(opts),
5916
6508
  assistant: new PostgreSQLAssistantStore(opts),
5917
- workflowTracking: new PostgreSQLWorkflowTrackingStore(optsAuto),
5918
- threadMessageQueue: new ThreadMessageQueueStore(optsAuto),
5919
- a2aApiKey: new PostgreSQLA2AApiKeyStore(optsAuto),
5920
- 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
5921
6516
  };
5922
6517
  }
5923
6518
 
5924
6519
  // src/stores/PostgreSQLSkillStore.ts
5925
- var import_pg18 = require("pg");
6520
+ var import_pg20 = require("pg");
5926
6521
 
5927
6522
  // src/migrations/skill_migrations.ts
5928
6523
  var createSkillsTable = {
@@ -6084,9 +6679,9 @@ var PostgreSQLSkillStore = class {
6084
6679
  this.ownsPool = true;
6085
6680
  this.initPromise = null;
6086
6681
  if (typeof options.poolConfig === "string") {
6087
- this.pool = new import_pg18.Pool({ connectionString: options.poolConfig });
6682
+ this.pool = new import_pg20.Pool({ connectionString: options.poolConfig });
6088
6683
  } else {
6089
- this.pool = new import_pg18.Pool(options.poolConfig);
6684
+ this.pool = new import_pg20.Pool(options.poolConfig);
6090
6685
  }
6091
6686
  this.migrationManager = new MigrationManager(this.pool);
6092
6687
  this.migrationManager.register(createSkillsTable);
@@ -6440,12 +7035,12 @@ var createChannelIdentityMappingTables = {
6440
7035
  };
6441
7036
 
6442
7037
  // src/stores/ChannelIdentityMappingStore.ts
6443
- var import_pg19 = require("pg");
7038
+ var import_pg21 = require("pg");
6444
7039
  var ChannelIdentityMappingStore = class {
6445
7040
  constructor(options) {
6446
7041
  this.initialized = false;
6447
7042
  this.initPromise = null;
6448
- 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);
6449
7044
  this.migrationManager = new MigrationManager(this.pool);
6450
7045
  this.migrationManager.register(createChannelIdentityMappingTables);
6451
7046
  if (options.autoMigrate !== false) {
@@ -6660,6 +7255,7 @@ function mapRowToChannelIdentityMapping(row) {
6660
7255
  0 && (module.exports = {
6661
7256
  ChannelBindingStore,
6662
7257
  ChannelIdentityMappingStore,
7258
+ MenuStore,
6663
7259
  MigrationManager,
6664
7260
  Pool,
6665
7261
  PostgreSQLA2AApiKeyStore,
@@ -6683,6 +7279,7 @@ function mapRowToChannelIdentityMapping(row) {
6683
7279
  addProjectConfigColumn,
6684
7280
  addScheduleTenantId,
6685
7281
  addSkillTenantId,
7282
+ addStepThreadId,
6686
7283
  addThreadTenantId,
6687
7284
  alterChannelInstallationsTable,
6688
7285
  changeAssistantPrimaryKey,
@@ -6700,6 +7297,7 @@ function mapRowToChannelIdentityMapping(row) {
6700
7297
  createEvalRunsTable,
6701
7298
  createEvalSuitesTable,
6702
7299
  createMcpServerConfigsTable,
7300
+ createMenuItemsTable,
6703
7301
  createMetricsConfigsTable,
6704
7302
  createPgStoreConfig,
6705
7303
  createProjectsTable,