eve 0.47.7 → 0.48.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 (271) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/src/channel/delivery-metadata.d.ts +1 -0
  3. package/dist/src/channel/delivery-metadata.js +1 -1
  4. package/dist/src/channel/types.d.ts +10 -8
  5. package/dist/src/chunks/{use-eve-agent-Dg5S44kG.js → use-eve-agent-BZnOzAVd.js} +25 -5
  6. package/dist/src/chunks/{use-eve-agent-B5zw1dwj.js → use-eve-agent-Bgp6INfi.js} +25 -5
  7. package/dist/src/cli/commands/init.js +1 -1
  8. package/dist/src/cli/commands/integration-connect.d.ts +2 -1
  9. package/dist/src/cli/commands/integration-connect.js +1 -1
  10. package/dist/src/cli/commands/register-integration-commands.d.ts +3 -1
  11. package/dist/src/cli/commands/register-integration-commands.js +1 -1
  12. package/dist/src/cli/dev/command-options.d.ts +2 -0
  13. package/dist/src/cli/dev/run-interactive-ui.js +1 -1
  14. package/dist/src/cli/dev/tui/blocks.js +1 -1
  15. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  16. package/dist/src/cli/dev/tui/registry-result-message.d.ts +17 -0
  17. package/dist/src/cli/dev/tui/registry-result-message.js +3 -0
  18. package/dist/src/cli/dev/tui/runner.d.ts +11 -4
  19. package/dist/src/cli/dev/tui/runner.js +1 -1
  20. package/dist/src/cli/dev/tui/setup-commands.d.ts +9 -3
  21. package/dist/src/cli/dev/tui/setup-commands.js +2 -3
  22. package/dist/src/cli/dev/tui/setup-flow.d.ts +15 -5
  23. package/dist/src/cli/dev/tui/setup-panel.d.ts +6 -1
  24. package/dist/src/cli/dev/tui/setup-panel.js +4 -4
  25. package/dist/src/cli/dev/tui/setup-selection-input.d.ts +1 -0
  26. package/dist/src/cli/dev/tui/setup-selection-input.js +1 -1
  27. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
  28. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  29. package/dist/src/cli/dev/tui/tui.d.ts +3 -4
  30. package/dist/src/cli/dev/tui/tui.js +1 -1
  31. package/dist/src/cli/run.js +2 -2
  32. package/dist/src/client/agent-info-schema.d.ts +1 -0
  33. package/dist/src/client/agent-info-schema.js +1 -1
  34. package/dist/src/client/open-stream.d.ts +1 -0
  35. package/dist/src/client/open-stream.js +1 -1
  36. package/dist/src/client/session.js +1 -1
  37. package/dist/src/compiled/.vendor-stamp.json +2 -1
  38. package/dist/src/compiled/@opentelemetry/api/index.d.ts +6 -0
  39. package/dist/src/compiled/@workflow/builders/LICENSE.md +201 -0
  40. package/dist/src/compiled/@workflow/builders/index.d.ts +62 -0
  41. package/dist/src/compiled/@workflow/builders/index.js +1 -0
  42. package/dist/src/compiler/extension-compatibility.d.ts +2 -2
  43. package/dist/src/compiler/extension-compatibility.js +1 -1
  44. package/dist/src/compiler/manifest.d.ts +2 -2
  45. package/dist/src/compiler/manifest.js +1 -1
  46. package/dist/src/compiler/normalize-tool.js +1 -1
  47. package/dist/src/context/keys.d.ts +3 -8
  48. package/dist/src/eve-channel/index.js +1 -1
  49. package/dist/src/eve-channel/types.d.ts +7 -7
  50. package/dist/src/execution/accepted-delivery-deployment.d.ts +7 -0
  51. package/dist/src/execution/accepted-delivery-deployment.js +1 -0
  52. package/dist/src/execution/cancel-descendant-turns-step.d.ts +4 -1
  53. package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
  54. package/dist/src/execution/delegation-tool.js +1 -1
  55. package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +7 -2
  56. package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -1
  57. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  58. package/dist/src/execution/dispatch-turn-step.js +1 -1
  59. package/dist/src/execution/durable-session-migrations/turn-workflow-v1-to-v2.d.ts +2 -0
  60. package/dist/src/execution/durable-session-migrations/turn-workflow-v1-to-v2.js +1 -0
  61. package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +25 -3
  62. package/dist/src/execution/durable-session-migrations/turn-workflow.js +1 -1
  63. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  64. package/dist/src/execution/finalize-terminal-session.d.ts +17 -0
  65. package/dist/src/execution/finalize-terminal-session.js +1 -0
  66. package/dist/src/execution/inline-turn.d.ts +29 -0
  67. package/dist/src/execution/inline-turn.js +1 -0
  68. package/dist/src/execution/next-driver-action.d.ts +4 -0
  69. package/dist/src/execution/node-step.js +1 -1
  70. package/dist/src/execution/parked-delivery-wait.js +1 -1
  71. package/dist/src/execution/pending-turn-state.d.ts +1 -0
  72. package/dist/src/execution/pending-turn-state.js +1 -1
  73. package/dist/src/execution/proxied-deliver-step.js +1 -1
  74. package/dist/src/execution/remote-agent-dispatch.d.ts +2 -0
  75. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  76. package/dist/src/execution/session-command-token.d.ts +2 -0
  77. package/dist/src/execution/session-command-token.js +1 -1
  78. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  79. package/dist/src/execution/stable-workflow-names.d.ts +12 -0
  80. package/dist/src/execution/stable-workflow-names.js +1 -0
  81. package/dist/src/execution/subagent-event-proxy-step.d.ts +3 -0
  82. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  83. package/dist/src/execution/subagent-hitl-proxy.d.ts +2 -1
  84. package/dist/src/execution/subagent-hitl-proxy.js +1 -1
  85. package/dist/src/execution/subagent-start-remote.d.ts +2 -0
  86. package/dist/src/execution/subagent-start-remote.js +1 -1
  87. package/dist/src/execution/tasks/child/steps.d.ts +2 -0
  88. package/dist/src/execution/tasks/child/steps.js +1 -1
  89. package/dist/src/execution/tasks/child/workflow.js +1 -1
  90. package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -1
  91. package/dist/src/execution/tasks/parent/dispatch.js +1 -1
  92. package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
  93. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  94. package/dist/src/execution/terminal-session-completion-step.js +1 -1
  95. package/dist/src/execution/terminal-session-event.d.ts +13 -0
  96. package/dist/src/execution/terminal-session-event.js +1 -0
  97. package/dist/src/execution/terminal-session-failure-step.d.ts +1 -0
  98. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  99. package/dist/src/execution/tool-run/answer.d.ts +3 -0
  100. package/dist/src/execution/tool-run/answer.js +1 -0
  101. package/dist/src/execution/tool-run/background.d.ts +14 -0
  102. package/dist/src/execution/tool-run/background.js +1 -0
  103. package/dist/src/execution/tool-run/cancel.d.ts +7 -0
  104. package/dist/src/execution/tool-run/cancel.js +1 -0
  105. package/dist/src/execution/tool-run/dispatch.d.ts +24 -0
  106. package/dist/src/execution/tool-run/dispatch.js +1 -0
  107. package/dist/src/execution/tool-run/emit-run-report-step.d.ts +7 -0
  108. package/dist/src/execution/tool-run/emit-run-report-step.js +1 -0
  109. package/dist/src/execution/tool-run/messages.d.ts +70 -0
  110. package/dist/src/execution/tool-run/messages.js +1 -0
  111. package/dist/src/execution/tool-run/owner-channels.d.ts +29 -0
  112. package/dist/src/execution/tool-run/owner-channels.js +1 -0
  113. package/dist/src/execution/tool-run/owner-inbox.d.ts +11 -0
  114. package/dist/src/execution/tool-run/owner-inbox.js +1 -0
  115. package/dist/src/execution/tool-run/owner.d.ts +13 -0
  116. package/dist/src/execution/tool-run/owner.js +1 -0
  117. package/dist/src/execution/tool-run/resume-hook-step.d.ts +4 -0
  118. package/dist/src/execution/tool-run/resume-hook-step.js +1 -0
  119. package/dist/src/execution/tool-run/run-control.d.ts +18 -0
  120. package/dist/src/execution/tool-run/run-control.js +1 -0
  121. package/dist/src/execution/tool-run/start.d.ts +11 -0
  122. package/dist/src/execution/tool-run/start.js +1 -0
  123. package/dist/src/execution/tool-run/types.d.ts +21 -0
  124. package/dist/src/execution/tool-run/types.js +1 -0
  125. package/dist/src/execution/tool-run/workflow.d.ts +9 -0
  126. package/dist/src/execution/tool-run/workflow.js +1 -0
  127. package/dist/src/execution/tools/subagent/local.js +1 -1
  128. package/dist/src/execution/turn-cancellation-control.d.ts +2 -0
  129. package/dist/src/execution/turn-cancellation-control.js +1 -1
  130. package/dist/src/execution/turn-control-receiver.js +1 -1
  131. package/dist/src/execution/turn-dispatch.d.ts +4 -2
  132. package/dist/src/execution/turn-dispatch.js +1 -1
  133. package/dist/src/execution/turn-execution-cursor.js +1 -1
  134. package/dist/src/execution/turn-workflow.js +1 -1
  135. package/dist/src/execution/wire/session-inbox-contract.d.ts +2 -2
  136. package/dist/src/execution/wire/session-inbox-contract.js +1 -1
  137. package/dist/src/execution/wire/session-inbox-encoder.d.ts +6 -2
  138. package/dist/src/execution/wire/session-inbox-encoder.js +1 -1
  139. package/dist/src/execution/wire/session-inbox-resume.js +1 -1
  140. package/dist/src/execution/wire/session-inbox-wire.js +1 -1
  141. package/dist/src/execution/wire/session-inbox-wire.v1.js +1 -1
  142. package/dist/src/execution/wire/session-inbox-wire.v2-migration.d.ts +0 -2
  143. package/dist/src/execution/wire/session-inbox-wire.v2-migration.js +1 -1
  144. package/dist/src/execution/wire/session-inbox-wire.v2.migration.d.ts +3 -0
  145. package/dist/src/execution/wire/session-inbox-wire.v2.migration.js +1 -0
  146. package/dist/src/execution/wire/session-inbox-wire.v3.d.ts +480 -0
  147. package/dist/src/execution/wire/session-inbox-wire.v3.js +1 -0
  148. package/dist/src/execution/wire/session-inbox-wire.v3.migration.d.ts +3 -0
  149. package/dist/src/execution/wire/session-inbox-wire.v3.migration.js +1 -0
  150. package/dist/src/execution/workflow-entry-finalization.js +1 -1
  151. package/dist/src/execution/workflow-entry.js +1 -1
  152. package/dist/src/execution/workflow-registry.d.ts +5 -0
  153. package/dist/src/execution/workflow-registry.js +1 -0
  154. package/dist/src/execution/workflow-runtime.d.ts +9 -11
  155. package/dist/src/execution/workflow-runtime.js +1 -1
  156. package/dist/src/execution/workflow-steps.js +1 -1
  157. package/dist/src/execution/workflow-webhook-route.d.ts +4 -0
  158. package/dist/src/execution/workflow-webhook-route.js +1 -0
  159. package/dist/src/harness/attachment-staging.js +1 -1
  160. package/dist/src/harness/emission.js +1 -1
  161. package/dist/src/harness/proxy-input-requests.d.ts +10 -0
  162. package/dist/src/harness/proxy-input-requests.js +1 -1
  163. package/dist/src/harness/runtime-actions.d.ts +2 -0
  164. package/dist/src/harness/runtime-actions.js +1 -1
  165. package/dist/src/harness/session-limit-enforcement.js +1 -1
  166. package/dist/src/harness/tool-loop.js +2 -2
  167. package/dist/src/harness/tool-runs.d.ts +21 -0
  168. package/dist/src/harness/tool-runs.js +1 -0
  169. package/dist/src/harness/tools.js +1 -1
  170. package/dist/src/instrumentation/content-policy.d.ts +3 -1
  171. package/dist/src/instrumentation/content-policy.js +1 -1
  172. package/dist/src/instrumentation/runtime.d.ts +2 -2
  173. package/dist/src/instrumentation/runtime.js +1 -1
  174. package/dist/src/internal/application/package.js +1 -1
  175. package/dist/src/internal/attachments/errors.d.ts +3 -0
  176. package/dist/src/internal/authored-module-loader.d.ts +7 -1
  177. package/dist/src/internal/authored-module-loader.js +3 -3
  178. package/dist/src/internal/authored-package-boundary.js +1 -1
  179. package/dist/src/internal/authored-runtime-modules.d.ts +2 -0
  180. package/dist/src/internal/authored-runtime-modules.js +1 -1
  181. package/dist/src/internal/nitro/development-generation.d.ts +2 -0
  182. package/dist/src/internal/nitro/development-generation.js +1 -1
  183. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  184. package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
  185. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  186. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  187. package/dist/src/internal/workflow-bundle/authored-workflow-directives.d.ts +17 -0
  188. package/dist/src/internal/workflow-bundle/authored-workflow-directives.js +1 -0
  189. package/dist/src/internal/workflow-bundle/authored-workflow-modules.d.ts +19 -0
  190. package/dist/src/internal/workflow-bundle/authored-workflow-modules.js +1 -0
  191. package/dist/src/internal/workflow-bundle/builder-support.d.ts +17 -2
  192. package/dist/src/internal/workflow-bundle/builder-support.js +4 -3
  193. package/dist/src/internal/workflow-bundle/builder.d.ts +2 -2
  194. package/dist/src/internal/workflow-bundle/builder.js +2 -2
  195. package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.d.ts +2 -0
  196. package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.js +1 -1
  197. package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.d.ts +3 -0
  198. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
  199. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  200. package/dist/src/internal/workflow-bundle/workflow-builders.d.ts +6 -2
  201. package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
  202. package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +3 -0
  203. package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
  204. package/dist/src/internal/workflow-bundle/workflow-directive-ast.d.ts +7 -0
  205. package/dist/src/internal/workflow-bundle/workflow-directive-ast.js +1 -0
  206. package/dist/src/internal/workflow-bundle/workflow-transformer.d.ts +15 -1
  207. package/dist/src/internal/workflow-bundle/workflow-transformer.js +4 -4
  208. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  209. package/dist/src/protocol/baggage.d.ts +6 -0
  210. package/dist/src/protocol/baggage.js +1 -0
  211. package/dist/src/public/channels/slack/attachments.js +1 -1
  212. package/dist/src/public/channels/teams/attachments.d.ts +2 -2
  213. package/dist/src/public/channels/teams/attachments.js +1 -1
  214. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  215. package/dist/src/public/channels/telegram/attachments.js +1 -1
  216. package/dist/src/public/definitions/remote-agent.d.ts +6 -3
  217. package/dist/src/public/workflow/index.d.ts +3 -0
  218. package/dist/src/public/workflow/index.js +1 -0
  219. package/dist/src/public/workflow-modules.d.js +1 -0
  220. package/dist/src/public/workflow-modules.d.ts +11 -0
  221. package/dist/src/runtime/actions/keys.js +1 -1
  222. package/dist/src/runtime/tools/registry.js +1 -1
  223. package/dist/src/setup/connection-connector.d.ts +4 -2
  224. package/dist/src/setup/connection-connector.js +2 -2
  225. package/dist/src/setup/flows/login.js +1 -1
  226. package/dist/src/setup/flows/model.js +1 -1
  227. package/dist/src/setup/flows/provider.d.ts +5 -0
  228. package/dist/src/setup/flows/provider.js +4 -4
  229. package/dist/src/setup/flows/registry-session.d.ts +24 -7
  230. package/dist/src/setup/flows/registry-session.js +1 -1
  231. package/dist/src/setup/flows/registry.d.ts +35 -29
  232. package/dist/src/setup/flows/registry.js +2 -1
  233. package/dist/src/setup/integrations/web/setup.d.ts +0 -2
  234. package/dist/src/setup/integrations/web/setup.js +1 -1
  235. package/dist/src/setup/prompter.d.ts +24 -4
  236. package/dist/src/setup/prompter.js +1 -1
  237. package/dist/src/setup/scaffold/create/project.js +2 -2
  238. package/dist/src/setup/vercel-project.js +0 -0
  239. package/dist/src/shared/dispatch-action.d.ts +6 -0
  240. package/dist/src/shared/forwarded-trace-policy.d.ts +28 -0
  241. package/dist/src/shared/forwarded-trace-policy.js +1 -0
  242. package/dist/src/shared/instrumentation-decision.d.ts +3 -0
  243. package/dist/src/shared/instrumentation-decision.js +1 -1
  244. package/dist/src/svelte/index.js +1 -1
  245. package/dist/src/svelte/use-eve-agent.js +1 -1
  246. package/dist/src/tools/behavior.d.ts +6 -0
  247. package/dist/src/tools/definition.d.ts +39 -3
  248. package/dist/src/tracing/agent-otel-provider.js +2 -2
  249. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  250. package/dist/src/tracing/agent-trace-context-store.d.ts +1 -1
  251. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  252. package/dist/src/tracing/otel-declaration.d.ts +5 -3
  253. package/dist/src/tracing/otel-registration.d.ts +1 -1
  254. package/dist/src/tracing/otel-registration.js +1 -1
  255. package/dist/src/vue/index.js +1 -1
  256. package/dist/src/vue/use-eve-agent.js +1 -1
  257. package/docs/channels/custom.mdx +2 -0
  258. package/docs/channels/eve.mdx +5 -1
  259. package/docs/channels/teams.mdx +6 -1
  260. package/docs/concepts/sessions-runs-and-streaming.md +4 -2
  261. package/docs/guides/auth-and-route-protection.md +5 -1
  262. package/docs/guides/client/messages.mdx +6 -0
  263. package/docs/guides/dev-tui.md +30 -18
  264. package/docs/guides/remote-agents.md +25 -0
  265. package/docs/reference/cli.md +2 -2
  266. package/docs/tools/meta.json +1 -1
  267. package/docs/tools/overview.mdx +7 -0
  268. package/docs/tools/workflows.mdx +288 -0
  269. package/package.json +12 -1
  270. package/dist/src/internal/authored-directive-prologue.d.ts +0 -4
  271. package/dist/src/internal/authored-directive-prologue.js +0 -1
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.82`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.47.7`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,n){let r=parseChatGptModelSelection(e);return r===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(r)}),\n${reasoningTemplateLine(n)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,n){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(n.model)!==void 0?renderAgentTemplate(n.model,n.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,n.appName).replaceAll(`__EVE_INIT_MODEL__`,n.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(n.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(n.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(n.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,n.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,n.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,n.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,n.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,n.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,n.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.82`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.48.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,n){let r=parseChatGptModelSelection(e);return r===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(r)}),\n${reasoningTemplateLine(n)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,n){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(n.model)!==void 0?renderAgentTemplate(n.model,n.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,n.appName).replaceAll(`__EVE_INIT_MODEL__`,n.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(n.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(n.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(n.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,n.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,n.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,n.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,n.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,n.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,n.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -77,7 +77,7 @@ eve deploy
77
77
  "target": "ES2022",
78
78
  "module": "esnext",
79
79
  "moduleResolution": "bundler",
80
- "types": ["node"],
80
+ "types": ["node", "eve/workflow-modules"],
81
81
  "strict": true,
82
82
  "esModuleInterop": true,
83
83
  "skipLibCheck": true,
Binary file
@@ -20,5 +20,11 @@ export type PendingTaskControlAction = PendingDispatchAction & {
20
20
  readonly kind: "task-cancel" | "task-update";
21
21
  }>;
22
22
  };
23
+ /** Pending action that runs a tool's execute body as a durable workflow. */
24
+ export type PendingWorkflowToolAction = PendingDispatchAction & {
25
+ readonly target: Extract<PreparedDispatchTarget, {
26
+ readonly kind: "workflow-tool-call";
27
+ }>;
28
+ };
23
29
  /** Fields common to task-control dispatch and its result projection helpers. */
24
30
  export type TaskControlInvocation = Pick<PendingDispatchAction, "callId" | "input" | "toolName">;
@@ -0,0 +1,28 @@
1
+ import type { ChannelAudience } from "#shared/channel-audience.js";
2
+ import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
3
+ export declare const FAIL_CLOSED_FORWARDED_TRACE_ASSERTION: ForwardedTraceAssertion;
4
+ export interface TraceContentCeiling {
5
+ readonly recordInputs: boolean;
6
+ readonly recordOutputs: boolean;
7
+ }
8
+ export interface ForwardedTraceAssertion {
9
+ readonly ceiling: TraceContentCeiling;
10
+ readonly originAudience: ChannelAudience;
11
+ }
12
+ export interface ResolvedForwardedTraceState {
13
+ readonly decision?: InstrumentationDecision;
14
+ readonly forwardedTracePolicy?: ForwardedTraceAssertion;
15
+ readonly traceFlags: number;
16
+ }
17
+ export interface ForwardedTraceSeedState {
18
+ readonly decision?: unknown;
19
+ readonly forwardedTracePolicy?: unknown;
20
+ readonly traceFlags: number;
21
+ }
22
+ export declare function decisionToTraceContentCeiling(value: unknown): TraceContentCeiling | undefined;
23
+ export declare function traceContentCeilingToDecision(ceiling: TraceContentCeiling): InstrumentationDecision;
24
+ export declare function formatTraceContentCeiling(ceiling: TraceContentCeiling): string;
25
+ /** Applies a distinct live delivery audience without re-capping callback or origin delivery. */
26
+ export declare function applyLiveDeliveryAudienceCeiling(decision: InstrumentationDecision, liveAudience: ChannelAudience, forwardedTracePolicy: ForwardedTraceAssertion | undefined): InstrumentationDecision;
27
+ export declare function readForwardedTraceAssertion(value: unknown): ForwardedTraceAssertion | undefined;
28
+ export declare function resolveForwardedTraceSeed(seed: ForwardedTraceSeedState | undefined, fallbackPolicy?: ForwardedTraceAssertion): ResolvedForwardedTraceState | undefined;
@@ -0,0 +1 @@
1
+ import{applyAudienceCeiling}from"#shared/instrumentation-content.js";import{DROP_INSTRUMENTATION,intersectInstrumentationDecisions,readInstrumentationDecision}from"#shared/instrumentation-decision.js";const FAIL_CLOSED_FORWARDED_TRACE_ASSERTION={ceiling:{recordInputs:!1,recordOutputs:!1},originAudience:`unknown`};function decisionToTraceContentCeiling(e){let t=readInstrumentationDecision(e);return t?.action===`record`?{recordInputs:t.recordInputs,recordOutputs:t.recordOutputs}:void 0}function traceContentCeilingToDecision(e){return{action:`record`,...e}}function formatTraceContentCeiling(e){return`i${e.recordInputs?`1`:`0`}o${e.recordOutputs?`1`:`0`}`}function applyLiveDeliveryAudienceCeiling(t,n,r){return r!==void 0&&(n===`unknown`||n===r.originAudience)?t:applyAudienceCeiling(t,n)}function readForwardedTraceAssertion(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return FAIL_CLOSED_FORWARDED_TRACE_ASSERTION;let t=e,n=t.ceiling;return typeof n!=`object`||!n||typeof n.recordInputs!=`boolean`||typeof n.recordOutputs!=`boolean`||t.originAudience!==`public`&&t.originAudience!==`private`&&t.originAudience!==`unknown`?FAIL_CLOSED_FORWARDED_TRACE_ASSERTION:{ceiling:{recordInputs:n.recordInputs,recordOutputs:n.recordOutputs},originAudience:t.originAudience}}function resolveForwardedTraceState(e){let i=readForwardedTraceAssertion(e.forwardedTracePolicy),a=readInstrumentationDecision(e.decision);if(i!==void 0){let e=traceContentCeilingToDecision(i.ceiling);a=a===void 0?DROP_INSTRUMENTATION:intersectInstrumentationDecisions(a,e)}return{decision:a,forwardedTracePolicy:i,traceFlags:a?.action===`drop`?e.traceFlags&-2:e.traceFlags}}function resolveForwardedTraceSeed(e,t){if(e===void 0)return;let n=Object.prototype.hasOwnProperty.call(e,`forwardedTracePolicy`);return resolveForwardedTraceState({decision:e.decision,forwardedTracePolicy:n?e.forwardedTracePolicy:t,traceFlags:e.traceFlags})}export{FAIL_CLOSED_FORWARDED_TRACE_ASSERTION,applyLiveDeliveryAudienceCeiling,decisionToTraceContentCeiling,formatTraceContentCeiling,readForwardedTraceAssertion,resolveForwardedTraceSeed,traceContentCeilingToDecision};
@@ -6,3 +6,6 @@ export type InstrumentationDecision = {
6
6
  readonly recordOutputs: boolean;
7
7
  };
8
8
  export declare const DROP_INSTRUMENTATION: InstrumentationDecision;
9
+ /** Reads durable decision state, treating malformed persisted values as drop. */
10
+ export declare function readInstrumentationDecision(value: unknown): InstrumentationDecision | undefined;
11
+ export declare function intersectInstrumentationDecisions(left: InstrumentationDecision, right: InstrumentationDecision): InstrumentationDecision;
@@ -1 +1 @@
1
- const DROP_INSTRUMENTATION={action:`drop`};export{DROP_INSTRUMENTATION};
1
+ const DROP_INSTRUMENTATION={action:`drop`};function readInstrumentationDecision(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return DROP_INSTRUMENTATION;let t=e;return t.action===`drop`?DROP_INSTRUMENTATION:t.action===`record`&&typeof t.recordInputs==`boolean`&&typeof t.recordOutputs==`boolean`?{action:`record`,recordInputs:t.recordInputs,recordOutputs:t.recordOutputs}:DROP_INSTRUMENTATION}function intersectInstrumentationDecisions(e,t){return e.action===`drop`||t.action===`drop`?DROP_INSTRUMENTATION:{action:`record`,recordInputs:e.recordInputs&&t.recordInputs,recordOutputs:e.recordOutputs&&t.recordOutputs}}export{DROP_INSTRUMENTATION,intersectInstrumentationDecisions,readInstrumentationDecision};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-Dg5S44kG.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-BZnOzAVd.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-Dg5S44kG.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-BZnOzAVd.js";
2
2
 
3
3
  export { useEveAgent };
@@ -11,6 +11,9 @@ export type CompiledToolHandling = {
11
11
  } | {
12
12
  readonly kind: "request-input";
13
13
  readonly request: "question";
14
+ } | {
15
+ readonly kind: "workflow-tool";
16
+ readonly workflowId: string;
14
17
  };
15
18
  /** Closed, serializable behavior carried by one selected compiled tool. */
16
19
  export interface CompiledToolBehavior {
@@ -35,6 +38,9 @@ export type PreparedDispatchTarget = {
35
38
  readonly kind: "task-cancel";
36
39
  } | {
37
40
  readonly kind: "task-update";
41
+ } | {
42
+ readonly kind: "workflow-tool-call";
43
+ readonly workflowId: string;
38
44
  };
39
45
  /** Runtime-prepared handling consumed by the harness and execution boundary. */
40
46
  export type PreparedToolHandling = {
@@ -5,6 +5,7 @@ import type { SessionContext } from "#context/session-context.js";
5
5
  import type { JsonObject } from "#shared/json.js";
6
6
  import type { TokenResult } from "#shared/connection-types.js";
7
7
  import type { ToolAuthOptions, ToolAuthProvider } from "#tools/auth.js";
8
+ import type { InputOption } from "#shared/input.js";
8
9
  import type { ToolModelOutput } from "#tools/model-output.js";
9
10
  import type { TaskDelegated, TaskExec, TaskReceipt } from "#tools/task.js";
10
11
  type ApprovalContextInput<TInput> = unknown extends TInput ? Record<string, unknown> : TInput;
@@ -50,15 +51,50 @@ export interface InternalToolDefinitionWithExecuteFn<TInput = unknown, TOutput =
50
51
  export interface PublicToolDefinitionWithExecuteFn<TInput = unknown, TOutput = unknown> extends PublicToolDefinition<TInput, TOutput> {
51
52
  execute: ToolExecuteFn<TInput, TOutput>;
52
53
  }
54
+ /**
55
+ * A question a workflow tool asks the human on the session's channel, sent
56
+ * with `ask` from `eve/workflow`. Channels render it the way they render
57
+ * `ask_question` and tool approvals.
58
+ */
59
+ export interface ToolInputRequest {
60
+ /**
61
+ * Whether the user may answer with free text instead of one of the
62
+ * {@link options}.
63
+ */
64
+ readonly allowFreeform?: boolean;
65
+ /** Rendering hint: confirmation buttons, a selection list, or a text field. */
66
+ readonly display?: "confirmation" | "select" | "text";
67
+ /** Selectable answers. */
68
+ readonly options?: readonly InputOption[];
69
+ readonly prompt: string;
70
+ }
71
+ /** The human's answer to a {@link ToolInputRequest}. */
72
+ export interface ToolInputResponse {
73
+ /** The selected option's `id`, when the user picked one. */
74
+ readonly optionId?: string;
75
+ /** Free text, when the user typed an answer. */
76
+ readonly text?: string;
77
+ }
53
78
  /**
54
79
  * Authored tool context. Passed as the last argument to
55
80
  * {@link ToolDefinition.execute}.
56
81
  *
57
82
  * Extends {@link SessionContext} with token accessors. Passing a provider
58
83
  * resolves that provider inline, which lets one tool use multiple credentials.
84
+ *
85
+ * A tool whose `execute` is a workflow (`"use workflow"`) receives the same
86
+ * context inside its durable body, except that `getSandbox`, `getSkill`,
87
+ * `getToken`, and `requireAuth` are unavailable there and throw when touched —
88
+ * read credentials inside a `"use step"` function instead.
59
89
  */
60
90
  export type ToolContext = SessionContext & {
61
- /** Aborts when the active turn is cancelled. */
91
+ /**
92
+ * Aborts when the work this tool is doing is cancelled: the active turn
93
+ * for an ordinary tool, the durable run for a workflow tool. In a workflow
94
+ * body the signal is durable — it survives replay and steps that receive it
95
+ * observe the abort — and the run waits a grace period for the body to
96
+ * unwind through `finally` before it ends.
97
+ */
62
98
  readonly abortSignal: AbortSignal;
63
99
  /**
64
100
  * Id of the current tool call — the same `callId` carried by the call's
@@ -118,7 +154,7 @@ export interface ToolDefinition<TInput = unknown, TOutput = unknown> extends Pub
118
154
  /** A tool whose executor can outlive the model tool-call phase as a durable task. */
119
155
  export interface BackgroundToolDefinition<TInput = unknown, TOutput = unknown> extends PublicToolDefinition<TInput, TOutput> {
120
156
  readonly execution: "background";
121
- execute(input: TInput, ctx: ToolContext, task: TaskExec): Promise<TaskDelegated | TOutput> | TaskDelegated | TOutput;
157
+ execute(input: TInput, ctx: ToolContext, task: TaskExec): Promise<TaskDelegated | TOutput> | TaskDelegated | TOutput | AsyncIterable<TOutput>;
122
158
  approval?: Approval<ApprovalContextInput<TInput>>;
123
159
  toModelOutput?: (output: TOutput) => ToolModelOutput | Promise<ToolModelOutput>;
124
160
  }
@@ -143,7 +179,7 @@ export declare function defineTool<TSchema extends StandardSchemaV1<unknown, unk
143
179
  execution: "background";
144
180
  inputSchema: TSchema;
145
181
  outputSchema?: PublicToolDefinition<unknown, BackgroundToolOutputFromExecuteReturn<TReturn>>["outputSchema"];
146
- execute(input: StandardSchemaV1.InferOutput<TSchema>, ctx: ToolContext, task: TaskExec): TReturn extends AsyncIterable<unknown> ? never : TReturn;
182
+ execute(input: StandardSchemaV1.InferOutput<TSchema>, ctx: ToolContext, task: TaskExec): TReturn;
147
183
  approval?: BackgroundToolDefinition<StandardSchemaV1.InferOutput<TSchema>, unknown>["approval"];
148
184
  toModelOutput?: BackgroundToolDefinition<unknown, BackgroundToolOutputFromExecuteReturn<TReturn>>["toModelOutput"];
149
185
  }): BackgroundToolDefinitionWithExecuteReturn<StandardSchemaV1.InferOutput<TSchema>, BackgroundToolOutputFromExecuteReturn<TReturn>, TReturn>;
@@ -1,2 +1,2 @@
1
- import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{isSampledTrace,resolveTracePolicyDecision}from"#tracing/sampled-trace.js";import{ROOT_CONTEXT,SpanKind,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{markAgentTraceContext}from"#tracing/agent-trace-context.js";import{attemptIdempotencyKey}from"#instrumentation/lifecycle.js";import{withoutInstrumentationContent}from"#instrumentation/content.js";import{contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";import{instrumentationEventForTraceDecision}from"#instrumentation/content-policy.js";import{createAgentActionInstrumentation}from"#tracing/agent-action-instrumentation.js";import{createAgentApprovalInstrumentation}from"#tracing/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/agent-channel-delivery-instrumentation.js";import{createAgentToolInstrumentation}from"#tracing/agent-tool-instrumentation.js";import{runtimeContextAttributes}from"#tracing/agent-otel-runtime-context.js";import{createAgentOtelSessionContext}from"#tracing/agent-otel-session-context.js";import{suppressTracing}from"#tracing/suppress-tracing.js";function createAgentOtelInstrumentation(e){let a=e.recordInputs??!1,s=e.recordOutputs??!1,p=new WeakMap,m=new Map,h=new WeakMap,g=new WeakMap,_=createAgentActionInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:a,recordOutputs:s,resolveTraceContext:async t=>(await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId))?.context,stateStore:e.stateStore,tracer:e.tracer}),v=createAgentApprovalInstrumentation({actionContextFor:_.contextFor,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,tracer:e.tracer}),y=createAgentToolInstrumentation({actionContextFor:_.contextFor,idGenerator:e.idGenerator,recordInputs:a,recordOutputs:s,resolveFallback:e=>{let t=m.get(e.scope.attemptId)??e.scope,n=h.get(t);return n===void 0?void 0:{context:n.context,spanContext:n.span.spanContext()}},tracer:e.tracer}),{ensureSessionContext:b,prepareSessionTrace:x,prepareTurnTrace:S}=createAgentOtelSessionContext(e),projectEvent=async o=>{let c=await e.stateStore.getSession(sessionIdForEvent(o)),l=audienceForEvent(o,c?.channelAudience),u=`traceSeed`in o?o.traceSeed:void 0,d=contextStorage.getStore()?.get(SessionTraceSeedKey),f=u?.decision??d?.decision??c?.decision??(u===void 0?d===void 0?c===void 0?void 0:resolveTracePolicyDecision(isSampledTrace(c.context),l):resolveTracePolicyDecision(isSampledTrace(d),l):resolveTracePolicyDecision(isSampledTrace(u),l));return f===void 0?withoutInstrumentationContent(o):instrumentationEventForTraceDecision(o,f.action===`drop`?f:{action:`record`,recordInputs:a&&f.recordInputs,recordOutputs:s&&f.recordOutputs},l)},onSessionStarted=async e=>{await x(e)},onTurnStarted=async e=>{await S(e)},onStepStarted=async t=>{let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(n===void 0||!isSampledTrace(n.context))return;let i=withChannelAudience(contextFromSpanContext(n.context),t.scope.channelAudience),a=trace.getSpan(context.active())?.spanContext(),o=e.idGenerator.withSpanId(e.idGenerator.deriveSpanId(attemptIdempotencyKey(t.scope)),()=>e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId,...runtimeContextAttributes(t.runtimeContext)},links:a===void 0||a.traceId===n.context.traceId?void 0:[{attributes:{"eve.link.type":`workflow.delivery`},context:a}]},i));o.addEvent(`step.started`);let s=trace.setSpan(i,o);h.set(t.scope,{context:s,span:o}),m.set(t.scope.attemptId,t.scope)},onStepTerminal=async e=>{let t=m.get(e.scope.attemptId)??e.scope;p.delete(t),drainOpenSpans({...e,scope:t}),y.drain(e.scope.attemptId,e.type===`step.attempt.failed`?{error:e.error}:void 0),e.type===`step.attempt.failed`&&await _.failForAttempt(t,e.error),m.delete(e.scope.attemptId);let n=h.get(t);n!==void 0&&(n.span.addEvent(e.type===`step.attempt.completed`?`step.completed`:`step.failed`),e.type===`step.attempt.failed`&&recordError(n.span,e.error),n.span.end(),h.delete(t))},onTurnTerminal=async t=>{(t.type===`turn.cancelled`||t.type===`turn.failed`)&&await _.deleteForTurn(t.sessionId,t.turnId),await e.stateStore.updateTurn(t.sessionId,t.turnId,e=>({...e,terminal:t.type===`turn.failed`?{error:t.error,type:t.type}:{type:t.type}}))},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let i=await e.stateStore.getSession(t.sessionId);if(isSampledTrace(n.context)){let r=i?.agentName??n.subagentName,a=e.idGenerator.withSpanId(n.context.spanId,()=>e.tracer.startSpan(agentSpanName(r),{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":r,"agent.session.id":t.sessionId,"agent.subagent.name":n.subagentName,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence,"gen_ai.agent.name":r,"gen_ai.conversation.id":t.sessionId,"gen_ai.operation.name":`invoke_agent`},kind:SpanKind.INTERNAL,startTime:n.startTimeMs},withChannelAudience(contextFromSpanContext({isRemote:n.parentIsRemote??!1,spanId:n.parentSpanId,traceFlags:n.context.traceFlags,traceId:n.context.traceId}),i?.channelAudience)));setAgentInvocationUsage(a,n.modelUsage),a.addEvent(`turn.started`,void 0,n.startTimeMs),n.terminal!==void 0&&(a.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(a,n.terminal.error)),a.end()}await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&(await _.deleteForSession(t.sessionId),await e.stateStore.deleteSession(t.sessionId))},onModelCallStarted=t=>{let n=h.get(t.scope);if(n===void 0)return;n.span.setAttribute(`agent.model.id`,t.model.modelId),n.span.setAttribute(`agent.model.provider`,t.model.provider);let r=e.tracer.startSpan(modelSpanName(t.model.modelId),{attributes:{"gen_ai.agent.name":t.scope.functionId,"gen_ai.operation.name":`chat`,"gen_ai.provider.name":t.model.provider,"gen_ai.request.model":t.model.modelId,...runtimeContextAttributes(t.runtimeContext)}},n.context);if(a&&t.input!==void 0){let e=messagesContentAttribute(t.input.messages);e!==void 0&&r.setAttribute(`ai.prompt.messages`,e);let n=genAiInputMessagesAttribute(t.input.messages);n!==void 0&&r.setAttribute(`gen_ai.input.messages`,n);let i=systemPromptAttribute(t.input.instructions);i!==void 0&&r.setAttribute(`ai.prompt.system`,i);let a=genAiSystemInstructionsAttribute(t.input.instructions);a!==void 0&&r.setAttribute(`gen_ai.system_instructions`,a)}let i={context:trace.setSpan(n.context,r),span:r};getExecutionContexts(t.scope).set(t.idempotencyKey,i.context),getSpanStates(g,t.scope).set(t.idempotencyKey,i)},onModelCallTerminal=async e=>{p.get(e.scope)?.delete(e.idempotencyKey);let t=takeSpanState(g,e.scope,e.idempotencyKey);if(t!==void 0){if(e.type===`model.call.failed`)recordError(t.span,e.error);else{await recordTurnUsage(e),setAgentUsage(t.span,e.usage),t.span.setAttribute(`gen_ai.response.finish_reasons`,[e.finishReason]);let n=h.get(e.scope);if(n!==void 0&&setAgentUsage(n.span,e.usage),s){t.span.setAttribute(`ai.response.finish_reason`,e.finishReason);let n=e.content;if(n===void 0){t.span.end();return}let r=genAiOutputMessagesAttribute(n,e.finishReason);r!==void 0&&t.span.setAttribute(`gen_ai.output.messages`,r);let i=textContentAttribute(n.filter(e=>e.type===`reasoning`).map(e=>e.text).filter(e=>e.trim().length>0).join(`
2
- `));i!==void 0&&t.span.setAttribute(`ai.response.reasoning`,i);let a=textContentAttribute(n.filter(e=>e.type===`text`).map(e=>e.text).join(``));a!==void 0&&t.span.setAttribute(`ai.response.text`,a);let o=n.filter(e=>e.type===`tool-call`).map(e=>({callId:e.callId,input:e.input,toolName:e.toolName}));if(o.length>0){let e=contentAttribute(o,!1);e!==void 0&&t.span.setAttribute(`ai.response.tool_calls`,e)}let s=n.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{callId:e.callId,input:e.input,output:e.output,toolName:e.toolName}:{callId:e.callId,error:errorText(e.error),input:e.input,toolName:e.toolName});if(s.length>0){let e=toolResultsContentAttribute(s);e!==void 0&&t.span.setAttribute(`ai.response.tool_results`,e)}}}t.span.end()}},recordTurnUsage=async t=>{t.usage.inputTokens===void 0&&t.usage.outputTokens===void 0||await e.stateStore.updateTurn(t.scope.sessionId,t.scope.turnId,e=>({...e,modelUsage:{inputTokens:t.usage.inputTokens===void 0?e.modelUsage?.inputTokens:(e.modelUsage?.inputTokens??0)+t.usage.inputTokens,outputTokens:t.usage.outputTokens===void 0?e.modelUsage?.outputTokens:(e.modelUsage?.outputTokens??0)+t.usage.outputTokens}}))},C=createAgentChannelDeliveryInstrumentation({ensureSessionContext:b,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:a,stateStore:e.stateStore,tracer:e.tracer}),onStepMetadata=e=>{let t=h.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.span.setAttribute(e,r)};return{hook:{events:{...C,"action.completed":_.events[`action.completed`],"action.failed":_.events[`action.failed`],async"action.started"(e,t){await _.events[`action.started`](e,t),await y.actionStarted(e)},...v,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...y.events,"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted},name:`eve.otel`,projectEvent,tracePolicy:()=>({emit:!0,recordInputs:a,recordOutputs:s})},prepareSessionTrace:x,prepareTurnTrace:S,async runInContext(t,n){let i=m.get(t.scope.attemptId)??t.scope,a=p.get(i),o=t.type===`model.call`?a?.get(t.idempotencyKey):y.contextFor(t.scope.attemptId,t.idempotencyKey);if(o===void 0){let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);n!==void 0&&(o=withChannelAudience(contextFromSpanContext(n.context),t.scope.channelAudience),isSampledTrace(n.context)||(o=suppressTracing(o)))}return o===void 0?n():context.with(markAgentTraceContext(o),n)}};function getExecutionContexts(e){let t=p.get(e);return t===void 0&&(t=new Map,p.set(e,t)),t}function drainOpenSpans(e){for(let t of g.get(e.scope)?.values()??[])e.type===`step.attempt.failed`&&recordError(t.span,e.error),t.span.end();g.delete(e.scope)}}function sessionIdForEvent(e){return`scope`in e?e.scope.sessionId:e.sessionId}function audienceForEvent(t,n){return`delivery`in t?normalizeChannelAudience(t.delivery.channelAudience):`scope`in t&&t.scope.channelAudience!==void 0?normalizeChannelAudience(t.scope.channelAudience):t.type===`session.started`?normalizeChannelAudience(t.channelAudience):normalizeChannelAudience(n)}function getSpanStates(e,t){let n=e.get(t);return n===void 0&&(n=new Map,e.set(t,n)),n}function takeSpanState(e,t,n){let r=e.get(t),i=r?.get(n);if(r!==void 0)return r.delete(n),r.size===0&&e.delete(t),i}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function readGatewayCost(e){let t=e.gateway;if(!isRecord(t))return;let n={},r=readUsd(t.cost);r!==void 0&&(n[`gen_ai.usage.cost`]=r);let i=readUsd(t.gatewayCost);i!==void 0&&(n[`gen_ai.usage.gateway_cost`]=i);let a=readUsd(t.inputInferenceCost);a!==void 0&&(n[`gen_ai.usage.input_cost`]=a);let o=readUsd(t.outputInferenceCost);return o!==void 0&&(n[`gen_ai.usage.output_cost`]=o),typeof t.generationId==`string`&&t.generationId.length>0&&(n[`gen_ai.generation.id`]=t.generationId),Object.keys(n).length===0?void 0:n}function readUsd(e){if(typeof e!=`string`)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function modelSpanName(e){return`chat ${e}`}function agentSpanName(e){return e===void 0?`invoke_agent`:`invoke_agent ${e}`}function setAgentInvocationUsage(e,t){t!==void 0&&(t.inputTokens!==void 0&&e.setAttribute(`gen_ai.usage.input_tokens`,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(`gen_ai.usage.output_tokens`,t.outputTokens))}function errorText(e){return e instanceof Error?e.message:e}function recordError(e,t){e.setAttribute(`error.type`,t instanceof Error?t.name||`Error`:`_OTHER`),t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentOtelInstrumentation};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{applyLiveDeliveryAudienceCeiling,resolveForwardedTraceSeed}from"#shared/forwarded-trace-policy.js";import{isSampledTrace,resolveTracePolicyDecision}from"#tracing/sampled-trace.js";import{ROOT_CONTEXT,SpanKind,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{markAgentTraceContext}from"#tracing/agent-trace-context.js";import{attemptIdempotencyKey}from"#instrumentation/lifecycle.js";import{withoutInstrumentationContent}from"#instrumentation/content.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";import{contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";import{instrumentationEventForTraceDecision}from"#instrumentation/content-policy.js";import{createAgentActionInstrumentation}from"#tracing/agent-action-instrumentation.js";import{createAgentApprovalInstrumentation}from"#tracing/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/agent-channel-delivery-instrumentation.js";import{createAgentToolInstrumentation}from"#tracing/agent-tool-instrumentation.js";import{runtimeContextAttributes}from"#tracing/agent-otel-runtime-context.js";import{createAgentOtelSessionContext}from"#tracing/agent-otel-session-context.js";import{suppressTracing}from"#tracing/suppress-tracing.js";function createAgentOtelInstrumentation(e){let s=e.recordInputs??!1,l=e.recordOutputs??!1,_=new WeakMap,v=new Map,y=new WeakMap,b=new WeakMap,x=createAgentActionInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:s,recordOutputs:l,resolveTraceContext:async t=>(await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId))?.context,stateStore:e.stateStore,tracer:e.tracer}),S=createAgentApprovalInstrumentation({actionContextFor:x.contextFor,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,tracer:e.tracer}),C=createAgentToolInstrumentation({actionContextFor:x.contextFor,idGenerator:e.idGenerator,recordInputs:s,recordOutputs:l,resolveFallback:e=>{let t=v.get(e.scope.attemptId)??e.scope,n=y.get(t);return n===void 0?void 0:{context:n.context,spanContext:n.span.spanContext()}},tracer:e.tracer}),{ensureSessionContext:w,prepareSessionTrace:T,prepareTurnTrace:E}=createAgentOtelSessionContext(e),projectEvent=async c=>{let u=await e.stateStore.getSession(sessionIdForEvent(c)),d=audienceForEvent(c,u?.channelAudience),f=`traceSeed`in c?c.traceSeed:void 0,p=contextStorage.getStore()?.get(SessionTraceSeedKey),m=resolveForwardedTraceSeed(p),h=resolveForwardedTraceSeed(f,m?.forwardedTracePolicy),g=h?.decision??m?.decision??readInstrumentationDecision(u?.decision)??(f===void 0?p===void 0?u===void 0?void 0:resolveTracePolicyDecision(isSampledTrace(u.context),d):resolveTracePolicyDecision(isSampledTrace(p),d):resolveTracePolicyDecision(isSampledTrace(f),d));return g===void 0?withoutInstrumentationContent(c):instrumentationEventForTraceDecision(h===void 0||!(`traceSeed`in c)||c.traceSeed===void 0?c:{...c,traceSeed:{...c.traceSeed,decision:h.decision,traceFlags:h.traceFlags}},applyLiveDeliveryAudienceCeiling(g.action===`drop`?g:{action:`record`,recordInputs:s&&g.recordInputs,recordOutputs:l&&g.recordOutputs},d,h?.forwardedTracePolicy??m?.forwardedTracePolicy),d,{applyAudienceCeiling:!1})},onSessionStarted=async e=>{await T(e)},onTurnStarted=async e=>{await E(e)},onStepStarted=async t=>{let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(n===void 0||!isSampledTrace(n.context))return;let r=withChannelAudience(contextFromSpanContext(n.context),t.scope.channelAudience),i=trace.getSpan(context.active())?.spanContext(),o=e.idGenerator.withSpanId(e.idGenerator.deriveSpanId(attemptIdempotencyKey(t.scope)),()=>e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId,...runtimeContextAttributes(t.runtimeContext)},links:i===void 0||i.traceId===n.context.traceId?void 0:[{attributes:{"eve.link.type":`workflow.delivery`},context:i}]},r));o.addEvent(`step.started`);let s=trace.setSpan(r,o);y.set(t.scope,{context:s,span:o}),v.set(t.scope.attemptId,t.scope)},onStepTerminal=async e=>{let t=v.get(e.scope.attemptId)??e.scope;_.delete(t),drainOpenSpans({...e,scope:t}),C.drain(e.scope.attemptId,e.type===`step.attempt.failed`?{error:e.error}:void 0),e.type===`step.attempt.failed`&&await x.failForAttempt(t,e.error),v.delete(e.scope.attemptId);let n=y.get(t);n!==void 0&&(n.span.addEvent(e.type===`step.attempt.completed`?`step.completed`:`step.failed`),e.type===`step.attempt.failed`&&recordError(n.span,e.error),n.span.end(),y.delete(t))},onTurnTerminal=async t=>{(t.type===`turn.cancelled`||t.type===`turn.failed`)&&await x.deleteForTurn(t.sessionId,t.turnId),await e.stateStore.updateTurn(t.sessionId,t.turnId,e=>({...e,terminal:t.type===`turn.failed`?{error:t.error,type:t.type}:{type:t.type}}))},onSessionTransition=async t=>{if(t.type===`session.failed`&&t.turnId!==void 0&&await e.stateStore.updateTurn(t.sessionId,t.turnId,e=>({...e,terminal:e.terminal??{error:t.error,type:`turn.failed`}})),t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let r=await e.stateStore.getSession(t.sessionId);if(isSampledTrace(n.context)){let i=r?.agentName??n.subagentName,a=e.idGenerator.withSpanId(n.context.spanId,()=>e.tracer.startSpan(agentSpanName(i),{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":i,"agent.session.id":t.sessionId,"agent.subagent.name":n.subagentName,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence,"gen_ai.agent.name":i,"gen_ai.conversation.id":t.sessionId,"gen_ai.operation.name":`invoke_agent`},kind:SpanKind.INTERNAL,startTime:n.startTimeMs},withChannelAudience(contextFromSpanContext({isRemote:n.parentIsRemote??!1,spanId:n.parentSpanId,traceFlags:n.context.traceFlags,traceId:n.context.traceId}),r?.channelAudience)));setAgentInvocationUsage(a,n.modelUsage),a.addEvent(`turn.started`,void 0,n.startTimeMs),n.terminal!==void 0&&(a.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(a,n.terminal.error)),a.end()}await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&(await x.deleteForSession(t.sessionId),await e.stateStore.deleteSession(t.sessionId))},onModelCallStarted=t=>{let n=y.get(t.scope);if(n===void 0)return;n.span.setAttribute(`agent.model.id`,t.model.modelId),n.span.setAttribute(`agent.model.provider`,t.model.provider);let r=e.tracer.startSpan(modelSpanName(t.model.modelId),{attributes:{"gen_ai.agent.name":t.scope.functionId,"gen_ai.operation.name":`chat`,"gen_ai.provider.name":t.model.provider,"gen_ai.request.model":t.model.modelId,...runtimeContextAttributes(t.runtimeContext)}},n.context);if(s&&t.input!==void 0){let e=messagesContentAttribute(t.input.messages);e!==void 0&&r.setAttribute(`ai.prompt.messages`,e);let n=genAiInputMessagesAttribute(t.input.messages);n!==void 0&&r.setAttribute(`gen_ai.input.messages`,n);let i=systemPromptAttribute(t.input.instructions);i!==void 0&&r.setAttribute(`ai.prompt.system`,i);let a=genAiSystemInstructionsAttribute(t.input.instructions);a!==void 0&&r.setAttribute(`gen_ai.system_instructions`,a)}let i={context:trace.setSpan(n.context,r),span:r};getExecutionContexts(t.scope).set(t.idempotencyKey,i.context),getSpanStates(b,t.scope).set(t.idempotencyKey,i)},onModelCallTerminal=async e=>{_.get(e.scope)?.delete(e.idempotencyKey);let t=takeSpanState(b,e.scope,e.idempotencyKey);if(t!==void 0){if(e.type===`model.call.failed`)recordError(t.span,e.error);else{await recordTurnUsage(e),setAgentUsage(t.span,e.usage),t.span.setAttribute(`gen_ai.response.finish_reasons`,[e.finishReason]);let n=y.get(e.scope);if(n!==void 0&&setAgentUsage(n.span,e.usage),l){t.span.setAttribute(`ai.response.finish_reason`,e.finishReason);let n=e.content;if(n===void 0){t.span.end();return}let r=genAiOutputMessagesAttribute(n,e.finishReason);r!==void 0&&t.span.setAttribute(`gen_ai.output.messages`,r);let i=textContentAttribute(n.filter(e=>e.type===`reasoning`).map(e=>e.text).filter(e=>e.trim().length>0).join(`
2
+ `));i!==void 0&&t.span.setAttribute(`ai.response.reasoning`,i);let a=textContentAttribute(n.filter(e=>e.type===`text`).map(e=>e.text).join(``));a!==void 0&&t.span.setAttribute(`ai.response.text`,a);let o=n.filter(e=>e.type===`tool-call`).map(e=>({callId:e.callId,input:e.input,toolName:e.toolName}));if(o.length>0){let e=contentAttribute(o,!1);e!==void 0&&t.span.setAttribute(`ai.response.tool_calls`,e)}let s=n.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{callId:e.callId,input:e.input,output:e.output,toolName:e.toolName}:{callId:e.callId,error:errorText(e.error),input:e.input,toolName:e.toolName});if(s.length>0){let e=toolResultsContentAttribute(s);e!==void 0&&t.span.setAttribute(`ai.response.tool_results`,e)}}}t.span.end()}},recordTurnUsage=async t=>{t.usage.inputTokens===void 0&&t.usage.outputTokens===void 0||await e.stateStore.updateTurn(t.scope.sessionId,t.scope.turnId,e=>({...e,modelUsage:{inputTokens:t.usage.inputTokens===void 0?e.modelUsage?.inputTokens:(e.modelUsage?.inputTokens??0)+t.usage.inputTokens,outputTokens:t.usage.outputTokens===void 0?e.modelUsage?.outputTokens:(e.modelUsage?.outputTokens??0)+t.usage.outputTokens}}))},D=createAgentChannelDeliveryInstrumentation({ensureSessionContext:w,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:s,stateStore:e.stateStore,tracer:e.tracer}),onStepMetadata=e=>{let t=y.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.span.setAttribute(e,r)};return{hook:{events:{...D,"action.completed":x.events[`action.completed`],"action.failed":x.events[`action.failed`],async"action.started"(e,t){await x.events[`action.started`](e,t),await C.actionStarted(e)},...S,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...C.events,"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted},name:`eve.otel`,projectEvent,tracePolicy:()=>({emit:!0,recordInputs:s,recordOutputs:l})},prepareSessionTrace:T,prepareTurnTrace:E,async runInContext(t,n){let r=v.get(t.scope.attemptId)??t.scope,i=_.get(r),o=t.type===`model.call`?i?.get(t.idempotencyKey):C.contextFor(t.scope.attemptId,t.idempotencyKey);if(o===void 0){let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);n!==void 0&&(o=withChannelAudience(contextFromSpanContext(n.context),t.scope.channelAudience),isSampledTrace(n.context)||(o=suppressTracing(o)))}return o===void 0?n():context.with(markAgentTraceContext(o),n)}};function getExecutionContexts(e){let t=_.get(e);return t===void 0&&(t=new Map,_.set(e,t)),t}function drainOpenSpans(e){for(let t of b.get(e.scope)?.values()??[])e.type===`step.attempt.failed`&&recordError(t.span,e.error),t.span.end();b.delete(e.scope)}}function sessionIdForEvent(e){return`scope`in e?e.scope.sessionId:e.sessionId}function audienceForEvent(t,n){return`delivery`in t?normalizeChannelAudience(t.delivery.channelAudience):`scope`in t&&t.scope.channelAudience!==void 0?normalizeChannelAudience(t.scope.channelAudience):t.type===`session.started`?normalizeChannelAudience(t.channelAudience):normalizeChannelAudience(n)}function getSpanStates(e,t){let n=e.get(t);return n===void 0&&(n=new Map,e.set(t,n)),n}function takeSpanState(e,t,n){let r=e.get(t),i=r?.get(n);if(r!==void 0)return r.delete(n),r.size===0&&e.delete(t),i}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function readGatewayCost(e){let t=e.gateway;if(!isRecord(t))return;let n={},r=readUsd(t.cost);r!==void 0&&(n[`gen_ai.usage.cost`]=r);let i=readUsd(t.gatewayCost);i!==void 0&&(n[`gen_ai.usage.gateway_cost`]=i);let a=readUsd(t.inputInferenceCost);a!==void 0&&(n[`gen_ai.usage.input_cost`]=a);let o=readUsd(t.outputInferenceCost);return o!==void 0&&(n[`gen_ai.usage.output_cost`]=o),typeof t.generationId==`string`&&t.generationId.length>0&&(n[`gen_ai.generation.id`]=t.generationId),Object.keys(n).length===0?void 0:n}function readUsd(e){if(typeof e!=`string`)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function modelSpanName(e){return`chat ${e}`}function agentSpanName(e){return e===void 0?`invoke_agent`:`invoke_agent ${e}`}function setAgentInvocationUsage(e,t){t!==void 0&&(t.inputTokens!==void 0&&e.setAttribute(`gen_ai.usage.input_tokens`,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(`gen_ai.usage.output_tokens`,t.outputTokens))}function errorText(e){return e instanceof Error?e.message:e}function recordError(e,t){e.setAttribute(`error.type`,t instanceof Error?t.name||`Error`:`_OTHER`),t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentOtelInstrumentation};
@@ -1 +1 @@
1
- import{normalizeChannelAudience}from"#shared/channel-audience.js";import{isSampledTrace,resolveTracePolicy,resolveTracePolicyDecision}from"#tracing/sampled-trace.js";import{sessionIdempotencyKey}from"#instrumentation/lifecycle.js";function createAgentOtelSessionContext(n){let openSessionTrace=e=>{if(e.traceSeed!==void 0){if(!isSampledTrace(e.traceSeed))return{isRemote:!1,spanId:e.traceSeed.spanId,traceFlags:0,traceId:e.traceSeed.traceId};let startSpan=()=>n.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":3},root:!0}),r=n.idGenerator.withSpanId(e.traceSeed.spanId,()=>n.idGenerator.withTraceId(e.traceSeed.traceId,startSpan));return r.addEvent(`session.started`),r.end(),r.spanContext()}if(e.traceDecision.action===`drop`)return{isRemote:!1,spanId:n.idGenerator.deriveSpanId(`session:${e.sessionId}`),traceFlags:0,traceId:n.idGenerator.generateTraceId()};let r=n.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":3},root:!0});return r.addEvent(`session.started`),r.end(),r.spanContext()},ensureSessionContext=async t=>{let r=await n.stateStore.getSession(t.sessionId);if(r===void 0){let i=normalizeChannelAudience(t.channelAudience),a=resolveSessionTraceDecision(t,i,n.tracePolicy);r={agentName:t.agentName,channelAudience:i,channelKind:t.channelKind,decision:a,context:t.parentTraceContext===void 0?openSessionTrace({agentName:t.agentName,channelAudience:i,channelType:t.channelType,rootSessionId:t.rootSessionId,sessionId:t.sessionId,traceDecision:a,traceSeed:t.traceSeed}):adoptedSpanContext(t.parentTraceContext),rootSessionId:t.rootSessionId},await n.stateStore.setSession(t.sessionId,r)}return r};return{ensureSessionContext,prepareSessionTrace:async e=>{let t=await ensureSessionContext(e);return portableSpanContext(t.context,t.decision)},prepareTurnTrace:async e=>{let t=await n.stateStore.getTurn(e.sessionId,e.turnId);if(t!==void 0)return{decision:(await n.stateStore.getSession(e.sessionId))?.decision,spanId:t.parentSpanId,traceFlags:t.context.traceFlags,traceId:t.context.traceId};let r=await ensureSessionContext({agentName:e.agentName,channelAudience:`unknown`,channelKind:void 0,idempotencyKey:sessionIdempotencyKey(e.sessionId),parentTraceContext:e.parentTraceContext,rootSessionId:e.rootSessionId,sessionId:e.sessionId,type:`session.started`}),a={isRemote:!1,spanId:n.idGenerator.deriveSpanId(`turn:${e.idempotencyKey}`),traceFlags:r.context.traceFlags,traceId:r.context.traceId};return await n.stateStore.setTurn(e.sessionId,e.turnId,{context:a,parentIsRemote:r.context.isRemote,parentSpanId:r.context.spanId,rootSessionId:e.rootSessionId,sequence:e.sequence,startTimeMs:Date.now(),subagentName:e.parentLineage?.subagentName}),portableSpanContext(r.context,r.decision)}}}function portableSpanContext(e,t){return{decision:t,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function adoptedSpanContext(e){return{isRemote:`isRemote`in e&&e.isRemote===!0,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function resolveSessionTraceDecision(e,i,a){return e.traceSeed?.decision===void 0?e.traceSeed===void 0?e.parentTraceContext===void 0?e.agentName===void 0?a===void 0?resolveTracePolicyDecision(!0,i):{action:`drop`}:resolveTracePolicy(a,{agentName:e.agentName,audience:i,channelType:e.channelType}):resolveTracePolicyDecision(isSampledTrace(e.parentTraceContext),i):resolveTracePolicyDecision(isSampledTrace(e.traceSeed),i):e.traceSeed.decision}export{createAgentOtelSessionContext};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{isSampledTrace,resolveTracePolicy,resolveTracePolicyDecision}from"#tracing/sampled-trace.js";import{sessionIdempotencyKey}from"#instrumentation/lifecycle.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";function createAgentOtelSessionContext(n){let openSessionTrace=e=>{if(e.traceSeed!==void 0){if(e.traceDecision.action===`drop`||!isSampledTrace(e.traceSeed))return{isRemote:!1,spanId:e.traceSeed.spanId,traceFlags:0,traceId:e.traceSeed.traceId};let startSpan=()=>n.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":3},root:!0}),r=n.idGenerator.withSpanId(e.traceSeed.spanId,()=>n.idGenerator.withTraceId(e.traceSeed.traceId,startSpan));return r.addEvent(`session.started`),r.end(),r.spanContext()}if(e.traceDecision.action===`drop`)return{isRemote:!1,spanId:n.idGenerator.deriveSpanId(`session:${e.sessionId}`),traceFlags:0,traceId:n.idGenerator.generateTraceId()};let r=n.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":3},root:!0});return r.addEvent(`session.started`),r.end(),r.spanContext()},ensureSessionContext=async t=>{let r=await n.stateStore.getSession(t.sessionId);if(r===void 0){let i=normalizeChannelAudience(t.channelAudience),a=resolveSessionTraceDecision(t,i,n.tracePolicy);r={agentName:t.agentName,channelAudience:i,channelKind:t.channelKind,decision:a,context:t.parentTraceContext===void 0?openSessionTrace({agentName:t.agentName,channelAudience:i,channelType:t.channelType,rootSessionId:t.rootSessionId,sessionId:t.sessionId,traceDecision:a,traceSeed:t.traceSeed}):adoptedSpanContext(t.parentTraceContext),rootSessionId:t.rootSessionId},await n.stateStore.setSession(t.sessionId,r)}return r};return{ensureSessionContext,prepareSessionTrace:async e=>{let t=await ensureSessionContext(e);return portableSpanContext(t.context,t.decision)},prepareTurnTrace:async e=>{let t=await n.stateStore.getTurn(e.sessionId,e.turnId);if(t!==void 0)return{decision:(await n.stateStore.getSession(e.sessionId))?.decision,spanId:t.parentSpanId,traceFlags:t.context.traceFlags,traceId:t.context.traceId};let r=await ensureSessionContext({agentName:e.agentName,channelAudience:`unknown`,channelKind:void 0,idempotencyKey:sessionIdempotencyKey(e.sessionId),parentTraceContext:e.parentTraceContext,rootSessionId:e.rootSessionId,sessionId:e.sessionId,type:`session.started`}),a={isRemote:!1,spanId:n.idGenerator.deriveSpanId(`turn:${e.idempotencyKey}`),traceFlags:r.context.traceFlags,traceId:r.context.traceId};return await n.stateStore.setTurn(e.sessionId,e.turnId,{context:a,parentIsRemote:r.context.isRemote,parentSpanId:r.context.spanId,rootSessionId:e.rootSessionId,sequence:e.sequence,startTimeMs:Date.now(),subagentName:e.parentLineage?.subagentName}),portableSpanContext(r.context,r.decision)}}}function portableSpanContext(e,t){return{decision:t,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function adoptedSpanContext(e){return{isRemote:`isRemote`in e&&e.isRemote===!0,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function resolveSessionTraceDecision(e,i,o){return e.traceSeed?.decision===void 0?e.traceSeed===void 0?e.parentTraceContext===void 0?e.agentName===void 0?o===void 0?resolveTracePolicyDecision(!0,i):{action:`drop`}:resolveTracePolicy(o,{agentName:e.agentName,audience:i,channelType:e.channelType}):resolveTracePolicyDecision(isSampledTrace(e.parentTraceContext),i):resolveTracePolicyDecision(isSampledTrace(e.traceSeed),i):readInstrumentationDecision(e.traceSeed.decision)??{action:`drop`}}export{createAgentOtelSessionContext};
@@ -1,7 +1,7 @@
1
1
  import type { SessionTraceContext } from "#channel/types.js";
2
2
  import type { ContextAccessor } from "#context/key.js";
3
3
  import type { AgentActionTraceState, AgentSessionTraceState, AgentTraceStateStore, AgentTurnTraceState } from "#tracing/agent-trace-state.js";
4
- import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
4
+ import { type InstrumentationDecision } from "#shared/instrumentation-decision.js";
5
5
  /** Reads the decision already bound to a session in the current worker context. */
6
6
  export declare function readCurrentSessionTraceDecision(sessionId: string): InstrumentationDecision | undefined;
7
7
  export declare function readSessionTraceDecision(context: ContextAccessor, sessionId: string): InstrumentationDecision | undefined;
@@ -1 +1 @@
1
- import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage,loadContext}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{ContextKey}from"#context/key.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function readCurrentSessionTraceDecision(e){let n=contextStorage.getStore();return n===void 0?void 0:readSessionTraceDecision(n,e)}function readSessionTraceDecision(e,t){return e.get(AgentTraceContextKey)?.sessions[t]?.decision}function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n===void 0)return;let r=deserializeState(n).sessions[t];return r===void 0?void 0:withTraceDecision(e,r.context,r.decision)}function readActionTraceContext(e,t,n,r){let i=e[AgentTraceContextKey.name];if(i===void 0)return;let o=deserializeState(i),s=Object.values(o.actions).find(e=>e.sessionId===t&&e.turnId===n&&e.callId===r);if(s!==void 0)return withTraceDecision(e,{isRemote:!1,spanId:s.spanId,traceFlags:s.parent.traceFlags,traceId:s.parent.traceId},o.sessions[s.sessionId]?.decision)}function withTraceDecision(e,t,n){let i=e[SessionTraceSeedKey.name],a=n??i?.decision;return a===void 0?t:{...t,decision:a}}var ContextAgentTraceStateStore=class{deleteAction(e){updateState(t=>{let n={...t.actions};return delete n[e],{...t,actions:n}})}deleteActions(e,t){updateState(n=>{let r={...n.actions};for(let[n,i]of Object.entries(r))i.sessionId===e&&(t===void 0||i.turnId===t)&&delete r[n];return{...n,actions:r}})}deleteSession(e){updateState(t=>{let n={...t.sessions};return delete n[e],{...t,sessions:n}})}deleteTurn(e,t){updateState(n=>{let r={...n.turns};return delete r[turnKey(e,t)],{...n,turns:r}})}findAction(e,n){return Object.values(contextStorage.getStore()?.get(AgentTraceContextKey)?.actions??{}).find(t=>t.sessionId===e&&t.callId===n)}getAction(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.actions[e]}getSession(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[e]}getTurn(e,n){return contextStorage.getStore()?.get(AgentTraceContextKey)?.turns[turnKey(e,n)]}setAction(e,t){updateState(n=>({...n,actions:{...n.actions,[e]:t}}))}setSession(e,t){updateState(n=>({...n,sessions:{...n.sessions,[e]:t}}))}setTurn(e,t,n){updateState(r=>({...r,turns:{...r.turns,[turnKey(e,t)]:n}}))}updateTurn(e,t,n){updateState(r=>{let i=turnKey(e,t),a=r.turns[i];return a===void 0?r:{...r,turns:{...r.turns,[i]:n(a)}}})}};function updateState(e){loadContext().set(AgentTraceContextKey,t=>e(t??{actions:{},sessions:{},turns:{}}))}function turnKey(e,t){return`${e}\0${t}`}function serializeState(e){return{actions:e.actions,sessions:Object.fromEntries(Object.entries(e.sessions).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context)}])),turns:Object.fromEntries(Object.entries(e.turns).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context),terminal:t.terminal===void 0?void 0:t.terminal.type===`turn.failed`?{error:serializeError(t.terminal.error),type:t.terminal.type}:{type:t.terminal.type}}]))}}function deserializeState(t){return isRecord(t)?{actions:deserializeRecord(t.actions,deserializeAction),sessions:deserializeRecord(t.sessions,t=>{if(!(!isRecord(t)||!isSpanContext(t.context)))return{agentName:typeof t.agentName==`string`?t.agentName:void 0,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:typeof t.channelKind==`string`?t.channelKind:void 0,context:t.context,decision:deserializeInstrumentationDecision(t.decision),rootSessionId:typeof t.rootSessionId==`string`?t.rootSessionId:``}}),turns:deserializeRecord(t.turns,e=>{if(!(!isRecord(e)||!isSpanContext(e.context))&&!(typeof e.parentSpanId!=`string`||typeof e.startTimeMs!=`number`))return{context:e.context,modelUsage:deserializeModelUsage(e.modelUsage),parentIsRemote:typeof e.parentIsRemote==`boolean`?e.parentIsRemote:void 0,parentSpanId:e.parentSpanId,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,terminal:deserializeTerminal(e.terminal)}})}:{actions:{},sessions:{},turns:{}}}function deserializeModelUsage(e){if(!isRecord(e))return;let t=typeof e.inputTokens==`number`?e.inputTokens:void 0,n=typeof e.outputTokens==`number`?e.outputTokens:void 0;return t===void 0&&n===void 0?void 0:{inputTokens:t,outputTokens:n}}function deserializeAction(t){if(!(!isRecord(t)||typeof t.attemptIndex!=`number`||typeof t.callId!=`string`||!isActionKind(t.kind)||typeof t.name!=`string`||!isSpanContext(t.parent)||typeof t.rootSessionId!=`string`||typeof t.sessionId!=`string`||typeof t.spanId!=`string`||typeof t.startTimeMs!=`number`||typeof t.stepIndex!=`number`||typeof t.turnId!=`string`))return{attemptIndex:t.attemptIndex,callId:t.callId,channelAudience:normalizeChannelAudience(t.channelAudience),inputAttribute:typeof t.inputAttribute==`string`?t.inputAttribute:void 0,kind:t.kind,name:t.name,parent:t.parent,rootSessionId:t.rootSessionId,sessionId:t.sessionId,spanId:t.spanId,startTimeMs:t.startTimeMs,stepIndex:t.stepIndex,turnId:t.turnId}}function isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function deserializeRecord(e,t){if(!isRecord(e))return{};let n={};for(let[r,i]of Object.entries(e)){let e=t(i);e!==void 0&&(n[r]=e)}return n}function deserializeTerminal(e){if(!isRecord(e)||typeof e.type!=`string`)return;let t=e.type;if(isTurnTerminalType(t))return t===`turn.failed`?{error:deserializeError(e.error),type:t}:{type:t}}function serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function serializeError(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:void 0}function deserializeError(e){if(!isRecord(e)||typeof e.message!=`string`)return;let t=Error(e.message);return typeof e.name==`string`&&(t.name=e.name),typeof e.stack==`string`&&(t.stack=e.stack),t}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function deserializeInstrumentationDecision(e){if(isRecord(e))return e.action===`drop`?{action:`drop`}:e.action===`record`&&typeof e.recordInputs==`boolean`&&typeof e.recordOutputs==`boolean`?{action:`record`,recordInputs:e.recordInputs,recordOutputs:e.recordOutputs}:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{ContextAgentTraceStateStore,preserveSerializedAgentTraceState,readActionTraceContext,readCurrentSessionTraceDecision,readSessionTraceContext,readSessionTraceDecision};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage,loadContext}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{ContextKey}from"#context/key.js";import{decisionToTraceContentCeiling,resolveForwardedTraceSeed}from"#shared/forwarded-trace-policy.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function readCurrentSessionTraceDecision(e){let n=contextStorage.getStore();return n===void 0?void 0:readSessionTraceDecision(n,e)}function readSessionTraceDecision(e,t){return e.get(AgentTraceContextKey)?.sessions[t]?.decision}function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n===void 0)return;let r=deserializeState(n).sessions[t];return r===void 0?void 0:withTraceDecision(e,r.context,r.decision)}function readActionTraceContext(e,t,n,r){let i=e[AgentTraceContextKey.name];if(i===void 0)return;let a=deserializeState(i),o=Object.values(a.actions).find(e=>e.sessionId===t&&e.turnId===n&&e.callId===r);if(o!==void 0)return withTraceDecision(e,{isRemote:!1,spanId:o.spanId,traceFlags:o.parent.traceFlags,traceId:o.parent.traceId},a.sessions[o.sessionId]?.decision)}function withTraceDecision(e,t,n){let i=e[SessionTraceSeedKey.name],s=resolveForwardedTraceSeed({decision:n??i?.decision,forwardedTracePolicy:i?.forwardedTracePolicy,traceFlags:t.traceFlags}),c=s.decision,l=s.forwardedTracePolicy,u=decisionToTraceContentCeiling(c),d={...t,traceFlags:s.traceFlags};if(l===void 0)return c===void 0?d:{...d,decision:c};let f=u===void 0?l:{...l,ceiling:u};return c===void 0?{...d,forwardedTracePolicy:f}:{...d,decision:c,forwardedTracePolicy:f}}var ContextAgentTraceStateStore=class{deleteAction(e){updateState(t=>{let n={...t.actions};return delete n[e],{...t,actions:n}})}deleteActions(e,t){updateState(n=>{let r={...n.actions};for(let[n,i]of Object.entries(r))i.sessionId===e&&(t===void 0||i.turnId===t)&&delete r[n];return{...n,actions:r}})}deleteSession(e){updateState(t=>{let n={...t.sessions};return delete n[e],{...t,sessions:n}})}deleteTurn(e,t){updateState(n=>{let r={...n.turns};return delete r[turnKey(e,t)],{...n,turns:r}})}findAction(e,n){return Object.values(contextStorage.getStore()?.get(AgentTraceContextKey)?.actions??{}).find(t=>t.sessionId===e&&t.callId===n)}getAction(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.actions[e]}getSession(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[e]}getTurn(e,n){return contextStorage.getStore()?.get(AgentTraceContextKey)?.turns[turnKey(e,n)]}setAction(e,t){updateState(n=>({...n,actions:{...n.actions,[e]:t}}))}setSession(e,t){updateState(n=>({...n,sessions:{...n.sessions,[e]:t}}))}setTurn(e,t,n){updateState(r=>({...r,turns:{...r.turns,[turnKey(e,t)]:n}}))}updateTurn(e,t,n){updateState(r=>{let i=turnKey(e,t),a=r.turns[i];return a===void 0?r:{...r,turns:{...r.turns,[i]:n(a)}}})}};function updateState(e){loadContext().set(AgentTraceContextKey,t=>e(t??{actions:{},sessions:{},turns:{}}))}function turnKey(e,t){return`${e}\0${t}`}function serializeState(e){return{actions:e.actions,sessions:Object.fromEntries(Object.entries(e.sessions).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context)}])),turns:Object.fromEntries(Object.entries(e.turns).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context),terminal:t.terminal===void 0?void 0:t.terminal.type===`turn.failed`?{error:serializeError(t.terminal.error),type:t.terminal.type}:{type:t.terminal.type}}]))}}function deserializeState(t){return isRecord(t)?{actions:deserializeRecord(t.actions,deserializeAction),sessions:deserializeRecord(t.sessions,t=>{if(!(!isRecord(t)||!isSpanContext(t.context)))return{agentName:typeof t.agentName==`string`?t.agentName:void 0,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:typeof t.channelKind==`string`?t.channelKind:void 0,context:t.context,decision:readInstrumentationDecision(t.decision),rootSessionId:typeof t.rootSessionId==`string`?t.rootSessionId:``}}),turns:deserializeRecord(t.turns,e=>{if(!(!isRecord(e)||!isSpanContext(e.context))&&!(typeof e.parentSpanId!=`string`||typeof e.startTimeMs!=`number`))return{context:e.context,modelUsage:deserializeModelUsage(e.modelUsage),parentIsRemote:typeof e.parentIsRemote==`boolean`?e.parentIsRemote:void 0,parentSpanId:e.parentSpanId,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,terminal:deserializeTerminal(e.terminal)}})}:{actions:{},sessions:{},turns:{}}}function deserializeModelUsage(e){if(!isRecord(e))return;let t=typeof e.inputTokens==`number`?e.inputTokens:void 0,n=typeof e.outputTokens==`number`?e.outputTokens:void 0;return t===void 0&&n===void 0?void 0:{inputTokens:t,outputTokens:n}}function deserializeAction(t){if(!(!isRecord(t)||typeof t.attemptIndex!=`number`||typeof t.callId!=`string`||!isActionKind(t.kind)||typeof t.name!=`string`||!isSpanContext(t.parent)||typeof t.rootSessionId!=`string`||typeof t.sessionId!=`string`||typeof t.spanId!=`string`||typeof t.startTimeMs!=`number`||typeof t.stepIndex!=`number`||typeof t.turnId!=`string`))return{attemptIndex:t.attemptIndex,callId:t.callId,channelAudience:normalizeChannelAudience(t.channelAudience),inputAttribute:typeof t.inputAttribute==`string`?t.inputAttribute:void 0,kind:t.kind,name:t.name,parent:t.parent,rootSessionId:t.rootSessionId,sessionId:t.sessionId,spanId:t.spanId,startTimeMs:t.startTimeMs,stepIndex:t.stepIndex,turnId:t.turnId}}function isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function deserializeRecord(e,t){if(!isRecord(e))return{};let n={};for(let[r,i]of Object.entries(e)){let e=t(i);e!==void 0&&(n[r]=e)}return n}function deserializeTerminal(e){if(!isRecord(e)||typeof e.type!=`string`)return;let t=e.type;if(isTurnTerminalType(t))return t===`turn.failed`?{error:deserializeError(e.error),type:t}:{type:t}}function serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function serializeError(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:void 0}function deserializeError(e){if(!isRecord(e)||typeof e.message!=`string`)return;let t=Error(e.message);return typeof e.name==`string`&&(t.name=e.name),typeof e.stack==`string`&&(t.stack=e.stack),t}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{ContextAgentTraceStateStore,preserveSerializedAgentTraceState,readActionTraceContext,readCurrentSessionTraceDecision,readSessionTraceContext,readSessionTraceDecision};
@@ -38,9 +38,11 @@ export interface OtelOptions {
38
38
  * existing audience-aware behavior; explicit decisions can disable emission
39
39
  * or select input and output capture independently. Defaults to emitting
40
40
  * every audience, with content only for public conversations. The result is
41
- * an OpenTelemetry capture ceiling: per-delivery audience and destination
42
- * settings can only narrow it. It never changes what authored instrumentation
43
- * providers receive. A thrown error rejects trace production without
41
+ * an OpenTelemetry capture ceiling: local delivery audience and destination
42
+ * settings can only narrow it. For a trusted remote trace, eve evaluates this
43
+ * policy against the immutable origin audience and intersects it with the
44
+ * parent's effective ceiling, so every hop can only narrow capture. It never
45
+ * changes what authored instrumentation providers receive. A thrown error rejects trace production without
44
46
  * silencing lifecycle providers. The policy may be invoked more than once
45
47
  * while a new session is being prepared, so it must be deterministic for
46
48
  * consistent results.
@@ -13,7 +13,7 @@ export declare function registerOtelPipeline(input: {
13
13
  readonly pipeline: OtelPipeline;
14
14
  readonly serviceName: string;
15
15
  }): RegisteredOtelPipeline;
16
- /** Lifecycle retained from the tracer provider that owns every destination. */
16
+ /** Lifecycle retained from the providers that own every destination. */
17
17
  export interface RegisteredOtelPipeline {
18
18
  readonly forceFlush: () => Promise<void>;
19
19
  readonly idGenerator: AgentSpanIdGenerator;
@@ -1 +1 @@
1
- import{createRequire}from"node:module";import{context,propagation,trace}from"#compiled/@opentelemetry/api/index.js";import{AgentSpanIdGenerator}from"#tracing/agent-span-id-generator.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";const REGISTRATION_SPAN_NAME=`eve.otel.registration`,REPLAY_DEDUPLICATION_LIMIT=1e5,require=createRequire(import.meta.url);var RegistrationMarkerPropagator=class{#e=!1;extract(e){return e}fields(){return[]}inject(){this.#e=!0}isInstalled(){return this.#e=!1,propagation.inject(context.active(),{},{set:()=>{}}),this.#e}},PrivateSpanFilteringProcessor=class{endedSpans=new Set;forwardedSpans=new Set;pendingByParent=new Map;pendingSpanCount=0;processors;startedSpans=new Set;constructor(e){this.processors=e}async forceFlush(){this.drainPendingSpans(),await Promise.all(this.processors.map(e=>e.forceFlush()))}onEnd(e){if(isRegistrationSpan(e))return;let t=spanIdentity(e);if(t!==void 0){if(this.endedSpans.has(t))return;if(this.endedSpans.size>=REPLAY_DEDUPLICATION_LIMIT){let e=this.endedSpans.values().next().value;e!==void 0&&this.endedSpans.delete(e)}this.endedSpans.add(t)}let n=parentIdentity(e);if(n!==void 0&&this.startedSpans.has(n)&&!this.forwardedSpans.has(n)){let t=this.pendingByParent.get(n)??[];t.push(e),this.pendingByParent.set(n,t),this.pendingSpanCount+=1,this.pendingSpanCount>1e4&&this.releaseOldestPendingParent();return}this.forward(e,t)}onStart(e,t){if(isRegistrationSpan(e))return;let n=spanIdentity(e);n!==void 0&&addBounded(this.startedSpans,n);for(let n of this.processors)n.onStart(e,t)}async shutdown(){this.drainPendingSpans(),await Promise.all(this.processors.map(e=>e.shutdown()))}drainPendingSpans(){for(;this.pendingByParent.size>0;)this.releaseOldestPendingParent()}releaseOldestPendingParent(){let e=this.pendingByParent.keys().next().value;e!==void 0&&this.releaseChildren(e)}releaseChildren(e){let t=this.pendingByParent.get(e);if(t!==void 0){this.pendingByParent.delete(e),this.pendingSpanCount-=t.length;for(let e of t)this.forward(e,spanIdentity(e))}}forward(e,t){for(let t of this.processors)t.onEnd(e);t!==void 0&&(addBounded(this.forwardedSpans,t),this.releaseChildren(t))}};function registerOtelPipeline(e){let{pipeline:t}=e,n=captureOptionalPeerTracerProxy(),r=new AgentSpanIdGenerator,i=new RegistrationMarkerPropagator,a={attributes:t.resource,autoDetectResources:!1,idGenerator:r,instrumentations:t.instrumentations??[],metricReaders:t.metricReaders,propagators:[...t.propagators??[`auto`],i],serviceName:e.serviceName,spanProcessors:t.spanProcessors.map(e=>isSpanProcessor(e)?new PrivateSpanFilteringProcessor([e]):e)};registerOTel(t.sampler===void 0?a:{...a,traceSampler:t.sampler});let o=globalTracerUses(r),s=i.isInstalled();if((!o||!s)&&rollbackRegistration({ownsPropagator:s,ownsTracer:o}),!o)throw Error("eve could not register OpenTelemetry because another runtime already owns the global tracer provider. Remove the other `registerOTel` call, or move its exporters into eve's `otelIntegration({ spanProcessors: [...] })`.");if(!s)throw Error("eve could not register OpenTelemetry because another runtime already owns the global propagator. Remove the other global propagator registration and declare propagators through eve's `otel()` instead.");let c=runtimeTracerProvider();if(typeof c.forceFlush!=`function`||typeof c.shutdown!=`function`)throw rollbackRegistration({ownsPropagator:s,ownsTracer:o}),Error(`The registered OpenTelemetry tracer provider has no lifecycle methods.`);return n?.setDelegate(c),{forceFlush:()=>c.forceFlush(),idGenerator:r,samplesTrace:e=>samplerAdmitsTrace(r,e),shutdown:()=>c.shutdown()}}function samplerAdmitsTrace(e,t){return(e.withTraceId(t,()=>trace.getTracer(`eve.registration`).startSpan(REGISTRATION_SPAN_NAME,{root:!0})).spanContext().traceFlags&1)==1}function captureOptionalPeerTracerProxy(){try{let e=require("@opentelemetry/api"),t=e.trace.getTracerProvider();return t instanceof e.ProxyTracerProvider?t:void 0}catch{return}}function rollbackRegistration(e){if(e.ownsPropagator&&propagation.disable(),!e.ownsTracer)return;let t=runtimeTracerProvider();if(typeof t.shutdown==`function`)try{t.shutdown().catch(()=>{})}catch{}trace.disable()}function runtimeTracerProvider(){let e=trace.getTracerProvider();return e.getDelegate?.()??e}function globalTracerUses(e){let t=e.allocateSpanId();return e.withSpanId(t,()=>trace.getTracer(`eve.registration`).startSpan(REGISTRATION_SPAN_NAME)).spanContext().spanId===t}function isRegistrationSpan(e){return typeof e==`object`&&!!e&&`name`in e&&e.name===REGISTRATION_SPAN_NAME}function spanIdentity(e){if(typeof e!=`object`||!e||!(`spanContext`in e)||typeof e.spanContext!=`function`)return;let t=e.spanContext();return typeof t.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function parentIdentity(e){if(typeof e!=`object`||!e||!(`parentSpanContext`in e))return;let t=e.parentSpanContext;return typeof t?.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function addBounded(e,t){if(e.size>=REPLAY_DEDUPLICATION_LIMIT){let t=e.values().next().value;t!==void 0&&e.delete(t)}e.add(t)}function isSpanProcessor(e){return e!==`auto`}export{registerOtelPipeline};
1
+ import{createRequire}from"node:module";import{context,metrics,propagation,trace}from"#compiled/@opentelemetry/api/index.js";import{AgentSpanIdGenerator}from"#tracing/agent-span-id-generator.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";const REGISTRATION_SPAN_NAME=`eve.otel.registration`,REPLAY_DEDUPLICATION_LIMIT=1e5,require=createRequire(import.meta.url);var RegistrationMarkerPropagator=class{#e=!1;extract(e){return e}fields(){return[]}inject(){this.#e=!0}isInstalled(){return this.#e=!1,propagation.inject(context.active(),{},{set:()=>{}}),this.#e}},PrivateSpanFilteringProcessor=class{endedSpans=new Set;forwardedSpans=new Set;pendingByParent=new Map;pendingSpanCount=0;processors;startedSpans=new Set;constructor(e){this.processors=e}async forceFlush(){this.drainPendingSpans(),await Promise.all(this.processors.map(e=>e.forceFlush()))}onEnd(e){if(isRegistrationSpan(e))return;let t=spanIdentity(e);if(t!==void 0){if(this.endedSpans.has(t))return;if(this.endedSpans.size>=REPLAY_DEDUPLICATION_LIMIT){let e=this.endedSpans.values().next().value;e!==void 0&&this.endedSpans.delete(e)}this.endedSpans.add(t)}let n=parentIdentity(e);if(n!==void 0&&this.startedSpans.has(n)&&!this.forwardedSpans.has(n)){let t=this.pendingByParent.get(n)??[];t.push(e),this.pendingByParent.set(n,t),this.pendingSpanCount+=1,this.pendingSpanCount>1e4&&this.releaseOldestPendingParent();return}this.forward(e,t)}onStart(e,t){if(isRegistrationSpan(e))return;let n=spanIdentity(e);n!==void 0&&addBounded(this.startedSpans,n);for(let n of this.processors)n.onStart(e,t)}async shutdown(){this.drainPendingSpans(),await Promise.all(this.processors.map(e=>e.shutdown()))}drainPendingSpans(){for(;this.pendingByParent.size>0;)this.releaseOldestPendingParent()}releaseOldestPendingParent(){let e=this.pendingByParent.keys().next().value;e!==void 0&&this.releaseChildren(e)}releaseChildren(e){let t=this.pendingByParent.get(e);if(t!==void 0){this.pendingByParent.delete(e),this.pendingSpanCount-=t.length;for(let e of t)this.forward(e,spanIdentity(e))}}forward(e,t){for(let t of this.processors)t.onEnd(e);t!==void 0&&(addBounded(this.forwardedSpans,t),this.releaseChildren(t))}};function registerOtelPipeline(e){let{pipeline:t}=e,n=captureOptionalPeerTracerProxy(),r=new AgentSpanIdGenerator,i=new RegistrationMarkerPropagator,a={attributes:t.resource,autoDetectResources:!1,idGenerator:r,instrumentations:t.instrumentations??[],metricReaders:t.metricReaders,propagators:[...t.propagators??[`auto`],i],serviceName:e.serviceName,spanProcessors:t.spanProcessors.map(e=>isSpanProcessor(e)?new PrivateSpanFilteringProcessor([e]):e)};registerOTel(t.sampler===void 0?a:{...a,traceSampler:t.sampler});let o=globalTracerUses(r),s=i.isInstalled();if((!o||!s)&&rollbackRegistration({ownsPropagator:s,ownsTracer:o}),!o)throw Error("eve could not register OpenTelemetry because another runtime already owns the global tracer provider. Remove the other `registerOTel` call, or move its exporters into eve's `otelIntegration({ spanProcessors: [...] })`.");if(!s)throw Error("eve could not register OpenTelemetry because another runtime already owns the global propagator. Remove the other global propagator registration and declare propagators through eve's `otel()` instead.");let c=runtimeTracerProvider();if(typeof c.forceFlush!=`function`||typeof c.shutdown!=`function`)throw rollbackRegistration({ownsPropagator:s,ownsTracer:o}),Error(`The registered OpenTelemetry tracer provider has no lifecycle methods.`);n?.setDelegate(c);let l=runtimeMeterProvider();return{forceFlush:async()=>{await Promise.all([c.forceFlush(),l.forceFlush?.()])},idGenerator:r,samplesTrace:e=>samplerAdmitsTrace(r,e),shutdown:async()=>{disableInstrumentations(t.instrumentations),await Promise.all([c.shutdown(),l.shutdown?.()])}}}function samplerAdmitsTrace(e,t){return(e.withTraceId(t,()=>trace.getTracer(`eve.registration`).startSpan(REGISTRATION_SPAN_NAME,{root:!0})).spanContext().traceFlags&1)==1}function captureOptionalPeerTracerProxy(){try{let e=require("@opentelemetry/api"),t=e.trace.getTracerProvider();return t instanceof e.ProxyTracerProvider?t:void 0}catch{return}}function rollbackRegistration(e){if(e.ownsPropagator&&propagation.disable(),!e.ownsTracer)return;let t=runtimeTracerProvider();if(typeof t.shutdown==`function`)try{t.shutdown().catch(()=>{})}catch{}trace.disable()}function runtimeTracerProvider(){let e=trace.getTracerProvider();return e.getDelegate?.()??e}function runtimeMeterProvider(){let e=metrics.getMeterProvider();return{forceFlush:typeof e?.forceFlush==`function`?()=>e.forceFlush():void 0,shutdown:typeof e?.shutdown==`function`?()=>e.shutdown():void 0}}function disableInstrumentations(e){for(let t of e??[]){let e=t?.disable;if(typeof e==`function`)try{e.call(t)}catch{}}}function globalTracerUses(e){let t=e.allocateSpanId();return e.withSpanId(t,()=>trace.getTracer(`eve.registration`).startSpan(REGISTRATION_SPAN_NAME)).spanContext().spanId===t}function isRegistrationSpan(e){return typeof e==`object`&&!!e&&`name`in e&&e.name===REGISTRATION_SPAN_NAME}function spanIdentity(e){if(typeof e!=`object`||!e||!(`spanContext`in e)||typeof e.spanContext!=`function`)return;let t=e.spanContext();return typeof t.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function parentIdentity(e){if(typeof e!=`object`||!e||!(`parentSpanContext`in e))return;let t=e.parentSpanContext;return typeof t?.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function addBounded(e,t){if(e.size>=REPLAY_DEDUPLICATION_LIMIT){let t=e.values().next().value;t!==void 0&&e.delete(t)}e.add(t)}function isSpanProcessor(e){return e!==`auto`}export{registerOtelPipeline};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-B5zw1dwj.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-Bgp6INfi.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-B5zw1dwj.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-Bgp6INfi.js";
2
2
 
3
3
  export { useEveAgent };
@@ -405,6 +405,8 @@ defineChannel({
405
405
  });
406
406
  ```
407
407
 
408
+ If `fetchFile` throws, eve replaces that attachment with a model-visible error note and continues the turn. Built-in channels include safe details such as the upstream HTTP status. Custom channel errors use a generic note, while eve keeps the original error in operator logs.
409
+
408
410
  The `URL` object survives the queue boundary as a string and is reconstituted inside the workflow step. The staging pipeline calls `fetchFile` with the URL serialized as a string (the URL's `href`), which is why the example matches on `url.startsWith(...)`. Return bytes to stage the file to the sandbox, or `null` to let the URL pass through to the model provider.
409
411
 
410
412
  The framework handles staging bytes to the sandbox, enforcing upload policy, hydrating files for the model call, and reconstituting `URL` objects after queue serialization. See [Inbound attachments](../sandbox#inbound-attachments) for the shared storage, size, and provider-input behavior.
@@ -47,6 +47,10 @@ curl -X POST https://<deployment>/eve/v1/session \
47
47
  # {"ok":true,"sessionId":"wrun_A","status":"accepted"}
48
48
  ```
49
49
 
50
+ The `202` response means Workflow accepted the durable run. The command inbox may still be
51
+ starting, so an immediate follow-up or control request can report that the session is not active.
52
+ The event-stream client retries the brief window before the new run becomes readable.
53
+
50
54
  Authenticated callers that may retry a create request can pass their own `operationId` for
51
55
  create-once semantics. The same operation under the same authenticated principal returns the
52
56
  active session it already created instead of dispatching the input again. The first accepted
@@ -72,7 +76,7 @@ curl -X POST https://<deployment>/eve/v1/session/wrun_A \
72
76
 
73
77
  Follow-up messages use `turnPolicy: "steer"` by default. If a turn is active, eve buffers the message before cooperatively cancelling that turn, then starts the follow-up as a replacement turn with a new turn ID. Set `turnPolicy: "queue"` on `eveChannel(...)` when follow-ups should wait for active turns to finish. `inputResponses` never steer.
74
78
 
75
- Sending a message to an unknown or terminal session ID returns `409` with
79
+ Sending a message to an unknown, terminal, or not-yet-active session ID returns `409` with
76
80
  `{"code":"session_not_active","error":"The session is no longer active.","ok":false}`.
77
81
  TypeScript clients expose the stable code as `ClientError.code`. The route never
78
82
  creates or follows a replacement session.
@@ -70,10 +70,15 @@ Inbound files are off by default. Opt in to allow personal-scope downloads and p
70
70
 
71
71
  ```ts
72
72
  export default teamsChannel({
73
- files: { enabled: true, allowedHosts: ["contoso.sharepoint.com"] },
73
+ files: {
74
+ enabled: true,
75
+ allowedHosts: ["smba.trafficmanager.net", "contoso.sharepoint.com"],
76
+ },
74
77
  });
75
78
  ```
76
79
 
80
+ eve authenticates downloads from Microsoft Bot Connector hosts with your bot credentials. Downloads from other allowlisted hosts remain unauthenticated.
81
+
77
82
  ## What to read next
78
83
 
79
84
  - [Channels overview](./overview): the channel contract and every built-in channel
@@ -32,8 +32,10 @@ curl -X POST http://127.0.0.1:2000/eve/v1/session \
32
32
  -d '{"message":"Summarize the latest forecast."}'
33
33
  ```
34
34
 
35
- eve responds right away with the durable `sessionId` in the JSON body and
36
- `x-eve-session-id` header.
35
+ eve responds with `202` and the durable `sessionId` in the JSON body and
36
+ `x-eve-session-id` header as soon as Workflow accepts the run. The command inbox can still be
37
+ starting at that point. An immediate follow-up can return `409 session_not_active`; wait for
38
+ `session.waiting` before sending the next message.
37
39
 
38
40
  ## Stream a session
39
41
 
@@ -239,7 +239,11 @@ export default eveChannel({
239
239
 
240
240
  The predicate authorizes the _forwarder_ (the verified route-auth principal — who is asserting), not the forwarded principal (what is asserted). Match it precisely: a permissive predicate like `() => true` lets any caller that passes route auth assert any principal, including preview deployments of your own project when `vercelOidc()` is in the walk. `trustedForwarders` exists only on your authored channel — the framework default channel never accepts a forwarded principal, so a receiving deployment must author `agent/channels/eve.ts`.
241
241
 
242
- When the predicate accepts a create request, `ctx.session.auth.current` and `.initiator` carry the forwarded user exactly as if they had called your deployment directly. On continuation, only `auth.current` is replaced; `auth.initiator` remains the session creator. User-scoped connections, local subagents, and further `forwardPrincipal` hops therefore see the active turn's caller. The forwarder is recorded on accepted contexts as the `eve:forwarded-by` attribute (always overwritten by the receiver, so a forwarder cannot falsify it). Rejections fail loud: a forwarded body without `trustedForwarders` configured or with a forwarder the predicate refuses is a `403`, and a malformed payload is a `400`. Only principal metadata is ever accepted — tokens and credentials never cross the hop.
242
+ When the predicate accepts a create request, `ctx.session.auth.current` and `.initiator` carry the forwarded user exactly as if they had called your deployment directly. On continuation, only `auth.current` is replaced; `auth.initiator` remains the session creator. User-scoped connections, local subagents, and further `forwardPrincipal` hops therefore see the active turn's caller.
243
+
244
+ The forwarder is recorded on accepted contexts as the `eve:forwarded-by` attribute (always overwritten by the receiver, so a forwarder cannot falsify it). Rejections fail loud: a forwarded body without `trustedForwarders` configured or with a forwarder the predicate refuses is a `403`, and a malformed payload is a `400`. Only principal metadata is ever accepted — tokens and credentials never cross the hop.
245
+
246
+ For requests marked as remote delegations by a callback body and valid sampled `traceparent`, the same accepted `trustedForwarders` result may admit an origin audience and directional content ceiling from one W3C Baggage member. The assertion is not an authorization grant: the receiver's trace policy independently decides against the immutable origin audience, and the two decisions are intersected. Every later hop forwards only that narrowed result. Malformed, partial, unsampled, or mixed-version assertions become metadata-only. The callback and headers are caller-supplied—the verified transport principal and `trustedForwarders` are the trust boundary. See [Preserving trace content](./remote-agents#preserving-trace-content).
243
247
 
244
248
  > ⚠️ Both deployments must support continuation forwarding before you resume persistent remote sessions. A create-only receiver rejects a forwarded continuation with HTTP 400; the sender does not fall back to service authority. See [Forwarding the caller identity](./remote-agents#forwarding-the-caller-identity) for the upgrade behavior.
245
249
 
@@ -36,6 +36,12 @@ console.log(result.status, result.message);
36
36
 
37
37
  When the stream includes `session.failed`, the turn returns `status: "failed"` rather than throwing. Transport and route errors throw `ClientError`.
38
38
 
39
+ `session.send()` retries `409 session_not_active` three times when a durable run has been accepted
40
+ but its command inbox is still starting. The retries wait 250 ms, 500 ms, and 1 second. Other
41
+ errors, `session.respond()`, control methods, and raw HTTP requests do not use this retry. An unknown
42
+ session still throws `ClientError` immediately, while a terminal session throws after the final
43
+ attempt. The client never creates a replacement session.
44
+
39
45
  ## Send a full turn payload
40
46
 
41
47
  Pass the full payload to `create()` for the first turn or `send()` for a follow-up:
@@ -13,35 +13,47 @@ The transcript remains in your terminal scrollback after you exit. Run `/help` i
13
13
 
14
14
  ## Commands
15
15
 
16
- | Command | Description |
17
- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
18
- | `/model` | Configure the model and its provider. Pass a model ID to set it directly: `/model provider/model-id`. |
19
- | `/add` | Browse and install channels, MCP connections, extensions, and observability integrations. Pass an item address to open it directly: `/add channel/slack`. |
20
- | `/deploy` | Deploy the agent to Vercel production. Links the directory first if needed. |
21
- | `/vc:install` | Install the Vercel CLI. |
22
- | `/vc:login` | Log in to Vercel or restore access to a remote deployment. |
23
- | `/info` | Show the resolved application, compiled artifacts, discovery diagnostics, and messaging routes. |
24
- | `/loglevel` | Choose which server and agent logs appear in the transcript. |
25
- | `/traces` | Open the local trace viewer. Pass a trace ID prefix to open a specific trace. |
26
- | `/reset` | Start a fresh session. |
27
- | `/cancel` | Cancel the current turn without discarding settled context. |
28
- | `/clear` | Clear the session's model-message history. `/new` is an alias. |
29
- | `/compact` | Compact the current session's context. |
30
- | `/exit` | Quit the UI. |
31
- | `/help` | List available commands. |
16
+ | Command | Description |
17
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
18
+ | `/model` | Configure the model and its provider. Pass a model ID to set it directly: `/model provider/model-id`. |
19
+ | `/add` | Select and install channels, MCP connections, extensions, and observability integrations. Pass an item address to confirm and install it directly: `/add channel/slack`. |
20
+ | `/deploy` | Deploy the agent to Vercel production. Links the directory first if needed. |
21
+ | `/vc:install` | Install the Vercel CLI. |
22
+ | `/vc:login` | Log in to Vercel or restore access to a remote deployment. |
23
+ | `/info` | Show the resolved application, compiled artifacts, discovery diagnostics, and messaging routes. |
24
+ | `/loglevel` | Choose which server and agent logs appear in the transcript. |
25
+ | `/traces` | Open the local trace viewer. Pass a trace ID prefix to open a specific trace. |
26
+ | `/reset` | Start a fresh session. |
27
+ | `/cancel` | Cancel the current turn without discarding settled context. |
28
+ | `/clear` | Clear the session's model-message history. `/new` is an alias. |
29
+ | `/compact` | Compact the current session's context. |
30
+ | `/exit` | Quit the UI. |
31
+ | `/help` | List available commands. |
32
32
 
33
33
  `/model`, `/add`, `/deploy`, `/info`, and `/traces` are available when `eve dev` runs locally. They are unavailable when the UI connects to a server with `--url`.
34
34
 
35
+ ## Set up a new agent
36
+
37
+ After `eve init`, the terminal UI guides you through **Model**, **Channels**, **Integrations**, and **Review** before the first chat prompt. The progress rail keeps the four steps visible throughout onboarding. Model setup can install or upgrade the Vercel CLI, open Vercel login, and resume project linking without leaving the flow.
38
+
39
+ Model and Vercel changes take effect when you complete Model, then onboarding continues to Channels. Channel and integration selections remain drafts until you finish Review. You can move back and forth between Channels, Integrations, and Review; use `/model` after onboarding to change the committed model configuration.
40
+
35
41
  ## Add an integration
36
42
 
37
- Bare `/add` opens the categorized registry browser. Pass an item address — `<category>/<name>`, where category is `channel`, `connection`, `extension`, or `instrumentation` — to skip the category and search screens and open that item directly:
43
+ Bare `/add` opens the standalone planner on **Channels**. It does not include model configuration. The progress rail shows selection counts as you move between **Channels**, **Integrations**, and **Review**.
44
+
45
+ Press `Space` or `Enter` to toggle the highlighted item. Press `Right Arrow` to preserve the current selections and continue, `Left Arrow` to preserve them and go back, or `Esc` to cancel. Installation requires `Enter` on **Install and set up** from Review. During installation, `Esc` cancels only the active item and continues with the remaining selections. The final summary reports installed, cancelled, and failed items separately.
46
+
47
+ Pass an item address to `/add` to confirm and install that exact address without opening the planner:
38
48
 
39
49
  ```text
40
50
  /add channel/slack
41
51
  /add extension/agent-browser
52
+ /add linear
53
+ /add @acme/analytics
42
54
  ```
43
55
 
44
- Either way the UI shows the item's details and asks to confirm before installing, then runs the same installation and setup prompts. Choosing **Back** on a directly addressed item returns to the registry browser.
56
+ The UI installs planner selections in order and offers deployment once after the batch when an installed item requires it.
45
57
 
46
58
  ## Work with the agent
47
59