eve 0.27.13 → 0.28.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 (144) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/src/channel/adapter.d.ts +5 -5
  3. package/dist/src/channel/session.d.ts +2 -2
  4. package/dist/src/channel/types.d.ts +10 -6
  5. package/dist/src/chunks/{use-eve-agent-CsSQOKnp.js → use-eve-agent-CZkX_ZTT.js} +90 -1
  6. package/dist/src/chunks/{use-eve-agent-CWYe-vqE.js → use-eve-agent-hdPX68_i.js} +90 -1
  7. package/dist/src/cli/dev/tui/runner.js +1 -1
  8. package/dist/src/cli/dev/tui/subagent-pump.d.ts +8 -2
  9. package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
  10. package/dist/src/cli/invoke/result.d.ts +15 -0
  11. package/dist/src/cli/invoke/result.js +1 -1
  12. package/dist/src/client/eve-agent-store.d.ts +7 -4
  13. package/dist/src/client/eve-agent-store.js +1 -1
  14. package/dist/src/client/index.d.ts +3 -3
  15. package/dist/src/client/index.js +1 -1
  16. package/dist/src/client/message-action-parts.js +1 -1
  17. package/dist/src/client/message-reducer-types.d.ts +5 -3
  18. package/dist/src/client/message-response.d.ts +4 -4
  19. package/dist/src/client/ndjson.d.ts +3 -3
  20. package/dist/src/client/open-stream.d.ts +2 -2
  21. package/dist/src/client/output-schema.d.ts +2 -2
  22. package/dist/src/client/reducer.d.ts +2 -2
  23. package/dist/src/client/session-utils.d.ts +5 -5
  24. package/dist/src/client/session.d.ts +2 -2
  25. package/dist/src/client/types.d.ts +2 -2
  26. package/dist/src/compiler/compile-from-memory.d.ts +1 -0
  27. package/dist/src/compiler/extension-compatibility.d.ts +8 -8
  28. package/dist/src/compiler/extension-compatibility.js +1 -1
  29. package/dist/src/compiler/manifest.d.ts +2 -2
  30. package/dist/src/compiler/manifest.js +1 -1
  31. package/dist/src/compiler/normalize-agent-config.js +1 -1
  32. package/dist/src/context/dynamic-instruction-lifecycle.d.ts +2 -2
  33. package/dist/src/context/dynamic-model-lifecycle.d.ts +2 -2
  34. package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -2
  35. package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -2
  36. package/dist/src/context/hook-lifecycle.d.ts +2 -2
  37. package/dist/src/evals/assertions/run.d.ts +3 -3
  38. package/dist/src/evals/match.d.ts +4 -4
  39. package/dist/src/evals/runner/derive-run-facts.d.ts +2 -2
  40. package/dist/src/evals/session.d.ts +3 -3
  41. package/dist/src/evals/types.d.ts +12 -12
  42. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  43. package/dist/src/execution/route-child-delivery.d.ts +4 -3
  44. package/dist/src/execution/route-child-delivery.js +1 -1
  45. package/dist/src/execution/session-delivery-hook.d.ts +1 -0
  46. package/dist/src/execution/session-delivery-hook.js +1 -1
  47. package/dist/src/execution/session-timeout-control.d.ts +9 -0
  48. package/dist/src/execution/session-timeout-control.js +1 -0
  49. package/dist/src/execution/session-timeout-steps.d.ts +13 -0
  50. package/dist/src/execution/session-timeout-steps.js +1 -0
  51. package/dist/src/execution/session-timeout-workflow.d.ts +6 -0
  52. package/dist/src/execution/session-timeout-workflow.js +1 -0
  53. package/dist/src/execution/session-timeout.d.ts +2 -0
  54. package/dist/src/execution/session-timeout.js +1 -0
  55. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  56. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  57. package/dist/src/execution/subagent-hitl-proxy.d.ts +5 -1
  58. package/dist/src/execution/subagent-hitl-proxy.js +1 -1
  59. package/dist/src/execution/terminal-session-completion-step.d.ts +5 -0
  60. package/dist/src/execution/terminal-session-completion-step.js +1 -0
  61. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  62. package/dist/src/execution/turn-workflow.js +1 -1
  63. package/dist/src/execution/workflow-entry.d.ts +1 -0
  64. package/dist/src/execution/workflow-entry.js +1 -1
  65. package/dist/src/execution/workflow-runtime.d.ts +4 -0
  66. package/dist/src/execution/workflow-runtime.js +1 -1
  67. package/dist/src/execution/workflow-steps.d.ts +5 -2
  68. package/dist/src/execution/workflow-steps.js +1 -1
  69. package/dist/src/harness/agent-otel-provider.js +1 -1
  70. package/dist/src/harness/ai-sdk-hook-bridge.js +1 -1
  71. package/dist/src/harness/input-extraction.js +1 -1
  72. package/dist/src/harness/input-request-class.d.ts +23 -0
  73. package/dist/src/harness/input-request-class.js +1 -0
  74. package/dist/src/harness/input-requests.d.ts +20 -9
  75. package/dist/src/harness/input-requests.js +1 -1
  76. package/dist/src/harness/instrumentation-lifecycle.d.ts +12 -1
  77. package/dist/src/harness/proxy-input-requests.d.ts +10 -4
  78. package/dist/src/harness/proxy-input-requests.js +1 -1
  79. package/dist/src/harness/session-limit-continuation.d.ts +0 -11
  80. package/dist/src/harness/session-limit-continuation.js +1 -1
  81. package/dist/src/harness/session-limit-enforcement.d.ts +3 -2
  82. package/dist/src/harness/session-limit-enforcement.js +1 -1
  83. package/dist/src/harness/session-token-limits.d.ts +41 -0
  84. package/dist/src/harness/session-token-limits.js +1 -0
  85. package/dist/src/harness/stale-input-responses.js +1 -1
  86. package/dist/src/harness/subagent-token-budget.d.ts +6 -4
  87. package/dist/src/harness/subagent-token-budget.js +1 -1
  88. package/dist/src/harness/tool-loop.js +1 -1
  89. package/dist/src/harness/turn-tag-state.d.ts +26 -17
  90. package/dist/src/harness/turn-tag-state.js +1 -1
  91. package/dist/src/harness/types.d.ts +4 -4
  92. package/dist/src/harness/workflow-lifecycle.d.ts +2 -2
  93. package/dist/src/internal/application/package.js +1 -1
  94. package/dist/src/internal/authored-definition/core.js +1 -1
  95. package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +1 -1
  96. package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
  97. package/dist/src/protocol/event-dedupe.d.ts +25 -0
  98. package/dist/src/protocol/event-dedupe.js +1 -0
  99. package/dist/src/protocol/event-id.d.ts +16 -0
  100. package/dist/src/protocol/event-id.js +1 -0
  101. package/dist/src/protocol/message.d.ts +39 -23
  102. package/dist/src/protocol/message.js +2 -2
  103. package/dist/src/public/channels/discord/discordChannel.d.ts +3 -3
  104. package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
  105. package/dist/src/public/channels/linear/linearChannel.d.ts +3 -3
  106. package/dist/src/public/channels/slack/hitl.js +1 -1
  107. package/dist/src/public/channels/slack/slackChannel.d.ts +3 -3
  108. package/dist/src/public/channels/teams/hitl.js +1 -1
  109. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
  110. package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -3
  111. package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
  112. package/dist/src/public/definitions/channel.d.ts +4 -4
  113. package/dist/src/public/definitions/hook.d.ts +2 -2
  114. package/dist/src/react/use-eve-agent.d.ts +3 -2
  115. package/dist/src/runtime/framework-tools/ask-question.js +1 -1
  116. package/dist/src/runtime/hooks/registry.d.ts +2 -2
  117. package/dist/src/runtime/input/types.d.ts +19 -4
  118. package/dist/src/runtime/input/types.js +1 -1
  119. package/dist/src/runtime/resolve-agent.js +1 -1
  120. package/dist/src/runtime/types.d.ts +2 -2
  121. package/dist/src/setup/scaffold/create/project.js +1 -1
  122. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  123. package/dist/src/setup/scaffold/create/web-template.js +2 -2
  124. package/dist/src/shared/agent-definition.d.ts +12 -0
  125. package/dist/src/shared/dynamic-tool-definition.d.ts +2 -2
  126. package/dist/src/shared/ulid.d.ts +39 -0
  127. package/dist/src/shared/ulid.js +1 -0
  128. package/dist/src/svelte/index.js +1 -1
  129. package/dist/src/svelte/use-eve-agent.d.ts +4 -4
  130. package/dist/src/svelte/use-eve-agent.js +1 -1
  131. package/dist/src/vue/index.js +1 -1
  132. package/dist/src/vue/use-eve-agent.d.ts +4 -4
  133. package/dist/src/vue/use-eve-agent.js +1 -1
  134. package/docs/agent-config.md +28 -16
  135. package/docs/concepts/execution-model-and-durability.mdx +1 -1
  136. package/docs/concepts/sessions-runs-and-streaming.md +61 -0
  137. package/docs/guides/client/streaming.mdx +9 -3
  138. package/docs/guides/frontend/overview.mdx +4 -2
  139. package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -1
  140. package/docs/guides/frontend/use-eve-agent-vue.mdx +10 -10
  141. package/docs/guides/hooks.md +40 -2
  142. package/docs/guides/instrumentation.md +4 -0
  143. package/docs/tools/human-in-the-loop.md +5 -0
  144. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # eve
2
2
 
3
+ ## 0.28.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 98d17c7: Input requests now include a required `kind` discriminator so clients can route tool approvals, questions, and session-limit decisions without inferring behavior from tool names or request IDs. Descendant session-limit Stop responses now let the parent own turn cancellation, avoiding a parent-child wait cycle.
8
+ - 7ff4f77: Every session stream event now carries a stable, `evt_`-prefixed ULID in `meta.id`, and stream consumers use it to drop re-delivery without collapsing distinct events. Retried steps re-emit under new ids, while reconnects, rewinds, and saved-log overlap preserve the original id.
9
+
10
+ **Breaking:** `MessageStreamEvent` is now the canonical public type for events read from a stream, with `meta.id` and `meta.at` required. `HandleMessageStreamEvent` remains as a deprecated alias, so existing imports continue to compile; code that constructs unstamped events under that type must add the envelope. Client, channel, hook, frontend, and eval APIs carry `MessageStreamEvent` end to end, so consumers can read `meta.id` without guards. Events persisted by an earlier version carry `meta.at` but no `meta.id`, so rewinding into a session that started before this release yields events whose id is absent despite the type. eve passes those through rather than dropping them, and they cannot be deduplicated; the exposure ends when those sessions do.
11
+
12
+ ### Patch Changes
13
+
14
+ - 28417c4: Declining a session token-limit prompt no longer leaves a stale copy of the prompt in the parked session. Previously the cancelled turn settled with a snapshot that resurrected the already-answered prompt, so every follow-up message was queued behind it and never re-raised the prompt; follow-ups now reach the budget gate, which re-raises a fresh prompt while the session is over budget.
15
+ - 33ea372: Records Vercel AI Gateway cost on local trace spans: `agent.step` spans now carry `gen_ai.usage.cost`, `gen_ai.usage.gateway_cost`, `gen_ai.usage.input_cost`/`output_cost`, and `gen_ai.generation.id` when the gateway reports them. The attributes only exist for gateway-served calls — other providers emit nothing.
16
+ - 28417c4: Session token limits are now tracked as a runtime limit — an absolute lifetime-usage ceiling that each approved continuation re-anchors to `usage + configured limit` — replacing the window-baseline bookkeeping. Behavior is unchanged except the continuation prompt's `usedTokens` now reports the absolute session total instead of the window-relative amount.
17
+ - feac858: Complete durable sessions after 30 days by default, and add `limits.sessionTimeoutMs` to configure or disable the lifetime for each agent. Once an expired session settles, the next qualifying channel message for its continuation starts a fresh session.
18
+ - 28417c4: Keep one session token-limit prompt pending while concurrent input queues behind it. Approving restores the configured budget window, delegated sessions inherit from the fresh window, and zero-quota child tasks no longer raise continuation prompts that cannot grant tokens.
19
+ - dbc8eae: Splits token usage on local trace spans: model and step spans now record `gen_ai.usage.cache_read.input_tokens` and `gen_ai.usage.cache_creation.input_tokens` (OTel GenAI semantic-convention names) alongside the input/output totals when the provider reports detailed usage — cached tokens price differently, so the split makes cost attribution exact. Providers without detailed usage emit only the totals.
20
+ - 46c6ce3: The dev TUI now renders the session token-limit continuation prompt as a proper question — prompt copy and labeled Approve/Stop options in the question pane — instead of a generic y/n tool-approval line, and answers every confirmation prompt with the request's own option ids instead of hardcoded `approve`/`deny`. Previously, approving the continuation prompt in the TUI submitted an option the server did not recognize, so the same prompt was re-raised indefinitely.
21
+
3
22
  ## 0.27.13
4
23
 
5
24
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  import type { ContextAccessor } from "#context/key.js";
2
2
  import type { StepInput } from "#harness/types.js";
3
- import type { HandleMessageStreamEvent } from "#protocol/message.js";
3
+ import type { UnstampedMessageStreamEvent } from "#protocol/message.js";
4
4
  import type { SessionHandle } from "#channel/session.js";
5
5
  import type { DeliverPayload } from "#channel/types.js";
6
6
  import type { FetchFileResult, FetchFileFunction } from "#shared/channel-definition.js";
@@ -44,7 +44,7 @@ type StateOf<TCtx> = TCtx extends ChannelAdapterContext<infer S> ? S : Record<st
44
44
  * Extracts the `data` field type from a stream event by its `type` discriminant.
45
45
  * Events that carry no `data` field (e.g. `session.completed`) resolve to `undefined`.
46
46
  */
47
- type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessageStreamEvent, {
47
+ type EventData<T extends UnstampedMessageStreamEvent["type"]> = Extract<UnstampedMessageStreamEvent, {
48
48
  type: T;
49
49
  }> extends {
50
50
  data: infer D;
@@ -53,14 +53,14 @@ type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessa
53
53
  * A single outbound event handler. Receives the event's `data` (not the full
54
54
  * envelope) and the adapter context. Void return — side effects only.
55
55
  */
56
- type EventHandler<T extends HandleMessageStreamEvent["type"], TCtx extends ChannelAdapterContext<any> = ChannelAdapterContext> = (data: EventData<T>, ctx: TCtx) => void | Promise<void>;
56
+ type EventHandler<T extends UnstampedMessageStreamEvent["type"], TCtx extends ChannelAdapterContext<any> = ChannelAdapterContext> = (data: EventData<T>, ctx: TCtx) => void | Promise<void>;
57
57
  /**
58
58
  * Map of outbound event handlers keyed by event type. The adapter declares
59
59
  * handlers for the event types it cares about. For undeclared types, the
60
60
  * framework's default handlers run.
61
61
  */
62
62
  export type ChannelEventHandlers<TCtx extends ChannelAdapterContext<any> = ChannelAdapterContext> = {
63
- [K in HandleMessageStreamEvent["type"]]?: EventHandler<K, TCtx>;
63
+ [K in UnstampedMessageStreamEvent["type"]]?: EventHandler<K, TCtx>;
64
64
  };
65
65
  /**
66
66
  * Enriched return shape from a channel's {@link ChannelAdapter.fetchFile}
@@ -155,4 +155,4 @@ export declare function getAdapterKind(adapter: ChannelAdapter): string;
155
155
  * Throwing handlers are logged and swallowed so a downstream delivery
156
156
  * failure does not corrupt the event stream write path.
157
157
  */
158
- export declare function callAdapterEventHandler(adapter: ChannelAdapter, event: HandleMessageStreamEvent, ctx: ChannelAdapterContext): Promise<HandleMessageStreamEvent>;
158
+ export declare function callAdapterEventHandler(adapter: ChannelAdapter, event: UnstampedMessageStreamEvent, ctx: ChannelAdapterContext): Promise<UnstampedMessageStreamEvent>;
@@ -1,5 +1,5 @@
1
1
  import type { ContextAccessor } from "#context/key.js";
2
- import type { HandleMessageStreamEvent } from "#protocol/message.js";
2
+ import type { MessageStreamEvent } from "#protocol/message.js";
3
3
  import type { CancelTurnResult, Runtime } from "#channel/types.js";
4
4
  import type { SessionAuth } from "#context/keys.js";
5
5
  /**
@@ -29,7 +29,7 @@ export interface Session {
29
29
  */
30
30
  getEventStream(options?: {
31
31
  startIndex?: number;
32
- }): Promise<ReadableStream<HandleMessageStreamEvent>>;
32
+ }): Promise<ReadableStream<MessageStreamEvent>>;
33
33
  /**
34
34
  * Resolves the durable tail of the event stream: the zero-based index of
35
35
  * the last recorded event, or `-1` before the first.
@@ -1,5 +1,5 @@
1
1
  import type { UserContent } from "ai";
2
- import type { HandleMessageStreamEvent } from "#protocol/message.js";
2
+ import type { UnstampedMessageStreamEvent, MessageStreamEvent } from "#protocol/message.js";
3
3
  import type { CancelTurnStatus } from "#protocol/cancel-turn.js";
4
4
  import type { RunMode } from "#shared/run-mode.js";
5
5
  import type { RuntimeActionResult } from "#runtime/actions/types.js";
@@ -83,7 +83,7 @@ export interface SessionAuthContext {
83
83
  * Backed by `getWritable()` in the workflow runtime. Not part of the adapter
84
84
  * interface: the runtime always writes events itself.
85
85
  */
86
- export type EventEmitFn = (event: HandleMessageStreamEvent) => Promise<void>;
86
+ export type EventEmitFn = (event: UnstampedMessageStreamEvent) => Promise<void>;
87
87
  /**
88
88
  * Base deliver payload crossing the runtime boundary.
89
89
  *
@@ -117,6 +117,10 @@ export interface DeliverHookPayload {
117
117
  readonly kind: "deliver";
118
118
  readonly payloads: readonly DeliverPayload[];
119
119
  }
120
+ /** Internal deadline signal sent through the session's delivery hook. */
121
+ export interface SessionTimeoutHookPayload {
122
+ readonly kind: "session-timeout";
123
+ }
120
124
  /**
121
125
  * Runtime-action results resumed back into a parked parent workflow.
122
126
  */
@@ -153,7 +157,7 @@ export interface SubagentInputRequestHookPayload {
153
157
  readonly subagentName: string;
154
158
  }
155
159
  /** Authorization lifecycle event forwarded from a delegated child. */
156
- export type SubagentAuthorizationEvent = Extract<HandleMessageStreamEvent, {
160
+ export type SubagentAuthorizationEvent = Extract<UnstampedMessageStreamEvent, {
157
161
  type: "authorization.required" | "authorization.completed";
158
162
  }>;
159
163
  /**
@@ -172,7 +176,7 @@ export interface SubagentAuthorizationEventHookPayload {
172
176
  /**
173
177
  * Serializable payload sent through the workflow `resumeHook`.
174
178
  */
175
- export type HookPayload = DeliverHookPayload | RuntimeActionResultHookPayload | SubagentAuthorizationEventHookPayload | SubagentInputRequestHookPayload;
179
+ export type HookPayload = DeliverHookPayload | RuntimeActionResultHookPayload | SessionTimeoutHookPayload | SubagentAuthorizationEventHookPayload | SubagentInputRequestHookPayload;
176
180
  /**
177
181
  * Terminal callback metadata attached to a session at creation.
178
182
  *
@@ -318,7 +322,7 @@ export type RunResult = {
318
322
  */
319
323
  export interface RunHandle {
320
324
  readonly continuationToken: string;
321
- readonly events: ReadableStream<HandleMessageStreamEvent>;
325
+ readonly events: ReadableStream<MessageStreamEvent>;
322
326
  /**
323
327
  * Runtime-owned identifier for this session. Stream and inspection APIs
324
328
  * key on it: workflow-backed runs expose the workflow run id.
@@ -367,7 +371,7 @@ export interface Runtime {
367
371
  * The framework HTTP session-stream route forwards the `startIndex` query
368
372
  * parameter unchanged.
369
373
  */
370
- getEventStream(sessionId: string, options?: GetEventStreamOptions): Promise<ReadableStream<HandleMessageStreamEvent>>;
374
+ getEventStream(sessionId: string, options?: GetEventStreamOptions): Promise<ReadableStream<MessageStreamEvent>>;
371
375
  /**
372
376
  * Resolves the durable tail of a session's event stream: the zero-based
373
377
  * index of the last recorded event, or `-1` before the first. Callers use
@@ -296,6 +296,71 @@ function safeJsonStringify(value) {
296
296
  }
297
297
  }
298
298
 
299
+ //#endregion
300
+ //#region src/shared/ulid.ts
301
+ const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
302
+ const TIME_CHARS = 10;
303
+ const TIME_MAX = 2 ** 48 - 1;
304
+ const RANDOM_BYTES = 10;
305
+ function createUlidFactory() {
306
+ let lastTimeMs = -1;
307
+ const lastRandom = new Uint8Array(RANDOM_BYTES);
308
+ return function createUlidFromFactory() {
309
+ const now = Date.now();
310
+ if (!Number.isInteger(now) || now < 0 || now > TIME_MAX) throw new Error(`Cannot mint a ULID: timestamp must be an integer from 0 to ${TIME_MAX}.`);
311
+ if (now > lastTimeMs) {
312
+ lastTimeMs = now;
313
+ randomFill(lastRandom);
314
+ } else if (!incrementRandom(lastRandom)) {
315
+ if (lastTimeMs === TIME_MAX) throw new Error("Cannot mint a ULID: random component overflowed at the maximum timestamp.");
316
+ lastTimeMs += 1;
317
+ randomFill(lastRandom);
318
+ }
319
+ return `${encodeTime(lastTimeMs)}${encodeRandom(lastRandom)}`;
320
+ };
321
+ }
322
+ const createUlid = createUlidFactory();
323
+ function randomFill(target) {
324
+ const webCrypto = globalThis.crypto;
325
+ if (typeof webCrypto?.getRandomValues !== "function") throw new Error("Cannot mint a ULID: globalThis.crypto.getRandomValues is unavailable.");
326
+ webCrypto.getRandomValues(target);
327
+ }
328
+ function encodeTime(timeMs) {
329
+ let remaining = timeMs;
330
+ let encoded = "";
331
+ for (let index = 0; index < TIME_CHARS; index += 1) {
332
+ encoded = ENCODING[remaining % 32] + encoded;
333
+ remaining = Math.floor(remaining / 32);
334
+ }
335
+ return encoded;
336
+ }
337
+ function encodeRandom(bytes) {
338
+ let buffer = 0;
339
+ let bufferedBits = 0;
340
+ let encoded = "";
341
+ for (const byte of bytes) {
342
+ buffer = buffer << 8 | byte;
343
+ bufferedBits += 8;
344
+ while (bufferedBits >= 5) {
345
+ bufferedBits -= 5;
346
+ encoded += ENCODING[buffer >>> bufferedBits & 31];
347
+ }
348
+ buffer &= (1 << bufferedBits) - 1;
349
+ }
350
+ return encoded;
351
+ }
352
+ function incrementRandom(bytes) {
353
+ for (let index = bytes.length - 1; index >= 0; index -= 1) {
354
+ const byte = bytes[index] ?? 0;
355
+ if (byte < 255) {
356
+ bytes[index] = byte + 1;
357
+ bytes.fill(0, index + 1);
358
+ return true;
359
+ }
360
+ }
361
+ return false;
362
+ }
363
+
299
364
  //#endregion
300
365
  //#region src/protocol/message.ts
301
366
  const EVE_SESSION_ID_HEADER = "x-eve-session-id";
@@ -1081,6 +1146,24 @@ function withRedirectPolicy(init, redirect) {
1081
1146
  };
1082
1147
  }
1083
1148
 
1149
+ //#endregion
1150
+ //#region src/protocol/event-dedupe.ts
1151
+ function createEventDeduper() {
1152
+ const seen = /* @__PURE__ */ new Set();
1153
+ return {
1154
+ admit(event) {
1155
+ const id = event.meta?.id;
1156
+ if (id === void 0) return true;
1157
+ if (seen.has(id)) return false;
1158
+ seen.add(id);
1159
+ return true;
1160
+ },
1161
+ get size() {
1162
+ return seen.size;
1163
+ }
1164
+ };
1165
+ }
1166
+
1084
1167
  //#endregion
1085
1168
  //#region src/client/eve-agent-store.ts
1086
1169
  var EveAgentStore = class {
@@ -1088,6 +1171,7 @@ var EveAgentStore = class {
1088
1171
  #optimistic;
1089
1172
  #reducer;
1090
1173
  #subscribers = /* @__PURE__ */ new Set();
1174
+ #seenEvents = createEventDeduper();
1091
1175
  #abortController;
1092
1176
  #callbacks = {};
1093
1177
  #data;
@@ -1105,7 +1189,9 @@ var EveAgentStore = class {
1105
1189
  headers: init.headers,
1106
1190
  host: init.host ?? ""
1107
1191
  }).session(init.initialSession);
1108
- this.#events = [...init.initialEvents ?? []];
1192
+ const initialEvents = [];
1193
+ for (const event of init.initialEvents ?? []) if (this.#seenEvents.admit(event)) initialEvents.push(event);
1194
+ this.#events = initialEvents;
1109
1195
  this.#projectionEvents = [...this.#events];
1110
1196
  this.#optimistic = init.optimistic ?? true;
1111
1197
  this.#reducer = init.reducer;
@@ -1150,6 +1236,7 @@ var EveAgentStore = class {
1150
1236
  sawEvent = true;
1151
1237
  this.#status = "streaming";
1152
1238
  }
1239
+ if (!this.#seenEvents.admit(event)) continue;
1153
1240
  this.#events = [...this.#events, event];
1154
1241
  this.#applyServerEvent(event);
1155
1242
  this.#callbacks.onEvent?.(event);
@@ -1187,6 +1274,7 @@ var EveAgentStore = class {
1187
1274
  this.#abortController = void 0;
1188
1275
  this.#session = this.#createSession?.() ?? this.#session;
1189
1276
  this.#events = [];
1277
+ this.#seenEvents = createEventDeduper();
1190
1278
  this.#pendingMessageSubmission = void 0;
1191
1279
  this.#projectionEvents = [];
1192
1280
  this.#data = this.#reducer.initial();
@@ -1403,6 +1491,7 @@ function toMessageInputRequest(request) {
1403
1491
  return {
1404
1492
  allowFreeform: request.allowFreeform,
1405
1493
  display: request.display,
1494
+ kind: request.kind,
1406
1495
  options: request.options,
1407
1496
  prompt: request.prompt,
1408
1497
  requestId: request.requestId
@@ -296,6 +296,71 @@ function safeJsonStringify(value) {
296
296
  }
297
297
  }
298
298
 
299
+ //#endregion
300
+ //#region src/shared/ulid.ts
301
+ const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
302
+ const TIME_CHARS = 10;
303
+ const TIME_MAX = 2 ** 48 - 1;
304
+ const RANDOM_BYTES = 10;
305
+ function createUlidFactory() {
306
+ let lastTimeMs = -1;
307
+ const lastRandom = new Uint8Array(RANDOM_BYTES);
308
+ return function createUlidFromFactory() {
309
+ const now = Date.now();
310
+ if (!Number.isInteger(now) || now < 0 || now > TIME_MAX) throw new Error(`Cannot mint a ULID: timestamp must be an integer from 0 to ${TIME_MAX}.`);
311
+ if (now > lastTimeMs) {
312
+ lastTimeMs = now;
313
+ randomFill(lastRandom);
314
+ } else if (!incrementRandom(lastRandom)) {
315
+ if (lastTimeMs === TIME_MAX) throw new Error("Cannot mint a ULID: random component overflowed at the maximum timestamp.");
316
+ lastTimeMs += 1;
317
+ randomFill(lastRandom);
318
+ }
319
+ return `${encodeTime(lastTimeMs)}${encodeRandom(lastRandom)}`;
320
+ };
321
+ }
322
+ const createUlid = createUlidFactory();
323
+ function randomFill(target) {
324
+ const webCrypto = globalThis.crypto;
325
+ if (typeof webCrypto?.getRandomValues !== "function") throw new Error("Cannot mint a ULID: globalThis.crypto.getRandomValues is unavailable.");
326
+ webCrypto.getRandomValues(target);
327
+ }
328
+ function encodeTime(timeMs) {
329
+ let remaining = timeMs;
330
+ let encoded = "";
331
+ for (let index = 0; index < TIME_CHARS; index += 1) {
332
+ encoded = ENCODING[remaining % 32] + encoded;
333
+ remaining = Math.floor(remaining / 32);
334
+ }
335
+ return encoded;
336
+ }
337
+ function encodeRandom(bytes) {
338
+ let buffer = 0;
339
+ let bufferedBits = 0;
340
+ let encoded = "";
341
+ for (const byte of bytes) {
342
+ buffer = buffer << 8 | byte;
343
+ bufferedBits += 8;
344
+ while (bufferedBits >= 5) {
345
+ bufferedBits -= 5;
346
+ encoded += ENCODING[buffer >>> bufferedBits & 31];
347
+ }
348
+ buffer &= (1 << bufferedBits) - 1;
349
+ }
350
+ return encoded;
351
+ }
352
+ function incrementRandom(bytes) {
353
+ for (let index = bytes.length - 1; index >= 0; index -= 1) {
354
+ const byte = bytes[index] ?? 0;
355
+ if (byte < 255) {
356
+ bytes[index] = byte + 1;
357
+ bytes.fill(0, index + 1);
358
+ return true;
359
+ }
360
+ }
361
+ return false;
362
+ }
363
+
299
364
  //#endregion
300
365
  //#region src/protocol/message.ts
301
366
  const EVE_SESSION_ID_HEADER = "x-eve-session-id";
@@ -1081,6 +1146,24 @@ function withRedirectPolicy(init, redirect) {
1081
1146
  };
1082
1147
  }
1083
1148
 
1149
+ //#endregion
1150
+ //#region src/protocol/event-dedupe.ts
1151
+ function createEventDeduper() {
1152
+ const seen = /* @__PURE__ */ new Set();
1153
+ return {
1154
+ admit(event) {
1155
+ const id = event.meta?.id;
1156
+ if (id === void 0) return true;
1157
+ if (seen.has(id)) return false;
1158
+ seen.add(id);
1159
+ return true;
1160
+ },
1161
+ get size() {
1162
+ return seen.size;
1163
+ }
1164
+ };
1165
+ }
1166
+
1084
1167
  //#endregion
1085
1168
  //#region src/client/eve-agent-store.ts
1086
1169
  var EveAgentStore = class {
@@ -1088,6 +1171,7 @@ var EveAgentStore = class {
1088
1171
  #optimistic;
1089
1172
  #reducer;
1090
1173
  #subscribers = /* @__PURE__ */ new Set();
1174
+ #seenEvents = createEventDeduper();
1091
1175
  #abortController;
1092
1176
  #callbacks = {};
1093
1177
  #data;
@@ -1105,7 +1189,9 @@ var EveAgentStore = class {
1105
1189
  headers: init.headers,
1106
1190
  host: init.host ?? ""
1107
1191
  }).session(init.initialSession);
1108
- this.#events = [...init.initialEvents ?? []];
1192
+ const initialEvents = [];
1193
+ for (const event of init.initialEvents ?? []) if (this.#seenEvents.admit(event)) initialEvents.push(event);
1194
+ this.#events = initialEvents;
1109
1195
  this.#projectionEvents = [...this.#events];
1110
1196
  this.#optimistic = init.optimistic ?? true;
1111
1197
  this.#reducer = init.reducer;
@@ -1150,6 +1236,7 @@ var EveAgentStore = class {
1150
1236
  sawEvent = true;
1151
1237
  this.#status = "streaming";
1152
1238
  }
1239
+ if (!this.#seenEvents.admit(event)) continue;
1153
1240
  this.#events = [...this.#events, event];
1154
1241
  this.#applyServerEvent(event);
1155
1242
  this.#callbacks.onEvent?.(event);
@@ -1187,6 +1274,7 @@ var EveAgentStore = class {
1187
1274
  this.#abortController = void 0;
1188
1275
  this.#session = this.#createSession?.() ?? this.#session;
1189
1276
  this.#events = [];
1277
+ this.#seenEvents = createEventDeduper();
1190
1278
  this.#pendingMessageSubmission = void 0;
1191
1279
  this.#projectionEvents = [];
1192
1280
  this.#data = this.#reducer.initial();
@@ -1403,6 +1491,7 @@ function toMessageInputRequest(request) {
1403
1491
  return {
1404
1492
  allowFreeform: request.allowFreeform,
1405
1493
  display: request.display,
1494
+ kind: request.kind,
1406
1495
  options: request.options,
1407
1496
  prompt: request.prompt,
1408
1497
  requestId: request.requestId
@@ -1 +1 @@
1
- import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{failureKey,formatFailureDetail,formatFailureHint,formatFailureMessage,isInterruptedError,localFailureHint}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createMcpConnectionStatusTracker}from"./mcp-connection-status.js";import{createRemoteConnectionController}from"./remote-connection.js";import{SubagentPump}from"./subagent-pump.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{toErrorMessage}from"#shared/errors.js";import"#client/index.js";import{probeAgentInfo}from"#services/dev-client/agent-info-probe.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createDevelopmentRuntimeArtifactRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";async function delayMs(e){await new Promise(t=>{setTimeout(t,e).unref?.()})}function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D;#O=pickAgentHeaderTip();#k;#A=new Map;#j;#M=new Map;#N=new Set;#P=!1;#F;#I;constructor(t){this.#e=t.session,t.client!==void 0&&(this.#t=t.client),t.lifecycle!==void 0&&(this.#I=t.lifecycle),this.#n=createRenderer(t);let n={formatActionResultError};if(this.#t!==void 0&&(n.client=this.#t),this.#n.subagents!==void 0&&(n.view=this.#n.subagents),this.#j=new SubagentPump(n),this.#r=t.name??`eve`,this.#i=t.tools??`full`,this.#a=t.reasoning??`full`,this.#o=t.subagents??`full`,this.#s=t.connectionAuth??`full`,this.#c=t.assistantResponseStats??`tokensPerSecond`,this.#l=t.contextSize,this.#u=t.formatTransportError??toErrorMessage,t.initialInput!==void 0&&(this.#m=t.initialInput),t.appRoot!==void 0){this.#p=t.appRoot;let e={appRoot:t.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};t.detectProjectIdentity!==void 0&&(e.detectIdentity=t.detectProjectIdentity),this.#E=createVercelStatusTracker(e),t.probeMcpConnection!==void 0&&(this.#D=createMcpConnectionStatusTracker({onChange:()=>{},probe:t.probeMcpConnection}))}if(t.promptCommandHandler!==void 0&&(this.#h=t.promptCommandHandler),this.#g=t.availablePromptCommands??PROMPT_COMMANDS,t.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:t.remote.credentials,target:t.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:t.remote.resolveOidcToken,resolveDeployment:t.remote.resolveDeployment})}this.#v=t.bootDetections??BOOT_DETECTIONS,this.#y=t.getVercelAuthStatus??getVercelAuthStatus,t.onBootProgress!==void 0&&(this.#b=t.onBootProgress),t.serverUrl!==void 0&&(this.#f=t.serverUrl),t.serverUrl!==void 0&&t.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactRefresher({serverUrl:t.serverUrl}))}async#L(){if(this.#f===void 0){this.#z(),await this.#J(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else{let t=this.#t;if(t!==void 0)try{let n=await devBootPhase(`connecting to agent`,()=>probeAgentInfo({client:t}),this.#b);n.kind===`ready`&&(e=n.info)}catch{e=void 0}}this.#z();let t=this.#R(e);await this.#J(t)}#R(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#k=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#O),this.#n.renderAgentHeader?.(r),t}#z(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){let onStop=()=>this.#n.requestInterrupt?.();this.#I?.signal.aborted===!0?onStop():this.#I?.signal.addEventListener(`abort`,onStop,{once:!0});try{await this.#B()}finally{this.#I?.signal.removeEventListener(`abort`,onStop),this.#x=!0,this.#S.abort(),this.#j.abortAll(),this.#F?.(),this.#F=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#D?.dispose(),this.#_?.dispose()}}async#B(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#L(),this.#_?.current().connection.state===`auth-required`&&await this.#ie({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#Q(),this.#E?.refreshIdentity(),this.#D?.refresh();let l=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(l?.type===`extension`&&l.name===`model`&&l.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#ae(e));;){if(this.#I?.signal.aborted===!0||this.#n.exitRequested?.()===!0)return;if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#U(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let l=parsePromptCommand(r);if(l?.type===`exit`)return;if(l?.type===`new`){if(!await this.#H()){i=void 0,o=!1,r=void 0;continue}i=void 0,o=!1,r=void 0;continue}if(l?.type===`help`){this.#$(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(l?.type===`loglevel`){this.#$(this.#se(l.argument)),i=void 0,o=!1,r=void 0;continue}if(l?.type===`extension`){try{await this.#ie(l,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let l=await this.#W({prompt:o?void 0:r,inputResponses:i}),u=this.#e.state.sessionId;u!==void 0&&this.#n.setSessionId?.(u);let d=r,f=!1;try{for(;;){await this.#n.renderStream(l,{title:e,submittedPrompt:d,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=l.turnState?.pendingApprovals??[],n=l.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#A.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#A.delete(t.requestId)}}if(a.length===0)break;o=!0,i=a,r=void 0,f=!0;break}if(this.#fe(l)){l=this.#K(),d=void 0;continue}if(l.turnState&&l.turnState.boundaryEvent===void 0)if(l.turnState.aborted)this.#P=!0;else{let e=this.#e.state.sessionId;this.#n.renderNotice?.(e?`Lost the event stream — the turn may still be running on the server (session ${e}). Your next message resumes this session; use /cancel to stop the turn.`:`Lost the connection to the running turn.`)}break}}catch(e){if(isInterruptedError(e))return;throw e}if(f)continue;o=!1,i=void 0,r=void 0;let p=l.turnState?.boundaryEvent;!this.#P&&(p===`session.waiting`||p===`session.completed`)&&(r=this.#n.takeQueuedPrompt?.()),this.#P&&(this.#P=!1,this.#V(),l.turnState?.aborted?this.#n.renderNotice?.(`Stopped following the turn and started a new session. Earlier context was cleared; the interrupted turn may still be running on the server.`):this.#n.renderSessionBoundary===void 0?this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`):this.#n.renderSessionBoundary())}}#V(){this.#j.abortAll(),this.#A.clear(),this.#M.clear(),this.#N.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#H(){try{await this.#e.reset()}catch(e){return this.#n.renderNotice?.(`Couldn't reset the session: ${toErrorMessage(e)}`),!1}return this.#V(),this.#n.reset?.(),!0}async#U(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#d;if(n===void 0)return await t;let r=!1,i=!1,a,refresh=async()=>{if(!(r||i)){i=!0;try{await n.refreshIdle({onRuntimeArtifactsChanged:()=>this.#ue()})}finally{i=!1}}},startRefresh=()=>{if(r||i)return;let e=refresh().finally(()=>{a===e&&(a=void 0)});a=e};startRefresh();let o=setInterval(()=>{startRefresh()},500);o.unref?.();try{return await t}finally{r=!0,clearInterval(o),await a}}async#W(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{this.#d!==void 0&&await this.#d.refresh({inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#ue()}),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#P=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#q(r,()=>t.abort())}async#G(e){if(e.cancelInFlight!==!0){e.cancelInFlight=!0;try{for(let t=0;t<8;t+=1){if(e.boundaryEvent!==void 0||e.aborted===!0)return;let t=e.turnId;try{if((await this.#e.cancel(t===void 0?void 0:{turnId:t})).status===`accepted`)return}catch{}await delayMs(250)}}finally{e.cancelInFlight=!1}}}#K(){let e=new AbortController;return this.#q(this.#e.stream({signal:e.signal}),()=>e.abort())}#q(e,t){let n=createTurnState();return{abort:()=>{n.aborted=!0,t()},cancel:()=>{this.#G(n)},events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#A,turnState:n,onSubagentCalled:e=>this.#j.begin(e),onSubagentCompleted:e=>this.#j.settle(e),onTurnCancelled:()=>this.#j.settleAll(),onConnectionAuthRequired:e=>this.#de(e),onConnectionAuthCompleted:e=>this.#pe(e),onTerminalFailure:()=>{this.#P=!0},failureHintOverride:this.#p===void 0?void 0:localFailureHint}),turnState:n}}async#J(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#Y(),this.#X())}#Y(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#X(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#Y())}async#Z(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#Y()}#Q(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#F===void 0&&(this.#F=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#$(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#ee(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_},i=this.#D?.current(),a=i!==void 0&&Object.keys(i).length>0?{...r,disabledConnectionReasons:i}:r;return t.keepSetupFlowOpen===!0?await n.handle(e,{...a,keepSetupFlowOpen:!0}):await n.handle(e,a)}#te(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#ne(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#re(),await this.#ce();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ce();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#Z(this.#k))}async#re(){let e=this.#d;e!==void 0&&await e.refreshAfterSourceChange({onRuntimeArtifactsChanged:()=>this.#ue()})}async#ie(e,t,n){let r=await this.#ee(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#te(e,n.trigger),this.#$(r?.message),await this.#ne(r?.effect),this.#oe()}async#ae(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#ie({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#ie({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#ie({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#oe(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#k||(this.#k=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#se(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#ce(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#R(await this.#le());this.#Z(t)}async#le(){let e=this.#t;if(e===void 0)return;let t=await probeAgentInfo({client:e});return t.kind===`ready`?t.info:void 0}async#ue(){let e=this.#k,t=await this.#le();t!==void 0&&this.#R(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#de(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#M.set(e.data.name,t),this.#me(t)}#fe(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#M.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#N.add(e.name),this.#me(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#N.size),this.#N.size>0}#pe(e){let t=this.#M.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#M.set(e.data.name,t),this.#N.delete(e.data.name),this.#me(t),this.#n.setConnectionAuthPendingCount?.(this.#N.size)}#me(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen,diagnostics:e.diagnostics,onExitRequest:e.lifecycle?.requestStop})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,turnState:r,onSubagentCalled:i,onSubagentCompleted:a,onTurnCancelled:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureHintOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=!1,v=!1,y;for await(let e of t)if(!(v&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`message.received`:break;case`turn.started`:r.turnId=e.data.turnId;break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;y=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!h.has(e.requestId)){if(h.add(e.requestId),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(r,e);continue}upsertPendingApproval(r,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!m.has(n))break;switch(t.data.status){case`completed`:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break;case`failed`:yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)};break;case`rejected`:yield{type:`tool-rejected`,toolCallId:n,reason:formatActionResultError(t)};break}break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,g,u);t&&(yield t);break}case`session.failed`:{r.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,g,u);t&&(yield t),r.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return}case`session.waiting`:case`session.completed`:r.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y},_=!0;return;case`turn.completed`:v=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`turn.cancelled`:o?.(),yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`turn-cancelled`};break;case`subagent.called`:i?.(e);break;case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:a?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}_||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:y})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{aborted:!1,pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let c={type:`error`,errorText:formatFailureMessage(e)},l=n?.(e)??formatFailureHint(e);l!==void 0&&(c.hint=l);let u=formatFailureDetail(e);return u!==void 0&&(c.detail=u),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`||e.display!==`confirmation`&&e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}export{EveTUIRunner,parsePromptCommand};
1
+ import{PROMPT_COMMANDS,formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{pickAgentHeaderTip}from"./agent-header.js";import{failureKey,formatFailureDetail,formatFailureHint,formatFailureMessage,isInterruptedError,localFailureHint}from"./errors.js";import{parseLogDisplayMode}from"./log-display-mode.js";import{createMcpConnectionStatusTracker}from"./mcp-connection-status.js";import{createRemoteConnectionController}from"./remote-connection.js";import{SubagentPump}from"./subagent-pump.js";import{BOOT_DETECTIONS,CLI_MISSING_SETUP_ISSUE,LOGIN_SETUP_ISSUE,detectSetupIssues,formatSetupIssuesLine,orderedSetupIssues,resolveModelProviderState}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{toErrorMessage}from"#shared/errors.js";import"#client/index.js";import{probeAgentInfo}from"#services/dev-client/agent-info-probe.js";import{subscribeDevelopmentSandboxPrewarmLogs}from"#execution/sandbox/development-prewarm.js";import{createEventDeduper}from"#protocol/event-dedupe.js";import{createDevelopmentRuntimeArtifactRefresher}from"#services/dev-client.js";import{devBootPhase}from"#internal/dev-boot-progress.js";async function delayMs(e){await new Promise(t=>{setTimeout(t,e).unref?.()})}function authIssueForStatus(e){if(e===`logged-out`)return LOGIN_SETUP_ISSUE;if(e===`cli-missing`)return CLI_MISSING_SETUP_ISSUE}var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x=!1;#S=new AbortController;#C=!1;#w=[];#T;#E;#D;#O=pickAgentHeaderTip();#k;#A=new Map;#j;#M=new Map;#N=new Set;#P=!1;#F;#I;constructor(t){this.#e=t.session,t.client!==void 0&&(this.#t=t.client),t.lifecycle!==void 0&&(this.#I=t.lifecycle),this.#n=createRenderer(t);let n={formatActionResultError};if(this.#t!==void 0&&(n.client=this.#t),this.#n.subagents!==void 0&&(n.view=this.#n.subagents),this.#j=new SubagentPump(n),this.#r=t.name??`eve`,this.#i=t.tools??`full`,this.#a=t.reasoning??`full`,this.#o=t.subagents??`full`,this.#s=t.connectionAuth??`full`,this.#c=t.assistantResponseStats??`tokensPerSecond`,this.#l=t.contextSize,this.#u=t.formatTransportError??toErrorMessage,t.initialInput!==void 0&&(this.#m=t.initialInput),t.appRoot!==void 0){this.#p=t.appRoot;let e={appRoot:t.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};t.detectProjectIdentity!==void 0&&(e.detectIdentity=t.detectProjectIdentity),this.#E=createVercelStatusTracker(e),t.probeMcpConnection!==void 0&&(this.#D=createMcpConnectionStatusTracker({onChange:()=>{},probe:t.probeMcpConnection}))}if(t.promptCommandHandler!==void 0&&(this.#h=t.promptCommandHandler),this.#g=t.availablePromptCommands??PROMPT_COMMANDS,t.remote!==void 0){if(this.#t===void 0)throw Error(`A remote TUI requires a configured development client.`);this.#_=createRemoteConnectionController({client:this.#t,credentials:t.remote.credentials,target:t.remote.target,onChange:e=>this.#n.setRemoteConnectionStatus?.(e),resolveOidcToken:t.remote.resolveOidcToken,resolveDeployment:t.remote.resolveDeployment})}this.#v=t.bootDetections??BOOT_DETECTIONS,this.#y=t.getVercelAuthStatus??getVercelAuthStatus,t.onBootProgress!==void 0&&(this.#b=t.onBootProgress),t.serverUrl!==void 0&&(this.#f=t.serverUrl),t.serverUrl!==void 0&&t.remote===void 0&&(this.#d=createDevelopmentRuntimeArtifactRefresher({serverUrl:t.serverUrl}))}async#L(){if(this.#f===void 0){this.#z(),await this.#J(void 0);return}let e;if(this.#_!==void 0){let t=await this.#_.check();t.state===`ready`&&(e=t.info)}else{let t=this.#t;if(t!==void 0)try{let n=await devBootPhase(`connecting to agent`,()=>probeAgentInfo({client:t}),this.#b);n.kind===`ready`&&(e=n.info)}catch{e=void 0}}this.#z();let t=this.#R(e);await this.#J(t)}#R(e){let t=this.#p===void 0?e:resolveModelProviderState(e,process.env);this.#k=t;let n=this.#f;if(n===void 0)return t;let r={name:this.#r,serverUrl:n};return t!==void 0&&(r.info=t),this.#p!==void 0&&(r.tip=this.#O),this.#n.renderAgentHeader?.(r),t}#z(){let e=this.#b;this.#b=void 0,e?.({type:`before-first-paint`})}async run(){let onStop=()=>this.#n.requestInterrupt?.();this.#I?.signal.aborted===!0?onStop():this.#I?.signal.addEventListener(`abort`,onStop,{once:!0});try{await this.#B()}finally{this.#I?.signal.removeEventListener(`abort`,onStop),this.#x=!0,this.#S.abort(),this.#j.abortAll(),this.#F?.(),this.#F=void 0,this.#n.shutdown?.(),this.#E?.dispose(),this.#D?.dispose(),this.#_?.dispose()}}async#B(){let e=this.#r,r,i,a=!1,o=!1,s=this.#m;await this.#L(),this.#_?.current().connection.state===`auth-required`&&await this.#ie({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`}),this.#Q(),this.#E?.refreshIdentity(),this.#D?.refresh();let l=this.#m===void 0?void 0:parsePromptCommand(this.#m);for(l?.type===`extension`&&l.name===`model`&&l.argument===``&&this.#p!==void 0&&this.#h!==void 0&&this.#n.setupFlow!==void 0&&(s=void 0,await this.#ae(e));;){if(this.#I?.signal.aborted===!0||this.#n.exitRequested?.()===!0)return;if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}let t={title:e};s!==void 0&&(t.initialDraft=s,s=void 0);try{r=await this.#U(t)}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let l=parsePromptCommand(r);if(l?.type===`exit`)return;if(l?.type===`new`){if(!await this.#H()){i=void 0,o=!1,r=void 0;continue}i=void 0,o=!1,r=void 0;continue}if(l?.type===`help`){this.#$(formatPromptCommandHelp(this.#g)),i=void 0,o=!1,r=void 0;continue}if(l?.type===`loglevel`){this.#$(this.#se(l.argument)),i=void 0,o=!1,r=void 0;continue}if(l?.type===`extension`){try{await this.#ie(l,e,{trigger:`command`})}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let l=await this.#W({prompt:o?void 0:r,inputResponses:i}),u=this.#e.state.sessionId;u!==void 0&&this.#n.setSessionId?.(u);let d=r,f=!1;try{for(;;){await this.#n.renderStream(l,{title:e,submittedPrompt:d,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=l.turnState?.pendingApprovals??[],n=l.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#A.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#A.delete(t.requestId)}}if(a.length===0)break;o=!0,i=a,r=void 0,f=!0;break}if(this.#fe(l)){l=this.#K(),d=void 0;continue}if(l.turnState&&l.turnState.boundaryEvent===void 0)if(l.turnState.aborted)this.#P=!0;else{let e=this.#e.state.sessionId;this.#n.renderNotice?.(e?`Lost the event stream — the turn may still be running on the server (session ${e}). Your next message resumes this session; use /cancel to stop the turn.`:`Lost the connection to the running turn.`)}break}}catch(e){if(isInterruptedError(e))return;throw e}if(f)continue;o=!1,i=void 0,r=void 0;let p=l.turnState?.boundaryEvent;!this.#P&&(p===`session.waiting`||p===`session.completed`)&&(r=this.#n.takeQueuedPrompt?.()),this.#P&&(this.#P=!1,this.#V(),l.turnState?.aborted?this.#n.renderNotice?.(`Stopped following the turn and started a new session. Earlier context was cleared; the interrupted turn may still be running on the server.`):this.#n.renderSessionBoundary===void 0?this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`):this.#n.renderSessionBoundary())}}#V(){this.#j.abortAll(),this.#A.clear(),this.#M.clear(),this.#N.clear(),this.#n.setConnectionAuthPendingCount?.(0),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#H(){try{await this.#e.reset()}catch(e){return this.#n.renderNotice?.(`Couldn't reset the session: ${toErrorMessage(e)}`),!1}return this.#V(),this.#n.reset?.(),!0}async#U(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#d;if(n===void 0)return await t;let r=!1,i=!1,a,refresh=async()=>{if(!(r||i)){i=!0;try{await n.refreshIdle({onRuntimeArtifactsChanged:()=>this.#ue()})}finally{i=!1}}},startRefresh=()=>{if(r||i)return;let e=refresh().finally(()=>{a===e&&(a=void 0)});a=e};startRefresh();let o=setInterval(()=>{startRefresh()},500);o.unref?.();try{return await t}finally{r=!0,clearInterval(o),await a}}async#W(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{this.#d!==void 0&&await this.#d.refresh({inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#ue()}),n.message!==void 0&&(n.inputResponses?.length??0)===0&&this.#n.flushDelayedDevBuildErrors?.(),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#_?.reportFailure(e),this.#P=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}return this.#q(r,()=>t.abort())}async#G(e){if(e.cancelInFlight!==!0){e.cancelInFlight=!0;try{for(let t=0;t<8;t+=1){if(e.boundaryEvent!==void 0||e.aborted===!0)return;let t=e.turnId;try{if((await this.#e.cancel(t===void 0?void 0:{turnId:t})).status===`accepted`)return}catch{}await delayMs(250)}}finally{e.cancelInFlight=!1}}}#K(){let e=new AbortController;return this.#q(this.#e.stream({signal:e.signal}),()=>e.abort())}#q(e,t){let n=createTurnState();return{abort:()=>{n.aborted=!0,t()},cancel:()=>{this.#G(n)},events:eveEventsToTUIStream({events:e,pendingInputRequests:this.#A,turnState:n,onSubagentCalled:e=>this.#j.begin(e),onSubagentCompleted:e=>this.#j.settle(e),onTurnCancelled:()=>this.#j.settleAll(),onConnectionAuthRequired:e=>this.#de(e),onConnectionAuthCompleted:e=>this.#pe(e),onTerminalFailure:()=>{this.#P=!0},failureHintOverride:this.#p===void 0?void 0:localFailureHint}),turnState:n}}async#J(e){if(this.#p===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e),this.#w=await detectSetupIssues(t,this.#v),this.#n.renderSetupWarning!==void 0&&(this.#Y(),this.#X())}#Y(){let e=orderedSetupIssues(this.#w,this.#T);e.length>0?this.#n.renderSetupWarning?.(formatSetupIssuesLine(e)):this.#n.clearSetupWarning?.()}async#X(){let e=this.#p;if(e===void 0)return;let t;try{t=await this.#y(e,{signal:this.#S.signal})}catch{return}this.#x||this.#C||(this.#T=authIssueForStatus(t),this.#Y())}async#Z(e){let t=this.#p;if(t===void 0||this.#n.renderSetupWarning===void 0)return;let n={appRoot:t,env:process.env};e!==void 0&&(n.info=e);try{this.#w=await detectSetupIssues(n,this.#v);let e=await this.#y(t,{signal:this.#S.signal});this.#T=authIssueForStatus(e)}catch{return}this.#x||this.#Y()}#Q(){this.#p===void 0||this.#n.renderSandboxLog===void 0||this.#F===void 0&&(this.#F=subscribeDevelopmentSandboxPrewarmLogs({appRoot:this.#p,log:e=>this.#n.renderSandboxLog?.(e)}))}#$(e){if(e!==void 0){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}}async#ee(e,t){let n=this.#h;if(n===void 0)return{message:`/${e.name} is not available in this session.`};let r={renderer:this.#n,title:t.title,initialModelStep:t.initialModelStep,remoteConnection:this.#_},i=this.#D?.current(),a=i!==void 0&&Object.keys(i).length>0?{...r,disabledConnectionReasons:i}:r;return t.keepSetupFlowOpen===!0?await n.handle(e,{...a,keepSetupFlowOpen:!0}):await n.handle(e,a)}#te(e,t){if(t!==`startup`)return;let n=this.#_?.current().connection.state,r=n===`auth-failed`||n===`unavailable`?`failed`:void 0,i=e.argument.length===0?``:` ${e.argument}`;this.#n.renderCommandInvocation?.(`/${e.name}${i}`,r)}async#ne(e){if(e?.kind===`connection-added`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#re(),await this.#ce();return}if(e?.kind===`model-access-changed`){this.#E?.applyEffect({kind:`refresh-identity`}),this.#C=!0,await this.#ce();return}e!==void 0&&(this.#E?.applyEffect(e),this.#C=!0,this.#Z(this.#k))}async#re(){let e=this.#d;e!==void 0&&await e.refreshAfterSourceChange({onRuntimeArtifactsChanged:()=>this.#ue()})}async#ie(e,t,n){let r=await this.#ee(e,{initialModelStep:n.initialModelStep,keepSetupFlowOpen:n.keepSetupFlowOpen,title:t});this.#te(e,n.trigger),this.#$(r?.message),await this.#ne(r?.effect),this.#oe()}async#ae(e){let t=this.#p;if(t===void 0)return;let authStatus=async()=>{try{return await this.#y(t,{signal:this.#S.signal})}catch{return}},n=await authStatus();if(n===`cli-missing`&&(await this.#ie({type:`extension`,name:`vc:install`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`)){this.#n.setupFlow?.end();return}if(n===`logged-out`&&(await this.#ie({type:`extension`,name:`vc:login`,argument:``},e,{trigger:`startup`,keepSetupFlowOpen:!0}),n=await authStatus(),n===`cli-missing`||n===`logged-out`)){this.#n.setupFlow?.end();return}await this.#ie({type:`extension`,name:`model`,argument:``},e,{trigger:`startup`,initialModelStep:`provider`})}#oe(){let e=this.#_?.current().connection;e?.state!==`ready`||e.info===this.#k||(this.#k=e.info,this.#f!==void 0&&this.#n.renderAgentHeader?.({info:e.info,name:this.#r,serverUrl:this.#f}))}#se(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|sandbox|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, sandbox, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`sandbox`:return`Showing sandbox logs only.`;case`all`:return`Showing all logs.`}}async#ce(){let e=this.#p;if(e===void 0)return;loadDevelopmentEnvironmentFiles(e);let t=this.#R(await this.#le());this.#Z(t)}async#le(){let e=this.#t;if(e===void 0)return;let t=await probeAgentInfo({client:e});return t.kind===`ready`?t.info:void 0}async#ue(){let e=this.#k,t=await this.#le();t!==void 0&&this.#R(t),(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#de(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#M.set(e.data.name,t),this.#me(t)}#fe(e){if(e.turnState?.boundaryEvent!==`session.waiting`)return!1;let t=!1;for(let e of this.#M.values())e.state!==`required`||e.webhookUrl===void 0||(e.state=`pending`,this.#N.add(e.name),this.#me(e),t=!0);return t&&this.#n.setConnectionAuthPendingCount?.(this.#N.size),this.#N.size>0}#pe(e){let t=this.#M.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#M.set(e.data.name,t),this.#N.delete(e.data.name),this.#me(t),this.#n.setConnectionAuthPendingCount?.(this.#N.size)}#me(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,availablePromptCommands:e.availablePromptCommands,input:e.userInput,output:e.screen,diagnostics:e.diagnostics,onExitRequest:e.lifecycle?.requestStop})}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,turnState:r,onSubagentCalled:i,onSubagentCompleted:a,onTurnCancelled:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureHintOverride:u}=e,d=new Map,f=new Map,p=createEventDeduper(),m=0,h=new Set,g=new Set,_=new Set,v=!1,y=!1,b;for await(let e of t)if(p.admit(e)&&!(y&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`message.received`:break;case`turn.started`:r.turnId=e.data.turnId;break;case`step.started`:m+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;b=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,m),yield*closeOpenParts(f,`reasoning-complete`,m),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(m<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||m<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=m,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=m,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=m,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=m,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(m<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||m<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=m;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=m,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data.actions.filter(e=>e.kind===`tool-call`);if(t.length===0)break;for(let e of t)h.has(e.callId)||(h.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests.filter(e=>e.action.kind===`tool-call`);if(t.length===0)break;for(let e of t){let t=e.action.callId;if(e.kind!==`session-limit`&&!h.has(t)&&(h.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),!g.has(e.requestId)){if(g.add(e.requestId),n.set(e.requestId,e),e.kind!==`tool-approval`){upsertPendingQuestion(r,e);continue}upsertPendingApproval(r,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(!h.has(n))break;switch(t.data.status){case`completed`:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break;case`failed`:yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)};break;case`rejected`:yield{type:`tool-rejected`,toolCallId:n,reason:formatActionResultError(t)};break}break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,_,u);t&&(yield t);break}case`session.failed`:{r.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,_,u);t&&(yield t),r.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,m),yield*closeOpenParts(f,`reasoning-complete`,m),yield{type:`finish`,usage:b},v=!0;return}case`session.waiting`:case`session.completed`:r.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,m),yield*closeOpenParts(f,`reasoning-complete`,m),yield{type:`finish`,usage:b},v=!0;return;case`turn.completed`:y=!0,yield*closeOpenParts(d,`assistant-complete`,m),yield*closeOpenParts(f,`reasoning-complete`,m);break;case`turn.cancelled`:o?.(),yield*closeOpenParts(d,`assistant-complete`,m),yield*closeOpenParts(f,`reasoning-complete`,m),yield{type:`turn-cancelled`};break;case`subagent.called`:i?.(e);break;case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:a?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}v||(yield*closeOpenParts(d,`assistant-complete`,m),yield*closeOpenParts(f,`reasoning-complete`,m),yield{type:`finish`,usage:b})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{aborted:!1,pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let r=failureKey(e);if(t.has(r))return;t.add(r);let c={type:`error`,errorText:formatFailureMessage(e)},l=n?.(e)??formatFailureHint(e);l!==void 0&&(c.hint=l);let u=formatFailureDetail(e);return u!==void 0&&(c.detail=u),c}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}export{EveTUIRunner,parsePromptCommand};
@@ -6,6 +6,7 @@
6
6
  * {@link SubagentView} seam.
7
7
  */
8
8
  import type { Client } from "#client/index.js";
9
+ import { type EventDeduper } from "#protocol/event-dedupe.js";
9
10
  import { type ActionResultStreamEvent, type SubagentCalledStreamEvent } from "#protocol/message.js";
10
11
  /**
11
12
  * The renderer's subagent surface. One cohesive capability: a renderer that
@@ -75,6 +76,11 @@ export type SubagentRun = {
75
76
  /** Monotonic counter for new section keys. */
76
77
  nextSectionKey: number;
77
78
  tools: Map<string, SubagentToolState>;
79
+ /**
80
+ * Child events already folded into this run. A restarted pump replays the
81
+ * child stream from `streamIndex: 0` while this run's state survives.
82
+ */
83
+ seenChildEvents: EventDeduper;
78
84
  };
79
85
  export type SubagentStepUpdate = {
80
86
  callId: string;
@@ -108,8 +114,8 @@ export declare class SubagentPump {
108
114
  * placeholder — subagent dispatches never upgrade one, since their
109
115
  * actions are not tool-call kind). Without this the placeholder is
110
116
  * swept at the step boundary and nothing shows until the child's first
111
- * content arrives. Idempotent for SSE-resume re-entries, which only
112
- * refresh the name.
117
+ * content arrives. A later parent-stream translator may replay the call;
118
+ * re-entry only refreshes the name.
113
119
  */
114
120
  begin(called: SubagentCalledStreamEvent): void;
115
121
  /**
@@ -1 +1 @@
1
- import{isAbortLikeError}from"./errors.js";import{toErrorMessage}from"#shared/errors.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";var SubagentPump=class{#e;#t;#n;#r=new Map;#i=new Map;constructor(e){this.#e=e.client,this.#t=e.view,this.#n=e.formatActionResultError}begin(e){let t=e.data.callId,n=this.#r.get(t);n===void 0?this.#r.set(t,{name:e.data.name,status:`running`,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map}):n.name=e.data.name,this.#t?.markChildToolCallId(t),this.#t?.begin({callId:t,name:e.data.name}),this.#a(e)}settle(e){this.#s(e)}abortAll(){for(let e of this.#i.values())e.abort();this.#i.clear(),this.#r.clear()}settleAll(){for(let e of this.#r.keys())this.#s(e);for(let e of this.#i.values())e.abort();this.#i.clear()}#a(r){let i=r.data.callId;if(this.#i.has(i))return;let a=this.#e;if(!a)return;let o=new AbortController;this.#i.set(i,o),(async()=>{let s=!1;try{let e=a.session({sessionId:r.data.childSessionId,streamIndex:0}).stream({signal:o.signal});for await(let t of e){if(o.signal.aborted)break;if(this.#l(i,t),isCurrentTurnBoundaryEvent(t)){s=!0;break}}}catch(n){if(!isAbortLikeError(n)){let e=toErrorMessage(n),r=this.#r.get(i);if(r){let{key:t,step:n}=openCurrentSubagentSection(r);n.message=n.message?`${n.message}\n\nstream error: ${e}`:`stream error: ${e}`,n.finalized=!0,r.currentSectionKey=null,this.#t?.upsertStep({callId:i,subagentName:r.name,sectionKey:t,reasoning:n.reasoning,message:n.message,finalized:!0})}}}finally{this.#i.delete(i)}s&&this.#s(i)})()}#o(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={preparing:0,"approval-requested":1,executing:2,done:3,failed:3,rejected:3};e[n.status]>e[r.status]&&(r.status=n.status),n.input!==void 0&&(r.input=n.input)}else t.tools.set(n.childCallId,i);this.#t?.markChildToolCallId(n.childCallId),this.#t?.upsertTool({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#s(e){let t=this.#r.get(e);if(!(!t||t.status===`settled`)){t.status=`settled`;for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#t?.upsertStep({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null,this.#c(e,t),this.#t?.complete({callId:e})}}#c(e,t){for(let[n,r]of t.tools)r.status===`preparing`&&(t.tools.delete(n),this.#t?.removeTool({callId:e,childCallId:n}))}#l(e,t){let n=this.#r.get(e);if(!n)return;n.status===`settled`&&(n.status=`running`,this.#t?.begin({callId:e,name:n.name}));let r=this.#t,emit=(t,i)=>{r?.upsertStep({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent(),this.#c(e,n);break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#o(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#o(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;switch(t.data.status){case`completed`:a.status=`done`,a.output=i.output;break;case`failed`:a.status=`failed`,a.errorText=this.#n(t);break;case`rejected`:a.status=`rejected`,a.errorText=this.#n(t);break}let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r?.upsertTool(o);break}default:break}}};function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{SubagentPump};
1
+ import{isAbortLikeError}from"./errors.js";import{toErrorMessage}from"#shared/errors.js";import{createEventDeduper}from"#protocol/event-dedupe.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";var SubagentPump=class{#e;#t;#n;#r=new Map;#i=new Map;constructor(e){this.#e=e.client,this.#t=e.view,this.#n=e.formatActionResultError}begin(e){let t=e.data.callId,r=this.#r.get(t);r===void 0?this.#r.set(t,{name:e.data.name,status:`running`,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map,seenChildEvents:createEventDeduper()}):r.name=e.data.name,this.#t?.markChildToolCallId(t),this.#t?.begin({callId:t,name:e.data.name}),this.#a(e)}settle(e){this.#s(e)}abortAll(){for(let e of this.#i.values())e.abort();this.#i.clear(),this.#r.clear()}settleAll(){for(let e of this.#r.keys())this.#s(e);for(let e of this.#i.values())e.abort();this.#i.clear()}#a(n){let i=n.data.callId;if(this.#i.has(i))return;let a=this.#e;if(!a)return;let o=new AbortController;this.#i.set(i,o),(async()=>{let s=!1;try{let e=a.session({sessionId:n.data.childSessionId,streamIndex:0}).stream({signal:o.signal});for await(let t of e){if(o.signal.aborted)break;if(this.#l(i,t),isCurrentTurnBoundaryEvent(t)){s=!0;break}}}catch(n){if(!isAbortLikeError(n)){let e=toErrorMessage(n),r=this.#r.get(i);if(r){let{key:t,step:n}=openCurrentSubagentSection(r);n.message=n.message?`${n.message}\n\nstream error: ${e}`:`stream error: ${e}`,n.finalized=!0,r.currentSectionKey=null,this.#t?.upsertStep({callId:i,subagentName:r.name,sectionKey:t,reasoning:n.reasoning,message:n.message,finalized:!0})}}}finally{this.#i.delete(i)}s&&this.#s(i)})()}#o(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={preparing:0,"approval-requested":1,executing:2,done:3,failed:3,rejected:3};e[n.status]>e[r.status]&&(r.status=n.status),n.input!==void 0&&(r.input=n.input)}else t.tools.set(n.childCallId,i);this.#t?.markChildToolCallId(n.childCallId),this.#t?.upsertTool({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#s(e){let t=this.#r.get(e);if(!(!t||t.status===`settled`)){t.status=`settled`;for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#t?.upsertStep({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null,this.#c(e,t),this.#t?.complete({callId:e})}}#c(e,t){for(let[n,r]of t.tools)r.status===`preparing`&&(t.tools.delete(n),this.#t?.removeTool({callId:e,childCallId:n}))}#l(e,t){let n=this.#r.get(e);if(!n||!n.seenChildEvents.admit(t))return;n.status===`settled`&&(n.status=`running`,this.#t?.begin({callId:e,name:n.name}));let r=this.#t,emit=(t,i)=>{r?.upsertStep({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent(),this.#c(e,n);break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#o(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#o(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;switch(t.data.status){case`completed`:a.status=`done`,a.output=i.output;break;case`failed`:a.status=`failed`,a.errorText=this.#n(t);break;case`rejected`:a.status=`rejected`,a.errorText=this.#n(t);break}let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r?.upsertTool(o);break}default:break}}};function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{SubagentPump};
@@ -16,6 +16,11 @@ declare const invokeResumeSchema: z.ZodObject<{
16
16
  }, z.core.$strict>;
17
17
  declare const invocationInputRequestSchema: z.ZodObject<{
18
18
  allowFreeform: z.ZodOptional<z.ZodBoolean>;
19
+ kind: z.ZodEnum<{
20
+ question: "question";
21
+ "session-limit": "session-limit";
22
+ "tool-approval": "tool-approval";
23
+ }>;
19
24
  prompt: z.ZodString;
20
25
  requestId: z.ZodString;
21
26
  options: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -42,6 +47,11 @@ declare const invokeResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
42
47
  }, z.core.$strict>, z.ZodObject<{
43
48
  requests: z.ZodReadonly<z.ZodArray<z.ZodObject<{
44
49
  allowFreeform: z.ZodOptional<z.ZodBoolean>;
50
+ kind: z.ZodEnum<{
51
+ question: "question";
52
+ "session-limit": "session-limit";
53
+ "tool-approval": "tool-approval";
54
+ }>;
45
55
  prompt: z.ZodString;
46
56
  requestId: z.ZodString;
47
57
  options: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -221,6 +231,11 @@ export declare const invokeResultJsonSchema: {
221
231
  }, z.core.$strict>, z.ZodObject<{
222
232
  requests: z.ZodReadonly<z.ZodArray<z.ZodObject<{
223
233
  allowFreeform: z.ZodOptional<z.ZodBoolean>;
234
+ kind: z.ZodEnum<{
235
+ question: "question";
236
+ "session-limit": "session-limit";
237
+ "tool-approval": "tool-approval";
238
+ }>;
224
239
  prompt: z.ZodString;
225
240
  requestId: z.ZodString;
226
241
  options: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{inputOptionSchema,inputRequestSchema}from"#client/index.js";const sessionCursorSchema=z.object({continuationToken:z.string().optional(),sessionId:z.string().min(1),streamIndex:z.number().int().nonnegative()}).strict(),targetSchema=z.discriminatedUnion(`kind`,[z.object({kind:z.literal(`local`)}).strict(),z.object({kind:z.literal(`remote`),serverUrl:z.url()}).strict()]),invokeResumeSchema=z.object({session:sessionCursorSchema,target:targetSchema}).strict(),invocationInputRequestSchema=inputRequestSchema.omit({action:!0,display:!0,options:!0}).extend({options:z.array(inputOptionSchema.omit({style:!0})).optional()}),authorizationChallengeSchema=z.object({displayName:z.string().optional(),expiresAt:z.string().optional(),instructions:z.string().optional(),url:z.string().optional(),userCode:z.string().optional()}).strict(),authorizationInterruptSchema=z.object({authorization:authorizationChallengeSchema.optional(),description:z.string(),name:z.string(),webhookUrl:z.string().optional()}).strict(),turnOutcomeSchema=z.discriminatedUnion(`status`,[z.object({message:z.string().optional(),status:z.literal(`completed`)}).strict(),z.object({message:z.string(),status:z.literal(`failed`)}).strict()]),invokeResultSchema=z.discriminatedUnion(`status`,[z.object({resume:invokeResumeSchema,status:z.literal(`running`)}).strict(),z.object({requests:z.array(invocationInputRequestSchema).readonly(),resume:invokeResumeSchema,status:z.literal(`input-required`)}).strict(),z.object({authorizations:z.array(authorizationInterruptSchema).min(1).readonly(),resume:invokeResumeSchema,status:z.literal(`authorization-required`)}).strict(),z.object({outcome:turnOutcomeSchema,resume:invokeResumeSchema,status:z.literal(`ready`)}).strict(),z.object({message:z.string(),status:z.literal(`failed`)}).strict(),z.object({code:z.string().optional(),message:z.string(),resume:invokeResumeSchema.optional(),status:z.literal(`authentication-required`)}).strict()]);function projectInvocationInputRequest(e){let{allowFreeform:t,options:n,prompt:r,requestId:i}=e;return{allowFreeform:t,options:n?.map(({description:e,id:t,label:n})=>({description:e,id:t,label:n})),prompt:r,requestId:i}}function parseInvokeResumeInput(e){let t=invokeResultSchema.safeParse(e);if(t.success&&`resume`in t.data&&t.data.resume!==void 0)return t.data;throw Error(`Resume JSON is not a valid resumable eve invoke result.`)}const invokeResultJsonSchema={...z.toJSONSchema(invokeResultSchema,{io:`input`,target:`draft-2020-12`,unrepresentable:`any`}),$id:`https://eve.dev/schemas/invoke-result.json`,title:`eve invoke result`};export{invokeResultJsonSchema,parseInvokeResumeInput,projectInvocationInputRequest};
1
+ import{z}from"#compiled/zod/index.js";import{inputOptionSchema,inputRequestSchema}from"#client/index.js";const sessionCursorSchema=z.object({continuationToken:z.string().optional(),sessionId:z.string().min(1),streamIndex:z.number().int().nonnegative()}).strict(),targetSchema=z.discriminatedUnion(`kind`,[z.object({kind:z.literal(`local`)}).strict(),z.object({kind:z.literal(`remote`),serverUrl:z.url()}).strict()]),invokeResumeSchema=z.object({session:sessionCursorSchema,target:targetSchema}).strict(),invocationInputRequestSchema=inputRequestSchema.omit({action:!0,display:!0,options:!0}).extend({options:z.array(inputOptionSchema.omit({style:!0})).optional()}),authorizationChallengeSchema=z.object({displayName:z.string().optional(),expiresAt:z.string().optional(),instructions:z.string().optional(),url:z.string().optional(),userCode:z.string().optional()}).strict(),authorizationInterruptSchema=z.object({authorization:authorizationChallengeSchema.optional(),description:z.string(),name:z.string(),webhookUrl:z.string().optional()}).strict(),turnOutcomeSchema=z.discriminatedUnion(`status`,[z.object({message:z.string().optional(),status:z.literal(`completed`)}).strict(),z.object({message:z.string(),status:z.literal(`failed`)}).strict()]),invokeResultSchema=z.discriminatedUnion(`status`,[z.object({resume:invokeResumeSchema,status:z.literal(`running`)}).strict(),z.object({requests:z.array(invocationInputRequestSchema).readonly(),resume:invokeResumeSchema,status:z.literal(`input-required`)}).strict(),z.object({authorizations:z.array(authorizationInterruptSchema).min(1).readonly(),resume:invokeResumeSchema,status:z.literal(`authorization-required`)}).strict(),z.object({outcome:turnOutcomeSchema,resume:invokeResumeSchema,status:z.literal(`ready`)}).strict(),z.object({message:z.string(),status:z.literal(`failed`)}).strict(),z.object({code:z.string().optional(),message:z.string(),resume:invokeResumeSchema.optional(),status:z.literal(`authentication-required`)}).strict()]);function projectInvocationInputRequest(e){let{allowFreeform:t,kind:n,options:r,prompt:i,requestId:a}=e;return{allowFreeform:t,kind:n,options:r?.map(({description:e,id:t,label:n})=>({description:e,id:t,label:n})),prompt:i,requestId:a}}function parseInvokeResumeInput(e){let t=invokeResultSchema.safeParse(e);if(t.success&&`resume`in t.data&&t.data.resume!==void 0)return t.data;throw Error(`Resume JSON is not a valid resumable eve invoke result.`)}const invokeResultJsonSchema={...z.toJSONSchema(invokeResultSchema,{io:`input`,target:`draft-2020-12`,unrepresentable:`any`}),$id:`https://eve.dev/schemas/invoke-result.json`,title:`eve invoke result`};export{invokeResultJsonSchema,parseInvokeResumeInput,projectInvocationInputRequest};