eve 0.69.0 → 0.70.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 (326) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/src/acp/adapter.js +1 -1
  3. package/dist/src/channel/task-card.d.ts +3 -3
  4. package/dist/src/channel/task-card.js +1 -1
  5. package/dist/src/channel/types.d.ts +18 -0
  6. package/dist/src/chunks/{use-eve-agent-Dab2MnT2.js → use-eve-agent-CJQeE7-t.js} +1873 -1236
  7. package/dist/src/chunks/{use-eve-agent-D_5129A9.js → use-eve-agent-DdemtY6C.js} +1874 -1234
  8. package/dist/src/cli/dev/command.js +1 -1
  9. package/dist/src/cli/dev/console-records-preload.d.ts +1 -0
  10. package/dist/src/cli/dev/console-records-preload.js +1 -0
  11. package/dist/src/cli/dev/console-records.d.ts +17 -0
  12. package/dist/src/cli/dev/console-records.js +3 -0
  13. package/dist/src/cli/dev/diagnostic-sink.d.ts +1 -0
  14. package/dist/src/cli/dev/local-server-process.js +1 -1
  15. package/dist/src/cli/dev/tui/blocks.d.ts +2 -1
  16. package/dist/src/cli/dev/tui/blocks.js +3 -3
  17. package/dist/src/cli/dev/tui/conversation-view.d.ts +54 -0
  18. package/dist/src/cli/dev/tui/conversation-view.js +1 -0
  19. package/dist/src/cli/dev/tui/flow-drawer.d.ts +5 -2
  20. package/dist/src/cli/dev/tui/flow-drawer.js +1 -1
  21. package/dist/src/cli/dev/tui/log-display-mode.d.ts +4 -10
  22. package/dist/src/cli/dev/tui/log-display-mode.js +1 -1
  23. package/dist/src/cli/dev/tui/message-queue.d.ts +7 -63
  24. package/dist/src/cli/dev/tui/message-queue.js +3 -1
  25. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  26. package/dist/src/cli/dev/tui/question-panel.d.ts +3 -1
  27. package/dist/src/cli/dev/tui/question-panel.js +1 -1
  28. package/dist/src/cli/dev/tui/runner.d.ts +56 -193
  29. package/dist/src/cli/dev/tui/runner.js +3 -3
  30. package/dist/src/cli/dev/tui/task-activity.d.ts +11 -7
  31. package/dist/src/cli/dev/tui/task-activity.js +1 -1
  32. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +15 -37
  33. package/dist/src/cli/dev/tui/terminal-renderer.js +10 -13
  34. package/dist/src/cli/dev/tui/terminal-tool-part.d.ts +2 -0
  35. package/dist/src/cli/dev/tui/terminal-tool-part.js +1 -0
  36. package/dist/src/cli/dev/tui/test/fake-eve-server.d.ts +34 -0
  37. package/dist/src/cli/dev/tui/test/fake-eve-server.js +1 -0
  38. package/dist/src/cli/dev/tui/test/index.d.ts +1 -0
  39. package/dist/src/cli/dev/tui/test/index.js +1 -1
  40. package/dist/src/cli/dev/tui/tool-block-groups.js +1 -1
  41. package/dist/src/cli/dev/tui/tool-presentation.d.ts +1 -0
  42. package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
  43. package/dist/src/cli/dev/tui/tool-rows.d.ts +1 -0
  44. package/dist/src/cli/dev/tui/tool-rows.js +2 -2
  45. package/dist/src/cli/dev/tui/transcript-parts.d.ts +73 -0
  46. package/dist/src/cli/dev/tui/transcript-parts.js +3 -0
  47. package/dist/src/cli/dev/tui/transcript.d.ts +47 -0
  48. package/dist/src/cli/dev/tui/transcript.js +1 -0
  49. package/dist/src/cli/dev/tui/tui.js +1 -1
  50. package/dist/src/cli/dev/tui/turn-clock.d.ts +11 -26
  51. package/dist/src/cli/dev/tui/turn-clock.js +1 -1
  52. package/dist/src/cli/dev/tui/types.d.ts +2 -4
  53. package/dist/src/cli/dev/ui-options.js +1 -1
  54. package/dist/src/client/agent-stream-follower.d.ts +26 -0
  55. package/dist/src/client/agent-stream-follower.js +1 -0
  56. package/dist/src/client/authorization-message-parts.js +1 -1
  57. package/dist/src/client/conversation-client.d.ts +40 -0
  58. package/dist/src/client/conversation-client.js +1 -0
  59. package/dist/src/client/conversation-reducer.d.ts +29 -0
  60. package/dist/src/client/conversation-reducer.js +1 -0
  61. package/dist/src/client/conversation-state.d.ts +110 -0
  62. package/dist/src/client/conversation-state.js +1 -0
  63. package/dist/src/client/eve-agent-projection.d.ts +24 -7
  64. package/dist/src/client/eve-agent-projection.js +1 -1
  65. package/dist/src/client/eve-agent-store-helpers.d.ts +21 -2
  66. package/dist/src/client/eve-agent-store-helpers.js +2 -2
  67. package/dist/src/client/eve-agent-store-state.d.ts +15 -3
  68. package/dist/src/client/eve-agent-store.d.ts +10 -1
  69. package/dist/src/client/eve-agent-store.js +1 -1
  70. package/dist/src/client/index.d.ts +4 -1
  71. package/dist/src/client/index.js +1 -1
  72. package/dist/src/client/message-reducer-primitives.d.ts +1 -2
  73. package/dist/src/client/message-reducer-primitives.js +1 -1
  74. package/dist/src/client/message-reducer-types.d.ts +9 -2
  75. package/dist/src/client/message-reducer.js +1 -1
  76. package/dist/src/client/message-response.js +1 -1
  77. package/dist/src/client/message-run-parts.d.ts +10 -6
  78. package/dist/src/client/message-run-parts.js +1 -1
  79. package/dist/src/client/optimistic-message-submissions.d.ts +6 -4
  80. package/dist/src/client/optimistic-message-submissions.js +1 -1
  81. package/dist/src/client/reducer.d.ts +5 -1
  82. package/dist/src/client/session-turn-dispatch.d.ts +15 -0
  83. package/dist/src/client/session-turn-dispatch.js +1 -0
  84. package/dist/src/client/session-utils.d.ts +27 -10
  85. package/dist/src/client/session-utils.js +1 -1
  86. package/dist/src/client/session.js +1 -1
  87. package/dist/src/client/types.d.ts +2 -1
  88. package/dist/src/compiled/.vendor-stamp.json +1 -1
  89. package/dist/src/compiler/extension-compatibility.d.ts +18 -18
  90. package/dist/src/compiler/extension-compatibility.js +1 -1
  91. package/dist/src/compiler/load-binding-namespace.js +1 -1
  92. package/dist/src/context/keys.d.ts +5 -2
  93. package/dist/src/context/keys.js +1 -1
  94. package/dist/src/context/provider.d.ts +5 -9
  95. package/dist/src/context/run-step.d.ts +4 -4
  96. package/dist/src/context/run-step.js +1 -1
  97. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  98. package/dist/src/evals/runner/execute-task.js +1 -1
  99. package/dist/src/evals/session.js +2 -2
  100. package/dist/src/evals/types.d.ts +16 -0
  101. package/dist/src/eve-channel/index.js +1 -1
  102. package/dist/src/execution/agent-sessions/context.d.ts +4 -2
  103. package/dist/src/execution/agent-sessions/context.js +1 -1
  104. package/dist/src/execution/agent-sessions/steps.js +1 -1
  105. package/dist/src/execution/cancelled-model-call-batch.js +1 -1
  106. package/dist/src/execution/coordination-dispatch-shared.d.ts +6 -4
  107. package/dist/src/execution/coordination-dispatch-shared.js +1 -1
  108. package/dist/src/execution/create-session-step.d.ts +4 -2
  109. package/dist/src/execution/create-session-step.js +1 -1
  110. package/dist/src/execution/durable-session-store.d.ts +10 -4
  111. package/dist/src/execution/durable-session-store.js +1 -1
  112. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  113. package/dist/src/execution/legacy-session/completion-step.d.ts +2 -0
  114. package/dist/src/execution/legacy-session/completion-step.js +1 -1
  115. package/dist/src/execution/legacy-session/interrupt-step.js +1 -1
  116. package/dist/src/execution/legacy-session/prepare-step.d.ts +1 -0
  117. package/dist/src/execution/legacy-session/prepare-step.js +1 -1
  118. package/dist/src/execution/legacy-session/snapshot.d.ts +8 -4
  119. package/dist/src/execution/legacy-session/snapshot.js +1 -1
  120. package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
  121. package/dist/src/execution/proxied-deliver-step.js +1 -1
  122. package/dist/src/execution/publish-session-events.d.ts +27 -7
  123. package/dist/src/execution/publish-session-events.js +1 -1
  124. package/dist/src/execution/reconcile-session-continuation-token.d.ts +2 -2
  125. package/dist/src/execution/runtime-context.js +1 -1
  126. package/dist/src/execution/session/active-turn.d.ts +97 -0
  127. package/dist/src/execution/session/active-turn.js +1 -0
  128. package/dist/src/execution/session/entry.js +1 -1
  129. package/dist/src/execution/session/finalization.js +1 -1
  130. package/dist/src/execution/session/handoff.d.ts +5 -3
  131. package/dist/src/execution/session/handoff.js +1 -1
  132. package/dist/src/execution/session/input-queue.d.ts +19 -13
  133. package/dist/src/execution/session/input-queue.js +1 -1
  134. package/dist/src/execution/session/next-input.d.ts +2 -10
  135. package/dist/src/execution/session/next-input.js +1 -1
  136. package/dist/src/execution/session/program.d.ts +2 -0
  137. package/dist/src/execution/session/program.js +1 -1
  138. package/dist/src/execution/session/state-cursor.d.ts +22 -16
  139. package/dist/src/execution/session/state-cursor.js +1 -1
  140. package/dist/src/execution/session/state-delta.d.ts +8 -1
  141. package/dist/src/execution/session/state-delta.js +1 -1
  142. package/dist/src/execution/session/turn-event-handler.js +1 -1
  143. package/dist/src/execution/session/turn-step-result.js +1 -1
  144. package/dist/src/execution/session/turn-step-types.d.ts +13 -4
  145. package/dist/src/execution/session/turn-step.js +1 -1
  146. package/dist/src/execution/session/turn-waiting-step.js +1 -1
  147. package/dist/src/execution/session/turn.d.ts +8 -1
  148. package/dist/src/execution/session/turn.js +1 -1
  149. package/dist/src/execution/session.d.ts +5 -5
  150. package/dist/src/execution/session.js +2 -2
  151. package/dist/src/execution/settle-cancelled-turn-step.d.ts +5 -4
  152. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  153. package/dist/src/execution/tasks/start.d.ts +2 -2
  154. package/dist/src/execution/tasks/task-id-input.d.ts +1 -1
  155. package/dist/src/execution/tasks/task-id-input.js +1 -1
  156. package/dist/src/execution/terminal-session-completion-step.d.ts +2 -0
  157. package/dist/src/execution/terminal-session-completion-step.js +1 -1
  158. package/dist/src/execution/terminal-session-failure-step.d.ts +2 -0
  159. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  160. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  161. package/dist/src/execution/tools/connection-target.d.ts +5 -0
  162. package/dist/src/execution/tools/connection-target.js +1 -1
  163. package/dist/src/execution/tools/connection-tools.js +2 -2
  164. package/dist/src/execution/tools/workflow/start.d.ts +3 -3
  165. package/dist/src/harness/authorization.d.ts +15 -2
  166. package/dist/src/harness/authorization.js +1 -1
  167. package/dist/src/harness/cancelled-turn-emission.d.ts +2 -1
  168. package/dist/src/harness/cancelled-turn-emission.js +1 -1
  169. package/dist/src/harness/coordination.d.ts +5 -3
  170. package/dist/src/harness/emission.d.ts +5 -2
  171. package/dist/src/harness/emission.js +1 -1
  172. package/dist/src/harness/held-requests.d.ts +18 -0
  173. package/dist/src/harness/held-requests.js +1 -0
  174. package/dist/src/harness/hitl/approval-input-requests.d.ts +16 -0
  175. package/dist/src/harness/hitl/approval-input-requests.js +1 -1
  176. package/dist/src/harness/input-extraction.js +1 -1
  177. package/dist/src/harness/input-requests.d.ts +0 -4
  178. package/dist/src/harness/input-requests.js +1 -1
  179. package/dist/src/harness/model-call-error.js +1 -1
  180. package/dist/src/harness/proxy-input-requests.d.ts +4 -4
  181. package/dist/src/harness/session-limit-enforcement.js +1 -1
  182. package/dist/src/harness/stale-input-responses.js +1 -1
  183. package/dist/src/harness/tool-loop.js +2 -2
  184. package/dist/src/harness/turn-tag-state.d.ts +2 -0
  185. package/dist/src/harness/turn-tag-state.js +1 -1
  186. package/dist/src/harness/types.d.ts +23 -11
  187. package/dist/src/instrumentation/channel-delivery.d.ts +1 -0
  188. package/dist/src/instrumentation/channel-delivery.js +1 -1
  189. package/dist/src/instrumentation/lifecycle.d.ts +4 -0
  190. package/dist/src/instrumentation/memory.d.ts +2 -0
  191. package/dist/src/instrumentation/memory.js +1 -1
  192. package/dist/src/instrumentation/native-events.d.ts +1 -0
  193. package/dist/src/instrumentation/native-events.js +1 -1
  194. package/dist/src/instrumentation/runtime.d.ts +4 -3
  195. package/dist/src/instrumentation/runtime.js +1 -1
  196. package/dist/src/instrumentation/session-init.js +1 -1
  197. package/dist/src/internal/application/package.js +1 -1
  198. package/dist/src/internal/authored-module-loader.d.ts +14 -6
  199. package/dist/src/internal/authored-module-loader.js +1 -1
  200. package/dist/src/internal/authored-package-boundary.d.ts +1 -1
  201. package/dist/src/internal/authored-package-boundary.js +1 -1
  202. package/dist/src/internal/bundler/extension-mount-plugin.js +1 -1
  203. package/dist/src/internal/workflow-bundle/dynamic-remote-agent-transform.js +1 -1
  204. package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.d.ts +27 -1
  205. package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.js +1 -1
  206. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +2 -2
  207. package/dist/src/protocol/message.d.ts +41 -3
  208. package/dist/src/protocol/message.js +2 -2
  209. package/dist/src/public/channels/slack/action-status.d.ts +2 -2
  210. package/dist/src/public/channels/slack/action-status.js +1 -1
  211. package/dist/src/public/channels/slack/approval-cards.d.ts +15 -0
  212. package/dist/src/public/channels/slack/approval-cards.js +2 -0
  213. package/dist/src/public/channels/slack/auth.d.ts +2 -0
  214. package/dist/src/public/channels/slack/auth.js +1 -1
  215. package/dist/src/public/channels/slack/connections.d.ts +15 -11
  216. package/dist/src/public/channels/slack/connections.js +1 -1
  217. package/dist/src/public/channels/slack/defaults.d.ts +1 -15
  218. package/dist/src/public/channels/slack/defaults.js +3 -4
  219. package/dist/src/public/channels/slack/hitl.js +1 -1
  220. package/dist/src/public/channels/slack/inbound.d.ts +10 -2
  221. package/dist/src/public/channels/slack/inbound.js +1 -1
  222. package/dist/src/public/channels/slack/index.d.ts +2 -0
  223. package/dist/src/public/channels/slack/index.js +1 -1
  224. package/dist/src/public/channels/slack/input-response.js +1 -1
  225. package/dist/src/public/channels/slack/interaction-cards.js +1 -1
  226. package/dist/src/public/channels/slack/interactions.js +1 -1
  227. package/dist/src/public/channels/slack/limits.d.ts +5 -3
  228. package/dist/src/public/channels/slack/private-approval-delivery.js +1 -1
  229. package/dist/src/public/channels/slack/renderers.d.ts +1 -1
  230. package/dist/src/public/channels/slack/renderers.js +1 -1
  231. package/dist/src/public/channels/slack/reply-delivery.d.ts +72 -0
  232. package/dist/src/public/channels/slack/reply-delivery.js +1 -0
  233. package/dist/src/public/channels/slack/sign-in-cancel.d.ts +20 -0
  234. package/dist/src/public/channels/slack/sign-in-cancel.js +1 -0
  235. package/dist/src/public/channels/slack/slackChannel.d.ts +15 -0
  236. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  237. package/dist/src/public/channels/slack/task-card.js +1 -1
  238. package/dist/src/public/channels/teams/defaults.d.ts +1 -1
  239. package/dist/src/public/channels/teams/defaults.js +2 -2
  240. package/dist/src/public/definitions/channel.d.ts +1 -0
  241. package/dist/src/public/definitions/channel.js +1 -1
  242. package/dist/src/public/next/index.js +1 -1
  243. package/dist/src/public/next/server.d.ts +2 -0
  244. package/dist/src/public/next/server.js +1 -2
  245. package/dist/src/public/nuxt/module.d.ts +6 -0
  246. package/dist/src/public/nuxt/module.js +1 -1
  247. package/dist/src/react/index.d.ts +3 -0
  248. package/dist/src/react/index.js +1 -1
  249. package/dist/src/react/use-eve-agent.d.ts +7 -5
  250. package/dist/src/react/use-eve-agent.js +1 -1
  251. package/dist/src/runtime/connections/scoped-authorization.d.ts +2 -0
  252. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  253. package/dist/src/setup/boxes/deploy-project.js +1 -1
  254. package/dist/src/setup/integrations/web/setup.js +6 -2
  255. package/dist/src/setup/scaffold/create/project.js +1 -1
  256. package/dist/src/setup/scaffold/create/web-template.d.ts +2 -2
  257. package/dist/src/setup/scaffold/create/web-template.js +28 -9
  258. package/dist/src/setup/vercel-project-framework.js +1 -1
  259. package/dist/src/shared/display-name.d.ts +15 -0
  260. package/dist/src/shared/display-name.js +1 -0
  261. package/dist/src/shared/framework-eve-server.d.ts +43 -0
  262. package/dist/src/shared/framework-eve-server.js +2 -0
  263. package/dist/src/shared/token-usage.d.ts +2 -0
  264. package/dist/src/shared/token-usage.js +1 -1
  265. package/dist/src/shared/trace-root.d.ts +8 -0
  266. package/dist/src/shared/trace-root.js +1 -0
  267. package/dist/src/subagents/hitl-proxy.d.ts +3 -3
  268. package/dist/src/subagents/hitl-proxy.js +1 -1
  269. package/dist/src/subagents/invocation.d.ts +3 -1
  270. package/dist/src/subagents/tool.js +1 -1
  271. package/dist/src/svelte/index.d.ts +3 -0
  272. package/dist/src/svelte/index.js +2 -2
  273. package/dist/src/svelte/use-eve-agent.d.ts +7 -4
  274. package/dist/src/svelte/use-eve-agent.js +1 -1
  275. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  276. package/dist/src/tools/provided/load-skill.js +1 -1
  277. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  278. package/dist/src/tracing/agent-action-instrumentation.js +1 -1
  279. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  280. package/dist/src/tracing/agent-memory-instrumentation.js +1 -1
  281. package/dist/src/tracing/agent-otel-attributes.d.ts +6 -0
  282. package/dist/src/tracing/agent-otel-attributes.js +1 -1
  283. package/dist/src/tracing/agent-otel-provider.js +2 -2
  284. package/dist/src/tracing/agent-otel-runtime-context.d.ts +1 -1
  285. package/dist/src/tracing/agent-otel-runtime-context.js +1 -1
  286. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  287. package/dist/src/tracing/agent-span-contract.js +1 -1
  288. package/dist/src/tracing/agent-tool-instrumentation.js +1 -1
  289. package/dist/src/tracing/agent-trace-context-codec.d.ts +4 -0
  290. package/dist/src/tracing/agent-trace-context-codec.js +1 -1
  291. package/dist/src/tracing/agent-trace-span-processor.js +1 -1
  292. package/dist/src/tracing/agent-trace-state.d.ts +3 -0
  293. package/dist/src/tracing/conversation-context.d.ts +10 -0
  294. package/dist/src/tracing/conversation-context.js +1 -1
  295. package/dist/src/tracing/otel-registration.js +1 -1
  296. package/dist/src/vue/index.d.ts +3 -0
  297. package/dist/src/vue/index.js +2 -2
  298. package/dist/src/vue/use-eve-agent.d.ts +7 -3
  299. package/dist/src/vue/use-eve-agent.js +1 -1
  300. package/docs/channels/slack.mdx +60 -13
  301. package/docs/concepts/built-in-tools.md +3 -2
  302. package/docs/concepts/sessions-runs-and-streaming.md +4 -4
  303. package/docs/connections/overview.mdx +9 -3
  304. package/docs/evals/reporters.mdx +4 -0
  305. package/docs/extensions.md +11 -0
  306. package/docs/guides/client/streaming.mdx +7 -6
  307. package/docs/guides/deployment/vercel.mdx +2 -1
  308. package/docs/guides/dev-tui.md +15 -15
  309. package/docs/guides/dynamic-capabilities.md +1 -1
  310. package/docs/guides/frontend/nuxt.mdx +24 -4
  311. package/docs/guides/frontend/overview.mdx +44 -38
  312. package/docs/guides/frontend/use-eve-agent-svelte.mdx +4 -10
  313. package/docs/guides/frontend/use-eve-agent-vue.mdx +4 -10
  314. package/docs/guides/instrumentation/otel.mdx +24 -6
  315. package/docs/guides/remote-agents.md +26 -8
  316. package/docs/reference/cli.md +4 -4
  317. package/docs/tools/human-in-the-loop.md +4 -4
  318. package/docs/tools/overview.mdx +1 -1
  319. package/docs/tools/tasks.md +8 -8
  320. package/package.json +1 -1
  321. package/dist/src/cli/dev/tui/steering-stream.d.ts +0 -15
  322. package/dist/src/cli/dev/tui/steering-stream.js +0 -1
  323. package/dist/src/cli/dev/tui/subagent-pump.d.ts +0 -134
  324. package/dist/src/cli/dev/tui/subagent-pump.js +0 -1
  325. package/dist/src/public/nuxt/dev-server.d.ts +0 -25
  326. package/dist/src/public/nuxt/dev-server.js +0 -1
@@ -94,29 +94,29 @@ Required authorization or deployment setup still runs for the selected item. Pre
94
94
 
95
95
  ## Work with the agent
96
96
 
97
- Type a message and press `Enter` to send it. When the agent asks a question or requests tool approval, respond in the prompt shown by the UI. Connection authorization can open a browser; keep local `eve dev` running until the browser returns to it.
97
+ Type a message and press `Enter` to send it. When the agent asks a question or requests tool approval, respond in the prompt shown by the UI. Each answer is sent as soon as you give it. When several requests are open, the prompt shows its place among them, such as `2 of 5`, and names the task that asked as its transcript lines do. Connection authorization can open a browser; keep local `eve dev` running until the browser returns to it.
98
98
 
99
- The activity line shows **Thinking** while the model reasons or waits to respond, **Generating** while it writes a response or tool input, **Running** while tools execute, and **Waiting for** followed by task names while the turn waits on [tasks](../tools/tasks). A blinking dot and elapsed time indicate progress, with token counts shown when available. The activity line disappears when the turn finishes or needs your input.
99
+ The activity line shows **Thinking** while the model reasons or waits to respond, **Generating** while it writes a response or tool input, and **Running** while tools execute. A blinking dot and elapsed time indicate progress, with token counts shown when available. While [tasks](../tools/tasks) work, the drawer header replaces this line: it shows the parent's current activity, task count, and turn elapsed time without token counts. **Waiting** means the parent is waiting on work; **Working** appears without a turn timer when tasks remain active between turns.
100
100
 
101
- A task, such as a call to a subagent, writes one line to the transcript when it starts and one when it finishes, fails, or is stopped. The finished line names how long the task took and, for a subagent, what it did, such as `Read 3 files, Ran 2 commands`. While tasks work, a panel above the prompt shows each task's current activity and elapsed time. The UI does not show the model's own `task_wait` and `task_cancel` calls; their effect appears as the waiting activity line and a stopped task's line.
101
+ A task, such as a call to a subagent, writes one line to the transcript when it starts and one when it finishes, fails, or is stopped. The finished line names how long the task took and, for a subagent, what it did, such as `Read 3 files, Ran 2 commands`. Task starts use the same tool-call styling as synchronous calls. While tasks work, an activity drawer above the prompt shows each task's name, current activity, and elapsed time without repeating its launch prompt. Subagents use labels such as `subagent(self-modification)`, with elapsed time beside the name and the latest observed tool grouped beneath an elbow. The tool remains visible between calls rather than switching to a starting placeholder. During questions and approvals, activity stays visible above the request with a shared divider when screen space permits; the request takes priority on small terminals. Background work started by a followed subagent appears beneath that subagent; deeper work uses an ownership path instead of further indentation. The panel caps its height and prioritizes tasks needing approval when work overflows. The UI does not show the model's own `task_wait` and `task_cancel` calls; their effect appears as the **Waiting** header and a stopped task's line.
102
102
 
103
- While a turn is running, `Enter` sends your message immediately as steering. Before assistant output begins, the runtime interrupts pending model generation and continues the same turn with your correction. Executing tools finish safely. After output begins, steering applies at the next workflow boundary and preserves streamed text.
103
+ The prompt stays open while the agent works, including turns started elsewhere, such as a scheduled run. While a turn is running, `Enter` sends your message immediately as steering. Before assistant output begins, the runtime interrupts pending model generation and continues the same turn with your correction. Executing tools finish safely. After output begins, steering applies at the next workflow boundary and preserves streamed text.
104
104
 
105
- Slash commands wait until the turn ends, except `/cancel`, which cancels directly. If the session does not support steering, messages queue for the next turn. Press `Esc` or `Ctrl+C` to cancel a turn with no queued messages. With queued messages, these keys select the oldest message for steering, or for the next turn if steering is unavailable. If a direct cancellation requested with `/cancel` or `Ctrl+C` does not settle, press `Ctrl+C` to stop waiting. The UI then returns to the prompt and asks you to press `Ctrl+C` again to exit. At an idle prompt, press `Ctrl+C` twice to exit.
105
+ Slash commands run immediately, even during a turn. Press `Esc` or `Ctrl+C`, or run `/cancel`, to cancel a running turn. If you cancel before the turn has started, eve waits for that turn's ID before sending cancellation, so the request cannot cancel a later turn. If a cancellation does not settle, press `Ctrl+C` again to stop waiting: eve starts a new session, and the next `Ctrl+C` exits. At an idle prompt, press `Ctrl+C` twice to exit.
106
106
 
107
- | Key | Action |
108
- | ------------- | ----------------------------------------------------------------------------------------------------------------------- |
109
- | `Enter` | Send the current message or answer. |
110
- | `Shift+Enter` | Insert a newline. Requires a terminal that reports modified keys. |
111
- | `Esc` | Cancel a running turn, or steer with the oldest queued message. |
112
- | `Ctrl+C` | Cancel or steer during a turn; stop a pending cancellation, then exit on the next press; press twice to exit when idle. |
113
- | `↑` / `↓` | Move through input lines or sent-message history. |
114
- | `Ctrl+L` | Cycle log display modes. |
115
- | `Ctrl+R` | Redraw the screen. |
107
+ | Key | Action |
108
+ | ------------- | ---------------------------------------------------------------------------------------------------------- |
109
+ | `Enter` | Send the current message or answer. |
110
+ | `Shift+Enter` | Insert a newline. Requires a terminal that reports modified keys. |
111
+ | `Esc` | Cancel a running turn. |
112
+ | `Ctrl+C` | Cancel a running turn; press again to stop waiting and start a new session; press twice to exit when idle. |
113
+ | `↑` / `↓` | Move through input lines or sent-message history. |
114
+ | `Ctrl+L` | Cycle log display modes. |
115
+ | `Ctrl+R` | Redraw the screen. |
116
116
 
117
117
  ## Logs and traces
118
118
 
119
- By default, the UI shows `stderr` logs. Use `/loglevel <all|stderr|sandbox|none>` to change the display; bare `/loglevel` reports the current setting. `Ctrl+L` cycles the same modes.
119
+ By default, the UI shows severity-tagged errors. Use `/loglevel <none|error|warn|debug|all>` to change the display; bare `/loglevel` reports the current setting. `warn` adds warnings, `debug` adds all severity-tagged records, and `all` also shows unclassified stdout, stderr, and sandbox output. `none` hides logs. Errors render red, warnings yellow, and unclassified stderr neutral. `Ctrl+L` cycles the same modes. These modes filter received records; they do not change `EVE_LOG_LEVEL` or enable a dependency's debug logging.
120
120
 
121
121
  Workflow SDK output, such as lines tagged `[workflow-sdk]` or `[world-local]`, reports internal runtime details, so the transcript shows it only in `all` mode.
122
122
 
@@ -362,7 +362,7 @@ A dynamic connection, tool, or skill whose name matches an **authored** one **ov
362
362
 
363
363
  At `turn.started`, model, tool, skill, and subagent resolvers receive the visible conversation history and incoming message in `ctx.messages`, oldest first. Request context is included, and history projection still applies. Read these messages from the handler's second argument; the event itself contains turn metadata. Instruction resolvers use the separate snapshot described under [Dynamic instructions](#dynamic-instructions).
364
364
 
365
- This also applies while a session-limit prompt keeps the incoming message queued and when authorization completes. Authorization callbacks without new or queued input receive the visible history. When memory recall runs, its results appear in the projected snapshot before incoming input.
365
+ A message that steers a held turn, or waits behind its session-limit prompt, joins that turn instead of starting one, as does a completed sign-in, so `turn.started` resolvers do not see it; `step.started` resolvers do. When memory recall runs, its results appear in the projected snapshot before incoming input.
366
366
 
367
367
  ### Execution order
368
368
 
@@ -30,7 +30,26 @@ export default defineNuxtConfig({
30
30
  });
31
31
  ```
32
32
 
33
- The `eve` key accepts only two options, `eveRoot` and `eveBuildCommand`.
33
+ ### `eve/nuxt` options
34
+
35
+ All fields are optional.
36
+
37
+ | Option | Type | Default | Purpose |
38
+ | -------------------- | -------- | ----------------- | ----------------------------------------------------------------------------------------------------------------- |
39
+ | `eveRoot` | `string` | Nuxt project root | eve project root, relative to the Nuxt project root unless absolute. |
40
+ | `eveBuildCommand` | `string` | generated | Build command for the generated eve Vercel service. |
41
+ | `devServerTimeoutMs` | `number` | `180000` | Maximum time to wait for the eve development server to start, including when another Nuxt process is starting it. |
42
+
43
+ For slow cold starts, increase the development timeout:
44
+
45
+ ```ts
46
+ export default defineNuxtConfig({
47
+ modules: ["eve/nuxt"],
48
+ eve: {
49
+ devServerTimeoutMs: 300_000,
50
+ },
51
+ });
52
+ ```
34
53
 
35
54
  ## Call the composable
36
55
 
@@ -65,7 +84,7 @@ The browser still needs a production authentication policy. See [Authenticate br
65
84
 
66
85
  ## Dev vs deploy topology
67
86
 
68
- - **Local dev.** `npm run dev` starts the eve dev server next to `nuxt dev` and proxies the eve routes through it. As far as the browser knows, everything is the Nuxt origin.
87
+ - **Local dev.** `npm run dev` starts the eve dev server next to `nuxt dev` and proxies the eve routes through it. As far as the browser knows, everything is the Nuxt origin. Concurrent Nuxt processes for the same eve root share one eve dev server. Set `EVE_BASE_URL` to proxy to an eve dev server you already run instead.
69
88
  - **Vercel.** The web app and the eve runtime deploy as a single project. On Vercel builds the module adds Build Output [`services`](https://vercel.com/docs/services) for eve and `routes` that send `/eve/v1/**` to that service before filesystem routing; the Nuxt app itself remains the default app. No `vercel.json` is required. By default the generated service runs the installed eve binary from the agent root, so the agent directory does not need its own `package.json`. When the agent needs its own build step, set `eveBuildCommand`:
70
89
 
71
90
  ```ts
@@ -77,13 +96,14 @@ The browser still needs a production authentication policy. See [Authenticate br
77
96
  });
78
97
  ```
79
98
 
80
- - **Non-Vercel hosts.** Point Nuxt at a separate eve origin with `EVE_NUXT_PRODUCTION_ORIGIN`. To override the local port (default `4274`), use `EVE_NUXT_PRODUCTION_PORT`:
99
+ - **Non-Vercel hosts.** The module does not start eve in production; run the eve service yourself. `nuxt build` writes a proxy rule that sends `/eve/v1/**` to `EVE_NUXT_PRODUCTION_ORIGIN`, or to `http://127.0.0.1:4274` when that variable is unset. Override the local port with `EVE_NUXT_PRODUCTION_PORT`. Set these variables when you run `nuxt build`, because the destination is fixed in the build output:
81
100
 
82
101
  ```bash
83
102
  EVE_NUXT_PRODUCTION_ORIGIN=https://agent.example.com npm run build
84
- EVE_NUXT_PRODUCTION_PORT=5000 npm run build && npm run preview
85
103
  ```
86
104
 
105
+ `eve build` and `nuxt build` both write `.output/`. When the agent lives in the Nuxt project root, build and serve eve from a separate directory (set `eveRoot` to it) so the two outputs do not overwrite each other. See [Self-host eve](../deployment/self-hosting) for running the eve service.
106
+
87
107
  ## Managing vercel.json yourself
88
108
 
89
109
  When `vercel.json` declares [`services`](https://vercel.com/docs/services), the module generates nothing and your configuration owns routing. It must include the eve service (`framework: "eve"`) and a rewrite that exposes the eve transport, or the module fails the build:
@@ -53,7 +53,7 @@ export function Chat() {
53
53
  <article key={message.id}>
54
54
  <header>{message.role}</header>
55
55
  {message.parts.map((part, index) =>
56
- part.type === "text" ? <p key={index}>{part.text}</p> : null,
56
+ part.type === "text" ? <p key={part.id ?? index}>{part.text}</p> : null,
57
57
  )}
58
58
  </article>
59
59
  ))}
@@ -70,21 +70,22 @@ export function Chat() {
70
70
 
71
71
  `useEveAgent()` returns the current UI state plus commands:
72
72
 
73
- | Field | What it is |
74
- | --------- | ----------------------------------------------------------------------------------------- |
75
- | `data` | Projected UI state from the reducer. Defaults to `{ messages }`. |
76
- | `status` | `"ready"`, `"resuming"`, `"submitted"`, `"streaming"`, or `"error"`. Drives the composer. |
77
- | `error` | The latest session creation, stream, resume, or turn failure. |
78
- | `events` | Raw eve stream events for this session. |
79
- | `session` | Serializable fixed session cursor (`sessionId`, `streamIndex`). |
80
- | `prewarm` | Create the durable session without starting a turn. |
81
- | `send` | Send text or a multi-part message, with per-turn options. |
82
- | `respond` | Answer pending HITL input requests, with per-turn options. |
83
- | `resume` | Replay an attached session and follow its in-flight turn. |
84
- | `cancel` | Request durable cancellation of the active turn. |
85
- | `reset` | Clear local events, data, errors, and the local session cursor. |
86
-
87
- Most chat UIs only need `data.messages` and `status`. Drop down to `events` when you need the authoritative wire events directly, for example to persist an audit log or build a custom projection.
73
+ | Field | What it is |
74
+ | -------------- | ----------------------------------------------------------------------------------------- |
75
+ | `data` | The selected projection: `ConversationState` by default, or your custom reducer's state. |
76
+ | `conversation` | Canonical conversation state, including messages, root turns and inputs, and child state. |
77
+ | `status` | `"ready"`, `"resuming"`, `"submitted"`, `"streaming"`, or `"error"`. Drives the composer. |
78
+ | `error` | The latest session creation, stream, resume, or turn failure. |
79
+ | `events` | Raw eve stream events for this session. |
80
+ | `session` | Serializable fixed session cursor (`sessionId`, `streamIndex`). |
81
+ | `prewarm` | Create the durable session without starting a turn. |
82
+ | `send` | Send text or a multi-part message, with per-turn options. |
83
+ | `respond` | Answer pending HITL input requests, with per-turn options. |
84
+ | `resume` | Replay an attached session and follow its in-flight turn. |
85
+ | `cancel` | Request durable cancellation of the active turn. |
86
+ | `reset` | Clear local events, data, errors, and the local session cursor. |
87
+
88
+ Most chat UIs only need `data.messages` and `status` with the default reducer. Use `conversation` for session state when a custom reducer shapes `data`. Drop down to `events` when you need the authoritative wire events directly, for example to persist an audit log or build a custom projection.
88
89
 
89
90
  Pass `prewarm: true` to start a workflow when the chat mounts and after each reset:
90
91
 
@@ -157,9 +158,10 @@ change the option from `false` to `true` again, reset, or send a message to reco
157
158
 
158
159
  The hook keeps consuming one session stream across turns and idle periods. Replies,
159
160
  authorization updates, and turns started elsewhere all update the same projection. Separately
160
- delivered participant messages remain separate bubbles even when they steer the same active turn;
161
- a single event that coalesces multiple deliveries remains one bubble. A turn settling does not
162
- close the connection. The transport reconnects from its cursor after a disconnect or the
161
+ delivered participant messages remain separate bubbles before that turn's assistant response, even
162
+ when they arrive after the response begins. A single event that coalesces multiple deliveries
163
+ remains one bubble. A turn settling does not close the connection. The transport reconnects from
164
+ its cursor after a disconnect or the
163
165
  server's renewable 60-second lease; lease renewal does not start a turn or clear UI state.
164
166
  Unmounting or resetting closes the local stream without cancelling the old durable session.
165
167
 
@@ -168,9 +170,15 @@ the reset, it prepares the next owned session; otherwise, the next send creates
168
170
  supplied `session` remains externally owned and is never replaced by prewarming or reset. Use
169
171
  `initialSession` with `resume: true` to restore a saved chat.
170
172
 
171
- `data.messages` are eve-owned `EveMessage[]`. Common text, reasoning, file, and dynamic-tool parts follow the [AI SDK `UIMessage`](https://ai-sdk.dev/docs/reference/ai-sdk-core/ui-message) rendering convention, but the types are not interchangeable. eve also exposes authorization and HITL metadata, and a file part's URL can be absent. Adapt those parts before passing messages to an API typed as `UIMessage[]`.
173
+ `data.messages` are eve-owned `EveMessage[]`. Assistant text and reasoning parts have a stable `id` from the event that created the part. Appends and completion retain that ID. Use `part.id` to key streamed assistant content, including successive text parts within one step. Older events without an ID get a best-effort fallback. User text parts may not have an ID.
172
174
 
173
- When the root agent delegates, its stream emits `agent.started` with the child's `sessionId`, and the subagent tool call's `task.settled` carries the child's reply. The child session can remain available for reuse. Detailed child progress lives on the child session's stream instead of being flattened into the root `data.messages`. When your UI needs live subagent activity, attach a [client session](../client/overview#sessions) to the parent and pass the `agent.started` event from `events` to [`session.agent()`](../client/streaming#follow-a-subagent) and follow the child with `stream()`. It follows local and remote children through the parent, so the browser never calls a remote deployment directly. See [What the parent sees](../../subagents#what-the-parent-sees) for the complete contract.
175
+ Common text, reasoning, file, and dynamic-tool parts follow the [AI SDK `UIMessage`](https://ai-sdk.dev/docs/reference/ai-sdk-core/ui-message) rendering convention, but the types are not interchangeable. eve also exposes authorization and HITL metadata, and a file part's URL can be absent. Adapt those parts before passing messages to an API typed as `UIMessage[]`.
176
+
177
+ When the root agent delegates, its stream emits `task.started` for the call, `agent.started` with the child's `sessionId`, and `task.settled` with the call's result, failure, or cancellation. The default reducer settles the subagent's tool part from `task.settled`, so the part shows the call's outcome rather than its start receipt. `data.tasks[taskId].calls[callId]` records each call's `status`, `output`, and `error`, and `data.agents[sessionId]` records each session a call opened, with its `taskId` and opening `callId`. These records come from the root stream alone.
178
+
179
+ Detailed child progress lives on the child session's stream, not in the root `data.messages`. Pass `followSubagents: true` to follow the session each subagent call reaches while the component is mounted; following is off by default. Narrow `data.agents[sessionId].observation.status` before reading its `conversation`: `"not-followed"` has no child detail, `"following"` has live detail, and `"idle"` has everything the calls so far produced and resumes when another call reaches the task. `"unavailable"` means the stream failed, not that the child failed. Calls that continue a task with its `taskId` reach the same session, so one session's `conversation.messages`, `inputs`, and `turns` span all of them. Sessions that a custom task opens with `ctx.agent` are recorded but not followed.
180
+
181
+ If you manage your own session rather than using the hook, pass an `agent.started` event from `events` to [`session.agent()`](../client/streaming#follow-a-subagent) and follow the child with `stream()`. It follows local and remote children through the parent, so the browser never calls a remote deployment directly. See [What the parent sees](../../subagents#what-the-parent-sees) for the complete contract.
174
182
 
175
183
  ## Sending and streaming
176
184
 
@@ -192,13 +200,15 @@ await agent.send([
192
200
 
193
201
  Assistant text, reasoning, tool calls, and tool results stream into `data` as they arrive, and a new turn moves `status` from `ready` to `submitted` to `streaming` and back. Resuming an attached session uses `resuming` while eve performs bounded catch-up. Disable message and HITL submission in that state. A settled tail moves directly to `ready`; an in-flight tail moves to `streaming` before eve follows it.
194
202
 
203
+ A turn stays open while tasks it started are working. `status` stays `streaming` until the turn ends, and `data.turns[turnId].waiting` is `true` while the turn is parked, until its next step starts. When a call the turn runs asks a question, `send()` resolves at that point, as `session.send().result()` does; answer with `respond()` while the turn stays open.
204
+
195
205
  To steer an active turn with a follow-up, send the message with `turnPolicy: "steer"`. Before answer output or local tool execution begins, eve interrupts pending model generation and continues the same turn with the correction. Executing tools finish and checkpoint their results first; after answer output starts, steering waits for the next committed workflow boundary. Reasoning and search progress do not count as answer output. The hook stays attached through completion:
196
206
 
197
207
  ```tsx
198
208
  await agent.send(message, { turnPolicy: "steer" });
199
209
  ```
200
210
 
201
- Other message sends and HITL responses reject while the hook is processing a turn. Call `cancel()` to stop the durable server-side turn without replacing it, and `reset()` to clear local state so the next send starts a fresh durable session.
211
+ Other message sends reject while the hook is processing a turn. Answers to open input requests are accepted at any time; see [Human-in-the-loop prompts](#human-in-the-loop-prompts). The default `data.inputs` ledger keeps each request's originating `turnId` and `stepIndex`, response and settlement status, including requests left open after their originating turn ends; `data.activeTurnId` tracks the current root turn when known. A request from a task's run also carries that task's `taskId`. Each followed session keeps its own ledger in `data.agents[sessionId].observation.conversation`. Call `cancel()` to stop the durable server-side turn without replacing it, and `reset()` to clear local state so the next send starts a fresh durable session.
202
212
 
203
213
  `cancel()` can be called as soon as `status` is `"submitted"`; the hook waits for the active response to identify its turn when necessary, sends one guarded cancellation request, and keeps the event stream attached. The promise resolves when eve accepts the request or reports that no turn is active, and rejects if the cancellation request fails. The turn then settles on the same stream as `turn.cancelled` followed by `session.waiting`, so the session is safe to continue.
204
214
 
@@ -216,18 +226,14 @@ received attachment as a `file` part on the user message. The part includes `med
216
226
 
217
227
  ## Human-in-the-loop prompts
218
228
 
219
- Tools opt into approval with `approval`, and workflow tools such as the opt-in `ask_question` tool ask the user a question with `ctx.ask()` — see [Human-in-the-loop](/docs/human-in-the-loop) for the server-side model. Either way the stream emits an `input.requested` event, and the pending request rides on a `dynamic-tool` part at `part.toolMetadata?.eve?.inputRequest`. Scan every message because an unrelated turn can add newer messages while an approval stays open, then answer through the same session with `respond()`:
229
+ Tools opt into approval with `approval`, and workflow tools such as the opt-in `ask_question` tool ask the user a question with `ctx.ask()` — see [Human-in-the-loop](/docs/human-in-the-loop) for the server-side model. Either way the stream emits an `input.requested` event. The default projection keeps open requests in `data.inputs`, including a request that sits on an earlier message than the latest one. Render from that ledger and answer through the same session with `respond()`. The request also appears on its originating `dynamic-tool` part at `part.toolMetadata?.eve?.inputRequest` for inline display:
220
230
 
221
231
  ```tsx
222
- const pendingRequests = agent.data.messages
223
- .flatMap((message) => message.parts)
224
- .flatMap((part) => {
225
- if (part.type !== "dynamic-tool" || part.state !== "approval-requested") return [];
226
- const request = part.toolMetadata?.eve?.inputRequest;
227
- return request ? [request] : [];
228
- });
232
+ import { openConversationInputs } from "eve/react";
233
+
234
+ const pendingRequests = openConversationInputs(agent.data).map((input) => input.request);
229
235
 
230
- const inputDisabled = ["submitted", "streaming", "resuming"].includes(agent.status);
236
+ const inputDisabled = agent.status === "resuming";
231
237
 
232
238
  return pendingRequests.map((request) => (
233
239
  <fieldset disabled={inputDisabled} key={request.requestId}>
@@ -252,11 +258,11 @@ return pendingRequests.map((request) => (
252
258
  ));
253
259
  ```
254
260
 
255
- For a question with `allowFreeform`, render a text input and send `{ requestId, text }`. The default reducer keeps each request pending until the server confirms its resolution through `input.resolved` or `approval.settled`. Disable input controls while the response is being processed; a refused approval attempt leaves the request answerable. Approved tools update again when eve streams their result.
261
+ For a question with `allowFreeform`, render a text input and send `{ requestId, text }`. You can answer while other work runs. For example, when one model step asks to approve two tools, the first approval settles on its own and the second stays answerable while the batch waits for it. `respond()` marks each answered request `responded` in `data.inputs` until the server settles it through `approval.settled` or `input.resolved`, so `openConversationInputs()` no longer returns it. Answering a request that is no longer open rejects without contacting the server. A refused approval attempt, or a response that never reaches the server, reopens the request. Approved tools update again when eve streams their result.
256
262
 
257
263
  ## Authorization prompts
258
264
 
259
- Connections and tools that need OAuth or another grant emit `authorization.required`. The default reducer projects that into an `authorization` message part with the display name, instructions, device code, and user-facing sign-in URL. Render that part as a normal chat message, then keep the session cursor; eve resumes the parked turn when the callback completes and updates the part after `authorization.completed`:
265
+ Connections and tools that need OAuth or another grant emit `authorization.required`. The default reducer projects that into an `authorization` message part with the display name, instructions, device code, and user-facing sign-in URL. When multiple people authorize the same connection in one session, the client matches completion to the corresponding `attemptId`, not merely the connection name. The part stays `required` until eve reports the outcome, then becomes `completed`. `awaitsCallback` is `true` when the sign-in's callback settles the attempt and resumes the parked turn. Render the part as a normal chat message and keep the session cursor so eve can resume the parked turn:
260
266
 
261
267
  ```tsx
262
268
  import type { EveMessagePart } from "eve/react";
@@ -284,7 +290,7 @@ function AuthorizationPrompt({ part }: { part: EveMessagePart }) {
284
290
  }
285
291
  ```
286
292
 
287
- For fully custom state machines, `authorization.required` and `authorization.completed` are still available on `events` and `onEvent`.
293
+ With a custom reducer, authorization attempts remain available in `conversation.messages`; `authorization.required` and `authorization.completed` are also available on `events` and `onEvent`.
288
294
 
289
295
  ## Attach page context per turn
290
296
 
@@ -324,11 +330,11 @@ const agent = useEveAgent({
324
330
  });
325
331
  ```
326
332
 
327
- The `optimistic` option (default `true`) projects submitted user messages into `data` before eve confirms them with a `message.received` event. These are reducer-facing projection events only. `events` stays the authoritative eve stream. For an existing session, the hook reconciles each placeholder with the server's delivery ID, so an unrelated or identical message cannot consume it.
333
+ The `optimistic` option (default `true`) projects submitted user messages into `data` before eve confirms them with a `message.received` event. Steered follow-ups appear before the active turn's assistant response once the turn is known; if the send fails, the failed placeholder stays in place. These are reducer-facing projection events only. `events` stays the authoritative eve stream. For an existing session, the hook reconciles each placeholder with the server's delivery ID, so an unrelated or identical message cannot consume it.
328
334
 
329
335
  ## Custom reducer
330
336
 
331
- The default reducer projects events into `{ messages }` (`EveMessageData`). When you want `data` shaped differently, pass a `reducer` implementing `EveAgentReducer<TData>`:
337
+ The default hook uses `conversationReducer`, which includes the `EveMessageData` message fields plus turn and input state (`ConversationState`). When you want `data` shaped differently, pass a `reducer` implementing `EveAgentReducer<TData>`:
332
338
 
333
339
  ```tsx
334
340
  import { useEveAgent } from "eve/react";
@@ -345,10 +351,10 @@ const toolCounter: EveAgentReducer<ToolLog> = {
345
351
  };
346
352
 
347
353
  const agent = useEveAgent({ reducer: toolCounter });
348
- // agent.data is ToolLog
354
+ // agent.data is ToolLog; agent.conversation remains ConversationState.
349
355
  ```
350
356
 
351
- `reduce(data, event)` receives both authoritative eve stream events and client projection events (`client.message.submitted`, `client.message.failed`, `client.input.responded`). `client.input.responded` notifies custom reducers that an answer was submitted, not that it was accepted. The default reducer waits for server settlement; the durable `input.resolved` event records the server-accepted outcome and lets replayed history rebuild the same HITL state. Return `data` unchanged for events your reducer does not handle.
357
+ `reduce(data, event)` receives authoritative eve stream events and client projection events (`client.message.submitted`, `client.message.failed`, `client.input.responded`). The custom reducer only shapes `data`: the client maintains `conversation` separately for authorization, input requests, turns, and child following. Agent-session observations update `conversation.agents`, not the custom reducer. The built-in reducer makes `data` and `conversation` the same state. `client.input.responded` tells a custom reducer an answer was submitted, not that the server accepted it; the durable `input.resolved` event confirms settlement. Return `data` unchanged for events your reducer does not handle.
352
358
 
353
359
  ## Resumable sessions
354
360
 
@@ -62,21 +62,15 @@ Call `agent.send(text)` for text or pass content parts for attachments. The API
62
62
 
63
63
  ## Human-in-the-loop prompts
64
64
 
65
- Pending requests appear in `agent.data.messages`. Use the Svelte exports when narrowing message parts, then answer through `agent.respond()`:
65
+ Open requests appear in the `agent.data.inputs` ledger. Read them with `openConversationInputs()`, then answer through `agent.respond()`. An answered request leaves the list right away, so its buttons can't be pressed twice:
66
66
 
67
67
  ```svelte
68
68
  <script lang="ts">
69
- import { useEveAgent } from "eve/svelte";
69
+ import { openConversationInputs, useEveAgent } from "eve/svelte";
70
70
 
71
71
  const agent = useEveAgent();
72
72
  const pendingRequests = $derived(
73
- agent.data.messages.flatMap((message) =>
74
- message.parts.flatMap((part) => {
75
- if (part.type !== "dynamic-tool" || part.state !== "approval-requested") return [];
76
- const request = part.toolMetadata?.eve?.inputRequest;
77
- return request ? [request] : [];
78
- }),
79
- ),
73
+ openConversationInputs(agent.data).map((input) => input.request),
80
74
  );
81
75
  </script>
82
76
 
@@ -128,7 +122,7 @@ Pass `onEvent`, `onError`, `onFinish`, or `onSessionChange` when the application
128
122
 
129
123
  ## Custom reducer
130
124
 
131
- Import `EveAgentReducer` from `eve/svelte` when projecting events into application-specific state. The resulting `agent.data` uses the reducer's `TData` type. See [Custom reducer](./overview#custom-reducer) for the reducer contract and client projection events.
125
+ Import `EveAgentReducer` from `eve/svelte` when projecting events into application-specific state. The resulting `agent.data` uses the reducer's `TData` type; `agent.conversation` remains `ConversationState`. See [Custom reducer](./overview#custom-reducer) for the reducer contract and client projection events.
132
126
 
133
127
  ## What to read next
134
128
 
@@ -61,23 +61,17 @@ Call `send(text)` for text or pass content parts for attachments. The API and tr
61
61
 
62
62
  ## Human-in-the-loop prompts
63
63
 
64
- Pending requests appear in `data.value.messages`. Use the Vue exports when narrowing message parts, then answer through `respond()`:
64
+ Open requests appear in the `data.value.inputs` ledger. Read them with `openConversationInputs()`, then answer through `respond()`. An answered request leaves the list right away, so its buttons can't be pressed twice:
65
65
 
66
66
  ```vue
67
67
  <script setup lang="ts">
68
68
  import { computed } from "vue";
69
- import { useEveAgent } from "eve/vue";
69
+ import { openConversationInputs, useEveAgent } from "eve/vue";
70
70
 
71
71
  const { data, respond } = useEveAgent();
72
72
 
73
73
  const pendingRequests = computed(() =>
74
- data.value.messages.flatMap((message) =>
75
- message.parts.flatMap((part) => {
76
- if (part.type !== "dynamic-tool" || part.state !== "approval-requested") return [];
77
- const request = part.toolMetadata?.eve?.inputRequest;
78
- return request ? [request] : [];
79
- }),
80
- ),
74
+ openConversationInputs(data.value).map((input) => input.request),
81
75
  );
82
76
  </script>
83
77
 
@@ -130,7 +124,7 @@ Pass `onEvent`, `onError`, `onFinish`, or `onSessionChange` when the application
130
124
 
131
125
  ## Custom reducer
132
126
 
133
- Import `EveAgentReducer` from `eve/vue` when projecting events into application-specific state. The resulting `data` remains a `ComputedRef<TData>`. See [Custom reducer](./overview#custom-reducer) for the reducer contract and client projection events.
127
+ Import `EveAgentReducer` from `eve/vue` when projecting events into application-specific state. The resulting `data` remains a `ComputedRef<TData>`; `conversation` remains a `ComputedRef<ConversationState>` regardless of your reducer. See [Custom reducer](./overview#custom-reducer) for the reducer contract and client projection events.
134
128
 
135
129
  ## What to read next
136
130
 
@@ -139,12 +139,30 @@ invoke_agent <agent>
139
139
  └── execute_tool <tool>
140
140
  ```
141
141
 
142
- Each turn starts a new trace. The first subagent trace links to its caller with
143
- `eve.link.type=agent.dispatch`; the link is not an authorization grant. For a
144
- remote agent, `trustedForwarders` lets the receiver accept the sender's session
145
- lineage and trace-content policy. See [Remote agents](../guides/remote-agents#preserving-trace-content).
146
- Use `gen_ai.conversation.id` to find the traces for one conversation in your
147
- destination's span-search surface.
142
+ Each root agent turn starts a new trace. If eve receives a local caller's trace
143
+ context, the first local subagent turn uses that trace. Its span is a
144
+ child of the dispatch span and has a different span ID. Without caller trace
145
+ context, the first subagent turn starts a new trace. Later turns in the child
146
+ session start new traces. They do not use the original dispatch span as their
147
+ parent.
148
+
149
+ A remote child starts a separate trace with a root `invoke_agent` span. Its first
150
+ turn links to the caller with `eve.link.type=agent.dispatch`. The receiving
151
+ deployment applies its sampler. Queries for local dispatches must use
152
+ `parentSpanId` or `agent.parent_run.id` and `agent.parent_call.id` instead of a
153
+ dispatch link.
154
+
155
+ Use `gen_ai.conversation.id` to find the root session and its child sessions
156
+ across traces. eve adds this ID to spans created during model, tool, and memory
157
+ execution. This includes spans from third-party instrumentation. `agent.run.id`
158
+ identifies one agent session, not the full conversation.
159
+
160
+ The shared conversation ID does not give access to message history, agent state,
161
+ or credentials. It does not give authorization or require the same worker for
162
+ each turn. Remote requests carry the conversation ID in W3C Baggage.
163
+ `trustedForwarders` controls whether the receiver accepts parent session data
164
+ and the trace-content policy. See
165
+ [Remote agents](../guides/remote-agents#preserving-trace-content).
148
166
 
149
167
  ## Local traces
150
168
 
@@ -59,9 +59,16 @@ remain lazy and resolve before each outbound request without entering durable
59
59
  workflow state.
60
60
 
61
61
  Author `auth` and `headers` directly in the `defineRemoteAgent({ ... })` object
62
- and keep their functions self-contained with module imports or environment
63
- variables. They are rehydrated outside the event handler, so they cannot close
64
- over `_event`, `ctx`, or handler-local values.
62
+ and keep their functions self-contained with module imports, module-level
63
+ constants, or environment variables. They are rehydrated outside the event
64
+ handler, so they cannot close over `_event`, `ctx`, or handler-local values. The
65
+ build fails with an error that names the handler-local value when they do.
66
+
67
+ eve compiles only `auth` and `headers` written directly in the
68
+ `defineRemoteAgent({ ... })` object in the subagent file. When they arrive
69
+ through a spread, a variable passed as the argument, or a definition built in
70
+ another module, eve rejects the definition at runtime, logs the error, and runs
71
+ the agent without that subagent.
65
72
 
66
73
  ## Runtime URLs
67
74
 
@@ -141,16 +148,27 @@ Forwarding identity is explicit on both sides. The receiver names which deployme
141
148
 
142
149
  ## Trace propagation
143
150
 
144
- Each remote turn starts a new trace. eve links the child trace to the
145
- dispatching turn and carries `gen_ai.conversation.id` so you can find the
146
- traces for one conversation. Trace context is observability metadata, not an
147
- authorization grant. See [OpenTelemetry](../observability/otel#trace-topology)
148
- for the trace topology.
151
+ A remote child starts its own trace with a root `invoke_agent` span. When caller
152
+ trace context is available, the first turn links to the dispatch span with
153
+ `eve.link.type=agent.dispatch`. The receiving deployment applies its sampler.
154
+ Later turns start new traces without the original dispatch link. The first turn
155
+ of a local child can use the remote agent's trace as a nested span.
156
+
157
+ Use `gen_ai.conversation.id` to find all turns and child sessions for one
158
+ conversation. The child has its own session ID, message history, and agent
159
+ state. Trace context identifies related work. It does not give authorization.
160
+ See [OpenTelemetry](../observability/otel#trace-topology) for the trace structure.
149
161
 
150
162
  eve carries parent session lineage separately. The receiver accepts it only
151
163
  when `trustedForwarders` approves the authenticated caller; otherwise, trace
152
164
  correlation continues without it.
153
165
 
166
+ On Vercel, a remote agent's spans and its local subagents' spans carry the
167
+ remote session's ID as `vercel.session_id`, so the receiving project groups
168
+ them as their own session. `gen_ai.conversation.id` still names the sender's
169
+ conversation, and the remote agent's `agent.parent_run.id` names the calling
170
+ session.
171
+
154
172
  ## Preserving trace content
155
173
 
156
174
  With `forwardPrincipal: true`, a sampled remote dispatch forwards its original
@@ -276,7 +276,7 @@ Starts a local development server and terminal UI. To connect the UI to an exist
276
276
  | `--connection-auth <mode>` | enum | `full` | Connection-authorization rendering |
277
277
  | `--assistant-response-stats <mode>` | enum | `tokensPerSecond` | Assistant header statistic |
278
278
  | `--context-size <tokens>` | number | none | Model context window size |
279
- | `--logs <mode>` | enum | `stderr` | Server and agent logs to show |
279
+ | `--logs <mode>` | enum | `error` | Display `none`, `error`, `warn`, `debug`, or `all` logs |
280
280
 
281
281
  Local development mounts bundled development extensions without adding files to your project. Pass `--no-default-extensions` to disable them. See [Self-Modification](../guides/self-modification) for details.
282
282
 
@@ -391,13 +391,13 @@ Reads the immutable OTLP/JSON segments under `.eve/traces/v1`, so `eve dev` need
391
391
 
392
392
  Span rows carry inline metrics when the span recorded them — `↑input`/`↓output` token counts, gateway cost, and the tool name for `execute_tool` spans. The header lists models across the trace, sums token usage and cost from step spans, and counts all error-bearing spans. `--verbose` expands each span under its tree row: status (with the error message on failures), timing, ids, every attribute (prompts, responses, and tool payloads as transcripts or pretty-printed JSON), and every span event with its offset from span start. `--json` prints the same records as JSON, one object per selected trace.
393
393
 
394
- Every subagent activation starts its own trace. The first child's `invoke_agent` root links to the dispatching caller with `eve.link.type=agent.dispatch`; remote agents preserve that caller in W3C `tracestate` even when HTTP `traceparent` advances through platform ingress. Later turns also start fresh traces without repeating the initial caller link. All related sessions retain the same `gen_ai.conversation.id`, and `agent.subagent.name` labels the child invocation.
394
+ With local caller trace context, the first local subagent turn uses the caller's trace. Its span is a child of the dispatch span. A remote child starts a separate root trace and links its first turn to the dispatch with `eve.link.type=agent.dispatch`. Remote requests use W3C `tracestate` to identify that dispatch span if platform HTTP handling changes `traceparent`. Later child turns start new traces. All related sessions have the same `gen_ai.conversation.id`. `agent.subagent.name` identifies the subagent.
395
395
 
396
- Each workflow tool call has one `agent.action` span and keeps its `execute_tool <tool>` span. Sessions the tool opens with `ctx.agent` link to that call's `agent.action` span as their dispatching caller; individual `ctx.agent` calls get no span of their own. Only agent execution uses `invoke_agent`.
396
+ Each workflow tool call has an `agent.action` span and an `execute_tool <tool>` span. The first turn of each local session it opens with `ctx.agent` is a child of the call's `agent.action` span. A remote session links to that action from its own trace. An individual `ctx.agent` call does not create a separate dispatch span. Only agent execution uses `invoke_agent`.
397
397
 
398
398
  Outbound MCP `tools/call` requests add MCP semantic attributes to the matching `execute_tool` span. When eve has no tool span to enrich, it creates a `CLIENT` `tools/call <tool>` span. Each `tools/list` discovery also has a `CLIENT` span. Configured OpenTelemetry propagation fields are injected into MCP `params._meta` for JSON-RPC bodies up to 1 MiB and propagation metadata up to 8 KiB; larger requests are sent unchanged. eve removes its audience and session-lineage baggage before forwarding, and keeps the input/output content-capture policy local.
399
399
 
400
- A durable conversation produces one bounded trace per turn. Worker replacements reuse the prepared context for the same turn, while a later turn or an independently replayed attempt starts a fresh trace. Passing the conversation ID shows every trace it produced, oldest first.
400
+ Each root agent turn starts a new trace. With local caller trace context, that trace includes the first turn of each local subagent it starts. Remote child turns and later local child turns start separate traces. If a worker is replaced, the new worker uses the prepared trace context for the same turn. Supply the conversation ID to show all related traces, oldest first.
401
401
 
402
402
  Every span carries a real duration. A turn's root `invoke_agent` span is written when the turn settles, so a running turn shows only its steps.
403
403
 
@@ -9,7 +9,7 @@ Human-in-the-loop (HITL) is any point where the agent durably pauses and waits f
9
9
  - **Approvals** — a tool policy allows, denies, or pauses a call for a person to review. The agent decides to call the tool; the policy decides whether it runs automatically or needs a human decision.
10
10
  - **Questions** — the agent itself asks the user a clarifying question or a choice mid-turn, and parks until they answer.
11
11
 
12
- An approval ends the turn and the session parks at `session.waiting`. A question keeps the turn open, and the stream reports `turn.waiting`. Either way the run waits durably, for as long as it takes — seconds or days — and picks back up exactly where it left off once the answer arrives. Channels render the request for you.
12
+ Both keep the turn open, and the stream reports `turn.waiting`. The run waits durably, for as long as it takes — seconds or days — and picks back up exactly where it left off once the answer arrives. Channels render the request for you.
13
13
 
14
14
  ## Approvals
15
15
 
@@ -212,7 +212,7 @@ Approvals and questions share one protocol:
212
212
 
213
213
  1. A tool call needs approval, or a workflow tool such as `ask_question` calls `ctx.ask()`.
214
214
  2. eve emits an `input.requested` stream event carrying the pending requests.
215
- 3. The run parks durably, for as long as it takes. An approval ends the turn with `turn.completed`, then `session.waiting`. A question keeps the turn open: the stream emits `turn.waiting`, and after the answer the turn resumes under the same `turnId`.
215
+ 3. The run parks durably, for as long as it takes. The turn stays open: the stream emits `turn.waiting`, and after the answer the turn resumes under the same `turnId`. That `turn.waiting` carries `on: "input"`, since a person must act.
216
216
  4. The client answers with `inputResponses` (structured, keyed by `requestId`) or a normal follow-up `message`. A follow-up whose text matches an option ID, option label, or numeric option index resolves automatically, including approval options such as `approve` and `cancel`.
217
217
 
218
218
  For `ctx.ask()` questions from tools, a follow-up message answers the question only when exactly one question is pending. The message must match an option, or the question must allow free text. Otherwise the message follows the session's `turnPolicy`. A steering message, the default, aborts the `ctx.abortSignal` of each `execute` workflow tool call the turn waits on, so a question such a call asked, such as `ask_question`'s, is withdrawn and resolves as `cancelled`. The model reads the message once those calls settle. Questions from subagents need a structured response.
@@ -226,7 +226,7 @@ The run picks back up exactly where it parked. Because the pause is durable, not
226
226
 
227
227
  When a subagent requests input, eve emits the same `input.requested` event on its parent session. Answering through that parent session routes the response directly to the blocked child without invoking the parent model.
228
228
 
229
- For approval requests, unrelated follow-up text does not deny the tool call. eve keeps the approval pending and records that pending state in model-visible session history. Follow-up turns run normally and may call other tools while the approval remains unresolved. Once it is answered, eve settles the original tool call exactly once.
229
+ For approval requests, a follow-up message that doesn't match an option steers the turn instead of answering it. eve cancels the turn's pending approval, so the call doesn't run and `input.resolved` reports `outcome: "ignored"`, and the model reads the message next. This happens even when the message is sent with `turnPolicy: "queue"`, because a turn held on a person can't end until they act. Calls the person already approved in the same batch still run. A message from someone other than the person the turn serves waits until the turn ends. Cancelling the turn withdraws its approval: the call doesn't run, `input.resolved` reports `outcome: "cancelled"`, and a later answer to it approves nothing.
230
230
 
231
231
  See [Sessions, runs & streaming](/docs/concepts/sessions-runs-and-streaming) for the full event and resume contract that this builds on.
232
232
 
@@ -236,7 +236,7 @@ Channels turn requests into native UI: the Slack adapter renders approvals as bu
236
236
 
237
237
  From your own frontend, scan all messages for pending requests and answer through the same session — see [Building a frontend](/docs/guides/frontend/overview#human-in-the-loop-prompts) for the client-side reducer and `inputResponses` shape.
238
238
 
239
- The default message reducer waits for server confirmation before marking any input request answered. Use the store's `submitted` or `streaming` status to show that a response is being processed; submitting a response alone does not resolve an approval, question, or session-limit prompt. The `client.input.responded` event remains a submission notification for custom reducers, not confirmation that the server accepted the answer.
239
+ You can answer while a turn is running, such as the second approval of a batch while the first answer is still settling. The default message reducer waits for server confirmation before marking any input request answered. A submitted answer marks its request `responded` in `data.inputs` until `approval.settled` or `input.resolved` arrives; submitting a response alone does not resolve an approval, question, or session-limit prompt. Answering a request that is no longer open rejects without a server request. The `client.input.responded` event remains a submission notification for custom reducers, not confirmation that the server accepted the answer.
240
240
 
241
241
  ## What to read next
242
242
 
@@ -126,7 +126,7 @@ export default defineTool({
126
126
  });
127
127
  ```
128
128
 
129
- The label is presentation only. It does not replace the path-derived tool name, enter model input, or change execution. eve records the bounded label on the corresponding public action event so activity renderers and other authorized stream consumers can use it without interpreting raw tool data. Built-in channel activity can show `Deploy storefront to production` instead of `deploy`; if the callback throws or returns an empty label, activity falls back to the tool name.
129
+ The label is presentation only. It does not replace the path-derived tool name, enter model input, or change execution. eve records the bounded label on the corresponding public action event so activity renderers and other authorized stream consumers can use it without interpreting raw tool data. Built-in channel activity can show `Deploy storefront to production` instead of `Deploy`; if the callback throws or returns an empty label, activity falls back to a readable form of the tool name, such as `Sync accounts` for `sync_accounts`.
130
130
 
131
131
  Provided tools define labels for `bash`, `glob`, `grep`, `load_skill`, `read_file`, `web_fetch`, `web_search`, and `write_file`.
132
132