eve 0.43.0 → 0.44.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 (84) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/src/channel/adapter.d.ts +2 -1
  3. package/dist/src/channel/instrumentation.js +1 -1
  4. package/dist/src/cli/commands/registry-project.d.ts +3 -0
  5. package/dist/src/cli/commands/registry-project.js +2 -1
  6. package/dist/src/cli/commands/registry.d.ts +2 -0
  7. package/dist/src/cli/commands/registry.js +1 -1
  8. package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
  9. package/dist/src/compiled/.vendor-stamp.json +1 -1
  10. package/dist/src/compiled/jsonc-parser/index.d.ts +19 -0
  11. package/dist/src/compiler/extension-compatibility.d.ts +2 -2
  12. package/dist/src/compiler/extension-compatibility.js +1 -1
  13. package/dist/src/execution/workflow-trace-context.js +1 -1
  14. package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
  15. package/dist/src/harness/instrumentation/lifecycle.d.ts +4 -0
  16. package/dist/src/harness/instrumentation/native-events.d.ts +2 -0
  17. package/dist/src/harness/instrumentation/native-events.js +1 -1
  18. package/dist/src/harness/prepare-trace-context.d.ts +2 -0
  19. package/dist/src/harness/prepare-trace-context.js +1 -1
  20. package/dist/src/harness/tool-loop.js +2 -2
  21. package/dist/src/internal/application/package.js +1 -1
  22. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  23. package/dist/src/public/channels/chat-sdk/audience.d.ts +2 -0
  24. package/dist/src/public/channels/chat-sdk/audience.js +1 -0
  25. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +2 -0
  26. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  27. package/dist/src/public/channels/discord/audience.d.ts +5 -0
  28. package/dist/src/public/channels/discord/audience.js +1 -0
  29. package/dist/src/public/channels/discord/discordChannel.d.ts +2 -0
  30. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  31. package/dist/src/public/channels/discord/inbound.d.ts +1 -0
  32. package/dist/src/public/channels/discord/inbound.js +1 -1
  33. package/dist/src/public/channels/discord/index.d.ts +1 -0
  34. package/dist/src/public/channels/index.d.ts +3 -2
  35. package/dist/src/public/channels/slack/slackChannel.d.ts +4 -0
  36. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  37. package/dist/src/public/channels/teams/index.d.ts +1 -0
  38. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  39. package/dist/src/public/channels/telegram/audience.d.ts +3 -0
  40. package/dist/src/public/channels/telegram/audience.js +1 -0
  41. package/dist/src/public/channels/telegram/index.d.ts +1 -0
  42. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  43. package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -0
  44. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  45. package/dist/src/public/definitions/channel.d.ts +1 -0
  46. package/dist/src/public/instrumentation/otel.d.ts +6 -10
  47. package/dist/src/public/instrumentation/otel.js +1 -1
  48. package/dist/src/setup/scaffold/create/project.js +1 -1
  49. package/dist/src/setup/scaffold/create/web-template.d.ts +2 -1
  50. package/dist/src/setup/scaffold/create/web-template.js +373 -1
  51. package/dist/src/shared/channel-audience.d.ts +7 -0
  52. package/dist/src/shared/channel-audience.js +1 -0
  53. package/dist/src/shared/channel-definition.d.ts +2 -1
  54. package/dist/src/tracing/agent-action-instrumentation.js +1 -1
  55. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  56. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -1
  57. package/dist/src/tracing/agent-otel-provider.d.ts +2 -0
  58. package/dist/src/tracing/agent-otel-provider.js +2 -2
  59. package/dist/src/tracing/agent-otel-session-context.d.ts +2 -0
  60. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  61. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  62. package/dist/src/tracing/agent-trace-state.d.ts +3 -0
  63. package/dist/src/tracing/channel-audience-context.d.ts +4 -0
  64. package/dist/src/tracing/channel-audience-context.js +1 -0
  65. package/dist/src/tracing/content-attributes.js +1 -1
  66. package/dist/src/tracing/content-span-processor.d.ts +7 -7
  67. package/dist/src/tracing/content-span-processor.js +1 -1
  68. package/dist/src/tracing/install-instrumentation-runtime.js +1 -1
  69. package/dist/src/tracing/local-instrumentation-runtime.d.ts +3 -0
  70. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  71. package/dist/src/tracing/local-traces.d.ts +1 -10
  72. package/dist/src/tracing/local-traces.js +1 -1
  73. package/dist/src/tracing/otel-declaration.d.ts +34 -27
  74. package/dist/src/tracing/otel-declaration.js +1 -1
  75. package/dist/src/tracing/sampled-trace.d.ts +2 -0
  76. package/dist/src/tracing/sampled-trace.js +1 -0
  77. package/dist/src/tracing/span-export-policy.d.ts +41 -0
  78. package/dist/src/tracing/span-export-policy.js +1 -0
  79. package/dist/src/tracing/suppress-tracing.d.ts +2 -0
  80. package/dist/src/tracing/suppress-tracing.js +1 -0
  81. package/docs/channels/custom.mdx +2 -0
  82. package/docs/guides/instrumentation.md +2 -0
  83. package/docs/tutorial/ship-it.mdx +1 -1
  84. package/package.json +1 -1
@@ -1 +1 @@
1
- import{contextStorage,loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n!==void 0)return deserializeState(n).sessions[t]?.context}function readActionTraceContext(e,t,n,i){let a=e[AgentTraceContextKey.name];if(a===void 0)return;let o=Object.values(deserializeState(a).actions).find(e=>e.sessionId===t&&e.turnId===n&&e.callId===i);if(o!==void 0)return{isRemote:!1,spanId:o.spanId,traceFlags:o.parent.traceFlags,traceId:o.parent.traceId}}var ContextAgentTraceStateStore=class{deleteAction(e){updateState(t=>{let n={...t.actions};return delete n[e],{...t,actions:n}})}deleteActions(e,t){updateState(n=>{let r={...n.actions};for(let[n,i]of Object.entries(r))i.sessionId===e&&(t===void 0||i.turnId===t)&&delete r[n];return{...n,actions:r}})}deleteSession(e){updateState(t=>{let n={...t.sessions};return delete n[e],{...t,sessions:n}})}deleteTurn(e,t){updateState(n=>{let r={...n.turns};return delete r[turnKey(e,t)],{...n,turns:r}})}findAction(t,n){return Object.values(contextStorage.getStore()?.get(AgentTraceContextKey)?.actions??{}).find(e=>e.sessionId===t&&e.callId===n)}getAction(t){return contextStorage.getStore()?.get(AgentTraceContextKey)?.actions[t]}getSession(t){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[t]}getTurn(t,n){return contextStorage.getStore()?.get(AgentTraceContextKey)?.turns[turnKey(t,n)]}setAction(e,t){updateState(n=>({...n,actions:{...n.actions,[e]:t}}))}setSession(e,t){updateState(n=>({...n,sessions:{...n.sessions,[e]:t}}))}setTurn(e,t,n){updateState(r=>({...r,turns:{...r.turns,[turnKey(e,t)]:n}}))}};function updateState(e){loadContext().set(AgentTraceContextKey,t=>e(t??{actions:{},sessions:{},turns:{}}))}function turnKey(e,t){return`${e}\0${t}`}function serializeState(e){return{actions:e.actions,sessions:Object.fromEntries(Object.entries(e.sessions).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context)}])),turns:Object.fromEntries(Object.entries(e.turns).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context),terminal:t.terminal===void 0?void 0:t.terminal.type===`turn.failed`?{error:serializeError(t.terminal.error),type:t.terminal.type}:{type:t.terminal.type}}]))}}function deserializeState(e){return isRecord(e)?{actions:deserializeRecord(e.actions,deserializeAction),sessions:deserializeRecord(e.sessions,e=>{if(!(!isRecord(e)||!isSpanContext(e.context)))return{agentName:typeof e.agentName==`string`?e.agentName:void 0,channelKind:typeof e.channelKind==`string`?e.channelKind:void 0,context:e.context,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,turnsInWindow:typeof e.turnsInWindow==`number`?e.turnsInWindow:0,window:typeof e.window==`number`?e.window:0}}),turns:deserializeRecord(e.turns,e=>{if(!(!isRecord(e)||!isSpanContext(e.context))&&!(typeof e.parentSpanId!=`string`||typeof e.startTimeMs!=`number`))return{context:e.context,lineage:deserializeLineage(e.lineage),parentIsRemote:typeof e.parentIsRemote==`boolean`?e.parentIsRemote:void 0,parentSpanId:e.parentSpanId,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,terminal:deserializeTerminal(e.terminal)}})}:{actions:{},sessions:{},turns:{}}}function deserializeAction(e){if(!(!isRecord(e)||typeof e.attemptIndex!=`number`||typeof e.callId!=`string`||!isActionKind(e.kind)||typeof e.name!=`string`||!isSpanContext(e.parent)||typeof e.rootSessionId!=`string`||typeof e.sessionId!=`string`||typeof e.spanId!=`string`||typeof e.startTimeMs!=`number`||typeof e.stepIndex!=`number`||typeof e.turnId!=`string`))return{attemptIndex:e.attemptIndex,callId:e.callId,inputAttribute:typeof e.inputAttribute==`string`?e.inputAttribute:void 0,kind:e.kind,name:e.name,parent:e.parent,rootSessionId:e.rootSessionId,sessionId:e.sessionId,spanId:e.spanId,startTimeMs:e.startTimeMs,stepIndex:e.stepIndex,turnId:e.turnId}}function isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function deserializeRecord(e,t){if(!isRecord(e))return{};let n={};for(let[r,i]of Object.entries(e)){let e=t(i);e!==void 0&&(n[r]=e)}return n}function deserializeLineage(e){if(!(!isRecord(e)||typeof e.callId!=`string`||typeof e.sessionId!=`string`||typeof e.turnId!=`string`))return{callId:e.callId,sessionId:e.sessionId,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,turnId:e.turnId}}function deserializeTerminal(e){if(!isRecord(e)||typeof e.type!=`string`)return;let t=e.type;if(isTurnTerminalType(t))return t===`turn.failed`?{error:deserializeError(e.error),type:t}:{type:t}}function serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function serializeError(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:void 0}function deserializeError(e){if(!isRecord(e)||typeof e.message!=`string`)return;let t=Error(e.message);return typeof e.name==`string`&&(t.name=e.name),typeof e.stack==`string`&&(t.stack=e.stack),t}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{ContextAgentTraceStateStore,preserveSerializedAgentTraceState,readActionTraceContext,readSessionTraceContext};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage,loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n!==void 0)return deserializeState(n).sessions[t]?.context}function readActionTraceContext(e,t,n,r){let a=e[AgentTraceContextKey.name];if(a===void 0)return;let o=Object.values(deserializeState(a).actions).find(e=>e.sessionId===t&&e.turnId===n&&e.callId===r);if(o!==void 0)return{isRemote:!1,spanId:o.spanId,traceFlags:o.parent.traceFlags,traceId:o.parent.traceId}}var ContextAgentTraceStateStore=class{deleteAction(e){updateState(t=>{let n={...t.actions};return delete n[e],{...t,actions:n}})}deleteActions(e,t){updateState(n=>{let r={...n.actions};for(let[n,i]of Object.entries(r))i.sessionId===e&&(t===void 0||i.turnId===t)&&delete r[n];return{...n,actions:r}})}deleteSession(e){updateState(t=>{let n={...t.sessions};return delete n[e],{...t,sessions:n}})}deleteTurn(e,t){updateState(n=>{let r={...n.turns};return delete r[turnKey(e,t)],{...n,turns:r}})}findAction(e,n){return Object.values(contextStorage.getStore()?.get(AgentTraceContextKey)?.actions??{}).find(t=>t.sessionId===e&&t.callId===n)}getAction(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.actions[e]}getSession(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[e]}getTurn(e,n){return contextStorage.getStore()?.get(AgentTraceContextKey)?.turns[turnKey(e,n)]}setAction(e,t){updateState(n=>({...n,actions:{...n.actions,[e]:t}}))}setSession(e,t){updateState(n=>({...n,sessions:{...n.sessions,[e]:t}}))}setTurn(e,t,n){updateState(r=>({...r,turns:{...r.turns,[turnKey(e,t)]:n}}))}};function updateState(e){loadContext().set(AgentTraceContextKey,t=>e(t??{actions:{},sessions:{},turns:{}}))}function turnKey(e,t){return`${e}\0${t}`}function serializeState(e){return{actions:e.actions,sessions:Object.fromEntries(Object.entries(e.sessions).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context)}])),turns:Object.fromEntries(Object.entries(e.turns).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context),terminal:t.terminal===void 0?void 0:t.terminal.type===`turn.failed`?{error:serializeError(t.terminal.error),type:t.terminal.type}:{type:t.terminal.type}}]))}}function deserializeState(t){return isRecord(t)?{actions:deserializeRecord(t.actions,deserializeAction),sessions:deserializeRecord(t.sessions,t=>{if(!(!isRecord(t)||!isSpanContext(t.context)))return{agentName:typeof t.agentName==`string`?t.agentName:void 0,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:typeof t.channelKind==`string`?t.channelKind:void 0,context:t.context,rootSessionId:typeof t.rootSessionId==`string`?t.rootSessionId:``,turnsInWindow:typeof t.turnsInWindow==`number`?t.turnsInWindow:0,window:typeof t.window==`number`?t.window:0}}),turns:deserializeRecord(t.turns,e=>{if(!(!isRecord(e)||!isSpanContext(e.context))&&!(typeof e.parentSpanId!=`string`||typeof e.startTimeMs!=`number`))return{context:e.context,lineage:deserializeLineage(e.lineage),parentIsRemote:typeof e.parentIsRemote==`boolean`?e.parentIsRemote:void 0,parentSpanId:e.parentSpanId,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,terminal:deserializeTerminal(e.terminal)}})}:{actions:{},sessions:{},turns:{}}}function deserializeAction(t){if(!(!isRecord(t)||typeof t.attemptIndex!=`number`||typeof t.callId!=`string`||!isActionKind(t.kind)||typeof t.name!=`string`||!isSpanContext(t.parent)||typeof t.rootSessionId!=`string`||typeof t.sessionId!=`string`||typeof t.spanId!=`string`||typeof t.startTimeMs!=`number`||typeof t.stepIndex!=`number`||typeof t.turnId!=`string`))return{attemptIndex:t.attemptIndex,callId:t.callId,channelAudience:normalizeChannelAudience(t.channelAudience),inputAttribute:typeof t.inputAttribute==`string`?t.inputAttribute:void 0,kind:t.kind,name:t.name,parent:t.parent,rootSessionId:t.rootSessionId,sessionId:t.sessionId,spanId:t.spanId,startTimeMs:t.startTimeMs,stepIndex:t.stepIndex,turnId:t.turnId}}function isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function deserializeRecord(e,t){if(!isRecord(e))return{};let n={};for(let[r,i]of Object.entries(e)){let e=t(i);e!==void 0&&(n[r]=e)}return n}function deserializeLineage(e){if(!(!isRecord(e)||typeof e.callId!=`string`||typeof e.sessionId!=`string`||typeof e.turnId!=`string`))return{callId:e.callId,sessionId:e.sessionId,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,turnId:e.turnId}}function deserializeTerminal(e){if(!isRecord(e)||typeof e.type!=`string`)return;let t=e.type;if(isTurnTerminalType(t))return t===`turn.failed`?{error:deserializeError(e.error),type:t}:{type:t}}function serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function serializeError(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:void 0}function deserializeError(e){if(!isRecord(e)||typeof e.message!=`string`)return;let t=Error(e.message);return typeof e.name==`string`&&(t.name=e.name),typeof e.stack==`string`&&(t.stack=e.stack),t}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{ContextAgentTraceStateStore,preserveSerializedAgentTraceState,readActionTraceContext,readSessionTraceContext};
@@ -1,8 +1,10 @@
1
1
  import type { SpanContext } from "#compiled/@opentelemetry/api/index.js";
2
2
  import type { InstrumentationActionKind, InstrumentationParentLineage, InstrumentationTraceContext, InstrumentationTurnFailedEvent, InstrumentationTurnSettledEvent } from "#harness/instrumentation/lifecycle.js";
3
+ import type { ChannelAudience } from "#shared/channel-audience.js";
3
4
  /** Sized so an ordinary session stays one trace and only an outsized one rolls. */
4
5
  export declare const SESSION_WINDOW_TURN_LIMIT = 200;
5
6
  export interface AgentSessionTraceState {
7
+ readonly channelAudience?: ChannelAudience;
6
8
  readonly agentName?: string;
7
9
  readonly channelKind?: string;
8
10
  readonly context: SpanContext;
@@ -28,6 +30,7 @@ export interface AgentTurnTraceState {
28
30
  export interface AgentActionTraceState {
29
31
  readonly attemptIndex: number;
30
32
  readonly callId: string;
33
+ readonly channelAudience?: ChannelAudience;
31
34
  readonly inputAttribute?: string;
32
35
  readonly kind: InstrumentationActionKind;
33
36
  readonly name: string;
@@ -0,0 +1,4 @@
1
+ import { type Context } from "#compiled/@opentelemetry/api/index.js";
2
+ import { type ChannelAudience } from "#shared/channel-audience.js";
3
+ export declare function channelAudienceFromContext(context: unknown): ChannelAudience;
4
+ export declare function withChannelAudience(context: Context, audience: unknown): Context;
@@ -0,0 +1 @@
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{createContextKey}from"#compiled/@opentelemetry/api/index.js";const CHANNEL_AUDIENCE_KEY=createContextKey(`eve.channel.audience`);function channelAudienceFromContext(e){if(typeof e!=`object`||!e)return`unknown`;let t=Reflect.get(e,`getValue`);return typeof t==`function`?normalizeChannelAudience(Reflect.apply(t,e,[CHANNEL_AUDIENCE_KEY])):`unknown`}function withChannelAudience(e,t){return e.setValue(CHANNEL_AUDIENCE_KEY,normalizeChannelAudience(t))}export{channelAudienceFromContext,withChannelAudience};
@@ -1 +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};
1
+ const INPUT_CONTENT_ATTRIBUTES=new Set([`agent.channel.delivery.input`,`agent.approval.request`,`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([`agent.approval.response`,`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};
@@ -1,13 +1,13 @@
1
1
  import type { SpanProcessor } from "#compiled/@vercel/otel/index.js";
2
- import { type ResolvedContentOptions } from "#tracing/content-attributes.js";
2
+ import { type SpanExportPolicy } from "#tracing/span-export-policy.js";
3
3
  /**
4
4
  * Puts one destination's content policy in front of it.
5
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.
6
+ * Accepted traces carry content before they reach destination policies. This
7
+ * cannot strip an attribute in place: the span object is shared with every
8
+ * processor in the pipeline, and editing it would strip the attribute
9
+ * everywhere. So it gives the destination a facade whose attributes omit what
10
+ * its policy redacted.
11
11
  *
12
12
  * One facade follows the original from start through end. This preserves the
13
13
  * object identity stateful processors key on without ever exposing the original
@@ -16,4 +16,4 @@ import { type ResolvedContentOptions } from "#tracing/content-attributes.js";
16
16
  *
17
17
  * @internal
18
18
  */
19
- export declare function contentFilteringProcessor(downstream: SpanProcessor, content: ResolvedContentOptions): SpanProcessor;
19
+ export declare function contentFilteringProcessor(downstream: SpanProcessor, exportPolicy?: SpanExportPolicy): SpanProcessor;
@@ -1 +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};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{hasSessionRelease}from"#tracing/local-traces.js";import{channelAudienceFromContext}from"#tracing/channel-audience-context.js";import{withoutDeclinedContent}from"#tracing/content-attributes.js";import{contentRedactionForSpan,spanExportPolicyStages}from"#tracing/span-export-policy.js";function contentFilteringProcessor(e,t){if(t===void 0)return e;let n=e;for(let e of spanExportPolicyStages(t).toReversed())n=policyFilteringProcessor(n,e);return n}function policyFilteringProcessor(e,r){let i=new WeakMap,a=new WeakSet,o={forceFlush:()=>e.forceFlush(),onEnd:t=>{if(typeof t!=`object`||!t)return;let n=facadeFor(t,r,i);if(a.has(t)||!n.exported){a.delete(t),i.delete(t);return}n.refresh();try{e.onEnd(n.value)}finally{i.delete(t)}},onStart:(t,o)=>{if(typeof t!=`object`||!t)return;let s=facadeFor(t,r,i,channelAudienceFromContext(o));if(!s.exported){a.add(t);return}e.onStart(s.value,o)},shutdown:()=>e.shutdown()};return hasSessionRelease(e)?{...o,releaseSession:t=>e.releaseSession(t)}:o}function facadeFor(e,t,n,r){let i=n.get(e);if(i!==void 0)return i;let a=spanExportContext(e,r),o=contentForSpan(a,t),s={},c=[],l={},u=Object.create(Reflect.getPrototypeOf(e)),d=new Map,refresh=()=>{refreshAttributes(s,e,o,a,t),refreshEvents(c,e,o),refreshStatus(l,e,o)},f,readOriginal=t=>{let n=Reflect.get(e,t,e);if(typeof n!=`function`||t===`constructor`)return n;let r=d.get(t);if(r!==void 0)return r;let created=(...t)=>{let r=Reflect.apply(n,e,t);return refresh(),r===e?f:r};return d.set(t,created),created};Object.defineProperty(u,"attributes",{configurable:!0,enumerable:!0,value:s}),Object.defineProperty(u,"events",{configurable:!0,enumerable:!0,value:c}),Object.defineProperty(u,"status",{configurable:!0,enumerable:!0,value:l});for(let t of Reflect.ownKeys(e)){if(t===`attributes`||t===`events`||t===`status`)continue;let n=Reflect.getOwnPropertyDescriptor(e,t);Object.defineProperty(u,t,{configurable:!0,enumerable:n?.enumerable??!1,get:()=>readOriginal(t)})}f=new Proxy(u,{get:(e,t,n)=>Object.hasOwn(e,t)?Reflect.get(e,t,n):readOriginal(t)});let p={context:a,exported:shouldExport(a,t),refresh,value:f};return p.refresh(),n.set(e,p),p}function contentForSpan(e,t){let n=contentRedactionForSpan(t,e);return{recordInputs:!n.redactInputs,recordOutputs:!n.redactOutputs}}function refreshAttributes(e,t,n,i,a){for(let t of Object.keys(e))delete e[t];let o=t.attributes;if(typeof o!=`object`||!o)return;let s=withoutDeclinedContent(o,n)??o;for(let[t,n]of Object.entries(s)){let r=attributeDecision(a,{key:t,span:i,value:n});r.action===`keep`?e[t]=n:r.action===`replace`&&(e[t]=r.value)}}function spanExportContext(t,n=`unknown`){let r=t.attributes,i=typeof r==`object`&&r?r:{},a=[i[`agent.channel.audience`],i[`ai.settings.context.eve.channel.audience`]].filter(e=>e!==void 0).map(normalizeChannelAudience),o=a.length>0&&a.every(e=>e===a[0])?a[0]:a.length>0?`unknown`:n,s=t.spanContext?.(),c=typeof s==`object`&&s?s:{},l=t.name;return{attributes:i,audience:o,name:typeof l==`string`?l:``,spanId:typeof c.spanId==`string`?c.spanId:``,traceId:typeof c.traceId==`string`?c.traceId:``}}function shouldExport(e,t){if(t===void 0)return!0;try{return t.span?.(e)!==!1}catch{return!1}}function attributeDecision(e,t){if(e?.attribute===void 0)return{action:`keep`};try{return e.attribute(t)}catch{return{action:`drop`}}}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};
@@ -1 +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,s,c,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`}),s=r.prepareSessionTrace,c=r.prepareTurnTrace,runInContext=r.runInContext;let i=e.collected.pipeline.spanProcessors.filter(isSpanProcessor).filter(hasSessionRelease);i.length>0&&a.push(sessionReleaseProvider(i))}let l=[...t,...e.providers,...a],u;return registerInstrumentationRuntime({forceFlush:()=>settleAll([...o===void 0?[]:[o.forceFlush],...l.map(e=>()=>e.flush?.())]),hooks:createInstrumentationHooks({parallel:e.providers,serialAfter:a,serialBefore:t}),otelSettings:e.collected.declared?e.collected.settings:void 0,prepareSessionTrace:s,prepareTurnTrace:c,runtimeContextResolvers:e.runtimeContextResolvers,runInContext,shutdown:()=>(u??=settleAll([...o===void 0?[]:[o.shutdown],...l.map(e=>()=>e.shutdown?.())]),u)})}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
+ 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,s,c,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),tracePolicy:e.collected.settings.tracePolicy});t.push({...r.hook,stateNamespace:`internal:otel`}),s=r.prepareSessionTrace,c=r.prepareTurnTrace,runInContext=r.runInContext;let i=e.collected.pipeline.spanProcessors.filter(isSpanProcessor).filter(hasSessionRelease);i.length>0&&a.push(sessionReleaseProvider(i))}let l=[...t,...e.providers,...a],u;return registerInstrumentationRuntime({forceFlush:()=>settleAll([...o===void 0?[]:[o.forceFlush],...l.map(e=>()=>e.flush?.())]),hooks:createInstrumentationHooks({parallel:e.providers,serialAfter:a,serialBefore:t}),otelSettings:e.collected.declared?e.collected.settings:void 0,prepareSessionTrace:s,prepareTurnTrace:c,runtimeContextResolvers:e.runtimeContextResolvers,runInContext,shutdown:()=>(u??=settleAll([...o===void 0?[]:[o.shutdown],...l.map(e=>()=>e.shutdown?.())]),u)})}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,4 +1,7 @@
1
1
  import { type InstrumentationRuntime } from "#harness/instrumentation/runtime.js";
2
+ import { type TraceCapturePolicy } from "#tracing/otel-declaration.js";
3
+ /** Zero-config local tracing keeps unclassified HTTP/TUI sessions observable. @internal */
4
+ export declare const localTracePolicy: TraceCapturePolicy;
2
5
  /** Installs the zero-config local OTel runtime once in an `eve dev` worker. */
3
6
  export declare function installLocalInstrumentationRuntime(input: {
4
7
  readonly appRoot: string;
@@ -1 +1 @@
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};
1
+ import{getInstrumentationRuntime}from"#harness/instrumentation/runtime.js";import{installInstrumentationRuntime}from"#tracing/install-instrumentation-runtime.js";import{collectOtelPipeline,managedOtelIntegration,otel}from"#tracing/otel-declaration.js";import{createLocalTracesProcessor,resolveLocalTracesContent}from"#tracing/local-traces.js";const localTracePolicy=({audience:e})=>e===`public`||e===`unknown`;function installLocalInstrumentationRuntime(t){let n=getInstrumentationRuntime();if(n!==void 0)return n;let r=createLocalTracesProcessor({appRoot:t.appRoot});return installInstrumentationRuntime({collected:collectOtelPipeline([otel({tracePolicy:localTracePolicy}),managedOtelIntegration({...resolveLocalTracesContent(),spanProcessors:[r]})]),frameworkVersion:t.frameworkVersion,providers:[],serviceName:t.serviceName})}export{installLocalInstrumentationRuntime,localTracePolicy};
@@ -37,16 +37,7 @@ export declare function hasSessionRelease(processor: SpanProcessor): processor i
37
37
  export declare function createLocalTracesProcessor(input?: {
38
38
  readonly appRoot?: string;
39
39
  }): LocalTracesProcessor;
40
- /**
41
- * The local spool's content policy: its options, intersected with
42
- * `EVE_TRACES_CONTENT`.
43
- *
44
- * The variable applies to this destination only. `on` opts the zero-config
45
- * spool into content, while `off` overrides authored local options without
46
- * changing what a hosted backend beside it receives.
47
- *
48
- * @internal
49
- */
40
+ /** Maps legacy local content configuration onto destination redaction. @internal */
50
41
  export declare function resolveLocalTracesContent(options?: {
51
42
  readonly recordInputs?: boolean;
52
43
  readonly recordOutputs?: boolean;
@@ -1 +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(r={}){let i=r.appRoot??process.env.EVE_DEV_WORKER_APP_ROOT;if(i===void 0)return inertLocalTracesProcessor();let a=resolveLocalTraceRetentionSettings(),o=new AgentTraceSpanProcessor(a.enabled?[new LocalTraceSpanProcessor(i)]:[]),requestPrune=()=>{a.enabled&&requestLocalTraceStorePrune({activeTraceIds:o.activeTraceIds(),appRoot:i,maxAgeMs:a.maxAgeMs,maxTotalBytes:a.maxTotalBytes,retainCount:a.retainCount})};return requestPrune(),{forceFlush:()=>o.forceFlush(),onEnd:e=>o.onEnd(e),onStart:(e,t)=>o.onStart(e,t),async releaseSession(e){return await o.forceFlush(),o.releaseSession(e)?(requestPrune(),!0):!1},shutdown:()=>o.shutdown()}}function resolveLocalTracesContent(e={}){let t=process.env.EVE_TRACES_CONTENT===`on`,n=process.env.EVE_TRACES_CONTENT!==`off`;return{recordInputs:n&&(e.recordInputs??t),recordOutputs:n&&(e.recordOutputs??t)}}function inertLocalTracesProcessor(){return{forceFlush:async()=>void 0,onEnd:()=>void 0,onStart:()=>void 0,releaseSession:async()=>!1,shutdown:async()=>void 0}}export{createLocalTracesProcessor,hasSessionRelease,resolveLocalTracesContent};
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={}){return process.env.EVE_TRACES_CONTENT===`off`?{recordInputs:!1,recordOutputs:!1}:{recordInputs:e.recordInputs!==!1,recordOutputs: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};
@@ -3,6 +3,10 @@ import { type InstrumentationProvider } from "#public/instrumentation/provider.j
3
3
  import type { InstrumentationRuntimeContextInput } from "#public/instrumentation/index.js";
4
4
  import type { JsonObject } from "#shared/json.js";
5
5
  import type { ResolvedContentOptions } from "#tracing/content-attributes.js";
6
+ import type { ChannelAudience } from "#shared/channel-audience.js";
7
+ import { type SpanExportPolicy } from "#tracing/span-export-policy.js";
8
+ export type { SpanAttributeDecision, SpanExportAttributeValue, SpanExportContext, SpanExportPolicy, SpanExportPredicate, } from "#tracing/span-export-policy.js";
9
+ export { composeSpanExportPolicies, redactSpanInputs, redactSpanOutputs, } from "#tracing/span-export-policy.js";
6
10
  /**
7
11
  * The process-wide OpenTelemetry settings, declared by `otel()`.
8
12
  *
@@ -28,6 +32,11 @@ export interface OtelOptions {
28
32
  * outgoing HTTP spans. Defaults to `false`.
29
33
  */
30
34
  readonly traceChannelRequests?: boolean;
35
+ /**
36
+ * Process-wide head gate for an agent session trace. Defaults to retaining
37
+ * only public conversations. A thrown error rejects the trace.
38
+ */
39
+ readonly tracePolicy?: TraceCapturePolicy;
31
40
  /**
32
41
  * Resource attributes merged into eve's own, which already carry the
33
42
  * service name.
@@ -52,22 +61,27 @@ export interface OtelOptions {
52
61
  */
53
62
  readonly instrumentations?: readonly unknown[];
54
63
  }
55
- /**
56
- * What one destination records of the conversation itself.
57
- *
58
- * Declining is per destination, not per process: content is written onto the
59
- * span if any destination wants it, and one that declined never exports it. So
60
- * an agent whose every destination declines still never materializes a prompt —
61
- * the union of nothing is nothing — but a local spool and a hosted backend no
62
- * longer have to agree.
63
- */
64
+ export interface ManagedTraceOptions {
65
+ /** Destination policy applied before spans are exported. */
66
+ readonly exportPolicy?: SpanExportPolicy;
67
+ /** @deprecated Use `exportPolicy: redactSpanInputs()` instead. */
68
+ readonly recordInputs?: boolean;
69
+ /** @deprecated Use `exportPolicy: redactSpanOutputs()` instead. */
70
+ readonly recordOutputs?: boolean;
71
+ }
72
+ /** @deprecated Compose `redactSpanInputs()` and `redactSpanOutputs()` into an export policy. */
64
73
  export interface ContentOptions {
65
- /** Record model prompts and tool call inputs. Defaults to `false`. */
66
74
  readonly recordInputs?: boolean;
67
- /** Record model responses and tool call outputs. Defaults to `false`. */
68
75
  readonly recordOutputs?: boolean;
69
76
  }
70
- /** Where one `otelIntegration()` sends spans, and what it records. */
77
+ export interface TraceCaptureContext {
78
+ readonly agentName?: string;
79
+ readonly audience: ChannelAudience;
80
+ readonly rootSessionId: string;
81
+ readonly sessionId: string;
82
+ }
83
+ export type TraceCapturePolicy = (trace: TraceCaptureContext) => boolean;
84
+ /** Where one `otelIntegration()` sends spans. */
71
85
  export interface OtelIntegrationOptions extends ContentOptions {
72
86
  /** Merged into the pipeline in declaration order. */
73
87
  readonly spanProcessors?: readonly SpanProcessor[];
@@ -98,7 +112,7 @@ export interface OtelDeclaration extends InstrumentationProvider {
98
112
  /** One declared destination. A process may have as many as it has files. */
99
113
  export interface OtelIntegration extends InstrumentationProvider {
100
114
  readonly [OTEL_INTEGRATION]: true;
101
- /** Resolved from `ContentOptions`, so the union does not re-apply defaults. */
115
+ /** @deprecated Content is captured upstream and redacted by destination policies. */
102
116
  readonly content: ResolvedContentOptions;
103
117
  readonly runtimeContext?: (input: InstrumentationRuntimeContextInput) => JsonObject | undefined;
104
118
  readonly spanProcessors: readonly SpanProcessorOrName[];
@@ -118,13 +132,14 @@ export declare function otel(options?: OtelOptions): OtelDeclaration;
118
132
  * the one-line form of a hosted backend enough. Pass `spanProcessors` instead
119
133
  * when the destination needs its own batching, sampling, or filtering.
120
134
  *
121
- * Declining content wraps every processor here, an author's included: they are
122
- * this destination, and the point of declining is that nothing under it sees
123
- * what was said.
135
+ * The export policy wraps every processor here, an author's included: they are
136
+ * this destination, and nothing beneath the policy sees what it removes.
124
137
  */
125
138
  export declare function otelIntegration(options?: OtelIntegrationOptions): OtelIntegration;
139
+ /** @internal Local and Agent Runs destination declaration. */
140
+ export declare function managedOtelIntegration(options?: OtelIntegrationOptions & ManagedTraceOptions): OtelIntegration;
126
141
  /** Vercel Agent Runs through the production request-context transport. @internal */
127
- export declare function agentRunsIntegration(options?: ContentOptions): OtelIntegration;
142
+ export declare function agentRunsIntegration(options?: ManagedTraceOptions): OtelIntegration;
128
143
  export declare function resolveContentOptions(options: ContentOptions): ResolvedContentOptions;
129
144
  export declare function isOtelDeclaration(value: unknown): value is OtelDeclaration;
130
145
  export declare function isOtelIntegration(value: unknown): value is OtelIntegration;
@@ -140,11 +155,8 @@ export interface OtelPipeline {
140
155
  export interface OtelHarnessSettings {
141
156
  readonly functionId?: string;
142
157
  readonly traceChannelRequests: boolean;
143
- /**
144
- * What to write onto a span at all, as opposed to what any one destination
145
- * exports. `agent/instrumentation.ts` sets this directly; a provider
146
- * directory arrives at it as the union of its destinations.
147
- */
158
+ readonly tracePolicy?: TraceCapturePolicy;
159
+ /** Legacy `defineInstrumentation()` capture settings. Provider destinations capture fully. */
148
160
  readonly recordInputs?: boolean;
149
161
  readonly recordOutputs?: boolean;
150
162
  }
@@ -169,11 +181,6 @@ export interface CollectedOtel {
169
181
  * happened to visit first. With one declaration per file that collision needs
170
182
  * two files both exporting `otel()`, which is the only way to reach it.
171
183
  *
172
- * Content capture is the union of what the destinations asked for, because it
173
- * governs what is written rather than what is exported. Each destination's own
174
- * processors already drop what it declined.
175
- *
176
184
  * @internal
177
185
  */
178
186
  export declare function collectOtelPipeline(values: readonly unknown[]): CollectedOtel;
179
- export {};
@@ -1 +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===!0,recordOutputs:r.recordOutputs===!0},o=r.spanProcessors??[],s=r.traceExporter===void 0?o:[...o,batchSpanProcessor(r.traceExporter)];return{[OTEL_INTEGRATION]:!0,[PROVIDER]:!0,content:i,runtimeContext:r.runtimeContext,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===!0,recordOutputs:e.recordOutputs===!0}}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,i=!1,a=!1,o=!1;for(let s of e){if(isOtelIntegration(s)){i=!0,a||=s.content.recordInputs,o||=s.content.recordOutputs,t.push(...s.spanProcessors),s.runtimeContext!==void 0&&n.push(s.runtimeContext);continue}if(isOtelDeclaration(s)){if(r!==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()`.");i=!0,r=s}}let s=r?.options??{};return{declared:i,pipeline:{instrumentations:s.instrumentations,propagators:s.propagators,resource:s.resource,sampler:s.sampler,spanProcessors:t},runtimeContextResolvers:n,settings:{functionId:s.functionId,recordInputs:a,recordOutputs:o,traceChannelRequests:s.traceChannelRequests===!0}}}export{agentRunsIntegration,collectOtelPipeline,isOtelDeclaration,isOtelIntegration,otel,otelIntegration,resolveContentOptions};
1
+ import{PROVIDER}from"#public/instrumentation/provider.js";import{composeSpanExportPolicies,composeSpanExportPolicies as composeSpanExportPolicies$1,redactSpanInputs,redactSpanInputs as redactSpanInputs$1,redactSpanOutputs,redactSpanOutputs as redactSpanOutputs$1}from"#tracing/span-export-policy.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(e={}){return createOtelIntegration(e)}function managedOtelIntegration(e={}){return createOtelIntegration(e,e.exportPolicy)}function createOtelIntegration(t,n){let r=t.spanProcessors??[],i=t.traceExporter===void 0?r:[...r,batchSpanProcessor(t.traceExporter)];return{[OTEL_INTEGRATION]:!0,[PROVIDER]:!0,content:resolveContentOptions(t),runtimeContext:t.runtimeContext,spanProcessors:i.map(e=>withExportPolicies(e,legacyContentRedactionPolicy(t),n))}}function agentRunsIntegration(t={}){return{[OTEL_INTEGRATION]:!0,[PROVIDER]:!0,content:resolveContentOptions(t),spanProcessors:[withExportPolicies(vercelRuntimeSpanProcessor(),legacyContentRedactionPolicy(t),t.exportPolicy)]}}function legacyContentRedactionPolicy(e){let t=[];return e.recordInputs===!1&&t.push(redactSpanInputs$1()),e.recordOutputs===!1&&t.push(redactSpanOutputs$1()),t.length===0?void 0:composeSpanExportPolicies$1(...t)}function resolveContentOptions(e){return{recordInputs:e.recordInputs!==!1,recordOutputs:e.recordOutputs!==!1}}function withExportPolicies(e,...t){let n=e;for(let e of t.toReversed())n=contentFilteringProcessor(n,e);return n}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,i=!1,a=!1;for(let o of e){if(isOtelIntegration(o)){i=!0,a=!0,t.push(...o.spanProcessors),o.runtimeContext!==void 0&&n.push(o.runtimeContext);continue}if(isOtelDeclaration(o)){if(r!==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()`.");i=!0,r=o}}let o=r?.options??{},s={functionId:o.functionId,recordInputs:a,recordOutputs:a,traceChannelRequests:o.traceChannelRequests===!0};return o.tracePolicy!==void 0&&Object.assign(s,{tracePolicy:o.tracePolicy}),{declared:i,pipeline:{instrumentations:o.instrumentations,propagators:o.propagators,resource:o.resource,sampler:o.sampler,spanProcessors:t},runtimeContextResolvers:n,settings:s}}export{agentRunsIntegration,collectOtelPipeline,composeSpanExportPolicies,isOtelDeclaration,isOtelIntegration,managedOtelIntegration,otel,otelIntegration,redactSpanInputs,redactSpanOutputs,resolveContentOptions};
@@ -0,0 +1,2 @@
1
+ import { type SpanContext } from "#compiled/@opentelemetry/api/index.js";
2
+ export declare function isSampledTrace(context: Pick<SpanContext, "traceFlags">): boolean;
@@ -0,0 +1 @@
1
+ import{TraceFlags}from"#compiled/@opentelemetry/api/index.js";function isSampledTrace(e){return(e.traceFlags&TraceFlags.SAMPLED)===TraceFlags.SAMPLED}export{isSampledTrace};
@@ -0,0 +1,41 @@
1
+ import type { ChannelAudience } from "#shared/channel-audience.js";
2
+ export interface SpanExportContext {
3
+ readonly attributes: Readonly<Record<string, unknown>>;
4
+ readonly audience: ChannelAudience;
5
+ readonly name: string;
6
+ readonly spanId: string;
7
+ readonly traceId: string;
8
+ }
9
+ export type SpanExportPredicate = (span: SpanExportContext) => boolean;
10
+ export type SpanExportAttributeValue = string | number | boolean | readonly string[] | readonly number[] | readonly boolean[];
11
+ export type SpanAttributeDecision = {
12
+ readonly action: "keep";
13
+ } | {
14
+ readonly action: "drop";
15
+ } | {
16
+ readonly action: "replace";
17
+ readonly value: SpanExportAttributeValue;
18
+ };
19
+ export interface SpanExportPolicy {
20
+ /** Return false to block one span without blocking its trace. */
21
+ readonly span?: SpanExportPredicate;
22
+ /** Drop or replace individual span attributes after content filtering. */
23
+ readonly attribute?: (input: {
24
+ readonly key: string;
25
+ readonly span: SpanExportContext;
26
+ readonly value: unknown;
27
+ }) => SpanAttributeDecision;
28
+ }
29
+ /** Redact input content from every matching span. */
30
+ export declare function redactSpanInputs(when?: SpanExportPredicate): SpanExportPolicy;
31
+ /** Redact output content, exception details, and status messages from every matching span. */
32
+ export declare function redactSpanOutputs(when?: SpanExportPredicate): SpanExportPolicy;
33
+ /** Compose policies in declaration order. A drop or redaction from any policy is final. */
34
+ export declare function composeSpanExportPolicies(...policies: readonly SpanExportPolicy[]): SpanExportPolicy;
35
+ /** @internal */
36
+ export declare function spanExportPolicyStages(policy: SpanExportPolicy): readonly SpanExportPolicy[];
37
+ /** @internal */
38
+ export declare function contentRedactionForSpan(policy: SpanExportPolicy | undefined, span: SpanExportContext): {
39
+ readonly redactInputs: boolean;
40
+ readonly redactOutputs: boolean;
41
+ };
@@ -0,0 +1 @@
1
+ const contentRedactions=new WeakMap,composedPolicies=new WeakMap;function redactSpanInputs(t=()=>!0){let n={};return contentRedactions.set(n,{inputs:[t],outputs:[]}),n}function redactSpanOutputs(t=()=>!0){let n={};return contentRedactions.set(n,{inputs:[],outputs:[t]}),n}function composeSpanExportPolicies(...e){if(e.length===0)return{};if(e.length===1)return e[0];let n={};return composedPolicies.set(n,e.flatMap(spanExportPolicyStages)),n}function spanExportPolicyStages(e){return composedPolicies.get(e)??[e]}function contentRedactionForSpan(t,n){let r=t===void 0?void 0:contentRedactions.get(t);return{redactInputs:r?.inputs.some(e=>matches(e,n))??!1,redactOutputs:r?.outputs.some(e=>matches(e,n))??!1}}function matches(e,t){try{return e(t)}catch{return!0}}export{composeSpanExportPolicies,contentRedactionForSpan,redactSpanInputs,redactSpanOutputs,spanExportPolicyStages};
@@ -0,0 +1,2 @@
1
+ import { type Context } from "#compiled/@opentelemetry/api/index.js";
2
+ export declare function suppressTracing(context: Context): Context;
@@ -0,0 +1 @@
1
+ import{createContextKey}from"#compiled/@opentelemetry/api/index.js";const SUPPRESS_TRACING_KEY=createContextKey(`OpenTelemetry SDK Context Key SUPPRESS_TRACING`);function suppressTracing(e){return e.setValue(SUPPRESS_TRACING_KEY,!0)}export{suppressTracing};
@@ -306,6 +306,8 @@ export default defineChannel({
306
306
 
307
307
  The projection is re-evaluated whenever adapter state changes after channel event handlers run. Dynamic tool resolvers read it via `ctx.channel.metadata` and narrow it with `isChannel`. See [Dynamic capabilities](../guides/dynamic-capabilities) for the full consumption pattern.
308
308
 
309
+ Metadata may include an `audience` classification: `public`, `private`, or `unknown`. Omit it when the channel cannot classify the conversation confidently; eve normalizes missing and invalid values to `unknown`. Consumers must treat `unknown` as non-public.
310
+
309
311
  When a parent agent dispatches a subagent, the framework forwards the parent's channel metadata projection to the child. The same `metadata(state)` projector also serves instrumentation metadata resolvers.
310
312
 
311
313
  ## Continuation tokens
@@ -58,6 +58,8 @@ 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
+ Built-in messaging channels classify their instrumentation metadata with an `audience`: `public`, `private`, or `unknown`. Slack public channels and Chat SDK workspace-visible threads are public; direct and private conversations are private; platform surfaces without enough visibility evidence remain unknown.
62
+
61
63
  ## Channel delivery traces
62
64
 
63
65
  Instrumentation providers receive `channel.delivery.started` followed by
@@ -73,7 +73,7 @@ export default function Page() {
73
73
  }
74
74
  ```
75
75
 
76
- `agent.data.messages` and `agent.status` cover most chat UIs. The hook also surfaces HITL prompts (the spend approval from [Step 8](./guard-the-spend)), so the dashboard can render approve/cancel controls. For the full API, see [Frontend](../guides/frontend/overview).
76
+ `agent.data.messages` and `agent.status` cover most chat UIs. The generated Web Chat renders HITL prompts directly in the conversation: approvals get action controls, and `ask_question` gets a visible form with vertical choices, a text field, or both. The spend approval from [Step 8](./guard-the-spend) uses the same response path. For the full API, see [Frontend](../guides/frontend/overview).
77
77
 
78
78
  ## Replace `placeholderAuth`
79
79
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [