eve 0.72.0 → 0.73.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 (285) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/src/channel/agent-description.d.ts +49 -9
  3. package/dist/src/channel/agent-description.js +1 -1
  4. package/dist/src/channel/invoke-tool.d.ts +26 -4
  5. package/dist/src/channel/invoke-tool.js +1 -1
  6. package/dist/src/channel/principal-identity.d.ts +9 -0
  7. package/dist/src/channel/principal-identity.js +1 -0
  8. package/dist/src/channel/prompt-queue.d.ts +31 -0
  9. package/dist/src/channel/prompt-queue.js +1 -0
  10. package/dist/src/channel/routes.d.ts +19 -4
  11. package/dist/src/channel/schedule.js +1 -1
  12. package/dist/src/channel/skill-files.d.ts +114 -0
  13. package/dist/src/channel/skill-files.js +1 -0
  14. package/dist/src/cli/commands/agent-instructions.js +1 -1
  15. package/dist/src/cli/commands/extension-init.js +1 -1
  16. package/dist/src/cli/commands/init-agent-workspace.js +1 -1
  17. package/dist/src/cli/commands/init-project.js +1 -1
  18. package/dist/src/cli/commands/init.js +1 -1
  19. package/dist/src/cli/dev/diagnostic-dump.js +1 -1
  20. package/dist/src/cli/dev/tui/blocks.d.ts +6 -0
  21. package/dist/src/cli/dev/tui/blocks.js +2 -2
  22. package/dist/src/cli/dev/tui/markdown.d.ts +5 -0
  23. package/dist/src/cli/dev/tui/markdown.js +2 -2
  24. package/dist/src/cli/dev/tui/transcript-parts.d.ts +4 -1
  25. package/dist/src/cli/dev/tui/transcript-parts.js +2 -2
  26. package/dist/src/cli/dev/tui/transcript.js +1 -1
  27. package/dist/src/compiled/.vendor-stamp.json +8 -8
  28. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  29. package/dist/src/compiled/@modelcontextprotocol/server/index.d.ts +68 -7
  30. package/dist/src/compiled/@workflow/core/capabilities.d.ts +33 -6
  31. package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +2 -0
  32. package/dist/src/compiled/@workflow/core/index.d.ts +1 -0
  33. package/dist/src/compiled/@workflow/core/index.js +2 -2
  34. package/dist/src/compiled/@workflow/core/private.js +1 -1
  35. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +6 -0
  36. package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
  37. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  38. package/dist/src/compiled/@workflow/core/serialization/codec.d.ts +8 -8
  39. package/dist/src/compiled/@workflow/core/serialization/compression.d.ts +13 -5
  40. package/dist/src/compiled/@workflow/core/serialization.d.ts +9 -9
  41. package/dist/src/compiled/@workflow/core/serialization.js +1 -1
  42. package/dist/src/compiled/@workflow/core/symbols.d.ts +2 -0
  43. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +2 -2
  44. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  45. package/dist/src/compiled/@workflow/core/workflow/index.d.ts +1 -0
  46. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  47. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  48. package/dist/src/compiled/@workflow/world/events.d.ts +11 -0
  49. package/dist/src/compiled/@workflow/world/hooks.d.ts +2 -0
  50. package/dist/src/compiled/@workflow/world/interfaces.d.ts +6 -0
  51. package/dist/src/compiled/@workflow/world-local/index.js +3 -3
  52. package/dist/src/compiled/@workflow/world-vercel/index.js +13 -13
  53. package/dist/src/compiled/_chunks/workflow/{attribute-changes-VaTKT4K8.js → attribute-changes-CSqvJx6j.js} +2 -2
  54. package/dist/src/compiled/_chunks/workflow/{dist-B7NC1c9-.js → dist-DmXynLVH.js} +1 -1
  55. package/dist/src/compiled/_chunks/workflow/dist-T5NnW-0k.js +3 -0
  56. package/dist/src/compiled/_chunks/workflow/helpers-BXCuoPUb.js +1 -0
  57. package/dist/src/compiled/_chunks/workflow/private-Dlf90Zvn.js +1 -0
  58. package/dist/src/compiled/_chunks/workflow/resume-hook-CvENCrxc.js +1 -0
  59. package/dist/src/compiled/_chunks/workflow/{run-DYKeqbob.js → run-8pLWuR2U.js} +6 -6
  60. package/dist/src/compiled/_chunks/workflow/serialization-vDozzDhh.js +16 -0
  61. package/dist/src/compiled/_chunks/workflow/sleep-BMqbraZM.js +1 -0
  62. package/dist/src/compiled/_chunks/workflow/wait-until-A344L2AG.js +1 -0
  63. package/dist/src/compiled/shadcn-registry/index.js +3408 -35163
  64. package/dist/src/compiler/artifacts.js +1 -1
  65. package/dist/src/compiler/compile-agent.js +1 -1
  66. package/dist/src/compiler/development-extensions.js +1 -1
  67. package/dist/src/compiler/extension-compatibility.d.ts +6 -6
  68. package/dist/src/compiler/extension-compatibility.js +1 -1
  69. package/dist/src/context/providers/session.js +1 -1
  70. package/dist/src/context/turn-principals.d.ts +12 -0
  71. package/dist/src/context/turn-principals.js +1 -0
  72. package/dist/src/evals/cli/eval-client.js +1 -1
  73. package/dist/src/evals/cli/eval.js +1 -1
  74. package/dist/src/evals/mock-model.js +1 -1
  75. package/dist/src/execution/cancelled-model-call-batch.js +1 -1
  76. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  77. package/dist/src/execution/invoke-tool.d.ts +6 -2
  78. package/dist/src/execution/invoke-tool.js +1 -1
  79. package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
  80. package/dist/src/execution/node-step.d.ts +1 -0
  81. package/dist/src/execution/node-step.js +1 -1
  82. package/dist/src/execution/publish-session-events.js +1 -1
  83. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
  84. package/dist/src/execution/sandbox/bindings/vercel-errors.d.ts +11 -0
  85. package/dist/src/execution/sandbox/bindings/vercel-errors.js +2 -1
  86. package/dist/src/execution/sandbox/bindings/vercel-tool-sessions.d.ts +7 -0
  87. package/dist/src/execution/sandbox/bindings/vercel-tool-sessions.js +1 -0
  88. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  89. package/dist/src/execution/sandbox/development-lazy-prewarm.js +1 -1
  90. package/dist/src/execution/sandbox/ensure.d.ts +14 -1
  91. package/dist/src/execution/sandbox/ensure.js +1 -1
  92. package/dist/src/execution/sandbox/prewarm.js +1 -1
  93. package/dist/src/execution/session/active-turn.d.ts +2 -1
  94. package/dist/src/execution/session/active-turn.js +1 -1
  95. package/dist/src/execution/session/entry.d.ts +10 -1
  96. package/dist/src/execution/session/entry.js +1 -1
  97. package/dist/src/execution/session/program.d.ts +4 -0
  98. package/dist/src/execution/session/program.js +1 -1
  99. package/dist/src/execution/session/timeout-control.d.ts +1 -2
  100. package/dist/src/execution/session/timeout-control.js +1 -1
  101. package/dist/src/execution/session/turn-control.d.ts +7 -0
  102. package/dist/src/execution/session/turn-control.js +1 -0
  103. package/dist/src/execution/session/turn-step.js +1 -1
  104. package/dist/src/execution/session/turn.d.ts +2 -0
  105. package/dist/src/execution/session/turn.js +1 -1
  106. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  107. package/dist/src/execution/tool-session/id.d.ts +22 -0
  108. package/dist/src/execution/tool-session/id.js +1 -0
  109. package/dist/src/execution/tool-session/sandbox.d.ts +22 -0
  110. package/dist/src/execution/tool-session/sandbox.js +1 -0
  111. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  112. package/dist/src/execution/tools/connection-tools.js +1 -1
  113. package/dist/src/harness/hitl/approvals.d.ts +1 -1
  114. package/dist/src/harness/hitl/approvals.js +1 -1
  115. package/dist/src/harness/hitl/delivery.d.ts +9 -2
  116. package/dist/src/harness/hitl/delivery.js +1 -1
  117. package/dist/src/harness/hitl/intake.js +1 -1
  118. package/dist/src/harness/model-call/usage.js +1 -1
  119. package/dist/src/harness/open-input-request.d.ts +8 -0
  120. package/dist/src/harness/open-input-request.js +1 -0
  121. package/dist/src/harness/session-machine/current.js +1 -1
  122. package/dist/src/harness/session-machine/transitions.js +1 -1
  123. package/dist/src/harness/tool-loop.js +1 -1
  124. package/dist/src/harness/types.d.ts +2 -0
  125. package/dist/src/internal/application/cache-metadata.js +1 -1
  126. package/dist/src/internal/application/compiled-artifacts.js +1 -1
  127. package/dist/src/internal/application/package.js +1 -1
  128. package/dist/src/internal/application/paths.js +1 -1
  129. package/dist/src/internal/application/runtime-compiled-artifacts-source.js +1 -1
  130. package/dist/src/internal/authored-definition/connection.js +1 -1
  131. package/dist/src/internal/authored-module-loader.js +1 -1
  132. package/dist/src/internal/authored-package-boundary.js +1 -1
  133. package/dist/src/internal/invocation/metadata.js +1 -1
  134. package/dist/src/internal/mcp/forwarded-principal-header.d.ts +31 -0
  135. package/dist/src/internal/mcp/forwarded-principal-header.js +1 -0
  136. package/dist/src/internal/mcp/published-tools.d.ts +9 -2
  137. package/dist/src/internal/mcp/published-tools.js +1 -1
  138. package/dist/src/internal/mcp/skills.d.ts +57 -0
  139. package/dist/src/internal/mcp/skills.js +1 -0
  140. package/dist/src/internal/mcp/streamable-http-server.d.ts +38 -6
  141. package/dist/src/internal/mcp/streamable-http-server.js +1 -1
  142. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  143. package/dist/src/internal/nitro/host/artifacts-config.js +1 -1
  144. package/dist/src/internal/nitro/host/build-application.js +1 -1
  145. package/dist/src/internal/nitro/host/build-extension.js +1 -1
  146. package/dist/src/internal/nitro/host/build-vercel-agent-summary.js +1 -1
  147. package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
  148. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  149. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  150. package/dist/src/internal/nitro/host/dev-runner.js +1 -1
  151. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -1
  152. package/dist/src/internal/nitro/host/skill-server-assets.d.ts +29 -0
  153. package/dist/src/internal/nitro/host/skill-server-assets.js +1 -0
  154. package/dist/src/internal/nitro/host/start-production-server.js +1 -1
  155. package/dist/src/internal/nitro/host/workspace-extensions.js +1 -1
  156. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  157. package/dist/src/internal/nitro/routes/channel-route-context.d.ts +4 -0
  158. package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
  159. package/dist/src/internal/vercel/build-agent-workspace.js +1 -1
  160. package/dist/src/internal/workflow/development-world-client.js +1 -1
  161. package/dist/src/internal/workflow/validate-world.js +1 -1
  162. package/dist/src/internal/workflow/vercel-world-defaults.js +1 -1
  163. package/dist/src/internal/workflow-bundle/builder-support.js +1 -1
  164. package/dist/src/internal/workflow-bundle/builder.js +1 -1
  165. package/dist/src/public/channels/chat-sdk/authorization.js +1 -1
  166. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +7 -1
  167. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  168. package/dist/src/public/channels/discord/defaults.d.ts +8 -7
  169. package/dist/src/public/channels/discord/discordChannel.d.ts +21 -1
  170. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  171. package/dist/src/public/channels/discord/index.d.ts +1 -1
  172. package/dist/src/public/channels/github/defaults.js +3 -3
  173. package/dist/src/public/channels/github/githubChannel.d.ts +4 -1
  174. package/dist/src/public/channels/github/state.d.ts +2 -1
  175. package/dist/src/public/channels/index.d.ts +1 -1
  176. package/dist/src/public/channels/linear/defaults.js +1 -1
  177. package/dist/src/public/channels/linear/linearChannel.d.ts +4 -1
  178. package/dist/src/public/channels/mcp.d.ts +26 -5
  179. package/dist/src/public/channels/mcp.js +1 -1
  180. package/dist/src/public/channels/slack/interactions.js +1 -1
  181. package/dist/src/public/channels/slack/slackChannel.d.ts +6 -0
  182. package/dist/src/public/channels/twilio/defaults.js +2 -4
  183. package/dist/src/public/channels/twilio/twilioChannel.d.ts +4 -1
  184. package/dist/src/public/definitions/channel.d.ts +1 -1
  185. package/dist/src/public/definitions/connections/mcp.d.ts +11 -0
  186. package/dist/src/public/sveltekit/dev-server.js +1 -1
  187. package/dist/src/runtime/cache-key.js +1 -1
  188. package/dist/src/runtime/connections/mcp-client.d.ts +18 -1
  189. package/dist/src/runtime/connections/mcp-client.js +1 -1
  190. package/dist/src/runtime/loaders/compile-metadata.js +1 -1
  191. package/dist/src/runtime/loaders/manifest.js +1 -1
  192. package/dist/src/runtime/loaders/module-map.js +1 -1
  193. package/dist/src/runtime/resolve-connection.js +1 -1
  194. package/dist/src/runtime/sandbox/prepared-artifacts.js +1 -1
  195. package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
  196. package/dist/src/runtime/sessions/runtime-session.d.ts +10 -0
  197. package/dist/src/runtime/sessions/runtime-session.js +1 -1
  198. package/dist/src/runtime/types.d.ts +2 -0
  199. package/dist/src/self-modification/config.d.ts +4 -63
  200. package/dist/src/self-modification/config.js +1 -1
  201. package/dist/src/self-modification/credentials.d.ts +1 -1
  202. package/dist/src/self-modification/deployed-sandbox.d.ts +14 -0
  203. package/dist/src/self-modification/deployed-sandbox.js +1 -0
  204. package/dist/src/self-modification/extension/config-schema.d.ts +2 -17
  205. package/dist/src/self-modification/extension/config-schema.js +1 -1
  206. package/dist/src/self-modification/extension/local-only.d.ts +1 -1
  207. package/dist/src/self-modification/extension/local-only.js +1 -1
  208. package/dist/src/self-modification/extension/subagents/agent/agent.d.ts +1 -1
  209. package/dist/src/self-modification/extension/subagents/agent/agent.js +1 -1
  210. package/dist/src/self-modification/extension/subagents/agent/instructions.js +3 -35
  211. package/dist/src/self-modification/extension/subagents/agent/tools/registry_add.d.ts +3 -31
  212. package/dist/src/self-modification/extension/subagents/agent/tools/registry_add.js +1 -1
  213. package/dist/src/self-modification/git-workspace.d.ts +1 -2
  214. package/dist/src/self-modification/git-workspace.js +1 -1
  215. package/dist/src/self-modification/github-publisher.d.ts +1 -1
  216. package/dist/src/self-modification/mode.d.ts +4 -4
  217. package/dist/src/self-modification/mode.js +1 -1
  218. package/dist/src/self-modification/proposal.js +1 -1
  219. package/dist/src/self-modification/remote/config-schema.d.ts +20 -0
  220. package/dist/src/self-modification/remote/config-schema.js +1 -0
  221. package/dist/src/self-modification/remote/config.d.ts +66 -0
  222. package/dist/src/self-modification/remote/config.js +1 -0
  223. package/dist/src/self-modification/remote/extension.d.ts +5 -0
  224. package/dist/src/self-modification/remote/extension.js +1 -0
  225. package/dist/src/self-modification/remote/production-registry-add.js +1 -0
  226. package/dist/src/self-modification/remote/subagents/agent/agent.d.ts +4 -0
  227. package/dist/src/self-modification/remote/subagents/agent/agent.js +1 -0
  228. package/dist/src/self-modification/remote/subagents/agent/instructions.d.ts +2 -0
  229. package/dist/src/self-modification/remote/subagents/agent/instructions.js +5 -0
  230. package/dist/src/self-modification/remote/subagents/agent/sandbox.d.ts +2 -0
  231. package/dist/src/self-modification/remote/subagents/agent/sandbox.js +1 -0
  232. package/dist/src/self-modification/remote/subagents/agent/tools/edit_file.d.ts +1 -0
  233. package/dist/src/self-modification/remote/subagents/agent/tools/edit_file.js +1 -0
  234. package/dist/src/self-modification/remote/subagents/agent/tools/publish.js +1 -0
  235. package/dist/src/self-modification/remote/subagents/agent/tools/registry_add.d.ts +32 -0
  236. package/dist/src/self-modification/remote/subagents/agent/tools/registry_add.js +1 -0
  237. package/dist/src/self-modification/remote/subagents/agent/tools/search_models.d.ts +1 -0
  238. package/dist/src/self-modification/remote/subagents/agent/tools/search_models.js +1 -0
  239. package/dist/src/self-modification/remote/subagents/agent/tools/search_registry.d.ts +1 -0
  240. package/dist/src/self-modification/remote/subagents/agent/tools/search_registry.js +1 -0
  241. package/dist/src/self-modification/sandbox.d.ts +1 -6
  242. package/dist/src/self-modification/sandbox.js +1 -1
  243. package/dist/src/self-modification/scaffold.js +1 -1
  244. package/dist/src/self-modification/setup.d.ts +6 -0
  245. package/dist/src/self-modification/setup.js +46 -48
  246. package/dist/src/self-modification/subagent-guidance.d.ts +15 -0
  247. package/dist/src/self-modification/subagent-guidance.js +29 -0
  248. package/dist/src/services/dev-client/request-headers.js +1 -1
  249. package/dist/src/setup/flows/model-source-change.js +1 -1
  250. package/dist/src/setup/integrations/self-modification/setup.js +1 -1
  251. package/dist/src/setup/project-resolution.js +1 -1
  252. package/dist/src/setup/scaffold/create/project.js +1 -1
  253. package/dist/src/setup/verified-remote-client.d.ts +3 -0
  254. package/dist/src/setup/verified-remote-client.js +1 -1
  255. package/dist/src/shared/framework-eve-server.js +1 -1
  256. package/dist/src/subagents/hitl-proxy.js +1 -1
  257. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  258. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  259. package/dist/src/tracing/invoke-tool-span.d.ts +1 -0
  260. package/docs/channels/chat-sdk.mdx +27 -0
  261. package/docs/channels/custom.mdx +5 -2
  262. package/docs/channels/discord.mdx +22 -0
  263. package/docs/channels/mcp.mdx +102 -4
  264. package/docs/channels/slack.mdx +1 -1
  265. package/docs/concepts/built-in-tools.md +2 -2
  266. package/docs/connections/mcp.mdx +30 -0
  267. package/docs/connections/overview.mdx +1 -1
  268. package/docs/evals/targets.mdx +5 -1
  269. package/docs/guides/self-modification.md +50 -3
  270. package/docs/tools/human-in-the-loop.md +14 -2
  271. package/docs/tutorial/guard-the-spend.mdx +1 -1
  272. package/package.json +25 -7
  273. package/dist/src/compiled/@workflow/core/runtime/vm-serde-bundle.generated.d.ts +0 -14
  274. package/dist/src/compiled/_chunks/workflow/dist-CaNNONeg.js +0 -3
  275. package/dist/src/compiled/_chunks/workflow/global-DKbOgrts.js +0 -1
  276. package/dist/src/compiled/_chunks/workflow/helpers-CP9TjeO8.js +0 -1
  277. package/dist/src/compiled/_chunks/workflow/logger-oqfblE3p.js +0 -14
  278. package/dist/src/compiled/_chunks/workflow/resume-hook-yq-NAdBu.js +0 -1
  279. package/dist/src/compiled/_chunks/workflow/serialization-APSKphN5.js +0 -3
  280. package/dist/src/compiled/_chunks/workflow/sleep-Ba8SExMt.js +0 -1
  281. package/dist/src/compiled/_chunks/workflow/wait-until-Dc9s3yyP.js +0 -1
  282. package/dist/src/self-modification/extension/production-registry-add.js +0 -1
  283. package/dist/src/self-modification/extension/subagents/agent/tools/publish.js +0 -1
  284. /package/dist/src/self-modification/{extension → remote}/production-registry-add.d.ts +0 -0
  285. /package/dist/src/self-modification/{extension → remote}/subagents/agent/tools/publish.d.ts +0 -0
@@ -67,11 +67,14 @@ Each route receives these operation surfaces:
67
67
  - `attachSession(sessionId)` creates an I/O-free handle pinned to one durable session ID.
68
68
  - `to(channel, target).send(message, options)` hands work to another authored channel.
69
69
  - `params`, `waitUntil`, and `requestIp` provide request metadata and lifetime control.
70
- - `describe()` returns the agent's name, description, and the compiled tools a caller can run outside a turn, with their JSON schemas, sorted by name. It carries no paths, config, or other inspection detail, so a channel can publish it to its callers. Tools that need a turn (framework tools, workflow and provider tools, tools without `execute`) and tools added by dynamic resolvers or subagents are left out.
71
- - `invokeTool(name, input, { auth })` runs one of those tools as `auth`, outside any conversation: no model, turn, or workflow run. Each call gets its own session. Authored state starts from its initial value and is not kept, and a sandbox the tool opens is deleted when the call ends. It resolves to `completed` with the tool's output, or to `invalid-input`, `denied`, `failed`, `approval-required` when the tool's approval policy asks a person (the tool did not run), or `authorization-required` with the connections the tool needs a sign-in to.
70
+ - `describe()` returns the agent's name, description, the compiled tools a caller can run outside a turn, with their JSON schemas, and the compiled skills, each with its `name` and `description`, sorted by name. It reads the compiled manifest only, never a skill file, and carries no other paths, config, or inspection detail, so a channel can publish it to its callers. Tools that need a turn (framework tools, workflow and provider tools, tools without `execute`) and tools and skills added by dynamic resolvers or subagents are left out.
71
+ - `invokeTool(name, input, { auth, key })` runs one of those tools as `auth`, outside any conversation: no model, turn, or workflow run. Authored state starts from its initial value and is not kept. Without `key`, each call gets its own session, and a sandbox the tool opens is deleted when the call ends. With `key` (1 to 512 characters), calls from the same `auth` principal with the same key share a session id and a sandbox, which is kept between calls; this needs Vercel Sandbox or just-bash, and an authenticated `auth` (a keyed call from the anonymous principal is `denied`); see [MCP tool sessions](./mcp#tool-sessions). When a trusted forwarder asserted `auth`, pass the principal your route verified as `forwardedBy`: it is part of the session, so one user reached through two forwarders gets two sessions. It resolves to `completed` with the tool's output, or to `invalid-input`, `denied`, `failed`, `approval-required` when the tool's approval policy asks a person (the tool did not run), or `authorization-required` with the connections the tool needs a sign-in to.
72
72
 
73
73
  A direct call doesn't go through the AI SDK, so AI SDK telemetry integrations never see it. Conversation tool calls do: an integration that an `agent/instrumentation/*.ts` module registers with `registerTelemetry()` from `ai` receives `onToolExecutionStart` and `onToolExecutionEnd` for each of them. A direct call is traced by eve itself instead. It gets an `execute_tool` span under the caller's trace and emits `tool.call.started` and `tool.call.completed` to instrumentation. Over MCP, the caller's trace comes from the request's `_meta` trace context (see [Trace context](./mcp#trace-context)).
74
74
 
75
+ - `listSkillFiles(skill)` resolves to the skill's regular files, each with its `path` under the skill root and its `size` in bytes, sorted by path. It rejects a skill the agent does not have.
76
+ - `readSkill(skill, path?)` resolves to one skill file's raw bytes as a `Uint8Array`; decode text yourself, for example with `new TextDecoder().decode(bytes)`. `path` is relative to the skill root, such as `references/api.md`, and defaults to the skill's `SKILL.md`. It rejects absolute paths, paths with `.`, `..`, or empty segments, files the skill does not list, and files over 512 KiB.
77
+
75
78
  Event handlers receive `(eventData, channel, ctx)`. `ctx.session.id` identifies
76
79
  the exact session, while `channel.continuation` exposes the current address and
77
80
  `alias()` when this channel needs to add another address. `session.failed`
@@ -94,6 +94,28 @@ Typing fires on `turn.started` and `actions.requested`, but only when a bot toke
94
94
 
95
95
  HITL renders as Discord components. Confirmations and options become buttons, `display: "select"` becomes a string select, and freeform input becomes a button that opens a modal. When the user responds, the parked session (paused awaiting input) resumes.
96
96
 
97
+ A press, select, or modal submission answers as the Discord user who made it, with the same `defaultDiscordAuth` principal a command from them gets by default. Approval response policies compare against that principal. Approvals are requester-only by default, so only the person whose command asked can approve. `onInputResponse(ctx, interaction)` decides the answer's `auth`: return `{ auth }` to accept it, or `null` (or throw) to drop it and keep the request pending. `ctx.defaultAuth` is the presser's `defaultDiscordAuth`; it identifies them but doesn't authorize them by itself.
98
+
99
+ If you customize `onCommand`, eve drops every press and submission until you also set `onInputResponse`, and logs a warning saying so. The default Discord principal wouldn't match the principals your `onCommand` returns, so a requester-only approval would refuse the requester. It would also let someone your `onCommand` turns away answer open approvals. Give both hooks the same mapping and gating:
100
+
101
+ ```ts
102
+ import { discordChannel } from "eve/channels/discord";
103
+
104
+ const auth = (interaction: { user: { id: string } }) => ({
105
+ auth: {
106
+ principalId: `user:${interaction.user.id}`,
107
+ principalType: "user" as const,
108
+ authenticator: "discord",
109
+ attributes: {},
110
+ },
111
+ });
112
+
113
+ export default discordChannel({
114
+ onCommand: (_ctx, interaction) => auth(interaction),
115
+ onInputResponse: (_ctx, interaction) => auth(interaction),
116
+ });
117
+ ```
118
+
97
119
  ### Proactive sessions
98
120
 
99
121
  Start a session without an inbound interaction through `to(discord, target).send(message, { auth })` from a schedule `run` handler, or `ctx.to(discord, target).send(message, { auth })` from another channel. The proactive target shape is `{ channelId, conversationId?, initialMessage? }`. Either path needs a bot token, supplied by Connect or `DISCORD_BOT_TOKEN`.
@@ -3,7 +3,7 @@ title: "MCP Channel"
3
3
  description: "Publish an eve agent as an MCP server with auth support."
4
4
  ---
5
5
 
6
- The MCP channel lets clients such as Claude Code delegate durable work to an eve agent through four tools: `agent_start`, `agent_get`, `agent_update`, and `agent_cancel`. It can also publish the agent's own tools, so a client calls them directly; see [Publish the agent's tools](#publish-the-agents-tools).
6
+ The MCP channel lets clients such as Claude Code delegate durable work to an eve agent through four tools: `agent_start`, `agent_get`, `agent_update`, and `agent_cancel`. It can also publish the agent's own tools, so a client calls them directly, and its skills, so a client reads them; see [Publish the agent's tools](#publish-the-agents-tools) and [Publish the agent's skills](#publish-the-agents-skills).
7
7
 
8
8
  Use an [MCP connection](../connections/mcp) instead when your eve agent needs to call someone else's MCP server.
9
9
 
@@ -225,9 +225,9 @@ export default mcpChannel({
225
225
  });
226
226
  ```
227
227
 
228
- `tools/list` returns the `agent_*` tools first, then the agent's tools in name order with their input and output JSON schemas. Framework tools, workflow and provider tools, tools without `execute`, and tools added by dynamic resolvers or subagents are not published. While `agent` is on, an agent tool named `agent_start`, `agent_get`, `agent_update`, or `agent_cancel` is not published, and eve logs a warning. With `agent: false`, the channel sends no `agent_*` instructions. Turning off both `agent` and `tools` throws.
228
+ `tools/list` returns the `agent_*` tools first, then the agent's tools in name order with their input and output JSON schemas. Framework tools, workflow and provider tools, tools without `execute`, and tools added by dynamic resolvers or subagents are not published. While `agent` is on, an agent tool named `agent_start`, `agent_get`, `agent_update`, or `agent_cancel` is not published, and eve logs a warning. With `agent: false`, the channel sends no `agent_*` instructions. Turning off `agent`, `tools`, and `skills` all at once throws, since the channel would publish nothing.
229
229
 
230
- Each `tools/call` checks the arguments against the tool's input schema, then runs the tool as the route-authenticated caller, with no model, turn, or workflow run. Every caller the channel's `auth` admits can call these tools, outside the agent's instructions, so review what becomes callable before you turn this on. Each call gets its own session:
230
+ Each `tools/call` checks the arguments against the tool's input schema, then runs the tool as the route-authenticated caller, or as a [forwarded user](#forwarded-principals), with no model, turn, or workflow run. Every caller the channel's `auth` admits can call these tools, outside the agent's instructions, so review what becomes callable before you turn this on. Unless the call joins a [tool session](#tool-sessions), it gets its own session:
231
231
 
232
232
  - Authored state starts from its initial value, and updates are not kept.
233
233
  - A sandbox the tool opens is deleted when the call ends.
@@ -238,7 +238,7 @@ A tool that cannot finish over MCP returns an error result with `isError: true`
238
238
  | Code | When |
239
239
  | ------------------------ | ------------------------------------------------------------------------------------------------ |
240
240
  | `invalid_input` | The tool rejected its input. |
241
- | `denied` | The tool's approval policy denied the call. |
241
+ | `denied` | The tool's approval policy denied the call, or an anonymous caller sent a tool session key. |
242
242
  | `approval_required` | The approval policy asks a person. The tool did not run; call it from a conversation instead. |
243
243
  | `authorization_required` | The tool needs a sign-in to a connection first. Sign in from a conversation, then call it again. |
244
244
  | `internal` | The tool failed. The message carries an error id that matches the server logs. |
@@ -249,6 +249,104 @@ MCP clients send W3C trace context in each request's `params._meta`, not in HTTP
249
249
 
250
250
  `_meta.baggage` is never read. A caller cannot choose the trace audience, session lineage, or content capture: those come from the channel and your `tracePolicy`, as they do for conversations. The `execute_tool` span records the call's arguments and result only when that content decision allows it, and never records exception text.
251
251
 
252
+ ### Forwarded principals
253
+
254
+ A router that calls the channel on behalf of its own users, such as another eve agent's [`forwardPrincipal` connection](../connections/mcp#forward-the-caller-to-an-eve-agent), can name the user in the `eve-forwarded-principal` header: unpadded base64url of UTF-8 JSON `{ current, initiator? }`, at most 16 KiB. eve accepts the header only when `trustedForwarders` is set, and only from a route-authenticated forwarder the predicate accepts:
255
+
256
+ ```ts title="agent/channels/mcp.ts"
257
+ import { vercelOidc, vercelSubject } from "eve/channels/auth";
258
+ import { mcpChannel } from "eve/channels/mcp";
259
+
260
+ export default mcpChannel({
261
+ auth: [vercelOidc()],
262
+ tools: true,
263
+ // Only the router deployment may name the user a tool runs as.
264
+ trustedForwarders: (forwarder) =>
265
+ forwarder.subject === vercelSubject({ teamSlug: "acme", projectName: "router" }),
266
+ });
267
+ ```
268
+
269
+ The predicate receives the verified forwarder and the principals it asserts, as the [eve channel](./eve)'s `trustedForwarders` does, so match the forwarder precisely; see [Accepting forwarded identity](../guides/auth-and-route-protection#accepting-forwarded-identity-from-another-deployment). A published tool called with an accepted header runs as the forwarded user: `ctx.session.auth.current` is that user, `ctx.session.auth.initiator` is the asserted initiator or that user, and both carry the forwarder's `principalId` in the `eve:forwarded-by` attribute. The `agent_*` tools still act as the route-authenticated caller.
270
+
271
+ | Request | Response |
272
+ | ------------------------------------------------------ | ------------------------ |
273
+ | No header | Runs as the route caller |
274
+ | Malformed or over 16 KiB | `400` |
275
+ | The predicate refuses the forwarder or what it asserts | `403` |
276
+ | The forwarder is anonymous (`none()`) | `403` |
277
+ | The channel has no `trustedForwarders` | `403` |
278
+ | The predicate throws | `500` |
279
+
280
+ ### Tool sessions
281
+
282
+ A tool session lets several `tools/call` requests share one sandbox, so a file one call writes is there for the next. With `tools: true`, the channel advertises the `dev.eve/tool-sessions` extension in `capabilities.extensions` of `server/discover`. A client joins a session by declaring the same extension in the request's `io.modelcontextprotocol/clientCapabilities` and sending a key of 1 to 512 characters in `_meta["dev.eve/tool-session"]`:
283
+
284
+ ```json
285
+ {
286
+ "jsonrpc": "2.0",
287
+ "id": 1,
288
+ "method": "tools/call",
289
+ "params": {
290
+ "name": "write_note",
291
+ "arguments": { "text": "Feed Biscuit at 18:00." },
292
+ "_meta": {
293
+ "dev.eve/tool-session": "alice-front-desk",
294
+ "io.modelcontextprotocol/protocolVersion": "2026-07-28",
295
+ "io.modelcontextprotocol/clientInfo": { "name": "front-desk", "version": "1.0.0" },
296
+ "io.modelcontextprotocol/clientCapabilities": {
297
+ "extensions": { "dev.eve/tool-sessions": {} }
298
+ }
299
+ }
300
+ }
301
+ }
302
+ ```
303
+
304
+ eve derives the session id from the principal the call runs as (the route-authenticated caller, or a [forwarded user](#forwarded-principals) together with the verified router that forwarded them) and the key, so calls from the same principal with the same key share the session, and another caller who sends the same key gets a different one. That holds for forwarded users too: two users forwarded with the same key, or one user forwarded by two routers, get separate sessions. The router counted is the one the channel's `auth` verified, never one named in the forwarded principal. A key from a client that did not declare the extension is ignored, and the call gets its own session. Clients on the 2025-11-25 protocol send no per-request capabilities, so they always get their own session.
305
+
306
+ Tool sessions need an authenticated caller. With `auth: none()` every request is the same anonymous principal, so a key alone would name the session and anyone who knew it could read what another client left in the sandbox. A keyed call from an anonymous caller is therefore denied with the `denied` error code before anything runs; unkeyed anonymous calls still get a one-off session.
307
+
308
+ In a tool session:
309
+
310
+ - The sandbox opens on the first `ctx.getSandbox()` and is kept for later calls with the same key. Concurrent first calls share one sandbox.
311
+ - The sandbox belongs to the agent's current sandbox definition. A deploy that changes it (the template, its snapshot, or the open options in `sandbox.ts` and its resources) starts a fresh, empty sandbox for the same key; the old one expires as below.
312
+ - `ctx.session.id` is the same for every call with the key.
313
+ - Traces still show each call as its own run. Its `agent.run.id` and `gen_ai.conversation.id` are a fresh id for that call, not `ctx.session.id`, so traces do not link calls that share a key.
314
+ - Authored state still starts from its initial value on every call, and updates are not kept. Keep data that must outlive a call in the sandbox.
315
+ - Calls may still run in parallel, and nothing orders them.
316
+
317
+ Tool sessions need a sandbox provider that finds the session's sandbox again: Vercel Sandbox or just-bash. On another provider, a call with a key fails with a `Sandbox provider "<name>" cannot keep a sandbox between invokeTool calls` error when the tool opens its sandbox. Tools that never open a sandbox still run. just-bash keeps its sandboxes on the local disk, so on Vercel Functions a just-bash tool session lasts only as long as the function instance.
318
+
319
+ A tool session has no end, so eve bounds how long its sandbox is kept. On Vercel Sandbox, a tool-session sandbox's saved filesystem expires a day after its last use, and each call that resumes it restarts that day. The next call with the key after that replaces it with a fresh, empty sandbox. If two calls with the key find the expired filesystem at the same time, each can replace the sandbox, and files the first one writes can be lost. Vercel only keeps the latest snapshot of the sandbox. Tool sessions use this one-day expiry whatever `snapshotExpiration` `sandbox.ts` sets; sessions that conversations start keep the authored setting.
320
+
321
+ just-bash keeps tool-session sandboxes on the local disk, and nothing removes them.
322
+
323
+ ## Publish the agent's skills
324
+
325
+ Set `skills: true` to serve the agent's skills as [SEP-2640](https://modelcontextprotocol.io/seps/2640) skills under `skill://`, so a client that calls the agent's tools can also read the workflow knowledge behind them:
326
+
327
+ ```ts title="agent/channels/mcp.ts"
328
+ import { localDev } from "eve/channels/auth";
329
+ import { mcpChannel } from "eve/channels/mcp";
330
+
331
+ export default mcpChannel({
332
+ auth: localDev(),
333
+ skills: true,
334
+ tools: true,
335
+ });
336
+ ```
337
+
338
+ The channel declares the `io.modelcontextprotocol/skills` extension and serves `skills/list`, `skills/get`, `resources/list`, `resources/templates/list`, `resources/read`, and `resources/directory/read`. Every caller the channel's `auth` admits can read every served skill. Each skill's entry is `skill://<name>/SKILL.md`, and its `resources` list every file with its `size` in bytes and a `sha256:` digest. `resources/list` returns one resource per served skill, its `SKILL.md`; the other files of a skill are reachable through `resources/directory/read` and the entry's `resources`, not listed there. `resources/directory/read` lists every directory of a skill, including empty ones, which return no children. `resources/templates/list` is always empty. `resources/read` returns UTF-8 text as `text` and anything else, such as images or Latin-1 files, as a base64 `blob`, byte for byte. Every skill and resource method carries the same cache hint as `tools/list`: private, for 5 minutes. The server's `resources` capability declares `listChanged: false`; eve never sends `notifications/resources/list_changed`, so a client re-reads after the hint expires. For each compiled artifact version, eve builds each skill's catalog snapshot once, listing its files and reading them to compute their sizes and digests. Only the served `SKILL.md` is kept in memory; `resources/read` reads other files from storage again, and a file removed since the snapshot is an unknown resource (`-32602`).
339
+
340
+ A skill is served whole or not at all. eve leaves a skill out of every method, and logs one warning naming the reason, when:
341
+
342
+ - its `SKILL.md` frontmatter does not meet the Agent Skills format: a `name` of up to 64 lowercase letters, digits, and single hyphens, and a `description` of 1 to 1024 characters;
343
+ - it has more than 512 files or more than 16 MiB in total;
344
+ - any of its files is over 512 KiB, unreadable, or has a path that cannot be a `skill://` URI.
345
+
346
+ A `SKILL.md` whose frontmatter already names the skill and has a `description` is served as authored. Otherwise, as for flat `.md` and module skills, eve serves it with frontmatter that carries the skill's name and description, and the digest describes that served document. Skills added by dynamic resolvers or subagents are not served.
347
+
348
+ Production builds ship skill files as eve-owned server assets, so they count toward the deployed function's size. `eve build` also drops Nitro's default `server` server-asset entry, the one that would bundle the app's `assets/` directory; eve reads only its own asset bases, and a route that reads `assets:server` storage finds it empty in production.
349
+
252
350
  ## Invocation ownership
253
351
 
254
352
  Every MCP operation reruns the configured auth policy. With authenticated policies, an invocation belongs to the principal that started it; knowing its ID is not sufficient. Bearer tokens are not stored with the invocation or forwarded to the agent's tools.
@@ -167,7 +167,7 @@ Only the first available handler runs. A message hook returning `null` drops the
167
167
 
168
168
  Message hooks only decide whether and how a message starts a turn. They don't render anything, so replacing one never changes what people see: eve still acknowledges the message, shows progress, and posts the reply. To change what the agent posts, add [renderers](#customize-rendering).
169
169
 
170
- `onInteraction(action, ctx)` separately handles user-owned `block_actions` callbacks. eve-owned HITL buttons and modal submissions go through `onInputResponse(ctx, submission)` instead. eve attaches the triggering Slack user id to the same model message as its text, preserving speaker attribution without profile lookups.
170
+ `onInteraction(action, ctx)` separately handles user-owned `block_actions` callbacks. eve-owned HITL buttons and modal submissions go through `onInputResponse(ctx, submission)` instead. `action.triggerId` carries the click's `trigger_id`, so a button can open a modal with `ctx.slack.request("views.open", { trigger_id, view })`. Slack accepts the id for about 3 seconds. eve attaches the triggering Slack user id to the same model message as its text, preserving speaker attribution without profile lookups.
171
171
 
172
172
  Use `onShortcut(shortcut, ctx)` for message shortcuts and global shortcuts configured under **Interactivity & Shortcuts** in your Slack app. The handler receives the shortcut callback ID, user, workspace, and trigger ID. Message shortcuts also include the selected message and channel. The context exposes workspace-scoped Slack API access because global shortcuts have no channel or message. eve acknowledges shortcut requests immediately and keeps their handlers alive in the background.
173
173
 
@@ -298,9 +298,9 @@ export default disableTool();
298
298
 
299
299
  `connection_search` and `connection_execute` give the model every tool from the agent's [connections](../connections) without adding each tool to the model's tool list. eve adds both when the agent has a static connection or a dynamic connection resolver, even when `defaultTools` is `false`, so there is no add command.
300
300
 
301
- - `connection_search({ query?, connection?, signIn?, limit?, offset? })` returns matching tools with their connection, name, description, and a TypeScript signature rendered from the tool's schemas. Omit `query` to list every tool, or pair it with `connection` to list one connection's tools. A plain search never asks the user to sign in. For a connection the user has not signed in to, the result tells the model that sign-in is needed before its tools can be listed: the connection appears under `unavailable` with `requiresSignIn: true` and an error that points to `signIn: true`. Tools from the other connections are still returned.
301
+ - `connection_search({ query?, connection?, signIn?, limit?, offset? })` returns matching tools with their connection, name, description, and a TypeScript signature rendered from the tool's schemas. Omit `query` to list every tool, or pair it with `connection` to list one connection's tools. A plain search never asks the user to sign in. For a connection whose server will not list its tools until the user signs in, the result tells the model that sign-in is needed: the connection appears under `unavailable` with `requiresSignIn: true` and an error that points to `signIn: true`. Tools from the other connections are still returned.
302
302
  - `connection_search({ connection, signIn: true, query? })` asks the user to sign in to that one connection when they have not yet, then returns its matching tools. Without `connection` it fails, so the user is asked about one service at a time.
303
- - `connection_execute({ connection, tool, input })` checks `input` against the tool's input schema, calls the tool, and returns its result. When the connection needs the user's authorization, it also asks the user to sign in and the call parks until sign-in completes. The stream reports the call as a nested action named `<connection>__<tool>`, such as `linear__list_issues`, whose `parentCallId` is the `connection_execute` call id.
303
+ - `connection_execute({ connection, tool, input })` checks `input` against the tool's input schema, calls the tool, and returns its result. When the server asks for the user's authorization, it also asks the user to sign in and the call parks until sign-in completes. The stream reports the call as a nested action named `<connection>__<tool>`, such as `linear__list_issues`, whose `parentCallId` is the `connection_execute` call id.
304
304
 
305
305
  The definitions of both tools never change during a session. eve lists connection names and descriptions in append-only context messages rather than in the system prompt, so finding a tool, signing in, or resolving a dynamic connection keeps the cached prompt prefix.
306
306
 
@@ -44,6 +44,17 @@ For OAuth-backed MCP servers, use the shared [Vercel Connect flow](../connection
44
44
 
45
45
  `connect("...")` is user-scoped by default and requires an authenticated user on the active eve session. Use `connect({ connector, principalType: "app" })` when the server should act as the agent instead. The connections overview covers connector setup, session requirements, app and user scope, callback behavior, and troubleshooting.
46
46
 
47
+ ## When eve asks for sign-in
48
+
49
+ eve asks the user to sign in only when the MCP server asks for it. When a connection has `auth` but no token yet, because its `getToken` throws `ConnectionAuthorizationRequiredError`, eve connects without an `Authorization` header and lists the server's tools. Any other error from `getToken` still fails the connection.
50
+
51
+ - **The server rejects every request without a token.** Most hosted OAuth servers, such as Linear, GitHub, and Notion, answer `initialize` or `tools/list` with HTTP `401`. A plain `connection_search` lists the connection under `unavailable` with `requiresSignIn: true`. Calling `connection_search({ connection, signIn: true })` or any of its tools with `connection_execute` asks the user to sign in.
52
+ - **The server lists tools without a token.** `connection_search` returns its tools with no prompt, and `connection_execute` runs tools the server answers anonymously. Sign-in starts only when a tool call comes back with HTTP `401`, or with an error result that carries a `WWW-Authenticate` challenge in `_meta["mcp/www_authenticate"]`.
53
+
54
+ After the user signs in, the call that asked for it runs again. eve reconnects with the token and reloads the tool list, which may now include tools the server hides from anonymous callers. A connection that already has a token sends it on every request, as before.
55
+
56
+ A server that leaves protected tools out of its anonymous `tools/list` never triggers sign-in, because the model cannot find those tools. Servers that support anonymous use should list every tool and refuse the protected calls.
57
+
47
58
  ## Static tokens and headers
48
59
 
49
60
  MCP connections accept the shared connection `auth` and `headers` options. Use `auth.getToken` for a bearer token, `headers` for another scheme, and resolver functions when credentials or routing depend on the caller. See [Static-token auth](../connections#static-token-auth), [Headers](../connections#headers), and [Per-caller auth and headers](../connections#per-caller-auth-and-headers) for the canonical examples and token-lifecycle behavior.
@@ -148,6 +159,25 @@ Return `"user-approval"` (or `true`) to pause for a person and `"not-applicable"
148
159
 
149
160
  [Human-in-the-loop](/docs/human-in-the-loop#approvals) covers the full set of statuses, how `approvedTools` and `session.auth` factor in, and how a gated call pauses and resumes durably.
150
161
 
162
+ ## Forward the caller to an eve agent
163
+
164
+ When the server is another eve agent's [`mcpChannel`](../channels/mcp), set `forwardPrincipal: true` so its published tools run as the user of the current turn instead of as this deployment:
165
+
166
+ ```ts title="agent/connections/specialist.ts"
167
+ import { defineMcpClientConnection } from "eve/connections";
168
+
169
+ export default defineMcpClientConnection({
170
+ url: "https://specialist.example.com/eve/v1/mcp",
171
+ description: "The specialist agent's tools.",
172
+ headers: { authorization: `Bearer ${process.env.SPECIALIST_TOKEN}` },
173
+ forwardPrincipal: true,
174
+ });
175
+ ```
176
+
177
+ eve sends the turn's user, and its initiator when that differs, in the `eve-forwarded-principal` header on every request. A turn with no caller, or an anonymous one, sends no header. The server must trust this deployment's route-authenticated identity in `trustedForwarders`; otherwise it refuses the request with `403`. See [Forwarded principals](../channels/mcp#forwarded-principals). A request carrying the header fails rather than follow a redirect, so the header never reaches another host. A principal over 16 KiB encoded fails the call before it is sent; trim its attributes.
178
+
179
+ Authenticate the connection as this deployment, with a stable service credential, like the token above, not with user-scoped `connect("...")` or a per-caller resolver. eve resolves `auth` and `headers` once when it opens the client, but one client can serve turns from different users in a shared session, so the header is what names the user on each request. The server trusts the forwarder by that service identity, and grants the user's own access to downstream services itself.
180
+
151
181
  ## Control result size
152
182
 
153
183
  `connection_execute` returns an MCP tool's `structuredContent` when the server sends it. Otherwise it returns the result's text, parsed as JSON when the tool declares no output schema. Image, audio, and resource content reaches the model as file parts, and a result with `isError: true` fails the call with its text. MCP connections do not expose a per-result transform equivalent to an authored tool's [`toModelOutput`](/docs/tools#shape-what-the-model-sees-with-tomodeloutput).
@@ -227,7 +227,7 @@ export default defineMcpClientConnection({
227
227
 
228
228
  Use the connector UID returned by `vercel connect create`; the display name passed to `--name` is not the UID. `connect("linear/myagent")` is shorthand for a user-scoped interactive OAuth connection: eve resolves a token for the active user before each tool call, emits `authorization.required` when that user has not authorized yet, and resumes the parked turn after the callback completes.
229
229
 
230
- Discovering tools never posts a sign-in prompt for a service the answer does not need. A plain `connection_search` lists connections the user has not authorized yet under `unavailable` with `requiresSignIn: true`. Most OAuth MCP servers reject even tool listing without the user's token, so the model asks for sign-in explicitly, one connection at a time, with `connection_search({ connection, signIn: true })`, which returns that connection's tools once the user signs in. Calling a tool with `connection_execute` on a connection the user has not authorized also asks for sign-in.
230
+ Discovering tools never posts a sign-in prompt for a service the answer does not need. Before the user signs in, eve connects to an MCP server without a token, so a server that lists its tools anonymously is searched like any other connection, and sign-in starts only when one of its tools asks for it (see [When eve asks for sign-in](/docs/connections/mcp#when-eve-asks-for-sign-in)). Most OAuth MCP servers reject even tool listing without the user's token. A plain `connection_search` lists those connections under `unavailable` with `requiresSignIn: true`, and the model asks for sign-in explicitly, one connection at a time, with `connection_search({ connection, signIn: true })`, which returns that connection's tools once the user signs in. Calling a tool with `connection_execute` on such a connection also asks for sign-in.
231
231
 
232
232
  A sign-in holds the turn open until the user connects, the turn is cancelled, or the user sends another message. That message steers the turn: eve cancels the sign-in, reports `authorization.completed` with `outcome: "declined"`, and the model reads the message next. Messages from other people in a shared thread wait until the turn ends, and the completed sign-in resumes the turn as the person who started it.
233
233
 
@@ -36,7 +36,11 @@ These helpers handle the session protocol, retries, and event collection for the
36
36
 
37
37
  ## Authentication
38
38
 
39
- Local targets send no auth: `eve eval` owns the dev server it boots. For a remote `--url`, eve gets the expected Vercel owner and project from `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` when both are set. Otherwise it reads `.vercel/project.json`. Eve then asks Vercel to resolve the exact HTTPS origin and sends ambient credentials only when the project IDs match. An arbitrary URL remains anonymous.
39
+ Local targets send no auth: `eve eval` owns the dev server it boots.
40
+
41
+ For a remote `--url`, eve gets the expected Vercel owner and project from `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` when both values are nonblank. Otherwise it reads the local Vercel project link: `.vercel/project.json`, or the matching project in `.vercel/repo.json` for a linked monorepo.
42
+
43
+ With a project reference, eve looks up the exact HTTPS origin under that owner, regardless of the Vercel CLI's current team. The deployment's project ID must match before eve sends ambient credentials. Without a project reference, eve verifies the URL under the CLI's current scope. URLs that Vercel cannot verify remain anonymous.
40
44
 
41
45
  After verification, eve sends the available Vercel credentials:
42
46
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: "Self-Modification"
3
- description: "Ask your agent to update its own instructions, tools, skills, and other authored files during local development."
3
+ description: "Ask your agent to update its own authored files during local development, or let a deployed agent propose changes as draft pull requests."
4
4
  ---
5
5
 
6
6
  When `eve dev` starts a local server, it mounts the bundled self-modification extension by default. Ask your agent to change its instructions, tools, skills, or other files under `agent/`; eve delegates the source work to the `self-modification__agent` subagent. Connecting to an existing server with `eve remote connect --url <url>` does not add the bundled extension to that server.
7
7
 
8
- The bundled extension is for local development and is not included in production builds.
8
+ The bundled extension is `eve/self-modification/local`. It is for local development and is not included in production builds. To let a deployed agent propose source changes, mount the separate [`eve/self-modification/remote`](#propose-changes-from-a-deployed-agent) extension.
9
9
 
10
10
  ```bash
11
11
  eve dev
@@ -27,7 +27,54 @@ The subagent uses your agent's model by default. To give it a different model or
27
27
  Switch the self-modification subagent to openai/gpt-6-sol with low reasoning.
28
28
  ```
29
29
 
30
- The first time, this creates `agent/extensions/self-modification/extension.ts` with those settings. After that file exists, later changes edit it. You can also edit the file yourself: it accepts `model` and `reasoning` options.
30
+ The first time, this creates `agent/extensions/self-modification/extension.ts` with those settings. After that file exists, later changes edit it. You can also edit the file yourself: it accepts `model`, `reasoning`, and `local.enabled` options.
31
+
32
+ ```ts
33
+ // agent/extensions/self-modification/extension.ts
34
+ import selfModification from "eve/self-modification/local";
35
+
36
+ export default selfModification({
37
+ model: "openai/gpt-6-sol",
38
+ reasoning: "low",
39
+ });
40
+ ```
41
+
42
+ Mounts that import `eve/self-modification` still work; that specifier is an alias for `eve/self-modification/local`. Neither specifier accepts a `deployed` option. If your mount sets `deployed`, eve rejects it and asks you to move that configuration to an `eve/self-modification/remote` mount.
43
+
44
+ ## Propose changes from a deployed agent
45
+
46
+ `eve/self-modification/remote` is a separate extension for deployed agents. It adds a subagent that checks out your repository in a sandbox, edits the authored source, and opens a draft pull request against a target branch. It never changes the running deployment. Changes take effect only after you review, merge, and redeploy.
47
+
48
+ Mount it under its own namespace so it does not replace the local extension:
49
+
50
+ ```ts
51
+ // agent/extensions/self-modification-remote/extension.ts
52
+ import selfModification from "eve/self-modification/remote";
53
+
54
+ export default selfModification({
55
+ source: {
56
+ git: {
57
+ repository: "github.com/acme/agents",
58
+ directory: "apps/support",
59
+ },
60
+ },
61
+ target: { branch: "main" },
62
+ credentials: { pat: true },
63
+ authorize: ({ channel, principal }) =>
64
+ channel.kind === "http" && principal?.principalId === "release-bot",
65
+ });
66
+ ```
67
+
68
+ | Option | Description |
69
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
+ | `source.git.repository` | GitHub repository in `github.com/owner/repo` form. |
71
+ | `source.git.directory` | Application directory relative to the repository root. Use `"."` for the root. |
72
+ | `target.branch` | Branch that is checked out and targeted by draft pull requests. |
73
+ | `authorize` | Required. Receives the requesting `channel` and `principal` and returns whether that caller can use the subagent. The subagent is hidden when it returns `false` or throws. |
74
+ | `credentials` | Required. An object with a `resolve({ capability, repository })` function that returns a GitHub token, or `{ pat: true }` to read `EVE_SELF_MODIFICATION_GITHUB_TOKEN` from the deployment environment. |
75
+ | `model`, `reasoning` | Optional model and reasoning level for the deployed subagent. It defaults to the parent agent's model. |
76
+
77
+ The deployed subagent is never offered during `eve dev`. In a deployment, it needs a sandbox provider that supports runtime credential transforms: Vercel Sandbox on Vercel, or microsandbox on a supported self-hosted system. eve applies the GitHub token as a sandbox network credential only while it checks out or publishes, so commands in the sandbox cannot read it.
31
78
 
32
79
  ## Run without self-modification
33
80
 
@@ -158,7 +158,9 @@ export default defineTool({
158
158
  });
159
159
  ```
160
160
 
161
- When a response is refused without starting a turn, the session returns to `session.waiting`. The client finishes the submission and keeps the approval prompt answerable. Submitting an answer does not confirm approval: `approval.settled` or `input.resolved` records the server's decision. You can inspect `approval.candidate` events for the response policy's refusal reason.
161
+ When the policy refuses a response, the approval stays pending and the turn stays held. The stream emits `approval.candidate` with `outcome: "pending"`, then `approval.candidate` with `outcome: "rejected"` and the policy's `reason`, then `turn.waiting` with `on: "input"` for the same `turnId`. It does not emit `session.waiting`, so a client that stops reading at a session boundary keeps reading through a refusal. The client finishes the submission and the approval prompt stays answerable. Submitting an answer does not confirm approval: `approval.settled` or `input.resolved` records the server's decision.
162
+
163
+ Every response a policy evaluates starts the same way, not only refusals. eve first records the response as an `approval.candidate` with `outcome: "pending"`, then runs the policy so slow policy work cannot lose the response. An allowed response then emits `approval.settled` and `input.resolved`. An approval without a `response` policy settles directly and emits no `approval.candidate`. A candidate can also end with `failed`, `timed-out`, or `stale`; inspect `approval.candidate` events for the reason.
162
164
 
163
165
  ### Skipping approval for schedule-dispatched turns
164
166
 
@@ -217,7 +219,7 @@ Approvals and questions share one protocol:
217
219
  3. The run parks durably, for as long as it takes. The turn stays open: the stream emits `turn.waiting`, and after the answer the turn resumes under the same `turnId`. That `turn.waiting` carries `on: "input"`, since a person must act.
218
220
  4. The client answers with `inputResponses` (structured, keyed by `requestId`) or a normal follow-up `message`. A follow-up whose text matches an option ID, option label, or numeric option index resolves automatically, including approval options such as `approve` and `cancel`.
219
221
 
220
- For `ctx.ask()` questions from tools, a follow-up message answers the question only when exactly one question is pending. The message must match an option, or the question must allow free text. Otherwise the message follows the session's `turnPolicy`. A steering message, the default, aborts the `ctx.abortSignal` of each `execute` workflow tool call the turn waits on, so a question such a call asked, such as `ask_question`'s, is withdrawn and resolves as `cancelled`. The model reads the message once those calls settle. Questions from subagents need a structured response.
222
+ For `ctx.ask()` questions from tools, a follow-up message answers the first open request, as described in [Several requests at once](#several-requests-at-once). The message must match an option, or the question must allow free text. Otherwise the message follows the session's `turnPolicy`. A steering message, the default, aborts the `ctx.abortSignal` of each `execute` workflow tool call the turn waits on, so a question such a call asked, such as `ask_question`'s, is withdrawn and resolves as `cancelled`. The model reads the message once those calls settle. Questions from subagents need a structured response.
221
223
 
222
224
  Each request includes a `kind` discriminator: `tool-approval`, `question`, or
223
225
  `session-limit`. Clients should use `kind` to choose behavior and presentation.
@@ -232,6 +234,16 @@ If a tool is approved by another user, only the approved call runs with that use
232
234
 
233
235
  For approval requests, a follow-up message that doesn't match an option steers the turn instead of answering it. eve cancels the turn's pending approval, so the call doesn't run and `input.resolved` reports `outcome: "ignored"`, and the model reads the message next. This happens even when the message is sent with `turnPolicy: "queue"`, because a turn held on a person can't end until they act. Calls the person already approved in the same batch still run. A message from someone other than the person the turn serves waits until the turn ends. Cancelling the turn withdraws its approval: the call doesn't run, `input.resolved` reports `outcome: "cancelled"`, and a later answer to it approves nothing.
234
236
 
237
+ ### Several requests at once
238
+
239
+ A turn can wait on more than one request, such as two `ctx.ask()` questions a workflow tool asks with `Promise.all`, or approvals for two tool calls the model made in one step. A follow-up message answers only the first open request: a [runtime limit](/docs/agent-config#runtime-limits) continuation prompt if one is open, and otherwise the request eve asked for first, in the order of its `input.requested` events.
240
+
241
+ The message answers that request when it matches one of its options, or when the request accepts free text. Otherwise the message is not an answer and follows the rules above. To answer several requests by text, send one message per request.
242
+
243
+ An approval for a tool call made in the same step as a workflow tool call, such as `ask_question`, is not requested until the workflow tool call finishes, because the approved call can't run before then. The person answers the question first, then sees the approval.
244
+
245
+ Channels that show only text show one request at a time, in this order, and post the next once the current one is answered, so a reply answers the request the person sees. Twilio, GitHub, Linear, and Chat SDK channels work this way. Chat SDK can't tell whether an adapter shows buttons, so every Chat SDK channel shows requests one at a time, including Linq, Photon, and adapters with buttons. Native channels with buttons, such as Slack, show every open request so a person can press any of them, and a typed reply still answers the first.
246
+
235
247
  See [Sessions, runs & streaming](/docs/concepts/sessions-runs-and-streaming) for the full event and resume contract that this builds on.
236
248
 
237
249
  ## Answering from a client or channel
@@ -51,7 +51,7 @@ Ask for something that forces a large unfiltered scan:
51
51
  Total revenue across all customers, all time, broken out by day.
52
52
  ```
53
53
 
54
- The model proposes the query, `approval` returns `"user-approval"`, and the turn parks. The stream emits `input.requested`, then `session.waiting`. How the prompt looks depends on the channel, whether buttons in the TUI, Block Kit in Slack, or a UI control on the web. Approve it and the run resumes from exactly that step, then the query runs. Deny it and the tool is skipped, with the model told why.
54
+ The model proposes the query, `approval` returns `"user-approval"`, and the turn parks. The stream emits `input.requested`, then `turn.waiting` with `on: "input"`, and the turn stays open until someone answers. How the prompt looks depends on the channel, whether buttons in the TUI, Block Kit in Slack, or a UI control on the web. Approve it and the run resumes from exactly that step, then the query runs. Deny it and the tool is skipped, with the model told why.
55
55
 
56
56
  Each session has exactly one active continuation. Answer an approval against a stale handle and it's rejected, so there's no way to double-resume the same parked turn.
57
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.72.0",
3
+ "version": "0.73.0",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -333,6 +333,18 @@
333
333
  "import": "./dist/src/self-modification/extension/extension.js",
334
334
  "default": "./dist/src/self-modification/extension/extension.js"
335
335
  },
336
+ "./self-modification/local": {
337
+ "eve-source": "./dist/src/self-modification/extension/extension.js",
338
+ "types": "./dist/src/self-modification/extension/extension.d.ts",
339
+ "import": "./dist/src/self-modification/extension/extension.js",
340
+ "default": "./dist/src/self-modification/extension/extension.js"
341
+ },
342
+ "./self-modification/remote": {
343
+ "eve-source": "./dist/src/self-modification/remote/extension.js",
344
+ "types": "./dist/src/self-modification/remote/extension.d.ts",
345
+ "import": "./dist/src/self-modification/remote/extension.js",
346
+ "default": "./dist/src/self-modification/remote/extension.js"
347
+ },
336
348
  "./self-modification/agent": {
337
349
  "eve-source": "./dist/src/self-modification/agent.js",
338
350
  "types": "./dist/src/self-modification/agent.d.ts",
@@ -534,6 +546,7 @@
534
546
  "@opentelemetry/otlp-transformer": "0.214.0",
535
547
  "@opentelemetry/sdk-trace-base": "2.6.1",
536
548
  "@photon-ai/chat-adapter-imessage": "3.2.0",
549
+ "@shadcn/registry": "0.1.3",
537
550
  "@slack/web-api": "7.19.0",
538
551
  "@standard-schema/spec": "1.1.0",
539
552
  "@sveltejs/kit": "^2.0.0",
@@ -547,12 +560,12 @@
547
560
  "@vercel/otel": "2.1.3",
548
561
  "@vercel/sandbox": "3.3.0",
549
562
  "@vercel/sdk": "1.28.8",
550
- "@workflow/core": "5.0.1",
551
- "@workflow/errors": "5.0.1",
563
+ "@workflow/core": "5.1.0",
564
+ "@workflow/errors": "5.0.2",
552
565
  "@workflow/serde": "5.0.0",
553
- "@workflow/world": "5.0.1",
554
- "@workflow/world-local": "5.0.1",
555
- "@workflow/world-vercel": "5.0.1",
566
+ "@workflow/world": "5.0.2",
567
+ "@workflow/world-local": "5.0.2",
568
+ "@workflow/world-vercel": "5.1.0",
556
569
  "ai": "^7.0.128",
557
570
  "chat": "4.41.0",
558
571
  "chokidar": "5.0.0",
@@ -575,7 +588,6 @@
575
588
  "react-test-renderer": "19.2.6",
576
589
  "run": "2.1.2",
577
590
  "semver": "7.8.4",
578
- "shadcn": "4.18.0",
579
591
  "svelte": "^5.0.0",
580
592
  "turndown": "7.2.4",
581
593
  "vite": "^8.3.1",
@@ -621,6 +633,12 @@
621
633
  "./self-modification": {
622
634
  "dist": "./dist/src/self-modification/extension"
623
635
  },
636
+ "./self-modification/local": {
637
+ "dist": "./dist/src/self-modification/extension"
638
+ },
639
+ "./self-modification/remote": {
640
+ "dist": "./dist/src/self-modification/remote"
641
+ },
624
642
  "./extensions/code": {
625
643
  "dist": "./dist/src/extensions/code/extension"
626
644
  },
@@ -1,14 +0,0 @@
1
- /**
2
- * Auto-generated by scripts/build-vm-serde-bundle.js
3
- * Do not edit manually.
4
- *
5
- * This is the VM serialization bundle — a self-contained IIFE that sets up
6
- * the serialize/deserialize functions inside the QuickJS WASM VM. It
7
- * includes devalue and all workflow-mode reducers/revivers. (TextEncoder,
8
- * TextDecoder, and Headers are provided by quickjs-wasi's native C
9
- * extensions — no JS polyfills are bundled.)
10
- *
11
- * Size: 25.6 KB minified
12
- */
13
- export declare const VM_SERDE_BUNDLE: string;
14
- //# sourceMappingURL=vm-serde-bundle.generated.d.ts.map
@@ -1,3 +0,0 @@
1
- import{s as e,t}from"./rolldown-runtime-B_knIduE.js";function n(e,t,n){return n===1?e:t}var r=t(((e,t)=>{var n=1e3,r=n*60,i=r*60,a=i*24,o=a*7,s=a*365.25;t.exports=function(e,t){t||={};var n=typeof e;if(n===`string`&&e.length>0)return c(e);if(n===`number`&&isFinite(e))return t.long?u(e):l(e);throw Error(`val is not a non-empty string or a valid number. val=`+JSON.stringify(e))};function c(e){if(e=String(e),!(e.length>100)){var t=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(t){var c=parseFloat(t[1]);switch((t[2]||`ms`).toLowerCase()){case`years`:case`year`:case`yrs`:case`yr`:case`y`:return c*s;case`weeks`:case`week`:case`w`:return c*o;case`days`:case`day`:case`d`:return c*a;case`hours`:case`hour`:case`hrs`:case`hr`:case`h`:return c*i;case`minutes`:case`minute`:case`mins`:case`min`:case`m`:return c*r;case`seconds`:case`second`:case`secs`:case`sec`:case`s`:return c*n;case`milliseconds`:case`millisecond`:case`msecs`:case`msec`:case`ms`:return c;default:return}}}}function l(e){var t=Math.abs(e);return t>=a?Math.round(e/a)+`d`:t>=i?Math.round(e/i)+`h`:t>=r?Math.round(e/r)+`m`:t>=n?Math.round(e/n)+`s`:e+`ms`}function u(e){var t=Math.abs(e);return t>=a?d(e,t,a,`day`):t>=i?d(e,t,i,`hour`):t>=r?d(e,t,r,`minute`):t>=n?d(e,t,n,`second`):e+` ms`}function d(e,t,n,r){var i=t>=n*1.5;return Math.round(e/n)+` `+r+(i?`s`:``)}})),i=e(r(),1);function a(e){if(typeof e==`string`){let t=(0,i.default)(e);if(typeof t!=`number`||t<0)throw Error(`Invalid duration: "${e}". Expected a valid duration string like "1s", "1m", "1h", etc.`);return new Date(Date.now()+t)}if(typeof e==`number`){if(e<0||!Number.isFinite(e))throw Error(`Invalid duration: ${e}. Expected a non-negative finite number of milliseconds.`);return new Date(Date.now()+e)}if(e instanceof Date||e&&typeof e==`object`&&typeof e.getTime==`function`)return e instanceof Date?e:new Date(e.getTime());throw Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`)}const o={USER_ERROR:`USER_ERROR`,RUNTIME_ERROR:`RUNTIME_ERROR`,CORRUPTED_EVENT_LOG:`CORRUPTED_EVENT_LOG`,REPLAY_DIVERGENCE:`REPLAY_DIVERGENCE`,MAX_DELIVERIES_EXCEEDED:`MAX_DELIVERIES_EXCEEDED`,MAX_EVENTS_EXCEEDED:`MAX_EVENTS_EXCEEDED`,REPLAY_TIMEOUT:`REPLAY_TIMEOUT`,STREAM_ERROR:`STREAM_ERROR`,WORLD_CONTRACT_ERROR:`WORLD_CONTRACT_ERROR`,DEPLOYMENT_MISMATCH:`DEPLOYMENT_MISMATCH`};function s(e){return typeof e==`object`&&!!e&&`name`in e&&`message`in e}function c(e,t){if(t.length===0)return e;let n=[e];return t.forEach((e,r)=>{let i=r===t.length-1,a=i?`╰▶ `:`├▶ `,o=i?` `:`│ `;`${e.label}: ${e.value}`.split(`
2
- `).forEach((e,t)=>{n.push(`${t===0?a:o}${e}`)})}),n.join(`
3
- `)}function l(e,t){let n=[];return e&&n.push({label:`hint`,value:e}),t&&n.push({label:`docs`,value:`https://workflow-sdk.dev/err/${t}`}),n}const u={NODE_JS_MODULE_IN_WORKFLOW:`node-js-module-in-workflow`,START_INVALID_WORKFLOW_FUNCTION:`start-invalid-workflow-function`,SERIALIZATION_FAILED:`serialization-failed`,WEBHOOK_INVALID_RESPOND_WITH_VALUE:`webhook-invalid-respond-with-value`,WEBHOOK_RESPONSE_NOT_SENT:`webhook-response-not-sent`,FETCH_IN_WORKFLOW_FUNCTION:`fetch-in-workflow`,TIMEOUT_FUNCTIONS_IN_WORKFLOW:`timeout-in-workflow`,HOOK_CONFLICT:`hook-conflict`,HOOK_FORCE_CLAIMED:`hook-force-claimed`,CORRUPTED_EVENT_LOG:`corrupted-event-log`,REPLAY_DIVERGENCE:`replay-divergence`,STEP_NOT_REGISTERED:`step-not-registered`,WORKFLOW_NOT_REGISTERED:`workflow-not-registered`,RUNTIME_DECRYPTION_FAILED:`runtime-decryption-failed`,DEPLOYMENT_MISMATCH:`deployment-mismatch`};var d=class extends Error{cause;constructor(e,t){let n=c(e,l(void 0,t?.slug));super(n,{cause:t?.cause}),t?.cause!==void 0&&(this.cause=t.cause),t?.cause instanceof Error&&(this.stack=`${this.stack}\nCaused by: ${t.cause.stack}`)}static is(e){return s(e)&&e.name===`WorkflowError`}},f=class extends d{status;code;url;retryAfter;field;constructor(e,t){super(e,{cause:t?.cause}),this.name=`WorkflowWorldError`,this.status=t?.status,this.code=t?.code,this.url=t?.url,this.retryAfter=t?.retryAfter,this.field=t?.field}static is(e){return s(e)&&e.name===`WorkflowWorldError`}},p=class extends d{fatal=!0;runId;errorCode;constructor(e,t,n={}){let r=t instanceof Error?t.message:typeof t==`string`?t:t&&typeof t==`object`&&`message`in t?String(t.message):`Unknown error`;super(`Workflow run "${e}" failed: ${r}`,{cause:t}),this.name=`WorkflowRunFailedError`,this.runId=e,n.errorCode!==void 0&&(this.errorCode=n.errorCode)}static is(e){return s(e)&&e.name===`WorkflowRunFailedError`}},m=class extends d{runId;status;constructor(e,t){super(`Workflow run "${e}" has not completed`,{}),this.name=`WorkflowRunNotCompletedError`,this.runId=e,this.status=t}static is(e){return s(e)&&e.name===`WorkflowRunNotCompletedError`}},h=class extends d{constructor(e,t){super(e,{...t}),this.name=`WorkflowRuntimeError`}static is(e){return s(e)&&e.name===`WorkflowRuntimeError`}},g=class extends h{constructor(e,t){super(e,{...t,slug:u.CORRUPTED_EVENT_LOG}),this.name=`CorruptedEventLogError`}static is(e){return s(e)&&e.name===`CorruptedEventLogError`}},_=class extends h{eventId;constructor(e,t){super(e,{...t,slug:u.REPLAY_DIVERGENCE}),this.name=`ReplayDivergenceError`,this.eventId=t.eventId}static is(e){return s(e)&&e.name===`ReplayDivergenceError`&&typeof e.eventId==`string`}},v=class extends d{eventCount;limit;constructor(e,t,n){super(`Workflow exceeded the maximum of ${t} events per run`,n),this.name=`MaxEventsExceededError`,this.eventCount=e,this.limit=t}static is(e){return s(e)&&e.name===`MaxEventsExceededError`}},y=class extends h{constructor(e,t){super(e,{cause:t?.cause,slug:u.RUNTIME_DECRYPTION_FAILED}),this.name=`RuntimeDecryptionError`,t?.context!==void 0&&(this.context=t.context)}static is(e){return s(e)&&e.name===`RuntimeDecryptionError`}},b=class extends d{hint;constructor(e,t){let n=c(e,l(t?.hint,void 0));super(n,{cause:t?.cause}),this.name=`WorkflowBuildError`,this.hint=t?.hint}static is(e){return s(e)&&e.name===`WorkflowBuildError`}},x=class extends d{hint;fatal=!0;constructor(e,t){let n=c(e,l(t?.hint,void 0));super(n,{cause:t?.cause}),this.name=`SerializationError`,this.hint=t?.hint}static is(e){return s(e)&&e.name===`SerializationError`}},S=class extends h{stepName;constructor(e){super(`Step "${e}" is not registered in the current deployment. This usually indicates a build or bundling issue that caused the step to not be included in the deployment.`,{slug:u.STEP_NOT_REGISTERED}),this.name=`StepNotRegisteredError`,this.stepName=e}static is(e){return s(e)&&e.name===`StepNotRegisteredError`}},C=class extends h{workflowName;constructor(e){super(`Workflow "${e}" is not registered in the current deployment. This usually means a run was started against a deployment that does not have this workflow, or there was a build/bundling issue.`,{slug:u.WORKFLOW_NOT_REGISTERED}),this.name=`WorkflowNotRegisteredError`,this.workflowName=e}static is(e){return s(e)&&e.name===`WorkflowNotRegisteredError`}},w=class extends h{runId;expectedDeploymentId;actualDeploymentId;recoveryAttempts;constructor(e,t,r,i){let a=i?.recoveryAttempts??0,o=a>0?` The runtime re-routed the message to "${t}" ${a} ${n(`time`,`times`,a)} and it kept arriving elsewhere, so the run was stopped to protect against code-skew errors.`:` The run was stopped to protect against code-skew errors.`;super(`Workflow run "${e}" is pinned to deployment "${t}", but was received by deployment "${r}".${o} Verify that the run's deployment is still available and that queue callbacks are routed to it.`,{slug:u.DEPLOYMENT_MISMATCH,cause:i?.cause}),this.name=`WorkflowDeploymentMismatchError`,this.runId=e,this.expectedDeploymentId=t,this.actualDeploymentId=r,this.recoveryAttempts=a}static is(e){return s(e)&&e.name===`WorkflowDeploymentMismatchError`}},T=class extends d{runId;constructor(e){super(`Workflow run "${e}" not found`,{}),this.name=`WorkflowRunNotFoundError`,this.runId=e}static is(e){return s(e)&&e.name===`WorkflowRunNotFoundError`}},E=class extends d{token;conflictingRunId;constructor(e,t){super(`Hook token "${e}" is already in use by another workflow${t?` (run "${t}")`:``}`,{slug:u.HOOK_CONFLICT}),this.name=`HookConflictError`,this.token=e,t!==void 0&&(this.conflictingRunId=t)}static is(e){return s(e)&&e.name===`HookConflictError`}},D=class extends d{token;claimedByRunId;claimedByHookId;constructor(e,t,n){super(`Hook token "${e}" was force-claimed by another workflow (run "${t}")`,{slug:u.HOOK_FORCE_CLAIMED}),this.name=`HookForceClaimedError`,this.token=e,this.claimedByRunId=t,n!==void 0&&(this.claimedByHookId=n)}static is(e){return s(e)&&e.name===`HookForceClaimedError`}},O=class extends d{token;constructor(e){super(`Hook not found`,{}),this.name=`HookNotFoundError`,this.token=e}static is(e){return s(e)&&e.name===`HookNotFoundError`}},k=class extends f{constructor(e){super(e),this.name=`EntityConflictError`}static is(e){return s(e)&&e.name===`EntityConflictError`}},A=class extends f{runId;runStatus;expiredAt;constructor(e,t,n,r){super(e,{status:410,code:`run-expired`}),this.runId=t,this.runStatus=n,this.expiredAt=r,this.name=`RunExpiredError`}static is(e){return s(e)&&e.name===`RunExpiredError`}},j=class extends f{constructor(e,t){super(e,{code:o.STREAM_ERROR,cause:t?.cause,url:t?.url,status:t?.status}),this.name=`StreamError`}static is(e){return s(e)&&e.name===`StreamError`}},M=class extends f{runId;streamId;expiredAt;constructor(e,t,n,r){super(e,{status:410,code:`stream-expired`}),this.runId=t,this.streamId=n,this.expiredAt=r,this.name=`StreamExpiredError`}static is(e){return s(e)&&e.name===`StreamExpiredError`}},N=class extends f{constructor(e,t){super(e,{retryAfter:t?.retryAfter}),this.name=`TooEarlyError`}static is(e){return s(e)&&e.name===`TooEarlyError`}},P=class extends f{retryAfter;constructor(e,t){super(e),this.name=`ThrottleError`,this.retryAfter=t?.retryAfter}static is(e){return s(e)&&e.name===`ThrottleError`}},F=class extends f{details;constructor(e,t){super(e,{status:412,retryAfter:t?.retryAfter}),this.name=`PreconditionFailedError`,this.details=t?.details}static is(e){return s(e)&&e.name===`PreconditionFailedError`}},I=class extends d{fatal=!0;runId;constructor(e){super(`Workflow run "${e}" cancelled`,{}),this.name=`WorkflowRunCancelledError`,this.runId=e}static is(e){return s(e)&&e.name===`WorkflowRunCancelledError`}},L=class extends d{runSpecVersion;worldSpecVersion;constructor(e,t){super(`Run requires spec version ${e}, but world supports version ${t}. Please upgrade 'workflow' package.`),this.name=`RunNotSupportedError`,this.runSpecVersion=e,this.worldSpecVersion=t}static is(e){return s(e)&&e.name===`RunNotSupportedError`}},R=class extends Error{fatal=!0;constructor(e){super(e),this.name=`FatalError`}static is(e){return s(e)?e.name===`FatalError`||e.fatal===!0:!1}},z=class extends Error{retryAfter;constructor(e,t={}){super(e),this.name=`RetryableError`,this.retryAfter=t.retryAfter===void 0?new Date(Date.now()+1e3):a(t.retryAfter)}static is(e){return s(e)&&e.name===`RetryableError`}};const B="Your current vercel account does not have access to this resource. Use `vercel login` or `vercel switch` to ensure you are linked to the right account.",V=Symbol.for(`@workflow/errors//FatalError`),H=Symbol.for(`@workflow/errors//RetryableError`),U=Symbol.for(`@workflow/errors//HookConflictError`),W=Symbol.for(`@workflow/errors//HookForceClaimedError`),G=Symbol.for(`@workflow/errors//RuntimeDecryptionError`),K=Symbol.for(`@workflow/errors//StreamError`);typeof globalThis<`u`&&(Object.hasOwn(globalThis,V)||Object.defineProperty(globalThis,V,{value:R,writable:!1,enumerable:!1,configurable:!1}),Object.hasOwn(globalThis,H)||Object.defineProperty(globalThis,H,{value:z,writable:!1,enumerable:!1,configurable:!1}),Object.hasOwn(globalThis,U)||Object.defineProperty(globalThis,U,{value:E,writable:!1,enumerable:!1,configurable:!1}),Object.hasOwn(globalThis,W)||Object.defineProperty(globalThis,W,{value:D,writable:!1,enumerable:!1,configurable:!1}),Object.hasOwn(globalThis,G)||Object.defineProperty(globalThis,G,{value:y,writable:!1,enumerable:!1,configurable:!1}),Object.hasOwn(globalThis,K)||Object.defineProperty(globalThis,K,{value:j,writable:!1,enumerable:!1,configurable:!1}));export{h as A,w as C,p as D,I as E,n as F,o as M,a as N,m as O,r as P,b as S,C as T,j as _,E as a,N as b,v as c,z as d,A as f,S as g,x as h,R as i,f as j,T as k,F as l,y as m,u as n,D as o,L as p,k as r,O as s,g as t,_ as u,M as v,d as w,B as x,P as y};
@@ -1 +0,0 @@
1
- import{A as e,F as t}from"./dist-CaNNONeg.js";function n(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function r(e){let t={get value(){let n=e();return Object.defineProperty(t,"value",{value:n}),n}};return t}var i=class e extends Error{items;steps;globalThis;stepCount;hookCount;waitCount;attributeCount;hookDisposedCount;abortCount;constructor(e,n){let r=[...e.values()],i=0,a=0,o=0,s=0,c=0,l=0;for(let e of r)e.type===`step`?i++:e.type===`hook`?e.disposed?c++:e.abortRequested?l++:a++:e.type===`wait`?o++:e.type===`attribute`&&s++;let u=[];i>0&&u.push(`${i} ${t(`step`,`steps`,i)}`),a>0&&u.push(`${a} ${t(`hook`,`hooks`,a)}`),o>0&&u.push(`${o} ${t(`wait`,`waits`,o)}`),s>0&&u.push(`${s} ${t(`attribute write`,`attribute writes`,s)}`),c>0&&u.push(`${c} hook ${t(`disposal`,`disposals`,c)}`);let d=i+a+o+s+c,f=t(`has`,`have`,d),p=+(i>0)+ +(a>0)+ +(o>0)+ +(s>0)+ +(c>0),m;m=p>1?`processed`:i>0?`run`:a>0||o>0?`created`:s>0?`written`:c>0?`processed`:`received`;let h=u.length>0?`${u.join(` and `)} ${f} not been ${m} yet`:`0 steps have not been run yet`;super(h),this.name=`WorkflowSuspension`,this.items=r,this.steps=r,this.globalThis=n,this.stepCount=i,this.hookCount=a,this.waitCount=o,this.attributeCount=s,this.hookDisposedCount=c,this.abortCount=l}static is(t){return t instanceof e}};function a(){throw new e(`This API is not available inside a workflow function. Workflow functions run in a deterministic VM; move the call to a step function for full Node.js access.`)}export{n as i,i as n,r,a as t};
@@ -1 +0,0 @@
1
- import{D as e,T as t,_t as n,b as r,f as i,ht as a,pt as o,st as s}from"./dist-B7NC1c9-.js";import{B as c,G as l,H as u,L as d,Ln as f,R as p,V as m,Xn as ee,at as h,d as g,er as _,fn as te,n as v,nn as ne,ot as y,rn as re,st as b,tr as x,y as S,yn as ie,z as ae}from"./logger-oqfblE3p.js";import{M as C,j as w,l as oe}from"./dist-CaNNONeg.js";const T=`5.0.1`;function se(){return a(`WORKFLOW_MAX_QUEUE_DELIVERIES`,48,{integer:!0,min:1,max:48})}const E=24e4,D=3e4,O=78e4,k=n(`@workflow/core//envWarnings`,1,()=>({replayTimeoutValues:new Set,maxInlineStepsValues:new Set,maxEventsValues:new Set}));function A(e,t,n){k.replayTimeoutValues.has(e)||(k.replayTimeoutValues.add(e),v.warn(t,n))}function ce(){let e=process.env.WORKFLOW_REPLAY_TIMEOUT_MS;if(!e)return E;let t=Number(e);return!Number.isFinite(t)||t<=0?(A(e,`Ignoring WORKFLOW_REPLAY_TIMEOUT_MS: not a positive finite number; using default`,{raw:e,defaultMs:E}),E):t<3e4?(A(e,`WORKFLOW_REPLAY_TIMEOUT_MS below minimum; clamped`,{raw:e,clampedMs:D,minMs:D}),D):t>78e4?(A(e,`WORKFLOW_REPLAY_TIMEOUT_MS above maximum; clamped`,{raw:e,clampedMs:O,maxMs:O}),O):t}function le(){return a(`WORKFLOW_REPLAY_TIMEOUT_MAX_RETRIES`,3,{integer:!0})}function ue(){let e=process.env.WORKFLOW_MAX_INLINE_STEPS;if(!e)return 3;let t=Number(e);return!Number.isInteger(t)||t<=0?(k.maxInlineStepsValues.has(e)||(k.maxInlineStepsValues.add(e),v.warn(`Ignoring WORKFLOW_MAX_INLINE_STEPS: not a positive integer; using default`,{raw:e,defaultValue:3})),3):t<1?1:t>16?(k.maxInlineStepsValues.has(e)||(k.maxInlineStepsValues.add(e),v.warn(`WORKFLOW_MAX_INLINE_STEPS above maximum; clamped`,{raw:e,clampedValue:16,maxValue:16})),16):t}const de=131072;function fe(){return process.env.WORKFLOW_RESILIENT_STEP_DISPATCH===`1`}function pe(){let e=process.env.WORKFLOW_BATCH_TRANSITIONS;return e===void 0||e===``||e!==`0`&&e.toLowerCase()!==`false`}function me(){let e=process.env.WORKFLOW_MAX_EVENTS_OVERRIDE;if(!e)return;let t=Number(e);if(!Number.isInteger(t)||t<=0){k.maxEventsValues.has(e)||(k.maxEventsValues.add(e),v.warn(`Ignoring WORKFLOW_MAX_EVENTS_OVERRIDE: not a positive integer; using server limit`,{raw:e}));return}return t}function j(){let e=process.env.WORKFLOW_OPTIMISTIC_INLINE_START;return e===void 0||e===``?!1:e===`1`||e.toLowerCase()===`true`}function M(){let e=process.env.WORKFLOW_OPTIMISTIC_INLINE_START;return e===void 0||e===``?!1:e===`0`||e.toLowerCase()===`false`}function N(){let e=process.env.WORKFLOW_TURBO;return e===void 0||e===``||e!==`0`&&e.toLowerCase()!==`false`}function P(){let e=process.env.WORKFLOW_RETAINED_VM;return e===void 0||e===``||e!==`0`&&e.toLowerCase()!==`false`}const F=`WORKFLOW_EXPERIMENTAL_DYNAMIC_WORKFLOWS`;function I(){let e=process.env[F];return e===void 0?!1:e===`1`||e.toLowerCase()===`true`}function L(){let e=process.env.WORKFLOW_INLINE_OWNERSHIP;return e===void 0||e===``||e!==`0`&&e.toLowerCase()!==`false`}function R(){return a(`WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS`,860,{integer:!0,min:1,max:900})}function z(){return a(`WORKFLOW_REPLAY_DIVERGENCE_MAX_RETRIES`,3,{integer:!0})}function he(){return a(`WORKFLOW_OPEN_WAIT_CLOCK_SKEW_MS`,3e4,{integer:!0})}function ge(){return a(`WORKFLOW_PRECONDITION_MAX_INPROCESS_RESTARTS`,3,{integer:!0})}function _e(){return a(`WORKFLOW_PRECONDITION_MAX_REINVOCATIONS`,5,{integer:!0})}function ve(){return a(`WORKFLOW_PRECONDITION_REINVOKE_DELAY_SECONDS`,2,{integer:!0})}function ye(){return a(`WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES`,3,{integer:!0,min:0})}const be=/^[a-zA-Z0-9_\-./@()[\]]+$/;function xe(n,r){if(!be.test(n))throw Error(`Invalid workflow name "${n}": must only contain alphanumeric characters, underscores, hyphens, dots, forward slashes, at signs, parentheses, or square brackets`);return`${t(`workflow`,e(r))}${n}`}const Se=o();function B(e){return`__health_check__${e}`}const Ce=1;function we(e){let t=r.safeParse(e);if(t.success)return t.data}function V(e){return`wrun_hc_${e}`}async function Te(e,t){let n=await x(),r=B(e.correlationId),i;if(e.runId)try{let t=await n.getEncryptionKeyForRun?.(e.runId);t&&(i=ee((await _(t)).publicKey))}catch(t){v.warn(`Health check could not derive a run public key; the caller will fall back to a key lookup`,{correlationId:e.correlationId,error:t instanceof Error?t.message:String(t)})}let a=JSON.stringify({healthy:!0,correlationId:e.correlationId,specVersion:t??8,workflowCoreVersion:T,hookResumeInputVersion:1,...I()?{dynamicWorkflowVersion:1}:{},...i?{encryptionPublicKey:i}:{},timestamp:Date.now()}),o=V(e.correlationId);await n.streams.write(o,r,a),await n.streams.close(o,r)}function Ee(e,t){let n;return Promise.race([e,new Promise((e,r)=>{n=setTimeout(()=>r(Error(`Operation timed out after ${t}ms`)),t)})]).finally(()=>clearTimeout(n))}async function De(e,t){let n=[],r=!1,i=!1;for(;!r&&!i;){let a=e.read(),o=new Promise(e=>setTimeout(()=>{i=!0,e({done:!0,value:void 0})},t)),s=await Promise.race([a,o]);r=s.done,s.value&&n.push(s.value)}return{chunks:n,timedOut:i}}function Oe(e){if(e.length===0)return null;let t=e.reduce((e,t)=>e+t.length,0),n=new Uint8Array(t),r=0;for(let t of e)n.set(t,r),r+=t.length;let i=new TextDecoder().decode(n),a;try{a=JSON.parse(i)}catch{return i.length>0?{healthy:!0,format:`text`}:null}if(typeof a!=`object`||!a||!(`healthy`in a)||typeof a.healthy!=`boolean`)return null;let o=a,s={healthy:o.healthy,format:`json`};return typeof o.specVersion==`number`&&(s.specVersion=o.specVersion),typeof o.workflowCoreVersion==`string`&&(s.workflowCoreVersion=o.workflowCoreVersion),typeof o.encryptionPublicKey==`string`&&(s.encryptionPublicKey=o.encryptionPublicKey),typeof o.hookResumeInputVersion==`number`&&(s.hookResumeInputVersion=o.hookResumeInputVersion),typeof o.dynamicWorkflowVersion==`number`&&(s.dynamicWorkflowVersion=o.dynamicWorkflowVersion),s}async function ke(n,r){let i=r?.timeout??3e4,a=n.createRunId?.()??Se(),o=B(a),s=`${t(`workflow`,e(r?.namespace))}health_check`,c=Date.now();try{for(await n.queue(s,{__healthCheck:!0,correlationId:a,...r?.runId?{runId:r.runId}:{}},{specVersion:1,deploymentId:r?.deploymentId});Date.now()-c<i;)try{let e=i-(Date.now()-c),t=(await Ee(n.streams.get(V(a),o),e)).getReader(),{chunks:r,timedOut:s}=await De(t,500);if(s){try{t.cancel()}catch{}await new Promise(e=>setTimeout(e,100));continue}let l=Oe(r);if(l)return{...l,latencyMs:Date.now()-c};await new Promise(e=>setTimeout(e,100))}catch{await new Promise(e=>setTimeout(e,100))}return{healthy:!1,error:`Health check timed out after ${i}ms`}}catch(e){return{healthy:!1,error:e instanceof Error?e.message:String(e)}}}function H(e,t){return new w(`Event pagination ${t} for workflow run "${e}".`,{code:C.WORLD_CONTRACT_ERROR})}function Ae(e,t,n){if(t){if(n.has(t))throw H(e,`did not advance`);n.add(t)}}function U(e,t,n){if(t.length===0)return;let r=n??new Set(e.map(e=>e.eventId));for(let n of t)r.has(n.eventId)||(r.add(n.eventId),e.push(n))}function je(e,t){let n=e.length;for(;n>0;){let r=e[n-1];if(r.eventId===t.eventId)return;if(r.eventId<t.eventId)break;n--}e.splice(n,0,t)}function Me(e,t,n,r){if(t){if(n===null)throw H(e,`returned more pages without a cursor`);if(r.has(n))throw H(e,`repeated a cursor`)}}function Ne(e,t,n){return t!==null&&!n&&w.is(e)&&e.status===400}const W=`skip-step-inputs`;function Pe(e){return e?.sinceCursor===void 0?e:{resolveData:W,...e}}async function G(e,t){let n=t!==void 0;return S(`workflow.replay.load`,async r=>{r?.setAttributes({...ie(e),...te(n?`events_list_incremental`:`events_list`)});let i=[],a=new Set,o=new Set,s=t??null,c=!0,l=0,u=!1,d=await x(),f=Date.now();for(;c;){let t=Date.now(),r=s;Ae(e,r,o);let f;try{f=await d.events.list({runId:e,pagination:{sortOrder:`asc`,cursor:r??void 0},resolveData:W})}catch(t){if(Ne(t,r,u)){v.warn(`Event cursor was rejected; retrying with a full event reload.`,{workflowRunId:e}),i.length=0,a.clear(),o.clear(),s=null,u=!0;continue}throw t}U(i,f.data,a),c=f.hasMore,Me(e,c,f.cursor,o),s=f.cursor??s,l++,v.debug(`Loaded event page`,{workflowRunId:e,incremental:n,page:l,pageEvents:f.data.length,totalEvents:i.length,hasMore:c,pageMs:Date.now()-t})}return v.debug(`Event load complete`,{workflowRunId:e,incremental:n,totalEvents:i.length,pagesLoaded:l,totalMs:Date.now()-f}),r?.setAttributes({...ne(i.length),...re(l)}),{events:i,cursor:s}})}function Fe(e,t){U(e.events,t.events),e.cursor=t.cursor??e.cursor}function Ie(){return process.env.WORKFLOW_SLOT_GAP_CHECK!==`0`}function K(e,t){let n=e.length;U(e,t);let r=e.length-n;return r>0&&e.sort((e,t)=>e.eventId<t.eventId?-1:+(e.eventId>t.eventId)),r}function Le(e,t){let n=t.events?.length??0;return n===0?{added:0,offered:0,truncated:!1}:t.hasMore===!0?{added:0,offered:n,truncated:!0}:{added:K(e,t.events??[]),offered:n,truncated:!1}}function q(e){let t;for(let n of e){let e=i(n.eventId);(t===void 0||e>t)&&(t=e)}return t}function J(e){let t=new Set,n=0;for(let r of e){let e=i(r.eventId);t.add(e),e>n&&(n=e)}if(n===0)return;let r=t.has(1)?1:2;if(t.size===n-r+1)return;let a,o=0;for(let e=r;e<=n;e++)t.has(e)||(a??=e,o++);if(a!==void 0)return{firstMissingSlot:a,missingCount:o,maxSlot:n}}const Re=3;async function Y(e,t){let n=t,r=J(n.events);for(let t=0;r!==void 0&&t<3;t++)await new Promise(e=>setTimeout(e,25*2**t)),n=await G(e),r=J(n.events);return{log:n,gap:r}}function ze(e){let t=q(e);return t===void 0?{}:{eventCount:t}}function Be(e,t){if(!oe.is(e))return null;let n=e.details;if(typeof n!=`object`||!n)return null;let{events:r,cursor:i}=n;if(!Array.isArray(r)||r.length===0)return null;for(let e of r)if(typeof e!=`object`||!e||typeof e.eventId!=`string`||e.runId!==t)return null;return{events:r,cursor:typeof i==`string`?i:null}}const X={"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST, OPTIONS, GET, HEAD`,"Access-Control-Allow-Headers":`Content-Type`};function Ve(e,t){return async n=>{let r=new URL(n.url);return r.searchParams.has(`__health`)?n.method===`OPTIONS`?new Response(null,{status:204,headers:X}):new Response(JSON.stringify({healthy:!0,endpoint:r.pathname,specVersion:t??8,workflowCoreVersion:T}),{status:200,headers:{"Content-Type":`application/json`,...X}}):await e(n)}}function Z(e,t){return e?.[s]??t}function He(e){return{deploymentId:e.deploymentId,specVersion:e.specVersion??0,...e.startedAt?{startedAt:+e.startedAt}:{},rootRunId:Z(e.attributes,e.runId)}}function Ue(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,`0`)}function We(e,t){return`${e}:${Ue(t)}`}async function Q(e,...t){let n=t[0];await S(`queue.publish`,{attributes:{...m(`vercel-queue`),...p(n),...c(`publish`),...u(`vercel-queue`),...b(`vercel-queue`),...y(`vqs`),...h(`publish`)},kind:await g(`PRODUCER`)},async n=>{let{messageId:r}=await e.queue(...t);r&&n?.setAttributes(ae(r))})}async function Ge(e,t,n){if(n.length===0)return;let r=e.queueBatch?.bind(e);if(!r){await Promise.all(n.map(n=>Q(e,t,n.message,n.opts)));return}await S(`queue.publish`,{attributes:{...m(`vercel-queue`),...p(t),...c(`publish`),...d(n.length),...u(`vercel-queue`),...b(`vercel-queue`),...y(`vqs`),...h(`publishBatch`)},kind:await g(`PRODUCER`)},async()=>{let e=await r(t,n);if(e.length!==n.length)throw Object.assign(Error(`Queue batch for ${t} returned ${e.length} result(s) for ${n.length} message(s)`),{retryable:!0});let i=e.filter(e=>e.error!==void 0);if(i.length===0)return;let a=i.some(e=>e.error!==void 0&&e.retryable),o=Error(`Failed to publish ${i.length} of ${n.length} queue message(s) to ${t}: ${i[0]?.error}`);throw Object.assign(o,{retryable:a}),o})}function Ke(e){if(e.requestedAt)try{return l(Date.now()-e.requestedAt.getTime())}catch{return}}async function $(e,t,n){let r=typeof t==`string`?await e.getEncryptionKeyForRun?.(t,n):await e.getEncryptionKeyForRun?.(t);return r?await f(r):void 0}function qe(e,t){let n;return()=>(n||=$(e,t),n)}export{F as A,ve as B,Z as C,We as D,ze as E,ue as F,I as G,le as H,se as I,M as J,L as K,he as L,ye as M,R as N,Ve as O,me as P,T as Q,ge as R,$ as S,Y as T,ce as U,z as V,pe as W,N as X,fe as Y,P as Z,K as _,Fe as a,Q as b,Ke as c,ke as d,je as f,qe as g,q as h,Le as i,de as j,Pe as k,xe as l,G as m,W as n,U as o,Ie as p,j as q,Re as r,J as s,Ce as t,Te as u,we as v,He as w,Ge as x,Be as y,_e as z};