@sixb/pg 0.1.1 → 0.1.2

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.
Files changed (97) hide show
  1. package/README.md +7 -6
  2. package/dist/agents/agent-storage.d.ts +2 -1
  3. package/dist/agents/agent-storage.d.ts.map +1 -1
  4. package/dist/agents/rows.d.ts +4 -11
  5. package/dist/agents/rows.d.ts.map +1 -1
  6. package/dist/agents/runs.d.ts +3 -2
  7. package/dist/agents/runs.d.ts.map +1 -1
  8. package/dist/auth-storage/service-accounts.d.ts.map +1 -1
  9. package/dist/auth-storage/shared.d.ts +0 -4
  10. package/dist/auth-storage/shared.d.ts.map +1 -1
  11. package/dist/connector-connection-storage.d.ts +9 -0
  12. package/dist/connector-connection-storage.d.ts.map +1 -0
  13. package/dist/index.d.ts +8 -5
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3086 -730
  16. package/dist/index.js.map +28 -25
  17. package/dist/latest-run-query.d.ts.map +1 -1
  18. package/dist/migrations.d.ts.map +1 -1
  19. package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
  20. package/dist/ontology-storage/materialization-state.d.ts +0 -2
  21. package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
  22. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
  23. package/dist/ontology-storage/materializations.d.ts.map +1 -1
  24. package/dist/ontology-storage/outbox.d.ts.map +1 -1
  25. package/dist/ontology-storage/shared.d.ts +3 -6
  26. package/dist/ontology-storage/shared.d.ts.map +1 -1
  27. package/dist/pg-action-run-storage.d.ts +3 -2
  28. package/dist/pg-action-run-storage.d.ts.map +1 -1
  29. package/dist/pg-ai-usage-storage.d.ts +16 -0
  30. package/dist/pg-ai-usage-storage.d.ts.map +1 -0
  31. package/dist/pg-execution-storage.d.ts +14 -0
  32. package/dist/pg-execution-storage.d.ts.map +1 -0
  33. package/dist/pg-pipeline-run-storage.d.ts +5 -2
  34. package/dist/pg-pipeline-run-storage.d.ts.map +1 -1
  35. package/dist/pg-projection-run-storage.d.ts +5 -2
  36. package/dist/pg-projection-run-storage.d.ts.map +1 -1
  37. package/dist/pg-sync-run-storage.d.ts +5 -2
  38. package/dist/pg-sync-run-storage.d.ts.map +1 -1
  39. package/dist/pg-webhook-run-storage.d.ts +5 -2
  40. package/dist/pg-webhook-run-storage.d.ts.map +1 -1
  41. package/dist/pg-workflow-run-storage.d.ts +5 -3
  42. package/dist/pg-workflow-run-storage.d.ts.map +1 -1
  43. package/dist/run-list-query.d.ts +1 -1
  44. package/dist/run-list-query.d.ts.map +1 -1
  45. package/dist/testing.d.ts +6 -0
  46. package/dist/testing.d.ts.map +1 -0
  47. package/package.json +3 -3
  48. package/src/agents/agent-storage.ts +3 -2
  49. package/src/agents/rows.ts +12 -43
  50. package/src/agents/runs.ts +29 -15
  51. package/src/auth-storage/service-accounts.ts +14 -15
  52. package/src/auth-storage/shared.ts +0 -8
  53. package/src/connector-connection-storage.ts +760 -0
  54. package/src/index.ts +32 -15
  55. package/src/latest-run-query.ts +7 -1
  56. package/src/migrations/004-executions.sql +140 -0
  57. package/src/migrations/005-workflow-executions.sql +10 -0
  58. package/src/migrations/006-narrow-ontology-source-root-index.sql +4 -0
  59. package/src/migrations/007-split-overrides.sql +153 -0
  60. package/src/migrations/008-action-executions.sql +7 -0
  61. package/src/migrations/009-agent-executions.sql +21 -0
  62. package/src/migrations/010-ai-usage-accounting-foundation.sql +76 -0
  63. package/src/migrations/011-sync-failure-record.sql +23 -0
  64. package/src/migrations/012-pipeline-failure-record.sql +47 -0
  65. package/src/migrations/013-workflow-failure-record.sql +45 -0
  66. package/src/migrations/014-agent-failure-record.sql +56 -0
  67. package/src/migrations/015-projection-failure-record.sql +20 -0
  68. package/src/migrations/016-webhook-run-failure-record.sql +19 -0
  69. package/src/migrations/017-action-failure-record.sql +65 -0
  70. package/src/migrations/018-ontology-outbox-failure-record.sql +29 -0
  71. package/src/migrations/019-webhook-delivery-failure-record.sql +27 -0
  72. package/src/migrations/020-drop-run-usage-projections.sql +8 -0
  73. package/src/migrations/021-sync-pipeline-executions.sql +50 -0
  74. package/src/migrations/022-projection-executions.sql +115 -0
  75. package/src/migrations/023-webhook-executions.sql +30 -0
  76. package/src/migrations/024-ontology-commit-executions.sql +12 -0
  77. package/src/migrations/025-connector-connections.sql +231 -0
  78. package/src/migrations.ts +72 -0
  79. package/src/ontology-storage/materialization-session.ts +25 -28
  80. package/src/ontology-storage/materialization-state.ts +159 -43
  81. package/src/ontology-storage/materialization-writer.ts +146 -75
  82. package/src/ontology-storage/materializations.ts +3 -1
  83. package/src/ontology-storage/outbox.ts +9 -2
  84. package/src/ontology-storage/shared.ts +10 -20
  85. package/src/pg-action-run-storage.ts +43 -67
  86. package/src/pg-ai-usage-storage.ts +290 -0
  87. package/src/pg-execution-storage.ts +147 -0
  88. package/src/pg-pipeline-run-storage.ts +107 -41
  89. package/src/pg-projection-run-storage.ts +159 -91
  90. package/src/pg-sync-run-storage.ts +100 -28
  91. package/src/pg-webhook-run-storage.ts +89 -57
  92. package/src/pg-workflow-run-storage.ts +97 -130
  93. package/src/run-list-query.ts +9 -4
  94. package/src/testing.ts +18 -0
  95. package/dist/pg-webhook-delivery-storage.d.ts +0 -17
  96. package/dist/pg-webhook-delivery-storage.d.ts.map +0 -1
  97. package/src/pg-webhook-delivery-storage.ts +0 -180
@@ -0,0 +1,147 @@
1
+ import {
2
+ type ExecutionStorageRow,
3
+ executionRecordFromStorageRow,
4
+ executionRecordToStorageRow,
5
+ normalizeExecutionRecord,
6
+ validateExecutionRecordReferences,
7
+ } from "@sixb/core/internal/execution-storage"
8
+ import type { CreateExecutionInput, ExecutionRecord, ExecutionStorage } from "@sixb/core/storage"
9
+ import { ExecutionStorageError } from "@sixb/core/storage"
10
+ import type { PgAuthStorage } from "./auth-storage"
11
+ import { isUniqueViolation } from "./storage-errors"
12
+ import type { PgStoreClient } from "./transactions"
13
+
14
+ export class PgExecutionStorage implements ExecutionStorage {
15
+ constructor(
16
+ private readonly sql: PgStoreClient,
17
+ private readonly auth: PgAuthStorage
18
+ ) {}
19
+
20
+ async create(input: CreateExecutionInput): Promise<ExecutionRecord> {
21
+ const record = normalizeExecutionRecord(input)
22
+ await validateExecutionRecordReferences(record, {
23
+ auth: this.auth,
24
+ getExecution: (params) => this.getById(params),
25
+ })
26
+ const row = executionRecordToStorageRow(record)
27
+
28
+ try {
29
+ const [created] = await this.sql<PgExecutionRow[]>`
30
+ INSERT INTO executions (
31
+ project_id,
32
+ id,
33
+ executor_kind,
34
+ executor_id,
35
+ source_kind,
36
+ source_id,
37
+ requested_by_user_id,
38
+ requested_by_service_account_id,
39
+ correlation_id,
40
+ parent_execution_id,
41
+ authority_kind,
42
+ authority_user_id,
43
+ authority_service_account_id,
44
+ authority_session_id,
45
+ authority_access_token_id,
46
+ authority_primitive_kind,
47
+ authority_primitive_id,
48
+ authority_kernel_operation,
49
+ created_at
50
+ ) VALUES (
51
+ ${row.projectId},
52
+ ${row.id},
53
+ ${row.executorKind},
54
+ ${row.executorId},
55
+ ${row.sourceKind},
56
+ ${row.sourceId},
57
+ ${row.requestedByUserId},
58
+ ${row.requestedByServiceAccountId},
59
+ ${row.correlationId},
60
+ ${row.parentExecutionId},
61
+ ${row.authorityKind},
62
+ ${row.authorityUserId},
63
+ ${row.authorityServiceAccountId},
64
+ ${row.authoritySessionId},
65
+ ${row.authorityAccessTokenId},
66
+ ${row.authorityPrimitiveKind},
67
+ ${row.authorityPrimitiveId},
68
+ ${row.authorityKernelOperation},
69
+ ${row.createdAt}
70
+ )
71
+ RETURNING *
72
+ `
73
+
74
+ if (!created) {
75
+ throw new Error("[SixbPg] Execution insert returned no row.")
76
+ }
77
+ return executionRecordFromStorageRow(toStorageRow(created))
78
+ } catch (error) {
79
+ if (isUniqueViolation(error)) {
80
+ throw new ExecutionStorageError(
81
+ "duplicate_execution",
82
+ `[SixbPg] Execution '${record.id}' already exists in project '${record.projectId}'.`,
83
+ { cause: error }
84
+ )
85
+ }
86
+ throw error
87
+ }
88
+ }
89
+
90
+ async getById(params: {
91
+ readonly projectId: string
92
+ readonly id: string
93
+ }): Promise<ExecutionRecord | null> {
94
+ const [row] = await this.sql<PgExecutionRow[]>`
95
+ SELECT *
96
+ FROM executions
97
+ WHERE project_id = ${params.projectId} AND id = ${params.id}
98
+ `
99
+ return row ? executionRecordFromStorageRow(toStorageRow(row)) : null
100
+ }
101
+ }
102
+
103
+ function toStorageRow(row: PgExecutionRow): ExecutionStorageRow {
104
+ return {
105
+ projectId: row.project_id,
106
+ id: row.id,
107
+ executorKind: row.executor_kind,
108
+ executorId: row.executor_id,
109
+ sourceKind: row.source_kind,
110
+ sourceId: row.source_id,
111
+ requestedByUserId: row.requested_by_user_id,
112
+ requestedByServiceAccountId: row.requested_by_service_account_id,
113
+ correlationId: row.correlation_id,
114
+ parentExecutionId: row.parent_execution_id,
115
+ authorityKind: row.authority_kind,
116
+ authorityUserId: row.authority_user_id,
117
+ authorityServiceAccountId: row.authority_service_account_id,
118
+ authoritySessionId: row.authority_session_id,
119
+ authorityAccessTokenId: row.authority_access_token_id,
120
+ authorityPrimitiveKind: row.authority_primitive_kind,
121
+ authorityPrimitiveId: row.authority_primitive_id,
122
+ authorityKernelOperation: row.authority_kernel_operation,
123
+ createdAt: new Date(row.created_at),
124
+ }
125
+ }
126
+
127
+ interface PgExecutionRow {
128
+ readonly project_id: string
129
+ readonly id: string
130
+ readonly executor_kind: ExecutionStorageRow["executorKind"]
131
+ readonly executor_id: string
132
+ readonly source_kind: ExecutionStorageRow["sourceKind"]
133
+ readonly source_id: string
134
+ readonly requested_by_user_id: string | null
135
+ readonly requested_by_service_account_id: string | null
136
+ readonly correlation_id: string
137
+ readonly parent_execution_id: string | null
138
+ readonly authority_kind: ExecutionStorageRow["authorityKind"]
139
+ readonly authority_user_id: string | null
140
+ readonly authority_service_account_id: string | null
141
+ readonly authority_session_id: string | null
142
+ readonly authority_access_token_id: string | null
143
+ readonly authority_primitive_kind: ExecutionStorageRow["authorityPrimitiveKind"]
144
+ readonly authority_primitive_id: string | null
145
+ readonly authority_kernel_operation: ExecutionStorageRow["authorityKernelOperation"]
146
+ readonly created_at: Date | string
147
+ }
@@ -1,5 +1,9 @@
1
+ import type { JsonValue } from "@sixb/core"
2
+ import { parseSixbFailure, serializeSixbFailure } from "@sixb/core/internal/errors"
3
+ import { assertPipelineRunExecution } from "@sixb/core/internal/pipeline-run-storage-provider"
1
4
  import type { DatasetVersionRef } from "@sixb/core/lake-storage"
2
5
  import type {
6
+ ExecutionStorage,
3
7
  FinishPipelineRunInput,
4
8
  FinishPipelineStepRunInput,
5
9
  ListLatestPipelineRunsInput,
@@ -8,14 +12,18 @@ import type {
8
12
  ListPipelineRunsResult,
9
13
  ListPipelineStepRunsInput,
10
14
  ListPipelineStepRunsResult,
11
- PipelineRunFailure,
12
15
  PipelineRunRecord,
13
16
  PipelineRunStorage,
14
17
  PipelineStepRunRecord,
18
+ QueuePipelineRunInput,
15
19
  StartPipelineRunInput,
16
20
  StartPipelineStepRunInput,
17
21
  } from "@sixb/core/storage"
18
- import { PipelineRunError } from "@sixb/core/storage"
22
+ import {
23
+ canRequeuePipelineRunAfterEnqueueFailure,
24
+ PIPELINE_RUN_FAILURE_CODES,
25
+ PipelineRunError,
26
+ } from "@sixb/core/storage"
19
27
  import { queryLatestRunsByOwnerId } from "./latest-run-query"
20
28
  import type { SqlParameter } from "./pg-client"
21
29
  import { appendRunListFilters, hasEmptyStatuses, queryRunList } from "./run-list-query"
@@ -23,23 +31,37 @@ import { isUniqueViolation } from "./storage-errors"
23
31
  import { type PgStoreClient, runPgTransaction } from "./transactions"
24
32
 
25
33
  export class PgPipelineRunStorage implements PipelineRunStorage {
26
- constructor(private readonly sql: PgStoreClient) {}
27
-
28
- async start(input: StartPipelineRunInput): Promise<PipelineRunRecord> {
34
+ constructor(
35
+ private readonly sql: PgStoreClient,
36
+ private readonly executions: ExecutionStorage
37
+ ) {}
38
+
39
+ async queue(input: QueuePipelineRunInput): Promise<PipelineRunRecord> {
40
+ await assertPipelineRunExecution({
41
+ executions: this.executions,
42
+ projectId: input.projectId,
43
+ executionId: input.executionId,
44
+ runId: input.id,
45
+ pipelineId: input.pipelineId,
46
+ })
29
47
  try {
30
48
  const [row] = await this.sql<PipelineRunDatabaseRow[]>`
31
49
  INSERT INTO pipeline_runs (
32
50
  project_id,
33
51
  id,
52
+ execution_id,
34
53
  pipeline_id,
35
54
  status,
55
+ queued_at,
36
56
  started_at
37
57
  ) VALUES (
38
58
  ${input.projectId},
39
59
  ${input.id},
60
+ ${input.executionId},
40
61
  ${input.pipelineId},
41
- ${"running"},
42
- ${input.startedAt ?? new Date()}
62
+ ${"queued"},
63
+ ${input.queuedAt ?? new Date()},
64
+ ${null}
43
65
  )
44
66
  RETURNING *
45
67
  `
@@ -47,13 +69,62 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
47
69
  return rowToPipelineRunRecord(row)
48
70
  } catch (error) {
49
71
  if (isUniqueViolation(error)) {
72
+ return this.requeueAfterEnqueueFailure(input)
73
+ }
74
+
75
+ throw error
76
+ }
77
+ }
78
+
79
+ private async requeueAfterEnqueueFailure(
80
+ input: QueuePipelineRunInput
81
+ ): Promise<PipelineRunRecord> {
82
+ return runPgTransaction(this.sql, async (tx) => {
83
+ const [existing] = await tx<PipelineRunDatabaseRow[]>`
84
+ SELECT * FROM pipeline_runs
85
+ WHERE project_id = ${input.projectId} AND id = ${input.id}
86
+ FOR UPDATE
87
+ `
88
+ if (
89
+ !existing ||
90
+ !canRequeuePipelineRunAfterEnqueueFailure(rowToPipelineRunRecord(existing), input)
91
+ ) {
50
92
  throw new PipelineRunError(
51
93
  `[SixbPg] Pipeline run '${input.id}' already exists for project '${input.projectId}'.`
52
94
  )
53
95
  }
54
96
 
55
- throw error
97
+ const [updated] = await tx<PipelineRunDatabaseRow[]>`
98
+ UPDATE pipeline_runs
99
+ SET status = ${"queued"}, queued_at = ${input.queuedAt ?? new Date()},
100
+ started_at = ${null}, finished_at = ${null}, output_dataset_id = ${null},
101
+ output_version_id = ${null}, error = ${null}
102
+ WHERE project_id = ${input.projectId} AND id = ${input.id}
103
+ RETURNING *
104
+ `
105
+ return rowToPipelineRunRecord(updated)
106
+ })
107
+ }
108
+
109
+ async start(input: StartPipelineRunInput): Promise<PipelineRunRecord> {
110
+ const [updated] = await this.sql<PipelineRunDatabaseRow[]>`
111
+ UPDATE pipeline_runs
112
+ SET status = ${"running"}, started_at = ${input.startedAt ?? new Date()},
113
+ error = ${null}
114
+ WHERE project_id = ${input.projectId} AND id = ${input.id} AND status = ${"queued"}
115
+ RETURNING *
116
+ `
117
+ if (updated) return rowToPipelineRunRecord(updated)
118
+
119
+ const existing = await this.getById({ projectId: input.projectId, id: input.id })
120
+ if (!existing) {
121
+ throw new PipelineRunError(
122
+ `[SixbPg] Pipeline run '${input.id}' not found for project '${input.projectId}'.`
123
+ )
56
124
  }
125
+ throw new PipelineRunError(
126
+ `[SixbPg] Pipeline run '${input.id}' cannot start from status '${existing.status}'.`
127
+ )
57
128
  }
58
129
 
59
130
  async finish(input: FinishPipelineRunInput): Promise<PipelineRunRecord> {
@@ -69,9 +140,14 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
69
140
  )
70
141
  }
71
142
 
72
- if (existing.status !== "running") {
143
+ const enqueueFailure =
144
+ input.status === "failed" && input.error.code === "queue.enqueue_failed"
145
+ if (
146
+ (enqueueFailure && existing.status !== "queued") ||
147
+ (!enqueueFailure && existing.status !== "running")
148
+ ) {
73
149
  throw new PipelineRunError(
74
- `[SixbPg] Pipeline run '${input.id}' for project '${input.projectId}' is already terminal.`
150
+ `[SixbPg] Pipeline run '${input.id}' cannot finish from status '${existing.status}'.`
75
151
  )
76
152
  }
77
153
 
@@ -84,8 +160,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
84
160
  finished_at = ${input.finishedAt ?? new Date()},
85
161
  output_dataset_id = ${input.output?.datasetId ?? null},
86
162
  output_version_id = ${input.output?.versionId ?? null},
87
- error_name = ${null},
88
- error_message = ${null}
163
+ error = ${null}
89
164
  WHERE project_id = ${input.projectId} AND id = ${input.id}
90
165
  RETURNING *
91
166
  `
@@ -96,8 +171,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
96
171
  finished_at = ${input.finishedAt ?? new Date()},
97
172
  output_dataset_id = ${null},
98
173
  output_version_id = ${null},
99
- error_name = ${input.error?.name ?? null},
100
- error_message = ${input.error?.message ?? null}
174
+ error = ${input.error === undefined ? null : serializeSixbFailure(input.error, PIPELINE_RUN_FAILURE_CODES)}::text::jsonb
101
175
  WHERE project_id = ${input.projectId} AND id = ${input.id}
102
176
  RETURNING *
103
177
  `
@@ -208,8 +282,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
208
282
  finished_at = ${input.finishedAt ?? new Date()},
209
283
  output_version_id = ${input.output.versionId},
210
284
  rows_written = ${input.rowsWritten ?? existing.rows_written ?? null},
211
- error_name = ${null},
212
- error_message = ${null}
285
+ error = ${null}
213
286
  WHERE project_id = ${input.projectId} AND id = ${input.id}
214
287
  RETURNING *
215
288
  `
@@ -220,8 +293,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
220
293
  finished_at = ${input.finishedAt ?? new Date()},
221
294
  output_version_id = ${null},
222
295
  rows_written = ${input.rowsWritten ?? existing.rows_written ?? null},
223
- error_name = ${input.error?.name ?? null},
224
- error_message = ${input.error?.message ?? null}
296
+ error = ${input.error === undefined ? null : serializeSixbFailure(input.error, PIPELINE_RUN_FAILURE_CODES)}::text::jsonb
225
297
  WHERE project_id = ${input.projectId} AND id = ${input.id}
226
298
  RETURNING *
227
299
  `
@@ -263,7 +335,13 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
263
335
  params.push(...input.pipelineIds)
264
336
  }
265
337
 
266
- index = appendRunListFilters(whereClauses, params, index, input)
338
+ index = appendRunListFilters(
339
+ whereClauses,
340
+ params,
341
+ index,
342
+ input,
343
+ "COALESCE(started_at, queued_at)"
344
+ )
267
345
 
268
346
  const { rows, total, hasMore } = await queryRunList<PipelineRunDatabaseRow>({
269
347
  sql: this.sql,
@@ -356,27 +434,15 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
356
434
  }
357
435
  }
358
436
 
359
- function toFailure(row: {
360
- readonly error_name: string | null
361
- readonly error_message: string | null
362
- }): PipelineRunFailure | undefined {
363
- if (!row.error_message) {
364
- return undefined
365
- }
366
-
367
- return {
368
- name: row.error_name ?? undefined,
369
- message: row.error_message,
370
- }
371
- }
372
-
373
437
  function rowToPipelineRunRecord(row: PipelineRunDatabaseRow): PipelineRunRecord {
374
438
  return {
375
439
  id: row.id,
376
440
  projectId: row.project_id,
441
+ executionId: row.execution_id,
377
442
  pipelineId: row.pipeline_id,
378
443
  status: row.status,
379
- startedAt: new Date(row.started_at),
444
+ queuedAt: new Date(row.queued_at),
445
+ startedAt: row.started_at ? new Date(row.started_at) : undefined,
380
446
  finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,
381
447
  output:
382
448
  row.output_dataset_id && row.output_version_id
@@ -385,7 +451,7 @@ function rowToPipelineRunRecord(row: PipelineRunDatabaseRow): PipelineRunRecord
385
451
  versionId: row.output_version_id,
386
452
  }
387
453
  : undefined,
388
- error: toFailure(row),
454
+ error: row.error === null ? undefined : parseSixbFailure(row.error, PIPELINE_RUN_FAILURE_CODES),
389
455
  }
390
456
  }
391
457
 
@@ -409,7 +475,7 @@ function rowToPipelineStepRunRecord(row: PipelineStepRunDatabaseRow): PipelineSt
409
475
  }
410
476
  : undefined,
411
477
  rowsWritten: row.rows_written != null ? Number(row.rows_written) : undefined,
412
- error: toFailure(row),
478
+ error: row.error === null ? undefined : parseSixbFailure(row.error, PIPELINE_RUN_FAILURE_CODES),
413
479
  }
414
480
  }
415
481
 
@@ -428,14 +494,15 @@ function assertOptionalNonNegativeInteger(value: number | undefined, fieldName:
428
494
  interface PipelineRunDatabaseRow {
429
495
  project_id: string
430
496
  id: string
497
+ execution_id: string
431
498
  pipeline_id: string
432
499
  status: PipelineRunRecord["status"]
433
- started_at: Date | string
500
+ queued_at: Date | string
501
+ started_at: Date | string | null
434
502
  finished_at: Date | string | null
435
503
  output_dataset_id: string | null
436
504
  output_version_id: string | null
437
- error_name: string | null
438
- error_message: string | null
505
+ error: JsonValue | null
439
506
  }
440
507
 
441
508
  interface PipelineStepRunDatabaseRow {
@@ -452,6 +519,5 @@ interface PipelineStepRunDatabaseRow {
452
519
  inputs: readonly DatasetVersionRef[] | string
453
520
  output_version_id: string | null
454
521
  rows_written: number | string | null
455
- error_name: string | null
456
- error_message: string | null
522
+ error: JsonValue | null
457
523
  }