eve 0.33.3 → 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 (225) hide show
  1. package/CHANGELOG.md +22 -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/githubChannel.d.ts +3 -3
  144. package/dist/src/public/channels/github/githubChannel.js +1 -1
  145. package/dist/src/public/channels/slack/defaults.js +3 -3
  146. package/dist/src/public/channels/slack/interactions.js +1 -1
  147. package/dist/src/public/channels/slack/slackChannel.d.ts +11 -3
  148. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  149. package/dist/src/public/definitions/approval.d.ts +57 -16
  150. package/dist/src/public/definitions/approval.js +1 -1
  151. package/dist/src/public/definitions/channel.d.ts +2 -2
  152. package/dist/src/public/definitions/channel.js +1 -1
  153. package/dist/src/public/definitions/hook.d.ts +4 -2
  154. package/dist/src/public/instrumentation/index.d.ts +32 -17
  155. package/dist/src/public/instrumentation/index.js +1 -1
  156. package/dist/src/public/instrumentation/otel.d.ts +31 -0
  157. package/dist/src/public/instrumentation/otel.js +1 -0
  158. package/dist/src/public/instrumentation/provider.d.ts +117 -0
  159. package/dist/src/public/instrumentation/provider.js +1 -0
  160. package/dist/src/public/tools/approval/approval-helpers.d.ts +4 -4
  161. package/dist/src/public/tools/index.d.ts +1 -1
  162. package/dist/src/runtime/actions/results.d.ts +3 -3
  163. package/dist/src/runtime/attributes/emit.js +1 -1
  164. package/dist/src/runtime/connections/principal.d.ts +3 -0
  165. package/dist/src/runtime/connections/principal.js +1 -1
  166. package/dist/src/runtime/connections/scoped-authorization.d.ts +3 -5
  167. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  168. package/dist/src/runtime/connections/types.d.ts +5 -0
  169. package/dist/src/runtime/resolve-agent.js +1 -1
  170. package/dist/src/runtime/resolve-tool.js +1 -1
  171. package/dist/src/setup/index.d.ts +1 -0
  172. package/dist/src/setup/index.js +1 -1
  173. package/dist/src/setup/scaffold/create/project.js +1 -1
  174. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  175. package/dist/src/setup/verified-remote-agent.d.ts +30 -0
  176. package/dist/src/setup/verified-remote-agent.js +1 -0
  177. package/dist/src/shared/agent-definition.d.ts +9 -0
  178. package/dist/src/shared/channel-definition.d.ts +3 -1
  179. package/dist/src/svelte/index.js +1 -1
  180. package/dist/src/svelte/use-eve-agent.js +1 -1
  181. package/dist/src/tracing/agent-action-instrumentation.d.ts +31 -0
  182. package/dist/src/tracing/agent-action-instrumentation.js +1 -0
  183. package/dist/src/tracing/agent-approval-instrumentation.d.ts +13 -0
  184. package/dist/src/tracing/agent-approval-instrumentation.js +1 -0
  185. package/dist/src/tracing/agent-channel-delivery-instrumentation.d.ts +13 -0
  186. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -0
  187. package/dist/src/tracing/agent-otel-content.d.ts +6 -0
  188. package/dist/src/tracing/agent-otel-content.js +2 -2
  189. package/dist/src/tracing/agent-otel-provider.d.ts +7 -7
  190. package/dist/src/tracing/agent-otel-provider.js +2 -2
  191. package/dist/src/tracing/agent-otel-usage.d.ts +4 -0
  192. package/dist/src/tracing/agent-otel-usage.js +1 -0
  193. package/dist/src/tracing/agent-span-id-generator.d.ts +2 -0
  194. package/dist/src/tracing/agent-span-id-generator.js +1 -1
  195. package/dist/src/tracing/agent-tool-instrumentation.d.ts +28 -0
  196. package/dist/src/tracing/agent-tool-instrumentation.js +1 -0
  197. package/dist/src/tracing/agent-trace-context-store.d.ts +8 -1
  198. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  199. package/dist/src/tracing/agent-trace-span-processor.d.ts +0 -1
  200. package/dist/src/tracing/agent-trace-span-processor.js +1 -1
  201. package/dist/src/tracing/agent-trace-state.d.ts +33 -3
  202. package/dist/src/tracing/agent-trace-state.js +1 -1
  203. package/dist/src/tracing/batch-span-processor.d.ts +20 -0
  204. package/dist/src/tracing/batch-span-processor.js +1 -0
  205. package/dist/src/tracing/content-attributes.d.ts +28 -0
  206. package/dist/src/tracing/content-attributes.js +1 -0
  207. package/dist/src/tracing/content-span-processor.d.ts +19 -0
  208. package/dist/src/tracing/content-span-processor.js +1 -0
  209. package/dist/src/tracing/install-instrumentation-runtime.d.ts +19 -0
  210. package/dist/src/tracing/install-instrumentation-runtime.js +1 -0
  211. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  212. package/dist/src/tracing/local-traces.d.ts +56 -0
  213. package/dist/src/tracing/local-traces.js +1 -0
  214. package/dist/src/tracing/otel-declaration.d.ts +150 -0
  215. package/dist/src/tracing/otel-declaration.js +1 -0
  216. package/dist/src/tracing/otel-registration.d.ts +21 -0
  217. package/dist/src/tracing/otel-registration.js +1 -0
  218. package/dist/src/tracing/vercel-runtime-span-exporter.d.ts +5 -0
  219. package/dist/src/tracing/vercel-runtime-span-exporter.js +1 -0
  220. package/dist/src/vue/index.js +1 -1
  221. package/dist/src/vue/use-eve-agent.js +1 -1
  222. package/docs/guides/instrumentation.md +22 -0
  223. package/package.json +7 -1
  224. package/dist/src/harness/otel-integration.d.ts +0 -12
  225. package/dist/src/harness/otel-integration.js +0 -1
@@ -1,6 +1,13 @@
1
- import type { Telemetry } from "ai";
2
- type TelemetryEvent<TKey extends keyof Telemetry> = Parameters<NonNullable<Telemetry[TKey]>>[0];
3
- /** Stable eve identity for one actual model attempt. */
1
+ import type { InstrumentationStateSlot } from "#harness/instrumentation-state.js";
2
+ /**
3
+ * Stable eve identity for one actual model attempt.
4
+ *
5
+ * A step retried three times produces three of these, all sharing `stepIndex`
6
+ * and separated by `attemptIndex` — which is why the events carrying this
7
+ * scope are named `step.attempt.*` and not `step.*`. The protocol's `step.*`
8
+ * and the `events["step.started"]` resolver hook fire once per step; these
9
+ * fire once per attempt.
10
+ */
4
11
  export interface InstrumentationAttemptScope {
5
12
  readonly attemptId: string;
6
13
  readonly attemptIndex: number;
@@ -10,16 +17,204 @@ export interface InstrumentationAttemptScope {
10
17
  readonly stepIndex: number;
11
18
  readonly turnId: string;
12
19
  }
13
- export interface InstrumentationAttemptStartedEvent {
14
- readonly type: "attempt.started";
20
+ /** The model SDK operation an attempt runs through. */
21
+ export interface InstrumentationOperationRef {
22
+ readonly modelId: string;
23
+ readonly operationId: string;
24
+ readonly provider: string;
25
+ }
26
+ export interface InstrumentationModelRef {
27
+ readonly modelId: string;
28
+ readonly provider: string;
29
+ }
30
+ /** Token usage for one model call. A field is absent when the provider omits it. */
31
+ export interface InstrumentationUsage {
32
+ readonly inputTokenDetails?: {
33
+ readonly cacheReadTokens?: number;
34
+ readonly cacheWriteTokens?: number;
35
+ };
36
+ readonly inputTokens?: number;
37
+ readonly outputTokens?: number;
38
+ }
39
+ /** Final model input for one call. Message shape stays opaque to this layer. */
40
+ export interface InstrumentationModelInput {
41
+ readonly instructions?: unknown;
42
+ readonly messages: readonly unknown[];
43
+ }
44
+ /**
45
+ * The model response parts eve records. A kind outside this union is dropped
46
+ * when the bridge maps a response, so widening the union is what makes a new
47
+ * kind reachable by a provider.
48
+ */
49
+ export type InstrumentationContentPart = {
50
+ readonly type: "text";
51
+ readonly text: string;
52
+ } | {
53
+ readonly type: "reasoning";
54
+ readonly text: string;
55
+ } | {
56
+ readonly type: "tool-call";
57
+ readonly callId: string;
58
+ readonly input: unknown;
59
+ readonly toolName: string;
60
+ } | {
61
+ readonly type: "tool-result";
62
+ readonly callId: string;
63
+ readonly input: unknown;
64
+ readonly output: unknown;
65
+ readonly toolName: string;
66
+ } | {
67
+ readonly type: "tool-error";
68
+ readonly callId: string;
69
+ readonly error: unknown;
70
+ readonly input: unknown;
71
+ readonly toolName: string;
72
+ };
73
+ /**
74
+ * What eve dispatched an action as. The model sees every action as a tool, so
75
+ * this is the only thing that separates a subagent or remote-agent call from an
76
+ * ordinary tool in a trace.
77
+ */
78
+ export type InstrumentationActionKind = "load-skill" | "remote-agent-call" | "subagent-call" | "tool-call";
79
+ /**
80
+ * How one action ended.
81
+ *
82
+ * `type` survives a provider that declined content, so whether the tool errored
83
+ * is answerable without seeing what it returned.
84
+ */
85
+ export type InstrumentationActionOutput = {
86
+ readonly type: "result";
87
+ readonly output?: unknown;
88
+ } | {
89
+ readonly type: "error";
90
+ readonly error?: unknown;
91
+ };
92
+ /**
93
+ * How much of an event a provider is handed.
94
+ *
95
+ * `"metadata"` — the default — is structure, identity, usage, and timing: every
96
+ * field except what the conversation actually said. `"content"` adds the
97
+ * prompt, the response, tool arguments, and tool results.
98
+ *
99
+ * Declared per provider rather than per process, because two consumers of one
100
+ * bus rarely have the same retention path. Content is built at all only when
101
+ * some provider asked for it, and a provider that did not ask never receives
102
+ * it — which is the same guarantee a destination that declines content gets,
103
+ * one layer lower and without an OpenTelemetry pipeline to route it through.
104
+ */
105
+ export type InstrumentationCapture = "content" | "metadata";
106
+ /**
107
+ * Every event carries an `idempotencyKey` naming the operation it is about: a
108
+ * start and its terminal share one, and two operations never collide.
109
+ *
110
+ * Every part is identity eve reconstructs on replay — session and turn ids,
111
+ * `scope.attemptId` (itself `session:turn:step:attempt`), AI SDK step number,
112
+ * and durable runtime-action call ids. A provider writing rows can use the key
113
+ * as its row id and be idempotent by construction.
114
+ */
115
+ export declare function sessionIdempotencyKey(sessionId: string): string;
116
+ export declare function turnIdempotencyKey(sessionId: string, turnId: string): string;
117
+ export declare function attemptIdempotencyKey(scope: InstrumentationAttemptScope): string;
118
+ /** One model call occurs per AI SDK step within an eve attempt. */
119
+ export declare function modelCallIdempotencyKey(scope: InstrumentationAttemptScope, stepNumber: number): string;
120
+ export declare function toolCallIdempotencyKey(scope: InstrumentationAttemptScope, callId: string, stepNumber: number): string;
121
+ export declare function inputIdempotencyKey(sessionId: string, turnId: string, requestId: string): string;
122
+ export declare function channelDeliveryIdempotencyKey(sessionId: string, deliveryId: string): string;
123
+ export interface InstrumentationChannelDeliveryRef {
124
+ readonly channelKind: string;
125
+ readonly channelName: string;
126
+ readonly deliveryId: string;
127
+ readonly requestId?: string;
128
+ readonly requestTraceContext?: InstrumentationTraceContext;
129
+ }
130
+ /** Known framework delivery input; adapter-specific fields are never projected. */
131
+ export interface InstrumentationChannelDeliveryInput {
132
+ readonly context?: readonly string[];
133
+ readonly inputResponses?: readonly InstrumentationInputResponse[];
134
+ readonly message?: unknown;
135
+ readonly outputSchema?: unknown;
136
+ }
137
+ interface InstrumentationChannelDeliveryScope {
138
+ readonly agentName?: string;
139
+ readonly delivery: InstrumentationChannelDeliveryRef;
140
+ readonly idempotencyKey: string;
141
+ readonly rootSessionId: string;
142
+ readonly sequence?: number;
143
+ readonly sessionId: string;
144
+ readonly turnId?: string;
145
+ }
146
+ export interface InstrumentationChannelDeliveryStartedEvent extends InstrumentationChannelDeliveryScope {
147
+ readonly parentTraceContext?: InstrumentationTraceContext;
148
+ readonly type: "channel.delivery.started";
149
+ /** Content. Absent unless this provider declared `capture: "content"`. */
150
+ readonly input?: InstrumentationChannelDeliveryInput;
151
+ }
152
+ export type InstrumentationChannelDeliveryOutcome = "cancelled" | "completed" | "failed";
153
+ export interface InstrumentationChannelDeliveryTerminalEvent extends InstrumentationChannelDeliveryScope {
154
+ readonly type: "channel.delivery.cancelled" | "channel.delivery.completed" | "channel.delivery.failed";
155
+ /** Content. Absent unless this provider declared `capture: "content"`. */
156
+ readonly error?: unknown;
157
+ readonly errorCode?: string;
158
+ readonly outcome: InstrumentationChannelDeliveryOutcome;
159
+ }
160
+ /** Framework-owned reason an agent suspended for user input. */
161
+ export type InstrumentationInputKind = "question" | "session-limit" | "tool-approval";
162
+ export interface InstrumentationInputOption {
163
+ readonly description?: string;
164
+ readonly id: string;
165
+ readonly label: string;
166
+ readonly style?: "danger" | "default" | "primary";
167
+ }
168
+ /** User-facing input request content projected without runtime-owned types. */
169
+ export interface InstrumentationInputRequest {
170
+ readonly allowFreeform?: boolean;
171
+ readonly display?: "confirmation" | "select" | "text";
172
+ readonly options?: readonly InstrumentationInputOption[];
173
+ readonly prompt: string;
174
+ }
175
+ /** User response content projected without runtime-owned types. */
176
+ export interface InstrumentationInputResponse {
177
+ readonly optionId?: string;
178
+ readonly text?: string;
179
+ }
180
+ export type InstrumentationInputOutcome = "answered" | "approved" | "cancelled" | "denied" | "failed" | "ignored" | "invalid";
181
+ export interface InstrumentationInputRequestedEvent {
182
+ readonly type: "input.requested";
183
+ readonly action: {
184
+ readonly callId: string;
185
+ readonly name: string;
186
+ };
187
+ readonly idempotencyKey: string;
188
+ readonly kind: InstrumentationInputKind;
189
+ /** Content. Absent unless this provider declared `capture: "content"`. */
190
+ readonly request?: InstrumentationInputRequest;
191
+ readonly requestId: string;
192
+ readonly scope: InstrumentationAttemptScope;
193
+ }
194
+ export interface InstrumentationInputResolvedEvent {
195
+ readonly type: "input.resolved";
196
+ readonly error?: unknown;
197
+ readonly idempotencyKey: string;
198
+ readonly kind: InstrumentationInputKind;
199
+ readonly outcome: InstrumentationInputOutcome;
200
+ readonly requestId: string;
201
+ /** Content. Absent unless this provider declared `capture: "content"`. */
202
+ readonly response?: InstrumentationInputResponse;
203
+ readonly scope: InstrumentationAttemptScope;
204
+ }
205
+ /** Runtime action call IDs are durable and unique within one session. */
206
+ export declare function actionIdempotencyKey(sessionId: string, turnId: string, callId: string): string;
207
+ export interface InstrumentationStepAttemptStartedEvent {
208
+ readonly type: "step.attempt.started";
209
+ readonly idempotencyKey: string;
210
+ readonly operation: InstrumentationOperationRef;
15
211
  readonly scope: InstrumentationAttemptScope;
16
- readonly operation: TelemetryEvent<"onStart">;
17
- readonly step: TelemetryEvent<"onStepStart">;
18
212
  }
19
213
  export interface InstrumentationSessionStartedEvent {
20
214
  readonly type: "session.started";
21
215
  readonly agentName?: string;
22
216
  readonly channelKind?: string;
217
+ readonly idempotencyKey: string;
23
218
  readonly parentTraceContext?: InstrumentationTraceContext;
24
219
  readonly rootSessionId: string;
25
220
  readonly sessionId: string;
@@ -39,14 +234,31 @@ export interface InstrumentationParentLineage {
39
234
  readonly subagentName?: string;
40
235
  readonly turnId: string;
41
236
  }
42
- export interface InstrumentationSessionTransitionEvent {
43
- readonly type: "session.completed" | "session.failed" | "session.waiting";
237
+ /**
238
+ * A session transition that carries no failure.
239
+ *
240
+ * `session.waiting` sits here rather than with the failed shape because it is
241
+ * not terminal: the session suspends awaiting input or approval and may resume
242
+ * with a new turn.
243
+ */
244
+ export interface InstrumentationSessionSettledEvent {
245
+ readonly type: "session.completed" | "session.waiting";
246
+ readonly idempotencyKey: string;
247
+ readonly sessionId: string;
248
+ readonly turnId?: string;
249
+ }
250
+ export interface InstrumentationSessionFailedEvent {
251
+ readonly type: "session.failed";
252
+ /** Content. Absent unless this provider declared `capture: "content"`. */
44
253
  readonly error?: unknown;
254
+ readonly idempotencyKey: string;
45
255
  readonly sessionId: string;
46
256
  readonly turnId?: string;
47
257
  }
258
+ export type InstrumentationSessionTransitionEvent = InstrumentationSessionSettledEvent | InstrumentationSessionFailedEvent;
48
259
  export interface InstrumentationTurnStartedEvent {
49
260
  readonly type: "turn.started";
261
+ readonly idempotencyKey: string;
50
262
  readonly parentLineage?: InstrumentationParentLineage;
51
263
  readonly parentTraceContext?: InstrumentationTraceContext;
52
264
  readonly rootSessionId: string;
@@ -54,118 +266,229 @@ export interface InstrumentationTurnStartedEvent {
54
266
  readonly sessionId: string;
55
267
  readonly turnId: string;
56
268
  }
57
- export interface InstrumentationTurnTerminalEvent {
58
- readonly type: "turn.cancelled" | "turn.completed" | "turn.failed";
269
+ /**
270
+ * A turn that ended without a failure.
271
+ *
272
+ * `turn.cancelled` sits here rather than with the failed shape because
273
+ * cancellation is not an error: the harness settles a cancelled turn as
274
+ * `turn.cancelled` → `session.waiting`, with no failure surfaced anywhere.
275
+ */
276
+ export interface InstrumentationTurnSettledEvent {
277
+ readonly type: "turn.cancelled" | "turn.completed";
278
+ readonly idempotencyKey: string;
279
+ readonly sessionId: string;
280
+ readonly turnId: string;
281
+ }
282
+ export interface InstrumentationTurnFailedEvent {
283
+ readonly type: "turn.failed";
284
+ /** Content. Absent unless this provider declared `capture: "content"`. */
59
285
  readonly error?: unknown;
286
+ readonly idempotencyKey: string;
60
287
  readonly sessionId: string;
61
288
  readonly turnId: string;
62
289
  }
63
- export interface InstrumentationAttemptTerminalEvent {
64
- readonly type: "attempt.completed" | "attempt.failed";
290
+ export type InstrumentationTurnTerminalEvent = InstrumentationTurnSettledEvent | InstrumentationTurnFailedEvent;
291
+ export interface InstrumentationStepAttemptCompletedEvent {
292
+ readonly type: "step.attempt.completed";
293
+ readonly idempotencyKey: string;
294
+ readonly scope: InstrumentationAttemptScope;
295
+ }
296
+ export interface InstrumentationStepAttemptFailedEvent {
297
+ readonly type: "step.attempt.failed";
298
+ /** Content. Absent unless this provider declared `capture: "content"`. */
65
299
  readonly error?: unknown;
300
+ readonly idempotencyKey: string;
66
301
  readonly scope: InstrumentationAttemptScope;
67
302
  }
303
+ export type InstrumentationStepAttemptTerminalEvent = InstrumentationStepAttemptCompletedEvent | InstrumentationStepAttemptFailedEvent;
68
304
  /**
69
- * Provider metadata for one completed step, as reported by the AI SDK
305
+ * Provider metadata for one completed attempt, as reported by the AI SDK
70
306
  * (`StepResult.providerMetadata`). Carries Vercel AI Gateway cost data when
71
307
  * the request went through the gateway; absent for other providers.
72
308
  */
73
- export interface InstrumentationAttemptMetadataEvent {
74
- readonly type: "attempt.metadata";
309
+ export interface InstrumentationStepAttemptMetadataEvent {
310
+ readonly type: "step.attempt.metadata";
311
+ readonly idempotencyKey: string;
75
312
  readonly scope: InstrumentationAttemptScope;
76
313
  readonly providerMetadata: Readonly<Record<string, unknown>>;
77
314
  }
78
315
  export interface InstrumentationModelCallStartedEvent {
79
316
  readonly type: "model.call.started";
80
- readonly id: string;
317
+ readonly idempotencyKey: string;
318
+ /** Content. Absent unless this provider declared `capture: "content"`. */
319
+ readonly input?: InstrumentationModelInput;
320
+ readonly model: InstrumentationModelRef;
81
321
  readonly scope: InstrumentationAttemptScope;
82
- readonly source: TelemetryEvent<"onLanguageModelCallStart">;
83
322
  }
84
323
  export interface InstrumentationModelCallCompletedEvent {
85
324
  readonly type: "model.call.completed";
86
- readonly id: string;
325
+ /** Content. Absent unless this provider declared `capture: "content"`. */
326
+ readonly content?: readonly InstrumentationContentPart[];
327
+ readonly finishReason: string;
328
+ readonly idempotencyKey: string;
87
329
  readonly scope: InstrumentationAttemptScope;
88
- readonly source: TelemetryEvent<"onLanguageModelCallEnd">;
330
+ readonly usage: InstrumentationUsage;
89
331
  }
90
332
  export interface InstrumentationModelCallFailedEvent {
91
333
  readonly type: "model.call.failed";
92
- readonly error: unknown;
93
- readonly id: string;
334
+ /** Content. Absent unless this provider declared `capture: "content"`. */
335
+ readonly error?: unknown;
336
+ readonly idempotencyKey: string;
94
337
  readonly scope: InstrumentationAttemptScope;
95
338
  }
96
339
  export type InstrumentationModelCallTerminalEvent = InstrumentationModelCallCompletedEvent | InstrumentationModelCallFailedEvent;
340
+ export type InstrumentationToolOutput = InstrumentationActionOutput;
97
341
  export interface InstrumentationToolCallStartedEvent {
98
342
  readonly type: "tool.call.started";
99
- readonly id: string;
343
+ readonly callId: string;
344
+ readonly idempotencyKey: string;
345
+ readonly input: unknown;
100
346
  readonly scope: InstrumentationAttemptScope;
101
- readonly source: TelemetryEvent<"onToolExecutionStart">;
347
+ readonly toolName: string;
102
348
  }
103
349
  export interface InstrumentationToolCallCompletedEvent {
104
350
  readonly type: "tool.call.completed";
105
- readonly id: string;
351
+ readonly idempotencyKey: string;
352
+ readonly output: InstrumentationToolOutput;
106
353
  readonly scope: InstrumentationAttemptScope;
107
- readonly source: TelemetryEvent<"onToolExecutionEnd">;
108
354
  }
109
355
  export interface InstrumentationToolCallFailedEvent {
110
356
  readonly type: "tool.call.failed";
111
- readonly error: unknown;
112
- readonly id: string;
357
+ /** Content. Absent unless this provider declared `capture: "content"`. */
358
+ readonly error?: unknown;
359
+ readonly idempotencyKey: string;
113
360
  readonly scope: InstrumentationAttemptScope;
114
361
  }
115
362
  export type InstrumentationToolCallTerminalEvent = InstrumentationToolCallCompletedEvent | InstrumentationToolCallFailedEvent;
116
- export interface RelatedLifecycleHook<TStart, TTerminal> {
117
- readonly before?: (event: TStart) => unknown | PromiseLike<unknown>;
118
- readonly after?: (event: TTerminal, state: unknown) => void | PromiseLike<void>;
363
+ /**
364
+ * One thing the agent did on the model's behalf. `kind` is what separates a
365
+ * subagent or remote-agent call from an ordinary tool; `name` is the name the
366
+ * model called, which is the tool name for every kind.
367
+ */
368
+ export interface InstrumentationActionStartedEvent {
369
+ readonly type: "action.started";
370
+ readonly callId: string;
371
+ readonly idempotencyKey: string;
372
+ /** Content. Absent unless this provider declared `capture: "content"`. */
373
+ readonly input?: unknown;
374
+ readonly kind: InstrumentationActionKind;
375
+ readonly name: string;
376
+ readonly scope: InstrumentationAttemptScope;
377
+ }
378
+ export type InstrumentationActionOutcome = "abandoned" | "cancelled" | "completed" | "failed" | "rejected";
379
+ export interface InstrumentationActionCompletedEvent {
380
+ readonly type: "action.completed";
381
+ readonly acceptedAtMs?: number;
382
+ readonly idempotencyKey: string;
383
+ readonly outcome: "completed";
384
+ readonly output: InstrumentationActionOutput;
385
+ readonly scope: InstrumentationAttemptScope;
386
+ readonly usage?: InstrumentationUsage;
387
+ }
388
+ export interface InstrumentationActionFailedEvent {
389
+ readonly type: "action.failed";
390
+ readonly acceptedAtMs?: number;
391
+ /** Content. Absent unless this provider declared `capture: "content"`. */
392
+ readonly error?: unknown;
393
+ readonly errorCode?: string;
394
+ readonly idempotencyKey: string;
395
+ readonly outcome: Exclude<InstrumentationActionOutcome, "completed">;
396
+ readonly scope: InstrumentationAttemptScope;
397
+ }
398
+ export type InstrumentationActionTerminalEvent = InstrumentationActionCompletedEvent | InstrumentationActionFailedEvent;
399
+ /** The second argument to every handler. */
400
+ export interface InstrumentationHandlerContext {
401
+ /** Durable state scoped to this provider and this operation. */
402
+ readonly state: InstrumentationStateSlot;
119
403
  }
404
+ /**
405
+ * The AI SDK can omit a model terminal when an incomplete stream closes. A
406
+ * handler can use `ctx.state` for durable correlation when a terminal arrives,
407
+ * but providers must scope live resources to the attempt and release anything
408
+ * still open when the step attempt terminates.
409
+ */
410
+ export type InstrumentationEventHandler<TEvent> = (event: TEvent, ctx: InstrumentationHandlerContext) => void | PromiseLike<void>;
120
411
  /** Internal provider shape mirrored by the future public hook contract. */
121
412
  export interface InstrumentationProviderDefinition {
413
+ readonly name: string;
414
+ /** Durable state identity, separate from the human-readable log name. */
415
+ readonly stateNamespace?: string;
416
+ /** Defaults to `"metadata"`. See {@link InstrumentationCapture}. */
417
+ readonly capture?: InstrumentationCapture;
122
418
  readonly events?: {
123
- readonly "model.call"?: RelatedLifecycleHook<InstrumentationModelCallStartedEvent, InstrumentationModelCallTerminalEvent>;
124
- readonly "attempt.started"?: (event: InstrumentationAttemptStartedEvent) => void | PromiseLike<void>;
125
- readonly "attempt.completed"?: (event: InstrumentationAttemptTerminalEvent) => void | PromiseLike<void>;
126
- readonly "attempt.failed"?: (event: InstrumentationAttemptTerminalEvent) => void | PromiseLike<void>;
127
- readonly "attempt.metadata"?: (event: InstrumentationAttemptMetadataEvent) => void | PromiseLike<void>;
128
- readonly "session.completed"?: (event: InstrumentationSessionTransitionEvent) => void | PromiseLike<void>;
129
- readonly "session.failed"?: (event: InstrumentationSessionTransitionEvent) => void | PromiseLike<void>;
130
- readonly "session.started"?: (event: InstrumentationSessionStartedEvent) => void | PromiseLike<void>;
131
- readonly "session.waiting"?: (event: InstrumentationSessionTransitionEvent) => void | PromiseLike<void>;
132
- readonly "tool.call"?: RelatedLifecycleHook<InstrumentationToolCallStartedEvent, InstrumentationToolCallTerminalEvent>;
133
- readonly "turn.cancelled"?: (event: InstrumentationTurnTerminalEvent) => void | PromiseLike<void>;
134
- readonly "turn.completed"?: (event: InstrumentationTurnTerminalEvent) => void | PromiseLike<void>;
135
- readonly "turn.failed"?: (event: InstrumentationTurnTerminalEvent) => void | PromiseLike<void>;
136
- readonly "turn.started"?: (event: InstrumentationTurnStartedEvent) => void | PromiseLike<void>;
419
+ readonly "channel.delivery.started"?: InstrumentationEventHandler<InstrumentationChannelDeliveryStartedEvent>;
420
+ readonly "channel.delivery.cancelled"?: InstrumentationEventHandler<InstrumentationChannelDeliveryTerminalEvent>;
421
+ readonly "channel.delivery.completed"?: InstrumentationEventHandler<InstrumentationChannelDeliveryTerminalEvent>;
422
+ readonly "channel.delivery.failed"?: InstrumentationEventHandler<InstrumentationChannelDeliveryTerminalEvent>;
423
+ readonly "step.attempt.started"?: InstrumentationEventHandler<InstrumentationStepAttemptStartedEvent>;
424
+ readonly "step.attempt.completed"?: InstrumentationEventHandler<InstrumentationStepAttemptCompletedEvent>;
425
+ readonly "step.attempt.failed"?: InstrumentationEventHandler<InstrumentationStepAttemptFailedEvent>;
426
+ readonly "step.attempt.metadata"?: InstrumentationEventHandler<InstrumentationStepAttemptMetadataEvent>;
427
+ readonly "model.call.started"?: InstrumentationEventHandler<InstrumentationModelCallStartedEvent>;
428
+ readonly "model.call.completed"?: InstrumentationEventHandler<InstrumentationModelCallCompletedEvent>;
429
+ readonly "model.call.failed"?: InstrumentationEventHandler<InstrumentationModelCallFailedEvent>;
430
+ readonly "input.requested"?: InstrumentationEventHandler<InstrumentationInputRequestedEvent>;
431
+ readonly "input.resolved"?: InstrumentationEventHandler<InstrumentationInputResolvedEvent>;
432
+ readonly "session.completed"?: InstrumentationEventHandler<InstrumentationSessionSettledEvent>;
433
+ readonly "session.failed"?: InstrumentationEventHandler<InstrumentationSessionFailedEvent>;
434
+ readonly "session.started"?: InstrumentationEventHandler<InstrumentationSessionStartedEvent>;
435
+ readonly "session.waiting"?: InstrumentationEventHandler<InstrumentationSessionSettledEvent>;
436
+ readonly "action.started"?: InstrumentationEventHandler<InstrumentationActionStartedEvent>;
437
+ readonly "action.completed"?: InstrumentationEventHandler<InstrumentationActionCompletedEvent>;
438
+ readonly "action.failed"?: InstrumentationEventHandler<InstrumentationActionFailedEvent>;
439
+ readonly "tool.call.started"?: InstrumentationEventHandler<InstrumentationToolCallStartedEvent>;
440
+ readonly "tool.call.completed"?: InstrumentationEventHandler<InstrumentationToolCallCompletedEvent>;
441
+ readonly "tool.call.failed"?: InstrumentationEventHandler<InstrumentationToolCallFailedEvent>;
442
+ readonly "turn.cancelled"?: InstrumentationEventHandler<InstrumentationTurnSettledEvent>;
443
+ readonly "turn.completed"?: InstrumentationEventHandler<InstrumentationTurnSettledEvent>;
444
+ readonly "turn.failed"?: InstrumentationEventHandler<InstrumentationTurnFailedEvent>;
445
+ readonly "turn.started"?: InstrumentationEventHandler<InstrumentationTurnStartedEvent>;
137
446
  };
447
+ /** Drains anything buffered. Driven by the runtime, not by the bus. */
448
+ readonly flush?: () => void | PromiseLike<void>;
449
+ /** Releases resources when the process is going away. */
450
+ readonly shutdown?: () => void | PromiseLike<void>;
138
451
  }
139
- export interface InstrumentationRelatedEventMap {
140
- readonly "model.call": {
141
- readonly start: InstrumentationModelCallStartedEvent;
142
- readonly terminal: InstrumentationModelCallTerminalEvent;
143
- };
144
- readonly "tool.call": {
145
- readonly start: InstrumentationToolCallStartedEvent;
146
- readonly terminal: InstrumentationToolCallTerminalEvent;
147
- };
452
+ type InstrumentationProviderInput = Omit<InstrumentationProviderDefinition, "name"> & {
453
+ readonly name?: string;
454
+ };
455
+ export interface InstrumentationDispatchGroups {
456
+ readonly serialBefore?: readonly InstrumentationProviderDefinition[];
457
+ readonly parallel?: readonly InstrumentationProviderDefinition[];
458
+ readonly serialAfter?: readonly InstrumentationProviderDefinition[];
148
459
  }
149
- export type InstrumentationRelatedEventName = keyof InstrumentationRelatedEventMap;
150
- export type InstrumentationPointEvent = InstrumentationAttemptStartedEvent | InstrumentationAttemptMetadataEvent | InstrumentationAttemptTerminalEvent | InstrumentationSessionStartedEvent | InstrumentationSessionTransitionEvent | InstrumentationTurnStartedEvent | InstrumentationTurnTerminalEvent;
460
+ export type InstrumentationHooksInput = readonly InstrumentationProviderInput[] | InstrumentationDispatchGroups;
461
+ /** Events that pair a start with its terminal under one `idempotencyKey`. */
462
+ export type InstrumentationCorrelatedEvent = InstrumentationChannelDeliveryStartedEvent | InstrumentationChannelDeliveryTerminalEvent | InstrumentationInputRequestedEvent | InstrumentationInputResolvedEvent | InstrumentationActionStartedEvent | InstrumentationActionTerminalEvent | InstrumentationModelCallStartedEvent | InstrumentationModelCallTerminalEvent | InstrumentationToolCallStartedEvent | InstrumentationToolCallTerminalEvent;
463
+ export type InstrumentationPointEvent = InstrumentationStepAttemptStartedEvent | InstrumentationStepAttemptMetadataEvent | InstrumentationStepAttemptTerminalEvent | InstrumentationSessionStartedEvent | InstrumentationSessionTransitionEvent | InstrumentationTurnStartedEvent | InstrumentationTurnTerminalEvent;
464
+ export type InstrumentationEvent = InstrumentationCorrelatedEvent | InstrumentationPointEvent;
151
465
  /** Trusted framework operation for activating context around AI SDK execution. */
152
466
  export type InstrumentationContextRunner = <T>(operation: InstrumentationExecutionOperation, execute: () => PromiseLike<T>) => PromiseLike<T>;
153
467
  /** Stable identity supplied only to a trusted framework context runner. */
154
468
  export type InstrumentationExecutionOperation = {
155
- readonly id: string;
469
+ readonly idempotencyKey: string;
156
470
  readonly scope: InstrumentationAttemptScope;
157
- readonly type: "model.call";
471
+ readonly type: "tool.call";
158
472
  } | {
159
- readonly id: string;
473
+ readonly idempotencyKey: string;
160
474
  readonly scope: InstrumentationAttemptScope;
161
- readonly type: "tool.call";
475
+ readonly type: "model.call";
162
476
  };
163
477
  /** Provider-neutral hook operations consumed by the AI SDK bridge. */
164
478
  export interface InstrumentationHooks {
165
- after<TKey extends InstrumentationRelatedEventName>(name: TKey, event: InstrumentationRelatedEventMap[TKey]["terminal"]): Promise<void>;
166
- before<TKey extends InstrumentationRelatedEventName>(name: TKey, event: InstrumentationRelatedEventMap[TKey]["start"]): Promise<void>;
167
- publish(event: InstrumentationPointEvent): Promise<void>;
479
+ /**
480
+ * Whether any registered provider declared `capture: "content"`.
481
+ *
482
+ * False means nothing downstream can read what was said, so the publisher
483
+ * should not serialize it in the first place. This is the only way the
484
+ * projection is skipped rather than merely withheld.
485
+ */
486
+ readonly capturesContent: boolean;
487
+ publish(event: InstrumentationEvent): Promise<void>;
488
+ }
489
+ export interface CreateInstrumentationHooksOptions {
490
+ readonly handlerTimeoutMs?: number;
168
491
  }
169
- /** Creates failure-isolated hooks backed by an ordered provider list. */
170
- export declare function createInstrumentationHooks(providers: readonly InstrumentationProviderDefinition[]): InstrumentationHooks;
492
+ /** Creates failure-isolated hooks backed by normalized dispatch groups. */
493
+ export declare function createInstrumentationHooks(input: InstrumentationHooksInput, options?: CreateInstrumentationHooksOptions): InstrumentationHooks;
171
494
  export {};
@@ -1 +1 @@
1
- import{createLogger,formatError}from"#internal/logging.js";const log=createLogger(`harness.instrumentation-lifecycle`);function createInstrumentationHooks(e){let r=new WeakMap,publish=async t=>{for(let n of e){let e=n.events?.[t.type];if(e!==void 0)try{await e(t)}catch(e){warn(t.type,e)}}},before=async(t,n)=>{let i=r.get(n.scope)??new Map;r.set(n.scope,i);for(let[r,a]of e.entries()){let e=a.events?.[t]?.before;if(e!==void 0)try{let t=await e(n);i.set(relatedStateKey(r,n.id),t)}catch(e){warn(`${t}.before`,e)}}},after=async(t,n)=>{let i=r.get(n.scope);for(let[r,a]of e.entries()){let e=a.events?.[t]?.after,o=relatedStateKey(r,n.id);if(e===void 0||!i?.has(o))continue;let s=i.get(o);i.delete(o);try{await e(n,s)}catch(e){warn(`${t}.after`,e)}}},warn=(e,r)=>{log.warn(`instrumentation provider failed`,{boundary:e,error:formatError(r)})};return{after,before,publish}}function relatedStateKey(e,t){return`${e}:${t}`}export{createInstrumentationHooks};
1
+ import{createInstrumentationDispatcher}from"#harness/instrumentation-dispatch.js";function sessionIdempotencyKey(e){return`session:${e}`}function turnIdempotencyKey(e,t){return`turn:${e}:${t}`}function attemptIdempotencyKey(e){return`step:${e.attemptId}`}function modelCallIdempotencyKey(e,t){return`model:${e.attemptId}:${String(t)}`}function toolCallIdempotencyKey(e,t,n){return`tool:${e.attemptId}:${t}:${String(n)}`}function inputIdempotencyKey(e,t,n){return`input:${e}:${t}:${n}`}function channelDeliveryIdempotencyKey(e,t){return`channel-delivery:${e}:${t}`}function actionIdempotencyKey(e,t,n){return`action:${e}:${t}:${n}`}function createInstrumentationHooks(t,n={}){return createInstrumentationDispatcher(t,n)}export{actionIdempotencyKey,attemptIdempotencyKey,channelDeliveryIdempotencyKey,createInstrumentationHooks,inputIdempotencyKey,modelCallIdempotencyKey,sessionIdempotencyKey,toolCallIdempotencyKey,turnIdempotencyKey};
@@ -1,7 +1,10 @@
1
- import type { InstrumentationHooks, InstrumentationParentLineage, InstrumentationTraceContext } from "#harness/instrumentation-lifecycle.js";
1
+ import type { InstrumentationAttemptScope, InstrumentationHooks, InstrumentationParentLineage, InstrumentationTraceContext } from "#harness/instrumentation-lifecycle.js";
2
+ import type { ResolvedInputBatch } from "#harness/input-requests.js";
2
3
  import type { HandleEventFn } from "#harness/types.js";
3
4
  export interface CreateInstrumentationHandleEventInput {
4
5
  readonly agentName?: string;
6
+ readonly channelKind?: string;
7
+ readonly getAttemptScope?: () => InstrumentationAttemptScope | undefined;
5
8
  readonly handleEvent?: HandleEventFn;
6
9
  readonly hooks?: InstrumentationHooks;
7
10
  readonly parentLineage?: InstrumentationParentLineage;
@@ -12,3 +15,9 @@ export interface CreateInstrumentationHandleEventInput {
12
15
  }
13
16
  /** Publishes eve-native lifecycle transitions after durable event acceptance. */
14
17
  export declare function createInstrumentationHandleEvent(input: CreateInstrumentationHandleEventInput): HandleEventFn | undefined;
18
+ /** Publishes accepted input resolutions against their original request scope. */
19
+ export declare function publishInputResolutions(input: {
20
+ readonly batch: ResolvedInputBatch;
21
+ readonly hooks: InstrumentationHooks;
22
+ readonly sessionId: string;
23
+ }): Promise<void>;
@@ -1 +1 @@
1
- function createInstrumentationHandleEvent(e){if(e.hooks===void 0)return e.handleEvent;if(e.handleEvent===void 0)return;let t=e.handleEvent,n=e.hooks,r=e.turnId;return async(i,a)=>{await t(i,a);let o=toLifecycleEvent(i,e,r);i.type===`turn.started`&&(r=i.data.turnId),o!==void 0&&await n.publish(o)}}function toLifecycleEvent(e,t,n){switch(e.type){case`session.started`:return{agentName:t.agentName,parentTraceContext:t.parentTraceContext,rootSessionId:t.rootSessionId??t.sessionId,sessionId:t.sessionId,type:`session.started`};case`session.completed`:case`session.waiting`:return{sessionId:t.sessionId,turnId:n,type:e.type};case`session.failed`:return{error:Error(e.data.message),sessionId:t.sessionId,turnId:n,type:`session.failed`};case`turn.started`:return{parentLineage:t.parentLineage,parentTraceContext:t.parentTraceContext,rootSessionId:t.rootSessionId??t.sessionId,sequence:e.data.sequence,sessionId:t.sessionId,turnId:e.data.turnId,type:`turn.started`};case`turn.completed`:case`turn.cancelled`:return{sessionId:t.sessionId,turnId:e.data.turnId,type:e.type};case`turn.failed`:return{error:Error(e.data.message),sessionId:t.sessionId,turnId:e.data.turnId,type:`turn.failed`};default:return}}export{createInstrumentationHandleEvent};
1
+ import{contextStorage}from"#context/container.js";import{instrumentChannelDelivery}from"#harness/channel-delivery-instrumentation.js";import{rememberInstrumentationActionScope,rememberInstrumentationInputScope,takeInstrumentationActionScopeForCall,takeInstrumentationInputScope}from"#harness/instrumentation-state.js";import{RuntimeActionSettlementTimesKey}from"#harness/runtime-action-settlement-state.js";import{actionIdempotencyKey,inputIdempotencyKey,sessionIdempotencyKey,turnIdempotencyKey}from"#harness/instrumentation-lifecycle.js";function createInstrumentationHandleEvent(n){if(n.hooks===void 0)return n.handleEvent;if(n.handleEvent===void 0)return;let r=n.handleEvent,i=n.hooks,a=new Set,o=new Set,s=n.turnId;return async(c,l)=>{await r(c,l);let u=toLifecycleEvent(c,n,s);if(c.type===`turn.started`&&(s=c.data.turnId),c.type===`turn.cancelled`||c.type===`turn.completed`||c.type===`turn.failed`||c.type===`session.completed`||c.type===`session.failed`){let n=contextStorage.getStore();n!==void 0&&await instrumentChannelDelivery({ctx:n,error:c.type===`turn.failed`||c.type===`session.failed`?Error(c.data.message):void 0,errorCode:c.type===`turn.failed`||c.type===`session.failed`?c.data.code:void 0,hooks:i,includeTurn:c.type===`turn.cancelled`||c.type===`turn.completed`||c.type===`turn.failed`,outcome:c.type===`turn.failed`||c.type===`session.failed`?`failed`:c.type===`turn.cancelled`?`cancelled`:`completed`})}u!==void 0&&await i.publish(u),c.type===`actions.requested`?await publishActionStarts(c,n,i,a):c.type===`action.result`?await publishActionTerminal(c,n,i):c.type===`input.requested`&&await publishInputStarts(c,n,i,o)}}async function publishInputStarts(e,t,n,i){let a=t.getAttemptScope?.();if(a!==void 0)for(let o of e.data.requests){let s=inputIdempotencyKey(t.sessionId,e.data.turnId,o.requestId);i.has(s)||(i.add(s),rememberInstrumentationInputScope(s,a),await n.publish(Object.freeze({action:Object.freeze({callId:o.action.callId,name:o.action.toolName}),idempotencyKey:s,kind:o.kind,request:n.capturesContent?Object.freeze({allowFreeform:o.allowFreeform,display:o.display,options:o.options,prompt:o.prompt}):void 0,requestId:o.requestId,scope:a,type:`input.requested`})))}}async function publishInputResolutions(e){for(let t of e.batch.inputs){let n=inputIdempotencyKey(e.sessionId,e.batch.event.turnId,t.request.requestId),r=takeInstrumentationInputScope(n);r!==void 0&&await e.hooks.publish(Object.freeze({idempotencyKey:n,kind:t.request.kind,outcome:t.outcome,requestId:t.request.requestId,response:!e.hooks.capturesContent||t.response===void 0?void 0:Object.freeze({optionId:t.response.optionId,text:t.response.text}),scope:r,type:`input.resolved`}))}}async function publishActionStarts(e,t,r,i){let a=t.getAttemptScope?.();if(a!==void 0)for(let o of e.data.actions){let c=actionIdempotencyKey(t.sessionId,e.data.turnId,o.callId);i.has(c)||(i.add(c),rememberInstrumentationActionScope(c,a),await r.publish(Object.freeze({callId:o.callId,idempotencyKey:c,input:r.capturesContent?o.input:void 0,kind:o.kind,name:actionName(o),scope:a,type:`action.started`})))}}async function publishActionTerminal(t,n,r){let a=takeInstrumentationActionScopeForCall(n.sessionId,t.data.result.callId);if(a===void 0)return;let{idempotencyKey:s,scope:c}=a;if(t.data.status===`completed`){await r.publish(Object.freeze({acceptedAtMs:contextStorage.getStore()?.get(RuntimeActionSettlementTimesKey)?.[t.data.result.callId],idempotencyKey:s,outcome:`completed`,output:Object.freeze(r.capturesContent?{output:t.data.result.output,type:`result`}:{type:`result`}),scope:c,type:`action.completed`,usage:actionUsage(t.data.result)}));return}let l=t.data.error===void 0?t.data.result.output:Object.assign(Error(t.data.error.message),{code:t.data.error.code});await r.publish(Object.freeze({acceptedAtMs:contextStorage.getStore()?.get(RuntimeActionSettlementTimesKey)?.[t.data.result.callId],error:l,errorCode:t.data.error?.code,idempotencyKey:s,outcome:t.data.status,scope:c,type:`action.failed`}))}function actionUsage(e){if(!(e.kind!==`subagent-result`||e.origin!==`child`||e.usage===void 0))return{inputTokenDetails:{cacheReadTokens:e.usage.cacheReadTokens,cacheWriteTokens:e.usage.cacheWriteTokens},inputTokens:e.usage.inputTokens,outputTokens:e.usage.outputTokens}}function actionName(e){return e.kind===`tool-call`?e.toolName:e.kind===`load-skill`?`load_skill`:e.name}function toLifecycleEvent(e,t,n){switch(e.type){case`session.started`:return{agentName:t.agentName,channelKind:t.channelKind,idempotencyKey:sessionIdempotencyKey(t.sessionId),parentTraceContext:t.parentTraceContext,rootSessionId:t.rootSessionId??t.sessionId,sessionId:t.sessionId,type:`session.started`};case`session.completed`:case`session.waiting`:return{idempotencyKey:sessionIdempotencyKey(t.sessionId),sessionId:t.sessionId,turnId:n,type:e.type};case`session.failed`:return{error:Error(e.data.message),idempotencyKey:sessionIdempotencyKey(t.sessionId),sessionId:t.sessionId,turnId:n,type:`session.failed`};case`turn.started`:return{idempotencyKey:turnIdempotencyKey(t.sessionId,e.data.turnId),parentLineage:t.parentLineage,parentTraceContext:t.parentTraceContext,rootSessionId:t.rootSessionId??t.sessionId,sequence:e.data.sequence,sessionId:t.sessionId,turnId:e.data.turnId,type:`turn.started`};case`turn.completed`:case`turn.cancelled`:return{idempotencyKey:turnIdempotencyKey(t.sessionId,e.data.turnId),sessionId:t.sessionId,turnId:e.data.turnId,type:e.type};case`turn.failed`:return{error:Error(e.data.message),idempotencyKey:turnIdempotencyKey(t.sessionId,e.data.turnId),sessionId:t.sessionId,turnId:e.data.turnId,type:`turn.failed`};default:return}}export{createInstrumentationHandleEvent,publishInputResolutions};
@@ -0,0 +1,50 @@
1
+ import { type InstrumentationRuntime } from "#harness/instrumentation-runtime.js";
2
+ import { type InstrumentationProvider } from "#public/instrumentation/provider.js";
3
+ /** One provider and the `instrumentation/<slot>.ts` file it came from. */
4
+ export interface RegisteredInstrumentationProvider {
5
+ readonly provider: InstrumentationProvider;
6
+ readonly slot: string;
7
+ }
8
+ /** Fills reserved slots before authored files may reconfigure or disable them. */
9
+ export declare function seedInstrumentationProviders(): void;
10
+ /**
11
+ * Registers one authored provider and awaits its `setup`.
12
+ *
13
+ * Called once per `instrumentation/<slot>.ts` by the generated Nitro plugin at
14
+ * server startup, before any event is published. A default export that is not
15
+ * a `defineInstrumentation` result throws rather than being skipped: a slot
16
+ * that registers nothing is telemetry that silently does nothing, which is the
17
+ * failure this surface exists to prevent.
18
+ *
19
+ * @internal — not part of the public API.
20
+ */
21
+ export declare function registerInstrumentationProvider(input: {
22
+ readonly agentName: string;
23
+ readonly slot: string;
24
+ readonly value: unknown;
25
+ }): Promise<void>;
26
+ /** Registered providers in slot order. @internal */
27
+ export declare function getInstrumentationProviders(): readonly RegisteredInstrumentationProvider[];
28
+ /**
29
+ * Installs the process instrumentation runtime from the registered providers.
30
+ *
31
+ * Called once by the generated Nitro plugin after every slot has registered,
32
+ * which is also why it cannot happen inside `setup`: the OpenTelemetry pipeline
33
+ * is the union of every destination declared in the directory, so no single
34
+ * file knows enough to build it. A `setup` that reaches for a tracer therefore
35
+ * gets the no-op one; declare destinations as values and let this assemble
36
+ * them.
37
+ *
38
+ * A directory that declared no OpenTelemetry at all still gets a bus. Its
39
+ * providers see every event; they just have no spans to hang them on.
40
+ *
41
+ * @internal — not part of the public API.
42
+ */
43
+ export declare function finalizeInstrumentationProviders(input: {
44
+ readonly serviceName: string;
45
+ }): InstrumentationRuntime;
46
+ /**
47
+ * Releases every registered provider and OTel processor from Nitro's close
48
+ * hook, the last point a buffered exporter can still reach the network.
49
+ */
50
+ export declare function shutdownInstrumentationProviders(): Promise<void>;