eve 0.24.4 → 0.24.5

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 (152) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/src/channel/types.d.ts +13 -0
  3. package/dist/src/chunks/{use-eve-agent-Dwa2j1wE.js → use-eve-agent-8rerxDHY.js} +59 -6
  4. package/dist/src/chunks/{use-eve-agent-BP9FpQsJ.js → use-eve-agent-DhgdHzDG.js} +59 -6
  5. package/dist/src/cli/commands/build.d.ts +14 -0
  6. package/dist/src/cli/commands/build.js +1 -0
  7. package/dist/src/cli/commands/channels.js +1 -1
  8. package/dist/src/cli/commands/link.d.ts +6 -5
  9. package/dist/src/cli/commands/link.js +1 -1
  10. package/dist/src/cli/run.d.ts +3 -2
  11. package/dist/src/cli/run.js +1 -1
  12. package/dist/src/client/index.d.ts +1 -1
  13. package/dist/src/client/ndjson.js +1 -1
  14. package/dist/src/client/open-stream.d.ts +3 -2
  15. package/dist/src/client/open-stream.js +1 -1
  16. package/dist/src/client/session.d.ts +15 -3
  17. package/dist/src/client/session.js +1 -1
  18. package/dist/src/client/types.d.ts +8 -0
  19. package/dist/src/compiled/.vendor-stamp.json +5 -5
  20. package/dist/src/compiled/@workflow/core/index.js +2 -2
  21. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +55 -0
  22. package/dist/src/compiled/@workflow/core/runtime/run-id-time.d.ts +9 -0
  23. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +2 -0
  24. package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +70 -4
  25. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +10 -1
  26. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  27. package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +6 -0
  28. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +25 -0
  29. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  30. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  31. package/dist/src/compiled/@workflow/errors/index.d.ts +16 -0
  32. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  33. package/dist/src/compiled/@workflow/world/attributes.d.ts +7 -0
  34. package/dist/src/compiled/@workflow/world/events.d.ts +16 -0
  35. package/dist/src/compiled/@workflow/world/index.d.ts +1 -1
  36. package/dist/src/compiled/@workflow/world-local/index.js +3 -3
  37. package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
  38. package/dist/src/compiled/_chunks/workflow/attribute-changes-DXbmITuI.js +20 -0
  39. package/dist/src/compiled/_chunks/workflow/{dist-DpDDcpTl.js → dist-BYo8Gno2.js} +1 -1
  40. package/dist/src/compiled/_chunks/workflow/{dist-Blxnyb7-.js → dist-CSfKNxQW.js} +1 -1
  41. package/dist/src/compiled/_chunks/workflow/resume-hook-DvvgYsRt.js +1 -0
  42. package/dist/src/compiled/_chunks/workflow/run-BdvQmV5a.js +1 -0
  43. package/dist/src/compiled/_chunks/workflow/run-id-BdE0MZz9.js +1 -0
  44. package/dist/src/compiled/_chunks/workflow/sleep-DzxrwWTs.js +1 -0
  45. package/dist/src/evals/assertions/run.d.ts +3 -3
  46. package/dist/src/evals/context.js +1 -1
  47. package/dist/src/evals/index.d.ts +2 -1
  48. package/dist/src/evals/match.d.ts +4 -0
  49. package/dist/src/evals/match.js +1 -1
  50. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  51. package/dist/src/evals/session.d.ts +10 -2
  52. package/dist/src/evals/session.js +1 -1
  53. package/dist/src/evals/target.js +1 -1
  54. package/dist/src/evals/types.d.ts +52 -2
  55. package/dist/src/execution/cancel-descendant-turns-step.d.ts +6 -0
  56. package/dist/src/execution/cancel-descendant-turns-step.js +1 -0
  57. package/dist/src/execution/create-session-step.js +1 -1
  58. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  59. package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
  60. package/dist/src/execution/node-step.js +1 -1
  61. package/dist/src/execution/remote-agent-dispatch.d.ts +6 -0
  62. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  63. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  64. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  65. package/dist/src/execution/turn-cancellation-control.d.ts +0 -13
  66. package/dist/src/execution/turn-cancellation-control.js +1 -1
  67. package/dist/src/execution/turn-cancellation-token.d.ts +9 -0
  68. package/dist/src/execution/turn-cancellation-token.js +1 -0
  69. package/dist/src/execution/turn-workflow.js +1 -1
  70. package/dist/src/execution/workflow-runtime.d.ts +3 -1
  71. package/dist/src/execution/workflow-runtime.js +1 -1
  72. package/dist/src/execution/workflow-steps.js +1 -1
  73. package/dist/src/harness/advertised-tools.js +1 -1
  74. package/dist/src/harness/execute-tool.d.ts +0 -1
  75. package/dist/src/harness/runtime-actions.d.ts +16 -12
  76. package/dist/src/harness/runtime-actions.js +1 -1
  77. package/dist/src/internal/application/build-profile.d.ts +64 -0
  78. package/dist/src/internal/application/build-profile.js +1 -0
  79. package/dist/src/internal/application/package.js +1 -1
  80. package/dist/src/internal/authored-module-loader.d.ts +10 -0
  81. package/dist/src/internal/authored-module-loader.js +2 -2
  82. package/dist/src/internal/authored-module-map-loader.js +1 -1
  83. package/dist/src/internal/materialized-authored-modules.d.ts +2 -4
  84. package/dist/src/internal/materialized-authored-modules.js +1 -1
  85. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  86. package/dist/src/internal/nitro/host/build-application.js +1 -1
  87. package/dist/src/internal/nitro/host/types.d.ts +2 -0
  88. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  89. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +7 -1
  90. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  91. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  92. package/dist/src/internal/nitro/routes/channel-route-context.d.ts +3 -0
  93. package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
  94. package/dist/src/internal/nitro/routes/runtime-stack.js +1 -1
  95. package/dist/src/internal/nitro/routes/schedule-task.js +1 -1
  96. package/dist/src/protocol/cancel-turn.d.ts +11 -0
  97. package/dist/src/protocol/cancel-turn.js +1 -0
  98. package/dist/src/protocol/routes.d.ts +10 -0
  99. package/dist/src/protocol/routes.js +1 -1
  100. package/dist/src/public/channels/eve.d.ts +2 -1
  101. package/dist/src/public/channels/eve.js +1 -1
  102. package/dist/src/public/channels/linear/api.d.ts +0 -1
  103. package/dist/src/public/channels/linear/api.js +17 -22
  104. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  105. package/dist/src/public/definitions/channel.d.ts +20 -10
  106. package/dist/src/public/next/index.js +1 -1
  107. package/dist/src/public/next/resolve-eve-binary.d.ts +12 -0
  108. package/dist/src/public/next/resolve-eve-binary.js +1 -0
  109. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  110. package/dist/src/runtime/framework-tools/agent.d.ts +13 -0
  111. package/dist/src/runtime/framework-tools/agent.js +1 -0
  112. package/dist/src/runtime/framework-tools/index.d.ts +7 -2
  113. package/dist/src/runtime/framework-tools/index.js +1 -1
  114. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  115. package/dist/src/runtime/types.d.ts +2 -1
  116. package/dist/src/setup/boxes/reconcile-host-framework-preset.d.ts +26 -0
  117. package/dist/src/setup/boxes/reconcile-host-framework-preset.js +1 -0
  118. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  119. package/dist/src/setup/index.js +1 -1
  120. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  121. package/dist/src/setup/scaffold/create/project.js +2 -2
  122. package/dist/src/setup/scaffold/index.d.ts +1 -1
  123. package/dist/src/setup/scaffold/index.js +1 -1
  124. package/dist/src/setup/scaffold/update/channels.d.ts +7 -1
  125. package/dist/src/setup/scaffold/update/channels.js +2 -2
  126. package/dist/src/setup/scaffold/update/connections.js +3 -3
  127. package/dist/src/setup/vercel-project-framework.d.ts +12 -0
  128. package/dist/src/setup/vercel-project-framework.js +1 -1
  129. package/dist/src/svelte/index.js +1 -1
  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.js +1 -1
  133. package/docs/channels/eve.mdx +11 -1
  134. package/docs/concepts/default-harness.md +2 -0
  135. package/docs/concepts/sessions-runs-and-streaming.md +11 -0
  136. package/docs/evals/assertions.mdx +2 -2
  137. package/docs/evals/cases.mdx +31 -0
  138. package/docs/evals/overview.mdx +1 -1
  139. package/docs/evals/targets.mdx +2 -1
  140. package/docs/guides/client/continuations.mdx +2 -0
  141. package/docs/guides/client/streaming.mdx +17 -1
  142. package/docs/guides/frontend/overview.mdx +4 -2
  143. package/docs/guides/frontend/use-eve-agent-svelte.mdx +2 -2
  144. package/docs/guides/frontend/use-eve-agent-vue.mdx +2 -2
  145. package/docs/guides/remote-agents.md +2 -0
  146. package/docs/reference/cli.md +15 -2
  147. package/docs/subagents.mdx +10 -0
  148. package/package.json +6 -6
  149. package/dist/src/compiled/_chunks/workflow/attribute-changes-MGTOG_uX.js +0 -20
  150. package/dist/src/compiled/_chunks/workflow/resume-hook-DHP5ql3-.js +0 -1
  151. package/dist/src/compiled/_chunks/workflow/run-D8hv1ptT.js +0 -1
  152. package/dist/src/compiled/_chunks/workflow/sleep-uA9pS-PT.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # eve
2
2
 
3
+ ## 0.24.5
4
+
5
+ ### Patch Changes
6
+
7
+ - bfbbe92: Add `eve build --profile <path>` for a machine-readable build-timing and final-output-size report. Profile collection is best-effort, so reporting failures do not fail an otherwise successful build.
8
+ - dab9889: Allow agents to remove the root-only built-in `agent` delegation tool with `disableTool()` from `agent/tools/agent.ts`.
9
+ - e1cb505: Retry transient network failures while reopening client session streams so active turns remain attached.
10
+ - 2568387: Cancel active local, nested, and remote subagent turns when their parent turn is cancelled. Client and eval sessions can now cancel active turns directly, and eval live-turn handles can wait for typed mid-turn events before cancellation or settlement.
11
+ - 20cd9a1: Added `POST /eve/v1/session/:sessionId/cancel` to the eve HTTP channel for requesting cancellation of an in-flight turn. The optional `{ turnId }` body limits the request to the turn the caller observed; the response reports `"accepted"` when a cancellation hook accepts it or the benign `"no_active_turn"` when no resumable target exists.
12
+ - 02698fd: Fix Vercel deploys for the Next.js web channel. `eve` no longer scaffolds a
13
+ `vercel.json` `experimentalServices` block, which the Vercel platform now
14
+ rejects (it requires the `services` key and a stricter schema). For Next.js the
15
+ block was also redundant — `withEve()` generates the eve service and
16
+ `/eve/v1/*` routes into the Build Output at build time — so the scaffold now
17
+ writes a minimal `vercel.json`.
18
+ - e45a066: `eve link` now lets you create a Vercel project or link an existing one, matching the project setup available through `/model` usage.
19
+ - 5f8818b: `eve channels add web` now updates the Vercel Framework Preset when adding a
20
+ Next.js web channel to an already-linked eve project to prevent deployment
21
+ failures.
22
+ - 887908c: Bundle authored modules in each development generation as one shared graph, avoiding repeated parsing and emission of dependencies for every tool.
23
+ - 376a82f: Report the root-only `agent` action alongside other framework tools in agent info, including whether it is active, disabled, or replaced.
24
+ - 4f2863d: Update the bundled Workflow runtime dependencies to their latest 5.0 beta releases.
25
+ - d9d3226: Fix `withEve` producing a broken Vercel build command in npm workspaces, where the `eve` module is located in the workspace root.
26
+
3
27
  ## 0.24.4
4
28
 
5
29
  ### Patch Changes
@@ -1,5 +1,6 @@
1
1
  import type { UserContent } from "ai";
2
2
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
3
+ import type { CancelTurnStatus } from "#protocol/cancel-turn.js";
3
4
  import type { RunMode } from "#shared/run-mode.js";
4
5
  import type { RuntimeActionResult } from "#runtime/actions/types.js";
5
6
  import type { InputRequest, InputResponse } from "#runtime/input/types.js";
@@ -10,6 +11,16 @@ export type { ContextAccessor } from "#context/key.js";
10
11
  export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
11
12
  import type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
12
13
  export type RunSessionLimits = Pick<AgentLimitsDefinition, "maxInputTokensPerSession" | "maxOutputTokensPerSession">;
14
+ /** Identifies the session turn to cancel. */
15
+ export interface CancelTurnInput {
16
+ readonly sessionId: string;
17
+ /** Limits the request to the turn the caller observed. */
18
+ readonly turnId?: string;
19
+ }
20
+ /** Result of requesting turn cancellation. Both statuses are successful. */
21
+ export interface CancelTurnResult {
22
+ readonly status: CancelTurnStatus;
23
+ }
13
24
  /**
14
25
  * Identifies one turn within a session.
15
26
  *
@@ -314,6 +325,8 @@ export interface Runtime {
314
325
  * completion.
315
326
  */
316
327
  run(input: RunInput): Promise<RunHandle>;
328
+ /** Requests cancellation of a session's in-flight turn. */
329
+ cancelTurn(input: CancelTurnInput): Promise<CancelTurnResult>;
317
330
  /**
318
331
  * Delivers a follow-up message to a parked session.
319
332
  */
@@ -8,6 +8,7 @@ const EVE_INFO_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/info`;
8
8
  const EVE_CREATE_SESSION_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/session`;
9
9
  const EVE_CONTINUE_SESSION_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId`;
10
10
  const EVE_MESSAGE_STREAM_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/stream`;
11
+ const EVE_CANCEL_TURN_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/cancel`;
11
12
  const EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
12
13
  const EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`;
13
14
  const EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH = `${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`;
@@ -19,6 +20,9 @@ function createEveMessageStreamRoutePath(sessionId) {
19
20
  function createEveContinueSessionRoutePath(sessionId) {
20
21
  return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}`;
21
22
  }
23
+ function createEveCancelTurnRoutePath(sessionId) {
24
+ return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}/cancel`;
25
+ }
22
26
 
23
27
  //#endregion
24
28
  //#region src/client/agent-info-error.ts
@@ -290,6 +294,14 @@ function isCurrentTurnBoundaryEvent(event) {
290
294
  return event.type === "session.completed" || event.type === "session.failed" || event.type === "session.waiting";
291
295
  }
292
296
 
297
+ //#endregion
298
+ //#region src/protocol/cancel-turn.ts
299
+ const CancelTurnResponseSchema = z.object({
300
+ ok: z.literal(true),
301
+ sessionId: z.string().min(1),
302
+ status: z.enum(["accepted", "no_active_turn"])
303
+ });
304
+
293
305
  //#endregion
294
306
  //#region src/shared/json.ts
295
307
  const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
@@ -442,7 +454,7 @@ function isStreamDisconnectError(error) {
442
454
  if (error instanceof DOMException) return error.name === "AbortError";
443
455
  if (!(error instanceof Error)) return false;
444
456
  const errorCode = "code" in error && typeof error.code === "string" ? error.code : void 0;
445
- return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
457
+ return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || error instanceof TypeError && /^(?:failed to fetch|fetch failed)$/i.test(error.message) || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
446
458
  }
447
459
  async function* readNdjsonStream(body) {
448
460
  const reader = body.getReader();
@@ -548,11 +560,18 @@ async function openStreamBody(input) {
548
560
  for (let attempt = 0; attempt < STREAM_OPEN_RETRY_ATTEMPTS; attempt += 1) {
549
561
  const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId), input.startIndex !== 0 ? { startIndex: String(input.startIndex) } : void 0);
550
562
  const headers = await input.resolveHeaders();
551
- const response = await fetch(url, {
552
- headers,
553
- redirect: input.redirect,
554
- signal: input.signal ?? null
555
- });
563
+ let response;
564
+ try {
565
+ response = await fetch(url, {
566
+ headers,
567
+ redirect: input.redirect,
568
+ signal: input.signal ?? null
569
+ });
570
+ } catch (error) {
571
+ if (input.signal?.aborted || !isStreamDisconnectError(error) || attempt === STREAM_OPEN_RETRY_ATTEMPTS - 1) throw error;
572
+ await sleep$1(STREAM_OPEN_RETRY_DELAY_MS);
573
+ continue;
574
+ }
556
575
  if (response.ok) {
557
576
  if (!response.body) throw new ClientError(response.status, "Response body is null.", response.headers);
558
577
  return response.body;
@@ -587,12 +606,40 @@ var ClientSession = class {
587
606
  const payload = normalizeSendTurnInput(input);
588
607
  const state = this.#state;
589
608
  const { continuationToken, sessionId } = await this.#postTurn(payload, state);
609
+ if (this.#state === state) this.#state = {
610
+ ...state,
611
+ sessionId
612
+ };
590
613
  return new MessageResponse({
591
614
  continuationToken,
592
615
  createStream: () => this.#createEventStream(sessionId, continuationToken, state, payload),
593
616
  sessionId
594
617
  });
595
618
  }
619
+ async cancel() {
620
+ const sessionId = this.#state.sessionId;
621
+ if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
622
+ const url = createClientUrl(this.#context.host, createEveCancelTurnRoutePath(sessionId));
623
+ const headers = await this.#context.resolveHeaders();
624
+ const response = await fetch(url, withRedirectPolicy$1({
625
+ headers,
626
+ method: "POST"
627
+ }, this.#context.redirect));
628
+ const body = await response.text();
629
+ if (!response.ok) throw new ClientError(response.status, body, response.headers);
630
+ let payload;
631
+ try {
632
+ payload = JSON.parse(body);
633
+ } catch {
634
+ throw new Error(`Cancel route returned invalid JSON (${response.status}).`);
635
+ }
636
+ const result = CancelTurnResponseSchema.safeParse(payload);
637
+ if (!result.success || result.data.sessionId !== sessionId) throw new Error(`Cancel route returned an invalid response (${response.status}).`);
638
+ return {
639
+ sessionId: result.data.sessionId,
640
+ status: result.data.status
641
+ };
642
+ }
596
643
  stream(options) {
597
644
  const sessionId = this.#state.sessionId;
598
645
  if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
@@ -746,6 +793,12 @@ function createHandleMessageBody(input) {
746
793
  if (input.session.continuationToken !== void 0 && body.message === void 0 && body.inputResponses === void 0) return null;
747
794
  return body;
748
795
  }
796
+ function withRedirectPolicy$1(init, redirect) {
797
+ return redirect === void 0 ? init : {
798
+ ...init,
799
+ redirect
800
+ };
801
+ }
749
802
 
750
803
  //#endregion
751
804
  //#region src/client/types.ts
@@ -8,6 +8,7 @@ const EVE_INFO_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/info`;
8
8
  const EVE_CREATE_SESSION_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/session`;
9
9
  const EVE_CONTINUE_SESSION_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId`;
10
10
  const EVE_MESSAGE_STREAM_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/stream`;
11
+ const EVE_CANCEL_TURN_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/cancel`;
11
12
  const EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
12
13
  const EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`;
13
14
  const EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH = `${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`;
@@ -19,6 +20,9 @@ function createEveMessageStreamRoutePath(sessionId) {
19
20
  function createEveContinueSessionRoutePath(sessionId) {
20
21
  return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}`;
21
22
  }
23
+ function createEveCancelTurnRoutePath(sessionId) {
24
+ return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}/cancel`;
25
+ }
22
26
 
23
27
  //#endregion
24
28
  //#region src/client/agent-info-error.ts
@@ -290,6 +294,14 @@ function isCurrentTurnBoundaryEvent(event) {
290
294
  return event.type === "session.completed" || event.type === "session.failed" || event.type === "session.waiting";
291
295
  }
292
296
 
297
+ //#endregion
298
+ //#region src/protocol/cancel-turn.ts
299
+ const CancelTurnResponseSchema = z.object({
300
+ ok: z.literal(true),
301
+ sessionId: z.string().min(1),
302
+ status: z.enum(["accepted", "no_active_turn"])
303
+ });
304
+
293
305
  //#endregion
294
306
  //#region src/shared/json.ts
295
307
  const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
@@ -442,7 +454,7 @@ function isStreamDisconnectError(error) {
442
454
  if (error instanceof DOMException) return error.name === "AbortError";
443
455
  if (!(error instanceof Error)) return false;
444
456
  const errorCode = "code" in error && typeof error.code === "string" ? error.code : void 0;
445
- return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
457
+ return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || error instanceof TypeError && /^(?:failed to fetch|fetch failed)$/i.test(error.message) || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
446
458
  }
447
459
  async function* readNdjsonStream(body) {
448
460
  const reader = body.getReader();
@@ -548,11 +560,18 @@ async function openStreamBody(input) {
548
560
  for (let attempt = 0; attempt < STREAM_OPEN_RETRY_ATTEMPTS; attempt += 1) {
549
561
  const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId), input.startIndex !== 0 ? { startIndex: String(input.startIndex) } : void 0);
550
562
  const headers = await input.resolveHeaders();
551
- const response = await fetch(url, {
552
- headers,
553
- redirect: input.redirect,
554
- signal: input.signal ?? null
555
- });
563
+ let response;
564
+ try {
565
+ response = await fetch(url, {
566
+ headers,
567
+ redirect: input.redirect,
568
+ signal: input.signal ?? null
569
+ });
570
+ } catch (error) {
571
+ if (input.signal?.aborted || !isStreamDisconnectError(error) || attempt === STREAM_OPEN_RETRY_ATTEMPTS - 1) throw error;
572
+ await sleep$1(STREAM_OPEN_RETRY_DELAY_MS);
573
+ continue;
574
+ }
556
575
  if (response.ok) {
557
576
  if (!response.body) throw new ClientError(response.status, "Response body is null.", response.headers);
558
577
  return response.body;
@@ -587,12 +606,40 @@ var ClientSession = class {
587
606
  const payload = normalizeSendTurnInput(input);
588
607
  const state = this.#state;
589
608
  const { continuationToken, sessionId } = await this.#postTurn(payload, state);
609
+ if (this.#state === state) this.#state = {
610
+ ...state,
611
+ sessionId
612
+ };
590
613
  return new MessageResponse({
591
614
  continuationToken,
592
615
  createStream: () => this.#createEventStream(sessionId, continuationToken, state, payload),
593
616
  sessionId
594
617
  });
595
618
  }
619
+ async cancel() {
620
+ const sessionId = this.#state.sessionId;
621
+ if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
622
+ const url = createClientUrl(this.#context.host, createEveCancelTurnRoutePath(sessionId));
623
+ const headers = await this.#context.resolveHeaders();
624
+ const response = await fetch(url, withRedirectPolicy$1({
625
+ headers,
626
+ method: "POST"
627
+ }, this.#context.redirect));
628
+ const body = await response.text();
629
+ if (!response.ok) throw new ClientError(response.status, body, response.headers);
630
+ let payload;
631
+ try {
632
+ payload = JSON.parse(body);
633
+ } catch {
634
+ throw new Error(`Cancel route returned invalid JSON (${response.status}).`);
635
+ }
636
+ const result = CancelTurnResponseSchema.safeParse(payload);
637
+ if (!result.success || result.data.sessionId !== sessionId) throw new Error(`Cancel route returned an invalid response (${response.status}).`);
638
+ return {
639
+ sessionId: result.data.sessionId,
640
+ status: result.data.status
641
+ };
642
+ }
596
643
  stream(options) {
597
644
  const sessionId = this.#state.sessionId;
598
645
  if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
@@ -746,6 +793,12 @@ function createHandleMessageBody(input) {
746
793
  if (input.session.continuationToken !== void 0 && body.message === void 0 && body.inputResponses === void 0) return null;
747
794
  return body;
748
795
  }
796
+ function withRedirectPolicy$1(init, redirect) {
797
+ return redirect === void 0 ? init : {
798
+ ...init,
799
+ redirect
800
+ };
801
+ }
749
802
 
750
803
  //#endregion
751
804
  //#region src/client/types.ts
@@ -0,0 +1,14 @@
1
+ import type { Command } from "#compiled/commander/index.js";
2
+ import type { ApplicationBuildOptions } from "#internal/nitro/host/types.js";
3
+ export type BuildHost = (appRoot: string, options: ApplicationBuildOptions) => Promise<string>;
4
+ interface BuildCommandLogger {
5
+ log(message: string): void;
6
+ }
7
+ /** Registers the production application build command. */
8
+ export declare function registerBuildCommand(input: {
9
+ readonly appRoot: string;
10
+ readonly buildHost?: BuildHost;
11
+ readonly logger: BuildCommandLogger;
12
+ readonly program: Command;
13
+ }): void;
14
+ export {};
@@ -0,0 +1 @@
1
+ import{resolve}from"node:path";import{resolveInternalVercelServiceOutput}from"#cli/vercel-service-output.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";function registerBuildCommand(t){let n=createCliTheme();t.program.command(`build`).description(`Build the current eve application.`).option(`--profile <path>`,`Write best-effort timing and output-size profile JSON to a file`).option(`--skip-sandbox-prewarm`,`Skip sandbox template prewarm for a Vercel build; output may not be deployable`).action(async e=>{let{loadDevelopmentEnvironmentFiles:r}=await import(`#cli/dev/environment.js`);r(t.appRoot);let i=t.buildHost??(await import(`#internal/nitro/host.js`)).buildApplication,a=e.profile===void 0?void 0:resolve(t.appRoot,e.profile),o={skipVercelSandboxPrewarm:e.skipSandboxPrewarm===!0,vercelServiceOutput:resolveInternalVercelServiceOutput(t.appRoot)};a!==void 0&&(o.profileOutputPath=a);let s=await i(t.appRoot,o);t.logger.log(renderCliTaggedLine(n,{message:`built output at ${s}`,tag:`build`,tone:`success`}))})}export{registerBuildCommand};
@@ -1 +1 @@
1
- import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{isEveProject,listAuthoredChannels}from"#setup/scaffold/index.js";import{interactiveAsker}from"#setup/ask.js";import{addChannels}from"#setup/boxes/add-channels.js";import{deployProject}from"#setup/boxes/deploy-project.js";import{selectChannels}from"#setup/boxes/select-channels.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{createPrompter}from"#setup/prompter.js";import{runInteractive}from"#setup/runner.js";import{createDefaultSetupState,snapshotSetupState}from"#setup/state.js";const KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment};async function runAddChannelsFlow(n,r,i,s){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let c=s.createPrompter?.()??createPrompter();c.intro(`Add channels to your eve agent`),c.log.message(`Checking the current Vercel project...`);let l={...createDefaultSetupState(),project:projectResolutionFromDeployment(await s.detectDeployment(n)),projectPath:{kind:`resolved`,inPlace:!0,path:n}},u;function inspectRegistrations(){return u===void 0&&(c.log.message(`Inspecting existing channel registrations...`),u=inspectExistingChannelRegistrations(n)),u}let d=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0,f=await runInteractive([selectChannels({asker:interactiveAsker(c),variant:`channels-add`,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:d,validateSelection:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),addChannels({asker:interactiveAsker(c),prompter:c,presetCreateSlackbot:i.yes?!0:void 0,force:i.force,configureVercelServices:!0,ensureLinkedProject:`interactive-vercel-link`,deps:s.addChannelsDeps}),deployProject({prompter:c,ensureLinkedProject:`interactive-vercel-link`,deps:s.deployProjectDeps})],l,{write:e=>c.log.message(e)},{snapshot:snapshotSetupState});f.kind!==`cancelled`&&c.outro(f.state.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,i,a=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,i.kind===void 0?void 0:parseChannelKind(i.kind),i.options,a)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,a){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let o=await listAuthoredChannels(t);if(a.json){e.log(JSON.stringify({channels:o},null,2));return}if(o.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of o)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
1
+ import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{isEveProject,listAuthoredChannels}from"#setup/scaffold/index.js";import{interactiveAsker}from"#setup/ask.js";import{addChannels}from"#setup/boxes/add-channels.js";import{deployProject}from"#setup/boxes/deploy-project.js";import{reconcileHostFrameworkPreset}from"#setup/boxes/reconcile-host-framework-preset.js";import{selectChannels}from"#setup/boxes/select-channels.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{createPrompter}from"#setup/prompter.js";import{runInteractive}from"#setup/runner.js";import{createDefaultSetupState,snapshotSetupState}from"#setup/state.js";const KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment};async function runAddChannelsFlow(n,r,i,s){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let c=s.createPrompter?.()??createPrompter();c.intro(`Add channels to your eve agent`),c.log.message(`Checking the current Vercel project...`);let l={...createDefaultSetupState(),project:projectResolutionFromDeployment(await s.detectDeployment(n)),projectPath:{kind:`resolved`,inPlace:!0,path:n}},u;function inspectRegistrations(){return u===void 0&&(c.log.message(`Inspecting existing channel registrations...`),u=inspectExistingChannelRegistrations(n)),u}let d=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0,f=await runInteractive([selectChannels({asker:interactiveAsker(c),variant:`channels-add`,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:d,validateSelection:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),addChannels({asker:interactiveAsker(c),prompter:c,presetCreateSlackbot:i.yes?!0:void 0,force:i.force,configureVercelServices:!0,ensureLinkedProject:`interactive-vercel-link`,deps:s.addChannelsDeps}),reconcileHostFrameworkPreset({prompter:c}),deployProject({prompter:c,ensureLinkedProject:`interactive-vercel-link`,deps:s.deployProjectDeps})],l,{write:e=>c.log.message(e)},{snapshot:snapshotSetupState});f.kind!==`cancelled`&&c.outro(f.state.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,i,a=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,i.kind===void 0?void 0:parseChannelKind(i.kind),i.options,a)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,a){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let o=await listAuthoredChannels(t);if(a.json){e.log(JSON.stringify({channels:o},null,2));return}if(o.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of o)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
@@ -12,10 +12,11 @@ export interface LinkCommandDependencies {
12
12
  flowDeps?: Partial<LinkFlowDeps>;
13
13
  }
14
14
  /**
15
- * `eve link`: pick a Vercel team and project (re-linking when one is already
16
- * linked), run `vercel link` for the selected project, then pull env so the AI Gateway
17
- * credential lands in `.env.local`. The flow itself is {@link runLinkFlow}, shared with the dev
18
- * TUI `/model` menu's provider row. Interactive only: the pickers are the point of the command,
19
- * so a non-TTY run refuses with guidance instead of guessing a project.
15
+ * `eve link`: pick a Vercel team, then create or select a project (re-linking
16
+ * when one is already linked), run `vercel link` for the resolved project,
17
+ * then pull env so the AI Gateway credential lands in `.env.local`. The flow
18
+ * itself is {@link runLinkFlow}, shared with the dev TUI `/model` menu's
19
+ * provider row. Interactive only: the pickers are the point of the command, so
20
+ * a non-TTY run refuses with guidance instead of guessing a project.
20
21
  */
21
22
  export declare function runLinkCommand(logger: LinkCliLogger, appRoot: string, dependencies?: LinkCommandDependencies): Promise<void>;
@@ -1 +1 @@
1
- import{NOT_AN_AGENT_MESSAGE,hasInteractiveTerminal}from"./preconditions.js";import{isEveProject}from"#setup/scaffold/index.js";import{createPrompter}from"#setup/prompter.js";import{runLinkFlow}from"#setup/flows/link.js";const defaultDependencies={isEveProject,hasInteractiveTerminal};async function runLinkCommand(t,n,r=defaultDependencies){if(!await r.isEveProject(n)){t.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}if(!r.hasInteractiveTerminal()){t.error("`eve link` needs an interactive terminal to pick the team and project. In CI, run `vercel link --project <name> --yes --non-interactive` instead."),process.exitCode=1;return}let i=r.createPrompter?.()??createPrompter();i.intro(`Link your eve agent to Vercel`);try{let e=await runLinkFlow({appRoot:n,prompter:i,deps:r.flowDeps});i.outro(e.kind===`cancelled`?`Cancelled.`:`Project linked.`)}catch(e){t.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}export{runLinkCommand};
1
+ import{NOT_AN_AGENT_MESSAGE,hasInteractiveTerminal}from"./preconditions.js";import{isEveProject}from"#setup/scaffold/index.js";import{createPrompter}from"#setup/prompter.js";import{runLinkFlow}from"#setup/flows/link.js";const defaultDependencies={isEveProject,hasInteractiveTerminal};async function runLinkCommand(t,n,r=defaultDependencies){if(!await r.isEveProject(n)){t.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}if(!r.hasInteractiveTerminal()){t.error("`eve link` needs an interactive terminal to pick the team and project. In CI, run `vercel link --project <name> --yes --non-interactive` instead."),process.exitCode=1;return}let i=r.createPrompter?.()??createPrompter();i.intro(`Link your eve agent to Vercel`);try{let e=await runLinkFlow({appRoot:n,prompter:i,projectSelection:`create-or-link`,deps:r.flowDeps});i.outro(e.kind===`cancelled`?`Cancelled.`:`Project linked.`)}catch(e){t.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}export{runLinkCommand};
@@ -1,6 +1,7 @@
1
+ import { type BuildHost } from "#cli/commands/build.js";
1
2
  import { resolveDevUiMode, resolveTuiDisplayOptions } from "#cli/dev/ui-options.js";
2
3
  import type { RunDevelopmentTuiInput } from "#cli/dev/tui/tui.js";
3
- import type { ApplicationBuildOptions, DevelopmentServer, DevelopmentServerOptions, ProductionServerHandle } from "#internal/nitro/host/types.js";
4
+ import type { DevelopmentServer, DevelopmentServerOptions, ProductionServerHandle } from "#internal/nitro/host/types.js";
4
5
  export { resolveDevUiMode, resolveTuiDisplayOptions };
5
6
  interface CliLogger {
6
7
  error(message: string): void;
@@ -12,7 +13,7 @@ interface CliRuntimeDependencies {
12
13
  readonly appRoot: string;
13
14
  readonly serverUrl: string;
14
15
  }): Promise<boolean>;
15
- buildHost(appRoot: string, options: ApplicationBuildOptions): Promise<string>;
16
+ buildHost: BuildHost;
16
17
  printApplicationInfo(logger: CliLogger, appRoot: string, options?: {
17
18
  json?: boolean;
18
19
  }): Promise<void>;
@@ -1,3 +1,3 @@
1
- import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{resolveInternalVercelServiceOutput}from"#cli/vercel-service-output.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{parseDevelopmentHeaderOption,resolveDevelopmentUrlTarget}from"#cli/dev/url-target.js";import{LOG_DISPLAY_MODES,parseLogDisplayMode}from"#cli/dev/tui/log-display-mode.js";import{resolveTuiTitle}from"#cli/dev/tui/target.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";const devBootLog=createLogger(`dev.boot`);function createDevBootProgressReporter(e){return t=>{switch(t.type){case`phase-started`:e?.update(`Building your agent`,t.phase),devBootLog.debug(t.phase);return;case`phase-finished`:devBootLog.debug(`${t.phase} finished`,{ms:t.elapsedMs});return;case`before-first-paint`:e?.stop();return;default:return t}}}async function loadBuildHost(){return(await import(`#internal/nitro/host.js`)).buildApplication}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentTui(){return(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#internal/nitro/host.js`)).createDevelopmentServer}const loadIsActiveDevelopmentServerForApp=async()=>(await import(`#internal/nitro/host.js`)).isActiveDevelopmentServerForApp;async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function shouldPrintCliBootBanner(e){return e.name()===`info`||e.name()===`dev`||e.name()===`init`}async function waitForShutdownSignal(e){await new Promise((t,n)=>{let r=!1,cleanup=()=>{process.off(`SIGINT`,handleSignal),process.off(`SIGTERM`,handleSignal)},handleSignal=()=>{r||(r=!0,cleanup(),e.close().then(t,n))};process.once(`SIGINT`,handleSignal),process.once(`SIGTERM`,handleSignal)})}async function waitForProductionServer(e){await Promise.race([e.wait(),waitForShutdownSignal({close:()=>e.close()})])}function parsePortOption(e){if(!/^-?\d+$/.test(e))throw new InvalidArgumentError(`Expected a numeric port, received "${e}".`);let t=Number(e);if(t<0||t>65535)throw new InvalidArgumentError(`Expected a port between 0 and 65535, received "${e}".`);return t}const DISPLAY_MODES=new Set([`full`,`collapsed`,`auto-collapsed`,`hidden`]),STATS_MODES=new Set([`tokens`,`tokensPerSecond`]);function parseDisplayMode(e){if(!DISPLAY_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...DISPLAY_MODES].join(`, `)}, received "${e}".`);return e}function parseStatsMode(e){if(!STATS_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...STATS_MODES].join(`, `)}, received "${e}".`);return e}function parseLogsMode(e){let t=parseLogDisplayMode(e);if(t===void 0)throw new InvalidArgumentError(`Expected one of ${LOG_DISPLAY_MODES.join(`, `)}, received "${e}".`);return t}function parseContextSizeOption(e){let t=Number(e);if(!Number.isFinite(t)||t<=0)throw new InvalidArgumentError(`Expected a positive number, received "${e}".`);return t}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function createCliProgram(e,i){let c=resolveApplicationRoot(),m=resolveInstalledPackageInfo().version,h=new Command,_=createCliTheme();h.name(`eve`).description(`Build and run an eve application.`).version(m).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{shouldPrintCliBootBanner(n)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}});let v=h.command(`channels`).description(`Manage user-authored channels in the current project.`);v.command(`add [kind]`).description(`Add channels interactively, or scaffold a channel kind (slack | web).`).option(`-f, --force`,`Overwrite existing channel files`).option(`-y, --yes`,`Assume yes for confirmations; requires an explicit channel kind`).action(async(t,n)=>{let{runChannelsAddCommand:r}=await import(`#cli/commands/channels.js`);await r(e,c,{kind:t,options:n})}),v.command(`list`).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async t=>{let{runChannelsListCommand:n}=await import(`#cli/commands/channels.js`);await n(e,c,t)});let y=h.command(`extension`).description(`Create and build reusable eve extension packages.`);return y.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:r}=await import(`#cli/commands/extension-init.js`);await r(e,c,t)}),y.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);t(c);let{runExtensionBuildCommand:n}=await import(`#cli/commands/extension-build.js`);await n(e,c)}),h.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:r}=await import(`#cli/commands/init.js`);await r(e,c,t,{channelWebNextjs:n.channelWebNextjs})}),registerProjectCommands({program:h,logger:e,appRoot:c}),h.command(`build`).description(`Build the current eve application.`).option(`--skip-sandbox-prewarm`,`Skip Vercel sandbox template prewarm; output may not be deployable`).action(async t=>{let{loadDevelopmentEnvironmentFiles:n}=await import(`#cli/dev/environment.js`);n(c);let a=await(i.buildHost??await loadBuildHost())(c,{skipVercelSandboxPrewarm:t.skipSandboxPrewarm===!0,vercelServiceOutput:resolveInternalVercelServiceOutput(c)});e.log(renderCliTaggedLine(_,{message:`built output at ${a}`,tag:`build`,tone:`success`}))}),h.command(`start`).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async t=>{let{loadDevelopmentEnvironmentFiles:n}=await import(`#cli/dev/environment.js`);n(c);let a=await(i.startProductionHost??await loadStartProductionHost())(c,{host:t.host,port:t.port});e.log(renderCliTaggedLine(_,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForProductionServer(a)}),h.command(`dev`).description(`Start the eve development server or connect to an existing URL.`).argument(`[url]`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 2000)`,parsePortOption).option(`-u, --url <url>`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`-H, --header <header>`,`Request header for a URL target, in "Name: value" form (repeatable)`,parseDevelopmentHeaderOption).option(`--no-ui`,`Start the server without an interactive UI`).option(`--name <name>`,`Title shown in the terminal UI (defaults to the app folder name)`).option(`--input <text>`,`Pre-fill the prompt input, or start onboarding with /model`).option(`--tools <mode>`,`How tool calls render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--reasoning <mode>`,`How reasoning renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--subagents <mode>`,`How subagent sections render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--connection-auth <mode>`,`How connection authorization renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--assistant-response-stats <mode>`,`Assistant header statistic: tokens | tokensPerSecond`,parseStatsMode).option(`--context-size <tokens>`,`Model context window size, shown as a usage percentage`,parseContextSizeOption).option(`--logs <mode>`,`Which server/agent logs to show: all | stderr | sandbox | none`,parseLogsMode).addHelpText(`after`,`
1
+ import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{parseDevelopmentHeaderOption,resolveDevelopmentUrlTarget}from"#cli/dev/url-target.js";import{LOG_DISPLAY_MODES,parseLogDisplayMode}from"#cli/dev/tui/log-display-mode.js";import{resolveTuiTitle}from"#cli/dev/tui/target.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";const devBootLog=createLogger(`dev.boot`);function createDevBootProgressReporter(e){return t=>{switch(t.type){case`phase-started`:e?.update(`Building your agent`,t.phase),devBootLog.debug(t.phase);return;case`phase-finished`:devBootLog.debug(`${t.phase} finished`,{ms:t.elapsedMs});return;case`before-first-paint`:e?.stop();return;default:return t}}}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentTui(){return(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#internal/nitro/host.js`)).createDevelopmentServer}const loadIsActiveDevelopmentServerForApp=async()=>(await import(`#internal/nitro/host.js`)).isActiveDevelopmentServerForApp;async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function shouldPrintCliBootBanner(e){return e.name()===`info`||e.name()===`dev`||e.name()===`init`}async function waitForShutdownSignal(e){await new Promise((t,n)=>{let r=!1,cleanup=()=>{process.off(`SIGINT`,handleSignal),process.off(`SIGTERM`,handleSignal)},handleSignal=()=>{r||(r=!0,cleanup(),e.close().then(t,n))};process.once(`SIGINT`,handleSignal),process.once(`SIGTERM`,handleSignal)})}async function waitForProductionServer(e){await Promise.race([e.wait(),waitForShutdownSignal({close:()=>e.close()})])}function parsePortOption(e){if(!/^-?\d+$/.test(e))throw new InvalidArgumentError(`Expected a numeric port, received "${e}".`);let t=Number(e);if(t<0||t>65535)throw new InvalidArgumentError(`Expected a port between 0 and 65535, received "${e}".`);return t}const DISPLAY_MODES=new Set([`full`,`collapsed`,`auto-collapsed`,`hidden`]),STATS_MODES=new Set([`tokens`,`tokensPerSecond`]);function parseDisplayMode(e){if(!DISPLAY_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...DISPLAY_MODES].join(`, `)}, received "${e}".`);return e}function parseStatsMode(e){if(!STATS_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...STATS_MODES].join(`, `)}, received "${e}".`);return e}function parseLogsMode(e){let t=parseLogDisplayMode(e);if(t===void 0)throw new InvalidArgumentError(`Expected one of ${LOG_DISPLAY_MODES.join(`, `)}, received "${e}".`);return t}function parseContextSizeOption(e){let t=Number(e);if(!Number.isFinite(t)||t<=0)throw new InvalidArgumentError(`Expected a positive number, received "${e}".`);return t}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function createCliProgram(e,i){let c=resolveApplicationRoot(),m=resolveInstalledPackageInfo().version,h=new Command,_=createCliTheme();h.name(`eve`).description(`Build and run an eve application.`).version(m).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{shouldPrintCliBootBanner(n)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}});let v=h.command(`channels`).description(`Manage user-authored channels in the current project.`);v.command(`add [kind]`).description(`Add channels interactively, or scaffold a channel kind (slack | web).`).option(`-f, --force`,`Overwrite existing channel files`).option(`-y, --yes`,`Assume yes for confirmations; requires an explicit channel kind`).action(async(t,n)=>{let{runChannelsAddCommand:r}=await import(`#cli/commands/channels.js`);await r(e,c,{kind:t,options:n})}),v.command(`list`).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async t=>{let{runChannelsListCommand:n}=await import(`#cli/commands/channels.js`);await n(e,c,t)});let y=h.command(`extension`).description(`Create and build reusable eve extension packages.`);return y.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:r}=await import(`#cli/commands/extension-init.js`);await r(e,c,t)}),y.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);t(c);let{runExtensionBuildCommand:n}=await import(`#cli/commands/extension-build.js`);await n(e,c)}),h.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:r}=await import(`#cli/commands/init.js`);await r(e,c,t,{channelWebNextjs:n.channelWebNextjs})}),registerProjectCommands({program:h,logger:e,appRoot:c}),registerBuildCommand({appRoot:c,buildHost:i.buildHost,logger:e,program:h}),h.command(`start`).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async t=>{let{loadDevelopmentEnvironmentFiles:n}=await import(`#cli/dev/environment.js`);n(c);let a=await(i.startProductionHost??await loadStartProductionHost())(c,{host:t.host,port:t.port});e.log(renderCliTaggedLine(_,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForProductionServer(a)}),h.command(`dev`).description(`Start the eve development server or connect to an existing URL.`).argument(`[url]`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 2000)`,parsePortOption).option(`-u, --url <url>`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`-H, --header <header>`,`Request header for a URL target, in "Name: value" form (repeatable)`,parseDevelopmentHeaderOption).option(`--no-ui`,`Start the server without an interactive UI`).option(`--name <name>`,`Title shown in the terminal UI (defaults to the app folder name)`).option(`--input <text>`,`Pre-fill the prompt input, or start onboarding with /model`).option(`--tools <mode>`,`How tool calls render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--reasoning <mode>`,`How reasoning renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--subagents <mode>`,`How subagent sections render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--connection-auth <mode>`,`How connection authorization renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--assistant-response-stats <mode>`,`Assistant header statistic: tokens | tokensPerSecond`,parseStatsMode).option(`--context-size <tokens>`,`Model context window size, shown as a usage percentage`,parseContextSizeOption).option(`--logs <mode>`,`Which server/agent logs to show: all | stderr | sandbox | none`,parseLogsMode).addHelpText(`after`,`
2
2
  You can also pass a bare URL, for example: eve dev https://example.com
3
3
  `).action(async(t,n)=>{let a=resolveDevelopmentUrlTarget(n,t),s=a?.serverUrl,u=hasInteractiveTerminal(),d=resolveDevUiMode({options:n,interactive:u});if(n.input!==void 0&&d===`headless`)throw new InvalidArgumentError(`--input requires the interactive UI.`);let f=!1;s!==void 0&&(f=await(i.isActiveDevelopmentServerForApp??await loadIsActiveDevelopmentServerForApp())({appRoot:c,serverUrl:s}));let runInteractiveUi=async(e,t)=>{let r=await devBootPhase(`loading interactive UI`,async()=>i.runDevelopmentTui??await loadRunDevelopmentTui(),t),o=resolveTuiDisplayOptions(n),l=s===void 0||f?{kind:`local`,serverUrl:e.serverUrl,workspaceRoot:e.appRoot??c}:{kind:`remote`,serverUrl:e.serverUrl,workspaceRoot:c},u=resolveTuiTitle({name:n.name,target:l});u!==void 0&&(o.name=u);let d={target:l,initialInput:n.input,onBootProgress:t,...o};a?.headers===void 0?await r(d):await r({...d,headers:a.headers})};if(s){let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);if(t(c),e.log(`↗ ${f?`local`:`remote`} mode targeting ${_.info(new URL(s).host)}`),d===`headless`){e.log(renderCliTaggedLine(_,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}e.log(``),await runInteractiveUi({serverUrl:s});return}d===`tui`&&e.log(``);let p=d===`tui`?startCliLiveRow(e):void 0,m=createDevBootProgressReporter(p);p?.update(`Building your agent`);let h=!1,g,closeServer=async()=>{h||g===void 0||(h=!0,await g.close())};try{g=(i.startHost??await loadStartHost())(c,{existing:d===`tui`?`attach-if-unconfigured`:`reject`,host:n.host,onBootProgress:m,port:n.port});let t=await g.start();if(d!==`tui`&&e.log(renderCliTaggedLine(_,{message:`server listening at ${t.url}`,tag:`dev`,tone:`success`})),d===`headless`)return n.ui!==!1&&!u&&e.log(renderCliTaggedLine(_,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`})),await waitForShutdownSignal({close:closeServer});await runInteractiveUi({appRoot:t.appRoot,serverUrl:t.url},m)}finally{p?.stop(),await closeServer()}}),h.command(`info`).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async t=>{await(i.printApplicationInfo??await loadPrintApplicationInfo())(e,c,t)}),h.command(`eval`).description(`Run evals against an eve agent.`).argument(`[evalIds...]`,`Eval ids (or directory prefixes) to run (all discovered evals when omitted)`).option(`--url <url>`,`Remote agent URL (skip local host startup)`,parseDevelopmentServerUrl).option(`--tag <tag...>`,`Run only evals carrying a tag`).option(`--strict`,`Fail the exit code when any score falls below its threshold`).option(`--list`,`Print discovered evals without running them`).option(`--timeout <ms>`,`Per-eval timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent eval executions`).option(`--json`,`Output results as JSON`).option(`--junit <path>`,`Write JUnit XML results to a file`).option(`--skip-report`,`Skip eval-defined reporters (e.g. Braintrust)`).option(`--verbose`,`Stream per-eval t.log lines to stdout`).action(async(t,n)=>{await(i.runEvalCommand??await loadRunEvalCommand())(t,n,e)}),h}async function runCli(e=process.argv.slice(2),t=console,n={}){let r=createCliProgram(t,n),a=e.length===0?[`dev`]:e;try{await r.parseAsync(a,{from:`user`})}catch(e){if(e instanceof CommanderError){if(e.exitCode===0)return;let r=await(n.isCodingAgentLaunch??isCodingAgentLaunch)();if(a[0]===`init`&&r){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}}export{resolveDevUiMode,resolveTuiDisplayOptions,runCli};
@@ -7,7 +7,7 @@ export { createDataUrlFilePart, createTextWithFileContent } from "#client/file-p
7
7
  export { MessageResponse } from "#client/message-response.js";
8
8
  export { ClientSession } from "#client/session.js";
9
9
  export type { EveAgentStoreCallbacks, EveAgentStoreInit, EveAgentStoreSnapshot, EveAgentStoreStatus, PrepareSend, } from "#client/eve-agent-store.js";
10
- export type { AgentInfoEntry, AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoFrameworkChannelEntry, AgentInfoFrameworkToolEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoResult, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, ClientAuth, ClientOptions, ClientRedirectPolicy, HeadersValue, HealthResult, MessageResult, SendTurnInput, SendTurnPayload, SessionState, StreamOptions, TokenValue, } from "#client/types.js";
10
+ export type { AgentInfoEntry, AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoFrameworkChannelEntry, AgentInfoFrameworkToolEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoResult, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, CancelSessionResult, ClientAuth, ClientOptions, ClientRedirectPolicy, HeadersValue, HealthResult, MessageResult, SendTurnInput, SendTurnPayload, SessionState, StreamOptions, TokenValue, } from "#client/types.js";
11
11
  export type { EveAgentReducer, EveAgentReducerEvent, ClientInputRespondedEvent, ClientMessageFailedEvent, ClientMessageSubmittedEvent, } from "#client/reducer.js";
12
12
  export type { EveAuthorizationChallenge, EveAuthorizationOutcome, EveAuthorizationPart, EveMessageData, EveDynamicToolPart, EveMessageInputRequest, EveMessage, EveMessageMetadata, EveMessagePart, EveMessageToolMetadata, } from "#client/message-reducer.js";
13
13
  export type { ActionResultStreamEvent, ActionsRequestedStreamEvent, AssistantStepFinishReason, AuthorizationOutcome, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedPart, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, ResultCompletedStreamEvent, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionStartedStreamEvent, SessionWaitingStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, SubagentCalledStreamEvent, SubagentChildEventStreamEvent, SubagentCompletedStreamEvent, SubagentStartedStreamEvent, TurnCancelledStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, TurnFailureStreamEvent, } from "#protocol/message.js";
@@ -1,3 +1,3 @@
1
- function isStreamDisconnectError(e){if(e instanceof DOMException)return e.name===`AbortError`;if(!(e instanceof Error))return!1;let t=`code`in e&&typeof e.code==`string`?e.code:void 0;return e.name===`AbortError`||e.message===`terminated`||t===`UND_ERR_SOCKET`||/abort|cancel|disconnect|premature close|socket|terminated/i.test(e.message)}async function*readNdjsonStream(e){let t=e.getReader(),n=new TextDecoder,r=``,i=!1;try{for(;;){let e=await t.read();if(e.done){i=!0,r+=n.decode();break}e.value&&(r+=n.decode(e.value,{stream:!0}));let a=r.indexOf(`
1
+ function isStreamDisconnectError(e){if(e instanceof DOMException)return e.name===`AbortError`;if(!(e instanceof Error))return!1;let t=`code`in e&&typeof e.code==`string`?e.code:void 0;return e.name===`AbortError`||e.message===`terminated`||t===`UND_ERR_SOCKET`||e instanceof TypeError&&/^(?:failed to fetch|fetch failed)$/i.test(e.message)||/abort|cancel|disconnect|premature close|socket|terminated/i.test(e.message)}async function*readNdjsonStream(e){let t=e.getReader(),n=new TextDecoder,r=``,i=!1;try{for(;;){let e=await t.read();if(e.done){i=!0,r+=n.decode();break}e.value&&(r+=n.decode(e.value,{stream:!0}));let a=r.indexOf(`
2
2
  `);for(;a!==-1;){let e=r.slice(0,a).trim();r=r.slice(a+1),e.length>0&&(yield JSON.parse(e)),a=r.indexOf(`
3
3
  `)}}let e=r.trim();e.length>0&&(yield JSON.parse(e))}finally{i||await t.cancel().catch(()=>{}),t.releaseLock()}}export{isStreamDisconnectError,readNdjsonStream};
@@ -19,8 +19,9 @@ type OpenStreamBodyInput = Omit<OpenStreamInput, "maxReconnectAttempts">;
19
19
  */
20
20
  export declare function openStreamIterable(input: OpenStreamInput): AsyncGenerator<HandleMessageStreamEvent>;
21
21
  /**
22
- * Opens one stream response body, retrying the short propagation window where
23
- * a just-acknowledged session may not yet be readable from the stream route.
22
+ * Opens one stream response body, retrying transient network errors and the
23
+ * short propagation window where a just-acknowledged session may not yet be
24
+ * readable from the stream route.
24
25
  */
25
26
  export declare function openStreamBody(input: OpenStreamBodyInput): Promise<ReadableStream<Uint8Array>>;
26
27
  export {};
@@ -1 +1 @@
1
- import{createEveMessageStreamRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";const STREAM_OPEN_RETRYABLE_STATUS=new Set([404,409,425,500,502,503,504]);async function*openStreamIterable(e){let t=e.startIndex,n=e.startIndex<0?0:e.maxReconnectAttempts;for(;;){let a=await openStreamBody({...e,startIndex:t}),o=!1;try{for await(let e of readNdjsonStream(a))t+=1,yield e}catch(e){if(!isStreamDisconnectError(e))throw e;o=!0}if(!o||e.signal?.aborted||n<=0)return;--n}}async function openStreamBody(r){let i,o,s;for(let c=0;c<12;c+=1){let l=createClientUrl(r.host,createEveMessageStreamRoutePath(r.sessionId),r.startIndex===0?void 0:{startIndex:String(r.startIndex)}),u=await r.resolveHeaders(),d=await fetch(l,{headers:u,redirect:r.redirect,signal:r.signal??null});if(d.ok){if(!d.body)throw new ClientError(d.status,`Response body is null.`,d.headers);return d.body}if(i=d.status,o=await d.text(),s=d.headers,!STREAM_OPEN_RETRYABLE_STATUS.has(d.status))throw new ClientError(d.status,o,d.headers);c<11&&await sleep(250)}throw new ClientError(i??0,o??`Failed to open message stream.`,s)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}export{openStreamBody,openStreamIterable};
1
+ import{createEveMessageStreamRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";const STREAM_OPEN_RETRYABLE_STATUS=new Set([404,409,425,500,502,503,504]);async function*openStreamIterable(e){let t=e.startIndex,n=e.startIndex<0?0:e.maxReconnectAttempts;for(;;){let i=await openStreamBody({...e,startIndex:t}),a=!1;try{for await(let e of readNdjsonStream(i))t+=1,yield e}catch(e){if(!isStreamDisconnectError(e))throw e;a=!0}if(!a||e.signal?.aborted||n<=0)return;--n}}async function openStreamBody(r){let a,o,s;for(let c=0;c<12;c+=1){let l=createClientUrl(r.host,createEveMessageStreamRoutePath(r.sessionId),r.startIndex===0?void 0:{startIndex:String(r.startIndex)}),u=await r.resolveHeaders(),d;try{d=await fetch(l,{headers:u,redirect:r.redirect,signal:r.signal??null})}catch(e){if(r.signal?.aborted||!isStreamDisconnectError(e)||c===11)throw e;await sleep(250);continue}if(d.ok){if(!d.body)throw new ClientError(d.status,`Response body is null.`,d.headers);return d.body}if(a=d.status,o=await d.text(),s=d.headers,!STREAM_OPEN_RETRYABLE_STATUS.has(d.status))throw new ClientError(d.status,o,d.headers);c<11&&await sleep(250)}throw new ClientError(a??0,o??`Failed to open message stream.`,s)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}export{openStreamBody,openStreamIterable};
@@ -1,6 +1,6 @@
1
1
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
2
2
  import { MessageResponse } from "#client/message-response.js";
3
- import type { ClientRedirectPolicy, SendTurnInput, SessionState, StreamOptions } from "#client/types.js";
3
+ import type { CancelSessionResult, ClientRedirectPolicy, SendTurnInput, SessionState, StreamOptions } from "#client/types.js";
4
4
  /**
5
5
  * Internal interface that a {@link ClientSession} uses to access client-level
6
6
  * configuration without depending on the full {@link Client} class.
@@ -24,8 +24,9 @@ export declare class ClientSession {
24
24
  /** @internal */
25
25
  constructor(context: SessionContext, state: SessionState);
26
26
  /**
27
- * Current session cursor. Always reflects the latest state after each
28
- * completed turn. Serialize this to persist and resume later.
27
+ * Current session cursor. The assigned session ID appears as soon as a send
28
+ * is accepted; the continuation token and stream index advance as its event
29
+ * stream is consumed. Serialize this to persist and resume later.
29
30
  */
30
31
  get state(): SessionState;
31
32
  /**
@@ -36,6 +37,17 @@ export declare class ClientSession {
36
37
  * headers in a single request.
37
38
  */
38
39
  send<TOutput = unknown>(input: SendTurnInput<TOutput>): Promise<MessageResponse<TOutput>>;
40
+ /**
41
+ * Requests cooperative cancellation of this session's active turn.
42
+ *
43
+ * Both `accepted` and `no_active_turn` are successful outcomes. The latter
44
+ * means the active turn settled before the request arrived or the session is
45
+ * already parked. Credentials are resolved immediately before the request.
46
+ *
47
+ * @throws {Error} If this handle has not started or attached to a session.
48
+ * @throws {ClientError} If the cancel route returns a non-successful status.
49
+ */
50
+ cancel(): Promise<CancelSessionResult>;
39
51
  /**
40
52
  * Opens this session's event stream for the current session ID.
41
53
  *
@@ -1 +1 @@
1
- import{EVE_CREATE_SESSION_ROUTE_PATH,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{normalizeOutputSchemaForRequest}from"#client/output-schema.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";import{openStreamBody,openStreamIterable}from"#client/open-stream.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);return new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return this.#a(t,e)}async#n(n,r){let a=r.sessionId?createEveContinueSessionRoutePath(r.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,s=createClientUrl(this.#e.host,a),c=await this.#e.resolveHeaders(n.headers);c.set(`content-type`,`application/json`);let l=createHandleMessageBody({input:n,outputSchema:normalizeOutputSchemaForRequest(n.outputSchema),session:r});if(l===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let u=await postTurnWithRetry({body:JSON.stringify(l),headers:c,mustDeliver:(n.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:n.signal,url:s}),d=await u.json(),f=(typeof d.sessionId==`string`?d.sessionId:void 0)??u.headers.get(EVE_SESSION_ID_HEADER)?.trim()??r.sessionId;if(!f)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof d.continuationToken==`string`?d.continuationToken:void 0,sessionId:f}}async*#r(e,t,n,i){let a=[];try{let t=n.sessionId===e?n.streamIndex:0,r=this.#e.maxReconnectAttempts;for(;;){let n=await this.#i(e,t,i.signal,i.headers),o=!1;try{for await(let e of readNdjsonStream(n))if(a.push(e),t+=1,yield e,isCurrentTurnBoundaryEvent(e)){o=!0;break}}catch(e){if(!isStreamDisconnectError(e))throw e}if(o||i.signal?.aborted||r<=0)break;--r}}finally{this.#t=advanceSession({continuationToken:t,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async#i(e,t,n,r){return await openStreamBody({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(r),redirect:this.#e.redirect,sessionId:e,signal:n,startIndex:t})}async*#a(e,t){let n=this.#t,i=t?.startIndex??n.streamIndex,a=[];try{for await(let n of openStreamIterable({host:this.#e.host,maxReconnectAttempts:this.#e.maxReconnectAttempts,resolveHeaders:()=>this.#e.resolveHeaders(),redirect:this.#e.redirect,sessionId:e,signal:t?.signal,startIndex:i}))a.push(n),yield n}finally{i>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:i},sessionId:e}))}}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,r,i,a;for(let o=0;o<t;o+=1){let s=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(s.ok)return s;if(r=s.status,i=await s.text(),a=s.headers,!isRetryableDeliveryFailure(s.status,i))throw new ClientError(s.status,i,s.headers);o<t-1&&await sleep(200)}throw new ClientError(r??0,i??`Failed to deliver session turn.`,a)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}export{ClientSession};
1
+ import{EVE_CREATE_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{normalizeOutputSchemaForRequest}from"#client/output-schema.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{openStreamBody,openStreamIterable}from"#client/open-stream.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);return this.#t===n&&(this.#t={...n,sessionId:i}),new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}async cancel(){let e=this.#t.sessionId;if(!e)throw Error(`Session has no session ID. Send a message first.`);let n=createClientUrl(this.#e.host,createEveCancelTurnRoutePath(e)),i=await this.#e.resolveHeaders(),o=await fetch(n,withRedirectPolicy({headers:i,method:`POST`},this.#e.redirect)),s=await o.text();if(!o.ok)throw new ClientError(o.status,s,o.headers);let c;try{c=JSON.parse(s)}catch{throw Error(`Cancel route returned invalid JSON (${o.status}).`)}let l=CancelTurnResponseSchema.safeParse(c);if(!l.success||l.data.sessionId!==e)throw Error(`Cancel route returned an invalid response (${o.status}).`);return{sessionId:l.data.sessionId,status:l.data.status}}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return this.#a(t,e)}async#n(t,r){let i=r.sessionId?createEveContinueSessionRoutePath(r.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,o=createClientUrl(this.#e.host,i),c=await this.#e.resolveHeaders(t.headers);c.set(`content-type`,`application/json`);let u=createHandleMessageBody({input:t,outputSchema:normalizeOutputSchemaForRequest(t.outputSchema),session:r});if(u===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let d=await postTurnWithRetry({body:JSON.stringify(u),headers:c,mustDeliver:(t.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:t.signal,url:o}),f=await d.json(),p=(typeof f.sessionId==`string`?f.sessionId:void 0)??d.headers.get(EVE_SESSION_ID_HEADER)?.trim()??r.sessionId;if(!p)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof f.continuationToken==`string`?f.continuationToken:void 0,sessionId:p}}async*#r(e,t,n,r){let a=[];try{let t=n.sessionId===e?n.streamIndex:0,i=this.#e.maxReconnectAttempts;for(;;){let n=await this.#i(e,t,r.signal,r.headers),o=!1;try{for await(let e of readNdjsonStream(n))if(a.push(e),t+=1,yield e,isCurrentTurnBoundaryEvent(e)){o=!0;break}}catch(e){if(!isStreamDisconnectError(e))throw e}if(o||r.signal?.aborted||i<=0)break;--i}}finally{this.#t=advanceSession({continuationToken:t,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async#i(e,t,n,r){return await openStreamBody({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(r),redirect:this.#e.redirect,sessionId:e,signal:n,startIndex:t})}async*#a(e,t){let n=this.#t,r=t?.startIndex??n.streamIndex,a=[];try{for await(let n of openStreamIterable({host:this.#e.host,maxReconnectAttempts:this.#e.maxReconnectAttempts,resolveHeaders:()=>this.#e.resolveHeaders(),redirect:this.#e.redirect,sessionId:e,signal:t?.signal,startIndex:r}))a.push(n),yield n}finally{r>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:r},sessionId:e}))}}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,n,i,a;for(let o=0;o<t;o+=1){let s=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(s.ok)return s;if(n=s.status,i=await s.text(),a=s.headers,!isRetryableDeliveryFailure(s.status,i))throw new ClientError(s.status,i,s.headers);o<t-1&&await sleep(200)}throw new ClientError(n??0,i??`Failed to deliver session turn.`,a)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{ClientSession};
@@ -1,6 +1,7 @@
1
1
  import type { UserContent } from "ai";
2
2
  import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
3
3
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
4
+ import type { CancelTurnStatus } from "#protocol/cancel-turn.js";
4
5
  import type { InputRequest, InputResponse } from "#runtime/input/types.js";
5
6
  import type { JsonObject } from "#shared/json.js";
6
7
  export type { AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoEntry, AgentInfoFrameworkChannelEntry, AgentInfoFrameworkToolEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoResult, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, } from "./agent-info-schema.js";
@@ -147,6 +148,13 @@ export interface StreamOptions {
147
148
  */
148
149
  readonly signal?: AbortSignal;
149
150
  }
151
+ /** Result of requesting cancellation for a client session's active turn. */
152
+ export interface CancelSessionResult {
153
+ /** Session whose active turn was targeted. */
154
+ readonly sessionId: string;
155
+ /** Both outcomes are successful; `no_active_turn` means there was nothing left to cancel. */
156
+ readonly status: CancelTurnStatus;
157
+ }
150
158
  /**
151
159
  * Aggregated result of one message turn, returned by
152
160
  * {@link MessageResponse.result}.
@@ -28,12 +28,12 @@
28
28
  "@vercel/detect-agent": "1.2.3",
29
29
  "@vercel/oidc": "3.5.0",
30
30
  "@vercel/sandbox": "2.3.0",
31
- "@workflow/core": "5.0.0-beta.34",
32
- "@workflow/errors": "5.0.0-beta.10",
31
+ "@workflow/core": "5.0.0-beta.35",
32
+ "@workflow/errors": "5.0.0-beta.11",
33
33
  "@workflow/serde": "5.0.0-beta.2",
34
- "@workflow/world": "5.0.0-beta.20",
35
- "@workflow/world-local": "5.0.0-beta.28",
36
- "@workflow/world-vercel": "5.0.0-beta.30",
34
+ "@workflow/world": "5.0.0-beta.21",
35
+ "@workflow/world-local": "5.0.0-beta.29",
36
+ "@workflow/world-vercel": "5.0.0-beta.31",
37
37
  "zod": "4.4.3",
38
38
  "zod-validation-error": "5.0.0"
39
39
  },
@@ -1,2 +1,2 @@
1
- import{c as e,i as t}from"../../_chunks/workflow/dist-DpDDcpTl.js";import{An as n,C as r,Cn as i,Dn as a,En as o,Mn as s,R as c,T as l,Tn as u,fn as d,h as f,jn as p,mn as m,pn as h,t as g,z as _}from"../../_chunks/workflow/attribute-changes-MGTOG_uX.js";import"../../_chunks/workflow/dist-Blxnyb7-.js";import{n as v}from"../../_chunks/workflow/resume-hook-DHP5ql3-.js";import{t as y}from"../../_chunks/workflow/sleep-uA9pS-PT.js";function b(e){p(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,b)}function x(e){p(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,x)}function S({schema:e}={}){function t(e){p(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await v(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
- `)}`)}return await v(t,r.value)}}}async function C(e,n={}){let r=_.getStore(),a=r?.workflowMetadata?.workflowRunId;if(!a)throw new t(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let o=g(e,n);if(o.length!==0){if(r.runReadyBarrier)try{await r.runReadyBarrier}catch{}await(await i()).events.create(a,{eventType:`attr_set`,specVersion:5,eventData:{changes:o,writer:{type:`step`,stepId:r.stepMetadata.stepId,attempt:r.stepMetadata.attempt},...n.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}const w=C;function T(){let e=_.getStore();return e||n(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,T),e.stepMetadata}function E(){let e=_.getStore();return e||s(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,E),e.workflowMetadata}function D(e={}){let t=_.getStore();t||s(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,D);let{namespace:n}=e,i=t.workflowMetadata.workflowRunId,p=c(i,n),g=t.writables??=new Map,v=g.get(p);if(v)return v.writable;let y=l(r(globalThis,t.ops,i,t.encryptionKey,!0,t.runReadyBarrier),t.encryptionKey),b=new f(i,p,t.runReadyBarrier),x=u();return t.ops.push(x.promise),o(y.readable,b,x).catch(()=>{}),a(y.writable,x),Object.defineProperty(y.writable,d,{value:p,writable:!1}),Object.defineProperty(y.writable,m,{value:i,writable:!1}),t.workflowDeploymentId&&Object.defineProperty(y.writable,h,{value:t.workflowDeploymentId,writable:!1}),g.set(p,{writable:y.writable,state:x}),y.writable}export{t as FatalError,e as RetryableError,b as createHook,x as createWebhook,S as defineHook,w as experimental_setAttributes,T as getStepMetadata,E as getWorkflowMetadata,D as getWritable,C as setAttributes,y as sleep};
1
+ import{i as e,l as t}from"../../_chunks/workflow/dist-BYo8Gno2.js";import{An as n,B as r,D as i,Dn as a,Fn as o,In as s,Pn as c,T as l,V as u,_ as d,_n as f,gn as p,jn as m,kn as h,t as g,vn as _}from"../../_chunks/workflow/attribute-changes-DXbmITuI.js";import"../../_chunks/workflow/dist-CSfKNxQW.js";import{n as v}from"../../_chunks/workflow/resume-hook-DvvgYsRt.js";import{t as y}from"../../_chunks/workflow/sleep-DzxrwWTs.js";function b(e){o(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,b)}function x(e){o(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,x)}function S({schema:e}={}){function t(e){o(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await v(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
+ `)}`)}return await v(t,r.value)}}}async function C(t,n={}){let r=u.getStore(),i=r?.workflowMetadata?.workflowRunId;if(!i)throw new e(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let o=g(t,n);if(o.length!==0){if(r.runReadyBarrier)try{await r.runReadyBarrier}catch{}await(await a()).events.create(i,{eventType:`attr_set`,specVersion:5,eventData:{changes:o,writer:{type:`step`,stepId:r.stepMetadata.stepId,attempt:r.stepMetadata.attempt},...n.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}const w=C;function T(){let e=u.getStore();return e||c(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,T),e.stepMetadata}function E(){let e=u.getStore();return e||s(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,E),e.workflowMetadata}function D(e={}){let t=u.getStore();t||s(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,D);let{namespace:a}=e,o=t.workflowMetadata.workflowRunId,c=r(o,a),g=t.writables??=new Map,v=g.get(c);if(v)return v.writable;let y=i(l(globalThis,t.ops,o,t.encryptionKey,!0,t.runReadyBarrier),t.encryptionKey),b=new d(o,c,t.runReadyBarrier),x=h();return t.ops.push(x.promise),n(y.readable,b,x).catch(()=>{}),m(y.writable,x),Object.defineProperty(y.writable,p,{value:c,writable:!1}),Object.defineProperty(y.writable,_,{value:o,writable:!1}),t.workflowDeploymentId&&Object.defineProperty(y.writable,f,{value:t.workflowDeploymentId,writable:!1}),g.set(c,{writable:y.writable,state:x}),y.writable}export{e as FatalError,t as RetryableError,b as createHook,x as createWebhook,S as defineHook,w as experimental_setAttributes,T as getStepMetadata,E as getWorkflowMetadata,D as getWritable,C as setAttributes,y as sleep};