eve 0.81.0 → 0.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/src/channel/channel-address.d.ts +21 -2
  3. package/dist/src/channel/channel-address.js +1 -1
  4. package/dist/src/channel/channel-operations.d.ts +32 -1
  5. package/dist/src/channel/channel-operations.js +1 -1
  6. package/dist/src/channel/delivery-idempotency.d.ts +4 -0
  7. package/dist/src/channel/delivery-idempotency.js +1 -0
  8. package/dist/src/channel/routes.d.ts +6 -0
  9. package/dist/src/channel/session.d.ts +5 -0
  10. package/dist/src/channel/session.js +1 -1
  11. package/dist/src/channel/types.d.ts +14 -11
  12. package/dist/src/chunks/{use-eve-agent-Bp6nbhfV.js → use-eve-agent-DTu78IAF.js} +36 -0
  13. package/dist/src/chunks/{use-eve-agent-DLkjJIm3.js → use-eve-agent-DlznYwQk.js} +36 -0
  14. package/dist/src/cli/dev/command-options.d.ts +1 -0
  15. package/dist/src/cli/dev/diagnostic-dump.js +1 -1
  16. package/dist/src/cli/run.d.ts +1 -0
  17. package/dist/src/cli/run.js +1 -1
  18. package/dist/src/client/index.d.ts +1 -1
  19. package/dist/src/client/message-reducer-types.d.ts +7 -3
  20. package/dist/src/client/message-reducer.js +1 -1
  21. package/dist/src/client/transcript-reducer.d.ts +6 -3
  22. package/dist/src/client/transcript-reducer.js +1 -1
  23. package/dist/src/compiled/.vendor-stamp.json +2 -2
  24. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  25. package/dist/src/compiler/extension-compatibility.d.ts +19 -18
  26. package/dist/src/compiler/extension-compatibility.js +1 -1
  27. package/dist/src/compiler/load-binding-namespace.d.ts +2 -0
  28. package/dist/src/compiler/load-binding-namespace.js +1 -1
  29. package/dist/src/compiler/manifest.js +1 -1
  30. package/dist/src/compiler/module-lifecycle.d.ts +1 -1
  31. package/dist/src/compiler/module-lifecycle.js +1 -1
  32. package/dist/src/compiler/module-map.js +1 -1
  33. package/dist/src/compiler/normalize-agent-config.js +1 -1
  34. package/dist/src/compiler/normalize-manifest.js +1 -1
  35. package/dist/src/compiler/project-sources.d.ts +6 -0
  36. package/dist/src/compiler/project-sources.js +1 -1
  37. package/dist/src/context/keys.d.ts +2 -0
  38. package/dist/src/context/keys.js +1 -1
  39. package/dist/src/evals/cli/eval-state-directory.d.ts +7 -0
  40. package/dist/src/evals/cli/eval-state-directory.js +1 -0
  41. package/dist/src/evals/cli/eval.js +2 -2
  42. package/dist/src/eve-channel/create-request.d.ts +2 -1
  43. package/dist/src/eve-channel/index.js +1 -1
  44. package/dist/src/eve-channel/request.d.ts +2 -1
  45. package/dist/src/eve-channel/request.js +1 -2
  46. package/dist/src/eve-channel/support.d.ts +11 -1
  47. package/dist/src/eve-channel/support.js +2 -1
  48. package/dist/src/eve-channel/types.d.ts +25 -0
  49. package/dist/src/execution/agent-sessions/context.d.ts +2 -13
  50. package/dist/src/execution/agent-sessions/context.js +1 -1
  51. package/dist/src/execution/agent-sessions/runtime-overrides.d.ts +5 -0
  52. package/dist/src/execution/agent-sessions/runtime-overrides.js +1 -0
  53. package/dist/src/execution/agent-sessions/session.d.ts +2 -2
  54. package/dist/src/execution/agent-sessions/session.js +1 -1
  55. package/dist/src/execution/agent-sessions/steps.d.ts +2 -0
  56. package/dist/src/execution/agent-sessions/steps.js +1 -1
  57. package/dist/src/execution/coordination-dispatch-shared.d.ts +5 -5
  58. package/dist/src/execution/coordination-dispatch-step.d.ts +17 -2
  59. package/dist/src/execution/coordination-dispatch-step.js +1 -1
  60. package/dist/src/execution/create-session-step.d.ts +5 -2
  61. package/dist/src/execution/create-session-step.js +1 -1
  62. package/dist/src/execution/deliver-payloads.js +1 -1
  63. package/dist/src/execution/durable-session-store.d.ts +0 -1
  64. package/dist/src/execution/dynamic-connection-recovery.js +1 -1
  65. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  66. package/dist/src/execution/effective-agent-config.d.ts +8 -2
  67. package/dist/src/execution/effective-agent-config.js +1 -1
  68. package/dist/src/execution/hook-ownership.d.ts +8 -0
  69. package/dist/src/execution/hook-ownership.js +1 -1
  70. package/dist/src/execution/install-workflow-deployment-id.d.ts +3 -0
  71. package/dist/src/execution/install-workflow-deployment-id.js +1 -0
  72. package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
  73. package/dist/src/execution/node-step.d.ts +1 -0
  74. package/dist/src/execution/node-step.js +1 -1
  75. package/dist/src/execution/runtime-context.d.ts +2 -0
  76. package/dist/src/execution/runtime-context.js +1 -1
  77. package/dist/src/execution/session/active-turn.js +1 -1
  78. package/dist/src/execution/session/admission.js +1 -1
  79. package/dist/src/execution/session/checkpoint-migrations.js +1 -1
  80. package/dist/src/execution/session/entry-input.d.ts +20 -8
  81. package/dist/src/execution/session/entry-input.js +1 -1
  82. package/dist/src/execution/session/entry.js +1 -1
  83. package/dist/src/execution/session/finalization.js +1 -1
  84. package/dist/src/execution/session/handoff-steps.d.ts +75 -13
  85. package/dist/src/execution/session/handoff-steps.js +1 -1
  86. package/dist/src/execution/session/handoff.d.ts +73 -34
  87. package/dist/src/execution/session/handoff.js +1 -1
  88. package/dist/src/execution/session/input-queue.d.ts +5 -1
  89. package/dist/src/execution/session/input-queue.js +1 -1
  90. package/dist/src/execution/session/pending-history.d.ts +5 -0
  91. package/dist/src/execution/session/pending-history.js +1 -0
  92. package/dist/src/execution/session/pending-turn-state.js +1 -1
  93. package/dist/src/execution/session/program.d.ts +1 -1
  94. package/dist/src/execution/session/program.js +1 -1
  95. package/dist/src/execution/session/run-watch.d.ts +22 -0
  96. package/dist/src/execution/session/run-watch.js +1 -0
  97. package/dist/src/execution/session/timeout-control.d.ts +18 -4
  98. package/dist/src/execution/session/timeout-control.js +1 -1
  99. package/dist/src/execution/session/timeout.d.ts +1 -2
  100. package/dist/src/execution/session/timeout.js +1 -1
  101. package/dist/src/execution/session/turn-event-handler.js +1 -1
  102. package/dist/src/execution/session/turn-step-result.js +1 -1
  103. package/dist/src/execution/session/turn-step.js +1 -1
  104. package/dist/src/execution/session/turn-waiting-step.js +1 -1
  105. package/dist/src/execution/session/turn.js +1 -1
  106. package/dist/src/execution/session-inbox/address.d.ts +4 -1
  107. package/dist/src/execution/session-inbox/end-stranded-session.js +1 -1
  108. package/dist/src/execution/session-inbox/hook-release.d.ts +9 -2
  109. package/dist/src/execution/session-inbox/hook-release.js +1 -1
  110. package/dist/src/execution/session-inbox/inbox.d.ts +66 -6
  111. package/dist/src/execution/session-inbox/inbox.js +1 -1
  112. package/dist/src/execution/session-inbox/protocol.js +1 -1
  113. package/dist/src/execution/session-inbox/resume.d.ts +4 -3
  114. package/dist/src/execution/session.d.ts +0 -12
  115. package/dist/src/execution/session.js +2 -2
  116. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  117. package/dist/src/execution/tasks/model-step.js +1 -1
  118. package/dist/src/execution/tasks/start.d.ts +4 -4
  119. package/dist/src/execution/tasks/start.js +1 -1
  120. package/dist/src/execution/tasks/steps.js +1 -1
  121. package/dist/src/execution/terminate-child-sessions-step.js +1 -1
  122. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  123. package/dist/src/execution/tools/workflow/body.d.ts +2 -2
  124. package/dist/src/execution/workflow-runtime.d.ts +11 -12
  125. package/dist/src/execution/workflow-runtime.js +1 -1
  126. package/dist/src/harness/hitl/approvals.js +1 -1
  127. package/dist/src/harness/hitl/budget-request.d.ts +12 -6
  128. package/dist/src/harness/hitl/budget-request.js +1 -1
  129. package/dist/src/harness/hitl/budget.d.ts +7 -1
  130. package/dist/src/harness/hitl/budget.js +1 -1
  131. package/dist/src/harness/hitl/coordinator.js +1 -1
  132. package/dist/src/harness/hitl/delivery.d.ts +1 -1
  133. package/dist/src/harness/hitl/delivery.js +1 -1
  134. package/dist/src/harness/hitl/index.js +1 -1
  135. package/dist/src/harness/hitl/intake.d.ts +2 -2
  136. package/dist/src/harness/hitl/intake.js +1 -1
  137. package/dist/src/harness/messages.d.ts +5 -0
  138. package/dist/src/harness/messages.js +1 -1
  139. package/dist/src/harness/model-call/call.d.ts +2 -2
  140. package/dist/src/harness/model-call/call.js +1 -1
  141. package/dist/src/harness/model-call/request.d.ts +2 -2
  142. package/dist/src/harness/session-machine/transitions.d.ts +3 -1
  143. package/dist/src/harness/session-machine/transitions.js +1 -1
  144. package/dist/src/harness/step/context.d.ts +3 -0
  145. package/dist/src/harness/step/context.js +1 -1
  146. package/dist/src/harness/step/intake.d.ts +5 -2
  147. package/dist/src/harness/step/intake.js +1 -1
  148. package/dist/src/harness/tool-loop.js +1 -1
  149. package/dist/src/harness/turn-tag-state.d.ts +7 -26
  150. package/dist/src/harness/turn-tag-state.js +1 -1
  151. package/dist/src/harness/types.d.ts +10 -25
  152. package/dist/src/instrumentation/content.d.ts +1 -1
  153. package/dist/src/instrumentation/content.js +1 -1
  154. package/dist/src/instrumentation/lifecycle.d.ts +4 -2
  155. package/dist/src/internal/application/build-profile.d.ts +3 -0
  156. package/dist/src/internal/application/build-profile.js +1 -1
  157. package/dist/src/internal/application/compiled-artifacts.js +2 -2
  158. package/dist/src/internal/application/dev-environment.d.ts +13 -0
  159. package/dist/src/internal/application/dev-environment.js +1 -1
  160. package/dist/src/internal/application/stamped-package-version.js +1 -1
  161. package/dist/src/internal/authored-definition/connection.js +1 -1
  162. package/dist/src/internal/authored-definition/core.js +1 -1
  163. package/dist/src/internal/authored-module-build-options.d.ts +7 -0
  164. package/dist/src/internal/authored-module-build-options.js +1 -0
  165. package/dist/src/internal/authored-module-graph.d.ts +13 -0
  166. package/dist/src/internal/authored-module-graph.js +1 -0
  167. package/dist/src/internal/authored-module-loader.d.ts +22 -1
  168. package/dist/src/internal/authored-module-loader.js +1 -3
  169. package/dist/src/internal/authored-module.d.ts +7 -0
  170. package/dist/src/internal/authored-module.js +1 -1
  171. package/dist/src/internal/authored-package-boundary.js +1 -1
  172. package/dist/src/internal/bundler/nitro-rolldown.d.ts +5 -1
  173. package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
  174. package/dist/src/internal/development-programmatic-source-loader.d.ts +1 -0
  175. package/dist/src/internal/development-programmatic-source-loader.js +1 -1
  176. package/dist/src/internal/mcp/skills.js +1 -1
  177. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  178. package/dist/src/internal/nitro/dev-runtime-generation-metadata.js +1 -1
  179. package/dist/src/internal/nitro/host/build-application.js +1 -1
  180. package/dist/src/internal/nitro/host/build-deployment-id.d.ts +8 -0
  181. package/dist/src/internal/nitro/host/build-deployment-id.js +1 -0
  182. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  183. package/dist/src/internal/nitro/host/dev-server-state.js +1 -1
  184. package/dist/src/internal/nitro/host/skill-server-assets.js +1 -1
  185. package/dist/src/internal/nitro/host/stage-build-deployment-id.d.ts +2 -0
  186. package/dist/src/internal/nitro/host/stage-build-deployment-id.js +1 -0
  187. package/dist/src/internal/nitro/host/start-production-server.d.ts +1 -0
  188. package/dist/src/internal/nitro/host/start-production-server.js +3 -3
  189. package/dist/src/internal/nitro/routes/schedule-task.d.ts +3 -0
  190. package/dist/src/internal/nitro/routes/schedule-task.js +1 -1
  191. package/dist/src/internal/programmatic-source-loader.d.ts +1 -0
  192. package/dist/src/internal/programmatic-source-loader.js +1 -1
  193. package/dist/src/internal/schedules/disabled.d.ts +2 -0
  194. package/dist/src/internal/schedules/disabled.js +1 -0
  195. package/dist/src/internal/workflow/development-world-client.js +1 -1
  196. package/dist/src/internal/workflow/development-world-server.js +1 -1
  197. package/dist/src/internal/workflow/local-world-data-directory.d.ts +2 -1
  198. package/dist/src/internal/workflow/local-world-data-directory.js +1 -1
  199. package/dist/src/internal/workflow-bundle/builder.js +1 -1
  200. package/dist/src/protocol/message.d.ts +27 -1
  201. package/dist/src/protocol/message.js +2 -2
  202. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +13 -0
  203. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  204. package/dist/src/public/channels/chat-sdk/fetch-message.d.ts +10 -0
  205. package/dist/src/public/channels/chat-sdk/fetch-message.js +1 -0
  206. package/dist/src/public/channels/chat-sdk/index.d.ts +1 -1
  207. package/dist/src/public/channels/chat-sdk/messageToUserContent.d.ts +2 -1
  208. package/dist/src/public/channels/chat-sdk/messageToUserContent.js +1 -1
  209. package/dist/src/public/channels/chat-sdk/reply-context.d.ts +15 -0
  210. package/dist/src/public/channels/chat-sdk/reply-context.js +2 -0
  211. package/dist/src/public/channels/discord/discordChannel.d.ts +3 -0
  212. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  213. package/dist/src/public/channels/github/dispatch.js +1 -1
  214. package/dist/src/public/channels/github/githubChannel.d.ts +3 -0
  215. package/dist/src/public/channels/imessage-tapbacks.d.ts +74 -0
  216. package/dist/src/public/channels/imessage-tapbacks.js +1 -0
  217. package/dist/src/public/channels/index.d.ts +2 -1
  218. package/dist/src/public/channels/index.js +1 -1
  219. package/dist/src/public/channels/linear/linearChannel.d.ts +3 -0
  220. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  221. package/dist/src/public/channels/linq/inboundContent.d.ts +7 -0
  222. package/dist/src/public/channels/linq/inboundContent.js +1 -1
  223. package/dist/src/public/channels/linq/index.d.ts +1 -0
  224. package/dist/src/public/channels/linq/index.js +1 -1
  225. package/dist/src/public/channels/linq/linqChannel.d.ts +17 -1
  226. package/dist/src/public/channels/linq/linqChannel.js +1 -1
  227. package/dist/src/public/channels/photon/attachments.d.ts +5 -2
  228. package/dist/src/public/channels/photon/attachments.js +1 -1
  229. package/dist/src/public/channels/photon/inboundContent.d.ts +7 -0
  230. package/dist/src/public/channels/photon/inboundContent.js +2 -1
  231. package/dist/src/public/channels/photon/index.d.ts +1 -0
  232. package/dist/src/public/channels/photon/index.js +1 -1
  233. package/dist/src/public/channels/photon/photonIMessageChannel.d.ts +17 -1
  234. package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -1
  235. package/dist/src/public/channels/slack/api.d.ts +14 -1
  236. package/dist/src/public/channels/slack/api.js +1 -1
  237. package/dist/src/public/channels/slack/model-context.d.ts +7 -0
  238. package/dist/src/public/channels/slack/model-context.js +1 -1
  239. package/dist/src/public/channels/slack/reply-delivery.d.ts +5 -0
  240. package/dist/src/public/channels/slack/reply-delivery.js +1 -1
  241. package/dist/src/public/channels/slack/slackChannel.d.ts +17 -3
  242. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  243. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -0
  244. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  245. package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -0
  246. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  247. package/dist/src/public/definitions/agent.d.ts +1 -1
  248. package/dist/src/public/definitions/channel.d.ts +2 -2
  249. package/dist/src/public/definitions/channel.js +1 -1
  250. package/dist/src/public/definitions/hook.d.ts +1 -0
  251. package/dist/src/public/index.d.ts +1 -1
  252. package/dist/src/public/tools/index.d.ts +1 -1
  253. package/dist/src/runtime/agent/resolve-model.d.ts +4 -0
  254. package/dist/src/runtime/agent/resolve-model.js +1 -1
  255. package/dist/src/runtime/resolve-agent.js +1 -1
  256. package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
  257. package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +2 -1
  258. package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
  259. package/dist/src/runtime/types.d.ts +3 -2
  260. package/dist/src/setup/scaffold/create/project.js +1 -1
  261. package/dist/src/shared/agent-definition.d.ts +31 -42
  262. package/dist/src/shared/gateway-routing.d.ts +20 -0
  263. package/dist/src/shared/gateway-routing.js +1 -0
  264. package/dist/src/shared/session-history.d.ts +22 -0
  265. package/dist/src/shared/session-history.js +1 -0
  266. package/dist/src/shared/skill-package.js +1 -1
  267. package/dist/src/subagents/tool.d.ts +1 -3
  268. package/dist/src/subagents/tool.js +1 -1
  269. package/dist/src/svelte/index.js +1 -1
  270. package/dist/src/svelte/use-eve-agent.js +1 -1
  271. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  272. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  273. package/dist/src/tools/workflow-definition.d.ts +14 -1
  274. package/dist/src/tracing/eve/agent-otel-provider.js +1 -1
  275. package/dist/src/tracing/eve/conversation-context.d.ts +4 -1
  276. package/dist/src/tracing/eve/conversation-context.js +1 -1
  277. package/dist/src/tracing/eve/gateway.d.ts +5 -0
  278. package/dist/src/tracing/eve/gateway.js +1 -1
  279. package/dist/src/tracing/eve/invoke-tool-span.js +1 -1
  280. package/dist/src/tracing/eve/operation-input.d.ts +0 -12
  281. package/dist/src/tracing/eve/operation-input.js +1 -1
  282. package/dist/src/tracing/eve/otel-registration.js +1 -1
  283. package/dist/src/tracing/eve/policy.d.ts +1 -1
  284. package/dist/src/tracing/eve/policy.js +1 -1
  285. package/dist/src/tracing/eve/session.d.ts +5 -2
  286. package/dist/src/tracing/eve/session.js +1 -1
  287. package/dist/src/vue/index.js +1 -1
  288. package/dist/src/vue/use-eve-agent.js +1 -1
  289. package/docs/README.md +1 -0
  290. package/docs/agent-config.md +108 -65
  291. package/docs/channels/chat-sdk.mdx +10 -3
  292. package/docs/channels/custom.mdx +38 -6
  293. package/docs/channels/eve.mdx +73 -0
  294. package/docs/channels/linq.mdx +51 -0
  295. package/docs/channels/photon.mdx +68 -2
  296. package/docs/channels/slack.mdx +6 -2
  297. package/docs/concepts/built-in-tools.md +1 -1
  298. package/docs/concepts/execution-model-and-durability.mdx +27 -11
  299. package/docs/concepts/sessions-runs-and-streaming.md +9 -8
  300. package/docs/connections/overview.mdx +1 -1
  301. package/docs/experimental/dynamic-schedules.mdx +186 -0
  302. package/docs/experimental/meta.json +4 -0
  303. package/docs/guides/client/streaming.mdx +1 -0
  304. package/docs/guides/deployment/self-hosting.md +3 -0
  305. package/docs/guides/hooks.md +21 -1
  306. package/docs/guides/instrumentation/otel.mdx +20 -0
  307. package/docs/memory/overview.mdx +2 -1
  308. package/docs/patterns/dynamic-scheduling.md +3 -1
  309. package/docs/patterns/meta.json +1 -0
  310. package/docs/patterns/voice-notes.md +67 -0
  311. package/docs/reference/cli.md +14 -7
  312. package/docs/sandbox/index.mdx +2 -0
  313. package/docs/schedules.mdx +2 -0
  314. package/docs/subagents/index.mdx +2 -0
  315. package/docs/tools/overview.mdx +2 -1
  316. package/docs/tools/tasks-upgrade.md +12 -7
  317. package/docs/tools/tasks.md +10 -6
  318. package/docs/tools/workflows.mdx +36 -5
  319. package/docs/tutorial/connect-a-warehouse.mdx +1 -1
  320. package/docs/tutorial/run-analysis.mdx +1 -1
  321. package/package.json +1 -1
  322. package/dist/src/execution/run-session-limits.d.ts +0 -12
  323. package/dist/src/execution/run-session-limits.js +0 -1
  324. package/dist/src/harness/session-usage-limits.d.ts +0 -49
  325. package/dist/src/harness/session-usage-limits.js +0 -1
  326. package/dist/src/subagents/token-budget.d.ts +0 -15
  327. package/dist/src/subagents/token-budget.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # eve
2
2
 
3
+ ## 0.82.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c543585: Breaking: replace `limits.maxInputTokensPerSession`, `limits.maxOutputTokensPerSession` and `limits.maxTokenCostUsdPerSession` with one `limits.sessionUsage` function. It receives the session's `total` usage and its `window` since the last approved continuation, and returns `true` when the limit is reached; Continue starts a new window. The default is 40M new input tokens (input minus cache reads) per window. Subagents now check their own window with their own `sessionUsage` or the root agent's instead of receiving a share of the parent's remaining quota. Sessions that can't ask now fail with `SESSION_USAGE_LIMIT_REACHED`, replacing `SESSION_TOKEN_LIMIT_REACHED` and `SESSION_TOKEN_COST_LIMIT_REACHED`.
8
+
9
+ ### Patch Changes
10
+
11
+ - baf3030: Attach the agent trace session ID to auto-instrumented child spans on Vercel so Agent Runs can include network and other third-party spans in a session trace.
12
+ - 91b3183: The session input-token limit now counts only new input (uncached input plus cache writes). Cache reads no longer count toward the limit, the grant after Continue, or the quota shared with subagents, so long cache-heavy sessions stop hitting continuation prompts for replaying their own history. Usage telemetry still reports raw input and cache totals. Providers that report no cache details count exactly as before.
13
+ - 8aba0f6: Allow authored workflow tools to select an AI Gateway model when they open a local session with `ctx.agent()`. The child keeps the target agent's other configuration, and the selected model applies for the session's lifetime.
14
+ - 0aea7fc: `eve eval` now runs while an `eve dev` session for the same agent is open, instead of failing with "A dev server is already running for this eve agent." The eval server keeps its runtime generations, local Workflow data, and server record in a per-run directory under `.eve/eval-servers/`, so it never swaps or prunes the dev session's state.
15
+ - a9f5065: Channel and session sends and responses now accept `idempotencyKey` to ignore retries across replay and owner handoffs. Photon supplies message IDs automatically; deduplication requires a shared Workflow World and only covers keys in the session's recent-key window.
16
+ - 6752c95: Fix a workflow tool task running twice when the session was interrupted while publishing `task.started`, for example during a slow `task.started` hook. The session now records each task's run before it publishes the event, so a retry only publishes `task.started` again and never starts a second run.
17
+ - 964a41f: `limits.sessionTimeoutMs` is now an idle timeout: the window restarts each time a turn settles, so a session in active use no longer ends 30 days after it was created. Idle sessions still complete when the window elapses, and the next channel message at their address starts a fresh session as before.
18
+ - dd8c231: Linq and Photon iMessage channels now tell the model when a message is a reply, and include the text of the message it quotes.
19
+ - cf824a8: The Photon and Linq channels can now pass tapbacks to the agent with a new `onTapback` hook, which can also answer the approval or question posted in the message the tapback is on, for example approving with a like. `channel.tapbackTool()` gives the model a tool that reacts to the latest message with a standard tapback or any emoji. Tapbacks stay ignored unless you opt in.
20
+ - 743b498: `eve start --no-schedules` and `EVE_SCHEDULES_DISABLED=1` start a server that does not fire authored cron schedules, so only one process runs them when you scale out.
21
+ - b34844b: Channel `send()`, channel message hooks, and a new `create()` on channel addresses accept `history` to add prior user and assistant messages, such as a stored transcript, as real turns. `create()` starts a session that waits for its first message and reports with `created` whether it did. A new `history.imported` stream event publishes added messages; the default client reducer renders them, and `transcriptReducer()` includes them. Slack `threadContext` now adds earlier replies as history when a message starts the thread's session; later messages keep the existing transcript.
22
+ - e40d7d7: `eve build` and `eve dev` now evaluate a module shared by several tools, channels, or other authored files once per compile instead of once per importing file. Compile memory now grows with the code an agent actually has, not with the number of files that import it, so agents with many tools over a shared SDK or workspace package no longer run out of memory on smaller build machines. Authored modules transpiled to CommonJS with an `__esModule` marker, such as a `tools/*.cjs` file with `exports.default = …`, now also compile and run correctly instead of resolving to the whole `exports` object. On Windows, CommonJS authored modules can now `require()` eve and other external packages.
23
+ - 62d3227: Skip the final Slack reply when the message that started the turn was deleted, instead of letting Slack post it as a top-level channel message.
24
+ - ee5e8e9: Self-hosted `eve build` output now carries a build identity derived from its contents. eve exposes it to Workflow Worlds as `WORKFLOW_DEPLOYMENT_ID` unless that variable is already set, and records it in `eve build --profile` reports.
25
+ - 7b8a520: Fix unnecessary `eve dev` runtime-generation changes when Nitro installs newer Rolldown versions. No-op rebuilds and environment-only reloads now keep the active runtime snapshot unchanged instead of treating bundler debug comments as runtime changes.
26
+
27
+ ## 0.81.1
28
+
29
+ ### Patch Changes
30
+
31
+ - e4e0cd1: Fix activation trace-content markers to respect the resolved session policy, provider capture settings, and live audience ceiling. Metadata-only sessions now report withheld content accurately without removing content allowed by an explicit trace policy.
32
+ - 54d63fd: A session keeps accepting messages during a deployment or compaction handoff, so the first message after a handoff reaches the model sooner and messages sent mid-handoff no longer retry or return `409 session_not_ready`; messages already waiting when a compaction finishes now run before the session moves. Sessions started on an earlier eve release still move to this release: their first move uses the previous handoff, and every move after it uses the new one. On Workflow worlds without hook force-claim support, sessions no longer move between runs, so their run history keeps growing for as long as the session lives.
33
+ - fc4dbd0: Cancelling a turn while the model is responding no longer marks its `agent.step` span as an error, so user-initiated stops stop showing up as failures in error tracking.
34
+ - 299db19: Connections now accept the documented `auth.displayName` field instead of failing validation with `Unknown key "displayName"`.
35
+ - 09b423a: `agent.step` spans for AI Gateway model calls now record the Gateway's session affinity report: the session ID, where that ID came from, the affinity outcome, and the pinned and displaced providers. Use these attributes to match a step to its session in the AI Gateway logs Sessions view.
36
+ - f9ea546: The eve channel's `onMessage` can now read the request's `clientContext` as `ctx.eve.clientContext` and return its own `clientContext` to replace it for that turn, so the model sees server-checked context without it being kept in session history.
37
+ - 4d9fc9f: iMessage voice notes now reach Photon agents. Photon's webhook leaves out a voice note's attachment id, so eve refetches the message by id to download it. Across Chat SDK channels, an attachment the platform gives no way to download now reaches the agent as a short note instead of being dropped, so an attachment-only message still gets a reply.
38
+ - 02bb7c4: `ctx.thread.postEphemeral()` on a fresh top-level Slack message now posts to the channel instead of an empty thread, where Slack hid it. Replies inside an existing thread stay threaded.
39
+
3
40
  ## 0.81.0
4
41
 
5
42
  ### Minor Changes
@@ -4,27 +4,46 @@ import { type ChannelDeliverySource } from "#channel/delivery-metadata.js";
4
4
  import type { SendPayload } from "#channel/routes.js";
5
5
  import { type Session } from "#channel/session.js";
6
6
  import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, TurnPolicy } from "#channel/types.js";
7
+ interface BaseChannelAddressCreateOptions {
8
+ readonly auth: SessionAuthContext | null;
9
+ readonly history?: SendPayload["history"];
10
+ readonly initiatorAuth?: SessionAuthContext | null;
11
+ readonly title?: string;
12
+ }
13
+ type ChannelAddressCreateOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelAddressCreateOptions : BaseChannelAddressCreateOptions & {
14
+ readonly state?: Partial<TState>;
15
+ };
7
16
  interface BaseChannelAddressDeliveryOptions {
17
+ readonly idempotencyKey?: string;
8
18
  readonly auth: SessionAuthContext | null;
9
19
  readonly callback?: SessionCallback;
10
20
  readonly initiatorAuth?: SessionAuthContext | null;
11
21
  readonly title?: string;
12
22
  readonly turnPolicy?: TurnPolicy;
13
23
  }
24
+ /**
25
+ * Result of `create()`. `created` is `false` when another session already owned the address, or
26
+ * won it concurrently; that session is returned unchanged and any `history` was not added.
27
+ */
28
+ export interface ChannelCreateResult {
29
+ readonly created: boolean;
30
+ readonly session: Session;
31
+ }
14
32
  /** Delivery options for a channel address whose continuation token is already bound. */
15
33
  export type ChannelAddressDeliveryOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelAddressDeliveryOptions : BaseChannelAddressDeliveryOptions & {
16
34
  readonly state?: Partial<TState>;
17
35
  };
18
36
  /**
19
37
  * Dynamic handle for whichever durable session currently owns one channel-local address.
20
- * Only {@link send} may create a session: when the address is unowned, or in
21
- * place of a stranded session that another eve version built. Sends to a session whose
38
+ * Only {@link create} and {@link send} may create a session: when the address is unowned, and
39
+ * `send` also in place of a stranded session that another eve version built. Sends to a session whose
22
40
  * owner is only unavailable throw `SessionStrandedError` and deliver nothing.
23
41
  * Responses to an address no session holds throw `SessionNotActiveError`.
24
42
  */
25
43
  interface ChannelAddress<TState = undefined> {
26
44
  readonly continuationToken: string;
27
45
  deliver(input: SendPayload, options: ChannelAddressDeliveryOptions<TState>): Promise<Session>;
46
+ create(options: ChannelAddressCreateOptions<TState>): Promise<ChannelCreateResult>;
28
47
  send(message: string | UserContent, options: ChannelAddressDeliveryOptions<TState>): Promise<Session>;
29
48
  respond(inputResponses: SendPayload["inputResponses"], options: ChannelAddressDeliveryOptions<TState>): Promise<Session>;
30
49
  cancel(options?: {
@@ -1 +1 @@
1
- import{createSession,sessionCallbackToTurnCaller}from"#channel/session.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{normalizeSendInput,serializeFilePartsInMessage}from"#channel/send-input.js";import{SessionNotActiveError}from"#channel/session-not-active-error.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{isReservedSessionCommandToken}from"#execution/session-inbox/address.js";function createChannelAddress(e){let t=e.metadata??{},n=`${e.channelName}:${e.continuationToken}`;if(isReservedSessionCommandToken(n))throw Error(`Channel address "${n}" uses eve's reserved session namespace.`);return{continuationToken:e.continuationToken,async deliver(r,i){let a=t.channelKind!==void 0&&t.channelName!==void 0?createChannelDeliveryMetadata(t):void 0,o=normalizeSendInput(r),s=sessionCallbackToTurnCaller(i.callback),c={auth:i.auth,delivery:a,kind:`send`,payload:{...o,message:serializeFilePartsInMessage(o.message)},requestId:t.requestId,turnPolicy:o.message===void 0?void 0:i.turnPolicy??e.turnPolicy??DEFAULT_TURN_POLICY},l=s===void 0?c:{...c,caller:s},u=i.state,d={adapter:u===void 0?e.adapter:{...e.adapter,state:{...e.adapter.state,...u}},auth:i.auth,capabilities:{requestInput:!0},callback:i.callback,channelName:e.channelName,continuationConflictCommand:l,continuationToken:n,delivery:a,initiatorAuth:i.initiatorAuth,input:{context:o.context,message:serializeFilePartsInMessage(o.message)??``,outputSchema:o.outputSchema,state:o.state},requestId:t.requestId,title:i.title},toSession=n=>createSession(n,e.runtime,{...t,turnPolicy:e.turnPolicy}),f=await e.runtime.dispatchContinuation({command:l,continuationToken:n,successor:d});if(f.status===`accepted`)return toSession(f.sessionId);if(o.inputResponses&&o.inputResponses.length>0)throw new SessionNotActiveError;return toSession((await e.runtime.createSession(d)).sessionId)},async send(e,t){return await this.deliver({message:e},t)},async respond(e,t){if(e===void 0||e.length===0)throw Error(`respond() requires at least one input response.`);return await this.deliver({inputResponses:e},t)},async cancel(t){return await e.runtime.dispatchContinuation({command:{kind:`cancel`,turnId:t?.turnId},continuationToken:n})},async compact(){return await e.runtime.dispatchContinuation({command:{kind:`compact`},continuationToken:n})},async clear(){return await e.runtime.dispatchContinuation({command:{kind:`clear`},continuationToken:n})},async reset(t){return await e.runtime.dispatchContinuation({command:{kind:`reset`,reason:t?.reason},continuationToken:n})},async resolveSession(){let r=await e.runtime.resolveContinuation(n);return r===void 0?void 0:createSession(r.sessionId,e.runtime,{...t,turnPolicy:e.turnPolicy})}}}function createChannelAddressFn(e){return t=>createChannelAddress({...e,continuationToken:t})}export{createChannelAddress,createChannelAddressFn};
1
+ import{createSession,sessionCallbackToTurnCaller}from"#channel/session.js";import{validateDeliveryIdempotencyKey}from"#channel/delivery-idempotency.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{normalizeSendInput,serializeFilePartsInMessage}from"#channel/send-input.js";import{SessionNotActiveError}from"#channel/session-not-active-error.js";import{SessionStrandedError,describeStrandedSession}from"#channel/session-stranded-error.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{isReservedSessionCommandToken}from"#execution/session-inbox/address.js";import{validateSessionHistory}from"#shared/session-history.js";function createChannelAddress(e){let t=e.metadata??{},n=`${e.channelName}:${e.continuationToken}`;if(isReservedSessionCommandToken(n))throw Error(`Channel address "${n}" uses eve's reserved session namespace.`);return{continuationToken:e.continuationToken,async deliver(r,i){validateDeliveryIdempotencyKey(i.idempotencyKey);let a=t.channelKind!==void 0&&t.channelName!==void 0?createChannelDeliveryMetadata(t):void 0,o=withValidatedHistory(normalizeSendInput(r)),s=sessionCallbackToTurnCaller(i.callback),c={idempotencyKey:i.idempotencyKey,auth:i.auth,delivery:a,kind:`send`,payload:{...o,message:serializeFilePartsInMessage(o.message)},requestId:t.requestId,turnPolicy:o.message===void 0?void 0:i.turnPolicy??e.turnPolicy??DEFAULT_TURN_POLICY},l=s===void 0?c:{...c,caller:s},u=i.state,d=u===void 0?e.adapter:{...e.adapter,state:{...e.adapter.state,...u}},f={idempotencyKey:i.idempotencyKey,adapter:d,auth:i.auth,capabilities:{requestInput:!0},callback:i.callback,channelName:e.channelName,continuationConflictCommand:l,continuationToken:n,delivery:a,initiatorAuth:i.initiatorAuth,input:{context:o.context,history:o.history,message:serializeFilePartsInMessage(o.message)??``,outputSchema:o.outputSchema,state:o.state},requestId:t.requestId,title:i.title},toSession=n=>createSession(n,e.runtime,{...t,turnPolicy:e.turnPolicy}),p=await e.runtime.dispatchContinuation({command:l,continuationToken:n,successor:f});if(p.status===`accepted`)return toSession(p.sessionId);if(o.inputResponses&&o.inputResponses.length>0)throw new SessionNotActiveError;return toSession((await e.runtime.createSession(f)).sessionId)},async create(r){let i=validateSessionHistory(r.history),toSession=n=>createSession(n,e.runtime,{...t,turnPolicy:e.turnPolicy}),a;try{a=await e.runtime.resolveContinuation(n,{runnable:!0})}catch(e){throw SessionStrandedError.is(e)?new SessionStrandedError(e.owner,describeStrandedSession(e.owner,`Call reset() on the address, then create() again to start a session from your history.`)):e}if(a!==void 0)return{created:!1,session:toSession(a.sessionId)};let o=r.state,s=await e.runtime.createSession({adapter:o===void 0?e.adapter:{...e.adapter,state:{...e.adapter.state,...o}},auth:r.auth,capabilities:{requestInput:!0},channelName:e.channelName,continuationToken:n,initiatorAuth:r.initiatorAuth,input:i===void 0?{}:{history:i},requestId:t.requestId,title:r.title}),c=await waitForContinuationOwner(e.runtime,n,s.sessionId);return{created:c.sessionId===s.sessionId,session:toSession(c.sessionId)}},async send(e,t){return await this.deliver({message:e},t)},async respond(e,t){if(e===void 0||e.length===0)throw Error(`respond() requires at least one input response.`);return await this.deliver({inputResponses:e},t)},async cancel(t){return await e.runtime.dispatchContinuation({command:{kind:`cancel`,turnId:t?.turnId},continuationToken:n})},async compact(){return await e.runtime.dispatchContinuation({command:{kind:`compact`},continuationToken:n})},async clear(){return await e.runtime.dispatchContinuation({command:{kind:`clear`},continuationToken:n})},async reset(t){return await e.runtime.dispatchContinuation({command:{kind:`reset`,reason:t?.reason},continuationToken:n})},async resolveSession(){let r=await e.runtime.resolveContinuation(n);return r===void 0?void 0:createSession(r.sessionId,e.runtime,{...t,turnPolicy:e.turnPolicy})}}}function createChannelAddressFn(e){return t=>createChannelAddress({...e,continuationToken:t})}function withValidatedHistory(e){let{history:t,...n}=e,r=validateSessionHistory(t);return r===void 0?n:{...n,history:r}}const CREATE_CLAIM_TIMEOUT_MS=15e3;async function waitForContinuationOwner(e,t,n){let r=Date.now()+CREATE_CLAIM_TIMEOUT_MS;for(let i=25;;i=Math.min(i*2,500)){let a=await e.resolveContinuation(t);if(a!==void 0)return a;if(Date.now()+i>r)throw Error(`create() started session "${n}" for "${t}", but no session claimed the address within ${CREATE_CLAIM_TIMEOUT_MS/1e3}s. Call resolveSession() on the address to find its owner once one does.`);await new Promise(e=>setTimeout(e,i))}}export{createChannelAddress,createChannelAddressFn};
@@ -1,14 +1,25 @@
1
1
  import type { UserContent } from "ai";
2
2
  import type { ChannelAdapter } from "#channel/adapter.js";
3
3
  import type { ChannelDeliverySource } from "#channel/delivery-metadata.js";
4
+ import { type ChannelCreateResult } from "#channel/channel-address.js";
5
+ export type { ChannelCreateResult } from "#channel/channel-address.js";
4
6
  import type { Session } from "#channel/session.js";
5
7
  import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, TurnPolicy } from "#channel/types.js";
6
8
  import { type InputResponse, type StrictInputResponses } from "#shared/input.js";
7
9
  import type { JsonObject } from "#shared/json.js";
10
+ import type { SessionHistoryMessage } from "#shared/session-history.js";
8
11
  interface BaseChannelSendOptions {
12
+ /** Stable delivery identity, deduplicated within this session's recent-key window. */
13
+ readonly idempotencyKey?: string;
9
14
  readonly auth: SessionAuthContext | null;
10
15
  readonly callback?: SessionCallback;
11
16
  readonly context?: readonly string[];
17
+ /**
18
+ * Prior conversation added as user and assistant turns before this
19
+ * message and its `context`. Seeds a session this send creates, or
20
+ * extends the history of the session that owns the address.
21
+ */
22
+ readonly history?: readonly SessionHistoryMessage[];
12
23
  readonly initiatorAuth?: SessionAuthContext | null;
13
24
  /** JSON Schema for a structured final answer, as on `Session.send()`. */
14
25
  readonly outputSchema?: JsonObject;
@@ -20,16 +31,37 @@ export type ChannelSendOptions<TState = undefined> = [TState] extends [undefined
20
31
  readonly state: TState;
21
32
  };
22
33
  interface BaseChannelRespondOptions<TState = undefined> {
34
+ /** Stable delivery identity, with the same scope and retention as `send()`. */
35
+ readonly idempotencyKey?: string;
23
36
  readonly auth: SessionAuthContext | null;
24
37
  readonly context?: readonly string[];
25
38
  readonly state?: Partial<TState>;
26
39
  }
27
40
  /** Options for answering pending input requests at an existing continuation address. */
28
41
  export type ChannelRespondOptions<TState = undefined> = BaseChannelRespondOptions<TState>;
42
+ interface BaseChannelCreateOptions {
43
+ readonly auth: SessionAuthContext | null;
44
+ /** Prior conversation the session starts with; it joins history with the first message. */
45
+ readonly history?: readonly SessionHistoryMessage[];
46
+ readonly initiatorAuth?: SessionAuthContext | null;
47
+ readonly title?: string;
48
+ }
49
+ /** Options for creating a session at a channel-local address without running a turn. */
50
+ export type ChannelCreateOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelCreateOptions : BaseChannelCreateOptions & {
51
+ readonly state: TState;
52
+ };
29
53
  /** Dynamic handle for whichever session currently owns one channel-local address. */
30
54
  export interface ChannelSource<TState = undefined> {
31
55
  /** Starts or resumes a turn with a user message. May create a session. */
32
56
  send(message: string | UserContent, options: ChannelSendOptions<TState>): Promise<Session>;
57
+ /**
58
+ * Creates a session that waits for its first message, without running a
59
+ * turn. When another session owns the address, or claims it concurrently,
60
+ * returns that session unchanged with `created: false`; its `history` was not
61
+ * added. Throws `SessionStrandedError` when the owner is stranded; reset the
62
+ * address, then create again.
63
+ */
64
+ create(options: ChannelCreateOptions<TState>): Promise<ChannelCreateResult>;
33
65
  /** Answers pending input requests. Never creates a session. */
34
66
  respond<const TResponses extends readonly InputResponse[]>(inputResponses: StrictInputResponses<TResponses>, options: ChannelRespondOptions<TState>): Promise<Session>;
35
67
  /** Cooperatively cancels the active turn without creating a session. */
@@ -62,4 +94,3 @@ export declare function createChannelOperations<TState = undefined>(input: {
62
94
  readonly runtime: Runtime;
63
95
  readonly turnPolicy?: TurnPolicy;
64
96
  }): ChannelReceiveContext<TState>;
65
- export {};
@@ -1 +1 @@
1
- import{attachInputText,readInputText}from"#internal/input-text.js";import{createChannelAddressFn}from"#channel/channel-address.js";import{parseInputResponses}from"#shared/input.js";function createChannelOperations(e){let t=createChannelAddressFn(e);return{from(e){let n=t(e);return{async send(e,t){return await n.deliver(attachInputText({context:t.context,message:e,outputSchema:t.outputSchema,state:t.state},readInputText(t)),t)},async respond(e,t){if(e.length===0)throw Error(`respond() requires at least one input response.`);let r=parseInputResponses(e);return await n.deliver({context:t.context,inputResponses:r,state:t.state},t)},async cancel(e){return await n.cancel(e)},async compact(){return await n.compact()},async clear(){return await n.clear()},async reset(e){return await n.reset(e)}}},async resolveSession(e){return await t(e).resolveSession()}}}export{createChannelOperations};
1
+ import{attachInputText,readInputText}from"#internal/input-text.js";import{createChannelAddressFn}from"#channel/channel-address.js";import{parseInputResponses}from"#shared/input.js";function createChannelOperations(e){let t=createChannelAddressFn(e);return{from(e){let n=t(e);return{async send(e,t){return await n.deliver(attachInputText({context:t.context,history:t.history,message:e,outputSchema:t.outputSchema,state:t.state},readInputText(t)),t)},async create(e){return await n.create(e)},async respond(e,t){if(e.length===0)throw Error(`respond() requires at least one input response.`);let r=parseInputResponses(e);return await n.deliver({context:t.context,inputResponses:r,state:t.state},t)},async cancel(e){return await n.cancel(e)},async compact(){return await n.compact()},async clear(){return await n.clear()},async reset(e){return await n.reset(e)}}},async resolveSession(e){return await t(e).resolveSession()}}}export{createChannelOperations};
@@ -0,0 +1,4 @@
1
+ /** Maximum number of distinct delivery keys remembered by one logical session. */
2
+ export declare const DELIVERY_IDEMPOTENCY_WINDOW = 1024;
3
+ export declare const MAX_DELIVERY_IDEMPOTENCY_KEY_LENGTH = 256;
4
+ export declare function validateDeliveryIdempotencyKey(key: unknown): asserts key is string | undefined;
@@ -0,0 +1 @@
1
+ const DELIVERY_IDEMPOTENCY_WINDOW=1024,MAX_DELIVERY_IDEMPOTENCY_KEY_LENGTH=256;function validateDeliveryIdempotencyKey(e){if(e!==void 0&&(typeof e!=`string`||e.length===0||e.length>256))throw Error(`idempotencyKey must be a nonempty string of at most 256 characters.`)}export{DELIVERY_IDEMPOTENCY_WINDOW,MAX_DELIVERY_IDEMPOTENCY_KEY_LENGTH,validateDeliveryIdempotencyKey};
@@ -5,6 +5,7 @@ import type { InvokeToolFn } from "#channel/invoke-tool.js";
5
5
  import type { InputResponse } from "#shared/input.js";
6
6
  import type { Session } from "#channel/session.js";
7
7
  import type { JsonObject } from "#shared/json.js";
8
+ import type { SessionHistoryMessage } from "#shared/session-history.js";
8
9
  import type { ChannelMethod } from "#public/definitions/channel.js";
9
10
  import type { AgentDescription, AgentSkillFileDescription } from "#channel/agent-description.js";
10
11
  type WebSocketHeaders = Headers | readonly (readonly [string, string])[] | Record<string, string>;
@@ -65,6 +66,11 @@ export interface SendPayload {
65
66
  * message and persists it across the session.
66
67
  */
67
68
  readonly context?: readonly string[];
69
+ /**
70
+ * Prior conversation added as user and assistant turns before this
71
+ * delivery's `context` and message.
72
+ */
73
+ readonly history?: readonly SessionHistoryMessage[];
68
74
  /**
69
75
  * Run-scoped JSON schema the turn's result must match.
70
76
  */
@@ -6,6 +6,7 @@ import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, GetEve
6
6
  import type { SessionAuth } from "#context/keys.js";
7
7
  import { type InputResponse, type StrictInputResponses } from "#shared/input.js";
8
8
  import type { JsonObject } from "#shared/json.js";
9
+ import { type SessionHistoryMessage } from "#shared/session-history.js";
9
10
  /** Immutable-ID handle for one exact durable session. */
10
11
  export interface Session {
11
12
  readonly id: string;
@@ -38,6 +39,8 @@ export interface Session {
38
39
  getStreamTailIndex(): Promise<number>;
39
40
  }
40
41
  interface SessionDeliveryOptions {
42
+ /** Stable delivery identity, deduplicated within this session's recent-key window. */
43
+ readonly idempotencyKey?: string;
41
44
  readonly auth: SessionAuthContext | null;
42
45
  /** Public callback destination for a delegated continuation turn. */
43
46
  readonly callback?: SessionCallback;
@@ -46,6 +49,8 @@ interface SessionDeliveryOptions {
46
49
  }
47
50
  /** Options for sending a message through a fixed session handle. */
48
51
  export type SessionSendOptions = SessionDeliveryOptions & {
52
+ /** Prior conversation added as user and assistant turns before this message and its `context`. */
53
+ readonly history?: readonly SessionHistoryMessage[];
49
54
  /** Initial workflow title for a prewarmed session. */
50
55
  readonly title?: string;
51
56
  readonly turnPolicy?: TurnPolicy;
@@ -1 +1 @@
1
- import{attachClientContext,readClientContext}from"#internal/client-context.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{serializeFilePartsInMessage}from"#channel/send-input.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{parseInputResponses}from"#shared/input.js";import{AuthKey,ContinuationHookTokensKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";function createSession(e,t,n={}){return{id:e,async send(r,i){let a=createDelivery(n),o=sessionCallbackToTurnCaller(i.callback),s=attachClientContext({message:serializeFilePartsInMessage(r)},readClientContext(i));i.context!==void 0&&(s.context=i.context),i.outputSchema!==void 0&&(s.outputSchema=i.outputSchema);let c={auth:i.auth,delivery:a,kind:`send`,payload:s,requestId:n.requestId,turnPolicy:i.turnPolicy??n.turnPolicy??DEFAULT_TURN_POLICY,title:i.title};return await t.dispatchSession({command:o===void 0?c:{...c,caller:o},sessionId:e})},async respond(r,i){if(r.length===0)throw Error(`respond() requires at least one input response.`);let a=parseInputResponses(r),o=sessionCallbackToTurnCaller(i.callback),s=createDelivery(n),c=attachClientContext({inputResponses:a},readClientContext(i));i.context!==void 0&&(c.context=i.context),i.outputSchema!==void 0&&(c.outputSchema=i.outputSchema);let l={auth:i.auth,delivery:s,kind:`send`,payload:c,requestId:n.requestId};return await t.dispatchSession({command:o===void 0?l:{...l,caller:o},sessionId:e})},async cancel(n){let r={kind:`cancel`};return n?.turnId!==void 0&&(r.turnId=n.turnId),await t.dispatchSession({command:r,sessionId:e})},async compact(){return await t.dispatchSession({command:{kind:`compact`},sessionId:e})},async clear(){return await t.dispatchSession({command:{kind:`clear`},sessionId:e})},async reset(n){return await t.dispatchSession({command:{kind:`reset`,reason:n?.reason},sessionId:e})},async getEventStream(n){return t.getEventStream(e,n)},async getStreamTailIndex(){return t.getStreamTailIndex(e)}}}function createAttachSessionFn(e,t={}){return n=>createSession(n,e,t)}function createDelivery(e){return e.channelKind!==void 0&&e.channelName!==void 0?createChannelDeliveryMetadata(e):void 0}function buildSessionHandle(e){return{get id(){return e.get(SessionIdKey)??``},get auth(){return{current:e.get(AuthKey)??null,initiator:e.get(InitiatorAuthKey)??null}},get continuation(){let t=e.get(ContinuationTokenKey);if(t!==void 0&&t.length!==0)return{token:toChannelLocalContinuationToken(t),alias(n){if(n.length===0)throw Error(`A session alias requires a nonempty token.`);let r=namespaceContinuationToken(t,n);t!==r&&(e.set(ContinuationHookTokensKey,e=>{let n=e??[t];return n.includes(r)?n:[...n,r]}),e.set(ContinuationTokenKey,r))}}}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}function sessionCallbackToTurnCaller(e){return e===void 0?void 0:{callId:e.callId,replyTo:{kind:`callback`,token:e.token,url:e.url},subagentName:e.subagentName}}export{buildSessionHandle,createAttachSessionFn,createSession,sessionCallbackToTurnCaller};
1
+ import{attachClientContext,readClientContext}from"#internal/client-context.js";import{validateDeliveryIdempotencyKey}from"#channel/delivery-idempotency.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{serializeFilePartsInMessage}from"#channel/send-input.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{validateSessionHistory}from"#shared/session-history.js";import{parseInputResponses}from"#shared/input.js";import{AuthKey,ContinuationHookTokensKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";function createSession(e,t,n={}){return{id:e,async send(r,i){validateDeliveryIdempotencyKey(i.idempotencyKey);let a=createDelivery(n),o=sessionCallbackToTurnCaller(i.callback),s=validateSessionHistory(i.history),c=attachClientContext({message:serializeFilePartsInMessage(r)},readClientContext(i));i.context!==void 0&&(c.context=i.context),s!==void 0&&(c.history=s),i.outputSchema!==void 0&&(c.outputSchema=i.outputSchema);let l={idempotencyKey:i.idempotencyKey,auth:i.auth,delivery:a,kind:`send`,payload:c,requestId:n.requestId,turnPolicy:i.turnPolicy??n.turnPolicy??DEFAULT_TURN_POLICY,title:i.title};return await t.dispatchSession({command:o===void 0?l:{...l,caller:o},sessionId:e})},async respond(r,i){if(validateDeliveryIdempotencyKey(i.idempotencyKey),r.length===0)throw Error(`respond() requires at least one input response.`);let a=parseInputResponses(r),o=sessionCallbackToTurnCaller(i.callback),s=createDelivery(n),c=attachClientContext({inputResponses:a},readClientContext(i));i.context!==void 0&&(c.context=i.context),i.outputSchema!==void 0&&(c.outputSchema=i.outputSchema);let l={idempotencyKey:i.idempotencyKey,auth:i.auth,delivery:s,kind:`send`,payload:c,requestId:n.requestId};return await t.dispatchSession({command:o===void 0?l:{...l,caller:o},sessionId:e})},async cancel(n){let r={kind:`cancel`};return n?.turnId!==void 0&&(r.turnId=n.turnId),await t.dispatchSession({command:r,sessionId:e})},async compact(){return await t.dispatchSession({command:{kind:`compact`},sessionId:e})},async clear(){return await t.dispatchSession({command:{kind:`clear`},sessionId:e})},async reset(n){return await t.dispatchSession({command:{kind:`reset`,reason:n?.reason},sessionId:e})},async getEventStream(n){return t.getEventStream(e,n)},async getStreamTailIndex(){return t.getStreamTailIndex(e)}}}function createAttachSessionFn(e,t={}){return n=>createSession(n,e,t)}function createDelivery(e){return e.channelKind!==void 0&&e.channelName!==void 0?createChannelDeliveryMetadata(e):void 0}function buildSessionHandle(e){return{get id(){return e.get(SessionIdKey)??``},get auth(){return{current:e.get(AuthKey)??null,initiator:e.get(InitiatorAuthKey)??null}},get continuation(){let t=e.get(ContinuationTokenKey);if(t!==void 0&&t.length!==0)return{token:toChannelLocalContinuationToken(t),alias(n){if(n.length===0)throw Error(`A session alias requires a nonempty token.`);let r=namespaceContinuationToken(t,n);t!==r&&(e.set(ContinuationHookTokensKey,e=>{let n=e??[t];return n.includes(r)?n:[...n,r]}),e.set(ContinuationTokenKey,r))}}}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}function sessionCallbackToTurnCaller(e){return e===void 0?void 0:{callId:e.callId,replyTo:{kind:`callback`,token:e.token,url:e.url},subagentName:e.subagentName}}export{buildSessionHandle,createAttachSessionFn,createSession,sessionCallbackToTurnCaller};
@@ -6,8 +6,8 @@ import type { CancelTurnResult as ProtocolCancelTurnResult } from "#protocol/can
6
6
  import type { RuntimeSubagentChildResult, RuntimeSubagentDispatchFailure, RuntimeToolResultActionResult } from "#shared/action-types.js";
7
7
  import type { InputRequest, InputResponse } from "#shared/input.js";
8
8
  import type { ChannelAdapter } from "#channel/adapter.js";
9
- import type { AgentLimitsDefinition } from "#shared/agent-definition.js";
10
9
  import type { JsonObject } from "#shared/json.js";
10
+ import type { SessionHistoryMessage } from "#shared/session-history.js";
11
11
  import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
12
12
  import type { ForwardedTraceAssertion } from "#shared/forwarded-trace-policy.js";
13
13
  import type { ConversationContext } from "#shared/conversation-context.js";
@@ -15,7 +15,6 @@ import type { StubScope } from "#tool-stubs/types.js";
15
15
  export type { ContextAccessor } from "#context/key.js";
16
16
  export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
17
17
  import type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
18
- export type RunSessionLimits = Pick<AgentLimitsDefinition, "maxInputTokensPerSession" | "maxOutputTokensPerSession" | "maxTokenCostUsdPerSession">;
19
18
  /** Identifies the session turn to cancel. */
20
19
  export interface CancelTurnInput {
21
20
  readonly sessionId: string;
@@ -155,6 +154,8 @@ export interface DeliverPayload {
155
154
  readonly inputResponses?: readonly InputResponse[];
156
155
  readonly message?: string | UserContent;
157
156
  readonly context?: readonly string[];
157
+ /** Prior conversation added as user and assistant turns before this delivery's input. */
158
+ readonly history?: readonly SessionHistoryMessage[];
158
159
  readonly outputSchema?: JsonObject;
159
160
  readonly [key: string]: unknown;
160
161
  }
@@ -164,6 +165,7 @@ export type TurnPolicy = "steer" | "queue";
164
165
  export declare const DEFAULT_TURN_POLICY: TurnPolicy;
165
166
  /** One command accepted by a durable session inbox. */
166
167
  export type SessionCommand = {
168
+ readonly idempotencyKey?: string;
167
169
  readonly auth?: SessionAuthContext | null;
168
170
  readonly caller?: TurnCaller;
169
171
  /** Initial workflow title when delivering to a prewarmed session. */
@@ -230,6 +232,7 @@ export interface DispatchSessionInput<TCommand extends SessionCommand = SessionC
230
232
  * metadata so both cross the durable hook boundary outside adapter-owned data.
231
233
  */
232
234
  export interface DeliverHookPayload {
235
+ readonly idempotencyKey?: string;
233
236
  readonly schedule?: import("#context/session-schedule.js").SessionSchedule;
234
237
  /** Initial workflow title; ignored once session initialization has run. */
235
238
  readonly title?: string;
@@ -371,6 +374,8 @@ export interface SessionCapabilities {
371
374
  * subagent tool wrapper).
372
375
  */
373
376
  export interface RunInput {
377
+ /** Optional stable identity of the initial delivery, scoped to this logical session. */
378
+ readonly idempotencyKey?: string;
374
379
  /**
375
380
  * @internal Set by the server after it authorizes tool stubs.
376
381
  * Local subagents match rules qualified by their full path, such as researcher/list_tasks.
@@ -456,6 +461,8 @@ export interface RunInput {
456
461
  /** Omitted only when creating a conversation session before its first turn. */
457
462
  readonly message?: string | UserContent;
458
463
  readonly context?: readonly string[];
464
+ /** Prior conversation; with no message, it waits for the first message's turn. */
465
+ readonly history?: readonly SessionHistoryMessage[];
459
466
  readonly outputSchema?: JsonObject;
460
467
  /** Channel payload state for the first delivery, as later deliveries carry it. */
461
468
  readonly state?: unknown;
@@ -470,13 +477,6 @@ export interface RunInput {
470
477
  * because trace state is scoped to one session's context.
471
478
  */
472
479
  readonly parentTraceContext?: SessionTraceContext;
473
- /**
474
- * Runtime-supplied session limits. Delegated local subagents use this to
475
- * carry the parent's remaining quota and delegation caps with the same limit
476
- * fields authors configure on agents; `false` means no inherited token cap
477
- * for that axis.
478
- */
479
- readonly limits?: RunSessionLimits;
480
480
  /** Framework-owned metadata for a protocol-neutral external invocation. */
481
481
  readonly externalInvocation?: {
482
482
  readonly continuationToken: string;
@@ -551,9 +551,12 @@ export interface Runtime {
551
551
  /**
552
552
  * Resolves the session that currently owns a continuation token without
553
553
  * delivering input or starting a run. Returns `undefined` when no session
554
- * owns the token.
554
+ * owns the token. With `runnable`, throws `SessionStrandedError` when the
555
+ * owner is stranded and can run nothing.
555
556
  */
556
- resolveContinuation(continuationToken: string): Promise<{
557
+ resolveContinuation(continuationToken: string, options?: {
558
+ readonly runnable?: boolean;
559
+ }): Promise<{
557
560
  sessionId: string;
558
561
  } | undefined>;
559
562
  /**
@@ -3506,6 +3506,7 @@ function reduceContent(data, event) {
3506
3506
  parts: projectReceivedParts(event.data.parts, event.data.message),
3507
3507
  role: "user"
3508
3508
  }, event.data.turnId);
3509
+ case "history.imported": return importHistory(data, event);
3509
3510
  case "step.started": return updateAssistantMessage(data, event.data.turnId, (message) => ensureStepStartPart(message, event.data.stepIndex));
3510
3511
  case "step.completed":
3511
3512
  if (data.messages.find((message) => message.role === "assistant" && message.metadata?.turnId === event.data.turnId) === void 0) return data;
@@ -3698,6 +3699,41 @@ function reduceContent(data, event) {
3698
3699
  default: return data;
3699
3700
  }
3700
3701
  }
3702
+ function importHistory(data, event) {
3703
+ const eventId = event.meta.id ?? `${event.data.turnId}:${event.data.sequence}`;
3704
+ const imported = event.data.messages.map((message, index) => ({
3705
+ id: `${eventId}:imported:${index}`,
3706
+ metadata: message.id === void 0 ? {
3707
+ imported: true,
3708
+ status: "complete"
3709
+ } : {
3710
+ historyId: message.id,
3711
+ imported: true,
3712
+ status: "complete"
3713
+ },
3714
+ parts: [message.role === "assistant" ? {
3715
+ state: "done",
3716
+ text: message.text,
3717
+ type: "text"
3718
+ } : {
3719
+ text: message.text,
3720
+ type: "text"
3721
+ }],
3722
+ role: message.role
3723
+ }));
3724
+ const ids = new Set(imported.map((message) => message.id));
3725
+ const messages = data.messages.filter((message) => !ids.has(message.id));
3726
+ const before = messages.findIndex((message) => message.metadata?.optimistic === true || message.role === "assistant" && message.metadata?.turnId === event.data.turnId);
3727
+ const at = before === -1 ? messages.length : before;
3728
+ return {
3729
+ ...data,
3730
+ messages: [
3731
+ ...messages.slice(0, at),
3732
+ ...imported,
3733
+ ...messages.slice(at)
3734
+ ]
3735
+ };
3736
+ }
3701
3737
  function toolCallIds(data, event) {
3702
3738
  const byRequest = (requestId) => findToolPartByApprovalId(data, requestId)?.toolCallId ?? [];
3703
3739
  switch (event.type) {
@@ -3507,6 +3507,7 @@ function reduceContent(data, event) {
3507
3507
  parts: projectReceivedParts(event.data.parts, event.data.message),
3508
3508
  role: "user"
3509
3509
  }, event.data.turnId);
3510
+ case "history.imported": return importHistory(data, event);
3510
3511
  case "step.started": return updateAssistantMessage(data, event.data.turnId, (message) => ensureStepStartPart(message, event.data.stepIndex));
3511
3512
  case "step.completed":
3512
3513
  if (data.messages.find((message) => message.role === "assistant" && message.metadata?.turnId === event.data.turnId) === void 0) return data;
@@ -3699,6 +3700,41 @@ function reduceContent(data, event) {
3699
3700
  default: return data;
3700
3701
  }
3701
3702
  }
3703
+ function importHistory(data, event) {
3704
+ const eventId = event.meta.id ?? `${event.data.turnId}:${event.data.sequence}`;
3705
+ const imported = event.data.messages.map((message, index) => ({
3706
+ id: `${eventId}:imported:${index}`,
3707
+ metadata: message.id === void 0 ? {
3708
+ imported: true,
3709
+ status: "complete"
3710
+ } : {
3711
+ historyId: message.id,
3712
+ imported: true,
3713
+ status: "complete"
3714
+ },
3715
+ parts: [message.role === "assistant" ? {
3716
+ state: "done",
3717
+ text: message.text,
3718
+ type: "text"
3719
+ } : {
3720
+ text: message.text,
3721
+ type: "text"
3722
+ }],
3723
+ role: message.role
3724
+ }));
3725
+ const ids = new Set(imported.map((message) => message.id));
3726
+ const messages = data.messages.filter((message) => !ids.has(message.id));
3727
+ const before = messages.findIndex((message) => message.metadata?.optimistic === true || message.role === "assistant" && message.metadata?.turnId === event.data.turnId);
3728
+ const at = before === -1 ? messages.length : before;
3729
+ return {
3730
+ ...data,
3731
+ messages: [
3732
+ ...messages.slice(0, at),
3733
+ ...imported,
3734
+ ...messages.slice(at)
3735
+ ]
3736
+ };
3737
+ }
3702
3738
  function toolCallIds(data, event) {
3703
3739
  const byRequest = (requestId) => findToolPartByApprovalId(data, requestId)?.toolCallId ?? [];
3704
3740
  switch (event.type) {
@@ -23,4 +23,5 @@ export interface DevelopmentCliOptions {
23
23
  export interface ProductionCliOptions {
24
24
  host?: string;
25
25
  port?: number;
26
+ schedules?: boolean;
26
27
  }
@@ -1 +1 @@
1
- import{access,readdir,stat,writeFile}from"node:fs/promises";import{constants}from"node:fs";import{delimiter,join,relative,sep}from"node:path";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{LOCAL_WORKFLOW_WORLD_DATA_DIRECTORY_RELATIVE_PATH}from"#internal/workflow/local-world-data-directory.js";import{captureVercel,resolveVercelInvocation}from"#setup/primitives/run-vercel.js";function createDevDiagnosticDump(e,t,n={}){let r=t.replace(/\.log$/,`.dump`),i=n.now??(()=>new Date),a=i().getTime(),o,s,c=Promise.resolve(),l=!1,u=!1,write=()=>{if(u||l)return;let e=formatDump({at:i(),durationMs:i().getTime()-a,environment:o,stats:s});c=c.then(()=>writeFile(r,e,{encoding:`utf8`,mode:384})).catch(()=>{l=!0})};return write(),(n.environment??(()=>collectDevEnvironmentInfo(e)))().then(e=>{o=e,write()}).catch(()=>{}),{path:r,displayPath:relative(e,r).split(sep).join(`/`),updateSessionStats(e){s=e,write()},async close(){u||(write(),u=!0,await c)}}}function formatDump(e){let t={updatedAt:e.at.toISOString(),durationMs:e.durationMs,environment:e.environment??null,session:e.stats??null};return`${JSON.stringify(t,null,2)}\n`}async function collectDevEnvironmentInfo(e){let[t,n]=await Promise.all([detectVercelCli(e),measureSessionsDirectory(e)]),r={eveVersion:resolveInstalledPackageInfo().version,nodeVersion:process.version,platform:`${process.platform} ${process.arch}`,...t};return n!==void 0&&(r.sessionsDirectory=n),r}async function detectVercelCli(e){let t=resolveVercelInvocation(e),[n,r]=await Promise.all([captureVercel([`--version`],{cwd:e,nonInteractive:!0,timeoutMs:5e3}),t.command===`vercel`?findOnPath(`vercel`):Promise.resolve(t.command)]),i=n.ok?n.stdout:`${n.failure.stdout}\n${n.failure.stderr}`,a=/(\d+\.\d+\.\d+\S*)/.exec(i)?.[1],o={};return a!==void 0&&(o.vercelCliVersion=a),r!==void 0&&(o.vercelCliPath=r),o}async function findOnPath(e){let t=(process.env.PATH??``).split(delimiter).filter(e=>e.length>0);for(let n of t){let t=join(n,e);try{return await access(t,constants.X_OK),t}catch{}}}async function measureSessionsDirectory(e){let t=join(e,LOCAL_WORKFLOW_WORLD_DATA_DIRECTORY_RELATIVE_PATH),n;try{n=await readdir(t,{recursive:!0,withFileTypes:!0})}catch{return}let r=0,i=0;for(let e of n)if(e.isFile()){r+=1;try{i+=(await stat(join(e.parentPath,e.name))).size}catch{}}return{path:LOCAL_WORKFLOW_WORLD_DATA_DIRECTORY_RELATIVE_PATH,files:r,bytes:i}}export{createDevDiagnosticDump,measureSessionsDirectory};
1
+ import{access,readdir,stat,writeFile}from"node:fs/promises";import{constants}from"node:fs";import{delimiter,join,relative,sep}from"node:path";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{displayLocalWorkflowWorldDataDirectory,resolveLocalWorkflowWorldDataDirectory}from"#internal/workflow/local-world-data-directory.js";import{captureVercel,resolveVercelInvocation}from"#setup/primitives/run-vercel.js";function createDevDiagnosticDump(e,t,n={}){let r=t.replace(/\.log$/,`.dump`),i=n.now??(()=>new Date),a=i().getTime(),o,s,c=Promise.resolve(),l=!1,u=!1,write=()=>{if(u||l)return;let e=formatDump({at:i(),durationMs:i().getTime()-a,environment:o,stats:s});c=c.then(()=>writeFile(r,e,{encoding:`utf8`,mode:384})).catch(()=>{l=!0})};return write(),(n.environment??(()=>collectDevEnvironmentInfo(e)))().then(e=>{o=e,write()}).catch(()=>{}),{path:r,displayPath:relative(e,r).split(sep).join(`/`),updateSessionStats(e){s=e,write()},async close(){u||(write(),u=!0,await c)}}}function formatDump(e){let t={updatedAt:e.at.toISOString(),durationMs:e.durationMs,environment:e.environment??null,session:e.stats??null};return`${JSON.stringify(t,null,2)}\n`}async function collectDevEnvironmentInfo(e){let[t,n]=await Promise.all([detectVercelCli(e),measureSessionsDirectory(e)]),r={eveVersion:resolveInstalledPackageInfo().version,nodeVersion:process.version,platform:`${process.platform} ${process.arch}`,...t};return n!==void 0&&(r.sessionsDirectory=n),r}async function detectVercelCli(e){let t=resolveVercelInvocation(e),[n,r]=await Promise.all([captureVercel([`--version`],{cwd:e,nonInteractive:!0,timeoutMs:5e3}),t.command===`vercel`?findOnPath(`vercel`):Promise.resolve(t.command)]),i=n.ok?n.stdout:`${n.failure.stdout}\n${n.failure.stderr}`,a=/(\d+\.\d+\.\d+\S*)/.exec(i)?.[1],o={};return a!==void 0&&(o.vercelCliVersion=a),r!==void 0&&(o.vercelCliPath=r),o}async function findOnPath(e){let t=(process.env.PATH??``).split(delimiter).filter(e=>e.length>0);for(let n of t){let t=join(n,e);try{return await access(t,constants.X_OK),t}catch{}}}async function measureSessionsDirectory(e){let t=resolveLocalWorkflowWorldDataDirectory(e),n;try{n=await readdir(t,{recursive:!0,withFileTypes:!0})}catch{return}let r=0,i=0;for(let e of n)if(e.isFile()){r+=1;try{i+=(await stat(join(e.parentPath,e.name))).size}catch{}}return{path:displayLocalWorkflowWorldDataDirectory(e),files:r,bytes:i}}export{createDevDiagnosticDump,measureSessionsDirectory};
@@ -31,6 +31,7 @@ interface CliRuntimeDependencies {
31
31
  startProductionHost(appRoot: string, options?: {
32
32
  host?: string;
33
33
  port?: number;
34
+ schedules?: boolean;
34
35
  }): Promise<ProductionServerHandle>;
35
36
  }
36
37
  type CliRuntimeOverrides = Partial<CliRuntimeDependencies>;
@@ -1,2 +1,2 @@
1
- import{Command,CommanderError}from"#compiled/commander/index.js";import{agentCommand}from"#cli/agent-command.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";import{waitForShutdownSignal}from"#cli/shutdown.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{findEveProjectContext,resolveEveProjectContext}from"#internal/project-context.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{findCliApplicationRoot,resolveCliApplicationProject}from"#cli/application-root.js";import{registerIntegrationCommands}from"#cli/commands/register-integration-commands.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{registerRegistryCommands}from"#cli/commands/register-registry-commands.js";import{registerDevelopmentCommand,registerRemoteCommands}from"#cli/dev/command.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{registerAcpCommand}from"#cli/acp/command.js";import{registerRuntimeInvokeCommand}from"#cli/invoke/command.js";import{parseAgentNamesOption,parsePortOption,parseReasoningOption}from"#cli/option-parsers.js";import{registerEveTelemetryCommands}from"#cli/telemetry/command.js";import{canonicalCommand,createEveCliTelemetry}from"#cli/telemetry/index.js";async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function createCliProgram(e,t,n,r){let i=resolveInstalledPackageInfo().version,a=new Command,o=createCliTheme();a.name(`eve`).description(`Build and run an eve application.`).version(i).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{let{json:r}=n.opts();!r&&(n.name()===`info`||n.name()===`init`&&n.parent!==a)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}}),registerEveTelemetryCommands(a,e),registerIntegrationCommands({program:a,logger:e,applicationContext:n});let s=a.command(`extension`).description(`Create and build reusable eve extension packages.`);s.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:a}=await import(`#cli/commands/extension-init.js`);await a(e,n.root,t,void 0,e=>{r.trackSetupStep({flow:`extension_init`,step:e})})}),s.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);await t(n.root);let{runExtensionBuildCommand:r}=await import(`#cli/commands/extension-build.js`);await r(e,n.root)}),registerRegistryCommands({program:a,logger:e,applicationContext:n}),a.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`--agents <names>`,`Create an agents/ workspace with comma-separated agent names`,parseAgentNamesOption).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`-n, --non-interactive`,`Scaffold the agent without starting development`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:a}=await import(`#cli/commands/init.js`);await a(e,n.root,t,{agents:i.agents,channelWebNextjs:i.channelWebNextjs,model:i.model,reasoning:i.reasoning,nonInteractive:i.nonInteractive},void 0,e=>{r.trackSetupStep({flow:`init`,step:e})},(e,t,n)=>{r.trackSetupTerminal({flow:`init`,step:e,result:t,failureCode:n})})});let c=a.command(`set`).description(`Change root agent model settings.`);agentCommand(c.command(`model [model]`),n).description(`Set the agent model and reasoning effort.`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).action(async(t,r)=>{let{runSetCommand:i}=await import(`#cli/commands/set.js`);await i(e,n.root,{model:t,reasoning:r.reasoning})}),registerProjectCommands({program:a,logger:e,applicationContext:n}),registerBuildCommand({applicationContext:n,buildHost:t.buildHost,logger:e,program:a}),agentCommand(a.command(`start`),n).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async r=>{let{loadDevelopmentEnvironmentFiles:i}=await import(`#cli/dev/environment.js`);await i(n.root);let a=await(t.startProductionHost??await loadStartProductionHost())(n.root,{host:r.host,port:r.port});e.log(renderCliTaggedLine(o,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForShutdownSignal({close:()=>a.close(),wait:()=>a.wait()})});let l=a.command(`remote`).description(`Connect to an existing eve agent.`);registerRemoteCommands({applicationContext:n,logger:e,program:l,runtime:t,telemetry:r}),registerRuntimeInvokeCommand({applicationContext:n,logger:e,program:l,runtime:t}),registerAcpCommand({applicationContext:n,eveVersion:i,program:a,resolveVerifiedRemoteDevelopmentClient:t.resolveVerifiedRemoteDevelopmentClient,runAcpServer:t.runAcpServer,startHost:t.startHost}),registerDevelopmentCommand({applicationContext:n,logger:e,program:a,runtime:t,telemetry:r});let u=a.command(`logs`).description("Inspect local `eve dev` diagnostic logs (.eve/logs).");agentCommand(u.command(`show [logid]`,{isDefault:!0}),n).description(`Print a diagnostic log (the most recent when logid is omitted).`).option(`--dump`,`Prepend the log's environment dump (.dump sibling)`).option(`--events`,`Interleave session events from the local workflow store`).action(async(t,r)=>{let{runLogsShowCommand:i}=await import(`#cli/commands/logs.js`);await i(e,n.root,t,r)}),agentCommand(u.command(`list`).alias(`ls`),n).description(`List diagnostic logs, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runLogsListCommand:r}=await import(`#cli/commands/logs.js`);await r(e,n.root,t)});let d=a.command(`traces`).usage(`[options] [trace]
1
+ import{Command,CommanderError}from"#compiled/commander/index.js";import{agentCommand}from"#cli/agent-command.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";import{waitForShutdownSignal}from"#cli/shutdown.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{findEveProjectContext,resolveEveProjectContext}from"#internal/project-context.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{areSchedulesDisabled}from"#internal/schedules/disabled.js";import{findCliApplicationRoot,resolveCliApplicationProject}from"#cli/application-root.js";import{registerIntegrationCommands}from"#cli/commands/register-integration-commands.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{registerRegistryCommands}from"#cli/commands/register-registry-commands.js";import{registerDevelopmentCommand,registerRemoteCommands}from"#cli/dev/command.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{registerAcpCommand}from"#cli/acp/command.js";import{registerRuntimeInvokeCommand}from"#cli/invoke/command.js";import{parseAgentNamesOption,parsePortOption,parseReasoningOption}from"#cli/option-parsers.js";import{registerEveTelemetryCommands}from"#cli/telemetry/command.js";import{canonicalCommand,createEveCliTelemetry}from"#cli/telemetry/index.js";async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function createCliProgram(e,t,n,r){let i=resolveInstalledPackageInfo().version,a=new Command,o=createCliTheme();a.name(`eve`).description(`Build and run an eve application.`).version(i).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{let{json:r}=n.opts();!r&&(n.name()===`info`||n.name()===`init`&&n.parent!==a)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}}),registerEveTelemetryCommands(a,e),registerIntegrationCommands({program:a,logger:e,applicationContext:n});let s=a.command(`extension`).description(`Create and build reusable eve extension packages.`);s.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:a}=await import(`#cli/commands/extension-init.js`);await a(e,n.root,t,void 0,e=>{r.trackSetupStep({flow:`extension_init`,step:e})})}),s.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);await t(n.root);let{runExtensionBuildCommand:r}=await import(`#cli/commands/extension-build.js`);await r(e,n.root)}),registerRegistryCommands({program:a,logger:e,applicationContext:n}),a.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`--agents <names>`,`Create an agents/ workspace with comma-separated agent names`,parseAgentNamesOption).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`-n, --non-interactive`,`Scaffold the agent without starting development`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:a}=await import(`#cli/commands/init.js`);await a(e,n.root,t,{agents:i.agents,channelWebNextjs:i.channelWebNextjs,model:i.model,reasoning:i.reasoning,nonInteractive:i.nonInteractive},void 0,e=>{r.trackSetupStep({flow:`init`,step:e})},(e,t,n)=>{r.trackSetupTerminal({flow:`init`,step:e,result:t,failureCode:n})})});let c=a.command(`set`).description(`Change root agent model settings.`);agentCommand(c.command(`model [model]`),n).description(`Set the agent model and reasoning effort.`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).action(async(t,r)=>{let{runSetCommand:i}=await import(`#cli/commands/set.js`);await i(e,n.root,{model:t,reasoning:r.reasoning})}),registerProjectCommands({program:a,logger:e,applicationContext:n}),registerBuildCommand({applicationContext:n,buildHost:t.buildHost,logger:e,program:a}),agentCommand(a.command(`start`),n).description(`Start a built eve application.`).option(`--no-schedules`,`Start without running authored cron schedules`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async r=>{let{loadDevelopmentEnvironmentFiles:i}=await import(`#cli/dev/environment.js`);await i(n.root);let a=await(t.startProductionHost??await loadStartProductionHost())(n.root,{host:r.host,port:r.port,schedules:r.schedules});e.log(renderCliTaggedLine(o,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),(r.schedules===!1||areSchedulesDisabled())&&e.log(renderCliTaggedLine(o,{message:`schedules disabled`,tag:`start`,tone:`info`})),await waitForShutdownSignal({close:()=>a.close(),wait:()=>a.wait()})});let l=a.command(`remote`).description(`Connect to an existing eve agent.`);registerRemoteCommands({applicationContext:n,logger:e,program:l,runtime:t,telemetry:r}),registerRuntimeInvokeCommand({applicationContext:n,logger:e,program:l,runtime:t}),registerAcpCommand({applicationContext:n,eveVersion:i,program:a,resolveVerifiedRemoteDevelopmentClient:t.resolveVerifiedRemoteDevelopmentClient,runAcpServer:t.runAcpServer,startHost:t.startHost}),registerDevelopmentCommand({applicationContext:n,logger:e,program:a,runtime:t,telemetry:r});let u=a.command(`logs`).description("Inspect local `eve dev` diagnostic logs (.eve/logs).");agentCommand(u.command(`show [logid]`,{isDefault:!0}),n).description(`Print a diagnostic log (the most recent when logid is omitted).`).option(`--dump`,`Prepend the log's environment dump (.dump sibling)`).option(`--events`,`Interleave session events from the local workflow store`).action(async(t,r)=>{let{runLogsShowCommand:i}=await import(`#cli/commands/logs.js`);await i(e,n.root,t,r)}),agentCommand(u.command(`list`).alias(`ls`),n).description(`List diagnostic logs, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runLogsListCommand:r}=await import(`#cli/commands/logs.js`);await r(e,n.root,t)});let d=a.command(`traces`).usage(`[options] [trace]
2
2
  eve traces list [options]`).description("Inspect local `eve dev` traces.");return agentCommand(d.command(`show [trace]`,{isDefault:!0}),n).description(`Show a local trace (the most recent when trace is omitted).`).option(`--verbose`,`Expand every span with all attributes and events`).option(`--json`,`Output as JSON`).action(async(t,r)=>{let{runTraceShowCommand:i}=await import(`#cli/commands/trace.js`);await i(e,n.root,t,r)}),agentCommand(d.command(`list`).alias(`ls`),n).description(`List local traces, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runTraceListCommand:r}=await import(`#cli/commands/trace.js`);await r(e,n.root,t)}),agentCommand(a.command(`info`),n).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async r=>{await(t.printApplicationInfo??await loadPrintApplicationInfo())(e,n.root,r)}),agentCommand(a.command(`eval`),n,e=>e.opts().url===void 0).description(`Run evals against an eve agent.`).argument(`[evalIds...]`,`Eval ids (or directory prefixes) to run (all discovered evals when omitted)`).option(`--url <url>`,`Remote agent URL (skip local host startup)`,parseDevelopmentServerUrl).option(`--tag <tag...>`,`Run only evals carrying a tag`).option(`--exclude-tag <tag...>`,`Skip evals carrying a tag`).option(`--strict`,`Fail the exit code when any score falls below its threshold`).option(`--list`,`Print discovered evals without running them`).option(`--timeout <ms>`,`Per-eval timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent eval executions`).option(`--json`,`Output results as JSON`).option(`--junit <path>`,`Write JUnit XML results to a file`).option(`--skip-report`,`Skip eval-defined reporters (e.g. Braintrust)`).option(`--verbose`,`Stream per-eval logs and workflow run IDs to stdout`).action(async(r,i)=>{await(t.runEvalCommand??await loadRunEvalCommand())(r,i,e,n.root)}),a}async function runCli(e=process.argv.slice(2),t=console,n={}){let r={root:resolveApplicationRoot(),async resolve(){let e=await(n.resolveApplicationProject??resolveCliApplicationProject)(r.root);r.project=e,r.root=e.appRoot},async resolveAgent(){return resolveEveProjectContext(r.root)}},i=createEveCliTelemetry(resolveInstalledPackageInfo().version),a=createCliProgram(t,n,r,i),o=e;if(o.length===0){let e=await(n.findApplicationRoot??findCliApplicationRoot)(r.root);e===void 0?o=(await findEveProjectContext(r.root))?.kind===`workspace`?[`dev`]:[`init`]:(r.root=e,o=[`dev`])}let s=canonicalCommand(o);i.trackCommand(s),s!==`telemetry`&&await i.notify(t);try{await a.parseAsync(o,{from:`user`}),i.trackOutcome(`success`)}catch(e){if(e instanceof CommanderError&&e.exitCode===0){i.trackOutcome(`success`);return}if(i.trackOutcome(e instanceof CommanderError?`usage_error`:`error`),e instanceof CommanderError){let r=await(n.isCodingAgentLaunch??isCodingAgentLaunch)();if(o[0]===`init`&&r){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}finally{await i.flush()}}export{createCliProgram,resolveDevUiMode,resolveTuiDisplayOptions,runCli};
@@ -18,7 +18,7 @@ export type { EveAgentStoreCallbacks, EveAgentStoreInit, EveAgentStoreSnapshot,
18
18
  export type { AgentInfoEntry, AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoResult, AgentInfoRemoteAgentEntry, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, CancelSessionResult, ClearResult, CompactResult, ClientAuth, ClientOptions, ClientRedirectPolicy, CreateSessionOptions, HeadersValue, HealthResult, MessageResult, RespondTurnOptions, ResetResult, ResolvedStreamReconnectPolicy, SendTurnInput, SendTurnOptions, SessionSnapshot, ClientSessionState, StreamOptions, StreamReconnectPolicy, StreamReconnectRetryPolicy, TokenValue, } from "#client/types.js";
19
19
  export type { EveAgentReducer, EveAgentReducerEvent, ClientInputRespondedEvent, ClientMessageFailedEvent, ClientMessageSubmittedEvent, } from "#client/reducer.js";
20
20
  export type { EveAuthorizationChallenge, EveAuthorizationOutcome, EveAuthorizationPart, EveMessageData, EveDynamicToolPart, EveMessageInputRequest, EveMessage, EveMessageMetadata, EveMessagePart, EveMessageToolMetadata, } from "#client/message-reducer.js";
21
- export type { ActionPartialStreamEvent, ActionResultStreamEvent, ActionsRequestedStreamEvent, AgentStartedStreamEvent, AssistantStepFinishReason, AuthorizationOutcome, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, MessageStreamEventMeta, InputResolution, InputResolutionOutcome, InputResolvedStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedPart, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, ResultCompletedStreamEvent, RuntimeTraceContext, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionPredecessor, SessionStartedStreamEvent, SessionWaitingStreamEvent, MessageStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, TaskSettledStreamEvent, TaskStartedStreamEvent, TurnCancelledStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, TurnFailureStreamEvent, TurnWaitingOn, TurnWaitingStreamEvent, } from "#protocol/message.js";
21
+ export type { ActionPartialStreamEvent, ActionResultStreamEvent, ActionsRequestedStreamEvent, AgentStartedStreamEvent, AssistantStepFinishReason, AuthorizationOutcome, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, HistoryImportedMessage, HistoryImportedStreamEvent, MessageStreamEventMeta, InputResolution, InputResolutionOutcome, InputResolvedStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedPart, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, ResultCompletedStreamEvent, RuntimeTraceContext, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionPredecessor, SessionStartedStreamEvent, SessionWaitingStreamEvent, MessageStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, TaskSettledStreamEvent, TaskStartedStreamEvent, TurnCancelledStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, TurnFailureStreamEvent, TurnWaitingOn, TurnWaitingStreamEvent, } from "#protocol/message.js";
22
22
  export { isCurrentTurnBoundaryEvent, isTurnFailureEvent } from "#protocol/message.js";
23
23
  export type { InputOption, InputRequest, InputRequestKind, InputResponse } from "#shared/input.js";
24
24
  export { isInputRequest, isInputResponse, parseInputResponse, parseInputResponses, } from "#shared/input.js";
@@ -21,11 +21,15 @@ export interface EveMessage {
21
21
  * `status` tracks this message's own lifecycle (distinct from session-level
22
22
  * status): user messages use `"submitted"` or `"failed"`, assistant messages
23
23
  * use `"streaming"` or `"complete"`. `optimistic` is set only while a
24
- * client-projected user message awaits server confirmation. `turnId` links the
25
- * message to its runtime turn; `result` holds the harness structured result
26
- * once the turn finalizes.
24
+ * client-projected user message awaits server confirmation. `imported` marks a
25
+ * message added through `history`, ahead of its turn's message, and carries no
26
+ * `turnId`; `historyId` is the app-owned `id` that history entry carried.
27
+ * `turnId` links the message to its runtime turn; `result` holds the harness
28
+ * structured result once the turn finalizes.
27
29
  */
28
30
  export interface EveMessageMetadata {
31
+ readonly historyId?: string;
32
+ readonly imported?: true;
29
33
  readonly optimistic?: true;
30
34
  readonly result?: unknown;
31
35
  readonly status?: "complete" | "failed" | "streaming" | "submitted";