@sixb/sqlite 0.1.1 → 0.1.3

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 (123) hide show
  1. package/README.md +18 -13
  2. package/dist/action-run-storage.d.ts +5 -2
  3. package/dist/action-run-storage.d.ts.map +1 -1
  4. package/dist/agents/agent-storage.d.ts +9 -5
  5. package/dist/agents/agent-storage.d.ts.map +1 -1
  6. package/dist/agents/checkpoints.d.ts +14 -0
  7. package/dist/agents/checkpoints.d.ts.map +1 -0
  8. package/dist/agents/index.d.ts +1 -0
  9. package/dist/agents/index.d.ts.map +1 -1
  10. package/dist/agents/messages.d.ts +2 -1
  11. package/dist/agents/messages.d.ts.map +1 -1
  12. package/dist/agents/rows.d.ts +21 -11
  13. package/dist/agents/rows.d.ts.map +1 -1
  14. package/dist/agents/runs.d.ts +3 -2
  15. package/dist/agents/runs.d.ts.map +1 -1
  16. package/dist/ai-cost-storage.d.ts +15 -0
  17. package/dist/ai-cost-storage.d.ts.map +1 -0
  18. package/dist/ai-usage-storage.d.ts +22 -0
  19. package/dist/ai-usage-storage.d.ts.map +1 -0
  20. package/dist/auth-storage/service-accounts.d.ts.map +1 -1
  21. package/dist/auth-storage/shared.d.ts +1 -10
  22. package/dist/auth-storage/shared.d.ts.map +1 -1
  23. package/dist/connector-connection-storage.d.ts +9 -0
  24. package/dist/connector-connection-storage.d.ts.map +1 -0
  25. package/dist/execution-storage.d.ts +14 -0
  26. package/dist/execution-storage.d.ts.map +1 -0
  27. package/dist/index.d.ts +14 -9
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4633 -1066
  30. package/dist/index.js.map +33 -28
  31. package/dist/latest-run-query.d.ts.map +1 -1
  32. package/dist/migrations.d.ts +0 -1
  33. package/dist/migrations.d.ts.map +1 -1
  34. package/dist/ontology-storage/materialization-session.d.ts +50 -8
  35. package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
  36. package/dist/ontology-storage/materialization-state.d.ts +4 -5
  37. package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
  38. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
  39. package/dist/ontology-storage/materializations.d.ts +0 -2
  40. package/dist/ontology-storage/materializations.d.ts.map +1 -1
  41. package/dist/ontology-storage/outbox.d.ts.map +1 -1
  42. package/dist/ontology-storage/shared.d.ts +3 -3
  43. package/dist/ontology-storage/shared.d.ts.map +1 -1
  44. package/dist/ontology-storage/sources.d.ts.map +1 -1
  45. package/dist/pipeline-run-storage.d.ts +7 -2
  46. package/dist/pipeline-run-storage.d.ts.map +1 -1
  47. package/dist/projection-run-storage.d.ts +9 -2
  48. package/dist/projection-run-storage.d.ts.map +1 -1
  49. package/dist/run-list-query.d.ts +1 -1
  50. package/dist/run-list-query.d.ts.map +1 -1
  51. package/dist/sync-run-storage.d.ts +7 -2
  52. package/dist/sync-run-storage.d.ts.map +1 -1
  53. package/dist/testing.d.ts +6 -0
  54. package/dist/testing.d.ts.map +1 -0
  55. package/dist/transactions.d.ts +3 -0
  56. package/dist/transactions.d.ts.map +1 -1
  57. package/dist/webhook-run-storage.d.ts +9 -2
  58. package/dist/webhook-run-storage.d.ts.map +1 -1
  59. package/dist/workflow-run-storage.d.ts +7 -3
  60. package/dist/workflow-run-storage.d.ts.map +1 -1
  61. package/package.json +3 -3
  62. package/src/action-run-storage.ts +51 -74
  63. package/src/agents/agent-storage.ts +11 -6
  64. package/src/agents/checkpoints.ts +175 -0
  65. package/src/agents/index.ts +1 -0
  66. package/src/agents/messages.ts +59 -0
  67. package/src/agents/rows.ts +52 -40
  68. package/src/agents/runs.ts +27 -21
  69. package/src/ai-cost-storage.ts +744 -0
  70. package/src/ai-usage-storage.ts +324 -0
  71. package/src/auth-storage/service-accounts.ts +14 -21
  72. package/src/auth-storage/shared.ts +0 -22
  73. package/src/connector-connection-storage.ts +784 -0
  74. package/src/execution-storage.ts +158 -0
  75. package/src/index.ts +69 -22
  76. package/src/latest-run-query.ts +7 -1
  77. package/src/migrations/004-executions.sql +142 -0
  78. package/src/migrations/005-workflow-executions.sql +7 -0
  79. package/src/migrations/006-narrow-ontology-source-root-index.sql +4 -0
  80. package/src/migrations/007-split-overrides.sql +154 -0
  81. package/src/migrations/008-action-executions.sql +4 -0
  82. package/src/migrations/009-agent-executions.sql +115 -0
  83. package/src/migrations/010-ai-usage-accounting-foundation.sql +74 -0
  84. package/src/migrations/011-sync-failure-record.sql +22 -0
  85. package/src/migrations/012-pipeline-failure-record.sql +45 -0
  86. package/src/migrations/013-workflow-failure-record.sql +45 -0
  87. package/src/migrations/014-agent-failure-record.sql +59 -0
  88. package/src/migrations/015-projection-failure-record.sql +20 -0
  89. package/src/migrations/016-webhook-run-failure-record.sql +19 -0
  90. package/src/migrations/017-action-failure-record.sql +65 -0
  91. package/src/migrations/018-ontology-outbox-failure-record.sql +80 -0
  92. package/src/migrations/019-webhook-delivery-failure-record.sql +62 -0
  93. package/src/migrations/020-drop-run-usage-projections.sql +7 -0
  94. package/src/migrations/021-sync-pipeline-executions.sql +101 -0
  95. package/src/migrations/022-projection-executions.sql +244 -0
  96. package/src/migrations/023-webhook-executions.sql +51 -0
  97. package/src/migrations/024-ontology-commit-executions.sql +58 -0
  98. package/src/migrations/025-connector-connections.sql +257 -0
  99. package/src/migrations/026-ai-cost-accounting.sql +57 -0
  100. package/src/migrations/027-agent-context-checkpoints.sql +28 -0
  101. package/src/migrations/028-object-override-edit-times.sql +3 -0
  102. package/src/migrations.ts +129 -4
  103. package/src/ontology-storage/materialization-session.ts +317 -143
  104. package/src/ontology-storage/materialization-state.ts +323 -112
  105. package/src/ontology-storage/materialization-writer.ts +145 -67
  106. package/src/ontology-storage/materializations.ts +67 -141
  107. package/src/ontology-storage/outbox.ts +10 -3
  108. package/src/ontology-storage/shared.ts +10 -4
  109. package/src/ontology-storage/sources.ts +4 -1
  110. package/src/pipeline-run-storage.ts +128 -43
  111. package/src/projection-run-storage.ts +209 -97
  112. package/src/run-list-query.ts +9 -4
  113. package/src/sync-run-storage.ts +118 -32
  114. package/src/testing.ts +20 -0
  115. package/src/transactions.ts +10 -3
  116. package/src/webhook-run-storage.ts +118 -74
  117. package/src/workflow-run-storage.ts +117 -131
  118. package/dist/validation.d.ts +0 -5
  119. package/dist/validation.d.ts.map +0 -1
  120. package/dist/webhook-delivery-storage.d.ts +0 -27
  121. package/dist/webhook-delivery-storage.d.ts.map +0 -1
  122. package/src/validation.ts +0 -30
  123. package/src/webhook-delivery-storage.ts +0 -272
@@ -0,0 +1,257 @@
1
+ CREATE TABLE connector_connection_runs (
2
+ project_id TEXT NOT NULL,
3
+ connector_id TEXT NOT NULL,
4
+ id TEXT NOT NULL,
5
+ kind TEXT NOT NULL CHECK (kind IN ('connect', 'reauthorize')),
6
+ slot TEXT NOT NULL,
7
+ initiated_by_execution_id TEXT NOT NULL,
8
+ status TEXT NOT NULL CHECK (status IN ('waiting', 'running', 'succeeded', 'failed', 'cancelled', 'expired')),
9
+ waiting_for TEXT CHECK (waiting_for IN ('provider_authorization', 'account_selection')),
10
+ processing_id TEXT,
11
+ callback_started_at TEXT,
12
+ expires_at TEXT,
13
+ authorization_id TEXT,
14
+ cleanup_authorization_id TEXT,
15
+ connections TEXT CHECK (
16
+ connections IS NULL OR (json_valid(connections) AND json_type(connections) = 'array')
17
+ ),
18
+ error TEXT CHECK (error IS NULL OR (json_valid(error) AND json_type(error) = 'object')),
19
+ created_at TEXT NOT NULL,
20
+ updated_at TEXT NOT NULL,
21
+ finished_at TEXT,
22
+ PRIMARY KEY (project_id, connector_id, id),
23
+ UNIQUE (project_id, id),
24
+ CHECK (
25
+ (
26
+ status = 'waiting'
27
+ AND waiting_for = 'provider_authorization'
28
+ AND processing_id IS NULL
29
+ AND callback_started_at IS NULL
30
+ AND expires_at IS NOT NULL
31
+ AND authorization_id IS NULL
32
+ AND cleanup_authorization_id IS NULL
33
+ AND connections IS NULL
34
+ AND error IS NULL
35
+ AND finished_at IS NULL
36
+ )
37
+ OR
38
+ (
39
+ status = 'waiting'
40
+ AND waiting_for = 'account_selection'
41
+ AND processing_id IS NULL
42
+ AND callback_started_at IS NULL
43
+ AND expires_at IS NOT NULL
44
+ AND authorization_id IS NOT NULL
45
+ AND cleanup_authorization_id IS NULL
46
+ AND connections IS NULL
47
+ AND error IS NULL
48
+ AND finished_at IS NULL
49
+ )
50
+ OR
51
+ (
52
+ status = 'running'
53
+ AND waiting_for IS NULL
54
+ AND processing_id IS NOT NULL
55
+ AND callback_started_at IS NOT NULL
56
+ AND expires_at IS NOT NULL
57
+ AND cleanup_authorization_id IS NULL
58
+ AND connections IS NULL
59
+ AND error IS NULL
60
+ AND finished_at IS NULL
61
+ )
62
+ OR
63
+ (
64
+ status = 'succeeded'
65
+ AND waiting_for IS NULL
66
+ AND processing_id IS NULL
67
+ AND callback_started_at IS NULL
68
+ AND expires_at IS NULL
69
+ AND authorization_id IS NOT NULL
70
+ AND connections IS NOT NULL
71
+ AND error IS NULL
72
+ AND finished_at IS NOT NULL
73
+ )
74
+ OR
75
+ (
76
+ status = 'failed'
77
+ AND waiting_for IS NULL
78
+ AND processing_id IS NULL
79
+ AND callback_started_at IS NULL
80
+ AND expires_at IS NULL
81
+ AND cleanup_authorization_id IS NULL
82
+ AND connections IS NULL
83
+ AND error IS NOT NULL
84
+ AND finished_at IS NOT NULL
85
+ )
86
+ OR
87
+ (
88
+ status IN ('cancelled', 'expired')
89
+ AND waiting_for IS NULL
90
+ AND processing_id IS NULL
91
+ AND callback_started_at IS NULL
92
+ AND expires_at IS NULL
93
+ AND cleanup_authorization_id IS NULL
94
+ AND connections IS NULL
95
+ AND error IS NULL
96
+ AND finished_at IS NOT NULL
97
+ )
98
+ )
99
+ );
100
+
101
+ CREATE INDEX idx_connector_runs_status
102
+ ON connector_connection_runs (project_id, connector_id, status, updated_at);
103
+
104
+ CREATE TABLE connector_authorization_attempts (
105
+ project_id TEXT NOT NULL,
106
+ connector_id TEXT NOT NULL,
107
+ id TEXT NOT NULL,
108
+ slot TEXT NOT NULL,
109
+ initiated_by_execution_id TEXT NOT NULL,
110
+ state_hash TEXT NOT NULL,
111
+ code_verifier TEXT NOT NULL CHECK (
112
+ json_valid(code_verifier) AND json_type(code_verifier) = 'object'
113
+ ),
114
+ redirect_uri TEXT NOT NULL,
115
+ connection_run_id TEXT,
116
+ return_to TEXT,
117
+ callback_binding_hash TEXT,
118
+ reauthorization_id TEXT,
119
+ reauthorization_revision INTEGER CHECK (
120
+ reauthorization_revision IS NULL OR reauthorization_revision >= 0
121
+ ),
122
+ reauthorization_connection_ids TEXT CHECK (
123
+ reauthorization_connection_ids IS NULL
124
+ OR (json_valid(reauthorization_connection_ids) AND json_type(reauthorization_connection_ids) = 'array')
125
+ ),
126
+ created_at TEXT NOT NULL,
127
+ expires_at TEXT NOT NULL,
128
+ PRIMARY KEY (project_id, connector_id, id),
129
+ UNIQUE (project_id, id),
130
+ UNIQUE (project_id, connector_id, connection_run_id),
131
+ FOREIGN KEY (project_id, connector_id, connection_run_id)
132
+ REFERENCES connector_connection_runs (project_id, connector_id, id)
133
+ ON DELETE RESTRICT,
134
+ CHECK (
135
+ (connection_run_id IS NULL AND return_to IS NULL AND callback_binding_hash IS NULL)
136
+ OR
137
+ (connection_run_id IS NOT NULL AND return_to IS NOT NULL AND callback_binding_hash IS NOT NULL)
138
+ ),
139
+ CHECK (
140
+ (reauthorization_id IS NULL AND reauthorization_revision IS NULL AND reauthorization_connection_ids IS NULL)
141
+ OR
142
+ (reauthorization_id IS NOT NULL AND reauthorization_revision IS NOT NULL AND reauthorization_connection_ids IS NOT NULL)
143
+ )
144
+ );
145
+
146
+ CREATE INDEX idx_connector_attempts_expiry
147
+ ON connector_authorization_attempts (project_id, connector_id, expires_at);
148
+
149
+ CREATE TABLE connector_authorizations (
150
+ project_id TEXT NOT NULL,
151
+ connector_id TEXT NOT NULL,
152
+ id TEXT NOT NULL,
153
+ authorized_by TEXT NOT NULL CHECK (
154
+ json_valid(authorized_by) AND json_type(authorized_by) = 'object'
155
+ ),
156
+ credentials TEXT CHECK (
157
+ credentials IS NULL OR (json_valid(credentials) AND json_type(credentials) = 'object')
158
+ ),
159
+ credential_expires_at TEXT,
160
+ scopes TEXT NOT NULL CHECK (json_valid(scopes) AND json_type(scopes) = 'array'),
161
+ accounts TEXT NOT NULL CHECK (json_valid(accounts) AND json_type(accounts) = 'array'),
162
+ status TEXT NOT NULL CHECK (status IN ('pending_selection', 'active', 'needs_reauthorization', 'revocation_pending', 'revoked')),
163
+ selection_expires_at TEXT,
164
+ revision INTEGER NOT NULL CHECK (revision >= 0),
165
+ mutation_id TEXT,
166
+ mutation_kind TEXT CHECK (mutation_kind IN ('refresh', 'reauthorization', 'revocation')),
167
+ mutation_phase TEXT CHECK (mutation_phase IN ('prepared', 'executing', 'result_staged')),
168
+ mutation_holder_id TEXT,
169
+ mutation_expires_at TEXT,
170
+ mutation_deadline_at TEXT,
171
+ mutation_expected_connection_ids TEXT CHECK (
172
+ mutation_expected_connection_ids IS NULL
173
+ OR (json_valid(mutation_expected_connection_ids) AND json_type(mutation_expected_connection_ids) = 'array')
174
+ ),
175
+ staged_credentials TEXT CHECK (
176
+ staged_credentials IS NULL
177
+ OR (json_valid(staged_credentials) AND json_type(staged_credentials) = 'object')
178
+ ),
179
+ staged_credential_expires_at TEXT,
180
+ staged_scopes TEXT CHECK (
181
+ staged_scopes IS NULL OR (json_valid(staged_scopes) AND json_type(staged_scopes) = 'array')
182
+ ),
183
+ created_at TEXT NOT NULL,
184
+ updated_at TEXT NOT NULL,
185
+ PRIMARY KEY (project_id, connector_id, id),
186
+ UNIQUE (project_id, id),
187
+ CHECK (
188
+ (mutation_id IS NULL AND mutation_kind IS NULL AND mutation_phase IS NULL AND mutation_holder_id IS NULL AND mutation_expires_at IS NULL AND mutation_deadline_at IS NULL AND mutation_expected_connection_ids IS NULL AND staged_credentials IS NULL AND staged_credential_expires_at IS NULL AND staged_scopes IS NULL)
189
+ OR
190
+ (mutation_id IS NOT NULL AND mutation_kind IS NOT NULL AND mutation_phase IS NOT NULL AND mutation_holder_id IS NOT NULL AND mutation_expires_at IS NOT NULL AND mutation_deadline_at IS NOT NULL)
191
+ ),
192
+ CHECK (
193
+ (
194
+ mutation_phase IS NULL
195
+ AND staged_credentials IS NULL
196
+ AND staged_credential_expires_at IS NULL
197
+ AND staged_scopes IS NULL
198
+ )
199
+ OR
200
+ (
201
+ mutation_phase IN ('prepared', 'executing')
202
+ AND staged_credentials IS NULL
203
+ AND staged_credential_expires_at IS NULL
204
+ AND staged_scopes IS NULL
205
+ )
206
+ OR
207
+ (
208
+ mutation_phase = 'result_staged'
209
+ AND mutation_kind = 'revocation'
210
+ AND staged_credentials IS NULL
211
+ AND staged_credential_expires_at IS NULL
212
+ AND staged_scopes IS NULL
213
+ )
214
+ OR
215
+ (
216
+ mutation_phase = 'result_staged'
217
+ AND mutation_kind IN ('refresh', 'reauthorization')
218
+ AND staged_credentials IS NOT NULL
219
+ AND staged_scopes IS NOT NULL
220
+ )
221
+ ),
222
+ CHECK ((status = 'pending_selection') = (selection_expires_at IS NOT NULL)),
223
+ CHECK ((status = 'revoked') = (credentials IS NULL))
224
+ );
225
+
226
+ CREATE INDEX idx_connector_authorizations_status
227
+ ON connector_authorizations (project_id, connector_id, status, updated_at);
228
+ CREATE INDEX idx_connector_authorizations_mutation_expiry
229
+ ON connector_authorizations (project_id, connector_id, mutation_expires_at)
230
+ WHERE mutation_id IS NOT NULL;
231
+
232
+ CREATE TABLE connector_connections (
233
+ project_id TEXT NOT NULL,
234
+ connector_id TEXT NOT NULL,
235
+ id TEXT NOT NULL,
236
+ authorization_id TEXT NOT NULL,
237
+ slot TEXT NOT NULL,
238
+ account TEXT NOT NULL CHECK (json_valid(account) AND json_type(account) = 'object'),
239
+ account_id TEXT NOT NULL,
240
+ status TEXT NOT NULL CHECK (status IN ('connected', 'disconnected')),
241
+ disconnected_at TEXT,
242
+ created_at TEXT NOT NULL,
243
+ updated_at TEXT NOT NULL,
244
+ PRIMARY KEY (project_id, connector_id, id),
245
+ UNIQUE (project_id, id),
246
+ UNIQUE (project_id, connector_id, slot),
247
+ FOREIGN KEY (project_id, connector_id, authorization_id)
248
+ REFERENCES connector_authorizations (project_id, connector_id, id)
249
+ ON DELETE RESTRICT,
250
+ CHECK ((status = 'connected') = (disconnected_at IS NULL)),
251
+ CHECK (json_extract(account, '$.id') IS NOT NULL AND json_extract(account, '$.id') = account_id)
252
+ );
253
+
254
+ CREATE INDEX idx_connector_connections_authorization
255
+ ON connector_connections (project_id, connector_id, authorization_id, status, id);
256
+ CREATE INDEX idx_connector_connections_status
257
+ ON connector_connections (project_id, connector_id, status, id);
@@ -0,0 +1,57 @@
1
+ CREATE TABLE ai_model_call_valuations (
2
+ project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
3
+ usage_record_id TEXT NOT NULL CHECK (length(trim(usage_record_id)) > 0),
4
+ status TEXT NOT NULL CHECK (status IN ('rated', 'unpriceable')),
5
+ provider_id TEXT CHECK (provider_id IS NULL OR length(trim(provider_id)) > 0),
6
+ model_id TEXT CHECK (model_id IS NULL OR length(trim(model_id)) > 0),
7
+ currency TEXT CHECK (
8
+ currency IS NULL OR (length(currency) = 3 AND currency GLOB '[A-Z][A-Z][A-Z]')
9
+ ),
10
+ amount_nanos INTEGER CHECK (
11
+ amount_nanos IS NULL OR (typeof(amount_nanos) = 'integer' AND amount_nanos >= 0)
12
+ ),
13
+ reason TEXT CHECK (
14
+ reason IS NULL OR reason IN (
15
+ 'missingBillingIdentity',
16
+ 'missingCatalogEntry',
17
+ 'missingUsageMeter',
18
+ 'unsupportedPricingDimension',
19
+ 'invalidUsageForFormula'
20
+ )
21
+ ),
22
+ details TEXT NOT NULL CHECK (json_valid(details) AND json_type(details) = 'object'),
23
+ rated_at TEXT NOT NULL CHECK (length(trim(rated_at)) > 0),
24
+ PRIMARY KEY (project_id, usage_record_id),
25
+ FOREIGN KEY (project_id, usage_record_id)
26
+ REFERENCES ai_model_call_usage(project_id, id)
27
+ ON DELETE RESTRICT,
28
+ CHECK (
29
+ (
30
+ status = 'rated'
31
+ AND provider_id IS NOT NULL
32
+ AND model_id IS NOT NULL
33
+ AND currency IS NOT NULL
34
+ AND amount_nanos IS NOT NULL
35
+ AND reason IS NULL
36
+ )
37
+ OR
38
+ (
39
+ status = 'unpriceable'
40
+ AND currency IS NULL
41
+ AND amount_nanos IS NULL
42
+ AND reason IS NOT NULL
43
+ AND (
44
+ (reason = 'missingBillingIdentity' AND provider_id IS NULL AND model_id IS NULL)
45
+ OR
46
+ (reason <> 'missingBillingIdentity' AND provider_id IS NOT NULL AND model_id IS NOT NULL)
47
+ )
48
+ )
49
+ )
50
+ );
51
+
52
+ CREATE INDEX idx_ai_model_call_usage_provider_model_time
53
+ ON ai_model_call_usage (project_id, provider_id, requested_model_id, occurred_at, id);
54
+ CREATE INDEX idx_ai_model_call_usage_model_time
55
+ ON ai_model_call_usage (project_id, requested_model_id, occurred_at, id);
56
+ CREATE INDEX idx_ai_model_call_valuations_summary
57
+ ON ai_model_call_valuations (project_id, status, currency, usage_record_id);
@@ -0,0 +1,28 @@
1
+ CREATE TABLE agent_context_checkpoints (
2
+ project_id TEXT NOT NULL,
3
+ id TEXT NOT NULL,
4
+ thread_id TEXT NOT NULL,
5
+ created_by_run_id TEXT NOT NULL,
6
+ previous_checkpoint_id TEXT,
7
+ reason TEXT NOT NULL CHECK (reason IN ('threshold', 'overflow')),
8
+ summary TEXT NOT NULL CHECK (length(trim(summary)) > 0),
9
+ summary_format_version INTEGER NOT NULL CHECK (summary_format_version = 1),
10
+ summarized_through_seq INTEGER NOT NULL CHECK (summarized_through_seq >= 1),
11
+ observed_head_seq INTEGER NOT NULL,
12
+ estimated_input_tokens_before INTEGER NOT NULL CHECK (estimated_input_tokens_before >= 0),
13
+ estimated_input_tokens_after INTEGER NOT NULL CHECK (estimated_input_tokens_after >= 0),
14
+ summary_model_id TEXT NOT NULL CHECK (length(trim(summary_model_id)) > 0),
15
+ created_at TEXT NOT NULL,
16
+ PRIMARY KEY (project_id, id),
17
+ UNIQUE (project_id, created_by_run_id),
18
+ FOREIGN KEY (project_id, thread_id)
19
+ REFERENCES agent_threads(project_id, id) ON DELETE CASCADE,
20
+ FOREIGN KEY (project_id, created_by_run_id)
21
+ REFERENCES agent_runs(project_id, id) ON DELETE RESTRICT,
22
+ FOREIGN KEY (project_id, previous_checkpoint_id)
23
+ REFERENCES agent_context_checkpoints(project_id, id) ON DELETE RESTRICT,
24
+ CHECK (summarized_through_seq < observed_head_seq)
25
+ );
26
+
27
+ CREATE INDEX idx_agent_context_checkpoints_thread_latest
28
+ ON agent_context_checkpoints(project_id, thread_id, summarized_through_seq DESC, created_at DESC, id DESC);
@@ -0,0 +1,3 @@
1
+ ALTER TABLE ontology_object_overrides
2
+ ADD COLUMN edited_at TEXT NOT NULL DEFAULT '{}'
3
+ CHECK (json_valid(edited_at) AND json_type(edited_at) = 'object');
package/src/migrations.ts CHANGED
@@ -19,6 +19,63 @@ import {
19
19
  import initialSchemaSql from "./migrations/001-initial-schema.sql" with { type: "text" }
20
20
  import workflowRunOutputSql from "./migrations/002-workflow-run-output.sql" with { type: "text" }
21
21
  import mergeSyncRunsSql from "./migrations/003-merge-sync-runs.sql" with { type: "text" }
22
+ import executionsSql from "./migrations/004-executions.sql" with { type: "text" }
23
+ import workflowExecutionsSql from "./migrations/005-workflow-executions.sql" with { type: "text" }
24
+ import narrowOntologySourceRootIndexSql from "./migrations/006-narrow-ontology-source-root-index.sql" with {
25
+ type: "text",
26
+ }
27
+ import splitOverridesSql from "./migrations/007-split-overrides.sql" with { type: "text" }
28
+ import actionExecutionsSql from "./migrations/008-action-executions.sql" with { type: "text" }
29
+ import agentExecutionsSql from "./migrations/009-agent-executions.sql" with { type: "text" }
30
+ import aiUsageAccountingFoundationSql from "./migrations/010-ai-usage-accounting-foundation.sql" with {
31
+ type: "text",
32
+ }
33
+ import syncFailureRecordSql from "./migrations/011-sync-failure-record.sql" with { type: "text" }
34
+ import pipelineFailureRecordSql from "./migrations/012-pipeline-failure-record.sql" with {
35
+ type: "text",
36
+ }
37
+ import workflowFailureRecordSql from "./migrations/013-workflow-failure-record.sql" with {
38
+ type: "text",
39
+ }
40
+ import agentFailureRecordSql from "./migrations/014-agent-failure-record.sql" with { type: "text" }
41
+ import projectionFailureRecordSql from "./migrations/015-projection-failure-record.sql" with {
42
+ type: "text",
43
+ }
44
+ import webhookRunFailureRecordSql from "./migrations/016-webhook-run-failure-record.sql" with {
45
+ type: "text",
46
+ }
47
+ import actionFailureRecordSql from "./migrations/017-action-failure-record.sql" with {
48
+ type: "text",
49
+ }
50
+ import ontologyOutboxFailureRecordSql from "./migrations/018-ontology-outbox-failure-record.sql" with {
51
+ type: "text",
52
+ }
53
+ import webhookDeliveryFailureRecordSql from "./migrations/019-webhook-delivery-failure-record.sql" with {
54
+ type: "text",
55
+ }
56
+ import dropRunUsageProjectionsSql from "./migrations/020-drop-run-usage-projections.sql" with {
57
+ type: "text",
58
+ }
59
+ import syncPipelineExecutionsSql from "./migrations/021-sync-pipeline-executions.sql" with {
60
+ type: "text",
61
+ }
62
+ import projectionExecutionsSql from "./migrations/022-projection-executions.sql" with {
63
+ type: "text",
64
+ }
65
+ import webhookExecutionsSql from "./migrations/023-webhook-executions.sql" with { type: "text" }
66
+ import ontologyCommitExecutionsSql from "./migrations/024-ontology-commit-executions.sql" with {
67
+ type: "text",
68
+ }
69
+ import connectorConnectionsSql from "./migrations/025-connector-connections.sql" with {
70
+ type: "text",
71
+ }
72
+ import aiCostAccountingSql from "./migrations/026-ai-cost-accounting.sql" with { type: "text" }
73
+ import agentContextCheckpointsSql from "./migrations/027-agent-context-checkpoints.sql" with {
74
+ type: "text",
75
+ }
76
+ import objectOverrideEditTimesSql from "./migrations/028-object-override-edit-times.sql" with {
77
+ type: "text",
78
+ }
22
79
 
23
80
  const MIGRATIONS_TABLE_SQL = `
24
81
  CREATE TABLE IF NOT EXISTS sixb_migrations (
@@ -42,6 +99,66 @@ export const sqliteStorageMigrations = defineMigrations({
42
99
  sqliteSql("001-initial-schema", initialSchemaSql),
43
100
  sqliteSql("002-workflow-run-output", workflowRunOutputSql),
44
101
  sqliteSql("003-merge-sync-runs", mergeSyncRunsSql),
102
+ sqliteSql("004-executions", executionsSql),
103
+ sqliteSql("005-workflow-executions", workflowExecutionsSql),
104
+ sqliteSql("006-narrow-ontology-source-root-index", narrowOntologySourceRootIndexSql),
105
+ sqliteSql("007-split-overrides", splitOverridesSql),
106
+ sqliteSql("008-action-executions", actionExecutionsSql),
107
+ sqliteSql("009-agent-executions", agentExecutionsSql),
108
+ sqliteSql("010-ai-usage-accounting-foundation", aiUsageAccountingFoundationSql),
109
+ sqliteSql("011-sync-failure-record", syncFailureRecordSql),
110
+ sqliteSql("012-pipeline-failure-record", pipelineFailureRecordSql),
111
+ sqliteSql("013-workflow-failure-record", workflowFailureRecordSql),
112
+ sqliteSql("014-agent-failure-record", agentFailureRecordSql),
113
+ sqliteSql("015-projection-failure-record", projectionFailureRecordSql),
114
+ sqliteSql("016-webhook-run-failure-record", webhookRunFailureRecordSql),
115
+ sqliteSql("017-action-failure-record", actionFailureRecordSql),
116
+ sqliteSql("018-ontology-outbox-failure-record", ontologyOutboxFailureRecordSql),
117
+ sqliteSql("019-webhook-delivery-failure-record", webhookDeliveryFailureRecordSql),
118
+ sqliteSql("020-drop-run-usage-projections", dropRunUsageProjectionsSql),
119
+ sqliteSql("021-sync-pipeline-executions", syncPipelineExecutionsSql),
120
+ sqliteStep(
121
+ "022-projection-executions",
122
+ (db) => {
123
+ if (db.query("SELECT 1 FROM projection_runs LIMIT 1").get()) {
124
+ throw new Error(
125
+ "[SixbSqliteStorage] Projection execution migration cannot preserve legacy runs with unknown authority."
126
+ )
127
+ }
128
+ db.run(projectionExecutionsSql)
129
+ },
130
+ { checksum: checksum(projectionExecutionsSql) }
131
+ ),
132
+ sqliteStep(
133
+ "023-webhook-executions",
134
+ (db) => {
135
+ const hasRuns = db.query("SELECT 1 FROM webhook_runs LIMIT 1").get()
136
+ const hasDeliveries = db.query("SELECT 1 FROM webhook_deliveries LIMIT 1").get()
137
+ if (hasRuns || hasDeliveries) {
138
+ throw new Error(
139
+ "[SixbSqliteStorage] Webhook execution migration cannot preserve legacy runs or deliveries with unknown authority."
140
+ )
141
+ }
142
+ db.run(webhookExecutionsSql)
143
+ },
144
+ { checksum: checksum(webhookExecutionsSql) }
145
+ ),
146
+ sqliteStep(
147
+ "024-ontology-commit-executions",
148
+ (db) => {
149
+ if (db.query("SELECT 1 FROM ontology_commits LIMIT 1").get()) {
150
+ throw new Error(
151
+ "[SixbSqliteStorage] Ontology commit execution migration cannot preserve commits with unknown authority."
152
+ )
153
+ }
154
+ db.run(ontologyCommitExecutionsSql)
155
+ },
156
+ { checksum: checksum(ontologyCommitExecutionsSql) }
157
+ ),
158
+ sqliteSql("025-connector-connections", connectorConnectionsSql),
159
+ sqliteSql("026-ai-cost-accounting", aiCostAccountingSql),
160
+ sqliteSql("027-agent-context-checkpoints", agentContextCheckpointsSql),
161
+ sqliteSql("028-object-override-edit-times", objectOverrideEditTimesSql),
45
162
  ],
46
163
  })
47
164
 
@@ -120,10 +237,6 @@ export async function migrateSqliteStorage(basePath: string): Promise<void> {
120
237
  }
121
238
  }
122
239
 
123
- export async function migrateSqliteDatabase(path: string): Promise<void> {
124
- await createSqliteMigrator({ path, migrations: sqliteStorageMigrations }).migrate()
125
- }
126
-
127
240
  function sqliteMigrationHistoryStore(db: Database): MigrationHistoryStore {
128
241
  return {
129
242
  ensure() {
@@ -156,15 +269,27 @@ function sqliteMigrationHistoryStore(db: Database): MigrationHistoryStore {
156
269
  `).run(at, adapterId, migration.version)
157
270
  },
158
271
  async transaction(run) {
272
+ // SQLite cannot rebuild a referenced parent table while foreign-key enforcement is active,
273
+ // even when the replacement satisfies every deferred reference. Migrations therefore run
274
+ // with enforcement paused, validate the complete schema before commit, then restore it.
275
+ db.run("PRAGMA foreign_keys = OFF")
159
276
  db.run("BEGIN")
160
277
 
161
278
  try {
162
279
  const result = await run()
280
+ const violations = db.query("PRAGMA foreign_key_check").all()
281
+ if (violations.length > 0) {
282
+ throw new Error(
283
+ `[${SQLITE_STORAGE_ADAPTER_ID}] Migration produced ${violations.length} foreign-key violation(s).`
284
+ )
285
+ }
163
286
  db.run("COMMIT")
164
287
  return result
165
288
  } catch (error) {
166
289
  rollbackQuietly(db)
167
290
  throw error
291
+ } finally {
292
+ db.run("PRAGMA foreign_keys = ON")
168
293
  }
169
294
  },
170
295
  }