@lostgradient/weft 0.3.0 → 0.4.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 (508) hide show
  1. package/README.md +79 -24
  2. package/dist/cli/conformance.js +7 -1
  3. package/dist/cli/generated/operation-client.generated.d.ts +28 -13
  4. package/dist/cli/generated/operation-client.generated.js +1 -0
  5. package/dist/cli/help-text.d.ts +1 -1
  6. package/dist/cli/help-text.js +1 -0
  7. package/dist/cli/operation-catalog-snapshot.d.ts +8 -0
  8. package/dist/cli/operation-catalog-snapshot.js +11 -0
  9. package/dist/cli/parse-schedule-arguments.js +3 -1
  10. package/dist/cli/schedule.js +2 -1
  11. package/dist/cli/types.d.ts +1 -0
  12. package/dist/cli-main.js +79 -78
  13. package/dist/client/handle-delegation.d.ts +3 -2
  14. package/dist/client/handle-delegation.js +3 -1
  15. package/dist/client/http-client-requests.d.ts +2 -1
  16. package/dist/client/http-client-requests.js +7 -0
  17. package/dist/client/http-client.d.ts +9 -6
  18. package/dist/client/http-client.js +10 -1
  19. package/dist/client/http-request.d.ts +11 -1
  20. package/dist/client/http-request.js +17 -7
  21. package/dist/client/index.d.ts +1 -1
  22. package/dist/client/interface.d.ts +46 -5
  23. package/dist/client/local.d.ts +4 -1
  24. package/dist/client/local.js +12 -4
  25. package/dist/client/start-body.d.ts +4 -3
  26. package/dist/core/byte-arrays.d.ts +5 -0
  27. package/dist/core/byte-arrays.js +5 -0
  28. package/dist/core/checkpoint/lifecycle.d.ts +3 -0
  29. package/dist/core/checkpoint/lifecycle.js +9 -4
  30. package/dist/core/checkpoint/serialization.js +12 -5
  31. package/dist/core/codec/extension-codec.d.ts +16 -0
  32. package/dist/core/codec/extension-codec.js +100 -6
  33. package/dist/core/context/activity-retry-state.d.ts +38 -0
  34. package/dist/core/context/activity-retry-state.js +89 -0
  35. package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
  36. package/dist/core/context/activity-schedule-to-close.js +69 -0
  37. package/dist/core/context/child-workflow-pipe.d.ts +5 -5
  38. package/dist/core/context/child-workflow-pipe.js +15 -2
  39. package/dist/core/context/context-presence.d.ts +19 -0
  40. package/dist/core/context/context-presence.js +13 -0
  41. package/dist/core/context/durable-operations.d.ts +25 -0
  42. package/dist/core/context/durable-operations.js +64 -0
  43. package/dist/core/context/index.d.ts +9 -5
  44. package/dist/core/context/index.js +17 -12
  45. package/dist/core/context/internals.d.ts +20 -0
  46. package/dist/core/context/internals.js +3 -1
  47. package/dist/core/context/operation-request.d.ts +35 -0
  48. package/dist/core/context/parallel-cache-entry.d.ts +14 -5
  49. package/dist/core/context/run-operation.d.ts +6 -1
  50. package/dist/core/context/run-operation.js +41 -87
  51. package/dist/core/context/session-state.js +7 -8
  52. package/dist/core/context/speculative-child.js +2 -0
  53. package/dist/core/context/types.d.ts +15 -0
  54. package/dist/core/context/version-patching.d.ts +8 -0
  55. package/dist/core/context/version-patching.js +40 -0
  56. package/dist/core/context/workflow-logger.d.ts +98 -0
  57. package/dist/core/context/workflow-logger.js +68 -0
  58. package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
  59. package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
  60. package/dist/core/engine/activity-per-attempt-timeout.d.ts +41 -0
  61. package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
  62. package/dist/core/engine/activity-reconciliation.d.ts +1 -0
  63. package/dist/core/engine/activity-reconciliation.js +12 -1
  64. package/dist/core/engine/activity-resolution.d.ts +23 -0
  65. package/dist/core/engine/activity-resolution.js +37 -0
  66. package/dist/core/engine/aggregate.js +66 -30
  67. package/dist/core/engine/async-activity-completion.d.ts +23 -6
  68. package/dist/core/engine/async-activity-completion.js +53 -12
  69. package/dist/core/engine/attributes-tags.js +9 -4
  70. package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
  71. package/dist/core/engine/bulk-operations-purge.js +38 -3
  72. package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
  73. package/dist/core/engine/bulk-operations-shared.js +8 -2
  74. package/dist/core/engine/bulk-operations.d.ts +4 -1
  75. package/dist/core/engine/bulk-operations.js +235 -24
  76. package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
  77. package/dist/core/engine/callback-creators-bundles.js +30 -2
  78. package/dist/core/engine/callback-creators-core.js +6 -4
  79. package/dist/core/engine/callback-creators-router.js +10 -0
  80. package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
  81. package/dist/core/engine/callback-creators-schedule.js +12 -8
  82. package/dist/core/engine/candidate-read-batching.d.ts +6 -0
  83. package/dist/core/engine/candidate-read-batching.js +1 -0
  84. package/dist/core/engine/checkpoint-io.js +61 -25
  85. package/dist/core/engine/checkpoint-reads.js +3 -2
  86. package/dist/core/engine/checkpoint-replay.d.ts +20 -0
  87. package/dist/core/engine/checkpoint-replay.js +242 -0
  88. package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
  89. package/dist/core/engine/checkpoint-side-effects.js +35 -0
  90. package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
  91. package/dist/core/engine/child-workflow-cancellation.js +40 -0
  92. package/dist/core/engine/child-workflow.js +27 -4
  93. package/dist/core/engine/condition-waiters.d.ts +14 -0
  94. package/dist/core/engine/condition-waiters.js +5 -0
  95. package/dist/core/engine/construction.d.ts +3 -0
  96. package/dist/core/engine/construction.js +21 -8
  97. package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
  98. package/dist/core/engine/coordination-branch-executors.js +107 -0
  99. package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
  100. package/dist/core/engine/deferred-consume-envelope.js +14 -0
  101. package/dist/core/engine/disposal.js +13 -0
  102. package/dist/core/engine/engine-create-types.d.ts +14 -4
  103. package/dist/core/engine/engine-internal-types.d.ts +26 -3
  104. package/dist/core/engine/errors.d.ts +47 -0
  105. package/dist/core/engine/errors.js +20 -0
  106. package/dist/core/engine/event-log-compaction.d.ts +8 -0
  107. package/dist/core/engine/event-log-compaction.js +20 -2
  108. package/dist/core/engine/fenced-write.d.ts +65 -0
  109. package/dist/core/engine/fenced-write.js +71 -0
  110. package/dist/core/engine/finalizer-state.d.ts +28 -0
  111. package/dist/core/engine/finalizer-state.js +16 -0
  112. package/dist/core/engine/handles.d.ts +8 -0
  113. package/dist/core/engine/index.d.ts +34 -16
  114. package/dist/core/engine/index.js +133 -8
  115. package/dist/core/engine/inline-parking.js +3 -2
  116. package/dist/core/engine/internals.d.ts +107 -3
  117. package/dist/core/engine/lease-codec.d.ts +35 -0
  118. package/dist/core/engine/lease-codec.js +32 -0
  119. package/dist/core/engine/lease-deposition.d.ts +66 -0
  120. package/dist/core/engine/lease-deposition.js +10 -0
  121. package/dist/core/engine/lease-errors.d.ts +99 -0
  122. package/dist/core/engine/lease-errors.js +30 -0
  123. package/dist/core/engine/lease-manager.d.ts +114 -0
  124. package/dist/core/engine/lease-manager.js +135 -0
  125. package/dist/core/engine/lifecycle/persist.js +10 -32
  126. package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
  127. package/dist/core/engine/lifecycle/recovered-services.js +18 -3
  128. package/dist/core/engine/lifecycle/resume.js +16 -9
  129. package/dist/core/engine/lifecycle/shared.d.ts +8 -1
  130. package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
  131. package/dist/core/engine/lifecycle/start-batch.js +2 -1
  132. package/dist/core/engine/lifecycle/start-commit.d.ts +9 -0
  133. package/dist/core/engine/lifecycle/start-commit.js +50 -8
  134. package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
  135. package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
  136. package/dist/core/engine/lifecycle/start-or-signal.d.ts +3 -2
  137. package/dist/core/engine/lifecycle/start-or-signal.js +11 -81
  138. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
  139. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
  140. package/dist/core/engine/lifecycle/start.d.ts +4 -4
  141. package/dist/core/engine/lifecycle/start.js +17 -9
  142. package/dist/core/engine/lifecycle/transition.js +17 -5
  143. package/dist/core/engine/lifecycle.d.ts +1 -1
  144. package/dist/core/engine/list-candidate-resolution.js +2 -2
  145. package/dist/core/engine/listing.js +9 -5
  146. package/dist/core/engine/operations-activity.d.ts +4 -11
  147. package/dist/core/engine/operations-activity.js +22 -49
  148. package/dist/core/engine/operations-coordination.d.ts +10 -0
  149. package/dist/core/engine/operations-coordination.js +43 -8
  150. package/dist/core/engine/operations-router.d.ts +6 -0
  151. package/dist/core/engine/operations-router.js +2 -0
  152. package/dist/core/engine/operations-speculate.js +6 -2
  153. package/dist/core/engine/operations-stream.js +12 -2
  154. package/dist/core/engine/operations-time.d.ts +4 -2
  155. package/dist/core/engine/operations-time.js +14 -2
  156. package/dist/core/engine/operations-wait-condition.d.ts +23 -0
  157. package/dist/core/engine/operations-wait-condition.js +62 -0
  158. package/dist/core/engine/ownership-options.d.ts +23 -0
  159. package/dist/core/engine/ownership-options.js +26 -0
  160. package/dist/core/engine/payload-size-policy.d.ts +3 -0
  161. package/dist/core/engine/payload-size-policy.js +4 -0
  162. package/dist/core/engine/pending-updates.d.ts +17 -0
  163. package/dist/core/engine/pending-updates.js +33 -11
  164. package/dist/core/engine/queries.js +1 -1
  165. package/dist/core/engine/registration.d.ts +1 -0
  166. package/dist/core/engine/registration.js +18 -3
  167. package/dist/core/engine/schedule-jitter.d.ts +5 -0
  168. package/dist/core/engine/schedule-jitter.js +10 -0
  169. package/dist/core/engine/schedule-run.d.ts +17 -0
  170. package/dist/core/engine/schedule-run.js +38 -0
  171. package/dist/core/engine/schedule-timer.js +81 -17
  172. package/dist/core/engine/schedules.d.ts +7 -4
  173. package/dist/core/engine/schedules.js +37 -16
  174. package/dist/core/engine/search-attribute-records.d.ts +4 -0
  175. package/dist/core/engine/search-attribute-records.js +17 -0
  176. package/dist/core/engine/signals.d.ts +18 -2
  177. package/dist/core/engine/signals.js +42 -21
  178. package/dist/core/engine/state-utilities.d.ts +49 -2
  179. package/dist/core/engine/state-utilities.js +114 -3
  180. package/dist/core/engine/storage-io.d.ts +16 -2
  181. package/dist/core/engine/storage-io.js +26 -5
  182. package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
  183. package/dist/core/engine/stream-chunk-loading.js +24 -1
  184. package/dist/core/engine/sub-operation.js +22 -3
  185. package/dist/core/engine/termination/cleanup.d.ts +3 -1
  186. package/dist/core/engine/termination/cleanup.js +25 -1
  187. package/dist/core/engine/termination/complete.js +44 -6
  188. package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
  189. package/dist/core/engine/termination/finalizer-activity.js +30 -0
  190. package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
  191. package/dist/core/engine/termination/finalizer-claim.js +80 -0
  192. package/dist/core/engine/termination/finalizer.d.ts +48 -0
  193. package/dist/core/engine/termination/finalizer.js +159 -0
  194. package/dist/core/engine/termination/suspend.d.ts +3 -1
  195. package/dist/core/engine/termination.d.ts +1 -0
  196. package/dist/core/engine/termination.js +4 -0
  197. package/dist/core/engine/updates.js +5 -25
  198. package/dist/core/engine/validation/schedule.d.ts +2 -1
  199. package/dist/core/engine/validation/schedule.js +51 -2
  200. package/dist/core/engine/validation.js +32 -5
  201. package/dist/core/engine/waiting-update-response.d.ts +8 -0
  202. package/dist/core/engine/waiting-update-response.js +22 -0
  203. package/dist/core/engine/workflow-concurrency.d.ts +10 -0
  204. package/dist/core/engine/workflow-concurrency.js +136 -0
  205. package/dist/core/engine/workflow-feed.d.ts +4 -5
  206. package/dist/core/engine/workflow-feed.js +4 -1
  207. package/dist/core/engine/workflow-indexes.d.ts +9 -0
  208. package/dist/core/engine/workflow-indexes.js +10 -0
  209. package/dist/core/engine/workflow-state-stream.js +33 -13
  210. package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
  211. package/dist/core/engine-helpers.js +1 -0
  212. package/dist/core/events/activity-events.d.ts +43 -12
  213. package/dist/core/events/activity-events.js +28 -0
  214. package/dist/core/events/attribute-events.d.ts +2 -3
  215. package/dist/core/events/event-map.d.ts +18 -12
  216. package/dist/core/events/index.d.ts +1 -0
  217. package/dist/core/events/index.js +1 -0
  218. package/dist/core/events/schedule-events.d.ts +71 -0
  219. package/dist/core/events/schedule-events.js +29 -0
  220. package/dist/core/events/signal-events.d.ts +4 -6
  221. package/dist/core/events/system-events.d.ts +29 -19
  222. package/dist/core/events/system-events.js +26 -0
  223. package/dist/core/events/update-events.d.ts +6 -8
  224. package/dist/core/events/workflow-events.d.ts +88 -23
  225. package/dist/core/events/workflow-events.js +26 -0
  226. package/dist/core/failure-categories.js +5 -17
  227. package/dist/core/fault-code.d.ts +9 -3
  228. package/dist/core/fault-code.js +1 -0
  229. package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
  230. package/dist/core/inline-execution-strategy.context-options.js +56 -0
  231. package/dist/core/inline-execution-strategy.d.ts +31 -36
  232. package/dist/core/inline-execution-strategy.js +16 -27
  233. package/dist/core/list-filter-validation.d.ts +1 -1
  234. package/dist/core/payload-size.d.ts +1 -1
  235. package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
  236. package/dist/core/review/events.d.ts +6 -8
  237. package/dist/core/scheduler/scheduler-class.d.ts +10 -1
  238. package/dist/core/scheduler/scheduler-class.js +38 -11
  239. package/dist/core/scheduler/timer-batch.js +9 -1
  240. package/dist/core/scheduler/timer-sources.d.ts +1 -0
  241. package/dist/core/scheduler/timer-sources.js +11 -5
  242. package/dist/core/session-state.d.ts +0 -1
  243. package/dist/core/session-state.js +2 -2
  244. package/dist/core/start-workflow-validation.d.ts +34 -0
  245. package/dist/core/start-workflow-validation.js +19 -0
  246. package/dist/core/types/activity-verification.d.ts +67 -0
  247. package/dist/core/types/activity-verification.js +0 -0
  248. package/dist/core/types/activity.d.ts +80 -61
  249. package/dist/core/types/bulk.d.ts +50 -9
  250. package/dist/core/types/checkpoint.d.ts +44 -8
  251. package/dist/core/types/list-options.d.ts +146 -0
  252. package/dist/core/types/list-options.js +0 -0
  253. package/dist/core/types/options.d.ts +121 -165
  254. package/dist/core/types/schedules.d.ts +39 -3
  255. package/dist/core/types/services-resolution.d.ts +2 -2
  256. package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
  257. package/dist/core/types/workflow-builder-runtime.js +11 -2
  258. package/dist/core/types/workflow-builder.d.ts +42 -11
  259. package/dist/core/types/workflow-concurrency.d.ts +39 -0
  260. package/dist/core/types/workflow-concurrency.js +0 -0
  261. package/dist/core/types/workflow-context.d.ts +157 -14
  262. package/dist/core/types/workflow-definition.d.ts +53 -10
  263. package/dist/core/types/workflow-function.d.ts +84 -9
  264. package/dist/core/types/workflow-log.d.ts +98 -0
  265. package/dist/core/types/workflow-log.js +0 -0
  266. package/dist/core/types/workflow-registries.d.ts +14 -3
  267. package/dist/core/types/workflow-registry.d.ts +3 -0
  268. package/dist/core/types.d.ts +4 -0
  269. package/dist/core/types.js +4 -0
  270. package/dist/core/versioning.d.ts +9 -39
  271. package/dist/core/versioning.js +2 -12
  272. package/dist/core/weft-error.d.ts +44 -1
  273. package/dist/core/weft-error.js +16 -0
  274. package/dist/core/worker-execution-strategy-options.d.ts +26 -0
  275. package/dist/core/worker-execution-strategy.js +40 -36
  276. package/dist/core/worker-inbound-message.d.ts +38 -0
  277. package/dist/core/worker-inbound-message.js +37 -0
  278. package/dist/core/worker-log-abuse-counter.d.ts +175 -0
  279. package/dist/core/worker-log-abuse-counter.js +107 -0
  280. package/dist/core/worker-message-helpers.d.ts +47 -0
  281. package/dist/core/worker-message-helpers.js +26 -0
  282. package/dist/core/worker-protocol-guard.js +1 -1
  283. package/dist/core/worker-protocol-log.d.ts +56 -0
  284. package/dist/core/worker-protocol-log.js +18 -0
  285. package/dist/core/worker-protocol.d.ts +23 -0
  286. package/dist/core/worker-protocol.js +12 -2
  287. package/dist/core/workflow-version-tuple.d.ts +3 -9
  288. package/dist/core/workflow-version-tuple.js +2 -3
  289. package/dist/diagnostics/format.js +1 -6
  290. package/dist/diagnostics/types.d.ts +4 -5
  291. package/dist/diagnostics/validate.d.ts +0 -1
  292. package/dist/diagnostics/version-check.d.ts +1 -1
  293. package/dist/diagnostics/version-check.js +4 -9
  294. package/dist/index.d.ts +12 -10
  295. package/dist/index.js +29 -3
  296. package/dist/json-schema.js +3 -3
  297. package/dist/mcp/cli.js +27 -27
  298. package/dist/mcp/dispatcher.js +1 -1
  299. package/dist/mcp/http.js +16 -6
  300. package/dist/mcp/protocol.d.ts +2 -0
  301. package/dist/mcp/protocol.js +1 -1
  302. package/dist/mcp/session.d.ts +16 -0
  303. package/dist/mcp/session.js +59 -6
  304. package/dist/mcp/tools.js +73 -6
  305. package/dist/observability/index.js +2 -2
  306. package/dist/server/asyncapi-channels.js +5 -2
  307. package/dist/server/attribute-filters.d.ts +8 -3
  308. package/dist/server/attribute-filters.js +6 -1
  309. package/dist/server/authentication/api-key.d.ts +2 -1
  310. package/dist/server/authentication/api-key.js +5 -2
  311. package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
  312. package/dist/server/authentication/constant-time-api-key.js +24 -0
  313. package/dist/server/authentication/index.d.ts +1 -1
  314. package/dist/server/authentication/index.js +7 -4
  315. package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
  316. package/dist/server/authentication/rotating-api-key-store.js +19 -11
  317. package/dist/server/engine-event-feed-backend.d.ts +4 -5
  318. package/dist/server/fault-to-http.js +8 -1
  319. package/dist/server/fault-to-json-rpc.js +1 -0
  320. package/dist/server/fleet-event-feed.d.ts +31 -0
  321. package/dist/server/fleet-event-feed.js +157 -0
  322. package/dist/server/handler/index.js +1 -1
  323. package/dist/server/handler/response-helpers.js +2 -1
  324. package/dist/server/handler/route-dispatch.d.ts +6 -3
  325. package/dist/server/handler/route-dispatch.js +2 -2
  326. package/dist/server/handler.js +23 -23
  327. package/dist/server/index.d.ts +32 -2
  328. package/dist/server/index.js +26 -26
  329. package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
  330. package/dist/server/json-rpc-transport-helpers.js +2 -1
  331. package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
  332. package/dist/server/json-rpc-websocket-runtime.js +1 -0
  333. package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
  334. package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
  335. package/dist/server/json-rpc-websocket-types.d.ts +22 -0
  336. package/dist/server/json-rpc-websocket-types.js +0 -0
  337. package/dist/server/json-rpc-websocket-validation.js +20 -4
  338. package/dist/server/json-rpc-websocket.d.ts +2 -43
  339. package/dist/server/json-rpc-websocket.js +57 -74
  340. package/dist/server/openapi.d.ts +2 -1
  341. package/dist/server/openapi.js +1 -3
  342. package/dist/server/openrpc-document-schema.d.ts +78 -0
  343. package/dist/server/openrpc-document-schema.js +27 -1
  344. package/dist/server/openrpc-errors.d.ts +3 -0
  345. package/dist/server/openrpc-errors.js +2 -1
  346. package/dist/server/openrpc.js +32 -0
  347. package/dist/server/operation-catalog/index.d.ts +1 -1
  348. package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
  349. package/dist/server/operation-catalog/pipeline-stages.js +26 -12
  350. package/dist/server/operation-catalog/pipeline.js +8 -1
  351. package/dist/server/operation-catalog/registry.js +13 -0
  352. package/dist/server/operation-catalog/types.d.ts +20 -9
  353. package/dist/server/operation-fault.d.ts +10 -0
  354. package/dist/server/operation-fault.js +2 -0
  355. package/dist/server/operation-registry.d.ts +12 -11
  356. package/dist/server/operation-registry.js +12 -3
  357. package/dist/server/operations/aggregate-workflows.d.ts +15 -15
  358. package/dist/server/operations/async-activity.d.ts +2 -2
  359. package/dist/server/operations/async-activity.js +12 -7
  360. package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
  361. package/dist/server/operations/bulk-cancel-workflows.js +2 -2
  362. package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
  363. package/dist/server/operations/bulk-delete-workflows.js +2 -2
  364. package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
  365. package/dist/server/operations/bulk-filter-helpers.js +54 -24
  366. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
  367. package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
  368. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
  369. package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
  370. package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
  371. package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
  372. package/dist/server/operations/bulk-signal-workflows.js +2 -2
  373. package/dist/server/operations/cancel-schedule.d.ts +1 -1
  374. package/dist/server/operations/create-schedule.d.ts +3 -1
  375. package/dist/server/operations/create-schedule.js +29 -11
  376. package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
  377. package/dist/server/operations/fleet-events-subscription.js +99 -0
  378. package/dist/server/operations/fork-workflow.d.ts +1 -1
  379. package/dist/server/operations/fork-workflow.js +3 -2
  380. package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
  381. package/dist/server/operations/get-registry.d.ts +1 -1
  382. package/dist/server/operations/get-retention-overview.d.ts +1 -1
  383. package/dist/server/operations/get-review.d.ts +1 -1
  384. package/dist/server/operations/get-schedule.d.ts +1 -1
  385. package/dist/server/operations/get-stream-chunks.d.ts +1 -1
  386. package/dist/server/operations/get-system-metrics.d.ts +2 -2
  387. package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
  388. package/dist/server/operations/get-task-diagnostics.js +101 -7
  389. package/dist/server/operations/get-update-result.d.ts +1 -1
  390. package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
  391. package/dist/server/operations/get-workflow-events.d.ts +1 -1
  392. package/dist/server/operations/get-workflow-result.d.ts +1 -1
  393. package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
  394. package/dist/server/operations/get-workflow.d.ts +1 -1
  395. package/dist/server/operations/list-checkpoints.d.ts +1 -1
  396. package/dist/server/operations/list-reviews.d.ts +1 -1
  397. package/dist/server/operations/list-schedules.d.ts +1 -1
  398. package/dist/server/operations/list-task-queues.d.ts +2 -2
  399. package/dist/server/operations/list-workers.d.ts +2 -2
  400. package/dist/server/operations/list-workflows.d.ts +1 -1
  401. package/dist/server/operations/operation-helpers.d.ts +16 -1
  402. package/dist/server/operations/operation-helpers.js +15 -3
  403. package/dist/server/operations/pause-schedule.d.ts +1 -1
  404. package/dist/server/operations/purge-workflows.d.ts +5 -5
  405. package/dist/server/operations/purge-workflows.js +2 -2
  406. package/dist/server/operations/query-workflow.d.ts +1 -1
  407. package/dist/server/operations/query-workflow.js +3 -2
  408. package/dist/server/operations/recover-all.d.ts +1 -1
  409. package/dist/server/operations/replay-workflow.d.ts +1 -1
  410. package/dist/server/operations/resume-schedule.d.ts +1 -1
  411. package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
  412. package/dist/server/operations/set-workflow-attributes.js +6 -3
  413. package/dist/server/operations/signal-workflow.js +8 -3
  414. package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
  415. package/dist/server/operations/start-or-signal-workflow.d.ts +6 -1
  416. package/dist/server/operations/start-or-signal-workflow.js +14 -24
  417. package/dist/server/operations/start-workflow-options.d.ts +6 -0
  418. package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
  419. package/dist/server/operations/start-workflow-rest-input.js +31 -0
  420. package/dist/server/operations/start-workflow.d.ts +1 -1
  421. package/dist/server/operations/start-workflow.js +8 -23
  422. package/dist/server/operations/storage.d.ts +6 -6
  423. package/dist/server/operations/storage.js +24 -14
  424. package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
  425. package/dist/server/operations/submit-review-decision.d.ts +1 -1
  426. package/dist/server/operations/submit-review-decision.js +6 -3
  427. package/dist/server/operations/update-schedule.d.ts +1 -1
  428. package/dist/server/operations/update-schedule.js +7 -4
  429. package/dist/server/operations/update-workflow.d.ts +1 -1
  430. package/dist/server/operations/update-workflow.js +7 -3
  431. package/dist/server/operations/worker-drain.d.ts +8 -8
  432. package/dist/server/operations/worker-drain.js +11 -8
  433. package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
  434. package/dist/server/operations/workflow-events-subscription.js +43 -8
  435. package/dist/server/rest-binding.d.ts +3 -1
  436. package/dist/server/rest-bindings.js +12 -0
  437. package/dist/server/rest-body.d.ts +10 -0
  438. package/dist/server/rest-body.js +80 -0
  439. package/dist/server/runtime/authentication-bridge.d.ts +1 -0
  440. package/dist/server/runtime/authentication-bridge.js +33 -6
  441. package/dist/server/runtime/client-visible-events.d.ts +3 -0
  442. package/dist/server/runtime/client-visible-events.js +65 -0
  443. package/dist/server/runtime/context.d.ts +7 -0
  444. package/dist/server/runtime/event-broadcasting.d.ts +6 -0
  445. package/dist/server/runtime/event-broadcasting.js +72 -38
  446. package/dist/server/runtime/retry.d.ts +1 -0
  447. package/dist/server/runtime/retry.js +14 -0
  448. package/dist/server/runtime/shutdown.d.ts +7 -6
  449. package/dist/server/runtime/shutdown.js +6 -1
  450. package/dist/server/runtime/task-polling.js +61 -20
  451. package/dist/server/runtime/task-reconciliation.js +9 -1
  452. package/dist/server/runtime/task-result-resolution.d.ts +15 -0
  453. package/dist/server/runtime/task-result-resolution.js +81 -0
  454. package/dist/server/runtime/websocket-stream.d.ts +20 -1
  455. package/dist/server/runtime/websocket-stream.js +173 -7
  456. package/dist/server/runtime/websocket-upgrade.js +22 -3
  457. package/dist/server/runtime/websocket-worker.d.ts +1 -1
  458. package/dist/server/runtime/websocket-worker.js +38 -30
  459. package/dist/server/serve-internals.d.ts +3 -1
  460. package/dist/server/serve-internals.js +18 -2
  461. package/dist/server/task-state.d.ts +30 -0
  462. package/dist/server/task-state.js +28 -0
  463. package/dist/server/workflow-event-feed.d.ts +36 -115
  464. package/dist/server/workflow-event-feed.js +92 -27
  465. package/dist/service-worker/index.js +30 -30
  466. package/dist/storage/auto.js +1 -1
  467. package/dist/storage/bun-sql.js +24 -0
  468. package/dist/storage/compressed-storage.js +1 -1
  469. package/dist/storage/default-scope.d.ts +7 -4
  470. package/dist/storage/http.js +2 -2
  471. package/dist/storage/index.d.ts +76 -4
  472. package/dist/storage/indexeddb.js +1 -1
  473. package/dist/storage/interface.d.ts +163 -0
  474. package/dist/storage/interface.js +1 -1
  475. package/dist/storage/key-prefixes.d.ts +1 -1
  476. package/dist/storage/key-prefixes.js +10 -0
  477. package/dist/storage/lmdb.d.ts +4 -3
  478. package/dist/storage/lmdb.js +1 -1
  479. package/dist/storage/memory.js +1 -1
  480. package/dist/storage/neon-batch.d.ts +30 -0
  481. package/dist/storage/neon-batch.js +30 -0
  482. package/dist/storage/neon-value-mapping.d.ts +30 -3
  483. package/dist/storage/neon-value-mapping.js +12 -0
  484. package/dist/storage/neon.d.ts +16 -0
  485. package/dist/storage/neon.js +9 -4
  486. package/dist/storage/node-sqlite.js +23 -0
  487. package/dist/storage/postgres-key-value-queries.d.ts +69 -44
  488. package/dist/storage/postgres-key-value-queries.js +62 -24
  489. package/dist/storage/resolve.js +1 -1
  490. package/dist/storage/scoped-storage.js +1 -1
  491. package/dist/storage/testing.d.ts +168 -0
  492. package/dist/storage/testing.js +2 -0
  493. package/dist/storage/turso.d.ts +8 -0
  494. package/dist/storage/turso.js +2 -2
  495. package/dist/storage/typed-storage.js +1 -1
  496. package/dist/storage/web-extension.js +1 -1
  497. package/dist/testing/index.js +28 -28
  498. package/dist/version.d.ts +1 -1
  499. package/dist/version.js +1 -1
  500. package/dist/worker/protocol.js +1 -1
  501. package/dist/workers/worker-replay-state.d.ts +32 -0
  502. package/dist/workers/worker-replay-state.js +35 -0
  503. package/dist/workers/worker-state-namespace.d.ts +21 -0
  504. package/dist/workers/worker-state-namespace.js +13 -0
  505. package/dist/workers/workflow-runner.d.ts +19 -15
  506. package/dist/workers/workflow-runner.js +72 -60
  507. package/dist/workers/workflow-worker-entry.js +5 -2
  508. package/package.json +5 -1
@@ -103,7 +103,7 @@ function initialize(params, session) {
103
103
  return {
104
104
  protocolVersion: session.protocolVersion,
105
105
  capabilities: {
106
- tools: { listChanged: !1 },
106
+ tools: { listChanged: !0 },
107
107
  resources: { subscribe: !0, listChanged: !1 },
108
108
  prompts: {},
109
109
  logging: {},
package/dist/mcp/http.js CHANGED
@@ -109,7 +109,7 @@ function resolvePostSession(options, message) {
109
109
  if (session === void 0)
110
110
  return new Response("MCP session not found", { status: 404 });
111
111
  const principal = principalFromOptions(options);
112
- if (!isSameSessionOwner(session.principal, principal))
112
+ if (!isAuthorizedForSession(session, principal, sessionTokenFromHeaders(options.request.headers)))
113
113
  return new Response("Forbidden", { status: 403, headers: noStoreHeaders() });
114
114
  options.sessionManager.touch(session);
115
115
  return { session, createdSession: !1, principal };
@@ -134,7 +134,7 @@ function handleMcpGet(options) {
134
134
  if (session === void 0)
135
135
  return new Response("MCP session not found", { status: 404 });
136
136
  const principal = principalFromOptions(options);
137
- if (!isSameSessionOwner(session.principal, principal))
137
+ if (!isAuthorizedForSession(session, principal, sessionTokenFromHeaders(options.request.headers)))
138
138
  return new Response("Forbidden", { status: 403, headers: noStoreHeaders() });
139
139
  options.sessionManager.touch(session);
140
140
  const stream = new ReadableStream({
@@ -173,7 +173,7 @@ function handleMcpDelete(options) {
173
173
  const session = options.sessionManager.get(sessionId);
174
174
  if (session === void 0)
175
175
  return new Response("MCP session not found", { status: 404 });
176
- if (!isSameSessionOwner(session.principal, principalFromOptions(options)))
176
+ if (!isAuthorizedForSession(session, principalFromOptions(options), sessionTokenFromHeaders(options.request.headers)))
177
177
  return new Response("Forbidden", { status: 403, headers: noStoreHeaders() });
178
178
  options.sessionManager.delete(sessionId);
179
179
  return new Response(null, { status: 204, headers: noStoreHeaders() });
@@ -181,6 +181,9 @@ function handleMcpDelete(options) {
181
181
  function sessionIdFromHeaders(headers) {
182
182
  return headers.get("Mcp-Session-Id") ?? headers.get("MCP-Session-Id");
183
183
  }
184
+ function sessionTokenFromHeaders(headers) {
185
+ return headers.get("Mcp-Session-Token") ?? headers.get("MCP-Session-Token");
186
+ }
184
187
  function validateProtocolVersion(headers) {
185
188
  const version = headers.get("Mcp-Protocol-Version") ?? headers.get("MCP-Protocol-Version");
186
189
  if (version === null)
@@ -191,8 +194,10 @@ function validateProtocolVersion(headers) {
191
194
  }
192
195
  function maybeSessionHeaders(session, includeSession) {
193
196
  const headers = noStoreHeaders();
194
- if (includeSession)
197
+ if (includeSession) {
195
198
  headers["Mcp-Session-Id"] = session.id;
199
+ headers["Mcp-Session-Token"] = session.token;
200
+ }
196
201
  return headers;
197
202
  }
198
203
  function noStoreHeaders() {
@@ -204,6 +209,13 @@ function authRequiredFromOptions(options) {
204
209
  function principalFromOptions(options) {
205
210
  return options.principal ?? anonymousPrincipal();
206
211
  }
212
+ function isAuthorizedForSession(session, caller, presentedToken) {
213
+ if (!isSameSessionOwner(session.principal, caller))
214
+ return !1;
215
+ if (isAuthenticated(session.principal))
216
+ return !0;
217
+ return presentedToken !== null && presentedToken === session.token;
218
+ }
207
219
  function isSameSessionOwner(left, right) {
208
220
  if (left === right)
209
221
  return !0;
@@ -266,7 +278,5 @@ function validateOrigin(request, publicOrigin, trustedHosts) {
266
278
  return null;
267
279
  if (trustedHosts?.includes(originUrl.host))
268
280
  return null;
269
- if (originUrl.host === new URL(request.url).host)
270
- return null;
271
281
  return new Response("Forbidden", { status: 403 });
272
282
  }
@@ -15,6 +15,8 @@ import { type JsonRpcId } from '../server/json-rpc-protocol.ts';
15
15
  export declare const MCP_PROTOCOL_VERSION = "2025-11-25";
16
16
  /** MCP method used for live tool introspection. */
17
17
  export declare const MCP_TOOLS_LIST_METHOD = "tools/list";
18
+ /** MCP notification emitted when the live tools/list output changes. */
19
+ export declare const MCP_TOOLS_LIST_CHANGED_NOTIFICATION = "notifications/tools/list_changed";
18
20
  /** MCP method used for live resource introspection. */
19
21
  export declare const MCP_RESOURCES_LIST_METHOD = "resources/list";
20
22
  /** MCP method used for live resource-template introspection. */
@@ -2,7 +2,7 @@ import {
2
2
  JSON_RPC_ERROR_CODES,
3
3
  JSON_RPC_VERSION
4
4
  } from "../server/json-rpc-protocol.js";
5
- export const MCP_PROTOCOL_VERSION = "2025-11-25", MCP_TOOLS_LIST_METHOD = "tools/list", MCP_RESOURCES_LIST_METHOD = "resources/list", MCP_RESOURCE_TEMPLATES_LIST_METHOD = "resources/templates/list", DEFAULT_MCP_MAX_BODY_BYTES = 1048576;
5
+ export const MCP_PROTOCOL_VERSION = "2025-11-25", MCP_TOOLS_LIST_METHOD = "tools/list", MCP_TOOLS_LIST_CHANGED_NOTIFICATION = "notifications/tools/list_changed", MCP_RESOURCES_LIST_METHOD = "resources/list", MCP_RESOURCE_TEMPLATES_LIST_METHOD = "resources/templates/list", DEFAULT_MCP_MAX_BODY_BYTES = 1048576;
6
6
  export function successResponse(id, result) {
7
7
  return { jsonrpc: JSON_RPC_VERSION, id, result };
8
8
  }
@@ -63,6 +63,20 @@ export declare class McpSession {
63
63
  #private;
64
64
  readonly id: string;
65
65
  readonly principal: Principal;
66
+ /**
67
+ * Per-session continuation secret minted at creation. The session {@link id} is
68
+ * sent by the client on *every* continuation request (POST/GET/DELETE), so it is
69
+ * routinely exposed to proxy and access logs and is not, by itself, a credential.
70
+ * This token is the credential: it is disclosed to the creating client exactly
71
+ * once — in the `initialize` response — and never echoed on a continuation
72
+ * response. The HTTP transport requires it alongside the session id on every
73
+ * continuation request for sessions whose principal carries no other
74
+ * distinguishing secret (anonymous sessions under `authRequired: false`), so a
75
+ * leaked session id alone cannot drive, read, or terminate another caller's
76
+ * session. Authenticated sessions already re-present their credential per request
77
+ * and do not gate on this token.
78
+ */
79
+ readonly token: string;
66
80
  phase: McpSessionPhase;
67
81
  protocolVersion: string;
68
82
  readonly subscriptions: Set<string>;
@@ -79,6 +93,8 @@ export declare class McpSession {
79
93
  cancelRequest(requestId: unknown): string | undefined;
80
94
  /** True when an in-flight MCP request has received a cancellation notification. */
81
95
  isRequestCancelled(requestId: unknown): boolean;
96
+ /** Abort signal for an in-flight MCP request, if it can be cancelled. */
97
+ requestSignal(requestId: unknown): AbortSignal | undefined;
82
98
  /** Stop tracking an in-flight request after it completes. */
83
99
  untrackRequest(requestId: unknown): void;
84
100
  /** Return the workflow associated with an in-flight MCP request. */
@@ -1,6 +1,8 @@
1
+ import { WorkflowDefinitionRegisteredEvent } from "../core/events.js";
1
2
  import { WeftError } from "../core/weft-error.js";
2
- import { requestIdKey } from "./protocol.js";
3
+ import { MCP_TOOLS_LIST_CHANGED_NOTIFICATION, requestIdKey } from "./protocol.js";
3
4
  import { isWorkflowSearchResourceUri, workflowResourceUri } from "./resources.js";
5
+ import { listMcpTools } from "./tools.js";
4
6
 
5
7
  export class McpSessionLimitExceededError extends WeftError {
6
8
  constructor() {
@@ -25,6 +27,7 @@ const RESOURCE_EVENT_NAMES = [
25
27
  export class McpSession {
26
28
  id;
27
29
  principal;
30
+ token;
28
31
  phase = "new";
29
32
  protocolVersion = "2025-11-25";
30
33
  subscriptions = new Set;
@@ -36,6 +39,7 @@ export class McpSession {
36
39
  constructor(id, principal, currentTimeMilliseconds = Date.now()) {
37
40
  this.id = id;
38
41
  this.principal = principal;
42
+ this.token = crypto.randomUUID();
39
43
  this.createdAtMilliseconds = currentTimeMilliseconds;
40
44
  this.lastActivityMilliseconds = currentTimeMilliseconds;
41
45
  }
@@ -49,7 +53,7 @@ export class McpSession {
49
53
  const key = requestIdKey(asJsonRpcId(requestId));
50
54
  if (key === void 0)
51
55
  return;
52
- this.#pendingRequests.set(key, { workflowId });
56
+ this.#pendingRequests.set(key, { workflowId, abortController: new AbortController });
53
57
  }
54
58
  cancelRequest(requestId) {
55
59
  const key = requestIdKey(asJsonRpcId(requestId));
@@ -59,12 +63,19 @@ export class McpSession {
59
63
  if (request === void 0)
60
64
  return;
61
65
  this.#cancelledRequestKeys.add(key);
66
+ request.abortController.abort();
62
67
  return request.workflowId;
63
68
  }
64
69
  isRequestCancelled(requestId) {
65
70
  const key = requestIdKey(asJsonRpcId(requestId));
66
71
  return key !== void 0 && this.#cancelledRequestKeys.has(key);
67
72
  }
73
+ requestSignal(requestId) {
74
+ const key = requestIdKey(asJsonRpcId(requestId));
75
+ if (key === void 0)
76
+ return;
77
+ return this.#pendingRequests.get(key)?.abortController.signal;
78
+ }
68
79
  untrackRequest(requestId) {
69
80
  const key = requestIdKey(asJsonRpcId(requestId));
70
81
  if (key === void 0)
@@ -109,23 +120,30 @@ function asJsonRpcId(value) {
109
120
  export class McpSessionManager {
110
121
  #engine;
111
122
  #sessions = new Map;
112
- #listener;
123
+ #resourceListener;
124
+ #workflowDefinitionListener;
113
125
  #maximumSessions;
114
126
  #sessionIdleTimeoutMilliseconds;
115
127
  #currentTimeMilliseconds;
128
+ #toolListSignature;
116
129
  constructor(engine, options = {}) {
117
130
  this.#engine = engine;
118
131
  this.#maximumSessions = options.maximumSessions ?? 1024;
119
132
  this.#sessionIdleTimeoutMilliseconds = options.sessionIdleTimeoutMilliseconds ?? 1800000;
120
133
  this.#currentTimeMilliseconds = options.currentTimeMilliseconds ?? Date.now;
121
- this.#listener = (event) => {
134
+ this.#toolListSignature = toolListSignature(engine);
135
+ this.#resourceListener = (event) => {
122
136
  const workflowId = event.workflowId;
123
137
  if (typeof workflowId !== "string")
124
138
  return;
125
139
  this.#notifyWorkflowResourceUpdated(workflowId);
126
140
  };
141
+ this.#workflowDefinitionListener = () => {
142
+ this.#notifyToolListChangedIfNeeded();
143
+ };
127
144
  for (const eventName of RESOURCE_EVENT_NAMES)
128
- this.#engine.addEventListener(eventName, this.#listener);
145
+ this.#engine.addEventListener(eventName, this.#resourceListener);
146
+ this.#engine.addEventListener(WorkflowDefinitionRegisteredEvent.type, this.#workflowDefinitionListener);
129
147
  }
130
148
  create(principal) {
131
149
  this.#deleteExpiredSessions();
@@ -185,6 +203,20 @@ export class McpSessionManager {
185
203
  }
186
204
  this.#deleteExpiredSessions();
187
205
  }
206
+ #notifyToolListChangedIfNeeded() {
207
+ const nextSignature = toolListSignature(this.#engine);
208
+ if (toolListSignaturesEqual(this.#toolListSignature, nextSignature))
209
+ return;
210
+ this.#toolListSignature = nextSignature;
211
+ const now = this.#currentTimeMilliseconds();
212
+ for (const session of this.#sessions.values()) {
213
+ if (session.phase !== "ready")
214
+ continue;
215
+ session.touch(now);
216
+ session.notify(MCP_TOOLS_LIST_CHANGED_NOTIFICATION);
217
+ }
218
+ this.#deleteExpiredSessions();
219
+ }
188
220
  #deleteExpiredSessions() {
189
221
  const now = this.#currentTimeMilliseconds();
190
222
  for (const [sessionId, session] of this.#sessions) {
@@ -196,10 +228,31 @@ export class McpSessionManager {
196
228
  }
197
229
  async[Symbol.asyncDispose]() {
198
230
  for (const eventName of RESOURCE_EVENT_NAMES)
199
- this.#engine.removeEventListener(eventName, this.#listener);
231
+ this.#engine.removeEventListener(eventName, this.#resourceListener);
232
+ this.#engine.removeEventListener(WorkflowDefinitionRegisteredEvent.type, this.#workflowDefinitionListener);
200
233
  this.closeAll();
201
234
  }
202
235
  }
236
+ function toolListSignature(engine) {
237
+ return listMcpTools(engine).map((tool) => [
238
+ tool.name,
239
+ tool.title,
240
+ tool.description,
241
+ JSON.stringify(tool.inputSchema) ?? ""
242
+ ]);
243
+ }
244
+ function toolListSignaturesEqual(left, right) {
245
+ if (left.length !== right.length)
246
+ return !1;
247
+ for (let index = 0;index < left.length; index++) {
248
+ const leftEntry = left[index], rightEntry = right[index];
249
+ if (leftEntry === void 0 || rightEntry === void 0)
250
+ return !1;
251
+ if (leftEntry[0] !== rightEntry[0] || leftEntry[1] !== rightEntry[1] || leftEntry[2] !== rightEntry[2] || leftEntry[3] !== rightEntry[3])
252
+ return !1;
253
+ }
254
+ return !0;
255
+ }
203
256
  export function createMcpSessionManager(engine, options) {
204
257
  return new McpSessionManager(engine, options);
205
258
  }
package/dist/mcp/tools.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  listVisibleWorkflows
9
9
  } from "./access.js";
10
10
  import { parseMcpListFilter } from "./list-filter.js";
11
- const toolRegistryCache = new WeakMap;
11
+ const toolRegistryCache = new WeakMap, DEFAULT_WORKFLOW_TOOL_TIMEOUT_MS = 30000, MAX_WORKFLOW_TOOL_TIMEOUT_MS = 2147483647;
12
12
  export function listMcpTools(engine) {
13
13
  return getToolRegistry(engine).tools.map((tool) => tool.definition);
14
14
  }
@@ -71,7 +71,7 @@ function buildToolImplementations(engine) {
71
71
  },
72
72
  call: async (argumentsValue, context) => {
73
73
  assertScope(context, "workflows:write", "Calling workflow tools");
74
- const input = argumentsValue, workflowId = crypto.randomUUID();
74
+ const { input, timeoutMs } = parseWorkflowToolArguments(argumentsValue), workflowId = crypto.randomUUID();
75
75
  context.session.trackRequest(context.requestId, workflowId);
76
76
  try {
77
77
  if (context.session.isRequestCancelled(context.requestId))
@@ -81,8 +81,13 @@ function buildToolImplementations(engine) {
81
81
  });
82
82
  if (context.session.isRequestCancelled(context.requestId))
83
83
  await context.engine.cancel(handle.id);
84
- const result = await handle.result();
85
- return { workflowId: handle.id, result };
84
+ const outcome = await waitForWorkflowToolResult(handle, {
85
+ timeoutMs,
86
+ signal: context.session.requestSignal(context.requestId)
87
+ });
88
+ if (outcome.status === "timed-out")
89
+ return workflowToolStillRunningResult(handle.id, timeoutMs);
90
+ return { workflowId: handle.id, result: outcome.result };
86
91
  } finally {
87
92
  context.session.untrackRequest(context.requestId);
88
93
  }
@@ -93,11 +98,73 @@ function buildToolImplementations(engine) {
93
98
  }
94
99
  function convertWorkflowInputSchema(workflowType, schema) {
95
100
  try {
96
- return definitionSchemaToJsonSchema(schema, "input");
101
+ return withWorkflowToolTimeoutParameter(definitionSchemaToJsonSchema(schema, "input"));
97
102
  } catch (cause) {
98
103
  throw new RegistrySchemaConversionError("workflow", workflowType, "inputSchema", cause);
99
104
  }
100
105
  }
106
+ function withWorkflowToolTimeoutParameter(schema) {
107
+ return {
108
+ type: "object",
109
+ additionalProperties: !1,
110
+ required: ["input"],
111
+ properties: {
112
+ input: schema,
113
+ timeoutMs: {
114
+ type: "integer",
115
+ minimum: 1,
116
+ maximum: MAX_WORKFLOW_TOOL_TIMEOUT_MS,
117
+ default: DEFAULT_WORKFLOW_TOOL_TIMEOUT_MS,
118
+ description: "Maximum milliseconds to wait for the workflow result before returning a running status."
119
+ }
120
+ }
121
+ };
122
+ }
123
+ function parseWorkflowToolArguments(argumentsValue) {
124
+ if (argumentsValue === null || typeof argumentsValue !== "object" || Array.isArray(argumentsValue))
125
+ return { input: argumentsValue, timeoutMs: DEFAULT_WORKFLOW_TOOL_TIMEOUT_MS };
126
+ const record = argumentsValue, timeoutMs = parseWorkflowToolTimeoutMs(record.timeoutMs);
127
+ return { input: record.input, timeoutMs };
128
+ }
129
+ function parseWorkflowToolTimeoutMs(value) {
130
+ if (value === void 0)
131
+ return DEFAULT_WORKFLOW_TOOL_TIMEOUT_MS;
132
+ if (typeof value === "number" && Number.isSafeInteger(value) && value >= 1 && value <= MAX_WORKFLOW_TOOL_TIMEOUT_MS)
133
+ return value;
134
+ throw new McpToolExecutionError(`Tool argument "timeoutMs" must be an integer from 1 to ${MAX_WORKFLOW_TOOL_TIMEOUT_MS}`);
135
+ }
136
+ async function waitForWorkflowToolResult(handle, options) {
137
+ if (options.signal?.aborted)
138
+ throw new McpToolExecutionError("Workflow cancelled");
139
+ let timeout, cleanupAbortListener;
140
+ const resultPromise = handle.result().then((result) => ({ status: "completed", result })), timeoutPromise = new Promise((resolve) => {
141
+ timeout = setTimeout(() => resolve({ status: "timed-out" }), options.timeoutMs);
142
+ }), cancellationPromise = options.signal === void 0 ? void 0 : new Promise((_resolve, reject) => {
143
+ const abort = () => reject(new McpToolExecutionError("Workflow cancelled"));
144
+ options.signal?.addEventListener("abort", abort, { once: !0 });
145
+ cleanupAbortListener = () => options.signal?.removeEventListener("abort", abort);
146
+ });
147
+ try {
148
+ return await Promise.race(cancellationPromise === void 0 ? [resultPromise, timeoutPromise] : [resultPromise, timeoutPromise, cancellationPromise]);
149
+ } finally {
150
+ if (timeout !== void 0)
151
+ clearTimeout(timeout);
152
+ cleanupAbortListener?.();
153
+ }
154
+ }
155
+ function workflowToolStillRunningResult(workflowId, timeoutMs) {
156
+ return {
157
+ workflowId,
158
+ status: "running",
159
+ timedOut: !0,
160
+ timeoutMs,
161
+ message: "Workflow is still running and was not cancelled. Call get_workflow_state with this workflowId to poll for completion.",
162
+ followUp: {
163
+ tool: "get_workflow_state",
164
+ arguments: { workflowId }
165
+ }
166
+ };
167
+ }
101
168
  function builtInTools() {
102
169
  return [
103
170
  {
@@ -223,7 +290,7 @@ async function requireVisibleWorkflow(context, workflowId) {
223
290
  return state;
224
291
  }
225
292
  function toolSuccess(value) {
226
- return { content: [{ type: "text", text: JSON.stringify(value) }] };
293
+ return { isError: !1, content: [{ type: "text", text: JSON.stringify(value) }] };
227
294
  }
228
295
  function toolError(message) {
229
296
  return { isError: !0, content: [{ type: "text", text: message }] };
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- var DS=Object.defineProperty;var US=(S)=>S;function _S(S,$){this[S]=US.bind(null,$)}var S0=(S,$)=>{for(var G in $)DS(S,G,{get:$[G],enumerable:!0,configurable:!0,set:_S.bind($,G)})};var W=(S,$)=>()=>(S&&($=S(S=0)),$);var m,d,i,n;var o=W(()=>{m=class m extends Event{static type="activity:started";operationId;workflowId;activityName;attempt;constructor(S,$,G,K){super(m.type);this.operationId=S,this.workflowId=$,this.activityName=G,this.attempt=K}};d=class d extends Event{static type="activity:completed";operationId;workflowId;activityName;duration;constructor(S,$,G,K){super(d.type);this.operationId=S,this.workflowId=$,this.activityName=G,this.duration=K}};i=class i extends Event{static type="activity:async-pending";token;operationId;workflowId;activityName;attempt;constructor(S,$,G,K,L){super(i.type);this.token=S,this.operationId=$,this.workflowId=G,this.activityName=K,this.attempt=L}};n=class n extends Event{static type="activity:failed";operationId;workflowId;activityName;error;attempt;constructor(S,$,G,K,L){super(n.type);this.operationId=S,this.workflowId=$,this.activityName=G,this.error=K,this.attempt=L}}});var l;var r=W(()=>{l=class l extends Event{static type="attributes:changed";workflowId;changes;constructor(S,$){super(l.type);this.workflowId=S,this.changes=$}}});var s,a;var t=W(()=>{s=class s extends Event{static type="signal:received";workflowId;signalName;payload;constructor(S,$,G){super(s.type);this.workflowId=S,this.signalName=$,this.payload=G}};a=class a extends Event{static type="signal:delivered";workflowId;signalName;constructor(S,$){super(a.type);this.workflowId=S,this.signalName=$}}});var e,SS,$S,GS,KS,LS,xS;var XS=W(()=>{e=class e extends Event{static type="checkpoint:size-warning";workflowId;sizeBytes;step;constructor(S,$,G){super(e.type);this.workflowId=S,this.sizeBytes=$,this.step=G}};SS=class SS extends Event{static type="development:warning";workflowId;message;fieldPaths;constructor(S,$,G){super(SS.type);this.workflowId=S,this.message=$,this.fieldPaths=G}};$S=class $S extends Event{static type="cleanup:warning";source;error;workflowId;constructor(S,$,G){super($S.type);this.source=S,this.error=$,this.workflowId=G}};GS=class GS extends Event{static type="storage:size-reported";sizeBytes;constructor(S){super(GS.type);this.sizeBytes=S}};KS=class KS extends Event{static type="alert:fired";metric;threshold;currentValue;window;constructor(S,$,G,K){super(KS.type);this.metric=S,this.threshold=$,this.currentValue=G,this.window=K}};LS=class LS extends Event{static type="alert:resolved";metric;threshold;currentValue;window;constructor(S,$,G,K){super(LS.type);this.metric=S,this.threshold=$,this.currentValue=G,this.window=K}};xS=class xS extends Event{static type="constraint:violated";workflowId;constraintName;scope;onViolation;constructor(S,$,G,K){super(xS.type);this.workflowId=S,this.constraintName=$,this.scope=G,this.onViolation=K}}});var TS,JS;var QS=W(()=>{TS=class TS extends Event{static type="update:received";updateId;workflowId;name;payload;constructor(S,$,G,K){super(TS.type);this.updateId=S,this.workflowId=$,this.name=G,this.payload=K}};JS=class JS extends Event{static type="update:completed";updateId;workflowId;name;result;error;constructor(S,$,G,K,L){super(JS.type);this.updateId=S,this.workflowId=$,this.name=G,this.result=K,this.error=L}}});var WS,j,q,H,Y,P0,jS,qS,HS;var YS=W(()=>{WS=class WS extends Event{static type="workflow:started";workflowId;workflowType;input;constructor(S,$,G){super(WS.type);this.workflowId=S,this.workflowType=$,this.input=G}};j=class j extends Event{static type="workflow:completed";workflowId;result;duration;constructor(S,$,G){super(j.type);this.workflowId=S,this.result=$,this.duration=G}};q=class q extends Event{static type="workflow:failed";workflowId;error;constructor(S,$){super(q.type);this.workflowId=S,this.error=$}};H=class H extends Event{static type="workflow:cancelled";workflowId;constructor(S){super(H.type);this.workflowId=S}};Y=class Y extends Event{static type="workflow:timed-out";workflowId;timeoutType;elapsed;reason;constructor(S,$,G,K){super(Y.type);if(this.workflowId=S,this.timeoutType=$,this.elapsed=G,K!==void 0)this.reason=K}};P0=new Set([j.type,q.type,H.type,Y.type]);jS=class jS extends Event{static type="workflow:resumed";workflowId;fromStep;constructor(S,$){super(jS.type);this.workflowId=S,this.fromStep=$}};qS=class qS extends Event{static type="workflow:suspended";workflowId;constructor(S){super(qS.type);this.workflowId=S}};HS=class HS extends Event{static type="workflow:recovery-skipped";workflowId;workflowType;reason;constructor(S,$,G){super(HS.type);this.workflowId=S,this.workflowType=$,this.reason=G}}});var ZS=W(()=>{o();r();t();XS();QS();YS()});var MS=W(()=>{ZS()});var kS={traceId:"0".repeat(32),spanId:"0".repeat(16),traceFlags:0},D={setAttribute(){},setStatus(){},recordException(){},end(){},spanContext(){return kS}},f={setAttribute:(...S)=>D.setAttribute(...S),setStatus:(...S)=>D.setStatus(...S),recordException:(...S)=>D.recordException(...S),end:(...S)=>D.end(...S)},yS={startSpan(){return D}},V={record(){},add(){}},RS={createHistogram(){return V},createCounter(){return V},createUpDownCounter(){return V}},wS=Symbol("ROOT_CONTEXT"),AS={trace:{getTracer(){return yS},setSpan(S){return S}},metrics:{getMeter(){return RS}},context:{ROOT_CONTEXT:wS,with(S,$){return $()}},SpanStatusCode:{OK:1,ERROR:2,UNSET:0}},M;function VS(){let S=globalThis.require;if(typeof S==="function")return($)=>S($);return()=>{return}}function CS(S){return S?.trace?.getTracer!=null&&S.SpanStatusCode!=null}function zS(S=VS()){try{let $=S("@opentelemetry/api");if(CS($))return $}catch{}return}function B(S){if(M)return M;let $=zS(S);if($)return M=$,M;return M=AS,M}function I(S){let $=new Uint8Array(S);return crypto.getRandomValues($),Array.from($,(G)=>G.toString(16).padStart(2,"0")).join("")}var N="traceparent",fS=/^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/,IS="00000000000000000000000000000000",NS="0000000000000000";function p(S){let $=fS.exec(S);if(!$)return null;let[,G,K,L,X]=$;if(K===IS)return null;if(L===NS)return null;return{version:G,traceId:K,spanId:L,traceFlags:parseInt(X,16)}}function g(S){let $=S.traceFlags.toString(16).padStart(2,"0");return`${S.version}-${S.traceId}-${S.spanId}-${$}`}function U(S){let $=S.get(N);if(!$)return null;return p($)}function C(S,$){S.set(N,g($))}function pS(){return I(16)}function gS(){return I(8)}var u=1024;function F(S,$){let G;try{G=JSON.stringify(S)}catch{G=String(S)}if(G.length>$)return G.slice(0,$)+"...";return G}function uS(S){return S instanceof Error?S.message:String(S)}function hS(S){return S instanceof Error?S:Error(String(S))}function _(S,$){let G=S.spanContext();C($,{version:"00",traceId:G.traceId,spanId:G.spanId,traceFlags:G.traceFlags})}function O(S,$,G){let K=S.attributeExtractor;if(!K)return;let L=K(G);for(let[X,T]of Object.entries(L))$.setAttribute(X,T)}function k(S,$){let G=S.workflowSpans.get($);return G?S.trace.setSpan(S.api.context.ROOT_CONTEXT,G.span):S.api.context.ROOT_CONTEXT}function z(S,$,G){$.setStatus({code:S.SpanStatusCode.ERROR,message:uS(G)}),$.recordException(hS(G))}function h(S,$,G,K){try{let L=G();return $.setStatus({code:S.SpanStatusCode.OK}),K?.(L),L}catch(L){throw z(S,$,L),L}finally{$.end()}}async function y(S,$,G,K){try{let L=await G();return $.setStatus({code:S.SpanStatusCode.OK}),K?.(L),L}catch(L){throw z(S,$,L),L}finally{$.end()}}function*R(S,$,G,K){try{let L=yield*G();return $.setStatus({code:S.SpanStatusCode.OK}),K?.(L),L}catch(L){throw z(S,$,L),L}finally{$.end()}}function E(S){return{async execute($,G){let K=U($.headers),L=S.api.context.ROOT_CONTEXT;if(K){let T={...f,spanContext(){return{traceId:K.traceId,spanId:K.spanId,traceFlags:K.traceFlags}}};L=S.trace.setSpan(S.api.context.ROOT_CONTEXT,T)}let X=S.tracer.startSpan(`activity:execute:${$.activityName}`,{attributes:{"weft.activity.name":$.activityName,"weft.activity.attempt":$.attempt,...K?{"weft.parent.trace_id":K.traceId}:{}}},L);if(S.recordPayloads&&$.input!==void 0)X.setAttribute("weft.payload.input",F($.input,S.maxPayloadSize));return y(S,X,()=>G($))}}}var P={workflowDuration:{name:"weft.workflow.duration",description:"Duration of workflow execution in milliseconds",unit:"ms",type:"histogram"},activityDuration:{name:"weft.activity.duration",description:"Duration of activity execution in milliseconds",unit:"ms",type:"histogram"},activityAttempts:{name:"weft.activity.attempts",description:"Total activity execution attempts",unit:"attempts",type:"counter"},workflowActive:{name:"weft.workflow.active",description:"Number of currently active workflows",unit:"workflows",type:"gauge"},workflowStarted:{name:"weft.workflow.started",description:"Total workflows started",unit:"workflows",type:"counter"},workflowCompleted:{name:"weft.workflow.completed",description:"Total workflows completed",unit:"workflows",type:"counter"},workflowFailed:{name:"weft.workflow.failed",description:"Total workflows failed",unit:"workflows",type:"counter"},promptCacheHits:{name:"weft.prompt_cache.hits",description:"Total prompt prefix cache hits",unit:"hits",type:"counter"},promptCacheMisses:{name:"weft.prompt_cache.misses",description:"Total prompt prefix cache misses",unit:"misses",type:"counter"},dpmoDefects:{name:"weft.dpmo.defects",description:"Total failed workflows (DPMO numerator)",unit:"workflows",type:"counter"},dpmoOperations:{name:"weft.dpmo.operations",description:"Total started workflows (DPMO denominator)",unit:"workflows",type:"counter"},taskBacklog:{name:"weft.task.backlog",description:"Number of queued tasks waiting for workers",unit:"tasks",type:"gauge"},taskQueueLatency:{name:"weft.task.queue_latency",description:"Time tasks spend queued before dispatch in milliseconds",unit:"ms",type:"histogram"},taskExecutionLatency:{name:"weft.task.execution_latency",description:"Time tasks spend executing after worker start in milliseconds",unit:"ms",type:"histogram"},taskRetries:{name:"weft.task.retries",description:"Total task retry attempts after the first dispatch attempt",unit:"retries",type:"counter"},taskRequeues:{name:"weft.task.requeues",description:"Total visibility-timeout or disconnect task requeues",unit:"requeues",type:"counter"},taskStaleHeartbeats:{name:"weft.task.stale_heartbeats",description:"Number of in-flight tasks whose heartbeat age exceeds the diagnostic threshold",unit:"tasks",type:"gauge"},workerCapacitySaturation:{name:"weft.worker.capacity_saturation",description:"Ratio of in-flight worker slots to total worker concurrency",unit:"ratio",type:"gauge"}};var ES=1e4;class v{#S;#G=0;#$=0;constructor(S){this.#S=new Float64Array(S)}push(S){if(this.#S[this.#G]=S,this.#G=(this.#G+1)%this.#S.length,this.#$<this.#S.length)this.#$++}toArray(){if(this.#$<this.#S.length)return Array.from(this.#S.subarray(0,this.#$));let S=Array.from({length:this.#$});for(let $=0;$<this.#$;$++)S[$]=this.#S[(this.#G+$)%this.#S.length];return S}}class w{#S;#G;#$;constructor(){this.#S=new Map,this.#G=new Map,this.#$=new Map}increment(S,$=1){this.#S.set(S,(this.#S.get(S)??0)+$)}record(S,$){let G=this.#G.get(S);if(!G)G=new v(ES),this.#G.set(S,G);G.push($)}gauge(S,$){this.#$.set(S,$)}snapshot(){let S={};for(let[$,G]of this.#S)S[$]={type:"counter",value:G};for(let[$,G]of this.#G){let K=G.toArray(),L=cS(K);S[$]={type:"histogram",count:K.length,sum:mS(K),p50:L[Math.floor(L.length*0.5)]??0,p99:L[Math.floor(L.length*0.99)]??0,min:L[0]??0,max:L[L.length-1]??0}}for(let[$,G]of this.#$)S[$]={type:"gauge",value:G};return S}reset(){this.#S.clear(),this.#G.clear(),this.#$.clear()}}function vS(S){let $;if(typeof S==="string")$=B().metrics.getMeter(S);else if(S)$=S;else $=B().metrics.getMeter("weft");return{workflowDuration:$.createHistogram("weft.workflow.duration",{unit:"ms"}),activityDuration:$.createHistogram("weft.activity.duration",{unit:"ms"}),activityAttempts:$.createCounter("weft.activity.attempts"),activeWorkflows:$.createUpDownCounter("weft.workflow.active")}}function cS(S){let $=[...S];return $.sort((G,K)=>G-K),$}function mS(S){let $=0;for(let G of S)$+=G;return $}function dS(S,$){let G=$?.type==="histogram"?$.count:0,K=$?.type==="histogram"?$.sum:0;return[`# TYPE ${S} histogram`,`${S}_count ${G}`,`${S}_sum ${K}`]}function iS(S,$){let G=$?.type==="counter"?$.value:0;return[`# TYPE ${S} counter`,`${S}_total ${G}`]}function nS(S,$){let G=$?.type==="gauge"?$.value:0;return[`# TYPE ${S} gauge`,`${S} ${G}`]}var oS={histogram:dS,counter:iS,gauge:nS};function lS(S,$){let G=S.name.replace(/\./g,"_"),K=$[S.name];return[`# HELP ${G} ${S.description}`,...oS[S.type](G,K)]}function rS(S){let $=S[P.dpmoDefects.name],G=S[P.dpmoOperations.name],K=$?.type==="counter"?$.value:0,L=G?.type==="counter"?G.value:0,X=L===0?0:K*1e6/L,T="weft_dpmo";return["# HELP weft_dpmo Defects per million operations (failed workflows / started workflows * 1e6)","# TYPE weft_dpmo gauge",`weft_dpmo ${X}`]}function c(S){let $=[];for(let G of Object.values(P))$.push(...lS(G,S));return $.push(...rS(S)),$.join(`
2
+ var kS=Object.defineProperty;var zS=(S)=>S;function CS(S,W){this[S]=zS.bind(null,W)}var L0=(S,W)=>{for(var $ in W)kS(S,$,{get:W[$],enumerable:!0,configurable:!0,set:CS.bind(W,$)})};var L=(S,W)=>()=>(S&&(W=S(S=0)),W);var Q0=(S,W,$)=>{if(W!=null){if(typeof W!=="object"&&typeof W!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let x;if($)x=W[Symbol.asyncDispose];if(x===void 0)x=W[Symbol.dispose];if(typeof x!=="function")throw TypeError("Object not disposable");S.push([$,x,W])}else if($)S.push([$]);return W},j0=(S,W,$)=>{let x=(K)=>W=$?new SuppressedError(K,W,"An error was suppressed during disposal"):($=!0,K),G=(K)=>{while(K=S.pop())try{var J=K[1]&&K[1].call(K[2]);if(K[0])return Promise.resolve(J).then(G,(H)=>(x(H),G()))}catch(H){x(H)}if($)throw W};return G()};var c,i,d,n,l;var o=L(()=>{c=class c extends Event{static type="activity:started";operationId;workflowId;activityName;attempt;constructor(S,W,$,x){super(c.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.attempt=x}};i=class i extends Event{static type="activity:completed";operationId;workflowId;activityName;duration;constructor(S,W,$,x){super(i.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.duration=x}};d=class d extends Event{static type="activity:async-pending";token;operationId;workflowId;activityName;attempt;constructor(S,W,$,x,G){super(d.type);this.token=S,this.operationId=W,this.workflowId=$,this.activityName=x,this.attempt=G}};n=class n extends Event{static type="activity:failed";operationId;workflowId;activityName;error;attempt;constructor(S,W,$,x,G){super(n.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.error=x,this.attempt=G}};l=class l extends Event{static type="task:dead-lettered";operationId;workflowId;activityName;queue;workerId;reason;errorMessage;constructor({operationId:S,workflowId:W,activityName:$,queue:x,workerId:G,errorMessage:K}){super(l.type);this.operationId=S,this.workflowId=W,this.activityName=$,this.queue=x,this.workerId=G,this.reason="result-resolution-storage-exhausted",this.errorMessage=K}}});var r;var s=L(()=>{r=class r extends Event{static type="attributes:changed";workflowId;changes;constructor(S,W){super(r.type);this.workflowId=S,this.changes=W}}});var a,t;var e=L(()=>{a=class a extends Event{static type="schedule:fired";scheduleId;workflowId;firedAt;occurrence;constructor(S,W,$,x){super(a.type);this.scheduleId=S,this.workflowId=W,this.firedAt=$,this.occurrence=x}};t=class t extends Event{static type="schedule:missed-fire";scheduleId;missedCount;windowStart;windowEnd;constructor(S,W,$,x){super(t.type);this.scheduleId=S,this.missedCount=W,this.windowStart=$,this.windowEnd=x}}});var SS,WS;var $S=L(()=>{SS=class SS extends Event{static type="signal:received";workflowId;signalName;payload;constructor(S,W,$){super(SS.type);this.workflowId=S,this.signalName=W,this.payload=$}};WS=class WS extends Event{static type="signal:delivered";workflowId;signalName;constructor(S,W){super(WS.type);this.workflowId=S,this.signalName=W}}});var xS,GS,KS,XS,JS,LS,QS,jS,HS;var YS=L(()=>{xS=class xS extends Event{static type="checkpoint:size-warning";workflowId;sizeBytes;step;constructor(S,W,$){super(xS.type);this.workflowId=S,this.sizeBytes=W,this.step=$}};GS=class GS extends Event{static type="development:warning";workflowId;message;fieldPaths;constructor(S,W,$){super(GS.type);this.workflowId=S,this.message=W,this.fieldPaths=$}};KS=class KS extends Event{static type="cleanup:warning";source;error;workflowId;constructor(S,W,$){super(KS.type);this.source=S,this.error=W,this.workflowId=$}};XS=class XS extends Event{static type="storage:size-reported";sizeBytes;constructor(S){super(XS.type);this.sizeBytes=S}};JS=class JS extends Event{static type="worker:connected";workerId;queue;activities;concurrency;constructor(S,W,$,x){super(JS.type);this.workerId=S,this.queue=W,this.activities=$,this.concurrency=x}};LS=class LS extends Event{static type="worker:disconnected";workerId;inFlightTaskCount;constructor(S,W){super(LS.type);this.workerId=S,this.inFlightTaskCount=W}};QS=class QS extends Event{static type="alert:fired";metric;threshold;currentValue;window;constructor(S,W,$,x){super(QS.type);this.metric=S,this.threshold=W,this.currentValue=$,this.window=x}};jS=class jS extends Event{static type="alert:resolved";metric;threshold;currentValue;window;constructor(S,W,$,x){super(jS.type);this.metric=S,this.threshold=W,this.currentValue=$,this.window=x}};HS=class HS extends Event{static type="constraint:violated";workflowId;constraintName;scope;onViolation;constructor(S,W,$,x){super(HS.type);this.workflowId=S,this.constraintName=W,this.scope=$,this.onViolation=x}}});var ZS,OS;var BS=L(()=>{ZS=class ZS extends Event{static type="update:received";updateId;workflowId;name;payload;constructor(S,W,$,x){super(ZS.type);this.updateId=S,this.workflowId=W,this.name=$,this.payload=x}};OS=class OS extends Event{static type="update:completed";updateId;workflowId;name;result;error;constructor(S,W,$,x,G){super(OS.type);this.updateId=S,this.workflowId=W,this.name=$,this.result=x,this.error=G}}});var PS,qS,Y,Z,O,B,z0,TS,yS,US,_S;var bS=L(()=>{PS=class PS extends Event{static type="workflow:definition-registered";workflowType;constructor(S){super(PS.type);this.workflowType=S}};qS=class qS extends Event{static type="workflow:started";workflowId;workflowType;input;constructor(S,W,$){super(qS.type);this.workflowId=S,this.workflowType=W,this.input=$}};Y=class Y extends Event{static type="workflow:completed";workflowId;result;duration;constructor(S,W,$){super(Y.type);this.workflowId=S,this.result=W,this.duration=$}};Z=class Z extends Event{static type="workflow:failed";workflowId;error;constructor(S,W){super(Z.type);this.workflowId=S,this.error=W}};O=class O extends Event{static type="workflow:cancelled";workflowId;constructor(S){super(O.type);this.workflowId=S}};B=class B extends Event{static type="workflow:timed-out";workflowId;timeoutType;elapsed;reason;constructor(S,W,$,x){super(B.type);if(this.workflowId=S,this.timeoutType=W,this.elapsed=$,x!==void 0)this.reason=x}};z0=new Set([Y.type,Z.type,O.type,B.type]);TS=class TS extends Event{static type="workflow:resumed";workflowId;fromStep;constructor(S,W){super(TS.type);this.workflowId=S,this.fromStep=W}};yS=class yS extends Event{static type="workflow:suspended";workflowId;constructor(S){super(yS.type);this.workflowId=S}};US=class US extends Event{static type="workflow:recovery-skipped";workflowId;workflowType;reason;constructor(S,W,$){super(US.type);this.workflowId=S,this.workflowType=W,this.reason=$}};_S=class _S extends Event{static type="workflow:teardown";workflowId;workflowType;status;attempts;error;constructor(S,W,$,x,G){super(_S.type);this.workflowId=S,this.workflowType=W,this.status=$,this.attempts=x,this.error=G}}});var FS=L(()=>{o();s();e();$S();YS();BS();bS()});var MS=L(()=>{FS()});var wS={traceId:"0".repeat(32),spanId:"0".repeat(16),traceFlags:0},F={setAttribute(){},setStatus(){},recordException(){},end(){},spanContext(){return wS}},w={setAttribute:(...S)=>F.setAttribute(...S),setStatus:(...S)=>F.setStatus(...S),recordException:(...S)=>F.recordException(...S),end:(...S)=>F.end(...S)},pS={startSpan(){return F}},k={record(){},add(){}},IS={createHistogram(){return k},createCounter(){return k},createUpDownCounter(){return k}},NS=Symbol("ROOT_CONTEXT"),gS={trace:{getTracer(){return pS},setSpan(S){return S}},metrics:{getMeter(){return IS}},context:{ROOT_CONTEXT:NS,with(S,W){return W()}},SpanStatusCode:{OK:1,ERROR:2,UNSET:0}},q;function vS(){let S=globalThis.require;if(typeof S==="function")return(W)=>S(W);return()=>{return}}function ES(S){return S?.trace?.getTracer!=null&&S.SpanStatusCode!=null}function hS(S=vS()){try{let W=S("@opentelemetry/api");if(ES(W))return W}catch{}return}function T(S){if(q)return q;let W=hS(S);if(W)return q=W,q;return q=gS,q}function p(S){let W=new Uint8Array(S);return crypto.getRandomValues(W),Array.from(W,($)=>$.toString(16).padStart(2,"0")).join("")}var I="traceparent",uS=/^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/,mS="00000000000000000000000000000000",cS="0000000000000000";function N(S){let W=uS.exec(S);if(!W)return null;let[,$,x,G,K]=W;if(x===mS)return null;if(G===cS)return null;return{version:$,traceId:x,spanId:G,traceFlags:parseInt(K,16)}}function g(S){let W=S.traceFlags.toString(16).padStart(2,"0");return`${S.version}-${S.traceId}-${S.spanId}-${W}`}function M(S){let W=S.get(I);if(!W)return null;return N(W)}function z(S,W){S.set(I,g(W))}function iS(){return p(16)}function dS(){return p(8)}var v=1024;function y(S,W){let $;try{$=JSON.stringify(S)}catch{$=String(S)}if($.length>W)return $.slice(0,W)+"...";return $}function nS(S){return S instanceof Error?S.message:String(S)}function lS(S){return S instanceof Error?S:Error(String(S))}function R(S,W){let $=S.spanContext();z(W,{version:"00",traceId:$.traceId,spanId:$.spanId,traceFlags:$.traceFlags})}function U(S,W,$){let x=S.attributeExtractor;if(!x)return;let G=x($);for(let[K,J]of Object.entries(G))W.setAttribute(K,J)}function A(S,W){let $=S.workflowSpans.get(W);return $?S.trace.setSpan(S.api.context.ROOT_CONTEXT,$.span):S.api.context.ROOT_CONTEXT}function C(S,W,$){W.setStatus({code:S.SpanStatusCode.ERROR,message:nS($)}),W.recordException(lS($))}function E(S,W,$,x){try{let G=$();return W.setStatus({code:S.SpanStatusCode.OK}),x?.(G),G}catch(G){throw C(S,W,G),G}finally{W.end()}}async function f(S,W,$,x){try{let G=await $();return W.setStatus({code:S.SpanStatusCode.OK}),x?.(G),G}catch(G){throw C(S,W,G),G}finally{W.end()}}function*D(S,W,$,x){try{let G=yield*$();return W.setStatus({code:S.SpanStatusCode.OK}),x?.(G),G}catch(G){throw C(S,W,G),G}finally{W.end()}}function h(S){return{async execute(W,$){let x=M(W.headers),G=S.api.context.ROOT_CONTEXT;if(x){let J={...w,spanContext(){return{traceId:x.traceId,spanId:x.spanId,traceFlags:x.traceFlags}}};G=S.trace.setSpan(S.api.context.ROOT_CONTEXT,J)}let K=S.tracer.startSpan(`activity:execute:${W.activityName}`,{attributes:{"weft.activity.name":W.activityName,"weft.activity.attempt":W.attempt,...x?{"weft.parent.trace_id":x.traceId}:{}}},G);if(S.recordPayloads&&W.input!==void 0)K.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));return f(S,K,()=>$(W))}}}var _={workflowDuration:{name:"weft.workflow.duration",description:"Duration of workflow execution in milliseconds",unit:"ms",type:"histogram"},activityDuration:{name:"weft.activity.duration",description:"Duration of activity execution in milliseconds",unit:"ms",type:"histogram"},activityAttempts:{name:"weft.activity.attempts",description:"Total activity execution attempts",unit:"attempts",type:"counter"},workflowActive:{name:"weft.workflow.active",description:"Number of currently active workflows",unit:"workflows",type:"gauge"},workflowStarted:{name:"weft.workflow.started",description:"Total workflows started",unit:"workflows",type:"counter"},workflowCompleted:{name:"weft.workflow.completed",description:"Total workflows completed",unit:"workflows",type:"counter"},workflowFailed:{name:"weft.workflow.failed",description:"Total workflows failed",unit:"workflows",type:"counter"},promptCacheHits:{name:"weft.prompt_cache.hits",description:"Total prompt prefix cache hits",unit:"hits",type:"counter"},promptCacheMisses:{name:"weft.prompt_cache.misses",description:"Total prompt prefix cache misses",unit:"misses",type:"counter"},dpmoDefects:{name:"weft.dpmo.defects",description:"Total failed workflows (DPMO numerator)",unit:"workflows",type:"counter"},dpmoOperations:{name:"weft.dpmo.operations",description:"Total started workflows (DPMO denominator)",unit:"workflows",type:"counter"},taskBacklog:{name:"weft.task.backlog",description:"Number of queued tasks waiting for workers",unit:"tasks",type:"gauge"},taskQueueLatency:{name:"weft.task.queue_latency",description:"Time tasks spend queued before dispatch in milliseconds",unit:"ms",type:"histogram"},taskExecutionLatency:{name:"weft.task.execution_latency",description:"Time tasks spend executing after worker start in milliseconds",unit:"ms",type:"histogram"},taskRetries:{name:"weft.task.retries",description:"Total task retry attempts after the first dispatch attempt",unit:"retries",type:"counter"},taskRequeues:{name:"weft.task.requeues",description:"Total visibility-timeout or disconnect task requeues",unit:"requeues",type:"counter"},taskStaleHeartbeats:{name:"weft.task.stale_heartbeats",description:"Number of in-flight tasks whose heartbeat age exceeds the diagnostic threshold",unit:"tasks",type:"gauge"},workerCapacitySaturation:{name:"weft.worker.capacity_saturation",description:"Ratio of in-flight worker slots to total worker concurrency",unit:"ratio",type:"gauge"}};var oS=1e4;class u{#S;#$=0;#W=0;constructor(S){this.#S=new Float64Array(S)}push(S){if(this.#S[this.#$]=S,this.#$=(this.#$+1)%this.#S.length,this.#W<this.#S.length)this.#W++}toArray(){if(this.#W<this.#S.length)return Array.from(this.#S.subarray(0,this.#W));let S=Array.from({length:this.#W});for(let W=0;W<this.#W;W++)S[W]=this.#S[(this.#$+W)%this.#S.length];return S}}class V{#S;#$;#W;constructor(){this.#S=new Map,this.#$=new Map,this.#W=new Map}increment(S,W=1){this.#S.set(S,(this.#S.get(S)??0)+W)}record(S,W){let $=this.#$.get(S);if(!$)$=new u(oS),this.#$.set(S,$);$.push(W)}gauge(S,W){this.#W.set(S,W)}snapshot(){let S={};for(let[W,$]of this.#S)S[W]={type:"counter",value:$};for(let[W,$]of this.#$){let x=$.toArray(),G=sS(x);S[W]={type:"histogram",count:x.length,sum:aS(x),p50:G[Math.floor(G.length*0.5)]??0,p99:G[Math.floor(G.length*0.99)]??0,min:G[0]??0,max:G[G.length-1]??0}}for(let[W,$]of this.#W)S[W]={type:"gauge",value:$};return S}reset(){this.#S.clear(),this.#$.clear(),this.#W.clear()}}function rS(S){let W;if(typeof S==="string")W=T().metrics.getMeter(S);else if(S)W=S;else W=T().metrics.getMeter("weft");return{workflowDuration:W.createHistogram("weft.workflow.duration",{unit:"ms"}),activityDuration:W.createHistogram("weft.activity.duration",{unit:"ms"}),activityAttempts:W.createCounter("weft.activity.attempts"),activeWorkflows:W.createUpDownCounter("weft.workflow.active")}}function sS(S){let W=[...S];return W.sort(($,x)=>$-x),W}function aS(S){let W=0;for(let $ of S)W+=$;return W}function tS(S,W){let $=W?.type==="histogram"?W.count:0,x=W?.type==="histogram"?W.sum:0;return[`# TYPE ${S} histogram`,`${S}_count ${$}`,`${S}_sum ${x}`]}function eS(S,W){let $=W?.type==="counter"?W.value:0;return[`# TYPE ${S} counter`,`${S}_total ${$}`]}function S0(S,W){let $=W?.type==="gauge"?W.value:0;return[`# TYPE ${S} gauge`,`${S} ${$}`]}var W0={histogram:tS,counter:eS,gauge:S0};function $0(S,W){let $=S.name.replace(/\./g,"_"),x=W[S.name];return[`# HELP ${$} ${S.description}`,...W0[S.type]($,x)]}function x0(S){let W=S[_.dpmoDefects.name],$=S[_.dpmoOperations.name],x=W?.type==="counter"?W.value:0,G=$?.type==="counter"?$.value:0,K=G===0?0:x*1e6/G,J="weft_dpmo";return["# HELP weft_dpmo Defects per million operations (failed workflows / started workflows * 1e6)","# TYPE weft_dpmo gauge",`weft_dpmo ${K}`]}function m(S){let W=[];for(let $ of Object.values(_))W.push(...$0($,S));return W.push(...x0(S)),W.join(`
3
3
  `)+`
4
- `}function sS(S){return{serialize(){let $=S?.snapshot()??{};return c($)}}}MS();var aS=3600000,BS=1e4,tS=3600000;function FS(S){let $=Date.now();for(let[G,K]of S.workflowSpans)if($-K.createdAt>aS)K.span.end(),S.workflowSpans.delete(G);if(S.workflowSpans.size>BS){let G=S.workflowSpans.size-BS,K=0;for(let[L,X]of S.workflowSpans){if(K>=G)break;X.span.end(),S.workflowSpans.delete(L),K++}}}function OS(S,$){let G=S.workflowSpans.get($);if(G)G.span.end(),S.workflowSpans.delete($)}function PS(S){function $(x,Z,J){let Q=S.workflowSpans.get(x);if(!Q)return;if(Z==="error")Q.span.setStatus({code:S.SpanStatusCode.ERROR,...J?{message:J}:{}});else Q.span.setStatus({code:S.SpanStatusCode.OK});Q.span.end(),S.workflowSpans.delete(x)}let G=(x)=>{if(!(x instanceof j))return;$(x.workflowId,"ok")},K=(x)=>{if(!(x instanceof q))return;$(x.workflowId,"error",x.error.message),S.metrics.increment("weft.dpmo.defects")},L=(x)=>{if(!(x instanceof H))return;$(x.workflowId,"error","Workflow cancelled")},X=(x)=>{if(!(x instanceof Y))return;$(x.workflowId,"error",`Workflow timed out (${x.timeoutType}) after ${x.elapsed}ms`),S.metrics.increment("weft.dpmo.defects")};if(S.eventTarget)S.eventTarget.addEventListener(j.type,G),S.eventTarget.addEventListener(q.type,K),S.eventTarget.addEventListener(H.type,L),S.eventTarget.addEventListener(Y.type,X);function T(x=tS){let Z=Date.now()-x,J=0;for(let[Q,b]of S.workflowSpans)if(b.createdAt<=Z)b.span.setStatus({code:S.SpanStatusCode.ERROR,message:"span evicted (stale)"}),b.span.end(),S.workflowSpans.delete(Q),J++;return J}function A(){if(S.eventTarget)S.eventTarget.removeEventListener(j.type,G),S.eventTarget.removeEventListener(q.type,K),S.eventTarget.removeEventListener(H.type,L),S.eventTarget.removeEventListener(Y.type,X);for(let x of S.workflowSpans.values())x.span.setStatus({code:S.SpanStatusCode.ERROR,message:"Observability disposed"}),x.span.end();S.workflowSpans.clear()}return{endWorkflowSpan:$,evictStaleSpans:T,dispose:A}}function bS(S){return{workflowStart($,G){FS(S);let K=S.workflowSpans.get($.workflowId);if(K)K.span.setStatus({code:S.SpanStatusCode.OK}),OS(S,$.workflowId);let L=S.tracer.startSpan(`workflow:${$.workflowType}`,{attributes:{"weft.workflow.id":$.workflowId,"weft.workflow.type":$.workflowType}});if(S.workflowSpans.set($.workflowId,{span:L,createdAt:Date.now()}),_(L,$.headers),S.recordPayloads&&$.input!==void 0)L.setAttribute("weft.payload.input",F($.input,S.maxPayloadSize));O(S,L,$),S.metrics.increment("weft.workflow.started"),S.metrics.increment("weft.dpmo.operations"),G($)},*activity($,G){let K=S.tracer.startSpan(`activity:${$.activityName}`,{attributes:{"weft.activity.name":$.activityName,"weft.activity.attempt":$.attempt}},k(S,$.workflowId));if(_(K,$.headers),S.recordPayloads&&$.input!==void 0)K.setAttribute("weft.payload.input",F($.input,S.maxPayloadSize));O(S,K,$);let L=Date.now();return yield*R(S,K,()=>G($),()=>{S.metrics.record("weft.activity.duration",Date.now()-L),S.metrics.increment("weft.activity.attempts")})},*sleep($,G){let K=S.tracer.startSpan("sleep",{attributes:{"weft.sleep.duration":$.duration}},k(S,$.workflowId));O(S,K,$),yield*R(S,K,()=>G($))},*waitForSignal($,G){let K=S.tracer.startSpan("waitForSignal",{attributes:{"weft.signal.name":$.signalName}},k(S,$.workflowId));return O(S,K,$),yield*R(S,K,()=>G($))},async childWorkflow($,G){let K=[],L=U($.parentHeaders);if(L)K.push({context:{traceId:L.traceId,spanId:L.spanId,traceFlags:L.traceFlags}});let X=S.tracer.startSpan(`childWorkflow:${$.workflowType}`,{attributes:{"weft.child_workflow.type":$.workflowType,"weft.child_workflow.id":$.childWorkflowId,"weft.child_workflow.parent_id":$.workflowId},links:K},S.api.context.ROOT_CONTEXT);if(_(X,$.headers),S.recordPayloads&&$.input!==void 0)X.setAttribute("weft.payload.input",F($.input,S.maxPayloadSize));return S.metrics.increment("weft.child_workflow.started"),y(S,X,()=>G($))},signalReceived($,G){let K=S.tracer.startSpan(`signal:received:${$.signalName}`,{attributes:{"weft.signal.name":$.signalName,"weft.signal.workflow_id":$.workflowId}});O(S,K,$),h(S,K,()=>G($))}}}function eS(S){let{attributeExtractor:$,eventTarget:G,maxPayloadSize:K=u,metrics:L=new w,openTelemetryApi:X=B(),recordPayloads:T=!1,tracerName:A="weft",tracerVersion:x}=S??{},Z=X,{trace:J,SpanStatusCode:Q}=Z,b=J.getTracer(A,x);return{api:Z,trace:J,SpanStatusCode:Q,tracer:b,recordPayloads:T,maxPayloadSize:K,attributeExtractor:$,eventTarget:G,metrics:L,workflowSpans:new Map}}function d0(S){let $=eS(S),G=bS($),K=E($),L={...G,...K},X=PS($);return{interceptor:L,metrics:$.metrics,...X}}export{c as serializeMetricsSnapshotForPrometheus,p as parseTraceParent,C as injectTraceParent,B as getOpenTelemetryApi,pS as generateTraceId,gS as generateSpanId,g as formatTraceParent,U as extractTraceParent,vS as createOpenTelemetryMetrics,d0 as createObservabilityInterceptors,sS as createMetricsCollectorExporter,w as MetricsCollector,P as METRICS};
4
+ `}function G0(S){return{serialize(){let W=S?.snapshot()??{};return m(W)}}}MS();var K0=3600000,RS=1e4,X0=3600000;function AS(S){let W=Date.now();for(let[$,x]of S.workflowSpans)if(W-x.createdAt>K0)x.span.end(),S.workflowSpans.delete($);if(S.workflowSpans.size>RS){let $=S.workflowSpans.size-RS,x=0;for(let[G,K]of S.workflowSpans){if(x>=$)break;K.span.end(),S.workflowSpans.delete(G),x++}}}function fS(S,W){let $=S.workflowSpans.get(W);if($)$.span.end(),S.workflowSpans.delete(W)}function DS(S){function W(X,P,Q){let j=S.workflowSpans.get(X);if(!j)return;if(P==="error")j.span.setStatus({code:S.SpanStatusCode.ERROR,...Q?{message:Q}:{}});else j.span.setStatus({code:S.SpanStatusCode.OK});j.span.end(),S.workflowSpans.delete(X)}let $=(X)=>{if(!(X instanceof Y))return;W(X.workflowId,"ok")},x=(X)=>{if(!(X instanceof Z))return;W(X.workflowId,"error",X.error.message),S.metrics.increment("weft.dpmo.defects")},G=(X)=>{if(!(X instanceof O))return;W(X.workflowId,"error","Workflow cancelled")},K=(X)=>{if(!(X instanceof B))return;W(X.workflowId,"error",`Workflow timed out (${X.timeoutType}) after ${X.elapsed}ms`),S.metrics.increment("weft.dpmo.defects")};if(S.eventTarget)S.eventTarget.addEventListener(Y.type,$),S.eventTarget.addEventListener(Z.type,x),S.eventTarget.addEventListener(O.type,G),S.eventTarget.addEventListener(B.type,K);function J(X=X0){let P=Date.now()-X,Q=0;for(let[j,b]of S.workflowSpans)if(b.createdAt<=P)b.span.setStatus({code:S.SpanStatusCode.ERROR,message:"span evicted (stale)"}),b.span.end(),S.workflowSpans.delete(j),Q++;return Q}function H(){if(S.eventTarget)S.eventTarget.removeEventListener(Y.type,$),S.eventTarget.removeEventListener(Z.type,x),S.eventTarget.removeEventListener(O.type,G),S.eventTarget.removeEventListener(B.type,K);for(let X of S.workflowSpans.values())X.span.setStatus({code:S.SpanStatusCode.ERROR,message:"Observability disposed"}),X.span.end();S.workflowSpans.clear()}return{endWorkflowSpan:W,evictStaleSpans:J,dispose:H}}function VS(S){return{workflowStart(W,$){AS(S);let x=S.workflowSpans.get(W.workflowId);if(x)x.span.setStatus({code:S.SpanStatusCode.OK}),fS(S,W.workflowId);let G=S.tracer.startSpan(`workflow:${W.workflowType}`,{attributes:{"weft.workflow.id":W.workflowId,"weft.workflow.type":W.workflowType}});if(S.workflowSpans.set(W.workflowId,{span:G,createdAt:Date.now()}),R(G,W.headers),S.recordPayloads&&W.input!==void 0)G.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));U(S,G,W),S.metrics.increment("weft.workflow.started"),S.metrics.increment("weft.dpmo.operations"),$(W)},*activity(W,$){let x=S.tracer.startSpan(`activity:${W.activityName}`,{attributes:{"weft.activity.name":W.activityName,"weft.activity.attempt":W.attempt}},A(S,W.workflowId));if(R(x,W.headers),S.recordPayloads&&W.input!==void 0)x.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));U(S,x,W);let G=Date.now();return yield*D(S,x,()=>$(W),()=>{S.metrics.record("weft.activity.duration",Date.now()-G),S.metrics.increment("weft.activity.attempts")})},*sleep(W,$){let x=S.tracer.startSpan("sleep",{attributes:{"weft.sleep.duration":W.duration}},A(S,W.workflowId));U(S,x,W),yield*D(S,x,()=>$(W))},*waitForSignal(W,$){let x=S.tracer.startSpan("waitForSignal",{attributes:{"weft.signal.name":W.signalName}},A(S,W.workflowId));return U(S,x,W),yield*D(S,x,()=>$(W))},async childWorkflow(W,$){let x=[],G=M(W.parentHeaders);if(G)x.push({context:{traceId:G.traceId,spanId:G.spanId,traceFlags:G.traceFlags}});let K=S.tracer.startSpan(`childWorkflow:${W.workflowType}`,{attributes:{"weft.child_workflow.type":W.workflowType,"weft.child_workflow.id":W.childWorkflowId,"weft.child_workflow.parent_id":W.workflowId},links:x},S.api.context.ROOT_CONTEXT);if(R(K,W.headers),S.recordPayloads&&W.input!==void 0)K.setAttribute("weft.payload.input",y(W.input,S.maxPayloadSize));return S.metrics.increment("weft.child_workflow.started"),f(S,K,()=>$(W))},signalReceived(W,$){let x=S.tracer.startSpan(`signal:received:${W.signalName}`,{attributes:{"weft.signal.name":W.signalName,"weft.signal.workflow_id":W.workflowId}});U(S,x,W),E(S,x,()=>$(W))}}}function J0(S){let{attributeExtractor:W,eventTarget:$,maxPayloadSize:x=v,metrics:G=new V,openTelemetryApi:K=T(),recordPayloads:J=!1,tracerName:H="weft",tracerVersion:X}=S??{},P=K,{trace:Q,SpanStatusCode:j}=P,b=Q.getTracer(H,X);return{api:P,trace:Q,SpanStatusCode:j,tracer:b,recordPayloads:J,maxPayloadSize:x,attributeExtractor:W,eventTarget:$,metrics:G,workflowSpans:new Map}}function $W(S){let W=J0(S),$=VS(W),x=h(W),G={...$,...x},K=DS(W);return{interceptor:G,metrics:W.metrics,...K}}export{m as serializeMetricsSnapshotForPrometheus,N as parseTraceParent,z as injectTraceParent,T as getOpenTelemetryApi,iS as generateTraceId,dS as generateSpanId,g as formatTraceParent,M as extractTraceParent,rS as createOpenTelemetryMetrics,$W as createObservabilityInterceptors,G0 as createMetricsCollectorExporter,V as MetricsCollector,_ as METRICS};
@@ -1,6 +1,6 @@
1
1
  import { compareStrings } from "./json-schema-utilities.js";
2
2
  import { externalApiPath } from "./route-model.js";
3
- const JSON_RPC_VERSION = "2.0", EVENT_DELIVER_METHOD = "weft.events.deliver", EVENTS_TERMINATED_METHOD = "weft.events.terminated", UNSUBSCRIBE_METHOD = "weft.workflows.unsubscribe", JSON_RPC_ID_SCHEMA = {
3
+ const JSON_RPC_VERSION = "2.0", EVENT_DELIVER_METHOD = "weft.events.deliver", EVENTS_TERMINATED_METHOD = "weft.events.terminated", WORKFLOW_SUBSCRIPTION_OPERATION_NAME = "weft.workflows.events", WORKFLOW_SUBSCRIPTION_REQUEST_METHOD = "weft.workflows.subscribe", UNSUBSCRIBE_METHOD = "weft.workflows.unsubscribe", JSON_RPC_ID_SCHEMA = {
4
4
  oneOf: [{ type: "string" }, { type: "number" }, { type: "null" }]
5
5
  }, SUBSCRIPTION_TERMINATION_REASON_SCHEMA = {
6
6
  enum: ["client-unsubscribed", "server-closed", "validation-failed"],
@@ -39,7 +39,7 @@ export function buildWebSocketMessages(operation, definitionSchemaToJsonSchema)
39
39
  [names.subscribeRequest]: {
40
40
  name: names.subscribeRequest,
41
41
  contentType: "application/json",
42
- payload: jsonRpcRequestPayload(operation.name, inputSchema),
42
+ payload: jsonRpcRequestPayload(subscriptionRequestMethod(operation), inputSchema),
43
43
  summary: `Subscribe to ${operation.name}.`
44
44
  },
45
45
  [names.subscribeAck]: {
@@ -149,6 +149,9 @@ export function buildOperationEntry(operation, channelName, kind) {
149
149
  function operationPrefix(operation) {
150
150
  return operation.name.replaceAll(".", "_");
151
151
  }
152
+ function subscriptionRequestMethod(operation) {
153
+ return operation.name === WORKFLOW_SUBSCRIPTION_OPERATION_NAME ? WORKFLOW_SUBSCRIPTION_REQUEST_METHOD : operation.name;
154
+ }
152
155
  function webSocketMessageNames(operation) {
153
156
  const prefix = operationPrefix(operation);
154
157
  return {
@@ -10,9 +10,14 @@
10
10
  *
11
11
  * @module server/attribute-filters
12
12
  */
13
- import type { AttributeFilter, SearchAttributeValue } from '../core/types.ts';
14
- type ParsedAttributeFilter = Omit<AttributeFilter, 'key'> & {
13
+ import type { AttributeFilterScalarValue } from '../core/types.ts';
14
+ type ParsedAttributeFilter = {
15
15
  key: string;
16
+ value?: AttributeFilterScalarValue | AttributeFilterScalarValue[] | undefined;
17
+ gt?: AttributeFilterScalarValue | undefined;
18
+ lt?: AttributeFilterScalarValue | undefined;
19
+ gte?: AttributeFilterScalarValue | undefined;
20
+ lte?: AttributeFilterScalarValue | undefined;
16
21
  };
17
22
  /**
18
23
  * Parse `attr.{name}={value}`, `attr.{name}.gt={value}`,
@@ -33,5 +38,5 @@ export declare function parseAttributeFilters(params: URLSearchParams): ParsedAt
33
38
  * preserved. The empty string stays a string (it would otherwise
34
39
  * coerce to `0` via `Number('')`).
35
40
  */
36
- export declare function inferAttributeValue(raw: string): SearchAttributeValue;
41
+ export declare function inferAttributeValue(raw: string): AttributeFilterScalarValue;
37
42
  export {};
@@ -6,7 +6,7 @@ export function parseAttributeFilters(params) {
6
6
  const rest = key.slice(5), dotIndex = rest.indexOf(".");
7
7
  if (dotIndex === -1) {
8
8
  const name = rest, existing = filterMap.get(name) ?? { key: name };
9
- existing.value = inferAttributeValue(value);
9
+ existing.value = appendExactAttributeValue(existing.value, inferAttributeValue(value));
10
10
  filterMap.set(name, existing);
11
11
  } else {
12
12
  const name = rest.slice(0, dotIndex), operator = rest.slice(dotIndex + 1), existing = filterMap.get(name) ?? { key: name };
@@ -27,6 +27,11 @@ export function parseAttributeFilters(params) {
27
27
  }
28
28
  return [...filterMap.values()];
29
29
  }
30
+ function appendExactAttributeValue(current, next) {
31
+ if (current === void 0)
32
+ return next;
33
+ return [...Array.isArray(current) ? current : [current], next];
34
+ }
30
35
  export function inferAttributeValue(raw) {
31
36
  if (raw === "true")
32
37
  return !0;
@@ -1,3 +1,4 @@
1
1
  import type { AuthorizationScope } from '../authorization-scope.ts';
2
+ import { type ConstantTimeApiKeyEntry } from './constant-time-api-key.ts';
2
3
  import type { AuthConfig, AuthResult } from './types.ts';
3
- export declare function tryAdmitApiKey(presentedKey: string, resolver: AuthConfig['resolveApiKeyPrincipal'], apiKeySet: Set<string> | null, defaultApiKeyScopes: ReadonlyArray<AuthorizationScope>): Promise<AuthResult | 'continue'>;
4
+ export declare function tryAdmitApiKey(presentedKey: string, resolver: AuthConfig['resolveApiKeyPrincipal'], apiKeyEntries: ReadonlyArray<ConstantTimeApiKeyEntry<undefined>> | null, defaultApiKeyScopes: ReadonlyArray<AuthorizationScope>): Promise<AuthResult | 'continue'>;
@@ -1,4 +1,7 @@
1
1
  import { principalFromApiKey } from "../principal.js";
2
+ import {
3
+ findConstantTimeApiKeyMatch
4
+ } from "./constant-time-api-key.js";
2
5
  function validateApiKeyPrincipalMethod(principal) {
3
6
  if (principal.method !== "api-key") {
4
7
  console.warn(`resolveApiKeyPrincipal returned principal with method "${principal.method}"; expected "api-key". Rejecting.`);
@@ -56,7 +59,7 @@ function deepFreezeApiKeyPrincipal(principal) {
56
59
  };
57
60
  return Object.freeze(frozen);
58
61
  }
59
- export async function tryAdmitApiKey(presentedKey, resolver, apiKeySet, defaultApiKeyScopes) {
62
+ export async function tryAdmitApiKey(presentedKey, resolver, apiKeyEntries, defaultApiKeyScopes) {
60
63
  if (resolver !== void 0) {
61
64
  let resolved;
62
65
  try {
@@ -69,7 +72,7 @@ export async function tryAdmitApiKey(presentedKey, resolver, apiKeySet, defaultA
69
72
  return { authenticated: !0, method: "api-key", principal: deepFreezeApiKeyPrincipal(resolved) };
70
73
  return { authenticated: !1, error: "No valid credentials provided" };
71
74
  }
72
- if (apiKeySet?.has(presentedKey)) {
75
+ if (apiKeyEntries !== null && findConstantTimeApiKeyMatch(presentedKey, apiKeyEntries) !== null) {
73
76
  const principal = principalFromApiKey({
74
77
  subject: "api-key-caller",
75
78
  scopes: defaultApiKeyScopes
@@ -0,0 +1,15 @@
1
+ export type ConstantTimeApiKeyEntry<T> = {
2
+ readonly digest: Uint8Array;
3
+ readonly value: T;
4
+ };
5
+ export type ConstantTimeApiKeyMatcher<T> = {
6
+ readonly entries: ReadonlyArray<ConstantTimeApiKeyEntry<T>>;
7
+ matches(presentedKey: string): boolean;
8
+ };
9
+ export declare function createConstantTimeApiKeyEntry<T>(key: string, value: T): ConstantTimeApiKeyEntry<T>;
10
+ export declare function createConstantTimeApiKeyMatcher(keys: ReadonlyArray<string>): ConstantTimeApiKeyMatcher<undefined>;
11
+ export declare function createConstantTimeApiKeyMatcher<T>(keys: ReadonlyArray<{
12
+ readonly key: string;
13
+ readonly value: T;
14
+ }>): ConstantTimeApiKeyMatcher<T>;
15
+ export declare function findConstantTimeApiKeyMatch<T>(presentedKey: string, entries: ReadonlyArray<ConstantTimeApiKeyEntry<T>>): ConstantTimeApiKeyEntry<T> | null;