eve 0.43.0 → 0.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/src/channel/adapter.d.ts +2 -1
  3. package/dist/src/channel/instrumentation.js +1 -1
  4. package/dist/src/chunks/{use-eve-agent-C0SG1Ttk.js → use-eve-agent-BsLJiIbc.js} +224 -62
  5. package/dist/src/chunks/{use-eve-agent-D71oDil7.js → use-eve-agent-DpUEwS23.js} +222 -62
  6. package/dist/src/cli/commands/extension-init.js +1 -1
  7. package/dist/src/cli/commands/init.js +1 -1
  8. package/dist/src/cli/commands/registry-project.d.ts +3 -0
  9. package/dist/src/cli/commands/registry-project.js +2 -1
  10. package/dist/src/cli/commands/registry.d.ts +2 -0
  11. package/dist/src/cli/commands/registry.js +1 -1
  12. package/dist/src/cli/dev/tui/setup-commands.js +1 -1
  13. package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
  14. package/dist/src/client/eve-agent-store-helpers.d.ts +12 -0
  15. package/dist/src/client/eve-agent-store-helpers.js +2 -0
  16. package/dist/src/client/eve-agent-store.d.ts +8 -6
  17. package/dist/src/client/eve-agent-store.js +1 -2
  18. package/dist/src/client/ndjson.d.ts +3 -1
  19. package/dist/src/client/ndjson.js +3 -3
  20. package/dist/src/client/open-stream.d.ts +3 -0
  21. package/dist/src/client/open-stream.js +1 -1
  22. package/dist/src/compiled/.vendor-stamp.json +1 -1
  23. package/dist/src/compiled/jsonc-parser/index.d.ts +19 -0
  24. package/dist/src/compiler/extension-compatibility.d.ts +2 -2
  25. package/dist/src/compiler/extension-compatibility.js +1 -1
  26. package/dist/src/context/build-dynamic-tools.js +1 -1
  27. package/dist/src/context/dynamic-tool-lifecycle.d.ts +5 -1
  28. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  29. package/dist/src/context/keys.d.ts +4 -2
  30. package/dist/src/context/keys.js +1 -1
  31. package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
  32. package/dist/src/execution/dispatch-turn-step.js +1 -1
  33. package/dist/src/execution/eve-workflow-attributes.d.ts +3 -0
  34. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  35. package/dist/src/execution/pending-turn-state.d.ts +9 -0
  36. package/dist/src/execution/pending-turn-state.js +1 -0
  37. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  38. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  39. package/dist/src/execution/turn-workflow.js +1 -1
  40. package/dist/src/execution/workflow-steps.js +1 -1
  41. package/dist/src/execution/workflow-trace-context.js +1 -1
  42. package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
  43. package/dist/src/harness/instrumentation/content-policy.d.ts +6 -0
  44. package/dist/src/harness/instrumentation/content-policy.js +1 -0
  45. package/dist/src/harness/instrumentation/lifecycle.d.ts +6 -0
  46. package/dist/src/harness/instrumentation/native-events.d.ts +2 -0
  47. package/dist/src/harness/instrumentation/native-events.js +1 -1
  48. package/dist/src/harness/instrumentation/runtime-context.js +1 -1
  49. package/dist/src/harness/prepare-trace-context.d.ts +2 -0
  50. package/dist/src/harness/prepare-trace-context.js +1 -1
  51. package/dist/src/harness/runtime-actions.js +1 -1
  52. package/dist/src/harness/tool-loop.js +2 -2
  53. package/dist/src/internal/application/package.js +1 -1
  54. package/dist/src/internal/workflow-bundle/dynamic-remote-agent-transform.js +2 -2
  55. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +4 -4
  56. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +3 -4
  57. package/dist/src/internal/workflow-bundle/stable-module-id.d.ts +6 -0
  58. package/dist/src/internal/workflow-bundle/stable-module-id.js +1 -0
  59. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  60. package/dist/src/public/channels/chat-sdk/audience.d.ts +2 -0
  61. package/dist/src/public/channels/chat-sdk/audience.js +1 -0
  62. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +2 -0
  63. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  64. package/dist/src/public/channels/discord/audience.d.ts +5 -0
  65. package/dist/src/public/channels/discord/audience.js +1 -0
  66. package/dist/src/public/channels/discord/discordChannel.d.ts +2 -0
  67. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  68. package/dist/src/public/channels/discord/inbound.d.ts +1 -0
  69. package/dist/src/public/channels/discord/inbound.js +1 -1
  70. package/dist/src/public/channels/discord/index.d.ts +1 -0
  71. package/dist/src/public/channels/index.d.ts +3 -2
  72. package/dist/src/public/channels/slack/slackChannel.d.ts +4 -0
  73. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  74. package/dist/src/public/channels/teams/index.d.ts +1 -0
  75. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  76. package/dist/src/public/channels/telegram/audience.d.ts +3 -0
  77. package/dist/src/public/channels/telegram/audience.js +1 -0
  78. package/dist/src/public/channels/telegram/index.d.ts +1 -0
  79. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  80. package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -0
  81. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  82. package/dist/src/public/definitions/channel.d.ts +1 -0
  83. package/dist/src/public/instrumentation/otel.d.ts +6 -10
  84. package/dist/src/public/instrumentation/otel.js +1 -1
  85. package/dist/src/public/tools/approval/approval-helpers.js +1 -1
  86. package/dist/src/react/use-eve-agent.d.ts +10 -1
  87. package/dist/src/react/use-eve-agent.js +1 -1
  88. package/dist/src/runtime/attributes/emit.d.ts +1 -1
  89. package/dist/src/runtime/attributes/normalize.d.ts +1 -1
  90. package/dist/src/runtime/attributes/normalize.js +1 -1
  91. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -2
  92. package/dist/src/runtime/framework-tools/subagent/local.js +1 -1
  93. package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
  94. package/dist/src/setup/integrations/linq/connect.js +1 -1
  95. package/dist/src/setup/primitives/pm/npm.js +1 -1
  96. package/dist/src/setup/primitives/pm/pnpm.js +5 -9
  97. package/dist/src/setup/primitives/pm/types.d.ts +0 -2
  98. package/dist/src/setup/scaffold/create/project.js +1 -1
  99. package/dist/src/setup/scaffold/create/web-template.d.ts +10 -4
  100. package/dist/src/setup/scaffold/create/web-template.js +669 -74
  101. package/dist/src/shared/channel-audience.d.ts +7 -0
  102. package/dist/src/shared/channel-audience.js +1 -0
  103. package/dist/src/shared/channel-definition.d.ts +2 -1
  104. package/dist/src/shared/durable-dynamic-tool-callbacks.d.ts +43 -19
  105. package/dist/src/shared/durable-dynamic-tool-callbacks.js +1 -1
  106. package/dist/src/svelte/index.js +1 -1
  107. package/dist/src/svelte/use-eve-agent.d.ts +4 -0
  108. package/dist/src/svelte/use-eve-agent.js +1 -1
  109. package/dist/src/tasks/delivery-context.d.ts +9 -0
  110. package/dist/src/tasks/delivery-context.js +5 -2
  111. package/dist/src/tracing/agent-action-instrumentation.js +1 -1
  112. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  113. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -1
  114. package/dist/src/tracing/agent-otel-provider.d.ts +2 -0
  115. package/dist/src/tracing/agent-otel-provider.js +2 -2
  116. package/dist/src/tracing/agent-otel-session-context.d.ts +2 -0
  117. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  118. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  119. package/dist/src/tracing/agent-trace-state.d.ts +3 -0
  120. package/dist/src/tracing/channel-audience-context.d.ts +4 -0
  121. package/dist/src/tracing/channel-audience-context.js +1 -0
  122. package/dist/src/tracing/content-attributes.js +1 -1
  123. package/dist/src/tracing/content-span-processor.d.ts +7 -7
  124. package/dist/src/tracing/content-span-processor.js +1 -1
  125. package/dist/src/tracing/install-instrumentation-runtime.js +1 -1
  126. package/dist/src/tracing/local-instrumentation-runtime.d.ts +3 -0
  127. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  128. package/dist/src/tracing/local-traces.d.ts +1 -10
  129. package/dist/src/tracing/local-traces.js +1 -1
  130. package/dist/src/tracing/otel-declaration.d.ts +34 -27
  131. package/dist/src/tracing/otel-declaration.js +1 -1
  132. package/dist/src/tracing/sampled-trace.d.ts +2 -0
  133. package/dist/src/tracing/sampled-trace.js +1 -0
  134. package/dist/src/tracing/span-export-policy.d.ts +41 -0
  135. package/dist/src/tracing/span-export-policy.js +1 -0
  136. package/dist/src/tracing/suppress-tracing.d.ts +2 -0
  137. package/dist/src/tracing/suppress-tracing.js +1 -0
  138. package/dist/src/vue/index.js +1 -1
  139. package/dist/src/vue/use-eve-agent.d.ts +4 -0
  140. package/dist/src/vue/use-eve-agent.js +1 -1
  141. package/docs/channels/custom.mdx +2 -0
  142. package/docs/concepts/sessions-runs-and-streaming.md +1 -1
  143. package/docs/guides/dynamic-capabilities.md +10 -2
  144. package/docs/guides/frontend/nextjs.mdx +23 -0
  145. package/docs/guides/frontend/overview.mdx +24 -9
  146. package/docs/guides/frontend/use-eve-agent-svelte.mdx +9 -9
  147. package/docs/guides/frontend/use-eve-agent-vue.mdx +9 -9
  148. package/docs/guides/instrumentation.md +2 -0
  149. package/docs/tools/overview.mdx +5 -4
  150. package/docs/tutorial/ship-it.mdx +1 -1
  151. package/package.json +1 -1
@@ -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};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-D71oDil7.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-DpUEwS23.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -33,6 +33,8 @@ export interface UseEveAgentReturn<TData> {
33
33
  readonly error: ComputedRef<Error | undefined>;
34
34
  /** Raw server events from this session (authoritative stream). */
35
35
  readonly events: ComputedRef<readonly MessageStreamEvent[]>;
36
+ /** Replay the attached durable session and follow its in-flight turn, if any. */
37
+ readonly resume: () => Promise<void>;
36
38
  /** Clear all state and start a new session. */
37
39
  readonly reset: () => void;
38
40
  /** Send a message with optional turn settings. */
@@ -98,6 +100,8 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
98
100
  * @default defaultMessageReducer()
99
101
  */
100
102
  readonly reducer?: EveAgentReducer<TData>;
103
+ /** Replay the attached durable session after mount. Requires `initialSession` or `session`. */
104
+ readonly resume?: boolean;
101
105
  /**
102
106
  * Externally owned {@link ClientSession} to bind instead of creating one.
103
107
  *
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-D71oDil7.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-DpUEwS23.js";
2
2
 
3
3
  export { useEveAgent };
@@ -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
@@ -86,7 +86,7 @@ Note: consider the privacy, confidentiality, and user-experience implications fo
86
86
 
87
87
  A delegated subagent publishes progress on its own child-session stream. The parent only emits `subagent.called` with a `childSessionId`, which a client uses to attach.
88
88
 
89
- `step.failed` and `turn.failed` carry `{ code, message, details? }` for the failed fragment or turn, and `session.failed` is the terminal session-level variant. `turn.cancelled` is not a failure: the cancelled turn ends without any failure event, `session.waiting` follows, and the session accepts the next message normally — whatever the turn streamed before cancellation stays on the stream, while durable history keeps only what had already settled. When a turn requested an output schema, the finalized payload lands on `result.completed` as `data.result` before the turn boundary. `authorization.required` carries the sign-in challenge (`data.authorization` may include `url`, `userCode`, `expiresAt`, `instructions`), and `authorization.completed` carries `data.outcome` (`"authorized" | "declined" | "failed" | "timed-out"`).
89
+ `step.failed` and `turn.failed` carry `{ code, message, details? }` for the failed fragment or turn, and `session.failed` is the terminal session-level variant. `turn.cancelled` is not a failure: the cancelled turn ends without any failure event, `session.waiting` follows, and the session accepts the next message normally. Whatever the turn streamed before cancellation stays on the stream. Durable history keeps the accepted user input and previously settled work, but discards incomplete assistant output and unfinished tool state. When a turn requested an output schema, the finalized payload lands on `result.completed` as `data.result` before the turn boundary. `authorization.required` carries the sign-in challenge (`data.authorization` may include `url`, `userCode`, `expiresAt`, `instructions`), and `authorization.completed` carries `data.outcome` (`"authorized" | "declined" | "failed" | "timed-out"`).
90
90
 
91
91
  ## The event envelope
92
92
 
@@ -166,7 +166,15 @@ Write callback properties as inline function expressions, arrows, method shortha
166
166
 
167
167
  Closure values must be JSON-serializable. Plain objects, arrays, strings, finite numbers, booleans, and `null` are supported; `undefined` object properties are omitted. Functions, class instances, `Date`, `Map`, symbols, non-finite numbers, and cyclic values fail resolution with the tool name and callback phase instead of being serialized lossily.
168
168
 
169
- Call expressions such as `execute: makeExecutor()` are not transformed. Put the callback body directly in `defineTool()` inside an authored module; eve-provided factories may also supply pre-registered callbacks. eve rejects a dynamic tool if any present callback lacks durable metadata, and replay never reruns the current resolver to recover one.
169
+ Call expressions such as `execute: makeExecutor()` are not transformed. Put the callback body directly in `defineTool()` inside an authored module; eve-provided factories may also supply pre-registered callbacks. eve rejects a dynamic tool if any present callback lacks durable metadata.
170
+
171
+ ### Identity and redeploys
172
+
173
+ A parked call binds to its callback by **tool name and phase** — the same identity a static tool uses — never by source position. This gives dynamic tools static-tool semantics across deploys:
174
+
175
+ - Editing a callback body (or anything else that does not change tool names) is safe: replaying a parked call runs the latest deployed code with the closure values snapshotted when the call was made.
176
+ - If a persisted callback has no registered implementation (fresh process after a crash, or after a redeploy), eve re-runs `session.started` resolvers once to rebind it, then replays.
177
+ - If the tool no longer exists under that name, replay fails closed with an explicit error instead of invoking something else. Turn-scoped and step-scoped tools are not rebound; a parked call to a missing one errors.
170
178
 
171
179
  ### Naming
172
180
 
@@ -189,7 +197,7 @@ A dynamic tool or skill whose name matches an **authored** one **overrides** it
189
197
  | `turn.started` | Once per turn | Every model call in the turn |
190
198
  | `step.started` | Before each model call | That model call |
191
199
 
192
- ¹ Workflow recovery can redeliver a resolver event, so keep resolvers idempotent. Replaying a parked callback does not depend on running the resolver again.
200
+ ¹ Workflow recovery can redeliver a resolver event, so keep resolvers idempotent. Replaying a parked callback does not depend on running the resolver again — except for the one-shot rebind described under [Identity and redeploys](#identity-and-redeploys).
193
201
 
194
202
  ### Execution order
195
203
 
@@ -90,6 +90,29 @@ const agent = useEveAgent({
90
90
 
91
91
  The browser still needs a production authentication policy. See [Authenticate browser requests](./overview#authenticate-browser-requests) for the default fail-closed behavior and channel configuration.
92
92
 
93
+ ## Use the generated Web Chat routes
94
+
95
+ `eve init --channel-web-nextjs` and `eve add channel/web` generate a chat UI with URL-addressed durable sessions:
96
+
97
+ - `/` is the initial landing page.
98
+ - `/s` opens the conversation layout without creating an eve session. The first message creates the session.
99
+ - `/s/[sessionId]` attaches to that durable session, replays its transcript, and follows an in-flight turn.
100
+
101
+ After the first message is accepted, Web Chat replaces the browser URL with `/s/{sessionId}` without remounting the active stream. Reloading that URL passes the session to `useEveAgent` with `resume: true`, so completed history is replayed and an unfinished response continues streaming. **New chat** navigates to the sessionless `/s` route; it does not reset or delete the prior session, which remains available at its URL.
102
+
103
+ The generated UI keeps transcript scroll position in browser `sessionStorage`. This is presentation state only and is not written to the eve session.
104
+
105
+ For a custom Next.js chat route, pass the route session ID explicitly:
106
+
107
+ ```tsx
108
+ const agent = useEveAgent({
109
+ initialSession: { sessionId, streamIndex: 0 },
110
+ resume: true,
111
+ });
112
+ ```
113
+
114
+ See [Resumable sessions](./overview#resumable-sessions) for persistence and replay semantics.
115
+
93
116
  ## Dev vs deploy topology
94
117
 
95
118
  - **Local dev.** `npm run dev` boots the eve dev server next to `next dev` and rewrites the eve routes over to it. The browser only ever talks to the Next.js origin.
@@ -26,7 +26,7 @@ For a public demo, use `none()` from `eve/channels/auth` to admit anonymous requ
26
26
 
27
27
  ## Basic chat (React)
28
28
 
29
- The hook lives in `eve/react`. Render `data.messages`, gate the composer on `status`, and send text with `send`:
29
+ The hook lives in `eve/react`. Render `data.messages`, use `status` to steer follow-ups during an active turn, and send text with `send`:
30
30
 
31
31
  ```tsx
32
32
  "use client";
@@ -44,7 +44,7 @@ export function Chat() {
44
44
  const form = new FormData(event.currentTarget);
45
45
  const message = String(form.get("message") ?? "").trim();
46
46
  if (message.length > 0) {
47
- void agent.send(message);
47
+ void agent.send(message, isBusy ? { turnPolicy: "steer" } : undefined);
48
48
  }
49
49
  }}
50
50
  >
@@ -56,10 +56,8 @@ export function Chat() {
56
56
  )}
57
57
  </article>
58
58
  ))}
59
- <input name="message" disabled={isBusy} />
60
- <button disabled={isBusy} type="submit">
61
- Send
62
- </button>
59
+ <input name="message" />
60
+ <button type="submit">Send</button>
63
61
  </form>
64
62
  );
65
63
  }
@@ -78,6 +76,7 @@ export function Chat() {
78
76
  | `session` | Serializable fixed session cursor (`sessionId`, `streamIndex`). |
79
77
  | `send` | Send text or a multi-part message, with per-turn options. |
80
78
  | `respond` | Answer pending HITL input requests, with per-turn options. |
79
+ | `resume` | Replay an attached session and follow its in-flight turn. |
81
80
  | `cancel` | Request durable cancellation of the active turn. |
82
81
  | `reset` | Clear local events, data, errors, and the local session cursor. |
83
82
 
@@ -105,7 +104,13 @@ await agent.send([
105
104
  ]);
106
105
  ```
107
106
 
108
- Assistant text, reasoning, tool calls, and tool results stream into `data` as they arrive, and `status` moves from `ready` to `submitted` to `streaming` and back. Call `cancel()` to stop the durable server-side turn, and `reset()` to clear local state so the next send starts a fresh durable session.
107
+ Assistant text, reasoning, tool calls, and tool results stream into `data` as they arrive, and `status` moves from `ready` to `submitted` to `streaming` and back. To replace an active turn with a follow-up, send the message with `turnPolicy: "steer"`. eve accepts the message through the durable session, cancels the active turn, and keeps the hook attached through the replacement turn:
108
+
109
+ ```tsx
110
+ await agent.send(message, { turnPolicy: "steer" });
111
+ ```
112
+
113
+ Other message sends and HITL responses reject while the hook is processing a turn. Call `cancel()` to stop the durable server-side turn without replacing it, and `reset()` to clear local state so the next send starts a fresh durable session.
109
114
 
110
115
  `cancel()` can be called as soon as `status` is `"submitted"`; the hook waits for the active response to identify its turn when necessary, sends one guarded cancellation request, and keeps the event stream attached. The promise resolves when eve accepts the request or reports that no turn is active, and rejects if the cancellation request fails. The turn then settles on the same stream as `turn.cancelled` followed by `session.waiting`, so the session is safe to continue.
111
116
 
@@ -275,6 +280,7 @@ const [saved] = useState<SavedEveChat>(() => {
275
280
  const agent = useEveAgent({
276
281
  initialEvents: saved.events ?? [],
277
282
  initialSession: saved.session,
283
+ resume: saved.session !== undefined,
278
284
  onFinish(snapshot) {
279
285
  localStorage.setItem(
280
286
  "eve-chat",
@@ -295,9 +301,18 @@ then save a final snapshot in `onFinish`.
295
301
 
296
302
  `initialEvents` must be an ordered prefix of the same session's stream, but its endpoint does not have to line up exactly with where the stream resumes. Every event carries a stable [`meta.id`](/docs/concepts/sessions-runs-and-streaming#the-event-envelope), and the store drops any event whose id it has already applied — so a saved log that overlaps the replayed prefix renders once, and `onEvent` only fires for events your UI has not seen.
297
303
 
298
- For multiple chat threads, keep one saved event log and session cursor per thread. `agent`, `host`, `reducer`, `session`, `initialEvents`, `initialSession`, `auth`, `headers`, and `optimistic` are read when the hook creates its store, so remount the chat component when switching threads, for example with `key={chat.id}`.
304
+ For multiple chat threads, keep one saved event log and session cursor per thread. `agent`, `host`, `reducer`, `session`, `initialEvents`, `initialSession`, `auth`, `headers`, `optimistic`, and `resume` are read when the hook creates its store, so remount the chat component when switching threads, for example with `key={chat.id}`.
305
+
306
+ Pass `resume: true` with `initialSession` to rebuild the projection from the durable stream after mount. If the stream ends at an in-flight turn, the binding stays attached until that turn reaches its boundary. If the stream already ends at a settled session boundary, replay stops at the history tail.
307
+
308
+ ```tsx
309
+ const agent = useEveAgent({
310
+ initialSession: { sessionId, streamIndex: 0 },
311
+ resume: true,
312
+ });
313
+ ```
299
314
 
300
- If the user can refresh or navigate immediately after pressing send, create your app-level chat row and store the pending user message before calling `send()`. After the request starts, persist the session state as soon as it contains a `sessionId`, then reconnect an interrupted in-flight turn with `session.stream({ startIndex: savedEvents.length })` from the lower-level client.
315
+ If the user can refresh or navigate immediately after pressing send, create your app-level chat row before calling `send()`, then persist the session ID from `onSessionChange`. This lets the reloaded UI mount with that ID and pass `resume: true` while the durable turn is still running.
301
316
 
302
317
  ## Custom hosts and headers
303
318
 
@@ -44,14 +44,14 @@ Call the binding once for a conversation and read its reactive getters directly.
44
44
 
45
45
  The state fields are reactive getters; the commands are ordinary methods:
46
46
 
47
- | Property | Svelte shape |
48
- | ------------------------------------ | --------------------------------- |
49
- | `data` | `TData` |
50
- | `status` | `UseEveAgentStatus` |
51
- | `error` | `Error \| undefined` |
52
- | `events` | `readonly MessageStreamEvent[]` |
53
- | `session` | `ClientSessionState \| undefined` |
54
- | `send`, `respond`, `cancel`, `reset` | Methods |
47
+ | Property | Svelte shape |
48
+ | ---------------------------------------------- | --------------------------------- |
49
+ | `data` | `TData` |
50
+ | `status` | `UseEveAgentStatus` |
51
+ | `error` | `Error \| undefined` |
52
+ | `events` | `readonly MessageStreamEvent[]` |
53
+ | `session` | `ClientSessionState \| undefined` |
54
+ | `send`, `respond`, `resume`, `cancel`, `reset` | Methods |
55
55
 
56
56
  Read the getters directly in templates, `$derived`, or `$effect`. The [shared returned-state reference](./overview#returned-state) describes what each value and command does.
57
57
 
@@ -106,7 +106,7 @@ See [Human-in-the-loop prompts](./overview#human-in-the-loop-prompts) for reques
106
106
 
107
107
  ## Cancel, reset, and resume
108
108
 
109
- Call `agent.cancel()` to stop the durable server-side turn while the binding remains attached through settlement. Destroying the component only disconnects its local stream; it does not cancel server execution. Call `agent.reset()` to clear local state and start a new session. Pass `initialSession` and `initialEvents` to restore a saved conversation. See [Resumable sessions](./overview#resumable-sessions) for the persistence contract and [Sending and streaming](./overview#sending-and-streaming) for cancellation behavior.
109
+ Call `agent.cancel()` to stop the durable server-side turn while the binding remains attached through settlement. Destroying the component only disconnects its local stream; it does not cancel server execution. Call `agent.reset()` to clear local state and start a new session. Pass `initialSession`, `initialEvents`, and `resume: true` to restore a saved conversation and follow an in-flight turn. Use `agent.resume()` directly when restoration is controlled imperatively. See [Resumable sessions](./overview#resumable-sessions) for the persistence contract and [Sending and streaming](./overview#sending-and-streaming) for cancellation behavior.
110
110
 
111
111
  ## Custom host and credentials
112
112
 
@@ -43,14 +43,14 @@ async function handleSubmit() {
43
43
 
44
44
  The state fields are computed refs; the commands are ordinary methods:
45
45
 
46
- | Property | Vue shape |
47
- | ------------------------------------ | ---------------------------------------------- |
48
- | `data` | `ComputedRef<TData>` |
49
- | `status` | `ComputedRef<UseEveAgentStatus>` |
50
- | `error` | `ComputedRef<Error \| undefined>` |
51
- | `events` | `ComputedRef<readonly MessageStreamEvent[]>` |
52
- | `session` | `ComputedRef<ClientSessionState \| undefined>` |
53
- | `send`, `respond`, `cancel`, `reset` | Methods |
46
+ | Property | Vue shape |
47
+ | ---------------------------------------------- | ---------------------------------------------- |
48
+ | `data` | `ComputedRef<TData>` |
49
+ | `status` | `ComputedRef<UseEveAgentStatus>` |
50
+ | `error` | `ComputedRef<Error \| undefined>` |
51
+ | `events` | `ComputedRef<readonly MessageStreamEvent[]>` |
52
+ | `session` | `ComputedRef<ClientSessionState \| undefined>` |
53
+ | `send`, `respond`, `resume`, `cancel`, `reset` | Methods |
54
54
 
55
55
  Destructuring preserves reactivity because each state value remains a ref. Read refs with `.value` in `<script>` and without `.value` in a template. The [shared returned-state reference](./overview#returned-state) describes what each value and command does.
56
56
 
@@ -108,7 +108,7 @@ See [Human-in-the-loop prompts](./overview#human-in-the-loop-prompts) for reques
108
108
 
109
109
  ## Cancel, reset, and resume
110
110
 
111
- Call `cancel()` to stop the durable server-side turn while the composable remains attached through settlement. Disposing the component only disconnects its local stream; it does not cancel server execution. Call `reset()` to clear local state and start a new session. Pass `initialSession` and `initialEvents` to restore a saved conversation. See [Resumable sessions](./overview#resumable-sessions) for the persistence contract and [Sending and streaming](./overview#sending-and-streaming) for cancellation behavior.
111
+ Call `cancel()` to stop the durable server-side turn while the composable remains attached through settlement. Disposing the component only disconnects its local stream; it does not cancel server execution. Call `reset()` to clear local state and start a new session. Pass `initialSession`, `initialEvents`, and `resume: true` to restore a saved conversation and follow an in-flight turn. Use `resume()` directly when restoration is controlled imperatively. See [Resumable sessions](./overview#resumable-sessions) for the persistence contract and [Sending and streaming](./overview#sending-and-streaming) for cancellation behavior.
112
112
 
113
113
  ## Custom host and credentials
114
114
 
@@ -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
@@ -70,10 +70,11 @@ progress with `task.send({ kind: "update", message })` and the terminal result w
70
70
  in-memory callback dies with the process — so the cross-process executor wire remains
71
71
  framework-owned and is not yet a stable authored-tool API.
72
72
 
73
- Each task-triggered parent turn includes runtime-authored state for tasks started by the same
74
- parent turn. The model is instructed to keep related intermediate results silent while that state
75
- contains pending tasks. Once every related task is terminal, the state includes their outputs so
76
- the model can combine the useful results.
73
+ After the initiating turn accepts background tasks, eve supplies runtime-authored state for that
74
+ cohort and instructs the model to acknowledge that the work started without waiting for results.
75
+ Later task-triggered parent turns receive fresh state for the same cohort. The model is instructed
76
+ to keep related intermediate results silent while any task remains pending. Once every related
77
+ task is terminal, the state includes their outputs so the model can combine the useful results.
77
78
 
78
79
  ### The `ctx` parameter
79
80
 
@@ -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.1",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [