eve 0.82.0 → 0.83.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 (480) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/NOTICE +1 -1
  3. package/dist/src/channel/pending-authorization.d.ts +5 -0
  4. package/dist/src/channel/pending-authorization.js +1 -1
  5. package/dist/src/channel/session.d.ts +2 -0
  6. package/dist/src/channel/session.js +1 -1
  7. package/dist/src/channel/types.d.ts +5 -0
  8. package/dist/src/chunks/{use-eve-agent-DlznYwQk.js → use-eve-agent-3-WRmJkd.js} +40 -5
  9. package/dist/src/chunks/{use-eve-agent-DTu78IAF.js → use-eve-agent-Ci5dr0aR.js} +40 -5
  10. package/dist/src/cli/dev/local-server-child.js +1 -1
  11. package/dist/src/cli/dev/local-server-cleanup.js +1 -1
  12. package/dist/src/cli/dev/tui/question-panel.d.ts +4 -1
  13. package/dist/src/cli/dev/tui/question-panel.js +1 -1
  14. package/dist/src/cli/dev/tui/terminal-renderer.js +4 -4
  15. package/dist/src/client/eve-agent-store.d.ts +1 -1
  16. package/dist/src/client/eve-agent-store.js +1 -1
  17. package/dist/src/client/index.d.ts +1 -0
  18. package/dist/src/client/session-controls.d.ts +6 -0
  19. package/dist/src/client/session-controls.js +1 -1
  20. package/dist/src/client/session.d.ts +4 -0
  21. package/dist/src/client/session.js +1 -1
  22. package/dist/src/compiled/.vendor-stamp.json +8 -8
  23. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  24. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +2 -0
  25. package/dist/src/compiled/@workflow/core/index.js +2 -2
  26. package/dist/src/compiled/@workflow/core/private.d.ts +5 -3
  27. package/dist/src/compiled/@workflow/core/private.js +1 -1
  28. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +1 -37
  29. package/dist/src/compiled/@workflow/core/runtime/event-limit-warning.d.ts +32 -0
  30. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +5 -6
  31. package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
  32. package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +8 -0
  33. package/dist/src/compiled/@workflow/core/runtime/start.d.ts +16 -0
  34. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +15 -18
  35. package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +20 -0
  36. package/dist/src/compiled/@workflow/core/runtime.js +4 -4
  37. package/dist/src/compiled/@workflow/core/seeded-nanoid.d.ts +2 -0
  38. package/dist/src/compiled/@workflow/core/serialization/compression.d.ts +14 -3
  39. package/dist/src/compiled/@workflow/core/serialization.d.ts +1 -1
  40. package/dist/src/compiled/@workflow/core/serialization.js +1 -1
  41. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +0 -18
  42. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  43. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  44. package/dist/src/compiled/@workflow/errors/index.d.ts +48 -0
  45. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  46. package/dist/src/compiled/@workflow/world/env-config.d.ts +24 -0
  47. package/dist/src/compiled/@workflow/world/events.d.ts +126 -7
  48. package/dist/src/compiled/@workflow/world/index.d.ts +3 -3
  49. package/dist/src/compiled/@workflow/world/interfaces.d.ts +59 -8
  50. package/dist/src/compiled/@workflow/world/queue.d.ts +71 -9
  51. package/dist/src/compiled/@workflow/world/recovery.d.ts +6 -0
  52. package/dist/src/compiled/@workflow/world/test-support/duplicate-event-fixtures.d.ts +3 -0
  53. package/dist/src/compiled/@workflow/world/test-support/in-band-fence-conformance.d.ts +46 -0
  54. package/dist/src/compiled/@workflow/world-local/index.js +5 -5
  55. package/dist/src/compiled/@workflow/world-vercel/index.js +18 -18
  56. package/dist/src/compiled/_chunks/workflow/{attribute-changes-BW-kbMMn.js → attribute-changes-7se_SE2q.js} +3 -3
  57. package/dist/src/compiled/_chunks/workflow/dist-CcnNPAp4.js +1 -0
  58. package/dist/src/compiled/_chunks/workflow/dist-S9cZRway.js +3 -0
  59. package/dist/src/compiled/_chunks/workflow/helpers-CxNRXH0a.js +1 -0
  60. package/dist/src/compiled/_chunks/workflow/private-DLYTSBbu.js +1 -0
  61. package/dist/src/compiled/_chunks/workflow/resume-hook-CPiIfe8r.js +1 -0
  62. package/dist/src/compiled/_chunks/workflow/{run-DzdAqdb1.js → run-BJSLCXR4.js} +6 -6
  63. package/dist/src/compiled/_chunks/workflow/serialization-B9gneT9Z.js +15 -0
  64. package/dist/src/compiled/_chunks/workflow/sleep-BL0oQs3R.js +1 -0
  65. package/dist/src/compiled/_chunks/workflow/{wait-until-xbRRDuUf.js → wait-until-BPou0RGO.js} +1 -1
  66. package/dist/src/compiled/_chunks/workflow/workflow-routes-BaljomCk.js +1 -0
  67. package/dist/src/compiled/{@ai-sdk/code-mode → run}/LICENSE +1 -1
  68. package/dist/src/compiled/run/index.d.ts +384 -0
  69. package/dist/src/compiled/run/index.js +650 -0
  70. package/dist/src/compiler/extension-compatibility.d.ts +21 -14
  71. package/dist/src/compiler/extension-compatibility.js +1 -1
  72. package/dist/src/compiler/manifest.js +1 -1
  73. package/dist/src/compiler/normalize-agent-config.js +1 -1
  74. package/dist/src/compiler/normalize-manifest.js +1 -1
  75. package/dist/src/compiler/normalize-sandbox.js +1 -1
  76. package/dist/src/compiler/workspace-resources.js +1 -1
  77. package/dist/src/context/build-callback-context.js +1 -1
  78. package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
  79. package/dist/src/context/providers/sandbox.js +1 -1
  80. package/dist/src/discover/extension-specifier.d.ts +1 -0
  81. package/dist/src/discover/extension-specifier.js +1 -1
  82. package/dist/src/evals/cli/eval.js +2 -2
  83. package/dist/src/evals/runner/artifacts.js +1 -1
  84. package/dist/src/evals/runner/derive-run-facts.d.ts +12 -0
  85. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  86. package/dist/src/evals/runner/execute-task.js +1 -1
  87. package/dist/src/evals/types.d.ts +3 -2
  88. package/dist/src/eve-channel/index.js +1 -1
  89. package/dist/src/eve-channel/request.d.ts +0 -1
  90. package/dist/src/eve-channel/request.js +2 -2
  91. package/dist/src/execution/agent-sessions/context.d.ts +1 -1
  92. package/dist/src/execution/agent-sessions/context.js +1 -1
  93. package/dist/src/execution/coordination-dispatch-shared.d.ts +3 -0
  94. package/dist/src/execution/coordination-dispatch-shared.js +1 -1
  95. package/dist/src/execution/dynamic-workflow/program-step.d.ts +7 -7
  96. package/dist/src/execution/dynamic-workflow/program-step.js +1 -1
  97. package/dist/src/execution/dynamic-workflow/schema.d.ts +18 -11
  98. package/dist/src/execution/dynamic-workflow/schema.js +1 -1
  99. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  100. package/dist/src/execution/dynamic-workflow/workflow.js +1 -1
  101. package/dist/src/execution/eve-workflow-attributes.d.ts +3 -1
  102. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  103. package/dist/src/execution/invoke-tool.js +1 -1
  104. package/dist/src/execution/sandbox/abort-bound-session.js +1 -1
  105. package/dist/src/execution/sandbox/active-connections.d.ts +28 -0
  106. package/dist/src/execution/sandbox/active-connections.js +1 -0
  107. package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +10 -2
  108. package/dist/src/execution/sandbox/bindings/docker-cli.js +2 -2
  109. package/dist/src/execution/sandbox/bindings/docker-connection.d.ts +15 -0
  110. package/dist/src/execution/sandbox/bindings/docker-connection.js +2 -0
  111. package/dist/src/execution/sandbox/bindings/docker-container.d.ts +2 -0
  112. package/dist/src/execution/sandbox/bindings/docker-container.js +1 -1
  113. package/dist/src/execution/sandbox/bindings/docker-network.d.ts +5 -0
  114. package/dist/src/execution/sandbox/bindings/docker-network.js +1 -1
  115. package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
  116. package/dist/src/execution/sandbox/bindings/docker.d.ts +12 -15
  117. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  118. package/dist/src/execution/sandbox/bindings/just-bash-runtime.d.ts +19 -29
  119. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  120. package/dist/src/execution/sandbox/bindings/just-bash.d.ts +2 -4
  121. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
  122. package/dist/src/execution/sandbox/bindings/local-provider-utils.d.ts +0 -20
  123. package/dist/src/execution/sandbox/bindings/local-provider-utils.js +1 -1
  124. package/dist/src/execution/sandbox/bindings/local.d.ts +4 -6
  125. package/dist/src/execution/sandbox/bindings/local.js +1 -1
  126. package/dist/src/execution/sandbox/bindings/vercel-base-runtime.d.ts +2 -0
  127. package/dist/src/execution/sandbox/bindings/vercel-base-runtime.js +2 -2
  128. package/dist/src/execution/sandbox/bindings/vercel-errors.js +2 -2
  129. package/dist/src/execution/sandbox/bindings/vercel-lifecycle.d.ts +7 -5
  130. package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
  131. package/dist/src/execution/sandbox/bindings/vercel.d.ts +5 -11
  132. package/dist/src/execution/sandbox/bindings/vercel.js +1 -2
  133. package/dist/src/execution/sandbox/development-cleanup.d.ts +0 -1
  134. package/dist/src/execution/sandbox/development-cleanup.js +1 -1
  135. package/dist/src/execution/sandbox/development-lazy-prewarm.js +1 -1
  136. package/dist/src/execution/sandbox/development-run.d.ts +0 -2
  137. package/dist/src/execution/sandbox/development-run.js +1 -1
  138. package/dist/src/execution/sandbox/dockerfile.d.ts +0 -4
  139. package/dist/src/execution/sandbox/dockerfile.js +1 -1
  140. package/dist/src/execution/sandbox/ensure.d.ts +23 -11
  141. package/dist/src/execution/sandbox/ensure.js +1 -1
  142. package/dist/src/execution/sandbox/glob-tool.js +3 -3
  143. package/dist/src/execution/sandbox/grep-tool.js +1 -1
  144. package/dist/src/execution/sandbox/logging-session.js +1 -1
  145. package/dist/src/execution/sandbox/prewarm.d.ts +23 -3
  146. package/dist/src/execution/sandbox/prewarm.js +2 -1
  147. package/dist/src/execution/sandbox/read-file.js +1 -1
  148. package/dist/src/execution/sandbox/require-sandbox.d.ts +3 -2
  149. package/dist/src/execution/sandbox/require-sandbox.js +1 -1
  150. package/dist/src/execution/sandbox/ripgrep-probe.js +1 -1
  151. package/dist/src/execution/sandbox/session.d.ts +10 -20
  152. package/dist/src/execution/sandbox/session.js +2 -2
  153. package/dist/src/execution/session/admission.js +1 -1
  154. package/dist/src/execution/session/checkpoint-migrations.js +1 -1
  155. package/dist/src/execution/session/entry-input.d.ts +5 -4
  156. package/dist/src/execution/session/entry.js +1 -1
  157. package/dist/src/execution/session/handoff-state.d.ts +5 -0
  158. package/dist/src/execution/session/handoff-state.js +1 -0
  159. package/dist/src/execution/session/handoff-steps.d.ts +0 -5
  160. package/dist/src/execution/session/handoff-steps.js +1 -1
  161. package/dist/src/execution/session/handoff.d.ts +2 -1
  162. package/dist/src/execution/session/handoff.js +1 -1
  163. package/dist/src/execution/session/input-queue.d.ts +3 -0
  164. package/dist/src/execution/session/input-queue.js +1 -1
  165. package/dist/src/execution/session/next-input.d.ts +3 -0
  166. package/dist/src/execution/session/next-input.js +1 -1
  167. package/dist/src/execution/session/program.js +1 -1
  168. package/dist/src/execution/session/timeout-control.d.ts +4 -0
  169. package/dist/src/execution/session/timeout-control.js +1 -1
  170. package/dist/src/execution/session/turn-control.d.ts +5 -2
  171. package/dist/src/execution/session/turn-control.js +1 -1
  172. package/dist/src/execution/session/turn.js +1 -1
  173. package/dist/src/execution/session-inbox/inbox.d.ts +9 -1
  174. package/dist/src/execution/session-inbox/inbox.js +1 -1
  175. package/dist/src/execution/session-inbox/protocol.d.ts +2 -1
  176. package/dist/src/execution/session-inbox/protocol.js +1 -1
  177. package/dist/src/execution/session-inbox/resume.d.ts +2 -1
  178. package/dist/src/execution/session-inbox/resume.js +1 -1
  179. package/dist/src/execution/session-prewarm.d.ts +8 -0
  180. package/dist/src/execution/session-prewarm.js +1 -0
  181. package/dist/src/execution/skills/instructions.js +1 -1
  182. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  183. package/dist/src/execution/tools/workflow/body.js +1 -1
  184. package/dist/src/execution/tools/workflow/step-context.d.ts +11 -0
  185. package/dist/src/execution/tools/workflow/step-execution.js +1 -1
  186. package/dist/src/execution/tools/workflow/step.js +1 -1
  187. package/dist/src/execution/workflow-runtime.js +1 -1
  188. package/dist/src/extensions/git/extension/lib/github-shell-schema.js +1 -1
  189. package/dist/src/framework/sources/modules/sandbox.d.ts +1 -1
  190. package/dist/src/harness/attachment-staging.d.ts +0 -7
  191. package/dist/src/harness/attachment-staging.js +1 -1
  192. package/dist/src/harness/hitl/index.d.ts +2 -1
  193. package/dist/src/harness/hitl/index.js +1 -1
  194. package/dist/src/harness/hitl/view.d.ts +1 -0
  195. package/dist/src/harness/hitl/view.js +1 -0
  196. package/dist/src/harness/model-call/run.js +1 -1
  197. package/dist/src/harness/semantic-errors/rules/sandbox.d.ts +3 -5
  198. package/dist/src/harness/semantic-errors/rules/sandbox.js +1 -1
  199. package/dist/src/harness/step/prompt.js +1 -1
  200. package/dist/src/harness/tool-history-repair.d.ts +9 -0
  201. package/dist/src/harness/tool-history-repair.js +1 -0
  202. package/dist/src/harness/tool-model-output.d.ts +19 -3
  203. package/dist/src/harness/tool-model-output.js +1 -1
  204. package/dist/src/internal/application/compiled-artifacts.js +8 -4
  205. package/dist/src/internal/application/optional-package-import.d.ts +10 -0
  206. package/dist/src/internal/application/optional-package-import.js +1 -1
  207. package/dist/src/internal/application/stamped-package-version.js +1 -1
  208. package/dist/src/internal/attachments/limited-read.d.ts +2 -2
  209. package/dist/src/internal/authored-module-build-options.d.ts +6 -0
  210. package/dist/src/internal/authored-module-build-options.js +1 -1
  211. package/dist/src/internal/authored-module-cache.d.ts +10 -0
  212. package/dist/src/internal/authored-module-cache.js +1 -0
  213. package/dist/src/internal/authored-module-graph.js +1 -1
  214. package/dist/src/internal/authored-module-loader.js +1 -1
  215. package/dist/src/internal/authored-relative-extension-resolver.js +1 -1
  216. package/dist/src/internal/bundler/nitro-rolldown.d.ts +3 -1
  217. package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
  218. package/dist/src/internal/bundler/pseudo-packages.d.ts +11 -0
  219. package/dist/src/internal/bundler/pseudo-packages.js +1 -0
  220. package/dist/src/internal/nitro/host/build-extension.d.ts +6 -0
  221. package/dist/src/internal/nitro/host/build-extension.js +2 -2
  222. package/dist/src/internal/nitro/host/compiled-sandbox-provider-prune-plugin.d.ts +3 -1
  223. package/dist/src/internal/nitro/host/compiled-sandbox-provider-prune-plugin.js +3 -5
  224. package/dist/src/internal/nitro/host/create-application-nitro.d.ts +2 -3
  225. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  226. package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.d.ts +2 -0
  227. package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.js +1 -1
  228. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  229. package/dist/src/internal/nitro/host/dev-build-host.d.ts +83 -0
  230. package/dist/src/internal/nitro/host/dev-build-host.js +1 -0
  231. package/dist/src/internal/nitro/host/dev-build-operations.d.ts +6 -0
  232. package/dist/src/internal/nitro/host/dev-build-operations.js +1 -0
  233. package/dist/src/internal/nitro/host/dev-build-process.d.ts +1 -0
  234. package/dist/src/internal/nitro/host/dev-build-process.js +1 -0
  235. package/dist/src/internal/nitro/host/development-runtime-prune-plugin.d.ts +4 -1
  236. package/dist/src/internal/nitro/host/development-runtime-prune-plugin.js +3 -2
  237. package/dist/src/internal/nitro/host/drained-nitro-dev-server.d.ts +13 -0
  238. package/dist/src/internal/nitro/host/drained-nitro-dev-server.js +1 -1
  239. package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.js +1 -1
  240. package/dist/src/internal/nitro/host/prepare-application-host.d.ts +3 -0
  241. package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
  242. package/dist/src/internal/nitro/host/sandbox-shutdown-plugin.js +1 -1
  243. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  244. package/dist/src/internal/nitro/host/start-production-server.js +3 -3
  245. package/dist/src/internal/nitro/host/workflow-sandbox-runtime-plugin.js +1 -1
  246. package/dist/src/internal/nitro/host.js +1 -1
  247. package/dist/src/internal/workflow/local-world-delivery-auth.d.ts +17 -0
  248. package/dist/src/internal/workflow/local-world-delivery-auth.js +1 -0
  249. package/dist/src/internal/workflow/queue-namespace.d.ts +2 -0
  250. package/dist/src/internal/workflow/queue-namespace.js +1 -1
  251. package/dist/src/internal/workflow-bundle/builder-support.d.ts +0 -1
  252. package/dist/src/internal/workflow-bundle/builder-support.js +2 -2
  253. package/dist/src/internal/workflow-bundle/builder.js +2 -2
  254. package/dist/src/internal/workflow-bundle/vercel-workflow-output.d.ts +1 -1
  255. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  256. package/dist/src/protocol/prewarm-session.d.ts +14 -0
  257. package/dist/src/protocol/prewarm-session.js +1 -0
  258. package/dist/src/protocol/routes.d.ts +2 -2
  259. package/dist/src/public/channels/discord/authorization.d.ts +45 -0
  260. package/dist/src/public/channels/discord/authorization.js +3 -0
  261. package/dist/src/public/channels/discord/defaults.d.ts +14 -3
  262. package/dist/src/public/channels/discord/defaults.js +2 -2
  263. package/dist/src/public/channels/discord/discordChannel.d.ts +15 -1
  264. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  265. package/dist/src/public/channels/discord/gateway/connection.d.ts +26 -0
  266. package/dist/src/public/channels/discord/gateway/connection.js +1 -0
  267. package/dist/src/public/channels/discord/gateway/forwarder.d.ts +14 -0
  268. package/dist/src/public/channels/discord/gateway/forwarder.js +1 -0
  269. package/dist/src/public/channels/discord/gateway/index.d.ts +59 -0
  270. package/dist/src/public/channels/discord/gateway/index.js +1 -0
  271. package/dist/src/public/channels/discord/inbound.d.ts +10 -3
  272. package/dist/src/public/channels/discord/inbound.js +2 -2
  273. package/dist/src/public/channels/discord/index.d.ts +3 -2
  274. package/dist/src/public/channels/discord/index.js +1 -1
  275. package/dist/src/public/channels/discord/messages.d.ts +116 -0
  276. package/dist/src/public/channels/discord/messages.js +2 -0
  277. package/dist/src/public/channels/github/checkout.js +1 -1
  278. package/dist/src/public/channels/linq/linqChannel.d.ts +4 -1
  279. package/dist/src/public/channels/linq/linqChannel.js +1 -1
  280. package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -1
  281. package/dist/src/public/channels/same-environment-oidc.d.ts +7 -0
  282. package/dist/src/public/channels/same-environment-oidc.js +1 -0
  283. package/dist/src/public/definitions/channel.js +1 -1
  284. package/dist/src/public/definitions/sandbox.d.ts +1 -1
  285. package/dist/src/public/next/server.js +1 -1
  286. package/dist/src/public/sandbox/docker-sandbox.d.ts +6 -1
  287. package/dist/src/public/sandbox/docker.d.ts +1 -8
  288. package/dist/src/public/sandbox/index.d.ts +3 -3
  289. package/dist/src/public/sandbox/just-bash-sandbox.d.ts +87 -7
  290. package/dist/src/public/sandbox/just-bash.d.ts +1 -1
  291. package/dist/src/public/sandbox/provider.d.ts +5 -1
  292. package/dist/src/public/sandbox/provider.js +1 -1
  293. package/dist/src/public/sandbox/vercel-sandbox.d.ts +16 -9
  294. package/dist/src/public/sandbox/vercel.d.ts +0 -1
  295. package/dist/src/public/sandbox/vercel.js +1 -1
  296. package/dist/src/public/tools/agent.d.ts +8 -1
  297. package/dist/src/public/tools/agent.js +1 -1
  298. package/dist/src/react/use-eve-agent.d.ts +1 -1
  299. package/dist/src/runtime/agent/resolve-model.js +1 -1
  300. package/dist/src/runtime/connections/openapi-client.d.ts +2 -0
  301. package/dist/src/runtime/connections/openapi-client.js +1 -1
  302. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  303. package/dist/src/runtime/resolve-agent.js +1 -1
  304. package/dist/src/runtime/resolve-channel.js +1 -1
  305. package/dist/src/runtime/resolve-sandbox.js +1 -1
  306. package/dist/src/runtime/sandbox/prepared-artifacts.js +1 -1
  307. package/dist/src/runtime/sandbox/registry.d.ts +2 -0
  308. package/dist/src/runtime/sandbox/registry.js +1 -1
  309. package/dist/src/runtime/subagents/workflow.d.ts +6 -0
  310. package/dist/src/runtime/subagents/workflow.js +1 -1
  311. package/dist/src/runtime/workspace/seed-files.d.ts +9 -12
  312. package/dist/src/runtime/workspace/seed-files.js +1 -1
  313. package/dist/src/runtime/workspace/spec.d.ts +1 -1
  314. package/dist/src/runtime/workspace/spec.js +1 -1
  315. package/dist/src/runtime/workspace/types.d.ts +2 -6
  316. package/dist/src/sandbox/provider.d.ts +185 -0
  317. package/dist/src/sandbox/provider.js +1 -0
  318. package/dist/src/sandbox/providers/default.d.ts +20 -19
  319. package/dist/src/sandbox/providers/default.js +1 -1
  320. package/dist/src/sandbox/providers/docker.d.ts +5 -2
  321. package/dist/src/sandbox/providers/docker.js +1 -1
  322. package/dist/src/sandbox/providers/just-bash.d.ts +4 -3
  323. package/dist/src/sandbox/providers/just-bash.js +1 -1
  324. package/dist/src/sandbox/providers/vercel.d.ts +4 -10
  325. package/dist/src/sandbox/providers/vercel.js +1 -1
  326. package/dist/src/sandbox/providers.d.ts +0 -1
  327. package/dist/src/sandbox/providers.js +1 -1
  328. package/dist/src/sandbox/state.d.ts +44 -0
  329. package/dist/src/sandbox/state.js +1 -1
  330. package/dist/src/self-modification/deployed-sandbox.d.ts +4 -9
  331. package/dist/src/self-modification/deployed-sandbox.js +1 -1
  332. package/dist/src/self-modification/filesystem.d.ts +3 -3
  333. package/dist/src/self-modification/remote/config.d.ts +2 -2
  334. package/dist/src/self-modification/remote/config.js +1 -1
  335. package/dist/src/self-modification/setup.d.ts +0 -1
  336. package/dist/src/self-modification/setup.js +8 -8
  337. package/dist/src/setup/integrations/discord/api.d.ts +7 -0
  338. package/dist/src/setup/integrations/discord/api.js +1 -1
  339. package/dist/src/setup/integrations/discord/daemon.d.ts +18 -0
  340. package/dist/src/setup/integrations/discord/daemon.js +21 -0
  341. package/dist/src/setup/integrations/discord/setup.d.ts +24 -4
  342. package/dist/src/setup/integrations/discord/setup.js +5 -4
  343. package/dist/src/setup/integrations/self-modification/setup.js +1 -1
  344. package/dist/src/setup/scaffold/create/project.js +1 -1
  345. package/dist/src/setup/scaffold/update/web-options.js +1 -1
  346. package/dist/src/setup/scaffold/version-tokens.d.ts +0 -1
  347. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  348. package/dist/src/shared/agent-definition.d.ts +2 -0
  349. package/dist/src/shared/built-server-start-failure.d.ts +12 -0
  350. package/dist/src/shared/built-server-start-failure.js +3 -0
  351. package/dist/src/shared/framework-eve-server.d.ts +2 -0
  352. package/dist/src/shared/framework-eve-server.js +2 -2
  353. package/dist/src/shared/sandbox-environment.d.ts +4 -10
  354. package/dist/src/shared/sandbox-environment.js +1 -1
  355. package/dist/src/shared/sandbox-network-policy.d.ts +45 -9
  356. package/dist/src/shared/sandbox-provider.d.ts +0 -103
  357. package/dist/src/shared/sandbox-provider.js +1 -1
  358. package/dist/src/shared/sandbox-recorded-data-error.d.ts +4 -0
  359. package/dist/src/shared/sandbox-recorded-data-error.js +1 -0
  360. package/dist/src/shared/sandbox-session-gone-error.d.ts +12 -0
  361. package/dist/src/shared/sandbox-session-gone-error.js +1 -0
  362. package/dist/src/shared/sandbox-session.d.ts +97 -83
  363. package/dist/src/shared/sandbox-template-error.d.ts +19 -4
  364. package/dist/src/shared/sandbox-template-error.js +1 -1
  365. package/dist/src/shared/sandbox-tool-session-error.d.ts +4 -0
  366. package/dist/src/shared/sandbox-tool-session-error.js +1 -0
  367. package/dist/src/shared/skill-package.js +1 -1
  368. package/dist/src/shared/skill-paths.d.ts +4 -5
  369. package/dist/src/shared/skill-paths.js +2 -2
  370. package/dist/src/shared/workflow-sandbox.d.ts +4 -41
  371. package/dist/src/shared/workflow-sandbox.js +1 -1
  372. package/dist/src/svelte/index.js +1 -1
  373. package/dist/src/svelte/use-eve-agent.d.ts +1 -1
  374. package/dist/src/svelte/use-eve-agent.js +1 -1
  375. package/dist/src/tools/model-output.d.ts +23 -5
  376. package/dist/src/tools/model-output.js +1 -1
  377. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  378. package/dist/src/tools/provided/glob.js +1 -1
  379. package/dist/src/tools/provided/grep.js +1 -1
  380. package/dist/src/tools/provided/read-file.js +1 -1
  381. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  382. package/dist/src/tools/provided/workflow.js +1 -1
  383. package/dist/src/tools/provided/write-file.js +1 -1
  384. package/dist/src/tools/workflow-definition.d.ts +19 -4
  385. package/dist/src/vue/index.js +1 -1
  386. package/dist/src/vue/use-eve-agent.d.ts +1 -1
  387. package/dist/src/vue/use-eve-agent.js +1 -1
  388. package/docs/channels/custom.mdx +3 -3
  389. package/docs/channels/discord.mdx +279 -7
  390. package/docs/channels/eve.mdx +13 -2
  391. package/docs/channels/linq.mdx +2 -2
  392. package/docs/channels/mcp.mdx +2 -2
  393. package/docs/channels/overview.mdx +1 -1
  394. package/docs/channels/photon.mdx +1 -1
  395. package/docs/concepts/built-in-tools.md +31 -8
  396. package/docs/concepts/execution-model-and-durability.mdx +6 -101
  397. package/docs/concepts/security-model.md +2 -0
  398. package/docs/concepts/sessions-runs-and-streaming.md +44 -36
  399. package/docs/connections/openapi.mdx +2 -0
  400. package/docs/evals/reporters.mdx +1 -1
  401. package/docs/evals/running.mdx +1 -1
  402. package/docs/guides/client/messages.mdx +1 -1
  403. package/docs/guides/deployment/overview.md +4 -4
  404. package/docs/guides/deployment/self-hosting.md +50 -1
  405. package/docs/guides/dev-tui.md +1 -1
  406. package/docs/guides/dynamic-capabilities.md +1 -1
  407. package/docs/guides/frontend/overview.mdx +26 -6
  408. package/docs/guides/instrumentation/agent-runs.mdx +16 -0
  409. package/docs/guides/self-modification.md +1 -1
  410. package/docs/guides/session-context.md +1 -1
  411. package/docs/instructions.mdx +1 -1
  412. package/docs/reference/agent-files.md +3 -3
  413. package/docs/reference/cli.md +7 -2
  414. package/docs/reference/typescript-api.md +9 -3
  415. package/docs/sandbox/custom-providers.mdx +254 -0
  416. package/docs/sandbox/default.mdx +71 -4
  417. package/docs/sandbox/docker.mdx +15 -3
  418. package/docs/sandbox/index.mdx +27 -103
  419. package/docs/sandbox/just-bash.mdx +54 -0
  420. package/docs/sandbox/meta.json +9 -1
  421. package/docs/sandbox/troubleshooting.mdx +215 -0
  422. package/docs/sandbox/vercel.mdx +48 -7
  423. package/docs/skills.mdx +1 -1
  424. package/docs/subagents/index.mdx +2 -2
  425. package/docs/tools/overview.mdx +19 -0
  426. package/docs/tools/workflows.mdx +73 -5
  427. package/docs/tutorial/run-analysis.mdx +2 -2
  428. package/package.json +14 -20
  429. package/dist/src/compiled/@ai-sdk/code-mode/_run.d.ts +0 -1
  430. package/dist/src/compiled/@ai-sdk/code-mode/index.d.ts +0 -325
  431. package/dist/src/compiled/@ai-sdk/code-mode/index.js +0 -660
  432. package/dist/src/compiled/_chunks/workflow/dist-CyBgVS7g.js +0 -1
  433. package/dist/src/compiled/_chunks/workflow/dist-T5NnW-0k.js +0 -3
  434. package/dist/src/compiled/_chunks/workflow/helpers-DlLD3ov_.js +0 -1
  435. package/dist/src/compiled/_chunks/workflow/private-tQUuwBoQ.js +0 -1
  436. package/dist/src/compiled/_chunks/workflow/resume-hook-DMsV_b4n.js +0 -1
  437. package/dist/src/compiled/_chunks/workflow/serialization-DPdYS_w2.js +0 -16
  438. package/dist/src/compiled/_chunks/workflow/sleep-BY6leHh8.js +0 -1
  439. package/dist/src/compiled/_chunks/workflow/workflow-routes-CwqB063q.js +0 -1
  440. package/dist/src/execution/sandbox/active-handles.d.ts +0 -32
  441. package/dist/src/execution/sandbox/active-handles.js +0 -1
  442. package/dist/src/execution/sandbox/bindings/docker-session.d.ts +0 -6
  443. package/dist/src/execution/sandbox/bindings/docker-session.js +0 -2
  444. package/dist/src/execution/sandbox/bindings/immutable-resources.d.ts +0 -15
  445. package/dist/src/execution/sandbox/bindings/immutable-resources.js +0 -2
  446. package/dist/src/execution/sandbox/bindings/microsandbox-create.d.ts +0 -12
  447. package/dist/src/execution/sandbox/bindings/microsandbox-create.js +0 -1
  448. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.d.ts +0 -42
  449. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +0 -1
  450. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.d.ts +0 -29
  451. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.js +0 -1
  452. package/dist/src/execution/sandbox/bindings/microsandbox-network.d.ts +0 -18
  453. package/dist/src/execution/sandbox/bindings/microsandbox-network.js +0 -1
  454. package/dist/src/execution/sandbox/bindings/microsandbox-options.d.ts +0 -37
  455. package/dist/src/execution/sandbox/bindings/microsandbox-options.js +0 -1
  456. package/dist/src/execution/sandbox/bindings/microsandbox-platform.d.ts +0 -21
  457. package/dist/src/execution/sandbox/bindings/microsandbox-platform.js +0 -21
  458. package/dist/src/execution/sandbox/bindings/microsandbox-process.d.ts +0 -3
  459. package/dist/src/execution/sandbox/bindings/microsandbox-process.js +0 -1
  460. package/dist/src/execution/sandbox/bindings/microsandbox-provider-state.d.ts +0 -11
  461. package/dist/src/execution/sandbox/bindings/microsandbox-provider-state.js +0 -1
  462. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +0 -82
  463. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +0 -1
  464. package/dist/src/execution/sandbox/bindings/microsandbox-templates.d.ts +0 -12
  465. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +0 -1
  466. package/dist/src/execution/sandbox/bindings/microsandbox.d.ts +0 -16
  467. package/dist/src/execution/sandbox/bindings/microsandbox.js +0 -1
  468. package/dist/src/execution/sandbox/provider-host-development.d.ts +0 -2
  469. package/dist/src/execution/sandbox/provider-host-development.js +0 -1
  470. package/dist/src/execution/sandbox/provider-host.d.ts +0 -2
  471. package/dist/src/execution/sandbox/provider-host.js +0 -1
  472. package/dist/src/execution/tool-session/sandbox.d.ts +0 -22
  473. package/dist/src/execution/tool-session/sandbox.js +0 -1
  474. package/dist/src/public/sandbox/microsandbox-sandbox.d.ts +0 -48
  475. package/dist/src/public/sandbox/microsandbox-sandbox.js +0 -1
  476. package/dist/src/public/sandbox/microsandbox.d.ts +0 -9
  477. package/dist/src/public/sandbox/microsandbox.js +0 -1
  478. package/dist/src/sandbox/providers/microsandbox.d.ts +0 -12
  479. package/dist/src/sandbox/providers/microsandbox.js +0 -1
  480. package/docs/sandbox/microsandbox.mdx +0 -31
@@ -1,4 +1,4 @@
1
- import{builtinModules}from"node:module";import{mkdir,readFile,readdir}from"node:fs/promises";import{existsSync}from"node:fs";import{dirname,extname,join,relative,resolve}from"node:path";import{resolvePackageRoot,resolveWorkflowModulePath}from"#internal/application/package.js";import{normalizeEsmImportSpecifier}from"#internal/application/import-specifier.js";import{WORKFLOW_REGISTRY_GLOBAL}from"#execution/workflow-registry.js";import{atomicWriteFile}from"#shared/atomic-write-file.js";import{applyWorkflowTransform,getImportPath}from"#internal/workflow-bundle/workflow-builders.js";const WORKFLOW_VIRTUAL_ENTRY_ID=`\0eve-workflow-entry`,PSEUDO_PACKAGES=new Set([`server-only`,`client-only`,`next/dist/compiled/server-only`,`next/dist/compiled/client-only`]),NODE_BUILTIN_MODULES=new Set([...builtinModules,...builtinModules.map(e=>`node:${e}`)]),WORKFLOW_SOURCE_EXTENSIONS=[`.ts`,`.tsx`,`.mts`,`.cts`,`.js`,`.jsx`,`.mjs`,`.cjs`];function isWorkflowSourceFile(e){return WORKFLOW_SOURCE_EXTENSIONS.includes(extname(e))}const IGNORED_INPUT_DIRECTORIES=new Set([`node_modules`,`.git`,`.next`,`.nuxt`,`.output`,`.vercel`,`.workflow-vitest`,`.well-known`,`.svelte-kit`,`.turbo`,`.cache`,`.yarn`,`.pnpm-store`]);async function collectWorkflowInputFiles(e){let t=[];async function visit(e){let n;try{n=await readdir(e,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}for(let r of n){if(r.isDirectory()){IGNORED_INPUT_DIRECTORIES.has(r.name)||await visit(join(e,r.name));continue}r.isFile()&&isWorkflowSourceFile(r.name)&&t.push(join(e,r.name))}}return await visit(e),t}function createWorkflowImport(e,t){let{importPath:n,isPackage:r}=getImportPath(e,t);return r?`import ${JSON.stringify(n)};`:`import ${JSON.stringify(toRelativeImportSpecifier(t,e))};`}function createWorkflowVirtualEntryPlugin(e){return{name:`eve-workflow-virtual-entry`,resolveId(e){if(e===`\0eve-workflow-entry`)return{id:e}},load(t){if(t===`\0eve-workflow-entry`)return{code:e,moduleSideEffects:!0,moduleType:`js`}}}}function createWorkflowPseudoPackagePlugin(){return{name:`eve-workflow-pseudo-packages`,resolveId(e){if(PSEUDO_PACKAGES.has(e))return{id:`\0eve-workflow-pseudo-package:${e}`}},load(e){if(e.startsWith(`\0eve-workflow-pseudo-package:`))return{code:``,moduleType:`js`}}}}function createWorkflowDriverAliasPlugin(e){return{name:`eve-workflow-driver-aliases`,resolveId(t,n){if(t===`workflow/errors`)return resolveWorkflowModulePath(t);if(t===`workflow/api`||t===`workflow/runtime`){let e=n?` (imported by "${n}")`:``;throw Error(`Workflow bundle cannot import "${t}"${e}: the runtime API is not available inside a workflow body. Call it from a "use step" function and await that step from the body.`)}if(t===`workflow`)return resolveFirstExistingPath([join(e,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.ts`),join(e,`dist`,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.js`)])}}}function createEvePackageImportsPlugin(e,t={}){let n=[...new Set([e,resolvePackageRoot()])];return{name:`eve-package-imports`,resolveId(e){let r=e.match(/^#compiled\/(.+)$/)?.[1];if(r!==void 0)return t.workflowCondition===!0&&r===`@workflow/core/index.js`?resolveFirstExistingPath(n.flatMap(e=>[join(e,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.ts`),join(e,`dist`,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.js`)])):resolveFirstExistingPath(n.flatMap(e=>[join(e,`.generated`,`compiled`,r),join(e,`dist`,`src`,`compiled`,r)]));let i=e.match(/^#(.+)\.js$/)?.[1];if(i!==void 0)return resolveFirstExistingPath(n.flatMap(e=>WORKFLOW_SOURCE_EXTENSIONS.flatMap(t=>[join(e,`src`,`${i}${t}`),join(e,`dist`,`src`,`${i}${t}`)])))}}}function createWorkflowTransformPlugin(e){let t=new Set(e.sideEffectFiles?.map(e=>e.replaceAll(`\\`,`/`))??[]);return{name:`eve-workflow-transform`,async load(n){if(!isJavaScriptLikePath(n))return;let r=await readFile(n,`utf8`),i=createManifestRelativeFilepath(e.workingDir,n),a=await applyWorkflowTransform(i,r.replace(/require\(\s*(['"])server-only\1\s*\)/g,`void 0`).replace(/require\(\s*(['"])client-only\1\s*\)/g,`void 0`),e.mode??`workflow`,n,e.projectRoot);return mergeWorkflowManifest(e.manifest,a.workflowManifest),{code:a.code,map:null,moduleSideEffects:t.has(n.replaceAll(`\\`,`/`))||void 0}}}}function createWorkflowNodeBuiltinGuardPlugin(){return{name:`eve-workflow-node-builtins`,resolveId(e,t){let n=e.startsWith(`node:`)?e.slice(5):e;if(!NODE_BUILTIN_MODULES.has(e)&&!NODE_BUILTIN_MODULES.has(n))return;let r=t?` (imported by "${t}")`:``;throw Error(`Workflow bundle cannot import Node.js builtin "${e}"${r}. Move Node.js APIs behind a "use step" function, or keep the importing module out of the workflow driver body (only reachable through a "use step").`)}}}async function bundleFinalWorkflowOutput(e){let t=createWorkflowEntrypointSource({code:e.code,queueNamespace:e.queueNamespace,stepRegistrationsImport:e.stepRegistrationsPath===void 0?void 0:toRelativeImportSpecifier(dirname(e.outfile),e.stepRegistrationsPath)});await writeWorkflowBundleAtomically(e.outfile,t)}const WORKFLOW_REGISTRY_BANNER=`globalThis.${WORKFLOW_REGISTRY_GLOBAL} = new Map();`;function composeWorkflowDriverCode(e){let t=e.map(e=>e.trim()).filter(e=>e.length>0).map(e=>`(function () {\n${e}\n})();`);return[WORKFLOW_REGISTRY_BANNER,...t].join(`
1
+ import{builtinModules}from"node:module";import{mkdir,readFile,readdir}from"node:fs/promises";import{existsSync}from"node:fs";import{dirname,extname,join,relative,resolve}from"node:path";import{resolvePackageRoot,resolveWorkflowModulePath}from"#internal/application/package.js";import{normalizeEsmImportSpecifier}from"#internal/application/import-specifier.js";import{WORKFLOW_REGISTRY_GLOBAL}from"#execution/workflow-registry.js";import{atomicWriteFile}from"#shared/atomic-write-file.js";import{applyWorkflowTransform,getImportPath}from"#internal/workflow-bundle/workflow-builders.js";const WORKFLOW_VIRTUAL_ENTRY_ID=`\0eve-workflow-entry`,NODE_BUILTIN_MODULES=new Set([...builtinModules,...builtinModules.map(e=>`node:${e}`)]),WORKFLOW_SOURCE_EXTENSIONS=[`.ts`,`.tsx`,`.mts`,`.cts`,`.js`,`.jsx`,`.mjs`,`.cjs`];function isWorkflowSourceFile(e){return WORKFLOW_SOURCE_EXTENSIONS.includes(extname(e))}const IGNORED_INPUT_DIRECTORIES=new Set([`node_modules`,`.git`,`.next`,`.nuxt`,`.output`,`.vercel`,`.workflow-vitest`,`.well-known`,`.svelte-kit`,`.turbo`,`.cache`,`.yarn`,`.pnpm-store`]);async function collectWorkflowInputFiles(e){let t=[];async function visit(e){let n;try{n=await readdir(e,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}for(let r of n){if(r.isDirectory()){IGNORED_INPUT_DIRECTORIES.has(r.name)||await visit(join(e,r.name));continue}r.isFile()&&isWorkflowSourceFile(r.name)&&t.push(join(e,r.name))}}return await visit(e),t}function createWorkflowImport(e,t){let{importPath:n,isPackage:r}=getImportPath(e,t);return r?`import ${JSON.stringify(n)};`:`import ${JSON.stringify(toRelativeImportSpecifier(t,e))};`}function createWorkflowVirtualEntryPlugin(e){return{name:`eve-workflow-virtual-entry`,resolveId(e){if(e===`\0eve-workflow-entry`)return{id:e}},load(t){if(t===`\0eve-workflow-entry`)return{code:e,moduleSideEffects:!0,moduleType:`js`}}}}function createWorkflowDriverAliasPlugin(e){return{name:`eve-workflow-driver-aliases`,resolveId(t,n){if(t===`workflow/errors`)return resolveWorkflowModulePath(t);if(t===`workflow/api`||t===`workflow/runtime`){let e=n?` (imported by "${n}")`:``;throw Error(`Workflow bundle cannot import "${t}"${e}: the runtime API is not available inside a workflow body. Call it from a "use step" function and await that step from the body.`)}if(t===`workflow`)return resolveFirstExistingPath([join(e,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.ts`),join(e,`dist`,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.js`)])}}}function createEvePackageImportsPlugin(e,t={}){let n=[...new Set([e,resolvePackageRoot()])];return{name:`eve-package-imports`,resolveId(e){let r=e.match(/^#compiled\/(.+)$/)?.[1];if(r!==void 0)return t.workflowCondition===!0&&r===`@workflow/core/index.js`?resolveFirstExistingPath(n.flatMap(e=>[join(e,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.ts`),join(e,`dist`,`src`,`internal`,`workflow-bundle`,`workflow-core-shim.js`)])):resolveFirstExistingPath(n.flatMap(e=>[join(e,`.generated`,`compiled`,r),join(e,`dist`,`src`,`compiled`,r)]));let i=e.match(/^#(.+)\.js$/)?.[1];if(i!==void 0)return resolveFirstExistingPath(n.flatMap(e=>WORKFLOW_SOURCE_EXTENSIONS.flatMap(t=>[join(e,`src`,`${i}${t}`),join(e,`dist`,`src`,`${i}${t}`)])))}}}function createWorkflowTransformPlugin(e){let t=new Set(e.sideEffectFiles?.map(e=>e.replaceAll(`\\`,`/`))??[]);return{name:`eve-workflow-transform`,async load(n){if(!isJavaScriptLikePath(n))return;let r=await readFile(n,`utf8`),i=createManifestRelativeFilepath(e.workingDir,n),a=await applyWorkflowTransform(i,r.replace(/require\(\s*(['"])server-only\1\s*\)/g,`void 0`).replace(/require\(\s*(['"])client-only\1\s*\)/g,`void 0`),e.mode??`workflow`,n,e.projectRoot);return mergeWorkflowManifest(e.manifest,a.workflowManifest),{code:a.code,map:null,moduleSideEffects:t.has(n.replaceAll(`\\`,`/`))||void 0}}}}function createWorkflowNodeBuiltinGuardPlugin(){return{name:`eve-workflow-node-builtins`,resolveId(e,t){let n=e.startsWith(`node:`)?e.slice(5):e;if(!NODE_BUILTIN_MODULES.has(e)&&!NODE_BUILTIN_MODULES.has(n))return;let r=t?` (imported by "${t}")`:``;throw Error(`Workflow bundle cannot import Node.js builtin "${e}"${r}. Move Node.js APIs behind a "use step" function, or keep the importing module out of the workflow driver body (only reachable through a "use step").`)}}}async function bundleFinalWorkflowOutput(e){let t=createWorkflowEntrypointSource({code:e.code,queueNamespace:e.queueNamespace,stepRegistrationsImport:e.stepRegistrationsPath===void 0?void 0:toRelativeImportSpecifier(dirname(e.outfile),e.stepRegistrationsPath)});await writeWorkflowBundleAtomically(e.outfile,t)}const WORKFLOW_REGISTRY_BANNER=`globalThis.${WORKFLOW_REGISTRY_GLOBAL} = new Map();`;function composeWorkflowDriverCode(e){let t=e.map(e=>e.trim()).filter(e=>e.length>0).map(e=>`(function () {\n${e}\n})();`);return[WORKFLOW_REGISTRY_BANNER,...t].join(`
2
2
  `)}function createWorkflowEntrypointSource(e){let t=normalizeEsmImportSpecifier(resolveWorkflowModulePath(`workflow/runtime`)),n=Buffer.from(e.code.endsWith(`
3
3
  `)?e.code:`${e.code}\n`,`utf8`).toString(`base64`).match(/.{1,16384}/gu)??[``],r=e.stepRegistrationsImport===void 0?``:`import { __steps_registered as __eveWorkflowStepsRegistered } from ${JSON.stringify(e.stepRegistrationsImport)};\nvoid __eveWorkflowStepsRegistered;`;return`// Generated by eve. Do not edit by hand.
4
4
  import { workflowEntrypoint } from ${JSON.stringify(t)};
@@ -7,4 +7,4 @@ ${r}
7
7
  const workflowCode = Buffer.from(${JSON.stringify(n)}.join(""), "base64").toString("utf8");
8
8
 
9
9
  export const POST = workflowEntrypoint(workflowCode, { namespace: ${JSON.stringify(e.queueNamespace)} });
10
- `}function convertStepsManifest(e){let t={};for(let[n,r]of Object.entries(e??{})){t[n]={};for(let[e,i]of Object.entries(r))t[n][e]={stepId:i.stepId}}return t}function convertWorkflowsManifest(e){let t={};for(let[n,r]of Object.entries(e??{})){t[n]={};for(let[e,i]of Object.entries(r))t[n][e]={graph:{edges:[],nodes:[]},workflowId:i.workflowId}}return t}function convertClassesManifest(e){let t={};for(let[n,r]of Object.entries(e??{})){t[n]={};for(let[e,i]of Object.entries(r))t[n][e]={classId:i.classId}}return t}function toRelativeImportSpecifier(e,t){let n=relative(e,t).replaceAll(`\\`,`/`);return n.startsWith(`./`)||n.startsWith(`../`)?n:`./${n}`}function resolveFirstExistingPath(e){for(let t of e)if(existsSync(t))return{id:resolve(t)}}async function writeWorkflowBundleAtomically(e,t){await mkdir(dirname(e),{recursive:!0}),await atomicWriteFile(e,t)}function mergeWorkflowManifest(e,t){e.steps=mergeWorkflowManifestSection(e.steps,t.steps),e.workflows=mergeWorkflowManifestSection(e.workflows,t.workflows),e.classes=mergeWorkflowManifestSection(e.classes,t.classes)}function mergeWorkflowManifestSection(e,t){if(t===void 0)return e;let n={...e};for(let[e,r]of Object.entries(t))n[e]={...n[e],...r};return n}function createManifestRelativeFilepath(e,t){let n=t.replaceAll(`\\`,`/`),r=e.replaceAll(`\\`,`/`),i=relative(r,n).replaceAll(`\\`,`/`);return i.startsWith(`../`)&&(i=i.split(`/`).filter(e=>e!==`..`).join(`/`)),i}function isJavaScriptLikePath(e){return/\.(?:[cm]?[jt]sx?)$/.test(e)}export{WORKFLOW_SOURCE_EXTENSIONS,WORKFLOW_VIRTUAL_ENTRY_ID,bundleFinalWorkflowOutput,collectWorkflowInputFiles,composeWorkflowDriverCode,convertClassesManifest,convertStepsManifest,convertWorkflowsManifest,createEvePackageImportsPlugin,createWorkflowDriverAliasPlugin,createWorkflowEntrypointSource,createWorkflowImport,createWorkflowNodeBuiltinGuardPlugin,createWorkflowPseudoPackagePlugin,createWorkflowTransformPlugin,createWorkflowVirtualEntryPlugin,isWorkflowSourceFile,mergeWorkflowManifest};
10
+ `}function convertStepsManifest(e){let t={};for(let[n,r]of Object.entries(e??{})){t[n]={};for(let[e,i]of Object.entries(r))t[n][e]={stepId:i.stepId}}return t}function convertWorkflowsManifest(e){let t={};for(let[n,r]of Object.entries(e??{})){t[n]={};for(let[e,i]of Object.entries(r))t[n][e]={graph:{edges:[],nodes:[]},workflowId:i.workflowId}}return t}function convertClassesManifest(e){let t={};for(let[n,r]of Object.entries(e??{})){t[n]={};for(let[e,i]of Object.entries(r))t[n][e]={classId:i.classId}}return t}function toRelativeImportSpecifier(e,t){let n=relative(e,t).replaceAll(`\\`,`/`);return n.startsWith(`./`)||n.startsWith(`../`)?n:`./${n}`}function resolveFirstExistingPath(e){for(let t of e)if(existsSync(t))return{id:resolve(t)}}async function writeWorkflowBundleAtomically(e,t){await mkdir(dirname(e),{recursive:!0}),await atomicWriteFile(e,t)}function mergeWorkflowManifest(e,t){e.steps=mergeWorkflowManifestSection(e.steps,t.steps),e.workflows=mergeWorkflowManifestSection(e.workflows,t.workflows),e.classes=mergeWorkflowManifestSection(e.classes,t.classes)}function mergeWorkflowManifestSection(e,t){if(t===void 0)return e;let n={...e};for(let[e,r]of Object.entries(t))n[e]={...n[e],...r};return n}function createManifestRelativeFilepath(e,t){let n=t.replaceAll(`\\`,`/`),r=e.replaceAll(`\\`,`/`),i=relative(r,n).replaceAll(`\\`,`/`);return i.startsWith(`../`)&&(i=i.split(`/`).filter(e=>e!==`..`).join(`/`)),i}function isJavaScriptLikePath(e){return/\.(?:[cm]?[jt]sx?)$/.test(e)}export{WORKFLOW_SOURCE_EXTENSIONS,WORKFLOW_VIRTUAL_ENTRY_ID,bundleFinalWorkflowOutput,collectWorkflowInputFiles,composeWorkflowDriverCode,convertClassesManifest,convertStepsManifest,convertWorkflowsManifest,createEvePackageImportsPlugin,createWorkflowDriverAliasPlugin,createWorkflowEntrypointSource,createWorkflowImport,createWorkflowNodeBuiltinGuardPlugin,createWorkflowTransformPlugin,createWorkflowVirtualEntryPlugin,isWorkflowSourceFile,mergeWorkflowManifest};
@@ -1,2 +1,2 @@
1
- import{mkdir,readFile,writeFile}from"node:fs/promises";import{dirname,join,resolve}from"node:path";import{resolvePackageSourceDirectoryPath,resolveWorkflowModulePath}from"#internal/application/package.js";import{createAuthoredPackageTsConfigPathsPlugin}from"#internal/authored-package-tsconfig-paths.js";import{createAuthoredRelativeExtensionResolverPlugin}from"#internal/authored-relative-extension-resolver.js";import{buildSingleRolldownChunk}from"#internal/bundler/nitro-rolldown.js";import{findWorkflowPatterns}from"#internal/workflow-bundle/workflow-builders.js";import{mapConcurrent}from"#shared/map-concurrent.js";import{onVendoredDependencyLog}from"#internal/bundler/vendored-dependency-log.js";import{prepareEveVersionedCacheDirectory,writeEveVersionedCacheMetadata}from"#internal/application/cache-metadata.js";import{WORKFLOW_BUILDER_DEFERRED_PACKAGES,WORKFLOW_STEP_EXTERNAL_PACKAGES}from"#internal/workflow-bundle/vercel-workflow-output.js";import{deriveEveWorkflowQueueNamespace}from"#internal/workflow/queue-namespace.js";import{runQueuedWorkflowBuild}from"#internal/workflow-bundle/build-queue.js";import{WORKFLOW_SOURCE_EXTENSIONS,WORKFLOW_VIRTUAL_ENTRY_ID,bundleFinalWorkflowOutput,collectWorkflowInputFiles,composeWorkflowDriverCode,convertClassesManifest,convertStepsManifest,convertWorkflowsManifest,createEvePackageImportsPlugin,createWorkflowDriverAliasPlugin,createWorkflowImport,createWorkflowNodeBuiltinGuardPlugin,createWorkflowPseudoPackagePlugin,createWorkflowTransformPlugin,createWorkflowVirtualEntryPlugin,mergeWorkflowManifest}from"#internal/workflow-bundle/builder-support.js";import{writeNitroStepEntrypoint}from"#internal/workflow-bundle/nitro-step-entry.js";var WorkflowBundleBuilder=class{#e;#t;#n;#r;config;constructor(e){let t=[resolvePackageSourceDirectoryPath(`src/execution`),resolvePackageSourceDirectoryPath(`src/runtime/subagents`),resolvePackageSourceDirectoryPath(`src/runtime/connections/events`),resolvePackageSourceDirectoryPath(`src/subagents`),resolvePackageSourceDirectoryPath(`src/tools/provided`)];e.includeTestFixtures===!0&&t.push(resolvePackageSourceDirectoryPath(`src/internal/testing`)),this.config={buildTarget:`standalone`,dirs:t,externalPackages:[...WORKFLOW_STEP_EXTERNAL_PACKAGES,...WORKFLOW_BUILDER_DEFERRED_PACKAGES],projectRoot:e.appRoot,watch:e.watch,workingDir:e.rootDir},this.#e=e.authoredWorkflowModules??{directiveModules:[],workflowModules:[]},this.#t=e.compiledArtifactsBootstrapPath,this.#n=e.outDir,this.#r=deriveEveWorkflowQueueNamespace(e.agentName)}async build(e={}){await runQueuedWorkflowBuild(this.#n,async()=>this.#i(e))}async#i(e){await prepareEveVersionedCacheDirectory(this.#n);let t=await this.#o();if(t.length===0)throw Error(`Expected framework workflow source files under eve's execution, runtime/subagents, subagents, or tools/provided source directories.`);let n=await this.findTsConfigPath();await mkdir(this.#n,{recursive:!0});let r=await this.discoverEntries(t),i=this.#e,a=mergeStepEntries(r,i),o=join(this.#n,`steps.mjs`),s=join(this.#n,`workflows.mjs`),c=e.nitroStepOutfile,l=e.nitroWorkflowOutfile,writeStepEntry=(e,t)=>writeNitroStepEntrypoint({builtinsPath:resolveWorkflowModulePath(`workflow/internal/builtins`),discoveredEntries:a,outfile:e,precomputedManifest:t,preferAbsoluteFileImports:!0,projectRoot:this.config.projectRoot??this.config.workingDir,sideEffectFiles:[this.#t],workingDir:this.config.workingDir}),u=await writeStepEntry(o);c!==void 0&&c!==o&&await writeStepEntry(c,u);let{manifest:d}=await this.createWorkflowsBundle({additionalOutputs:l===void 0||l===s?[]:[{outfile:l,stepRegistrationsPath:c??o}],appWorkflowFiles:i.workflowModules,frameworkSerdeFiles:r.discoveredSerdeFiles,frameworkWorkflowFiles:r.discoveredWorkflows,outfile:s,stepRegistrationsPath:o,tsconfigPath:n});await this.createManifest({workflowBundlePath:join(this.#n,`workflows.mjs`),manifestDir:this.#n,manifest:{steps:{...u.steps,...d.steps},workflows:{...u.workflows,...d.workflows},classes:{...u.classes,...d.classes}}}),await writeEveVersionedCacheMetadata(this.#n)}get transformProjectRoot(){return this.config.projectRoot??this.config.workingDir}async findTsConfigPath(){let e=this.transformProjectRoot;for(;;){for(let t of[`tsconfig.json`,`jsconfig.json`]){let n=join(e,t);try{return await readFile(n),n}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}}let t=dirname(e);if(t===e)return;e=t}}async getInputFiles(){let e=this.config.dirs.map(e=>resolve(this.config.workingDir,e));return(await Promise.all(e.map(e=>collectWorkflowInputFiles(e)))).flat()}async discoverEntries(e){let t={discoveredSerdeFiles:[],discoveredSteps:[],discoveredWorkflows:[]},n=await mapConcurrent(e,async e=>{let t=await readFile(e,`utf8`);return{filePath:e,patterns:await findWorkflowPatterns(e,t)}});for(let{filePath:e,patterns:r}of n)r.hasUseStep&&t.discoveredSteps.push(e),r.hasUseWorkflow&&t.discoveredWorkflows.push(e),r.hasSerde&&t.discoveredSerdeFiles.push(e);return t}async createWorkflowsBundle({additionalOutputs:e=[],appWorkflowFiles:t,frameworkSerdeFiles:n,frameworkWorkflowFiles:r,outfile:i,stepRegistrationsPath:a,tsconfigPath:o}){let s={},c=await mapConcurrent([{label:`framework`,serdeFiles:n,workflowFiles:r},{label:`app`,serdeFiles:[],workflowFiles:t}],async e=>{let t={};return{code:await this.#a({...e,manifest:t,tsconfigPath:o}),manifest:t}});for(let e of c)mergeWorkflowManifest(s,e.manifest);let l=composeWorkflowDriverCode(c.map(e=>e.code));return await Promise.all([{outfile:i,stepRegistrationsPath:a},...e].map(e=>bundleFinalWorkflowOutput({code:l,outfile:e.outfile,queueNamespace:this.#r,stepRegistrationsPath:e.stepRegistrationsPath}))),{manifest:s}}async#a(e){let t=[...e.workflowFiles].sort(),n=new Set(t),r=[...e.serdeFiles].sort().filter(e=>!n.has(e));if(t.length===0&&r.length===0)return``;let i=[...t.map(e=>createWorkflowImport(e,this.config.workingDir)),...r.map(e=>createWorkflowImport(e,this.config.workingDir))].join(`
2
- `);return(await buildSingleRolldownChunk(`${e.label} workflow driver chunk`,{cwd:this.config.workingDir,onLog(e,t,n){if(e===`warn`&&t.code===`UNRESOLVED_IMPORT`)throw Error(`Cannot build workflow bundle: ${t.message}`);onVendoredDependencyLog(e,t,n)},input:WORKFLOW_VIRTUAL_ENTRY_ID,platform:`neutral`,plugins:[createWorkflowVirtualEntryPlugin(i),createWorkflowPseudoPackagePlugin(),createWorkflowDriverAliasPlugin(this.config.workingDir),createAuthoredRelativeExtensionResolverPlugin({extensions:WORKFLOW_SOURCE_EXTENSIONS}),createAuthoredPackageTsConfigPathsPlugin({appPackageRoot:this.transformProjectRoot,extensions:WORKFLOW_SOURCE_EXTENSIONS}),createEvePackageImportsPlugin(this.config.workingDir,{workflowCondition:!0}),createWorkflowTransformPlugin({manifest:e.manifest,projectRoot:this.transformProjectRoot,sideEffectFiles:[...t,...r],workingDir:this.config.workingDir}),createWorkflowNodeBuiltinGuardPlugin()],resolve:{conditionNames:[`eve-source`,`workflow`],extensions:WORKFLOW_SOURCE_EXTENSIONS,mainFields:[`module`,`main`]},tsconfig:e.tsconfigPath??!1,output:{comments:!1,format:`cjs`,sourcemap:`inline`}})).code}async createManifest({manifest:e,manifestDir:t}){let n={version:`1.0.0`,steps:convertStepsManifest(e.steps),workflows:convertWorkflowsManifest(e.workflows),classes:convertClassesManifest(e.classes)},r=JSON.stringify(n,null,2);return await mkdir(t,{recursive:!0}),await writeFile(join(t,`manifest.json`),r),r}async#o(){return await this.getInputFiles()}};function mergeStepEntries(e,t){return{discoveredSerdeFiles:e.discoveredSerdeFiles,discoveredSteps:[...new Set([...e.discoveredSteps,...t.directiveModules])]}}export{WorkflowBundleBuilder};
1
+ import{mkdir,readFile,writeFile}from"node:fs/promises";import{dirname,join,resolve}from"node:path";import{resolvePackageSourceDirectoryPath,resolveWorkflowModulePath}from"#internal/application/package.js";import{createAuthoredPackageTsConfigPathsPlugin}from"#internal/authored-package-tsconfig-paths.js";import{createAuthoredRelativeExtensionResolverPlugin}from"#internal/authored-relative-extension-resolver.js";import{buildSingleRolldownChunk}from"#internal/bundler/nitro-rolldown.js";import{findWorkflowPatterns}from"#internal/workflow-bundle/workflow-builders.js";import{mapConcurrent}from"#shared/map-concurrent.js";import{onVendoredDependencyLog}from"#internal/bundler/vendored-dependency-log.js";import{prepareEveVersionedCacheDirectory,writeEveVersionedCacheMetadata}from"#internal/application/cache-metadata.js";import{WORKFLOW_BUILDER_DEFERRED_PACKAGES,WORKFLOW_STEP_EXTERNAL_PACKAGES}from"#internal/workflow-bundle/vercel-workflow-output.js";import{deriveEveWorkflowQueueNamespace}from"#internal/workflow/queue-namespace.js";import{runQueuedWorkflowBuild}from"#internal/workflow-bundle/build-queue.js";import{WORKFLOW_SOURCE_EXTENSIONS,WORKFLOW_VIRTUAL_ENTRY_ID,bundleFinalWorkflowOutput,collectWorkflowInputFiles,composeWorkflowDriverCode,convertClassesManifest,convertStepsManifest,convertWorkflowsManifest,createEvePackageImportsPlugin,createWorkflowDriverAliasPlugin,createWorkflowImport,createWorkflowNodeBuiltinGuardPlugin,createWorkflowTransformPlugin,createWorkflowVirtualEntryPlugin,mergeWorkflowManifest}from"#internal/workflow-bundle/builder-support.js";import{writeNitroStepEntrypoint}from"#internal/workflow-bundle/nitro-step-entry.js";var WorkflowBundleBuilder=class{#e;#t;#n;#r;config;constructor(e){let t=[resolvePackageSourceDirectoryPath(`src/execution`),resolvePackageSourceDirectoryPath(`src/runtime/subagents`),resolvePackageSourceDirectoryPath(`src/runtime/connections/events`),resolvePackageSourceDirectoryPath(`src/subagents`),resolvePackageSourceDirectoryPath(`src/tools/provided`)];e.includeTestFixtures===!0&&t.push(resolvePackageSourceDirectoryPath(`src/internal/testing`)),this.config={buildTarget:`standalone`,dirs:t,externalPackages:[...WORKFLOW_STEP_EXTERNAL_PACKAGES,...WORKFLOW_BUILDER_DEFERRED_PACKAGES],projectRoot:e.appRoot,watch:e.watch,workingDir:e.rootDir},this.#e=e.authoredWorkflowModules??{directiveModules:[],workflowModules:[]},this.#t=e.compiledArtifactsBootstrapPath,this.#n=e.outDir,this.#r=deriveEveWorkflowQueueNamespace(e.agentName)}async build(e={}){await runQueuedWorkflowBuild(this.#n,async()=>this.#i(e))}async#i(e){await prepareEveVersionedCacheDirectory(this.#n);let t=await this.#o();if(t.length===0)throw Error(`Expected framework workflow source files under eve's execution, runtime/subagents, subagents, or tools/provided source directories.`);let n=await this.findTsConfigPath();await mkdir(this.#n,{recursive:!0});let r=await this.discoverEntries(t),i=this.#e,a=mergeStepEntries(r,i),o=join(this.#n,`steps.mjs`),s=join(this.#n,`workflows.mjs`),c=e.nitroStepOutfile,l=e.nitroWorkflowOutfile,writeStepEntry=(e,t)=>writeNitroStepEntrypoint({builtinsPath:resolveWorkflowModulePath(`workflow/internal/builtins`),discoveredEntries:a,outfile:e,precomputedManifest:t,preferAbsoluteFileImports:!0,projectRoot:this.config.projectRoot??this.config.workingDir,sideEffectFiles:[this.#t],workingDir:this.config.workingDir}),u=await writeStepEntry(o);c!==void 0&&c!==o&&await writeStepEntry(c,u);let{manifest:d}=await this.createWorkflowsBundle({additionalOutputs:l===void 0||l===s?[]:[{outfile:l,stepRegistrationsPath:c??o}],appWorkflowFiles:i.workflowModules,frameworkSerdeFiles:r.discoveredSerdeFiles,frameworkWorkflowFiles:r.discoveredWorkflows,outfile:s,stepRegistrationsPath:o,tsconfigPath:n});await this.createManifest({workflowBundlePath:join(this.#n,`workflows.mjs`),manifestDir:this.#n,manifest:{steps:{...u.steps,...d.steps},workflows:{...u.workflows,...d.workflows},classes:{...u.classes,...d.classes}}}),await writeEveVersionedCacheMetadata(this.#n)}get transformProjectRoot(){return this.config.projectRoot??this.config.workingDir}async findTsConfigPath(){let e=this.transformProjectRoot;for(;;){for(let t of[`tsconfig.json`,`jsconfig.json`]){let n=join(e,t);try{return await readFile(n),n}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}}let t=dirname(e);if(t===e)return;e=t}}async getInputFiles(){let e=this.config.dirs.map(e=>resolve(this.config.workingDir,e));return(await Promise.all(e.map(e=>collectWorkflowInputFiles(e)))).flat()}async discoverEntries(e){let t={discoveredSerdeFiles:[],discoveredSteps:[],discoveredWorkflows:[]},n=await mapConcurrent(e,async e=>{let t=await readFile(e,`utf8`);return{filePath:e,patterns:await findWorkflowPatterns(e,t)}});for(let{filePath:e,patterns:r}of n)r.hasUseStep&&t.discoveredSteps.push(e),r.hasUseWorkflow&&t.discoveredWorkflows.push(e),r.hasSerde&&t.discoveredSerdeFiles.push(e);return t}async createWorkflowsBundle({additionalOutputs:e=[],appWorkflowFiles:t,frameworkSerdeFiles:n,frameworkWorkflowFiles:r,outfile:i,stepRegistrationsPath:a,tsconfigPath:o}){let s={},c=await mapConcurrent([{label:`framework`,serdeFiles:n,workflowFiles:r},{label:`app`,serdeFiles:[],workflowFiles:t}],async e=>{let t={};return{code:await this.#a({...e,manifest:t,tsconfigPath:o}),manifest:t}});for(let e of c)mergeWorkflowManifest(s,e.manifest);let l=composeWorkflowDriverCode(c.map(e=>e.code));return await Promise.all([{outfile:i,stepRegistrationsPath:a},...e].map(e=>bundleFinalWorkflowOutput({code:l,outfile:e.outfile,queueNamespace:this.#r,stepRegistrationsPath:e.stepRegistrationsPath}))),{manifest:s}}async#a(e){let t=[...e.workflowFiles].sort(),n=new Set(t),r=[...e.serdeFiles].sort().filter(e=>!n.has(e));if(t.length===0&&r.length===0)return``;let i=[...t.map(e=>createWorkflowImport(e,this.config.workingDir)),...r.map(e=>createWorkflowImport(e,this.config.workingDir))].join(`
2
+ `);return(await buildSingleRolldownChunk(`${e.label} workflow driver chunk`,{cwd:this.config.workingDir,onLog(e,t,n){if(e===`warn`&&t.code===`UNRESOLVED_IMPORT`)throw Error(`Cannot build workflow bundle: ${t.message}`);onVendoredDependencyLog(e,t,n)},input:WORKFLOW_VIRTUAL_ENTRY_ID,platform:`neutral`,plugins:[createWorkflowVirtualEntryPlugin(i),createWorkflowDriverAliasPlugin(this.config.workingDir),createAuthoredRelativeExtensionResolverPlugin({extensions:WORKFLOW_SOURCE_EXTENSIONS}),createAuthoredPackageTsConfigPathsPlugin({appPackageRoot:this.transformProjectRoot,extensions:WORKFLOW_SOURCE_EXTENSIONS}),createEvePackageImportsPlugin(this.config.workingDir,{workflowCondition:!0}),createWorkflowTransformPlugin({manifest:e.manifest,projectRoot:this.transformProjectRoot,sideEffectFiles:[...t,...r],workingDir:this.config.workingDir}),createWorkflowNodeBuiltinGuardPlugin()],resolve:{conditionNames:[`eve-source`,`workflow`],extensions:WORKFLOW_SOURCE_EXTENSIONS,mainFields:[`module`,`main`]},tsconfig:e.tsconfigPath??!1,output:{comments:!1,format:`cjs`,sourcemap:`inline`}})).code}async createManifest({manifest:e,manifestDir:t}){let n={version:`1.0.0`,steps:convertStepsManifest(e.steps),workflows:convertWorkflowsManifest(e.workflows),classes:convertClassesManifest(e.classes)},r=JSON.stringify(n,null,2);return await mkdir(t,{recursive:!0}),await writeFile(join(t,`manifest.json`),r),r}async#o(){return await this.getInputFiles()}};function mergeStepEntries(e,t){return{discoveredSerdeFiles:e.discoveredSerdeFiles,discoveredSteps:[...new Set([...e.discoveredSteps,...t.directiveModules])]}}export{WorkflowBundleBuilder};
@@ -1,4 +1,4 @@
1
- export declare const WORKFLOW_STEP_EXTERNAL_PACKAGES: readonly ["@mongodb-js/zstd", "just-bash", "microsandbox", "node-liblzma"];
1
+ export declare const WORKFLOW_STEP_EXTERNAL_PACKAGES: readonly ["@mongodb-js/zstd", "just-bash", "node-liblzma"];
2
2
  /**
3
3
  * Packages that must stay external during the initial workflow builder
4
4
  * pass so `node:*` transitive dependencies do not fail the workflow VM check.
@@ -1 +1 @@
1
- import{cp,mkdir,readFile,readdir,realpath,rename,rm,symlink,writeFile}from"node:fs/promises";import{dirname,join,relative}from"node:path";import{EVE_SHARED_SERVER_FUNCTION_PATH,EVE_WORKFLOW_FLOW_ROUTE_PATH,isEveVercelFunctionPath,normalizeEveVercelRoutes}from"#internal/workflow-bundle/eve-service-route-output.js";const WORKFLOW_STEP_EXTERNAL_PACKAGES=[`@mongodb-js/zstd`,`just-bash`,`microsandbox`,`node-liblzma`],WORKFLOW_BUILDER_DEFERRED_PACKAGES=[`@chat-adapter/slack`,`chat`];function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function materializeVercelWorkflowFunctionOutput(e){let t=join(e,`functions`),n=await realpath(join(t,`__server.func`)),r=join(t,`${EVE_WORKFLOW_FLOW_ROUTE_PATH.slice(1)}.func`),i=await readFile(join(r,`.vc-config.json`)),a=`${r}.eve-staging`;await rm(a,{force:!0,recursive:!0}),await cp(n,a,{recursive:!0,verbatimSymlinks:!0}),await writeFile(join(a,`.vc-config.json`),i),await rm(r,{force:!0,recursive:!0}),await rename(a,r)}async function normalizeEveVercelFunctionOutput(e,t={}){let n=join(e,`functions`),r=await prepareSharedEveServerFunction(n);r!==null&&await repointEveFunctionSymlinksInDirectory(n,r),await pruneNonEveFunctionEntries(n,n),await pruneNonEveVercelRoutes(e,t.servicePrefix)}async function prepareSharedEveServerFunction(e){let t=join(e,`__server.func`),n=join(e,EVE_SHARED_SERVER_FUNCTION_PATH),r;try{r=await realpath(t)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return null;throw e}let i=`${n}.eve-staging`;return await mkdir(dirname(n),{recursive:!0}),await rm(i,{force:!0,recursive:!0}),await cp(r,i,{dereference:!0,recursive:!0}),await rm(n,{force:!0,recursive:!0}),await rename(i,n),n}async function repointEveFunctionSymlinksInDirectory(e,t,n=e){let r;try{r=await readdir(e,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}await Promise.all(r.map(async r=>{let i=join(e,r.name),a=normalizeVercelOutputPath(relative(n,i));if(r.isSymbolicLink()){r.name.endsWith(`.func`)&&isEveVercelFunctionPath(a)&&await repointFunctionSymlink(i,t);return}r.isDirectory()&&!r.name.endsWith(`.func`)&&await repointEveFunctionSymlinksInDirectory(i,t,n)}))}async function repointFunctionSymlink(e,t){await rm(e,{force:!0,recursive:!0}),await symlink(normalizeVercelOutputPath(relative(dirname(e),t)),e,`dir`)}async function pruneNonEveFunctionEntries(e,t){let n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}await Promise.all(n.map(async n=>{let r=join(t,n.name),i=normalizeVercelOutputPath(relative(e,r));if(n.name.endsWith(`.func`)){isEveVercelFunctionPath(i)||await rm(r,{force:!0,recursive:!0});return}n.isDirectory()&&await pruneNonEveFunctionEntries(e,r)}))}async function pruneNonEveVercelRoutes(e,t){let n=join(e,`config.json`),r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}isRecord(r)&&Array.isArray(r.routes)&&(r.routes=normalizeEveVercelRoutes(r.routes,t),await writeFile(n,`${JSON.stringify(r,null,2)}\n`))}function normalizeVercelOutputPath(e){return e.replaceAll(`\\`,`/`)}export{WORKFLOW_BUILDER_DEFERRED_PACKAGES,WORKFLOW_STEP_EXTERNAL_PACKAGES,materializeVercelWorkflowFunctionOutput,normalizeEveVercelFunctionOutput};
1
+ import{cp,mkdir,readFile,readdir,realpath,rename,rm,symlink,writeFile}from"node:fs/promises";import{dirname,join,relative}from"node:path";import{EVE_SHARED_SERVER_FUNCTION_PATH,EVE_WORKFLOW_FLOW_ROUTE_PATH,isEveVercelFunctionPath,normalizeEveVercelRoutes}from"#internal/workflow-bundle/eve-service-route-output.js";const WORKFLOW_STEP_EXTERNAL_PACKAGES=[`@mongodb-js/zstd`,`just-bash`,`node-liblzma`],WORKFLOW_BUILDER_DEFERRED_PACKAGES=[`@chat-adapter/slack`,`chat`];function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function materializeVercelWorkflowFunctionOutput(e){let t=join(e,`functions`),n=await realpath(join(t,`__server.func`)),r=join(t,`${EVE_WORKFLOW_FLOW_ROUTE_PATH.slice(1)}.func`),i=await readFile(join(r,`.vc-config.json`)),a=`${r}.eve-staging`;await rm(a,{force:!0,recursive:!0}),await cp(n,a,{recursive:!0,verbatimSymlinks:!0}),await writeFile(join(a,`.vc-config.json`),i),await rm(r,{force:!0,recursive:!0}),await rename(a,r)}async function normalizeEveVercelFunctionOutput(e,t={}){let n=join(e,`functions`),r=await prepareSharedEveServerFunction(n);r!==null&&await repointEveFunctionSymlinksInDirectory(n,r),await pruneNonEveFunctionEntries(n,n),await pruneNonEveVercelRoutes(e,t.servicePrefix)}async function prepareSharedEveServerFunction(e){let t=join(e,`__server.func`),n=join(e,EVE_SHARED_SERVER_FUNCTION_PATH),r;try{r=await realpath(t)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return null;throw e}let i=`${n}.eve-staging`;return await mkdir(dirname(n),{recursive:!0}),await rm(i,{force:!0,recursive:!0}),await cp(r,i,{dereference:!0,recursive:!0}),await rm(n,{force:!0,recursive:!0}),await rename(i,n),n}async function repointEveFunctionSymlinksInDirectory(e,t,n=e){let r;try{r=await readdir(e,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}await Promise.all(r.map(async r=>{let i=join(e,r.name),a=normalizeVercelOutputPath(relative(n,i));if(r.isSymbolicLink()){r.name.endsWith(`.func`)&&isEveVercelFunctionPath(a)&&await repointFunctionSymlink(i,t);return}r.isDirectory()&&!r.name.endsWith(`.func`)&&await repointEveFunctionSymlinksInDirectory(i,t,n)}))}async function repointFunctionSymlink(e,t){await rm(e,{force:!0,recursive:!0}),await symlink(normalizeVercelOutputPath(relative(dirname(e),t)),e,`dir`)}async function pruneNonEveFunctionEntries(e,t){let n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}await Promise.all(n.map(async n=>{let r=join(t,n.name),i=normalizeVercelOutputPath(relative(e,r));if(n.name.endsWith(`.func`)){isEveVercelFunctionPath(i)||await rm(r,{force:!0,recursive:!0});return}n.isDirectory()&&await pruneNonEveFunctionEntries(e,r)}))}async function pruneNonEveVercelRoutes(e,t){let n=join(e,`config.json`),r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}isRecord(r)&&Array.isArray(r.routes)&&(r.routes=normalizeEveVercelRoutes(r.routes,t),await writeFile(n,`${JSON.stringify(r,null,2)}\n`))}function normalizeVercelOutputPath(e){return e.replaceAll(`\\`,`/`)}export{WORKFLOW_BUILDER_DEFERRED_PACKAGES,WORKFLOW_STEP_EXTERNAL_PACKAGES,materializeVercelWorkflowFunctionOutput,normalizeEveVercelFunctionOutput};
@@ -0,0 +1,14 @@
1
+ import { z } from "#compiled/zod/index.js";
2
+ /** Acceptance is durable, but does not mean the successor has activated. */
3
+ export type PrewarmSessionResult = {
4
+ readonly status: "ready" | "accepted" | "unsupported" | "no_active_session";
5
+ };
6
+ export declare const PrewarmResponseSchema: z.ZodObject<{
7
+ ok: z.ZodLiteral<true>;
8
+ status: z.ZodEnum<{
9
+ accepted: "accepted";
10
+ no_active_session: "no_active_session";
11
+ ready: "ready";
12
+ unsupported: "unsupported";
13
+ }>;
14
+ }, z.core.$strip>;
@@ -0,0 +1 @@
1
+ import{z}from"#compiled/zod/index.js";const PrewarmResponseSchema=z.object({ok:z.literal(!0),status:z.enum([`ready`,`accepted`,`unsupported`,`no_active_session`])});export{PrewarmResponseSchema};
@@ -17,7 +17,7 @@ export declare const EVE_HEALTH_ROUTE_PATH = "/eve/v1/health";
17
17
  export declare const EVE_INFO_ROUTE_PATH = "/eve/v1/info";
18
18
  /** Stable route for creating ID-addressed sessions. */
19
19
  export declare const EVE_SESSION_ROUTE_PATH = "/eve/v1/session";
20
- /** Stable route pattern for sending a message to one exact session ID. */
20
+ /** Stable route pattern for preparing or delivering input to one exact session ID. */
21
21
  export declare const EVE_SESSION_ROUTE_PATTERN = "/eve/v1/session/:sessionId";
22
22
  /** Stable route pattern for cancelling one exact session ID. */
23
23
  export declare const EVE_SESSION_CANCEL_ROUTE_PATTERN = "/eve/v1/session/:sessionId/cancel";
@@ -95,7 +95,7 @@ export declare const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN = "/eve/v1/connection
95
95
  * is unauthenticated by design and resumes the matching parked runtime action.
96
96
  */
97
97
  export declare const EVE_CALLBACK_ROUTE_PATTERN = "/eve/v1/callback/:token";
98
- /** Builds the ID-addressed message route for one session. */
98
+ /** Builds the ID-addressed preparation and input route for one session. */
99
99
  export declare function createEveSessionRoutePath(sessionId: string): string;
100
100
  /** Builds the ID-addressed cancel route for one session. */
101
101
  export declare function createEveSessionCancelRoutePath(sessionId: string): string;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Discord connection sign-ins. A sign-in link is a credential: whoever
3
+ * completes it binds their account to the person who asked. In a DM the bot
4
+ * posts the link directly. In a server the shared message carries no link or
5
+ * code, only a button, and eve answers its press with an ephemeral message
6
+ * that shows the challenge to the presser alone, and only when the presser is
7
+ * the person who must sign in.
8
+ */
9
+ import type { Session } from "#channel/session.js";
10
+ import type { SessionAuthContext } from "#channel/types.js";
11
+ import type { AuthorizationCompletedStreamEvent, AuthorizationRequiredStreamEvent } from "#protocol/message.js";
12
+ import type { DiscordMessageBody } from "#public/channels/discord/api.js";
13
+ type AuthorizationRequired = AuthorizationRequiredStreamEvent["data"];
14
+ type AuthorizationCompleted = AuthorizationCompletedStreamEvent["data"];
15
+ /** Custom id prefix of the shared sign-in message's button. */
16
+ export declare const DISCORD_AUTHORIZATION_CUSTOM_ID_PREFIX = "eve_auth:";
17
+ /** The sign-in attempt a shared message's button names, as an opaque digest. */
18
+ export interface DiscordAuthorizationReveal {
19
+ readonly attempt: string;
20
+ }
21
+ /** The full sign-in, link and code included, for the person signing in alone. */
22
+ export declare function renderDiscordAuthorizationPrompt(event: AuthorizationRequired): DiscordMessageBody;
23
+ /** The shared sign-in message: who must sign in, and a button that shows them the challenge. */
24
+ export declare function renderDiscordAuthorizationStatus(event: AuthorizationRequired): DiscordMessageBody;
25
+ /** What a sign-in's message says once it settles. */
26
+ export declare function renderDiscordAuthorizationCompleted(event: AuthorizationCompleted): string;
27
+ /** Reads the sign-in attempt a button names, or `null` for any other component. */
28
+ export declare function readDiscordAuthorizationReveal(customId: string): DiscordAuthorizationReveal | null;
29
+ /**
30
+ * Answers a press of the shared message's button with an ephemeral message.
31
+ * The challenge comes from the session's own stream and goes back only when
32
+ * the presser's principal is the one that must sign in; nothing the button
33
+ * carries is trusted for identity.
34
+ */
35
+ export declare function answerDiscordAuthorizationReveal(input: {
36
+ readonly auth: SessionAuthContext | null;
37
+ readonly resolveSession: () => Promise<Session | undefined>;
38
+ readonly reveal: DiscordAuthorizationReveal;
39
+ }): Promise<DiscordMessageBody>;
40
+ /** The key a channel's state tracks one sign-in attempt's message under. */
41
+ export declare function discordAuthorizationMessageKey(event: {
42
+ readonly attemptId?: string;
43
+ readonly name: string;
44
+ }): string;
45
+ export {};
@@ -0,0 +1,3 @@
1
+ import{createHash}from"node:crypto";import{createLogger}from"#internal/logging.js";import{displayProperName}from"#shared/display-name.js";import{attemptKey,findPendingAuthorization}from"#channel/pending-authorization.js";import{DISCORD_COMPONENT_TYPE}from"#public/channels/discord/hitl.js";const log=createLogger(`discord.authorization`),DISCORD_AUTHORIZATION_CUSTOM_ID_PREFIX=`eve_auth:`,NOT_YOURS=`Only the person who needs to sign in can open this sign-in.`;function displayNameOf(e){return e.authorization?.displayName??displayProperName(e.name)}function renderDiscordAuthorizationPrompt(e){let t=displayNameOf(e),n=e.authorization?.url,r=e.authorization?.userCode,i=[`Sign in to ${t} to continue.`,e.authorization?.instructions,r?`If ${t} asks for a confirmation code, enter ${r}.`:void 0].filter(Boolean).join(`
2
+
3
+ `);return n?{components:[{components:[{label:`Sign in to ${t}`,style:5,type:DISCORD_COMPONENT_TYPE.BUTTON,url:n}],type:DISCORD_COMPONENT_TYPE.ACTION_ROW}],content:i}:{content:i}}function renderDiscordAuthorizationStatus(e){let t=discordUserIdOf(e.principalId),n=t?`<@${t}> needs`:`Someone needs`;return{components:[{components:[{custom_id:authorizationCustomId(e),label:`Sign in`,style:1,type:DISCORD_COMPONENT_TYPE.BUTTON}],type:DISCORD_COMPONENT_TYPE.ACTION_ROW}],content:`${n} to sign in to ${displayNameOf(e)} to continue. Only they can open the sign-in.`}}function renderDiscordAuthorizationCompleted(e){let t=displayNameOf(e);if(e.outcome===`authorized`)return`${t} connected.`;let n=e.reason===void 0?``:` (${e.reason})`;return`${t} sign-in ${e.outcome}${n}.`}function readDiscordAuthorizationReveal(e){if(!e.startsWith(`eve_auth:`))return null;let t=e.slice(9);return t?{attempt:t}:null}async function answerDiscordAuthorizationReveal(e){if(e.auth===null)return{content:NOT_YOURS};let t;try{let n=await e.resolveSession();t=n&&await findPendingAuthorization(n,t=>attemptDigest(t)===e.reveal.attempt)}catch(e){log.error(`Discord sign-in lookup failed`,{error:e})}return t===void 0?{content:`This sign-in is no longer active.`}:e.auth.principalId===t.principalId?renderDiscordAuthorizationPrompt(t):{content:NOT_YOURS}}function authorizationCustomId(e){return`${DISCORD_AUTHORIZATION_CUSTOM_ID_PREFIX}${attemptDigest(e)}`}function attemptDigest(e){return createHash(`sha256`).update(attemptKey(e)).digest(`base64url`).slice(0,32)}function discordAuthorizationMessageKey(e){return attemptDigest(e)}function discordUserIdOf(e){return/^discord:(\d+)$/u.exec(e??``)?.[1]}export{DISCORD_AUTHORIZATION_CUSTOM_ID_PREFIX,answerDiscordAuthorizationReveal,discordAuthorizationMessageKey,readDiscordAuthorizationReveal,renderDiscordAuthorizationCompleted,renderDiscordAuthorizationPrompt,renderDiscordAuthorizationStatus};
@@ -1,15 +1,24 @@
1
1
  import type { SessionAuthContext } from "#channel/types.js";
2
2
  import type { DiscordCommandInteraction, DiscordInteractionBase } from "#public/channels/discord/inbound.js";
3
+ import type { DiscordGatewayMessage, DiscordMessageResult } from "#public/channels/discord/messages.js";
3
4
  import type { DiscordChannelEvents, DiscordCommandResult, DiscordContext, DiscordHandle, DiscordHitlPrompt } from "#public/channels/discord/discordChannel.js";
4
5
  /**
5
6
  * Builds the default {@link SessionAuthContext} for the user behind a Discord
6
7
  * interaction (a command, button press, select, or modal submission):
7
8
  * authenticator `discord-interaction`, guild-scoped issuer/principalId when
8
- * invoked in a guild (else user-scoped), and `principalType` `service` for bot
9
- * actors or `user` otherwise. Copies the channel, interaction, user, guild,
10
- * and member-nick attributes.
9
+ * invoked in a guild (else user-scoped), and `principalType` `service` for bot actors or
10
+ * `user` otherwise. Copies the channel, interaction, user, guild, and
11
+ * member-nick attributes. A message from the same person gets the same
12
+ * principal from {@link defaultDiscordMessageAuth}.
11
13
  */
12
14
  export declare function defaultDiscordAuth(interaction: DiscordInteractionBase): SessionAuthContext;
15
+ /**
16
+ * Builds the default {@link SessionAuthContext} for the author of a Discord
17
+ * message forwarded from the Gateway. The principal matches what
18
+ * {@link defaultDiscordAuth} builds for the same person, so their button
19
+ * presses answer approvals their messages asked for.
20
+ */
21
+ export declare function defaultDiscordMessageAuth(message: DiscordGatewayMessage): SessionAuthContext;
13
22
  /** Default command hook: dispatch with Discord user auth. */
14
23
  export declare function defaultOnCommand(_ctx: DiscordContext, interaction: DiscordCommandInteraction): DiscordCommandResult;
15
24
  /**
@@ -17,5 +26,7 @@ export declare function defaultOnCommand(_ctx: DiscordContext, interaction: Disc
17
26
  * choices replaced by `label`. Throws when Discord refuses the edit.
18
27
  */
19
28
  export declare function editDiscordResolvedPrompt(discord: Pick<DiscordHandle, "channelId" | "request">, prompt: Pick<DiscordHitlPrompt, "content" | "messageId">, label: string): Promise<void>;
29
+ /** Default Gateway message hook: dispatch messages addressed to the bot with Discord user auth. */
30
+ export declare function defaultOnMessage(_ctx: DiscordContext, message: DiscordGatewayMessage): DiscordMessageResult;
20
31
  /** Built-in Discord event handlers for typing, replies, HITL, and terminal errors. */
21
32
  export declare const defaultEvents: DiscordChannelEvents;
@@ -1,3 +1,3 @@
1
- import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{resolvedPromptLabel}from"#channel/resolved-prompt.js";import{DISCORD_MESSAGE_CONTENT_MAX_LENGTH,splitDiscordMessageContent}from"#public/channels/discord/api.js";import{renderInputRequestComponents}from"#public/channels/discord/hitl.js";const log=createLogger(`discord.defaults`);function defaultDiscordAuth(e){let t={channel_id:e.channelId,interaction_id:e.id,user_id:e.user.id,username:e.user.username};return e.guildId!==void 0&&(t.guild_id=e.guildId),e.member?.nick!==void 0&&(t.member_nick=e.member.nick),{attributes:t,authenticator:`discord-interaction`,issuer:e.guildId?`discord:${e.guildId}`:`discord`,principalId:e.guildId?`discord:${e.guildId}:${e.user.id}`:`discord:${e.user.id}`,principalType:e.user.isBot?`service`:`user`}}function defaultOnCommand(e,t){return{auth:defaultDiscordAuth(t)}}async function editDiscordResolvedPrompt(e,t,n){let r=`${t.content}\n\n${n}`.slice(0,DISCORD_MESSAGE_CONTENT_MAX_LENGTH),i=await e.request(`/channels/${encodeURIComponent(e.channelId)}/messages/${encodeURIComponent(t.messageId)}`,{components:[],content:r},{botAuth:!0,method:`PATCH`});if(!i.ok)throw Error(`Discord prompt edit failed with HTTP ${i.status}.`)}const defaultEvents={async"turn.started"(e,t,n){await t.discord.startTyping()},async"authorization.completed"(e,t,n){e.outcome===`authorized`&&await t.discord.startTyping()},async"actions.requested"(e,t,n){await t.discord.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=splitDiscordMessageContent(n.prompt)[0]??n.prompt,r=renderInputRequestComponents(n),i=await t.discord.post({components:r,content:e});r.length!==0&&i.id&&(t.state.hitlPrompts={...t.state.hitlPrompts,[n.requestId]:{content:e,messageId:i.id,options:(n.options??[]).map(({id:e,label:t})=>({id:e,label:t}))}})}},async"input.resolved"(e,t,n){for(let n of e.resolutions){let e=t.state.hitlPrompts?.[n.requestId];if(e===void 0)continue;let{[n.requestId]:r,...i}=t.state.hitlPrompts??{};t.state.hitlPrompts=i;let a=resolvedPromptLabel(n,e.options);try{await editDiscordResolvedPrompt(t.discord,e,a)}catch(e){log.warn(`Discord answered prompt edit failed`,{error:e,requestId:n.requestId})}}},async"message.completed"(e,t,n){e.finishReason!==`tool-calls`&&e.message&&await t.discord.post(e.message)},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.discord.post([`This session could not recover from an error${n}.`,``,`Start a new command to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
1
+ import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{resolvedPromptLabel}from"#channel/resolved-prompt.js";import{renderInputRequestComponents}from"#public/channels/discord/hitl.js";import{DISCORD_MESSAGE_CONTENT_MAX_LENGTH,DISCORD_NO_MENTIONS,splitDiscordMessageContent}from"#public/channels/discord/api.js";import{discordAuthorizationMessageKey,renderDiscordAuthorizationCompleted,renderDiscordAuthorizationPrompt,renderDiscordAuthorizationStatus}from"#public/channels/discord/authorization.js";const log=createLogger(`discord.defaults`);function defaultDiscordAuth(e){let t={channel_id:e.channelId,interaction_id:e.id};return e.member?.nick!==void 0&&(t.member_nick=e.member.nick),discordUserAuth(e.user,e.guildId,t)}function defaultDiscordMessageAuth(e){return discordUserAuth(e.author,e.guildId,{channel_id:e.channelId,message_id:e.id})}function discordUserAuth(e,t,n){let r={...n,user_id:e.id,username:e.username};return t!==void 0&&(r.guild_id=t),{attributes:r,authenticator:`discord-interaction`,issuer:t?`discord:${t}`:`discord`,principalId:t?`discord:${t}:${e.id}`:`discord:${e.id}`,principalType:e.isBot?`service`:`user`}}function defaultOnCommand(e,t){return{auth:defaultDiscordAuth(t)}}async function editDiscordResolvedPrompt(e,t,n){let r=`${t.content}\n\n${n}`.slice(0,DISCORD_MESSAGE_CONTENT_MAX_LENGTH);await editDiscordMessage(e,t.messageId,r)}async function editDiscordMessage(e,t,n){let r=await e.request(`/channels/${encodeURIComponent(e.channelId)}/messages/${encodeURIComponent(t)}`,{allowed_mentions:DISCORD_NO_MENTIONS,components:[],content:n},{botAuth:!0,method:`PATCH`});if(!r.ok)throw Error(`Discord message edit failed with HTTP ${r.status}.`)}function defaultOnMessage(e,t){return t.addressed?{auth:defaultDiscordMessageAuth(t)}:null}const defaultEvents={async"turn.started"(e,t,n){await t.discord.startTyping()},async"authorization.required"(e,t,n){let r=t.state.directMessage===!0?renderDiscordAuthorizationPrompt(e):renderDiscordAuthorizationStatus(e);try{let n=await t.discord.post(r);n.id&&(t.state.pendingAuthMessageIds={...t.state.pendingAuthMessageIds,[discordAuthorizationMessageKey(e)]:n.id})}catch(t){log.error(`Discord sign-in delivery failed`,{error:t,name:e.name})}},async"authorization.completed"(e,t,n){e.outcome===`authorized`&&await t.discord.startTyping();let r=discordAuthorizationMessageKey(e),i=t.state.pendingAuthMessageIds?.[r];if(i===void 0)return;let{[r]:a,...o}=t.state.pendingAuthMessageIds??{};t.state.pendingAuthMessageIds=o;try{await editDiscordMessage(t.discord,i,renderDiscordAuthorizationCompleted(e))}catch(t){log.warn(`Discord sign-in edit failed`,{error:t,name:e.name})}},async"actions.requested"(e,t,n){await t.discord.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=splitDiscordMessageContent(n.prompt)[0]??n.prompt,r=renderInputRequestComponents(n),i=await t.discord.post({components:r,content:e});r.length!==0&&i.id&&(t.state.hitlPrompts={...t.state.hitlPrompts,[n.requestId]:{content:e,messageId:i.id,options:(n.options??[]).map(({id:e,label:t})=>({id:e,label:t}))}})}},async"input.resolved"(e,t,n){for(let n of e.resolutions){let e=t.state.hitlPrompts?.[n.requestId];if(e===void 0)continue;let{[n.requestId]:r,...i}=t.state.hitlPrompts??{};t.state.hitlPrompts=i;let a=resolvedPromptLabel(n,e.options);try{await editDiscordResolvedPrompt(t.discord,e,a)}catch(e){log.warn(`Discord answered prompt edit failed`,{error:e,requestId:n.requestId})}}},async"message.completed"(e,t,n){e.finishReason!==`tool-calls`&&e.message&&await t.discord.post(e.message)},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.discord.post([`This session could not recover from an error${n}.`,``,`Send a new message or command to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
2
2
  `))},async"turn.failed"(e,t,n){if(e.terminal)return;let r=formatErrorHint(e),i=extractErrorId(e.details);await t.discord.post([`I hit an error while handling your request${r}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...i?[``,`Error id: ${i}`]:[]].join(`
3
- `))}};export{defaultDiscordAuth,defaultEvents,defaultOnCommand,editDiscordResolvedPrompt};
3
+ `))}};export{defaultDiscordAuth,defaultDiscordMessageAuth,defaultEvents,defaultOnCommand,defaultOnMessage,editDiscordResolvedPrompt};
@@ -6,6 +6,7 @@ import type { ChannelContinuationOps } from "#public/definitions/channel.js";
6
6
  import type { UnstampedMessageStreamEvent } from "#protocol/message.js";
7
7
  import { type DiscordApiOptions, type DiscordApiResponse, type DiscordCredentials, type DiscordMessageBody, type DiscordPostedMessage } from "#public/channels/discord/api.js";
8
8
  import { type DiscordCommandInteraction, type DiscordComponentInteraction, type DiscordModalSubmitInteraction } from "#public/channels/discord/inbound.js";
9
+ import { type DiscordGatewayConfig } from "#public/channels/discord/messages.js";
9
10
  import { type DiscordWebhookVerifier } from "#public/channels/discord/verify.js";
10
11
  import { type JsonObject } from "#shared/json.js";
11
12
  import { type Channel } from "#public/definitions/channel.js";
@@ -51,6 +52,10 @@ export interface DiscordChannelState {
51
52
  hasMessageAnchor: boolean;
52
53
  /** Posted prompts with components, keyed by requestId, until eve resolves them. */
53
54
  hitlPrompts?: Record<string, DiscordHitlPrompt>;
55
+ /** Each pending sign-in's message, keyed by sign-in attempt, until the sign-in settles. */
56
+ pendingAuthMessageIds?: Record<string, string>;
57
+ /** Whether the conversation is a 1:1 DM with the bot, where nobody else can see a sign-in. */
58
+ directMessage?: boolean;
54
59
  }
55
60
  /** What a posted prompt needs so its message can be edited once eve resolves it. */
56
61
  export interface DiscordHitlPrompt {
@@ -133,6 +138,12 @@ export interface DiscordChannelConfig {
133
138
  * give a person's answers the same principal, and gating, as their commands.
134
139
  */
135
140
  onInputResponse?(ctx: DiscordInputResponseContext, interaction: DiscordInputResponseInteraction): DiscordInputResponseResult | Promise<DiscordInputResponseResult>;
141
+ /**
142
+ * Accepts ordinary messages (DMs, mentions, and thread follow-ups) that a
143
+ * relay forwards from the Discord Gateway, such as `experimental_runDiscordGatewayRelay`
144
+ * from `eve/channels/discord/gateway`. Mounts `POST /eve/v1/discord/gateway`.
145
+ */
146
+ readonly gateway?: DiscordGatewayConfig;
136
147
  readonly events?: DiscordChannelEvents;
137
148
  }
138
149
  /** Low-level Discord handle exposed to hooks and event handlers. */
@@ -170,6 +181,9 @@ export interface DiscordRequestOptions {
170
181
  /** Concrete return type of {@link discordChannel}. */
171
182
  export interface DiscordChannel extends Channel<DiscordChannelState, DiscordReceiveTarget, DiscordInstrumentationMetadata> {
172
183
  }
173
- /** Discord channel factory for HTTP Interactions and proactive channel messages. */
184
+ /**
185
+ * Discord channel factory for HTTP Interactions, proactive channel messages,
186
+ * and, with `gateway`, ordinary messages forwarded from the Discord Gateway.
187
+ */
174
188
  export declare function discordChannel(config?: DiscordChannelConfig): DiscordChannel;
175
189
  export {};
@@ -1 +1 @@
1
- import{discordAudience,discordInstrumentationMetadata}from"./audience.js";import{createLogger,logError}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{INACTIVE_REQUEST_NOTICE,respondOrRetireInactivePrompt}from"#channel/inactive-prompt.js";import"#public/channels/discord/verify.js";import{callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordBotToken,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent}from"#public/channels/discord/hitl.js";import{defaultDiscordAuth,defaultEvents,defaultOnCommand,editDiscordResolvedPrompt}from"#public/channels/discord/defaults.js";import{DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordDeferredJson,discordJson,discordJsonBody,readMessageContent}from"#public/channels/discord/responses.js";import{verifyDiscordInbound}from"#public/channels/discord/verifyInbound.js";import{createDiscordFetchFile,discordCommandContent}from"#public/channels/discord/attachments.js";const log=createLogger(`discord.channel`);function discordChannel(e={}){let t=e.onCommand??defaultOnCommand,n=e.onInputResponse??(e.onCommand===void 0?acceptAsPresser:dropUnmappedInputResponse),r={...defaultEvents,...e.events};return defineChannel({kindHint:`discord`,turnPolicy:e.turnPolicy,state:initialDiscordState(),metadata:discordInstrumentationMetadata,audience:({state:e})=>e.audience??`unknown`,fetchFile:createDiscordFetchFile(e.api?.fetch),context(t,n){return rebuildDiscordContext(t,n,e)},routes:[POST(e.route??`/eve/v1/discord`,async(r,{from:i,waitUntil:a})=>{let o=await verifyDiscordInbound(r,e.credentials);if(o===null)return new Response(`unauthorized`,{status:401});let s;try{s=parseJsonObject(JSON.parse(o))}catch(e){return log.warn(`inbound Discord body is not valid JSON`,{error:e}),discordJson({content:`invalid request`,ephemeral:!0})}if(s.type===DISCORD_INTERACTION_TYPE.PING)return discordJson({type:DISCORD_INTERACTION_RESPONSE_TYPE.PONG});let c=parseDiscordInteraction(s);return c===null?discordJson({content:`Unsupported Discord interaction.`,ephemeral:!0}):handleInteraction({config:e,interaction:c,onCommand:t,onInputResponse:n,from:i,waitUntil:a})})],async receive(t,{from:n}){let r=t.target,i=readNonEmptyString(r.channelId);if(!i)throw Error(`discordChannel().receive requires target.channelId.`);let a=readNonEmptyString(r.conversationId),o=r.initialMessage;if(o!==void 0&&a!==void 0)throw Error("discordChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let s=a??``,c=a!==void 0;if(o!==void 0){let t=await buildDiscordHandle({config:e,state:{...initialDiscordState(),channelId:i}}).sendChannelMessage(o);s=t.id,c=t.id.length>0}return n(discordContinuationToken(i,s)).send(t.message,{auth:t.auth,state:{applicationId:null,channelId:i,conversationId:s||null,guildId:null,hasMessageAnchor:c,initialResponseSent:!0,interactionToken:null}})},events:r})}function rebuildDiscordContext(e,t,n){return{discord:buildDiscordHandle({config:n,session:t,state:e}),state:e}}function buildDiscordHandle(e){let t=e.config.api,n=e.state,r=mergeCredentials(e.config.credentials,n);function anchor(t,r){t.id&&(n.hasMessageAnchor&&r.components===void 0||(n.hasMessageAnchor||=(n.conversationId=t.id,!0),n.channelId&&e.session?.continuation?.alias(discordContinuationToken(n.channelId,t.id))))}async function sendViaChannel(e){let i=n.channelId??``;if(!i)throw Error(`discordChannel: missing channel id for outbound message.`);let a=normalizePostInput(e),o=await sendDiscordChannelMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,channelId:i});return anchor(o,a),o}async function editOriginal(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for original response edit.`);let a=normalizePostInput(e),o=await editDiscordOriginalResponse({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,interactionToken:i});return n.initialResponseSent=!0,anchor(o,a),o}async function followup(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for followup message.`);let a=normalizePostInput(e),o=await createDiscordFollowupMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,interactionToken:i});return anchor(o,a),o}async function startTyping(){let e=n.channelId??``;if(e)try{await triggerDiscordTypingIndicator({apiBaseUrl:t?.apiBaseUrl,credentials:r,fetch:t?.fetch,channelId:e})}catch(t){logError(log,`Discord typing indicator failed — swallowed`,t,{channelId:e})}}return{applicationId:n.applicationId??void 0,channelId:n.channelId??``,conversationId:n.conversationId??``,guildId:n.guildId??void 0,interactionToken:n.interactionToken??void 0,request(e,n,i){return callDiscordApi({apiBaseUrl:t?.apiBaseUrl,body:n,botToken:i?.botAuth===!0?r.botToken:void 0,fetch:t?.fetch,method:i?.method,path:e})},async post(e){let t=expandPostBodies(normalizePostInput(e)),r;for(let e of t){let t=await postOne({body:e,editOriginal,followup,sendViaChannel,state:n});r===void 0&&(r=t)}return r??{id:``,raw:null}},editOriginalResponse:editOriginal,followup,sendChannelMessage:sendViaChannel,startTyping}}async function postOne(e){if(e.state.interactionToken&&e.state.applicationId)try{return e.state.initialResponseSent?await e.followup(e.body):await e.editOriginal(e.body)}catch(e){log.warn(`Discord interaction-token delivery failed, falling back to channel message`,{error:e})}return e.sendViaChannel(e.body)}async function handleInteraction(e){return e.interaction.type===DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND?handleCommandInteraction({config:e.config,interaction:e.interaction,onCommand:e.onCommand,from:e.from,waitUntil:e.waitUntil}):e.interaction.type===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT?handleComponentInteraction({config:e.config,interaction:e.interaction,onInputResponse:e.onInputResponse,from:e.from,waitUntil:e.waitUntil}):handleModalSubmitInteraction({config:e.config,interaction:e.interaction,onInputResponse:e.onInputResponse,from:e.from,waitUntil:e.waitUntil})}async function handleCommandInteraction(e){let t=stateFromInteraction(e.interaction,{conversationId:e.interaction.id,hasMessageAnchor:!1,initialResponseSent:!1}),n={discord:buildDiscordHandle({config:e.config,state:t})},r;try{r=await e.onCommand(n,e.interaction)}catch(e){return log.error(`command handler failed`,{error:e}),discordJson({content:`The Discord command handler failed.`,ephemeral:!0})}return r==null?discordJson({content:`Command ignored.`,ephemeral:!0}):(e.waitUntil(dispatchCommand({interaction:e.interaction,result:r,from:e.from,state:t})),discordDeferredJson(r.ephemeral===!0))}function handleComponentInteraction(e){if(isDiscordFreeformComponent(e.interaction.customId)){let t=readMessageContent(e.interaction.raw);return discordJsonBody(buildFreeformModalResponse({customId:e.interaction.customId,prompt:t}))}let t=deriveComponentInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({config:e.config,onInputResponse:e.onInputResponse,conversationId:e.interaction.messageId,inputResponses:t,interaction:e.interaction,from:e.from})),discordJsonBody({type:DISCORD_INTERACTION_RESPONSE_TYPE.DEFERRED_UPDATE_MESSAGE})}function handleModalSubmitInteraction(e){let t=deriveModalInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({config:e.config,onInputResponse:e.onInputResponse,conversationId:e.interaction.messageId??e.interaction.id,inputResponses:t,interaction:e.interaction,from:e.from})),discordJson({content:`Answer received.`,ephemeral:!0})}async function dispatchCommand(e){let t=discordCommandContent(commandInteractionMessage(e.interaction),e.interaction.attachments),n=formatDiscordContextBlock({applicationId:e.interaction.applicationId,channelId:e.interaction.channelId,commandName:e.interaction.commandName,guildId:e.interaction.guildId,interactionId:e.interaction.id,userId:e.interaction.user.id,username:e.interaction.user.username}),r=e.result.context??[];try{await e.from(discordContinuationToken(e.interaction.channelId,e.interaction.id)).send(t,{auth:e.result.auth,context:[n,...r],history:e.result.history,state:e.state,title:e.result.title})}catch(e){log.error(`command delivery failed`,{error:e})}}async function dispatchInputResponses(e){let t=stateFromInteraction(e.interaction,{conversationId:e.conversationId,hasMessageAnchor:e.conversationId!==e.interaction.id,initialResponseSent:!0}),n=buildDiscordHandle({config:e.config,state:t}),r;try{r=await e.onInputResponse({defaultAuth:defaultDiscordAuth(e.interaction),discord:n},e.interaction)}catch(e){log.error(`input response handler failed`,{error:e});return}if(r===null)return;let{auth:i}=r,a=e.from(discordContinuationToken(e.interaction.channelId,e.conversationId)),o=await respondOrRetireInactivePrompt(()=>a.respond(e.inputResponses,{auth:i}),{retirePrompt:async t=>{let r=e.interaction.messageId,i=readMessageContent(e.interaction.raw);r!==void 0&&i!==void 0&&await editDiscordResolvedPrompt(n,{content:i,messageId:r},t)}},log);o.outcome===`inactive`&&await Promise.all([o.retirement,sendInactiveNotice(n)])}async function sendInactiveNotice(e){try{await e.followup({content:INACTIVE_REQUEST_NOTICE,flags:DISCORD_EPHEMERAL_MESSAGE_FLAG})}catch(e){log.error(`inactive prompt notice failed`,{error:e})}}function acceptAsPresser(e){return{auth:e.defaultAuth}}function dropUnmappedInputResponse(){return log.warn(`dropped a Discord input response: onCommand is customized but onInputResponse is not; set onInputResponse to accept button presses and modal submissions`),null}function stateFromInteraction(e,t){return{audience:discordAudience(e.channelType),applicationId:e.applicationId,channelId:e.channelId,conversationId:t.conversationId,guildId:e.guildId??null,hasMessageAnchor:t.hasMessageAnchor,initialResponseSent:t.initialResponseSent,interactionToken:e.token}}function initialDiscordState(){return{applicationId:null,channelId:null,conversationId:null,guildId:null,hasMessageAnchor:!1,initialResponseSent:!1,interactionToken:null}}function mergeCredentials(e,t){return{applicationId:t.applicationId??e?.applicationId,botToken:e?.botToken??(()=>resolveDiscordBotToken()),publicKey:e?.publicKey,webhookVerifier:e?.webhookVerifier}}function normalizePostInput(e){return typeof e==`string`?{content:e}:e}function expandPostBodies(e){return typeof e.content==`string`?splitDiscordMessageContent(e.content).map((t,n)=>n===0?{...e,content:t}:{allowed_mentions:e.allowed_mentions,content:t}):[e]}export{discordChannel};
1
+ import{discordAudience,discordInstrumentationMetadata}from"./audience.js";import{createLogger,logError}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{INACTIVE_REQUEST_NOTICE,respondOrRetireInactivePrompt}from"#channel/inactive-prompt.js";import"#public/channels/discord/verify.js";import{buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent}from"#public/channels/discord/hitl.js";import{callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordBotToken,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{answerDiscordAuthorizationReveal,readDiscordAuthorizationReveal}from"#public/channels/discord/authorization.js";import{defaultDiscordAuth,defaultEvents,defaultOnCommand,editDiscordResolvedPrompt}from"#public/channels/discord/defaults.js";import{DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordDeferredJson,discordJson,discordJsonBody,readMessageContent}from"#public/channels/discord/responses.js";import{createDiscordGatewayRoute}from"#public/channels/discord/messages.js";import{verifyDiscordInbound}from"#public/channels/discord/verifyInbound.js";import{createDiscordFetchFile,discordCommandContent}from"#public/channels/discord/attachments.js";const log=createLogger(`discord.channel`);function discordChannel(e={}){let t=e.onCommand??defaultOnCommand,n=e.onInputResponse??(e.onCommand===void 0?acceptAsPresser:dropUnmappedInputResponse),r={...defaultEvents,...e.events};return defineChannel({kindHint:`discord`,turnPolicy:e.turnPolicy,state:initialDiscordState(),metadata:discordInstrumentationMetadata,audience:({state:e})=>e.audience??`unknown`,fetchFile:createDiscordFetchFile(e.api?.fetch),context(t,n){return rebuildDiscordContext(t,n,e)},routes:[POST(e.route??`/eve/v1/discord`,async(r,{from:i,resolveSession:a,waitUntil:o})=>{let s=await verifyDiscordInbound(r,e.credentials);if(s===null)return new Response(`unauthorized`,{status:401});let c;try{c=parseJsonObject(JSON.parse(s))}catch(e){return log.warn(`inbound Discord body is not valid JSON`,{error:e}),discordJson({content:`invalid request`,ephemeral:!0})}if(c.type===DISCORD_INTERACTION_TYPE.PING)return discordJson({type:DISCORD_INTERACTION_RESPONSE_TYPE.PONG});let l=parseDiscordInteraction(c);return l===null?discordJson({content:`Unsupported Discord interaction.`,ephemeral:!0}):handleInteraction({config:e,interaction:l,onCommand:t,onInputResponse:n,from:i,resolveSession:a,waitUntil:o})}),...e.gateway===void 0?[]:[createDiscordGatewayRoute({buildContext:t=>({discord:buildDiscordHandle({config:e,state:t})}),config:e,gateway:e.gateway})]],async receive(t,{from:n}){let r=t.target,i=readNonEmptyString(r.channelId);if(!i)throw Error(`discordChannel().receive requires target.channelId.`);let a=readNonEmptyString(r.conversationId),o=r.initialMessage;if(o!==void 0&&a!==void 0)throw Error("discordChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let s=a??``,c=a!==void 0;if(o!==void 0){let t=await buildDiscordHandle({config:e,state:{...initialDiscordState(),channelId:i}}).sendChannelMessage(o);s=t.id,c=t.id.length>0}return n(discordContinuationToken(i,s)).send(t.message,{auth:t.auth,state:{applicationId:null,channelId:i,conversationId:s||null,guildId:null,hasMessageAnchor:c,initialResponseSent:!0,interactionToken:null}})},events:r})}function rebuildDiscordContext(e,t,n){return{discord:buildDiscordHandle({config:n,session:t,state:e}),state:e}}function buildDiscordHandle(e){let t=e.config.api,n=e.state,r=mergeCredentials(e.config.credentials,n);function anchor(t){t.id&&(n.hasMessageAnchor||=(n.conversationId=t.id,!0),n.channelId&&e.session?.continuation?.alias(discordContinuationToken(n.channelId,t.id)))}async function sendViaChannel(e){let i=n.channelId??``;if(!i)throw Error(`discordChannel: missing channel id for outbound message.`);let a=normalizePostInput(e),o=await sendDiscordChannelMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,channelId:i});return anchor(o),o}async function editOriginal(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for original response edit.`);let a=normalizePostInput(e),o=await editDiscordOriginalResponse({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,interactionToken:i});return n.initialResponseSent=!0,anchor(o),o}async function followup(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for followup message.`);let a=normalizePostInput(e),o=await createDiscordFollowupMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,interactionToken:i});return anchor(o),o}async function startTyping(){let e=n.channelId??``;if(e)try{await triggerDiscordTypingIndicator({apiBaseUrl:t?.apiBaseUrl,credentials:r,fetch:t?.fetch,channelId:e})}catch(t){logError(log,`Discord typing indicator failed — swallowed`,t,{channelId:e})}}return{applicationId:n.applicationId??void 0,channelId:n.channelId??``,conversationId:n.conversationId??``,guildId:n.guildId??void 0,interactionToken:n.interactionToken??void 0,request(e,n,i){return callDiscordApi({apiBaseUrl:t?.apiBaseUrl,body:n,botToken:i?.botAuth===!0?r.botToken:void 0,fetch:t?.fetch,method:i?.method,path:e})},async post(e){let t=expandPostBodies(normalizePostInput(e)),r;for(let e of t){let t=await postOne({body:e,editOriginal,followup,sendViaChannel,state:n});r===void 0&&(r=t)}return r??{id:``,raw:null}},editOriginalResponse:editOriginal,followup,sendChannelMessage:sendViaChannel,startTyping}}async function postOne(e){if(e.state.interactionToken&&e.state.applicationId)try{return e.state.initialResponseSent?await e.followup(e.body):await e.editOriginal(e.body)}catch(e){log.warn(`Discord interaction-token delivery failed, falling back to channel message`,{error:e})}return e.sendViaChannel(e.body)}async function handleInteraction(e){if(e.interaction.type===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT){let t=readDiscordAuthorizationReveal(e.interaction.customId);if(t!==null)return revealAuthorization({...e,interaction:e.interaction,reveal:t})}return e.interaction.type===DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND?handleCommandInteraction({config:e.config,interaction:e.interaction,onCommand:e.onCommand,from:e.from,waitUntil:e.waitUntil}):e.interaction.type===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT?handleComponentInteraction({config:e.config,interaction:e.interaction,onInputResponse:e.onInputResponse,from:e.from,waitUntil:e.waitUntil}):handleModalSubmitInteraction({config:e.config,interaction:e.interaction,onInputResponse:e.onInputResponse,from:e.from,waitUntil:e.waitUntil})}async function handleCommandInteraction(e){let t=stateFromInteraction(e.interaction,{conversationId:e.interaction.id,hasMessageAnchor:!1,initialResponseSent:!1}),n={discord:buildDiscordHandle({config:e.config,state:t})},r;try{r=await e.onCommand(n,e.interaction)}catch(e){return log.error(`command handler failed`,{error:e}),discordJson({content:`The Discord command handler failed.`,ephemeral:!0})}return r==null?discordJson({content:`Command ignored.`,ephemeral:!0}):(e.waitUntil(dispatchCommand({interaction:e.interaction,result:r,from:e.from,state:t})),discordDeferredJson(r.ephemeral===!0))}function revealAuthorization(e){return e.waitUntil(answerRevealedAuthorization(e)),discordDeferredJson(!0)}async function answerRevealedAuthorization(e){let{interaction:t}=e,n=stateFromInteraction(t,{conversationId:t.messageId,hasMessageAnchor:!0,initialResponseSent:!1}),r=buildDiscordHandle({config:e.config,state:n}),i=null;try{i=(await e.onInputResponse({defaultAuth:defaultDiscordAuth(t),discord:r},t))?.auth??null}catch(e){log.error(`Discord sign-in press authorization failed`,{error:e})}let a=await answerDiscordAuthorizationReveal({auth:i,resolveSession:()=>e.resolveSession(discordContinuationToken(t.channelId,t.messageId)),reveal:e.reveal});try{await r.editOriginalResponse(a)}catch(e){log.error(`Discord sign-in reply failed`,{error:e})}}function handleComponentInteraction(e){if(isDiscordFreeformComponent(e.interaction.customId)){let t=readMessageContent(e.interaction.raw);return discordJsonBody(buildFreeformModalResponse({customId:e.interaction.customId,prompt:t}))}let t=deriveComponentInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({config:e.config,onInputResponse:e.onInputResponse,conversationId:e.interaction.messageId,inputResponses:t,interaction:e.interaction,from:e.from})),discordJsonBody({type:DISCORD_INTERACTION_RESPONSE_TYPE.DEFERRED_UPDATE_MESSAGE})}function handleModalSubmitInteraction(e){let t=deriveModalInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({config:e.config,onInputResponse:e.onInputResponse,conversationId:e.interaction.messageId??e.interaction.id,inputResponses:t,interaction:e.interaction,from:e.from})),discordJson({content:`Answer received.`,ephemeral:!0})}async function dispatchCommand(e){let t=discordCommandContent(commandInteractionMessage(e.interaction),e.interaction.attachments),n=formatDiscordContextBlock({applicationId:e.interaction.applicationId,channelId:e.interaction.channelId,commandName:e.interaction.commandName,guildId:e.interaction.guildId,interactionId:e.interaction.id,userId:e.interaction.user.id,username:e.interaction.user.username}),r=e.result.context??[];try{await e.from(discordContinuationToken(e.interaction.channelId,e.interaction.id)).send(t,{auth:e.result.auth,context:[n,...r],history:e.result.history,state:e.state,title:e.result.title})}catch(e){log.error(`command delivery failed`,{error:e})}}async function dispatchInputResponses(e){let t=stateFromInteraction(e.interaction,{conversationId:e.conversationId,hasMessageAnchor:e.conversationId!==e.interaction.id,initialResponseSent:!0}),n=buildDiscordHandle({config:e.config,state:t}),r;try{r=await e.onInputResponse({defaultAuth:defaultDiscordAuth(e.interaction),discord:n},e.interaction)}catch(e){log.error(`input response handler failed`,{error:e});return}if(r===null)return;let{auth:i}=r,a=e.from(discordContinuationToken(e.interaction.channelId,e.conversationId)),o=await respondOrRetireInactivePrompt(()=>a.respond(e.inputResponses,{auth:i}),{retirePrompt:async t=>{let r=e.interaction.messageId,i=readMessageContent(e.interaction.raw);r!==void 0&&i!==void 0&&await editDiscordResolvedPrompt(n,{content:i,messageId:r},t)}},log);o.outcome===`inactive`&&await Promise.all([o.retirement,sendInactiveNotice(n)])}async function sendInactiveNotice(e){try{await e.followup({content:INACTIVE_REQUEST_NOTICE,flags:DISCORD_EPHEMERAL_MESSAGE_FLAG})}catch(e){log.error(`inactive prompt notice failed`,{error:e})}}function acceptAsPresser(e){return{auth:e.defaultAuth}}function dropUnmappedInputResponse(){return log.warn(`dropped a Discord input response: onCommand is customized but onInputResponse is not; set onInputResponse to accept button presses and modal submissions`),null}function stateFromInteraction(e,t){return{audience:discordAudience(e.channelType),directMessage:e.channelType===1,applicationId:e.applicationId,channelId:e.channelId,conversationId:t.conversationId,guildId:e.guildId??null,hasMessageAnchor:t.hasMessageAnchor,initialResponseSent:t.initialResponseSent,interactionToken:e.token}}function initialDiscordState(){return{applicationId:null,channelId:null,conversationId:null,guildId:null,hasMessageAnchor:!1,initialResponseSent:!1,interactionToken:null}}function mergeCredentials(e,t){return{applicationId:t.applicationId??e?.applicationId,botToken:e?.botToken??(()=>resolveDiscordBotToken()),publicKey:e?.publicKey,webhookVerifier:e?.webhookVerifier}}function normalizePostInput(e){return typeof e==`string`?{content:e}:e}function expandPostBodies(e){return typeof e.content==`string`?splitDiscordMessageContent(e.content).map((t,n)=>n===0?{...e,content:t}:{allowed_mentions:e.allowed_mentions,content:t}):[e]}export{discordChannel};
@@ -0,0 +1,26 @@
1
+ import { type DiscordFetch } from "#public/channels/discord/api.js";
2
+ /** Raised when Discord refuses the bot outright, so reconnecting cannot help. */
3
+ export declare class DiscordGatewayFatalError extends Error {
4
+ }
5
+ /** A Gateway dispatch (op 0) as Discord sends it. */
6
+ export interface DiscordGatewayDispatch {
7
+ readonly op: 0;
8
+ readonly t: string;
9
+ readonly s: number;
10
+ readonly d: unknown;
11
+ }
12
+ export interface GatewayConnectionOptions {
13
+ readonly apiBaseUrl?: string;
14
+ readonly fetch?: DiscordFetch;
15
+ readonly intents: number;
16
+ readonly resolveToken: () => Promise<string>;
17
+ readonly onDispatch: (dispatch: DiscordGatewayDispatch) => void;
18
+ readonly signal: AbortSignal;
19
+ }
20
+ /**
21
+ * Holds one Discord Gateway session until `signal` aborts, resuming across
22
+ * reconnects so dispatches are not lost while the process lives.
23
+ */
24
+ export declare function runGatewayConnection(options: GatewayConnectionOptions): Promise<void>;
25
+ /** Resolves after `ms`, or as soon as `signal` aborts. */
26
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
@@ -0,0 +1 @@
1
+ import{createLogger}from"#internal/logging.js";import{isNonEmptyString,isObject}from"#shared/guards.js";import{callDiscordApi}from"#public/channels/discord/api.js";const log=createLogger(`discord.gateway`),RESUMABLE_CLOSE=4e3,FATAL_CLOSE_CODES=new Set([4004,4010,4011,4012,4013,4014]),SESSION_RESET_CLOSE_CODES=new Set([4007,4009]);var DiscordGatewayFatalError=class extends Error{};async function runGatewayConnection(e){let t,n=null,r=0,i;for(;!e.signal.aborted;){let a,o;try{if(a=await e.resolveToken(),t!==void 0)o=t.resumeUrl;else{let e=await discoverGatewayUrl(a);if(`fatal`in e)throw new DiscordGatewayFatalError(e.fatal);o=e.url}}catch(t){if(t instanceof DiscordGatewayFatalError)throw t;log.warn(`Discord Gateway connect failed`,{error:t}),await sleep(backoff(r++),e.signal);continue}if(e.signal.aborted)return;let s=await connect(o,a);if(e.signal.aborted)return;if(FATAL_CLOSE_CODES.has(s.code))throw new DiscordGatewayFatalError(`Discord closed the Gateway with ${s.code} (${s.reason}). Check the bot token and that every requested intent is enabled under Bot in the Discord Developer Portal.`);SESSION_RESET_CLOSE_CODES.has(s.code)&&(t=void 0,n=null);let c=i??backoff(r++);i=void 0,log.warn(`Discord Gateway closed`,{code:s.code,reason:s.reason,retryInMs:Math.round(c)}),await sleep(c,e.signal)}async function discoverGatewayUrl(t){let n=await callDiscordApi({apiBaseUrl:e.apiBaseUrl,botToken:t,fetch:e.fetch,method:`GET`,path:`/gateway/bot`});if(n.status===401)return{fatal:`Discord rejected the bot token while looking up the Gateway URL.`};if(!n.ok||!isObject(n.body)||!isNonEmptyString(n.body.url))throw Error(`Discord Gateway URL lookup failed with HTTP ${n.status}.`);return{url:n.body.url}}function connect(r,a){return new Promise(o=>{let s=new URL(r);s.searchParams.set(`v`,`10`),s.searchParams.set(`encoding`,`json`);let c=new WebSocket(s),l,u,d=!0,f=!1,settle=(t,n)=>{f||(f=!0,clearTimeout(l),clearTimeout(u),e.signal.removeEventListener(`abort`,onAbort),o({code:t,reason:n}))},send=e=>{c.readyState===WebSocket.OPEN&&c.send(JSON.stringify(e))},close=(e,t)=>{c.readyState!==WebSocket.CLOSING&&c.readyState!==WebSocket.CLOSED&&(c.close(e,t),u=setTimeout(()=>settle(e,t),3e3))},onAbort=()=>close(1e3,`shutdown`);e.signal.addEventListener(`abort`,onAbort,{once:!0});let heartbeat=e=>{if(!d){close(RESUMABLE_CLOSE,`heartbeat not acknowledged`);return}d=!1,send({op:1,d:n}),l=setTimeout(()=>heartbeat(e),e)},identifyOrResume=()=>{if(t!==void 0&&n!==null){send({op:6,d:{seq:n,session_id:t.id,token:a}});return}send({op:2,d:{intents:e.intents,properties:{browser:`eve`,device:`eve`,os:process.platform},token:a}})};c.addEventListener(`message`,e=>{if(f)return;let r;try{r=JSON.parse(String(e.data))}catch{log.warn(`Discord Gateway sent a payload that is not JSON`);return}switch(typeof r.s==`number`&&(n=r.s),r.op){case 0:onDispatch(r);return;case 1:send({op:1,d:n});return;case 7:i=0,close(RESUMABLE_CLOSE,`reconnect requested`);return;case 9:r.d!==!0&&(t=void 0,n=null),i=1e3+Math.random()*4e3,close(RESUMABLE_CLOSE,`invalid session`);return;case 10:{let e=Number(isObject(r.d)?r.d.heartbeat_interval:void 0);l=setTimeout(()=>heartbeat(e),e*Math.random()),identifyOrResume();return}case 11:d=!0;return}}),c.addEventListener(`close`,e=>settle(e.code,e.reason))})}function onDispatch(i){if(i.t===`READY`){let e=isObject(i.d)?i.d:{};isNonEmptyString(e.session_id)&&isNonEmptyString(e.resume_gateway_url)&&(t={id:e.session_id,resumeUrl:e.resume_gateway_url}),r=0,log.info(`Discord Gateway ready`,{sessionId:t?.id});return}if(i.t===`RESUMED`){r=0,log.info(`Discord Gateway resumed`,{sequence:n});return}typeof i.t==`string`&&typeof i.s==`number`&&e.onDispatch({d:i.d,op:0,s:i.s,t:i.t})}}function backoff(e){return Math.min(6e4,1e3*2**e)*(.5+Math.random()/2)}function sleep(e,t){return new Promise(n=>{let r=setTimeout(done,e);t?.addEventListener(`abort`,done,{once:!0});function done(){clearTimeout(r),t?.removeEventListener(`abort`,done),n()}})}export{DiscordGatewayFatalError,runGatewayConnection,sleep};
@@ -0,0 +1,14 @@
1
+ import type { DiscordGatewayDispatch } from "#public/channels/discord/gateway/connection.js";
2
+ export interface Forwarder {
3
+ enqueue(dispatch: DiscordGatewayDispatch): void;
4
+ /** Resolves once the backlog is delivered or `timeoutMs` elapses. */
5
+ drain(timeoutMs: number): Promise<void>;
6
+ }
7
+ /**
8
+ * Delivers dispatches to eve one at a time, in Gateway order. A bounded
9
+ * backlog keeps a long eve outage from growing the relay's memory without limit.
10
+ */
11
+ export declare function createForwarder(options: {
12
+ readonly url: URL;
13
+ readonly headers: () => Promise<Readonly<Record<string, string>>>;
14
+ }): Forwarder;
@@ -0,0 +1 @@
1
+ import{createLogger}from"#internal/logging.js";import{sleep}from"#public/channels/discord/gateway/connection.js";const log=createLogger(`discord.gateway`),UNSENT_ERROR_CODES=new Set([`ECONNREFUSED`,`ENOTFOUND`,`EAI_AGAIN`,`UND_ERR_CONNECT_TIMEOUT`]);function createForwarder(e){let t=Promise.resolve(),n=0;return{enqueue(e){if(n>=500){log.error(`Discord Gateway backlog is full; dropped a dispatch`,{event:e.t,sequence:e.s});return}n+=1,t=t.then(()=>deliver(e)).finally(()=>{--n})},async drain(e){if(n>0){let n=new AbortController;await Promise.race([t,sleep(e,n.signal)]),n.abort()}n>0&&log.warn(`Discord Gateway relay stopped with undelivered dispatches`,{pending:n})}};async function deliver(t){let n=JSON.stringify(t),r={event:t.t,sequence:t.s};for(let t=1;t<=5;t+=1){try{let i=await fetch(e.url,{body:n,headers:{"content-type":`application/json`,...await e.headers()},method:`POST`,signal:AbortSignal.timeout(3e4)});if(i.ok)return;let a=(await i.text()).slice(0,200);if(i.status>=500){log.error(`Gave up forwarding a Discord dispatch that eve may have received`,{...r,detail:a,status:i.status});return}if(i.status!==429){log.error(`eve rejected a forwarded Discord dispatch`,{...r,detail:a,hint:i.status===401||i.status===403?`eve did not accept the relay's credentials. On Vercel, check that the relay runs in the same project as the agent.`:`Check that ${e.url.href} is the agent's discordChannel({ gateway }) route.`,status:i.status});return}log.warn(`Retrying a forwarded Discord dispatch`,{...r,attempt:t,detail:a,status:i.status})}catch(e){if(!UNSENT_ERROR_CODES.has(errorCode(e))){log.error(`Gave up forwarding a Discord dispatch that eve may have received`,{...r,error:e});return}log.warn(`Retrying a forwarded Discord dispatch`,{...r,attempt:t,error:e})}t<5&&await sleep(Math.min(3e4,1e3*2**(t-1)))}log.error(`Gave up forwarding a Discord dispatch`,{...r,attempts:5})}}function errorCode(e){let t=(e instanceof Error?e.cause:void 0)?.code;return typeof t==`string`?t:``}export{createForwarder};
@@ -0,0 +1,59 @@
1
+ /**
2
+ * A long-running relay that holds a Discord Gateway connection and forwards
3
+ * message dispatches to an eve agent's `discordChannel({ gateway })` route.
4
+ * Run it in a process that stays up, such as a Vercel Daemon; it does not
5
+ * belong in the agent itself.
6
+ */
7
+ import { type OutboundAuthFn } from "#public/agents/auth.js";
8
+ import { type DiscordApiOptions, type DiscordBotToken } from "#public/channels/discord/api.js";
9
+ import { DiscordGatewayFatalError } from "#public/channels/discord/gateway/connection.js";
10
+ export { DiscordGatewayFatalError };
11
+ /** Options for {@link experimental_runDiscordGatewayRelay}. */
12
+ export interface DiscordGatewayRelayOptions {
13
+ /**
14
+ * Bot credentials. Pass the same object as the agent's `discordChannel`,
15
+ * such as `connectDiscordCredentials(...)`. `botToken` falls back to
16
+ * `DISCORD_BOT_TOKEN`.
17
+ */
18
+ readonly credentials?: {
19
+ readonly botToken?: DiscordBotToken;
20
+ };
21
+ /** Discord REST API overrides. */
22
+ readonly api?: Omit<DiscordApiOptions, "credentials">;
23
+ /**
24
+ * Base URL of the eve deployment. Defaults to
25
+ * `https://$VERCEL_PROJECT_PRODUCTION_URL`, which a Vercel Daemon has. Set it
26
+ * to `http://localhost:<port>` to relay to `eve dev`.
27
+ */
28
+ readonly url?: string | URL;
29
+ /** Path of the agent's Gateway route. Defaults to `/eve/v1/discord/gateway`. */
30
+ readonly route?: string;
31
+ /**
32
+ * Headers that authenticate each forwarded dispatch. Defaults to this
33
+ * project's Vercel OIDC token, which the route accepts by default. Without a
34
+ * token, as on a laptop, requests go out unauthenticated, which `eve dev`
35
+ * accepts.
36
+ */
37
+ readonly auth?: OutboundAuthFn;
38
+ /**
39
+ * Also request the privileged Message Content intent, so messages that do
40
+ * not mention the bot, such as thread follow-ups, arrive with their text.
41
+ * Enable it under Bot in the Discord Developer Portal first, or Discord
42
+ * refuses the connection.
43
+ */
44
+ readonly messageContent?: boolean;
45
+ /** Stops the relay. Defaults to the process's `SIGTERM` and `SIGINT`. */
46
+ readonly signal?: AbortSignal;
47
+ }
48
+ /**
49
+ * Connects to the Discord Gateway as the bot and forwards every
50
+ * `MESSAGE_CREATE` dispatch, unchanged and in order, to the agent's
51
+ * `discordChannel({ gateway })` route. Reconnects and resumes on its own.
52
+ * Resolves after `signal` aborts and in-flight deliveries drain; rejects with
53
+ * {@link DiscordGatewayFatalError} when Discord refuses the bot's token or
54
+ * intents.
55
+ *
56
+ * Run exactly one relay per bot: Discord sends every message to each
57
+ * connection, so a second relay makes the agent answer twice.
58
+ */
59
+ export declare function experimental_runDiscordGatewayRelay(options?: DiscordGatewayRelayOptions): Promise<void>;
@@ -0,0 +1 @@
1
+ import{createLogger}from"#internal/logging.js";import{resolveDiscordBotToken}from"#public/channels/discord/api.js";import{DiscordGatewayFatalError,runGatewayConnection}from"#public/channels/discord/gateway/connection.js";import{vercelOidc}from"#public/agents/auth.js";import{createForwarder}from"#public/channels/discord/gateway/forwarder.js";const log=createLogger(`discord.gateway`);async function experimental_runDiscordGatewayRelay(e={}){let t=new URL(e.route??`/eve/v1/discord/gateway`,resolveBaseUrl(e.url)),n=e.signal===void 0?listenForShutdown():void 0,r=e.signal??n.signal,i=createForwarder({headers:outboundHeaders(e.auth),url:t});log.info(`Discord Gateway relay started`,{target:t.href});try{await runGatewayConnection({apiBaseUrl:e.api?.apiBaseUrl,fetch:e.api?.fetch,intents:4608|(e.messageContent===!0?32768:0),onDispatch:e=>{e.t===`MESSAGE_CREATE`&&i.enqueue(e)},resolveToken:()=>resolveDiscordBotToken(e.credentials?.botToken),signal:r})}finally{n?.dispose(),await i.drain(8e3)}}function resolveBaseUrl(e){if(e!==void 0)return new URL(e);let t=process.env.VERCEL_PROJECT_PRODUCTION_URL?.trim();if(t)return new URL(`https://${t}`);throw Error("experimental_runDiscordGatewayRelay needs the eve deployment's URL: pass `url`, such as http://localhost:2000 for eve dev, or run it where VERCEL_PROJECT_PRODUCTION_URL is set.")}function outboundHeaders(e){if(e!==void 0)return async()=>(await e()).headers;let t=vercelOidc(),n=!1;return async()=>{try{return(await t()).headers}catch(e){return n||(n=!0,log.warn(`No Vercel OIDC token; forwarding without credentials`,{error:e})),{}}}}function listenForShutdown(){let e=new AbortController,t=[`SIGTERM`,`SIGINT`],onSignal=t=>{log.info(`Discord Gateway relay shutting down`,{signal:t}),e.abort()};for(let e of t)process.once(e,onSignal);return{signal:e.signal,dispose:()=>{for(let e of t)process.off(e,onSignal)}}}export{DiscordGatewayFatalError,experimental_runDiscordGatewayRelay};
@@ -101,15 +101,18 @@ export interface DiscordModalSubmitInteraction extends DiscordInteractionBase {
101
101
  export type DiscordInteraction = DiscordCommandInteraction | DiscordComponentInteraction | DiscordModalSubmitInteraction;
102
102
  /**
103
103
  * Fields rendered into the model-visible `<discord_context>` block by
104
- * {@link formatDiscordContextBlock}. The optional fields (username, guildId,
105
- * commandName) are omitted from the block when not provided.
104
+ * {@link formatDiscordContextBlock}. Optional fields are omitted from the
105
+ * block when not provided.
106
106
  */
107
107
  export interface DiscordInboundContext {
108
108
  readonly applicationId?: string;
109
109
  readonly channelId: string;
110
110
  readonly commandName?: string;
111
111
  readonly guildId?: string;
112
- readonly interactionId: string;
112
+ /** Set for interactions such as slash commands. */
113
+ readonly interactionId?: string;
114
+ /** Set for ordinary messages forwarded from the Discord Gateway. */
115
+ readonly messageId?: string;
113
116
  readonly userId: string;
114
117
  readonly username?: string;
115
118
  }
@@ -119,3 +122,7 @@ export declare function parseDiscordInteraction(value: unknown): DiscordInteract
119
122
  export declare function commandInteractionMessage(interaction: DiscordCommandInteraction): string;
120
123
  /** Renders one {@link DiscordInboundContext} as a deterministic context block. */
121
124
  export declare function formatDiscordContextBlock(context: DiscordInboundContext): string;
125
+ /** Parses a raw Discord user object, as interactions and Gateway messages carry it. */
126
+ export declare function parseDiscordUser(value: unknown): DiscordUser | null;
127
+ /** Parses a raw Discord attachment object, as Gateway messages and resolved command data carry it. */
128
+ export declare function parseDiscordAttachment(raw: unknown): DiscordAttachment | null;
@@ -1,2 +1,2 @@
1
- import{isNonEmptyString,isObject}from"#shared/guards.js";const DISCORD_INTERACTION_TYPE={APPLICATION_COMMAND:2,MESSAGE_COMPONENT:3,MODAL_SUBMIT:5,PING:1},DISCORD_INTERACTION_RESPONSE_TYPE={CHANNEL_MESSAGE_WITH_SOURCE:4,DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE:5,DEFERRED_UPDATE_MESSAGE:6,MODAL:9,PONG:1},DISCORD_EPHEMERAL_MESSAGE_FLAG=64;function parseDiscordInteraction(e){if(!isObject(e))return null;let t=e.type;return t===DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND?parseCommandInteraction(e):t===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT?parseComponentInteraction(e):t===DISCORD_INTERACTION_TYPE.MODAL_SUBMIT?parseModalSubmitInteraction(e):null}function commandInteractionMessage(e){let t=findOptionValue(e.options,`message`);if(typeof t==`string`&&t.trim().length>0)return t;let n=formatCommandOptions(e.options);return n?`/${e.commandName} ${n}`:`/${e.commandName}`}function formatDiscordContextBlock(e){return[`<discord_context>`,`response_medium: discord`,`response_instructions: Reply for Discord in concise Markdown. Avoid mass mentions, long tables, and messages that need more than a few short posts.`,...e.applicationId?[`application_id: ${e.applicationId}`]:[],`user_id: ${e.userId}`,...e.username?[`username: ${e.username}`]:[],`channel_id: ${e.channelId}`,...e.guildId?[`guild_id: ${e.guildId}`]:[],`interaction_id: ${e.interactionId}`,...e.commandName?[`command_name: ${e.commandName}`]:[],`</discord_context>`].join(`
2
- `)}function parseCommandInteraction(e){let t=parseInteractionBase(e),n=isObject(e.data)?e.data:null;if(!t||!n||!isNonEmptyString(n.name))return null;let r=parseOptions(n.options);return{...t,attachments:resolveAttachments(r,n.resolved),commandId:isNonEmptyString(n.id)?n.id:void 0,commandName:n.name,options:r,type:DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND}}function parseComponentInteraction(e){let t=parseInteractionBase(e),n=isObject(e.data)?e.data:null,r=isObject(e.message)?e.message:null;if(!t||!n||!isNonEmptyString(n.custom_id))return null;let i=isNonEmptyString(r?.id)?r.id:``;return i?{...t,componentType:typeof n.component_type==`number`?n.component_type:0,customId:n.custom_id,messageId:i,type:DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT,values:Array.isArray(n.values)?n.values.filter(e=>typeof e==`string`):[]}:null}function parseModalSubmitInteraction(e){let t=parseInteractionBase(e),n=isObject(e.data)?e.data:null;if(!t||!n||!isNonEmptyString(n.custom_id))return null;let r=isObject(e.message)?e.message:null;return{...t,customId:n.custom_id,messageId:isNonEmptyString(r?.id)?r.id:void 0,textInputs:parseTextInputs(n.components),type:DISCORD_INTERACTION_TYPE.MODAL_SUBMIT}}function parseInteractionBase(e){if(!isNonEmptyString(e.id)||!isNonEmptyString(e.application_id)||!isNonEmptyString(e.channel_id)||!isNonEmptyString(e.token))return null;let t=parseInteractionUser(e);if(!t)return null;let n=isObject(e.channel)?e.channel:void 0;return{applicationId:e.application_id,channelId:e.channel_id,channelType:typeof n?.type==`number`?n.type:void 0,guildId:isNonEmptyString(e.guild_id)?e.guild_id:void 0,id:e.id,member:parseMember(e.member),raw:e,token:e.token,user:t}}function parseInteractionUser(e){return parseUser(e.user)||(parseMember(e.member)?.user??null)}function parseMember(e){if(!isObject(e))return;let t=parseUser(e.user);if(t)return{nick:isNonEmptyString(e.nick)?e.nick:void 0,roles:Array.isArray(e.roles)?e.roles.filter(e=>typeof e==`string`):[],user:t}}function parseUser(e){return!isObject(e)||!isNonEmptyString(e.id)||!isNonEmptyString(e.username)?null:{avatar:isNonEmptyString(e.avatar)?e.avatar:void 0,discriminator:isNonEmptyString(e.discriminator)?e.discriminator:void 0,globalName:isNonEmptyString(e.global_name)?e.global_name:void 0,id:e.id,isBot:e.bot===!0,username:e.username}}function parseOptions(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!isObject(n)||!isNonEmptyString(n.name))continue;let e={name:n.name,options:parseOptions(n.options),type:typeof n.type==`number`?n.type:void 0,value:parseOptionValue(n.value)};t.push(e)}return t}function resolveAttachments(e,t){let n=isObject(t)&&isObject(t.attachments)?t.attachments:void 0;return n===void 0?[]:attachmentOptionIds(e).flatMap(e=>{let t=n[e];return!isObject(t)||!isNonEmptyString(t.url)||!isNonEmptyString(t.filename)?[]:[{contentType:isNonEmptyString(t.content_type)?t.content_type:void 0,filename:t.filename,id:e,size:typeof t.size==`number`?t.size:void 0,url:t.url}]})}function attachmentOptionIds(e){return e.flatMap(e=>[...e.type===11&&typeof e.value==`string`?[e.value]:[],...attachmentOptionIds(e.options)])}function parseOptionValue(e){if(typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e}function parseTextInputs(e){let t={};if(!Array.isArray(e))return t;for(let n of e)if(isObject(n)&&Array.isArray(n.components))for(let e of n.components)isObject(e)&&isNonEmptyString(e.custom_id)&&typeof e.value==`string`&&(t[e.custom_id]=e.value);return t}function findOptionValue(e,t){for(let n of e){if(n.name===t&&n.value!==void 0)return n.value;let e=findOptionValue(n.options,t);if(e!==void 0)return e}}function formatCommandOptions(e){return e.map(formatOption).filter(e=>e.length>0).join(` `)}function formatOption(e){if(e.type===11)return``;if(e.value!==void 0)return`${e.name}:${String(e.value)}`;let t=formatCommandOptions(e.options);return t?`${e.name} ${t}`:e.name}export{DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction};
1
+ import{isNonEmptyString,isObject}from"#shared/guards.js";const DISCORD_INTERACTION_TYPE={APPLICATION_COMMAND:2,MESSAGE_COMPONENT:3,MODAL_SUBMIT:5,PING:1},DISCORD_INTERACTION_RESPONSE_TYPE={CHANNEL_MESSAGE_WITH_SOURCE:4,DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE:5,DEFERRED_UPDATE_MESSAGE:6,MODAL:9,PONG:1},DISCORD_EPHEMERAL_MESSAGE_FLAG=64;function parseDiscordInteraction(e){if(!isObject(e))return null;let t=e.type;return t===DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND?parseCommandInteraction(e):t===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT?parseComponentInteraction(e):t===DISCORD_INTERACTION_TYPE.MODAL_SUBMIT?parseModalSubmitInteraction(e):null}function commandInteractionMessage(e){let t=findOptionValue(e.options,`message`);if(typeof t==`string`&&t.trim().length>0)return t;let n=formatCommandOptions(e.options);return n?`/${e.commandName} ${n}`:`/${e.commandName}`}function formatDiscordContextBlock(e){return[`<discord_context>`,`response_medium: discord`,`response_instructions: Reply for Discord in concise Markdown. Avoid mass mentions, long tables, and messages that need more than a few short posts.`,...e.applicationId?[`application_id: ${e.applicationId}`]:[],`user_id: ${e.userId}`,...e.username?[`username: ${e.username}`]:[],`channel_id: ${e.channelId}`,...e.guildId?[`guild_id: ${e.guildId}`]:[],...e.interactionId?[`interaction_id: ${e.interactionId}`]:[],...e.messageId?[`message_id: ${e.messageId}`]:[],...e.commandName?[`command_name: ${e.commandName}`]:[],`</discord_context>`].join(`
2
+ `)}function parseCommandInteraction(e){let t=parseInteractionBase(e),n=isObject(e.data)?e.data:null;if(!t||!n||!isNonEmptyString(n.name))return null;let r=parseOptions(n.options);return{...t,attachments:resolveAttachments(r,n.resolved),commandId:isNonEmptyString(n.id)?n.id:void 0,commandName:n.name,options:r,type:DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND}}function parseComponentInteraction(e){let t=parseInteractionBase(e),n=isObject(e.data)?e.data:null,r=isObject(e.message)?e.message:null;if(!t||!n||!isNonEmptyString(n.custom_id))return null;let i=isNonEmptyString(r?.id)?r.id:``;return i?{...t,componentType:typeof n.component_type==`number`?n.component_type:0,customId:n.custom_id,messageId:i,type:DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT,values:Array.isArray(n.values)?n.values.filter(e=>typeof e==`string`):[]}:null}function parseModalSubmitInteraction(e){let t=parseInteractionBase(e),n=isObject(e.data)?e.data:null;if(!t||!n||!isNonEmptyString(n.custom_id))return null;let r=isObject(e.message)?e.message:null;return{...t,customId:n.custom_id,messageId:isNonEmptyString(r?.id)?r.id:void 0,textInputs:parseTextInputs(n.components),type:DISCORD_INTERACTION_TYPE.MODAL_SUBMIT}}function parseInteractionBase(e){if(!isNonEmptyString(e.id)||!isNonEmptyString(e.application_id)||!isNonEmptyString(e.channel_id)||!isNonEmptyString(e.token))return null;let t=parseInteractionUser(e);if(!t)return null;let n=isObject(e.channel)?e.channel:void 0;return{applicationId:e.application_id,channelId:e.channel_id,channelType:typeof n?.type==`number`?n.type:void 0,guildId:isNonEmptyString(e.guild_id)?e.guild_id:void 0,id:e.id,member:parseMember(e.member),raw:e,token:e.token,user:t}}function parseInteractionUser(e){return parseDiscordUser(e.user)||(parseMember(e.member)?.user??null)}function parseMember(e){if(!isObject(e))return;let t=parseDiscordUser(e.user);if(t)return{nick:isNonEmptyString(e.nick)?e.nick:void 0,roles:Array.isArray(e.roles)?e.roles.filter(e=>typeof e==`string`):[],user:t}}function parseDiscordUser(e){return!isObject(e)||!isNonEmptyString(e.id)||!isNonEmptyString(e.username)?null:{avatar:isNonEmptyString(e.avatar)?e.avatar:void 0,discriminator:isNonEmptyString(e.discriminator)?e.discriminator:void 0,globalName:isNonEmptyString(e.global_name)?e.global_name:void 0,id:e.id,isBot:e.bot===!0,username:e.username}}function parseOptions(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!isObject(n)||!isNonEmptyString(n.name))continue;let e={name:n.name,options:parseOptions(n.options),type:typeof n.type==`number`?n.type:void 0,value:parseOptionValue(n.value)};t.push(e)}return t}function resolveAttachments(e,t){let n=isObject(t)&&isObject(t.attachments)?t.attachments:void 0;return n===void 0?[]:attachmentOptionIds(e).flatMap(e=>{let t=parseDiscordAttachment({...isObject(n[e])?n[e]:{},id:e});return t?[t]:[]})}function parseDiscordAttachment(e){return!isObject(e)||!isNonEmptyString(e.id)||!isNonEmptyString(e.url)||!isNonEmptyString(e.filename)?null:{contentType:isNonEmptyString(e.content_type)?e.content_type:void 0,filename:e.filename,id:e.id,size:typeof e.size==`number`?e.size:void 0,url:e.url}}function attachmentOptionIds(e){return e.flatMap(e=>[...e.type===11&&typeof e.value==`string`?[e.value]:[],...attachmentOptionIds(e.options)])}function parseOptionValue(e){if(typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e}function parseTextInputs(e){let t={};if(!Array.isArray(e))return t;for(let n of e)if(isObject(n)&&Array.isArray(n.components))for(let e of n.components)isObject(e)&&isNonEmptyString(e.custom_id)&&typeof e.value==`string`&&(t[e.custom_id]=e.value);return t}function findOptionValue(e,t){for(let n of e){if(n.name===t&&n.value!==void 0)return n.value;let e=findOptionValue(n.options,t);if(e!==void 0)return e}}function formatCommandOptions(e){return e.map(formatOption).filter(e=>e.length>0).join(` `)}function formatOption(e){if(e.type===11)return``;if(e.value!==void 0)return`${e.name}:${String(e.value)}`;let t=formatCommandOptions(e.options);return t?`${e.name} ${t}`:e.name}export{DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordAttachment,parseDiscordInteraction,parseDiscordUser};
@@ -17,7 +17,8 @@ export interface DiscordInstrumentationMetadata extends Record<string, unknown>
17
17
  }
18
18
  export { discordChannel, type DiscordChannel, type DiscordChannelConfig, type DiscordChannelCredentials, type DiscordChannelEvents, type DiscordChannelState, type DiscordCommandResult, type DiscordCommandResultOrPromise, type DiscordContext, type DiscordEventContext, type DiscordHandle, type DiscordInputResponseContext, type DiscordInputResponseInteraction, type DiscordInputResponseResult, type DiscordReceiveTarget, type DiscordRequestOptions, } from "#public/channels/discord/discordChannel.js";
19
19
  export { callDiscordApi, createDiscordFollowupMessage, discordContinuationToken, DISCORD_MESSAGE_CONTENT_MAX_LENGTH, DISCORD_NO_MENTIONS, editDiscordOriginalResponse, resolveDiscordApplicationId, resolveDiscordBotToken, resolveDiscordPublicKey, sendDiscordChannelMessage, splitDiscordMessageContent, triggerDiscordTypingIndicator, type DiscordApiOptions, type DiscordApiResponse, type DiscordApplicationId, type DiscordBotToken, type DiscordCredentials, type DiscordFetch, type DiscordMessageBody, type DiscordPostedMessage, } from "#public/channels/discord/api.js";
20
- export { DISCORD_EPHEMERAL_MESSAGE_FLAG, DISCORD_INTERACTION_RESPONSE_TYPE, DISCORD_INTERACTION_TYPE, commandInteractionMessage, formatDiscordContextBlock, parseDiscordInteraction, type DiscordCommandInteraction, type DiscordCommandOption, type DiscordComponentInteraction, type DiscordInboundContext, type DiscordInteraction, type DiscordInteractionBase, type DiscordMember, type DiscordModalSubmitInteraction, type DiscordUser, } from "#public/channels/discord/inbound.js";
20
+ export { DISCORD_EPHEMERAL_MESSAGE_FLAG, DISCORD_INTERACTION_RESPONSE_TYPE, DISCORD_INTERACTION_TYPE, commandInteractionMessage, formatDiscordContextBlock, parseDiscordInteraction, type DiscordAttachment, type DiscordCommandInteraction, type DiscordCommandOption, type DiscordComponentInteraction, type DiscordInboundContext, type DiscordInteraction, type DiscordInteractionBase, type DiscordMember, type DiscordModalSubmitInteraction, type DiscordUser, } from "#public/channels/discord/inbound.js";
21
21
  export { DISCORD_COMPONENT_TYPE, DISCORD_HITL_CUSTOM_ID_PREFIX, DISCORD_HITL_FREEFORM_CUSTOM_ID_PREFIX, DISCORD_HITL_FREEFORM_TEXT_INPUT_ID, buildFreeformModalResponse, deriveComponentInputResponses, deriveModalInputResponses, isDiscordFreeformComponent, renderInputRequestComponents, } from "#public/channels/discord/hitl.js";
22
- export { defaultDiscordAuth } from "#public/channels/discord/defaults.js";
22
+ export { defaultDiscordAuth, defaultDiscordMessageAuth, } from "#public/channels/discord/defaults.js";
23
+ export type { DiscordGatewayConfig, DiscordGatewayMessage, DiscordMessageResult, DiscordMessageResultOrPromise, DiscordStartThreadOptions, DiscordThreadAutoArchiveMinutes, } from "#public/channels/discord/messages.js";
23
24
  export { verifyDiscordRequest, verifyDiscordSignature, type DiscordPublicKey, type DiscordVerifyOptions, type DiscordWebhookVerifier, } from "#public/channels/discord/verify.js";
@@ -1 +1 @@
1
- import{verifyDiscordRequest,verifyDiscordSignature}from"#public/channels/discord/verify.js";import{DISCORD_MESSAGE_CONTENT_MAX_LENGTH,DISCORD_NO_MENTIONS,callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordApplicationId,resolveDiscordBotToken,resolveDiscordPublicKey,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{DISCORD_COMPONENT_TYPE,DISCORD_HITL_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_TEXT_INPUT_ID,buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent,renderInputRequestComponents}from"#public/channels/discord/hitl.js";import{defaultDiscordAuth}from"#public/channels/discord/defaults.js";import{DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordChannel}from"#public/channels/discord/discordChannel.js";export{DISCORD_COMPONENT_TYPE,DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_HITL_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_TEXT_INPUT_ID,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,DISCORD_MESSAGE_CONTENT_MAX_LENGTH,DISCORD_NO_MENTIONS,buildFreeformModalResponse,callDiscordApi,commandInteractionMessage,createDiscordFollowupMessage,defaultDiscordAuth,deriveComponentInputResponses,deriveModalInputResponses,discordChannel,discordContinuationToken,editDiscordOriginalResponse,formatDiscordContextBlock,isDiscordFreeformComponent,parseDiscordInteraction,renderInputRequestComponents,resolveDiscordApplicationId,resolveDiscordBotToken,resolveDiscordPublicKey,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator,verifyDiscordRequest,verifyDiscordSignature};
1
+ import{verifyDiscordRequest,verifyDiscordSignature}from"#public/channels/discord/verify.js";import{DISCORD_COMPONENT_TYPE,DISCORD_HITL_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_TEXT_INPUT_ID,buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent,renderInputRequestComponents}from"#public/channels/discord/hitl.js";import{DISCORD_MESSAGE_CONTENT_MAX_LENGTH,DISCORD_NO_MENTIONS,callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordApplicationId,resolveDiscordBotToken,resolveDiscordPublicKey,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{defaultDiscordAuth,defaultDiscordMessageAuth}from"#public/channels/discord/defaults.js";import{DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordChannel}from"#public/channels/discord/discordChannel.js";export{DISCORD_COMPONENT_TYPE,DISCORD_EPHEMERAL_MESSAGE_FLAG,DISCORD_HITL_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_CUSTOM_ID_PREFIX,DISCORD_HITL_FREEFORM_TEXT_INPUT_ID,DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,DISCORD_MESSAGE_CONTENT_MAX_LENGTH,DISCORD_NO_MENTIONS,buildFreeformModalResponse,callDiscordApi,commandInteractionMessage,createDiscordFollowupMessage,defaultDiscordAuth,defaultDiscordMessageAuth,deriveComponentInputResponses,deriveModalInputResponses,discordChannel,discordContinuationToken,editDiscordOriginalResponse,formatDiscordContextBlock,isDiscordFreeformComponent,parseDiscordInteraction,renderInputRequestComponents,resolveDiscordApplicationId,resolveDiscordBotToken,resolveDiscordPublicKey,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator,verifyDiscordRequest,verifyDiscordSignature};