@axiom-lattice/pg-stores 1.0.47 → 1.0.49
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 +16 -0
- package/dist/index.d.mts +41 -3
- package/dist/index.d.ts +41 -3
- package/dist/index.js +354 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +352 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +10 -0
- package/src/migrations/workflow_tracking_migrations.ts +79 -0
- package/src/stores/PostgreSQLWorkflowTrackingStore.ts +293 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiom-lattice/pg-stores",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.49",
|
|
4
4
|
"description": "PG stores implementation for Axiom Lattice framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"pg": "^8.16.3",
|
|
24
|
-
"@axiom-lattice/protocols": "2.1.
|
|
25
|
-
"@axiom-lattice/core": "2.1.
|
|
24
|
+
"@axiom-lattice/protocols": "2.1.31",
|
|
25
|
+
"@axiom-lattice/core": "2.1.59"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^20.11.24",
|
package/src/index.ts
CHANGED
|
@@ -42,9 +42,11 @@ export * from "./migrations/tenant_migrations";
|
|
|
42
42
|
export * from "./migrations/thread_message_queue_migrations";
|
|
43
43
|
export * from "./migrations/channel_identity_mapping_migration";
|
|
44
44
|
export * from "./migrations/channel_installation_migrations";
|
|
45
|
+
export * from "./migrations/workflow_tracking_migrations";
|
|
45
46
|
export * from "./stores/ThreadMessageQueueStore";
|
|
46
47
|
export * from "./stores/ChannelIdentityMappingStore";
|
|
47
48
|
export * from "./stores/PostgreSQLChannelInstallationStore";
|
|
49
|
+
export * from "./stores/PostgreSQLWorkflowTrackingStore";
|
|
48
50
|
|
|
49
51
|
// Re-export for convenience
|
|
50
52
|
export { PostgreSQLThreadStore } from "./stores/PostgreSQLThreadStore";
|
|
@@ -61,6 +63,7 @@ export { PostgreSQLTenantStore } from "./stores/PostgreSQLTenantStore";
|
|
|
61
63
|
export { PostgreSQLUserTenantLinkStore } from "./stores/PostgreSQLUserTenantLinkStore";
|
|
62
64
|
export { ChannelIdentityMappingStore } from "./stores/ChannelIdentityMappingStore";
|
|
63
65
|
export { PostgreSQLChannelInstallationStore } from "./stores/PostgreSQLChannelInstallationStore";
|
|
66
|
+
export { PostgreSQLWorkflowTrackingStore } from "./stores/PostgreSQLWorkflowTrackingStore";
|
|
64
67
|
|
|
65
68
|
// Re-export types from protocols
|
|
66
69
|
export type {
|
|
@@ -120,4 +123,11 @@ export type {
|
|
|
120
123
|
UserTenantRole,
|
|
121
124
|
CreateUserTenantLinkRequest,
|
|
122
125
|
UpdateUserTenantLinkRequest,
|
|
126
|
+
WorkflowTrackingStore,
|
|
127
|
+
WorkflowRun,
|
|
128
|
+
RunStep,
|
|
129
|
+
CreateWorkflowRunRequest,
|
|
130
|
+
UpdateWorkflowRunRequest,
|
|
131
|
+
CreateRunStepRequest,
|
|
132
|
+
UpdateRunStepRequest,
|
|
123
133
|
} from "@axiom-lattice/protocols";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL migrations for workflow tracking tables
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Migration } from "./migration";
|
|
6
|
+
|
|
7
|
+
export const createWorkflowTrackingTables: Migration = {
|
|
8
|
+
name: "create_workflow_tracking_tables",
|
|
9
|
+
version: 103,
|
|
10
|
+
|
|
11
|
+
up: async (client) => {
|
|
12
|
+
await client.query(`
|
|
13
|
+
CREATE TABLE IF NOT EXISTS lattice_workflow_runs (
|
|
14
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
15
|
+
tenant_id VARCHAR(255) NOT NULL,
|
|
16
|
+
assistant_id VARCHAR(255) NOT NULL,
|
|
17
|
+
thread_id VARCHAR(255) NOT NULL,
|
|
18
|
+
status VARCHAR(50) NOT NULL DEFAULT 'running',
|
|
19
|
+
topology_edges JSONB NOT NULL DEFAULT '[]',
|
|
20
|
+
total_edges INTEGER NOT NULL DEFAULT 0,
|
|
21
|
+
completed_edges INTEGER NOT NULL DEFAULT 0,
|
|
22
|
+
error_message TEXT,
|
|
23
|
+
metadata JSONB DEFAULT '{}',
|
|
24
|
+
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
25
|
+
completed_at TIMESTAMPTZ,
|
|
26
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
27
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE TABLE IF NOT EXISTS lattice_workflow_steps (
|
|
31
|
+
id VARCHAR(255) NOT NULL,
|
|
32
|
+
run_id VARCHAR(255) NOT NULL REFERENCES lattice_workflow_runs(id) ON DELETE CASCADE,
|
|
33
|
+
tenant_id VARCHAR(255) NOT NULL,
|
|
34
|
+
step_type VARCHAR(50) NOT NULL,
|
|
35
|
+
step_name VARCHAR(255) NOT NULL,
|
|
36
|
+
edge_from VARCHAR(255),
|
|
37
|
+
edge_to VARCHAR(255),
|
|
38
|
+
edge_purpose TEXT,
|
|
39
|
+
input JSONB,
|
|
40
|
+
output JSONB,
|
|
41
|
+
status VARCHAR(50) NOT NULL DEFAULT 'running',
|
|
42
|
+
error_message TEXT,
|
|
43
|
+
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
44
|
+
completed_at TIMESTAMPTZ,
|
|
45
|
+
duration_ms INTEGER,
|
|
46
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
47
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
48
|
+
PRIMARY KEY (id, run_id)
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_runs_tenant
|
|
52
|
+
ON lattice_workflow_runs (tenant_id);
|
|
53
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_runs_thread
|
|
54
|
+
ON lattice_workflow_runs (tenant_id, thread_id);
|
|
55
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_runs_assistant
|
|
56
|
+
ON lattice_workflow_runs (tenant_id, assistant_id);
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_runs_status
|
|
58
|
+
ON lattice_workflow_runs (status);
|
|
59
|
+
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_steps_run
|
|
61
|
+
ON lattice_workflow_steps (run_id);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_steps_type_status
|
|
63
|
+
ON lattice_workflow_steps (run_id, step_type, status);
|
|
64
|
+
`);
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
down: async (client) => {
|
|
68
|
+
await client.query(`
|
|
69
|
+
DROP INDEX IF EXISTS idx_workflow_steps_type_status;
|
|
70
|
+
DROP INDEX IF EXISTS idx_workflow_steps_run;
|
|
71
|
+
DROP INDEX IF EXISTS idx_workflow_runs_status;
|
|
72
|
+
DROP INDEX IF EXISTS idx_workflow_runs_assistant;
|
|
73
|
+
DROP INDEX IF EXISTS idx_workflow_runs_thread;
|
|
74
|
+
DROP INDEX IF EXISTS idx_workflow_runs_tenant;
|
|
75
|
+
DROP TABLE IF EXISTS lattice_workflow_steps;
|
|
76
|
+
DROP TABLE IF EXISTS lattice_workflow_runs;
|
|
77
|
+
`);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL implementation of WorkflowTrackingStore
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Pool } from "pg";
|
|
6
|
+
import type { PoolConfig } from "pg";
|
|
7
|
+
import {
|
|
8
|
+
WorkflowTrackingStore,
|
|
9
|
+
WorkflowRun,
|
|
10
|
+
RunStep,
|
|
11
|
+
CreateWorkflowRunRequest,
|
|
12
|
+
UpdateWorkflowRunRequest,
|
|
13
|
+
CreateRunStepRequest,
|
|
14
|
+
UpdateRunStepRequest,
|
|
15
|
+
StepType,
|
|
16
|
+
WorkflowRunStatus,
|
|
17
|
+
} from "@axiom-lattice/protocols";
|
|
18
|
+
import { MigrationManager } from "../migrations/migration";
|
|
19
|
+
import { createWorkflowTrackingTables } from "../migrations/workflow_tracking_migrations";
|
|
20
|
+
|
|
21
|
+
export interface PostgreSQLWorkflowTrackingStoreOptions {
|
|
22
|
+
poolConfig: string | PoolConfig;
|
|
23
|
+
autoMigrate?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class PostgreSQLWorkflowTrackingStore implements WorkflowTrackingStore {
|
|
27
|
+
private pool: Pool;
|
|
28
|
+
private migrationManager: MigrationManager;
|
|
29
|
+
private initialized: boolean = false;
|
|
30
|
+
private initPromise: Promise<void> | null = null;
|
|
31
|
+
|
|
32
|
+
constructor(options: PostgreSQLWorkflowTrackingStoreOptions) {
|
|
33
|
+
if (typeof options.poolConfig === "string") {
|
|
34
|
+
this.pool = new Pool({ connectionString: options.poolConfig });
|
|
35
|
+
} else {
|
|
36
|
+
this.pool = new Pool(options.poolConfig);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
this.migrationManager = new MigrationManager(this.pool);
|
|
40
|
+
this.migrationManager.register(createWorkflowTrackingTables);
|
|
41
|
+
|
|
42
|
+
if (options.autoMigrate !== false) {
|
|
43
|
+
this.initialize().catch((error) => {
|
|
44
|
+
console.error("Failed to initialize PostgreSQLWorkflowTrackingStore:", error);
|
|
45
|
+
throw error;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async dispose(): Promise<void> {
|
|
51
|
+
await this.pool.end();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async initialize(): Promise<void> {
|
|
55
|
+
if (this.initialized) return;
|
|
56
|
+
if (this.initPromise) return this.initPromise;
|
|
57
|
+
|
|
58
|
+
this.initPromise = (async () => {
|
|
59
|
+
try {
|
|
60
|
+
await this.migrationManager.migrate();
|
|
61
|
+
this.initialized = true;
|
|
62
|
+
} finally {
|
|
63
|
+
this.initPromise = null;
|
|
64
|
+
}
|
|
65
|
+
})();
|
|
66
|
+
|
|
67
|
+
return this.initPromise;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private async ensureInitialized(): Promise<void> {
|
|
71
|
+
if (!this.initialized) await this.initialize();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async createWorkflowRun(request: CreateWorkflowRunRequest): Promise<WorkflowRun> {
|
|
75
|
+
await this.ensureInitialized();
|
|
76
|
+
const now = new Date();
|
|
77
|
+
const id = `${request.threadId}_${Date.now()}`;
|
|
78
|
+
|
|
79
|
+
await this.pool.query(
|
|
80
|
+
`INSERT INTO lattice_workflow_runs (id, tenant_id, assistant_id, thread_id, status, topology_edges, total_edges, completed_edges, metadata, started_at, created_at, updated_at)
|
|
81
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,
|
|
82
|
+
[id, request.tenantId, request.assistantId, request.threadId, 'running',
|
|
83
|
+
JSON.stringify(request.topologyEdges), request.topologyEdges.length, 0,
|
|
84
|
+
JSON.stringify(request.metadata || {}), now, now, now]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
id, status: 'running', startedAt: now, completedAt: undefined,
|
|
89
|
+
...request, completedEdges: 0, totalEdges: request.topologyEdges.length,
|
|
90
|
+
createdAt: now, updatedAt: now,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async getWorkflowRun(runId: string): Promise<WorkflowRun | null> {
|
|
95
|
+
await this.ensureInitialized();
|
|
96
|
+
const result = await this.pool.query(
|
|
97
|
+
`SELECT * FROM lattice_workflow_runs WHERE id = $1`, [runId]
|
|
98
|
+
);
|
|
99
|
+
if (result.rows.length === 0) return null;
|
|
100
|
+
return this.mapRowToWorkflowRun(result.rows[0]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async updateWorkflowRun(runId: string, updates: UpdateWorkflowRunRequest): Promise<WorkflowRun | null> {
|
|
104
|
+
await this.ensureInitialized();
|
|
105
|
+
const now = new Date();
|
|
106
|
+
const setClauses: string[] = ['updated_at = $2'];
|
|
107
|
+
const values: any[] = [runId, now];
|
|
108
|
+
let paramIdx = 3;
|
|
109
|
+
|
|
110
|
+
if (updates.status !== undefined) {
|
|
111
|
+
setClauses.push(`status = $${paramIdx++}`);
|
|
112
|
+
values.push(updates.status);
|
|
113
|
+
}
|
|
114
|
+
if (updates.completedEdges !== undefined) {
|
|
115
|
+
setClauses.push(`completed_edges = $${paramIdx++}`);
|
|
116
|
+
values.push(updates.completedEdges);
|
|
117
|
+
}
|
|
118
|
+
if (updates.errorMessage !== undefined) {
|
|
119
|
+
setClauses.push(`error_message = $${paramIdx++}`);
|
|
120
|
+
values.push(updates.errorMessage);
|
|
121
|
+
}
|
|
122
|
+
if (updates.completedAt !== undefined) {
|
|
123
|
+
setClauses.push(`completed_at = $${paramIdx++}`);
|
|
124
|
+
values.push(updates.completedAt);
|
|
125
|
+
}
|
|
126
|
+
if (updates.metadata !== undefined) {
|
|
127
|
+
setClauses.push(`metadata = $${paramIdx++}`);
|
|
128
|
+
values.push(JSON.stringify(updates.metadata));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const query = `UPDATE lattice_workflow_runs SET ${setClauses.join(', ')} WHERE id = $1`;
|
|
132
|
+
await this.pool.query(query, values);
|
|
133
|
+
return this.getWorkflowRun(runId);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async getWorkflowRunsByThreadId(tenantId: string, threadId: string): Promise<WorkflowRun[]> {
|
|
137
|
+
await this.ensureInitialized();
|
|
138
|
+
const result = await this.pool.query(
|
|
139
|
+
`SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 AND thread_id = $2 ORDER BY created_at DESC`,
|
|
140
|
+
[tenantId, threadId]
|
|
141
|
+
);
|
|
142
|
+
return result.rows.map(this.mapRowToWorkflowRun);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async getWorkflowRunsByAssistantId(tenantId: string, assistantId: string): Promise<WorkflowRun[]> {
|
|
146
|
+
await this.ensureInitialized();
|
|
147
|
+
const result = await this.pool.query(
|
|
148
|
+
`SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 AND assistant_id = $2 ORDER BY created_at DESC`,
|
|
149
|
+
[tenantId, assistantId]
|
|
150
|
+
);
|
|
151
|
+
return result.rows.map(this.mapRowToWorkflowRun);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async getWorkflowRunsByTenantId(tenantId: string): Promise<WorkflowRun[]> {
|
|
155
|
+
await this.ensureInitialized();
|
|
156
|
+
const result = await this.pool.query(
|
|
157
|
+
`SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 ORDER BY created_at DESC`,
|
|
158
|
+
[tenantId]
|
|
159
|
+
);
|
|
160
|
+
return result.rows.map(this.mapRowToWorkflowRun);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async createRunStep(request: CreateRunStepRequest): Promise<RunStep> {
|
|
164
|
+
await this.ensureInitialized();
|
|
165
|
+
const now = new Date();
|
|
166
|
+
const id = `step_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
167
|
+
|
|
168
|
+
await this.pool.query(
|
|
169
|
+
`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)
|
|
170
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`,
|
|
171
|
+
[id, request.runId, request.tenantId, request.stepType, request.stepName,
|
|
172
|
+
request.edgeFrom || null, request.edgeTo || null, request.edgePurpose || null,
|
|
173
|
+
request.input ? JSON.stringify(request.input) : null,
|
|
174
|
+
'running', now, now, now]
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
id, runId: request.runId, tenantId: request.tenantId,
|
|
179
|
+
stepType: request.stepType, stepName: request.stepName,
|
|
180
|
+
edgeFrom: request.edgeFrom, edgeTo: request.edgeTo, edgePurpose: request.edgePurpose,
|
|
181
|
+
input: request.input, status: 'running', startedAt: now,
|
|
182
|
+
createdAt: now, updatedAt: now,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async updateRunStep(runId: string, stepId: string, updates: UpdateRunStepRequest): Promise<RunStep | null> {
|
|
187
|
+
await this.ensureInitialized();
|
|
188
|
+
const now = new Date();
|
|
189
|
+
const setClauses: string[] = ['updated_at = $3'];
|
|
190
|
+
const values: any[] = [runId, stepId, now];
|
|
191
|
+
let paramIdx = 4;
|
|
192
|
+
|
|
193
|
+
if (updates.status !== undefined) {
|
|
194
|
+
setClauses.push(`status = $${paramIdx++}`);
|
|
195
|
+
values.push(updates.status);
|
|
196
|
+
}
|
|
197
|
+
if (updates.output !== undefined) {
|
|
198
|
+
setClauses.push(`output = $${paramIdx++}`);
|
|
199
|
+
values.push(JSON.stringify(updates.output));
|
|
200
|
+
}
|
|
201
|
+
if (updates.errorMessage !== undefined) {
|
|
202
|
+
setClauses.push(`error_message = $${paramIdx++}`);
|
|
203
|
+
values.push(updates.errorMessage);
|
|
204
|
+
}
|
|
205
|
+
if (updates.completedAt !== undefined) {
|
|
206
|
+
setClauses.push(`completed_at = $${paramIdx++}`);
|
|
207
|
+
values.push(updates.completedAt);
|
|
208
|
+
}
|
|
209
|
+
if (updates.durationMs !== undefined) {
|
|
210
|
+
setClauses.push(`duration_ms = $${paramIdx++}`);
|
|
211
|
+
values.push(updates.durationMs);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const query = `UPDATE lattice_workflow_steps SET ${setClauses.join(', ')} WHERE run_id = $1 AND id = $2`;
|
|
215
|
+
const result = await this.pool.query(query, values);
|
|
216
|
+
|
|
217
|
+
if (result.rowCount === 0) return null;
|
|
218
|
+
|
|
219
|
+
const row = await this.pool.query(
|
|
220
|
+
`SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND id = $2`,
|
|
221
|
+
[runId, stepId]
|
|
222
|
+
);
|
|
223
|
+
return row.rows.length > 0 ? this.mapRowToRunStep(row.rows[0]) : null;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async getRunSteps(runId: string): Promise<RunStep[]> {
|
|
227
|
+
await this.ensureInitialized();
|
|
228
|
+
const result = await this.pool.query(
|
|
229
|
+
`SELECT * FROM lattice_workflow_steps WHERE run_id = $1 ORDER BY created_at ASC`,
|
|
230
|
+
[runId]
|
|
231
|
+
);
|
|
232
|
+
return result.rows.map(this.mapRowToRunStep);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async getRunStepsByType(runId: string, stepType: StepType): Promise<RunStep[]> {
|
|
236
|
+
await this.ensureInitialized();
|
|
237
|
+
const result = await this.pool.query(
|
|
238
|
+
`SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND step_type = $2 ORDER BY created_at ASC`,
|
|
239
|
+
[runId, stepType]
|
|
240
|
+
);
|
|
241
|
+
return result.rows.map(this.mapRowToRunStep);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async getInterruptedSteps(runId: string): Promise<RunStep[]> {
|
|
245
|
+
await this.ensureInitialized();
|
|
246
|
+
const result = await this.pool.query(
|
|
247
|
+
`SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND status = 'interrupted' ORDER BY created_at ASC`,
|
|
248
|
+
[runId]
|
|
249
|
+
);
|
|
250
|
+
return result.rows.map(this.mapRowToRunStep);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private mapRowToWorkflowRun(row: any): WorkflowRun {
|
|
254
|
+
return {
|
|
255
|
+
id: row.id,
|
|
256
|
+
tenantId: row.tenant_id,
|
|
257
|
+
assistantId: row.assistant_id,
|
|
258
|
+
threadId: row.thread_id,
|
|
259
|
+
status: row.status as WorkflowRunStatus,
|
|
260
|
+
topologyEdges: typeof row.topology_edges === 'string' ? JSON.parse(row.topology_edges) : row.topology_edges || [],
|
|
261
|
+
totalEdges: row.total_edges,
|
|
262
|
+
completedEdges: row.completed_edges,
|
|
263
|
+
errorMessage: row.error_message,
|
|
264
|
+
metadata: typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata || {},
|
|
265
|
+
startedAt: row.started_at,
|
|
266
|
+
completedAt: row.completed_at,
|
|
267
|
+
createdAt: row.created_at,
|
|
268
|
+
updatedAt: row.updated_at,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
private mapRowToRunStep(row: any): RunStep {
|
|
273
|
+
return {
|
|
274
|
+
id: row.id,
|
|
275
|
+
runId: row.run_id,
|
|
276
|
+
tenantId: row.tenant_id,
|
|
277
|
+
stepType: row.step_type as StepType,
|
|
278
|
+
stepName: row.step_name,
|
|
279
|
+
edgeFrom: row.edge_from,
|
|
280
|
+
edgeTo: row.edge_to,
|
|
281
|
+
edgePurpose: row.edge_purpose,
|
|
282
|
+
input: typeof row.input === 'string' ? JSON.parse(row.input) : row.input,
|
|
283
|
+
output: typeof row.output === 'string' ? JSON.parse(row.output) : row.output,
|
|
284
|
+
status: row.status,
|
|
285
|
+
errorMessage: row.error_message,
|
|
286
|
+
startedAt: row.started_at,
|
|
287
|
+
completedAt: row.completed_at,
|
|
288
|
+
durationMs: row.duration_ms,
|
|
289
|
+
createdAt: row.created_at,
|
|
290
|
+
updatedAt: row.updated_at,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|