eve 0.33.3 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (414) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +3 -3
  3. package/dist/src/channel/channel-address.d.ts +3 -6
  4. package/dist/src/channel/channel-address.js +1 -1
  5. package/dist/src/channel/channel-operations.d.ts +2 -3
  6. package/dist/src/channel/delivery-metadata.d.ts +9 -0
  7. package/dist/src/channel/delivery-metadata.js +1 -0
  8. package/dist/src/channel/routes.d.ts +1 -0
  9. package/dist/src/channel/session.d.ts +3 -4
  10. package/dist/src/channel/session.js +1 -1
  11. package/dist/src/channel/types.d.ts +20 -3
  12. package/dist/src/chunks/{use-eve-agent-B-Hky2f4.js → use-eve-agent-COmP-H8R.js} +39 -3
  13. package/dist/src/chunks/{use-eve-agent-3oBnxzhV.js → use-eve-agent-CnppTEFk.js} +39 -3
  14. package/dist/src/cli/commands/info.js +1 -1
  15. package/dist/src/cli/commands/trace-detail.d.ts +3 -2
  16. package/dist/src/cli/commands/trace-detail.js +1 -1
  17. package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +4 -6
  18. package/dist/src/cli/dev/tui/traces/trace-conversation.js +1 -2
  19. package/dist/src/client/agent-info-schema.d.ts +12 -4
  20. package/dist/src/client/agent-info-schema.js +1 -1
  21. package/dist/src/client/index.d.ts +1 -1
  22. package/dist/src/client/message-reducer.js +1 -1
  23. package/dist/src/compiled/.vendor-stamp.json +4 -4
  24. package/dist/src/compiled/@chat-adapter/slack/index.js +1 -1
  25. package/dist/src/compiled/@opentelemetry/api/index.d.ts +32 -3
  26. package/dist/src/compiled/@vercel/otel/index.d.ts +45 -2
  27. package/dist/src/compiled/@workflow/core/index.js +1 -1
  28. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  29. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  30. package/dist/src/compiled/@workflow/world/env-config.d.ts +1 -0
  31. package/dist/src/compiled/@workflow/world/events.d.ts +92 -35
  32. package/dist/src/compiled/@workflow/world/index.d.ts +3 -2
  33. package/dist/src/compiled/@workflow/world/interfaces.d.ts +25 -23
  34. package/dist/src/compiled/@workflow/world/queue.d.ts +4 -0
  35. package/dist/src/compiled/@workflow/world/runs.d.ts +4 -0
  36. package/dist/src/compiled/@workflow/world/slot-identity.d.ts +53 -0
  37. package/dist/src/compiled/@workflow/world/spec-version.d.ts +36 -1
  38. package/dist/src/compiled/@workflow/world/steps.d.ts +4 -0
  39. package/dist/src/compiled/@workflow/world/ulid.d.ts +6 -0
  40. package/dist/src/compiled/@workflow/world-local/index.js +4 -4
  41. package/dist/src/compiled/@workflow/world-vercel/index.js +13 -17
  42. package/dist/src/compiled/_chunks/workflow/{attribute-changes-6OqdYdi4.js → attribute-changes-BoH7JsWp.js} +3 -3
  43. package/dist/src/compiled/_chunks/workflow/dist-DlFv0aHY.js +40 -0
  44. package/dist/src/compiled/_chunks/workflow/env-config-DxamfI7T.js +1 -0
  45. package/dist/src/compiled/_chunks/workflow/frames-CTpeJYEQ.js +3 -0
  46. package/dist/src/compiled/_chunks/workflow/{functions-CXb61C6h.js → functions-CeeNvKsq.js} +1 -1
  47. package/dist/src/compiled/_chunks/workflow/resume-hook-BPQHjeY5.js +1 -0
  48. package/dist/src/compiled/_chunks/workflow/run-DQ5dOyjm.js +1 -0
  49. package/dist/src/compiled/_chunks/workflow/run-id-BdE0MZz9.js +1 -0
  50. package/dist/src/compiled/_chunks/workflow/sleep-CzdoBiqy.js +1 -0
  51. package/dist/src/compiled/_chunks/workflow/spec-version-DBUVfF_R.js +1 -0
  52. package/dist/src/compiled/_chunks/workflow/undici-CUIybhQ2.js +95 -0
  53. package/dist/src/compiled/_chunks/workflow/wait-until-DK2lnH6U.js +15 -0
  54. package/dist/src/compiled/_chunks/workflow/{wrapper-CDq65xJV.js → wrapper-CMGju7QA.js} +1 -1
  55. package/dist/src/compiled/_chunks/workflow/ws-transport-Csi6Cydc.js +1 -0
  56. package/dist/src/compiler/extension-compatibility.d.ts +14 -14
  57. package/dist/src/compiler/extension-compatibility.js +1 -1
  58. package/dist/src/compiler/manifest.d.ts +8 -8
  59. package/dist/src/compiler/manifest.js +1 -1
  60. package/dist/src/compiler/normalize-agent-config.js +1 -1
  61. package/dist/src/compiler/normalize-extension.d.ts +3 -3
  62. package/dist/src/compiler/normalize-extension.js +1 -1
  63. package/dist/src/compiler/normalize-instructions.d.ts +1 -1
  64. package/dist/src/compiler/normalize-instructions.js +1 -1
  65. package/dist/src/compiler/normalize-manifest.js +1 -3
  66. package/dist/src/context/build-dynamic-tools.d.ts +7 -0
  67. package/dist/src/context/build-dynamic-tools.js +1 -1
  68. package/dist/src/context/dynamic-instruction-lifecycle.d.ts +5 -1
  69. package/dist/src/context/dynamic-instruction-lifecycle.js +1 -1
  70. package/dist/src/context/dynamic-tool-lifecycle.d.ts +7 -0
  71. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  72. package/dist/src/context/keys.d.ts +18 -2
  73. package/dist/src/context/keys.js +1 -1
  74. package/dist/src/discover/filesystem.d.ts +1 -1
  75. package/dist/src/discover/filesystem.js +1 -1
  76. package/dist/src/discover/manifest.d.ts +1 -1
  77. package/dist/src/discover/manifest.js +1 -1
  78. package/dist/src/evals/cli/eval.js +2 -2
  79. package/dist/src/evals/index.d.ts +2 -2
  80. package/dist/src/evals/reporters/index.d.ts +1 -1
  81. package/dist/src/evals/runner/artifacts.js +1 -1
  82. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  83. package/dist/src/evals/runner/execute-eval.d.ts +5 -0
  84. package/dist/src/evals/runner/execute-eval.js +1 -1
  85. package/dist/src/evals/runner/execute-task.d.ts +3 -0
  86. package/dist/src/evals/runner/execute-task.js +1 -1
  87. package/dist/src/evals/runner/reporters/braintrust.js +1 -1
  88. package/dist/src/evals/runner/reporters/types.d.ts +28 -2
  89. package/dist/src/evals/runner/run-evals.js +1 -1
  90. package/dist/src/evals/session.d.ts +11 -2
  91. package/dist/src/evals/session.js +1 -1
  92. package/dist/src/evals/target.js +1 -1
  93. package/dist/src/evals/types.d.ts +10 -1
  94. package/dist/src/execution/dispatch-runtime-actions-step.d.ts +1 -5
  95. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  96. package/dist/src/execution/dispatch-turn-step.d.ts +5 -0
  97. package/dist/src/execution/dispatch-turn-step.js +1 -0
  98. package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +1 -0
  99. package/dist/src/execution/node-step.js +1 -1
  100. package/dist/src/execution/parked-delivery-wait.d.ts +1 -1
  101. package/dist/src/execution/parked-delivery-wait.js +1 -1
  102. package/dist/src/execution/remote-agent-dispatch.d.ts +2 -1
  103. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  104. package/dist/src/execution/route-child-delivery.d.ts +3 -4
  105. package/dist/src/execution/route-child-delivery.js +1 -1
  106. package/dist/src/execution/route-proxied-deliver-step.d.ts +34 -0
  107. package/dist/src/execution/route-proxied-deliver-step.js +1 -0
  108. package/dist/src/execution/runtime-context.js +1 -1
  109. package/dist/src/execution/session-command-inbox.d.ts +2 -2
  110. package/dist/src/execution/session-command-wire.js +1 -1
  111. package/dist/src/execution/session.js +1 -1
  112. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  113. package/dist/src/execution/subagent-adapter.js +1 -1
  114. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  115. package/dist/src/execution/tool-auth.d.ts +9 -0
  116. package/dist/src/execution/tool-auth.js +1 -1
  117. package/dist/src/execution/turn-control-receiver.js +1 -1
  118. package/dist/src/execution/turn-dispatch.js +1 -1
  119. package/dist/src/execution/turn-workflow.js +1 -1
  120. package/dist/src/execution/workflow-entry.js +1 -1
  121. package/dist/src/execution/workflow-runtime.js +1 -1
  122. package/dist/src/execution/workflow-steps.d.ts +1 -27
  123. package/dist/src/execution/workflow-steps.js +1 -1
  124. package/dist/src/execution/workflow-trace-context.d.ts +11 -0
  125. package/dist/src/execution/workflow-trace-context.js +1 -0
  126. package/dist/src/harness/ai-sdk-hook-bridge.d.ts +1 -1
  127. package/dist/src/harness/ai-sdk-hook-bridge.js +1 -1
  128. package/dist/src/harness/ai-sdk-telemetry.d.ts +19 -0
  129. package/dist/src/harness/ai-sdk-telemetry.js +1 -0
  130. package/dist/src/harness/approval-candidates.d.ts +109 -0
  131. package/dist/src/harness/approval-candidates.js +1 -0
  132. package/dist/src/harness/approval-delivery-coordinator.d.ts +39 -0
  133. package/dist/src/harness/approval-delivery-coordinator.js +1 -0
  134. package/dist/src/harness/authorization.d.ts +1 -0
  135. package/dist/src/harness/authorization.js +1 -1
  136. package/dist/src/harness/channel-delivery-instrumentation.d.ts +25 -0
  137. package/dist/src/harness/channel-delivery-instrumentation.js +1 -0
  138. package/dist/src/harness/emission.d.ts +2 -2
  139. package/dist/src/harness/emission.js +1 -1
  140. package/dist/src/harness/execute-tool.d.ts +1 -0
  141. package/dist/src/harness/hitl/approval-input-requests.js +1 -1
  142. package/dist/src/harness/hitl/pending-input-resolution.d.ts +3 -0
  143. package/dist/src/harness/hitl/pending-input-resolution.js +1 -1
  144. package/dist/src/harness/hitl/question-input-requests.js +1 -1
  145. package/dist/src/harness/hitl/session-limit-input-requests.js +1 -1
  146. package/dist/src/harness/input-extraction.js +1 -1
  147. package/dist/src/harness/input-request-resolution.d.ts +22 -0
  148. package/dist/src/harness/input-request-resolution.js +1 -0
  149. package/dist/src/harness/input-requests.d.ts +1 -0
  150. package/dist/src/harness/input-requests.js +1 -1
  151. package/dist/src/harness/{instrumentation-config.d.ts → instrumentation/config.d.ts} +9 -4
  152. package/dist/src/harness/instrumentation/config.js +1 -0
  153. package/dist/src/harness/instrumentation/content.d.ts +5 -0
  154. package/dist/src/harness/instrumentation/content.js +1 -0
  155. package/dist/src/harness/instrumentation/dispatch.d.ts +2 -0
  156. package/dist/src/harness/instrumentation/dispatch.js +1 -0
  157. package/dist/src/harness/instrumentation/lifecycle.d.ts +491 -0
  158. package/dist/src/harness/instrumentation/lifecycle.js +1 -0
  159. package/dist/src/harness/{instrumentation-native-events.d.ts → instrumentation/native-events.d.ts} +10 -1
  160. package/dist/src/harness/instrumentation/native-events.js +1 -0
  161. package/dist/src/harness/instrumentation/providers.d.ts +50 -0
  162. package/dist/src/harness/instrumentation/providers.js +1 -0
  163. package/dist/src/harness/{instrumentation-runtime.d.ts → instrumentation/runtime.d.ts} +7 -2
  164. package/dist/src/harness/{instrumentation-runtime.js → instrumentation/runtime.js} +1 -1
  165. package/dist/src/harness/instrumentation/setup-context.d.ts +12 -0
  166. package/dist/src/harness/instrumentation/setup-context.js +1 -0
  167. package/dist/src/harness/instrumentation/state.d.ts +59 -0
  168. package/dist/src/harness/instrumentation/state.js +1 -0
  169. package/dist/src/harness/messages.d.ts +2 -1
  170. package/dist/src/harness/messages.js +1 -1
  171. package/dist/src/harness/parent-lineage.d.ts +1 -1
  172. package/dist/src/harness/pending-input-batches.d.ts +2 -0
  173. package/dist/src/harness/pending-input-batches.js +1 -1
  174. package/dist/src/harness/prepare-trace-context.d.ts +16 -0
  175. package/dist/src/harness/prepare-trace-context.js +1 -0
  176. package/dist/src/harness/runtime-action-settlement-state.d.ts +3 -0
  177. package/dist/src/harness/runtime-action-settlement-state.js +1 -0
  178. package/dist/src/harness/runtime-actions.js +1 -1
  179. package/dist/src/harness/stale-input-responses.js +1 -1
  180. package/dist/src/harness/tool-call-action.d.ts +9 -0
  181. package/dist/src/harness/tool-call-action.js +1 -0
  182. package/dist/src/harness/tool-loop.js +2 -2
  183. package/dist/src/harness/tools.js +1 -1
  184. package/dist/src/harness/types.d.ts +16 -2
  185. package/dist/src/internal/application/compiled-artifacts.d.ts +13 -4
  186. package/dist/src/internal/application/compiled-artifacts.js +5 -4
  187. package/dist/src/internal/application/dev-environment.d.ts +12 -0
  188. package/dist/src/internal/application/dev-environment.js +1 -1
  189. package/dist/src/internal/application/package.js +1 -1
  190. package/dist/src/internal/authored-definition/approval.d.ts +3 -0
  191. package/dist/src/internal/authored-definition/approval.js +1 -0
  192. package/dist/src/internal/authored-definition/connection.js +1 -1
  193. package/dist/src/internal/authored-definition/core.d.ts +3 -3
  194. package/dist/src/internal/authored-definition/core.js +1 -1
  195. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  196. package/dist/src/internal/authored-package-boundary.js +1 -1
  197. package/dist/src/internal/helpers/markdown.js +1 -1
  198. package/dist/src/internal/instrumentation-layout.d.ts +28 -0
  199. package/dist/src/internal/instrumentation-layout.js +1 -0
  200. package/dist/src/internal/instrumentation.d.ts +1 -1
  201. package/dist/src/internal/materialized-authored-modules.d.ts +13 -2
  202. package/dist/src/internal/materialized-authored-modules.js +1 -1
  203. package/dist/src/internal/nitro/host/build-vercel-agent-summary.js +1 -1
  204. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  205. package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
  206. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.d.ts +5 -1
  207. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -1
  208. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  209. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +4 -3
  210. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  211. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  212. package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +2 -3
  213. package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
  214. package/dist/src/internal/vercel/project-link.d.ts +1 -1
  215. package/dist/src/internal/vercel/project-link.js +1 -1
  216. package/dist/src/internal/vercel-agent-summary.d.ts +10 -9
  217. package/dist/src/internal/vercel-agent-summary.js +1 -1
  218. package/dist/src/internal/workflow/development-world-client.js +1 -1
  219. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  220. package/dist/src/protocol/message.d.ts +51 -2
  221. package/dist/src/protocol/message.js +2 -2
  222. package/dist/src/protocol/traceparent.d.ts +10 -0
  223. package/dist/src/protocol/traceparent.js +1 -0
  224. package/dist/src/public/channels/eve.js +1 -1
  225. package/dist/src/public/channels/github/auth.d.ts +30 -0
  226. package/dist/src/public/channels/github/auth.js +2 -2
  227. package/dist/src/public/channels/github/defaults.d.ts +4 -3
  228. package/dist/src/public/channels/github/defaults.js +5 -2
  229. package/dist/src/public/channels/github/dispatch.d.ts +3 -2
  230. package/dist/src/public/channels/github/dispatch.js +1 -1
  231. package/dist/src/public/channels/github/githubChannel.d.ts +10 -5
  232. package/dist/src/public/channels/github/githubChannel.js +1 -1
  233. package/dist/src/public/channels/github/index.d.ts +1 -1
  234. package/dist/src/public/channels/slack/defaults.js +3 -3
  235. package/dist/src/public/channels/slack/interactions.js +1 -1
  236. package/dist/src/public/channels/slack/slackChannel.d.ts +11 -3
  237. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  238. package/dist/src/public/definitions/approval.d.ts +57 -16
  239. package/dist/src/public/definitions/approval.js +1 -1
  240. package/dist/src/public/definitions/channel.d.ts +2 -2
  241. package/dist/src/public/definitions/channel.js +1 -1
  242. package/dist/src/public/definitions/hook.d.ts +4 -2
  243. package/dist/src/public/definitions/instructions.d.ts +14 -4
  244. package/dist/src/public/definitions/instructions.js +1 -1
  245. package/dist/src/public/definitions/tool.d.ts +5 -8
  246. package/dist/src/public/instructions/index.d.ts +1 -2
  247. package/dist/src/public/instructions/index.js +1 -1
  248. package/dist/src/public/instrumentation/index.d.ts +36 -20
  249. package/dist/src/public/instrumentation/index.js +1 -1
  250. package/dist/src/public/instrumentation/otel.d.ts +32 -0
  251. package/dist/src/public/instrumentation/otel.js +1 -0
  252. package/dist/src/public/instrumentation/provider.d.ts +117 -0
  253. package/dist/src/public/instrumentation/provider.js +1 -0
  254. package/dist/src/public/tools/approval/approval-helpers.d.ts +4 -4
  255. package/dist/src/public/tools/index.d.ts +1 -1
  256. package/dist/src/runtime/actions/results.d.ts +3 -3
  257. package/dist/src/runtime/agent/bootstrap.d.ts +2 -0
  258. package/dist/src/runtime/agent/bootstrap.js +1 -1
  259. package/dist/src/runtime/attributes/emit.js +1 -1
  260. package/dist/src/runtime/connections/principal.d.ts +3 -0
  261. package/dist/src/runtime/connections/principal.js +1 -1
  262. package/dist/src/runtime/connections/scoped-authorization.d.ts +3 -5
  263. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  264. package/dist/src/runtime/connections/types.d.ts +5 -0
  265. package/dist/src/runtime/prompt/compose.d.ts +1 -1
  266. package/dist/src/runtime/prompt/compose.js +3 -1
  267. package/dist/src/runtime/resolve-agent.js +1 -1
  268. package/dist/src/runtime/resolve-tool.js +1 -1
  269. package/dist/src/runtime/types.d.ts +4 -3
  270. package/dist/src/setup/index.d.ts +1 -0
  271. package/dist/src/setup/index.js +1 -1
  272. package/dist/src/setup/project-resolution.d.ts +3 -3
  273. package/dist/src/setup/scaffold/create/project.js +1 -1
  274. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  275. package/dist/src/setup/slack-connect-lifecycle.d.ts +0 -9
  276. package/dist/src/setup/slack-connect-lifecycle.js +1 -1
  277. package/dist/src/setup/slackbot.d.ts +2 -1
  278. package/dist/src/setup/slackbot.js +1 -1
  279. package/dist/src/setup/verified-remote-agent.d.ts +30 -0
  280. package/dist/src/setup/verified-remote-agent.js +1 -0
  281. package/dist/src/shared/agent-definition.d.ts +9 -0
  282. package/dist/src/shared/channel-definition.d.ts +3 -1
  283. package/dist/src/shared/dynamic-tool-definition.d.ts +3 -4
  284. package/dist/src/shared/instructions-definition.d.ts +15 -11
  285. package/dist/src/svelte/index.js +1 -1
  286. package/dist/src/svelte/use-eve-agent.js +1 -1
  287. package/dist/src/tracing/agent-action-instrumentation.d.ts +31 -0
  288. package/dist/src/tracing/agent-action-instrumentation.js +1 -0
  289. package/dist/src/tracing/agent-approval-instrumentation.d.ts +13 -0
  290. package/dist/src/tracing/agent-approval-instrumentation.js +1 -0
  291. package/dist/src/tracing/agent-channel-delivery-instrumentation.d.ts +13 -0
  292. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -0
  293. package/dist/src/tracing/agent-otel-content.d.ts +6 -0
  294. package/dist/src/tracing/agent-otel-content.js +2 -2
  295. package/dist/src/tracing/agent-otel-provider.d.ts +10 -8
  296. package/dist/src/tracing/agent-otel-provider.js +2 -2
  297. package/dist/src/tracing/agent-otel-session-context.d.ts +17 -0
  298. package/dist/src/tracing/agent-otel-session-context.js +1 -0
  299. package/dist/src/tracing/agent-otel-usage.d.ts +4 -0
  300. package/dist/src/tracing/agent-otel-usage.js +1 -0
  301. package/dist/src/tracing/agent-span-id-generator.d.ts +2 -0
  302. package/dist/src/tracing/agent-span-id-generator.js +1 -1
  303. package/dist/src/tracing/agent-tool-instrumentation.d.ts +28 -0
  304. package/dist/src/tracing/agent-tool-instrumentation.js +1 -0
  305. package/dist/src/tracing/agent-trace-context-store.d.ts +8 -1
  306. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  307. package/dist/src/tracing/agent-trace-span-processor.d.ts +0 -1
  308. package/dist/src/tracing/agent-trace-span-processor.js +1 -1
  309. package/dist/src/tracing/agent-trace-state.d.ts +33 -3
  310. package/dist/src/tracing/agent-trace-state.js +1 -1
  311. package/dist/src/tracing/batch-span-processor.d.ts +20 -0
  312. package/dist/src/tracing/batch-span-processor.js +1 -0
  313. package/dist/src/tracing/content-attributes.d.ts +28 -0
  314. package/dist/src/tracing/content-attributes.js +1 -0
  315. package/dist/src/tracing/content-span-processor.d.ts +19 -0
  316. package/dist/src/tracing/content-span-processor.js +1 -0
  317. package/dist/src/tracing/install-instrumentation-runtime.d.ts +19 -0
  318. package/dist/src/tracing/install-instrumentation-runtime.js +1 -0
  319. package/dist/src/tracing/local-instrumentation-runtime.d.ts +1 -1
  320. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  321. package/dist/src/tracing/local-traces.d.ts +56 -0
  322. package/dist/src/tracing/local-traces.js +1 -0
  323. package/dist/src/tracing/otel-declaration.d.ts +150 -0
  324. package/dist/src/tracing/otel-declaration.js +1 -0
  325. package/dist/src/tracing/otel-registration.d.ts +21 -0
  326. package/dist/src/tracing/otel-registration.js +1 -0
  327. package/dist/src/tracing/vercel-runtime-span-exporter.d.ts +5 -0
  328. package/dist/src/tracing/vercel-runtime-span-exporter.js +1 -0
  329. package/dist/src/vue/index.js +1 -1
  330. package/dist/src/vue/use-eve-agent.js +1 -1
  331. package/docs/README.md +18 -20
  332. package/docs/agent-config.md +5 -5
  333. package/docs/channels/eve.mdx +10 -56
  334. package/docs/channels/github.mdx +1 -1
  335. package/docs/channels/meta.json +1 -0
  336. package/docs/concepts/context-control.md +32 -56
  337. package/docs/concepts/default-harness.md +2 -2
  338. package/docs/concepts/execution-model-and-durability.mdx +4 -4
  339. package/docs/concepts/meta.json +3 -1
  340. package/docs/concepts/sessions-runs-and-streaming.md +22 -10
  341. package/docs/{guides → concepts}/state.md +3 -3
  342. package/docs/connections/mcp.mdx +6 -89
  343. package/docs/connections/meta.json +1 -0
  344. package/docs/connections/openapi.mdx +5 -69
  345. package/docs/connections/overview.mdx +29 -3
  346. package/docs/evals/meta.json +1 -0
  347. package/docs/evals/reporters.mdx +14 -4
  348. package/docs/extensions.md +1 -1
  349. package/docs/getting-started.mdx +175 -13
  350. package/docs/guides/auth-and-route-protection.md +3 -18
  351. package/docs/guides/client/meta.json +2 -1
  352. package/docs/guides/client/output-schema.mdx +2 -2
  353. package/docs/guides/client/overview.mdx +1 -1
  354. package/docs/guides/deployment/meta.json +1 -0
  355. package/docs/guides/deployment/overview.md +1 -1
  356. package/docs/guides/deployment/self-hosting.md +3 -3
  357. package/docs/guides/deployment/vercel.mdx +1 -1
  358. package/docs/guides/dev-tui.md +3 -13
  359. package/docs/guides/dynamic-capabilities.md +26 -4
  360. package/docs/guides/frontend/meta.json +2 -1
  361. package/docs/guides/frontend/nextjs.mdx +1 -10
  362. package/docs/guides/frontend/nuxt.mdx +1 -10
  363. package/docs/guides/frontend/overview.mdx +12 -3
  364. package/docs/guides/frontend/sveltekit.mdx +1 -10
  365. package/docs/guides/frontend/use-eve-agent-svelte.mdx +39 -126
  366. package/docs/guides/frontend/use-eve-agent-vue.mdx +40 -139
  367. package/docs/guides/instrumentation.md +37 -15
  368. package/docs/guides/meta.json +1 -5
  369. package/docs/guides/remote-agents.md +9 -9
  370. package/docs/guides/session-context.md +34 -103
  371. package/docs/install-integrations.mdx +1 -1
  372. package/docs/instructions.mdx +45 -12
  373. package/docs/meta.json +24 -13
  374. package/docs/patterns/dynamic-scheduling.md +1 -1
  375. package/docs/patterns/meta.json +1 -0
  376. package/docs/patterns/multi-tenant-approvals.md +1 -1
  377. package/docs/patterns/multi-tenant-auth.md +1 -1
  378. package/docs/patterns/multi-tenant-memory.md +4 -3
  379. package/docs/{guides → protocols}/acp.md +1 -1
  380. package/docs/protocols/meta.json +5 -0
  381. package/docs/reference/cli.md +34 -34
  382. package/docs/reference/meta.json +1 -1
  383. package/docs/reference/typescript-api.md +4 -2
  384. package/docs/{subagents.mdx → subagents/index.mdx} +2 -2
  385. package/docs/subagents/meta.json +5 -0
  386. package/docs/{guides/dynamic-workflows.md → subagents/workflow-tool.md} +6 -6
  387. package/docs/tools/human-in-the-loop.md +1 -1
  388. package/docs/tools/meta.json +1 -0
  389. package/docs/tools/overview.mdx +1 -1
  390. package/docs/tutorial/connect-a-warehouse.mdx +1 -1
  391. package/docs/tutorial/meta.json +1 -0
  392. package/docs/tutorial/remember-definitions.mdx +2 -2
  393. package/docs/tutorial/ship-it.mdx +2 -2
  394. package/package.json +10 -4
  395. package/dist/src/compiled/_chunks/workflow/dist-C8PhDW9B.js +0 -1
  396. package/dist/src/compiled/_chunks/workflow/functions-xMPAeWFr.js +0 -1
  397. package/dist/src/compiled/_chunks/workflow/node-Smb57EnG.js +0 -40
  398. package/dist/src/compiled/_chunks/workflow/resume-hook-BrduAuFX.js +0 -1
  399. package/dist/src/compiled/_chunks/workflow/run-CX7_sJnW.js +0 -1
  400. package/dist/src/compiled/_chunks/workflow/sleep-tsb2HjWK.js +0 -1
  401. package/dist/src/compiled/_chunks/workflow/undici-BNc_0O4m.js +0 -95
  402. package/dist/src/compiled/_chunks/workflow/wait-until-BYKVqrwc.js +0 -15
  403. package/dist/src/harness/instrumentation-config.js +0 -1
  404. package/dist/src/harness/instrumentation-lifecycle.d.ts +0 -171
  405. package/dist/src/harness/instrumentation-lifecycle.js +0 -1
  406. package/dist/src/harness/instrumentation-native-events.js +0 -1
  407. package/dist/src/harness/otel-integration.d.ts +0 -12
  408. package/dist/src/harness/otel-integration.js +0 -1
  409. package/docs/installation.mdx +0 -66
  410. package/docs/project-structure.mdx +0 -53
  411. package/docs/reference/project-layout.md +0 -123
  412. /package/dist/src/harness/{instrumentation-runtime-context.d.ts → instrumentation/runtime-context.d.ts} +0 -0
  413. /package/dist/src/harness/{instrumentation-runtime-context.js → instrumentation/runtime-context.js} +0 -0
  414. /package/docs/{guides → protocols}/ucp.mdx +0 -0
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.58`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.33.3`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.58`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.35.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -1 +1 @@
1
- import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,join}from"node:path";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),TOKEN_SOURCES={[versionToken(`EVE_PACKAGE`)]:{kind:`eve-version`},[NODE_ENGINE_TOKEN]:{kind:`eve-node-engine`},[versionToken(`AI_SDK`)]:{kind:`catalog`,packageName:`ai`},[versionToken(`VERCEL_CONNECT`)]:{kind:`catalog`,packageName:`@vercel/connect`},[versionToken(`NEXT`)]:{kind:`catalog`,packageName:`next`},[versionToken(`REACT`)]:{kind:`catalog`,packageName:`react`},[versionToken(`REACT_DOM`)]:{kind:`catalog`,packageName:`react-dom`},[versionToken(`STREAMDOWN`)]:{kind:`catalog`,packageName:`streamdown`},[versionToken(`ZOD`)]:{kind:`catalog`,packageName:`zod`},[versionToken(`TYPESCRIPT`)]:{kind:`catalog`,packageName:`typescript`},[versionToken(`TYPES_REACT`)]:{kind:`catalog`,packageName:`@types/react`},[versionToken(`TYPES_REACT_DOM`)]:{kind:`catalog`,packageName:`@types/react-dom`}},resolvedTokens=new Map;function findEvePackageRoot(){let o=dirname(realpathSync(fileURLToPath(import.meta.url)));for(;;){let n=join(o,`package.json`);if(existsSync(n)&&JSON.parse(readFileSync(n,`utf8`)).name===`eve`)return o;let a=dirname(o);if(a===o)return;o=a}}function findWorkspaceManifest(t){let n=t;for(;;){let t=join(n,`pnpm-workspace.yaml`);if(existsSync(t))return t;let a=dirname(n);if(a===n)return;n=a}}function readCatalogVersion(e,n){let r=readFileSync(e,`utf8`).split(/\r?\n/),i=!1;for(let e of r){if(/^catalog:\s*$/.test(e)){i=!0;continue}if(!i)continue;if(/^\S/.test(e))break;let t=e.match(/^\s+(?:"([^"]+)"|([\w@/.-]+)):\s*"([^"]+)"/);if(t&&(t[1]??t[2])===n)return t[3]}}function resolveTokenFromDevTree(n){let r=TOKEN_SOURCES[n];if(r!==void 0)try{let n=findEvePackageRoot();if(n===void 0||!existsSync(join(n,`scripts/stamp-version-tokens.mjs`)))return;if(r.kind===`eve-version`){let e=JSON.parse(readFileSync(join(n,`package.json`),`utf8`));return typeof e.version==`string`?e.version:void 0}if(r.kind===`eve-node-engine`){let e=JSON.parse(readFileSync(join(n,`package.json`),`utf8`)).engines?.node;return typeof e==`string`?e:void 0}let a=findWorkspaceManifest(n);return a===void 0?void 0:readCatalogVersion(a,r.packageName)}catch{return}}function resolveVersionToken(e,t){if(!t.startsWith(`__`))return t;let n=resolvedTokens.get(t);if(n!==void 0)return n;let r=resolveTokenFromDevTree(t);if(r===void 0)throw Error(`Scaffold received unstamped version token (${e}=${t}). Build eve before using its dist entrypoint.`);return resolvedTokens.set(t,r),r}export{resolveVersionToken};
1
+ import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,join}from"node:path";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),TOKEN_SOURCES={[versionToken(`EVE_PACKAGE`)]:{kind:`eve-version`},[versionToken(`EVE_PACKAGE_DEPENDENCY`)]:{kind:`eve-version`},[NODE_ENGINE_TOKEN]:{kind:`eve-node-engine`},[versionToken(`AI_SDK`)]:{kind:`catalog`,packageName:`ai`},[versionToken(`VERCEL_CONNECT`)]:{kind:`catalog`,packageName:`@vercel/connect`},[versionToken(`NEXT`)]:{kind:`catalog`,packageName:`next`},[versionToken(`REACT`)]:{kind:`catalog`,packageName:`react`},[versionToken(`REACT_DOM`)]:{kind:`catalog`,packageName:`react-dom`},[versionToken(`STREAMDOWN`)]:{kind:`catalog`,packageName:`streamdown`},[versionToken(`ZOD`)]:{kind:`catalog`,packageName:`zod`},[versionToken(`TYPESCRIPT`)]:{kind:`catalog`,packageName:`typescript`},[versionToken(`TYPES_REACT`)]:{kind:`catalog`,packageName:`@types/react`},[versionToken(`TYPES_REACT_DOM`)]:{kind:`catalog`,packageName:`@types/react-dom`}},resolvedTokens=new Map;function findEvePackageRoot(){let o=dirname(realpathSync(fileURLToPath(import.meta.url)));for(;;){let n=join(o,`package.json`);if(existsSync(n)&&JSON.parse(readFileSync(n,`utf8`)).name===`eve`)return o;let a=dirname(o);if(a===o)return;o=a}}function findWorkspaceManifest(t){let n=t;for(;;){let t=join(n,`pnpm-workspace.yaml`);if(existsSync(t))return t;let a=dirname(n);if(a===n)return;n=a}}function readCatalogVersion(e,n){let r=readFileSync(e,`utf8`).split(/\r?\n/),i=!1;for(let e of r){if(/^catalog:\s*$/.test(e)){i=!0;continue}if(!i)continue;if(/^\S/.test(e))break;let t=e.match(/^\s+(?:"([^"]+)"|([\w@/.-]+)):\s*"([^"]+)"/);if(t&&(t[1]??t[2])===n)return t[3]}}function resolveTokenFromDevTree(n){let r=TOKEN_SOURCES[n];if(r!==void 0)try{let n=findEvePackageRoot();if(n===void 0||!existsSync(join(n,`scripts/stamp-version-tokens.mjs`)))return;if(r.kind===`eve-version`){let e=JSON.parse(readFileSync(join(n,`package.json`),`utf8`));return typeof e.version==`string`?e.version:void 0}if(r.kind===`eve-node-engine`){let e=JSON.parse(readFileSync(join(n,`package.json`),`utf8`)).engines?.node;return typeof e==`string`?e:void 0}let a=findWorkspaceManifest(n);return a===void 0?void 0:readCatalogVersion(a,r.packageName)}catch{return}}function resolveVersionToken(e,t){if(!t.startsWith(`__`))return t;let n=resolvedTokens.get(t);if(n!==void 0)return n;let r=resolveTokenFromDevTree(t);if(r===void 0)throw Error(`Scaffold received unstamped version token (${e}=${t}). Build eve before using its dist entrypoint.`);return resolvedTokens.set(t,r),r}export{resolveVersionToken};
@@ -1,13 +1,8 @@
1
1
  import { type ConnectTriggerAttachmentResult } from "#setup/connect-provisioning.js";
2
2
  import { createPromptCommandOutput, type ChannelSetupLog } from "#setup/cli/index.js";
3
3
  import { captureVercel, runVercel } from "#setup/primitives/run-vercel.js";
4
- import { z } from "zod";
5
4
  import { type RawSlackConnector, type SlackConnectorDetails, type SlackConnectorRef, type SlackWorkspaceConnection } from "./slack-connect.js";
6
5
  export declare const CONNECT_LOOKUP_TIMEOUT_MS = 60000;
7
- declare const VercelProjectLinkSchema: z.ZodObject<{
8
- projectId: z.ZodString;
9
- orgId: z.ZodString;
10
- }, z.core.$strip>;
11
6
  /** Connect subprocess operations needed to inventory and remove Slack connectors. */
12
7
  export interface SlackConnectLifecycleDeps {
13
8
  captureVercel: typeof captureVercel;
@@ -37,10 +32,6 @@ export interface SlackConnectorCleanupContext {
37
32
  }
38
33
  /** Reads and validates the account-level Slack connector inventory. */
39
34
  export declare function listSlackConnectors(deps: SlackConnectLifecycleDeps, projectRoot: string, onOutput: CommandOutput, signal?: AbortSignal): Promise<SlackConnectorInventory>;
40
- /** Project and team identifiers from a valid on-disk Vercel link. */
41
- export type VercelProjectLink = z.infer<typeof VercelProjectLinkSchema>;
42
- /** Reads the linked Vercel project and team ids from `.vercel/project.json`. */
43
- export declare function readProjectLink(projectRoot: string): Promise<VercelProjectLink | undefined>;
44
35
  export type SlackConnectorLookup = {
45
36
  state: "found";
46
37
  connectors: readonly SlackConnectorRef[];
@@ -1 +1 @@
1
- import{object,string}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{parseSlackConnectorDetails,parseSlackConnectors}from"./slack-connect.js";import{readFile}from"node:fs/promises";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import"#setup/primitives/run-vercel.js";import"#setup/cli/index.js";import{CONNECT_MUTATION_TIMEOUT_MS,replaceConnectTrigger}from"#setup/connect-provisioning.js";const CONNECT_LOOKUP_TIMEOUT_MS=6e4,VercelProjectLinkSchema=object({projectId:string().min(1),orgId:string().min(1)});async function listSlackConnectors(e,t,n,i){let a=await e.captureVercel([`connect`,`list`,`-F`,`json`,`--all-projects`],{cwd:t,onOutput:n,timeoutMs:CONNECT_LOOKUP_TIMEOUT_MS,signal:i});if(!a.ok)return{state:`failed`,message:a.failure.message};try{let e=JSON.parse(a.stdout);if(typeof e!=`object`||!e)return{state:`failed`,message:`Vercel returned a malformed connector list.`};let t=e;return Array.isArray(t.connectors??t.clients)?{state:`ok`,body:e,connectors:parseSlackConnectors(e)}:{state:`failed`,message:`Vercel returned a malformed connector list.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the connector list.`}}}async function readProjectLink(e){try{let t=await readFile(join(e,`.vercel`,`project.json`),`utf8`),n=VercelProjectLinkSchema.safeParse(JSON.parse(t));return n.success?n.data:void 0}catch{return}}async function findSlackConnector(e,t,n,r,i,a){let o=await listSlackConnectors(e,t,i,a);if(o.state===`failed`)return o;let s=new Set(o.connectors.map(e=>e.uid));if(n===void 0)return{state:`not-found`,connectorUids:s};let c=o.connectors.filter(e=>e.id!==void 0&&e.projectIds.includes(n)).sort((e,t)=>t.createdAt-e.createdAt).map(({uid:e,id:t})=>({uid:e,id:t}));if(c.length===0)return{state:`not-found`,connectorUids:s};let l=c.find(e=>e.uid===r);return l===void 0?{state:`found`,connectors:c,connectorUids:s}:{state:`found`,connectors:c,preferred:l,connectorUids:s}}async function attachSlackConnector(e,t,n,r,i){return replaceConnectTrigger({connectorUid:n.uid,projectRoot:t,triggerPath:SLACK_CHANNEL_DEFAULT_ROUTE,onOutput:r,signal:i,deps:e})}async function fetchSlackConnectorDetails(e){let t=e.orgId===void 0?``:`?teamId=${encodeURIComponent(e.orgId)}`,r=[`api`,`/v1/connect/connectors/${encodeURIComponent(e.connectorId)}${t}`];e.orgId!==void 0&&r.push(`--scope`,e.orgId);let i=await e.deps.captureVercel(r,{cwd:e.projectRoot,onOutput:e.onOutput,timeoutMs:e.timeoutMs,signal:e.signal});if(!i.ok)return{state:`failed`,message:i.failure.message};try{let t=parseSlackConnectorDetails(JSON.parse(i.stdout));return t?.ref.id===e.connectorId?{state:`found`,details:t}:{state:`failed`,message:`Vercel returned an invalid Slack connector.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the Slack connector.`}}}async function fetchSlackWorkspace(e){let t=await fetchSlackConnectorDetails(e);return t.state===`failed`?t:t.details.workspace===void 0?{state:`pending`}:{state:`connected`,workspace:t.details.workspace}}async function cleanupConnectorUid(e,t){let{log:n,deps:r,projectRoot:i,onOutput:a}=e;return await r.runVercel([`connect`,`remove`,t,`--disconnect-all`,`--yes`],{cwd:i,onOutput:a,timeoutMs:CONNECT_MUTATION_TIMEOUT_MS})?!0:(n.warning(`Could not remove the abandoned Slack connector. Run \`vercel connect remove ${t} --disconnect-all --yes\` to clean it up.`),!1)}async function cleanupConnectorUids(e,t){let n=[];for(let r of new Set(t))await cleanupConnectorUid(e,r)||n.push(r);return n.length===0?{state:`clean`}:{state:`failed`,connectorUids:n}}async function cleanupCreatedAttempt(e,t){if(t.createdRef)return cleanupConnectorUids(e,[t.createdRef.uid]);e.log.warning(`Vercel returned no connector UID for the abandoned Slack Connect request, so eve cannot prove that request was cancelled. No connector was removed; do not retry until the browser request is no longer usable.`);let n=await listSlackConnectors(e.deps,e.projectRoot,e.onOutput);return n.state===`failed`?{state:`failed`,connectorUids:[]}:{state:`failed`,connectorUids:n.connectors.map(e=>e.uid).filter(e=>(e===t.expectedUid||e.startsWith(`${t.expectedUid}-`))&&!t.baselineConnectorUids.has(e))}}export{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackConnectorDetails,fetchSlackWorkspace,findSlackConnector,listSlackConnectors,readProjectLink};
1
+ import{parseSlackConnectorDetails,parseSlackConnectors}from"./slack-connect.js";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import"#setup/primitives/run-vercel.js";import"#setup/cli/index.js";import{CONNECT_MUTATION_TIMEOUT_MS,replaceConnectTrigger}from"#setup/connect-provisioning.js";const CONNECT_LOOKUP_TIMEOUT_MS=6e4;async function listSlackConnectors(e,n,r,i){let o=await e.captureVercel([`connect`,`list`,`-F`,`json`,`--all-projects`],{cwd:n,onOutput:r,timeoutMs:CONNECT_LOOKUP_TIMEOUT_MS,signal:i});if(!o.ok)return{state:`failed`,message:o.failure.message};try{let e=JSON.parse(o.stdout);if(typeof e!=`object`||!e)return{state:`failed`,message:`Vercel returned a malformed connector list.`};let n=e;return Array.isArray(n.connectors??n.clients)?{state:`ok`,body:e,connectors:parseSlackConnectors(e)}:{state:`failed`,message:`Vercel returned a malformed connector list.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the connector list.`}}}async function findSlackConnector(e,t,n,r,i,a){let o=await listSlackConnectors(e,t,i,a);if(o.state===`failed`)return o;let s=new Set(o.connectors.map(e=>e.uid));if(n===void 0)return{state:`not-found`,connectorUids:s};let c=o.connectors.filter(e=>e.id!==void 0&&e.projectIds.includes(n)).sort((e,t)=>t.createdAt-e.createdAt).map(({uid:e,id:t})=>({uid:e,id:t}));if(c.length===0)return{state:`not-found`,connectorUids:s};let l=c.find(e=>e.uid===r);return l===void 0?{state:`found`,connectors:c,connectorUids:s}:{state:`found`,connectors:c,preferred:l,connectorUids:s}}async function attachSlackConnector(e,t,r,a,o){return replaceConnectTrigger({connectorUid:r.uid,projectRoot:t,triggerPath:SLACK_CHANNEL_DEFAULT_ROUTE,onOutput:a,signal:o,deps:e})}async function fetchSlackConnectorDetails(t){let n=t.orgId===void 0?``:`?teamId=${encodeURIComponent(t.orgId)}`,r=[`api`,`/v1/connect/connectors/${encodeURIComponent(t.connectorId)}${n}`];t.orgId!==void 0&&r.push(`--scope`,t.orgId);let i=await t.deps.captureVercel(r,{cwd:t.projectRoot,onOutput:t.onOutput,timeoutMs:t.timeoutMs,signal:t.signal});if(!i.ok)return{state:`failed`,message:i.failure.message};try{let n=parseSlackConnectorDetails(JSON.parse(i.stdout));return n?.ref.id===t.connectorId?{state:`found`,details:n}:{state:`failed`,message:`Vercel returned an invalid Slack connector.`}}catch{return{state:`failed`,message:`Vercel returned invalid JSON for the Slack connector.`}}}async function fetchSlackWorkspace(e){let t=await fetchSlackConnectorDetails(e);return t.state===`failed`?t:t.details.workspace===void 0?{state:`pending`}:{state:`connected`,workspace:t.details.workspace}}async function cleanupConnectorUid(e,t){let{log:n,deps:i,projectRoot:a,onOutput:o}=e;return await i.runVercel([`connect`,`remove`,t,`--disconnect-all`,`--yes`],{cwd:a,onOutput:o,timeoutMs:CONNECT_MUTATION_TIMEOUT_MS})?!0:(n.warning(`Could not remove the abandoned Slack connector. Run \`vercel connect remove ${t} --disconnect-all --yes\` to clean it up.`),!1)}async function cleanupConnectorUids(e,t){let n=[];for(let r of new Set(t))await cleanupConnectorUid(e,r)||n.push(r);return n.length===0?{state:`clean`}:{state:`failed`,connectorUids:n}}async function cleanupCreatedAttempt(e,t){if(t.createdRef)return cleanupConnectorUids(e,[t.createdRef.uid]);e.log.warning(`Vercel returned no connector UID for the abandoned Slack Connect request, so eve cannot prove that request was cancelled. No connector was removed; do not retry until the browser request is no longer usable.`);let n=await listSlackConnectors(e.deps,e.projectRoot,e.onOutput);return n.state===`failed`?{state:`failed`,connectorUids:[]}:{state:`failed`,connectorUids:n.connectors.map(e=>e.uid).filter(e=>(e===t.expectedUid||e.startsWith(`${t.expectedUid}-`))&&!t.baselineConnectorUids.has(e))}}export{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackConnectorDetails,fetchSlackWorkspace,findSlackConnector,listSlackConnectors};
@@ -1,7 +1,8 @@
1
+ import { readProjectLink } from "#setup/project-resolution.js";
1
2
  import { type ChannelSetupAwaitChoice, type ChannelSetupLog } from "#setup/cli/index.js";
2
3
  import type { SlackConnectorRef } from "./slack-connect.js";
3
4
  import { type SlackConnectorCreateDeps } from "./slack-connect-create.js";
4
- import { readProjectLink, type SlackConnectLifecycleDeps, type SlackConnectorLookup } from "./slack-connect-lifecycle.js";
5
+ import { type SlackConnectLifecycleDeps, type SlackConnectorLookup } from "./slack-connect-lifecycle.js";
5
6
  export { parseCreatedSlackConnector, parseSlackConnectorDetails, pickSlackConnector, type SlackConnectorRef, } from "./slack-connect.js";
6
7
  /** Injected for tests; defaults to the real Vercel CLI subprocess primitives. */
7
8
  export interface SlackbotProvisionDeps extends SlackConnectLifecycleDeps, SlackConnectorCreateDeps {
@@ -1 +1 @@
1
- import{parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector}from"./slack-connect.js";import{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackWorkspace,findSlackConnector,listSlackConnectors,readProjectLink}from"./slack-connect-lifecycle.js";import{createSlackConnector}from"./slack-connect-create.js";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import{performance}from"node:perf_hooks";import{captureVercel,runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{setTimeout}from"node:timers/promises";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{updateSlackChannelConnectorUid}from"#setup/scaffold/update/update-slack-channel.js";const defaultDeps={captureVercel,runVercel,runVercelCaptureStdout},realDelay=(e,t)=>setTimeout(e,void 0,{signal:t}),monotonicNow=()=>performance.now();async function pollSlackWorkspace(e,t,n,i,a,s){let c=e.delay??realDelay,l=e.now??monotonicNow,u=l()+3e5;for(;;){s?.throwIfAborted();let d=u-l();if(d<=0)return{state:`timed-out`};let f=await fetchSlackWorkspace({deps:e,projectRoot:t,connectorId:n,orgId:i,onOutput:a,timeoutMs:Math.min(CONNECT_LOOKUP_TIMEOUT_MS,d),signal:s});if(s?.throwIfAborted(),f.state!==`pending`)return f;let p=u-l();if(p<=0)return{state:`timed-out`};await c(Math.min(3e3,p),s)}}function isAbortFromSignal(e,t){return t?.aborted===!0&&(e===t.reason||e instanceof Error&&e.name===`AbortError`)}function cleanupFailureResult(e){return{state:`cleanup-failed`,connectorUids:e.connectorUids}}async function runAttempt(e){let{log:t,deps:n,projectRoot:r,orgId:a,onOutput:o,signal:s,phase:c}=e,l,d;if(e.source.state===`existing`)l=e.source.ref;else{let i=await createSlackConnector({deps:n,projectRoot:r,orgId:a,slug:e.slug,onOutput:o,signal:s,phase:c,onCreated:e.onCreated,waitForWorkspace:async(e,t)=>{let i=await pollSlackWorkspace(n,r,e.id,a,o,t);return i.state===`connected`?i.workspace:void 0}});if(i.state===`failed`)return{state:`create-failed`};if(i.state===`unresolved`)return t.warning(`Vercel did not return an exact Slack connector UID for this request, so eve cannot attach or remove it safely.`),{state:`unresolved`};l=i.ref,i.via===`workspace`&&(d=i.workspace)}if(e.source.state===`existing`&&d===void 0){let e=await c(`Waiting for the Slack workspace connection...`,()=>pollSlackWorkspace(n,r,l.id,a,o,s));if(e.state===`timed-out`)return{state:`timed-out`,ref:l};if(e.state===`failed`)return{state:`failed`,ref:l,message:e.message};d=e.workspace}let f=await c(`Configuring Slack event delivery for this agent...`,()=>attachSlackConnector(n,r,l,o,s));return s?.throwIfAborted(),f.state===`attached`?d===void 0?{state:`attached`,ref:l}:{state:`attached`,ref:l,workspace:d}:{state:f.state,ref:l}}async function raceAttemptAgainstChoice(e){let t=new AbortController,n=e.outerSignal?AbortSignal.any([e.outerSignal,t.signal]):t.signal,r=e.run(n);try{let i=await Promise.race([r.then(e=>({via:`work`,outcome:e})),e.prompt.choice.then(e=>({via:`choice`,choice:e}))]);if(i.via===`work`)return i;t.abort();let a;try{a=await r}catch(e){if(!isAbortFromSignal(e,n))throw e}return{via:`choice`,choice:i.choice,settled:a}}catch(e){t.abort();try{await r}catch{}throw e}finally{e.prompt.close()}}async function inspectSlackbotConnectors(e,t,n,r,i=defaultDeps){let a=await findSlackConnector(i,t,(await(i.readProjectLink??readProjectLink)(t))?.projectId,`slack/${n}`,createPromptCommandOutput(e),r);if(a.state===`failed`)throw Error(a.message);return a}async function provisionSlackbot(e,t,n,r=defaultDeps,i={}){i.signal?.throwIfAborted();let o=createPromptCommandOutput(e),u={log:e,deps:r,projectRoot:t,onOutput:o},d=await(r.readProjectLink??readProjectLink)(t),p=d?.projectId,m=d?.orgId,h=`slack/${n}`,g=await withPhase(e,`Checking for an existing Slackbot...`,()=>findSlackConnector(r,t,p,h,o,i.signal));if(i.signal?.throwIfAborted(),g.state===`failed`)return e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${g.message}`),{state:`connector-lookup-failed`};if(p===void 0&&g.connectorUids.size>0)return e.warning("Could not verify which Slack connectors belong to this Vercel project, so eve did not create another one. Restore `.vercel/project.json`, then try again."),{state:`connector-lookup-failed`};let finishOutcome=async(t,n,r)=>{let i=n.state===`new`;switch(t.state){case`create-failed`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`unresolved`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`detach-failed`:return e.warning(`Could not remove the connector's existing trigger destination. Run \`vercel connect detach ${t.ref.uid} --yes\`, then \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\`.`),{state:`detach-failed`,connectorUid:t.ref.uid};case`attach-failed`:return e.warning(`Could not register this project as a trigger destination. Run \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\` to enable event delivery.`),{state:`attach-failed`,connectorUid:t.ref.uid};case`attached`:return t.workspace===void 0?{state:`attached`,connectorUid:t.ref.uid}:{state:`attached`,connectorUid:t.ref.uid,chatUrl:t.workspace.workspaceUrl,workspaceName:t.workspace.workspaceName};case`failed`:return e.warning(`Could not verify the Slack workspace connection. ${t.message}`),{state:`installation-check-failed`,connectorUid:t.ref.uid};case`timed-out`:if(e.warning(`The Slackbot did not connect to a Slack workspace in time.`),i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`not-installed`}}},cleanupNewAttempt=async(e,t)=>cleanupCreatedAttempt(u,{expectedUid:h,baselineConnectorUids:e.baselineConnectorUids,createdRef:t});function attemptInput(i,a){return{log:e,deps:r,projectRoot:t,orgId:m,slug:n,source:i,onOutput:o,onCreated:a}}async function runExistingConnector(t){let cleanupCurrentAttempt=async()=>({state:`clean`}),notInstalled=()=>(e.warning(`The existing Slack connector \`${t.ref.uid}\` is not connected to a Slack workspace. eve did not remove it because this run did not create it. If its original browser request is still open, complete it; otherwise run \`vercel connect remove ${t.ref.uid} --disconnect-all --yes\` before trying again.`),{state:`existing-not-installed`,connectorUid:t.ref.uid}),finishExistingOutcome=async e=>e.state===`timed-out`?notInstalled():finishOutcome(e,t,cleanupCurrentAttempt);if(i.awaitChoice!==void 0){let e=await raceAttemptAgainstChoice({prompt:i.awaitChoice({status:`Waiting for the existing Slack workspace connection...`,context:`Complete the original setup in the browser`,actions:[{value:`cancel`,label:`Stop waiting`}]}),outerSignal:i.signal,run:e=>runAttempt({...attemptInput(t,()=>{}),signal:e,phase:(e,t)=>t()})});return e.via===`work`?finishExistingOutcome(e.outcome):e.settled?.state===`attached`?finishExistingOutcome(e.settled):notInstalled()}return finishExistingOutcome(await runAttempt({...attemptInput(t,()=>{}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)}))}async function runUncontrolledAttempt(t){let n,cleanupCurrentAttempt=()=>cleanupNewAttempt(t,n),r=runAttempt({...attemptInput(t,e=>{n=e}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)});try{return await finishOutcome(await r,t,cleanupCurrentAttempt)}catch(e){throw i.signal?.aborted===!0&&await cleanupCurrentAttempt(),e}}async function runInteractiveAttempt(n,a){let s,cleanupCurrentAttempt=()=>cleanupNewAttempt(n,s),l=a({status:`Waiting for Slack setup to finish...`,context:`Complete setup in the browser, then wait while eve verifies the connection`,actions:[{value:`retry`,label:`Did your browser not open? Try again`},{value:`cancel`,label:`Cancel`}]}),u;try{u=await raceAttemptAgainstChoice({prompt:l,outerSignal:i.signal,run:t=>runAttempt({...attemptInput(n,e=>{s=e}),signal:t,phase:e.spinner===void 0?(e,t)=>t():(t,n)=>withPhase(e,t,n)})})}catch(e){throw await cleanupCurrentAttempt(),e}if(u.via===`work`)return{state:`finished`,result:await finishOutcome(u.outcome,n,cleanupCurrentAttempt)};if(u.settled?.state===`attached`)return{state:`finished`,result:await finishOutcome(u.settled,n,cleanupCurrentAttempt)};let d=await cleanupCurrentAttempt();if(d.state===`failed`)return{state:`finished`,result:cleanupFailureResult(d)};if(u.choice===`retry`){let n=await withPhase(e,`Checking existing Slack connectors...`,()=>listSlackConnectors(r,t,o,i.signal));return i.signal?.throwIfAborted(),n.state===`failed`?(e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${n.message}`),{state:`finished`,result:{state:`connector-lookup-failed`}}):{state:`retry`,source:{state:`new`,baselineConnectorUids:new Set(n.connectors.map(e=>e.uid))}}}return{state:`finished`,result:{state:`cancelled`}}}if(g.state===`found`){let e=i.selectConnector===void 0?g.preferred??g.connectors[0]:await i.selectConnector(g.connectors,g.preferred);if(i.signal?.throwIfAborted(),e!==`create`)return runExistingConnector({state:`existing`,ref:e})}let _={state:`new`,baselineConnectorUids:g.connectorUids};if(i.awaitChoice===void 0)return runUncontrolledAttempt(_);for(;;){let e=await runInteractiveAttempt(_,i.awaitChoice);if(e.state===`finished`)return e.result;_=e.source}}async function reconcileSlackUid(e,t,n,r){if(n.state!==`attached`||n.connectorUid===r)return!0;let{patched:i}=await updateSlackChannelConnectorUid(join(t,`agent/channels/slack.ts`),n.connectorUid);return i?!0:(e.warning(`Could not patch agent/channels/slack.ts automatically. Update \`connectSlackCredentials("...")\` to \`"${n.connectorUid}"\` and run \`vercel deploy --prod\`.`),!1)}export{inspectSlackbotConnectors,parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector,provisionSlackbot,reconcileSlackUid};
1
+ import{parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector}from"./slack-connect.js";import{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackWorkspace,findSlackConnector,listSlackConnectors}from"./slack-connect-lifecycle.js";import{createSlackConnector}from"./slack-connect-create.js";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import{performance}from"node:perf_hooks";import{readProjectLink}from"#setup/project-resolution.js";import{captureVercel,runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{setTimeout}from"node:timers/promises";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{updateSlackChannelConnectorUid}from"#setup/scaffold/update/update-slack-channel.js";const defaultDeps={captureVercel,runVercel,runVercelCaptureStdout},realDelay=(e,t)=>setTimeout(e,void 0,{signal:t}),monotonicNow=()=>performance.now();async function pollSlackWorkspace(e,t,n,i,a,s){let c=e.delay??realDelay,l=e.now??monotonicNow,u=l()+3e5;for(;;){s?.throwIfAborted();let d=u-l();if(d<=0)return{state:`timed-out`};let f=await fetchSlackWorkspace({deps:e,projectRoot:t,connectorId:n,orgId:i,onOutput:a,timeoutMs:Math.min(CONNECT_LOOKUP_TIMEOUT_MS,d),signal:s});if(s?.throwIfAborted(),f.state!==`pending`)return f;let p=u-l();if(p<=0)return{state:`timed-out`};await c(Math.min(3e3,p),s)}}function isAbortFromSignal(e,t){return t?.aborted===!0&&(e===t.reason||e instanceof Error&&e.name===`AbortError`)}function cleanupFailureResult(e){return{state:`cleanup-failed`,connectorUids:e.connectorUids}}async function runAttempt(e){let{log:t,deps:n,projectRoot:r,orgId:a,onOutput:o,signal:s,phase:c}=e,u,d;if(e.source.state===`existing`)u=e.source.ref;else{let i=await createSlackConnector({deps:n,projectRoot:r,orgId:a,slug:e.slug,onOutput:o,signal:s,phase:c,onCreated:e.onCreated,waitForWorkspace:async(e,t)=>{let i=await pollSlackWorkspace(n,r,e.id,a,o,t);return i.state===`connected`?i.workspace:void 0}});if(i.state===`failed`)return{state:`create-failed`};if(i.state===`unresolved`)return t.warning(`Vercel did not return an exact Slack connector UID for this request, so eve cannot attach or remove it safely.`),{state:`unresolved`};u=i.ref,i.via===`workspace`&&(d=i.workspace)}if(e.source.state===`existing`&&d===void 0){let e=await c(`Waiting for the Slack workspace connection...`,()=>pollSlackWorkspace(n,r,u.id,a,o,s));if(e.state===`timed-out`)return{state:`timed-out`,ref:u};if(e.state===`failed`)return{state:`failed`,ref:u,message:e.message};d=e.workspace}let f=await c(`Configuring Slack event delivery for this agent...`,()=>attachSlackConnector(n,r,u,o,s));return s?.throwIfAborted(),f.state===`attached`?d===void 0?{state:`attached`,ref:u}:{state:`attached`,ref:u,workspace:d}:{state:f.state,ref:u}}async function raceAttemptAgainstChoice(e){let t=new AbortController,n=e.outerSignal?AbortSignal.any([e.outerSignal,t.signal]):t.signal,r=e.run(n);try{let i=await Promise.race([r.then(e=>({via:`work`,outcome:e})),e.prompt.choice.then(e=>({via:`choice`,choice:e}))]);if(i.via===`work`)return i;t.abort();let a;try{a=await r}catch(e){if(!isAbortFromSignal(e,n))throw e}return{via:`choice`,choice:i.choice,settled:a}}catch(e){t.abort();try{await r}catch{}throw e}finally{e.prompt.close()}}async function inspectSlackbotConnectors(e,t,n,r,i=defaultDeps){let a=await findSlackConnector(i,t,(await(i.readProjectLink??readProjectLink)(t))?.projectId,`slack/${n}`,createPromptCommandOutput(e),r);if(a.state===`failed`)throw Error(a.message);return a}async function provisionSlackbot(e,t,n,r=defaultDeps,i={}){i.signal?.throwIfAborted();let o=createPromptCommandOutput(e),l={log:e,deps:r,projectRoot:t,onOutput:o},u=await(r.readProjectLink??readProjectLink)(t),f=u?.projectId,m=u?.orgId,h=`slack/${n}`,g=await withPhase(e,`Checking for an existing Slackbot...`,()=>findSlackConnector(r,t,f,h,o,i.signal));if(i.signal?.throwIfAborted(),g.state===`failed`)return e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${g.message}`),{state:`connector-lookup-failed`};if(f===void 0&&g.connectorUids.size>0)return e.warning("Could not verify which Slack connectors belong to this Vercel project, so eve did not create another one. Restore `.vercel/project.json`, then try again."),{state:`connector-lookup-failed`};let finishOutcome=async(t,n,r)=>{let i=n.state===`new`;switch(t.state){case`create-failed`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`unresolved`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`detach-failed`:return e.warning(`Could not remove the connector's existing trigger destination. Run \`vercel connect detach ${t.ref.uid} --yes\`, then \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\`.`),{state:`detach-failed`,connectorUid:t.ref.uid};case`attach-failed`:return e.warning(`Could not register this project as a trigger destination. Run \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\` to enable event delivery.`),{state:`attach-failed`,connectorUid:t.ref.uid};case`attached`:return t.workspace===void 0?{state:`attached`,connectorUid:t.ref.uid}:{state:`attached`,connectorUid:t.ref.uid,chatUrl:t.workspace.workspaceUrl,workspaceName:t.workspace.workspaceName};case`failed`:return e.warning(`Could not verify the Slack workspace connection. ${t.message}`),{state:`installation-check-failed`,connectorUid:t.ref.uid};case`timed-out`:if(e.warning(`The Slackbot did not connect to a Slack workspace in time.`),i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`not-installed`}}},cleanupNewAttempt=async(e,t)=>cleanupCreatedAttempt(l,{expectedUid:h,baselineConnectorUids:e.baselineConnectorUids,createdRef:t});function attemptInput(i,a){return{log:e,deps:r,projectRoot:t,orgId:m,slug:n,source:i,onOutput:o,onCreated:a}}async function runExistingConnector(t){let cleanupCurrentAttempt=async()=>({state:`clean`}),notInstalled=()=>(e.warning(`The existing Slack connector \`${t.ref.uid}\` is not connected to a Slack workspace. eve did not remove it because this run did not create it. If its original browser request is still open, complete it; otherwise run \`vercel connect remove ${t.ref.uid} --disconnect-all --yes\` before trying again.`),{state:`existing-not-installed`,connectorUid:t.ref.uid}),finishExistingOutcome=async e=>e.state===`timed-out`?notInstalled():finishOutcome(e,t,cleanupCurrentAttempt);if(i.awaitChoice!==void 0){let e=await raceAttemptAgainstChoice({prompt:i.awaitChoice({status:`Waiting for the existing Slack workspace connection...`,context:`Complete the original setup in the browser`,actions:[{value:`cancel`,label:`Stop waiting`}]}),outerSignal:i.signal,run:e=>runAttempt({...attemptInput(t,()=>{}),signal:e,phase:(e,t)=>t()})});return e.via===`work`?finishExistingOutcome(e.outcome):e.settled?.state===`attached`?finishExistingOutcome(e.settled):notInstalled()}return finishExistingOutcome(await runAttempt({...attemptInput(t,()=>{}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)}))}async function runUncontrolledAttempt(t){let n,cleanupCurrentAttempt=()=>cleanupNewAttempt(t,n),r=runAttempt({...attemptInput(t,e=>{n=e}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)});try{return await finishOutcome(await r,t,cleanupCurrentAttempt)}catch(e){throw i.signal?.aborted===!0&&await cleanupCurrentAttempt(),e}}async function runInteractiveAttempt(n,a){let s,cleanupCurrentAttempt=()=>cleanupNewAttempt(n,s),l=a({status:`Waiting for Slack setup to finish...`,context:`Complete setup in the browser, then wait while eve verifies the connection`,actions:[{value:`retry`,label:`Did your browser not open? Try again`},{value:`cancel`,label:`Cancel`}]}),u;try{u=await raceAttemptAgainstChoice({prompt:l,outerSignal:i.signal,run:t=>runAttempt({...attemptInput(n,e=>{s=e}),signal:t,phase:e.spinner===void 0?(e,t)=>t():(t,n)=>withPhase(e,t,n)})})}catch(e){throw await cleanupCurrentAttempt(),e}if(u.via===`work`)return{state:`finished`,result:await finishOutcome(u.outcome,n,cleanupCurrentAttempt)};if(u.settled?.state===`attached`)return{state:`finished`,result:await finishOutcome(u.settled,n,cleanupCurrentAttempt)};let d=await cleanupCurrentAttempt();if(d.state===`failed`)return{state:`finished`,result:cleanupFailureResult(d)};if(u.choice===`retry`){let n=await withPhase(e,`Checking existing Slack connectors...`,()=>listSlackConnectors(r,t,o,i.signal));return i.signal?.throwIfAborted(),n.state===`failed`?(e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${n.message}`),{state:`finished`,result:{state:`connector-lookup-failed`}}):{state:`retry`,source:{state:`new`,baselineConnectorUids:new Set(n.connectors.map(e=>e.uid))}}}return{state:`finished`,result:{state:`cancelled`}}}if(g.state===`found`){let e=i.selectConnector===void 0?g.preferred??g.connectors[0]:await i.selectConnector(g.connectors,g.preferred);if(i.signal?.throwIfAborted(),e!==`create`)return runExistingConnector({state:`existing`,ref:e})}let _={state:`new`,baselineConnectorUids:g.connectorUids};if(i.awaitChoice===void 0)return runUncontrolledAttempt(_);for(;;){let e=await runInteractiveAttempt(_,i.awaitChoice);if(e.state===`finished`)return e.result;_=e.source}}async function reconcileSlackUid(e,t,n,r){if(n.state!==`attached`||n.connectorUid===r)return!0;let{patched:i}=await updateSlackChannelConnectorUid(join(t,`agent/channels/slack.ts`),n.connectorUid);return i?!0:(e.warning(`Could not patch agent/channels/slack.ts automatically. Update \`connectSlackCredentials("...")\` to \`"${n.connectorUid}"\` and run \`vercel deploy --prod\`.`),!1)}export{inspectSlackbotConnectors,parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector,provisionSlackbot,reconcileSlackUid};
@@ -0,0 +1,30 @@
1
+ import { Client, type AgentInfoResult, type ClientOptions } from "#client/index.js";
2
+ import { type RemoteAuthFlow } from "#cli/dev/tui/remote-auth.js";
3
+ import type { Prompter } from "#setup/prompter.js";
4
+ import { resolveVerifiedRemoteDevelopmentClient, type VerifiedRemoteDevelopmentClient } from "#setup/verified-remote-client.js";
5
+ /** Result of inspecting an authenticated remote eve agent. */
6
+ export interface VerifiedRemoteAgentInspection {
7
+ readonly info: AgentInfoResult;
8
+ /** Verified Vercel scope to retain when reconnecting to the same deployment. */
9
+ readonly vercelScope?: string;
10
+ }
11
+ /** @internal Dependencies for testing verified remote inspection. */
12
+ export interface InspectVerifiedRemoteAgentDeps {
13
+ readonly createClient: (options: ClientOptions) => Pick<Client, "info">;
14
+ readonly resolveVerifiedRemoteDevelopmentClient: (input: Parameters<typeof resolveVerifiedRemoteDevelopmentClient>[0]) => Promise<VerifiedRemoteDevelopmentClient>;
15
+ readonly runRemoteAuthFlow: RemoteAuthFlow;
16
+ }
17
+ /**
18
+ * Inspects a remote eve agent using the same exact-origin credential boundary
19
+ * as remote development clients. When a verified Vercel target needs login or
20
+ * Trusted Sources configuration, an optional prompter completes that flow
21
+ * before inspection is retried.
22
+ */
23
+ export declare function inspectVerifiedRemoteAgent(input: {
24
+ readonly serverUrl: string;
25
+ readonly workspaceRoot: string;
26
+ readonly prompter?: Prompter;
27
+ readonly signal?: AbortSignal;
28
+ /** @internal Test seam. */
29
+ readonly deps?: Partial<InspectVerifiedRemoteAgentDeps>;
30
+ }): Promise<VerifiedRemoteAgentInspection>;
@@ -0,0 +1 @@
1
+ import{Client,ClientError}from"#client/index.js";import{WizardCancelledError}from"#setup/step.js";import{resolveVerifiedRemoteDevelopmentClient}from"#setup/verified-remote-client.js";import{runRemoteAuthFlow}from"#cli/dev/tui/remote-auth.js";const defaultDeps={createClient:t=>new Client(t),resolveVerifiedRemoteDevelopmentClient,runRemoteAuthFlow};async function inspectVerifiedRemoteAgent(e){let t={...defaultDeps,...e.deps},n=await t.resolveVerifiedRemoteDevelopmentClient({serverUrl:e.serverUrl,signal:e.signal,workspaceRoot:e.workspaceRoot});try{return inspection(await t.createClient(n.options).info(),verifiedScope(n))}catch(t){if(e.prompter===void 0||!isAuthenticationFailure(t)||!canAuthenticateInteractively(t,n))throw t}let r=await t.runRemoteAuthFlow({configureTrustedSources:!0,prompter:e.prompter,serverUrl:e.serverUrl,signal:e.signal,workspaceRoot:e.workspaceRoot});if(r.kind===`cancelled`)throw new WizardCancelledError;if(r.kind===`failed`)throw Error(r.message);let i={...n.options,auth:{vercelOidc:{token:r.resolveToken}},host:e.serverUrl,redirect:`manual`};return inspection(await t.createClient(i).info(),r.target.deployment.ownerId)}function inspection(e,t){return t===void 0?{info:e}:{info:e,vercelScope:t}}function verifiedScope(e){let t=e.deploymentResolution;return t?.kind===`resolved`?t.target.deployment.ownerId:void 0}function isAuthenticationFailure(e){return e instanceof ClientError&&(e.status>=300&&e.status<400||e.status===401||e.status===403)}function canAuthenticateInteractively(e,t){return e.status>=300&&e.status<400&&(e.headers.location??``).includes(`vercel.com/sso-api`)?!0:t.deploymentResolution?.kind===`resolved`||t.deploymentResolution?.kind===`forbidden`}export{inspectVerifiedRemoteAgent};
@@ -164,6 +164,15 @@ export interface AgentLimitsDefinition {
164
164
  * These options are unstable and may change or be removed in any release.
165
165
  */
166
166
  export interface AgentExperimentalDefinition {
167
+ /**
168
+ * Reads instrumentation from an `instrumentation/` directory of providers
169
+ * rather than a single `agent/instrumentation.ts` config object.
170
+ *
171
+ * The two layouts are mutually exclusive: with this on, an
172
+ * `agent/instrumentation.ts` is a build error, and with it off, an
173
+ * `instrumentation/` directory is.
174
+ */
175
+ readonly instrumentationProviders?: boolean;
167
176
  /**
168
177
  * Keeps this agent's delegated subagent sessions alive after they answer.
169
178
  * The model can pass `agentId` to a subagent tool to continue a previous
@@ -3,7 +3,8 @@ import type { UserContent } from "ai";
3
3
  import type { ChannelReceiveContext } from "#channel/channel-operations.js";
4
4
  import type { RouteDefinition } from "#channel/routes.js";
5
5
  import type { Session, SessionHandle } from "#channel/session.js";
6
- import type { SessionAuthContext, TurnPolicy } from "#channel/types.js";
6
+ import type { DeliverPayload, SessionAuthContext, TurnPolicy } from "#channel/types.js";
7
+ import type { StepInput } from "#harness/types.js";
7
8
  /**
8
9
  * Enriched return shape from a channel's {@link ChannelAdapter.fetchFile}
9
10
  * function. Return a bare {@link Buffer} when only bytes are known, or
@@ -42,6 +43,7 @@ export interface GenericReceiveInput<TReceiveTarget = Record<string, unknown>> {
42
43
  export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
43
44
  /** Policy used by message sends that do not provide an explicit override. */
44
45
  readonly turnPolicy?: TurnPolicy;
46
+ deliver?(payload: DeliverPayload, ctx: TCtx): StepInput | void | Promise<StepInput | void>;
45
47
  readonly state?: TState;
46
48
  /**
47
49
  * CORS policy for this channel's HTTP routes. `true` enables H3/Nitro's
@@ -13,14 +13,13 @@ export type DynamicToolEventName = Extract<UnstampedMessageStreamEvent["type"],
13
13
  export declare const ALLOWED_DYNAMIC_TOOL_EVENTS: ReadonlySet<string>;
14
14
  /**
15
15
  * Instructions and skills are restricted to session/turn boundaries.
16
- * They feed the system prompt, the most cache-sensitive position in the
17
- * wire format; keeping them stable across steps within a turn maximizes
18
- * cache hits.
16
+ * Keeping their resolved context stable within a turn avoids changing the
17
+ * model input between tool-loop steps.
19
18
  */
20
19
  export declare const ALLOWED_DYNAMIC_INSTRUCTION_EVENTS: ReadonlySet<string>;
21
20
  export declare const ALLOWED_DYNAMIC_SKILL_EVENTS: ReadonlySet<string>;
22
21
  /**
23
- * Context passed to a dynamic resolver's event handler (tools and skills).
22
+ * Context passed to a dynamic resolver's event handler.
24
23
  *
25
24
  * Exposes read-only session identity, auth, and channel metadata. State
26
25
  * is not exposed here; resolvers read it through `defineState` handles or
@@ -6,21 +6,25 @@
6
6
  * `instructions.{ts,cts,mts,js,cjs,mjs}`, or inside the
7
7
  * `agent/instructions/` directory for multi-file setups. Module-backed
8
8
  * static instructions execute once at build time. The compiler captures
9
- * the resulting markdown into the compiled manifest.
10
- *
11
- * When used inside a `defineDynamic` handler, the runtime lowers the
12
- * returned markdown to `{ role: "system", content: markdown }`.
13
- * Instructions produce system messages only. Use channel `context` for
14
- * user-role messages.
9
+ * the resulting content into the compiled manifest.
15
10
  */
16
- export interface PublicInstructionsDefinition {
17
- markdown: string;
18
- }
11
+ export type PublicInstructionsDefinition = {
12
+ readonly content: string;
13
+ readonly role?: "system" | "user";
14
+ readonly markdown?: never;
15
+ } | {
16
+ /** @deprecated Use `content`. */
17
+ readonly markdown: string;
18
+ readonly content?: never;
19
+ readonly role?: never;
20
+ };
21
+ export type InstructionsRole = "system" | "user";
19
22
  /**
20
23
  * Internal definition for an instructions prompt authored in markdown or
21
24
  * TypeScript.
22
25
  */
23
26
  export interface InternalInstructionsDefinition {
24
- name: string;
25
- markdown: string;
27
+ readonly content: string;
28
+ readonly name: string;
29
+ readonly role: InstructionsRole;
26
30
  }
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-B-Hky2f4.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-COmP-H8R.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-B-Hky2f4.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-COmP-H8R.js";
2
2
 
3
3
  export { useEveAgent };
@@ -0,0 +1,31 @@
1
+ import { type Context, type SpanContext, type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
+ import type { InstrumentationActionStartedEvent, InstrumentationAttemptScope, InstrumentationProviderDefinition } from "#harness/instrumentation/lifecycle.js";
3
+ import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
4
+ import type { AgentTraceStateStore } from "#tracing/agent-trace-state.js";
5
+ export interface AgentActionInstrumentation {
6
+ readonly events: Pick<NonNullable<InstrumentationProviderDefinition["events"]>, "action.completed" | "action.failed" | "action.started">;
7
+ deleteForSession(sessionId: string): void | PromiseLike<void>;
8
+ deleteForTurn(sessionId: string, turnId: string): void | PromiseLike<void>;
9
+ failForAttempt(scope: InstrumentationAttemptScope, error: unknown): Promise<void>;
10
+ contextFor(sessionId: string, turnId: string, callId: string): Promise<AgentActionContext | undefined>;
11
+ }
12
+ export interface AgentActionContext {
13
+ readonly context: Context;
14
+ readonly spanContext: SpanContext;
15
+ }
16
+ /** Builds durable `agent.action` spans around eve's runtime dispatch boundary. */
17
+ export declare function createAgentActionInstrumentation(input: {
18
+ readonly frameworkVersion: string;
19
+ readonly idGenerator: AgentSpanIdGenerator;
20
+ readonly recordInputs: boolean;
21
+ readonly recordOutputs: boolean;
22
+ readonly resolveParent: (event: InstrumentationActionStartedEvent) => {
23
+ readonly context: Context;
24
+ readonly spanContext: SpanContext;
25
+ } | undefined | PromiseLike<{
26
+ readonly context: Context;
27
+ readonly spanContext: SpanContext;
28
+ } | undefined>;
29
+ readonly stateStore: AgentTraceStateStore;
30
+ readonly tracer: Tracer;
31
+ }): AgentActionInstrumentation;
@@ -0,0 +1 @@
1
+ import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{actionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";function createAgentActionInstrumentation(e){let t=new Map,onStarted=async n=>{let r=await e.resolveParent(n);if(r===void 0)return;let a=await e.stateStore.getAction(n.idempotencyKey)??{attemptIndex:n.scope.attemptIndex,callId:n.callId,inputAttribute:e.recordInputs?contentAttribute(n.input,!1):void 0,kind:n.kind,name:n.name,parent:{spanId:r.spanContext.spanId,traceFlags:r.spanContext.traceFlags,traceId:r.spanContext.traceId},rootSessionId:n.scope.rootSessionId??n.scope.sessionId,sessionId:n.scope.sessionId,spanId:e.idGenerator.deriveSpanId(`action:${n.idempotencyKey}`),startTimeMs:Date.now(),stepIndex:n.scope.stepIndex,turnId:n.scope.turnId};await e.stateStore.setAction(n.idempotencyKey,a);let o=t.get(n.scope.attemptId)??new Set;o.add(n.idempotencyKey),t.set(n.scope.attemptId,o)},onTerminal=async t=>{let n=await e.stateStore.getAction(t.idempotencyKey);if(n!==void 0)try{let r=startSpan(n);if(r.setAttribute(`agent.action.outcome`,t.outcome),t.type===`action.failed`)t.errorCode!==void 0&&(r.setAttribute(`agent.action.error.code`,t.errorCode),r.setAttribute(`error.type`,t.errorCode)),recordError(r,t.error);else if(t.output.type===`error`)recordError(r,t.output.error);else if(t.usage!==void 0&&setAgentUsage(r,t.usage),e.recordOutputs){let e=contentAttribute(t.output.output,!1);e!==void 0&&r.setAttribute(`gen_ai.tool.call.result`,e)}r.end(t.acceptedAtMs)}finally{await e.stateStore.deleteAction(t.idempotencyKey),forget(t.idempotencyKey)}},startSpan=t=>{let n=e.idGenerator.withSpanId(t.spanId,()=>e.tracer.startSpan(`agent.action`,{attributes:{"agent.action.call_id":t.callId,"agent.action.kind":t.kind,"agent.action.name":t.name,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.rootSessionId,"agent.session.id":t.sessionId,"agent.step.attempt":t.attemptIndex,"agent.step.index":t.stepIndex,"agent.turn.id":t.turnId},startTime:t.startTimeMs},contextFromActionState(t)));return t.inputAttribute!==void 0&&n.setAttribute(`gen_ai.tool.call.arguments`,t.inputAttribute),n};return{async contextFor(t,n,i){let a=actionIdempotencyKey(t,n,i),o=await e.stateStore.getAction(a);if(o!==void 0)return actionContext(o);let s=await e.stateStore.findAction(t,i);return s===void 0?void 0:actionContext(s)},deleteForSession:t=>e.stateStore.deleteActions(t),deleteForTurn:(t,n)=>e.stateStore.deleteActions(t,n),async failForAttempt(n,r){let i=t.get(n.attemptId);if(i!==void 0){t.delete(n.attemptId);for(let t of i){let n=await e.stateStore.getAction(t);if(n===void 0)continue;let i=startSpan(n);recordError(i,r),i.end(),await e.stateStore.deleteAction(t)}}},events:{"action.completed":onTerminal,"action.failed":onTerminal,"action.started":onStarted}};function forget(e){for(let[n,r]of t)r.delete(e),r.size===0&&t.delete(n)}}function actionContext(t){let r={isRemote:!1,spanId:t.spanId,traceFlags:t.parent.traceFlags,traceId:t.parent.traceId};return{context:trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(r)),spanContext:r}}function contextFromActionState(t){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext({...t.parent,isRemote:!1}))}function recordError(e,n){n instanceof Error?(e.recordException(n),e.setStatus({code:SpanStatusCode.ERROR,message:n.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentActionInstrumentation};
@@ -0,0 +1,13 @@
1
+ import { type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
+ import type { InstrumentationProviderDefinition } from "#harness/instrumentation/lifecycle.js";
3
+ import type { AgentActionContext } from "#tracing/agent-action-instrumentation.js";
4
+ import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
5
+ /** Builds durable approval wait spans under their originating runtime action. */
6
+ export declare function createAgentApprovalInstrumentation(input: {
7
+ readonly actionContextFor: (sessionId: string, turnId: string, callId: string) => Promise<AgentActionContext | undefined>;
8
+ readonly frameworkVersion: string;
9
+ readonly idGenerator: AgentSpanIdGenerator;
10
+ readonly recordInputs: boolean;
11
+ readonly recordOutputs: boolean;
12
+ readonly tracer: Tracer;
13
+ }): Pick<NonNullable<InstrumentationProviderDefinition["events"]>, "input.requested" | "input.resolved">;
@@ -0,0 +1 @@
1
+ import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{contentAttribute}from"#tracing/agent-otel-content.js";function createAgentApprovalInstrumentation(t){return{"input.requested":async(e,n)=>{if(e.kind!==`tool-approval`||readState(n.state.get())!==void 0)return;let i=await t.actionContextFor(e.scope.sessionId,e.scope.turnId,e.action.callId);if(i===void 0)return;let a={actionCallId:e.action.callId,actionName:e.action.name,attemptIndex:e.scope.attemptIndex,parent:{spanId:i.spanContext.spanId,traceFlags:i.spanContext.traceFlags,traceId:i.spanContext.traceId},requestId:e.requestId,rootSessionId:e.scope.rootSessionId??e.scope.sessionId,sessionId:e.scope.sessionId,startTimeMs:Date.now(),stepIndex:e.scope.stepIndex,turnId:e.scope.turnId},o=t.recordInputs?contentAttribute(e.request,!1):void 0;o!==void 0&&(a.requestAttribute=o),n.state.set(a)},"input.resolved":(i,a)=>{let o=readState(a.state.get());if(o===void 0)return;let s=t.idGenerator.withSpanId(t.idGenerator.deriveSpanId(`approval:${i.idempotencyKey}`),()=>t.tracer.startSpan(`agent.approval`,{attributes:{"agent.action.call_id":o.actionCallId,"agent.action.name":o.actionName,"agent.approval.kind":`tool-approval`,"agent.approval.outcome":i.outcome,"agent.approval.request_id":o.requestId,"agent.framework.name":`eve`,"agent.framework.version":t.frameworkVersion,"agent.root.session.id":o.rootSessionId,"agent.session.id":o.sessionId,"agent.step.attempt":o.attemptIndex,"agent.step.index":o.stepIndex,"agent.turn.id":o.turnId},startTime:o.startTimeMs},trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext({...o.parent,isRemote:!1}))));if(o.requestAttribute!==void 0&&s.setAttribute(`agent.approval.request`,o.requestAttribute),t.recordOutputs&&i.response!==void 0){let e=contentAttribute(i.response,!1);e!==void 0&&s.setAttribute(`agent.approval.response`,e)}i.outcome===`failed`&&recordError(s,i.error),s.end()}}}function readState(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e,n=t.parent;if(typeof n!=`object`||!n||Array.isArray(n))return;let r=n;if(typeof t.actionCallId!=`string`||typeof t.actionName!=`string`||typeof t.attemptIndex!=`number`||typeof r.spanId!=`string`||typeof r.traceFlags!=`number`||typeof r.traceId!=`string`||typeof t.requestId!=`string`||typeof t.rootSessionId!=`string`||typeof t.sessionId!=`string`||typeof t.startTimeMs!=`number`||typeof t.stepIndex!=`number`||typeof t.turnId!=`string`)return;let i=t.requestAttribute;if(!(i!==void 0&&typeof i!=`string`))return{actionCallId:t.actionCallId,actionName:t.actionName,attemptIndex:t.attemptIndex,parent:{isRemote:!1,spanId:r.spanId,traceFlags:r.traceFlags,traceId:r.traceId},requestAttribute:i,requestId:t.requestId,rootSessionId:t.rootSessionId,sessionId:t.sessionId,startTimeMs:t.startTimeMs,stepIndex:t.stepIndex,turnId:t.turnId}}function recordError(e,n){n instanceof Error?(e.recordException(n),e.setStatus({code:SpanStatusCode.ERROR,message:n.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentApprovalInstrumentation};
@@ -0,0 +1,13 @@
1
+ import { type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
+ import type { InstrumentationProviderDefinition, InstrumentationSessionStartedEvent } from "#harness/instrumentation/lifecycle.js";
3
+ import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
4
+ import type { AgentSessionTraceState, AgentTraceStateStore } from "#tracing/agent-trace-state.js";
5
+ /** Builds durable channel delivery spans around the turn that consumes each request. */
6
+ export declare function createAgentChannelDeliveryInstrumentation(input: {
7
+ readonly ensureSessionContext: (event: InstrumentationSessionStartedEvent) => Promise<AgentSessionTraceState>;
8
+ readonly frameworkVersion: string;
9
+ readonly idGenerator: AgentSpanIdGenerator;
10
+ readonly recordInputs: boolean;
11
+ readonly stateStore: AgentTraceStateStore;
12
+ readonly tracer: Tracer;
13
+ }): Pick<NonNullable<InstrumentationProviderDefinition["events"]>, "channel.delivery.cancelled" | "channel.delivery.completed" | "channel.delivery.failed" | "channel.delivery.started">;
@@ -0,0 +1 @@
1
+ import{ROOT_CONTEXT,SpanKind,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute}from"#tracing/agent-otel-content.js";function createAgentChannelDeliveryInstrumentation(e){let onStarted=async(t,n)=>{let r=await e.ensureSessionContext({agentName:t.agentName,channelKind:t.delivery.channelKind,idempotencyKey:sessionIdempotencyKey(t.sessionId),parentTraceContext:t.parentTraceContext,rootSessionId:t.rootSessionId,sessionId:t.sessionId,type:`session.started`}),o=e.recordInputs?contentAttribute(t.input,!1):void 0,s={parent:{isRemote:r.context.isRemote??!1,spanId:r.context.spanId,traceFlags:r.context.traceFlags,traceId:r.context.traceId},spanId:e.idGenerator.deriveSpanId(`channel-delivery:${t.idempotencyKey}`),startTimeMs:Date.now(),window:r.window};o!==void 0&&(s.inputAttribute=o),t.delivery.requestTraceContext!==void 0&&(s.requestTraceContext={spanId:t.delivery.requestTraceContext.spanId,traceFlags:t.delivery.requestTraceContext.traceFlags,traceId:t.delivery.requestTraceContext.traceId}),n.state.set(s)},onTerminal=async(n,r)=>{let i=readState(r.state.get());if(i===void 0)return;let a=n.turnId===void 0?void 0:await e.stateStore.getTurn(n.sessionId,n.turnId),o=await e.stateStore.getSession(n.sessionId),s=a===void 0?i.parent:{isRemote:a.parentIsRemote??!1,spanId:a.parentSpanId,traceFlags:a.context.traceFlags,traceId:a.context.traceId},c=a===void 0?i.startTimeMs:Math.max(i.startTimeMs,a.startTimeMs),l=i.requestTraceContext,u=e.idGenerator.withSpanId(i.spanId,()=>e.tracer.startSpan(`agent.channel.delivery`,{attributes:{"agent.channel.delivery.id":n.delivery.deliveryId,"agent.channel.delivery.outcome":n.outcome,"agent.channel.kind":n.delivery.channelKind,"agent.channel.name":n.delivery.channelName,"agent.channel.request.id":n.delivery.requestId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":n.agentName,"agent.root.session.id":n.rootSessionId,"agent.session.id":n.sessionId,"agent.session.window":o?.window??i.window,"agent.turn.id":n.turnId,"agent.turn.sequence":n.sequence},kind:SpanKind.CONSUMER,links:l===void 0?void 0:[{attributes:{"eve.link.type":`channel.request`},context:l}],startTime:c},contextFromSpanContext(s)));if(u.addEvent(`channel.delivery.started`,void 0,c),u.addEvent(n.type),i.inputAttribute!==void 0&&u.setAttribute(`agent.channel.delivery.input`,i.inputAttribute),n.outcome===`failed`){let e=n.errorCode??(n.error instanceof Error?n.error.name:`Error`);u.setAttribute(`error.type`,e),n.errorCode!==void 0&&u.setAttribute(`agent.channel.delivery.error.code`,n.errorCode),recordError(u,n.error)}u.end()};return{"channel.delivery.cancelled":onTerminal,"channel.delivery.completed":onTerminal,"channel.delivery.failed":onTerminal,"channel.delivery.started":onStarted}}function readState(e){if(!isRecord(e)||!isSpanContext(e.parent)||typeof e.spanId!=`string`||typeof e.startTimeMs!=`number`||typeof e.window!=`number`)return;let t=isSpanContext(e.requestTraceContext)?e.requestTraceContext:void 0;return{inputAttribute:typeof e.inputAttribute==`string`?e.inputAttribute:void 0,parent:e.parent,requestTraceContext:t,spanId:e.spanId,startTimeMs:e.startTimeMs,window:e.window}}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)}function contextFromSpanContext(t){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(t))}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentChannelDeliveryInstrumentation};
@@ -19,6 +19,12 @@ export declare function contentAttribute(value: unknown, strip?: boolean): strin
19
19
  * the cap is truncated at the text level rather than the JSON level.
20
20
  */
21
21
  export declare function messagesContentAttribute(messages: unknown): string | undefined;
22
+ /** Serializes model messages using the OpenTelemetry GenAI message schema. */
23
+ export declare function genAiInputMessagesAttribute(messages: unknown): string | undefined;
24
+ /** Serializes the system prompt using the OpenTelemetry GenAI instruction schema. */
25
+ export declare function genAiSystemInstructionsAttribute(instructions: unknown): string | undefined;
26
+ /** Serializes one model response using the OpenTelemetry GenAI message schema. */
27
+ export declare function genAiOutputMessagesAttribute(content: readonly unknown[], finishReason: string): string | undefined;
22
28
  /**
23
29
  * Serializes provider-executed tool results, keeping the attribute valid
24
30
  * JSON under the cap: when the full payload is too big, each entry's input
@@ -1,4 +1,4 @@
1
- const CONTENT_ATTRIBUTE_LIMIT=32*1024,CONTENT_NOISE_KEYS=new Set([`providerOptions`,`providerMetadata`]),TRUNCATED_MESSAGES_KEY=`eve.truncated`;function contentAttribute(e,t=!0){if(e===void 0)return;let n=t?stripContentNoise(e,0):e,r;try{r=JSON.stringify(n)}catch{return}if(r!==void 0)return textContentAttribute(r)}function messagesContentAttribute(e){if(!Array.isArray(e))return contentAttribute(e);let t=stripContentNoise(e,0),r=stringifyContent(t);if(r!==void 0&&r.length<=32768)return r;for(let e=1;e<t.length;e+=1){let r=stringifyContent([{[TRUNCATED_MESSAGES_KEY]:{omittedMessages:e}},...t.slice(e)]);if(r!==void 0&&r.length<=32768)return r}return truncateSingleMessage(t)}function toolResultsContentAttribute(t){if(t.length===0)return;let n=stringifyContent(t);if(n!==void 0&&n.length<=32768)return n;for(let n=CONTENT_ATTRIBUTE_LIMIT;n>=0;n=n>=256?Math.floor(n/2):-1){let e=stringifyContent(t.map(e=>cappedToolResult(e,n)));if(e!==void 0&&e.length<=32768)return e}}function cappedToolResult(e,t){let n={toolName:e.toolName};for(let r of[`input`,`output`,`error`]){if(!(r in e))continue;let i=e[r],a=typeof i==`string`?i:stringifyContent(i)??``;n[r]=a.length<=t?a:`${a.slice(0,t)}… [truncated]`}return n}function systemPromptAttribute(e){if(typeof e==`string`)return textContentAttribute(e);if(!isRecord(e)&&!Array.isArray(e))return;let t=Array.isArray(e)?e:[e],n=[];for(let e of t)if(isRecord(e)){if(typeof e.content==`string`)n.push(e.content);else if(Array.isArray(e.content))for(let t of e.content)isRecord(t)&&t.type===`text`&&typeof t.text==`string`&&n.push(t.text)}let r=n.join(`
1
+ const CONTENT_ATTRIBUTE_LIMIT=32*1024,CONTENT_NOISE_KEYS=new Set([`providerOptions`,`providerMetadata`]),TRUNCATED_MESSAGES_KEY=`eve.truncated`;function contentAttribute(e,t=!0){if(e===void 0)return;let n=t?stripContentNoise(e,0):e,r;try{r=JSON.stringify(n)}catch{return}if(r!==void 0)return textContentAttribute(r)}function messagesContentAttribute(e){if(!Array.isArray(e))return contentAttribute(e);let t=stripContentNoise(e,0),r=stringifyContent(t);if(r!==void 0&&r.length<=32768)return r;for(let e=1;e<t.length;e+=1){let r=stringifyContent([{[TRUNCATED_MESSAGES_KEY]:{omittedMessages:e}},...t.slice(e)]);if(r!==void 0&&r.length<=32768)return r}return truncateSingleMessage(t)}function genAiInputMessagesAttribute(e){if(!Array.isArray(e))return;let t=e.flatMap(e=>{if(!isRecord(e)||e.role===`system`||typeof e.role!=`string`)return[];let t=semanticParts(e.content);return t.length===0?[]:[{parts:t,role:e.role}]});for(let e=0;e<t.length;e+=1){let n=semanticJsonAttribute(t.slice(e));if(n!==void 0)return n}return semanticJsonAttribute([])}function genAiSystemInstructionsAttribute(e){let t=systemPromptAttribute(e);return t===void 0?void 0:semanticJsonAttribute([{content:t,type:`text`}])}function genAiOutputMessagesAttribute(e,t){let n=semanticParts(e);return semanticJsonAttribute([{finish_reason:t===`tool-calls`?`tool_call`:t,parts:n,role:`assistant`}])}function toolResultsContentAttribute(t){if(t.length===0)return;let n=stringifyContent(t);if(n!==void 0&&n.length<=32768)return n;for(let n=CONTENT_ATTRIBUTE_LIMIT;n>=0;n=n>=256?Math.floor(n/2):-1){let e=stringifyContent(t.map(e=>cappedToolResult(e,n)));if(e!==void 0&&e.length<=32768)return e}}function cappedToolResult(e,t){let n={toolName:e.toolName};for(let r of[`input`,`output`,`error`]){if(!(r in e))continue;let i=e[r],a=typeof i==`string`?i:stringifyContent(i)??``;n[r]=a.length<=t?a:`${a.slice(0,t)}… [truncated]`}return n}function systemPromptAttribute(e){if(typeof e==`string`)return textContentAttribute(e);if(!isRecord(e)&&!Array.isArray(e))return;let t=Array.isArray(e)?e:[e],n=[];for(let e of t)if(isRecord(e)){if(typeof e.content==`string`)n.push(e.content);else if(Array.isArray(e.content))for(let t of e.content)isRecord(t)&&t.type===`text`&&typeof t.text==`string`&&n.push(t.text)}let r=n.join(`
2
2
 
3
3
  `).trim();return r.length===0?void 0:textContentAttribute(r)}function textContentAttribute(t){if(t.length!==0)return t.length<=32768?t:`${t.slice(0,CONTENT_ATTRIBUTE_LIMIT)}… [truncated]`}function stripContentNoise(e,n){if(n>32||typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(e=>stripContentNoise(e,n+1));let r={};for(let[i,a]of Object.entries(e))CONTENT_NOISE_KEYS.has(i)||(r[i]=stripContentNoise(a,n+1));return r}function truncateSingleMessage(t){if(t.length===0)return;let r=t[t.length-1];if(!isRecord(r))return;let i={[TRUNCATED_MESSAGES_KEY]:{omittedMessages:t.length-1}},a=typeof r.role==`string`?r.role:`user`,o=``;if(typeof r.content==`string`)o=r.content;else if(Array.isArray(r.content))for(let e of r.content)isRecord(e)&&e.type===`text`&&typeof e.text==`string`&&(o+=(o?`
4
- `:``)+e.text);for(let t=Math.min(o.length,CONTENT_ATTRIBUTE_LIMIT);t>0;t-=256){let e=stringifyContent([i,{role:a,content:t>=o.length?o:`${o.slice(0,t)}… [truncated]`}]);if(e!==void 0&&e.length<=32768)return e}return stringifyContent([i,{role:a,content:``}])}function stringifyContent(e){try{return JSON.stringify(e)}catch{return}}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{CONTENT_ATTRIBUTE_LIMIT,contentAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute};
4
+ `:``)+e.text);for(let t=Math.min(o.length,CONTENT_ATTRIBUTE_LIMIT);t>0;t-=256){let e=stringifyContent([i,{role:a,content:t>=o.length?o:`${o.slice(0,t)}… [truncated]`}]);if(e!==void 0&&e.length<=32768)return e}return stringifyContent([i,{role:a,content:``}])}function stringifyContent(e){try{return JSON.stringify(e)}catch{return}}function semanticJsonAttribute(e){let t=stringifyContent(e);return t!==void 0&&t.length<=32768?t:void 0}function semanticParts(e){if(typeof e==`string`)return[{content:e,type:`text`}];if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=semanticPart(n);e!==void 0&&t.push(e)}return t}function semanticPart(e){if(!(!isRecord(e)||typeof e.type!=`string`))switch(e.type){case`text`:case`reasoning`:{let t=typeof e.text==`string`?e.text:e.content;return typeof t==`string`?{content:t,type:e.type}:void 0}case`tool-call`:return{arguments:e.input,id:stringValue(e.toolCallId)??stringValue(e.callId)??null,name:e.toolName,type:`tool_call`};case`tool-result`:return{id:stringValue(e.toolCallId)??stringValue(e.callId)??null,response:toolResponse(e.output),type:`tool_call_response`};case`tool-error`:return{id:stringValue(e.toolCallId)??stringValue(e.callId)??null,response:e.error instanceof Error?e.error.message:e.error,type:`tool_call_response`};default:return{type:e.type}}}function toolResponse(e){return isRecord(e)?(e.type===`text`||e.type===`error-text`||e.type===`json`||e.type===`error-json`)&&`value`in e?e.value:e.type===`execution-denied`?{denied:!0,reason:e.reason}:e:e}function stringValue(e){return typeof e==`string`?e:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{CONTENT_ATTRIBUTE_LIMIT,contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute};
@@ -1,16 +1,16 @@
1
1
  import { type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
- import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
3
2
  import type { AgentTraceStateStore } from "#tracing/agent-trace-state.js";
4
- import type { InstrumentationContextRunner, InstrumentationProviderDefinition } from "#harness/instrumentation-lifecycle.js";
5
- /** Sized so an ordinary session stays one trace and only an outsized one rolls. */
6
- export declare const SESSION_WINDOW_TURN_LIMIT = 200;
3
+ import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
4
+ import type { InstrumentationContextRunner, InstrumentationProviderDefinition, InstrumentationSessionStartedEvent, InstrumentationTraceContext, InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.js";
7
5
  export interface AgentOtelInstrumentationInput {
8
6
  /**
9
- * Capture model prompts/responses and tool call inputs/outputs as span
10
- * attributes. Content stays on the local machine — this provider only
11
- * wires the dev-time local spool — but can be turned off per project.
7
+ * Whether to write model prompts and tool call inputs onto spans at all.
8
+ * This is the union across destinations, not one destination's policy: a
9
+ * destination that declined drops these on its way out instead.
12
10
  */
13
- readonly captureContent?: boolean;
11
+ readonly recordInputs?: boolean;
12
+ /** The same, for model responses and tool call outputs. */
13
+ readonly recordOutputs?: boolean;
14
14
  readonly frameworkVersion: string;
15
15
  readonly idGenerator: AgentSpanIdGenerator;
16
16
  readonly stateStore: AgentTraceStateStore;
@@ -19,6 +19,8 @@ export interface AgentOtelInstrumentationInput {
19
19
  /** OTel event definition and its trusted framework context runner. */
20
20
  export interface AgentOtelInstrumentation {
21
21
  readonly hook: InstrumentationProviderDefinition;
22
+ readonly prepareSessionTrace: (event: InstrumentationSessionStartedEvent) => Promise<InstrumentationTraceContext>;
23
+ readonly prepareTurnTrace: (event: InstrumentationTurnStartedEvent) => Promise<InstrumentationTraceContext>;
22
24
  readonly runInContext: InstrumentationContextRunner;
23
25
  }
24
26
  /** Creates OTel instrumentation for eve's structural `agent.*` convention. */
@@ -1,2 +1,2 @@
1
- import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{contentAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}from"#tracing/agent-otel-content.js";const SESSION_WINDOW_TURN_LIMIT=200;function createAgentOtelInstrumentation(e){let t=e.captureContent??!0,l=new WeakMap,u=new WeakMap,onSessionStarted=async e=>{await ensureSessionContext(e)},onTurnStarted=async t=>{let n=advanceSessionWindow(t.sessionId,await ensureSessionContext({agentName:void 0,channelKind:void 0,parentTraceContext:t.parentTraceContext,rootSessionId:t.rootSessionId,sessionId:t.sessionId,type:`session.started`})),r={isRemote:!1,spanId:e.idGenerator.allocateSpanId(),traceFlags:n.context.traceFlags,traceId:n.context.traceId};await e.stateStore.setSession(t.sessionId,{...n,turnsInWindow:n.turnsInWindow+1}),await e.stateStore.setTurn(t.sessionId,t.turnId,{context:r,lineage:t.parentLineage,parentSpanId:n.context.spanId,rootSessionId:t.rootSessionId,sequence:t.sequence,startTimeMs:Date.now()})},onAttemptStarted=async t=>{let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(n===void 0)return;let i=contextFromSpanContext(n.context),a=e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId}},i);a.addEvent(`step.started`);let o=trace.setSpan(i,a),s=t.operation.operationId,c=e.tracer.startSpan(s,{attributes:{"gen_ai.operation.name":s,"gen_ai.provider.name":t.operation.provider,"gen_ai.request.model":t.operation.modelId}},o);u.set(t.scope,{operation:{context:trace.setSpan(o,c),name:s,span:c},step:{context:o,span:a}})},onAttemptTerminal=e=>{l.delete(e.scope);let t=u.get(e.scope);t!==void 0&&(t.step.span.addEvent(e.type===`attempt.completed`?`step.completed`:`step.failed`),e.type===`attempt.failed`&&(recordError(t.operation.span,e.error),recordError(t.step.span,e.error)),t.operation.span.end(),t.step.span.end(),u.delete(e.scope))},onTurnTerminal=async t=>{let n=await e.stateStore.getTurn(t.sessionId,t.turnId);n!==void 0&&await e.stateStore.setTurn(t.sessionId,t.turnId,{...n,terminal:{error:t.error,type:t.type}})},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let r=await e.stateStore.getSession(t.sessionId),i=e.idGenerator.withSpanId(n.context.spanId,()=>e.tracer.startSpan(`agent.turn`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":r?.agentName,...parentLineageAttributes(n.lineage),"agent.root.session.id":n.rootSessionId,"agent.session.id":t.sessionId,"agent.session.window":r?.window,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence},startTime:n.startTimeMs},contextFromSpanContext({isRemote:!1,spanId:n.parentSpanId,traceFlags:n.context.traceFlags,traceId:n.context.traceId})));i.addEvent(`turn.started`,void 0,n.startTimeMs),n.terminal!==void 0&&(i.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(i,n.terminal.error)),i.addEvent(t.type),i.end(),await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&await e.stateStore.deleteSession(t.sessionId)},beforeModelCall=n=>{let i=u.get(n.scope);if(i===void 0)return;i.step.span.setAttribute(`agent.model.id`,n.source.modelId),i.step.span.setAttribute(`agent.model.provider`,n.source.provider);let s=e.tracer.startSpan(modelSpanName(i.operation.name),{attributes:{"gen_ai.operation.name":i.operation.name,"gen_ai.provider.name":n.source.provider,"gen_ai.request.model":n.source.modelId}},i.operation.context);if(t){let e=messagesContentAttribute(n.source.messages);e!==void 0&&s.setAttribute(`ai.prompt.messages`,e);let t=systemPromptAttribute(n.source.instructions);t!==void 0&&s.setAttribute(`ai.prompt.system`,t)}let c={context:trace.setSpan(i.operation.context,s),span:s};return getExecutionContexts(n.scope).models.set(n.id,c.context),c},afterModelCall=(e,n)=>{if(l.get(e.scope)?.models.delete(e.id),isSpanState(n)){if(e.type===`model.call.failed`)recordError(n.span,e.error);else{setUsage(n.span,e.source.usage);let r=u.get(e.scope);if(r!==void 0&&setUsage(r.step.span,e.source.usage),t){n.span.setAttribute(`ai.response.finish_reason`,e.source.finishReason);let t=textContentAttribute(e.source.content.filter(e=>e.type===`reasoning`).map(e=>e.text).filter(e=>e.trim().length>0).join(`
2
- `));t!==void 0&&n.span.setAttribute(`ai.response.reasoning`,t);let r=textContentAttribute(e.source.content.filter(e=>e.type===`text`).map(e=>e.text).join(``));r!==void 0&&n.span.setAttribute(`ai.response.text`,r);let a=e.source.content.filter(e=>e.type===`tool-call`).map(e=>({input:e.input,toolName:e.toolName}));if(a.length>0){let e=contentAttribute(a,!1);e!==void 0&&n.span.setAttribute(`ai.response.tool_calls`,e)}let o=e.source.content.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{input:e.input,output:e.output,toolName:e.toolName}:{error:errorText(e.error),input:e.input,toolName:e.toolName});if(o.length>0){let e=toolResultsContentAttribute(o);e!==void 0&&n.span.setAttribute(`ai.response.tool_results`,e)}}}n.span.end()}},beforeToolCall=n=>{let a=u.get(n.scope);if(a===void 0)return;let o=e.tracer.startSpan(`agent.action`,{attributes:{"agent.action.call_id":n.source.toolCall.toolCallId,"agent.action.kind":`tool`,"agent.action.name":n.source.toolCall.toolName,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":n.scope.rootSessionId??n.scope.sessionId,"agent.session.id":n.scope.sessionId,"agent.step.attempt":n.scope.attemptIndex,"agent.step.index":n.scope.stepIndex,"agent.turn.id":n.scope.turnId}},a.step.context),s=trace.setSpan(a.step.context,o),c=e.tracer.startSpan(`ai.toolCall`,{attributes:{"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":n.source.toolCall.toolCallId,"gen_ai.tool.name":n.source.toolCall.toolName}},s);if(t){let e=contentAttribute(n.source.toolCall.input,!1);e!==void 0&&c.setAttribute(`gen_ai.tool.call.arguments`,e)}let l={context:trace.setSpan(s,c),span:o,toolSpan:c};return getExecutionContexts(n.scope).tools.set(n.id,l.context),l},afterToolCall=(e,n)=>{if(l.get(e.scope)?.tools.delete(e.id),isToolSpanState(n)){if(e.type===`tool.call.failed`)recordError(n.toolSpan,e.error),recordError(n.span,e.error);else if(e.source.toolOutput.type!==`tool-result`)recordError(n.toolSpan,e.source.toolOutput.error),recordError(n.span,e.source.toolOutput.error);else if(t){let t=contentAttribute(e.source.toolOutput.output,!1);t!==void 0&&n.toolSpan.setAttribute(`gen_ai.tool.call.result`,t)}n.toolSpan.end(),n.span.end()}},openSessionWindow=t=>{let n=e.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":t.agentName,"agent.root.session.id":t.rootSessionId,"agent.session.id":t.sessionId,"agent.session.window":t.index,...t.previousTraceId===void 0?{}:{"agent.session.window.previous.trace.id":t.previousTraceId}},root:!0});return n.addEvent(t.index===0?`session.started`:`session.window.opened`),n.end(),n.spanContext()},ensureSessionContext=async t=>{let n=await e.stateStore.getSession(t.sessionId);return n===void 0&&(n={agentName:t.agentName,channelKind:t.channelKind,context:t.parentTraceContext===void 0?openSessionWindow({agentName:t.agentName,index:0,rootSessionId:t.rootSessionId,sessionId:t.sessionId}):adoptedSpanContext(t.parentTraceContext),rootSessionId:t.rootSessionId,turnsInWindow:0,window:0},await e.stateStore.setSession(t.sessionId,n)),n},advanceSessionWindow=(e,t)=>{if(t.turnsInWindow<200)return t;let n=t.window+1;return{...t,context:openSessionWindow({agentName:t.agentName,index:n,previousTraceId:t.context.traceId,rootSessionId:t.rootSessionId,sessionId:e}),turnsInWindow:0,window:n}};return{hook:{events:{"attempt.completed":onAttemptTerminal,"attempt.failed":onAttemptTerminal,"attempt.metadata":e=>{let t=u.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.step.span.setAttribute(e,r)},"attempt.started":onAttemptStarted,"model.call":{after:afterModelCall,before:beforeModelCall},"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,"tool.call":{after:afterToolCall,before:beforeToolCall},"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted}},runInContext(e,t){let r=l.get(e.scope),i=e.type===`model.call`?r?.models.get(e.id):r?.tools.get(e.id);return i===void 0?t():context.with(i,t)}};function getExecutionContexts(e){let t=l.get(e);return t===void 0&&(t={models:new Map,tools:new Map},l.set(e,t)),t}}function parentLineageAttributes(e){if(e===void 0)return{};let t={"agent.parent.call_id":e.callId,"agent.parent.session.id":e.sessionId,"agent.parent.turn.id":e.turnId};return e.subagentName!==void 0&&(t[`agent.subagent.name`]=e.subagentName),t}function adoptedSpanContext(e){return{isRemote:!1,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function contextFromSpanContext(t){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(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 isSpanState(e){return typeof e==`object`&&!!e&&`context`in e&&`span`in e}function isToolSpanState(e){return isSpanState(e)&&`toolSpan`in e}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function modelSpanName(e){return e===`ai.generateText`?`ai.generateText.doGenerate`:`ai.streamText.doStream`}function setUsage(e,t){t.inputTokens!==void 0&&e.setAttribute(`agent.usage.input_tokens`,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(`agent.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_creation.input_tokens`,n.cacheWriteTokens)}function errorText(e){return e instanceof Error?e.message:e}function recordError(e,n){n instanceof Error?(e.recordException(n),e.setStatus({code:SpanStatusCode.ERROR,message:n.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{SESSION_WINDOW_TURN_LIMIT,createAgentOtelInstrumentation};
1
+ import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";import{createAgentActionInstrumentation}from"#tracing/agent-action-instrumentation.js";import{createAgentApprovalInstrumentation}from"#tracing/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/agent-channel-delivery-instrumentation.js";import{createAgentToolInstrumentation}from"#tracing/agent-tool-instrumentation.js";import{createAgentOtelSessionContext}from"#tracing/agent-otel-session-context.js";function createAgentOtelInstrumentation(e){let t=e.recordInputs??!1,d=e.recordOutputs??!1,f=new WeakMap,p=new Map,m=new WeakMap,h=new WeakMap,g=createAgentActionInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:d,resolveParent:async t=>{let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);return n===void 0?void 0:{context:contextFromSpanContext(n.context),spanContext:n.context}},stateStore:e.stateStore,tracer:e.tracer}),_=createAgentApprovalInstrumentation({actionContextFor:g.contextFor,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:d,tracer:e.tracer}),v=createAgentToolInstrumentation({actionContextFor:g.contextFor,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:d,resolveFallback:e=>{let t=p.get(e.scope.attemptId)??e.scope,n=m.get(t)?.step;return n===void 0?void 0:{context:n.context,spanContext:n.span.spanContext()}},tracer:e.tracer}),{ensureSessionContext:y,prepareSessionTrace:b,prepareTurnTrace:x}=createAgentOtelSessionContext(e),onSessionStarted=async e=>{await b(e)},onTurnStarted=async e=>{await x(e)},onStepStarted=async t=>{let i=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(i===void 0)return;let a=contextFromSpanContext(i.context),o=trace.getSpan(context.active())?.spanContext(),s=e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId},links:o===void 0||o.traceId===i.context.traceId?void 0:[{attributes:{"eve.link.type":`workflow.delivery`},context:o}]},a);s.addEvent(`step.started`);let c=trace.setSpan(a,s),l=t.operation.operationId,u=e.tracer.startSpan(l,{attributes:{"ai.operation.name":l,"ai.provider.name":t.operation.provider,"ai.request.model":t.operation.modelId}},c);m.set(t.scope,{operation:{context:trace.setSpan(c,u),name:l,span:u},step:{context:c,span:s}}),p.set(t.scope.attemptId,t.scope)},onStepTerminal=async e=>{let t=p.get(e.scope.attemptId)??e.scope;f.delete(t),drainOpenSpans({...e,scope:t}),v.drain(e.scope.attemptId,e.type===`step.attempt.failed`?{error:e.error}:void 0),e.type===`step.attempt.failed`&&await g.failForAttempt(t,e.error),p.delete(e.scope.attemptId);let n=m.get(t);n!==void 0&&(n.step.span.addEvent(e.type===`step.attempt.completed`?`step.completed`:`step.failed`),e.type===`step.attempt.failed`&&(recordError(n.operation.span,e.error),recordError(n.step.span,e.error)),n.operation.span.end(),n.step.span.end(),m.delete(t))},onTurnTerminal=async t=>{(t.type===`turn.cancelled`||t.type===`turn.failed`)&&await g.deleteForTurn(t.sessionId,t.turnId);let n=await e.stateStore.getTurn(t.sessionId,t.turnId);n!==void 0&&await e.stateStore.setTurn(t.sessionId,t.turnId,{...n,terminal:t.type===`turn.failed`?{error:t.error,type:t.type}:{type:t.type}})},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let r=await e.stateStore.getSession(t.sessionId),i=e.idGenerator.withSpanId(n.context.spanId,()=>e.tracer.startSpan(`agent.turn`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":r?.agentName,...parentLineageAttributes(n.lineage),"agent.root.session.id":n.rootSessionId,"agent.session.id":t.sessionId,"agent.session.window":r?.window,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence},startTime:n.startTimeMs},contextFromSpanContext({isRemote:n.parentIsRemote??!1,spanId:n.parentSpanId,traceFlags:n.context.traceFlags,traceId:n.context.traceId})));i.addEvent(`turn.started`,void 0,n.startTimeMs),n.terminal!==void 0&&(i.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(i,n.terminal.error)),i.end(),await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&(await g.deleteForSession(t.sessionId),await e.stateStore.deleteSession(t.sessionId))},onModelCallStarted=n=>{let i=m.get(n.scope);if(i===void 0)return;i.step.span.setAttribute(`agent.model.id`,n.model.modelId),i.step.span.setAttribute(`agent.model.provider`,n.model.provider);let o=e.tracer.startSpan(modelSpanName(n.model.modelId),{attributes:{"gen_ai.agent.name":n.scope.functionId,"gen_ai.operation.name":`chat`,"gen_ai.provider.name":n.model.provider,"gen_ai.request.model":n.model.modelId}},i.operation.context);if(t&&n.input!==void 0){let e=messagesContentAttribute(n.input.messages);e!==void 0&&o.setAttribute(`ai.prompt.messages`,e);let t=genAiInputMessagesAttribute(n.input.messages);t!==void 0&&o.setAttribute(`gen_ai.input.messages`,t);let r=systemPromptAttribute(n.input.instructions);r!==void 0&&o.setAttribute(`ai.prompt.system`,r);let i=genAiSystemInstructionsAttribute(n.input.instructions);i!==void 0&&o.setAttribute(`gen_ai.system_instructions`,i)}let u={context:trace.setSpan(i.operation.context,o),span:o};getExecutionContexts(n.scope).set(n.idempotencyKey,u.context),getSpanStates(h,n.scope).set(n.idempotencyKey,u)},onModelCallTerminal=e=>{f.get(e.scope)?.delete(e.idempotencyKey);let t=takeSpanState(h,e.scope,e.idempotencyKey);if(t!==void 0){if(e.type===`model.call.failed`)recordError(t.span,e.error);else{setAgentUsage(t.span,e.usage),t.span.setAttribute(`gen_ai.response.finish_reasons`,[e.finishReason]);let n=m.get(e.scope);if(n!==void 0&&setAgentUsage(n.step.span,e.usage),d){t.span.setAttribute(`ai.response.finish_reason`,e.finishReason);let n=e.content??[],r=genAiOutputMessagesAttribute(n,e.finishReason);r!==void 0&&t.span.setAttribute(`gen_ai.output.messages`,r);let a=textContentAttribute(n.filter(e=>e.type===`reasoning`).map(e=>e.text).filter(e=>e.trim().length>0).join(`
2
+ `));a!==void 0&&t.span.setAttribute(`ai.response.reasoning`,a);let s=textContentAttribute(n.filter(e=>e.type===`text`).map(e=>e.text).join(``));s!==void 0&&t.span.setAttribute(`ai.response.text`,s);let c=n.filter(e=>e.type===`tool-call`).map(e=>({callId:e.callId,input:e.input,toolName:e.toolName}));if(c.length>0){let e=contentAttribute(c,!1);e!==void 0&&t.span.setAttribute(`ai.response.tool_calls`,e)}let l=n.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{callId:e.callId,input:e.input,output:e.output,toolName:e.toolName}:{callId:e.callId,error:errorText(e.error),input:e.input,toolName:e.toolName});if(l.length>0){let e=toolResultsContentAttribute(l);e!==void 0&&t.span.setAttribute(`ai.response.tool_results`,e)}}}t.span.end()}},S=createAgentChannelDeliveryInstrumentation({ensureSessionContext:y,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,stateStore:e.stateStore,tracer:e.tracer}),onStepMetadata=e=>{let t=m.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.step.span.setAttribute(e,r)};return{hook:{capture:t||d?`content`:`metadata`,events:{...S,"action.completed":g.events[`action.completed`],"action.failed":g.events[`action.failed`],async"action.started"(e,t){await g.events[`action.started`](e,t),await v.actionStarted(e)},..._,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...v.events,"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted},name:`eve.otel`},prepareSessionTrace:b,prepareTurnTrace:x,runInContext(e,t){let r=p.get(e.scope.attemptId)??e.scope,i=f.get(r),a=e.type===`model.call`?i?.get(e.idempotencyKey):v.contextFor(e.scope.attemptId,e.idempotencyKey);return a===void 0?t():context.with(a,t)}};function getExecutionContexts(e){let t=f.get(e);return t===void 0&&(t=new Map,f.set(e,t)),t}function drainOpenSpans(e){for(let t of h.get(e.scope)?.values()??[])e.type===`step.attempt.failed`&&recordError(t.span,e.error),t.span.end();h.delete(e.scope)}}function getSpanStates(e,t){let n=e.get(t);return n===void 0&&(n=new Map,e.set(t,n)),n}function takeSpanState(e,t,n){let r=e.get(t),i=r?.get(n);if(r!==void 0)return r.delete(n),r.size===0&&e.delete(t),i}function parentLineageAttributes(e){if(e===void 0)return{};let t={"agent.parent.call_id":e.callId,"agent.parent.session.id":e.sessionId,"agent.parent.turn.id":e.turnId};return e.subagentName!==void 0&&(t[`agent.subagent.name`]=e.subagentName),t}function contextFromSpanContext(t){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(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)}function modelSpanName(e){return`chat ${e}`}function errorText(e){return e instanceof Error?e.message:e}function recordError(e,n){n instanceof Error?(e.recordException(n),e.setStatus({code:SpanStatusCode.ERROR,message:n.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentOtelInstrumentation};
@@ -0,0 +1,17 @@
1
+ import type { Tracer } from "#compiled/@opentelemetry/api/index.js";
2
+ import { type InstrumentationSessionStartedEvent, type InstrumentationTraceContext, type InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.js";
3
+ import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
4
+ import { type AgentSessionTraceState, type AgentTraceStateStore } from "#tracing/agent-trace-state.js";
5
+ interface AgentOtelSessionContextInput {
6
+ readonly frameworkVersion: string;
7
+ readonly idGenerator: AgentSpanIdGenerator;
8
+ readonly stateStore: AgentTraceStateStore;
9
+ readonly tracer: Tracer;
10
+ }
11
+ interface AgentOtelSessionContext {
12
+ readonly ensureSessionContext: (event: InstrumentationSessionStartedEvent) => Promise<AgentSessionTraceState>;
13
+ readonly prepareSessionTrace: (event: InstrumentationSessionStartedEvent) => Promise<InstrumentationTraceContext>;
14
+ readonly prepareTurnTrace: (event: InstrumentationTurnStartedEvent) => Promise<InstrumentationTraceContext>;
15
+ }
16
+ export declare function createAgentOtelSessionContext(input: AgentOtelSessionContextInput): AgentOtelSessionContext;
17
+ export {};
@@ -0,0 +1 @@
1
+ import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{SESSION_WINDOW_TURN_LIMIT}from"#tracing/agent-trace-state.js";function createAgentOtelSessionContext(n){let openSessionWindow=e=>{let t=n.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.name":e.agentName,"agent.root.session.id":e.rootSessionId,"agent.session.id":e.sessionId,"agent.session.window":e.index,"agent.trace.schema.version":1,...e.previousTraceId===void 0?{}:{"agent.session.window.previous.trace.id":e.previousTraceId}},root:!0});return t.addEvent(e.index===0?`session.started`:`session.window.opened`),t.end(),t.spanContext()},ensureSessionContext=async e=>{let t=await n.stateStore.getSession(e.sessionId);return t===void 0&&(t={agentName:e.agentName,channelKind:e.channelKind,context:e.parentTraceContext===void 0?openSessionWindow({agentName:e.agentName,index:0,rootSessionId:e.rootSessionId,sessionId:e.sessionId}):adoptedSpanContext(e.parentTraceContext),rootSessionId:e.rootSessionId,turnsInWindow:0,window:0},await n.stateStore.setSession(e.sessionId,t)),t},advanceSessionWindow=(e,n)=>{if(n.turnsInWindow<SESSION_WINDOW_TURN_LIMIT)return n;let r=n.window+1;return{...n,context:openSessionWindow({agentName:n.agentName,index:r,previousTraceId:n.context.traceId,rootSessionId:n.rootSessionId,sessionId:e}),turnsInWindow:0,window:r}};return{ensureSessionContext,prepareSessionTrace:async e=>portableSpanContext((await ensureSessionContext(e)).context),prepareTurnTrace:async t=>{let r=await n.stateStore.getTurn(t.sessionId,t.turnId);if(r!==void 0)return{spanId:r.parentSpanId,traceFlags:r.context.traceFlags,traceId:r.context.traceId};let i=advanceSessionWindow(t.sessionId,await ensureSessionContext({agentName:void 0,channelKind:void 0,idempotencyKey:sessionIdempotencyKey(t.sessionId),parentTraceContext:t.parentTraceContext,rootSessionId:t.rootSessionId,sessionId:t.sessionId,type:`session.started`})),a={isRemote:!1,spanId:n.idGenerator.deriveSpanId(`turn:${t.idempotencyKey}`),traceFlags:i.context.traceFlags,traceId:i.context.traceId};return await n.stateStore.setSession(t.sessionId,{...i,turnsInWindow:i.turnsInWindow+1}),await n.stateStore.setTurn(t.sessionId,t.turnId,{context:a,lineage:t.parentLineage,parentIsRemote:i.context.isRemote,parentSpanId:i.context.spanId,rootSessionId:t.rootSessionId,sequence:t.sequence,startTimeMs:Date.now()}),portableSpanContext(i.context)}}}function portableSpanContext(e){return{spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function adoptedSpanContext(e){return{isRemote:`isRemote`in e&&e.isRemote===!0,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}export{createAgentOtelSessionContext};
@@ -0,0 +1,4 @@
1
+ import type { Span } from "#compiled/@opentelemetry/api/index.js";
2
+ import type { InstrumentationUsage } from "#harness/instrumentation/lifecycle.js";
3
+ /** Applies eve's structural token usage attributes to an agent span. */
4
+ export declare function setAgentUsage(span: Span, usage: InstrumentationUsage): void;
@@ -0,0 +1 @@
1
+ function setAgentUsage(e,t){t.inputTokens!==void 0&&e.setAttribute(`agent.usage.input_tokens`,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(`agent.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_creation.input_tokens`,n.cacheWriteTokens)}export{setAgentUsage};
@@ -8,6 +8,8 @@ export declare class AgentSpanIdGenerator {
8
8
  #private;
9
9
  /** Reserves a span id for a span emitted later via {@link withSpanId}. */
10
10
  allocateSpanId(): string;
11
+ /** Derives one span id for a replay-stable instrumentation event. */
12
+ deriveSpanId(key: string): string;
11
13
  generateSpanId(): string;
12
14
  generateTraceId(): string;
13
15
  /** Runs `startSpan` so the next span started carries `spanId`. */
@@ -1 +1 @@
1
- var AgentSpanIdGenerator=class{#e;allocateSpanId(){return randomHexId(16)}generateSpanId(){let e=this.#e;return e===void 0?randomHexId(16):(this.#e=void 0,e)}generateTraceId(){return randomHexId(32)}withSpanId(e,t){this.#e=e;try{return t()}finally{this.#e=void 0}}};function randomHexId(e){let t;do{t=``;for(let n=0;n<e;n+=1)t+=`0123456789abcdef`[Math.trunc(Math.random()*16)]}while(!/[1-9a-f]/u.test(t));return t}export{AgentSpanIdGenerator};
1
+ import{createHash}from"node:crypto";var AgentSpanIdGenerator=class{#e;allocateSpanId(){return randomHexId(16)}deriveSpanId(t){let n=createHash(`sha256`).update(t).digest(`hex`).slice(0,16);return/^0+$/u.test(n)?`0000000000000001`:n}generateSpanId(){let e=this.#e;return e===void 0?randomHexId(16):(this.#e=void 0,e)}generateTraceId(){return randomHexId(32)}withSpanId(e,t){this.#e=e;try{return t()}finally{this.#e=void 0}}};function randomHexId(e){let t;do{t=``;for(let n=0;n<e;n+=1)t+=`0123456789abcdef`[Math.trunc(Math.random()*16)]}while(!/[1-9a-f]/u.test(t));return t}export{AgentSpanIdGenerator};