eve 0.82.0 → 0.83.1

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 (528) hide show
  1. package/CHANGELOG.md +81 -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-DTu78IAF.js → use-eve-agent-DnbG9c7c.js} +73 -14
  9. package/dist/src/chunks/{use-eve-agent-DlznYwQk.js → use-eve-agent-ZY7NQ2VW.js} +73 -14
  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/cli/run.js +1 -1
  16. package/dist/src/client/eve-agent-store.d.ts +1 -1
  17. package/dist/src/client/eve-agent-store.js +1 -1
  18. package/dist/src/client/index.d.ts +1 -0
  19. package/dist/src/client/message-response.d.ts +18 -0
  20. package/dist/src/client/message-response.js +1 -1
  21. package/dist/src/client/session-controls.d.ts +6 -0
  22. package/dist/src/client/session-controls.js +1 -1
  23. package/dist/src/client/session.d.ts +4 -0
  24. package/dist/src/client/session.js +1 -1
  25. package/dist/src/compiled/.vendor-stamp.json +8 -8
  26. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  27. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +2 -0
  28. package/dist/src/compiled/@workflow/core/index.js +2 -2
  29. package/dist/src/compiled/@workflow/core/private.d.ts +5 -3
  30. package/dist/src/compiled/@workflow/core/private.js +1 -1
  31. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +1 -37
  32. package/dist/src/compiled/@workflow/core/runtime/event-limit-warning.d.ts +32 -0
  33. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +5 -6
  34. package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
  35. package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +8 -0
  36. package/dist/src/compiled/@workflow/core/runtime/start.d.ts +16 -0
  37. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +15 -18
  38. package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +20 -0
  39. package/dist/src/compiled/@workflow/core/runtime.js +4 -4
  40. package/dist/src/compiled/@workflow/core/seeded-nanoid.d.ts +2 -0
  41. package/dist/src/compiled/@workflow/core/serialization/compression.d.ts +14 -3
  42. package/dist/src/compiled/@workflow/core/serialization.d.ts +1 -1
  43. package/dist/src/compiled/@workflow/core/serialization.js +1 -1
  44. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +0 -18
  45. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  46. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  47. package/dist/src/compiled/@workflow/errors/index.d.ts +48 -0
  48. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  49. package/dist/src/compiled/@workflow/world/env-config.d.ts +24 -0
  50. package/dist/src/compiled/@workflow/world/events.d.ts +126 -7
  51. package/dist/src/compiled/@workflow/world/index.d.ts +3 -3
  52. package/dist/src/compiled/@workflow/world/interfaces.d.ts +59 -8
  53. package/dist/src/compiled/@workflow/world/queue.d.ts +71 -9
  54. package/dist/src/compiled/@workflow/world/recovery.d.ts +6 -0
  55. package/dist/src/compiled/@workflow/world/test-support/duplicate-event-fixtures.d.ts +3 -0
  56. package/dist/src/compiled/@workflow/world/test-support/in-band-fence-conformance.d.ts +46 -0
  57. package/dist/src/compiled/@workflow/world-local/index.js +5 -5
  58. package/dist/src/compiled/@workflow/world-vercel/index.js +18 -18
  59. package/dist/src/compiled/_chunks/workflow/{attribute-changes-BW-kbMMn.js → attribute-changes-7se_SE2q.js} +3 -3
  60. package/dist/src/compiled/_chunks/workflow/dist-CcnNPAp4.js +1 -0
  61. package/dist/src/compiled/_chunks/workflow/dist-S9cZRway.js +3 -0
  62. package/dist/src/compiled/_chunks/workflow/helpers-CxNRXH0a.js +1 -0
  63. package/dist/src/compiled/_chunks/workflow/private-DLYTSBbu.js +1 -0
  64. package/dist/src/compiled/_chunks/workflow/resume-hook-CPiIfe8r.js +1 -0
  65. package/dist/src/compiled/_chunks/workflow/{run-DzdAqdb1.js → run-BJSLCXR4.js} +6 -6
  66. package/dist/src/compiled/_chunks/workflow/serialization-B9gneT9Z.js +15 -0
  67. package/dist/src/compiled/_chunks/workflow/sleep-BL0oQs3R.js +1 -0
  68. package/dist/src/compiled/_chunks/workflow/{wait-until-xbRRDuUf.js → wait-until-BPou0RGO.js} +1 -1
  69. package/dist/src/compiled/_chunks/workflow/workflow-routes-BaljomCk.js +1 -0
  70. package/dist/src/compiled/{@ai-sdk/code-mode → run}/LICENSE +1 -1
  71. package/dist/src/compiled/run/index.d.ts +384 -0
  72. package/dist/src/compiled/run/index.js +650 -0
  73. package/dist/src/compiler/extension-compatibility.d.ts +21 -14
  74. package/dist/src/compiler/extension-compatibility.js +1 -1
  75. package/dist/src/compiler/manifest.js +1 -1
  76. package/dist/src/compiler/normalize-agent-config.js +1 -1
  77. package/dist/src/compiler/normalize-manifest.js +1 -1
  78. package/dist/src/compiler/normalize-sandbox.js +1 -1
  79. package/dist/src/compiler/workspace-resources.js +1 -1
  80. package/dist/src/context/build-callback-context.js +1 -1
  81. package/dist/src/context/build-dynamic-tools.js +1 -1
  82. package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -2
  83. package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
  84. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  85. package/dist/src/context/prewarm.d.ts +27 -0
  86. package/dist/src/context/prewarm.js +1 -0
  87. package/dist/src/context/providers/sandbox.d.ts +7 -0
  88. package/dist/src/context/providers/sandbox.js +1 -1
  89. package/dist/src/context/run-step.js +1 -1
  90. package/dist/src/discover/extension-specifier.d.ts +1 -0
  91. package/dist/src/discover/extension-specifier.js +1 -1
  92. package/dist/src/discover/lib.d.ts +4 -3
  93. package/dist/src/discover/lib.js +1 -1
  94. package/dist/src/discover/named-source-directory.d.ts +3 -2
  95. package/dist/src/evals/cli/eval.d.ts +2 -0
  96. package/dist/src/evals/cli/eval.js +2 -2
  97. package/dist/src/evals/define-eval-config.d.ts +5 -4
  98. package/dist/src/evals/define-eval-config.js +1 -1
  99. package/dist/src/evals/index.d.ts +1 -1
  100. package/dist/src/evals/runner/artifacts.js +2 -2
  101. package/dist/src/evals/runner/attempt-label.d.ts +2 -0
  102. package/dist/src/evals/runner/attempt-label.js +1 -0
  103. package/dist/src/evals/runner/derive-run-facts.d.ts +12 -0
  104. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  105. package/dist/src/evals/runner/execute-task.js +1 -1
  106. package/dist/src/evals/runner/reporters/braintrust.js +1 -1
  107. package/dist/src/evals/runner/reporters/console.js +1 -1
  108. package/dist/src/evals/runner/reporters/datadog.js +1 -1
  109. package/dist/src/evals/runner/reporters/junit.js +2 -2
  110. package/dist/src/evals/runner/reporters/types.d.ts +2 -0
  111. package/dist/src/evals/runner/run-evals.d.ts +5 -0
  112. package/dist/src/evals/runner/run-evals.js +1 -1
  113. package/dist/src/evals/session-manager.js +1 -1
  114. package/dist/src/evals/session.d.ts +4 -1
  115. package/dist/src/evals/session.js +2 -2
  116. package/dist/src/evals/types.d.ts +39 -2
  117. package/dist/src/eve-channel/index.js +1 -1
  118. package/dist/src/eve-channel/request.d.ts +0 -1
  119. package/dist/src/eve-channel/request.js +2 -2
  120. package/dist/src/execution/agent-sessions/context.d.ts +1 -1
  121. package/dist/src/execution/agent-sessions/context.js +1 -1
  122. package/dist/src/execution/coordination-dispatch-shared.d.ts +3 -0
  123. package/dist/src/execution/coordination-dispatch-shared.js +1 -1
  124. package/dist/src/execution/dynamic-workflow/program-step.d.ts +7 -7
  125. package/dist/src/execution/dynamic-workflow/program-step.js +1 -1
  126. package/dist/src/execution/dynamic-workflow/schema.d.ts +18 -11
  127. package/dist/src/execution/dynamic-workflow/schema.js +1 -1
  128. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  129. package/dist/src/execution/dynamic-workflow/workflow.js +1 -1
  130. package/dist/src/execution/eve-workflow-attributes.d.ts +3 -1
  131. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  132. package/dist/src/execution/invoke-tool.js +1 -1
  133. package/dist/src/execution/sandbox/abort-bound-session.js +1 -1
  134. package/dist/src/execution/sandbox/active-connections.d.ts +28 -0
  135. package/dist/src/execution/sandbox/active-connections.js +1 -0
  136. package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +10 -2
  137. package/dist/src/execution/sandbox/bindings/docker-cli.js +2 -2
  138. package/dist/src/execution/sandbox/bindings/docker-connection.d.ts +15 -0
  139. package/dist/src/execution/sandbox/bindings/docker-connection.js +2 -0
  140. package/dist/src/execution/sandbox/bindings/docker-container.d.ts +2 -0
  141. package/dist/src/execution/sandbox/bindings/docker-container.js +1 -1
  142. package/dist/src/execution/sandbox/bindings/docker-network.d.ts +5 -0
  143. package/dist/src/execution/sandbox/bindings/docker-network.js +1 -1
  144. package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
  145. package/dist/src/execution/sandbox/bindings/docker.d.ts +12 -15
  146. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  147. package/dist/src/execution/sandbox/bindings/just-bash-runtime.d.ts +19 -29
  148. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  149. package/dist/src/execution/sandbox/bindings/just-bash.d.ts +2 -4
  150. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
  151. package/dist/src/execution/sandbox/bindings/local-provider-utils.d.ts +0 -20
  152. package/dist/src/execution/sandbox/bindings/local-provider-utils.js +1 -1
  153. package/dist/src/execution/sandbox/bindings/local.d.ts +4 -6
  154. package/dist/src/execution/sandbox/bindings/local.js +1 -1
  155. package/dist/src/execution/sandbox/bindings/vercel-base-runtime.d.ts +2 -0
  156. package/dist/src/execution/sandbox/bindings/vercel-base-runtime.js +2 -2
  157. package/dist/src/execution/sandbox/bindings/vercel-errors.js +2 -2
  158. package/dist/src/execution/sandbox/bindings/vercel-lifecycle.d.ts +7 -5
  159. package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
  160. package/dist/src/execution/sandbox/bindings/vercel.d.ts +5 -11
  161. package/dist/src/execution/sandbox/bindings/vercel.js +1 -2
  162. package/dist/src/execution/sandbox/development-cleanup.d.ts +0 -1
  163. package/dist/src/execution/sandbox/development-cleanup.js +1 -1
  164. package/dist/src/execution/sandbox/development-lazy-prewarm.js +1 -1
  165. package/dist/src/execution/sandbox/development-run.d.ts +0 -2
  166. package/dist/src/execution/sandbox/development-run.js +1 -1
  167. package/dist/src/execution/sandbox/dockerfile.d.ts +0 -4
  168. package/dist/src/execution/sandbox/dockerfile.js +1 -1
  169. package/dist/src/execution/sandbox/ensure.d.ts +31 -11
  170. package/dist/src/execution/sandbox/ensure.js +1 -1
  171. package/dist/src/execution/sandbox/glob-tool.js +3 -3
  172. package/dist/src/execution/sandbox/grep-tool.js +1 -1
  173. package/dist/src/execution/sandbox/logging-session.js +1 -1
  174. package/dist/src/execution/sandbox/prewarm.d.ts +23 -3
  175. package/dist/src/execution/sandbox/prewarm.js +2 -1
  176. package/dist/src/execution/sandbox/read-file.js +1 -1
  177. package/dist/src/execution/sandbox/require-sandbox.d.ts +3 -2
  178. package/dist/src/execution/sandbox/require-sandbox.js +1 -1
  179. package/dist/src/execution/sandbox/ripgrep-probe.js +1 -1
  180. package/dist/src/execution/sandbox/session.d.ts +10 -20
  181. package/dist/src/execution/sandbox/session.js +2 -2
  182. package/dist/src/execution/session/admission.js +1 -1
  183. package/dist/src/execution/session/checkpoint-migrations.js +1 -1
  184. package/dist/src/execution/session/entry-input.d.ts +5 -4
  185. package/dist/src/execution/session/entry.js +1 -1
  186. package/dist/src/execution/session/handoff-state.d.ts +5 -0
  187. package/dist/src/execution/session/handoff-state.js +1 -0
  188. package/dist/src/execution/session/handoff-steps.d.ts +1 -5
  189. package/dist/src/execution/session/handoff-steps.js +1 -1
  190. package/dist/src/execution/session/handoff.d.ts +2 -1
  191. package/dist/src/execution/session/handoff.js +1 -1
  192. package/dist/src/execution/session/handover-tracing.d.ts +3 -0
  193. package/dist/src/execution/session/handover-tracing.js +1 -0
  194. package/dist/src/execution/session/input-queue.d.ts +3 -0
  195. package/dist/src/execution/session/input-queue.js +1 -1
  196. package/dist/src/execution/session/next-input.d.ts +3 -0
  197. package/dist/src/execution/session/next-input.js +1 -1
  198. package/dist/src/execution/session/prewarm-step.d.ts +13 -0
  199. package/dist/src/execution/session/prewarm-step.js +1 -0
  200. package/dist/src/execution/session/program.d.ts +4 -1
  201. package/dist/src/execution/session/program.js +1 -1
  202. package/dist/src/execution/session/state-cursor.d.ts +11 -0
  203. package/dist/src/execution/session/state-cursor.js +1 -1
  204. package/dist/src/execution/session/timeout-control.d.ts +4 -0
  205. package/dist/src/execution/session/timeout-control.js +1 -1
  206. package/dist/src/execution/session/turn-control.d.ts +5 -2
  207. package/dist/src/execution/session/turn-control.js +1 -1
  208. package/dist/src/execution/session/turn-step-types.d.ts +2 -0
  209. package/dist/src/execution/session/turn-step.js +1 -1
  210. package/dist/src/execution/session/turn.d.ts +1 -0
  211. package/dist/src/execution/session/turn.js +1 -1
  212. package/dist/src/execution/session-inbox/inbox.d.ts +17 -1
  213. package/dist/src/execution/session-inbox/inbox.js +1 -1
  214. package/dist/src/execution/session-inbox/protocol.d.ts +2 -1
  215. package/dist/src/execution/session-inbox/protocol.js +1 -1
  216. package/dist/src/execution/session-inbox/resume.d.ts +2 -1
  217. package/dist/src/execution/session-inbox/resume.js +1 -1
  218. package/dist/src/execution/session-prewarm.d.ts +8 -0
  219. package/dist/src/execution/session-prewarm.js +1 -0
  220. package/dist/src/execution/skills/instructions.js +1 -1
  221. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  222. package/dist/src/execution/tools/workflow/body.js +1 -1
  223. package/dist/src/execution/tools/workflow/step-context.d.ts +11 -0
  224. package/dist/src/execution/tools/workflow/step-execution.js +1 -1
  225. package/dist/src/execution/tools/workflow/step.js +1 -1
  226. package/dist/src/execution/workflow-runtime.js +1 -1
  227. package/dist/src/extensions/git/extension/lib/github-shell-schema.js +1 -1
  228. package/dist/src/framework/sources/modules/sandbox.d.ts +1 -1
  229. package/dist/src/harness/attachment-staging.d.ts +3 -7
  230. package/dist/src/harness/attachment-staging.js +1 -1
  231. package/dist/src/harness/hitl/index.d.ts +2 -1
  232. package/dist/src/harness/hitl/index.js +1 -1
  233. package/dist/src/harness/hitl/view.d.ts +1 -0
  234. package/dist/src/harness/hitl/view.js +1 -0
  235. package/dist/src/harness/model-call/run.js +1 -1
  236. package/dist/src/harness/semantic-errors/rules/sandbox.d.ts +3 -5
  237. package/dist/src/harness/semantic-errors/rules/sandbox.js +1 -1
  238. package/dist/src/harness/step/prompt.js +1 -1
  239. package/dist/src/harness/tool-history-repair.d.ts +9 -0
  240. package/dist/src/harness/tool-history-repair.js +1 -0
  241. package/dist/src/harness/tool-model-output.d.ts +19 -3
  242. package/dist/src/harness/tool-model-output.js +1 -1
  243. package/dist/src/internal/application/compiled-artifacts.js +8 -4
  244. package/dist/src/internal/application/optional-package-import.d.ts +10 -0
  245. package/dist/src/internal/application/optional-package-import.js +1 -1
  246. package/dist/src/internal/application/stamped-package-version.js +1 -1
  247. package/dist/src/internal/attachments/limited-read.d.ts +2 -2
  248. package/dist/src/internal/authored-module-build-options.d.ts +6 -0
  249. package/dist/src/internal/authored-module-build-options.js +1 -1
  250. package/dist/src/internal/authored-module-cache.d.ts +10 -0
  251. package/dist/src/internal/authored-module-cache.js +1 -0
  252. package/dist/src/internal/authored-module-graph.js +1 -1
  253. package/dist/src/internal/authored-module-loader.js +1 -1
  254. package/dist/src/internal/authored-relative-extension-resolver.js +1 -1
  255. package/dist/src/internal/bundler/nitro-rolldown.d.ts +3 -1
  256. package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
  257. package/dist/src/internal/bundler/pseudo-packages.d.ts +11 -0
  258. package/dist/src/internal/bundler/pseudo-packages.js +1 -0
  259. package/dist/src/internal/nitro/host/build-extension.d.ts +6 -0
  260. package/dist/src/internal/nitro/host/build-extension.js +2 -2
  261. package/dist/src/internal/nitro/host/compiled-sandbox-provider-prune-plugin.d.ts +3 -1
  262. package/dist/src/internal/nitro/host/compiled-sandbox-provider-prune-plugin.js +3 -5
  263. package/dist/src/internal/nitro/host/create-application-nitro.d.ts +2 -3
  264. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  265. package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.d.ts +2 -0
  266. package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.js +1 -1
  267. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  268. package/dist/src/internal/nitro/host/dev-build-host.d.ts +83 -0
  269. package/dist/src/internal/nitro/host/dev-build-host.js +1 -0
  270. package/dist/src/internal/nitro/host/dev-build-operations.d.ts +6 -0
  271. package/dist/src/internal/nitro/host/dev-build-operations.js +1 -0
  272. package/dist/src/internal/nitro/host/dev-build-process.d.ts +1 -0
  273. package/dist/src/internal/nitro/host/dev-build-process.js +1 -0
  274. package/dist/src/internal/nitro/host/development-runtime-prune-plugin.d.ts +4 -1
  275. package/dist/src/internal/nitro/host/development-runtime-prune-plugin.js +3 -2
  276. package/dist/src/internal/nitro/host/drained-nitro-dev-server.d.ts +13 -0
  277. package/dist/src/internal/nitro/host/drained-nitro-dev-server.js +1 -1
  278. package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.js +1 -1
  279. package/dist/src/internal/nitro/host/prepare-application-host.d.ts +3 -0
  280. package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
  281. package/dist/src/internal/nitro/host/sandbox-shutdown-plugin.js +1 -1
  282. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  283. package/dist/src/internal/nitro/host/start-production-server.js +3 -3
  284. package/dist/src/internal/nitro/host/workflow-sandbox-runtime-plugin.js +1 -1
  285. package/dist/src/internal/nitro/host.js +1 -1
  286. package/dist/src/internal/workflow/local-world-delivery-auth.d.ts +17 -0
  287. package/dist/src/internal/workflow/local-world-delivery-auth.js +1 -0
  288. package/dist/src/internal/workflow/queue-namespace.d.ts +2 -0
  289. package/dist/src/internal/workflow/queue-namespace.js +1 -1
  290. package/dist/src/internal/workflow-bundle/builder-support.d.ts +0 -1
  291. package/dist/src/internal/workflow-bundle/builder-support.js +2 -2
  292. package/dist/src/internal/workflow-bundle/builder.js +2 -2
  293. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  294. package/dist/src/internal/workflow-bundle/vercel-workflow-output.d.ts +1 -1
  295. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  296. package/dist/src/protocol/prewarm-session.d.ts +14 -0
  297. package/dist/src/protocol/prewarm-session.js +1 -0
  298. package/dist/src/protocol/routes.d.ts +2 -2
  299. package/dist/src/public/channels/discord/authorization.d.ts +45 -0
  300. package/dist/src/public/channels/discord/authorization.js +3 -0
  301. package/dist/src/public/channels/discord/defaults.d.ts +14 -3
  302. package/dist/src/public/channels/discord/defaults.js +2 -2
  303. package/dist/src/public/channels/discord/discordChannel.d.ts +15 -1
  304. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  305. package/dist/src/public/channels/discord/gateway/connection.d.ts +26 -0
  306. package/dist/src/public/channels/discord/gateway/connection.js +1 -0
  307. package/dist/src/public/channels/discord/gateway/forwarder.d.ts +14 -0
  308. package/dist/src/public/channels/discord/gateway/forwarder.js +1 -0
  309. package/dist/src/public/channels/discord/gateway/index.d.ts +59 -0
  310. package/dist/src/public/channels/discord/gateway/index.js +1 -0
  311. package/dist/src/public/channels/discord/inbound.d.ts +10 -3
  312. package/dist/src/public/channels/discord/inbound.js +2 -2
  313. package/dist/src/public/channels/discord/index.d.ts +3 -2
  314. package/dist/src/public/channels/discord/index.js +1 -1
  315. package/dist/src/public/channels/discord/messages.d.ts +116 -0
  316. package/dist/src/public/channels/discord/messages.js +2 -0
  317. package/dist/src/public/channels/github/checkout.js +1 -1
  318. package/dist/src/public/channels/linq/linqChannel.d.ts +4 -1
  319. package/dist/src/public/channels/linq/linqChannel.js +1 -1
  320. package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -1
  321. package/dist/src/public/channels/same-environment-oidc.d.ts +7 -0
  322. package/dist/src/public/channels/same-environment-oidc.js +1 -0
  323. package/dist/src/public/definitions/channel.js +1 -1
  324. package/dist/src/public/definitions/sandbox.d.ts +1 -1
  325. package/dist/src/public/next/server.js +1 -1
  326. package/dist/src/public/sandbox/docker-sandbox.d.ts +6 -1
  327. package/dist/src/public/sandbox/docker.d.ts +1 -8
  328. package/dist/src/public/sandbox/index.d.ts +3 -3
  329. package/dist/src/public/sandbox/just-bash-sandbox.d.ts +87 -7
  330. package/dist/src/public/sandbox/just-bash.d.ts +1 -1
  331. package/dist/src/public/sandbox/provider.d.ts +5 -1
  332. package/dist/src/public/sandbox/provider.js +1 -1
  333. package/dist/src/public/sandbox/vercel-sandbox.d.ts +16 -9
  334. package/dist/src/public/sandbox/vercel.d.ts +0 -1
  335. package/dist/src/public/sandbox/vercel.js +1 -1
  336. package/dist/src/public/tools/agent.d.ts +8 -1
  337. package/dist/src/public/tools/agent.js +1 -1
  338. package/dist/src/react/use-eve-agent.d.ts +1 -1
  339. package/dist/src/runtime/agent/resolve-model.js +1 -1
  340. package/dist/src/runtime/connections/openapi-client.d.ts +2 -0
  341. package/dist/src/runtime/connections/openapi-client.js +1 -1
  342. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  343. package/dist/src/runtime/resolve-agent.js +1 -1
  344. package/dist/src/runtime/resolve-channel.js +1 -1
  345. package/dist/src/runtime/resolve-sandbox.js +1 -1
  346. package/dist/src/runtime/sandbox/prepared-artifacts.js +1 -1
  347. package/dist/src/runtime/sandbox/registry.d.ts +2 -0
  348. package/dist/src/runtime/sandbox/registry.js +1 -1
  349. package/dist/src/runtime/subagents/workflow.d.ts +6 -0
  350. package/dist/src/runtime/subagents/workflow.js +1 -1
  351. package/dist/src/runtime/workspace/seed-files.d.ts +9 -12
  352. package/dist/src/runtime/workspace/seed-files.js +1 -1
  353. package/dist/src/runtime/workspace/spec.d.ts +1 -1
  354. package/dist/src/runtime/workspace/spec.js +1 -1
  355. package/dist/src/runtime/workspace/types.d.ts +2 -6
  356. package/dist/src/sandbox/provider.d.ts +185 -0
  357. package/dist/src/sandbox/provider.js +1 -0
  358. package/dist/src/sandbox/providers/default.d.ts +20 -19
  359. package/dist/src/sandbox/providers/default.js +1 -1
  360. package/dist/src/sandbox/providers/docker.d.ts +5 -2
  361. package/dist/src/sandbox/providers/docker.js +1 -1
  362. package/dist/src/sandbox/providers/just-bash.d.ts +4 -3
  363. package/dist/src/sandbox/providers/just-bash.js +1 -1
  364. package/dist/src/sandbox/providers/vercel.d.ts +4 -10
  365. package/dist/src/sandbox/providers/vercel.js +1 -1
  366. package/dist/src/sandbox/providers.d.ts +0 -1
  367. package/dist/src/sandbox/providers.js +1 -1
  368. package/dist/src/sandbox/state.d.ts +61 -0
  369. package/dist/src/sandbox/state.js +1 -1
  370. package/dist/src/self-modification/deployed-sandbox.d.ts +4 -9
  371. package/dist/src/self-modification/deployed-sandbox.js +1 -1
  372. package/dist/src/self-modification/filesystem.d.ts +3 -3
  373. package/dist/src/self-modification/remote/config.d.ts +2 -2
  374. package/dist/src/self-modification/remote/config.js +1 -1
  375. package/dist/src/self-modification/setup.d.ts +0 -1
  376. package/dist/src/self-modification/setup.js +8 -8
  377. package/dist/src/setup/integrations/discord/api.d.ts +7 -0
  378. package/dist/src/setup/integrations/discord/api.js +1 -1
  379. package/dist/src/setup/integrations/discord/daemon.d.ts +18 -0
  380. package/dist/src/setup/integrations/discord/daemon.js +21 -0
  381. package/dist/src/setup/integrations/discord/setup.d.ts +24 -4
  382. package/dist/src/setup/integrations/discord/setup.js +5 -4
  383. package/dist/src/setup/integrations/self-modification/setup.js +1 -1
  384. package/dist/src/setup/scaffold/create/project.js +1 -1
  385. package/dist/src/setup/scaffold/update/web-options.js +1 -1
  386. package/dist/src/setup/scaffold/version-tokens.d.ts +0 -1
  387. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  388. package/dist/src/shared/agent-definition.d.ts +2 -0
  389. package/dist/src/shared/built-server-start-failure.d.ts +12 -0
  390. package/dist/src/shared/built-server-start-failure.js +3 -0
  391. package/dist/src/shared/framework-eve-server.d.ts +2 -0
  392. package/dist/src/shared/framework-eve-server.js +2 -2
  393. package/dist/src/shared/sandbox-environment.d.ts +4 -10
  394. package/dist/src/shared/sandbox-environment.js +1 -1
  395. package/dist/src/shared/sandbox-network-policy.d.ts +45 -9
  396. package/dist/src/shared/sandbox-provider.d.ts +0 -103
  397. package/dist/src/shared/sandbox-provider.js +1 -1
  398. package/dist/src/shared/sandbox-recorded-data-error.d.ts +4 -0
  399. package/dist/src/shared/sandbox-recorded-data-error.js +1 -0
  400. package/dist/src/shared/sandbox-session-gone-error.d.ts +12 -0
  401. package/dist/src/shared/sandbox-session-gone-error.js +1 -0
  402. package/dist/src/shared/sandbox-session.d.ts +97 -83
  403. package/dist/src/shared/sandbox-template-error.d.ts +19 -4
  404. package/dist/src/shared/sandbox-template-error.js +1 -1
  405. package/dist/src/shared/sandbox-tool-session-error.d.ts +4 -0
  406. package/dist/src/shared/sandbox-tool-session-error.js +1 -0
  407. package/dist/src/shared/skill-package.js +1 -1
  408. package/dist/src/shared/skill-paths.d.ts +4 -5
  409. package/dist/src/shared/skill-paths.js +2 -2
  410. package/dist/src/shared/workflow-sandbox.d.ts +4 -41
  411. package/dist/src/shared/workflow-sandbox.js +1 -1
  412. package/dist/src/svelte/index.js +1 -1
  413. package/dist/src/svelte/use-eve-agent.d.ts +1 -1
  414. package/dist/src/svelte/use-eve-agent.js +1 -1
  415. package/dist/src/tools/definition.js +1 -1
  416. package/dist/src/tools/durable-callbacks.d.ts +5 -1
  417. package/dist/src/tools/durable-callbacks.js +1 -1
  418. package/dist/src/tools/dynamic.d.ts +3 -3
  419. package/dist/src/tools/model-output.d.ts +23 -5
  420. package/dist/src/tools/model-output.js +1 -1
  421. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  422. package/dist/src/tools/provided/glob.js +1 -1
  423. package/dist/src/tools/provided/grep.js +1 -1
  424. package/dist/src/tools/provided/read-file.js +1 -1
  425. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  426. package/dist/src/tools/provided/workflow.js +1 -1
  427. package/dist/src/tools/provided/write-file.js +1 -1
  428. package/dist/src/tools/workflow-definition.d.ts +19 -4
  429. package/dist/src/vue/index.js +1 -1
  430. package/dist/src/vue/use-eve-agent.d.ts +1 -1
  431. package/dist/src/vue/use-eve-agent.js +1 -1
  432. package/docs/channels/custom.mdx +3 -3
  433. package/docs/channels/discord.mdx +279 -7
  434. package/docs/channels/eve.mdx +13 -2
  435. package/docs/channels/linq.mdx +2 -2
  436. package/docs/channels/mcp.mdx +2 -2
  437. package/docs/channels/overview.mdx +1 -1
  438. package/docs/channels/photon.mdx +1 -1
  439. package/docs/concepts/built-in-tools.md +31 -8
  440. package/docs/concepts/execution-model-and-durability.mdx +6 -101
  441. package/docs/concepts/security-model.md +2 -0
  442. package/docs/concepts/sessions-runs-and-streaming.md +44 -36
  443. package/docs/connections/openapi.mdx +2 -0
  444. package/docs/evals/overview.mdx +1 -1
  445. package/docs/evals/reporters.mdx +5 -5
  446. package/docs/evals/running.mdx +19 -1
  447. package/docs/guides/client/messages.mdx +1 -1
  448. package/docs/guides/deployment/overview.md +4 -4
  449. package/docs/guides/deployment/self-hosting.md +50 -1
  450. package/docs/guides/dev-tui.md +1 -1
  451. package/docs/guides/dynamic-capabilities.md +2 -2
  452. package/docs/guides/frontend/overview.mdx +34 -10
  453. package/docs/guides/instrumentation/agent-runs.mdx +16 -0
  454. package/docs/guides/instrumentation/otel.mdx +23 -0
  455. package/docs/guides/self-modification.md +1 -1
  456. package/docs/guides/session-context.md +1 -1
  457. package/docs/instructions.mdx +1 -1
  458. package/docs/meta.json +1 -0
  459. package/docs/reference/agent-files.md +4 -4
  460. package/docs/reference/cli.md +24 -17
  461. package/docs/reference/typescript-api.md +9 -3
  462. package/docs/sandbox/custom-providers.mdx +254 -0
  463. package/docs/sandbox/default.mdx +71 -4
  464. package/docs/sandbox/docker.mdx +15 -3
  465. package/docs/sandbox/index.mdx +32 -106
  466. package/docs/sandbox/just-bash.mdx +54 -0
  467. package/docs/sandbox/meta.json +9 -1
  468. package/docs/sandbox/troubleshooting.mdx +215 -0
  469. package/docs/sandbox/vercel.mdx +48 -7
  470. package/docs/skills.mdx +1 -1
  471. package/docs/subagents/index.mdx +2 -2
  472. package/docs/tools/overview.mdx +20 -1
  473. package/docs/tools/workflows.mdx +73 -5
  474. package/docs/tutorial/run-analysis.mdx +2 -2
  475. package/docs/use-cases.mdx +250 -0
  476. package/package.json +14 -20
  477. package/dist/src/compiled/@ai-sdk/code-mode/_run.d.ts +0 -1
  478. package/dist/src/compiled/@ai-sdk/code-mode/index.d.ts +0 -325
  479. package/dist/src/compiled/@ai-sdk/code-mode/index.js +0 -660
  480. package/dist/src/compiled/_chunks/workflow/dist-CyBgVS7g.js +0 -1
  481. package/dist/src/compiled/_chunks/workflow/dist-T5NnW-0k.js +0 -3
  482. package/dist/src/compiled/_chunks/workflow/helpers-DlLD3ov_.js +0 -1
  483. package/dist/src/compiled/_chunks/workflow/private-tQUuwBoQ.js +0 -1
  484. package/dist/src/compiled/_chunks/workflow/resume-hook-DMsV_b4n.js +0 -1
  485. package/dist/src/compiled/_chunks/workflow/serialization-DPdYS_w2.js +0 -16
  486. package/dist/src/compiled/_chunks/workflow/sleep-BY6leHh8.js +0 -1
  487. package/dist/src/compiled/_chunks/workflow/workflow-routes-CwqB063q.js +0 -1
  488. package/dist/src/execution/sandbox/active-handles.d.ts +0 -32
  489. package/dist/src/execution/sandbox/active-handles.js +0 -1
  490. package/dist/src/execution/sandbox/bindings/docker-session.d.ts +0 -6
  491. package/dist/src/execution/sandbox/bindings/docker-session.js +0 -2
  492. package/dist/src/execution/sandbox/bindings/immutable-resources.d.ts +0 -15
  493. package/dist/src/execution/sandbox/bindings/immutable-resources.js +0 -2
  494. package/dist/src/execution/sandbox/bindings/microsandbox-create.d.ts +0 -12
  495. package/dist/src/execution/sandbox/bindings/microsandbox-create.js +0 -1
  496. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.d.ts +0 -42
  497. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +0 -1
  498. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.d.ts +0 -29
  499. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.js +0 -1
  500. package/dist/src/execution/sandbox/bindings/microsandbox-network.d.ts +0 -18
  501. package/dist/src/execution/sandbox/bindings/microsandbox-network.js +0 -1
  502. package/dist/src/execution/sandbox/bindings/microsandbox-options.d.ts +0 -37
  503. package/dist/src/execution/sandbox/bindings/microsandbox-options.js +0 -1
  504. package/dist/src/execution/sandbox/bindings/microsandbox-platform.d.ts +0 -21
  505. package/dist/src/execution/sandbox/bindings/microsandbox-platform.js +0 -21
  506. package/dist/src/execution/sandbox/bindings/microsandbox-process.d.ts +0 -3
  507. package/dist/src/execution/sandbox/bindings/microsandbox-process.js +0 -1
  508. package/dist/src/execution/sandbox/bindings/microsandbox-provider-state.d.ts +0 -11
  509. package/dist/src/execution/sandbox/bindings/microsandbox-provider-state.js +0 -1
  510. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +0 -82
  511. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +0 -1
  512. package/dist/src/execution/sandbox/bindings/microsandbox-templates.d.ts +0 -12
  513. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +0 -1
  514. package/dist/src/execution/sandbox/bindings/microsandbox.d.ts +0 -16
  515. package/dist/src/execution/sandbox/bindings/microsandbox.js +0 -1
  516. package/dist/src/execution/sandbox/provider-host-development.d.ts +0 -2
  517. package/dist/src/execution/sandbox/provider-host-development.js +0 -1
  518. package/dist/src/execution/sandbox/provider-host.d.ts +0 -2
  519. package/dist/src/execution/sandbox/provider-host.js +0 -1
  520. package/dist/src/execution/tool-session/sandbox.d.ts +0 -22
  521. package/dist/src/execution/tool-session/sandbox.js +0 -1
  522. package/dist/src/public/sandbox/microsandbox-sandbox.d.ts +0 -48
  523. package/dist/src/public/sandbox/microsandbox-sandbox.js +0 -1
  524. package/dist/src/public/sandbox/microsandbox.d.ts +0 -9
  525. package/dist/src/public/sandbox/microsandbox.js +0 -1
  526. package/dist/src/sandbox/providers/microsandbox.d.ts +0 -12
  527. package/dist/src/sandbox/providers/microsandbox.js +0 -1
  528. package/docs/sandbox/microsandbox.mdx +0 -31
@@ -23,6 +23,12 @@ replay unit.
23
23
 
24
24
  The Workflow SDK is not inherently tied to Vercel. In local development and in a self-deployed `eve start` process, eve uses the SDK's local world by default; that world persists workflow runs on disk under `.eve/.workflow-data` and dispatches through the same Nitro-hosted workflow routes. On Vercel, the same workflow code runs against Vercel Workflow instead, which adds deployment-aware routing and dashboard run metadata.
25
25
 
26
+ <span id="stranded-sessions" />
27
+ <span id="what-a-replacement-session-receives" />
28
+ <span id="how-a-stranded-session-ends" />
29
+
30
+ On Vercel, workflow runs continue on the deployment that started them, and idle sessions can move to a newer deployment on their next delivery. Self-hosted worlds without per-deployment routing can resume persisted sessions after a process restart with the same eve version, but cannot resume session runs built by another eve version. See [Recover a stranded session](../guides/deployment/self-hosting#recover-a-stranded-session) for recovery and optional conversation context in a replacement session.
31
+
26
32
  When a Vercel production deployment changes, a new delivery to an idle session hands the session's settled state to the exact deployment that accepted the request. This applies whether the delivery arrives through the session ID or through any channel continuation address the session has claimed. The session keeps its original ID and event stream, while the next model turn uses that deployment's current system-role instructions, model, and tools. Static user-role instructions stay pinned in the durable conversation history and are not seeded again. As with any turn, the triggering delivery restarts the session's [`sessionTimeoutMs`](../agent-config#runtime-limits) idle window, whether or not the handoff succeeds; disabled timeouts stay disabled.
27
33
 
28
34
  Before taking ownership, the target deployment upgrades the checkpoint when an older eve release wrote it, then checks that no pending work remains. A deployment accepts checkpoints from eve 0.66.0 and later, so upgrading eve does not leave long-lived sessions, such as a Slack thread, on their old deployment. An older release cannot read a newer checkpoint: after a rollback, a session that already moved to the newer deployment stays there. Extension state saved before eve 0.69 moves to its mount when exactly one mount of that extension package defines that state. State that the target deployment no longer defines, such as a removed `defineState` key, is dropped, and the target deployment's runtime logs show a `dropping unknown context key during deserialization` warning. When two or more mounts of one extension package define that state, eve cannot choose an owner, and the session stays on its current deployment. Idle subagent sessions that eve 0.66–0.68 kept for later reuse are stopped after the handoff. Authored session state remains opaque to this validation.
@@ -43,107 +49,6 @@ The move happens once the turn settles and nothing else is waiting: no queued me
43
49
 
44
50
  Both kinds of handoff need a Workflow world that can move a session's addresses from one run to another without releasing them, and can keep a released address reserved for a while (the `hookForceClaim` and `hookRetention` capabilities). Vercel Workflow, the local world, and `@workflow/world-postgres` 5.0.4 and later provide both. On a world without them, sessions never move between runs: deployment and compaction handoffs are skipped, and a session's run history grows for as long as the session lives. The first skipped attempt writes a `session handoff unavailable` warning to the runtime logs.
45
51
 
46
- ### Stranded sessions
47
-
48
- A session is stranded when another eve version built the workflow run that owns it. A run can only be replayed by the eve version that started it, so the conversation is still stored, but nothing on the current deployment can process a new message. On worlds without per-deployment routing, eve checks the owner before delivering channel messages and input responses, rather than committing them to a session that cannot answer.
49
-
50
- eve treats every world other than Vercel Workflow as running one eve version at a time, so a stranded session can never run again:
51
-
52
- | World | When a session is stranded |
53
- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
54
- | Vercel Workflow | eve does not check. Each run keeps executing on the deployment that started it, and handoff moves idle sessions to newer deployments. |
55
- | Local world with `eve start` | After any upgrade that changes the eve version. Sessions created before eve recorded its version on the run are treated the same way. |
56
- | Postgres and other worlds | Same as the local world. Serve one world from one eve version at a time: a deployment running another version cannot replay these sessions, and eve does not route runs between deployments. |
57
- | `eve dev` | After an eve version change. A session from a previous dev server invocation built by the same eve version is not stranded: it stays dormant until you restart `eve dev` with [`--resume`](../reference/cli#local-workflow-recovery). |
58
-
59
- eve ends a stranded session without running any of its code. When that happens depends on the kind of run:
60
-
61
- - **A root session**, one that a channel or client started, stays where it is. It keeps its address and executes nothing until a new channel message replaces it, a reset ends it, or its session timeout elapses, whichever comes first.
62
- - **A subagent session or workflow tool run**, including a task, is cancelled the next time the world delivers work to it, for example when the local world or Postgres recovers active runs at startup. No later message could resume its interrupted work, so eve does not wait.
63
-
64
- See [How a stranded session ends](#how-a-stranded-session-ends) for the details.
65
-
66
- For a root session, what happens next depends on how the message is addressed:
67
-
68
- - **A channel address**, such as a Slack thread or any `from(address).send(...)`, resets the stranded session and starts a fresh session at the same address. The message becomes the fresh session's first turn. Concurrent messages to the address produce one fresh session. The fresh session names the session it replaced, whose recorded conversation your instructions can read; see [What a replacement session receives](#what-a-replacement-session-receives). A delivery that carries input responses, with or without a message, throws `SessionStrandedError` and leaves the stranded session in place, because a fresh session has no request for them to answer. See [custom channels](../channels/custom#channel-operations-and-session-handles).
69
- - **`create()` on a channel address** throws `SessionStrandedError` and leaves the stranded session in place. Call `reset()` on the address, then `create()` again; see [Start from prior history](../channels/eve#start-from-prior-history).
70
- - **A session ID** is never reset implicitly. The eve HTTP channel returns `409` with `code: "session_stranded"` and the `eveVersion` that built the session when it recorded one. `Session.send()` and `Session.respond()` throw `SessionStrandedError` from `eve/channels`, and the TypeScript client's `ClientSession.send()` and `respond()` throw `ClientSessionStrandedError` from `eve/client`. Nothing is delivered, and the stranded run keeps its status and event log. See [Start and continue a session](../channels/eve#start-and-continue-a-session).
71
- - **Following a stream** of a stranded session returns the same `409 session_stranded`. The TypeScript client stops reconnecting and reports `ClientSessionStrandedError`; the TUI explains how to recover. An existing connection learns this when it reconnects. Messages accepted before the upgrade are not redelivered.
72
- - **Reading recorded history** still works. A bounded read (`stream({ follow: false })`, or `follow=false` on the stream route) returns the events recorded so far without inspecting or changing the session, so you can read a stranded conversation before deciding to reset it.
73
- - **Reset** works on a stranded session through a channel address or a session ID. **Clear** would keep a session that cannot run, so it is refused: `Session.clear()` throws `SessionStrandedError`, the eve HTTP channel returns `409 session_stranded`, and nothing changes. Reset the session instead.
74
- - **Session timeouts** end a stranded session the same way a reset does; see [How a stranded session ends](#how-a-stranded-session-ends).
75
-
76
- A reset ends the stranded session without running any of its code. eve cancels the session's owner run and, after a handoff, the original run that anchors its event stream, then waits until the world releases the session's addresses. If another run has taken over the session since eve inspected it, the reset ends nothing and fails so the request can be retried. The stranded session's `session.completed` and `session.failed` hooks do not run; the fresh session runs `session.started` as usual. Before cancelling, eve attempts to append a `session.failed` event with code `session_stranded` and close the old stream, without invoking authored hooks. Stream publication is best effort and waits at most 5 seconds: missing payload keys, unavailable storage, or a stalled write do not prevent reset. Each step tolerates an earlier attempt having completed it, so a reset that fails part way can be retried.
77
-
78
- Each reset logs a `warn` record, `Reset stranded session`, with the previous session ID, both eve versions, and the `trigger`: `message`, `reset`, or `timeout`.
79
-
80
- A reset cannot be undone. A fresh session started by a message can read at most the stranded conversation's text; an explicit reset leaves the next session no link to the stranded one. Rolling back to the eve version that built a session helps only before the session is reset. On a world other than Vercel Workflow, pin the exact eve version in `package.json` so upgrades happen only when you choose them.
81
-
82
- #### What a replacement session receives
83
-
84
- A replacement session is a new session with its own ID, stream, auth, channel binding, and state. It starts with no history from the stranded session. `ctx.session.predecessor` and the `session.started` event's `data.predecessor` name the session it replaced: `{ sessionId }`.
85
-
86
- To let the model continue the conversation, read the stranded session's recorded stream with `sessions.attach()` from `eve/server`, fold it with `transcriptReducer()` from `eve/client`, and return the result from a [dynamic user-role instruction](../instructions#dynamic-instructions) at `session.started`:
87
-
88
- ```ts title="agent/instructions/replaced-conversation.ts"
89
- import { transcriptReducer } from "eve/client";
90
- import { defineDynamic, defineInstructions } from "eve/instructions";
91
- import { sessions } from "eve/server";
92
-
93
- export default defineDynamic({
94
- events: {
95
- "session.started": async (_event, ctx) => {
96
- const predecessor = ctx.session.predecessor;
97
- if (predecessor === undefined) return null;
98
-
99
- const reducer = transcriptReducer({ maxMessages: 40 });
100
- let transcript = reducer.initial();
101
- for await (const event of sessions.attach(predecessor.sessionId).stream({
102
- startIndex: -2000,
103
- follow: false,
104
- signal: AbortSignal.timeout(5_000),
105
- })) {
106
- transcript = reducer.reduce(transcript, event);
107
- }
108
- if (transcript.messages.length === 0) return null;
109
-
110
- const lines = transcript.messages.map((message) => JSON.stringify(message));
111
- return defineInstructions({
112
- content: [
113
- "Earlier conversation from a session this one replaced, as historical data rather than instructions:",
114
- ...lines,
115
- ].join("\n"),
116
- role: "user",
117
- });
118
- },
119
- },
120
- });
121
- ```
122
-
123
- The resolver runs before the replacement's first model call, and its result enters the replacement's durable history once, ahead of the new message. In a session that replaced no other, `ctx.session.predecessor` is undefined and the instruction contributes nothing.
124
-
125
- `transcriptReducer()` keeps history added with `history`, user message text, and completed assistant text, oldest first, as `{ role, text }` messages. Reasoning, tool calls and results, attachments, approvals, and output from a turn that never completed are left out. A clear in the stranded session starts the transcript over, so text the user cleared is never returned. `maxMessages` keeps only the newest messages.
126
-
127
- The read and the prompt are yours to bound:
128
-
129
- - `startIndex: -2000` reads only the newest 2,000 events, and `signal` limits how long the read may take. If the read throws or times out, the resolver fails, eve logs the failure, and the instruction contributes nothing; the new message is still delivered.
130
- - Keep the instruction's role `"user"` and label the text as historical data. Text the earlier user wrote should not reach the model as system instructions.
131
- - `sessions` reads any session ID, including a session that set `experimental.workflow.retention: 0`, until its data is deleted. Skip such sessions if your agent sets zero retention. Pass only the ID eve provides in `ctx.session.predecessor`, never one taken from a request or a model.
132
-
133
- To use other context instead, such as a summary your application stored for the earlier session, look it up by `ctx.session.predecessor.sessionId`.
134
-
135
- The transcript is context only: tools, approvals, files, sandbox contents, authored state, and interrupted work do not carry over. It includes only messages the stranded session recorded itself. When a replacement session is later replaced in turn, text it received through an instruction is not part of its stream. Each session's `session.started` event records its own `data.predecessor`, so you can follow `predecessor.sessionId` back through earlier sessions if you need older text.
136
-
137
- #### How a stranded session ends
138
-
139
- A stranded root session ends on its next channel message, a reset, or its [session timeout](../agent-config#runtime-limits), whichever comes first. It executes nothing while it waits. When the local world or Postgres recovers active runs at startup, eve acknowledges the root session's delivery without replaying it and logs a warning naming the run and both eve versions. The run keeps its `pending` or `running` status and its addresses. A later restart skips it the same way.
140
-
141
- The timeout is the session's own durable timer, which its last owner armed for the end of an idle window (30 days by default). An owner re-arms the timer only when the timer fires before the window ends, so a stranded session ends at most `sessionTimeoutMs` after its last turn settled, and possibly sooner. The timer is a separate workflow run that keeps working after the upgrade, and when it fires on a stranded session it ends the session the same way a reset does, without starting a fresh one. The next message to the address then starts an ordinary session. A session with `sessionTimeoutMs: false` has no timer, so a stranded one stays until a message or a reset, just as a healthy one would stay open.
142
-
143
- Ending a root session does not find or cancel its subagent sessions and workflow tool runs. Each one is cancelled when a delivery for it reaches the current deployment, with the cancellation reason `Run retired: its eve deployment is no longer available`, and eve logs a `Retired stranded descendant run` warning. A run that never receives a delivery, such as one parked in a dormant `eve dev` generation, can stay active; cancel it in your Workflow world if you need to. Cancellation does not run authored cleanup or lifecycle hooks, undo side effects, or stop independent external jobs, and results and approvals do not carry over to a replacement session.
144
-
145
- Runs that recorded no eve version, including every run from a release before eve recorded versions, are treated as stranded.
146
-
147
52
  ### Upgrading sessions from the former execution model
148
53
 
149
54
  You can upgrade directly from a release that used a session driver and separate
@@ -18,6 +18,8 @@ The app runtime is the trusted side. Your tool implementations, model calls, con
18
18
 
19
19
  The sandbox is the isolated side. The model runs shell commands and accesses files there through the default `bash`, `read_file`, and `write_file` tools and any opt-in sandbox tools such as `glob` and `grep`. It gets its own `/workspace` filesystem, but no `process.env`, no secrets, and no path back into the app runtime. (On Vercel, each sandbox is a [Vercel Sandbox](https://vercel.com/docs/sandbox) microVM with hardware-level isolation.) Only shell commands execute in the sandbox. Even the built-in `bash`/`read_file`/`write_file` tools live in the app runtime and _proxy_ into the sandbox. The model sees tool definitions and results, never your secrets.
20
20
 
21
+ The [just-bash provider](../sandbox/just-bash) has a weaker boundary. Its shell is a JavaScript interpreter with a virtual filesystem that runs inside the app runtime process, not a separate container or VM. It provides no network isolation, and any `customCommands` you register run as host application code outside the virtual filesystem. Use a Vercel or Docker sandbox when the model runs commands you would not run in the app runtime.
22
+
21
23
  A concrete trace makes the boundary clear. When the model calls a custom `charge_card` tool, its `execute` runs in the app runtime, reads `process.env.STRIPE_KEY`, calls Stripe, and returns `{ ok: true }`. The model sees only `{ ok: true }`: the key never leaves the app runtime, and nothing about the call touches the sandbox. The built-in `write_file` is the mirror image, running in the app runtime and proxying the write into the sandbox `/workspace`. Either way the model drives the work through tool calls and their results, never by holding a credential or reaching the runtime directly.
22
24
 
23
25
  See [Agent loop and sandbox](./execution-model-and-durability#agent-loop-and-sandbox) for how eve connects these contexts while keeping their state and lifetimes separate.
@@ -16,6 +16,12 @@ event stream. A deployment or compaction handoff changes the executing run, not
16
16
  the session ID or stream. Stream namespaces belong to a run; eve does not support
17
17
  caller-assigned session IDs or globally addressed streams.
18
18
 
19
+ Before handoff, eve validates that the saved session state has no pending work
20
+ inside the workflow. The current owner keeps its inbox while the successor
21
+ starts and validates the checkpoint. Once the successor takes over the session
22
+ hooks, the original owner forwards messages it accepted during the move and
23
+ parks on the stream anchor until the final owner reports the session result.
24
+
19
25
  Authored channels also have channel-local continuation tokens. A token addresses
20
26
  whichever session currently owns a platform conversation, such as a Slack thread.
21
27
  That identity stays behind the channel boundary and is never accepted or returned
@@ -67,40 +73,40 @@ curl http://127.0.0.1:2000/eve/v1/session/<sessionId>/stream
67
73
 
68
74
  The stream is newline-delimited JSON (NDJSON), one event per line:
69
75
 
70
- | Event | Meaning |
71
- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
72
- | `session.started` | A durable session was created; carries `trace` when the runtime is traced, and `predecessor` when the session [replaced a stranded one](./execution-model-and-durability#what-a-replacement-session-receives). |
73
- | `history.imported` | A delivery added prior conversation with `history`; carries each message's `role`, `content`, and optional `id`. Precedes that delivery's `message.received` in the same turn. |
74
- | `turn.started` | A new turn began; carries the active `trace` when the runtime is traced. |
75
- | `message.received` | Input reached a turn; carries flattened text plus structured text/file parts. |
76
- | `step.started` | A model step began. |
77
- | `action.input.appended` | A raw tool-input text delta and its tool-call identity. |
78
- | `actions.requested` | The model requested one or more actions, including tool calls; calls stream before execution. |
79
- | `action.partial` | A locally executed tool generator yielded a preliminary output snapshot. |
80
- | `action.result` | A tool call returned. |
81
- | `input.requested` | The run paused for human input ([HITL](/docs/human-in-the-loop) approval or a `ctx.ask()` question); carries `requests`. |
82
- | `input.resolved` | The server accepted terminal human-input outcomes; carries `resolutions` with responses when provided. |
83
- | `agent.started` | A workflow run opened a session with `ctx.agent`, such as an agent tool's; carries `taskId` when the run is a task, `sessionId`, and the `streamPath` that `session.agent(started).stream()` follows. |
84
- | `task.started` | A tool call started a [task](#task-events); carries `taskId`, `callId`, `turnId`, the tool `name`, and `kind`: `"agent"` for an agent tool, `"tool"` otherwise. |
85
- | `task.settled` | A task's call settled; carries `taskId`, `callId`, `turnId`, the tool `name`, `kind`, `status`, and `output` or `error.message`; a cancelled call carries `cancel.reason` instead. |
86
- | `reasoning.appended` | A reasoning text delta. |
87
- | `reasoning.completed` | The finalized reasoning block. |
88
- | `message.appended` | An assistant text delta. |
89
- | `message.completed` | A finalized assistant text block. |
90
- | `result.completed` | The finalized structured result for a turn that requested an output schema; carries `result`. |
91
- | `compaction.requested` | Context-window compaction began; carries `modelId`, `sessionId`, `turnId`, `stepIndex`, and `usageInputTokens`. |
92
- | `compaction.completed` | A compaction checkpoint was written to durable history; carries the same model, session, turn, and step identity. |
93
- | `authorization.required` | A connection needs OAuth; carries `name`, `description`, and an `authorization` challenge. |
94
- | `authorization.completed` | A connection's authorization resolved; carries `outcome`. |
95
- | `step.completed` | A model step finished; carries `finishReason` and usage. |
96
- | `step.failed` | A model step failed; carries `{ code, message, details? }`. |
97
- | `turn.waiting` | The open turn parked; carries `turnId` and `on`: `"input"` while a person must act on a sign-in, approval, or question, `"tasks"` while work it started runs. The turn has not ended. |
98
- | `turn.completed` | The turn finished. |
99
- | `turn.failed` | The turn failed; carries `{ code, message, details?, terminal? }`. `terminal` is `true` when `session.failed` follows instead of `session.waiting`. |
100
- | `turn.cancelled` | The turn was cancelled before finishing; always followed by `session.waiting`. |
101
- | `session.waiting` | The session parked and is ready for the next message. |
102
- | `session.failed` | The session failed. |
103
- | `session.completed` | The session reached a terminal end. |
76
+ | Event | Meaning |
77
+ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
78
+ | `session.started` | A durable session was created; carries `trace` when the runtime is traced, and `predecessor` when the session [replaced a stranded one](../guides/deployment/self-hosting#recover-a-stranded-session). |
79
+ | `history.imported` | A delivery added prior conversation with `history`; carries each message's `role`, `content`, and optional `id`. Precedes that delivery's `message.received` in the same turn. |
80
+ | `turn.started` | A new turn began; carries the active `trace` when the runtime is traced. |
81
+ | `message.received` | Input reached a turn; carries flattened text plus structured text/file parts. |
82
+ | `step.started` | A model step began. |
83
+ | `action.input.appended` | A raw tool-input text delta and its tool-call identity. |
84
+ | `actions.requested` | The model requested one or more actions, including tool calls; calls stream before execution. |
85
+ | `action.partial` | A locally executed tool generator yielded a preliminary output snapshot. |
86
+ | `action.result` | A tool call returned. |
87
+ | `input.requested` | The run paused for human input ([HITL](/docs/human-in-the-loop) approval or a `ctx.ask()` question); carries `requests`. |
88
+ | `input.resolved` | The server accepted terminal human-input outcomes; carries `resolutions` with responses when provided. |
89
+ | `agent.started` | A workflow run opened a session with `ctx.agent`, such as an agent tool's; carries `taskId` when the run is a task, `sessionId`, and the `streamPath` that `session.agent(started).stream()` follows. |
90
+ | `task.started` | A tool call started a [task](#task-events); carries `taskId`, `callId`, `turnId`, the tool `name`, and `kind`: `"agent"` for an agent tool, `"tool"` otherwise. |
91
+ | `task.settled` | A task's call settled; carries `taskId`, `callId`, `turnId`, the tool `name`, `kind`, `status`, and `output` or `error.message`; a cancelled call carries `cancel.reason` instead. |
92
+ | `reasoning.appended` | A reasoning text delta. |
93
+ | `reasoning.completed` | The finalized reasoning block. |
94
+ | `message.appended` | An assistant text delta. |
95
+ | `message.completed` | A finalized assistant text block. |
96
+ | `result.completed` | The finalized structured result for a turn that requested an output schema; carries `result`. |
97
+ | `compaction.requested` | Context-window compaction began; carries `modelId`, `sessionId`, `turnId`, `stepIndex`, and `usageInputTokens`. |
98
+ | `compaction.completed` | A compaction checkpoint was written to durable history; carries the same model, session, turn, and step identity. |
99
+ | `authorization.required` | A connection needs OAuth; carries `name`, `description`, and an `authorization` challenge. |
100
+ | `authorization.completed` | A connection's authorization resolved; carries `outcome`. |
101
+ | `step.completed` | A model step finished; carries `finishReason` and usage. |
102
+ | `step.failed` | A model step failed; carries `{ code, message, details? }`. |
103
+ | `turn.waiting` | The open turn parked; carries `turnId` and `on`: `"input"` while a person must act on a sign-in, approval, or question, `"tasks"` while work it started runs. The turn has not ended. |
104
+ | `turn.completed` | The turn finished. |
105
+ | `turn.failed` | The turn failed; carries `{ code, message, details?, terminal? }`. `terminal` is `true` when `session.failed` follows instead of `session.waiting`. |
106
+ | `turn.cancelled` | The turn was cancelled before finishing; always followed by `session.waiting`. |
107
+ | `session.waiting` | The session parked and is ready for the next message. |
108
+ | `session.failed` | The session failed. |
109
+ | `session.completed` | The session reached a terminal end. |
104
110
 
105
111
  The optional `data.trace` on session and turn starts contains eve-owned W3C trace coordinates: `traceId`, `spanId`, and `traceFlags`. Use it to correlate stream consumers such as eval reporters with an observability backend. An uninstrumented target omits it.
106
112
 
@@ -134,6 +140,8 @@ A turn doesn't end while tasks are working. When the model ends its text early,
134
140
 
135
141
  `step.failed` and `turn.failed` carry `{ code, message, details? }` for the failed fragment or turn, and `session.failed` is the terminal session-level variant. `turn.failed` also carries `terminal`: `true` when the failure ends the session and `session.failed` follows, `false` when `session.waiting` follows and the next message can retry. Events from eve versions before `terminal` was added omit it. `turn.cancelled` is not a failure: the cancelled turn ends without any failure event, `session.waiting` follows, and the session accepts the next message normally. Whatever the turn streamed before cancellation stays on the stream. Durable history keeps the accepted user input and previously settled work, and discards incomplete assistant output. Tool calls the cancellation stopped stay in history, each answered as cancelled, so the model sees that the work started and stopped instead of a request left unanswered. Before `turn.cancelled`, the stream reports requests the cancel strands as `cancelled` in `input.resolved`. These include the turn's own questions, the session-limit prompt, and requests relayed from the work it stops. When a turn requested an output schema, the finalized payload lands on `result.completed` as `data.result` before the turn boundary. `authorization.required` carries the sign-in challenge (`data.authorization` may include `url`, `userCode`, `expiresAt`, `instructions`), and `authorization.completed` carries `data.outcome` (`"authorized" | "declined" | "failed" | "timed-out"`). Both carry `data.principalId` when a session principal started the sign-in. It holds the same value as `responderPrincipalId` on approval events, so a channel can deliver the challenge privately to that person even after someone else starts a later turn.
136
142
 
143
+ Before the next model request, eve repairs unambiguous orphaned local tool calls in saved history only when no result was recorded anywhere. An error result states that the execution outcome is unknown and external state must be checked before repeating side effects. This repair never executes the old call, moves recorded results, or settles work still owned by approvals, sign-in, workflows, or tasks. Provider-executed calls, SDK approvals, and duplicate call IDs are left unchanged.
144
+
137
145
  A provider response ending with `content-filter` fails with `MODEL_CALL_FAILED`,
138
146
  `details.semanticErrorId: "model-response-content-filtered"`, and
139
147
  `details.finishReason: "content-filter"`. Details also include the Gateway
@@ -266,7 +274,7 @@ Clear removes model-message history in place, including static and dynamic user-
266
274
 
267
275
  Reset terminally retires the exact session ID. A reset ID never becomes a new session; create another session explicitly for a fresh conversation. Compact, clear, and reset return `"no_active_session"` when the target is already inactive.
268
276
 
269
- A [stranded session](./execution-model-and-durability#stranded-sessions) cannot run commands. Reset still works: eve cancels the stranded workflow run and returns `"reset"`. Clear is refused with `409 session_stranded` (`SessionStrandedError` from a `Session` handle), because it would keep a session that cannot run. Compact returns `"no_active_session"` and cancel returns `"no_active_turn"`.
277
+ A [stranded session](../guides/deployment/self-hosting#recover-a-stranded-session) cannot run commands. Reset still works: eve cancels the stranded workflow run and returns `"reset"`. Clear is refused with `409 session_stranded` (`SessionStrandedError` from a `Session` handle), because it would keep a session that cannot run. Compact returns `"no_active_session"` and cancel returns `"no_active_turn"`.
270
278
 
271
279
  ## Reconnect and rewind
272
280
 
@@ -297,7 +305,7 @@ curl -i "http://127.0.0.1:2000/eve/v1/session/<sessionId>/stream?startIndex=<cou
297
305
  # x-eve-stream-tail-index: <tail>
298
306
  ```
299
307
 
300
- The lookup is opt-in; requests without the parameter get no header. Passing `follow=false` instead bounds the response at the durable tail on the server and implies the header. A bounded read only reads recorded history, so it also works for a [stranded session](./execution-model-and-durability#stranded-sessions), whose live stream returns `409 session_stranded`. The TypeScript client wraps this into `stream({ follow: false })`.
308
+ The lookup is opt-in; requests without the parameter get no header. Passing `follow=false` instead bounds the response at the durable tail on the server and implies the header. A bounded read only reads recorded history, so it also works for a [stranded session](../guides/deployment/self-hosting#recover-a-stranded-session), whose live stream returns `409 session_stranded`. The TypeScript client wraps this into `stream({ follow: false })`.
301
309
 
302
310
  ## Use the client from TypeScript
303
311
 
@@ -39,6 +39,8 @@ Use `baseUrl` when the spec is missing server data, points at the wrong environm
39
39
 
40
40
  The resolved base URL must use `https` too (loopback hosts may use `http` for local development), since operation calls carry the connection's credentials.
41
41
 
42
+ For the same reason, operation calls follow redirects only within the base URL's origin, up to 10 hops; a longer chain fails the call as a redirect loop. A redirect to another origin is not followed. The tool returns the redirect response with its absolute target in `location`, such as `{ status: 302, statusText, body, location: "https://storage.example.com/..." }`, and the connection's credentials never reach the other host. Endpoints that hand downloads off to a storage host return that `location`, which the agent can fetch without the connection's credentials. If an API has moved to a new domain, point `baseUrl` at the new domain.
43
+
42
44
  ```ts title="agent/connections/crm.ts"
43
45
  import { defineOpenAPIConnection } from "eve/connections";
44
46
 
@@ -58,7 +58,7 @@ export default defineEvalConfig({
58
58
  });
59
59
  ```
60
60
 
61
- Everything is optional. `judge` sets the default model for [LLM-as-judge](./judge) assertions (`t.judge(...)`); omit it to use the default decider, `typesafe-ai/jev`. Deterministic evals make no judge requests. `reporters`, `maxConcurrency`, and `timeoutMs` round out the defaults. Config `reporters` observe every eval in the run, so set one `Braintrust()` here instead of adding it to each eval. CLI flags (`--max-concurrency`, `--timeout`) and per-eval values take precedence over the config defaults.
61
+ Everything is optional. `judge` sets the default model for [LLM-as-judge](./judge) assertions (`t.judge(...)`); omit it to use the default decider, `typesafe-ai/jev`. Deterministic evals make no judge requests. `reporters`, `maxConcurrency`, `timeoutMs`, and `repeat` round out the defaults. Config `reporters` observe every eval in the run, so set one `Braintrust()` here instead of adding it to each eval. `repeat` runs every eval several times to measure repeatability; see [Repeat evals](./running#repeat-evals). CLI flags (`--max-concurrency`, `--timeout`, `--repeat`) and per-eval values take precedence over the config defaults.
62
62
 
63
63
  ### Run setup and teardown
64
64
 
@@ -38,7 +38,7 @@ export default defineEval({
38
38
  });
39
39
  ```
40
40
 
41
- The reporter config takes an optional `projectName` and `experimentName`, plus a base experiment (by name or id) to diff against. Gate assertions log as binary scores under a `gate:` prefix so experiments diff gate regressions the same way they diff soft-score regressions. Assertions that share a name, such as several unlabeled judges, log one score: the lowest. The console warns under the eval when merged soft scores differ; use `.label(name)` to group or separate them. Errored assertions log no score. Each assertion's score is stored in the Braintrust metadata under `eveAssertionScores` and failed assertion details under `eveFailedAssertions`; observed traces are stored under `eveTraceIds` and `eveTraceContexts`.
41
+ The reporter config takes an optional `projectName` and `experimentName`, plus a base experiment (by name or id) to diff against. Gate assertions log as binary scores under a `gate:` prefix so experiments diff gate regressions the same way they diff soft-score regressions. Assertions that share a name, such as several unlabeled judges, log one score: the lowest. The console warns under the eval when merged soft scores differ; use `.label(name)` to group or separate them. Errored assertions log no score. Each assertion's score is stored in the Braintrust metadata under `eveAssertionScores` and failed assertion details under `eveFailedAssertions`; observed traces are stored under `eveTraceIds` and `eveTraceContexts`. In a [repeated run](./running#repeat-evals), each attempt logs its own row with the id `<id>#<attempt>` and the attempt number under `eveAttempt`.
42
42
 
43
43
  A reporter instance observes the evals that reference it. Share one instance across several evals (the config, a `shared.ts` export, or every entry of a dataset array) and their results land in a single experiment. Listing the same config reporter on an eval too does not double-report it.
44
44
 
@@ -61,7 +61,7 @@ The reporter creates one Datadog Experiment, submits one synthetic experiment sp
61
61
 
62
62
  `dd-trace` generates dataset record, experiment trace, and experiment span identifiers. For sampled eve sessions, the reporter also adds identifier-only `experimentRuntimeTraceLinks` metadata, holding the IDs Datadog assigns when it indexes the runtime traces, so an Experiment row can link to the agent trace that produced it. Runtime spans keep their stored IDs and parentage.
63
63
 
64
- Every run reuses the dataset named by `datasetName` (default `<projectName> evals`), so Datadog can compare experiments across runs. Records are matched by eval description, with `#2`, `#3` suffixes for duplicates, so give each case a unique description.
64
+ Every run reuses the dataset named by `datasetName` (default `<projectName> evals`), so Datadog can compare experiments across runs. Records are matched by eval description, with `#2`, `#3` suffixes for duplicates, so give each case a unique description. In a [repeated run](./running#repeat-evals), every attempt of an eval links to that eval's single dataset record, and each experiment span's `runIteration` is the attempt number.
65
65
 
66
66
  Assertion metrics use descriptive assertion names by default: characters outside letters, numbers, underscores, and hyphens are normalized to underscores, gate labels receive a `gate_` prefix, assertions that share a label report one metric with the lowest score, and labels that collide with built-in metrics receive a numeric suffix. For example, `succeeded` becomes `gate_succeeded` and `calledTool(get_stock_quote)` becomes `gate_calledTool_get_stock_quote`. Authors can use `.label("stable name")` on an assertion handle to choose a stable metric name. Because assertion names can contain authored expectations, review them before exporting sensitive evals. Each assertion's name and score are kept in row metadata under `eveAssertionScores`; pass `recordAssertionDetails: false` to omit them and failed assertion messages.
67
67
 
@@ -75,7 +75,7 @@ Datadog needs `dd-trace` installed in the app and Datadog credentials in the env
75
75
  eve eval --strict --junit .eve/junit.xml
76
76
  ```
77
77
 
78
- Each eval becomes one `<testcase>` named by its path-derived id; failed gates and execution errors become failures, while `t.skip(reason)` produces a JUnit `<skipped>` result.
78
+ Each eval becomes one `<testcase>` named by its path-derived id (one per attempt, named `<id>#<attempt>`, in a repeated run); failed gates and execution errors become failures, while `t.skip(reason)` produces a JUnit `<skipped>` result.
79
79
 
80
80
  ## Custom reporters
81
81
 
@@ -93,7 +93,7 @@ interface EvalReporter {
93
93
 
94
94
  `onRunStart` fires once before any eval runs, and `onRunComplete` fires once with the aggregated summary. Within that run:
95
95
 
96
- - `onEvalStart` fires when an eval is scheduled. It includes the eval definition, target, and start time.
96
+ - `onEvalStart` fires when an eval is scheduled. It includes the eval definition, target, and start time. In a [repeated run](./running#repeat-evals), it fires once per attempt, and the event and each `onSessionStart` event carry the 1-based `attempt`, which matches `result.attempt` on completion.
97
97
  - `onSessionStart` fires once for each session after eve receives its first trace context. It includes `sessionId`, `primary`, and `traceContext` with `traceId`, `spanId`, and `traceFlags`.
98
98
  - `onEvalComplete` fires with the checks, scores, and verdict. The runner also supplies `context`, including every distinct trace context collected across the eval's sessions. The same list is available as `result.result.traceContexts`.
99
99
 
@@ -103,7 +103,7 @@ An eval can create several sessions, and a long session can produce several trac
103
103
 
104
104
  `result.result.derived` holds the facts the runner derived from the eval's sessions, such as tool calls and `models`: the distinct ids of the models the steps started with, in session order. Each entry in `result.result.sessions` holds the same facts for one session, in first-use order, so a reporter can tell the primary session's models from those of the other sessions the eval created or attached. A delegated subagent runs in its own session, so its models appear only when the eval attaches that session with `t.target.attachSession`. Compaction and `auto` routing calls are not included.
105
105
 
106
- `derived.usage` is the token usage and cost from each session's latest `session.waiting`, `turn.waiting`, `session.failed`, or `session.completed`, including what its delegated agents spent; on a turn, it is the session's total so far. The eval's `usage` counts each captured session once, by its latest usage, and leaves out sessions another captured session opened, because that session already counts their spend. It is absent when a counted session reported no usage. It leaves out compaction calls, the turns an eval sends directly to a child session it attached, and delegated spend counted after a session's last such event.
106
+ `derived.usage` is the token usage and cost from each session's latest `session.waiting`, `turn.waiting`, `session.failed`, or `session.completed`, including what its delegated agents spent; on a turn, it is the session's total so far. The eval's `usage` counts each captured session once, by its latest usage in time (an eval can capture a session again with an earlier snapshot), and leaves out sessions another captured session opened, because that session already counts their spend. It is absent when a counted session reported no usage, and its `costUsd` is absent when a counted session reported no cost, so a partial sum never reads as the eval's cost. Compaction summary calls are included. It leaves out the turns an eval sends directly to a child session it attached, and delegated spend counted after a session's last such event.
107
107
 
108
108
  Reporter callbacks for an eval stay ordered—eval start, traced session starts, then completion—even when several evals run concurrently. Reach for a custom reporter only when a destination isn't covered. The per-run artifacts under `.eve/evals/` retain the trace contexts alongside the result for ad-hoc inspection.
109
109
 
@@ -14,11 +14,13 @@ eve eval --exclude-tag slow # skip evals carrying a tag
14
14
  eve eval --strict # soft below-threshold assertions also fail the exit code
15
15
  eve eval --timeout 60000 # per-eval timeout in milliseconds
16
16
  eve eval --max-concurrency 4 # cap concurrent eval executions (default 8)
17
+ eve eval --repeat 5 # run every eval 5 times to measure repeatability
17
18
  eve eval --junit .eve/junit.xml # write JUnit XML
18
19
  eve eval --list # print discovered evals without running
19
20
  eve eval --verbose # stream per-eval logs and workflow run IDs
20
21
  eve eval --json # machine-readable output
21
22
  eve eval --skip-report # skip config and eval-defined reporters (e.g. Braintrust)
23
+ eve eval --keep-state # keep the local server's state and Workflow data after the run
22
24
  ```
23
25
 
24
26
  Positional ids match exactly or by directory prefix: `eve eval weather` runs `evals/weather.eval.ts`, every eval under `evals/weather/`, and every entry of an array-exported `weather.eval.ts`.
@@ -39,9 +41,25 @@ An eval that calls `t.skip(reason)` is reported as skipped, does not count as pa
39
41
 
40
42
  With `--verbose`, eve prefixes each line with its eval ID. It streams authored `t.log()` lines as they occur, then prints the workflow run ID for every captured primary and secondary session. Use those `wrun_...` IDs to find the corresponding runs in your workflow provider.
41
43
 
44
+ ## Repeat evals
45
+
46
+ Model-backed evals can pass on one run and fail on the next. To measure how often an eval passes, pass `--repeat <n>` or set `repeat` in `evals.config.ts`, and eve runs every selected eval `n` times in one run. The CLI flag overrides the config value. The default is `1`, and output does not change at that value.
47
+
48
+ ```bash
49
+ eve eval weather --repeat 5
50
+ ```
51
+
52
+ With `n` greater than `1`, each attempt is a separate result with a 1-based `attempt` field:
53
+
54
+ - The console and `--verbose` lines label each attempt `<id>#<attempt>`, and the summary adds a per-eval pass rate such as `3/5 passed`. The pass rate counts attempts that passed or failed their gates; scored and skipped attempts are left out.
55
+ - `--json` results, JUnit test cases (named `<id>#<attempt>`), and [reporters](./reporters) receive one result per attempt.
56
+ - Every attempt counts toward the run totals and the exit code, so one failed attempt fails the run.
57
+
58
+ Attempts share the `--max-concurrency` pool with every other eval, so attempts of the same eval can run at the same time. If an eval depends on shared state or a rate-limited provider, lower `--max-concurrency` so contention does not show up as flakiness.
59
+
42
60
  ## Artifacts
43
61
 
44
- Each run drops artifacts under `.eve/evals/<timestamp>/`: a run `summary.json`, a `results.jsonl` index, and per-eval assertion results, verdicts, captured event streams, and `t.log` lines under `evals/`. The console output stays tight on purpose; when an eval fails, the artifact has the full story.
62
+ Each run drops artifacts under `.eve/evals/<timestamp>/`: a run `summary.json`, a `results.jsonl` index, and per-eval assertion results, verdicts, start and completion times, captured event streams with the client's send and arrival times for each session, and `t.log` lines under `evals/`. In a repeated run, each attempt's detail and event files get an `.attempt-<n>` suffix, such as `evals/weather.attempt-2.json`. The console output stays tight on purpose; when an eval fails, the artifact has the full story.
45
63
 
46
64
  ## CI
47
65
 
@@ -41,7 +41,7 @@ seconds when a durable run has been accepted but its command inbox is still star
41
41
  abort signal cancels the wait. Other errors, `session.respond()`, control methods, and raw HTTP
42
42
  requests do not use this retry. An unknown
43
43
  or terminal session throws `ClientError` immediately with `session_not_active`. A
44
- [stranded](../../concepts/execution-model-and-durability#stranded-sessions) session throws
44
+ [stranded](../deployment/self-hosting#recover-a-stranded-session) session throws
45
45
  `ClientSessionStrandedError`, a `ClientError` with `code: "session_stranded"` and the
46
46
  `eveVersion` that built the session when it recorded one. It is never retried automatically. Call
47
47
  `session.reset()` and create a new session.
@@ -9,10 +9,10 @@ Deploy eve to Vercel or run it as a Node service on your own infrastructure. You
9
9
 
10
10
  Choose where the eve runtime will run:
11
11
 
12
- | Strategy | Build output | Workflows | Sandbox | Choose it when |
13
- | ------------------------------ | ---------------------- | ------------------------------ | ------------------------------- | ----------------------------------------------------- |
14
- | [Vercel](./vercel) | `.vercel/output` | Vercel Workflow | Vercel Sandbox | You want Vercel to operate the runtime services |
15
- | [Self-hosting](./self-hosting) | `.output/` Node server | Local or custom Workflow world | Docker, microsandbox, or custom | You operate your own Node or container infrastructure |
12
+ | Strategy | Build output | Workflows | Sandbox | Choose it when |
13
+ | ------------------------------ | ---------------------- | ------------------------------ | ---------------- | ----------------------------------------------------- |
14
+ | [Vercel](./vercel) | `.vercel/output` | Vercel Workflow | Vercel Sandbox | You want Vercel to operate the runtime services |
15
+ | [Self-hosting](./self-hosting) | `.output/` Node server | Local or custom Workflow world | Docker or custom | You operate your own Node or container infrastructure |
16
16
 
17
17
  eve is frontend agnostic and can be deployed within Next.js, Nuxt, SvelteKit, or TanStack Start applications. See [Frontend integrations](../frontend/overview) for more details.
18
18
 
@@ -28,6 +28,10 @@ Don’t rely on `vercelOidc()` as the only production authenticator outside Verc
28
28
 
29
29
  The default local Workflow world stores run state under `.eve/.workflow-data`. Mount that directory on persistent storage so runs survive process and container replacement.
30
30
 
31
+ With the default local world, each `eve start` process accepts workflow queue deliveries only from its own queue. Keep deliveries on the process that enqueued them. Do not point `WORKFLOW_LOCAL_BASE_URL` at a load balancer that can forward deliveries to another replica; that replica rejects them with HTTP 401. Use a custom world designed for shared queue delivery when scaling across replicas.
32
+
33
+ On startup, eve re-enqueues pending and running local workflow runs with a new per-process delivery proof. Local recovery always runs; `WORKFLOW_LOCAL_RECOVER_ACTIVE_RUNS=0` or `false` does not disable it in `eve start`.
34
+
31
35
  You can instead select an installed Workflow world package in the root `agent.ts`:
32
36
 
33
37
  ```typescript
@@ -47,12 +51,57 @@ The package must export a default factory or `createWorld()` function. Read cred
47
51
 
48
52
  See [Workflow Worlds](https://workflow-sdk.dev/worlds) for the underlying Workflow software development kit (SDK) abstraction.
49
53
 
54
+ ## Recover a stranded session
55
+
56
+ A session is **stranded** when its owner run was built by another eve version and the current deployment cannot replay it. Its recorded history remains readable, but it cannot process new work. Sessions whose runs recorded no eve version are treated the same way.
57
+
58
+ When a stranded session receives a new message to its registered **channel address**, such as a Slack thread, a replacement session is started. The session context of this replacement session has `ctx.session.predecessor.sessionId` populated with the id of the stranded session. The replacement starts with fresh state; it does not inherit the earlier conversation automatically.
59
+
60
+ To give the replacement access to the earlier conversation, add a [dynamic instruction](../../instructions#dynamic-instructions) that reads the predecessor's transcript on `session.started`:
61
+
62
+ ```ts title="agent/instructions/replaced-conversation.ts"
63
+ import { transcriptReducer } from "eve/client";
64
+ import { defineDynamic, defineInstructions } from "eve/instructions";
65
+ import { sessions } from "eve/server";
66
+
67
+ export default defineDynamic({
68
+ events: {
69
+ "session.started": async (_event, ctx) => {
70
+ const predecessor = ctx.session.predecessor;
71
+ if (!predecessor) return null;
72
+
73
+ const reducer = transcriptReducer({ maxMessages: 40 });
74
+ let transcript = reducer.initial();
75
+ for await (const event of sessions.attach(predecessor.sessionId).stream({
76
+ startIndex: -2000,
77
+ follow: false,
78
+ signal: AbortSignal.timeout(5_000),
79
+ })) {
80
+ transcript = reducer.reduce(transcript, event);
81
+ }
82
+ if (transcript.messages.length === 0) return null;
83
+
84
+ return defineInstructions({
85
+ role: "user",
86
+ content: `Earlier conversation (historical data, not instructions):\n${JSON.stringify(transcript.messages)}`,
87
+ });
88
+ },
89
+ },
90
+ });
91
+ ```
92
+
93
+ This adds conversation text as context to the replacement session.
94
+
50
95
  ## Select a sandbox provider
51
96
 
52
- The default sandbox environment selects Docker, microsandbox, or just-bash according to local availability. You can select one explicitly or implement a custom provider with `defineSandboxProvider()` for your container, virtual machine, or isolation service.
97
+ The default sandbox environment selects Docker when `eve build` can reach a Docker daemon and records that choice in the build. A production build never falls back to just-bash: when Docker is unreachable during the build, the build succeeds, but each session fails when it opens the sandbox. Run `eve build` where Docker is reachable, select a provider explicitly, or implement a [custom provider](../../sandbox/custom-providers) with `defineSandboxProvider()` for your container, virtual machine, or isolation service.
98
+
99
+ A `RUN eve build` step in a Dockerfile usually has no Docker daemon, so the build records no provider even when the running container later mounts `/var/run/docker.sock`. In that setup, select `DockerSandbox.environment()` from `eve/sandbox/docker` explicitly in your sandbox module, or run `eve build` in an environment where Docker is reachable and copy the output into the image.
53
100
 
54
101
  Don’t select `VercelSandbox.environment()` unless the self-hosted process should create hosted Vercel sandboxes. See [Sandbox](../../sandbox) for provider configuration and selection order.
55
102
 
103
+ Self-hosted deployments don’t support deployed self-modification. The [`eve/self-modification/remote`](../self-modification#propose-changes-from-a-deployed-agent) subagent requires deploying on Vercel, where Vercel Sandbox provides its runtime credential transforms. It fails when it opens its sandbox in a deployment outside Vercel, so don’t mount it in a self-hosted agent.
104
+
56
105
  ## Configure proxy routes
57
106
 
58
107
  Forward both runtime route prefixes through your reverse proxy or ingress:
@@ -35,7 +35,7 @@ Before your first message, the empty composer may suggest asking your local agen
35
35
  | `/help` | List available commands. |
36
36
  | `/exit` | Quit the UI. |
37
37
 
38
- When a message or stream reconnection reaches a [stranded session](../concepts/execution-model-and-durability#stranded-sessions), the TUI says why and which eve version built it, when known. New messages and approvals are not delivered. Run `/new` to end the stranded session; your next message starts a fresh one. `/clear` is refused, because it would keep the stranded session. A session from a previous `eve dev` invocation that the same eve version built is not stranded; see [local workflow recovery](../reference/cli#local-workflow-recovery). A message accepted before the upgrade is not redelivered.
38
+ When a message or stream reconnection reaches a [stranded session](./deployment/self-hosting#recover-a-stranded-session), the TUI says why and which eve version built it, when known. New messages and approvals are not delivered. Run `/new` to end the stranded session; your next message starts a fresh one. `/clear` is refused, because it would keep the stranded session. A session from a previous `eve dev` invocation that the same eve version built is not stranded; see [local workflow recovery](../reference/cli#local-workflow-recovery). A message accepted before the upgrade is not redelivered.
39
39
 
40
40
  `/login`, `/model`, `/add`, `/deploy`, `/info`, and `/traces` are available when `eve dev` runs locally. They are unavailable when the UI connects through `eve remote connect`.
41
41
 
@@ -248,7 +248,7 @@ the handler.
248
248
 
249
249
  ## Dynamic tools
250
250
 
251
- Pass `defineDynamic` an `events` object whose handlers return either a single `defineTool(...)`, a `Record<string, defineTool(...)>`, or `null` for no tools. Wrap every entry in `defineTool()`. eve records durable descriptors for `execute`, approval request and response policies, input-scoped `approvalKey` callbacks, and `toModelOutput`, so a parked call can reconstruct the same callbacks in a fresh process.
251
+ Pass `defineDynamic` an `events` object whose handlers return either a single `defineTool(...)`, a `Record<string, defineTool(...)>`, or `null` for no tools. Wrap every entry in `defineTool()`. eve records durable descriptors for `execute`, approval request and response policies, input-scoped `approvalKey` callbacks, `toModelOutput`, and an `endsTurn` function, so a parked call can reconstruct the same callbacks in a fresh process.
252
252
 
253
253
  Dynamic tool executors receive the same `ToolContext` as static authored tools, including inline provider auth through `ctx.getToken(provider)` and `ctx.requireAuth(provider)`.
254
254
 
@@ -448,7 +448,7 @@ Skills follow the same naming rule as tools: a single `defineSkill(...)` is name
448
448
 
449
449
  A dynamic skill with `deferred: true` is left out of the dynamic skill announcement and isn't named in context. The model finds it with `eve__search` and loads it with `eve__skill({ name })`, like a static deferred skill. When it overrides a static skill that isn't deferred, the system prompt still lists the static skill's description, and loading returns the dynamic body.
450
450
 
451
- A dynamic skill that returns only `markdown` never starts a sandbox: eve keeps its instructions in session state and returns them when the model loads the skill. When the skill also returns `files`, eve writes the package to the sandbox skill root when the resolver first returns it, and again only when its contents change or the session gets a new sandbox. A changed package replaces the previous directory, so files omitted from the new result are removed.
451
+ A dynamic skill that returns only `markdown` never starts a sandbox: eve keeps its instructions in session state and returns them when the model loads the skill. When the skill also returns `files`, eve writes the package to the sandbox skill root when the resolver first returns it, and again only when its contents change or the session gets a new sandbox. The write does not delay the model call: eve opens the sandbox and writes the package in the background, and a tool or hook that uses the sandbox waits until the write finishes. If the write fails twice in a row, eve logs it and writes the package again the next time the resolver returns it; a resolver that runs only at `session.started` does not run again, so its files stay missing for the rest of the session. Resolvers run when the turn starts, before the sandbox opens, so when eve replaces a sandbox that was removed outside eve, it writes the files into the new sandbox at the start of the next turn. A replacement made by a subagent or workflow step that shares the session's sandbox is not detected: the session treats the files as written until their contents change. A changed package replaces the previous directory, so files omitted from the new result are removed, and a skill the resolver stops returning has its files removed. A skill that keeps its name but stops returning `files` keeps the files already written, since the sandbox may provide them another way, such as from its snapshot. Keep content meant for only some callers in `markdown`, or stop returning the skill for the others.
452
452
 
453
453
  ## Dynamic instructions
454
454