eve 0.71.3 → 0.72.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +22 -6
  3. package/dist/src/acp/adapter.js +1 -1
  4. package/dist/src/ai/decide.d.ts +7 -0
  5. package/dist/src/ai/decide.js +1 -0
  6. package/dist/src/chunks/{use-eve-agent-CFCaYnrI.js → use-eve-agent-C1GYGCtb.js} +698 -388
  7. package/dist/src/chunks/{use-eve-agent-DcDhXNv1.js → use-eve-agent-hZJ7CB8t.js} +698 -388
  8. package/dist/src/cli/commands/integration-setup.js +1 -1
  9. package/dist/src/cli/commands/registry.js +1 -1
  10. package/dist/src/cli/commands/trace-detail.d.ts +1 -1
  11. package/dist/src/cli/commands/trace-detail.js +1 -1
  12. package/dist/src/cli/dev/tui/runner.js +1 -1
  13. package/dist/src/cli/dev/tui/setup-flow.d.ts +1 -0
  14. package/dist/src/cli/dev/tui/setup-panel.d.ts +1 -0
  15. package/dist/src/cli/dev/tui/setup-panel.js +2 -1
  16. package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +2 -2
  17. package/dist/src/cli/dev/tui/traces/trace-conversation.js +2 -2
  18. package/dist/src/cli/dev/tui/transcript-parts.d.ts +2 -1
  19. package/dist/src/cli/dev/tui/transcript-parts.js +1 -1
  20. package/dist/src/cli/dev/tui/transcript.js +1 -1
  21. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  22. package/dist/src/client/conversation-projection.d.ts +4 -0
  23. package/dist/src/client/conversation-projection.js +1 -0
  24. package/dist/src/client/conversation-reducer.js +1 -1
  25. package/dist/src/client/conversation-state.d.ts +5 -26
  26. package/dist/src/client/conversation-state.js +1 -1
  27. package/dist/src/client/index.d.ts +1 -0
  28. package/dist/src/client/index.js +1 -1
  29. package/dist/src/client/message-action-parts.d.ts +1 -11
  30. package/dist/src/client/message-action-parts.js +1 -1
  31. package/dist/src/client/message-reducer.d.ts +3 -1
  32. package/dist/src/client/message-reducer.js +1 -1
  33. package/dist/src/client/session-utils.js +1 -1
  34. package/dist/src/client/session.js +1 -1
  35. package/dist/src/client/tool-call-state.d.ts +23 -0
  36. package/dist/src/client/tool-call-state.js +1 -0
  37. package/dist/src/client/tool-part-state.d.ts +7 -0
  38. package/dist/src/client/tool-part-state.js +1 -0
  39. package/dist/src/compiled/.vendor-stamp.json +10 -10
  40. package/dist/src/compiled/@ai-sdk/anthropic/index.d.ts +1453 -1358
  41. package/dist/src/compiled/@ai-sdk/anthropic/index.js +1 -2
  42. package/dist/src/compiled/@ai-sdk/code-mode/index.d.ts +172 -163
  43. package/dist/src/compiled/@ai-sdk/code-mode/index.js +15 -20
  44. package/dist/src/compiled/@ai-sdk/google/index.d.ts +772 -733
  45. package/dist/src/compiled/@ai-sdk/google/index.js +6 -8
  46. package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +887 -790
  47. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  48. package/dist/src/compiled/@ai-sdk/openai/index.d.ts +1722 -1691
  49. package/dist/src/compiled/@ai-sdk/openai/index.js +3 -14
  50. package/dist/src/compiled/@ai-sdk/otel/index.d.ts +216 -159
  51. package/dist/src/compiled/@ai-sdk/otel/index.js +3 -3
  52. package/dist/src/compiled/@ai-sdk/provider/index.d.ts +7542 -7271
  53. package/dist/src/compiled/@ai-sdk/provider/index.js +1 -3
  54. package/dist/src/compiled/@ai-sdk/provider-utils/index.d.ts +1799 -1600
  55. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  56. package/dist/src/compiled/_chunks/workflow/dist-DXLdlucM.js +15 -0
  57. package/dist/src/compiled/_chunks/workflow/experimental-decision-BrfWf6-n.js +3 -0
  58. package/dist/src/compiler/extension-compatibility.d.ts +36 -20
  59. package/dist/src/compiler/extension-compatibility.js +1 -1
  60. package/dist/src/compiler/manifest.js +1 -1
  61. package/dist/src/context/build-dynamic-tools.js +1 -1
  62. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  63. package/dist/src/context/dynamic-tool-metadata.d.ts +1 -0
  64. package/dist/src/context/providers/session.js +1 -1
  65. package/dist/src/evals/define-eval.d.ts +1 -1
  66. package/dist/src/evals/judge.d.ts +1 -1
  67. package/dist/src/evals/judge.js +2 -2
  68. package/dist/src/evals/mock-model.js +1 -1
  69. package/dist/src/evals/types.d.ts +8 -8
  70. package/dist/src/execution/cancel-descendant-turns-step.d.ts +1 -0
  71. package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
  72. package/dist/src/execution/cancelled-model-call-batch.js +1 -1
  73. package/dist/src/execution/coordination-dispatch-shared.js +1 -1
  74. package/dist/src/execution/coordination-dispatch-step.js +1 -1
  75. package/dist/src/execution/durable-session-read.d.ts +5 -0
  76. package/dist/src/execution/durable-session-read.js +1 -0
  77. package/dist/src/execution/durable-session-store.d.ts +4 -10
  78. package/dist/src/execution/durable-session-store.js +1 -1
  79. package/dist/src/execution/dynamic-connections.d.ts +3 -3
  80. package/dist/src/execution/dynamic-connections.js +1 -1
  81. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  82. package/dist/src/execution/legacy-session/interrupt-step.js +1 -1
  83. package/dist/src/execution/legacy-session/snapshot.d.ts +3 -0
  84. package/dist/src/execution/legacy-session/snapshot.js +1 -1
  85. package/dist/src/execution/model-call-batching.js +1 -1
  86. package/dist/src/execution/node-step.d.ts +2 -0
  87. package/dist/src/execution/node-step.js +1 -1
  88. package/dist/src/execution/proxied-deliver-step.js +1 -1
  89. package/dist/src/execution/publish-session-events.d.ts +7 -2
  90. package/dist/src/execution/publish-session-events.js +1 -1
  91. package/dist/src/execution/session/active-turn.js +1 -1
  92. package/dist/src/execution/session/answer-caller.js +1 -1
  93. package/dist/src/execution/session/checkpoint-migrations.js +1 -1
  94. package/dist/src/execution/session/finalization.js +1 -1
  95. package/dist/src/execution/session/handoff-steps.d.ts +3 -1
  96. package/dist/src/execution/session/handoff-steps.js +1 -1
  97. package/dist/src/execution/session/handoff.d.ts +1 -1
  98. package/dist/src/execution/session/handoff.js +1 -1
  99. package/dist/src/execution/session/pending-turn-state.d.ts +8 -3
  100. package/dist/src/execution/session/pending-turn-state.js +1 -1
  101. package/dist/src/execution/session/task-tool-tracing-step.d.ts +5 -0
  102. package/dist/src/execution/session/task-tool-tracing-step.js +1 -0
  103. package/dist/src/execution/session/turn-step-result.js +1 -1
  104. package/dist/src/execution/session/turn-step.js +1 -1
  105. package/dist/src/execution/session/turn-waiting-step.js +1 -1
  106. package/dist/src/execution/session/turn.d.ts +1 -0
  107. package/dist/src/execution/session/turn.js +1 -1
  108. package/dist/src/execution/settle-cancelled-turn-step.d.ts +4 -6
  109. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  110. package/dist/src/execution/tasks/start.d.ts +3 -3
  111. package/dist/src/execution/tasks/start.js +1 -1
  112. package/dist/src/execution/tasks/steps.d.ts +1 -1
  113. package/dist/src/execution/tasks/steps.js +1 -1
  114. package/dist/src/execution/terminal-session-completion-step.d.ts +5 -1
  115. package/dist/src/execution/terminal-session-completion-step.js +1 -1
  116. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  117. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  118. package/dist/src/execution/tools/connection-tools.js +2 -2
  119. package/dist/src/execution/tools/workflow/harness-definition.js +1 -1
  120. package/dist/src/execution/tools/workflow/step.js +1 -1
  121. package/dist/src/execution/tools/workflow/withdraw-step.d.ts +7 -9
  122. package/dist/src/execution/tools/workflow/withdraw-step.js +1 -1
  123. package/dist/src/execution/workflow-trace-context.d.ts +2 -2
  124. package/dist/src/harness/authorization.d.ts +4 -2
  125. package/dist/src/harness/authorization.js +1 -1
  126. package/dist/src/harness/{compaction.js → compaction/engine.js} +1 -1
  127. package/dist/src/harness/compaction/step.d.ts +46 -0
  128. package/dist/src/harness/compaction/step.js +1 -0
  129. package/dist/src/harness/coordination.d.ts +32 -68
  130. package/dist/src/harness/coordination.js +1 -1
  131. package/dist/src/harness/current-messages.d.ts +1 -3
  132. package/dist/src/harness/current-messages.js +1 -1
  133. package/dist/src/harness/emission.d.ts +4 -52
  134. package/dist/src/harness/emission.js +1 -1
  135. package/dist/src/harness/execute-tool.d.ts +1 -0
  136. package/dist/src/harness/final-output.d.ts +5 -0
  137. package/dist/src/harness/final-output.js +1 -1
  138. package/dist/src/harness/hitl/approvals.d.ts +115 -0
  139. package/dist/src/harness/hitl/approvals.js +1 -0
  140. package/dist/src/harness/hitl/approved-call-callers.d.ts +14 -0
  141. package/dist/src/harness/hitl/approved-call-callers.js +1 -0
  142. package/dist/src/harness/hitl/approved-calls.d.ts +37 -0
  143. package/dist/src/harness/hitl/approved-calls.js +1 -0
  144. package/dist/src/harness/hitl/budget.d.ts +21 -0
  145. package/dist/src/harness/hitl/budget.js +1 -0
  146. package/dist/src/harness/{approval-candidates.d.ts → hitl/candidates.d.ts} +9 -18
  147. package/dist/src/harness/hitl/candidates.js +1 -0
  148. package/dist/src/harness/hitl/coordinator.js +1 -0
  149. package/dist/src/harness/hitl/delivery.d.ts +37 -0
  150. package/dist/src/harness/hitl/delivery.js +1 -0
  151. package/dist/src/harness/hitl/index.d.ts +49 -0
  152. package/dist/src/harness/hitl/index.js +1 -0
  153. package/dist/src/harness/hitl/intake.d.ts +67 -0
  154. package/dist/src/harness/hitl/intake.js +1 -0
  155. package/dist/src/harness/{stale-input-responses.d.ts → hitl/stale-responses.d.ts} +5 -3
  156. package/dist/src/harness/hitl/stale-responses.js +3 -0
  157. package/dist/src/harness/inline-tool-authorization.d.ts +4 -0
  158. package/dist/src/harness/inline-tool-authorization.js +1 -1
  159. package/dist/src/harness/input-extraction.d.ts +1 -10
  160. package/dist/src/harness/input-extraction.js +1 -1
  161. package/dist/src/harness/input-request-resolution.d.ts +1 -5
  162. package/dist/src/harness/input-request-resolution.js +1 -1
  163. package/dist/src/harness/model-call/call.d.ts +78 -0
  164. package/dist/src/harness/model-call/call.js +1 -0
  165. package/dist/src/harness/{model-call-error.d.ts → model-call/errors.d.ts} +1 -1
  166. package/dist/src/harness/model-call/failure.d.ts +52 -0
  167. package/dist/src/harness/model-call/failure.js +1 -0
  168. package/dist/src/harness/model-call/model.d.ts +18 -0
  169. package/dist/src/harness/model-call/model.js +1 -0
  170. package/dist/src/harness/model-call/recovery.d.ts +52 -0
  171. package/dist/src/harness/model-call/recovery.js +1 -0
  172. package/dist/src/harness/model-call/request.d.ts +30 -0
  173. package/dist/src/harness/model-call/request.js +3 -0
  174. package/dist/src/harness/model-call/response.d.ts +39 -0
  175. package/dist/src/harness/model-call/response.js +1 -0
  176. package/dist/src/harness/model-call/retry.d.ts +11 -0
  177. package/dist/src/harness/model-call/retry.js +1 -0
  178. package/dist/src/harness/model-call/run.d.ts +38 -0
  179. package/dist/src/harness/model-call/run.js +1 -0
  180. package/dist/src/harness/model-call/tools.d.ts +48 -0
  181. package/dist/src/harness/model-call/tools.js +1 -0
  182. package/dist/src/harness/model-call/usage.d.ts +23 -0
  183. package/dist/src/harness/model-call/usage.js +1 -0
  184. package/dist/src/harness/nested-actions.d.ts +2 -2
  185. package/dist/src/harness/provider-tools.d.ts +2 -2
  186. package/dist/src/harness/provider-tools.js +1 -1
  187. package/dist/src/harness/proxy-input-requests.d.ts +4 -12
  188. package/dist/src/harness/proxy-input-requests.js +1 -1
  189. package/dist/src/harness/session-machine/commit.d.ts +28 -0
  190. package/dist/src/harness/session-machine/commit.js +1 -0
  191. package/dist/src/harness/session-machine/current.d.ts +29 -0
  192. package/dist/src/harness/session-machine/current.js +1 -0
  193. package/dist/src/harness/session-machine/events.d.ts +6 -0
  194. package/dist/src/harness/session-machine/events.js +1 -0
  195. package/dist/src/harness/session-machine/resolver-events.d.ts +12 -0
  196. package/dist/src/harness/session-machine/resolver-events.js +1 -0
  197. package/dist/src/harness/session-machine/state.d.ts +47 -0
  198. package/dist/src/harness/session-machine/state.js +1 -0
  199. package/dist/src/harness/session-machine/transitions.d.ts +188 -0
  200. package/dist/src/harness/session-machine/transitions.js +1 -0
  201. package/dist/src/harness/session-machine/view.d.ts +58 -0
  202. package/dist/src/harness/session-machine/view.js +1 -0
  203. package/dist/src/harness/step/after-model.d.ts +7 -0
  204. package/dist/src/harness/step/after-model.js +1 -0
  205. package/dist/src/harness/step/context.d.ts +59 -0
  206. package/dist/src/harness/step/context.js +1 -0
  207. package/dist/src/harness/step/intake.d.ts +34 -0
  208. package/dist/src/harness/step/intake.js +1 -0
  209. package/dist/src/harness/step/prompt.d.ts +37 -0
  210. package/dist/src/harness/step/prompt.js +1 -0
  211. package/dist/src/harness/step-hooks.d.ts +8 -13
  212. package/dist/src/harness/step-hooks.js +1 -1
  213. package/dist/src/harness/tool-loop.d.ts +7 -22
  214. package/dist/src/harness/tool-loop.js +1 -3
  215. package/dist/src/harness/tools.d.ts +13 -0
  216. package/dist/src/harness/tools.js +1 -1
  217. package/dist/src/harness/turn-tag-state.d.ts +1 -1
  218. package/dist/src/harness/types.d.ts +6 -0
  219. package/dist/src/instrumentation/ai-sdk-hook-bridge.d.ts +1 -1
  220. package/dist/src/instrumentation/ai-sdk-hook-bridge.js +1 -1
  221. package/dist/src/instrumentation/content.js +1 -1
  222. package/dist/src/instrumentation/dispatch.js +1 -1
  223. package/dist/src/instrumentation/lifecycle.d.ts +28 -56
  224. package/dist/src/instrumentation/native-events.d.ts +2 -1
  225. package/dist/src/instrumentation/native-events.js +1 -1
  226. package/dist/src/instrumentation/provider.d.ts +1 -1
  227. package/dist/src/instrumentation/runtime-context.d.ts +2 -3
  228. package/dist/src/instrumentation/runtime-context.js +1 -1
  229. package/dist/src/instrumentation/runtime.d.ts +11 -1
  230. package/dist/src/instrumentation/runtime.js +1 -1
  231. package/dist/src/instrumentation/state.d.ts +6 -1
  232. package/dist/src/instrumentation/state.js +1 -1
  233. package/dist/src/internal/application/package.js +1 -1
  234. package/dist/src/internal/attachments/limited-read.d.ts +16 -0
  235. package/dist/src/internal/attachments/limited-read.js +1 -0
  236. package/dist/src/internal/authored-definition/schema-backed.d.ts +2 -1
  237. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  238. package/dist/src/internal/mcp/published-tools.d.ts +13 -0
  239. package/dist/src/internal/mcp/published-tools.js +1 -0
  240. package/dist/src/internal/mcp/request-trace-context.d.ts +12 -0
  241. package/dist/src/internal/mcp/request-trace-context.js +1 -0
  242. package/dist/src/internal/mcp/streamable-http-server.d.ts +7 -3
  243. package/dist/src/internal/mcp/streamable-http-server.js +1 -1
  244. package/dist/src/internal/model-auth/transport.d.ts +3 -3
  245. package/dist/src/internal/model-auth/transport.js +1 -1
  246. package/dist/src/models/auto.d.ts +5 -5
  247. package/dist/src/models/auto.js +2 -2
  248. package/dist/src/protocol/message.d.ts +7 -0
  249. package/dist/src/protocol/message.js +1 -1
  250. package/dist/src/protocol/session-projection.d.ts +159 -0
  251. package/dist/src/protocol/session-projection.js +1 -0
  252. package/dist/src/public/ai/index.d.ts +1 -1
  253. package/dist/src/public/ai/index.js +1 -1
  254. package/dist/src/public/channels/chat-sdk/attachment-refs.d.ts +15 -0
  255. package/dist/src/public/channels/chat-sdk/attachment-refs.js +1 -0
  256. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  257. package/dist/src/public/channels/chat-sdk/messageToUserContent.d.ts +11 -5
  258. package/dist/src/public/channels/chat-sdk/messageToUserContent.js +1 -1
  259. package/dist/src/public/channels/discord/attachments.d.ts +15 -0
  260. package/dist/src/public/channels/discord/attachments.js +1 -0
  261. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  262. package/dist/src/public/channels/discord/inbound.d.ts +13 -0
  263. package/dist/src/public/channels/discord/inbound.js +1 -1
  264. package/dist/src/public/channels/linear/inbound-uploads.d.ts +21 -0
  265. package/dist/src/public/channels/linear/inbound-uploads.js +1 -0
  266. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  267. package/dist/src/public/channels/linq/inboundContent.d.ts +7 -1
  268. package/dist/src/public/channels/linq/inboundContent.js +1 -1
  269. package/dist/src/public/channels/linq/linqChannel.js +1 -1
  270. package/dist/src/public/channels/mcp.d.ts +17 -2
  271. package/dist/src/public/channels/mcp.js +1 -1
  272. package/dist/src/public/channels/photon/attachments.d.ts +21 -0
  273. package/dist/src/public/channels/photon/attachments.js +1 -0
  274. package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -1
  275. package/dist/src/public/channels/slack/attachments.d.ts +3 -1
  276. package/dist/src/public/channels/slack/attachments.js +1 -1
  277. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  278. package/dist/src/public/channels/teams/attachments.d.ts +4 -4
  279. package/dist/src/public/channels/teams/attachments.js +1 -1
  280. package/dist/src/public/channels/telegram/attachments.js +1 -1
  281. package/dist/src/public/channels/twilio/api.d.ts +7 -0
  282. package/dist/src/public/channels/twilio/api.js +1 -1
  283. package/dist/src/public/channels/twilio/inbound.d.ts +7 -0
  284. package/dist/src/public/channels/twilio/inbound.js +2 -2
  285. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  286. package/dist/src/public/definitions/connections/mcp.d.ts +1 -1
  287. package/dist/src/public/definitions/connections/openapi.d.ts +1 -1
  288. package/dist/src/react/index.d.ts +1 -0
  289. package/dist/src/react/index.js +1 -1
  290. package/dist/src/runtime/agent/mock-model-adapter.js +2 -2
  291. package/dist/src/runtime/connections/mcp-client.d.ts +18 -1
  292. package/dist/src/runtime/connections/mcp-client.js +1 -1
  293. package/dist/src/runtime/resolve-tool.js +1 -1
  294. package/dist/src/setup/boxes/resolve-provisioning.d.ts +2 -0
  295. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  296. package/dist/src/setup/cli/prompt-ui.d.ts +3 -0
  297. package/dist/src/setup/cli/prompt-ui.js +3 -1
  298. package/dist/src/setup/cli/select-component.d.ts +1 -0
  299. package/dist/src/setup/cli/select-component.js +1 -1
  300. package/dist/src/setup/flows/ensure-vercel-project.d.ts +2 -0
  301. package/dist/src/setup/flows/ensure-vercel-project.js +1 -1
  302. package/dist/src/setup/integrations/discord/api.js +1 -1
  303. package/dist/src/setup/integrations/web/auth-options.d.ts +4 -0
  304. package/dist/src/setup/integrations/web/auth-options.js +1 -0
  305. package/dist/src/setup/integrations/web/auth-scaffold.d.ts +7 -0
  306. package/dist/src/setup/integrations/web/auth-scaffold.js +1 -0
  307. package/dist/src/setup/integrations/web/provision-auth.d.ts +3 -0
  308. package/dist/src/setup/integrations/web/provision-auth.js +1 -0
  309. package/dist/src/setup/integrations/web/setup.d.ts +11 -6
  310. package/dist/src/setup/integrations/web/setup.js +3 -3
  311. package/dist/src/setup/prompter.d.ts +2 -0
  312. package/dist/src/setup/prompter.js +1 -1
  313. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  314. package/dist/src/setup/scaffold/create/project.js +2 -2
  315. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  316. package/dist/src/setup/scaffold/create/web-template.js +1 -0
  317. package/dist/src/setup/scaffold/update/web-options.js +1 -1
  318. package/dist/src/setup/vercel-project-api.d.ts +9 -0
  319. package/dist/src/setup/vercel-project-api.js +1 -1
  320. package/dist/src/setup/vercel-project.d.ts +4 -2
  321. package/dist/src/setup/vercel-project.js +0 -0
  322. package/dist/src/shared/web-search.d.ts +1 -1
  323. package/dist/src/subagents/adapter.js +1 -1
  324. package/dist/src/subagents/event-proxy-step.js +1 -1
  325. package/dist/src/subagents/hitl-proxy.d.ts +4 -28
  326. package/dist/src/subagents/hitl-proxy.js +1 -1
  327. package/dist/src/svelte/index.d.ts +2 -0
  328. package/dist/src/svelte/index.js +39 -2
  329. package/dist/src/svelte/use-eve-agent.js +1 -1
  330. package/dist/src/tools/approval/policies.d.ts +5 -5
  331. package/dist/src/tools/approval/policies.js +1 -1
  332. package/dist/src/tools/framework/agent.js +1 -1
  333. package/dist/src/tools/provided/agent-router.js +1 -1
  334. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  335. package/dist/src/tools/provided/ask-question.js +2 -2
  336. package/dist/src/tools/provided/bash.js +1 -1
  337. package/dist/src/tools/provided/framework-tool.d.ts +3 -0
  338. package/dist/src/tools/provided/framework-tool.js +1 -0
  339. package/dist/src/tools/provided/glob.js +2 -2
  340. package/dist/src/tools/provided/grep.js +2 -2
  341. package/dist/src/tools/provided/load-skill.js +1 -1
  342. package/dist/src/tools/provided/no-reply.js +1 -1
  343. package/dist/src/tools/provided/read-file.js +2 -2
  344. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  345. package/dist/src/tools/provided/sleep.js +1 -1
  346. package/dist/src/tools/provided/task-cancel.js +1 -1
  347. package/dist/src/tools/provided/task-wait.js +1 -1
  348. package/dist/src/tools/provided/web-fetch.js +2 -2
  349. package/dist/src/tools/provided/web-search.js +1 -1
  350. package/dist/src/tools/provided/workflow.js +1 -1
  351. package/dist/src/tools/provided/write-file.js +2 -2
  352. package/dist/src/tracing/agent-approval-instrumentation.d.ts +2 -2
  353. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  354. package/dist/src/tracing/agent-otel-provider.js +2 -2
  355. package/dist/src/tracing/agent-otel-usage.d.ts +1 -1
  356. package/dist/src/tracing/agent-otel-usage.js +1 -1
  357. package/dist/src/tracing/agent-span-contract.d.ts +0 -1
  358. package/dist/src/tracing/agent-span-contract.js +1 -1
  359. package/dist/src/tracing/agent-tool-instrumentation.d.ts +16 -6
  360. package/dist/src/tracing/agent-tool-instrumentation.js +1 -1
  361. package/dist/src/tracing/agent-trace-context-codec.js +1 -1
  362. package/dist/src/tracing/agent-trace-state.d.ts +7 -3
  363. package/dist/src/tracing/invoke-tool-span.js +1 -1
  364. package/dist/src/tracing/local-trace-analysis.js +1 -1
  365. package/dist/src/vue/index.d.ts +2 -0
  366. package/dist/src/vue/index.js +39 -2
  367. package/dist/src/vue/use-eve-agent.js +1 -1
  368. package/docs/agent-config.md +2 -2
  369. package/docs/channels/chat-sdk.mdx +3 -1
  370. package/docs/channels/custom.mdx +2 -0
  371. package/docs/channels/discord.mdx +5 -4
  372. package/docs/channels/eve.mdx +65 -0
  373. package/docs/channels/linear.mdx +1 -1
  374. package/docs/channels/linq.mdx +2 -0
  375. package/docs/channels/mcp.mdx +39 -1
  376. package/docs/channels/photon.mdx +5 -0
  377. package/docs/channels/teams.mdx +4 -7
  378. package/docs/channels/twilio.mdx +1 -1
  379. package/docs/concepts/built-in-tools.md +14 -2
  380. package/docs/concepts/sessions-runs-and-streaming.md +3 -3
  381. package/docs/connections/mcp.mdx +11 -0
  382. package/docs/connections/overview.mdx +2 -2
  383. package/docs/dynamic-configuration/meta.json +1 -1
  384. package/docs/evals/judge.mdx +16 -16
  385. package/docs/evals/overview.mdx +1 -1
  386. package/docs/guides/{evaluate.md → decide.md} +35 -35
  387. package/docs/guides/dynamic-capabilities.md +1 -1
  388. package/docs/guides/frontend/overview.mdx +3 -1
  389. package/docs/guides/hooks.md +1 -1
  390. package/docs/guides/instrumentation/instrumentation.mdx +23 -22
  391. package/docs/guides/instrumentation/otel.mdx +13 -2
  392. package/docs/reference/cli.md +3 -3
  393. package/docs/reference/typescript-api.md +4 -2
  394. package/docs/tools/human-in-the-loop.md +6 -4
  395. package/docs/tools/workflows.mdx +4 -4
  396. package/package.json +11 -11
  397. package/dist/src/ai/evaluate.d.ts +0 -7
  398. package/dist/src/ai/evaluate.js +0 -1
  399. package/dist/src/client/message-task-parts.d.ts +0 -8
  400. package/dist/src/client/message-task-parts.js +0 -1
  401. package/dist/src/compiled/_chunks/workflow/dist-C3ZE62yI.js +0 -25
  402. package/dist/src/compiled/_chunks/workflow/experimental-evaluation-Dm32egEG.js +0 -5
  403. package/dist/src/harness/active-turn-id.d.ts +0 -11
  404. package/dist/src/harness/active-turn-id.js +0 -1
  405. package/dist/src/harness/approval-candidates.js +0 -1
  406. package/dist/src/harness/approval-delivery-coordinator.js +0 -1
  407. package/dist/src/harness/approved-call-callers.d.ts +0 -11
  408. package/dist/src/harness/approved-call-callers.js +0 -1
  409. package/dist/src/harness/cancelled-turn-emission.d.ts +0 -12
  410. package/dist/src/harness/cancelled-turn-emission.js +0 -1
  411. package/dist/src/harness/emission-state.d.ts +0 -36
  412. package/dist/src/harness/emission-state.js +0 -1
  413. package/dist/src/harness/held-requests.d.ts +0 -18
  414. package/dist/src/harness/held-requests.js +0 -1
  415. package/dist/src/harness/hitl/approval-input-requests.d.ts +0 -27
  416. package/dist/src/harness/hitl/approval-input-requests.js +0 -1
  417. package/dist/src/harness/hitl/pending-input-resolution.d.ts +0 -54
  418. package/dist/src/harness/hitl/pending-input-resolution.js +0 -1
  419. package/dist/src/harness/hitl/session-limit-input-requests.d.ts +0 -12
  420. package/dist/src/harness/hitl/session-limit-input-requests.js +0 -1
  421. package/dist/src/harness/input-requests.d.ts +0 -37
  422. package/dist/src/harness/input-requests.js +0 -1
  423. package/dist/src/harness/pending-input-batches.d.ts +0 -81
  424. package/dist/src/harness/pending-input-batches.js +0 -1
  425. package/dist/src/harness/session-limit-enforcement.d.ts +0 -45
  426. package/dist/src/harness/session-limit-enforcement.js +0 -1
  427. package/dist/src/harness/stale-input-responses.js +0 -3
  428. package/dist/src/harness/workflow-dispatch.d.ts +0 -30
  429. package/dist/src/harness/workflow-dispatch.js +0 -1
  430. package/dist/src/public/channels/linear/inbound-images.d.ts +0 -19
  431. package/dist/src/public/channels/linear/inbound-images.js +0 -1
  432. package/dist/src/tracing/agent-action-instrumentation.d.ts +0 -26
  433. package/dist/src/tracing/agent-action-instrumentation.js +0 -1
  434. /package/dist/src/harness/{compaction.d.ts → compaction/engine.d.ts} +0 -0
  435. /package/dist/src/harness/{compaction-prompt.d.ts → compaction/prompt.d.ts} +0 -0
  436. /package/dist/src/harness/{compaction-prompt.js → compaction/prompt.js} +0 -0
  437. /package/dist/src/harness/{session-limit-continuation.d.ts → hitl/budget-request.d.ts} +0 -0
  438. /package/dist/src/harness/{session-limit-continuation.js → hitl/budget-request.js} +0 -0
  439. /package/dist/src/harness/{approval-delivery-coordinator.d.ts → hitl/coordinator.d.ts} +0 -0
  440. /package/dist/src/harness/{model-call-error.js → model-call/errors.js} +0 -0
@@ -3,7 +3,7 @@ import type { InstrumentationUsage } from "#instrumentation/lifecycle.js";
3
3
  import type { AgentTurnTraceState } from "#tracing/agent-trace-state.js";
4
4
  /** Applies eve's structural token usage attributes to an agent span. */
5
5
  export declare function setAgentUsage(span: Span, usage: InstrumentationUsage): void;
6
- /** Applies standard GenAI token usage while retaining eve's compatibility attributes. */
6
+ /** Applies standard GenAI token usage and retains eve's cost attribute. */
7
7
  export declare function setGenAiUsage(span: Span, usage: InstrumentationUsage): void;
8
8
  export declare function setAgentInvocationUsage(span: Span, modelUsage: AgentTurnTraceState["modelUsage"]): void;
9
9
  /** Projects Vercel AI Gateway cost metadata onto GenAI span attributes. */
@@ -1 +1 @@
1
- import{AGENT_USAGE_ATTRIBUTES}from"#tracing/agent-span-contract.js";function setAgentUsage(e,t){t.costUsd!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.costUsd,t.costUsd),t.inputTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.inputTokens,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.outputTokens,t.outputTokens);let n=t.inputTokenDetails;n?.cacheReadTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.cacheReadTokens,n.cacheReadTokens),n?.cacheWriteTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.cacheWriteTokens,n.cacheWriteTokens)}function setGenAiUsage(e,t){setAgentUsage(e,t),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);let n=t.inputTokenDetails;n?.cacheReadTokens!==void 0&&e.setAttribute(`gen_ai.usage.cache_read.input_tokens`,n.cacheReadTokens),n?.cacheWriteTokens!==void 0&&e.setAttribute(`gen_ai.usage.cache_write.input_tokens`,n.cacheWriteTokens)}function setAgentInvocationUsage(e,t){t!==void 0&&setGenAiUsage(e,t)}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)}export{readGatewayCost,setAgentInvocationUsage,setAgentUsage,setGenAiUsage};
1
+ import{AGENT_USAGE_ATTRIBUTES}from"#tracing/agent-span-contract.js";function setAgentUsage(e,t){t.costUsd!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.costUsd,t.costUsd),t.inputTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.inputTokens,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.outputTokens,t.outputTokens);let n=t.inputTokenDetails;n?.cacheReadTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.cacheReadTokens,n.cacheReadTokens),n?.cacheWriteTokens!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.cacheWriteTokens,n.cacheWriteTokens)}function setGenAiUsage(e,t){t.costUsd!==void 0&&e.setAttribute(AGENT_USAGE_ATTRIBUTES.costUsd,t.costUsd),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);let n=t.inputTokenDetails;n?.cacheReadTokens!==void 0&&e.setAttribute(`gen_ai.usage.cache_read.input_tokens`,n.cacheReadTokens),n?.cacheWriteTokens!==void 0&&e.setAttribute(`gen_ai.usage.cache_write.input_tokens`,n.cacheWriteTokens)}function setAgentInvocationUsage(e,t){t!==void 0&&setGenAiUsage(e,t)}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)}export{readGatewayCost,setAgentInvocationUsage,setAgentUsage,setGenAiUsage};
@@ -1,6 +1,5 @@
1
1
  export declare const AGENT_TRACE_SCHEMA_VERSION = 4;
2
2
  export declare const AGENT_SPAN_NAMES: {
3
- readonly action: "agent.action";
4
3
  readonly approval: "agent.approval";
5
4
  readonly channelRequest: "agent.channel.request";
6
5
  readonly step: "agent.step";
@@ -1 +1 @@
1
- const AGENT_TRACE_SCHEMA_VERSION=4,AGENT_SPAN_NAMES={action:`agent.action`,approval:`agent.approval`,channelRequest:`agent.channel.request`,step:`agent.step`},AGENT_USAGE_ATTRIBUTES={costUsd:`agent.usage.cost_usd`,inputTokens:`agent.usage.input_tokens`,outputTokens:`agent.usage.output_tokens`,cacheReadTokens:`agent.usage.cache_read_tokens`,cacheWriteTokens:`agent.usage.cache_write_tokens`};function agentInvocationSpanName(e){return e===void 0?`invoke_agent`:`invoke_agent ${e}`}function modelSpanName(e){return`chat ${e}`}const DIRECT_TOOL_CALL_ATTRIBUTE=`eve.tool.invocation`,DIRECT_TOOL_CALL_VALUE=`direct`;function isDirectToolCallSpan(e){return e.attributes[DIRECT_TOOL_CALL_ATTRIBUTE]===DIRECT_TOOL_CALL_VALUE}function isAgentActivationSpan(e){return e.name===`agent.turn`||e.attributes[`gen_ai.operation.name`]===`invoke_agent`&&e.attributes[`agent.invocation.role`]!==`caller`&&typeof e.attributes[`agent.turn.id`]==`string`}function agentTurnIdentity(e){let t=e.attributes[`agent.run.id`],n=e.attributes[`agent.turn.id`];return typeof n==`string`?`${typeof t==`string`?t:``}\0${n}`:void 0}export{AGENT_SPAN_NAMES,AGENT_TRACE_SCHEMA_VERSION,AGENT_USAGE_ATTRIBUTES,DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE,agentInvocationSpanName,agentTurnIdentity,isAgentActivationSpan,isDirectToolCallSpan,modelSpanName};
1
+ const AGENT_TRACE_SCHEMA_VERSION=4,AGENT_SPAN_NAMES={approval:`agent.approval`,channelRequest:`agent.channel.request`,step:`agent.step`},AGENT_USAGE_ATTRIBUTES={costUsd:`agent.usage.cost_usd`,inputTokens:`agent.usage.input_tokens`,outputTokens:`agent.usage.output_tokens`,cacheReadTokens:`agent.usage.cache_read_tokens`,cacheWriteTokens:`agent.usage.cache_write_tokens`};function agentInvocationSpanName(e){return e===void 0?`invoke_agent`:`invoke_agent ${e}`}function modelSpanName(e){return`chat ${e}`}const DIRECT_TOOL_CALL_ATTRIBUTE=`eve.tool.invocation`,DIRECT_TOOL_CALL_VALUE=`direct`;function isDirectToolCallSpan(e){return e.attributes[DIRECT_TOOL_CALL_ATTRIBUTE]===DIRECT_TOOL_CALL_VALUE}function isAgentActivationSpan(e){return e.name===`agent.turn`||e.attributes[`gen_ai.operation.name`]===`invoke_agent`&&e.attributes[`agent.invocation.role`]!==`caller`&&typeof e.attributes[`agent.turn.id`]==`string`}function agentTurnIdentity(e){let t=e.attributes[`agent.run.id`],n=e.attributes[`agent.turn.id`];return typeof n==`string`?`${typeof t==`string`?t:``}\0${n}`:void 0}export{AGENT_SPAN_NAMES,AGENT_TRACE_SCHEMA_VERSION,AGENT_USAGE_ATTRIBUTES,DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE,agentInvocationSpanName,agentTurnIdentity,isAgentActivationSpan,isDirectToolCallSpan,modelSpanName};
@@ -1,10 +1,15 @@
1
1
  import { type Context, type SpanContext, type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
- import type { InstrumentationActionStartedEvent, InstrumentationToolCallStartedEvent, InstrumentationToolCallTerminalEvent } from "#instrumentation/lifecycle.js";
2
+ import type { InstrumentationAttemptScope, InstrumentationExecutionOperation, InstrumentationToolCallStartedEvent, InstrumentationToolCallTerminalEvent } from "#instrumentation/lifecycle.js";
3
3
  import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
4
- import type { AgentActionContext } from "#tracing/agent-action-instrumentation.js";
4
+ import type { AgentTraceStateStore } from "#tracing/agent-trace-state.js";
5
+ export interface AgentToolContext {
6
+ readonly context: Context;
7
+ readonly spanContext: SpanContext;
8
+ }
5
9
  interface AgentToolInstrumentation {
6
- actionStarted(event: InstrumentationActionStartedEvent): Promise<void>;
7
- startTimeForAction(idempotencyKey: string): number | undefined;
10
+ deleteForSession(sessionId: string): Promise<void>;
11
+ failForAttempt(scope: InstrumentationAttemptScope, error: unknown): Promise<void>;
12
+ dispatchContextFor(sessionId: string, turnId: string, callId: string): Promise<AgentToolContext | undefined>;
8
13
  contextFor(attemptId: string, idempotencyKey: string): Context | undefined;
9
14
  drain(attemptId: string, failure?: {
10
15
  readonly error: unknown;
@@ -14,10 +19,14 @@ interface AgentToolInstrumentation {
14
19
  readonly "tool.call.failed": (event: InstrumentationToolCallTerminalEvent) => Promise<void>;
15
20
  readonly "tool.call.started": (event: InstrumentationToolCallStartedEvent) => Promise<void>;
16
21
  };
22
+ runInContext<T>(operation: Extract<InstrumentationExecutionOperation, {
23
+ type: "tool.call";
24
+ }>, execute: (parent: Context | undefined) => PromiseLike<T>, recordOutputs: boolean): Promise<T>;
17
25
  }
18
- /** Keeps SDK tool spans parented to actions even when SDK telemetry wins the event race. */
26
+ /** Enriches durable tool calls, exporting SDK-only calls under their step. */
19
27
  export declare function createAgentToolInstrumentation(input: {
20
- readonly actionContextFor: (sessionId: string, turnId: string, callId: string) => Promise<AgentActionContext | undefined>;
28
+ readonly frameworkVersion: string;
29
+ readonly resolveTraceContext: (event: InstrumentationToolCallStartedEvent) => SpanContext | undefined | PromiseLike<SpanContext | undefined>;
21
30
  readonly idGenerator: AgentSpanIdGenerator;
22
31
  readonly recordInputs: boolean;
23
32
  readonly recordOutputs: boolean;
@@ -26,5 +35,6 @@ export declare function createAgentToolInstrumentation(input: {
26
35
  readonly spanContext: SpanContext;
27
36
  } | undefined;
28
37
  readonly tracer: Tracer;
38
+ readonly stateStore: AgentTraceStateStore;
29
39
  }): AgentToolInstrumentation;
30
40
  export {};
@@ -1 +1 @@
1
- import{ROOT_CONTEXT,SpanKind,trace}from"#compiled/@opentelemetry/api/index.js";import{actionIdempotencyKey}from"#instrumentation/lifecycle.js";import{agentSpanNamingAttributes}from"#tracing/agent-span-naming.js";import{contentAttribute}from"#tracing/agent-otel-content.js";import{recordAgentSpanError}from"#tracing/agent-span-error.js";import{withAgentToolSpanContext}from"#tracing/agent-tool-span-context.js";import{agentTraceIdentityAttributes,traceSessionIdOf}from"#tracing/agent-otel-attributes.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";function createAgentToolInstrumentation(e){let t=new Map,n=new Map,onStarted=async t=>{let n=actionIdempotencyKey(t.scope.sessionId,t.scope.turnId,t.callId),r=e.resolveFallback(t),i=r===void 0?void 0:reserve(t,n,r),a=await e.actionContextFor(t.scope.sessionId,t.scope.turnId,t.callId);if(i===void 0){if(a===void 0)return;i=reserve(t,n,a)}a!==void 0&&startSpan(i,a.context)},onTerminal=async t=>{let r=n.get(t.scope.attemptId)?.get(t.idempotencyKey);if(r!==void 0){if(r.terminal=t,r.span===void 0){let t=await e.actionContextFor(r.event.scope.sessionId,r.event.scope.turnId,r.event.callId);t!==void 0&&startSpan(r,t.context)}finishIfReady(r)}};return{startTimeForAction:e=>t.get(e)?.startTimeMs,async actionStarted(n){let r=t.get(n.idempotencyKey);if(r===void 0||r.span!==void 0||r.finished===!0)return;let i=await e.actionContextFor(n.scope.sessionId,n.scope.turnId,n.callId);i!==void 0&&(startSpan(r,i.context),finishIfReady(r))},contextFor:(e,t)=>n.get(e)?.get(t)?.context,drain(e,t){let r=n.get(e);if(r!==void 0){for(let e of r.values())e.finished!==!0&&(e.span===void 0&&startSpan(e,e.fallbackParent),finish(e,t));n.delete(e)}},events:{"tool.call.completed":onTerminal,"tool.call.failed":onTerminal,"tool.call.started":onStarted}};function getAttemptStates(e){let t=n.get(e);return t===void 0&&(t=new Map,n.set(e,t)),t}function reserve(n,r,i){let a=e.idGenerator.deriveSpanId(`tool:${n.idempotencyKey}`),o={actionKey:r,attemptId:n.scope.attemptId,additionalAttributes:{},context:withChannelAudience(contextFromSpanContext({isRemote:!1,spanId:a,traceFlags:i.spanContext.traceFlags,traceId:i.spanContext.traceId}),n.scope.channelAudience),event:n,fallbackParent:i.context,idempotencyKey:n.idempotencyKey,spanId:a,startTimeMs:Date.now()};return o.context=withAgentToolSpanContext(o.context,{recordInputs:e.recordInputs,recordOutputs:e.recordOutputs,setAttributes(e){if(Object.assign(o.additionalAttributes,e),o.span!==void 0)for(let[t,n]of Object.entries(e))n!==void 0&&o.span.setAttribute(t,n)},recordError(e,t){o.pendingError={error:e,errorType:t},o.span!==void 0&&recordAgentSpanError(o.span,e,t)}}),getAttemptStates(n.scope.attemptId).set(n.idempotencyKey,o),t.set(r,o),o}function startSpan(t,n){if(t.span===void 0&&t.finished!==!0&&(t.span=e.idGenerator.withSpanId(t.spanId,()=>e.tracer.startSpan(`execute_tool ${t.event.toolName}`,{attributes:{...toolAttributes(t.event),...t.additionalAttributes},kind:SpanKind.INTERNAL,startTime:t.startTimeMs},n)),t.pendingError!==void 0&&recordAgentSpanError(t.span,t.pendingError.error,t.pendingError.errorType),e.recordInputs)){let e=contentAttribute(t.event.input);e!==void 0&&t.span.setAttribute(`gen_ai.tool.call.arguments`,e)}}function finishIfReady(e){e.span!==void 0&&e.terminal!==void 0&&finish(e)}function finish(r,i){let a=r.span;if(a===void 0||r.finished===!0)return;r.finished=!0;let o=r.terminal;if(o?.type===`tool.call.completed`&&o.durationMs!==void 0&&a.setAttribute(`gen_ai.execute_tool.duration`,o.durationMs/1e3),i!==void 0)recordAgentSpanError(a,i.error);else if(o?.type===`tool.call.failed`)recordAgentSpanError(a,o.error);else if(o?.output.type===`error`)recordAgentSpanError(a,o.output.error);else if(o!==void 0&&e.recordOutputs){let e=contentAttribute(o.output.output);e!==void 0&&a.setAttribute(`gen_ai.tool.call.result`,e)}a.end(),t.delete(r.actionKey);let s=n.get(r.attemptId);s?.delete(r.idempotencyKey),s?.size===0&&n.delete(r.attemptId)}}function toolAttributes(e){return{...e.scope.functionId===void 0?{}:{"gen_ai.agent.name":e.scope.functionId},"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":e.callId,"gen_ai.tool.name":e.toolName,"gen_ai.tool.type":`function`,...agentSpanNamingAttributes(`execute_tool ${e.toolName}`,`execute_tool`),...agentTraceIdentityAttributes({rootSessionId:e.scope.rootSessionId??e.scope.sessionId,traceSessionId:traceSessionIdOf(e.scope),sessionId:e.scope.sessionId})}}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}export{createAgentToolInstrumentation};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{isSampledTrace}from"#tracing/sampled-trace.js";import{ROOT_CONTEXT,SpanKind,trace}from"#compiled/@opentelemetry/api/index.js";import{actionIdempotencyKey,attemptIdempotencyKey}from"#instrumentation/lifecycle.js";import{agentSpanNamingAttributes}from"#tracing/agent-span-naming.js";import{contentAttribute,textContentAttribute}from"#tracing/agent-otel-content.js";import{recordAgentSpanError}from"#tracing/agent-span-error.js";import{withAgentToolSpanContext}from"#tracing/agent-tool-span-context.js";import{agentTraceIdentityAttributes,traceSessionIdOf}from"#tracing/agent-otel-attributes.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";function createAgentToolInstrumentation(e){let t=new Map,n=new Map,r=new Map;async function dispatchContextFor(t,n,r){let i=await e.stateStore.getAction(actionIdempotencyKey(t,n,r))??await e.stateStore.findAction(t,r);if(i===void 0)return;let a={isRemote:!1,spanId:i.spanId,traceFlags:i.parent.traceFlags,traceId:i.parent.traceId};return{context:withChannelAudience(contextFromSpanContext(a),i.channelAudience),spanContext:a}}async function onDispatchStarted(n){let i=await e.resolveTraceContext(n);if(i===void 0||!isSampledTrace(i))return;let a=await e.stateStore.getAction(n.idempotencyKey)??{attemptIndex:n.scope.attemptIndex,callId:n.callId,channelAudience:normalizeChannelAudience(n.scope.channelAudience),inputAttribute:e.recordInputs?contentAttribute(n.input):void 0,kind:n.kind??`tool-call`,name:n.toolName,toolAttributes:{"agent.tool.is_framework":n.frameworkTool===!0},parent:{spanId:e.idGenerator.deriveSpanId(n.parentCallId===void 0?attemptIdempotencyKey(n.scope):`action:${actionIdempotencyKey(n.scope.sessionId,n.scope.turnId,n.parentCallId)}`),traceFlags:i.traceFlags,traceId:i.traceId},parentCallId:n.parentCallId,rootSessionId:n.scope.rootSessionId??n.scope.sessionId,traceSessionId:traceSessionIdOf(n.scope),sessionId:n.scope.sessionId,spanId:e.idGenerator.deriveSpanId(`action:${n.idempotencyKey}`),startTimeMs:Math.min(n.startedAtMs??Date.now(),t.get(n.idempotencyKey)?.startTimeMs??1/0),stepIndex:n.scope.stepIndex,turnId:n.scope.turnId};await e.stateStore.setAction(n.idempotencyKey,a),n.isWorkflowTool===!0&&await e.stateStore.setActionAnchor(n.idempotencyKey,a);let o=r.get(n.scope.attemptId)??new Set;o.add(n.idempotencyKey),r.set(n.scope.attemptId,o);let s=t.get(n.idempotencyKey);s!==void 0&&s.finished!==!0&&(await correlate(s),finishIfReady(s))}async function onDispatchTerminal(t){let n=await e.stateStore.getAction(t.idempotencyKey);if(n!==void 0)try{let r=startDispatchSpan(n),i=t.outcome??(t.type===`tool.call.failed`?`failed`:`completed`);if(r.setAttribute(`agent.action.outcome`,n.toolFailed===!0&&i===`completed`?`failed`:i),t.usage!==void 0&&setAgentUsage(r,t.usage),t.type===`tool.call.failed`)recordToolError(r,t.error,t.errorCode);else if(t.output.type===`error`)recordToolError(r,t.output.error);else if(n.toolFailed===!0)recordToolError(r,n.toolErrorAttribute,typeof n.toolAttributes?.[`error.type`]==`string`?n.toolAttributes[`error.type`]:void 0);else if(e.recordOutputs){let e=contentAttribute(t.output.output);e!==void 0&&r.setAttribute(`gen_ai.tool.call.result`,e)}r.end(t.acceptedAtMs??n.toolEndTimeMs)}finally{await e.stateStore.deleteAction(t.idempotencyKey);for(let[e,n]of r)n.delete(t.idempotencyKey),n.size===0&&r.delete(e)}}function startDispatchSpan(t){let n=t.kind===`subagent-call`||t.kind===`remote-agent-call`,r=e.idGenerator.withSpanId(t.spanId,()=>e.tracer.startSpan(`execute_tool ${t.name}`,{attributes:{"agent.action.kind":t.kind,"agent.action.name":t.name,...t.parentCallId===void 0?void 0:{"agent.action.parent_call_id":t.parentCallId},"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":t.callId,"gen_ai.tool.name":t.name,"gen_ai.tool.type":`function`,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.step.attempt":t.attemptIndex,"agent.step.index":t.stepIndex,"agent.turn.id":t.turnId,...agentSpanNamingAttributes(`execute_tool ${t.name}`,`execute_tool`),...agentTraceIdentityAttributes({rootSessionId:t.rootSessionId,traceSessionId:t.traceSessionId,sessionId:t.sessionId}),...n?{"gen_ai.agent.name":t.name,"agent.invocation.role":`caller`}:void 0,...t.toolAttributes},kind:t.kind===`remote-agent-call`?SpanKind.CLIENT:SpanKind.INTERNAL,startTime:t.startTimeMs},withChannelAudience(contextFromSpanContext({...t.parent,isRemote:!1}),t.channelAudience)));return t.inputAttribute!==void 0&&r.setAttribute(`gen_ai.tool.call.arguments`,t.inputAttribute),r}let onStarted=async t=>{if(n.get(t.scope.attemptId)?.has(t.idempotencyKey))return;let r=actionIdempotencyKey(t.scope.sessionId,t.scope.turnId,t.callId),i=e.resolveFallback(t),a=i===void 0?void 0:reserve(t,r,i),o=await dispatchContextFor(t.scope.sessionId,t.scope.turnId,t.callId);if(a===void 0){if(o===void 0)return;a=reserve(t,r,o)}o!==void 0&&await correlate(a)},onTerminal=async e=>{let t=n.get(e.scope.attemptId)?.get(e.idempotencyKey);t!==void 0&&(t.terminal=e,t.span===void 0&&await dispatchContextFor(t.event.scope.sessionId,t.event.scope.turnId,t.event.callId)!==void 0&&await correlate(t),finishIfReady(t))};return{dispatchContextFor,async deleteForSession(t){await e.stateStore.deleteActions(t),await e.stateStore.deleteActionAnchors(t)},async failForAttempt(t,n){let i=r.get(t.attemptId);r.delete(t.attemptId);for(let t of i??[]){let r=await e.stateStore.getAction(t);if(r===void 0)continue;let i=startDispatchSpan(r);recordAgentSpanError(i,n),i.end(),await e.stateStore.deleteAction(t)}},contextFor:(e,t)=>n.get(e)?.get(t)?.context,drain(e,t){let r=n.get(e);if(r!==void 0){for(let e of r.values())e.finished!==!0&&(e.span===void 0&&e.correlated!==!0&&startSpan(e,e.fallbackParent),finish(e,t));n.delete(e)}},events:{"tool.call.completed":onDispatchTerminal,"tool.call.failed":onDispatchTerminal,"tool.call.started":onDispatchStarted},async runInContext(e,t,r){if(e.callId===void 0||e.toolName===void 0)return t(n.get(e.scope.attemptId)?.get(e.idempotencyKey)?.context);await onStarted({...e,callId:e.callId,toolName:e.toolName,input:e.input,type:`tool.call.started`});let i=n.get(e.scope.attemptId)?.get(e.idempotencyKey),a=e.startedAtMs??Date.now();try{let n=await t(i?.context);return await onTerminal({type:e.failed?`tool.call.failed`:`tool.call.completed`,idempotencyKey:e.idempotencyKey,scope:e.scope,completedAtMs:e.completedAtMs??Date.now(),durationMs:(e.completedAtMs??Date.now())-a,output:{type:`result`,output:r?n:void 0}}),n}catch(t){throw await onTerminal({type:`tool.call.failed`,idempotencyKey:e.idempotencyKey,scope:e.scope,completedAtMs:Date.now(),error:r?t:void 0}),t}}};function getAttemptStates(e){let t=n.get(e);return t===void 0&&(t=new Map,n.set(e,t)),t}function reserve(n,r,i){let a=e.idGenerator.deriveSpanId(`action:${r}`),o={actionKey:r,attemptId:n.scope.attemptId,additionalAttributes:{},context:withChannelAudience(contextFromSpanContext({isRemote:!1,spanId:a,traceFlags:i.spanContext.traceFlags,traceId:i.spanContext.traceId}),n.scope.channelAudience),event:n,fallbackParent:i.context,idempotencyKey:n.idempotencyKey,spanId:a,startTimeMs:n.startedAtMs??Date.now()};return o.context=withAgentToolSpanContext(o.context,{recordInputs:e.recordInputs,recordOutputs:e.recordOutputs,setAttributes(e){if(Object.assign(o.additionalAttributes,e),o.span!==void 0)for(let[t,n]of Object.entries(e))n!==void 0&&o.span.setAttribute(t,n)},recordError(e,t){o.pendingError={error:e,errorType:t},o.span!==void 0&&recordAgentSpanError(o.span,e,t)}}),getAttemptStates(n.scope.attemptId).set(n.idempotencyKey,o),t.set(r,o),o}function startSpan(t,n){if(t.span===void 0&&t.finished!==!0&&(t.span=e.idGenerator.withSpanId(t.spanId,()=>e.tracer.startSpan(`execute_tool ${t.event.toolName}`,{attributes:{...toolAttributes(t.event),...t.additionalAttributes},kind:SpanKind.INTERNAL,startTime:t.startTimeMs},n)),t.pendingError!==void 0&&recordAgentSpanError(t.span,t.pendingError.error,t.pendingError.errorType),e.recordInputs)){let e=contentAttribute(t.event.input);e!==void 0&&t.span.setAttribute(`gen_ai.tool.call.arguments`,e)}}function finishIfReady(e){e.span===void 0&&e.correlated!==!0||e.terminal===void 0||finish(e)}async function correlate(t){let n=await e.stateStore.getAction(t.actionKey)??await e.stateStore.findAction(t.event.scope.sessionId,t.event.callId);if(n===void 0)return;t.correlated=!0,t.context=trace.setSpan(t.context,trace.wrapSpanContext({isRemote:!1,spanId:n.spanId,traceFlags:n.parent.traceFlags,traceId:n.parent.traceId}));let r=t.terminal,i=t.pendingError!==void 0||r?.type===`tool.call.failed`||r?.output.type===`error`,a=t.pendingError?.error??(r?.type===`tool.call.failed`?r.error:r?.output.type===`error`?r.output.error:void 0),o={...n.toolAttributes,...t.event.scope.functionId===void 0||n.kind===`subagent-call`||n.kind===`remote-agent-call`?void 0:{"gen_ai.agent.name":t.event.scope.functionId},"agent.tool.is_framework":t.event.frameworkTool===!0,...t.additionalAttributes,...t.pendingError?.errorType===void 0?void 0:{"error.type":t.pendingError.errorType},...r?.type===`tool.call.completed`&&r.durationMs!==void 0?{"gen_ai.execute_tool.duration":r.durationMs/1e3}:void 0};await e.stateStore.setAction(actionIdempotencyKey(n.sessionId,n.turnId,n.callId),{...n,startTimeMs:Math.min(n.startTimeMs,t.startTimeMs),toolAttributes:o,toolEndTimeMs:r?.completedAtMs??n.toolEndTimeMs,toolFailed:i||n.toolFailed,toolErrorAttribute:e.recordOutputs&&a!==void 0?contentAttribute(a instanceof Error?a.message:a):n.toolErrorAttribute})}function finish(t,n){let r=t.span;if(t.finished===!0)return;if(t.correlated===!0){t.finished=!0,forget(t);return}if(r===void 0)return;t.finished=!0;let i=t.terminal;if(i?.type===`tool.call.completed`&&i.durationMs!==void 0&&r.setAttribute(`gen_ai.execute_tool.duration`,i.durationMs/1e3),n!==void 0)recordAgentSpanError(r,n.error);else if(i?.type===`tool.call.failed`)recordAgentSpanError(r,i.error);else if(i?.output.type===`error`)recordAgentSpanError(r,i.output.error);else if(i!==void 0&&e.recordOutputs){let e=contentAttribute(i.output.output);e!==void 0&&r.setAttribute(`gen_ai.tool.call.result`,e)}r.end(i?.completedAtMs),forget(t)}function forget(e){t.delete(e.actionKey);let r=n.get(e.attemptId);r?.delete(e.idempotencyKey),r?.size===0&&n.delete(e.attemptId)}}function toolAttributes(e){return{"agent.tool.is_framework":e.frameworkTool===!0,...e.scope.functionId===void 0?{}:{"gen_ai.agent.name":e.scope.functionId},"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":e.callId,"gen_ai.tool.name":e.toolName,"gen_ai.tool.type":`function`,...agentSpanNamingAttributes(`execute_tool ${e.toolName}`,`execute_tool`),...agentTraceIdentityAttributes({rootSessionId:e.scope.rootSessionId??e.scope.sessionId,traceSessionId:traceSessionIdOf(e.scope),sessionId:e.scope.sessionId})}}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function recordToolError(e,t,n){if(t instanceof Error||t===void 0){recordAgentSpanError(e,t,n);return}let r=typeof t==`string`?textContentAttribute(t):contentAttribute(t),i=typeof t==`object`&&t&&!Array.isArray(t)?Reflect.get(t,`message`):void 0,a=typeof i==`string`?textContentAttribute(r===void 0?i:`${i}\n${r}`):r,o=a===void 0?void 0:Error(a);o!==void 0&&n!==void 0&&(o.name=n),recordAgentSpanError(e,o,n)}export{createAgentToolInstrumentation};
@@ -1 +1 @@
1
- import{normalizeChannelAudience}from"#shared/channel-audience.js";import{isInstrumentationPrincipalType}from"#instrumentation/lifecycle.js";import{boundedPrincipalId}from"#tracing/telemetry-budget.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";import{boundedTraceError}from"#tracing/bounded-error.js";const AGENT_TRACE_CONTEXT_KEY=`eve.harness.agentTrace`;function decodeTraceSessionId(e){return typeof e.traceSessionId==`string`?e.traceSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``}function emptyAgentTraceContextState(){return{actionAnchors:{},actions:{},sessions:{},turns:{}}}function serializeAgentTraceContextState(e){return{actionAnchors:e.actionAnchors,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,caller:t.caller===void 0?void 0:serializeSpanContext(t.caller),channelDelivery:t.channelDelivery===void 0?void 0:{...t.channelDelivery,requestTraceContext:t.channelDelivery.requestTraceContext===void 0?void 0:serializeSpanContext(t.channelDelivery.requestTraceContext)},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 deserializeAgentTraceContextState(e){return isRecord(e)?{actionAnchors:deserializeRecord(e.actionAnchors,deserializeAction),actions:deserializeRecord(e.actions,deserializeAction),sessions:deserializeRecord(e.sessions,deserializeSession),turns:deserializeRecord(e.turns,deserializeTurn)}:emptyAgentTraceContextState()}function deserializeSession(e){if(isRecord(e)&&isSpanContext(e.context))return{agentName:typeof e.agentName==`string`?e.agentName:void 0,channelAudience:normalizeChannelAudience(e.channelAudience),channelKind:typeof e.channelKind==`string`?e.channelKind:void 0,channelType:typeof e.channelType==`string`?e.channelType:void 0,context:e.context,decision:readInstrumentationDecision(e.decision),parentLineage:deserializeParentLineage(e.parentLineage),rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,traceSessionId:decodeTraceSessionId(e),scheduleId:typeof e.scheduleId==`string`?e.scheduleId:void 0,title:typeof e.title==`string`?e.title:void 0}}function deserializeTurn(e){if(isRecord(e)&&isSpanContext(e.context)&&typeof e.startTimeMs==`number`)return{caller:isSpanContext(e.caller)?e.caller:void 0,channelDelivery:deserializeTurnChannelDelivery(e.channelDelivery),context:e.context,currentPrincipal:deserializePrincipalSummary(e.currentPrincipal),initiatorPrincipal:deserializePrincipalSummary(e.initiatorPrincipal),modelUsage:deserializeModelUsage(e.modelUsage),parentLineage:deserializeParentLineage(e.parentLineage),rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,traceSessionId:decodeTraceSessionId(e),sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,terminal:deserializeTurnTerminal(e.terminal)}}function deserializeTurnChannelDelivery(e){if(isRecord(e)&&typeof e.channelKind==`string`&&typeof e.channelName==`string`&&typeof e.deliveryId==`string`)return{channelKind:e.channelKind,channelName:e.channelName,deliveryId:e.deliveryId,inputAttribute:typeof e.inputAttribute==`string`?e.inputAttribute:void 0,requestId:typeof e.requestId==`string`?e.requestId:void 0,requestTraceContext:isSpanContext(e.requestTraceContext)?e.requestTraceContext:void 0}}function deserializePrincipalSummary(e){if(!isRecord(e)||!isInstrumentationPrincipalType(e.type))return;let t=e.type===`none`?void 0:boundedPrincipalId(e.id);return t===void 0?{type:e.type}:{id:t,type:e.type}}function deserializeAction(e){if(isRecord(e)&&typeof e.attemptIndex==`number`&&typeof e.callId==`string`&&isActionKind(e.kind)&&typeof e.name==`string`&&isSpanContext(e.parent)&&typeof e.rootSessionId==`string`&&typeof e.sessionId==`string`&&typeof e.spanId==`string`&&typeof e.startTimeMs==`number`&&typeof e.stepIndex==`number`&&typeof e.turnId==`string`)return{attemptIndex:e.attemptIndex,callId:e.callId,channelAudience:normalizeChannelAudience(e.channelAudience),inputAttribute:typeof e.inputAttribute==`string`?e.inputAttribute:void 0,kind:e.kind,name:e.name,parent:e.parent,parentCallId:typeof e.parentCallId==`string`?e.parentCallId:void 0,rootSessionId:e.rootSessionId,traceSessionId:decodeTraceSessionId(e),sessionId:e.sessionId,spanId:e.spanId,startTimeMs:e.startTimeMs,stepIndex:e.stepIndex,turnId:e.turnId}}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 deserializeParentLineage(e){if(isRecord(e)&&typeof e.callId==`string`&&typeof e.sessionId==`string`&&typeof e.turnId==`string`)return{callId:e.callId,sessionId:e.sessionId,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,turnId:e.turnId}}function deserializeTurnTerminal(e){if(isRecord(e)&&isTurnTerminalType(e.type))return e.type===`turn.failed`?{error:deserializeError(e.error),type:e.type}:{type:e.type}}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 serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function serializeError(e){if(!(e instanceof Error))return;let t=boundedTraceError(e);return{message:t.message,name:t.name,stack:t.stack}}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 isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{AGENT_TRACE_CONTEXT_KEY,decodeTraceSessionId,deserializeAgentTraceContextState,emptyAgentTraceContextState,serializeAgentTraceContextState};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{isInstrumentationPrincipalType}from"#instrumentation/lifecycle.js";import{boundedPrincipalId}from"#tracing/telemetry-budget.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";import{boundedTraceError}from"#tracing/bounded-error.js";const AGENT_TRACE_CONTEXT_KEY=`eve.harness.agentTrace`;function decodeTraceSessionId(e){return typeof e.traceSessionId==`string`?e.traceSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``}function emptyAgentTraceContextState(){return{actionAnchors:{},actions:{},sessions:{},turns:{}}}function serializeAgentTraceContextState(e){return{actionAnchors:e.actionAnchors,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,caller:t.caller===void 0?void 0:serializeSpanContext(t.caller),channelDelivery:t.channelDelivery===void 0?void 0:{...t.channelDelivery,requestTraceContext:t.channelDelivery.requestTraceContext===void 0?void 0:serializeSpanContext(t.channelDelivery.requestTraceContext)},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 deserializeAgentTraceContextState(e){return isRecord(e)?{actionAnchors:deserializeRecord(e.actionAnchors,deserializeAction),actions:deserializeRecord(e.actions,deserializeAction),sessions:deserializeRecord(e.sessions,deserializeSession),turns:deserializeRecord(e.turns,deserializeTurn)}:emptyAgentTraceContextState()}function deserializeSession(e){if(isRecord(e)&&isSpanContext(e.context))return{agentName:typeof e.agentName==`string`?e.agentName:void 0,channelAudience:normalizeChannelAudience(e.channelAudience),channelKind:typeof e.channelKind==`string`?e.channelKind:void 0,channelType:typeof e.channelType==`string`?e.channelType:void 0,context:e.context,decision:readInstrumentationDecision(e.decision),parentLineage:deserializeParentLineage(e.parentLineage),rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,traceSessionId:decodeTraceSessionId(e),scheduleId:typeof e.scheduleId==`string`?e.scheduleId:void 0,title:typeof e.title==`string`?e.title:void 0}}function deserializeTurn(e){if(isRecord(e)&&isSpanContext(e.context)&&typeof e.startTimeMs==`number`)return{caller:isSpanContext(e.caller)?e.caller:void 0,channelDelivery:deserializeTurnChannelDelivery(e.channelDelivery),context:e.context,currentPrincipal:deserializePrincipalSummary(e.currentPrincipal),initiatorPrincipal:deserializePrincipalSummary(e.initiatorPrincipal),modelUsage:deserializeModelUsage(e.modelUsage),parentLineage:deserializeParentLineage(e.parentLineage),rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,traceSessionId:decodeTraceSessionId(e),sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,terminal:deserializeTurnTerminal(e.terminal)}}function deserializeTurnChannelDelivery(e){if(isRecord(e)&&typeof e.channelKind==`string`&&typeof e.channelName==`string`&&typeof e.deliveryId==`string`)return{channelKind:e.channelKind,channelName:e.channelName,deliveryId:e.deliveryId,inputAttribute:typeof e.inputAttribute==`string`?e.inputAttribute:void 0,requestId:typeof e.requestId==`string`?e.requestId:void 0,requestTraceContext:isSpanContext(e.requestTraceContext)?e.requestTraceContext:void 0}}function deserializePrincipalSummary(e){if(!isRecord(e)||!isInstrumentationPrincipalType(e.type))return;let t=e.type===`none`?void 0:boundedPrincipalId(e.id);return t===void 0?{type:e.type}:{id:t,type:e.type}}function deserializeAction(e){if(isRecord(e)&&typeof e.attemptIndex==`number`&&typeof e.callId==`string`&&isActionKind(e.kind)&&typeof e.name==`string`&&isSpanContext(e.parent)&&typeof e.rootSessionId==`string`&&typeof e.sessionId==`string`&&typeof e.spanId==`string`&&typeof e.startTimeMs==`number`&&typeof e.stepIndex==`number`&&typeof e.turnId==`string`)return{attemptIndex:e.attemptIndex,callId:e.callId,channelAudience:normalizeChannelAudience(e.channelAudience),inputAttribute:typeof e.inputAttribute==`string`?e.inputAttribute:void 0,kind:e.kind,name:e.name,parent:e.parent,parentCallId:typeof e.parentCallId==`string`?e.parentCallId:void 0,rootSessionId:e.rootSessionId,traceSessionId:decodeTraceSessionId(e),sessionId:e.sessionId,spanId:e.spanId,startTimeMs:e.startTimeMs,stepIndex:e.stepIndex,turnId:e.turnId,toolEndTimeMs:typeof e.toolEndTimeMs==`number`?e.toolEndTimeMs:void 0,toolFailed:e.toolFailed===!0,toolErrorAttribute:typeof e.toolErrorAttribute==`string`?e.toolErrorAttribute:void 0,toolAttributes:isRecord(e.toolAttributes)?Object.fromEntries(Object.entries(e.toolAttributes).filter(e=>{let t=e[1];return typeof t==`string`||typeof t==`number`||typeof t==`boolean`||Array.isArray(t)&&t.every(e=>[`string`,`number`,`boolean`].includes(typeof e))})):void 0}}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 deserializeParentLineage(e){if(isRecord(e)&&typeof e.callId==`string`&&typeof e.sessionId==`string`&&typeof e.turnId==`string`)return{callId:e.callId,sessionId:e.sessionId,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,turnId:e.turnId}}function deserializeTurnTerminal(e){if(isRecord(e)&&isTurnTerminalType(e.type))return e.type===`turn.failed`?{error:deserializeError(e.error),type:e.type}:{type:e.type}}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 serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function serializeError(e){if(!(e instanceof Error))return;let t=boundedTraceError(e);return{message:t.message,name:t.name,stack:t.stack}}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 isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{AGENT_TRACE_CONTEXT_KEY,decodeTraceSessionId,deserializeAgentTraceContextState,emptyAgentTraceContextState,serializeAgentTraceContextState};
@@ -1,5 +1,5 @@
1
- import type { SpanContext } from "#compiled/@opentelemetry/api/index.js";
2
- import type { InstrumentationActionKind, InstrumentationParentLineage, InstrumentationPrincipalSummary, InstrumentationTraceContext, InstrumentationTurnFailedEvent, InstrumentationTurnSettledEvent } from "#instrumentation/lifecycle.js";
1
+ import type { Attributes, SpanContext } from "#compiled/@opentelemetry/api/index.js";
2
+ import type { InstrumentationToolCallKind, InstrumentationParentLineage, InstrumentationPrincipalSummary, InstrumentationTraceContext, InstrumentationTurnFailedEvent, InstrumentationTurnSettledEvent } from "#instrumentation/lifecycle.js";
3
3
  import type { ChannelAudience } from "#shared/channel-audience.js";
4
4
  import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
5
5
  export interface AgentSessionTraceState {
@@ -52,7 +52,7 @@ export interface AgentActionTraceState {
52
52
  readonly callId: string;
53
53
  readonly channelAudience?: ChannelAudience;
54
54
  readonly inputAttribute?: string;
55
- readonly kind: InstrumentationActionKind;
55
+ readonly kind: InstrumentationToolCallKind;
56
56
  readonly name: string;
57
57
  readonly parent: InstrumentationTraceContext;
58
58
  readonly parentCallId?: string;
@@ -62,6 +62,10 @@ export interface AgentActionTraceState {
62
62
  readonly startTimeMs: number;
63
63
  readonly stepIndex: number;
64
64
  readonly turnId: string;
65
+ readonly toolAttributes?: Attributes;
66
+ readonly toolEndTimeMs?: number;
67
+ readonly toolFailed?: boolean;
68
+ readonly toolErrorAttribute?: string;
65
69
  }
66
70
  /** Provider-owned serializable storage for durable agent trace state. */
67
71
  export interface AgentTraceStateStore {
@@ -1 +1 @@
1
- import{createLogger,formatError}from"#internal/logging.js";import{applyLiveDeliveryAudienceCeiling}from"#shared/forwarded-trace-policy.js";import{DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE}from"#tracing/agent-span-contract.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{SpanKind,context,trace}from"#compiled/@opentelemetry/api/index.js";import{buildConversationContext}from"#channel/conversation-context.js";import{markAgentTraceContext}from"#tracing/agent-trace-context.js";import{toolCallIdempotencyKey}from"#instrumentation/lifecycle.js";import{resolveTracePolicy}from"#shared/trace-policy.js";import{withErrorContent}from"#tracing/error-content-context.js";import{getInstrumentationRuntime}from"#instrumentation/runtime-global.js";import{agentSpanNamingAttributes}from"#tracing/agent-span-naming.js";import{contentAttribute}from"#tracing/agent-otel-content.js";import{recordAgentSpanError}from"#tracing/agent-span-error.js";import{withAgentToolSpanContext}from"#tracing/agent-tool-span-context.js";import{agentTraceIdentityAttributes}from"#tracing/agent-otel-attributes.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";import{suppressTracing}from"#tracing/suppress-tracing.js";const log=createLogger(`invoke-tool`);async function withInvokeToolSpan(e,t){let n=withErrorContent(context.active(),!1);return await context.with(n,()=>traced(e,n,t))}async function traced(e,t,n){let r=getInstrumentationRuntime();if(r===void 0)return await n(silentObserver);let i=buildConversationContext({adapter:e.origin?.adapter??{kind:`channel`},auth:e.auth,channelName:e.origin?.channelName},resolveInstrumentationEnvironment()),a=toolCallEvents(r.hooks.forTrace?.({agentName:e.agentName,...i})??r.hooks,{attemptId:e.callId,attemptIndex:0,channelAudience:i.audience,functionId:e.agentName,rootSessionId:e.sessionId,sessionId:e.sessionId,stepIndex:0,traceSessionId:e.sessionId,turnId:e.callId},e),o=r.otelSettings;if(o===void 0)return await n(a.observer(void 0));let s=resolveTracePolicy(o.tracePolicy,{agentName:e.agentName,...i},e=>log.warn(`tracePolicy threw; dropping the tool call's trace`,{error:formatError(e)}));if(s.action===`drop`)return await context.with(suppressTracing(t),()=>n(a.observer(void 0)));let c=applyLiveDeliveryAudienceCeiling({action:`record`,recordInputs:o.recordInputs&&s.recordInputs,recordOutputs:o.recordOutputs&&s.recordOutputs},i.audience,void 0,i.environment),l=c.action===`record`&&c.recordInputs,u=c.action===`record`&&c.recordOutputs,d=`execute_tool ${e.toolName}`,f=withChannelAudience(t,i.audience),p={"gen_ai.agent.name":e.agentName,"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":e.callId,"gen_ai.tool.name":e.toolName,"gen_ai.tool.type":`function`,[DIRECT_TOOL_CALL_ATTRIBUTE]:DIRECT_TOOL_CALL_VALUE,...agentSpanNamingAttributes(d,`execute_tool`),...agentTraceIdentityAttributes({rootSessionId:e.sessionId,sessionId:e.sessionId,traceSessionId:e.sessionId})};e.origin!==void 0&&(p[`eve.channel.kind`]=i.channel.kind,p[`eve.channel.name`]=e.origin.channelName);let m=trace.getTracer(`eve.agent`).startSpan(d,{attributes:p,kind:SpanKind.INTERNAL},f),h=markAgentTraceContext(withAgentToolSpanContext(withErrorContent(trace.setSpan(f,m),u),{recordInputs:l,recordOutputs:u,recordError:(e,t)=>recordAgentSpanError(m,u?e:void 0,t),setAttributes:e=>setDefined(m,e)})),g,_=a.observer({failedWith:e=>{g={error:e}},recordInputs:l,span:m});try{let e=await context.with(h,()=>n(_));if(m.setAttribute(`eve.tool.outcome`,e.status),e.status===`completed`&&u){let t=contentAttribute(e.output);t!==void 0&&m.setAttribute(`gen_ai.tool.call.result`,t)}return e.status===`invalid-input`?recordAgentSpanError(m,void 0,e.status):e.status===`failed`&&recordAgentSpanError(m,u?g?.error:void 0,g===void 0?e.status:void 0),e}catch(e){throw recordAgentSpanError(m,u?e:void 0),e}finally{m.end(),await r.forceFlush().catch(e=>{log.warn(`flushing a tool call's trace failed`,{error:formatError(e)})})}}const silentObserver={executed:async()=>{},executing:async()=>{},failedWith:()=>{}};function toolCallEvents(e,t,n){let r=e.capturesInputs??e.capturesContent,i=e.capturesOutputs??e.capturesContent,a=toolCallIdempotencyKey(t,n.callId,0);return{observer(o){return{async executing(i){if(o?.recordInputs){let e=contentAttribute(i);e!==void 0&&o.span.setAttribute(`gen_ai.tool.call.arguments`,e)}await e.publish(Object.freeze({callId:n.callId,idempotencyKey:a,input:r?i:void 0,scope:t,toolName:n.toolName,type:`tool.call.started`}))},async executed(n){o?.span.setAttribute(`gen_ai.execute_tool.duration`,n.durationMs/1e3);let r=n.type===`result`?i?{output:n.output,type:`result`}:{type:`result`}:i?{error:n.error,type:`error`}:{type:`error`};await e.publish(Object.freeze({idempotencyKey:a,output:Object.freeze(r),scope:t,type:`tool.call.completed`}))},failedWith(e){o?.failedWith(e)}}}}}function setDefined(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&e.setAttribute(n,r)}export{withInvokeToolSpan};
1
+ import{createLogger,formatError}from"#internal/logging.js";import{applyLiveDeliveryAudienceCeiling}from"#shared/forwarded-trace-policy.js";import{DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE}from"#tracing/agent-span-contract.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{SpanKind,context,trace}from"#compiled/@opentelemetry/api/index.js";import{buildConversationContext}from"#channel/conversation-context.js";import{markAgentTraceContext}from"#tracing/agent-trace-context.js";import{toolCallIdempotencyKey}from"#instrumentation/lifecycle.js";import{resolveTracePolicy}from"#shared/trace-policy.js";import{withErrorContent}from"#tracing/error-content-context.js";import{getInstrumentationRuntime}from"#instrumentation/runtime-global.js";import{agentSpanNamingAttributes}from"#tracing/agent-span-naming.js";import{contentAttribute}from"#tracing/agent-otel-content.js";import{recordAgentSpanError}from"#tracing/agent-span-error.js";import{withAgentToolSpanContext}from"#tracing/agent-tool-span-context.js";import{agentTraceIdentityAttributes}from"#tracing/agent-otel-attributes.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";import{suppressTracing}from"#tracing/suppress-tracing.js";const log=createLogger(`invoke-tool`);async function withInvokeToolSpan(e,t){let n=withErrorContent(context.active(),!1);return await context.with(n,()=>traced(e,n,t))}async function traced(e,t,n){let r=getInstrumentationRuntime();if(r===void 0)return await n(silentObserver);let i=buildConversationContext({adapter:e.origin?.adapter??{kind:`channel`},auth:e.auth,channelName:e.origin?.channelName},resolveInstrumentationEnvironment()),a=toolCallEvents(r.hooks.forTrace?.({agentName:e.agentName,...i})??r.hooks,{attemptId:e.callId,attemptIndex:0,channelAudience:i.audience,functionId:e.agentName,rootSessionId:e.sessionId,sessionId:e.sessionId,stepIndex:0,traceSessionId:e.sessionId,turnId:e.callId},e),o=r.otelSettings;if(o===void 0)return await n(a.observer(void 0));let s=resolveTracePolicy(o.tracePolicy,{agentName:e.agentName,...i},e=>log.warn(`tracePolicy threw; dropping the tool call's trace`,{error:formatError(e)}));if(s.action===`drop`)return await context.with(suppressTracing(t),()=>n(a.observer(void 0)));let c=applyLiveDeliveryAudienceCeiling({action:`record`,recordInputs:o.recordInputs&&s.recordInputs,recordOutputs:o.recordOutputs&&s.recordOutputs},i.audience,void 0,i.environment),l=c.action===`record`&&c.recordInputs,u=c.action===`record`&&c.recordOutputs,d=`execute_tool ${e.toolName}`,f=withChannelAudience(t,i.audience),p={"agent.tool.is_framework":!1,"gen_ai.agent.name":e.agentName,"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":e.callId,"gen_ai.tool.name":e.toolName,"gen_ai.tool.type":`function`,[DIRECT_TOOL_CALL_ATTRIBUTE]:DIRECT_TOOL_CALL_VALUE,...agentSpanNamingAttributes(d,`execute_tool`),...agentTraceIdentityAttributes({rootSessionId:e.sessionId,sessionId:e.sessionId,traceSessionId:e.sessionId})};e.origin!==void 0&&(p[`eve.channel.kind`]=i.channel.kind,p[`eve.channel.name`]=e.origin.channelName);let m=trace.getTracer(`eve.agent`).startSpan(d,{attributes:p,kind:SpanKind.INTERNAL},f),h=markAgentTraceContext(withAgentToolSpanContext(withErrorContent(trace.setSpan(f,m),u),{recordInputs:l,recordOutputs:u,recordError:(e,t)=>recordAgentSpanError(m,u?e:void 0,t),setAttributes:e=>setDefined(m,e)})),g,_=a.observer({failedWith:e=>{g={error:e}},recordInputs:l,span:m});try{let e=await context.with(h,()=>n(_));if(m.setAttribute(`eve.tool.outcome`,e.status),e.status===`completed`&&u){let t=contentAttribute(e.output);t!==void 0&&m.setAttribute(`gen_ai.tool.call.result`,t)}return e.status===`invalid-input`?recordAgentSpanError(m,void 0,e.status):e.status===`failed`&&recordAgentSpanError(m,u?g?.error:void 0,g===void 0?e.status:void 0),e}catch(e){throw recordAgentSpanError(m,u?e:void 0),e}finally{m.end(),await r.forceFlush().catch(e=>{log.warn(`flushing a tool call's trace failed`,{error:formatError(e)})})}}const silentObserver={executed:async()=>{},executing:async()=>{},failedWith:()=>{}};function toolCallEvents(e,t,n){let r=e.capturesInputs??e.capturesContent,i=e.capturesOutputs??e.capturesContent,a=toolCallIdempotencyKey(t,n.callId,0);return{observer(o){return{async executing(i){if(o?.recordInputs){let e=contentAttribute(i);e!==void 0&&o.span.setAttribute(`gen_ai.tool.call.arguments`,e)}await e.publish(Object.freeze({callId:n.callId,idempotencyKey:a,input:r?i:void 0,scope:t,toolName:n.toolName,type:`tool.call.started`}))},async executed(n){o?.span.setAttribute(`gen_ai.execute_tool.duration`,n.durationMs/1e3);let r=n.type===`result`?i?{output:n.output,type:`result`}:{type:`result`}:i?{error:n.error,type:`error`}:{type:`error`};await e.publish(Object.freeze({durationMs:n.durationMs,idempotencyKey:a,output:Object.freeze(r),scope:t,type:`tool.call.completed`,outcome:n.type===`result`?`completed`:`failed`}))},failedWith(e){o?.failedWith(e)}}}}}function setDefined(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&e.setAttribute(n,r)}export{withInvokeToolSpan};
@@ -1 +1 @@
1
- import{summarizeLocalTrace}from"#tracing/local-trace-summary.js";import{localTraceOperations,traceModelName,traceSessionId,traceStringAttribute,traceToolName,uniqueLocalTraceSpans}from"#tracing/local-trace-operations.js";function analyzeLocalTrace(e,t,n={}){let r=uniqueLocalTraceSpans(t),i=new Map(localTraceOperations(r).map(({span:e})=>[e.spanId,e])),a=r.filter(e=>matches(i.get(e.spanId)??e,n)),o=a.reduce((e,t)=>t.startTimeNs<e?t.startTimeNs:e,a[0]?.startTimeNs??0n),s=localTraceOperations(a).map(e=>recordFor(e,o)).sort((e,t)=>e.startOffsetMs-t.startOffsetMs||e.endOffsetMs-t.endOffsetMs||e.spanId.localeCompare(t.spanId));return{summary:summarizeLocalTrace(e,a),groups:groups(s),modelWorkMs:sum(s,`model`),toolWorkMs:sum(s,`tool`),records:s}}function matches(e,t){let n=traceSessionId(e),r=traceStringAttribute(e,`agent.turn.id`);if(t.excludeSessionId!==void 0&&n===t.excludeSessionId||t.sessionId!==void 0&&n!==t.sessionId||t.turnId!==void 0&&r!==t.turnId)return!1;let i=Number(e.startTimeNs/1000000n);return(t.fromMs===void 0||i>=t.fromMs)&&(t.toMs===void 0||i<=t.toMs)}function recordFor(e,t){let{span:n,category:r}=e,i={category:r,durationMs:Number(n.endTimeNs-n.startTimeNs)/1e6,endOffsetMs:Number(n.endTimeNs-t)/1e6,outcome:n.statusCode===2?`failed`:`completed`,spanId:n.spanId,startOffsetMs:Number(n.startTimeNs-t)/1e6},a=traceStringAttribute(n,`agent.action.call_id`),o=traceModelName(n),s=traceSessionId(n),c=traceToolName(n),l=traceStringAttribute(n,`agent.turn.id`);if(a!==void 0&&(i.callId=a),n.statusMessage!==void 0&&(i.error=n.statusMessage),o!==void 0&&(i.model=o),n.parentSpanId!==void 0&&(i.parentSpanId=n.parentSpanId),s!==void 0&&(i.sessionId=s),c!==void 0&&r===`tool`&&(i.toolName=c),c!==void 0&&r===`other`&&(i.actionName=c),l!==void 0&&(i.turnId=l),e.actionDurationMs!==void 0&&(i.actionDurationMs=e.actionDurationMs),r===`model`){let e={};for(let[t,r]of Object.entries({inputTokens:`agent.usage.input_tokens`,outputTokens:`agent.usage.output_tokens`,cacheReadTokens:`agent.usage.cache_read_tokens`,cacheWriteTokens:`agent.usage.cache_write_tokens`})){let i=n.attributes[r];typeof i==`number`&&Number.isFinite(i)&&i>=0&&(e[t]=i)}Object.keys(e).length>0&&(i.usage=e)}return i}function groups(e){let t=new Map;for(let n of e){let e=JSON.stringify([n.sessionId,n.turnId]),r=t.get(e);r===void 0&&(r={modelCalls:0,modelWorkMs:0,toolCalls:0,toolWorkMs:0},n.sessionId!==void 0&&(r.sessionId=n.sessionId),n.turnId!==void 0&&(r.turnId=n.turnId),t.set(e,r)),n.category===`model`&&(r.modelCalls+=1,r.modelWorkMs+=n.durationMs),n.category===`tool`&&(r.toolCalls+=1,r.toolWorkMs+=n.durationMs)}return[...t.values()]}function sum(e,t){return e.reduce((e,n)=>e+(n.category===t?n.durationMs:0),0)}export{analyzeLocalTrace};
1
+ import{summarizeLocalTrace}from"#tracing/local-trace-summary.js";import{localTraceOperations,traceModelName,traceSessionId,traceStringAttribute,traceToolName,uniqueLocalTraceSpans}from"#tracing/local-trace-operations.js";function analyzeLocalTrace(e,t,n={}){let r=uniqueLocalTraceSpans(t),i=new Map(localTraceOperations(r).map(({span:e})=>[e.spanId,e])),a=r.filter(e=>matches(i.get(e.spanId)??e,n)),o=a.reduce((e,t)=>t.startTimeNs<e?t.startTimeNs:e,a[0]?.startTimeNs??0n),s=localTraceOperations(a).map(e=>recordFor(e,o)).sort((e,t)=>e.startOffsetMs-t.startOffsetMs||e.endOffsetMs-t.endOffsetMs||e.spanId.localeCompare(t.spanId));return{summary:summarizeLocalTrace(e,a),groups:groups(s),modelWorkMs:sum(s,`model`),toolWorkMs:sum(s,`tool`),records:s}}function matches(e,t){let n=traceSessionId(e),r=traceStringAttribute(e,`agent.turn.id`);if(t.excludeSessionId!==void 0&&n===t.excludeSessionId||t.sessionId!==void 0&&n!==t.sessionId||t.turnId!==void 0&&r!==t.turnId)return!1;let i=Number(e.startTimeNs/1000000n);return(t.fromMs===void 0||i>=t.fromMs)&&(t.toMs===void 0||i<=t.toMs)}function recordFor(e,t){let{span:n,category:r}=e,i={category:r,durationMs:Number(n.endTimeNs-n.startTimeNs)/1e6,endOffsetMs:Number(n.endTimeNs-t)/1e6,outcome:n.statusCode===2?`failed`:`completed`,spanId:n.spanId,startOffsetMs:Number(n.startTimeNs-t)/1e6},a=traceStringAttribute(n,`gen_ai.tool.call.id`),o=traceModelName(n),s=traceSessionId(n),c=traceToolName(n),l=traceStringAttribute(n,`agent.turn.id`);if(a!==void 0&&(i.callId=a),n.statusMessage!==void 0&&(i.error=n.statusMessage),o!==void 0&&(i.model=o),n.parentSpanId!==void 0&&(i.parentSpanId=n.parentSpanId),s!==void 0&&(i.sessionId=s),c!==void 0&&r===`tool`&&(i.toolName=c),c!==void 0&&r===`other`&&(i.actionName=c),l!==void 0&&(i.turnId=l),e.actionDurationMs!==void 0&&(i.actionDurationMs=e.actionDurationMs),r===`model`){let e={};for(let[t,r]of Object.entries({inputTokens:`gen_ai.usage.input_tokens`,outputTokens:`gen_ai.usage.output_tokens`,cacheReadTokens:`gen_ai.usage.cache_read.input_tokens`,cacheWriteTokens:`gen_ai.usage.cache_write.input_tokens`})){let i=n.attributes[r];typeof i==`number`&&Number.isFinite(i)&&i>=0&&(e[t]=i)}Object.keys(e).length>0&&(i.usage=e)}return i}function groups(e){let t=new Map;for(let n of e){let e=JSON.stringify([n.sessionId,n.turnId]),r=t.get(e);r===void 0&&(r={modelCalls:0,modelWorkMs:0,toolCalls:0,toolWorkMs:0},n.sessionId!==void 0&&(r.sessionId=n.sessionId),n.turnId!==void 0&&(r.turnId=n.turnId),t.set(e,r)),n.category===`model`&&(r.modelCalls+=1,r.modelWorkMs+=n.durationMs),n.category===`tool`&&(r.toolCalls+=1,r.toolWorkMs+=n.durationMs)}return[...t.values()]}function sum(e,t){return e.reduce((e,n)=>e+(n.category===t?n.durationMs:0),0)}export{analyzeLocalTrace};
@@ -2,5 +2,7 @@ export { useEveAgent, type PrepareSend, type UseEveAgentOptions, type UseEveAgen
2
2
  export { type EveAgentReducer, type EveAgentReducerEvent, type ClientInputRespondedEvent, type ClientMessageFailedEvent, type ClientMessageSubmittedEvent, } from "#client/reducer.js";
3
3
  export { conversationReducer } from "#client/conversation-reducer.js";
4
4
  export { openConversationInputs } from "#client/conversation-state.js";
5
+ export { toolCallState, type ToolCallState, type ToolCallStatus } from "#client/tool-call-state.js";
6
+ export type { SessionAuthorization, SessionCall, SessionCallStatus, SessionProjection, } from "#protocol/session-projection.js";
5
7
  export type { AgentObservation, ConversationAgentSession, ConversationInput, ConversationState, ConversationTask, ConversationTaskCall, ConversationTurn, } from "#client/conversation-state.js";
6
8
  export { defaultMessageReducer, type EveAuthorizationChallenge, type EveAuthorizationOutcome, type EveAuthorizationPart, type EveMessageData, type EveDynamicToolPart, type EveMessageInputRequest, type EveMessage, type EveMessageMetadata, type EveMessagePart, type EveMessageToolMetadata, } from "#client/message-reducer.js";
@@ -1,3 +1,40 @@
1
- import { i as openConversationInputs, n as conversationReducer, r as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-CFCaYnrI.js";
1
+ import { a as conversationProjection, i as openConversationInputs, n as conversationReducer, o as callStatus, r as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-C1GYGCtb.js";
2
2
 
3
- export { conversationReducer, defaultMessageReducer, openConversationInputs, useEveAgent };
3
+ //#region src/client/tool-call-state.ts
4
+ function toolCallState(conversation, callId, options = {}) {
5
+ const part = findToolPart(conversation, callId);
6
+ const projection = conversationProjection(conversation);
7
+ const call = projection.calls[callId];
8
+ const status = callStatus(projection, callId, options) ?? partStatus(part, options);
9
+ if (status === void 0) return void 0;
10
+ const taskCall = (call?.taskId === void 0 ? void 0 : conversation.tasks[call.taskId])?.calls[callId];
11
+ const output = taskCall?.output ?? part?.output;
12
+ const errorText = taskCall?.error?.message ?? part?.errorText ?? call?.error?.message ?? (part?.state === "output-denied" ? part.approval.reason : void 0);
13
+ const state = { status: respondedStatus(conversation, part, status) };
14
+ if (output !== void 0) state.output = output;
15
+ if (errorText !== void 0) state.errorText = errorText;
16
+ if (call?.error?.code !== void 0) state.errorCode = call.error.code;
17
+ return state;
18
+ }
19
+ function respondedStatus(conversation, part, status) {
20
+ if (status !== "awaiting-input" || part?.state !== "approval-requested") return status;
21
+ const input = conversation.inputs[part.approval.id];
22
+ if (input?.status !== "responded") return status;
23
+ return input.response?.optionId === "approve" ? "running" : "rejected";
24
+ }
25
+ function partStatus(part, options) {
26
+ if (part === void 0) return void 0;
27
+ switch (part.state) {
28
+ case "output-available": return part.partial === true ? "running" : "completed";
29
+ case "output-error": return "failed";
30
+ case "output-denied": return "rejected";
31
+ case "approval-requested": return "awaiting-input";
32
+ default: return options.streaming === false ? "interrupted" : "running";
33
+ }
34
+ }
35
+ function findToolPart(conversation, callId) {
36
+ for (let index = conversation.messages.length - 1; index >= 0; index -= 1) for (const part of conversation.messages[index].parts) if (part.type === "dynamic-tool" && part.toolCallId === callId) return part;
37
+ }
38
+
39
+ //#endregion
40
+ export { conversationReducer, defaultMessageReducer, openConversationInputs, toolCallState, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-CFCaYnrI.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-C1GYGCtb.js";
2
2
 
3
3
  export { useEveAgent };
@@ -69,8 +69,8 @@ takes precedence; AI Gateway hashes IDs longer than 256 characters.
69
69
 
70
70
  ### Choose the model dynamically
71
71
 
72
- To select a model from the incoming prompt with an AI SDK evaluation model, use
73
- [`auto` from `eve/models`](./guides/evaluate).
72
+ To select a model from the incoming prompt with an AI SDK decision model, use
73
+ [`auto` from `eve/models`](./guides/decide).
74
74
 
75
75
  `model` also accepts `defineDynamic({ events })`. Each matching handler must
76
76
  return the concrete model for its scope; a dynamic model has no compiled
@@ -208,7 +208,7 @@ await to(channel, { adapterName: "resend", threadId: "resend:user@example.com" }
208
208
 
209
209
  ### Attachments
210
210
 
211
- `send` takes plain text or an AI SDK `UserContent` array. To forward a Chat SDK message's attachments, convert it with `messageToUserContent`, which returns `message.text` when there are no attachments and a `UserContent` array (text plus one file part per attachment URL) when there are:
211
+ `send` takes plain text or an AI SDK `UserContent` array. To forward a Chat SDK message's attachments, convert it with `messageToUserContent`. It returns `message.text` when there are no attachments, and a `UserContent` array (the text plus one part per attachment) when there are:
212
212
 
213
213
  ```ts
214
214
  import { messageToUserContent } from "eve/channels/chat-sdk";
@@ -218,6 +218,8 @@ bot.onNewMention(async (thread, message) => {
218
218
  });
219
219
  ```
220
220
 
221
+ When the adapter can download an attachment (it sets `fetchData`, as the Slack, Google Chat, WhatsApp, and Twilio adapters do), eve downloads it with the adapter's credentials when the turn runs, not in the webhook, and passes the bytes. Platform file URLs usually need those credentials, so the model provider couldn't open them. eve rebuilds the download with the adapter's `rehydrateAttachment`; an adapter without one can't download after the webhook returns, so its files reach the agent as a short note. A failed download, or a file over 25 MB, also becomes a note. An attachment with only a URL is passed as that URL.
222
+
221
223
  See [File uploads](./custom#file-uploads) for how eve stages remote file URLs before the model call.
222
224
 
223
225
  ## Configuration reference
@@ -70,6 +70,8 @@ Each route receives these operation surfaces:
70
70
  - `describe()` returns the agent's name, description, and the compiled tools a caller can run outside a turn, with their JSON schemas, sorted by name. It carries no paths, config, or other inspection detail, so a channel can publish it to its callers. Tools that need a turn (framework tools, workflow and provider tools, tools without `execute`) and tools added by dynamic resolvers or subagents are left out.
71
71
  - `invokeTool(name, input, { auth })` runs one of those tools as `auth`, outside any conversation: no model, turn, or workflow run. Each call gets its own session. Authored state starts from its initial value and is not kept, and a sandbox the tool opens is deleted when the call ends. It resolves to `completed` with the tool's output, or to `invalid-input`, `denied`, `failed`, `approval-required` when the tool's approval policy asks a person (the tool did not run), or `authorization-required` with the connections the tool needs a sign-in to.
72
72
 
73
+ A direct call doesn't go through the AI SDK, so AI SDK telemetry integrations never see it. Conversation tool calls do: an integration that an `agent/instrumentation/*.ts` module registers with `registerTelemetry()` from `ai` receives `onToolExecutionStart` and `onToolExecutionEnd` for each of them. A direct call is traced by eve itself instead. It gets an `execute_tool` span under the caller's trace and emits `tool.call.started` and `tool.call.completed` to instrumentation. Over MCP, the caller's trace comes from the request's `_meta` trace context (see [Trace context](./mcp#trace-context)).
74
+
73
75
  Event handlers receive `(eventData, channel, ctx)`. `ctx.session.id` identifies
74
76
  the exact session, while `channel.continuation` exposes the current address and
75
77
  `alias()` when this channel needs to add another address. `session.failed`
@@ -19,7 +19,7 @@ The setup guides you through creating a Discord application and bot, then:
19
19
  - signs you in to Vercel and creates or links a project when needed;
20
20
  - validates the bot token;
21
21
  - creates a Vercel Connect client and attaches `/eve/v1/discord` as its trigger destination;
22
- - registers an application command with a required `message` option;
22
+ - registers an application command with a required `message` option and an optional `file` attachment option;
23
23
  - configures the Discord application's Interactions Endpoint URL;
24
24
  - scaffolds the channel with Connect-managed credentials; and
25
25
  - prints the bot installation URL.
@@ -41,13 +41,14 @@ The route is `POST /eve/v1/discord` by default. Connect resolves the application
41
41
 
42
42
  ### Configure Discord manually
43
43
 
44
- If you do not use the guided Connect setup, register a command with Discord's API or the Developer Portal. A string option named `message` lines up with eve's default prompt extraction:
44
+ If you do not use the guided Connect setup, register a command with Discord's API or the Developer Portal. A string option named `message` lines up with eve's default prompt extraction, and an attachment option lets people send a file with the command:
45
45
 
46
46
  ```bash
47
47
  curl -X PUT "https://discord.com/api/v10/applications/$DISCORD_APPLICATION_ID/commands" \
48
48
  -H "Authorization: Bot $DISCORD_BOT_TOKEN" -H "Content-Type: application/json" \
49
49
  -d '[{"name":"ask","description":"Ask the eve agent","type":1,
50
- "options":[{"name":"message","description":"What should the agent do?","type":3,"required":true}]}]'
50
+ "options":[{"name":"message","description":"What should the agent do?","type":3,"required":true},
51
+ {"name":"file","description":"A file for the agent to read","type":11,"required":false}]}]'
51
52
  ```
52
53
 
53
54
  Then configure the public `https://…/eve/v1/discord` route as the application's Interactions Endpoint URL. Pass `credentials: { applicationId, botToken, publicKey }` to `discordChannel`, or set the corresponding `DISCORD_APPLICATION_ID`, `DISCORD_BOT_TOKEN`, and `DISCORD_PUBLIC_KEY` environment variables.
@@ -99,7 +100,7 @@ Start a session without an inbound interaction through `to(discord, target).send
99
100
 
100
101
  ### Attachments
101
102
 
102
- Inbound file attachments are not supported on this channel today.
103
+ Files attached through a command's attachment options (type `11`) reach the agent as file parts. eve downloads each one from Discord's signed CDN URL (`cdn.discordapp.com` or `media.discordapp.net`) without credentials. A file over 25 MB, or one whose download fails, reaches the agent as a short note instead. Each command starts its own session, so a file is available in the conversation that command starts.
103
104
 
104
105
  ## What to read next
105
106
 
@@ -18,6 +18,71 @@ export default eveChannel({
18
18
  });
19
19
  ```
20
20
 
21
+ ## Web Chat with Sign in with Vercel
22
+
23
+ Run `eve add channel/web`, or select **Web Chat** from the terminal UI's channel
24
+ picker. Choose a hosting layout, then **Sign in with Vercel**. Setup uses a
25
+ linked Vercel project and creates a Vercel App that only members of that
26
+ project's team can sign in to.
27
+
28
+ For a new agent, initialize it first, then link a project and add Web Chat:
29
+
30
+ ```bash
31
+ eve init my-agent --non-interactive
32
+ cd my-agent
33
+ eve link
34
+ eve add channel/web
35
+ ```
36
+
37
+ `eve init --channel-web-nextjs` keeps its existing scaffolding behavior and does
38
+ not provision authentication. Sign-in setup runs through `eve add channel/web`
39
+ or the terminal UI's channel picker.
40
+
41
+ The generated Next.js app uses Better Auth sessions. The selected agent's HTTP
42
+ channel verifies the same session, while retaining Vercel OIDC and local
43
+ development access. In an agent workspace, setup configures only the selected
44
+ agent. Other agents keep their own authentication policies.
45
+
46
+ Setup registers `/api/auth/callback/vercel` as a project redirect URI, so Vercel
47
+ validates callbacks against the project's deployment domains. The app uses the
48
+ `authorization_code` grant, `client_secret_post` authentication, and the
49
+ `openid`, `email`, and `profile` scopes. Setup writes `VERCEL_APP_CLIENT_ID`,
50
+ `VERCEL_APP_CLIENT_SECRET`, and `BETTER_AUTH_SECRET` to production and preview;
51
+ secret values are marked sensitive and are never printed or written to source.
52
+ Run `eve deploy` after setup to publish the app. Local development continues
53
+ without browser sign-in.
54
+
55
+ For automation, supply the setup answers explicitly:
56
+
57
+ ```bash
58
+ eve add channel/web --non-interactive \
59
+ --answer 'web-hosting="vercel"' \
60
+ --answer 'web-authentication="vercel"'
61
+ ```
62
+
63
+ Use a linked project with permission to manage Vercel Apps and project
64
+ environment variables. A team owner can complete setup if your role cannot
65
+ create apps. The searchable team picker lists eligible teams first. Disabled
66
+ teams show `needs permission` or `couldn't verify`, with shared recovery guidance
67
+ below the list. If permissions cannot be verified, that team stays
68
+ disabled until you sign in or retry. Linked projects are checked before
69
+ interactive auth setup.
70
+ If setup reports a missing prerequisite, complete it and resume with
71
+ `eve add channel/web --skip-install`. Compatible existing apps
72
+ and credentials are reused; conflicting app settings or credentials stop setup
73
+ with an error. Authored channel or UI files are preserved unless you explicitly
74
+ pass `--overwrite`.
75
+
76
+ If the team has reached its Vercel App limit, remove an unused app in team
77
+ settings and retry. If a generated app name or slug is taken by an incompatible
78
+ app, rename the Vercel project in its settings and retry. Compatible apps from a
79
+ concurrent setup are reused. A client-secret limit requires removing an unused
80
+ secret from the app's settings; setup never removes an existing secret for you.
81
+
82
+ Choose **Configure authentication myself** (`web-authentication=custom`) to
83
+ keep the current channel policy. The default placeholder rejects production
84
+ browser requests until you configure your own authentication.
85
+
21
86
  ## Routes
22
87
 
23
88
  The default eve channel inspects the agent, creates sessions, accepts callbacks and task input, controls sessions, and streams events. Its public routes include:
@@ -95,7 +95,7 @@ Start a session without an inbound webhook with `receive(linear, { target })`. S
95
95
 
96
96
  ### Attachments
97
97
 
98
- Markdown images hosted at `https://uploads.linear.app` in Agent Session prompts are fetched with the resolved Linear access token and included as image file parts. eve sends the bearer token only to that exact HTTPS origin; images from other hosts remain markdown text. If a Linear upload fails or returns non-image content, eve preserves its markdown reference and continues the text turn. Other inbound file attachments are not supported on this channel today.
98
+ Files uploaded to Linear and referenced in an Agent Session prompt, whether as markdown images (`![name](url)`) or file links (`[name](url)`) hosted at `https://uploads.linear.app`, are fetched with the resolved Linear access token and included as file parts. eve sends the bearer token only to that exact HTTPS origin; images and links from other hosts remain markdown text. If a Linear upload fails, an image reference returns non-image content, or a file link returns an HTML page, the reference becomes its label in the text, the agent gets a short note that the file couldn't be retrieved, and the text turn continues.
99
99
 
100
100
  ### API handle
101
101
 
@@ -20,6 +20,8 @@ The default webhook route is `/eve/v1/linq`. The channel verifies forwarded webh
20
20
 
21
21
  Set `turnPolicy: "queue"` when every response should finish before Linq starts the next message.
22
22
 
23
+ Images and other files people send reach the agent as file parts. eve downloads each one from Linq's CDN and passes the bytes; a failed download, or a file over 25 MB, reaches the agent as a short note.
24
+
23
25
  Customize inbound dispatch with `onMessage`. Return `null` to ignore a message, or return `title` alongside `auth` to set the title when the dispatch starts a run:
24
26
 
25
27
  ```ts
@@ -3,7 +3,7 @@ title: "MCP Channel"
3
3
  description: "Publish an eve agent as an MCP server with auth support."
4
4
  ---
5
5
 
6
- The MCP channel lets clients such as Claude Code delegate durable work to an eve agent through four tools: `agent_start`, `agent_get`, `agent_update`, and `agent_cancel`.
6
+ The MCP channel lets clients such as Claude Code delegate durable work to an eve agent through four tools: `agent_start`, `agent_get`, `agent_update`, and `agent_cancel`. It can also publish the agent's own tools, so a client calls them directly; see [Publish the agent's tools](#publish-the-agents-tools).
7
7
 
8
8
  Use an [MCP connection](../connections/mcp) instead when your eve agent needs to call someone else's MCP server.
9
9
 
@@ -211,6 +211,44 @@ Requests are bounded: the whole MCP request body is limited to 1 MiB, `message`
211
211
  - `agent_update` answers one pending batch. Re-sending the same answers after eve has accepted them returns the current invocation state; sending different answers for an already-answered batch is a conflict.
212
212
  - `agent_cancel` is cooperative and can race with completion. Poll `agent_get` until the status is terminal (`cancelled`, `completed`, or `failed`), not specifically `cancelled`.
213
213
 
214
+ ## Publish the agent's tools
215
+
216
+ By default the channel serves only the `agent_*` tools. Set `tools: true` to also publish every tool the agent can run outside a conversation, and `agent: false` to stop serving the `agent_*` tools:
217
+
218
+ ```ts title="agent/channels/mcp.ts"
219
+ import { localDev } from "eve/channels/auth";
220
+ import { mcpChannel } from "eve/channels/mcp";
221
+
222
+ export default mcpChannel({
223
+ auth: localDev(),
224
+ tools: true,
225
+ });
226
+ ```
227
+
228
+ `tools/list` returns the `agent_*` tools first, then the agent's tools in name order with their input and output JSON schemas. Framework tools, workflow and provider tools, tools without `execute`, and tools added by dynamic resolvers or subagents are not published. While `agent` is on, an agent tool named `agent_start`, `agent_get`, `agent_update`, or `agent_cancel` is not published, and eve logs a warning. With `agent: false`, the channel sends no `agent_*` instructions. Turning off both `agent` and `tools` throws.
229
+
230
+ Each `tools/call` checks the arguments against the tool's input schema, then runs the tool as the route-authenticated caller, with no model, turn, or workflow run. Every caller the channel's `auth` admits can call these tools, outside the agent's instructions, so review what becomes callable before you turn this on. Each call gets its own session:
231
+
232
+ - Authored state starts from its initial value, and updates are not kept.
233
+ - A sandbox the tool opens is deleted when the call ends.
234
+ - Calls may run in parallel, and a call retried after a lost response runs again.
235
+
236
+ A tool that cannot finish over MCP returns an error result with `isError: true` and a `structuredContent.error.code`:
237
+
238
+ | Code | When |
239
+ | ------------------------ | ------------------------------------------------------------------------------------------------ |
240
+ | `invalid_input` | The tool rejected its input. |
241
+ | `denied` | The tool's approval policy denied the call. |
242
+ | `approval_required` | The approval policy asks a person. The tool did not run; call it from a conversation instead. |
243
+ | `authorization_required` | The tool needs a sign-in to a connection first. Sign in from a conversation, then call it again. |
244
+ | `internal` | The tool failed. The message carries an error id that matches the server logs. |
245
+
246
+ ### Trace context
247
+
248
+ MCP clients send W3C trace context in each request's `params._meta`, not in HTTP headers. When a request carries a valid `_meta.traceparent`, that span becomes the parent of everything the request runs, including a published tool's `execute_tool` span. It takes precedence over any parent your platform extracted from the HTTP request's headers. A missing, malformed, or all-zero `traceparent` leaves that parent in place. `_meta.tracestate` is kept only alongside a valid `_meta.traceparent` and only up to 512 characters; a longer value is dropped.
249
+
250
+ `_meta.baggage` is never read. A caller cannot choose the trace audience, session lineage, or content capture: those come from the channel and your `tracePolicy`, as they do for conversations. The `execute_tool` span records the call's arguments and result only when that content decision allows it, and never records exception text.
251
+
214
252
  ## Invocation ownership
215
253
 
216
254
  Every MCP operation reruns the configured auth policy. With authenticated policies, an invocation belongs to the principal that started it; knowing its ID is not sufficient. Bearer tokens are not stored with the invocation or forwarded to the agent's tools.
@@ -32,6 +32,11 @@ boundary. See [Overlapping messages](./overview#overlapping-messages).
32
32
 
33
33
  Set `turnPolicy: "queue"` when every response should finish before Photon starts the next message.
34
34
 
35
+ Images and other files people send reach the agent as file parts. Photon's
36
+ webhook lists each file without its bytes, so eve downloads it from Photon by
37
+ its attachment id with the project's credentials. A failed download, or a file
38
+ over 25 MB, reaches the agent as a short note.
39
+
35
40
  Customize inbound dispatch with `onMessage`. Return `null` to ignore a message, or return `title` alongside `auth` to set the title when the dispatch starts a run:
36
41
 
37
42
  ```ts
@@ -95,19 +95,16 @@ Proactive sessions need an existing conversation reference, because the Bot Fram
95
95
 
96
96
  ### Attachments
97
97
 
98
- Inbound files are off by default. Opt in to allow personal-scope downloads and public media URLs:
98
+ Inbound files reach the agent as file parts. eve downloads images pasted into a message from Microsoft Bot Connector hosts with your bot credentials, and files uploaded in a personal chat from their pre-authenticated SharePoint download URL (`*.sharepoint.com` or `*.sharepoint.us`). A failed download, or one over the upload limit (25 MB unless `files.uploadPolicy` sets `maxBytes`), reaches the agent as a short note. Personal-chat uploads need `supportsFiles: true` on the bot in your Teams app manifest.
99
+
100
+ Use `allowedHosts` to download from other hosts, unauthenticated, or `enabled: false` to drop attachments:
99
101
 
100
102
  ```ts
101
103
  export default teamsChannel({
102
- files: {
103
- enabled: true,
104
- allowedHosts: ["smba.trafficmanager.net", "contoso.sharepoint.com"],
105
- },
104
+ files: { allowedHosts: ["files.contoso.com"] },
106
105
  });
107
106
  ```
108
107
 
109
- eve authenticates downloads from Microsoft Bot Connector hosts with your bot credentials. Downloads from other allowlisted hosts remain unauthenticated.
110
-
111
108
  ## What to read next
112
109
 
113
110
  - [Channels overview](./overview): the channel contract and every built-in channel
@@ -70,7 +70,7 @@ Start a session without an inbound message through `to(twilio, target).send(mess
70
70
 
71
71
  ### Attachments
72
72
 
73
- Inbound media attachments are not supported on this channel today.
73
+ MMS media reaches the agent as file parts. eve downloads each media URL with the account SID and auth token, and only from the Twilio API origin (`https://api.twilio.com`, or `api.apiBaseUrl` when set). If a download fails, the agent gets a short note in place of the file and the text turn continues.
74
74
 
75
75
  ## Disclaimer
76
76