eve 0.33.2 → 0.34.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 (228) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/src/channel/channel-address.d.ts +3 -6
  3. package/dist/src/channel/channel-address.js +1 -1
  4. package/dist/src/channel/channel-operations.d.ts +2 -3
  5. package/dist/src/channel/delivery-metadata.d.ts +9 -0
  6. package/dist/src/channel/delivery-metadata.js +1 -0
  7. package/dist/src/channel/routes.d.ts +1 -0
  8. package/dist/src/channel/session.d.ts +3 -4
  9. package/dist/src/channel/session.js +1 -1
  10. package/dist/src/channel/types.d.ts +20 -3
  11. package/dist/src/chunks/{use-eve-agent-B-Hky2f4.js → use-eve-agent-BNdcle_M.js} +33 -0
  12. package/dist/src/chunks/{use-eve-agent-3oBnxzhV.js → use-eve-agent-FJkEMXYk.js} +33 -0
  13. package/dist/src/cli/dev/tui/traces/trace-conversation.js +1 -1
  14. package/dist/src/client/message-reducer.js +1 -1
  15. package/dist/src/compiled/.vendor-stamp.json +1 -1
  16. package/dist/src/compiled/@opentelemetry/api/index.d.ts +32 -3
  17. package/dist/src/compiled/@vercel/otel/index.d.ts +45 -2
  18. package/dist/src/compiler/extension-compatibility.d.ts +12 -12
  19. package/dist/src/compiler/extension-compatibility.js +1 -1
  20. package/dist/src/compiler/manifest.js +1 -1
  21. package/dist/src/compiler/normalize-agent-config.js +1 -1
  22. package/dist/src/context/build-dynamic-tools.d.ts +7 -0
  23. package/dist/src/context/build-dynamic-tools.js +1 -1
  24. package/dist/src/context/dynamic-tool-lifecycle.d.ts +7 -0
  25. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  26. package/dist/src/context/keys.d.ts +13 -1
  27. package/dist/src/context/keys.js +1 -1
  28. package/dist/src/discover/filesystem.d.ts +1 -1
  29. package/dist/src/discover/filesystem.js +1 -1
  30. package/dist/src/evals/cli/eval.js +2 -2
  31. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  32. package/dist/src/execution/dispatch-runtime-actions-step.d.ts +1 -5
  33. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  34. package/dist/src/execution/dispatch-turn-step.d.ts +5 -0
  35. package/dist/src/execution/dispatch-turn-step.js +1 -0
  36. package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +1 -0
  37. package/dist/src/execution/node-step.js +1 -1
  38. package/dist/src/execution/parked-delivery-wait.d.ts +1 -1
  39. package/dist/src/execution/parked-delivery-wait.js +1 -1
  40. package/dist/src/execution/remote-agent-dispatch.d.ts +2 -1
  41. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  42. package/dist/src/execution/route-child-delivery.d.ts +3 -4
  43. package/dist/src/execution/route-child-delivery.js +1 -1
  44. package/dist/src/execution/route-proxied-deliver-step.d.ts +34 -0
  45. package/dist/src/execution/route-proxied-deliver-step.js +1 -0
  46. package/dist/src/execution/runtime-context.js +1 -1
  47. package/dist/src/execution/session-command-inbox.d.ts +2 -2
  48. package/dist/src/execution/session-command-wire.js +1 -1
  49. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  50. package/dist/src/execution/subagent-adapter.js +1 -1
  51. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  52. package/dist/src/execution/tool-auth.d.ts +9 -0
  53. package/dist/src/execution/tool-auth.js +1 -1
  54. package/dist/src/execution/turn-control-receiver.js +1 -1
  55. package/dist/src/execution/turn-dispatch.js +1 -1
  56. package/dist/src/execution/turn-workflow.js +1 -1
  57. package/dist/src/execution/workflow-entry.js +1 -1
  58. package/dist/src/execution/workflow-runtime.js +1 -1
  59. package/dist/src/execution/workflow-steps.d.ts +1 -27
  60. package/dist/src/execution/workflow-steps.js +1 -1
  61. package/dist/src/harness/ai-sdk-hook-bridge.js +1 -1
  62. package/dist/src/harness/ai-sdk-telemetry.d.ts +19 -0
  63. package/dist/src/harness/ai-sdk-telemetry.js +1 -0
  64. package/dist/src/harness/approval-candidates.d.ts +109 -0
  65. package/dist/src/harness/approval-candidates.js +1 -0
  66. package/dist/src/harness/approval-delivery-coordinator.d.ts +39 -0
  67. package/dist/src/harness/approval-delivery-coordinator.js +1 -0
  68. package/dist/src/harness/authorization.d.ts +1 -0
  69. package/dist/src/harness/authorization.js +1 -1
  70. package/dist/src/harness/channel-delivery-instrumentation.d.ts +25 -0
  71. package/dist/src/harness/channel-delivery-instrumentation.js +1 -0
  72. package/dist/src/harness/execute-tool.d.ts +1 -0
  73. package/dist/src/harness/hitl/approval-input-requests.js +1 -1
  74. package/dist/src/harness/hitl/pending-input-resolution.d.ts +3 -0
  75. package/dist/src/harness/hitl/pending-input-resolution.js +1 -1
  76. package/dist/src/harness/hitl/question-input-requests.js +1 -1
  77. package/dist/src/harness/hitl/session-limit-input-requests.js +1 -1
  78. package/dist/src/harness/input-extraction.js +1 -1
  79. package/dist/src/harness/input-request-resolution.d.ts +22 -0
  80. package/dist/src/harness/input-request-resolution.js +1 -0
  81. package/dist/src/harness/input-requests.d.ts +1 -0
  82. package/dist/src/harness/input-requests.js +1 -1
  83. package/dist/src/harness/instrumentation-config.d.ts +9 -4
  84. package/dist/src/harness/instrumentation-config.js +1 -1
  85. package/dist/src/harness/instrumentation-content.d.ts +5 -0
  86. package/dist/src/harness/instrumentation-content.js +1 -0
  87. package/dist/src/harness/instrumentation-dispatch.d.ts +2 -0
  88. package/dist/src/harness/instrumentation-dispatch.js +1 -0
  89. package/dist/src/harness/instrumentation-lifecycle.d.ts +388 -65
  90. package/dist/src/harness/instrumentation-lifecycle.js +1 -1
  91. package/dist/src/harness/instrumentation-native-events.d.ts +10 -1
  92. package/dist/src/harness/instrumentation-native-events.js +1 -1
  93. package/dist/src/harness/instrumentation-providers.d.ts +50 -0
  94. package/dist/src/harness/instrumentation-providers.js +1 -0
  95. package/dist/src/harness/instrumentation-runtime.d.ts +3 -0
  96. package/dist/src/harness/instrumentation-runtime.js +1 -1
  97. package/dist/src/harness/instrumentation-setup-context.d.ts +12 -0
  98. package/dist/src/harness/instrumentation-setup-context.js +1 -0
  99. package/dist/src/harness/instrumentation-state.d.ts +59 -0
  100. package/dist/src/harness/instrumentation-state.js +1 -0
  101. package/dist/src/harness/messages.d.ts +2 -1
  102. package/dist/src/harness/messages.js +1 -1
  103. package/dist/src/harness/pending-input-batches.d.ts +2 -0
  104. package/dist/src/harness/pending-input-batches.js +1 -1
  105. package/dist/src/harness/runtime-action-settlement-state.d.ts +3 -0
  106. package/dist/src/harness/runtime-action-settlement-state.js +1 -0
  107. package/dist/src/harness/runtime-actions.js +1 -1
  108. package/dist/src/harness/stale-input-responses.js +1 -1
  109. package/dist/src/harness/tool-call-action.d.ts +9 -0
  110. package/dist/src/harness/tool-call-action.js +1 -0
  111. package/dist/src/harness/tool-loop.js +2 -2
  112. package/dist/src/harness/tools.js +1 -1
  113. package/dist/src/harness/types.d.ts +15 -1
  114. package/dist/src/internal/application/compiled-artifacts.d.ts +13 -4
  115. package/dist/src/internal/application/compiled-artifacts.js +5 -4
  116. package/dist/src/internal/application/dev-environment.d.ts +12 -0
  117. package/dist/src/internal/application/dev-environment.js +1 -1
  118. package/dist/src/internal/application/package.js +1 -1
  119. package/dist/src/internal/authored-definition/approval.d.ts +3 -0
  120. package/dist/src/internal/authored-definition/approval.js +1 -0
  121. package/dist/src/internal/authored-definition/connection.js +1 -1
  122. package/dist/src/internal/authored-definition/core.js +1 -1
  123. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  124. package/dist/src/internal/instrumentation-layout.d.ts +28 -0
  125. package/dist/src/internal/instrumentation-layout.js +1 -0
  126. package/dist/src/internal/materialized-authored-modules.d.ts +13 -2
  127. package/dist/src/internal/materialized-authored-modules.js +1 -1
  128. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  129. package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
  130. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.d.ts +5 -1
  131. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -1
  132. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  133. package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +2 -3
  134. package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
  135. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  136. package/dist/src/protocol/message.d.ts +36 -1
  137. package/dist/src/protocol/message.js +1 -1
  138. package/dist/src/protocol/traceparent.d.ts +10 -0
  139. package/dist/src/protocol/traceparent.js +1 -0
  140. package/dist/src/public/channels/eve.js +1 -1
  141. package/dist/src/public/channels/github/defaults.d.ts +1 -0
  142. package/dist/src/public/channels/github/defaults.js +5 -2
  143. package/dist/src/public/channels/github/dispatch.js +1 -1
  144. package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
  145. package/dist/src/public/channels/github/githubChannel.js +1 -1
  146. package/dist/src/public/channels/github/inbound.d.ts +0 -3
  147. package/dist/src/public/channels/github/inbound.js +1 -1
  148. package/dist/src/public/channels/slack/defaults.js +3 -3
  149. package/dist/src/public/channels/slack/interactions.js +1 -1
  150. package/dist/src/public/channels/slack/slackChannel.d.ts +11 -3
  151. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  152. package/dist/src/public/definitions/approval.d.ts +57 -16
  153. package/dist/src/public/definitions/approval.js +1 -1
  154. package/dist/src/public/definitions/channel.d.ts +2 -2
  155. package/dist/src/public/definitions/channel.js +1 -1
  156. package/dist/src/public/definitions/hook.d.ts +4 -2
  157. package/dist/src/public/instrumentation/index.d.ts +32 -17
  158. package/dist/src/public/instrumentation/index.js +1 -1
  159. package/dist/src/public/instrumentation/otel.d.ts +31 -0
  160. package/dist/src/public/instrumentation/otel.js +1 -0
  161. package/dist/src/public/instrumentation/provider.d.ts +117 -0
  162. package/dist/src/public/instrumentation/provider.js +1 -0
  163. package/dist/src/public/tools/approval/approval-helpers.d.ts +4 -4
  164. package/dist/src/public/tools/index.d.ts +1 -1
  165. package/dist/src/runtime/actions/results.d.ts +3 -3
  166. package/dist/src/runtime/attributes/emit.js +1 -1
  167. package/dist/src/runtime/connections/principal.d.ts +3 -0
  168. package/dist/src/runtime/connections/principal.js +1 -1
  169. package/dist/src/runtime/connections/scoped-authorization.d.ts +3 -5
  170. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  171. package/dist/src/runtime/connections/types.d.ts +5 -0
  172. package/dist/src/runtime/resolve-agent.js +1 -1
  173. package/dist/src/runtime/resolve-tool.js +1 -1
  174. package/dist/src/setup/index.d.ts +1 -0
  175. package/dist/src/setup/index.js +1 -1
  176. package/dist/src/setup/scaffold/create/project.js +1 -1
  177. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  178. package/dist/src/setup/verified-remote-agent.d.ts +30 -0
  179. package/dist/src/setup/verified-remote-agent.js +1 -0
  180. package/dist/src/shared/agent-definition.d.ts +9 -0
  181. package/dist/src/shared/channel-definition.d.ts +3 -1
  182. package/dist/src/svelte/index.js +1 -1
  183. package/dist/src/svelte/use-eve-agent.js +1 -1
  184. package/dist/src/tracing/agent-action-instrumentation.d.ts +31 -0
  185. package/dist/src/tracing/agent-action-instrumentation.js +1 -0
  186. package/dist/src/tracing/agent-approval-instrumentation.d.ts +13 -0
  187. package/dist/src/tracing/agent-approval-instrumentation.js +1 -0
  188. package/dist/src/tracing/agent-channel-delivery-instrumentation.d.ts +13 -0
  189. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -0
  190. package/dist/src/tracing/agent-otel-content.d.ts +6 -0
  191. package/dist/src/tracing/agent-otel-content.js +2 -2
  192. package/dist/src/tracing/agent-otel-provider.d.ts +7 -7
  193. package/dist/src/tracing/agent-otel-provider.js +2 -2
  194. package/dist/src/tracing/agent-otel-usage.d.ts +4 -0
  195. package/dist/src/tracing/agent-otel-usage.js +1 -0
  196. package/dist/src/tracing/agent-span-id-generator.d.ts +2 -0
  197. package/dist/src/tracing/agent-span-id-generator.js +1 -1
  198. package/dist/src/tracing/agent-tool-instrumentation.d.ts +28 -0
  199. package/dist/src/tracing/agent-tool-instrumentation.js +1 -0
  200. package/dist/src/tracing/agent-trace-context-store.d.ts +8 -1
  201. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  202. package/dist/src/tracing/agent-trace-span-processor.d.ts +0 -1
  203. package/dist/src/tracing/agent-trace-span-processor.js +1 -1
  204. package/dist/src/tracing/agent-trace-state.d.ts +33 -3
  205. package/dist/src/tracing/agent-trace-state.js +1 -1
  206. package/dist/src/tracing/batch-span-processor.d.ts +20 -0
  207. package/dist/src/tracing/batch-span-processor.js +1 -0
  208. package/dist/src/tracing/content-attributes.d.ts +28 -0
  209. package/dist/src/tracing/content-attributes.js +1 -0
  210. package/dist/src/tracing/content-span-processor.d.ts +19 -0
  211. package/dist/src/tracing/content-span-processor.js +1 -0
  212. package/dist/src/tracing/install-instrumentation-runtime.d.ts +19 -0
  213. package/dist/src/tracing/install-instrumentation-runtime.js +1 -0
  214. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  215. package/dist/src/tracing/local-traces.d.ts +56 -0
  216. package/dist/src/tracing/local-traces.js +1 -0
  217. package/dist/src/tracing/otel-declaration.d.ts +150 -0
  218. package/dist/src/tracing/otel-declaration.js +1 -0
  219. package/dist/src/tracing/otel-registration.d.ts +21 -0
  220. package/dist/src/tracing/otel-registration.js +1 -0
  221. package/dist/src/tracing/vercel-runtime-span-exporter.d.ts +5 -0
  222. package/dist/src/tracing/vercel-runtime-span-exporter.js +1 -0
  223. package/dist/src/vue/index.js +1 -1
  224. package/dist/src/vue/use-eve-agent.js +1 -1
  225. package/docs/guides/instrumentation.md +22 -0
  226. package/package.json +7 -1
  227. package/dist/src/harness/otel-integration.d.ts +0 -12
  228. package/dist/src/harness/otel-integration.js +0 -1
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Which span attributes carry conversation content, and in which direction.
3
+ *
4
+ * Two vocabularies land on the same spans: the ones eve sets on its own
5
+ * `agent.*` spans, and the ones the AI SDK's OpenTelemetry integration sets on
6
+ * the model-call spans beneath them. A destination that declined content has to
7
+ * be rid of both, so both are listed here rather than in the module that writes
8
+ * each.
9
+ *
10
+ * Listed by name rather than by prefix because the prefixes are shared with
11
+ * metadata that must survive: `ai.response.finish_reason` and
12
+ * `gen_ai.tool.name` say what happened, not what was said. The cost is that a
13
+ * new content attribute in a dependency is not covered until it is added here.
14
+ */
15
+ /** What one destination is willing to receive. */
16
+ export interface ResolvedContentOptions {
17
+ readonly recordInputs: boolean;
18
+ readonly recordOutputs: boolean;
19
+ }
20
+ /**
21
+ * The attributes with the declined content removed, or `undefined` when there
22
+ * was none to remove.
23
+ *
24
+ * The `undefined` return is what lets the caller forward the original span
25
+ * untouched in the common case, so a destination that declined a direction the
26
+ * span never carried costs one pass over its keys and no allocation.
27
+ */
28
+ export declare function withoutDeclinedContent(attributes: Readonly<Record<string, unknown>>, content: ResolvedContentOptions): Record<string, unknown> | undefined;
@@ -0,0 +1 @@
1
+ const INPUT_CONTENT_ATTRIBUTES=new Set([`agent.channel.delivery.input`,`ai.documents`,`ai.prompt`,`ai.prompt.messages`,`ai.prompt.system`,`ai.prompt.toolChoice`,`ai.prompt.tools`,`ai.value`,`ai.values`,`gen_ai.input.messages`,`gen_ai.system_instructions`,`gen_ai.tool.call.arguments`,`gen_ai.tool.definitions`]),OUTPUT_CONTENT_ATTRIBUTES=new Set([`ai.embedding`,`ai.embeddings`,`ai.ranking`,`ai.response.files`,`ai.response.object`,`ai.response.reasoning`,`ai.response.text`,`ai.response.toolCalls`,`ai.response.tool_calls`,`ai.response.tool_results`,`ai.toolCall.args`,`ai.toolCall.result`,`gen_ai.output.messages`,`gen_ai.tool.call.result`]);function isDeclined(n,r){return!r.recordInputs&&INPUT_CONTENT_ATTRIBUTES.has(n)?!0:!r.recordOutputs&&OUTPUT_CONTENT_ATTRIBUTES.has(n)}function withoutDeclinedContent(e,t){let n=Object.keys(e);if(!n.some(e=>isDeclined(e,t)))return;let r={};for(let i of n)isDeclined(i,t)||(r[i]=e[i]);return r}export{withoutDeclinedContent};
@@ -0,0 +1,19 @@
1
+ import type { SpanProcessor } from "#compiled/@vercel/otel/index.js";
2
+ import { type ResolvedContentOptions } from "#tracing/content-attributes.js";
3
+ /**
4
+ * Puts one destination's content policy in front of it.
5
+ *
6
+ * Content is written onto a span if any destination wants it, so the span
7
+ * reaching a destination that declined still carries it. This cannot strip the
8
+ * attribute in place: that span object is shared with every other processor in
9
+ * the pipeline, and editing it would strip the attribute everywhere. So it
10
+ * gives the destination a facade whose attributes omit what it declined.
11
+ *
12
+ * One facade follows the original from start through end. This preserves the
13
+ * object identity stateful processors key on without ever exposing the original
14
+ * span or its attribute map. Methods stay bound to the original, so private SDK
15
+ * state remains reachable without eve knowing that SDK's concrete span shape.
16
+ *
17
+ * @internal
18
+ */
19
+ export declare function contentFilteringProcessor(downstream: SpanProcessor, content: ResolvedContentOptions): SpanProcessor;
@@ -0,0 +1 @@
1
+ import{hasSessionRelease}from"#tracing/local-traces.js";import{withoutDeclinedContent}from"#tracing/content-attributes.js";function contentFilteringProcessor(t,n){if(n.recordInputs&&n.recordOutputs)return t;let r=new WeakMap,i={forceFlush:()=>t.forceFlush(),onEnd:e=>{if(typeof e!=`object`||!e){t.onEnd(e);return}let i=facadeFor(e,n,r);i.refresh();try{t.onEnd(i.value)}finally{r.delete(e)}},onStart:(e,i)=>{if(typeof e!=`object`||!e){t.onStart(e,i);return}t.onStart(facadeFor(e,n,r).value,i)},shutdown:()=>t.shutdown()};return hasSessionRelease(t)?{...i,releaseSession:e=>t.releaseSession(e)}:i}function facadeFor(e,t,n){let r=n.get(e);if(r!==void 0)return r;let i={},a=[],o={},s=Object.create(Reflect.getPrototypeOf(e)),c=new Map,refresh=()=>{refreshAttributes(i,e,t),refreshEvents(a,e,t),refreshStatus(o,e,t)},l,readOriginal=t=>{let n=Reflect.get(e,t,e);if(typeof n!=`function`||t===`constructor`)return n;let r=c.get(t);if(r!==void 0)return r;let created=(...t)=>{let r=Reflect.apply(n,e,t);return refresh(),r===e?l:r};return c.set(t,created),created};Object.defineProperty(s,"attributes",{configurable:!0,enumerable:!0,value:i}),Object.defineProperty(s,"events",{configurable:!0,enumerable:!0,value:a}),Object.defineProperty(s,"status",{configurable:!0,enumerable:!0,value:o});for(let t of Reflect.ownKeys(e)){if(t===`attributes`||t===`events`||t===`status`)continue;let n=Reflect.getOwnPropertyDescriptor(e,t);Object.defineProperty(s,t,{configurable:!0,enumerable:n?.enumerable??!1,get:()=>readOriginal(t)})}l=new Proxy(s,{get:(e,t,n)=>Object.hasOwn(e,t)?Reflect.get(e,t,n):readOriginal(t)});let u={refresh,value:l};return u.refresh(),n.set(e,u),u}function refreshAttributes(e,n,r){for(let t of Object.keys(e))delete e[t];let i=n.attributes;if(typeof i!=`object`||!i)return;let a=withoutDeclinedContent(i,r);Object.assign(e,a??i)}function refreshEvents(e,t,n){e.length=0;let r=t.events;if(Array.isArray(r)){if(n.recordOutputs){e.push(...r);return}for(let t of r){if(typeof t!=`object`||!t)continue;let n=t;n.name!==`exception`&&e.push({...n,attributes:void 0})}}}function refreshStatus(e,t,n){for(let t of Object.keys(e))delete e[t];let r=t.status;if(typeof r!=`object`||!r)return;let i=r;i.code!==void 0&&(e.code=i.code),n.recordOutputs&&i.message!==void 0&&(e.message=i.message)}export{contentFilteringProcessor};
@@ -0,0 +1,19 @@
1
+ import { type InstrumentationProviderDefinition } from "#harness/instrumentation-lifecycle.js";
2
+ import { type InstrumentationRuntime } from "#harness/instrumentation-runtime.js";
3
+ import type { CollectedOtel } from "#tracing/otel-declaration.js";
4
+ /**
5
+ * Installs the process instrumentation runtime around a collected pipeline.
6
+ *
7
+ * Both layouts land here. `eve dev`'s zero-config default and an authored
8
+ * `agent/instrumentation/` directory differ only in where the declared values
9
+ * came from, so sharing the install keeps them on one runtime path.
10
+ *
11
+ * A directory that declared no OpenTelemetry still gets a bus: its providers
12
+ * see every event, they just have no spans to hang them on.
13
+ */
14
+ export declare function installInstrumentationRuntime(input: {
15
+ readonly collected: CollectedOtel;
16
+ readonly frameworkVersion: string;
17
+ readonly providers: readonly InstrumentationProviderDefinition[];
18
+ readonly serviceName: string;
19
+ }): InstrumentationRuntime;
@@ -0,0 +1 @@
1
+ import{createLogger,formatError}from"#internal/logging.js";import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{registerInstrumentationRuntime}from"#harness/instrumentation-runtime.js";import{trace}from"#compiled/@opentelemetry/api/index.js";import{createInstrumentationHooks}from"#harness/instrumentation-lifecycle.js";import{hasSessionRelease}from"#tracing/local-traces.js";import{createAgentOtelInstrumentation}from"#tracing/agent-otel-provider.js";import{registerOtelPipeline}from"#tracing/otel-registration.js";const log=createLogger(`tracing.install-instrumentation-runtime`);function installInstrumentationRuntime(e){let t=[],a=[],o,runInContext=(e,t)=>t();if(e.collected.declared){o=registerOtelPipeline({pipeline:e.collected.pipeline,serviceName:e.serviceName});let r=createAgentOtelInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:o.idGenerator,recordInputs:e.collected.settings.recordInputs,recordOutputs:e.collected.settings.recordOutputs,stateStore:new ContextAgentTraceStateStore,tracer:trace.getTracer(`eve.agent`,e.frameworkVersion)});t.push({...r.hook,stateNamespace:`internal:otel`}),runInContext=r.runInContext;let i=e.collected.pipeline.spanProcessors.filter(isSpanProcessor).filter(hasSessionRelease);i.length>0&&a.push(sessionReleaseProvider(i))}let s=[...t,...e.providers,...a],c;return registerInstrumentationRuntime({forceFlush:()=>settleAll([...o===void 0?[]:[o.forceFlush],...s.map(e=>()=>e.flush?.())]),hooks:createInstrumentationHooks({parallel:e.providers,serialAfter:a,serialBefore:t}),otelSettings:e.collected.declared?e.collected.settings:void 0,runInContext,shutdown:()=>(c??=settleAll([...o===void 0?[]:[o.shutdown],...s.map(e=>()=>e.shutdown?.())]),c)})}function isSpanProcessor(e){return e!==`auto`}function sessionReleaseProvider(e){let release=async t=>{await Promise.all(e.map(e=>e.releaseSession(t.sessionId)))};return{events:{"session.completed":release,"session.failed":release},name:`eve.session-release`,stateNamespace:`internal:session-release`}}async function settleAll(e){let n=await Promise.allSettled(e.map(async e=>e()));for(let e of n)e.status===`rejected`&&log.warn(`instrumentation drain failed`,{error:formatError(e.reason)})}export{installInstrumentationRuntime};
@@ -1 +1 @@
1
- import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{getInstrumentationRuntime,registerInstrumentationRuntime}from"#harness/instrumentation-runtime.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";import{createAgentOtelInstrumentation}from"#tracing/agent-otel-provider.js";import{AgentSpanIdGenerator}from"#tracing/agent-span-id-generator.js";import{AgentTraceSpanProcessor}from"#tracing/agent-trace-span-processor.js";import{createInstrumentationHooks}from"#harness/instrumentation-lifecycle.js";import{requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings}from"#tracing/local-trace-retention.js";import{LocalTraceSpanProcessor}from"#tracing/local-trace-span-processor.js";function installLocalInstrumentationRuntime(t){let n=getInstrumentationRuntime();if(n!==void 0)return n;let r=resolveLocalTraceRetentionSettings(),i=new AgentTraceSpanProcessor(r.enabled?[new LocalTraceSpanProcessor(t.appRoot)]:[]),a=new AgentSpanIdGenerator;registerOTel({autoDetectResources:!1,idGenerator:a,instrumentations:[],propagators:[`none`],serviceName:t.serviceName,spanProcessors:[i]});let o=trace.getTracer(`eve.registration`).startSpan(`eve.otel.registration`),s=trace.setSpan(context.active(),o),c=context.with(s,()=>trace.getActiveSpan()===o);if(o.end(),!i.isAttached()||!c)throw Error(`eve could not register OpenTelemetry because another runtime already exists.`);let l=createAgentOtelInstrumentation({captureContent:process.env.EVE_TRACES_CONTENT!==`off`,frameworkVersion:t.frameworkVersion,idGenerator:a,stateStore:new ContextAgentTraceStateStore,tracer:trace.getTracer(`eve.agent`,t.frameworkVersion)}),u={events:{"session.completed":releaseSessionTrace,"session.failed":releaseSessionTrace}};return requestPrune(),registerInstrumentationRuntime({forceFlush:()=>i.forceFlush(),hooks:createInstrumentationHooks([l.hook,u]),runInContext:l.runInContext});async function releaseSessionTrace(e){await i.forceFlush(),i.releaseSession(e.sessionId)&&requestPrune()}function requestPrune(){r.enabled&&requestLocalTraceStorePrune({activeTraceIds:i.activeTraceIds(),appRoot:t.appRoot,maxAgeMs:r.maxAgeMs,maxTotalBytes:r.maxTotalBytes,retainCount:r.retainCount})}}export{installLocalInstrumentationRuntime};
1
+ import{getInstrumentationRuntime}from"#harness/instrumentation-runtime.js";import{installInstrumentationRuntime}from"#tracing/install-instrumentation-runtime.js";import{collectOtelPipeline,otel,otelIntegration}from"#tracing/otel-declaration.js";import{createLocalTracesProcessor,resolveLocalTracesContent}from"#tracing/local-traces.js";function installLocalInstrumentationRuntime(e){let t=getInstrumentationRuntime();if(t!==void 0)return t;let n=createLocalTracesProcessor({appRoot:e.appRoot});return installInstrumentationRuntime({collected:collectOtelPipeline([otel(),otelIntegration({...resolveLocalTracesContent(),spanProcessors:[n]})]),frameworkVersion:e.frameworkVersion,providers:[],serviceName:e.serviceName})}export{installLocalInstrumentationRuntime};
@@ -0,0 +1,56 @@
1
+ import type { SpanProcessor } from "#compiled/@vercel/otel/index.js";
2
+ /**
3
+ * The local spool, as a span processor.
4
+ *
5
+ * Session liveness and retention live in here rather than in the runtime that
6
+ * installs it, so nothing an author puts in the same `spanProcessors` list can
7
+ * see them — and eve's accept filter never reaches an author's exporters.
8
+ */
9
+ export interface LocalTracesProcessor extends SpanProcessor {
10
+ /**
11
+ * Settles pending writes and drops one root session's liveness, then bounds
12
+ * the store. A subagent child owns no traces, so releasing one is a no-op
13
+ * and leaves the shared trace pinned until its root finishes.
14
+ */
15
+ releaseSession(sessionId: string): Promise<boolean>;
16
+ }
17
+ /**
18
+ * Reports whether a processor tracks which session owns which trace, so eve can
19
+ * tell it when that session is done.
20
+ *
21
+ * Anything standing between eve and the spool has to answer for the spool, so
22
+ * this is the check a wrapper uses to decide whether it must forward the call.
23
+ *
24
+ * @internal
25
+ */
26
+ export declare function hasSessionRelease(processor: SpanProcessor): processor is LocalTracesProcessor;
27
+ /**
28
+ * Writes the OTLP/JSON spool under `.eve/traces/v1`.
29
+ *
30
+ * `EVE_TRACES=off` removes the writer but keeps the processor: eve still has
31
+ * to observe spans to track which session owns which trace.
32
+ *
33
+ * Internal because of `releaseSession`, which eve's runtime drives off session
34
+ * lifecycle. The authored surface is `localTraces()`, which wraps this in an
35
+ * `OtelIntegration`.
36
+ */
37
+ export declare function createLocalTracesProcessor(input?: {
38
+ readonly appRoot?: string;
39
+ }): LocalTracesProcessor;
40
+ /**
41
+ * The local spool's content policy: its options, intersected with
42
+ * `EVE_TRACES_CONTENT`.
43
+ *
44
+ * The variable used to be the process-wide switch. It now applies to this one
45
+ * destination, and only ever narrows — `off` still wins where it applies, but
46
+ * it no longer decides what a hosted backend beside it receives.
47
+ *
48
+ * @internal
49
+ */
50
+ export declare function resolveLocalTracesContent(options?: {
51
+ readonly recordInputs?: boolean;
52
+ readonly recordOutputs?: boolean;
53
+ }): {
54
+ readonly recordInputs: boolean;
55
+ readonly recordOutputs: boolean;
56
+ };
@@ -0,0 +1 @@
1
+ import{LocalTraceSpanProcessor}from"#tracing/local-trace-span-processor.js";import{AgentTraceSpanProcessor}from"#tracing/agent-trace-span-processor.js";import{requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings}from"#tracing/local-trace-retention.js";function hasSessionRelease(e){return typeof e.releaseSession==`function`}function createLocalTracesProcessor(n={}){let r=n.appRoot??process.env.EVE_DEV_WORKER_APP_ROOT;if(r===void 0)return inertLocalTracesProcessor();let i=resolveLocalTraceRetentionSettings(),a=new AgentTraceSpanProcessor(i.enabled?[new LocalTraceSpanProcessor(r)]:[]),requestPrune=()=>{i.enabled&&requestLocalTraceStorePrune({activeTraceIds:a.activeTraceIds(),appRoot:r,maxAgeMs:i.maxAgeMs,maxTotalBytes:i.maxTotalBytes,retainCount:i.retainCount})};return requestPrune(),{forceFlush:()=>a.forceFlush(),onEnd:e=>a.onEnd(e),onStart:(e,t)=>a.onStart(e,t),async releaseSession(e){return await a.forceFlush(),a.releaseSession(e)?(requestPrune(),!0):!1},shutdown:()=>a.shutdown()}}function resolveLocalTracesContent(e={}){let t=process.env.EVE_TRACES_CONTENT!==`off`;return{recordInputs:t&&e.recordInputs!==!1,recordOutputs:t&&e.recordOutputs!==!1}}function inertLocalTracesProcessor(){return{forceFlush:async()=>void 0,onEnd:()=>void 0,onStart:()=>void 0,releaseSession:async()=>!1,shutdown:async()=>void 0}}export{createLocalTracesProcessor,hasSessionRelease,resolveLocalTracesContent};
@@ -0,0 +1,150 @@
1
+ import type { PropagatorOrName, SamplerOrName, SpanExporter, SpanProcessor, SpanProcessorOrName } from "#compiled/@vercel/otel/index.js";
2
+ import { type InstrumentationProvider } from "#public/instrumentation/provider.js";
3
+ import type { ResolvedContentOptions } from "#tracing/content-attributes.js";
4
+ /**
5
+ * The process-wide OpenTelemetry settings, declared by `otel()`.
6
+ *
7
+ * Everything here is a singleton, which is why it is one file: a process has
8
+ * one tracer provider, so it has one resource, one sampler, and one propagator
9
+ * set. Destinations are the plural half and live in `otelIntegration()`.
10
+ *
11
+ * `contextManager` and `instrumentations` are deliberately absent: eve's span
12
+ * nesting depends on the former, and the latter cannot reach anything eve
13
+ * imported before setup ran.
14
+ */
15
+ export interface OtelOptions {
16
+ /**
17
+ * The function identifier attached to telemetry spans
18
+ * (`ai.telemetry.functionId`). Defaults to the agent name.
19
+ */
20
+ readonly functionId?: string;
21
+ /**
22
+ * Whether to emit the inbound HTTP `SERVER` span that wraps each channel
23
+ * request — the parent of the turn trace and of any `hook.resume` or
24
+ * outgoing HTTP spans. Defaults to `false`.
25
+ */
26
+ readonly traceChannelRequests?: boolean;
27
+ /**
28
+ * Resource attributes merged into eve's own, which already carry the
29
+ * service name.
30
+ */
31
+ readonly resource?: Readonly<Record<string, unknown>>;
32
+ /**
33
+ * Head sampling, and it is global: it decides whether a span is created at
34
+ * all, so it thins eve's own sinks and the `traceparent` eve propagates
35
+ * along with your exporters. To thin one backend only, drop spans in a
36
+ * processor.
37
+ */
38
+ readonly sampler?: SamplerOrName;
39
+ /** Composed into one propagator. All inject; the first to extract wins. */
40
+ readonly propagators?: readonly PropagatorOrName[];
41
+ }
42
+ /**
43
+ * What one destination records of the conversation itself.
44
+ *
45
+ * Declining is per destination, not per process: content is written onto the
46
+ * span if any destination wants it, and one that declined never exports it. So
47
+ * an agent whose every destination declines still never materializes a prompt —
48
+ * the union of nothing is nothing — but a local spool and a hosted backend no
49
+ * longer have to agree.
50
+ */
51
+ export interface ContentOptions {
52
+ /** Record model prompts and tool call inputs. Defaults to `true`. */
53
+ readonly recordInputs?: boolean;
54
+ /** Record model responses and tool call outputs. Defaults to `true`. */
55
+ readonly recordOutputs?: boolean;
56
+ }
57
+ /** Where one `otelIntegration()` sends spans, and what it records. */
58
+ export interface OtelIntegrationOptions extends ContentOptions {
59
+ /** Merged into the pipeline in declaration order. */
60
+ readonly spanProcessors?: readonly SpanProcessor[];
61
+ /** Wrapped in eve's batching processor and appended after `spanProcessors`. */
62
+ readonly traceExporter?: SpanExporter;
63
+ }
64
+ declare const OTEL_DECLARATION: unique symbol;
65
+ declare const OTEL_INTEGRATION: unique symbol;
66
+ /**
67
+ * The declared OpenTelemetry pipeline settings. eve collects this before
68
+ * building the tracer provider, so it is a value rather than a side effect.
69
+ */
70
+ export interface OtelDeclaration extends InstrumentationProvider {
71
+ readonly [OTEL_DECLARATION]: true;
72
+ readonly options: OtelOptions;
73
+ }
74
+ /** One declared destination. A process may have as many as it has files. */
75
+ export interface OtelIntegration extends InstrumentationProvider {
76
+ readonly [OTEL_INTEGRATION]: true;
77
+ /** Resolved from `ContentOptions`, so the union does not re-apply defaults. */
78
+ readonly content: ResolvedContentOptions;
79
+ readonly spanProcessors: readonly SpanProcessorOrName[];
80
+ }
81
+ /**
82
+ * Declares the process-wide OpenTelemetry settings.
83
+ *
84
+ * Export it from `agent/instrumentation/otel.ts`. Omitting the file is the
85
+ * common case: eve registers the pipeline for whatever destinations are
86
+ * declared beside it, and this only names what those destinations share.
87
+ */
88
+ export declare function otel(options?: OtelOptions): OtelDeclaration;
89
+ /**
90
+ * Declares one destination for this agent's traces.
91
+ *
92
+ * A `traceExporter` is wrapped in eve's batching processor, which is what makes
93
+ * the one-line form of a hosted backend enough. Pass `spanProcessors` instead
94
+ * when the destination needs its own batching, sampling, or filtering.
95
+ *
96
+ * Declining content wraps every processor here, an author's included: they are
97
+ * this destination, and the point of declining is that nothing under it sees
98
+ * what was said.
99
+ */
100
+ export declare function otelIntegration(options?: OtelIntegrationOptions): OtelIntegration;
101
+ /** Vercel Agent Runs through the production request-context transport. @internal */
102
+ export declare function agentRunsIntegration(options?: ContentOptions): OtelIntegration;
103
+ export declare function resolveContentOptions(options: ContentOptions): ResolvedContentOptions;
104
+ export declare function isOtelDeclaration(value: unknown): value is OtelDeclaration;
105
+ export declare function isOtelIntegration(value: unknown): value is OtelIntegration;
106
+ /** The one pipeline a process can register. @internal */
107
+ export interface OtelPipeline {
108
+ readonly propagators?: readonly PropagatorOrName[];
109
+ readonly resource?: Readonly<Record<string, unknown>>;
110
+ readonly sampler?: SamplerOrName;
111
+ readonly spanProcessors: readonly SpanProcessorOrName[];
112
+ }
113
+ /** What the harness reads at turn time, as opposed to at registration. @internal */
114
+ export interface OtelHarnessSettings {
115
+ readonly functionId?: string;
116
+ readonly traceChannelRequests: boolean;
117
+ /**
118
+ * What to write onto a span at all, as opposed to what any one destination
119
+ * exports. `agent/instrumentation.ts` sets this directly; a provider
120
+ * directory arrives at it as the union of its destinations.
121
+ */
122
+ readonly recordInputs?: boolean;
123
+ readonly recordOutputs?: boolean;
124
+ }
125
+ /** @internal */
126
+ export interface CollectedOtel {
127
+ /**
128
+ * Whether anything declared OpenTelemetry. False means eve should leave the
129
+ * global tracer provider slot alone rather than register an empty pipeline.
130
+ */
131
+ readonly declared: boolean;
132
+ readonly pipeline: OtelPipeline;
133
+ readonly settings: OtelHarnessSettings;
134
+ }
135
+ /**
136
+ * Folds the declared values into the one pipeline a process can register.
137
+ *
138
+ * Destinations concatenate in declaration order. The singletons cannot: two
139
+ * `otel()` values is a boot error rather than a silent win for whichever eve
140
+ * happened to visit first. With one declaration per file that collision needs
141
+ * two files both exporting `otel()`, which is the only way to reach it.
142
+ *
143
+ * Content capture is the union of what the destinations asked for, because it
144
+ * governs what is written rather than what is exported. Each destination's own
145
+ * processors already drop what it declined.
146
+ *
147
+ * @internal
148
+ */
149
+ export declare function collectOtelPipeline(values: readonly unknown[]): CollectedOtel;
150
+ export {};
@@ -0,0 +1 @@
1
+ import{PROVIDER}from"#public/instrumentation/provider.js";import{batchSpanProcessor}from"#tracing/batch-span-processor.js";import{contentFilteringProcessor}from"#tracing/content-span-processor.js";import{vercelRuntimeSpanProcessor}from"#tracing/vercel-runtime-span-exporter.js";const OTEL_DECLARATION=Symbol.for(`eve.instrumentation.otel`),OTEL_INTEGRATION=Symbol.for(`eve.instrumentation.otel-integration`);function otel(t={}){return{[OTEL_DECLARATION]:!0,[PROVIDER]:!0,options:t}}function otelIntegration(r={}){let i={recordInputs:r.recordInputs!==!1,recordOutputs:r.recordOutputs!==!1},o=r.spanProcessors??[],s=r.traceExporter===void 0?o:[...o,batchSpanProcessor(r.traceExporter)];return{[OTEL_INTEGRATION]:!0,[PROVIDER]:!0,content:i,spanProcessors:i.recordInputs&&i.recordOutputs?s:s.map(e=>contentFilteringProcessor(e,i))}}function agentRunsIntegration(t={}){let i=resolveContentOptions(t);return{[OTEL_INTEGRATION]:!0,[PROVIDER]:!0,content:i,spanProcessors:i.recordInputs&&i.recordOutputs?[`auto`]:[contentFilteringProcessor(vercelRuntimeSpanProcessor(),i)]}}function resolveContentOptions(e){return{recordInputs:e.recordInputs!==!1,recordOutputs:e.recordOutputs!==!1}}function isOtelDeclaration(e){return typeof e==`object`&&!!e&&e[OTEL_DECLARATION]===!0}function isOtelIntegration(e){return typeof e==`object`&&!!e&&e[OTEL_INTEGRATION]===!0}function collectOtelPipeline(e){let t=[],n,r=!1,i=!1,a=!1;for(let o of e){if(isOtelIntegration(o)){r=!0,i||=o.content.recordInputs,a||=o.content.recordOutputs,t.push(...o.spanProcessors);continue}if(isOtelDeclaration(o)){if(n!==void 0)throw Error("Instrumentation declares `otel()` more than once. One process has one OpenTelemetry tracer provider, so it has one resource, one sampler, and one propagator set — declare them in a single `otel()`.");r=!0,n=o}}let o=n?.options??{};return{declared:r,pipeline:{propagators:o.propagators,resource:o.resource,sampler:o.sampler,spanProcessors:t},settings:{functionId:o.functionId,recordInputs:i,recordOutputs:a,traceChannelRequests:o.traceChannelRequests===!0}}}export{agentRunsIntegration,collectOtelPipeline,isOtelDeclaration,isOtelIntegration,otel,otelIntegration,resolveContentOptions};
@@ -0,0 +1,21 @@
1
+ import { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
2
+ import type { OtelPipeline } from "#tracing/otel-declaration.js";
3
+ /**
4
+ * Builds the process's one OpenTelemetry tracer provider from a merged
5
+ * declaration, then proves it took the global slot.
6
+ *
7
+ * `registerOTel` reports a refused registration only through `diag`, which
8
+ * goes nowhere unless `OTEL_LOG_LEVEL` is set, so a second caller would export
9
+ * nothing and say nothing. eve primes its id generator and installs a private
10
+ * propagator, then verifies both through the global APIs.
11
+ */
12
+ export declare function registerOtelPipeline(input: {
13
+ readonly pipeline: OtelPipeline;
14
+ readonly serviceName: string;
15
+ }): RegisteredOtelPipeline;
16
+ /** Lifecycle retained from the tracer provider that owns every destination. */
17
+ export interface RegisteredOtelPipeline {
18
+ readonly forceFlush: () => Promise<void>;
19
+ readonly idGenerator: AgentSpanIdGenerator;
20
+ readonly shutdown: () => Promise<void>;
21
+ }
@@ -0,0 +1 @@
1
+ import{context,propagation,trace}from"#compiled/@opentelemetry/api/index.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";import{AgentSpanIdGenerator}from"#tracing/agent-span-id-generator.js";const REGISTRATION_SPAN_NAME=`eve.otel.registration`,REPLAY_DEDUPLICATION_LIMIT=1e5;var RegistrationMarkerPropagator=class{#e=!1;extract(e){return e}fields(){return[]}inject(){this.#e=!0}isInstalled(){return this.#e=!1,propagation.inject(context.active(),{},{set:()=>{}}),this.#e}},PrivateSpanFilteringProcessor=class{endedSpans=new Set;forwardedSpans=new Set;pendingByParent=new Map;processors;startedSpans=new Set;constructor(e){this.processors=e}async forceFlush(){await Promise.all(this.processors.map(e=>e.forceFlush()))}onEnd(e){if(isRegistrationSpan(e))return;let t=spanIdentity(e);if(t!==void 0){if(this.endedSpans.has(t))return;if(this.endedSpans.size>=REPLAY_DEDUPLICATION_LIMIT){let e=this.endedSpans.values().next().value;e!==void 0&&this.endedSpans.delete(e)}this.endedSpans.add(t)}let n=parentIdentity(e);if(n!==void 0&&this.startedSpans.has(n)&&!this.forwardedSpans.has(n)){let t=this.pendingByParent.get(n)??[];t.push(e),this.pendingByParent.set(n,t);return}this.forward(e,t)}onStart(e,t){if(isRegistrationSpan(e))return;let n=spanIdentity(e);n!==void 0&&addBounded(this.startedSpans,n);for(let n of this.processors)n.onStart(e,t)}async shutdown(){await Promise.all(this.processors.map(e=>e.shutdown()))}forward(e,t){for(let t of this.processors)t.onEnd(e);if(t===void 0)return;addBounded(this.forwardedSpans,t);let n=this.pendingByParent.get(t);if(n!==void 0){this.pendingByParent.delete(t);for(let e of n)this.forward(e,spanIdentity(e))}}};function registerOtelPipeline(e){let{pipeline:t}=e,n=new AgentSpanIdGenerator,i=new RegistrationMarkerPropagator,a={attributes:t.resource,autoDetectResources:!1,idGenerator:n,instrumentations:[],propagators:[...t.propagators??[`none`],i],serviceName:e.serviceName,spanProcessors:t.spanProcessors.map(e=>isSpanProcessor(e)?new PrivateSpanFilteringProcessor([e]):e)};registerOTel(t.sampler===void 0?a:{...a,traceSampler:t.sampler});let o=globalTracerUses(n),s=i.isInstalled();if((!o||!s)&&rollbackRegistration({ownsPropagator:s,ownsTracer:o}),!o)throw Error("eve could not register OpenTelemetry because another runtime already owns the global tracer provider. Remove the other `registerOTel` call, or move its exporters into eve's `otelIntegration({ spanProcessors: [...] })`.");if(!s)throw Error("eve could not register OpenTelemetry because another runtime already owns the global propagator. Remove the other global propagator registration and declare propagators through eve's `otel()` instead.");let c=runtimeTracerProvider();if(typeof c.forceFlush!=`function`||typeof c.shutdown!=`function`)throw rollbackRegistration({ownsPropagator:s,ownsTracer:o}),Error(`The registered OpenTelemetry tracer provider has no lifecycle methods.`);return{forceFlush:()=>c.forceFlush(),idGenerator:n,shutdown:()=>c.shutdown()}}function rollbackRegistration(e){if(e.ownsPropagator&&propagation.disable(),!e.ownsTracer)return;let r=runtimeTracerProvider();if(typeof r.shutdown==`function`)try{r.shutdown().catch(()=>{})}catch{}trace.disable()}function runtimeTracerProvider(){let e=trace.getTracerProvider();return e.getDelegate?.()??e}function globalTracerUses(e){let t=e.allocateSpanId();return e.withSpanId(t,()=>trace.getTracer(`eve.registration`).startSpan(REGISTRATION_SPAN_NAME)).spanContext().spanId===t}function isRegistrationSpan(e){return typeof e==`object`&&!!e&&`name`in e&&e.name===REGISTRATION_SPAN_NAME}function spanIdentity(e){if(typeof e!=`object`||!e||!(`spanContext`in e)||typeof e.spanContext!=`function`)return;let t=e.spanContext();return typeof t.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function parentIdentity(e){if(typeof e!=`object`||!e||!(`parentSpanContext`in e))return;let t=e.parentSpanContext;return typeof t?.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function addBounded(e,t){if(e.size>=REPLAY_DEDUPLICATION_LIMIT){let t=e.values().next().value;t!==void 0&&e.delete(t)}e.add(t)}function isSpanProcessor(e){return e!==`auto`}export{registerOtelPipeline};
@@ -0,0 +1,5 @@
1
+ import type { SpanExporter, SpanProcessor } from "#compiled/@vercel/otel/index.js";
2
+ /** The request-context transport behind @vercel/otel's automatic processor. */
3
+ export declare function vercelRuntimeSpanExporter(): SpanExporter;
4
+ /** Reports immediately so the span stays attached to its request context. */
5
+ export declare function vercelRuntimeSpanProcessor(): SpanProcessor;
@@ -0,0 +1 @@
1
+ import{createLogger,formatError}from"#internal/logging.js";import{TraceFlags}from"#compiled/@opentelemetry/api/index.js";import{JsonTraceSerializer}from"#compiled/@opentelemetry/otlp-transformer/index.js";const VERCEL_REQUEST_CONTEXT=Symbol.for(`@vercel/request-context`),log=createLogger(`tracing.vercel-runtime-span-exporter`);function vercelRuntimeSpanExporter(){return{export(e,t){let n=globalThis[VERCEL_REQUEST_CONTEXT]?.get()?.telemetry;if(n===void 0){t({code:0});return}try{let i=JsonTraceSerializer.serializeRequest([...e]);if(i===void 0)throw Error(`Failed to serialize spans.`);n.reportSpans(JSON.parse(new TextDecoder().decode(i))),t({code:0})}catch(e){t({code:1,error:e instanceof Error?e:Error(String(e))})}},forceFlush:async()=>void 0,shutdown:async()=>void 0}}function vercelRuntimeSpanProcessor(){let e=vercelRuntimeSpanExporter(),n=!1;return{forceFlush:()=>e.forceFlush?.()??Promise.resolve(),onEnd(r){n||!isSampled(r)||e.export([r],e=>{e.code!==0&&log.warn(`Agent Runs export failed`,{error:formatError(e.error??Error(`Span export failed.`))})})},onStart(){},async shutdown(){n=!0,await e.shutdown()}}}function isSampled(e){if(typeof e!=`object`||!e||!(`spanContext`in e))return!1;let t=e.spanContext;if(typeof t!=`function`)return!1;let r=Reflect.apply(t,e,[]);return typeof r.traceFlags==`number`&&(r.traceFlags&TraceFlags.SAMPLED)===TraceFlags.SAMPLED}export{vercelRuntimeSpanExporter,vercelRuntimeSpanProcessor};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-3oBnxzhV.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-FJkEMXYk.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-3oBnxzhV.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-FJkEMXYk.js";
2
2
 
3
3
  export { useEveAgent };
@@ -58,6 +58,28 @@ You are responsible for ensuring any observability or eval provider is approved
58
58
 
59
59
  The third configurable surface, [runtime context events](#runtime-context), attaches per-model-call values to these spans.
60
60
 
61
+ ## Channel delivery traces
62
+
63
+ Instrumentation providers receive `channel.delivery.started` followed by
64
+ `channel.delivery.completed`, `channel.delivery.cancelled`, or
65
+ `channel.delivery.failed` for every inbound channel operation. The lifecycle
66
+ covers durable processing through the terminal state of the resulting turn, not
67
+ messages an adapter sends back to Slack, Telegram, Twilio, or another platform.
68
+ Several deliveries can coalesce into one turn while retaining separate lifecycle
69
+ pairs, and an adapter can consume a delivery without starting a turn.
70
+
71
+ Each operation has a framework-owned `deliveryId` distinct from its optional
72
+ platform request ID. Metadata-only providers receive identity, channel, session,
73
+ and outcome fields. Content providers additionally receive only eve's known
74
+ message, context, input-response, and output-schema fields; adapter-specific
75
+ payload fields are never projected.
76
+
77
+ The built-in OpenTelemetry provider maps each pair to an
78
+ `agent.channel.delivery` consumer span under the durable session window. When
79
+ `traceChannelRequests: true` creates an inbound HTTP server span, the delivery
80
+ span links to it with `eve.link.type=channel.request` rather than using the
81
+ short-lived request span as its parent.
82
+
61
83
  ## Runtime context
62
84
 
63
85
  _Runtime context_ is an [AI SDK concept](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text): a user-defined object that flows through a generation lifecycle. eve exposes it through `events["step.started"]`, a callback that runs once eve has assembled the model input for an attempt and returns `{ runtimeContext }`. Because eve registers the AI SDK's OpenTelemetry integration with runtime context enabled, those returned values ride onto the model-call span and its children. The field is named `runtimeContext`, not `metadata`, because AI SDK v7 carries per-call attributes on runtime context rather than a dedicated metadata field.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.33.2",
3
+ "version": "0.34.0",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -206,6 +206,11 @@
206
206
  "import": "./dist/src/public/instrumentation/index.js",
207
207
  "default": "./dist/src/public/instrumentation/index.js"
208
208
  },
209
+ "./instrumentation/otel": {
210
+ "types": "./dist/src/public/instrumentation/otel.d.ts",
211
+ "import": "./dist/src/public/instrumentation/otel.js",
212
+ "default": "./dist/src/public/instrumentation/otel.js"
213
+ },
209
214
  "./schedules": {
210
215
  "types": "./dist/src/public/schedules/index.d.ts",
211
216
  "import": "./dist/src/public/schedules/index.js",
@@ -307,6 +312,7 @@
307
312
  "@clack/core": "1.3.1",
308
313
  "@nuxt/kit": "^4.0.0",
309
314
  "@opentelemetry/context-async-hooks": "2.6.1",
315
+ "@opentelemetry/core": "2.6.1",
310
316
  "@opentelemetry/otlp-transformer": "0.214.0",
311
317
  "@opentelemetry/sdk-trace-base": "2.6.1",
312
318
  "@photon-ai/chat-adapter-imessage": "3.2.0",
@@ -1,12 +0,0 @@
1
- import { type Telemetry } from "ai";
2
- /**
3
- * Registers the AI SDK OpenTelemetry integration once so that model
4
- * calls emit OTel spans, including runtime-context attributes. Safe to
5
- * call multiple times — only the first call has an effect.
6
- *
7
- * In AI SDK v7 the built-in OTel tracing was moved to `@ai-sdk/otel`
8
- * and must be registered explicitly.
9
- */
10
- export declare function ensureOtelIntegration(): void;
11
- /** Creates the existing OTel integration for explicit per-call composition. */
12
- export declare function createOtelIntegration(): Telemetry;
@@ -1 +0,0 @@
1
- import{registerTelemetry}from"ai";import{OpenTelemetry}from"#compiled/@ai-sdk/otel/index.js";let registered=!1;function ensureOtelIntegration(){registered||(registered=!0,registerTelemetry(createOtelIntegration()))}function createOtelIntegration(){return new OpenTelemetry({runtimeContext:!0})}export{createOtelIntegration,ensureOtelIntegration};