@axiom-lattice/pg-stores 2.0.10 → 3.0.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +60 -0
- package/dist/index.d.mts +52 -4
- package/dist/index.d.ts +52 -4
- package/dist/index.js +907 -123
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +905 -123
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/PostgreSQLA2AApiKeyStore.migrations.test.ts +76 -0
- package/src/__tests__/PostgreSQLA2AApiKeyStore.test.ts +133 -0
- package/src/__tests__/PostgreSQLAgentWebAppStore.migrations.test.ts +77 -0
- package/src/__tests__/PostgreSQLAgentWebAppStore.test.ts +290 -0
- package/src/__tests__/PostgreSQLChannelInstallationStore.test.ts +37 -2
- package/src/__tests__/PostgreSQLTaskStore.integration.test.ts +90 -0
- package/src/__tests__/PostgreSQLTaskStore.test.ts +287 -0
- package/src/__tests__/PostgreSQLTaskWorkItemStore.test.ts +104 -0
- package/src/__tests__/add_a2a_key_assistant_ids.test.ts +34 -0
- package/src/__tests__/workspace-project-store.test.ts +48 -0
- package/src/createPgStoreConfig.ts +10 -1
- package/src/index.ts +10 -0
- package/src/migrations/add_a2a_key_assistant_ids.ts +24 -0
- package/src/migrations/add_project_kind_column.ts +29 -0
- package/src/migrations/agent_web_apps_migration.ts +37 -0
- package/src/migrations/task_work_items_migration.ts +15 -0
- package/src/stores/PostgreSQLA2AApiKeyStore.ts +23 -8
- package/src/stores/PostgreSQLAgentWebAppStore.ts +280 -0
- package/src/stores/PostgreSQLProjectStore.ts +31 -8
- package/src/stores/PostgreSQLTaskStore.ts +272 -7
- package/src/stores/PostgreSQLTaskWorkItemStore.ts +42 -2
package/dist/index.js
CHANGED
|
@@ -35,8 +35,9 @@ __export(index_exports, {
|
|
|
35
35
|
MenuStore: () => MenuStore,
|
|
36
36
|
MigrationManager: () => MigrationManager,
|
|
37
37
|
PGVectorStoreProvider: () => PGVectorStoreProvider,
|
|
38
|
-
Pool: () =>
|
|
38
|
+
Pool: () => import_pg27.Pool,
|
|
39
39
|
PostgreSQLA2AApiKeyStore: () => PostgreSQLA2AApiKeyStore,
|
|
40
|
+
PostgreSQLAgentWebAppStore: () => PostgreSQLAgentWebAppStore,
|
|
40
41
|
PostgreSQLAssistantStore: () => PostgreSQLAssistantStore,
|
|
41
42
|
PostgreSQLChannelInstallationStore: () => PostgreSQLChannelInstallationStore,
|
|
42
43
|
PostgreSQLCollectionStore: () => PostgreSQLCollectionStore,
|
|
@@ -74,6 +75,7 @@ __export(index_exports, {
|
|
|
74
75
|
changeSkillPrimaryKey: () => changeSkillPrimaryKey,
|
|
75
76
|
changeThreadPrimaryKey: () => changeThreadPrimaryKey,
|
|
76
77
|
createA2AApiKeysTable: () => createA2AApiKeysTable,
|
|
78
|
+
createAgentWebAppsTable: () => createAgentWebAppsTable,
|
|
77
79
|
createAssistantsTable: () => createAssistantsTable,
|
|
78
80
|
createChannelBindingsTable: () => createChannelBindingsTable,
|
|
79
81
|
createChannelIdentityMappingTables: () => createChannelIdentityMappingTables,
|
|
@@ -107,10 +109,10 @@ __export(index_exports, {
|
|
|
107
109
|
safeParse: () => safeParse
|
|
108
110
|
});
|
|
109
111
|
module.exports = __toCommonJS(index_exports);
|
|
110
|
-
var
|
|
112
|
+
var import_pg27 = require("pg");
|
|
111
113
|
|
|
112
114
|
// src/createPgStoreConfig.ts
|
|
113
|
-
var
|
|
115
|
+
var import_pg24 = require("pg");
|
|
114
116
|
|
|
115
117
|
// src/migrations/migration.ts
|
|
116
118
|
var MigrationManager = class {
|
|
@@ -2460,6 +2462,24 @@ var dropProjectFolderPathColumn = {
|
|
|
2460
2462
|
}
|
|
2461
2463
|
};
|
|
2462
2464
|
|
|
2465
|
+
// src/migrations/add_project_kind_column.ts
|
|
2466
|
+
var addProjectKindColumn = {
|
|
2467
|
+
version: 165,
|
|
2468
|
+
name: "add_project_kind_column",
|
|
2469
|
+
up: async (client) => {
|
|
2470
|
+
await client.query(`
|
|
2471
|
+
ALTER TABLE lattice_projects
|
|
2472
|
+
ADD COLUMN IF NOT EXISTS kind TEXT NOT NULL DEFAULT 'business'
|
|
2473
|
+
`);
|
|
2474
|
+
},
|
|
2475
|
+
down: async (client) => {
|
|
2476
|
+
await client.query(`
|
|
2477
|
+
ALTER TABLE lattice_projects
|
|
2478
|
+
DROP COLUMN IF EXISTS kind
|
|
2479
|
+
`);
|
|
2480
|
+
}
|
|
2481
|
+
};
|
|
2482
|
+
|
|
2463
2483
|
// src/stores/PostgreSQLProjectStore.ts
|
|
2464
2484
|
var PostgreSQLProjectStore = class {
|
|
2465
2485
|
constructor(options) {
|
|
@@ -2482,6 +2502,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2482
2502
|
this.migrationManager.register(createProjectsTable);
|
|
2483
2503
|
this.migrationManager.register(addProjectConfigColumn);
|
|
2484
2504
|
this.migrationManager.register(dropProjectFolderPathColumn);
|
|
2505
|
+
this.migrationManager.register(addProjectKindColumn);
|
|
2485
2506
|
if (options.autoMigrate !== false) {
|
|
2486
2507
|
this.initialize().catch((error) => {
|
|
2487
2508
|
console.error("Failed to initialize PostgreSQLProjectStore:", error);
|
|
@@ -2527,6 +2548,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2527
2548
|
name: row.name,
|
|
2528
2549
|
description: row.description || void 0,
|
|
2529
2550
|
config: row.config || void 0,
|
|
2551
|
+
kind: row.kind || "business",
|
|
2530
2552
|
createdAt: row.created_at,
|
|
2531
2553
|
updatedAt: row.updated_at
|
|
2532
2554
|
};
|
|
@@ -2534,16 +2556,22 @@ var PostgreSQLProjectStore = class {
|
|
|
2534
2556
|
/**
|
|
2535
2557
|
* Get all projects for a specific workspace
|
|
2536
2558
|
*/
|
|
2537
|
-
async getProjectsByWorkspace(tenantId, workspaceId) {
|
|
2559
|
+
async getProjectsByWorkspace(tenantId, workspaceId, filter) {
|
|
2538
2560
|
await this.ensureInitialized();
|
|
2561
|
+
const conditions = ["tenant_id = $1", "workspace_id = $2"];
|
|
2562
|
+
const values = [tenantId, workspaceId];
|
|
2563
|
+
if (filter?.kind !== void 0) {
|
|
2564
|
+
values.push(filter.kind);
|
|
2565
|
+
conditions.push(`kind = $${values.length}`);
|
|
2566
|
+
}
|
|
2539
2567
|
const result = await this.pool.query(
|
|
2540
2568
|
`
|
|
2541
|
-
SELECT id, tenant_id, workspace_id, name, description, config, created_at, updated_at
|
|
2569
|
+
SELECT id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at
|
|
2542
2570
|
FROM lattice_projects
|
|
2543
|
-
WHERE
|
|
2571
|
+
WHERE ${conditions.join(" AND ")}
|
|
2544
2572
|
ORDER BY created_at DESC
|
|
2545
2573
|
`,
|
|
2546
|
-
|
|
2574
|
+
values
|
|
2547
2575
|
);
|
|
2548
2576
|
return result.rows.map(this.mapRowToProject);
|
|
2549
2577
|
}
|
|
@@ -2554,7 +2582,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2554
2582
|
await this.ensureInitialized();
|
|
2555
2583
|
const result = await this.pool.query(
|
|
2556
2584
|
`
|
|
2557
|
-
SELECT id, tenant_id, workspace_id, name, description, config, created_at, updated_at
|
|
2585
|
+
SELECT id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at
|
|
2558
2586
|
FROM lattice_projects
|
|
2559
2587
|
WHERE id = $1 AND tenant_id = $2
|
|
2560
2588
|
`,
|
|
@@ -2571,18 +2599,20 @@ var PostgreSQLProjectStore = class {
|
|
|
2571
2599
|
async createProject(tenantId, workspaceId, id, data) {
|
|
2572
2600
|
await this.ensureInitialized();
|
|
2573
2601
|
const now = /* @__PURE__ */ new Date();
|
|
2602
|
+
const kind = data.kind || "business";
|
|
2574
2603
|
await this.pool.query(
|
|
2575
2604
|
`
|
|
2576
|
-
INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, config, created_at, updated_at)
|
|
2577
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
2605
|
+
INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at)
|
|
2606
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
|
2578
2607
|
ON CONFLICT (id, tenant_id) DO UPDATE SET
|
|
2579
2608
|
workspace_id = EXCLUDED.workspace_id,
|
|
2580
2609
|
name = EXCLUDED.name,
|
|
2581
2610
|
description = EXCLUDED.description,
|
|
2582
2611
|
config = EXCLUDED.config,
|
|
2612
|
+
kind = EXCLUDED.kind,
|
|
2583
2613
|
updated_at = EXCLUDED.updated_at
|
|
2584
2614
|
`,
|
|
2585
|
-
[id, tenantId, workspaceId, data.name, data.description || null, data.config || null, now, now]
|
|
2615
|
+
[id, tenantId, workspaceId, data.name, data.description || null, data.config || null, kind, now, now]
|
|
2586
2616
|
);
|
|
2587
2617
|
return {
|
|
2588
2618
|
id,
|
|
@@ -2591,6 +2621,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2591
2621
|
name: data.name,
|
|
2592
2622
|
description: data.description,
|
|
2593
2623
|
config: data.config,
|
|
2624
|
+
kind,
|
|
2594
2625
|
createdAt: now,
|
|
2595
2626
|
updatedAt: now
|
|
2596
2627
|
};
|
|
@@ -2623,6 +2654,10 @@ var PostgreSQLProjectStore = class {
|
|
|
2623
2654
|
updateFields.push(`config = $${paramIndex++}`);
|
|
2624
2655
|
updateValues.push(updates.config || null);
|
|
2625
2656
|
}
|
|
2657
|
+
if (updates.kind !== void 0) {
|
|
2658
|
+
updateFields.push(`kind = $${paramIndex++}`);
|
|
2659
|
+
updateValues.push(updates.kind);
|
|
2660
|
+
}
|
|
2626
2661
|
if (updateFields.length === 0) {
|
|
2627
2662
|
return existing;
|
|
2628
2663
|
}
|
|
@@ -5853,6 +5888,24 @@ var createA2AApiKeysTable = {
|
|
|
5853
5888
|
}
|
|
5854
5889
|
};
|
|
5855
5890
|
|
|
5891
|
+
// src/migrations/add_a2a_key_assistant_ids.ts
|
|
5892
|
+
var addA2AKeyAssistantIds = {
|
|
5893
|
+
version: 167,
|
|
5894
|
+
name: "add_a2a_key_assistant_ids",
|
|
5895
|
+
up: async (client) => {
|
|
5896
|
+
await client.query(`
|
|
5897
|
+
ALTER TABLE lattice_a2a_api_keys
|
|
5898
|
+
ADD COLUMN IF NOT EXISTS assistant_ids JSONB
|
|
5899
|
+
`);
|
|
5900
|
+
},
|
|
5901
|
+
down: async (client) => {
|
|
5902
|
+
await client.query(`
|
|
5903
|
+
ALTER TABLE lattice_a2a_api_keys
|
|
5904
|
+
DROP COLUMN IF EXISTS assistant_ids
|
|
5905
|
+
`);
|
|
5906
|
+
}
|
|
5907
|
+
};
|
|
5908
|
+
|
|
5856
5909
|
// src/stores/PostgreSQLA2AApiKeyStore.ts
|
|
5857
5910
|
var import_core5 = require("@axiom-lattice/core");
|
|
5858
5911
|
var import_crypto2 = require("crypto");
|
|
@@ -5864,8 +5917,8 @@ function mapRowToRecord(row) {
|
|
|
5864
5917
|
id: row.id,
|
|
5865
5918
|
key: (0, import_core5.decrypt)(row.key_value),
|
|
5866
5919
|
tenantId: row.tenant_id,
|
|
5867
|
-
projectId: row.project_id
|
|
5868
|
-
|
|
5920
|
+
projectId: row.project_id,
|
|
5921
|
+
assistantIds: row.assistant_ids ?? void 0,
|
|
5869
5922
|
label: row.label || void 0,
|
|
5870
5923
|
enabled: row.enabled,
|
|
5871
5924
|
createdAt: row.created_at,
|
|
@@ -5888,6 +5941,7 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
5888
5941
|
})();
|
|
5889
5942
|
this.migrationManager = new MigrationManager(this.pool);
|
|
5890
5943
|
this.migrationManager.register(createA2AApiKeysTable);
|
|
5944
|
+
this.migrationManager.register(addA2AKeyAssistantIds);
|
|
5891
5945
|
if (options.autoMigrate !== false) {
|
|
5892
5946
|
this.initialize().catch((error) => {
|
|
5893
5947
|
console.error("Failed to initialize PostgreSQLA2AApiKeyStore:", error);
|
|
@@ -5926,6 +5980,14 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
5926
5980
|
}
|
|
5927
5981
|
return null;
|
|
5928
5982
|
}
|
|
5983
|
+
async findById(id) {
|
|
5984
|
+
await this.ensureInitialized();
|
|
5985
|
+
const result = await this.pool.query(
|
|
5986
|
+
`SELECT * FROM lattice_a2a_api_keys WHERE id = $1`,
|
|
5987
|
+
[id]
|
|
5988
|
+
);
|
|
5989
|
+
return result.rows[0] ? mapRowToRecord(result.rows[0]) : null;
|
|
5990
|
+
}
|
|
5929
5991
|
async list(params) {
|
|
5930
5992
|
await this.ensureInitialized();
|
|
5931
5993
|
const limit = params.limit || 100;
|
|
@@ -5947,9 +6009,9 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
5947
6009
|
await this.ensureInitialized();
|
|
5948
6010
|
const key = generateApiKey();
|
|
5949
6011
|
const result = await this.pool.query(
|
|
5950
|
-
`INSERT INTO lattice_a2a_api_keys (key_value, tenant_id, project_id,
|
|
6012
|
+
`INSERT INTO lattice_a2a_api_keys (key_value, tenant_id, project_id, assistant_ids, label)
|
|
5951
6013
|
VALUES ($1, $2, $3, $4, $5) RETURNING *`,
|
|
5952
|
-
[(0, import_core5.encrypt)(key), input.tenantId, input.projectId
|
|
6014
|
+
[(0, import_core5.encrypt)(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.label || null]
|
|
5953
6015
|
);
|
|
5954
6016
|
const record = mapRowToRecord(result.rows[0]);
|
|
5955
6017
|
record.key = key;
|
|
@@ -6000,16 +6062,240 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
6000
6062
|
map.set(key, {
|
|
6001
6063
|
key,
|
|
6002
6064
|
tenantId: row.tenant_id,
|
|
6003
|
-
projectId: row.project_id
|
|
6004
|
-
|
|
6065
|
+
projectId: row.project_id,
|
|
6066
|
+
assistantIds: row.assistant_ids ?? void 0
|
|
6005
6067
|
});
|
|
6006
6068
|
}
|
|
6007
6069
|
return map;
|
|
6008
6070
|
}
|
|
6009
6071
|
};
|
|
6010
6072
|
|
|
6011
|
-
// src/stores/
|
|
6073
|
+
// src/stores/PostgreSQLAgentWebAppStore.ts
|
|
6074
|
+
var import_crypto3 = require("crypto");
|
|
6012
6075
|
var import_pg17 = require("pg");
|
|
6076
|
+
|
|
6077
|
+
// src/migrations/agent_web_apps_migration.ts
|
|
6078
|
+
var createAgentWebAppsTable = {
|
|
6079
|
+
version: 169,
|
|
6080
|
+
name: "create_agent_web_apps_table",
|
|
6081
|
+
up: async (client) => {
|
|
6082
|
+
await client.query(`
|
|
6083
|
+
CREATE TABLE IF NOT EXISTS lattice_agent_web_apps (
|
|
6084
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
6085
|
+
tenant_id VARCHAR(255) NOT NULL,
|
|
6086
|
+
assistant_id VARCHAR(255) NOT NULL,
|
|
6087
|
+
name VARCHAR(255) NOT NULL,
|
|
6088
|
+
description TEXT,
|
|
6089
|
+
status VARCHAR(32) NOT NULL DEFAULT 'draft'
|
|
6090
|
+
CONSTRAINT chk_lattice_agent_web_apps_status CHECK (status IN ('draft', 'active', 'disabled')),
|
|
6091
|
+
integration JSONB NOT NULL,
|
|
6092
|
+
scope JSONB NOT NULL,
|
|
6093
|
+
features JSONB NOT NULL,
|
|
6094
|
+
appearance JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
6095
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT date_trunc('milliseconds', NOW()),
|
|
6096
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT date_trunc('milliseconds', NOW())
|
|
6097
|
+
)
|
|
6098
|
+
`);
|
|
6099
|
+
await client.query(`
|
|
6100
|
+
CREATE INDEX IF NOT EXISTS idx_lattice_agent_web_apps_tenant_assistant
|
|
6101
|
+
ON lattice_agent_web_apps(tenant_id, assistant_id)
|
|
6102
|
+
`);
|
|
6103
|
+
},
|
|
6104
|
+
down: async (client) => {
|
|
6105
|
+
await client.query(
|
|
6106
|
+
"DROP INDEX IF EXISTS idx_lattice_agent_web_apps_tenant_assistant"
|
|
6107
|
+
);
|
|
6108
|
+
await client.query("DROP TABLE IF EXISTS lattice_agent_web_apps");
|
|
6109
|
+
}
|
|
6110
|
+
};
|
|
6111
|
+
|
|
6112
|
+
// src/stores/PostgreSQLAgentWebAppStore.ts
|
|
6113
|
+
function isRecord(value) {
|
|
6114
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6115
|
+
}
|
|
6116
|
+
function isStringArray(value) {
|
|
6117
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
6118
|
+
}
|
|
6119
|
+
function isIntegration(value) {
|
|
6120
|
+
return isRecord(value) && value.type === "react_sdk";
|
|
6121
|
+
}
|
|
6122
|
+
function isScope(value) {
|
|
6123
|
+
return isRecord(value) && typeof value.defaultProjectId === "string" && isStringArray(value.allowedProjectIds) && (value.defaultModelKey === void 0 || typeof value.defaultModelKey === "string") && (value.allowedModelKeys === void 0 || isStringArray(value.allowedModelKeys));
|
|
6124
|
+
}
|
|
6125
|
+
function isFeatures(value) {
|
|
6126
|
+
return isRecord(value) && typeof value.projectSelector === "boolean" && typeof value.modelSelector === "boolean" && typeof value.threadManagement === "boolean" && typeof value.attachments === "boolean" && typeof value.hitl === "boolean" && typeof value.genUI === "boolean";
|
|
6127
|
+
}
|
|
6128
|
+
function isAppearance(value) {
|
|
6129
|
+
return isRecord(value) && (value.title === void 0 || typeof value.title === "string") && (value.welcomeMessage === void 0 || typeof value.welcomeMessage === "string") && (value.primaryColor === void 0 || typeof value.primaryColor === "string");
|
|
6130
|
+
}
|
|
6131
|
+
function isStatus(value) {
|
|
6132
|
+
return value === "draft" || value === "active" || value === "disabled";
|
|
6133
|
+
}
|
|
6134
|
+
function mapRow(row) {
|
|
6135
|
+
if (!isStatus(row.status) || !isIntegration(row.integration) || !isScope(row.scope) || !isFeatures(row.features) || !isAppearance(row.appearance)) {
|
|
6136
|
+
throw new Error(`Invalid agent web app row: ${row.id}`);
|
|
6137
|
+
}
|
|
6138
|
+
return {
|
|
6139
|
+
id: row.id,
|
|
6140
|
+
tenantId: row.tenant_id,
|
|
6141
|
+
assistantId: row.assistant_id,
|
|
6142
|
+
name: row.name,
|
|
6143
|
+
description: row.description ?? void 0,
|
|
6144
|
+
status: row.status,
|
|
6145
|
+
integration: row.integration,
|
|
6146
|
+
scope: row.scope,
|
|
6147
|
+
features: row.features,
|
|
6148
|
+
appearance: row.appearance,
|
|
6149
|
+
createdAt: row.created_at,
|
|
6150
|
+
updatedAt: row.updated_at
|
|
6151
|
+
};
|
|
6152
|
+
}
|
|
6153
|
+
var PostgreSQLAgentWebAppStore = class {
|
|
6154
|
+
constructor(options) {
|
|
6155
|
+
this.initialized = false;
|
|
6156
|
+
this.ownsPool = true;
|
|
6157
|
+
this.initPromise = null;
|
|
6158
|
+
if (options.pool) {
|
|
6159
|
+
this.pool = options.pool;
|
|
6160
|
+
this.ownsPool = false;
|
|
6161
|
+
this.initialized = true;
|
|
6162
|
+
return;
|
|
6163
|
+
}
|
|
6164
|
+
this.pool = typeof options.poolConfig === "string" ? new import_pg17.Pool({ connectionString: options.poolConfig }) : options.poolConfig ? new import_pg17.Pool(options.poolConfig) : (() => {
|
|
6165
|
+
throw new Error("Either pool or poolConfig must be provided");
|
|
6166
|
+
})();
|
|
6167
|
+
this.migrationManager = new MigrationManager(this.pool);
|
|
6168
|
+
this.migrationManager.register(createAgentWebAppsTable);
|
|
6169
|
+
if (options.autoMigrate !== false) {
|
|
6170
|
+
this.startInitialization();
|
|
6171
|
+
}
|
|
6172
|
+
}
|
|
6173
|
+
async initialize() {
|
|
6174
|
+
if (this.initialized) return;
|
|
6175
|
+
if (this.initPromise) return this.initPromise;
|
|
6176
|
+
return this.startInitialization();
|
|
6177
|
+
}
|
|
6178
|
+
startInitialization() {
|
|
6179
|
+
this.initPromise = this.migrationManager.migrate().then(() => {
|
|
6180
|
+
this.initialized = true;
|
|
6181
|
+
});
|
|
6182
|
+
void this.initPromise.catch(() => void 0);
|
|
6183
|
+
return this.initPromise;
|
|
6184
|
+
}
|
|
6185
|
+
async dispose() {
|
|
6186
|
+
if (this.ownsPool) await this.pool.end();
|
|
6187
|
+
}
|
|
6188
|
+
async ensureInitialized() {
|
|
6189
|
+
if (!this.initialized) await this.initialize();
|
|
6190
|
+
}
|
|
6191
|
+
async list(tenantId, assistantId) {
|
|
6192
|
+
await this.ensureInitialized();
|
|
6193
|
+
const result = assistantId === void 0 ? await this.pool.query(
|
|
6194
|
+
`SELECT * FROM lattice_agent_web_apps
|
|
6195
|
+
WHERE tenant_id = $1
|
|
6196
|
+
ORDER BY created_at DESC, id DESC`,
|
|
6197
|
+
[tenantId]
|
|
6198
|
+
) : await this.pool.query(
|
|
6199
|
+
`SELECT * FROM lattice_agent_web_apps
|
|
6200
|
+
WHERE tenant_id = $1 AND assistant_id = $2
|
|
6201
|
+
ORDER BY created_at DESC, id DESC`,
|
|
6202
|
+
[tenantId, assistantId]
|
|
6203
|
+
);
|
|
6204
|
+
return result.rows.map(mapRow);
|
|
6205
|
+
}
|
|
6206
|
+
async getById(tenantId, webAppId) {
|
|
6207
|
+
await this.ensureInitialized();
|
|
6208
|
+
const result = await this.pool.query(
|
|
6209
|
+
`SELECT * FROM lattice_agent_web_apps
|
|
6210
|
+
WHERE tenant_id = $1 AND id = $2`,
|
|
6211
|
+
[tenantId, webAppId]
|
|
6212
|
+
);
|
|
6213
|
+
return result.rows[0] ? mapRow(result.rows[0]) : null;
|
|
6214
|
+
}
|
|
6215
|
+
async findById(webAppId) {
|
|
6216
|
+
await this.ensureInitialized();
|
|
6217
|
+
const result = await this.pool.query(
|
|
6218
|
+
`SELECT * FROM lattice_agent_web_apps
|
|
6219
|
+
WHERE id = $1`,
|
|
6220
|
+
[webAppId]
|
|
6221
|
+
);
|
|
6222
|
+
return result.rows[0] ? mapRow(result.rows[0]) : null;
|
|
6223
|
+
}
|
|
6224
|
+
async create(tenantId, input) {
|
|
6225
|
+
await this.ensureInitialized();
|
|
6226
|
+
const id = `webapp_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`;
|
|
6227
|
+
const result = await this.pool.query(
|
|
6228
|
+
`INSERT INTO lattice_agent_web_apps
|
|
6229
|
+
(id, tenant_id, assistant_id, name, description, status, integration, scope, features, appearance)
|
|
6230
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8::jsonb, $9::jsonb, $10::jsonb)
|
|
6231
|
+
RETURNING *`,
|
|
6232
|
+
[
|
|
6233
|
+
id,
|
|
6234
|
+
tenantId,
|
|
6235
|
+
input.assistantId,
|
|
6236
|
+
input.name,
|
|
6237
|
+
input.description ?? null,
|
|
6238
|
+
"draft",
|
|
6239
|
+
JSON.stringify(input.integration),
|
|
6240
|
+
JSON.stringify(input.scope),
|
|
6241
|
+
JSON.stringify(input.features),
|
|
6242
|
+
JSON.stringify(input.appearance)
|
|
6243
|
+
]
|
|
6244
|
+
);
|
|
6245
|
+
return mapRow(result.rows[0]);
|
|
6246
|
+
}
|
|
6247
|
+
async update(tenantId, webAppId, patch, options) {
|
|
6248
|
+
await this.ensureInitialized();
|
|
6249
|
+
const assignments = [];
|
|
6250
|
+
const values = [];
|
|
6251
|
+
const add = (column, value) => {
|
|
6252
|
+
values.push(value);
|
|
6253
|
+
assignments.push(`${column} = $${values.length}`);
|
|
6254
|
+
};
|
|
6255
|
+
if (patch.name !== void 0) add("name", patch.name);
|
|
6256
|
+
if (Object.prototype.hasOwnProperty.call(patch, "description")) {
|
|
6257
|
+
add("description", patch.description ?? null);
|
|
6258
|
+
}
|
|
6259
|
+
if (patch.scope !== void 0) {
|
|
6260
|
+
add("scope", JSON.stringify(patch.scope));
|
|
6261
|
+
}
|
|
6262
|
+
if (patch.features !== void 0) {
|
|
6263
|
+
add("features", JSON.stringify(patch.features));
|
|
6264
|
+
}
|
|
6265
|
+
if (patch.appearance !== void 0) {
|
|
6266
|
+
add("appearance", JSON.stringify(patch.appearance));
|
|
6267
|
+
}
|
|
6268
|
+
if (patch.status !== void 0) add("status", patch.status);
|
|
6269
|
+
if (assignments.length === 0) return this.getById(tenantId, webAppId);
|
|
6270
|
+
values.push(tenantId, webAppId);
|
|
6271
|
+
const tenantParam = values.length - 1;
|
|
6272
|
+
const idParam = values.length;
|
|
6273
|
+
const expectedUpdatedAtClause = options?.expectedUpdatedAt ? ` AND date_trunc('milliseconds', updated_at) = $${values.push(options.expectedUpdatedAt)}` : "";
|
|
6274
|
+
const result = await this.pool.query(
|
|
6275
|
+
`UPDATE lattice_agent_web_apps
|
|
6276
|
+
SET ${assignments.join(", ")}, updated_at = GREATEST(
|
|
6277
|
+
date_trunc('milliseconds', clock_timestamp()),
|
|
6278
|
+
updated_at + interval '1 millisecond'
|
|
6279
|
+
)
|
|
6280
|
+
WHERE tenant_id = $${tenantParam} AND id = $${idParam}${expectedUpdatedAtClause}
|
|
6281
|
+
RETURNING *`,
|
|
6282
|
+
values
|
|
6283
|
+
);
|
|
6284
|
+
return result.rows[0] ? mapRow(result.rows[0]) : null;
|
|
6285
|
+
}
|
|
6286
|
+
async delete(tenantId, webAppId) {
|
|
6287
|
+
await this.ensureInitialized();
|
|
6288
|
+
const result = await this.pool.query(
|
|
6289
|
+
`DELETE FROM lattice_agent_web_apps
|
|
6290
|
+
WHERE tenant_id = $1 AND id = $2`,
|
|
6291
|
+
[tenantId, webAppId]
|
|
6292
|
+
);
|
|
6293
|
+
return result.rowCount === 1;
|
|
6294
|
+
}
|
|
6295
|
+
};
|
|
6296
|
+
|
|
6297
|
+
// src/stores/PostgreSQLScheduleStorage.ts
|
|
6298
|
+
var import_pg18 = require("pg");
|
|
6013
6299
|
var import_protocols = require("@axiom-lattice/protocols");
|
|
6014
6300
|
|
|
6015
6301
|
// src/migrations/schedule_migrations.ts
|
|
@@ -6184,9 +6470,9 @@ var PostgreSQLScheduleStorage = class {
|
|
|
6184
6470
|
return;
|
|
6185
6471
|
}
|
|
6186
6472
|
if (typeof options.poolConfig === "string") {
|
|
6187
|
-
this.pool = new
|
|
6473
|
+
this.pool = new import_pg18.Pool({ connectionString: options.poolConfig });
|
|
6188
6474
|
} else if (options.poolConfig) {
|
|
6189
|
-
this.pool = new
|
|
6475
|
+
this.pool = new import_pg18.Pool(options.poolConfig);
|
|
6190
6476
|
} else {
|
|
6191
6477
|
throw new Error("Either pool or poolConfig must be provided");
|
|
6192
6478
|
}
|
|
@@ -6624,7 +6910,7 @@ var PostgreSQLScheduleStorage = class {
|
|
|
6624
6910
|
};
|
|
6625
6911
|
|
|
6626
6912
|
// src/stores/PostgreSQLTaskStore.ts
|
|
6627
|
-
var
|
|
6913
|
+
var import_pg19 = require("pg");
|
|
6628
6914
|
|
|
6629
6915
|
// src/migrations/task_migration.ts
|
|
6630
6916
|
var createTasksTable = {
|
|
@@ -6723,6 +7009,49 @@ var taskMigrations = [
|
|
|
6723
7009
|
|
|
6724
7010
|
// src/stores/PostgreSQLTaskStore.ts
|
|
6725
7011
|
var import_uuid3 = require("uuid");
|
|
7012
|
+
function nextUpdatedAtSql(column = "updated_at") {
|
|
7013
|
+
return `to_char(
|
|
7014
|
+
date_trunc('milliseconds', GREATEST(
|
|
7015
|
+
clock_timestamp(),
|
|
7016
|
+
CASE
|
|
7017
|
+
WHEN ${canonicalTimestampValidationSql(column)}
|
|
7018
|
+
THEN ${column}::timestamptz + interval '1 millisecond'
|
|
7019
|
+
ELSE clock_timestamp()
|
|
7020
|
+
END
|
|
7021
|
+
))
|
|
7022
|
+
AT TIME ZONE 'UTC',
|
|
7023
|
+
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
7024
|
+
)`;
|
|
7025
|
+
}
|
|
7026
|
+
function canonicalTimestampValidationSql(column, allowMaximum = false) {
|
|
7027
|
+
const year = `substring(${column} FROM 1 FOR 4)::integer`;
|
|
7028
|
+
const month = `substring(${column} FROM 6 FOR 2)::integer`;
|
|
7029
|
+
const day = `substring(${column} FROM 9 FOR 2)::integer`;
|
|
7030
|
+
return `CASE
|
|
7031
|
+
WHEN ${column} ~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[.][0-9]{3}Z$' THEN
|
|
7032
|
+
${allowMaximum ? "" : `${column} <> '9999-12-31T23:59:59.999Z' AND`}
|
|
7033
|
+
${year} BETWEEN 1 AND 9999
|
|
7034
|
+
AND ${month} BETWEEN 1 AND 12
|
|
7035
|
+
AND ${day} BETWEEN 1 AND CASE
|
|
7036
|
+
WHEN ${month} = 2 THEN CASE
|
|
7037
|
+
WHEN (${year} % 400 = 0) OR (${year} % 4 = 0 AND ${year} % 100 <> 0) THEN 29
|
|
7038
|
+
ELSE 28
|
|
7039
|
+
END
|
|
7040
|
+
WHEN ${month} IN (4, 6, 9, 11) THEN 30
|
|
7041
|
+
ELSE 31
|
|
7042
|
+
END
|
|
7043
|
+
AND substring(${column} FROM 12 FOR 2)::integer BETWEEN 0 AND 23
|
|
7044
|
+
AND substring(${column} FROM 15 FOR 2)::integer BETWEEN 0 AND 59
|
|
7045
|
+
AND substring(${column} FROM 18 FOR 2)::integer BETWEEN 0 AND 59
|
|
7046
|
+
ELSE FALSE
|
|
7047
|
+
END`;
|
|
7048
|
+
}
|
|
7049
|
+
function canonicalTimestampSnapshotSql(column, parameter, allowMaximum = false) {
|
|
7050
|
+
return `CASE WHEN ${canonicalTimestampValidationSql(column, allowMaximum)}
|
|
7051
|
+
THEN ${column}::timestamptz = ${parameter}::timestamptz
|
|
7052
|
+
ELSE FALSE
|
|
7053
|
+
END`;
|
|
7054
|
+
}
|
|
6726
7055
|
function parseTaskFiles(raw) {
|
|
6727
7056
|
if (!raw) return void 0;
|
|
6728
7057
|
try {
|
|
@@ -6771,9 +7100,9 @@ var PostgreSQLTaskStore = class {
|
|
|
6771
7100
|
return;
|
|
6772
7101
|
}
|
|
6773
7102
|
if (typeof options.poolConfig === "string") {
|
|
6774
|
-
this.pool = new
|
|
7103
|
+
this.pool = new import_pg19.Pool({ connectionString: options.poolConfig });
|
|
6775
7104
|
} else if (options.poolConfig) {
|
|
6776
|
-
this.pool = new
|
|
7105
|
+
this.pool = new import_pg19.Pool(options.poolConfig);
|
|
6777
7106
|
} else {
|
|
6778
7107
|
throw new Error("Either pool or poolConfig must be provided");
|
|
6779
7108
|
}
|
|
@@ -6808,7 +7137,7 @@ var PostgreSQLTaskStore = class {
|
|
|
6808
7137
|
}
|
|
6809
7138
|
async create(params) {
|
|
6810
7139
|
await this.ensureInitialized();
|
|
6811
|
-
const id = (0, import_uuid3.v4)();
|
|
7140
|
+
const id = params.id ?? (0, import_uuid3.v4)();
|
|
6812
7141
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6813
7142
|
await this.pool.query(
|
|
6814
7143
|
`INSERT INTO lattice_tasks (id, tenant_id, owner_type, owner_id, title, description, status, priority, due_date, metadata, parent_id, source_id, context, require_review, dependencies, result, failure_reason, workspace_id, project_id, files, created_at, updated_at)
|
|
@@ -6952,7 +7281,7 @@ var PostgreSQLTaskStore = class {
|
|
|
6952
7281
|
}
|
|
6953
7282
|
if (updates.context !== void 0) {
|
|
6954
7283
|
setClauses.push(`context = $${paramIndex++}`);
|
|
6955
|
-
params.push(JSON.stringify(updates.context));
|
|
7284
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
6956
7285
|
}
|
|
6957
7286
|
if (updates.ownerType !== void 0) {
|
|
6958
7287
|
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
@@ -6989,103 +7318,537 @@ var PostgreSQLTaskStore = class {
|
|
|
6989
7318
|
if (setClauses.length === 0) {
|
|
6990
7319
|
return existing;
|
|
6991
7320
|
}
|
|
6992
|
-
setClauses.push(`updated_at =
|
|
6993
|
-
params.push((/* @__PURE__ */ new Date()).toISOString());
|
|
7321
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
6994
7322
|
params.push(tenantId, id);
|
|
6995
|
-
await this.pool.query(
|
|
6996
|
-
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex++}
|
|
7323
|
+
const result = await this.pool.query(
|
|
7324
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex++} AND updated_at <> '9999-12-31T23:59:59.999Z' RETURNING *`,
|
|
6997
7325
|
params
|
|
6998
7326
|
);
|
|
6999
|
-
return
|
|
7327
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7000
7328
|
}
|
|
7001
|
-
|
|
7329
|
+
/**
|
|
7330
|
+
* Atomically update a task unless its current status is blocked.
|
|
7331
|
+
*
|
|
7332
|
+
* @param tenantId Tenant identifier.
|
|
7333
|
+
* @param id Task identifier.
|
|
7334
|
+
* @param updates Partial task data to update.
|
|
7335
|
+
* @param blockedStatuses Current statuses that prevent the update.
|
|
7336
|
+
* @returns The updated task, or `null` when missing or blocked.
|
|
7337
|
+
*/
|
|
7338
|
+
async updateIfStatusNotIn(tenantId, id, updates, blockedStatuses) {
|
|
7002
7339
|
await this.ensureInitialized();
|
|
7003
|
-
const
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
)
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
async dispose() {
|
|
7010
|
-
if (this.ownsPool && this.pool) {
|
|
7011
|
-
await this.pool.end();
|
|
7340
|
+
const setClauses = [];
|
|
7341
|
+
const params = [];
|
|
7342
|
+
let paramIndex = 1;
|
|
7343
|
+
if (updates.title !== void 0) {
|
|
7344
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7345
|
+
params.push(updates.title);
|
|
7012
7346
|
}
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
await this.initialize();
|
|
7347
|
+
if (updates.description !== void 0) {
|
|
7348
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7349
|
+
params.push(updates.description);
|
|
7017
7350
|
}
|
|
7018
|
-
|
|
7019
|
-
};
|
|
7020
|
-
|
|
7021
|
-
// src/stores/PostgreSQLTaskWorkItemStore.ts
|
|
7022
|
-
var import_uuid4 = require("uuid");
|
|
7023
|
-
var PostgreSQLTaskWorkItemStore = class {
|
|
7024
|
-
constructor(pool) {
|
|
7025
|
-
this.pool = pool;
|
|
7026
|
-
}
|
|
7027
|
-
async create(params) {
|
|
7028
|
-
const id = (0, import_uuid4.v4)();
|
|
7029
|
-
const result = await this.pool.query(
|
|
7030
|
-
`INSERT INTO lattice_task_work_items
|
|
7031
|
-
(id, tenant_id, task_id, action, actor, thread_id, summary, detail, attempt, workspace_id, project_id)
|
|
7032
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
7033
|
-
RETURNING *`,
|
|
7034
|
-
[
|
|
7035
|
-
id,
|
|
7036
|
-
params.tenantId,
|
|
7037
|
-
params.taskId,
|
|
7038
|
-
params.action,
|
|
7039
|
-
params.actor,
|
|
7040
|
-
params.threadId || null,
|
|
7041
|
-
params.summary || null,
|
|
7042
|
-
params.detail ? JSON.stringify(params.detail) : null,
|
|
7043
|
-
params.attempt || null,
|
|
7044
|
-
params.workspaceId || null,
|
|
7045
|
-
params.projectId || null
|
|
7046
|
-
]
|
|
7047
|
-
);
|
|
7048
|
-
return this.rowToItem(result.rows[0]);
|
|
7049
|
-
}
|
|
7050
|
-
async list(filter) {
|
|
7051
|
-
let query = `SELECT * FROM lattice_task_work_items WHERE tenant_id = $1 AND task_id = $2`;
|
|
7052
|
-
const params = [filter.tenantId, filter.taskId];
|
|
7053
|
-
if (filter.action) {
|
|
7054
|
-
query += ` AND action = $${params.length + 1}`;
|
|
7055
|
-
params.push(filter.action);
|
|
7351
|
+
if (updates.status !== void 0) {
|
|
7352
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7353
|
+
params.push(updates.status);
|
|
7056
7354
|
}
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
params.push(filter.limit);
|
|
7355
|
+
if (updates.priority !== void 0) {
|
|
7356
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7357
|
+
params.push(updates.priority);
|
|
7061
7358
|
}
|
|
7062
|
-
if (
|
|
7063
|
-
|
|
7064
|
-
params.push(
|
|
7359
|
+
if (updates.dueDate !== void 0) {
|
|
7360
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7361
|
+
params.push(updates.dueDate);
|
|
7065
7362
|
}
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7363
|
+
if (updates.metadata !== void 0) {
|
|
7364
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7365
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7366
|
+
}
|
|
7367
|
+
if (updates.files !== void 0) {
|
|
7368
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7369
|
+
params.push(JSON.stringify(updates.files));
|
|
7370
|
+
}
|
|
7371
|
+
if (updates.parentId !== void 0) {
|
|
7372
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7373
|
+
params.push(updates.parentId);
|
|
7374
|
+
}
|
|
7375
|
+
if (updates.sourceId !== void 0) {
|
|
7376
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7377
|
+
params.push(updates.sourceId);
|
|
7378
|
+
}
|
|
7379
|
+
if (updates.context !== void 0) {
|
|
7380
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7381
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7382
|
+
}
|
|
7383
|
+
if (updates.ownerType !== void 0) {
|
|
7384
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7385
|
+
params.push(updates.ownerType);
|
|
7386
|
+
}
|
|
7387
|
+
if (updates.ownerId !== void 0) {
|
|
7388
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7389
|
+
params.push(updates.ownerId);
|
|
7390
|
+
}
|
|
7391
|
+
if (updates.requireReview !== void 0) {
|
|
7392
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7393
|
+
params.push(updates.requireReview);
|
|
7394
|
+
}
|
|
7395
|
+
if (updates.dependencies !== void 0) {
|
|
7396
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7397
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7398
|
+
}
|
|
7399
|
+
if (updates.result !== void 0) {
|
|
7400
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7401
|
+
params.push(updates.result);
|
|
7402
|
+
}
|
|
7403
|
+
if (updates.failureReason !== void 0) {
|
|
7404
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7405
|
+
params.push(updates.failureReason);
|
|
7406
|
+
}
|
|
7407
|
+
if (updates.workspaceId !== void 0) {
|
|
7408
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7409
|
+
params.push(updates.workspaceId);
|
|
7410
|
+
}
|
|
7411
|
+
if (updates.projectId !== void 0) {
|
|
7412
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7413
|
+
params.push(updates.projectId);
|
|
7414
|
+
}
|
|
7415
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
7416
|
+
const tenantParam = paramIndex++;
|
|
7417
|
+
const idParam = paramIndex++;
|
|
7418
|
+
params.push(tenantId, id);
|
|
7419
|
+
const blockedClause = blockedStatuses.length > 0 ? ` AND status <> ALL($${paramIndex}::text[])` : "";
|
|
7420
|
+
if (blockedStatuses.length > 0) params.push(blockedStatuses);
|
|
7421
|
+
const result = await this.pool.query(
|
|
7422
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${tenantParam} AND id = $${idParam} AND updated_at <> '9999-12-31T23:59:59.999Z'${blockedClause} RETURNING *`,
|
|
7423
|
+
params
|
|
7424
|
+
);
|
|
7425
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7426
|
+
}
|
|
7427
|
+
/** Atomically update a task only when its current status is expected. */
|
|
7428
|
+
async updateIfStatusIn(tenantId, id, updates, expectedStatuses) {
|
|
7429
|
+
await this.ensureInitialized();
|
|
7430
|
+
if (expectedStatuses.length === 0) return null;
|
|
7431
|
+
const setClauses = [];
|
|
7432
|
+
const params = [];
|
|
7433
|
+
let paramIndex = 1;
|
|
7434
|
+
if (updates.title !== void 0) {
|
|
7435
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7436
|
+
params.push(updates.title);
|
|
7437
|
+
}
|
|
7438
|
+
if (updates.description !== void 0) {
|
|
7439
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7440
|
+
params.push(updates.description);
|
|
7441
|
+
}
|
|
7442
|
+
if (updates.status !== void 0) {
|
|
7443
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7444
|
+
params.push(updates.status);
|
|
7445
|
+
}
|
|
7446
|
+
if (updates.priority !== void 0) {
|
|
7447
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7448
|
+
params.push(updates.priority);
|
|
7449
|
+
}
|
|
7450
|
+
if (updates.dueDate !== void 0) {
|
|
7451
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7452
|
+
params.push(updates.dueDate);
|
|
7453
|
+
}
|
|
7454
|
+
if (updates.metadata !== void 0) {
|
|
7455
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7456
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7457
|
+
}
|
|
7458
|
+
if (updates.files !== void 0) {
|
|
7459
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7460
|
+
params.push(JSON.stringify(updates.files));
|
|
7461
|
+
}
|
|
7462
|
+
if (updates.parentId !== void 0) {
|
|
7463
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7464
|
+
params.push(updates.parentId);
|
|
7465
|
+
}
|
|
7466
|
+
if (updates.sourceId !== void 0) {
|
|
7467
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7468
|
+
params.push(updates.sourceId);
|
|
7469
|
+
}
|
|
7470
|
+
if (updates.context !== void 0) {
|
|
7471
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7472
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7473
|
+
}
|
|
7474
|
+
if (updates.ownerType !== void 0) {
|
|
7475
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7476
|
+
params.push(updates.ownerType);
|
|
7477
|
+
}
|
|
7478
|
+
if (updates.ownerId !== void 0) {
|
|
7479
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7480
|
+
params.push(updates.ownerId);
|
|
7481
|
+
}
|
|
7482
|
+
if (updates.requireReview !== void 0) {
|
|
7483
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7484
|
+
params.push(updates.requireReview);
|
|
7485
|
+
}
|
|
7486
|
+
if (updates.dependencies !== void 0) {
|
|
7487
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7488
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7489
|
+
}
|
|
7490
|
+
if (updates.result !== void 0) {
|
|
7491
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7492
|
+
params.push(updates.result);
|
|
7493
|
+
}
|
|
7494
|
+
if (updates.failureReason !== void 0) {
|
|
7495
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7496
|
+
params.push(updates.failureReason);
|
|
7497
|
+
}
|
|
7498
|
+
if (updates.workspaceId !== void 0) {
|
|
7499
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7500
|
+
params.push(updates.workspaceId);
|
|
7501
|
+
}
|
|
7502
|
+
if (updates.projectId !== void 0) {
|
|
7503
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7504
|
+
params.push(updates.projectId);
|
|
7505
|
+
}
|
|
7506
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
7507
|
+
const tenantParam = paramIndex++;
|
|
7508
|
+
const idParam = paramIndex++;
|
|
7509
|
+
const statusesParam = paramIndex++;
|
|
7510
|
+
params.push(tenantId, id, expectedStatuses);
|
|
7511
|
+
const result = await this.pool.query(
|
|
7512
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${tenantParam} AND id = $${idParam} AND updated_at <> '9999-12-31T23:59:59.999Z' AND status = ANY($${statusesParam}::text[]) RETURNING *`,
|
|
7513
|
+
params
|
|
7514
|
+
);
|
|
7515
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7516
|
+
}
|
|
7517
|
+
/** Atomically update a task only when status and updatedAt match a read snapshot. */
|
|
7518
|
+
async updateIfStatusAndUpdatedAt(tenantId, id, updates, expectedStatuses, expectedUpdatedAt) {
|
|
7519
|
+
await this.ensureInitialized();
|
|
7520
|
+
if (expectedStatuses.length === 0) return null;
|
|
7521
|
+
const expectedIso = new Date(expectedUpdatedAt).toISOString();
|
|
7522
|
+
const setClauses = [];
|
|
7523
|
+
const params = [];
|
|
7524
|
+
let paramIndex = 1;
|
|
7525
|
+
if (updates.title !== void 0) {
|
|
7526
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7527
|
+
params.push(updates.title);
|
|
7528
|
+
}
|
|
7529
|
+
if (updates.description !== void 0) {
|
|
7530
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7531
|
+
params.push(updates.description);
|
|
7532
|
+
}
|
|
7533
|
+
if (updates.status !== void 0) {
|
|
7534
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7535
|
+
params.push(updates.status);
|
|
7536
|
+
}
|
|
7537
|
+
if (updates.priority !== void 0) {
|
|
7538
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7539
|
+
params.push(updates.priority);
|
|
7540
|
+
}
|
|
7541
|
+
if (updates.dueDate !== void 0) {
|
|
7542
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7543
|
+
params.push(updates.dueDate);
|
|
7544
|
+
}
|
|
7545
|
+
if (updates.metadata !== void 0) {
|
|
7546
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7547
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7548
|
+
}
|
|
7549
|
+
if (updates.files !== void 0) {
|
|
7550
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7551
|
+
params.push(JSON.stringify(updates.files));
|
|
7552
|
+
}
|
|
7553
|
+
if (updates.parentId !== void 0) {
|
|
7554
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7555
|
+
params.push(updates.parentId);
|
|
7556
|
+
}
|
|
7557
|
+
if (updates.sourceId !== void 0) {
|
|
7558
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7559
|
+
params.push(updates.sourceId);
|
|
7560
|
+
}
|
|
7561
|
+
if (updates.context !== void 0) {
|
|
7562
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7563
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7564
|
+
}
|
|
7565
|
+
if (updates.ownerType !== void 0) {
|
|
7566
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7567
|
+
params.push(updates.ownerType);
|
|
7568
|
+
}
|
|
7569
|
+
if (updates.ownerId !== void 0) {
|
|
7570
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7571
|
+
params.push(updates.ownerId);
|
|
7572
|
+
}
|
|
7573
|
+
if (updates.requireReview !== void 0) {
|
|
7574
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7575
|
+
params.push(updates.requireReview);
|
|
7576
|
+
}
|
|
7577
|
+
if (updates.dependencies !== void 0) {
|
|
7578
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7579
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7580
|
+
}
|
|
7581
|
+
if (updates.result !== void 0) {
|
|
7582
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7583
|
+
params.push(updates.result);
|
|
7584
|
+
}
|
|
7585
|
+
if (updates.failureReason !== void 0) {
|
|
7586
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7587
|
+
params.push(updates.failureReason);
|
|
7588
|
+
}
|
|
7589
|
+
if (updates.workspaceId !== void 0) {
|
|
7590
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7591
|
+
params.push(updates.workspaceId);
|
|
7592
|
+
}
|
|
7593
|
+
if (updates.projectId !== void 0) {
|
|
7594
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7595
|
+
params.push(updates.projectId);
|
|
7596
|
+
}
|
|
7597
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
7598
|
+
const tenantParam = paramIndex++;
|
|
7599
|
+
const idParam = paramIndex++;
|
|
7600
|
+
const statusesParam = paramIndex++;
|
|
7601
|
+
const updatedAtParam = paramIndex++;
|
|
7602
|
+
params.push(tenantId, id, expectedStatuses, expectedIso);
|
|
7603
|
+
const result = await this.pool.query(
|
|
7604
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${tenantParam} AND id = $${idParam} AND status = ANY($${statusesParam}::text[]) AND ${canonicalTimestampSnapshotSql("updated_at", `$${updatedAtParam}`)} RETURNING *`,
|
|
7605
|
+
params
|
|
7606
|
+
);
|
|
7607
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7608
|
+
}
|
|
7609
|
+
/** Atomically update a child only when both child and parent snapshots match. */
|
|
7610
|
+
async updateIfStatusUpdatedAtAndParentUpdatedAt(tenantId, id, updates, expectedStatuses, expectedUpdatedAt, parentId, expectedParentUpdatedAt) {
|
|
7611
|
+
await this.ensureInitialized();
|
|
7612
|
+
if (expectedStatuses.length === 0) return null;
|
|
7613
|
+
const setClauses = [];
|
|
7614
|
+
const params = [];
|
|
7615
|
+
let paramIndex = 1;
|
|
7616
|
+
if (updates.title !== void 0) {
|
|
7617
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7618
|
+
params.push(updates.title);
|
|
7619
|
+
}
|
|
7620
|
+
if (updates.description !== void 0) {
|
|
7621
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7622
|
+
params.push(updates.description);
|
|
7623
|
+
}
|
|
7624
|
+
if (updates.status !== void 0) {
|
|
7625
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7626
|
+
params.push(updates.status);
|
|
7627
|
+
}
|
|
7628
|
+
if (updates.priority !== void 0) {
|
|
7629
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7630
|
+
params.push(updates.priority);
|
|
7631
|
+
}
|
|
7632
|
+
if (updates.dueDate !== void 0) {
|
|
7633
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7634
|
+
params.push(updates.dueDate);
|
|
7635
|
+
}
|
|
7636
|
+
if (updates.metadata !== void 0) {
|
|
7637
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7638
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7639
|
+
}
|
|
7640
|
+
if (updates.files !== void 0) {
|
|
7641
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7642
|
+
params.push(JSON.stringify(updates.files));
|
|
7643
|
+
}
|
|
7644
|
+
if (updates.parentId !== void 0) {
|
|
7645
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7646
|
+
params.push(updates.parentId);
|
|
7647
|
+
}
|
|
7648
|
+
if (updates.sourceId !== void 0) {
|
|
7649
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7650
|
+
params.push(updates.sourceId);
|
|
7651
|
+
}
|
|
7652
|
+
if (updates.context !== void 0) {
|
|
7653
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7654
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7655
|
+
}
|
|
7656
|
+
if (updates.ownerType !== void 0) {
|
|
7657
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7658
|
+
params.push(updates.ownerType);
|
|
7659
|
+
}
|
|
7660
|
+
if (updates.ownerId !== void 0) {
|
|
7661
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7662
|
+
params.push(updates.ownerId);
|
|
7663
|
+
}
|
|
7664
|
+
if (updates.requireReview !== void 0) {
|
|
7665
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7666
|
+
params.push(updates.requireReview);
|
|
7667
|
+
}
|
|
7668
|
+
if (updates.dependencies !== void 0) {
|
|
7669
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7670
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7671
|
+
}
|
|
7672
|
+
if (updates.result !== void 0) {
|
|
7673
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7674
|
+
params.push(updates.result);
|
|
7675
|
+
}
|
|
7676
|
+
if (updates.failureReason !== void 0) {
|
|
7677
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7678
|
+
params.push(updates.failureReason);
|
|
7679
|
+
}
|
|
7680
|
+
if (updates.workspaceId !== void 0) {
|
|
7681
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7682
|
+
params.push(updates.workspaceId);
|
|
7683
|
+
}
|
|
7684
|
+
if (updates.projectId !== void 0) {
|
|
7685
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7686
|
+
params.push(updates.projectId);
|
|
7687
|
+
}
|
|
7688
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql("child.updated_at")}`);
|
|
7689
|
+
const tenantParam = paramIndex++;
|
|
7690
|
+
const idParam = paramIndex++;
|
|
7691
|
+
const statusesParam = paramIndex++;
|
|
7692
|
+
const updatedAtParam = paramIndex++;
|
|
7693
|
+
const parentIdParam = paramIndex++;
|
|
7694
|
+
const parentUpdatedAtParam = paramIndex++;
|
|
7695
|
+
params.push(
|
|
7696
|
+
tenantId,
|
|
7697
|
+
id,
|
|
7698
|
+
expectedStatuses,
|
|
7699
|
+
new Date(expectedUpdatedAt).toISOString(),
|
|
7700
|
+
parentId,
|
|
7701
|
+
new Date(expectedParentUpdatedAt).toISOString()
|
|
7702
|
+
);
|
|
7703
|
+
const result = await this.pool.query(
|
|
7704
|
+
`UPDATE lattice_tasks AS child SET ${setClauses.join(", ")}
|
|
7705
|
+
WHERE child.tenant_id = $${tenantParam} AND child.id = $${idParam}
|
|
7706
|
+
AND child.status = ANY($${statusesParam}::text[])
|
|
7707
|
+
AND ${canonicalTimestampSnapshotSql("child.updated_at", `$${updatedAtParam}`)}
|
|
7708
|
+
AND EXISTS (
|
|
7709
|
+
SELECT 1 FROM lattice_tasks AS parent
|
|
7710
|
+
WHERE parent.tenant_id = child.tenant_id
|
|
7711
|
+
AND parent.id = $${parentIdParam}
|
|
7712
|
+
AND ${canonicalTimestampSnapshotSql("parent.updated_at", `$${parentUpdatedAtParam}`, true)}
|
|
7713
|
+
)
|
|
7714
|
+
RETURNING child.*`,
|
|
7715
|
+
params
|
|
7716
|
+
);
|
|
7717
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7718
|
+
}
|
|
7719
|
+
async delete(tenantId, id) {
|
|
7720
|
+
await this.ensureInitialized();
|
|
7721
|
+
const result = await this.pool.query(
|
|
7722
|
+
`DELETE FROM lattice_tasks WHERE tenant_id = $1 AND id = $2`,
|
|
7723
|
+
[tenantId, id]
|
|
7724
|
+
);
|
|
7725
|
+
return (result.rowCount ?? 0) > 0;
|
|
7726
|
+
}
|
|
7727
|
+
async dispose() {
|
|
7728
|
+
if (this.ownsPool && this.pool) {
|
|
7729
|
+
await this.pool.end();
|
|
7730
|
+
}
|
|
7731
|
+
}
|
|
7732
|
+
async ensureInitialized() {
|
|
7733
|
+
if (!this.initialized) {
|
|
7734
|
+
await this.initialize();
|
|
7735
|
+
}
|
|
7736
|
+
}
|
|
7737
|
+
};
|
|
7738
|
+
|
|
7739
|
+
// src/stores/PostgreSQLTaskWorkItemStore.ts
|
|
7740
|
+
var import_uuid4 = require("uuid");
|
|
7741
|
+
var PostgreSQLTaskWorkItemStore = class {
|
|
7742
|
+
constructor(pool) {
|
|
7743
|
+
this.pool = pool;
|
|
7744
|
+
}
|
|
7745
|
+
async create(params) {
|
|
7746
|
+
const id = (0, import_uuid4.v4)();
|
|
7747
|
+
const result = await this.pool.query(
|
|
7748
|
+
`INSERT INTO lattice_task_work_items
|
|
7749
|
+
(id, tenant_id, task_id, action, actor, thread_id, summary, detail, attempt, workspace_id, project_id)
|
|
7750
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
7751
|
+
RETURNING *`,
|
|
7752
|
+
[
|
|
7753
|
+
id,
|
|
7754
|
+
params.tenantId,
|
|
7755
|
+
params.taskId,
|
|
7756
|
+
params.action,
|
|
7757
|
+
params.actor,
|
|
7758
|
+
params.threadId || null,
|
|
7759
|
+
params.summary || null,
|
|
7760
|
+
params.detail ? JSON.stringify(params.detail) : null,
|
|
7761
|
+
params.attempt || null,
|
|
7762
|
+
params.workspaceId || null,
|
|
7763
|
+
params.projectId || null
|
|
7764
|
+
]
|
|
7765
|
+
);
|
|
7766
|
+
return this.rowToItem(result.rows[0]);
|
|
7767
|
+
}
|
|
7768
|
+
/** Find an event by its tenant- and task-scoped key without pagination. */
|
|
7769
|
+
async findByEventKey(tenantId, taskId, eventKey) {
|
|
7770
|
+
const result = await this.pool.query(
|
|
7771
|
+
`SELECT * FROM lattice_task_work_items
|
|
7772
|
+
WHERE tenant_id = $1 AND task_id = $2 AND event_key = $3`,
|
|
7773
|
+
[tenantId, taskId, eventKey]
|
|
7774
|
+
);
|
|
7775
|
+
return result.rows[0] ? this.rowToItem(result.rows[0]) : null;
|
|
7776
|
+
}
|
|
7777
|
+
/** Atomically return an existing event or create it once. */
|
|
7778
|
+
async createIfAbsentByEventKey(params) {
|
|
7779
|
+
const result = await this.pool.query(
|
|
7780
|
+
`INSERT INTO lattice_task_work_items
|
|
7781
|
+
(id, tenant_id, task_id, action, actor, thread_id, summary, detail, attempt, workspace_id, project_id, event_key)
|
|
7782
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
|
7783
|
+
ON CONFLICT (tenant_id, task_id, event_key) WHERE event_key IS NOT NULL
|
|
7784
|
+
DO UPDATE SET event_key = EXCLUDED.event_key
|
|
7785
|
+
RETURNING *`,
|
|
7786
|
+
[
|
|
7787
|
+
(0, import_uuid4.v4)(),
|
|
7788
|
+
params.tenantId,
|
|
7789
|
+
params.taskId,
|
|
7790
|
+
params.action,
|
|
7791
|
+
params.actor,
|
|
7792
|
+
params.threadId || null,
|
|
7793
|
+
params.summary || null,
|
|
7794
|
+
params.detail ? JSON.stringify(params.detail) : null,
|
|
7795
|
+
params.attempt ?? null,
|
|
7796
|
+
params.workspaceId || null,
|
|
7797
|
+
params.projectId || null,
|
|
7798
|
+
params.eventKey
|
|
7799
|
+
]
|
|
7800
|
+
);
|
|
7801
|
+
return this.rowToItem(result.rows[0]);
|
|
7802
|
+
}
|
|
7803
|
+
async list(filter) {
|
|
7804
|
+
let query = `SELECT * FROM lattice_task_work_items WHERE tenant_id = $1 AND task_id = $2`;
|
|
7805
|
+
const params = [filter.tenantId, filter.taskId];
|
|
7806
|
+
if (filter.action) {
|
|
7807
|
+
query += ` AND action = $${params.length + 1}`;
|
|
7808
|
+
params.push(filter.action);
|
|
7809
|
+
}
|
|
7810
|
+
if (filter.workspaceId) {
|
|
7811
|
+
query += ` AND workspace_id = $${params.length + 1}`;
|
|
7812
|
+
params.push(filter.workspaceId);
|
|
7813
|
+
}
|
|
7814
|
+
if (filter.projectId) {
|
|
7815
|
+
query += ` AND project_id = $${params.length + 1}`;
|
|
7816
|
+
params.push(filter.projectId);
|
|
7817
|
+
}
|
|
7818
|
+
const order = filter.order === "desc" ? "DESC" : "ASC";
|
|
7819
|
+
query += ` ORDER BY created_at ${order}, id ${order}`;
|
|
7820
|
+
if (filter.limit) {
|
|
7821
|
+
query += ` LIMIT $${params.length + 1}`;
|
|
7822
|
+
params.push(filter.limit);
|
|
7823
|
+
}
|
|
7824
|
+
if (filter.offset) {
|
|
7825
|
+
query += ` OFFSET $${params.length + 1}`;
|
|
7826
|
+
params.push(filter.offset);
|
|
7827
|
+
}
|
|
7828
|
+
const result = await this.pool.query(query, params);
|
|
7829
|
+
return result.rows.map((row) => this.rowToItem(row));
|
|
7830
|
+
}
|
|
7831
|
+
rowToItem(row) {
|
|
7832
|
+
return {
|
|
7833
|
+
id: row.id,
|
|
7834
|
+
taskId: row.task_id,
|
|
7835
|
+
tenantId: row.tenant_id,
|
|
7836
|
+
action: row.action,
|
|
7837
|
+
actor: row.actor,
|
|
7838
|
+
threadId: row.thread_id,
|
|
7839
|
+
summary: row.summary,
|
|
7840
|
+
detail: row.detail,
|
|
7841
|
+
attempt: row.attempt,
|
|
7842
|
+
workspaceId: row.workspace_id,
|
|
7843
|
+
projectId: row.project_id,
|
|
7844
|
+
eventKey: row.event_key == null ? void 0 : row.event_key,
|
|
7845
|
+
createdAt: new Date(row.created_at)
|
|
7846
|
+
};
|
|
7847
|
+
}
|
|
7085
7848
|
};
|
|
7086
7849
|
|
|
7087
7850
|
// src/stores/MenuStore.ts
|
|
7088
|
-
var
|
|
7851
|
+
var import_pg20 = require("pg");
|
|
7089
7852
|
|
|
7090
7853
|
// src/migrations/menu_items_migration.ts
|
|
7091
7854
|
var createMenuItemsTable = {
|
|
@@ -7162,7 +7925,7 @@ var MenuStore = class {
|
|
|
7162
7925
|
this.initialized = true;
|
|
7163
7926
|
return;
|
|
7164
7927
|
}
|
|
7165
|
-
this.pool = typeof options.poolConfig === "string" ? new
|
|
7928
|
+
this.pool = typeof options.poolConfig === "string" ? new import_pg20.Pool({ connectionString: options.poolConfig }) : options.poolConfig ? new import_pg20.Pool(options.poolConfig) : (() => {
|
|
7166
7929
|
throw new Error("Either pool or poolConfig must be provided");
|
|
7167
7930
|
})();
|
|
7168
7931
|
this.migrationManager = new MigrationManager(this.pool);
|
|
@@ -7317,7 +8080,7 @@ var MenuStore = class {
|
|
|
7317
8080
|
};
|
|
7318
8081
|
|
|
7319
8082
|
// src/stores/PostgresSharedResourceStore.ts
|
|
7320
|
-
var
|
|
8083
|
+
var import_pg21 = require("pg");
|
|
7321
8084
|
|
|
7322
8085
|
// src/migrations/shared_resources_migration.ts
|
|
7323
8086
|
var createSharedResourcesTable = {
|
|
@@ -7371,7 +8134,7 @@ var PostgresSharedResourceStore = class {
|
|
|
7371
8134
|
this.initialized = true;
|
|
7372
8135
|
return;
|
|
7373
8136
|
}
|
|
7374
|
-
this.pool = typeof options.poolConfig === "string" ? new
|
|
8137
|
+
this.pool = typeof options.poolConfig === "string" ? new import_pg21.Pool({ connectionString: options.poolConfig }) : options.poolConfig ? new import_pg21.Pool(options.poolConfig) : (() => {
|
|
7375
8138
|
throw new Error("Either pool or poolConfig must be provided");
|
|
7376
8139
|
})();
|
|
7377
8140
|
this.migrationManager = new MigrationManager(this.pool);
|
|
@@ -7540,7 +8303,7 @@ var PostgresSharedResourceStore = class {
|
|
|
7540
8303
|
};
|
|
7541
8304
|
|
|
7542
8305
|
// src/stores/PostgreSQLCollectionStore.ts
|
|
7543
|
-
var
|
|
8306
|
+
var import_pg22 = require("pg");
|
|
7544
8307
|
var PostgreSQLCollectionStore = class {
|
|
7545
8308
|
constructor(options) {
|
|
7546
8309
|
this.initialized = false;
|
|
@@ -7553,9 +8316,9 @@ var PostgreSQLCollectionStore = class {
|
|
|
7553
8316
|
return;
|
|
7554
8317
|
}
|
|
7555
8318
|
if (typeof options.poolConfig === "string") {
|
|
7556
|
-
this.pool = new
|
|
8319
|
+
this.pool = new import_pg22.Pool({ connectionString: options.poolConfig });
|
|
7557
8320
|
} else if (options.poolConfig) {
|
|
7558
|
-
this.pool = new
|
|
8321
|
+
this.pool = new import_pg22.Pool(options.poolConfig);
|
|
7559
8322
|
} else {
|
|
7560
8323
|
throw new Error("Either pool or poolConfig must be provided");
|
|
7561
8324
|
}
|
|
@@ -7670,7 +8433,7 @@ var PostgreSQLCollectionStore = class {
|
|
|
7670
8433
|
var import_langgraph_checkpoint_postgres = require("@langchain/langgraph-checkpoint-postgres");
|
|
7671
8434
|
|
|
7672
8435
|
// src/PGVectorStoreProvider.ts
|
|
7673
|
-
var
|
|
8436
|
+
var import_pg23 = require("pg");
|
|
7674
8437
|
var import_pgvector = require("@langchain/community/vectorstores/pgvector");
|
|
7675
8438
|
var import_documents = require("@langchain/core/documents");
|
|
7676
8439
|
var import_core6 = require("@axiom-lattice/core");
|
|
@@ -7744,7 +8507,7 @@ var PGVectorStoreProvider = class {
|
|
|
7744
8507
|
}
|
|
7745
8508
|
};
|
|
7746
8509
|
function createPGVectorStoreProvider(connectionString) {
|
|
7747
|
-
const pool = new
|
|
8510
|
+
const pool = new import_pg23.Pool({ connectionString });
|
|
7748
8511
|
return {
|
|
7749
8512
|
provider: new PGVectorStoreProvider(pool, connectionString),
|
|
7750
8513
|
pool
|
|
@@ -8078,10 +8841,24 @@ var addWorkItemProjectFieldsMigration = {
|
|
|
8078
8841
|
`);
|
|
8079
8842
|
}
|
|
8080
8843
|
};
|
|
8844
|
+
var addTaskWorkItemEventKeyMigration = {
|
|
8845
|
+
version: 168,
|
|
8846
|
+
name: "add_task_work_item_event_key",
|
|
8847
|
+
up: async (client) => {
|
|
8848
|
+
await client.query(`
|
|
8849
|
+
ALTER TABLE lattice_task_work_items
|
|
8850
|
+
ADD COLUMN IF NOT EXISTS event_key TEXT
|
|
8851
|
+
`);
|
|
8852
|
+
await client.query(`
|
|
8853
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_task_work_items_event_key
|
|
8854
|
+
ON lattice_task_work_items (tenant_id, task_id, event_key) WHERE event_key IS NOT NULL
|
|
8855
|
+
`);
|
|
8856
|
+
}
|
|
8857
|
+
};
|
|
8081
8858
|
|
|
8082
8859
|
// src/createPgStoreConfig.ts
|
|
8083
8860
|
async function createPgStoreConfig(connectionString) {
|
|
8084
|
-
const pool = new
|
|
8861
|
+
const pool = new import_pg24.Pool({ connectionString });
|
|
8085
8862
|
const mm = new MigrationManager(pool);
|
|
8086
8863
|
mm.register(createThreadsTable);
|
|
8087
8864
|
mm.register(createScheduledTasksTable);
|
|
@@ -8132,6 +8909,10 @@ async function createPgStoreConfig(connectionString) {
|
|
|
8132
8909
|
mm.register(addWorkItemProjectFieldsMigration);
|
|
8133
8910
|
mm.register(createConnectionConfigsTable);
|
|
8134
8911
|
mm.register(addWorkflowRunsTenantStatusUpdatedIndex);
|
|
8912
|
+
mm.register(addProjectKindColumn);
|
|
8913
|
+
mm.register(addA2AKeyAssistantIds);
|
|
8914
|
+
mm.register(addTaskWorkItemEventKeyMigration);
|
|
8915
|
+
mm.register(createAgentWebAppsTable);
|
|
8135
8916
|
await mm.migrate();
|
|
8136
8917
|
const checkpoint = import_langgraph_checkpoint_postgres.PostgresSaver.fromConnString(connectionString);
|
|
8137
8918
|
checkpoint.setup().catch((err) => {
|
|
@@ -8159,6 +8940,7 @@ async function createPgStoreConfig(connectionString) {
|
|
|
8159
8940
|
task: new PostgreSQLTaskStore(opts),
|
|
8160
8941
|
taskWorkItem: taskWorkItemStore,
|
|
8161
8942
|
a2aApiKey: new PostgreSQLA2AApiKeyStore(opts),
|
|
8943
|
+
agentWebApp: new PostgreSQLAgentWebAppStore(opts),
|
|
8162
8944
|
schedule: new PostgreSQLScheduleStorage(opts),
|
|
8163
8945
|
menu: new MenuStore(opts),
|
|
8164
8946
|
sharedResource: new PostgresSharedResourceStore(opts),
|
|
@@ -8169,7 +8951,7 @@ async function createPgStoreConfig(connectionString) {
|
|
|
8169
8951
|
}
|
|
8170
8952
|
|
|
8171
8953
|
// src/stores/PostgreSQLSkillStore.ts
|
|
8172
|
-
var
|
|
8954
|
+
var import_pg25 = require("pg");
|
|
8173
8955
|
var PostgreSQLSkillStore = class {
|
|
8174
8956
|
constructor(options) {
|
|
8175
8957
|
this.initialized = false;
|
|
@@ -8182,9 +8964,9 @@ var PostgreSQLSkillStore = class {
|
|
|
8182
8964
|
return;
|
|
8183
8965
|
}
|
|
8184
8966
|
if (typeof options.poolConfig === "string") {
|
|
8185
|
-
this.pool = new
|
|
8967
|
+
this.pool = new import_pg25.Pool({ connectionString: options.poolConfig });
|
|
8186
8968
|
} else if (options.poolConfig) {
|
|
8187
|
-
this.pool = new
|
|
8969
|
+
this.pool = new import_pg25.Pool(options.poolConfig);
|
|
8188
8970
|
} else {
|
|
8189
8971
|
throw new Error("Either pool or poolConfig must be provided");
|
|
8190
8972
|
}
|
|
@@ -8485,7 +9267,7 @@ var PostgreSQLSkillStore = class {
|
|
|
8485
9267
|
};
|
|
8486
9268
|
|
|
8487
9269
|
// src/stores/ChannelIdentityMappingStore.ts
|
|
8488
|
-
var
|
|
9270
|
+
var import_pg26 = require("pg");
|
|
8489
9271
|
var ChannelIdentityMappingStore = class {
|
|
8490
9272
|
constructor(options) {
|
|
8491
9273
|
this.initialized = false;
|
|
@@ -8497,7 +9279,7 @@ var ChannelIdentityMappingStore = class {
|
|
|
8497
9279
|
this.initialized = true;
|
|
8498
9280
|
return;
|
|
8499
9281
|
}
|
|
8500
|
-
this.pool = typeof options.poolConfig === "string" ? new
|
|
9282
|
+
this.pool = typeof options.poolConfig === "string" ? new import_pg26.Pool({ connectionString: options.poolConfig }) : options.poolConfig ? new import_pg26.Pool(options.poolConfig) : (() => {
|
|
8501
9283
|
throw new Error("Either pool or poolConfig must be provided");
|
|
8502
9284
|
})();
|
|
8503
9285
|
this.migrationManager = new MigrationManager(this.pool);
|
|
@@ -8724,6 +9506,7 @@ function mapRowToChannelIdentityMapping(row) {
|
|
|
8724
9506
|
PGVectorStoreProvider,
|
|
8725
9507
|
Pool,
|
|
8726
9508
|
PostgreSQLA2AApiKeyStore,
|
|
9509
|
+
PostgreSQLAgentWebAppStore,
|
|
8727
9510
|
PostgreSQLAssistantStore,
|
|
8728
9511
|
PostgreSQLChannelInstallationStore,
|
|
8729
9512
|
PostgreSQLCollectionStore,
|
|
@@ -8761,6 +9544,7 @@ function mapRowToChannelIdentityMapping(row) {
|
|
|
8761
9544
|
changeSkillPrimaryKey,
|
|
8762
9545
|
changeThreadPrimaryKey,
|
|
8763
9546
|
createA2AApiKeysTable,
|
|
9547
|
+
createAgentWebAppsTable,
|
|
8764
9548
|
createAssistantsTable,
|
|
8765
9549
|
createChannelBindingsTable,
|
|
8766
9550
|
createChannelIdentityMappingTables,
|