@intx/db 0.1.2 → 0.3.0

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 (241) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +23 -4
  3. package/dist/approval-store.d.ts +52 -0
  4. package/dist/approval-store.js +79 -0
  5. package/dist/asset-resolution.d.ts +52 -0
  6. package/dist/asset-resolution.js +66 -0
  7. package/dist/catalog-resolution.d.ts +76 -0
  8. package/dist/catalog-resolution.js +151 -0
  9. package/dist/client.d.ts +19 -0
  10. package/dist/client.js +18 -0
  11. package/dist/config.d.ts +11 -0
  12. package/dist/config.js +16 -0
  13. package/dist/connection.d.ts +3 -0
  14. package/dist/connection.js +26 -0
  15. package/dist/credential-resolution.d.ts +222 -0
  16. package/dist/credential-resolution.js +255 -0
  17. package/dist/grant-store.d.ts +3 -0
  18. package/dist/grant-store.js +59 -0
  19. package/dist/index.d.ts +22 -0
  20. package/dist/index.js +20 -0
  21. package/dist/migrate.d.ts +36 -0
  22. package/dist/migrate.js +135 -0
  23. package/dist/model-source-resolution.d.ts +115 -0
  24. package/dist/model-source-resolution.js +291 -0
  25. package/dist/parse-row.d.ts +373 -0
  26. package/dist/parse-row.js +232 -0
  27. package/dist/pg-error.d.ts +3 -0
  28. package/dist/pg-error.js +19 -0
  29. package/dist/pricing.d.ts +15 -0
  30. package/dist/pricing.js +24 -0
  31. package/dist/rekey-credential-secrets.d.ts +13 -0
  32. package/dist/rekey-credential-secrets.js +61 -0
  33. package/dist/schema/approvals.d.ts +245 -0
  34. package/dist/schema/approvals.js +52 -0
  35. package/dist/schema/assets.d.ts +143 -0
  36. package/{src/schema/assets.ts → dist/schema/assets.js} +7 -16
  37. package/dist/schema/auth.d.ts +606 -0
  38. package/dist/schema/auth.js +47 -0
  39. package/dist/schema/catalog.d.ts +811 -0
  40. package/dist/schema/catalog.js +108 -0
  41. package/dist/schema/column-types.d.ts +26 -0
  42. package/dist/schema/column-types.js +15 -0
  43. package/dist/schema/credentials.d.ts +305 -0
  44. package/{src/schema/credentials.ts → dist/schema/credentials.js} +16 -22
  45. package/dist/schema/git-tokens.d.ts +256 -0
  46. package/{src/schema/git-tokens.ts → dist/schema/git-tokens.js} +16 -39
  47. package/dist/schema/grants.d.ts +211 -0
  48. package/dist/schema/grants.js +30 -0
  49. package/dist/schema/index.d.ts +25 -0
  50. package/dist/schema/index.js +25 -0
  51. package/dist/schema/messages.d.ts +414 -0
  52. package/dist/schema/messages.js +82 -0
  53. package/dist/schema/oauth-clients.d.ts +246 -0
  54. package/{src/schema/oauth-clients.ts → dist/schema/oauth-clients.js} +8 -14
  55. package/dist/schema/offerings.d.ts +160 -0
  56. package/dist/schema/offerings.js +24 -0
  57. package/dist/schema/principals.d.ts +128 -0
  58. package/dist/schema/principals.js +23 -0
  59. package/dist/schema/providers.d.ts +237 -0
  60. package/dist/schema/providers.js +22 -0
  61. package/dist/schema/roles.d.ts +242 -0
  62. package/dist/schema/roles.js +37 -0
  63. package/dist/schema/session-assets.d.ts +92 -0
  64. package/dist/schema/session-assets.js +45 -0
  65. package/dist/schema/sessions.d.ts +143 -0
  66. package/dist/schema/sessions.js +29 -0
  67. package/dist/schema/sidecar-allocation.d.ts +406 -0
  68. package/dist/schema/sidecar-allocation.js +57 -0
  69. package/dist/schema/sidecar.d.ts +145 -0
  70. package/dist/schema/sidecar.js +28 -0
  71. package/dist/schema/signal-correlations.d.ts +177 -0
  72. package/dist/schema/signal-correlations.js +31 -0
  73. package/dist/schema/tenants.d.ts +235 -0
  74. package/{src/schema/tenants.ts → dist/schema/tenants.js} +10 -27
  75. package/dist/schema/wallets.d.ts +354 -0
  76. package/dist/schema/wallets.js +43 -0
  77. package/dist/schema/workflow-definitions.d.ts +371 -0
  78. package/dist/schema/workflow-definitions.js +97 -0
  79. package/dist/schema/workflow-run-dispatch.d.ts +328 -0
  80. package/dist/schema/workflow-run-dispatch.js +56 -0
  81. package/dist/schema/workflow-run-execution.d.ts +126 -0
  82. package/dist/schema/workflow-run-execution.js +48 -0
  83. package/dist/schema/workflow-run-launch-spec.d.ts +200 -0
  84. package/dist/schema/workflow-run-launch-spec.js +26 -0
  85. package/dist/schema/workflow-run.d.ts +230 -0
  86. package/dist/schema/workflow-run.js +102 -0
  87. package/dist/sidecar-allocation-store.d.ts +171 -0
  88. package/dist/sidecar-allocation-store.js +512 -0
  89. package/dist/signal-correlation-store.d.ts +36 -0
  90. package/dist/signal-correlation-store.js +63 -0
  91. package/dist/tenant-hierarchy.d.ts +23 -0
  92. package/dist/tenant-hierarchy.js +60 -0
  93. package/dist/workflow-definition-store.d.ts +55 -0
  94. package/dist/workflow-definition-store.js +93 -0
  95. package/dist/workflow-run-dispatch-store.d.ts +80 -0
  96. package/dist/workflow-run-dispatch-store.js +298 -0
  97. package/dist/workflow-run-launch-spec-store.d.ts +13 -0
  98. package/dist/workflow-run-launch-spec-store.js +30 -0
  99. package/dist/workflow-run-store.d.ts +54 -0
  100. package/dist/workflow-run-store.js +85 -0
  101. package/migrations/0029_loose_warlock.sql +1 -0
  102. package/migrations/0030_session_asset_audit_split.sql +5 -0
  103. package/migrations/0031_gigantic_nicolaos.sql +68 -0
  104. package/migrations/0032_lethal_misty_knight.sql +1 -0
  105. package/migrations/0033_old_payback.sql +1 -0
  106. package/migrations/0034_sleepy_songbird.sql +11 -0
  107. package/migrations/0035_violet_giant_man.sql +3 -0
  108. package/migrations/0036_sharp_the_executioner.sql +2 -0
  109. package/migrations/0037_credential_use_backfill.sql +39 -0
  110. package/migrations/0038_chilly_blacklash.sql +37 -0
  111. package/migrations/0039_quick_carnage.sql +2 -0
  112. package/migrations/0040_reshape_approval_origin.sql +24 -0
  113. package/migrations/0041_make_approval_timeout_at_nullable.sql +1 -0
  114. package/migrations/0042_youthful_mantis.sql +2 -0
  115. package/migrations/0043_signal_correlation_deployment_fk.sql +1 -0
  116. package/migrations/0044_model_offering_quirks.sql +1 -0
  117. package/migrations/0045_create_workflow_run.sql +13 -0
  118. package/migrations/0046_approval_signal_correlation_run_fk.sql +2 -0
  119. package/migrations/0047_create_workflow_definition.sql +30 -0
  120. package/migrations/0048_workflow_definition_origin_agent_id.sql +2 -0
  121. package/migrations/0049_curly_omega_flight.sql +2 -0
  122. package/migrations/0050_late_crystal.sql +10 -0
  123. package/migrations/0051_funny_madelyne_pryor.sql +1 -0
  124. package/migrations/0052_drop_inference_turn_instance_fk.sql +1 -0
  125. package/migrations/0053_session_mail_session_id_index.sql +1 -0
  126. package/migrations/0054_rekey_instance_grants_to_workflow_run.sql +10 -0
  127. package/migrations/0055_backfill_anchor_workflow_runs.sql +69 -0
  128. package/migrations/0056_repoint_deployment_fks_to_anchor_run.sql +32 -0
  129. package/migrations/0057_drop_workflow_deployment_projection.sql +22 -0
  130. package/migrations/0058_repoint_offering_fk_to_definition.sql +41 -0
  131. package/migrations/0059_repoint_transaction_fk_to_run.sql +10 -0
  132. package/migrations/0060_drop_session_mail_instance_fk.sql +6 -0
  133. package/migrations/0061_drop_session_asset_instance_fk.sql +7 -0
  134. package/migrations/0062_drop_agent_asset_table.sql +11 -0
  135. package/migrations/0063_repoint_agent_role_fk_to_definition.sql +39 -0
  136. package/migrations/0064_repoint_agent_session_fk_to_definition.sql +47 -0
  137. package/migrations/0065_add_workflow_definition_model_requirements.sql +37 -0
  138. package/migrations/0066_rekey_agent_definition_principals_to_workflow.sql +27 -0
  139. package/migrations/0067_add_workflow_definition_kind.sql +10 -0
  140. package/migrations/0068_drop_agent_tables_and_origin_agent_id.sql +31 -0
  141. package/migrations/0069_drop_workflow_definition_kind.sql +10 -0
  142. package/migrations/0070_flashy_proteus.sql +13 -0
  143. package/migrations/0072_add_workflow_definition_credential_bindings.sql +1 -0
  144. package/migrations/0073_grant_target_exactly_one_check.sql +13 -0
  145. package/migrations/0074_add_provider_api_base_url.sql +1 -0
  146. package/migrations/0075_workflow_run_launch_spec.sql +17 -0
  147. package/migrations/0076_sidecar_allocation.sql +40 -0
  148. package/migrations/0077_workflow_run_dispatch.sql +29 -0
  149. package/migrations/0078_workflow_run_dispatch_kind.sql +2 -0
  150. package/migrations/0079_rename_workflow_run_deployment_id_to_anchor_run_id.sql +4 -0
  151. package/migrations/0080_rename_correlation_approval_deployment_id_to_anchor_run_id.sql +9 -0
  152. package/migrations/0081_workflow_definition_content_hash_and_approved_wire_hash.sql +4 -0
  153. package/migrations/0082_blue_black_queen.sql +1 -0
  154. package/migrations/0083_replace_launch_spec_snapshot_with_frozen_bundle.sql +3 -0
  155. package/migrations/0084_delete_orphaned_credential_grants.sql +22 -0
  156. package/migrations/meta/0029_snapshot.json +2664 -0
  157. package/migrations/meta/0030_snapshot.json +2670 -0
  158. package/migrations/meta/0031_snapshot.json +3100 -0
  159. package/migrations/meta/0032_snapshot.json +3106 -0
  160. package/migrations/meta/0033_snapshot.json +3112 -0
  161. package/migrations/meta/0034_snapshot.json +3198 -0
  162. package/migrations/meta/0035_snapshot.json +3225 -0
  163. package/migrations/meta/0036_snapshot.json +3237 -0
  164. package/migrations/meta/0037_snapshot.json +3237 -0
  165. package/migrations/meta/0038_snapshot.json +3470 -0
  166. package/migrations/meta/0039_snapshot.json +3470 -0
  167. package/migrations/meta/0040_snapshot.json +3489 -0
  168. package/migrations/meta/0041_snapshot.json +3489 -0
  169. package/migrations/meta/0042_snapshot.json +3489 -0
  170. package/migrations/meta/0043_snapshot.json +3498 -0
  171. package/migrations/meta/0044_snapshot.json +3504 -0
  172. package/migrations/meta/0045_snapshot.json +3589 -0
  173. package/migrations/meta/0046_snapshot.json +3607 -0
  174. package/migrations/meta/0047_snapshot.json +3832 -0
  175. package/migrations/meta/0048_snapshot.json +3853 -0
  176. package/migrations/meta/0049_snapshot.json +3854 -0
  177. package/migrations/meta/0050_snapshot.json +3924 -0
  178. package/migrations/meta/0051_snapshot.json +3940 -0
  179. package/migrations/meta/0052_snapshot.json +3931 -0
  180. package/migrations/meta/0053_snapshot.json +3952 -0
  181. package/migrations/meta/0054_snapshot.json +3952 -0
  182. package/migrations/meta/0055_snapshot.json +3952 -0
  183. package/migrations/meta/0056_snapshot.json +3952 -0
  184. package/migrations/meta/0057_snapshot.json +3839 -0
  185. package/migrations/meta/0058_snapshot.json +3839 -0
  186. package/migrations/meta/0059_snapshot.json +3839 -0
  187. package/migrations/meta/0060_snapshot.json +3830 -0
  188. package/migrations/meta/0061_snapshot.json +3821 -0
  189. package/migrations/meta/0062_snapshot.json +3723 -0
  190. package/migrations/meta/0063_snapshot.json +3723 -0
  191. package/migrations/meta/0064_snapshot.json +3723 -0
  192. package/migrations/meta/0065_snapshot.json +3729 -0
  193. package/migrations/meta/0066_snapshot.json +3729 -0
  194. package/migrations/meta/0067_snapshot.json +3736 -0
  195. package/migrations/meta/0068_snapshot.json +3347 -0
  196. package/migrations/meta/0069_snapshot.json +3340 -0
  197. package/migrations/meta/0070_snapshot.json +3444 -0
  198. package/migrations/meta/0072_snapshot.json +3450 -0
  199. package/migrations/meta/0073_snapshot.json +3455 -0
  200. package/migrations/meta/0074_snapshot.json +3461 -0
  201. package/migrations/meta/0075_snapshot.json +3567 -0
  202. package/migrations/meta/0076_snapshot.json +3851 -0
  203. package/migrations/meta/0077_snapshot.json +4067 -0
  204. package/migrations/meta/0078_snapshot.json +4078 -0
  205. package/migrations/meta/0079_snapshot.json +4078 -0
  206. package/migrations/meta/0080_snapshot.json +4078 -0
  207. package/migrations/meta/0081_snapshot.json +4096 -0
  208. package/migrations/meta/0082_snapshot.json +4102 -0
  209. package/migrations/meta/0083_snapshot.json +4096 -0
  210. package/migrations/meta/0084_snapshot.json +4096 -0
  211. package/migrations/meta/_journal.json +385 -0
  212. package/package.json +25 -11
  213. package/drizzle.config.ts +0 -23
  214. package/src/client.ts +0 -24
  215. package/src/config.ts +0 -19
  216. package/src/connection.ts +0 -27
  217. package/src/credential-resolution.ts +0 -378
  218. package/src/grant-store.ts +0 -51
  219. package/src/index.ts +0 -32
  220. package/src/migrate.test.ts +0 -35
  221. package/src/migrate.ts +0 -168
  222. package/src/parse-row.test.ts +0 -113
  223. package/src/parse-row.ts +0 -185
  224. package/src/schema/agent-assets.ts +0 -21
  225. package/src/schema/agents.ts +0 -49
  226. package/src/schema/auth.ts +0 -51
  227. package/src/schema/grants.ts +0 -26
  228. package/src/schema/index.ts +0 -19
  229. package/src/schema/instances.ts +0 -36
  230. package/src/schema/messages.ts +0 -108
  231. package/src/schema/offerings.ts +0 -20
  232. package/src/schema/principals.ts +0 -28
  233. package/src/schema/providers.ts +0 -23
  234. package/src/schema/roles.ts +0 -51
  235. package/src/schema/session-assets.ts +0 -49
  236. package/src/schema/sessions.ts +0 -26
  237. package/src/schema/sidecar.ts +0 -14
  238. package/src/schema/wallets.ts +0 -44
  239. package/src/tenant-hierarchy.ts +0 -34
  240. package/tsconfig.json +0 -4
  241. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,232 @@
1
+ import { type } from "arktype";
2
+ import { Capability, CredentialBinding, GrantRequirement, grantEffects, grantOrigins, InvokerModelPreferences, ModelProviderPlugin, ModelRequirements, principalKinds, principalStatuses, signalKinds, TenantConfig, workflowDefinitionStatuses, workflowDefinitionVersionStatuses, } from "@intx/types";
3
+ import { WireGrantRule } from "@intx/types/grant-wire";
4
+ import { FrozenApprovalBundle, RepoAction } from "@intx/types/sidecar";
5
+ import { ToolPackagePinArray } from "@intx/types/tool-packages";
6
+ const JSONObject = type("Record<string, unknown>");
7
+ const StringArray = type("string[]");
8
+ const WireGrantRuleArray = WireGrantRule.array();
9
+ const GrantEffectValidator = type.enumerated(...grantEffects);
10
+ const GrantOriginValidator = type.enumerated(...grantOrigins);
11
+ const approvalScopes = ["once", "always"];
12
+ const ApprovalScopeValidator = type.enumerated(...approvalScopes);
13
+ const approvalStatuses = [
14
+ "pending",
15
+ "approved",
16
+ "rejected",
17
+ "timeout",
18
+ "expired",
19
+ ];
20
+ const ApprovalStatusValidator = type.enumerated(...approvalStatuses);
21
+ const SignalKindValidator = type.enumerated(...signalKinds);
22
+ const workflowRunStatuses = [
23
+ "deployed",
24
+ "running",
25
+ "completed",
26
+ "failed",
27
+ "cancelled",
28
+ ];
29
+ const WorkflowRunStatusValidator = type.enumerated(...workflowRunStatuses);
30
+ const WorkflowRunDispatchStatusValidator = type.enumerated("pending", "acknowledged", "settled", "failed");
31
+ const WorkflowRunDispatchKindValidator = type.enumerated("mail", "signal");
32
+ const WorkflowDefinitionStatusValidator = type.enumerated(...workflowDefinitionStatuses);
33
+ const WorkflowDefinitionVersionStatusValidator = type.enumerated(...workflowDefinitionVersionStatuses);
34
+ const PrincipalKindValidator = type.enumerated(...principalKinds);
35
+ const PrincipalStatusValidator = type.enumerated(...principalStatuses);
36
+ const credentialTypes = [
37
+ "api_key",
38
+ "oauth_token",
39
+ "certificate",
40
+ "other",
41
+ ];
42
+ const CredentialTypeValidator = type.enumerated(...credentialTypes);
43
+ const credentialStatuses = ["active", "expired", "revoked", "error"];
44
+ const CredentialStatusValidator = type.enumerated(...credentialStatuses);
45
+ const walletBackendTypes = ["crypto", "fiat", "credits"];
46
+ const WalletBackendTypeValidator = type.enumerated(...walletBackendTypes);
47
+ const transactionDirections = ["inbound", "outbound"];
48
+ const TransactionDirectionValidator = type.enumerated(...transactionDirections);
49
+ const transactionStatuses = ["pending", "completed", "failed"];
50
+ const TransactionStatusValidator = type.enumerated(...transactionStatuses);
51
+ const gitTokenKinds = ["pat", "svc"];
52
+ export const GitTokenKindValidator = type.enumerated(...gitTokenKinds);
53
+ const turnPartTypes = [
54
+ "text",
55
+ "reasoning",
56
+ "tool",
57
+ "file",
58
+ "error",
59
+ "refusal",
60
+ "safety_rating",
61
+ "step-start",
62
+ "step-finish",
63
+ "snapshot",
64
+ "patch",
65
+ ];
66
+ const TurnPartTypeValidator = type.enumerated(...turnPartTypes);
67
+ export function parseWorkflowDefinitionRow(row) {
68
+ return {
69
+ ...row,
70
+ status: WorkflowDefinitionStatusValidator.assert(row.status),
71
+ grantRequirements: row.grantRequirements !== null
72
+ ? GrantRequirement.array().assert(row.grantRequirements)
73
+ : null,
74
+ modelRequirements: row.modelRequirements !== null
75
+ ? ModelRequirements.assert(row.modelRequirements)
76
+ : null,
77
+ // Nullable jsonb: `null` on a real drizzle row, `undefined` only on a
78
+ // partial row-shaped test stub that predates the column. Both mean "no
79
+ // bindings" -- treat them alike rather than asserting `undefined` as an
80
+ // array.
81
+ credentialBindings: row.credentialBindings === null || row.credentialBindings === undefined
82
+ ? null
83
+ : CredentialBinding.array().assert(row.credentialBindings),
84
+ };
85
+ }
86
+ export function parseWorkflowDefinitionVersionRow(row) {
87
+ return {
88
+ ...row,
89
+ status: WorkflowDefinitionVersionStatusValidator.assert(row.status),
90
+ };
91
+ }
92
+ export function parseGrantRow(row) {
93
+ return {
94
+ ...row,
95
+ effect: GrantEffectValidator.assert(row.effect),
96
+ origin: GrantOriginValidator.assert(row.origin),
97
+ conditions: row.conditions !== null ? JSONObject.assert(row.conditions) : null,
98
+ };
99
+ }
100
+ export function parseApprovalRow(row) {
101
+ return {
102
+ ...row,
103
+ scope: row.scope !== null ? ApprovalScopeValidator.assert(row.scope) : null,
104
+ status: ApprovalStatusValidator.assert(row.status),
105
+ toolDefinition: JSONObject.assert(row.toolDefinition),
106
+ toolArguments: JSONObject.assert(row.toolArguments),
107
+ };
108
+ }
109
+ export function parsePrincipalRow(row) {
110
+ return {
111
+ ...row,
112
+ kind: PrincipalKindValidator.assert(row.kind),
113
+ status: PrincipalStatusValidator.assert(row.status),
114
+ };
115
+ }
116
+ export function parseSignalCorrelationRow(row) {
117
+ return {
118
+ ...row,
119
+ kind: SignalKindValidator.assert(row.kind),
120
+ };
121
+ }
122
+ export function parseWorkflowRunRow(row) {
123
+ return {
124
+ ...row,
125
+ status: WorkflowRunStatusValidator.assert(row.status),
126
+ modelPreferences: row.modelPreferences !== null
127
+ ? InvokerModelPreferences.assert(row.modelPreferences)
128
+ : null,
129
+ };
130
+ }
131
+ export function parseWorkflowRunLaunchSpecRow(row) {
132
+ const sourceOfferingIds = StringArray.assert(row.sourceOfferingIds);
133
+ assertLaunchSpecSources(sourceOfferingIds, row.defaultSourceOfferingId);
134
+ return {
135
+ ...row,
136
+ frozenApprovalBundle: FrozenApprovalBundle.assert(row.frozenApprovalBundle),
137
+ sourceOfferingIds,
138
+ deployContent: JSONObject.assert(row.deployContent),
139
+ toolPackagePins: row.toolPackagePins !== null
140
+ ? ToolPackagePinArray.assert(row.toolPackagePins)
141
+ : null,
142
+ };
143
+ }
144
+ export function parseWorkflowRunDispatchRow(row) {
145
+ return {
146
+ ...row,
147
+ kind: WorkflowRunDispatchKindValidator.assert(row.kind),
148
+ status: WorkflowRunDispatchStatusValidator.assert(row.status),
149
+ stepGrants: WireGrantRuleArray.assert(row.stepGrants),
150
+ };
151
+ }
152
+ function assertLaunchSpecSources(sourceOfferingIds, defaultSourceOfferingId) {
153
+ if (sourceOfferingIds.length === 0) {
154
+ throw new Error("workflow launch spec requires at least one source offering");
155
+ }
156
+ if (new Set(sourceOfferingIds).size !== sourceOfferingIds.length) {
157
+ throw new Error("workflow launch spec source offering ids must be unique");
158
+ }
159
+ if (!sourceOfferingIds.includes(defaultSourceOfferingId)) {
160
+ throw new Error(`workflow launch spec default source ${defaultSourceOfferingId} is not in its source offering ids`);
161
+ }
162
+ }
163
+ export function parseOfferingRow(row) {
164
+ return {
165
+ ...row,
166
+ pricing: row.pricing !== null ? JSONObject.assert(row.pricing) : null,
167
+ schema: row.schema !== null ? JSONObject.assert(row.schema) : null,
168
+ };
169
+ }
170
+ export function parseCredentialRow(row) {
171
+ return {
172
+ ...row,
173
+ type: CredentialTypeValidator.assert(row.type),
174
+ status: CredentialStatusValidator.assert(row.status),
175
+ metadata: row.metadata !== null ? JSONObject.assert(row.metadata) : null,
176
+ };
177
+ }
178
+ export function parseProviderRow(row) {
179
+ return {
180
+ ...row,
181
+ metadata: row.metadata !== null ? JSONObject.assert(row.metadata) : null,
182
+ };
183
+ }
184
+ export function parseModelProviderRow(row) {
185
+ return {
186
+ ...row,
187
+ plugin: ModelProviderPlugin.assert(row.plugin),
188
+ };
189
+ }
190
+ export function parseModelOfferingRow(row) {
191
+ return {
192
+ ...row,
193
+ capabilities: Capability.array().assert(row.capabilities),
194
+ quirks: row.quirks !== null ? JSONObject.assert(row.quirks) : null,
195
+ };
196
+ }
197
+ export function parseTenantRow(row) {
198
+ return {
199
+ ...row,
200
+ config: row.config !== null ? TenantConfig.assert(row.config) : null,
201
+ };
202
+ }
203
+ export function parseWalletRow(row) {
204
+ return {
205
+ ...row,
206
+ backendType: WalletBackendTypeValidator.assert(row.backendType),
207
+ config: row.config !== null ? JSONObject.assert(row.config) : null,
208
+ };
209
+ }
210
+ export function parseTransactionRow(row) {
211
+ return {
212
+ ...row,
213
+ direction: TransactionDirectionValidator.assert(row.direction),
214
+ status: TransactionStatusValidator.assert(row.status),
215
+ };
216
+ }
217
+ export function parseOAuthClientRow(row) {
218
+ return {
219
+ ...row,
220
+ metadata: row.metadata !== null ? JSONObject.assert(row.metadata) : null,
221
+ };
222
+ }
223
+ export function parseGitTokenRow(row) {
224
+ return {
225
+ ...row,
226
+ kind: GitTokenKindValidator.assert(row.kind),
227
+ actions: RepoAction.array().assert(row.actions),
228
+ };
229
+ }
230
+ export function parseTurnPartType(partType) {
231
+ return TurnPartTypeValidator.assert(partType);
232
+ }
@@ -0,0 +1,3 @@
1
+ export declare const PG_UNIQUE_VIOLATION = "23505";
2
+ export declare const PG_FOREIGN_KEY_VIOLATION = "23503";
3
+ export declare function pgErrorCode(err: unknown): string | undefined;
@@ -0,0 +1,19 @@
1
+ import { hasCode } from "@intx/types";
2
+ // Postgres SQLSTATE codes. https://www.postgresql.org/docs/current/errcodes-appendix.html
3
+ export const PG_UNIQUE_VIOLATION = "23505";
4
+ export const PG_FOREIGN_KEY_VIOLATION = "23503";
5
+ // Extract a Postgres SQLSTATE from an error that a driver or ORM may have
6
+ // wrapped. postgres-js sets the code on the error it throws; Drizzle
7
+ // re-wraps that as the `cause` of a DrizzleQueryError, so the code can sit
8
+ // one or more levels down the cause chain. Walk the chain (depth-bounded so
9
+ // a self-referential cause cannot loop) and return the first code found.
10
+ export function pgErrorCode(err) {
11
+ let cur = err;
12
+ for (let depth = 0; cur != null && depth < 8; depth++) {
13
+ if (hasCode(cur)) {
14
+ return cur.code;
15
+ }
16
+ cur = cur.cause;
17
+ }
18
+ return undefined;
19
+ }
@@ -0,0 +1,15 @@
1
+ import type { modelPricing } from "./schema/catalog.js";
2
+ export type ModelPricingRow = typeof modelPricing.$inferSelect;
3
+ /**
4
+ * Selects the active pricing row per currency from an offering's append-only
5
+ * price history. For each currency, the active row is the one with the
6
+ * greatest `effectiveFrom` that is at or before `asOf`; rows dated after
7
+ * `asOf` are not yet in effect. The `(offeringId, currency, effectiveFrom)`
8
+ * uniqueness on the table guarantees no ties, so the selection is
9
+ * unambiguous.
10
+ *
11
+ * Pure: `asOf` is a parameter, never read from the clock, so the same
12
+ * function serves discovery (asOf = now) and historical cost attribution
13
+ * (asOf = the call's billing timestamp).
14
+ */
15
+ export declare function resolveActivePrice(rows: ModelPricingRow[], asOf: Date): ModelPricingRow[];
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Selects the active pricing row per currency from an offering's append-only
3
+ * price history. For each currency, the active row is the one with the
4
+ * greatest `effectiveFrom` that is at or before `asOf`; rows dated after
5
+ * `asOf` are not yet in effect. The `(offeringId, currency, effectiveFrom)`
6
+ * uniqueness on the table guarantees no ties, so the selection is
7
+ * unambiguous.
8
+ *
9
+ * Pure: `asOf` is a parameter, never read from the clock, so the same
10
+ * function serves discovery (asOf = now) and historical cost attribution
11
+ * (asOf = the call's billing timestamp).
12
+ */
13
+ export function resolveActivePrice(rows, asOf) {
14
+ const byCurrency = new Map();
15
+ for (const row of rows) {
16
+ if (row.effectiveFrom > asOf)
17
+ continue;
18
+ const current = byCurrency.get(row.currency);
19
+ if (current === undefined || row.effectiveFrom > current.effectiveFrom) {
20
+ byCurrency.set(row.currency, row);
21
+ }
22
+ }
23
+ return Array.from(byCurrency.values());
24
+ }
@@ -0,0 +1,13 @@
1
+ import { type CredentialCipher } from "@intx/types";
2
+ import type { DB } from "./client.js";
3
+ export type RekeyReport = {
4
+ /** Credential `secret` columns newly encrypted. */
5
+ credentialSecrets: number;
6
+ /** Credential `refresh_secret` columns newly encrypted. */
7
+ credentialRefreshSecrets: number;
8
+ /** OAuth-client `client_secret` columns newly encrypted. */
9
+ oauthClientSecrets: number;
10
+ /** Columns already encrypted and left unchanged. */
11
+ alreadyEncrypted: number;
12
+ };
13
+ export declare function rekeyCredentialSecrets(db: DB["db"], cipher: CredentialCipher): Promise<RekeyReport>;
@@ -0,0 +1,61 @@
1
+ // Re-key existing credential secrets: encrypt any secret still stored as
2
+ // plaintext, in place, under the given cipher.
3
+ //
4
+ // Ordinarily every secret is encrypted at its write site, so on a database
5
+ // created after encryption-at-rest landed there is nothing to do. This pass
6
+ // exists for the transition: a database whose rows predate encryption still
7
+ // holds plaintext, and the strict read path throws on a non-ciphertext value.
8
+ // Running this once (against a stopped hub, so no write races an un-re-keyed
9
+ // row) brings every row to the encrypted form.
10
+ //
11
+ // Idempotent: a value already a ciphertext is skipped, so the pass is safe to
12
+ // re-run or resume after a partial failure.
13
+ import { eq } from "drizzle-orm";
14
+ import { credentialAad } from "@intx/types";
15
+ import { isCiphertext } from "@intx/crypto";
16
+ import { credential } from "./schema/credentials.js";
17
+ import { oauthClient } from "./schema/oauth-clients.js";
18
+ export async function rekeyCredentialSecrets(db, cipher) {
19
+ const report = {
20
+ credentialSecrets: 0,
21
+ credentialRefreshSecrets: 0,
22
+ oauthClientSecrets: 0,
23
+ alreadyEncrypted: 0,
24
+ };
25
+ for (const row of await db.select().from(credential)) {
26
+ const updates = {};
27
+ if (isCiphertext(row.secret)) {
28
+ report.alreadyEncrypted += 1;
29
+ }
30
+ else {
31
+ updates.secret = await cipher.encrypt(row.secret, credentialAad(row.id, "secret"));
32
+ report.credentialSecrets += 1;
33
+ }
34
+ if (row.refreshSecret !== null) {
35
+ if (isCiphertext(row.refreshSecret)) {
36
+ report.alreadyEncrypted += 1;
37
+ }
38
+ else {
39
+ updates.refreshSecret = await cipher.encrypt(row.refreshSecret, credentialAad(row.id, "refreshSecret"));
40
+ report.credentialRefreshSecrets += 1;
41
+ }
42
+ }
43
+ if (updates.secret !== undefined || updates.refreshSecret !== undefined) {
44
+ await db.update(credential).set(updates).where(eq(credential.id, row.id));
45
+ }
46
+ }
47
+ for (const row of await db.select().from(oauthClient)) {
48
+ if (isCiphertext(row.clientSecret)) {
49
+ report.alreadyEncrypted += 1;
50
+ continue;
51
+ }
52
+ await db
53
+ .update(oauthClient)
54
+ .set({
55
+ clientSecret: await cipher.encrypt(row.clientSecret, credentialAad(row.id, "clientSecret")),
56
+ })
57
+ .where(eq(oauthClient.id, row.id));
58
+ report.oauthClientSecrets += 1;
59
+ }
60
+ return report;
61
+ }
@@ -0,0 +1,245 @@
1
+ export declare const approval: import("drizzle-orm/pg-core").PgTableWithColumns<{
2
+ name: "approval";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/pg-core").PgColumn<{
6
+ name: "id";
7
+ tableName: "approval";
8
+ dataType: "string";
9
+ columnType: "PgText";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: false;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: [string, ...string[]];
18
+ baseColumn: never;
19
+ identity: undefined;
20
+ generated: undefined;
21
+ }, {}, {}>;
22
+ tenantId: import("drizzle-orm/pg-core").PgColumn<{
23
+ name: "tenant_id";
24
+ tableName: "approval";
25
+ dataType: "string";
26
+ columnType: "PgText";
27
+ data: string;
28
+ driverParam: string;
29
+ notNull: true;
30
+ hasDefault: false;
31
+ isPrimaryKey: false;
32
+ isAutoincrement: false;
33
+ hasRuntimeDefault: false;
34
+ enumValues: [string, ...string[]];
35
+ baseColumn: never;
36
+ identity: undefined;
37
+ generated: undefined;
38
+ }, {}, {}>;
39
+ anchorRunId: import("drizzle-orm/pg-core").PgColumn<{
40
+ name: "anchor_run_id";
41
+ tableName: "approval";
42
+ dataType: "string";
43
+ columnType: "PgText";
44
+ data: string;
45
+ driverParam: string;
46
+ notNull: true;
47
+ hasDefault: false;
48
+ isPrimaryKey: false;
49
+ isAutoincrement: false;
50
+ hasRuntimeDefault: false;
51
+ enumValues: [string, ...string[]];
52
+ baseColumn: never;
53
+ identity: undefined;
54
+ generated: undefined;
55
+ }, {}, {}>;
56
+ runId: import("drizzle-orm/pg-core").PgColumn<{
57
+ name: "run_id";
58
+ tableName: "approval";
59
+ dataType: "string";
60
+ columnType: "PgText";
61
+ data: string;
62
+ driverParam: string;
63
+ notNull: true;
64
+ hasDefault: false;
65
+ isPrimaryKey: false;
66
+ isAutoincrement: false;
67
+ hasRuntimeDefault: false;
68
+ enumValues: [string, ...string[]];
69
+ baseColumn: never;
70
+ identity: undefined;
71
+ generated: undefined;
72
+ }, {}, {}>;
73
+ agentAddress: import("drizzle-orm/pg-core").PgColumn<{
74
+ name: "agent_address";
75
+ tableName: "approval";
76
+ dataType: "string";
77
+ columnType: "PgText";
78
+ data: string;
79
+ driverParam: string;
80
+ notNull: true;
81
+ hasDefault: false;
82
+ isPrimaryKey: false;
83
+ isAutoincrement: false;
84
+ hasRuntimeDefault: false;
85
+ enumValues: [string, ...string[]];
86
+ baseColumn: never;
87
+ identity: undefined;
88
+ generated: undefined;
89
+ }, {}, {}>;
90
+ correlationId: import("drizzle-orm/pg-core").PgColumn<{
91
+ name: "correlation_id";
92
+ tableName: "approval";
93
+ dataType: "string";
94
+ columnType: "PgText";
95
+ data: string;
96
+ driverParam: string;
97
+ notNull: true;
98
+ hasDefault: false;
99
+ isPrimaryKey: false;
100
+ isAutoincrement: false;
101
+ hasRuntimeDefault: false;
102
+ enumValues: [string, ...string[]];
103
+ baseColumn: never;
104
+ identity: undefined;
105
+ generated: undefined;
106
+ }, {}, {}>;
107
+ toolDefinition: import("drizzle-orm/pg-core").PgColumn<{
108
+ name: "tool_definition";
109
+ tableName: "approval";
110
+ dataType: "json";
111
+ columnType: "PgJsonb";
112
+ data: unknown;
113
+ driverParam: unknown;
114
+ notNull: true;
115
+ hasDefault: false;
116
+ isPrimaryKey: false;
117
+ isAutoincrement: false;
118
+ hasRuntimeDefault: false;
119
+ enumValues: undefined;
120
+ baseColumn: never;
121
+ identity: undefined;
122
+ generated: undefined;
123
+ }, {}, {}>;
124
+ toolArguments: import("drizzle-orm/pg-core").PgColumn<{
125
+ name: "tool_arguments";
126
+ tableName: "approval";
127
+ dataType: "json";
128
+ columnType: "PgJsonb";
129
+ data: unknown;
130
+ driverParam: unknown;
131
+ notNull: true;
132
+ hasDefault: false;
133
+ isPrimaryKey: false;
134
+ isAutoincrement: false;
135
+ hasRuntimeDefault: false;
136
+ enumValues: undefined;
137
+ baseColumn: never;
138
+ identity: undefined;
139
+ generated: undefined;
140
+ }, {}, {}>;
141
+ scope: import("drizzle-orm/pg-core").PgColumn<{
142
+ name: "scope";
143
+ tableName: "approval";
144
+ dataType: "string";
145
+ columnType: "PgText";
146
+ data: "always" | "once";
147
+ driverParam: string;
148
+ notNull: false;
149
+ hasDefault: false;
150
+ isPrimaryKey: false;
151
+ isAutoincrement: false;
152
+ hasRuntimeDefault: false;
153
+ enumValues: ["once", "always"];
154
+ baseColumn: never;
155
+ identity: undefined;
156
+ generated: undefined;
157
+ }, {}, {}>;
158
+ status: import("drizzle-orm/pg-core").PgColumn<{
159
+ name: "status";
160
+ tableName: "approval";
161
+ dataType: "string";
162
+ columnType: "PgText";
163
+ data: "pending" | "approved" | "rejected" | "timeout" | "expired";
164
+ driverParam: string;
165
+ notNull: true;
166
+ hasDefault: true;
167
+ isPrimaryKey: false;
168
+ isAutoincrement: false;
169
+ hasRuntimeDefault: false;
170
+ enumValues: ["pending", "approved", "rejected", "timeout", "expired"];
171
+ baseColumn: never;
172
+ identity: undefined;
173
+ generated: undefined;
174
+ }, {}, {}>;
175
+ timeoutAt: import("drizzle-orm/pg-core").PgColumn<{
176
+ name: "timeout_at";
177
+ tableName: "approval";
178
+ dataType: "date";
179
+ columnType: "PgTimestamp";
180
+ data: Date;
181
+ driverParam: string;
182
+ notNull: false;
183
+ hasDefault: false;
184
+ isPrimaryKey: false;
185
+ isAutoincrement: false;
186
+ hasRuntimeDefault: false;
187
+ enumValues: undefined;
188
+ baseColumn: never;
189
+ identity: undefined;
190
+ generated: undefined;
191
+ }, {}, {}>;
192
+ resolvedAt: import("drizzle-orm/pg-core").PgColumn<{
193
+ name: "resolved_at";
194
+ tableName: "approval";
195
+ dataType: "date";
196
+ columnType: "PgTimestamp";
197
+ data: Date;
198
+ driverParam: string;
199
+ notNull: false;
200
+ hasDefault: false;
201
+ isPrimaryKey: false;
202
+ isAutoincrement: false;
203
+ hasRuntimeDefault: false;
204
+ enumValues: undefined;
205
+ baseColumn: never;
206
+ identity: undefined;
207
+ generated: undefined;
208
+ }, {}, {}>;
209
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
210
+ name: "created_at";
211
+ tableName: "approval";
212
+ dataType: "date";
213
+ columnType: "PgTimestamp";
214
+ data: Date;
215
+ driverParam: string;
216
+ notNull: true;
217
+ hasDefault: true;
218
+ isPrimaryKey: false;
219
+ isAutoincrement: false;
220
+ hasRuntimeDefault: false;
221
+ enumValues: undefined;
222
+ baseColumn: never;
223
+ identity: undefined;
224
+ generated: undefined;
225
+ }, {}, {}>;
226
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
227
+ name: "updated_at";
228
+ tableName: "approval";
229
+ dataType: "date";
230
+ columnType: "PgTimestamp";
231
+ data: Date;
232
+ driverParam: string;
233
+ notNull: true;
234
+ hasDefault: true;
235
+ isPrimaryKey: false;
236
+ isAutoincrement: false;
237
+ hasRuntimeDefault: false;
238
+ enumValues: undefined;
239
+ baseColumn: never;
240
+ identity: undefined;
241
+ generated: undefined;
242
+ }, {}, {}>;
243
+ };
244
+ dialect: "pg";
245
+ }>;
@@ -0,0 +1,52 @@
1
+ import { index, jsonb, pgTable, text, timestamp } from "drizzle-orm/pg-core";
2
+ import { tenant } from "./tenants.js";
3
+ import { workflowRun } from "./workflow-run.js";
4
+ // Every approval originates from a workflow deployment, so the origin is
5
+ // modeled as the deployment's anchor run -- the workflow_run whose id equals
6
+ // the deployment id -- rather than a launched single agent. A workflow
7
+ // deployment has no `agent_instance` or `agent` row, and the principal its run
8
+ // executes under is a substrate principal, not a `principal`-table row -- so
9
+ // none of those tables can hold a valid referent for an approval's origin.
10
+ export const approval = pgTable("approval", {
11
+ id: text("id").primaryKey(),
12
+ tenantId: text("tenant_id")
13
+ .notNull()
14
+ .references(() => tenant.id, { onDelete: "cascade" }),
15
+ anchorRunId: text("anchor_run_id")
16
+ .notNull()
17
+ .references(() => workflowRun.id, { onDelete: "cascade" }),
18
+ // References the run this approval belongs to, making "this approval is for
19
+ // a real run of this deployment" a database invariant. Cascades on the
20
+ // run's delete; the `anchor_run_id` FK above stays as the lock and cascade
21
+ // anchor the co-write orders against.
22
+ runId: text("run_id")
23
+ .notNull()
24
+ .references(() => workflowRun.id, { onDelete: "cascade" }),
25
+ agentAddress: text("agent_address").notNull(),
26
+ correlationId: text("correlation_id").notNull().unique(),
27
+ // Always populated: the ask rail is the sole co-writer and the register
28
+ // frame's required snapshot guarantees both fields at insert time.
29
+ toolDefinition: jsonb("tool_definition").notNull(),
30
+ toolArguments: jsonb("tool_arguments").notNull(),
31
+ scope: text("scope", { enum: ["once", "always"] }),
32
+ status: text("status", {
33
+ enum: ["pending", "approved", "rejected", "timeout", "expired"],
34
+ })
35
+ .notNull()
36
+ .default("pending"),
37
+ // Nullable so an approval that holds indefinitely can be recorded with no
38
+ // deadline. An agent-step suspend parks on its correlation's signal with no
39
+ // timeout (`parkOnSignal` is called without a `timeout`), so no `timeoutAt`
40
+ // reaches the sidecar frame that co-writes this row -- the deadline lives in
41
+ // the reactor's gate, which the hold-indefinitely suspend path never sets.
42
+ // A null `timeoutAt` is the hold-indefinitely case; a resolver that adds
43
+ // per-workflow expiry populates it when a deadline is configured. Parallels
44
+ // the tool-snapshot columns above, which are likewise deferred.
45
+ timeoutAt: timestamp("timeout_at"),
46
+ resolvedAt: timestamp("resolved_at"),
47
+ createdAt: timestamp("created_at").notNull().defaultNow(),
48
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
49
+ }, (t) => [
50
+ index("approval_tenant_status_idx").on(t.tenantId, t.status, t.createdAt),
51
+ index("approval_anchor_run_idx").on(t.anchorRunId),
52
+ ]);