@desplega.ai/agent-swarm 1.167.0 → 1.169.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 (184) hide show
  1. package/dist/{acp-adapter-zpvy6321.js → acp-adapter-m47zfx4a.js} +2 -2
  2. package/dist/{actions-fq2zrwtf.js → actions-ws7k3tvq.js} +25 -19
  3. package/dist/{amp-adapter-5gbk7501.js → amp-adapter-nvv8k8j5.js} +1 -1
  4. package/dist/{app-nctetn1e.js → app-80w6qspx.js} +5 -5
  5. package/dist/{assistant-0aq8gjvj.js → assistant-jtq439kw.js} +29 -20
  6. package/dist/{boot-reembed-1ze5853n.js → boot-reembed-3nc0aaed.js} +4 -4
  7. package/dist/{boot-reembed-fmp5ww69.js → boot-reembed-feda8wn8.js} +4 -4
  8. package/dist/{boot-scrub-sweep-cbp8xd4e.js → boot-scrub-sweep-grsa2er0.js} +5 -5
  9. package/dist/{boot-seeds-22tx8a53.js → boot-seeds-gcfgq44f.js} +7 -7
  10. package/dist/{claude-adapter-0jhgeh1d.js → claude-adapter-pjv2q7t8.js} +7 -7
  11. package/dist/{claude-managed-adapter-tzwxy803.js → claude-managed-adapter-0wa8se82.js} +2 -2
  12. package/dist/{claude-managed-setup-nrhfx5b0.js → claude-managed-setup-zxa9p9tx.js} +1 -1
  13. package/dist/{claude-sdk-session-wh77rh83.js → claude-sdk-session-c9j6k9kx.js} +8772 -8663
  14. package/dist/{cli-c2tpw9ck.js → cli-3ry5gx4f.js} +1 -1
  15. package/dist/{cli-wydz3feg.js → cli-61tbnjpf.js} +214 -2472
  16. package/dist/{cli-cexctgn5.js → cli-7vz49g7h.js} +101 -34
  17. package/dist/{cli-6qxmjpem.js → cli-8xjst8q2.js} +34 -22
  18. package/dist/{cli-tx2zvn23.js → cli-91r17hb1.js} +3 -3
  19. package/dist/{cli-577bxkf6.js → cli-a8vps458.js} +182 -2208
  20. package/dist/{cli-tc5zec7v.js → cli-b7y8113e.js} +1 -1
  21. package/dist/{cli-69egj654.js → cli-bqrs5ycj.js} +1 -1
  22. package/dist/{cli-cf2vgn9d.js → cli-dv76vq5d.js} +30 -28
  23. package/dist/{cli-g5erf0zt.js → cli-e2prcx5m.js} +31 -0
  24. package/dist/{cli-c8r99akr.js → cli-e5qk3m2a.js} +209 -31
  25. package/dist/{cli-z1dqhc9y.js → cli-eqfbsxsn.js} +3 -3
  26. package/dist/{cli-kw0jcfje.js → cli-fyeft04q.js} +1 -1
  27. package/dist/{cli-5qkcdv8c.js → cli-gmdajfw5.js} +3 -3
  28. package/dist/{cli-ypgba1a8.js → cli-jkfxpg1b.js} +1 -1
  29. package/dist/{cli-mxvnnv5q.js → cli-jv36y8wz.js} +1 -1
  30. package/dist/{cli-m7vmeepg.js → cli-km8559dm.js} +6 -6
  31. package/dist/{cli-ykt8f7va.js → cli-kp3vfknv.js} +1 -1
  32. package/dist/{cli-ymmc1zxg.js → cli-m23r88re.js} +8 -5
  33. package/dist/{cli-v1pwxreq.js → cli-n4z21pt8.js} +1 -1
  34. package/dist/{cli-mxry91sa.js → cli-qg2zhjfc.js} +73 -4
  35. package/dist/{cli-1yrcfa5s.js → cli-rbr91whd.js} +4 -4
  36. package/dist/{cli-mkdsy1nq.js → cli-rg1c8ccw.js} +93 -7
  37. package/dist/cli-rh44xx46.js +2659 -0
  38. package/dist/cli-s0k2j7q9.js +2084 -0
  39. package/dist/{cli-ty4bzkqr.js → cli-sajr098b.js} +1 -1
  40. package/dist/{cli-6vfz44sr.js → cli-swrz3mj8.js} +1 -1
  41. package/dist/{cli-p8rt8spp.js → cli-vejds37t.js} +2 -2
  42. package/dist/{cli-jbzbr36n.js → cli-w6xa5nf5.js} +1 -1
  43. package/dist/{cli-9q3wt23f.js → cli-x6z90nq9.js} +1 -1
  44. package/dist/{cli-qzmzwegq.js → cli-ysnkvdx6.js} +102 -9
  45. package/dist/{cli-y0kjpfm9.js → cli-yvxfaem2.js} +2 -2
  46. package/dist/{cli-pkj1w46r.js → cli-z48ggfyq.js} +1 -1
  47. package/dist/{cli-6bpvv8h4.js → cli-zzev32jw.js} +1 -1
  48. package/dist/cli.js +20 -17
  49. package/dist/{codex-adapter-cgesnjkr.js → codex-adapter-0kpg09ca.js} +3 -3
  50. package/dist/{codex-hook-15dgc4cb.js → codex-hook-295jpbfa.js} +2 -2
  51. package/dist/{codex-session-runner-8kd7ddhr.js → codex-session-runner-8n672hxh.js} +3 -3
  52. package/dist/{commands-h6zaaxym.js → commands-mhmg5n0x.js} +4 -4
  53. package/dist/{cursor-adapter-v8mm6bp5.js → cursor-adapter-wn8n5zzk.js} +2 -2
  54. package/dist/{db-qg3myn53.js → db-wa6s1mwv.js} +4 -4
  55. package/dist/{dispatcher-7vnwj9qw.js → dispatcher-nhs2pkr8.js} +16 -14
  56. package/dist/{dsh-adapter-tz6hfp5r.js → dsh-adapter-5423p70m.js} +1 -1
  57. package/dist/{grok-adapter-jdt2dz2s.js → grok-adapter-28pkdt80.js} +3 -3
  58. package/dist/{handlers-2qtkpncr.js → handlers-5rtf9nng.js} +19 -17
  59. package/dist/{hook-51yfcgsv.js → hook-krjfkpzy.js} +4 -4
  60. package/dist/{hook-qnbdgwvd.js → hook-qkm73zk6.js} +5 -5
  61. package/dist/{http-jsmtag08.js → http-a397xcn4.js} +4845 -3484
  62. package/dist/{index-2t9kesn1.js → index-ac0v8v9d.js} +4 -4
  63. package/dist/{index-ekywyv2v.js → index-kqre45fr.js} +16 -14
  64. package/dist/{index-bt8wkv1w.js → index-rtxg15ah.js} +17 -15
  65. package/dist/{index-t4g06w93.js → index-vvsq7v45.js} +26 -23
  66. package/dist/{index-cx1sb9bq.js → index-ytdhtdry.js} +50 -11
  67. package/dist/{keepalive-4aezx4bj.js → keepalive-psfh8ysx.js} +6 -6
  68. package/dist/{lead-r44bkpm5.js → lead-m6rppjn7.js} +29 -27
  69. package/dist/{maintenance-grz5jrzh.js → maintenance-41f837ke.js} +4 -4
  70. package/dist/{node-qm9eb6z0.js → node-fkajaq96.js} +1 -1
  71. package/dist/{oauth-refresh-sweep-wm4ctjfj.js → oauth-refresh-sweep-6hr55hm8.js} +5 -5
  72. package/dist/{onboard-v60zgqf0.js → onboard-ktrtd7cz.js} +2 -2
  73. package/dist/{otel-impl-ghh4dyf8.js → otel-impl-dq4f2k3m.js} +1 -1
  74. package/dist/{pi-mono-adapter-0eg8kw2c.js → pi-mono-adapter-e5v9w0hv.js} +3 -2
  75. package/dist/{pricing-refresh-mjrqvnvw.js → pricing-refresh-kmk7j1ra.js} +6 -6
  76. package/dist/{rbac-roles-fd5tskj9.js → rbac-roles-9w1dkkxd.js} +4 -4
  77. package/dist/{rbac-roles-axv4d74x.js → rbac-roles-9ykx9tc5.js} +5 -5
  78. package/dist/{render-v2-k50j33qd.js → render-v2-ycqm53np.js} +5 -5
  79. package/dist/resume-cq2pkp8q.js +70 -0
  80. package/dist/{setup-4syh0pd2.js → setup-0dcmdvbn.js} +2 -2
  81. package/dist/{virtual-modules-ftr9kwe8.js → virtual-modules-1x9k4jcs.js} +1 -1
  82. package/dist/{work-objects-jcdbg8rr.js → work-objects-x01x2fh8.js} +19 -17
  83. package/dist/{worker-x8j8c9sx.js → worker-py1ssb1h.js} +29 -27
  84. package/openapi.json +15622 -15042
  85. package/package.json +8 -5
  86. package/src/apps/store.ts +1 -0
  87. package/src/artifact-sdk/feedback-overlay.ts +528 -0
  88. package/src/be/db/workflow-runs.ts +95 -0
  89. package/src/be/db-queries/slack-inbound.ts +489 -0
  90. package/src/be/db.ts +9 -2
  91. package/src/be/extensions/assets.ts +1 -1
  92. package/src/be/migrations/203_workflow_run_parent_step.sql +10 -0
  93. package/src/be/migrations/204_slack_inbound_receipts.sql +51 -0
  94. package/src/be/script-connections.ts +41 -7
  95. package/src/be/scripts/run-saved.ts +40 -20
  96. package/src/be/swarm-config-guard.ts +4 -0
  97. package/src/extensions/catalog.generated.json +17 -0
  98. package/src/extensions/catalog.ts +1 -1
  99. package/src/extensions/dispatcher.ts +3 -3
  100. package/src/heartbeat/heartbeat.ts +152 -2
  101. package/src/heartbeat/templates.ts +16 -0
  102. package/src/http/all-routes.ts +1 -0
  103. package/src/http/index.ts +2 -0
  104. package/src/http/integrations.ts +3 -1
  105. package/src/http/mcp-bridge.ts +1 -0
  106. package/src/http/pages-public.ts +7 -2
  107. package/src/http/pages.ts +178 -0
  108. package/src/http/script-connections.ts +35 -0
  109. package/src/http/slack-inbound.ts +107 -0
  110. package/src/http/tasks.ts +45 -27
  111. package/src/http/users.ts +1 -1
  112. package/src/http/webhooks.ts +20 -20
  113. package/src/prompts/session-templates.ts +32 -0
  114. package/src/providers/acp-targets.ts +1 -1
  115. package/src/providers/amp-adapter.ts +2 -2
  116. package/src/providers/claude-adapter.ts +6 -0
  117. package/src/providers/claude-background-keepalive.ts +100 -0
  118. package/src/providers/claude-managed-adapter.ts +2 -11
  119. package/src/providers/claude-sdk-session.ts +7 -1
  120. package/src/providers/dsh-adapter.ts +1 -1
  121. package/src/providers/opencode-adapter.ts +1 -2
  122. package/src/providers/pi-mono-adapter.ts +3 -3
  123. package/src/realtime/browser.generated.txt +8 -8
  124. package/src/realtime/browser.ts +3 -3
  125. package/src/scheduler/scheduler.ts +82 -13
  126. package/src/scripts-runtime/executors/quickjs-pool-config.ts +26 -0
  127. package/src/scripts-runtime/executors/quickjs.ts +9 -2
  128. package/src/scripts-runtime/executors/registry.ts +1 -1
  129. package/src/server.ts +1 -0
  130. package/src/slack/actions.ts +6 -2
  131. package/src/slack/app.ts +5 -0
  132. package/src/slack/assistant.ts +15 -5
  133. package/src/slack/egress-scrub.ts +3 -2
  134. package/src/slack/handlers.ts +36 -18
  135. package/src/slack/inbound-dispatch.ts +549 -0
  136. package/src/slack/inbound-files.ts +2 -0
  137. package/src/telemetry-context.ts +1 -0
  138. package/src/tests/claude-background-keepalive-wiring.test.ts +220 -0
  139. package/src/tests/claude-background-keepalive.fixture.ts +162 -0
  140. package/src/tests/claude-background-keepalive.test.ts +139 -0
  141. package/src/tests/codex-oauth-device.test.ts +1 -1
  142. package/src/tests/connection-embedded-auth.test.ts +51 -0
  143. package/src/tests/docs-index-footprint.test.js +3 -3
  144. package/src/tests/dsh-adapter.test.ts +1 -1
  145. package/src/tests/extensions-catalog.test.ts +1 -0
  146. package/src/tests/extensions-example-slack-reply-gate.test.ts +756 -0
  147. package/src/tests/heartbeat-checklist.test.ts +243 -0
  148. package/src/tests/pages-feedback.test.ts +218 -0
  149. package/src/tests/schedule-target-type.test.ts +136 -0
  150. package/src/tests/script-connections-http.test.ts +45 -0
  151. package/src/tests/script-connections-mcp.test.ts +41 -0
  152. package/src/tests/script-connections.test.ts +2 -0
  153. package/src/tests/script-executor-quickjs-pool.test.ts +106 -0
  154. package/src/tests/script-executor-registry.test.ts +56 -0
  155. package/src/tests/send-task-self-send.test.ts +107 -0
  156. package/src/tests/slack-inbound-diagnostics-auth.test.ts +93 -0
  157. package/src/tests/slack-inbound-receipts.test.ts +684 -0
  158. package/src/tests/slack-session-status.test.ts +4 -2
  159. package/src/tests/ui-e2e-ingest-payload.test.ts +5 -1
  160. package/src/tests/user-token-routes.test.ts +1 -1
  161. package/src/tests/workflow-executors.test.ts +3 -2
  162. package/src/tests/workflow-sub-workflow.test.ts +363 -0
  163. package/src/tools/script-connections/tool.ts +35 -3
  164. package/src/tools/send-task.ts +9 -1
  165. package/src/utils/internal-ai/complete-structured.ts +6 -3
  166. package/src/utils/runtime-model-catalog.ts +1 -1
  167. package/src/workflows/engine.ts +17 -1
  168. package/src/workflows/executors/agent-task.ts +2 -2
  169. package/src/workflows/executors/human-in-the-loop.ts +3 -3
  170. package/src/workflows/executors/registry.ts +2 -0
  171. package/src/workflows/executors/script.ts +1 -1
  172. package/src/workflows/executors/sub-workflow.ts +135 -0
  173. package/src/workflows/executors/wait.ts +3 -3
  174. package/src/workflows/recovery.ts +11 -1
  175. package/src/workflows/resume.ts +77 -0
  176. package/src/workflows/wait-filter.ts +5 -7
  177. package/templates/extensions/README.md +1 -0
  178. package/templates/extensions/slack-reply-gate/README.md +98 -0
  179. package/templates/extensions/slack-reply-gate/hooks.ts +582 -0
  180. package/templates/extensions/slack-reply-gate/manifest.json +8 -0
  181. package/templates/skills/heartbeat-runbook/content.md +3 -1
  182. package/templates/skills/pages/content.md +25 -0
  183. package/templates/skills/swarm-scripts/SKILL.md +10 -0
  184. package/templates/skills/swarm-scripts/content.md +10 -0
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  ensurePricingSeeded,
22
22
  ensureRbacSeeded
23
- } from "./cli-tx2zvn23.js";
23
+ } from "./cli-91r17hb1.js";
24
24
  import {
25
25
  buildCatalogEntries,
26
26
  getCatalogGeneration,
@@ -30,83 +30,67 @@ import {
30
30
  requestModelCatalogRefresh,
31
31
  startPricingRefreshLoop,
32
32
  upsertModelCatalogOverlay
33
- } from "./cli-p8rt8spp.js";
33
+ } from "./cli-vejds37t.js";
34
34
  import {
35
35
  loadModelsDevCache
36
- } from "./cli-v1pwxreq.js";
36
+ } from "./cli-n4z21pt8.js";
37
37
  import {
38
38
  AppDefinitionSchema,
39
39
  AppElementsSchema,
40
40
  AppNameSchema,
41
- BaseExecutor,
42
41
  ColumnKindSchema,
43
42
  ConnectionAuthInputSchema,
44
43
  DEFAULT_SCRIPT_RESOURCES,
45
- HumanInTheLoopExecutor,
46
44
  MAX_SCRIPT_WALL_CLOCK_MS,
47
45
  MIN_SCRIPT_WALL_CLOCK_MS,
48
46
  SCRIPT_LONG_TIMEOUT_HINT_MS,
49
47
  SORTABLE_SYSTEM_DATE_COLUMNS,
50
48
  SYSTEM_COLUMN_KINDS,
51
- SYSTEM_ONE_DECISION_NODE_TYPE,
52
- SystemOneDecisionExecutor,
53
49
  appDefinitionNeedsRepair,
54
50
  applyAppDefinitionPatch,
55
- applyDefinitionPatch,
56
51
  assertUrlSafe,
57
52
  buildSandboxedCommand,
58
53
  buildScriptCredentialBindings,
59
54
  buildScriptCredentialBindingsWithFailures,
60
55
  connectionAuthInputFromFlat,
61
56
  createApp,
62
- createApprovalFollowUpTask,
63
57
  createCappedStreamState,
64
58
  decodeAppDefinition,
65
- definitionNodeIds,
66
59
  deleteApp,
60
+ deleteScriptConnection,
67
61
  disableCredentialBinding,
68
62
  extractArgsJsonSchema,
69
63
  extractScriptSignature,
70
- findEntryNodes,
71
- generateEdges,
72
64
  getApp,
73
- getNextTargets,
74
65
  getOAuthBindingTokenStatus,
75
66
  getOAuthProviderConfig,
76
67
  getSavedScriptOwnerAgentId,
77
68
  getScriptApiConnectionDescriptors,
78
69
  getScriptConnectionById,
79
70
  getScriptMcpConnectionDescriptors,
80
- getSuccessors,
81
71
  isIso8601Date,
82
72
  listApps,
83
73
  listRelationalCredentialBindings,
84
74
  listScriptConnections,
85
75
  parseAppDefinition,
86
- postApprovalCancellationUpdates,
87
76
  publicEndpointSsrfOptions,
88
77
  readStreamCapped,
89
78
  refreshScriptConnection,
90
79
  require_dist as require_dist2,
91
80
  resolveSyncRunAs,
92
- resolveValidationPort,
93
- resolveWorkflowLlmConfig,
94
81
  runSavedScriptAsAgent,
95
82
  runScript,
96
83
  sandboxSpawnEnv,
97
84
  setScriptConnectionEnabled,
98
85
  snapshotCapped,
99
- systemOneRetryViolations,
100
- systemOneUnresolvedError,
101
86
  typecheckScript,
102
87
  updateApp,
103
88
  upgradeAppDefinition,
104
89
  upsertCredentialBinding,
105
90
  upsertScriptConnection,
106
- validateDefinition,
107
91
  validateScriptImports,
108
92
  writeBareImportShim
109
- } from "./cli-577bxkf6.js";
93
+ } from "./cli-a8vps458.js";
110
94
  import {
111
95
  getApiKey
112
96
  } from "./cli-f14fvzag.js";
@@ -121,12 +105,77 @@ import {
121
105
  ensureToken,
122
106
  ensureTokenOrThrow,
123
107
  onAuthorizationRefreshed
124
- } from "./cli-kw0jcfje.js";
108
+ } from "./cli-fyeft04q.js";
125
109
  import {
126
110
  AgentFsProvider,
127
111
  getFileStorageProvider,
128
112
  providerPath
129
113
  } from "./cli-mzfth0bp.js";
114
+ import {
115
+ FAILED_TASK_OUTPUT_PREFIX,
116
+ FOREACH_TERMINAL_STEP_STATUSES,
117
+ SubWorkflowExecutor,
118
+ TriggerSchemaError,
119
+ WaitExecutor,
120
+ buildForeachAggregate,
121
+ buildNodeInterpolationCtx,
122
+ cancelWorkflowRun,
123
+ cancelWorkflowRunRows,
124
+ checkpointPortStepAndResolveSuccessors,
125
+ checkpointStep,
126
+ checkpointStepFailure,
127
+ checkpointStepWaiting,
128
+ completeTaskStepAndResolveSuccessors,
129
+ failRunOnUnreadableReplay,
130
+ failStepAndRunIfWaiting,
131
+ finalizeOrWait,
132
+ findJsonSchemaShapeErrors,
133
+ findReadyNodes,
134
+ getAutomationSetupStates,
135
+ getMaxWorkflowStepsPerRun,
136
+ getSecretInputKeys,
137
+ holdWorkflowRun,
138
+ initWaitBusSubscriptions,
139
+ interpolateNodeConfig,
140
+ isNeedsSetupFailure,
141
+ isWorkflowRunActive,
142
+ loadCompletedStepRouting,
143
+ notifyAutomationPreflightFailure,
144
+ parseSyntheticNodeId,
145
+ preflightAutomation,
146
+ recordSchedulePreflightFailure,
147
+ rehydrateCompletedStepOutputs,
148
+ renderAutomationTokens,
149
+ resolveInputValue,
150
+ resumeFromChildRun,
151
+ resumeWaitState,
152
+ retryFailedRun,
153
+ runStepValidation,
154
+ schedulePreflightInput,
155
+ scheduleTaskStepRetry,
156
+ scriptBodyInterpolationError,
157
+ setupWorkflowResumeListener,
158
+ shapeApprovalResolution,
159
+ startWorkflowExecution,
160
+ validateJsonSchema,
161
+ walkGraph,
162
+ withSaveWarnings,
163
+ workflowSaveWarnings
164
+ } from "./cli-rh44xx46.js";
165
+ import {
166
+ BaseExecutor,
167
+ HumanInTheLoopExecutor,
168
+ SystemOneDecisionExecutor,
169
+ applyDefinitionPatch,
170
+ createApprovalFollowUpTask,
171
+ definitionNodeIds,
172
+ generateEdges,
173
+ getSuccessors,
174
+ postApprovalCancellationUpdates,
175
+ resolveValidationPort,
176
+ resolveWorkflowLlmConfig,
177
+ validateDefinition
178
+ } from "./cli-s0k2j7q9.js";
130
179
  import {
131
180
  ZodFirstPartyTypeKind,
132
181
  objectType
@@ -147,6 +196,7 @@ import {
147
196
  getTaskUrl,
148
197
  hasTaskCitationCheckRefusal,
149
198
  markdownToSlack,
199
+ noteSlackInboundSideEffect,
150
200
  renderTaskCitations,
151
201
  startSlackApp,
152
202
  stopSlackApp,
@@ -156,11 +206,11 @@ import {
156
206
  taskCitationWarnings,
157
207
  upsertTaskCitations,
158
208
  withSpan
159
- } from "./cli-c8r99akr.js";
209
+ } from "./cli-e5qk3m2a.js";
160
210
  import {
161
211
  getUserGrant,
162
212
  init_rbac_roles
163
- } from "./cli-ypgba1a8.js";
213
+ } from "./cli-jkfxpg1b.js";
164
214
  import {
165
215
  can,
166
216
  decideAdmission,
@@ -182,7 +232,6 @@ import {
182
232
  MEMORY_KEY_PATTERN,
183
233
  MEMORY_KEY_PATTERN_MESSAGE,
184
234
  SteeringRequestError,
185
- WorkflowReplayStateError,
186
235
  acceptTask,
187
236
  agentContextKey,
188
237
  agentmailContextKey,
@@ -192,7 +241,6 @@ import {
192
241
  buildJiraContextKey,
193
242
  buildRoutingAffinityFromAgent,
194
243
  cancelApprovalRequestById,
195
- cancelPendingApprovalRequestsForRun,
196
244
  cancelTask,
197
245
  checkDependencies,
198
246
  checkSlackRoutingCoherence,
@@ -220,8 +268,6 @@ import {
220
268
  createTaskExtended,
221
269
  createUser,
222
270
  createWorkflow,
223
- createWorkflowRun,
224
- createWorkflowRunStep,
225
271
  createWorkflowVersion,
226
272
  deleteAgentMailInboxMapping,
227
273
  deleteChannel,
@@ -237,7 +283,6 @@ import {
237
283
  deleteSwarmConfig,
238
284
  deleteUser,
239
285
  deleteWorkflow,
240
- detachTaskFromWorkflowRunStep,
241
286
  embedScript,
242
287
  emitMcpServerConnectedTelemetry,
243
288
  exports_db,
@@ -274,7 +319,6 @@ import {
274
319
  getCompletedStepNodeIds,
275
320
  getContextVersion,
276
321
  getContextVersionHistory,
277
- getCurrentStepForNode,
278
322
  getDailySpendForAgent,
279
323
  getDailySpendForUser,
280
324
  getDailySpendGlobal,
@@ -289,9 +333,6 @@ import {
289
333
  getInboxSummary,
290
334
  getInjectableGlobalConfigs,
291
335
  getKv,
292
- getLastRunStart,
293
- getLastSuccessfulRun,
294
- getLatestStepForNode,
295
336
  getLeadAgent,
296
337
  getLogsByTaskIdAndEventType,
297
338
  getLogsByTaskIdChronological,
@@ -310,9 +351,7 @@ import {
310
351
  getPage,
311
352
  getPageBySlug,
312
353
  getPageVersions,
313
- getPendingEventWaitNames,
314
354
  getPendingTaskForAgent,
315
- getPendingWaitsByEvent,
316
355
  getPromptTemplateById,
317
356
  getPromptTemplateHistory,
318
357
  getPromptTemplates,
@@ -329,14 +368,13 @@ import {
329
368
  getServiceByAgentAndName,
330
369
  getServiceById,
331
370
  getSessionLogsByTaskId,
371
+ getSettledChildRunParentSteps,
332
372
  getSkillById,
333
373
  getSkillByName,
334
374
  getSkillFile,
335
375
  getSkillFiles,
336
376
  getSlackTreeMessageByThread,
337
377
  getSteeringMessageById,
338
- getStepByIdempotencyKey,
339
- getStepCountForNode,
340
378
  getStuckApprovalRuns,
341
379
  getStuckWaitRuns,
342
380
  getStuckWorkflowRuns,
@@ -347,11 +385,9 @@ import {
347
385
  getSwarmRepos,
348
386
  getTaskAttachments,
349
387
  getTaskById,
350
- getTaskByWorkflowRunStepId,
351
388
  getUnassignedTasksCount,
352
389
  getUnreadMessages,
353
390
  getUserById,
354
- getWaitStateById,
355
391
  getWorkflow,
356
392
  getWorkflowRun,
357
393
  getWorkflowRunStep,
@@ -390,7 +426,7 @@ import {
390
426
  init_telemetry,
391
427
  init_telemetry_identity,
392
428
  init_templates1 as init_templates,
393
- init_workflow_replay,
429
+ init_workflow_runs,
394
430
  insertTaskAttachment,
395
431
  installMcpServer,
396
432
  installSkill,
@@ -431,6 +467,7 @@ import {
431
467
  promoteDraftTask,
432
468
  reassociateSessionLogs,
433
469
  recordBudgetRefusalNotification,
470
+ recordInlineScriptRun,
434
471
  recordSlackMessage,
435
472
  refreshDraftTaskLease,
436
473
  rejectTask,
@@ -443,13 +480,11 @@ import {
443
480
  resolveApprovalRequest,
444
481
  resolveSqliteVecExtensionPath,
445
482
  resolveStoreKey,
446
- resolveWaitState,
447
483
  restoreScratchScriptLastUsedIfUnchanged,
448
484
  rowToCandidate,
449
485
  runWithoutRequestAuth,
450
486
  scheduleContextKey,
451
487
  scheduleOrgDomainRecompute,
452
- scrubJsonValue,
453
488
  searchSkills,
454
489
  setBudgetRefusalFollowUpTaskId,
455
490
  setRequestAuth,
@@ -478,7 +513,6 @@ import {
478
513
  updateUser,
479
514
  updateWorkflow,
480
515
  updateWorkflowRun,
481
- updateWorkflowRunStep,
482
516
  upsertKv,
483
517
  upsertOAuthApp,
484
518
  upsertPromptTemplate,
@@ -488,7 +522,7 @@ import {
488
522
  upsertSwarmConfig,
489
523
  validateConfigValue,
490
524
  workflowContextKey
491
- } from "./cli-mkdsy1nq.js";
525
+ } from "./cli-rg1c8ccw.js";
492
526
  import {
493
527
  $OpenAPIRegistry,
494
528
  $OpenApiGeneratorV31,
@@ -523,7 +557,6 @@ import {
523
557
  ReasoningEffortSchema,
524
558
  RepoGuidelinesInputSchema,
525
559
  RepoHooksSchema,
526
- RetryPolicySchema,
527
560
  RoutingReasonSchema,
528
561
  ScheduledTaskTargetTypeSchema,
529
562
  ScriptRunStatusSchema,
@@ -557,11 +590,10 @@ import {
557
590
  init_task_attachment_links,
558
591
  taskAttachmentDisplayUrl,
559
592
  taskAttachmentFetchCommand
560
- } from "./cli-mxvnnv5q.js";
593
+ } from "./cli-jv36y8wz.js";
561
594
  import {
562
595
  getSlackConfiguration,
563
- init_config,
564
- isSlackConfigured
596
+ init_config
565
597
  } from "./cli-dmtrxqhg.js";
566
598
  import {
567
599
  deepInterpolate,
@@ -652,7 +684,7 @@ import {
652
684
  import {
653
685
  init_package,
654
686
  package_default
655
- } from "./cli-ymmc1zxg.js";
687
+ } from "./cli-m23r88re.js";
656
688
  import {
657
689
  init_event_bus,
658
690
  workflowEventBus
@@ -663,7 +695,6 @@ import {
663
695
  } from "./cli-zf8jjwex.js";
664
696
  import {
665
697
  init_secret_scrubber,
666
- isSensitiveKey,
667
698
  refreshSecretScrubberCache,
668
699
  registerSensitiveKeyName,
669
700
  registerVolatileSecret,
@@ -2464,8 +2495,8 @@ var require_keyword = __commonJS(function(exports) {
2464
2495
  var _a;
2465
2496
  const { gen, keyword, schema, parentSchema, $data, it } = cxt;
2466
2497
  checkAsyncKeyword(it, def);
2467
- const validate2 = !$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate;
2468
- const validateRef = useKeyword(gen, keyword, validate2);
2498
+ const validate = !$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate;
2499
+ const validateRef = useKeyword(gen, keyword, validate);
2469
2500
  const valid = gen.let("valid");
2470
2501
  cxt.block$data(valid, validateKeyword);
2471
2502
  cxt.ok((_a = def.valid) !== null && _a !== undefined ? _a : valid);
@@ -3524,28 +3555,28 @@ var require_compile = __commonJS(function(exports) {
3524
3555
  if (this.opts.code.process)
3525
3556
  sourceCode = this.opts.code.process(sourceCode, sch);
3526
3557
  const makeValidate = new Function(`${names_1.default.self}`, `${names_1.default.scope}`, sourceCode);
3527
- const validate2 = makeValidate(this, this.scope.get());
3528
- this.scope.value(validateName, { ref: validate2 });
3529
- validate2.errors = null;
3530
- validate2.schema = sch.schema;
3531
- validate2.schemaEnv = sch;
3558
+ const validate = makeValidate(this, this.scope.get());
3559
+ this.scope.value(validateName, { ref: validate });
3560
+ validate.errors = null;
3561
+ validate.schema = sch.schema;
3562
+ validate.schemaEnv = sch;
3532
3563
  if (sch.$async)
3533
- validate2.$async = true;
3564
+ validate.$async = true;
3534
3565
  if (this.opts.code.source === true) {
3535
- validate2.source = { validateName, validateCode, scopeValues: gen._values };
3566
+ validate.source = { validateName, validateCode, scopeValues: gen._values };
3536
3567
  }
3537
3568
  if (this.opts.unevaluated) {
3538
3569
  const { props, items } = schemaCxt;
3539
- validate2.evaluated = {
3570
+ validate.evaluated = {
3540
3571
  props: props instanceof codegen_1.Name ? undefined : props,
3541
3572
  items: items instanceof codegen_1.Name ? undefined : items,
3542
3573
  dynamicProps: props instanceof codegen_1.Name,
3543
3574
  dynamicItems: items instanceof codegen_1.Name
3544
3575
  };
3545
- if (validate2.source)
3546
- validate2.source.evaluated = (0, codegen_1.stringify)(validate2.evaluated);
3576
+ if (validate.source)
3577
+ validate.source.evaluated = (0, codegen_1.stringify)(validate.evaluated);
3547
3578
  }
3548
- sch.validate = validate2;
3579
+ sch.validate = validate;
3549
3580
  return sch;
3550
3581
  } catch (e) {
3551
3582
  delete sch.validate;
@@ -6860,8 +6891,8 @@ var require_ajv = __commonJS(function(exports, module) {
6860
6891
  var require_formats = __commonJS(function(exports) {
6861
6892
  Object.defineProperty(exports, "__esModule", { value: true });
6862
6893
  exports.formatNames = exports.fastFormats = exports.fullFormats = undefined;
6863
- function fmtDef(validate2, compare) {
6864
- return { validate: validate2, compare };
6894
+ function fmtDef(validate, compare) {
6895
+ return { validate, compare };
6865
6896
  }
6866
6897
  exports.fullFormats = {
6867
6898
  date: fmtDef(date2, compareDate),
@@ -7301,10 +7332,10 @@ var require_validate2 = __commonJS(function(exports) {
7301
7332
  function _interopRequireDefault(e) {
7302
7333
  return e && e.__esModule ? e : { default: e };
7303
7334
  }
7304
- function validate2(uuid2) {
7335
+ function validate(uuid2) {
7305
7336
  return typeof uuid2 === "string" && _regex.default.test(uuid2);
7306
7337
  }
7307
- var _default = exports.default = validate2;
7338
+ var _default = exports.default = validate;
7308
7339
  });
7309
7340
 
7310
7341
  // node_modules/uuid/dist/parse.js
@@ -14382,2393 +14413,27 @@ var require_dist5 = __commonJS(function(exports) {
14382
14413
  }
14383
14414
  exports.Svix = Svix;
14384
14415
  });
14385
- // src/automation-preflight-alert.ts
14386
- init_constants();
14387
- init_secret_scrubber();
14388
- async function notifyAutomationPreflightFailure(preflight) {
14389
- const channel = process.env.SLACK_ALERTS_CHANNEL?.trim();
14390
- if (!channel) {
14391
- console.warn("[Automation Preflight] SLACK_ALERTS_CHANNEL not set; skipping alert");
14392
- return;
14393
- }
14394
- try {
14395
- const { getSlackApp: getSlackApp2 } = await import("./app-nctetn1e.js");
14396
- const app = getSlackApp2();
14397
- if (!app) {
14398
- console.warn("[Automation Preflight] Slack not available, cannot send notification");
14399
- return;
14400
- }
14401
- await app.client.chat.postMessage({
14402
- channel,
14403
- text: scrubSecrets(`⚠️ Automation needs setup
14404
- ` + `Automation: ${preflight.kind} "${preflight.name}"
14405
- Missing params: ${preflight.missing.params.join(", ") || "none"}
14406
- Missing integrations: ${preflight.missing.integrations.join(", ") || "none"}
14407
- Fire SKIPPED. It was not retried or queued.
14408
- Fix setup: ${getAppUrl()}${preflight.fixUrl}`),
14409
- unfurl_links: false,
14410
- unfurl_media: false
14411
- });
14412
- } catch (error) {
14413
- console.error("[Automation Preflight] Failed to send Slack notification:", scrubSecrets(error instanceof Error ? error.message : String(error)));
14414
- }
14415
- }
14416
-
14417
- // src/be/automation-preflight.ts
14418
- init_config();
14419
- init_env_flag();
14420
- init_secret_scrubber();
14421
- init_db2();
14422
- init_oauth();
14423
- init_scrub_json();
14424
- var NEEDS_SETUP_PREFIX = "needs_setup:";
14425
- function hasValue(value) {
14426
- if (value == null)
14427
- return false;
14428
- if (typeof value === "string")
14429
- return value.trim().length > 0;
14430
- if (Array.isArray(value))
14431
- return value.length > 0;
14432
- return true;
14433
- }
14434
- var GITHUB_REPOSITORY_SLUG = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})\/[A-Za-z0-9][A-Za-z0-9._-]{0,99}(?:\.git)?$/;
14435
- var SAFE_SHELL_DATA = /^[A-Za-z0-9._~%/:@ -]+$/;
14436
- var DNS_NAME = /^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}$/;
14437
- var SAFE_EXTERNAL_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
14438
- var SAFE_GIT_REF = /^(?!-)(?!.*(?:\.\.|@\{|\/\/))[A-Za-z0-9._/-]+$/;
14439
- var SAFE_TAG_PATTERN = /^(?!-)(?!.*(?:\.\.|\/\/))[A-Za-z0-9._*?/-]+$/;
14440
- var SAFE_RELATIVE_PATH = /^(?![-/])(?!.*(?:^|\/)\.\.(?:\/|$))[A-Za-z0-9._/-]+$/;
14441
- var SAFE_REPORT_NAME = /^(?!\.{1,2}$)[A-Za-z0-9][A-Za-z0-9._ -]{0,127}$/;
14442
- function isSafeRepository(value) {
14443
- if (!SAFE_SHELL_DATA.test(value) || value.trim() !== value || value.includes(" "))
14444
- return false;
14445
- const slug = value.replace(/^https:\/\/github\.com\//, "").replace(/^git@github\.com:/, "").replace(/\/$/, "");
14446
- return GITHUB_REPOSITORY_SLUG.test(slug);
14447
- }
14448
- function isSafeGscProperty(value) {
14449
- if (!SAFE_SHELL_DATA.test(value) || value.trim() !== value)
14450
- return false;
14451
- return value.split(" ").every((property) => {
14452
- if (!property)
14453
- return false;
14454
- if (property.startsWith("sc-domain:"))
14455
- return DNS_NAME.test(property.slice(10));
14456
- if (DNS_NAME.test(property))
14457
- return true;
14458
- try {
14459
- const url = new URL(property);
14460
- return url.protocol === "https:" && !url.username && !url.password && !url.port && !url.search && !url.hash && DNS_NAME.test(url.hostname);
14461
- } catch {
14462
- return false;
14463
- }
14464
- });
14465
- }
14466
- var PARAM_VALIDATORS = {
14467
- REPO_URL: (value) => typeof value === "string" && isSafeRepository(value),
14468
- GSC_PROPERTY: (value) => typeof value === "string" && isSafeGscProperty(value),
14469
- BRANCH: (value) => typeof value === "string" && SAFE_GIT_REF.test(value),
14470
- SCOPE_PATH: (value) => typeof value === "string" && SAFE_RELATIVE_PATH.test(value),
14471
- REPORT_NAME: (value) => typeof value === "string" && value.trim() === value && SAFE_REPORT_NAME.test(value),
14472
- TAG_PATTERN: (value) => typeof value === "string" && SAFE_TAG_PATTERN.test(value),
14473
- AGENT_FS_ORG_ID: (value) => typeof value === "string" && SAFE_EXTERNAL_ID.test(value),
14474
- ORG_ID: (value) => typeof value === "string" && SAFE_EXTERNAL_ID.test(value)
14475
- };
14476
- function isUsableParam(key, value) {
14477
- if (!hasValue(value))
14478
- return false;
14479
- return PARAM_VALIDATORS[key]?.(value) ?? true;
14480
- }
14481
- function uniqueSorted(values) {
14482
- return [...new Set(values)].sort((a, b) => a.localeCompare(b));
14483
- }
14484
- function automationUrl(input) {
14485
- return input.kind === "schedule" ? `/schedules/${input.id}` : `/workflows/${input.id}`;
14486
- }
14487
- var INTEGRATION_FIX_URL = {
14488
- slack: "/settings/integrations/slack",
14489
- github: "/settings/integrations/github",
14490
- linear: "/settings/integrations/linear",
14491
- jira: "/settings/integrations/jira",
14492
- agentmail: "/settings/integrations/agentmail",
14493
- gsc: "/settings/integrations/gsc",
14494
- agentfs: "/settings/integrations/agentfs"
14495
- };
14496
- var INTEGRATION_FIRST_REQUIREMENTS = new Set([
14497
- "gsc",
14498
- "linear",
14499
- "agentmail"
14500
- ]);
14501
- function automationIntegrationFixUrl(id) {
14502
- return INTEGRATION_FIX_URL[id];
14503
- }
14504
- function isNeedsSetupFailure(reason) {
14505
- return reason?.startsWith(NEEDS_SETUP_PREFIX) ?? false;
14506
- }
14507
- function preflightAutomation(input, setup) {
14508
- const params = input.params ?? {};
14509
- const guardedParams = Object.keys(params).filter((key) => (key in PARAM_VALIDATORS));
14510
- const missingParams = uniqueSorted([...input.requiredParams ?? [], ...guardedParams].filter((key) => !isUsableParam(key, params[key])));
14511
- const missingIntegrations = uniqueSorted((input.requires ?? []).filter((id) => setup[id] === "unverified"));
14512
- const missing = { params: missingParams, integrations: missingIntegrations };
14513
- const baseUrl = automationUrl(input);
14514
- const fixes = [
14515
- ...missingParams.map((key) => ({
14516
- type: "param",
14517
- key,
14518
- url: `${baseUrl}?param=${encodeURIComponent(key)}`
14519
- })),
14520
- ...missingIntegrations.map((key) => ({
14521
- type: "integration",
14522
- key,
14523
- url: automationIntegrationFixUrl(key)
14524
- }))
14525
- ];
14526
- if (missingParams.length === 0 && missingIntegrations.length === 0) {
14527
- return {
14528
- id: input.id,
14529
- name: input.name,
14530
- kind: input.kind,
14531
- state: "running",
14532
- missing,
14533
- fixes,
14534
- fixUrl: baseUrl
14535
- };
14536
- }
14537
- const firstParam = missingParams[0];
14538
- const firstIntegration = (input.requires ?? []).find((id) => missingIntegrations.includes(id));
14539
- const integrationFirst = (input.requires ?? []).some((id) => INTEGRATION_FIRST_REQUIREMENTS.has(id));
14540
- const fixUrl = integrationFirst && firstIntegration ? automationIntegrationFixUrl(firstIntegration) : firstParam ? `${baseUrl}?param=${encodeURIComponent(firstParam)}` : firstIntegration ? automationIntegrationFixUrl(firstIntegration) : baseUrl;
14541
- const failureReason = `${NEEDS_SETUP_PREFIX} params=[${missingParams.join(",")}] integrations=[${missingIntegrations.join(",")}]`;
14542
- return {
14543
- id: input.id,
14544
- name: input.name,
14545
- kind: input.kind,
14546
- state: "needs_setup",
14547
- missing,
14548
- fixes,
14549
- fixUrl,
14550
- failureReason
14551
- };
14552
- }
14553
- var EXACT_TOKEN = /^\{\{\s*([^}]+?)\s*\}\}$/;
14554
- var TOKEN = /\{\{\s*([^}]+?)\s*\}\}/g;
14555
- function renderAutomationTokens(value, params) {
14556
- function render(current) {
14557
- if (typeof current === "string") {
14558
- const exact = EXACT_TOKEN.exec(current);
14559
- if (exact?.[1] && Object.hasOwn(params, exact[1]))
14560
- return params[exact[1]];
14561
- return current.replace(TOKEN, (token, key) => {
14562
- if (!Object.hasOwn(params, key))
14563
- return token;
14564
- const replacement = params[key];
14565
- return typeof replacement === "object" ? JSON.stringify(replacement) : String(replacement);
14566
- });
14567
- }
14568
- if (Array.isArray(current))
14569
- return current.map(render);
14570
- if (current != null && typeof current === "object") {
14571
- return Object.fromEntries(Object.entries(current).map(([key, nested]) => [key, render(nested)]));
14572
- }
14573
- return current;
14574
- }
14575
- return render(value);
14576
- }
14577
- function present(value) {
14578
- return !!value?.trim();
14579
- }
14580
- async function getAutomationSetupStates() {
14581
- const [linearTokens, jiraTokens, jiraApp] = await Promise.all([
14582
- getOAuthTokens("linear"),
14583
- getOAuthTokens("jira"),
14584
- getOAuthApp("jira")
14585
- ]);
14586
- let jiraCloudId = false;
14587
- try {
14588
- const metadata = jiraApp?.metadata ? JSON.parse(jiraApp.metadata) : null;
14589
- jiraCloudId = !!(metadata && typeof metadata === "object" && metadata.cloudId);
14590
- } catch {
14591
- jiraCloudId = false;
14592
- }
14593
- const agentFsKey = process.env.API_AGENT_FS_API_KEY ?? process.env.AGENT_FS_API_KEY;
14594
- const agentFsOrg = process.env.AGENT_FS_DEFAULT_ORG_ID ?? process.env.AGENT_FS_SHARED_ORG_ID;
14595
- const gscConfigured = present(process.env.GSC_SERVICE_ACCOUNT_BASE64) || present(process.env.GSC_SERVICE_ACCOUNT_JSON);
14596
- return {
14597
- slack: getSlackConfiguration().mode === "socket" && isSlackConfigured() ? "configured" : "unverified",
14598
- github: present(process.env.GITHUB_WEBHOOK_SECRET) && present(process.env.GITHUB_APP_ID) && present(process.env.GITHUB_APP_PRIVATE_KEY) ? "verified" : "unverified",
14599
- linear: linearTokens ? "verified" : "unverified",
14600
- jira: jiraTokens && jiraCloudId ? "verified" : "unverified",
14601
- gsc: gscConfigured ? "verified" : "unverified",
14602
- agentmail: !isEnvFlagEnabled("AGENTMAIL_DISABLE", false) && present(process.env.AGENTMAIL_API_KEY) ? "verified" : "unverified",
14603
- agentfs: present(process.env.AGENT_FS_API_URL) && present(agentFsKey) && present(agentFsOrg) && present(process.env.AGENT_FS_DEFAULT_DRIVE_ID) ? "verified" : "unverified"
14604
- };
14605
- }
14606
- function schedulePreflightInput(schedule) {
14607
- return { ...schedule, kind: "schedule" };
14608
- }
14609
- function workflowPreflightInput(workflow) {
14610
- return { ...workflow, kind: "workflow" };
14611
- }
14612
- async function listEnabledAutomationPreflightInputs() {
14613
- const rows = await getDbClient().query(`SELECT id, name, 'schedule' AS kind, params, requiredParams, requires
14614
- FROM scheduled_tasks
14615
- WHERE enabled = 1
14616
- UNION ALL
14617
- SELECT id, name, 'workflow' AS kind, params, requiredParams, requires
14618
- FROM workflows
14619
- WHERE enabled = 1`);
14620
- return rows.map((row) => ({
14621
- id: row.id,
14622
- name: row.name,
14623
- kind: row.kind,
14624
- params: JSON.parse(row.params),
14625
- requiredParams: JSON.parse(row.requiredParams),
14626
- requires: JSON.parse(row.requires)
14627
- }));
14628
- }
14629
- function utcDayBounds(now) {
14630
- const start = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
14631
- return { start: start.toISOString(), end: new Date(start.getTime() + 86400000).toISOString() };
14632
- }
14633
- async function recordSchedulePreflightFailure(scheduleId, failureReason, now = new Date) {
14634
- const message = scrubSecrets(failureReason);
14635
- return await getDbClient().transaction(async (tx) => {
14636
- const row = await tx.get("SELECT lastErrorAt, lastErrorMessage FROM scheduled_tasks WHERE id = ?", [scheduleId]);
14637
- if (!row)
14638
- return false;
14639
- if (row.lastErrorMessage === message && row.lastErrorAt?.slice(0, 10) === now.toISOString().slice(0, 10)) {
14640
- return false;
14641
- }
14642
- await tx.run(`UPDATE scheduled_tasks
14643
- SET lastErrorAt = ?, lastErrorMessage = ?, lastUpdatedAt = ?
14644
- WHERE id = ?`, [now.toISOString(), message, now.toISOString(), scheduleId]);
14645
- return true;
14646
- });
14647
- }
14648
- async function recordWorkflowPreflightFailure(input) {
14649
- const now = input.now ?? new Date;
14650
- const bounds = utcDayBounds(now);
14651
- return await getDbClient().transaction(async (tx) => {
14652
- const existing = await tx.get(`SELECT id FROM workflow_runs
14653
- WHERE workflowId = ? AND status = 'failed'
14654
- AND error LIKE 'needs_setup:%'
14655
- AND startedAt >= ? AND startedAt < ?
14656
- ORDER BY startedAt ASC LIMIT 1`, [input.workflowId, bounds.start, bounds.end]);
14657
- if (existing)
14658
- return { runId: existing.id, recorded: false };
14659
- const runId = crypto.randomUUID();
14660
- const timestamp = now.toISOString();
14661
- await tx.run(`INSERT INTO workflow_runs
14662
- (id, workflowId, status, triggerType, triggerData, error, created_by,
14663
- startedAt, lastUpdatedAt, finishedAt)
14664
- VALUES (?, ?, 'failed', ?, ?, ?, ?, ?, ?, ?)`, [
14665
- runId,
14666
- input.workflowId,
14667
- input.triggerType,
14668
- input.triggerData === undefined ? null : scrubJsonValue(input.triggerData),
14669
- scrubSecrets(input.failureReason),
14670
- input.createdBy ?? null,
14671
- timestamp,
14672
- timestamp,
14673
- timestamp
14674
- ]);
14675
- return { runId, recorded: true };
14676
- });
14677
- }
14678
-
14679
- // src/workflows/engine.ts
14680
- init_db2();
14681
- init_workflow_replay();
14682
- init_telemetry();
14683
-
14684
- // src/workflows/checkpoint.ts
14685
- init_db2();
14686
- async function checkpointStep(runId, stepId, nodeId, result, ctx) {
14687
- await getDbClient().transaction(async () => {
14688
- await updateWorkflowRunStep(stepId, {
14689
- status: "completed",
14690
- output: result.output,
14691
- nextPort: result.nextPort || undefined,
14692
- finishedAt: new Date().toISOString()
14693
- });
14694
- ctx[nodeId] = result.output;
14695
- await updateWorkflowRun(runId, {
14696
- context: ctx
14697
- });
14698
- });
14699
- }
14700
- async function checkpointStepFailure(runId, stepId, error, retryCount, retryPolicy, options) {
14701
- const now = new Date().toISOString();
14702
- if (retryPolicy && retryCount < retryPolicy.maxRetries) {
14703
- const delay = calculateBackoff(retryPolicy, retryCount);
14704
- const nextRetryAt = new Date(Date.now() + delay).toISOString();
14705
- await updateWorkflowRunStep(stepId, {
14706
- status: "failed",
14707
- error,
14708
- retryCount: retryCount + 1,
14709
- maxRetries: retryPolicy.maxRetries,
14710
- nextRetryAt
14711
- });
14712
- return { shouldRetry: true };
14713
- }
14714
- await updateWorkflowRunStep(stepId, {
14715
- status: "failed",
14716
- error,
14717
- finishedAt: now,
14718
- nextRetryAt: null
14719
- });
14720
- const markRunFailed = options?.markRunFailed ?? true;
14721
- if (markRunFailed) {
14722
- await getDbClient().transaction(async () => {
14723
- const run = await getWorkflowRun(runId);
14724
- if (run?.status !== "running" && run?.status !== "waiting")
14725
- return;
14726
- await updateWorkflowRun(runId, {
14727
- status: "failed",
14728
- error: `Step failed: ${error}`,
14729
- finishedAt: now
14730
- });
14731
- });
14732
- }
14733
- return { shouldRetry: false };
14734
- }
14735
- async function checkpointStepWaiting(runId, stepId, ctx) {
14736
- return getDbClient().transaction(async () => {
14737
- const step = await getDbClient().get(`UPDATE workflow_run_steps
14738
- SET status = 'waiting'
14739
- WHERE id = ? AND runId = ? AND status = 'running'
14740
- AND EXISTS (
14741
- SELECT 1 FROM workflow_runs
14742
- WHERE id = ? AND status IN ('running', 'waiting')
14743
- )
14744
- RETURNING id`, [stepId, runId, runId]);
14745
- if (!step)
14746
- return false;
14747
- await updateWorkflowRun(runId, { status: "waiting", context: ctx });
14748
- return true;
14749
- });
14750
- }
14751
- function calculateBackoff(policy, attempt) {
14752
- let delay;
14753
- switch (policy.strategy) {
14754
- case "exponential": {
14755
- const base = policy.baseDelayMs * 2 ** attempt;
14756
- delay = Math.random() * Math.min(base, policy.maxDelayMs);
14757
- break;
14758
- }
14759
- case "linear":
14760
- delay = policy.baseDelayMs * (attempt + 1);
14761
- break;
14762
- case "static":
14763
- delay = policy.baseDelayMs;
14764
- break;
14765
- default:
14766
- delay = policy.baseDelayMs;
14767
- }
14768
- return Math.min(delay, policy.maxDelayMs);
14769
- }
14770
-
14771
- // src/workflows/completed-step-routing.ts
14772
- init_db2();
14773
-
14774
- // src/workflows/foreach-join.ts
14775
- init_db2();
14776
- var FOREACH_TERMINAL_STEP_STATUSES = new Set([
14777
- "completed",
14778
- "failed",
14779
- "cancelled",
14780
- "skipped"
14781
- ]);
14782
- function parseSyntheticNodeId(nodeId) {
14783
- const separatorIndex = nodeId.indexOf("#");
14784
- if (separatorIndex <= 0 || separatorIndex === nodeId.length - 1)
14785
- return null;
14786
- return {
14787
- parentNodeId: nodeId.slice(0, separatorIndex),
14788
- itemKey: nodeId.slice(separatorIndex + 1)
14789
- };
14790
- }
14791
- function resolveForeachParent(def, nodeId) {
14792
- const parsed = parseSyntheticNodeId(nodeId);
14793
- if (!parsed)
14794
- return null;
14795
- const parent = def.nodes.find((node) => node.id === parsed.parentNodeId);
14796
- return parent?.type === "foreach" ? parent : null;
14797
- }
14798
- async function joinForeach(def, runId, childStep, ctx) {
14799
- const parent = resolveForeachParent(def, childStep.nodeId);
14800
- if (!parent) {
14801
- throw new Error(`Step "${childStep.nodeId}" is not a foreach child`);
14802
- }
14803
- const children = (await getWorkflowRunStepsByRunId(runId)).filter((step) => resolveForeachParent(def, step.nodeId)?.id === parent.id).sort((a, b) => childIndex(a) - childIndex(b));
14804
- if (children.some((step) => !FOREACH_TERMINAL_STEP_STATUSES.has(step.status))) {
14805
- return { joined: false, parentNodeId: parent.id, successors: [] };
14806
- }
14807
- const parentStep = await getLatestStepForNode(runId, parent.id);
14808
- if (!parentStep) {
14809
- throw new Error(`Waiting foreach parent step "${parent.id}" was not found`);
14810
- }
14811
- if (parentStep.status === "completed") {
14812
- return { joined: false, parentNodeId: parent.id, successors: [] };
14813
- }
14814
- const aggregate = buildForeachAggregate(children);
14815
- await checkpointStep(runId, parentStep.id, parent.id, { output: aggregate }, ctx);
14816
- return {
14817
- joined: true,
14818
- parentNodeId: parent.id,
14819
- successors: getSuccessors(def, parent.id)
14820
- };
14821
- }
14822
- function buildForeachAggregate(children) {
14823
- const orderedChildren = [...children].sort((a, b) => childIndex(a) - childIndex(b));
14824
- const results = orderedChildren.map((step) => {
14825
- const parsed = parseSyntheticNodeId(step.nodeId);
14826
- const status = resultStatus(step);
14827
- return {
14828
- itemKey: parsed.itemKey,
14829
- status,
14830
- output: step.output
14831
- };
14832
- });
14833
- const failedCount = results.filter((result) => result.status !== "completed").length;
14834
- const aggregate = {
14835
- results,
14836
- okCount: results.length - failedCount,
14837
- failedCount
14838
- };
14839
- return aggregate;
14840
- }
14841
- function childIndex(step) {
14842
- if (typeof step.input !== "object" || step.input === null)
14843
- return Number.MAX_SAFE_INTEGER;
14844
- const index = step.input.index;
14845
- return typeof index === "number" ? index : Number.MAX_SAFE_INTEGER;
14846
- }
14847
- function resultStatus(step) {
14848
- if (step.status !== "completed")
14849
- return step.status;
14850
- return step.error ? "failed" : "completed";
14851
- }
14852
-
14853
- // src/workflows/completed-step-routing.ts
14854
- async function loadCompletedStepRouting(def, runId, completedNodeIds) {
14855
- const activeEdges = new Set;
14856
- const stepsByNodeId = new Map;
14857
- for (const nodeId of completedNodeIds) {
14858
- if (resolveForeachParent(def, nodeId))
14859
- continue;
14860
- const step = await getLatestStepForNode(runId, nodeId);
14861
- if (step)
14862
- stepsByNodeId.set(nodeId, step);
14863
- const successors = step?.nextPort ? getSuccessors(def, nodeId, step.nextPort) : getSuccessors(def, nodeId);
14864
- for (const successor of successors) {
14865
- activeEdges.add(`${nodeId}→${successor.id}`);
14866
- }
14867
- }
14868
- return { activeEdges, stepsByNodeId };
14869
- }
14870
-
14871
- // src/workflows/cooldown.ts
14872
- init_db2();
14873
- function cooldownToMs(cooldown) {
14874
- let ms = 0;
14875
- if (cooldown.hours)
14876
- ms += cooldown.hours * 60 * 60 * 1000;
14877
- if (cooldown.minutes)
14878
- ms += cooldown.minutes * 60 * 1000;
14879
- if (cooldown.seconds)
14880
- ms += cooldown.seconds * 1000;
14881
- return ms;
14882
- }
14883
- async function shouldSkipCooldown(workflowId, cooldown) {
14884
- const cooldownMs = cooldownToMs(cooldown);
14885
- const now = Date.now();
14886
- const lastSuccess = await getLastSuccessfulRun(workflowId);
14887
- if (lastSuccess?.finishedAt) {
14888
- const lastFinished = new Date(lastSuccess.finishedAt).getTime();
14889
- if (now - lastFinished < cooldownMs)
14890
- return true;
14891
- }
14892
- const lastAttempt = await getLastRunStart(workflowId);
14893
- if (lastAttempt?.startedAt) {
14894
- const lastStarted = new Date(lastAttempt.startedAt).getTime();
14895
- if (now - lastStarted < cooldownMs)
14896
- return true;
14897
- }
14898
- return false;
14899
- }
14900
-
14901
- // src/workflows/input.ts
14902
- init_db2();
14903
- init_secret_scrubber();
14904
- async function resolveInputs(input) {
14905
- const resolved = {};
14906
- for (const [key, value] of Object.entries(input)) {
14907
- resolved[key] = await resolveInputValue(value);
14908
- }
14909
- return resolved;
14910
- }
14911
- async function resolveInputValue(value) {
14912
- const envMatch = /^\$\{(.+)\}$/.exec(value);
14913
- if (envMatch?.[1]) {
14914
- const envName = envMatch[1];
14915
- const envValue = process.env[envName];
14916
- if (envValue === undefined) {
14917
- throw new Error(`Environment variable "${envName}" is not set`);
14918
- }
14919
- return envValue;
14920
- }
14921
- if (value.startsWith("secret.")) {
14922
- const secretName = value.slice("secret.".length);
14923
- const configs = await getSwarmConfigs({ scope: "global", key: secretName });
14924
- const secretConfig = configs.find((c) => c.isSecret);
14925
- if (!secretConfig) {
14926
- throw new Error(`Secret "${secretName}" not found in config store`);
14927
- }
14928
- return secretConfig.value;
14929
- }
14930
- return value;
14931
- }
14932
- var REDACTED_SECRET_VALUE = "***REDACTED***";
14933
- function getSecretInputKeys(input) {
14934
- const keys = new Set;
14935
- if (!input)
14936
- return keys;
14937
- for (const [key, value] of Object.entries(input)) {
14938
- if (typeof value !== "string")
14939
- continue;
14940
- if (value.startsWith("secret.")) {
14941
- keys.add(key);
14942
- continue;
14943
- }
14944
- const envMatch = /^\$\{(.+)\}$/.exec(value);
14945
- if (envMatch?.[1] && isSensitiveKey(envMatch[1])) {
14946
- keys.add(key);
14947
- }
14948
- }
14949
- return keys;
14950
- }
14951
- function redactSecretsForStorage(ctx, secretKeys) {
14952
- if (secretKeys.size === 0)
14953
- return ctx;
14954
- const inputBlock = ctx.input;
14955
- if (!inputBlock || typeof inputBlock !== "object")
14956
- return ctx;
14957
- const redactedInput = { ...inputBlock };
14958
- let touched = false;
14959
- for (const key of secretKeys) {
14960
- if (key in redactedInput) {
14961
- redactedInput[key] = REDACTED_SECRET_VALUE;
14962
- touched = true;
14963
- }
14964
- }
14965
- if (!touched)
14966
- return ctx;
14967
- return { ...ctx, input: redactedInput };
14968
- }
14969
-
14970
- // src/workflows/json-schema-validator.ts
14971
- function validateJsonSchema(schema, data) {
14972
- const errors = [];
14973
- validate(schema, data, "", errors);
14974
- return errors;
14975
- }
14976
- function validate(schema, data, path, errors) {
14977
- const prefix = path || "root";
14978
- if (schema.type !== undefined) {
14979
- const expected = schema.type;
14980
- if (!matchesType(expected, data)) {
14981
- errors.push(`${prefix}: expected type "${expected}", got ${typeOf(data)}`);
14982
- return;
14983
- }
14984
- }
14985
- if (Array.isArray(schema.required) && typeof data === "object" && data !== null) {
14986
- const obj = data;
14987
- for (const key of schema.required) {
14988
- if (!(key in obj)) {
14989
- errors.push(`${prefix}: missing required property "${key}"`);
14990
- }
14991
- }
14992
- }
14993
- if (Array.isArray(schema.enum)) {
14994
- const allowed = schema.enum;
14995
- if (!allowed.some((v) => JSON.stringify(v) === JSON.stringify(data))) {
14996
- errors.push(`${prefix}: value ${JSON.stringify(data)} not in enum [${allowed.map((v) => JSON.stringify(v)).join(", ")}]`);
14997
- return;
14998
- }
14999
- }
15000
- if ("const" in schema) {
15001
- if (JSON.stringify(data) !== JSON.stringify(schema.const)) {
15002
- errors.push(`${prefix}: value ${JSON.stringify(data)} does not match const ${JSON.stringify(schema.const)}`);
15003
- return;
15004
- }
15005
- }
15006
- if (schema.properties !== undefined && typeof schema.properties === "object" && schema.properties !== null && typeof data === "object" && data !== null) {
15007
- const props = schema.properties;
15008
- const obj = data;
15009
- for (const [key, subSchema] of Object.entries(props)) {
15010
- if (key in obj) {
15011
- validate(subSchema, obj[key], path ? `${path}.${key}` : key, errors);
15012
- }
15013
- }
15014
- }
15015
- if (schema.items !== undefined && typeof schema.items === "object" && schema.items !== null && Array.isArray(data)) {
15016
- const itemSchema = schema.items;
15017
- for (let i = 0;i < data.length; i++) {
15018
- validate(itemSchema, data[i], `${prefix}[${i}]`, errors);
15019
- }
15020
- }
15021
- }
15022
- function matchesType(expected, data) {
15023
- switch (expected) {
15024
- case "string":
15025
- return typeof data === "string";
15026
- case "number":
15027
- return typeof data === "number";
15028
- case "boolean":
15029
- return typeof data === "boolean";
15030
- case "array":
15031
- return Array.isArray(data);
15032
- case "object":
15033
- return typeof data === "object" && data !== null && !Array.isArray(data);
15034
- default:
15035
- return true;
15036
- }
15037
- }
15038
- function typeOf(data) {
15039
- if (data === null)
15040
- return "null";
15041
- if (data === undefined)
15042
- return "undefined";
15043
- if (Array.isArray(data))
15044
- return "array";
15045
- return typeof data;
15046
- }
15047
- function isPlainObject(value) {
15048
- return typeof value === "object" && value !== null && !Array.isArray(value);
15049
- }
15050
- function findJsonSchemaShapeErrors(schema, path = "outputSchema") {
15051
- const errors = [];
15052
- if (!isPlainObject(schema)) {
15053
- errors.push(`${path}: must be a JSON Schema object, got ${typeOf(schema)}`);
15054
- return errors;
15055
- }
15056
- if (schema.type !== undefined && typeof schema.type !== "string") {
15057
- errors.push(`${path}.type: must be a string, got ${typeOf(schema.type)}`);
15058
- }
15059
- if (schema.required !== undefined && (!Array.isArray(schema.required) || !schema.required.every((v) => typeof v === "string"))) {
15060
- errors.push(`${path}.required: must be an array of strings`);
15061
- }
15062
- if (schema.enum !== undefined && !Array.isArray(schema.enum)) {
15063
- errors.push(`${path}.enum: must be an array`);
15064
- }
15065
- if (schema.properties !== undefined) {
15066
- if (!isPlainObject(schema.properties)) {
15067
- errors.push(`${path}.properties: must be an object mapping property names to schemas`);
15068
- } else {
15069
- for (const [key, value] of Object.entries(schema.properties)) {
15070
- errors.push(...findJsonSchemaShapeErrors(value, `${path}.properties.${key}`));
15071
- }
15072
- }
15073
- }
15074
- if (schema.items !== undefined) {
15075
- errors.push(...findJsonSchemaShapeErrors(schema.items, `${path}.items`));
15076
- }
15077
- return errors;
15078
- }
15079
-
15080
- // src/workflows/limits.ts
15081
- var DEFAULT_MAX_STEPS_PER_RUN = 500;
15082
- function getMaxWorkflowStepsPerRun() {
15083
- return Number(process.env.WORKFLOW_MAX_STEPS_PER_RUN) || DEFAULT_MAX_STEPS_PER_RUN;
15084
- }
15085
-
15086
- // src/workflows/readiness.ts
15087
- async function findWorkflowReadinessProblems(definition, registry) {
15088
- const nodesByType = new Map;
15089
- for (const node of definition.nodes) {
15090
- if (!registry.has(node.type))
15091
- continue;
15092
- const group = nodesByType.get(node.type) ?? [];
15093
- group.push({ id: node.id, config: node.config });
15094
- nodesByType.set(node.type, group);
15095
- }
15096
- const problems = [];
15097
- for (const [type, nodes] of nodesByType) {
15098
- try {
15099
- for (const problem of await registry.get(type).checkReadiness(nodes)) {
15100
- problems.push({ type, ...problem });
15101
- }
15102
- } catch {
15103
- problems.push({
15104
- type,
15105
- nodeIds: nodes.map((node) => node.id),
15106
- message: `Could not check whether "${type}" nodes are ready to run`
15107
- });
15108
- }
15109
- }
15110
- return problems;
15111
- }
15112
- function describeNodes(problem) {
15113
- const noun = problem.nodeIds.length === 1 ? "node" : "nodes";
15114
- return `${problem.type} ${noun} ${problem.nodeIds.map((id) => `"${id}"`).join(", ")}`;
15115
- }
15116
- function formatReadinessWarning(problem) {
15117
- return `${problem.message} Affects ${describeNodes(problem)}. Runs of this workflow fail before any node executes until this is fixed.`;
15118
- }
15119
- function formatReadinessProblems(problems) {
15120
- return problems.map((problem) => `${problem.message} Needed by ${describeNodes(problem)}.`).join(" ");
15121
- }
15122
- function formatReadinessRunError(problems) {
15123
- return `Run not started, no node executed: ${formatReadinessProblems(problems)}`;
15124
- }
15125
- async function workflowSaveWarnings(definition, registry) {
15126
- return (await findWorkflowReadinessProblems(definition, registry)).map(formatReadinessWarning);
15127
- }
15128
- function withSaveWarnings(text, warnings) {
15129
- return warnings.length === 0 ? text : `${text} ${warnings.map((warning) => `Warning: ${warning}`).join(" ")}`;
15130
- }
15131
-
15132
- // src/workflows/template.ts
15133
- init_template();
15134
-
15135
- // src/workflows/validation.ts
15136
- function extractPassResult(executorType, output) {
15137
- if (!output || typeof output !== "object")
15138
- return false;
15139
- const o = output;
15140
- switch (executorType) {
15141
- case "validate":
15142
- return o.pass === true;
15143
- case "script":
15144
- return o.exitCode === 0;
15145
- case "property-match":
15146
- return o.passed === true;
15147
- case "raw-llm":
15148
- if (typeof o.result === "object" && o.result !== null) {
15149
- return o.result.pass === true;
15150
- }
15151
- return false;
15152
- default:
15153
- return o.pass === true || o.passed === true || o.exitCode === 0;
15154
- }
15155
- }
15156
- async function runStepValidation(registry, stepNode, stepOutput, context, meta) {
15157
- if (!stepNode.validation) {
15158
- return { outcome: "pass" };
15159
- }
15160
- const validation = stepNode.validation;
15161
- const executorType = validation.executor || "validate";
15162
- const executor = registry.get(executorType);
15163
- const validationConfig = {
15164
- targetNodeId: meta.nodeId,
15165
- ...validation.config
15166
- };
15167
- const validationContext = {
15168
- ...context,
15169
- [meta.nodeId]: stepOutput
15170
- };
15171
- const result = await executor.run({
15172
- config: validationConfig,
15173
- context: validationContext,
15174
- meta: {
15175
- ...meta,
15176
- stepId: crypto.randomUUID()
15177
- }
15178
- });
15179
- const passed = result.status === "success" && extractPassResult(executorType, result.output);
15180
- if (passed) {
15181
- return { outcome: "pass", passed: true };
15182
- }
15183
- if (validation.mustPass) {
15184
- if (validation.retry) {
15185
- return {
15186
- outcome: "retry",
15187
- passed: false,
15188
- retryContext: {
15189
- previousOutput: stepOutput,
15190
- validationResult: result.output
15191
- }
15192
- };
15193
- }
15194
- return { outcome: "halt", passed: false };
15195
- }
15196
- return { outcome: "pass", passed: false };
15197
- }
15198
-
15199
- // src/workflows/engine.ts
15200
- var DEFAULT_TIMEOUT_MS = 30000;
15201
- function maxIterations() {
15202
- return Number(process.env.WORKFLOW_MAX_ITERATIONS) || 100;
15203
- }
15204
-
15205
- class TriggerSchemaError extends Error {
15206
- validationErrors;
15207
- constructor(validationErrors) {
15208
- super(`Trigger schema validation failed: ${validationErrors.join("; ")}`);
15209
- this.validationErrors = validationErrors;
15210
- this.name = "TriggerSchemaError";
15211
- }
15212
- }
15213
- async function resolveRenderedWorkflowInputs(input) {
15214
- const stringInputs = {};
15215
- const resolved = {};
15216
- for (const [key, value] of Object.entries(input)) {
15217
- if (typeof value === "string")
15218
- stringInputs[key] = value;
15219
- else
15220
- resolved[key] = value;
15221
- }
15222
- return { ...resolved, ...await resolveInputs(stringInputs) };
15223
- }
15224
- async function startWorkflowExecution(workflow, triggerData, registry, options = {}) {
15225
- const preflight = preflightAutomation(workflowPreflightInput(workflow), await getAutomationSetupStates());
15226
- if (preflight.state === "needs_setup") {
15227
- const { runId: runId2, recorded } = await recordWorkflowPreflightFailure({
15228
- workflowId: workflow.id,
15229
- triggerType: options.triggerType ?? "manual",
15230
- triggerData,
15231
- failureReason: preflight.failureReason,
15232
- createdBy: options.requestedByUserId
15233
- });
15234
- if (recorded)
15235
- await notifyAutomationPreflightFailure(preflight);
15236
- return runId2;
15237
- }
15238
- workflow = renderAutomationTokens(workflow, workflow.params ?? {});
15239
- if (workflow.triggerSchema) {
15240
- const validationErrors = validateJsonSchema(workflow.triggerSchema, triggerData);
15241
- if (validationErrors.length > 0) {
15242
- throw new TriggerSchemaError(validationErrors);
15243
- }
15244
- }
15245
- if (workflow.cooldown && await shouldSkipCooldown(workflow.id, workflow.cooldown)) {
15246
- const runId2 = crypto.randomUUID();
15247
- await createWorkflowRun({
15248
- id: runId2,
15249
- workflowId: workflow.id,
15250
- triggerType: options.triggerType ?? "manual",
15251
- triggerData,
15252
- createdBy: options.requestedByUserId
15253
- });
15254
- await updateWorkflowRun(runId2, {
15255
- status: "skipped",
15256
- error: "cooldown",
15257
- finishedAt: new Date().toISOString()
15258
- });
15259
- return runId2;
15260
- }
15261
- const runId = crypto.randomUUID();
15262
- await createWorkflowRun({
15263
- id: runId,
15264
- workflowId: workflow.id,
15265
- triggerType: options.triggerType ?? "manual",
15266
- triggerData,
15267
- createdBy: options.requestedByUserId
15268
- });
15269
- telemetry.workflow("started", {
15270
- workflowId: workflow.id,
15271
- nodeCount: workflow.definition.nodes.length,
15272
- triggerType: options.triggerType ?? "manual"
15273
- });
15274
- const notReady = await findWorkflowReadinessProblems(workflow.definition, registry);
15275
- if (notReady.length > 0) {
15276
- await updateWorkflowRun(runId, {
15277
- status: "failed",
15278
- error: formatReadinessRunError(notReady),
15279
- finishedAt: new Date().toISOString()
15280
- });
15281
- return runId;
15282
- }
15283
- const ctx = { trigger: triggerData };
15284
- if (options.requestedByUserId) {
15285
- ctx.swarm = { requestedByUserId: options.requestedByUserId };
15286
- }
15287
- if (workflow.dir || workflow.vcsRepo) {
15288
- ctx.workflow = { dir: workflow.dir, vcsRepo: workflow.vcsRepo };
15289
- }
15290
- if (workflow.input) {
15291
- try {
15292
- const resolved = await resolveRenderedWorkflowInputs(workflow.input);
15293
- Object.assign(ctx, { input: resolved });
15294
- } catch (err) {
15295
- await updateWorkflowRun(runId, {
15296
- status: "failed",
15297
- error: `Input resolution failed: ${err}`,
15298
- finishedAt: new Date().toISOString()
15299
- });
15300
- return runId;
15301
- }
15302
- }
15303
- const entryNodes = findEntryNodes(workflow.definition);
15304
- const secretKeys = getSecretInputKeys(workflow.input);
15305
- await walkGraph(workflow.definition, runId, ctx, entryNodes, registry, workflow.id, secretKeys, options);
15306
- return runId;
15307
- }
15308
- var activeWalks = new Map;
15309
- var executingSteps = new Set;
15310
- async function failRunOnUnreadableReplay(runId, err, stepId) {
15311
- if (!(err instanceof WorkflowReplayStateError))
15312
- return false;
15313
- const finishedAt = new Date().toISOString();
15314
- console.error(`[workflow] ${err.message}`);
15315
- if (stepId) {
15316
- await updateWorkflowRunStep(stepId, {
15317
- status: "failed",
15318
- error: err.message,
15319
- finishedAt,
15320
- nextRetryAt: null
15321
- });
15322
- }
15323
- await updateWorkflowRun(runId, { status: "failed", error: err.message, finishedAt });
15324
- return true;
15325
- }
15326
- function isWorkflowRunActive(runId) {
15327
- return activeWalks.has(runId);
15328
- }
15329
- function holdWorkflowRun(runId) {
15330
- activeWalks.set(runId, (activeWalks.get(runId) ?? 0) + 1);
15331
- let released = false;
15332
- return () => {
15333
- if (released)
15334
- return;
15335
- released = true;
15336
- const remaining = activeWalks.get(runId) - 1;
15337
- if (remaining === 0)
15338
- activeWalks.delete(runId);
15339
- else
15340
- activeWalks.set(runId, remaining);
15341
- };
15342
- }
15343
- async function walkGraph(def, runId, ctx, startNodes, registry, workflowId, secretKeys = new Set, options = {}) {
15344
- const release = holdWorkflowRun(runId);
15345
- try {
15346
- await walkGraphOwned(def, runId, ctx, startNodes, registry, workflowId, secretKeys, options);
15347
- } catch (err) {
15348
- if (!await failRunOnUnreadableReplay(runId, err))
15349
- throw err;
15350
- } finally {
15351
- release();
15352
- }
15353
- }
15354
- async function walkGraphOwned(def, runId, ctx, startNodes, registry, workflowId, secretKeys = new Set, options = {}) {
15355
- if (!options.requestedByUserId) {
15356
- options = {
15357
- ...options,
15358
- requestedByUserId: (await getWorkflowRun(runId))?.createdBy
15359
- };
15360
- }
15361
- let nodeExecutionCount = 0;
15362
- if (!("run" in ctx)) {
15363
- ctx.run = { id: runId };
15364
- }
15365
- const { completedNodeIds } = await rehydrateCompletedStepOutputs(def, runId, ctx, registry);
15366
- const { activeEdges } = await loadCompletedStepRouting(def, runId, completedNodeIds);
15367
- const allSteps = await getWorkflowRunStepsByRunId(runId);
15368
- if (allSteps.length >= getMaxWorkflowStepsPerRun()) {
15369
- await updateWorkflowRun(runId, {
15370
- status: "failed",
15371
- error: `Circuit breaker: run exceeded ${getMaxWorkflowStepsPerRun()} total steps (WORKFLOW_MAX_STEPS_PER_RUN)`,
15372
- finishedAt: new Date().toISOString()
15373
- });
15374
- return;
15375
- }
15376
- for (const step of allSteps) {
15377
- if (step.status !== "waiting")
15378
- continue;
15379
- const successors = getSuccessors(def, step.nodeId);
15380
- for (const succ of successors) {
15381
- activeEdges.add(`${step.nodeId}→${succ.id}`);
15382
- }
15383
- }
15384
- const awaited = awaitedNodeIds(allSteps, activeEdges);
15385
- let pendingNodes = startNodes.filter((n) => {
15386
- const preds = getAllPredecessors(def, n.id);
15387
- if (preds.length === 0) {
15388
- return !completedNodeIds.has(n.id);
15389
- }
15390
- const activePreds = preds.filter((predId) => activeEdges.has(`${predId}→${n.id}`) || awaited.has(predId));
15391
- const predsToCheck = activePreds.length > 0 ? activePreds : preds;
15392
- return predsToCheck.every((p) => completedNodeIds.has(p));
15393
- });
15394
- const executedInThisWalk = new Set;
15395
- while (pendingNodes.length > 0) {
15396
- nodeExecutionCount += pendingNodes.length;
15397
- if (nodeExecutionCount > maxIterations()) {
15398
- await updateWorkflowRun(runId, {
15399
- status: "failed",
15400
- error: `Max node executions (${maxIterations()}) exceeded — possible infinite loop`,
15401
- finishedAt: new Date().toISOString()
15402
- });
15403
- return;
15404
- }
15405
- const results = await Promise.all(pendingNodes.map((node) => executeStep(def, runId, ctx, node, registry, workflowId, secretKeys, options).catch(async (err) => {
15406
- await failRunOnUnreadableReplay(runId, err);
15407
- return { outcome: "failed", successors: [] };
15408
- })));
15409
- const nextBatch = new Map;
15410
- let hasWaiting = false;
15411
- for (let i = 0;i < results.length; i++) {
15412
- const result = results[i];
15413
- if (result.outcome === "failed") {
15414
- const currentRun = await getWorkflowRun(runId);
15415
- if (currentRun?.status === "failed")
15416
- return;
15417
- continue;
15418
- }
15419
- if (result.outcome === "waiting") {
15420
- hasWaiting = true;
15421
- continue;
15422
- }
15423
- const sourceNodeId = pendingNodes[i].id;
15424
- completedNodeIds.add(sourceNodeId);
15425
- executedInThisWalk.add(sourceNodeId);
15426
- for (const succ of result.successors) {
15427
- activeEdges.add(`${sourceNodeId}→${succ.id}`);
15428
- nextBatch.set(succ.id, succ);
15429
- }
15430
- }
15431
- if (hasWaiting)
15432
- return;
15433
- const readyNext = [];
15434
- const batchSteps = nextBatch.size > 0 ? await getWorkflowRunStepsByRunId(runId) : [];
15435
- const batchAwaited = awaitedNodeIds(batchSteps, activeEdges);
15436
- const batchLatest = latestStepByNode(batchSteps);
15437
- for (const [nodeId, node] of nextBatch) {
15438
- if (executedInThisWalk.has(nodeId))
15439
- continue;
15440
- const allPreds = getAllPredecessors(def, nodeId);
15441
- for (const predId of allPreds) {
15442
- if (completedNodeIds.has(predId))
15443
- continue;
15444
- const latest = batchLatest.get(predId);
15445
- if (latest?.status !== "completed")
15446
- continue;
15447
- completedNodeIds.add(predId);
15448
- if (latest.output !== undefined)
15449
- ctx[predId] = latest.output;
15450
- }
15451
- const activePreds = allPreds.filter((predId) => activeEdges.has(`${predId}→${nodeId}`) || batchAwaited.has(predId));
15452
- const allActivePredsCompleted = activePreds.every((p) => completedNodeIds.has(p));
15453
- if (allActivePredsCompleted) {
15454
- readyNext.push(node);
15455
- }
15456
- }
15457
- pendingNodes = readyNext;
15458
- }
15459
- await getDbClient().transaction(async () => {
15460
- const run = await getWorkflowRun(runId);
15461
- if (!run || run.status !== "running")
15462
- return;
15463
- const finalSteps = await getWorkflowRunStepsByRunId(runId);
15464
- if (hasRunningStep(finalSteps))
15465
- return;
15466
- const hasWaitingSteps = finalSteps.some((s) => s.status === "waiting");
15467
- const hasPendingRetries = finalSteps.some((s) => s.status === "failed" && s.nextRetryAt != null);
15468
- const failedSteps = finalSteps.filter((s) => s.status === "failed" && s.nextRetryAt == null);
15469
- const entryNodeIds = new Set(findEntryNodes(def).map((n) => n.id));
15470
- const hasCompletedSteps = finalSteps.some((s) => s.status === "completed" && !entryNodeIds.has(s.nodeId));
15471
- if (hasWaitingSteps) {
15472
- await updateWorkflowRun(runId, { status: "waiting" });
15473
- } else if (!hasPendingRetries) {
15474
- if (failedSteps.length > 0 && !hasCompletedSteps) {
15475
- const failedNodeIds = failedSteps.map((s) => s.nodeId).join(", ");
15476
- await updateWorkflowRun(runId, {
15477
- status: "failed",
15478
- error: `All branches failed. Failed nodes: ${failedNodeIds}`,
15479
- context: ctx,
15480
- finishedAt: new Date().toISOString()
15481
- });
15482
- } else if (failedSteps.length > 0) {
15483
- const failedNodeIds = failedSteps.map((s) => s.nodeId).join(", ");
15484
- await updateWorkflowRun(runId, {
15485
- status: "completed",
15486
- error: `Partial failure: nodes [${failedNodeIds}] failed (mustPass validation), but other branches completed successfully`,
15487
- context: ctx,
15488
- finishedAt: new Date().toISOString()
15489
- });
15490
- } else {
15491
- await updateWorkflowRun(runId, {
15492
- status: "completed",
15493
- context: ctx,
15494
- finishedAt: new Date().toISOString()
15495
- });
15496
- }
15497
- }
15498
- });
15499
- }
15500
- function latestStepByNode(steps) {
15501
- const latest = new Map;
15502
- for (const step of steps)
15503
- latest.set(step.nodeId, step);
15504
- return latest;
15505
- }
15506
- function awaitedNodeIds(steps, activeEdges) {
15507
- const latest = latestStepByNode(steps);
15508
- const awaited = new Set;
15509
- for (const [nodeId, step] of latest) {
15510
- if (step.status === "running" || step.status === "waiting")
15511
- awaited.add(nodeId);
15512
- }
15513
- for (const edge of activeEdges) {
15514
- const target = edge.slice(edge.indexOf("→") + 1);
15515
- if (!latest.has(target))
15516
- awaited.add(target);
15517
- }
15518
- return awaited;
15519
- }
15520
- function hasRunningStep(steps) {
15521
- for (const step of latestStepByNode(steps).values()) {
15522
- if (step.status === "running")
15523
- return true;
15524
- }
15525
- return false;
15526
- }
15527
- async function rehydrateCompletedStepOutputs(def, runId, ctx, registry) {
15528
- const completedNodeIds = new Set(await getCompletedStepNodeIds(runId));
15529
- const latestSteps = new Map;
15530
- for (const nodeId of completedNodeIds) {
15531
- if (resolveForeachParent(def, nodeId))
15532
- continue;
15533
- const step = await getLatestStepForNode(runId, nodeId);
15534
- if (!step)
15535
- continue;
15536
- if (step.output !== undefined) {
15537
- const node = def.nodes.find((candidate) => candidate.id === nodeId);
15538
- if (node && registry.has(node.type)) {
15539
- const executor = registry.get(node.type);
15540
- const parseResult = executor.outputSchema.safeParse(step.output);
15541
- if (!parseResult.success) {
15542
- console.warn(`[workflow] Recovery: step ${nodeId} output failed validation: ${parseResult.error.message}`);
15543
- continue;
15544
- }
15545
- }
15546
- ctx[nodeId] = step.output;
15547
- }
15548
- latestSteps.set(nodeId, step);
15549
- }
15550
- return { completedNodeIds, latestSteps };
15551
- }
15552
- function getAllPredecessors(def, nodeId) {
15553
- const preds = [];
15554
- for (const node of def.nodes) {
15555
- if (!node.next)
15556
- continue;
15557
- if (getNextTargets(node.next).includes(nodeId)) {
15558
- preds.push(node.id);
15559
- }
15560
- }
15561
- return preds;
15562
- }
15563
- async function executeStep(def, runId, ctx, node, registry, workflowId, secretKeys = new Set, options = {}) {
15564
- let claimedStepId;
15565
- const claimStep = async () => {
15566
- const run = await getWorkflowRun(runId);
15567
- if (!run || run.status !== "running" && run.status !== "waiting") {
15568
- return { halted: true };
15569
- }
15570
- if (node.type !== "foreach") {
15571
- const current = await getCurrentStepForNode(runId, node.id, getAllPredecessors(def, node.id));
15572
- if (current && (current.status !== "running" || executingSteps.has(current.id))) {
15573
- return { current };
15574
- }
15575
- }
15576
- const iteration = await getStepCountForNode(runId, node.id);
15577
- const idempotencyKey = `${runId}:${node.id}:${iteration}`;
15578
- const existingStep = await getStepByIdempotencyKey(idempotencyKey);
15579
- if (existingStep && (existingStep.status === "completed" || existingStep.status === "waiting")) {
15580
- return { existingStep, stepId: existingStep.id, deduped: true };
15581
- }
15582
- const latestForeachStep = node.type === "foreach" ? await getLatestStepForNode(runId, node.id) : undefined;
15583
- const reusableForeachStep = latestForeachStep && !FOREACH_TERMINAL_STEP_STATUSES.has(latestForeachStep.status) ? latestForeachStep : undefined;
15584
- const stepId = reusableForeachStep?.id ?? crypto.randomUUID();
15585
- if (!reusableForeachStep) {
15586
- await createWorkflowRunStep({
15587
- id: stepId,
15588
- runId,
15589
- nodeId: node.id,
15590
- nodeType: node.type,
15591
- input: redactSecretsForStorage(ctx, secretKeys),
15592
- idempotencyKey
15593
- });
15594
- }
15595
- claimedStepId = stepId;
15596
- executingSteps.add(stepId);
15597
- return { existingStep, stepId, deduped: false };
15598
- };
15599
- const dedup = await getDbClient().transaction(claimStep).catch((err) => {
15600
- if (claimedStepId)
15601
- executingSteps.delete(claimedStepId);
15602
- throw err;
15603
- });
15604
- if ("halted" in dedup)
15605
- return { outcome: "completed", successors: [] };
15606
- if ("current" in dedup && dedup.current) {
15607
- if (dedup.current.status !== "completed")
15608
- return { outcome: "waiting", successors: [] };
15609
- ctx[node.id] = dedup.current.output;
15610
- return { outcome: "completed", successors: [] };
15611
- }
15612
- if (dedup.deduped && dedup.existingStep) {
15613
- if (dedup.existingStep.status === "completed") {
15614
- ctx[node.id] = dedup.existingStep.output;
15615
- const successors = getSuccessors(def, node.id);
15616
- return { outcome: "completed", successors };
15617
- }
15618
- return { outcome: "waiting", successors: [] };
15619
- }
15620
- try {
15621
- return await runClaimedStep(def, runId, ctx, node, registry, dedup.existingStep, dedup.stepId, workflowId, options);
15622
- } catch (err) {
15623
- if (await failRunOnUnreadableReplay(runId, err, dedup.stepId)) {
15624
- return { outcome: "failed", successors: [] };
15625
- }
15626
- throw err;
15627
- } finally {
15628
- executingSteps.delete(dedup.stepId);
15629
- }
15630
- }
15631
- async function runClaimedStep(def, runId, ctx, node, registry, existingStep, stepId, workflowId, options = {}) {
15632
- const executor = registry.get(node.type);
15633
- const systemOneRetryProblems = systemOneRetryViolations(node);
15634
- if (systemOneRetryProblems.length > 0) {
15635
- await checkpointStepFailure(runId, stepId, systemOneRetryProblems.join("; "), 0);
15636
- return { outcome: "failed", successors: [] };
15637
- }
15638
- const interpolationCtx = buildNodeInterpolationCtx(node, ctx);
15639
- if (node.inputSchema) {
15640
- const inputErrors = validateJsonSchema(node.inputSchema, interpolationCtx);
15641
- if (inputErrors.length > 0) {
15642
- const errorMsg = `Input schema validation failed: ${inputErrors.join("; ")}`;
15643
- await checkpointStepFailure(runId, stepId, errorMsg, 0);
15644
- throw new Error(errorMsg);
15645
- }
15646
- }
15647
- const {
15648
- value: interpolatedValue,
15649
- unresolved,
15650
- scriptBodyUnresolved,
15651
- strictUnresolved
15652
- } = interpolateNodeConfig(node, interpolationCtx);
15653
- const interpolatedConfig = interpolatedValue;
15654
- const executionCtx = { ...ctx, ...interpolationCtx };
15655
- if (scriptBodyUnresolved && scriptBodyUnresolved.length > 0) {
15656
- const errorMsg = scriptBodyInterpolationError(node.id, scriptBodyUnresolved);
15657
- await checkpointStepFailure(runId, stepId, errorMsg, 0);
15658
- return { outcome: "failed", successors: [] };
15659
- }
15660
- if (strictUnresolved && strictUnresolved.length > 0) {
15661
- await checkpointStepFailure(runId, stepId, systemOneUnresolvedError(node.id, strictUnresolved), 0);
15662
- return { outcome: "failed", successors: [] };
15663
- }
15664
- if (unresolved.length > 0) {
15665
- console.warn(`[workflow] Step ${node.id}: unresolved interpolation tokens: ${unresolved.join(", ")}`);
15666
- await updateWorkflowRunStep(stepId, {
15667
- diagnostics: JSON.stringify({ unresolvedTokens: unresolved })
15668
- });
15669
- }
15670
- const meta = {
15671
- runId,
15672
- stepId,
15673
- nodeId: node.id,
15674
- workflowId: workflowId || "",
15675
- dryRun: false,
15676
- requestedByUserId: options.requestedByUserId,
15677
- inputCtx: interpolationCtx
15678
- };
15679
- const configuredTimeoutMs = typeof node.config?.timeoutMs === "number" ? node.config.timeoutMs : node.type === "script" && typeof node.config?.timeout === "number" ? node.config.timeout : undefined;
15680
- const timeoutMs = configuredTimeoutMs ?? DEFAULT_TIMEOUT_MS;
15681
- let result;
15682
- try {
15683
- result = await Promise.race([
15684
- executor.run({
15685
- config: interpolatedConfig,
15686
- context: executionCtx,
15687
- meta
15688
- }),
15689
- timeoutPromise(timeoutMs)
15690
- ]);
15691
- } catch (err) {
15692
- const errorMsg = err instanceof Error ? err.message : String(err);
15693
- const retryPolicy = node.retry || executor.retryPolicy;
15694
- const currentRetryCount = existingStep?.retryCount || 0;
15695
- const { shouldRetry } = await checkpointStepFailure(runId, stepId, errorMsg, currentRetryCount, retryPolicy);
15696
- if (!shouldRetry) {
15697
- throw err;
15698
- }
15699
- return { outcome: "completed", successors: [] };
15700
- }
15701
- if (result.status === "failed") {
15702
- const retryPolicy = node.retry || executor.retryPolicy;
15703
- const currentRetryCount = existingStep?.retryCount || 0;
15704
- const { shouldRetry } = await checkpointStepFailure(runId, stepId, result.error || "Executor returned failed status", currentRetryCount, retryPolicy);
15705
- if (result.output !== undefined) {
15706
- await updateWorkflowRunStep(stepId, { output: result.output });
15707
- }
15708
- if (!shouldRetry) {
15709
- throw new Error(result.error || "Step execution failed");
15710
- }
15711
- return { outcome: "completed", successors: [] };
15712
- }
15713
- if ("async" in result && result.async) {
15714
- const waiting = await checkpointStepWaiting(runId, stepId, ctx);
15715
- return { outcome: waiting ? "waiting" : "completed", successors: [] };
15716
- }
15717
- if (node.outputSchema && result.status === "success") {
15718
- const outputErrors = validateJsonSchema(node.outputSchema, result.output);
15719
- if (outputErrors.length > 0) {
15720
- const errorMsg = `Output schema validation failed: ${outputErrors.join("; ")}`;
15721
- await checkpointStepFailure(runId, stepId, errorMsg, 0);
15722
- throw new Error(errorMsg);
15723
- }
15724
- }
15725
- let validationResult;
15726
- if (node.validation) {
15727
- validationResult = await runStepValidation(registry, node, result.output, executionCtx, meta);
15728
- if (validationResult.outcome === "halt") {
15729
- const errorMsg = "Validation failed (mustPass)";
15730
- await checkpointStepFailure(runId, stepId, errorMsg, 0, undefined, { markRunFailed: false });
15731
- return { outcome: "failed", successors: [] };
15732
- }
15733
- if (validationResult.outcome === "retry") {
15734
- if (validationResult.retryContext) {
15735
- const historyKey = `${node.id}_validations`;
15736
- const existing = ctx[historyKey] || [];
15737
- ctx[historyKey] = [...existing, validationResult.retryContext];
15738
- }
15739
- const retryPolicy = node.validation.retry || node.retry;
15740
- const currentRetryCount = existingStep?.retryCount || 0;
15741
- await checkpointStepFailure(runId, stepId, "Validation failed, retrying", currentRetryCount, retryPolicy);
15742
- return { outcome: "completed", successors: [] };
15743
- }
15744
- }
15745
- result.nextPort = resolveValidationPort(node.next, result.nextPort, validationResult?.passed);
15746
- await checkpointStep(runId, stepId, node.id, result, ctx);
15747
- const successors = result.nextPort ? getSuccessors(def, node.id, result.nextPort) : getSuccessors(def, node.id);
15748
- return { outcome: "completed", successors };
15749
- }
15750
- function findReadyNodes(def, completedNodeIds, activeEdges) {
15751
- const predecessors = new Map;
15752
- for (const node of def.nodes) {
15753
- if (!predecessors.has(node.id)) {
15754
- predecessors.set(node.id, new Set);
15755
- }
15756
- }
15757
- for (const node of def.nodes) {
15758
- if (!node.next)
15759
- continue;
15760
- for (const target of getNextTargets(node.next)) {
15761
- if (!predecessors.has(target)) {
15762
- predecessors.set(target, new Set);
15763
- }
15764
- predecessors.get(target).add(node.id);
15765
- }
15766
- }
15767
- return def.nodes.filter((node) => {
15768
- if (completedNodeIds.has(node.id))
15769
- return false;
15770
- const preds = predecessors.get(node.id);
15771
- if (!preds || preds.size === 0)
15772
- return true;
15773
- if (activeEdges) {
15774
- const activePreds = [...preds].filter((predId) => activeEdges.has(`${predId}→${node.id}`));
15775
- if (activePreds.length === 0)
15776
- return false;
15777
- return activePreds.every((pred) => completedNodeIds.has(pred));
15778
- }
15779
- for (const pred of preds) {
15780
- if (!completedNodeIds.has(pred))
15781
- return false;
15782
- }
15783
- return true;
15784
- });
15785
- }
15786
- function buildNodeInterpolationCtx(node, ctx) {
15787
- const interpolationCtx = {};
15788
- if (ctx.trigger !== undefined)
15789
- interpolationCtx.trigger = ctx.trigger;
15790
- if (ctx.input !== undefined)
15791
- interpolationCtx.input = ctx.input;
15792
- if (ctx.workflow !== undefined)
15793
- interpolationCtx.workflow = ctx.workflow;
15794
- if (ctx.swarm !== undefined)
15795
- interpolationCtx.swarm = ctx.swarm;
15796
- if (ctx.run !== undefined)
15797
- interpolationCtx.run = ctx.run;
15798
- if (!node.inputs)
15799
- return interpolationCtx;
15800
- for (const [localName, sourcePath] of Object.entries(node.inputs)) {
15801
- const keys = sourcePath.split(".");
15802
- let value = ctx;
15803
- for (const key of keys) {
15804
- if (value == null || typeof value !== "object") {
15805
- value = undefined;
15806
- break;
15807
- }
15808
- value = value[key];
15809
- }
15810
- interpolationCtx[localName] = value;
15811
- }
15812
- return interpolationCtx;
15813
- }
15814
- var SCRIPT_BODY_ALLOWED_SOURCES = new Set(["input", "workflow", "swarm", "run"]);
15815
- function buildScriptBodyCtx(node, interpolationCtx) {
15816
- const aliases = node.inputs ?? {};
15817
- const safe = {};
15818
- for (const [key, value] of Object.entries(interpolationCtx)) {
15819
- const sourcePath = aliases[key];
15820
- const root = sourcePath === undefined ? key : sourcePath.split(".")[0] ?? "";
15821
- if (SCRIPT_BODY_ALLOWED_SOURCES.has(root))
15822
- safe[key] = value;
15823
- }
15824
- return safe;
15825
- }
15826
- function interpolateNodeConfig(node, interpolationCtx) {
15827
- if (node.type === SYSTEM_ONE_DECISION_NODE_TYPE) {
15828
- const { state, questions, ...rest } = node.config;
15829
- const restResult = deepInterpolate(rest, interpolationCtx);
15830
- const dynamic = {};
15831
- if (Object.hasOwn(node.config, "state"))
15832
- dynamic.state = state;
15833
- if (Object.hasOwn(node.config, "questions"))
15834
- dynamic.questions = questions;
15835
- const dynamicResult = deepInterpolate(dynamic, interpolationCtx, { preserveRawTokens: true });
15836
- const unresolved = [...restResult.unresolved, ...dynamicResult.unresolved];
15837
- return {
15838
- value: {
15839
- ...restResult.value,
15840
- ...dynamicResult.value
15841
- },
15842
- unresolved,
15843
- strictUnresolved: unresolved
15844
- };
15845
- }
15846
- if (node.type === "foreach" && Object.hasOwn(node.config, "over")) {
15847
- const { over, body, ...configWithoutOverAndBody } = node.config;
15848
- const configResult2 = deepInterpolate(configWithoutOverAndBody, interpolationCtx);
15849
- const overResult = deepInterpolate(over, interpolationCtx, { preserveRawTokens: true });
15850
- return {
15851
- value: {
15852
- ...configResult2.value,
15853
- over: overResult.value,
15854
- body
15855
- },
15856
- unresolved: [...configResult2.unresolved, ...overResult.unresolved]
15857
- };
15858
- }
15859
- if (node.type === "human-in-the-loop" && typeof node.config.questions === "string") {
15860
- const { questions, ...configWithoutQuestions } = node.config;
15861
- const configResult2 = deepInterpolate(configWithoutQuestions, interpolationCtx);
15862
- const questionsResult = deepInterpolate(questions, interpolationCtx, {
15863
- preserveRawTokens: true
15864
- });
15865
- return {
15866
- value: {
15867
- ...configResult2.value,
15868
- questions: questionsResult.value
15869
- },
15870
- unresolved: [...configResult2.unresolved, ...questionsResult.unresolved]
15871
- };
15872
- }
15873
- if (node.type === "script" && typeof node.config.script === "string") {
15874
- const { script, ...configWithoutScript } = node.config;
15875
- const restResult = deepInterpolate(configWithoutScript, interpolationCtx);
15876
- const scriptResult = deepInterpolate(script, buildScriptBodyCtx(node, interpolationCtx));
15877
- return {
15878
- value: {
15879
- ...restResult.value,
15880
- script: scriptResult.unresolved.length > 0 ? script : scriptResult.value
15881
- },
15882
- unresolved: [...restResult.unresolved, ...scriptResult.unresolved],
15883
- scriptBodyUnresolved: scriptResult.unresolved
15884
- };
15885
- }
15886
- if (node.type !== "swarm-script" || !Object.hasOwn(node.config, "args")) {
15887
- return deepInterpolate(node.config, interpolationCtx);
15888
- }
15889
- const { args, ...configWithoutArgs } = node.config;
15890
- const configResult = deepInterpolate(configWithoutArgs, interpolationCtx);
15891
- const argsResult = deepInterpolate(args, interpolationCtx, { preserveRawTokens: true });
15892
- return {
15893
- value: {
15894
- ...configResult.value,
15895
- args: argsResult.value
15896
- },
15897
- unresolved: [...configResult.unresolved, ...argsResult.unresolved]
15898
- };
15899
- }
15900
- function scriptBodyInterpolationError(nodeId, tokens) {
15901
- const renderedTokens = [...new Set(tokens)].map((token) => `{{${token}}}`).join(", ");
15902
- return `Script body interpolation failed for node "${nodeId}": unresolved or disallowed token(s): ${renderedTokens}. ` + "Executable source may interpolate only input, workflow, swarm, or run values. " + "Pass dynamic trigger or upstream values through config.args and read them from argv.";
15903
- }
15904
- function timeoutPromise(ms) {
15905
- return new Promise((_, reject) => {
15906
- setTimeout(() => reject(new Error(`Step timed out after ${ms}ms`)), ms);
15907
- });
15908
- }
15909
14416
 
15910
14417
  // src/workflows/index.ts
15911
14418
  init_event_bus();
15912
14419
 
15913
14420
  // src/workflows/recovery.ts
15914
14421
  init_db2();
15915
-
15916
- // src/workflows/approval-resolution.ts
15917
- function shapeApprovalResolution(registry, definition, nodeId, parkedOutput, approval) {
15918
- const node = definition.nodes.find((candidate) => candidate.id === nodeId);
15919
- if (node && registry.has(node.type)) {
15920
- const shaped = registry.get(node.type).resolveApproval(parkedOutput, approval);
15921
- if (shaped)
15922
- return shaped;
15923
- }
15924
- return {
15925
- output: {
15926
- requestId: approval.requestId,
15927
- status: approval.status,
15928
- responses: approval.responses
15929
- },
15930
- nextPort: approval.status === "timeout" ? "timeout" : approval.status === "rejected" ? "rejected" : "approved"
15931
- };
15932
- }
15933
-
15934
- // src/workflows/constants.ts
15935
- var FAILED_TASK_OUTPUT_PREFIX = "[FAILED:";
15936
-
15937
- // src/workflows/resume.ts
15938
- init_db2();
15939
- init_secret_scrubber();
15940
- init_event_bus();
15941
-
15942
- // src/workflows/executors/wait.ts
15943
- init_zod();
15944
-
15945
- // src/workflows/wait-filter.ts
15946
- var PARAM_SHADOW_KEYS = [
15947
- "require",
15948
- "process",
15949
- "Bun",
15950
- "globalThis",
15951
- "global",
15952
- "fetch",
15953
- "setTimeout",
15954
- "setInterval"
15955
- ];
15956
- var PARAM_SHADOW_VALUES = PARAM_SHADOW_KEYS.map(() => {
15957
- return;
15958
- });
15959
- var BODY_SHADOW_KEYS = ["eval", "Function", "AsyncFunction"];
15960
- var BODY_SHADOW_PREAMBLE = BODY_SHADOW_KEYS.map((k) => `var ${k} = undefined;`).join(" ");
15961
- var FILTER_TIMEOUT_MS = 50;
15962
- function getByDotPath(obj, path) {
15963
- if (obj === null || typeof obj !== "object") {
15964
- return { found: false, value: undefined };
15965
- }
15966
- const segments = path.split(".");
15967
- let cursor = obj;
15968
- for (const seg of segments) {
15969
- if (cursor === null || typeof cursor !== "object") {
15970
- return { found: false, value: undefined };
15971
- }
15972
- const rec = cursor;
15973
- if (!(seg in rec)) {
15974
- return { found: false, value: undefined };
15975
- }
15976
- cursor = rec[seg];
15977
- }
15978
- return { found: true, value: cursor };
15979
- }
15980
- function deepEqual(a, b) {
15981
- if (a === b)
15982
- return true;
15983
- if (typeof a !== typeof b)
15984
- return false;
15985
- if (a === null || b === null)
15986
- return false;
15987
- if (Array.isArray(a)) {
15988
- if (!Array.isArray(b))
15989
- return false;
15990
- if (a.length !== b.length)
15991
- return false;
15992
- for (let i = 0;i < a.length; i++) {
15993
- if (!deepEqual(a[i], b[i]))
15994
- return false;
15995
- }
15996
- return true;
15997
- }
15998
- if (typeof a === "object" && typeof b === "object") {
15999
- const aKeys = Object.keys(a);
16000
- const bKeys = Object.keys(b);
16001
- if (aKeys.length !== bKeys.length)
16002
- return false;
16003
- for (const k of aKeys) {
16004
- if (!deepEqual(a[k], b[k])) {
16005
- return false;
16006
- }
16007
- }
16008
- return true;
16009
- }
16010
- return false;
16011
- }
16012
- function matchObjectFilter(payload, filter) {
16013
- for (const [key, expected] of Object.entries(filter)) {
16014
- const { found, value } = getByDotPath(payload, key);
16015
- if (!found)
16016
- return false;
16017
- if (!deepEqual(value, expected))
16018
- return false;
16019
- }
16020
- return true;
16021
- }
16022
- async function runWithTimeout(fn) {
16023
- return new Promise((resolve) => {
16024
- let settled = false;
16025
- const timer = setTimeout(() => {
16026
- if (settled)
16027
- return;
16028
- settled = true;
16029
- resolve(null);
16030
- }, FILTER_TIMEOUT_MS);
16031
- queueMicrotask(() => {
16032
- if (settled)
16033
- return;
16034
- try {
16035
- const v = fn();
16036
- if (v !== null && typeof v === "object" && typeof v.then === "function") {
16037
- v.catch(() => {});
16038
- settled = true;
16039
- clearTimeout(timer);
16040
- resolve({ __asyncRejected: true });
16041
- return;
16042
- }
16043
- if (settled)
16044
- return;
16045
- settled = true;
16046
- clearTimeout(timer);
16047
- resolve(v);
16048
- } catch {
16049
- if (settled)
16050
- return;
16051
- settled = true;
16052
- clearTimeout(timer);
16053
- resolve(null);
16054
- }
16055
- });
16056
- });
16057
- }
16058
- var ASYNC_SENTINEL = "__asyncRejected";
16059
- function isAsyncSentinel(value) {
16060
- return value !== null && typeof value === "object" && value[ASYNC_SENTINEL] === true;
16061
- }
16062
- function compileStringFilter(filter) {
16063
- if (filter.length > 2048) {
16064
- throw new Error(`wait filter source exceeds 2KB cap (${filter.length} bytes)`);
16065
- }
16066
- let fn;
16067
- try {
16068
- fn = new Function(...PARAM_SHADOW_KEYS, "payload", `${BODY_SHADOW_PREAMBLE} return (${filter})(payload);`);
16069
- } catch (err) {
16070
- const msg = err instanceof Error ? err.message : String(err);
16071
- throw new Error(`wait filter compile error: ${msg}`);
16072
- }
16073
- return (payload) => fn(...PARAM_SHADOW_VALUES, payload);
16074
- }
16075
- function nullifyPrototypes(value) {
16076
- if (value === null || typeof value !== "object")
16077
- return value;
16078
- if (Array.isArray(value)) {
16079
- return value.map(nullifyPrototypes);
16080
- }
16081
- const out = Object.create(null);
16082
- for (const [k, v] of Object.entries(value)) {
16083
- out[k] = nullifyPrototypes(v);
16084
- }
16085
- return out;
16086
- }
16087
- async function matchesFilter(payload, filter) {
16088
- if (filter === undefined || filter === null)
16089
- return true;
16090
- if (typeof filter === "object" && !Array.isArray(filter)) {
16091
- return matchObjectFilter(payload, filter);
16092
- }
16093
- if (typeof filter === "string") {
16094
- let userFn;
16095
- try {
16096
- userFn = compileStringFilter(filter);
16097
- } catch {
16098
- return false;
16099
- }
16100
- let cloned;
16101
- try {
16102
- const cloneOnce = structuredClone(payload);
16103
- cloned = nullifyPrototypes(cloneOnce);
16104
- } catch {
16105
- try {
16106
- cloned = nullifyPrototypes(payload);
16107
- } catch {
16108
- cloned = payload;
16109
- }
16110
- }
16111
- const result = await runWithTimeout(() => userFn(cloned));
16112
- if (result === null)
16113
- return false;
16114
- if (isAsyncSentinel(result))
16115
- return false;
16116
- return !!result;
16117
- }
16118
- return false;
16119
- }
16120
-
16121
- // src/workflows/executors/wait.ts
16122
- var WaitConfigSchema = exports_external.discriminatedUnion("mode", [
16123
- exports_external.object({
16124
- mode: exports_external.literal("time"),
16125
- durationMs: exports_external.number().int().min(1).max(31536000000).describe("Wait duration in milliseconds (effective resolution ~5s)")
16126
- }),
16127
- exports_external.object({
16128
- mode: exports_external.literal("event"),
16129
- eventName: exports_external.string().min(1),
16130
- filter: exports_external.union([exports_external.record(exports_external.string(), exports_external.unknown()), exports_external.string().max(2048)]).optional(),
16131
- scope: exports_external.enum(["run", "global"]).default("run"),
16132
- timeoutMs: exports_external.number().int().min(1).max(31536000000).optional().describe("Timeout in milliseconds (effective resolution ~5s) — when reached, routes via 'timeout' port")
16133
- })
16134
- ]);
16135
- var WaitOutputSchema = exports_external.object({
16136
- waitId: exports_external.string().uuid(),
16137
- mode: exports_external.enum(["time", "event"]),
16138
- firedAt: exports_external.string().nullable(),
16139
- payload: exports_external.unknown().optional()
16140
- });
16141
-
16142
- class WaitExecutor extends BaseExecutor {
16143
- type = "wait";
16144
- mode = "async";
16145
- configSchema = WaitConfigSchema;
16146
- outputSchema = WaitOutputSchema;
16147
- async execute(config, _context, meta) {
16148
- const { db } = this.deps;
16149
- const existing = await db.getWaitStateByStepId(meta.stepId);
16150
- if (existing) {
16151
- if (existing.status !== "pending") {
16152
- const nextPort = computeNextPort(existing.mode, existing.status);
16153
- return {
16154
- status: "success",
16155
- output: {
16156
- waitId: existing.id,
16157
- mode: existing.mode,
16158
- firedAt: existing.resolvedAt,
16159
- payload: existing.firedPayload ?? undefined
16160
- },
16161
- nextPort
16162
- };
16163
- }
16164
- return {
16165
- status: "success",
16166
- async: true,
16167
- waitFor: "wait.fired",
16168
- correlationId: existing.id
16169
- };
16170
- }
16171
- if (config.mode === "time") {
16172
- const waitId2 = crypto.randomUUID();
16173
- const wakeUpAt = new Date(Date.now() + config.durationMs).toISOString();
16174
- await db.createWaitState({
16175
- id: waitId2,
16176
- workflowRunId: meta.runId,
16177
- workflowRunStepId: meta.stepId,
16178
- mode: "time",
16179
- wakeUpAt
16180
- });
16181
- return {
16182
- status: "success",
16183
- async: true,
16184
- waitFor: "wait.fired",
16185
- correlationId: waitId2
16186
- };
16187
- }
16188
- if (typeof config.filter === "string") {
16189
- compileStringFilter(config.filter);
16190
- }
16191
- const waitId = crypto.randomUUID();
16192
- const expiresAt = config.timeoutMs ? new Date(Date.now() + config.timeoutMs).toISOString() : null;
16193
- await db.createWaitState({
16194
- id: waitId,
16195
- workflowRunId: meta.runId,
16196
- workflowRunStepId: meta.stepId,
16197
- mode: "event",
16198
- eventName: config.eventName,
16199
- eventFilter: config.filter ?? null,
16200
- expiresAt,
16201
- scope: config.scope
16202
- });
16203
- subscribeWaitToBus(waitId, config.eventName);
16204
- return {
16205
- status: "success",
16206
- async: true,
16207
- waitFor: "wait.fired",
16208
- correlationId: waitId
16209
- };
16210
- }
16211
- }
16212
- function computeNextPort(mode, status) {
16213
- if (mode === "time")
16214
- return "default";
16215
- return status === "timeout" ? "timeout" : "event";
16216
- }
16217
-
16218
- // src/workflows/task-step-routing.ts
16219
- init_db2();
16220
- init_types();
16221
- async function isTaskBoundToStep(taskId, stepId) {
16222
- const task = await getTaskById(taskId);
16223
- return task?.workflowRunStepId === stepId;
16224
- }
16225
- async function failStepAndRunIfWaiting(stepId, runId, reason, ownerTaskId) {
16226
- const now = new Date().toISOString();
16227
- return await getDbClient().transaction(async () => {
16228
- const current = await getWorkflowRunStep(stepId);
16229
- if (!current || current.status !== "waiting")
16230
- return false;
16231
- if (ownerTaskId && !await isTaskBoundToStep(ownerTaskId, stepId))
16232
- return false;
16233
- await updateWorkflowRunStep(stepId, {
16234
- status: "failed",
16235
- error: reason,
16236
- finishedAt: now
16237
- });
16238
- await updateWorkflowRun(runId, {
16239
- status: "failed",
16240
- error: reason,
16241
- finishedAt: now
16242
- });
16243
- return true;
16244
- });
16245
- }
16246
- async function checkpointPortStepAndResolveSuccessors(def, runId, stepId, nodeId, output, nextPort, ctx) {
16247
- return await getDbClient().transaction(async () => {
16248
- const current = await getWorkflowRunStep(stepId);
16249
- if (!current || current.status !== "waiting")
16250
- return { claimed: false, successors: [] };
16251
- await checkpointStep(runId, stepId, nodeId, { output, nextPort }, ctx);
16252
- await updateWorkflowRun(runId, { status: "running" });
16253
- return { claimed: true, successors: getSuccessors(def, nodeId, nextPort) };
16254
- });
16255
- }
16256
- async function scheduleTaskStepRetry(def, runId, step, taskId, reason) {
16257
- const node = def.nodes.find((n) => n.id === step.nodeId);
16258
- if (!node || node.type !== "agent-task" || !node.retry)
16259
- return "not-eligible";
16260
- const parsed = RetryPolicySchema.safeParse(node.retry);
16261
- if (!parsed.success)
16262
- return "not-eligible";
16263
- const policy = parsed.data;
16264
- return await getDbClient().transaction(async () => {
16265
- const current = await getWorkflowRunStep(step.id);
16266
- if (!current || current.status !== "waiting")
16267
- return "not-claimed";
16268
- if (!await isTaskBoundToStep(taskId, step.id))
16269
- return "not-claimed";
16270
- if (current.retryCount >= policy.maxRetries)
16271
- return "not-eligible";
16272
- await detachTaskFromWorkflowRunStep(taskId);
16273
- await checkpointStepFailure(runId, step.id, reason, current.retryCount, policy);
16274
- return "scheduled";
16275
- });
16276
- }
16277
- var UNCLAIMED = {
16278
- claimed: false,
16279
- foreachChild: false,
16280
- joined: false,
16281
- successors: []
16282
- };
16283
- async function completeTaskStepAndResolveSuccessors(def, runId, step, output, ctx, failureReason, ownerTaskId) {
16284
- return await getDbClient().transaction(async () => {
16285
- const current = await getWorkflowRunStep(step.id);
16286
- if (!current || current.status !== "waiting")
16287
- return UNCLAIMED;
16288
- if (ownerTaskId && !await isTaskBoundToStep(ownerTaskId, step.id))
16289
- return UNCLAIMED;
16290
- const foreachParent = resolveForeachParent(def, step.nodeId);
16291
- if (foreachParent) {
16292
- await updateWorkflowRunStep(step.id, {
16293
- status: "completed",
16294
- output,
16295
- ...failureReason !== undefined ? { error: failureReason } : {},
16296
- finishedAt: new Date().toISOString()
16297
- });
16298
- const join = await joinForeach(def, runId, step, ctx);
16299
- await updateWorkflowRun(runId, { status: "running" });
16300
- return {
16301
- claimed: true,
16302
- foreachChild: true,
16303
- joined: join.joined,
16304
- successors: join.successors
16305
- };
16306
- }
16307
- await checkpointStep(runId, step.id, step.nodeId, { output }, ctx);
16308
- await updateWorkflowRun(runId, { status: "running" });
16309
- return {
16310
- claimed: true,
16311
- foreachChild: false,
16312
- joined: true,
16313
- successors: getSuccessors(def, step.nodeId)
16314
- };
16315
- });
16316
- }
16317
-
16318
- // src/workflows/resume.ts
16319
- function setupWorkflowResumeListener(eventBus, registry) {
16320
- const onTaskCompleted = async (data) => {
16321
- try {
16322
- const event = data;
16323
- if (!event.workflowRunId || !event.workflowRunStepId)
16324
- return;
16325
- await resumeFromTaskCompletion(event, registry);
16326
- } catch (err) {
16327
- console.error("[workflows] Resume from task completion failed:", err);
16328
- }
16329
- };
16330
- eventBus.on("task.completed", onTaskCompleted);
16331
- const onTaskFailed = async (data) => {
16332
- try {
16333
- const event = data;
16334
- if (!event.workflowRunId || !event.workflowRunStepId)
16335
- return;
16336
- await handleTaskFailure(event, event.failureReason ?? "Task failed", registry, {
16337
- retryable: true
16338
- });
16339
- } catch (err) {
16340
- console.error("[workflows] Handle task failure error:", err);
16341
- }
16342
- };
16343
- eventBus.on("task.failed", onTaskFailed);
16344
- const onTaskCancelled = async (data) => {
16345
- try {
16346
- const event = data;
16347
- if (!event.workflowRunId || !event.workflowRunStepId)
16348
- return;
16349
- await handleTaskFailure(event, "Task was cancelled", registry, { retryable: false });
16350
- } catch (err) {
16351
- console.error("[workflows] Handle task cancellation error:", err);
16352
- }
16353
- };
16354
- eventBus.on("task.cancelled", onTaskCancelled);
16355
- const onApprovalResolved = async (data) => {
16356
- try {
16357
- const event = data;
16358
- if (!event.workflowRunId || !event.workflowRunStepId)
16359
- return;
16360
- await resumeFromApprovalResolution(event, registry);
16361
- } catch (err) {
16362
- console.error("[workflows] Resume from approval resolution failed:", err);
16363
- }
16364
- };
16365
- eventBus.on("approval.resolved", onApprovalResolved);
16366
- return () => {
16367
- eventBus.off("task.completed", onTaskCompleted);
16368
- eventBus.off("task.failed", onTaskFailed);
16369
- eventBus.off("task.cancelled", onTaskCancelled);
16370
- eventBus.off("approval.resolved", onApprovalResolved);
16371
- };
16372
- }
16373
- async function failClosedOnUnreadableReplay(runId, stepId, resume) {
16374
- try {
16375
- await resume();
16376
- } catch (err) {
16377
- if (!await failRunOnUnreadableReplay(runId, err, stepId))
16378
- throw err;
16379
- }
16380
- }
16381
- async function resumeFromTaskCompletion(event, registry) {
16382
- await failClosedOnUnreadableReplay(event.workflowRunId, event.workflowRunStepId, () => resumeFromTaskCompletionUnguarded(event, registry));
16383
- }
16384
- async function resumeFromTaskCompletionUnguarded(event, registry) {
16385
- const run = await getWorkflowRun(event.workflowRunId);
16386
- if (!run || run.status !== "waiting" && run.status !== "running")
16387
- return;
16388
- const step = await getWorkflowRunStep(event.workflowRunStepId);
16389
- if (!step || step.status !== "waiting")
16390
- return;
16391
- if (await isStaleTaskEvent(step.id, event))
16392
- return;
16393
- const workflow = await getWorkflow(run.workflowId);
16394
- if (!workflow)
16395
- return;
16396
- const ctx = run.context ?? {};
16397
- let taskOutput = event.output;
16398
- if (event.output) {
16399
- try {
16400
- const parsed = JSON.parse(event.output);
16401
- if (typeof parsed === "object" && parsed !== null) {
16402
- taskOutput = parsed;
16403
- }
16404
- } catch {}
16405
- }
16406
- const stepOutput = { taskId: event.taskId, taskOutput };
16407
- const routing = await completeTaskStepAndResolveSuccessors(workflow.definition, run.id, step, stepOutput, ctx);
16408
- if (!routing.claimed)
16409
- return;
16410
- const successors = routing.successors;
16411
- if (successors.length > 0) {
16412
- const secretKeys = getSecretInputKeys(workflow.input);
16413
- await walkGraph(workflow.definition, run.id, ctx, successors, registry, workflow.id, secretKeys);
16414
- } else {
16415
- await finalizeOrWait(run.id);
16416
- }
16417
- }
16418
- async function finalizeOrWait(runId) {
16419
- await getDbClient().transaction(async () => {
16420
- const steps = await getWorkflowRunStepsByRunId(runId);
16421
- if (hasRunningStep(steps)) {
16422
- const run = await getWorkflowRun(runId);
16423
- if (run?.status === "waiting")
16424
- await updateWorkflowRun(runId, { status: "running" });
16425
- return;
16426
- }
16427
- const hasWaiting = steps.some((s) => s.status === "waiting" || s.status === "failed" && s.nextRetryAt != null);
16428
- if (hasWaiting) {
16429
- await updateWorkflowRun(runId, { status: "waiting" });
16430
- } else {
16431
- await updateWorkflowRun(runId, {
16432
- status: "completed",
16433
- finishedAt: new Date().toISOString()
16434
- });
16435
- }
16436
- });
16437
- }
16438
- async function handleTaskFailure(event, reason, registry, options) {
16439
- await failClosedOnUnreadableReplay(event.workflowRunId, event.workflowRunStepId, () => handleTaskFailureUnguarded(event, reason, registry, options));
16440
- }
16441
- async function handleTaskFailureUnguarded(event, reason, registry, options) {
16442
- const run = await getWorkflowRun(event.workflowRunId);
16443
- if (!run || run.status !== "waiting" && run.status !== "running")
16444
- return;
16445
- const step = await getWorkflowRunStep(event.workflowRunStepId);
16446
- if (!step || step.status !== "waiting")
16447
- return;
16448
- if (await isStaleTaskEvent(step.id, event))
16449
- return;
16450
- const workflow = await getWorkflow(run.workflowId);
16451
- if (!workflow)
16452
- return;
16453
- if (options.retryable) {
16454
- const retry = await scheduleTaskStepRetry(workflow.definition, run.id, step, event.taskId, reason);
16455
- if (retry === "scheduled") {
16456
- console.log(`[workflows] Task ${event.taskId} failed; step ${step.nodeId} of run ${run.id} queued for retry ${step.retryCount + 1}`);
16457
- return;
16458
- }
16459
- if (retry === "not-claimed")
16460
- return;
16461
- }
16462
- const onFailure = workflow.definition.onNodeFailure ?? "fail";
16463
- if (onFailure === "fail") {
16464
- await markRunFailed(event, reason);
16465
- return;
16466
- }
16467
- const ctx = run.context ?? {};
16468
- const stepOutput = {
16469
- taskId: event.taskId,
16470
- taskOutput: `${FAILED_TASK_OUTPUT_PREFIX} ${reason}] This node failed or was cancelled.`
16471
- };
16472
- const routing = await completeTaskStepAndResolveSuccessors(workflow.definition, run.id, step, stepOutput, ctx, reason);
16473
- if (!routing.claimed)
16474
- return;
16475
- const successors = routing.successors;
16476
- if (successors.length > 0) {
16477
- const secretKeys = getSecretInputKeys(workflow.input);
16478
- await walkGraph(workflow.definition, run.id, ctx, successors, registry, workflow.id, secretKeys);
16479
- } else {
16480
- await finalizeOrWait(run.id);
16481
- }
16482
- }
16483
- async function isStaleTaskEvent(stepId, event) {
16484
- if (!event.taskId)
16485
- return false;
16486
- const boundTask = await getTaskByWorkflowRunStepId(stepId);
16487
- return boundTask != null && boundTask.id !== event.taskId;
16488
- }
16489
- async function markRunFailed(event, reason) {
16490
- await failStepAndRunIfWaiting(event.workflowRunStepId, event.workflowRunId, reason);
16491
- }
16492
- async function retryFailedRun(runId, registry) {
16493
- const run = await getWorkflowRun(runId);
16494
- if (!run || run.status !== "failed")
16495
- throw new Error("Run is not in failed state");
16496
- const workflow = await getWorkflow(run.workflowId);
16497
- if (!workflow)
16498
- throw new Error("Workflow not found");
16499
- const steps = await getWorkflowRunStepsByRunId(runId);
16500
- const failedStep = steps.find((s) => s.status === "failed");
16501
- if (!failedStep)
16502
- throw new Error("No failed step found");
16503
- const completedNodeIds = new Set(await getCompletedStepNodeIds(runId));
16504
- const notReady = await findWorkflowReadinessProblems({ nodes: workflow.definition.nodes.filter((node) => !completedNodeIds.has(node.id)) }, registry);
16505
- if (notReady.length > 0) {
16506
- throw new Error(`Retry not started, run left failed: ${formatReadinessProblems(notReady)}`);
16507
- }
16508
- const { activeEdges } = await loadCompletedStepRouting(workflow.definition, runId, completedNodeIds);
16509
- const foreachParent = resolveForeachParent(workflow.definition, failedStep.nodeId);
16510
- const failedNode = foreachParent ?? workflow.definition.nodes.find((n) => n.id === failedStep.nodeId);
16511
- if (!failedNode)
16512
- throw new Error(`Node ${failedStep.nodeId} not found in workflow definition`);
16513
- const hasStructuralPredecessor = workflow.definition.nodes.some((node) => node.next && getNextTargets(node.next).includes(failedNode.id));
16514
- const hasActivePredecessor = [...activeEdges].some((edge) => edge.endsWith(`→${failedNode.id}`));
16515
- const shouldRetryFailedNode = foreachParent != null || !hasStructuralPredecessor || hasActivePredecessor;
16516
- const ctx = run.context ?? {};
16517
- const claimed = await getDbClient().transaction(async () => {
16518
- const current = await getWorkflowRun(runId);
16519
- if (!current || current.status !== "failed")
16520
- return false;
16521
- await updateWorkflowRunStep(failedStep.id, {
16522
- status: shouldRetryFailedNode ? "pending" : "cancelled",
16523
- error: shouldRetryFailedNode ? null : "Skipped on retry because its branch was not active"
16524
- });
16525
- await updateWorkflowRun(runId, { status: "running", error: null, context: ctx });
16526
- return true;
16527
- });
16528
- if (!claimed)
16529
- throw new Error("Run is not in failed state");
16530
- const liveNodeIds = new Set(steps.filter((s) => s.status === "running" || s.status === "waiting").map((s) => s.nodeId));
16531
- const readyNodes = findReadyNodes(workflow.definition, completedNodeIds, activeEdges).filter((n) => n.id === failedNode.id || !liveNodeIds.has(n.id));
16532
- const nodesToRun = !shouldRetryFailedNode || readyNodes.some((n) => n.id === failedNode.id) ? readyNodes : [failedNode, ...readyNodes];
16533
- const secretKeys = getSecretInputKeys(workflow.input);
16534
- await walkGraph(workflow.definition, runId, ctx, nodesToRun, registry, workflow.id, secretKeys);
16535
- }
16536
- async function cancelWorkflowRunRows(runId, cancelReason) {
16537
- const terminalStatuses = ["completed", "failed", "cancelled", "skipped"];
16538
- const now = new Date().toISOString();
16539
- return await getDbClient().transaction(async () => {
16540
- const current = await getWorkflowRun(runId);
16541
- if (!current || terminalStatuses.includes(current.status))
16542
- return false;
16543
- const steps = await getWorkflowRunStepsByRunId(runId);
16544
- for (const step of steps) {
16545
- if (terminalStatuses.includes(step.status))
16546
- continue;
16547
- const task = await getTaskByWorkflowRunStepId(step.id);
16548
- if (task) {
16549
- await cancelTask(task.id, cancelReason);
16550
- }
16551
- await updateWorkflowRunStep(step.id, {
16552
- status: "cancelled",
16553
- error: cancelReason,
16554
- finishedAt: now
16555
- });
16556
- }
16557
- await cancelPendingApprovalRequestsForRun(runId, cancelReason);
16558
- await updateWorkflowRun(runId, {
16559
- status: "cancelled",
16560
- error: cancelReason,
16561
- finishedAt: now
16562
- });
16563
- return true;
16564
- });
16565
- }
16566
- async function cancelWorkflowRun(runId, reason) {
16567
- const run = await getWorkflowRun(runId);
16568
- if (!run)
16569
- throw new Error("Workflow run not found");
16570
- const terminalStatuses = ["completed", "failed", "cancelled", "skipped"];
16571
- if (terminalStatuses.includes(run.status) && run.status !== "cancelled") {
16572
- throw new Error(`Cannot cancel run in '${run.status}' state`);
16573
- }
16574
- const cancelReason = reason ?? "Cancelled by user";
16575
- const applied = await cancelWorkflowRunRows(runId, cancelReason);
16576
- const cancelledApprovals = await listCancelledApprovalRequestsForRun(runId);
16577
- const latestRun = await getWorkflowRun(runId);
16578
- if (!applied && latestRun?.status !== "cancelled") {
16579
- throw new Error(`Cannot cancel run in '${latestRun?.status ?? "missing"}' state`);
16580
- }
16581
- await postApprovalCancellationUpdates(cancelledApprovals, applied ? cancelReason : latestRun?.error ?? cancelReason);
16582
- }
16583
- async function resumeFromApprovalResolution(event, registry) {
16584
- await failClosedOnUnreadableReplay(event.workflowRunId, event.workflowRunStepId, () => resumeFromApprovalResolutionUnguarded(event, registry));
16585
- }
16586
- async function resumeFromApprovalResolutionUnguarded(event, registry) {
16587
- const run = await getWorkflowRun(event.workflowRunId);
16588
- if (!run || run.status !== "waiting" && run.status !== "running")
16589
- return;
16590
- const step = await getWorkflowRunStep(event.workflowRunStepId);
16591
- if (!step || step.status !== "waiting")
16592
- return;
16593
- const workflow = await getWorkflow(run.workflowId);
16594
- if (!workflow)
16595
- return;
16596
- if (event.status === "cancelled") {
16597
- console.warn(`[workflows] approval ${event.requestId} is cancelled; step ${event.workflowRunStepId} stays waiting for the run cancel path`);
16598
- return;
16599
- }
16600
- const ctx = run.context ?? {};
16601
- const { output: stepOutput, nextPort } = shapeApprovalResolution(registry, workflow.definition, step.nodeId, step.output, { requestId: event.requestId, status: event.status, responses: event.responses });
16602
- const routing = await checkpointPortStepAndResolveSuccessors(workflow.definition, run.id, step.id, step.nodeId, stepOutput, nextPort, ctx);
16603
- if (!routing.claimed)
16604
- return;
16605
- const successors = routing.successors;
16606
- if (successors.length > 0) {
16607
- const secretKeys = getSecretInputKeys(workflow.input);
16608
- await walkGraph(workflow.definition, run.id, ctx, successors, registry, workflow.id, secretKeys);
16609
- } else {
16610
- await finalizeOrWait(run.id);
16611
- }
16612
- }
16613
- async function resumeWaitState(waitId, status, payload, registry) {
16614
- const cappedPayload = capPayload(payload);
16615
- const result = await resolveWaitState(waitId, { status, firedPayload: cappedPayload });
16616
- if (!result.updated || !result.row)
16617
- return;
16618
- const waitRow = result.row;
16619
- await failClosedOnUnreadableReplay(waitRow.workflowRunId, waitRow.workflowRunStepId, () => resumeClaimedWait(waitRow, status, cappedPayload, registry));
16620
- }
16621
- async function resumeClaimedWait(waitRow, status, cappedPayload, registry) {
16622
- const run = await getWorkflowRun(waitRow.workflowRunId);
16623
- if (!run || run.status !== "waiting" && run.status !== "running")
16624
- return;
16625
- const step = await getWorkflowRunStep(waitRow.workflowRunStepId);
16626
- if (!step || step.status !== "waiting")
16627
- return;
16628
- const workflow = await getWorkflow(run.workflowId);
16629
- if (!workflow)
16630
- return;
16631
- const nextPort = computeNextPort(waitRow.mode, status);
16632
- const ctx = run.context ?? {};
16633
- const stepOutput = {
16634
- waitId: waitRow.id,
16635
- mode: waitRow.mode,
16636
- firedAt: waitRow.resolvedAt,
16637
- payload: cappedPayload === undefined ? undefined : cappedPayload
16638
- };
16639
- const routing = await checkpointPortStepAndResolveSuccessors(workflow.definition, run.id, step.id, step.nodeId, stepOutput, nextPort, ctx);
16640
- if (!routing.claimed)
16641
- return;
16642
- if (waitRow.mode === "event" && waitRow.eventName) {
16643
- pruneWaitFromBus(waitRow.id, waitRow.eventName);
16644
- }
16645
- const successors = routing.successors;
16646
- if (successors.length > 0) {
16647
- const secretKeys = getSecretInputKeys(workflow.input);
16648
- await walkGraph(workflow.definition, run.id, ctx, successors, registry, workflow.id, secretKeys);
16649
- } else {
16650
- await finalizeOrWait(run.id);
16651
- }
16652
- }
16653
- var FIRED_PAYLOAD_BYTE_CAP = 64 * 1024;
16654
- function capPayload(payload) {
16655
- if (payload === undefined || payload === null)
16656
- return payload;
16657
- let encoded;
16658
- try {
16659
- encoded = JSON.stringify(payload);
16660
- } catch {
16661
- return { truncated: true, reason: "non-serializable" };
16662
- }
16663
- if (encoded.length <= FIRED_PAYLOAD_BYTE_CAP) {
16664
- return payload;
16665
- }
16666
- const summary = encoded.slice(0, 1024);
16667
- return {
16668
- truncated: true,
16669
- originalSize: encoded.length,
16670
- summary
16671
- };
16672
- }
16673
- var waitsByEvent = new Map;
16674
- var listenersByEvent = new Map;
16675
- var busRegistry = null;
16676
- async function initWaitBusSubscriptions(registry) {
16677
- busRegistry = registry;
16678
- const pendingNames = await collectPendingEventNames();
16679
- for (const name of pendingNames) {
16680
- const pending = await getPendingWaitsByEvent(name);
16681
- for (const w of pending) {
16682
- registerWait(w.id, name);
16683
- }
16684
- }
16685
- }
16686
- async function collectPendingEventNames() {
16687
- return new Set(await getPendingEventWaitNames());
16688
- }
16689
- function subscribeWaitToBus(waitId, eventName) {
16690
- registerWait(waitId, eventName);
16691
- }
16692
- function registerWait(waitId, eventName) {
16693
- let set = waitsByEvent.get(eventName);
16694
- if (!set) {
16695
- set = new Set;
16696
- waitsByEvent.set(eventName, set);
16697
- }
16698
- set.add(waitId);
16699
- if (!listenersByEvent.has(eventName)) {
16700
- const listener = (data) => {
16701
- processBusEvent(eventName, data).catch((err) => {
16702
- console.error(`[workflows] Wait bus listener failed for event=${eventName}:`, scrubSecrets(err instanceof Error ? err.message : String(err)));
16703
- });
16704
- };
16705
- listenersByEvent.set(eventName, listener);
16706
- workflowEventBus.on(eventName, listener);
16707
- }
16708
- }
16709
- function pruneWaitFromBus(waitId, eventName) {
16710
- const set = waitsByEvent.get(eventName);
16711
- if (!set)
16712
- return;
16713
- set.delete(waitId);
16714
- if (set.size === 0) {
16715
- waitsByEvent.delete(eventName);
16716
- const listener = listenersByEvent.get(eventName);
16717
- if (listener) {
16718
- workflowEventBus.off(eventName, listener);
16719
- listenersByEvent.delete(eventName);
16720
- }
16721
- }
16722
- }
16723
- async function processBusEvent(eventName, payload) {
16724
- const set = waitsByEvent.get(eventName);
16725
- if (!set || set.size === 0)
16726
- return;
16727
- if (!busRegistry)
16728
- return;
16729
- const waitIds = [...set];
16730
- for (const waitId of waitIds) {
16731
- try {
16732
- const row = await getWaitStateById(waitId);
16733
- if (!row || row.status !== "pending") {
16734
- set.delete(waitId);
16735
- continue;
16736
- }
16737
- if (row.eventScope === "run") {
16738
- if (!isPayloadInRun(payload, row.workflowRunId))
16739
- continue;
16740
- }
16741
- const ok = await matchesFilter(payload, row.eventFilter ?? undefined);
16742
- if (!ok)
16743
- continue;
16744
- await resumeWaitState(waitId, "fired", payload, busRegistry);
16745
- } catch (err) {
16746
- console.error(`[workflows] Wait bus listener failed for wait=${waitId} event=${eventName}:`, err);
16747
- }
16748
- }
16749
- if (set.size === 0) {
16750
- waitsByEvent.delete(eventName);
16751
- const listener = listenersByEvent.get(eventName);
16752
- if (listener) {
16753
- workflowEventBus.off(eventName, listener);
16754
- listenersByEvent.delete(eventName);
16755
- }
16756
- }
16757
- }
16758
- function isPayloadInRun(payload, runId) {
16759
- if (typeof payload !== "object" || payload === null)
16760
- return false;
16761
- const rec = payload;
16762
- return rec._runId === runId || rec.workflowRunId === runId;
16763
- }
16764
-
16765
- // src/workflows/recovery.ts
14422
+ init_workflow_runs();
16766
14423
  async function recoverIncompleteRuns(registry) {
16767
14424
  let recovered = 0;
16768
14425
  recovered += await recoverRunningRuns(registry);
16769
14426
  recovered += await recoverWaitingRuns(registry);
16770
14427
  recovered += await recoverApprovalWaitingRuns(registry);
16771
14428
  recovered += await recoverWaitStates(registry);
14429
+ for (const parentStepId of await getSettledChildRunParentSteps()) {
14430
+ try {
14431
+ if (await resumeFromChildRun(parentStepId, registry))
14432
+ recovered++;
14433
+ } catch (err) {
14434
+ console.error(`[workflows] Failed to resume sub-workflow step ${parentStepId}:`, err);
14435
+ }
14436
+ }
16772
14437
  if (recovered > 0) {
16773
14438
  console.log(`[workflows] Recovered ${recovered} incomplete run(s)`);
16774
14439
  }
@@ -18074,6 +15739,7 @@ var import_cron_parser = __toESM(require_dist2(), 1);
18074
15739
  init_db2();
18075
15740
  init_db();
18076
15741
  init_telemetry();
15742
+ init_secret_scrubber();
18077
15743
 
18078
15744
  // src/scheduler/deferred-task-waits.ts
18079
15745
  init_db2();
@@ -18500,18 +16166,64 @@ async function executeScheduleScript(schedule) {
18500
16166
  throw new Error(`Script '${schedule.scriptName}' not found`);
18501
16167
  }
18502
16168
  const agentId = schedule.createdByAgentId ?? "schedule";
18503
- const output = await runScript({
18504
- source: script.source,
18505
- args: schedule.scriptArgs ?? {},
18506
- fsMode: "none",
16169
+ const args = schedule.scriptArgs ?? {};
16170
+ const record2 = {
18507
16171
  agentId,
18508
- egressSecrets: await buildScriptCredentialBindings({ agentId }),
18509
- apiConnections: getScriptApiConnectionDescriptors({ agentId }),
18510
- mcpConnections: getScriptMcpConnectionDescriptors({ agentId }),
18511
- timeoutMs: 60000
18512
- });
16172
+ scriptName: schedule.scriptName,
16173
+ source: `// Scheduled run of '${script.name}' v${script.version} (global, contentHash ${script.contentHash}) by schedule '${schedule.name}'.
16174
+ // Full source: script_versions row for this version.
16175
+ `,
16176
+ args,
16177
+ startedAt: new Date().toISOString()
16178
+ };
16179
+ let output;
16180
+ try {
16181
+ output = await runScript({
16182
+ source: script.source,
16183
+ args,
16184
+ fsMode: "none",
16185
+ agentId,
16186
+ egressSecrets: await buildScriptCredentialBindings({ agentId }),
16187
+ apiConnections: getScriptApiConnectionDescriptors({ agentId }),
16188
+ mcpConnections: getScriptMcpConnectionDescriptors({ agentId }),
16189
+ timeoutMs: 60000
16190
+ });
16191
+ } catch (err) {
16192
+ await recordScheduleScriptRun({
16193
+ ...record2,
16194
+ status: "failed",
16195
+ error: err instanceof Error ? err.message : String(err)
16196
+ });
16197
+ throw err;
16198
+ }
18513
16199
  if (output.exitCode !== 0 || output.error) {
18514
- throw new Error(output.stderr || `Script '${schedule.scriptName}' exited with code ${output.exitCode}${output.error ? ` (${output.error})` : ""}`);
16200
+ const message = output.stderr || `Script '${schedule.scriptName}' exited with code ${output.exitCode}${output.error ? ` (${output.error})` : ""}`;
16201
+ await recordScheduleScriptRun({
16202
+ ...record2,
16203
+ status: "failed",
16204
+ output: output.result,
16205
+ error: message
16206
+ });
16207
+ throw new Error(message);
16208
+ }
16209
+ await recordScheduleScriptRun({ ...record2, status: "completed", output: output.result });
16210
+ }
16211
+ async function recordScheduleScriptRun(run) {
16212
+ try {
16213
+ await recordInlineScriptRun({
16214
+ id: crypto.randomUUID(),
16215
+ agentId: run.agentId,
16216
+ scriptName: run.scriptName,
16217
+ source: run.source,
16218
+ args: scrubObject(run.args),
16219
+ status: run.status,
16220
+ output: scrubObject(run.output),
16221
+ error: run.error === undefined ? undefined : scrubSecrets(run.error),
16222
+ startedAt: run.startedAt,
16223
+ finishedAt: new Date().toISOString()
16224
+ });
16225
+ } catch (err) {
16226
+ console.warn(`[scheduler] could not record script run for '${run.scriptName}': ${scrubSecrets(err instanceof Error ? err.message : String(err))}`);
18515
16227
  }
18516
16228
  }
18517
16229
 
@@ -23004,7 +20716,7 @@ class Protocol {
23004
20716
  };
23005
20717
  }
23006
20718
  }
23007
- function isPlainObject2(value) {
20719
+ function isPlainObject(value) {
23008
20720
  return value !== null && typeof value === "object" && !Array.isArray(value);
23009
20721
  }
23010
20722
  function mergeCapabilities(base, additional) {
@@ -23015,7 +20727,7 @@ function mergeCapabilities(base, additional) {
23015
20727
  if (addValue === undefined)
23016
20728
  continue;
23017
20729
  const baseValue = result[k];
23018
- if (isPlainObject2(baseValue) && isPlainObject2(addValue)) {
20730
+ if (isPlainObject(baseValue) && isPlainObject(addValue)) {
23019
20731
  result[k] = { ...baseValue, ...addValue };
23020
20732
  } else {
23021
20733
  result[k] = addValue;
@@ -29180,7 +26892,7 @@ async function notifySlack(text) {
29180
26892
  return;
29181
26893
  }
29182
26894
  try {
29183
- const { getSlackApp: getSlackApp2 } = await import("./app-nctetn1e.js");
26895
+ const { getSlackApp: getSlackApp2 } = await import("./app-80w6qspx.js");
29184
26896
  const app = getSlackApp2();
29185
26897
  if (!app) {
29186
26898
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -29251,7 +26963,7 @@ async function deleteJiraWebhook(webhookId) {
29251
26963
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
29252
26964
  }
29253
26965
  async function overwriteWebhookIds(next) {
29254
- const { getDbClient: getDbClient2 } = await import("./db-qg3myn53.js");
26966
+ const { getDbClient: getDbClient2 } = await import("./db-wa6s1mwv.js");
29255
26967
  await getDbClient2().transaction(async (tx) => {
29256
26968
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
29257
26969
  if (!row) {
@@ -103056,7 +100768,7 @@ async function reloadGlobalConfigsAndIntegrations() {
103056
100768
  return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
103057
100769
  }
103058
100770
  async function reloadGlobalConfigsAndIntegrationsInner() {
103059
- const { getEmbeddingProvider: getEmbeddingProvider2, resetEmbeddingProvider } = await import("./index-2t9kesn1.js");
100771
+ const { getEmbeddingProvider: getEmbeddingProvider2, resetEmbeddingProvider } = await import("./index-ac0v8v9d.js");
103060
100772
  const wasEmbeddingsConfigured = getEmbeddingProvider2().isConfigured();
103061
100773
  const updated = await loadGlobalConfigsIntoEnv(true);
103062
100774
  await stopSlackApp();
@@ -103069,10 +100781,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
103069
100781
  integrations.push("embeddings");
103070
100782
  }
103071
100783
  if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
103072
- import("./boot-reembed-fmp5ww69.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
100784
+ import("./boot-reembed-feda8wn8.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
103073
100785
  console.error("[config-reload] memory backfill failed (non-fatal):", err);
103074
100786
  });
103075
- import("./boot-reembed-1ze5853n.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
100787
+ import("./boot-reembed-3nc0aaed.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
103076
100788
  console.error("[config-reload] script backfill failed (non-fatal):", err);
103077
100789
  });
103078
100790
  }
@@ -104190,7 +101902,7 @@ function setPreloadedTools(server, names) {
104190
101902
  async function applyPreToolCall(name, args, requestInfo, inputSchema) {
104191
101903
  if (requestInfo.callOrigin !== "mcp")
104192
101904
  return { args };
104193
- const dispatcher = await import("./dispatcher-7vnwj9qw.js");
101905
+ const dispatcher = await import("./dispatcher-nhs2pkr8.js");
104194
101906
  const result = await dispatcher.dispatchPre("pre.tool.call", { tool: name, args, requestInfo }, inputSchema ? {
104195
101907
  validateModify: async (data) => {
104196
101908
  const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
@@ -110679,7 +108391,7 @@ async function applyRating(events, ctx = {}) {
110679
108391
  const accepted = [];
110680
108392
  const rejected = [];
110681
108393
  for (const event of events) {
110682
- const reason = validate2(event);
108394
+ const reason = validate(event);
110683
108395
  if (reason) {
110684
108396
  rejected.push({ event, reason });
110685
108397
  continue;
@@ -110786,7 +108498,7 @@ async function applyRating(events, ctx = {}) {
110786
108498
  }
110787
108499
  return { applied, rejected: [...rejected, ...lateRejects] };
110788
108500
  }
110789
- function validate2(event) {
108501
+ function validate(event) {
110790
108502
  if (!event.source || event.source.trim() === "") {
110791
108503
  return "source is required";
110792
108504
  }
@@ -125161,8 +122873,16 @@ init_zod();
125161
122873
  init_db2();
125162
122874
  init_rbac();
125163
122875
  var scriptConnectionsInputSchema = object({
125164
- action: _enum(["list", "upsert-openapi", "upsert-mcp", "upsert-graphql", "refresh", "disable"]).describe("List, create/update, refresh, or disable a script connection."),
125165
- id: string().uuid().optional().describe("Existing connection ID for update, refresh, or disable."),
122876
+ action: _enum([
122877
+ "list",
122878
+ "upsert-openapi",
122879
+ "upsert-mcp",
122880
+ "upsert-graphql",
122881
+ "refresh",
122882
+ "disable",
122883
+ "delete"
122884
+ ]).describe("List, create/update, refresh, disable, or delete a script connection. delete is permanent: it removes the connection, its managed credential binding, and any inline secret it owns."),
122885
+ id: string().uuid().optional().describe("Existing connection ID for update, refresh, disable, or delete."),
125166
122886
  slug: string().min(1).max(80).optional().describe("Stable script namespace slug exposed under ctx.api or ctx.mcp."),
125167
122887
  displayName: string().max(160).optional().describe("Human-readable connection name."),
125168
122888
  scope: _enum(["global", "agent", "repo"]).optional().describe("Connection visibility scope."),
@@ -125251,6 +122971,26 @@ var registerScriptConnectionsTool = (server) => {
125251
122971
  data: { yourAgentId: requestInfo.agentId, connections: connections2 }
125252
122972
  });
125253
122973
  }
122974
+ if (args2.action === "delete") {
122975
+ if (!args2.id) {
122976
+ return toolErr("id is required for delete.", {
122977
+ data: {
122978
+ yourAgentId: requestInfo.agentId,
122979
+ connections: listScriptConnections({ includeDisabled: true, allScopes: true })
122980
+ }
122981
+ });
122982
+ }
122983
+ const deleted = await deleteScriptConnection(args2.id);
122984
+ const connections2 = listScriptConnections({ includeDisabled: true, allScopes: true });
122985
+ if (!deleted) {
122986
+ return toolErr(`Script connection ${args2.id} not found.`, {
122987
+ data: { yourAgentId: requestInfo.agentId, connections: connections2 }
122988
+ });
122989
+ }
122990
+ return toolOk(`Script connection ${deleted.slug} deleted.`, {
122991
+ data: { yourAgentId: requestInfo.agentId, connections: connections2 }
122992
+ });
122993
+ }
125254
122994
  if (args2.action === "refresh") {
125255
122995
  if (!args2.id) {
125256
122996
  return toolErr("id is required for refresh.", {
@@ -125946,7 +123686,7 @@ async function sendTaskHandler(ctx, {
125946
123686
  data: { yourAgentId: creatorAgentId }
125947
123687
  });
125948
123688
  }
125949
- if (ctx.kind === "owner" && requestedAgentId === ctx.agentId) {
123689
+ if (ctx.kind === "owner" && requestedAgentId === ctx.agentId && ctx.requestInfo?.callOrigin !== "script-sdk") {
125950
123690
  return toolErr("Cannot send a task to yourself, are you drunk?", {
125951
123691
  data: { yourAgentId: ctx.agentId }
125952
123692
  });
@@ -127649,6 +125389,7 @@ async function downloadSlackFile(file, token, path3) {
127649
125389
  }
127650
125390
  }
127651
125391
  async function createSlackTaskWithFiles(description, options, inbound) {
125392
+ noteSlackInboundSideEffect("task_created");
127652
125393
  if (inbound.fetched.length === 0) {
127653
125394
  const task2 = await createTaskWithSiblingAwareness(description, options, { origin: "slack" });
127654
125395
  return { task: task2, unattached: inbound.failed };
@@ -133992,7 +131733,7 @@ async function runHandler(loaded, handler, event, payload) {
133992
131733
  const startedAt = Date.now();
133993
131734
  let timeout;
133994
131735
  try {
133995
- const timeoutPromise2 = new Promise((_, reject) => {
131736
+ const timeoutPromise = new Promise((_, reject) => {
133996
131737
  timeout = setTimeout(() => {
133997
131738
  controller.abort();
133998
131739
  reject(new ExtensionTimeoutError);
@@ -134001,7 +131742,7 @@ async function runHandler(loaded, handler, event, payload) {
134001
131742
  });
134002
131743
  const result = await Promise.race([
134003
131744
  Promise.resolve().then(() => handler.handler(payload, buildCtx(loaded, event, controller.signal))),
134004
- timeoutPromise2
131745
+ timeoutPromise
134005
131746
  ]);
134006
131747
  const durationMs = Date.now() - startedAt;
134007
131748
  return { ok: true, result, durationMs };
@@ -134064,8 +131805,8 @@ async function dispatchPre(event, payload, opts) {
134064
131805
  console.error("[extensions] pre dispatch inside transaction:", scrubSecrets(String(event)));
134065
131806
  return { action: "continue" };
134066
131807
  }
134067
- let currentPayload = payload;
134068
- let mergedData = {};
131808
+ let currentPayload = { ...payload };
131809
+ const mergedData = {};
134069
131810
  let modified = false;
134070
131811
  for (const { loaded, handler } of handlersFor(event, opts)) {
134071
131812
  if (!isRegistered(loaded.record.id))
@@ -134114,7 +131855,7 @@ async function dispatchPre(event, payload, opts) {
134114
131855
  throw validation.error;
134115
131856
  data = definedObject(validation.data);
134116
131857
  }
134117
- mergedData = { ...mergedData, ...data };
131858
+ Object.assign(mergedData, data);
134118
131859
  currentPayload = mergePayload(event, currentPayload, data);
134119
131860
  modified = true;
134120
131861
  await markSuccess(loaded);
@@ -134610,7 +132351,7 @@ class NotifyExecutor extends BaseExecutor {
134610
132351
  }
134611
132352
  }
134612
132353
  case "slack": {
134613
- const { getSlackApp: getSlackApp2 } = await import("./app-nctetn1e.js");
132354
+ const { getSlackApp: getSlackApp2 } = await import("./app-80w6qspx.js");
134614
132355
  const app = getSlackApp2();
134615
132356
  if (!app) {
134616
132357
  return {
@@ -135378,6 +133119,7 @@ function createExecutorRegistry(deps) {
135378
133119
  registry3.register(new ForeachExecutor(deps));
135379
133120
  registry3.register(new HumanInTheLoopExecutor(deps));
135380
133121
  registry3.register(new WaitExecutor(deps));
133122
+ registry3.register(new SubWorkflowExecutor(deps, registry3));
135381
133123
  return registry3;
135382
133124
  }
135383
133125
 
@@ -135418,4 +133160,4 @@ async function initWorkflows() {
135418
133160
  logOpenWebhookTriggers();
135419
133161
  }
135420
133162
 
135421
- export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, findUserById, findUserByExternalId, getUserIdentities, listUserEvents, listUserTokens, recordIdentityEvent, findOrCreateUserByEmail, linkIdentity, unlinkIdentity, mintToken, revokeToken, resolveUserByToken, mintSessionToken, revokeSessionToken, fingerprintApiKey, resolveIdentity, renderIdentity, createAdditiveBuffer, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, automationIntegrationFixUrl, preflightAutomation, getAutomationSetupStates, listEnabledAutomationPreflightInputs, validateJsonSchema, workflowSaveWarnings, TriggerSchemaError, startWorkflowExecution, setupWorkflowResumeListener, retryFailedRun, cancelWorkflowRun, resumeWaitState, initWaitBusSubscriptions, subscribeWaitToBus, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, handleWebhookTrigger, logOpenWebhookTriggers, handleEventTrigger, handleScheduleTrigger, verifyHmacSignature, WebhookError, snapshotWorkflow, snapshotAndUpdateWorkflow, startWaitPoller, stopWaitPoller, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry, initWorkflows, dispatchScheduleTarget, calculateNextRun, startScheduler, stopScheduler, runScheduleNow, parseSkillContent, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, warnIfCorsAllowsAnyOrigin, isOriginAllowedForCredentials, allowedCredentialRedirect, setCorsHeaders, parseQueryParams, getPathSegments, wireHttpSpanLifecycle, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, writeUnhandledError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, runtimeInstanceHeader, describeRequestRoute, route, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError, isRegistered, isExtensionAgentId, getExtensionBridgeToken, resolveBridgeCallOrigin, extensionIdForAgent, runContext, registerLoaded, unregister, listRegistered, dispatchPre, dispatchPost, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, repointTrackerSyncBySwarmId, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, parseCookieHeader, extractAndVerifyCookie, issuePageSessionCookie, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, MemoryKeyError, refreshLinks, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, indexMemoryContent, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };
133163
+ export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, findUserById, findUserByExternalId, getUserIdentities, listUserEvents, listUserTokens, recordIdentityEvent, findOrCreateUserByEmail, linkIdentity, unlinkIdentity, mintToken, revokeToken, resolveUserByToken, mintSessionToken, revokeSessionToken, fingerprintApiKey, resolveIdentity, renderIdentity, createAdditiveBuffer, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, handleWebhookTrigger, logOpenWebhookTriggers, handleEventTrigger, handleScheduleTrigger, verifyHmacSignature, WebhookError, snapshotWorkflow, snapshotAndUpdateWorkflow, startWaitPoller, stopWaitPoller, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry, initWorkflows, dispatchScheduleTarget, calculateNextRun, startScheduler, stopScheduler, runScheduleNow, parseSkillContent, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, warnIfCorsAllowsAnyOrigin, isOriginAllowedForCredentials, allowedCredentialRedirect, setCorsHeaders, parseQueryParams, getPathSegments, wireHttpSpanLifecycle, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, writeUnhandledError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, runtimeInstanceHeader, describeRequestRoute, route, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError, isRegistered, isExtensionAgentId, getExtensionBridgeToken, resolveBridgeCallOrigin, extensionIdForAgent, runContext, registerLoaded, unregister, listRegistered, dispatchPre, dispatchPost, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, repointTrackerSyncBySwarmId, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, parseCookieHeader, extractAndVerifyCookie, issuePageSessionCookie, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, MemoryKeyError, refreshLinks, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, indexMemoryContent, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };