eve 0.83.0 → 0.83.2

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 (147) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/src/channel/types.d.ts +3 -2
  3. package/dist/src/chunks/{use-eve-agent-Ci5dr0aR.js → use-eve-agent-DnbG9c7c.js} +33 -9
  4. package/dist/src/chunks/{use-eve-agent-3-WRmJkd.js → use-eve-agent-ZY7NQ2VW.js} +33 -9
  5. package/dist/src/cli/run.js +1 -1
  6. package/dist/src/client/message-response.d.ts +18 -0
  7. package/dist/src/client/message-response.js +1 -1
  8. package/dist/src/client/session.js +1 -1
  9. package/dist/src/compiled/.vendor-stamp.json +2 -2
  10. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  11. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  12. package/dist/src/context/build-dynamic-tools.js +1 -1
  13. package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -2
  14. package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
  15. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  16. package/dist/src/context/prewarm.d.ts +27 -0
  17. package/dist/src/context/prewarm.js +1 -0
  18. package/dist/src/context/providers/sandbox.d.ts +7 -0
  19. package/dist/src/context/providers/sandbox.js +1 -1
  20. package/dist/src/context/run-step.js +1 -1
  21. package/dist/src/discover/lib.d.ts +4 -3
  22. package/dist/src/discover/lib.js +1 -1
  23. package/dist/src/discover/named-source-directory.d.ts +3 -2
  24. package/dist/src/evals/assertions/run.js +1 -1
  25. package/dist/src/evals/cli/eval.d.ts +2 -0
  26. package/dist/src/evals/cli/eval.js +2 -2
  27. package/dist/src/evals/define-eval-config.d.ts +5 -4
  28. package/dist/src/evals/define-eval-config.js +1 -1
  29. package/dist/src/evals/index.d.ts +1 -1
  30. package/dist/src/evals/runner/artifacts.js +2 -2
  31. package/dist/src/evals/runner/attempt-label.d.ts +2 -0
  32. package/dist/src/evals/runner/attempt-label.js +1 -0
  33. package/dist/src/evals/runner/derive-run-facts.d.ts +13 -0
  34. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  35. package/dist/src/evals/runner/reporters/braintrust.js +1 -1
  36. package/dist/src/evals/runner/reporters/console.js +1 -1
  37. package/dist/src/evals/runner/reporters/datadog.js +1 -1
  38. package/dist/src/evals/runner/reporters/junit.js +2 -2
  39. package/dist/src/evals/runner/reporters/types.d.ts +2 -0
  40. package/dist/src/evals/runner/run-evals.d.ts +5 -0
  41. package/dist/src/evals/runner/run-evals.js +1 -1
  42. package/dist/src/evals/session-manager.js +1 -1
  43. package/dist/src/evals/session.d.ts +4 -1
  44. package/dist/src/evals/session.js +2 -2
  45. package/dist/src/evals/types.d.ts +37 -1
  46. package/dist/src/eve-channel/request.js +1 -1
  47. package/dist/src/execution/catalog/connection-entry.js +1 -1
  48. package/dist/src/execution/connections/callback-route.d.ts +3 -2
  49. package/dist/src/execution/connections/callback-route.js +1 -1
  50. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  51. package/dist/src/execution/node-step.d.ts +1 -0
  52. package/dist/src/execution/node-step.js +1 -1
  53. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  54. package/dist/src/execution/sandbox/ensure.d.ts +8 -0
  55. package/dist/src/execution/sandbox/ensure.js +1 -1
  56. package/dist/src/execution/sandbox/multiplexed-command.d.ts +9 -3
  57. package/dist/src/execution/sandbox/multiplexed-command.js +1 -1
  58. package/dist/src/execution/sandbox/read-file.js +1 -1
  59. package/dist/src/execution/session/handoff-steps.d.ts +1 -0
  60. package/dist/src/execution/session/handoff-steps.js +1 -1
  61. package/dist/src/execution/session/handoff.js +1 -1
  62. package/dist/src/execution/session/handover-tracing.d.ts +3 -0
  63. package/dist/src/execution/session/handover-tracing.js +1 -0
  64. package/dist/src/execution/session/prewarm-step.d.ts +13 -0
  65. package/dist/src/execution/session/prewarm-step.js +1 -0
  66. package/dist/src/execution/session/program.d.ts +4 -1
  67. package/dist/src/execution/session/program.js +1 -1
  68. package/dist/src/execution/session/state-cursor.d.ts +11 -0
  69. package/dist/src/execution/session/state-cursor.js +1 -1
  70. package/dist/src/execution/session/turn-step-types.d.ts +2 -0
  71. package/dist/src/execution/session/turn-step.js +1 -1
  72. package/dist/src/execution/session/turn.d.ts +1 -0
  73. package/dist/src/execution/session/turn.js +1 -1
  74. package/dist/src/execution/session-event-stream.d.ts +6 -0
  75. package/dist/src/execution/session-event-stream.js +1 -1
  76. package/dist/src/execution/session-inbox/inbox.d.ts +8 -0
  77. package/dist/src/execution/session-inbox/inbox.js +1 -1
  78. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  79. package/dist/src/execution/workflow-runtime.js +1 -1
  80. package/dist/src/extensions/git/extension/lib/gh-tool.d.ts +11 -2
  81. package/dist/src/extensions/git/extension/lib/gh-tool.js +1 -1
  82. package/dist/src/harness/attachment-staging.d.ts +3 -0
  83. package/dist/src/harness/attachment-staging.js +1 -1
  84. package/dist/src/harness/compaction/step.d.ts +7 -1
  85. package/dist/src/harness/compaction/step.js +1 -1
  86. package/dist/src/harness/hitl/approvals.d.ts +2 -0
  87. package/dist/src/harness/hitl/approvals.js +1 -1
  88. package/dist/src/harness/hitl/delivery.d.ts +1 -0
  89. package/dist/src/harness/hitl/delivery.js +1 -1
  90. package/dist/src/harness/hitl/intake.js +1 -1
  91. package/dist/src/harness/model-call/call.d.ts +2 -0
  92. package/dist/src/harness/model-call/call.js +1 -1
  93. package/dist/src/harness/model-call/request.d.ts +2 -1
  94. package/dist/src/harness/token-estimate.js +1 -1
  95. package/dist/src/harness/types.d.ts +6 -0
  96. package/dist/src/internal/application/stamped-package-version.js +1 -1
  97. package/dist/src/internal/attachments/media-metadata.d.ts +0 -2
  98. package/dist/src/internal/attachments/media-metadata.js +1 -1
  99. package/dist/src/internal/attachments/read-media-metadata.d.ts +7 -0
  100. package/dist/src/internal/attachments/read-media-metadata.js +2 -0
  101. package/dist/src/internal/authored-asset-import-plugin.d.ts +7 -0
  102. package/dist/src/internal/authored-asset-import-plugin.js +1 -1
  103. package/dist/src/internal/authored-module-build-options.js +1 -1
  104. package/dist/src/internal/authored-module-graph.js +1 -1
  105. package/dist/src/internal/authored-module-loader.d.ts +0 -1
  106. package/dist/src/internal/authored-module-loader.js +1 -1
  107. package/dist/src/internal/authored-package-boundary.d.ts +3 -0
  108. package/dist/src/internal/authored-package-boundary.js +1 -1
  109. package/dist/src/internal/input-text.d.ts +2 -1
  110. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  111. package/dist/src/internal/workflow-bundle/builder.js +2 -2
  112. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  113. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  114. package/dist/src/runtime/connections/authorization-complete-page.d.ts +14 -2
  115. package/dist/src/runtime/connections/authorization-complete-page.js +5 -5
  116. package/dist/src/runtime/subagents/workflow.js +1 -1
  117. package/dist/src/sandbox/state.d.ts +17 -0
  118. package/dist/src/setup/scaffold/create/project.js +1 -1
  119. package/dist/src/svelte/index.js +1 -1
  120. package/dist/src/svelte/use-eve-agent.js +1 -1
  121. package/dist/src/tools/definition.js +1 -1
  122. package/dist/src/tools/durable-callbacks.d.ts +5 -1
  123. package/dist/src/tools/durable-callbacks.js +1 -1
  124. package/dist/src/tools/dynamic.d.ts +3 -3
  125. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  126. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  127. package/dist/src/vue/index.js +1 -1
  128. package/dist/src/vue/use-eve-agent.js +1 -1
  129. package/docs/channels/custom.mdx +4 -0
  130. package/docs/channels/slack.mdx +2 -0
  131. package/docs/concepts/built-in-tools.md +1 -1
  132. package/docs/connections/mcp.mdx +1 -1
  133. package/docs/evals/overview.mdx +1 -1
  134. package/docs/evals/reporters.mdx +4 -4
  135. package/docs/evals/running.mdx +19 -1
  136. package/docs/guides/dynamic-capabilities.md +2 -2
  137. package/docs/guides/frontend/overview.mdx +7 -3
  138. package/docs/guides/instrumentation/otel.mdx +23 -0
  139. package/docs/meta.json +1 -0
  140. package/docs/reference/agent-files.md +1 -1
  141. package/docs/reference/cli.md +17 -15
  142. package/docs/sandbox/custom-providers.mdx +10 -10
  143. package/docs/sandbox/index.mdx +6 -4
  144. package/docs/tools/human-in-the-loop.md +3 -1
  145. package/docs/tools/overview.mdx +1 -1
  146. package/docs/use-cases.mdx +250 -0
  147. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # eve
2
2
 
3
+ ## 0.83.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 8329939: A parent agent's message to a subagent no longer answers the subagent's pending tool approval or session-limit prompt. Before, a follow-up such as `approve` or `continue` settled the prompt as if the person had answered it. Now only a person's structured answer settles it: the parent's message is delivered as an ordinary message, so a pending approval resolves as `ignored` and a session-limit prompt keeps waiting for the person. Thanks @devon-seitz for reporting this in #5075.
8
+ - 084b2bf: When compaction runs partway through a turn, notices the framework sends again, such as the deferred tool catalog notice, now go before the turn's input instead of after the latest tool result, where the model read them as the newest message.
9
+
10
+ Thanks @hrayn3 for reporting this in #5198.
11
+ - c37d279: The connection sign-in page now says "Authorization not completed" instead of "Authorization complete" when the provider redirects back with an OAuth error, such as the person declining consent. Thanks @dretanacr for reporting this in #5105.
12
+ - 4853062: Connection tool calls now fail after 5 minutes without an answer, instead of holding the turn until it is cancelled. eve cancels the request and returns a tool error the agent can report, so a tool that takes longer than 5 minutes now fails. Thanks @dretanacr for reporting this in #4977.
13
+ - 697741e: Record the input the model sent to an agent tool in eval facts, so a subagent or remote agent call in `turn.toolCalls` no longer shows `input: {}` and `t.calledTool(name, { input })` can match it. Thanks @dretanacr for reporting this in #5063.
14
+ - 6447c36: Evals keep an input request pending after a `respond()` that answers only some of the open requests. `session.pendingInputRequests` still lists the unanswered ones, and `parked()` holds (and `succeeded()` fails) while the run waits on them. Thanks @elrumordelaluz for reporting this in #5157.
15
+ - 3b9ceef: An expired session is no longer reported as failed when writing its final `session.completed` event fails. Before, channels such as Slack posted a `session.failed` error after they had already handled `session.completed`. Thanks @bisak for reporting this in #5261.
16
+ - 3d7eb49: A session stream request that does not report the durable tail no longer looks it up. Default opens and client reconnects now check that the session exists with one run lookup, instead of a tail lookup that on the local world opens every chunk file. Unknown and expired sessions still answer 404 and 410 before the stream starts. Thanks @KingAmo for reporting this in #5016.
17
+ - 7d653ef: MCP connections now fall back to the highest mutually supported legacy protocol version when `server/discover` returns `-32022`. Thanks @zico-io for reporting this in #4406, and @bluepegasus123 for proposing the fallback.
18
+ - 9b24d70: PDFs that store their pages in compressed object streams, as phone scans and `pdf-lib` output usually do, now get a per-page token estimate instead of one based on file size. A multi-megabyte scan no longer requests compaction on the first step of a session. Thanks @DLME2024 for reporting this and suggesting the fix in #5090.
19
+ - 1a735c6: `git({ github })` and the deprecated `code({ github })` register their authenticated `gh` tool at session start again, as do dynamic tools built with `defineGhTool` from `eve/extensions/git/sandbox`. Thanks @seahiLin for reporting this in #4986.
20
+ - 653a257: Slack apps that set `onInputResponse` or `approvalChannel` no longer let a message typed in the thread answer an open question. Before, the typed message answered it without running `onInputResponse`, and the answer was the whole `<slack_message>` envelope. The message now reaches the agent as a new message instead.
21
+ - e14685b: On Vercel Sandbox, aborting a `sandbox.run()` or `sandbox.spawn()` command after it starts now kills it, and `run()` rejects instead of waiting, as the `abortSignal` option documents. Before, the command kept running until it exited by itself, including after a turn was cancelled. Thanks @voidhrithik for reporting this in #5301.
22
+ - 64b5d06: Workflow and step modules can now use `?raw` and other relative asset imports. Before, `eve build` failed with `UNLOADABLE_DEPENDENCY` when a module reachable from a workflow imported a file this way, even though the same import worked in a tool. Thanks @gmstevenson for reporting this in #5269.
23
+
24
+ ## 0.83.1
25
+
26
+ ### Patch Changes
27
+
28
+ - 25c9fff: Dynamic tools now accept an `endsTurn` function, as static tools do. eve replays it from a durable descriptor like `execute`, so a tool returned by a `defineDynamic` resolver can decide from its output whether the call ends the turn.
29
+ - eda6122: Eval artifacts now record client timing for each captured session: when each request was sent and accepted (including time spent retrying `session_not_ready`) and when each event arrived. `eve eval --keep-state` keeps the local eval server's state, including its Workflow data, after the run.
30
+ - 77f4473: `eve eval --repeat <n>` and the `repeat` option in `evals.config.ts` run every eval `n` times to measure repeatability. Each attempt is reported as its own result with a 1-based `attempt`, with its own artifact files, Braintrust row, JUnit test case, and Datadog run iteration, and the console summary shows a per-eval pass rate such as `3/5 passed`.
31
+ - 6f551a7: Model calls no longer resume the session sandbox just to render attachment labels. Images and PDFs that eve staged or already read for the session are served from a bounded in-memory cache, so the sandbox is resumed only when eve needs bytes it doesn't already hold.
32
+ - d77462d: Non-module files under `agent/lib/`, such as a JSON file imported by a helper, no longer fail discovery. eve ignores them like it does in `tools/`, `channels/`, and `hooks/`, and the bundler resolves them when imported.
33
+ - 3fbef89: Sandbox work no longer delays the model call. Prewarmed sessions start the sandbox in the background, turns resume a sandbox the session already uses as they begin, and dynamic skill files are written in the background; a tool that uses the sandbox waits only for what remains. A first message sent to a prewarmed session no longer waits for prewarming, and its `defineSandbox()` selector runs with the auth of the request that created the session.
34
+ - 0a9f857: Add correlated OpenTelemetry events for session handover forwarding and inbox unblocking. Receiver observations include a replay-stable Workflow timestamp and are exported by the next existing turn step without adding tracing-only Workflow steps.
35
+
3
36
  ## 0.83.0
4
37
 
5
38
  ### Minor Changes
@@ -577,8 +577,9 @@ export interface Runtime {
577
577
  * parameter unchanged.
578
578
  *
579
579
  * A following read throws `SessionStrandedError` when the session's owner
580
- * cannot execute here. A historical read (`follow: false`) never inspects
581
- * or changes the session's lifecycle.
580
+ * cannot execute here, and rejects before returning when the session does
581
+ * not exist or its history has expired. A historical read (`follow: false`)
582
+ * never inspects or changes the session's lifecycle.
582
583
  */
583
584
  getEventStream(sessionId: string, options?: GetEventStreamOptions): Promise<ReadableStream<MessageStreamEvent>>;
584
585
  /**
@@ -1751,9 +1751,11 @@ function isResultCompletedEvent(event) {
1751
1751
  //#region src/client/message-response.ts
1752
1752
  const consumeResponse = Symbol("consumeMessageResponse");
1753
1753
  const acceptedDeliveryId = Symbol("acceptedDeliveryId");
1754
+ const sendReceipt = Symbol("sendReceipt");
1754
1755
  var MessageResponse = class {
1755
1756
  sessionId;
1756
1757
  [acceptedDeliveryId];
1758
+ [sendReceipt];
1757
1759
  #cancelTurn;
1758
1760
  #cancellation;
1759
1761
  #consumed = false;
@@ -1765,6 +1767,7 @@ var MessageResponse = class {
1765
1767
  this.#cancelTurn = input.cancelTurn;
1766
1768
  this.sessionId = input.sessionId;
1767
1769
  this[acceptedDeliveryId] = input.deliveryId;
1770
+ this[sendReceipt] = input.receipt;
1768
1771
  this.#createStream = input.createStream;
1769
1772
  this.#resumesTurn = input.resumesTurn ?? false;
1770
1773
  }
@@ -2346,14 +2349,22 @@ var ClientSession = class ClientSession {
2346
2349
  this.#state = state;
2347
2350
  }
2348
2351
  static async create(context, input) {
2352
+ const startedAt = Date.now();
2349
2353
  const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true, input.stubs);
2350
- const { sessionId } = await readAcceptedMessage(response);
2354
+ const acceptedAt = Date.now();
2355
+ const { sessionId, deliveryId } = await readAcceptedMessage(response);
2351
2356
  const session = new ClientSession(context, {
2352
2357
  sessionId,
2353
2358
  streamIndex: 0
2354
2359
  });
2360
+ const receipt = {
2361
+ deliveryId,
2362
+ startedAt,
2363
+ notReadyMs: 0,
2364
+ acceptedAt
2365
+ };
2355
2366
  return {
2356
- response: session.#messageResponse(response, input, 0),
2367
+ response: session.#messageResponse(response, input, 0, void 0, receipt),
2357
2368
  session
2358
2369
  };
2359
2370
  }
@@ -2400,11 +2411,14 @@ var ClientSession = class ClientSession {
2400
2411
  async #send(input, retrySessionNotReady) {
2401
2412
  const initialStreamIndex = this.#state.streamIndex;
2402
2413
  const path = createEveSessionRoutePath(this.#state.sessionId);
2403
- const response = retrySessionNotReady ? await postSessionSend(this.#context, path, input) : await postTurn(this.#context, path, input, false);
2414
+ const { response, timing } = await postSessionSend(this.#context, path, input, retrySessionNotReady);
2404
2415
  const { sessionId: responseSessionId, deliveryId } = await readAcceptedMessage(response, this.#state.sessionId);
2405
2416
  if (responseSessionId !== this.#state.sessionId) throw new Error("Message route returned a different session id.");
2406
2417
  if (input.message !== void 0 && deliveryId === void 0) throw new Error("Message route did not return a delivery id. Update the server before sending with this client.");
2407
- return this.#messageResponse(response, input, initialStreamIndex, input.message === void 0 ? void 0 : deliveryId);
2418
+ return this.#messageResponse(response, input, initialStreamIndex, input.message === void 0 ? void 0 : deliveryId, {
2419
+ ...timing,
2420
+ deliveryId
2421
+ });
2408
2422
  }
2409
2423
  async prewarm(options) {
2410
2424
  return await prewarmClientSession({
@@ -2452,12 +2466,13 @@ var ClientSession = class ClientSession {
2452
2466
  keepAlive: true
2453
2467
  });
2454
2468
  }
2455
- #messageResponse(response, input, initialStreamIndex, deliveryId) {
2469
+ #messageResponse(response, input, initialStreamIndex, deliveryId, receipt) {
2456
2470
  response.body?.cancel().catch(() => {});
2457
2471
  return new MessageResponse({
2458
2472
  cancelTurn: async (turnId) => await this.cancel({ turnId }),
2459
2473
  createStream: (source) => this.#createEventStream(initialStreamIndex, input, deliveryId, source),
2460
2474
  deliveryId,
2475
+ receipt,
2461
2476
  resumesTurn: input.inputResponses !== void 0,
2462
2477
  sessionId: this.#state.sessionId
2463
2478
  });
@@ -2538,14 +2553,23 @@ var ClientSession = class ClientSession {
2538
2553
  function followClientSession(session, options) {
2539
2554
  return session[followSession](options);
2540
2555
  }
2541
- async function postSessionSend(context, path, input) {
2542
- const readyDeadline = Date.now() + SESSION_SEND_READY_TIMEOUT_MS;
2556
+ async function postSessionSend(context, path, input, retrySessionNotReady) {
2557
+ const startedAt = Date.now();
2558
+ const readyDeadline = startedAt + SESSION_SEND_READY_TIMEOUT_MS;
2543
2559
  let retryDelayMs = SESSION_SEND_RETRY_BASE_DELAY_MS;
2544
2560
  for (;;) {
2561
+ const attemptAt = Date.now();
2545
2562
  try {
2546
- return await postTurn(context, path, input, false);
2563
+ return {
2564
+ response: await postTurn(context, path, input, false),
2565
+ timing: {
2566
+ startedAt,
2567
+ notReadyMs: attemptAt - startedAt,
2568
+ acceptedAt: Date.now()
2569
+ }
2570
+ };
2547
2571
  } catch (error) {
2548
- if (!isSessionNotReady(error)) throw error;
2572
+ if (!retrySessionNotReady || !isSessionNotReady(error)) throw error;
2549
2573
  const remainingMs = readyDeadline - Date.now();
2550
2574
  if (remainingMs <= 0) throw error;
2551
2575
  await sleep(Math.min(retryDelayMs, remainingMs), input.signal);
@@ -1752,9 +1752,11 @@ function isResultCompletedEvent(event) {
1752
1752
  //#region src/client/message-response.ts
1753
1753
  const consumeResponse = Symbol("consumeMessageResponse");
1754
1754
  const acceptedDeliveryId = Symbol("acceptedDeliveryId");
1755
+ const sendReceipt = Symbol("sendReceipt");
1755
1756
  var MessageResponse = class {
1756
1757
  sessionId;
1757
1758
  [acceptedDeliveryId];
1759
+ [sendReceipt];
1758
1760
  #cancelTurn;
1759
1761
  #cancellation;
1760
1762
  #consumed = false;
@@ -1766,6 +1768,7 @@ var MessageResponse = class {
1766
1768
  this.#cancelTurn = input.cancelTurn;
1767
1769
  this.sessionId = input.sessionId;
1768
1770
  this[acceptedDeliveryId] = input.deliveryId;
1771
+ this[sendReceipt] = input.receipt;
1769
1772
  this.#createStream = input.createStream;
1770
1773
  this.#resumesTurn = input.resumesTurn ?? false;
1771
1774
  }
@@ -2347,14 +2350,22 @@ var ClientSession = class ClientSession {
2347
2350
  this.#state = state;
2348
2351
  }
2349
2352
  static async create(context, input) {
2353
+ const startedAt = Date.now();
2350
2354
  const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true, input.stubs);
2351
- const { sessionId } = await readAcceptedMessage(response);
2355
+ const acceptedAt = Date.now();
2356
+ const { sessionId, deliveryId } = await readAcceptedMessage(response);
2352
2357
  const session = new ClientSession(context, {
2353
2358
  sessionId,
2354
2359
  streamIndex: 0
2355
2360
  });
2361
+ const receipt = {
2362
+ deliveryId,
2363
+ startedAt,
2364
+ notReadyMs: 0,
2365
+ acceptedAt
2366
+ };
2356
2367
  return {
2357
- response: session.#messageResponse(response, input, 0),
2368
+ response: session.#messageResponse(response, input, 0, void 0, receipt),
2358
2369
  session
2359
2370
  };
2360
2371
  }
@@ -2401,11 +2412,14 @@ var ClientSession = class ClientSession {
2401
2412
  async #send(input, retrySessionNotReady) {
2402
2413
  const initialStreamIndex = this.#state.streamIndex;
2403
2414
  const path = createEveSessionRoutePath(this.#state.sessionId);
2404
- const response = retrySessionNotReady ? await postSessionSend(this.#context, path, input) : await postTurn(this.#context, path, input, false);
2415
+ const { response, timing } = await postSessionSend(this.#context, path, input, retrySessionNotReady);
2405
2416
  const { sessionId: responseSessionId, deliveryId } = await readAcceptedMessage(response, this.#state.sessionId);
2406
2417
  if (responseSessionId !== this.#state.sessionId) throw new Error("Message route returned a different session id.");
2407
2418
  if (input.message !== void 0 && deliveryId === void 0) throw new Error("Message route did not return a delivery id. Update the server before sending with this client.");
2408
- return this.#messageResponse(response, input, initialStreamIndex, input.message === void 0 ? void 0 : deliveryId);
2419
+ return this.#messageResponse(response, input, initialStreamIndex, input.message === void 0 ? void 0 : deliveryId, {
2420
+ ...timing,
2421
+ deliveryId
2422
+ });
2409
2423
  }
2410
2424
  async prewarm(options) {
2411
2425
  return await prewarmClientSession({
@@ -2453,12 +2467,13 @@ var ClientSession = class ClientSession {
2453
2467
  keepAlive: true
2454
2468
  });
2455
2469
  }
2456
- #messageResponse(response, input, initialStreamIndex, deliveryId) {
2470
+ #messageResponse(response, input, initialStreamIndex, deliveryId, receipt) {
2457
2471
  response.body?.cancel().catch(() => {});
2458
2472
  return new MessageResponse({
2459
2473
  cancelTurn: async (turnId) => await this.cancel({ turnId }),
2460
2474
  createStream: (source) => this.#createEventStream(initialStreamIndex, input, deliveryId, source),
2461
2475
  deliveryId,
2476
+ receipt,
2462
2477
  resumesTurn: input.inputResponses !== void 0,
2463
2478
  sessionId: this.#state.sessionId
2464
2479
  });
@@ -2539,14 +2554,23 @@ var ClientSession = class ClientSession {
2539
2554
  function followClientSession(session, options) {
2540
2555
  return session[followSession](options);
2541
2556
  }
2542
- async function postSessionSend(context, path, input) {
2543
- const readyDeadline = Date.now() + SESSION_SEND_READY_TIMEOUT_MS;
2557
+ async function postSessionSend(context, path, input, retrySessionNotReady) {
2558
+ const startedAt = Date.now();
2559
+ const readyDeadline = startedAt + SESSION_SEND_READY_TIMEOUT_MS;
2544
2560
  let retryDelayMs = SESSION_SEND_RETRY_BASE_DELAY_MS;
2545
2561
  for (;;) {
2562
+ const attemptAt = Date.now();
2546
2563
  try {
2547
- return await postTurn(context, path, input, false);
2564
+ return {
2565
+ response: await postTurn(context, path, input, false),
2566
+ timing: {
2567
+ startedAt,
2568
+ notReadyMs: attemptAt - startedAt,
2569
+ acceptedAt: Date.now()
2570
+ }
2571
+ };
2548
2572
  } catch (error) {
2549
- if (!isSessionNotReady(error)) throw error;
2573
+ if (!retrySessionNotReady || !isSessionNotReady(error)) throw error;
2550
2574
  const remainingMs = readyDeadline - Date.now();
2551
2575
  if (remainingMs <= 0) throw error;
2552
2576
  await sleep(Math.min(retryDelayMs, remainingMs), input.signal);
@@ -1,2 +1,2 @@
1
1
  import{Command,CommanderError}from"#compiled/commander/index.js";import{agentCommand}from"#cli/agent-command.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";import{waitForShutdownSignal}from"#cli/shutdown.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{findEveProjectContext,resolveEveProjectContext}from"#internal/project-context.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{areSchedulesDisabled}from"#internal/schedules/disabled.js";import{findCliApplicationRoot,resolveCliApplicationProject}from"#cli/application-root.js";import{registerIntegrationCommands}from"#cli/commands/register-integration-commands.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{registerRegistryCommands}from"#cli/commands/register-registry-commands.js";import{registerDevelopmentCommand,registerRemoteCommands}from"#cli/dev/command.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{registerAcpCommand}from"#cli/acp/command.js";import{registerRuntimeInvokeCommand}from"#cli/invoke/command.js";import{parseAgentNamesOption,parsePortOption,parseReasoningOption}from"#cli/option-parsers.js";import{registerEveTelemetryCommands}from"#cli/telemetry/command.js";import{canonicalCommand,createEveCliTelemetry}from"#cli/telemetry/index.js";async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function createCliProgram(e,t,n,r){let i=resolveInstalledPackageInfo().version,a=new Command,o=createCliTheme();a.name(`eve`).description(`Build and run an eve application.`).version(i).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{let{json:r}=n.opts();!r&&(n.name()===`info`||n.name()===`init`&&n.parent!==a)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}}),registerEveTelemetryCommands(a,e),registerIntegrationCommands({program:a,logger:e,applicationContext:n});let s=a.command(`extension`).description(`Create and build reusable eve extension packages.`);s.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:a}=await import(`#cli/commands/extension-init.js`);await a(e,n.root,t,void 0,e=>{r.trackSetupStep({flow:`extension_init`,step:e})})}),s.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);await t(n.root);let{runExtensionBuildCommand:r}=await import(`#cli/commands/extension-build.js`);await r(e,n.root)}),registerRegistryCommands({program:a,logger:e,applicationContext:n}),a.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(`--agents <names>`,`Create an agents/ workspace with comma-separated agent names`,parseAgentNamesOption).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`-n, --non-interactive`,`Scaffold the agent without starting development`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:a}=await import(`#cli/commands/init.js`);await a(e,n.root,t,{agents:i.agents,channelWebNextjs:i.channelWebNextjs,model:i.model,reasoning:i.reasoning,nonInteractive:i.nonInteractive},void 0,e=>{r.trackSetupStep({flow:`init`,step:e})},(e,t,n)=>{r.trackSetupTerminal({flow:`init`,step:e,result:t,failureCode:n})})});let c=a.command(`set`).description(`Change root agent model settings.`);agentCommand(c.command(`model [model]`),n).description(`Set the agent model and reasoning effort.`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).action(async(t,r)=>{let{runSetCommand:i}=await import(`#cli/commands/set.js`);await i(e,n.root,{model:t,reasoning:r.reasoning})}),registerProjectCommands({program:a,logger:e,applicationContext:n}),registerBuildCommand({applicationContext:n,buildHost:t.buildHost,logger:e,program:a}),agentCommand(a.command(`start`),n).description(`Start a built eve application.`).option(`--no-schedules`,`Start without running authored cron schedules`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async r=>{let{loadDevelopmentEnvironmentFiles:i}=await import(`#cli/dev/environment.js`);await i(n.root);let a=await(t.startProductionHost??await loadStartProductionHost())(n.root,{host:r.host,port:r.port,schedules:r.schedules});e.log(renderCliTaggedLine(o,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),(r.schedules===!1||areSchedulesDisabled())&&e.log(renderCliTaggedLine(o,{message:`schedules disabled`,tag:`start`,tone:`info`})),await waitForShutdownSignal({close:()=>a.close(),wait:()=>a.wait()})});let l=a.command(`remote`).description(`Connect to an existing eve agent.`);registerRemoteCommands({applicationContext:n,logger:e,program:l,runtime:t,telemetry:r}),registerRuntimeInvokeCommand({applicationContext:n,logger:e,program:l,runtime:t}),registerAcpCommand({applicationContext:n,eveVersion:i,program:a,resolveVerifiedRemoteDevelopmentClient:t.resolveVerifiedRemoteDevelopmentClient,runAcpServer:t.runAcpServer,startHost:t.startHost}),registerDevelopmentCommand({applicationContext:n,logger:e,program:a,runtime:t,telemetry:r});let u=a.command(`logs`).description("Inspect local `eve dev` diagnostic logs (.eve/logs).");agentCommand(u.command(`show [logid]`,{isDefault:!0}),n).description(`Print a diagnostic log (the most recent when logid is omitted).`).option(`--dump`,`Prepend the log's environment dump (.dump sibling)`).option(`--events`,`Interleave session events from the local workflow store`).action(async(t,r)=>{let{runLogsShowCommand:i}=await import(`#cli/commands/logs.js`);await i(e,n.root,t,r)}),agentCommand(u.command(`list`).alias(`ls`),n).description(`List diagnostic logs, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runLogsListCommand:r}=await import(`#cli/commands/logs.js`);await r(e,n.root,t)});let d=a.command(`traces`).usage(`[options] [trace]
2
- eve traces list [options]`).description("Inspect local `eve dev` traces.");return agentCommand(d.command(`show [trace]`,{isDefault:!0}),n).description(`Show a local trace (the most recent when trace is omitted).`).option(`--verbose`,`Expand every span with all attributes and events`).option(`--json`,`Output as JSON`).action(async(t,r)=>{let{runTraceShowCommand:i}=await import(`#cli/commands/trace.js`);await i(e,n.root,t,r)}),agentCommand(d.command(`list`).alias(`ls`),n).description(`List local traces, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runTraceListCommand:r}=await import(`#cli/commands/trace.js`);await r(e,n.root,t)}),agentCommand(a.command(`info`),n).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async r=>{await(t.printApplicationInfo??await loadPrintApplicationInfo())(e,n.root,r)}),agentCommand(a.command(`eval`),n,e=>e.opts().url===void 0).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(`--exclude-tag <tag...>`,`Skip 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 logs and workflow run IDs to stdout`).action(async(r,i)=>{await(t.runEvalCommand??await loadRunEvalCommand())(r,i,e,n.root)}),a}async function runCli(e=process.argv.slice(2),t=console,n={}){let r={root:resolveApplicationRoot(),async resolve(){let e=await(n.resolveApplicationProject??resolveCliApplicationProject)(r.root);r.project=e,r.root=e.appRoot},async resolveAgent(){return resolveEveProjectContext(r.root)}},i=createEveCliTelemetry(resolveInstalledPackageInfo().version),a=createCliProgram(t,n,r,i),o=e;if(o.length===0){let e=await(n.findApplicationRoot??findCliApplicationRoot)(r.root);e===void 0?o=(await findEveProjectContext(r.root))?.kind===`workspace`?[`dev`]:[`init`]:(r.root=e,o=[`dev`])}let s=canonicalCommand(o);i.trackCommand(s),s!==`telemetry`&&await i.notify(t);try{await a.parseAsync(o,{from:`user`}),i.trackOutcome(`success`)}catch(e){if(e instanceof CommanderError&&e.exitCode===0){i.trackOutcome(`success`);return}if(i.trackOutcome(e instanceof CommanderError?`usage_error`:`error`),e instanceof CommanderError){let r=await(n.isCodingAgentLaunch??isCodingAgentLaunch)();if(o[0]===`init`&&r){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}finally{await i.flush()}}export{createCliProgram,resolveDevUiMode,resolveTuiDisplayOptions,runCli};
2
+ eve traces list [options]`).description("Inspect local `eve dev` traces.");return agentCommand(d.command(`show [trace]`,{isDefault:!0}),n).description(`Show a local trace (the most recent when trace is omitted).`).option(`--verbose`,`Expand every span with all attributes and events`).option(`--json`,`Output as JSON`).action(async(t,r)=>{let{runTraceShowCommand:i}=await import(`#cli/commands/trace.js`);await i(e,n.root,t,r)}),agentCommand(d.command(`list`).alias(`ls`),n).description(`List local traces, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runTraceListCommand:r}=await import(`#cli/commands/trace.js`);await r(e,n.root,t)}),agentCommand(a.command(`info`),n).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async r=>{await(t.printApplicationInfo??await loadPrintApplicationInfo())(e,n.root,r)}),agentCommand(a.command(`eval`),n,e=>e.opts().url===void 0).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(`--exclude-tag <tag...>`,`Skip 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(`--repeat <n>`,`Run every eval n times to measure repeatability`).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(`--keep-state`,`Keep the local eval server's state, including its Workflow data, after the run`).option(`--verbose`,`Stream per-eval logs and workflow run IDs to stdout`).action(async(r,i)=>{await(t.runEvalCommand??await loadRunEvalCommand())(r,i,e,n.root)}),a}async function runCli(e=process.argv.slice(2),t=console,n={}){let r={root:resolveApplicationRoot(),async resolve(){let e=await(n.resolveApplicationProject??resolveCliApplicationProject)(r.root);r.project=e,r.root=e.appRoot},async resolveAgent(){return resolveEveProjectContext(r.root)}},i=createEveCliTelemetry(resolveInstalledPackageInfo().version),a=createCliProgram(t,n,r,i),o=e;if(o.length===0){let e=await(n.findApplicationRoot??findCliApplicationRoot)(r.root);e===void 0?o=(await findEveProjectContext(r.root))?.kind===`workspace`?[`dev`]:[`init`]:(r.root=e,o=[`dev`])}let s=canonicalCommand(o);i.trackCommand(s),s!==`telemetry`&&await i.notify(t);try{await a.parseAsync(o,{from:`user`}),i.trackOutcome(`success`)}catch(e){if(e instanceof CommanderError&&e.exitCode===0){i.trackOutcome(`success`);return}if(i.trackOutcome(e instanceof CommanderError?`usage_error`:`error`),e instanceof CommanderError){let r=await(n.isCodingAgentLaunch??isCodingAgentLaunch)();if(o[0]===`init`&&r){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}finally{await i.flush()}}export{createCliProgram,resolveDevUiMode,resolveTuiDisplayOptions,runCli};
@@ -1,5 +1,18 @@
1
1
  import { type MessageStreamEvent } from "#protocol/message.js";
2
2
  import type { CancelSessionResult, MessageResult } from "#client/types.js";
3
+ /**
4
+ * @internal What the server accepted for a message or answer, and when the
5
+ * client sent it, in epoch milliseconds on the client's clock.
6
+ */
7
+ export interface ClientSendReceipt {
8
+ readonly deliveryId?: string;
9
+ /** The first attempt was issued. */
10
+ readonly startedAt: number;
11
+ /** Retrying `409 session_not_ready` before the accepted attempt was issued. */
12
+ readonly notReadyMs: number;
13
+ /** The accepted response arrived. */
14
+ readonly acceptedAt: number;
15
+ }
3
16
  /**
4
17
  * Internal configuration passed to construct a {@link MessageResponse}.
5
18
  */
@@ -10,9 +23,11 @@ interface MessageResponseInput {
10
23
  /** Answers resume a turn that started before their stream, so its `input.resolved` names it. */
11
24
  readonly resumesTurn?: boolean;
12
25
  readonly sessionId: string;
26
+ readonly receipt?: ClientSendReceipt;
13
27
  }
14
28
  declare const consumeResponse: unique symbol;
15
29
  declare const acceptedDeliveryId: unique symbol;
30
+ declare const sendReceipt: unique symbol;
16
31
  /**
17
32
  * The response from {@link ClientSession.send}.
18
33
  *
@@ -27,6 +42,7 @@ export declare class MessageResponse<TOutput = unknown> implements AsyncIterable
27
42
  */
28
43
  readonly sessionId: string;
29
44
  readonly [acceptedDeliveryId]: string | undefined;
45
+ readonly [sendReceipt]: ClientSendReceipt | undefined;
30
46
  /** @internal */
31
47
  constructor(input: MessageResponseInput);
32
48
  /**
@@ -51,6 +67,8 @@ export declare class MessageResponse<TOutput = unknown> implements AsyncIterable
51
67
  }
52
68
  /** @internal Returns the accepted message identity without consuming its response stream. */
53
69
  export declare function getMessageResponseDeliveryId(response: MessageResponse): string | undefined;
70
+ /** @internal Returns what the server accepted for the response's request, and when. */
71
+ export declare function getMessageResponseReceipt(response: MessageResponse): ClientSendReceipt | undefined;
54
72
  /** @internal Observe a turn through the frontend's existing session stream. */
55
73
  export declare function consumeMessageResponse(response: MessageResponse, source: AsyncIterable<MessageStreamEvent>): AsyncIterable<MessageStreamEvent>;
56
74
  export {};
@@ -1 +1 @@
1
- import{summarizeTurnEvents}from"#client/session-utils.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{extractCompletedResult}from"#client/output-schema.js";const consumeResponse=Symbol(`consumeMessageResponse`),acceptedDeliveryId=Symbol(`acceptedDeliveryId`);var MessageResponse=class{sessionId;[acceptedDeliveryId];#e;#t;#n=!1;#r;#i;#a=!1;#o=Promise.withResolvers();constructor(e){this.#e=e.cancelTurn,this.sessionId=e.sessionId,this[acceptedDeliveryId]=e.deliveryId,this.#r=e.createStream,this.#i=e.resumesTurn??!1}cancel(){if(this.#a)return Promise.resolve({status:`no_active_turn`});if(this.#t!==void 0)return this.#t;let e=this.#o.promise.then(e=>e===void 0?{status:`no_active_turn`}:this.#e(e));return this.#t=e,e.catch(()=>{!this.#a&&this.#t===e&&(this.#t=void 0)}),e}async result(){let e=[];for await(let t of this)e.push(t);let t=summarizeTurnEvents(e);return{data:extractCompletedResult(e),events:e,inputRequests:t.inputRequests,message:t.message,sessionId:this.sessionId,status:t.status}}[Symbol.asyncIterator](){return this[consumeResponse]()}[consumeResponse](e){if(this.#n)throw Error(`MessageResponse has already been consumed.`);return this.#n=!0,this.#s(e)}async*#s(e){try{for await(let t of this.#r(e))t.type===`turn.started`||this.#i&&t.type===`input.resolved`?this.#o.resolve(t.data.turnId):isCurrentTurnBoundaryEvent(t)&&(this.#a=!0,this.#o.resolve(void 0)),yield t}finally{this.#o.resolve(void 0)}}};function getMessageResponseDeliveryId(e){return e[acceptedDeliveryId]}function consumeMessageResponse(e,t){return e[consumeResponse](t)}export{MessageResponse,consumeMessageResponse,getMessageResponseDeliveryId};
1
+ import{summarizeTurnEvents}from"#client/session-utils.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{extractCompletedResult}from"#client/output-schema.js";const consumeResponse=Symbol(`consumeMessageResponse`),acceptedDeliveryId=Symbol(`acceptedDeliveryId`),sendReceipt=Symbol(`sendReceipt`);var MessageResponse=class{sessionId;[acceptedDeliveryId];[sendReceipt];#e;#t;#n=!1;#r;#i;#a=!1;#o=Promise.withResolvers();constructor(e){this.#e=e.cancelTurn,this.sessionId=e.sessionId,this[acceptedDeliveryId]=e.deliveryId,this[sendReceipt]=e.receipt,this.#r=e.createStream,this.#i=e.resumesTurn??!1}cancel(){if(this.#a)return Promise.resolve({status:`no_active_turn`});if(this.#t!==void 0)return this.#t;let e=this.#o.promise.then(e=>e===void 0?{status:`no_active_turn`}:this.#e(e));return this.#t=e,e.catch(()=>{!this.#a&&this.#t===e&&(this.#t=void 0)}),e}async result(){let e=[];for await(let t of this)e.push(t);let t=summarizeTurnEvents(e);return{data:extractCompletedResult(e),events:e,inputRequests:t.inputRequests,message:t.message,sessionId:this.sessionId,status:t.status}}[Symbol.asyncIterator](){return this[consumeResponse]()}[consumeResponse](e){if(this.#n)throw Error(`MessageResponse has already been consumed.`);return this.#n=!0,this.#s(e)}async*#s(e){try{for await(let t of this.#r(e))t.type===`turn.started`||this.#i&&t.type===`input.resolved`?this.#o.resolve(t.data.turnId):isCurrentTurnBoundaryEvent(t)&&(this.#a=!0,this.#o.resolve(void 0)),yield t}finally{this.#o.resolve(void 0)}}};function getMessageResponseDeliveryId(e){return e[acceptedDeliveryId]}function getMessageResponseReceipt(e){return e[sendReceipt]}function consumeMessageResponse(e,t){return e[consumeResponse](t)}export{MessageResponse,consumeMessageResponse,getMessageResponseDeliveryId,getMessageResponseReceipt};
@@ -1 +1 @@
1
- import{EVE_SESSION_ROUTE_PATH,createEveSessionRoutePath,createEveSessionStreamRoutePath}from"#protocol/routes.js";import{ClientError,createClientError}from"#client/client-error.js";import{TurnSegment}from"#client/session-utils.js";import{EVE_SESSION_ID_HEADER}from"#protocol/message.js";import{followStreamIterable,sleep}from"#client/open-stream.js";import{createClientUrl}from"#client/url.js";import{throwIfAborted}from"#client/abort-signal.js";import{MessageResponse}from"#client/message-response.js";import{ClientAgentSession}from"#client/agent-session.js";import{cancelClientSession,clearClientSession,compactClientSession,prewarmClientSession,resetClientSession}from"#client/session-controls.js";import{serializeOutputSchema}from"#tools/schema.js";const followSession=Symbol(`followClientSession`);var ClientSession=class ClientSession{#e;#t;constructor(e,t){this.#e=e,this.#t=t}static async create(e,t){let n=await postTurn(e,EVE_SESSION_ROUTE_PATH,t,!0,t.stubs),{sessionId:r}=await readAcceptedMessage(n),i=new ClientSession(e,{sessionId:r,streamIndex:0});return{response:i.#r(n,t,0),session:i}}static async prewarm(e,t={}){let{sessionId:n}=await readAcceptedMessage(await postCreateSession(e,t));return new ClientSession(e,{sessionId:n,streamIndex:0})}get state(){return this.#t}async snapshot(e){throwIfAborted(e?.signal);let t=[];for await(let n of this.#s({follow:!1,signal:e?.signal,startIndex:0}))t.push(n);return throwIfAborted(e?.signal),{events:t,session:{sessionId:this.#t.sessionId,streamIndex:t.length}}}async send(e,t={}){return await this.#n({...t,message:e},!0)}async respond(e,t={}){if(e.length===0)throw Error(`ClientSession.respond() requires at least one input response.`);return await this.#n({...t,inputResponses:e},!1)}async#n(e,t){let n=this.#t.streamIndex,r=createEveSessionRoutePath(this.#t.sessionId),i=t?await postSessionSend(this.#e,r,e):await postTurn(this.#e,r,e,!1),{sessionId:a,deliveryId:o}=await readAcceptedMessage(i,this.#t.sessionId);if(a!==this.#t.sessionId)throw Error(`Message route returned a different session id.`);if(e.message!==void 0&&o===void 0)throw Error(`Message route did not return a delivery id. Update the server before sending with this client.`);return this.#r(i,e,n,e.message===void 0?void 0:o)}async prewarm(e){return await prewarmClientSession({context:this.#e,sessionId:this.#t.sessionId,signal:e?.signal})}async cancel(e){return await cancelClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}async clear(){return await clearClientSession({context:this.#e,sessionId:this.#t.sessionId})}async compact(){return await compactClientSession({context:this.#e,sessionId:this.#t.sessionId})}async reset(e){return await resetClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}stream(e){if(e?.follow===!1&&(e.startIndex??this.#t.streamIndex)<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);return this.#a(e)}agent(e){return new ClientAgentSession(this.#e,e)}[followSession](e){return this.#a({...e,keepAlive:!0})}#r(e,t,n,r){return e.body?.cancel().catch(()=>{}),new MessageResponse({cancelTurn:async e=>await this.cancel({turnId:e}),createStream:e=>this.#i(n,t,r,e),deliveryId:r,resumesTurn:t.inputResponses!==void 0,sessionId:this.#t.sessionId})}async*#i(e,t,n,r){let i=0,a=n===void 0,o=!1,s=new TurnSegment({followCallbacks:!0});try{for await(let c of r??this.#s({headers:t.headers,keepAlive:!0,signal:t.signal,startIndex:e,streamReconnectPolicy:t.streamReconnectPolicy})){if(i+=1,n!==void 0){let e=c.meta?.deliveryIds?.includes(n)===!0,t=c.type===`session.failed`||c.type===`session.completed`;if(!e&&t&&(!a||c.type===`session.completed`))throw Error(`The session ended before the accepted message reached its turn boundary.`);if(!a&&!e)continue;let r=c.meta?.deliveryIds!==void 0;if(!t&&r&&!e)continue;a=!0}if(o=s.observe(c),yield c,o)break}if(n!==void 0&&!o&&!t.signal?.aborted)throw Error(`The response stream ended before the accepted message reached its turn boundary.`)}finally{this.#o(e+i)}}async*#a(e){let t=e?.startIndex??this.#t.streamIndex,n=0;for await(let r of this.#s({follow:e?.follow,headers:e?.headers,keepAlive:e?.keepAlive,onCaughtUp:e?.onCaughtUp,resolveHeaders:e?.resolveHeaders,resolveReconnectPolicy:e?.resolveReconnectPolicy,signal:e?.signal,startIndex:t,streamReconnectPolicy:e?.streamReconnectPolicy}))n+=1,t>=0&&this.#o(t+n),yield r}#o(e){this.#t={sessionId:this.#t.sessionId,streamIndex:Math.max(this.#t.streamIndex,e)}}#s(e){return followStreamIterable({onCaughtUp:e.onCaughtUp,follow:e.follow,host:this.#e.host,keepAlive:e.keepAlive,resolveHeaders:()=>this.#e.resolveHeaders(e.resolveHeaders?.()??e.headers),path:createEveSessionStreamRoutePath(this.#t.sessionId),redirect:this.#e.redirect,signal:e.signal,startIndex:e.startIndex,streamReconnectPolicy:e.streamReconnectPolicy,resolveReconnectPolicy:e.resolveReconnectPolicy})}};function followClientSession(e,t){return e[followSession](t)}async function postSessionSend(e,t,n){let r=Date.now()+2e4,i=250;for(;;){try{return await postTurn(e,t,n,!1)}catch(e){if(!isSessionNotReady(e))throw e;let t=r-Date.now();if(t<=0)throw e;await sleep(Math.min(i,t),n.signal)}throwIfAborted(n.signal),i=Math.min(i*2,2e3)}}async function postCreateSession(e,t){let n=await e.resolveHeaders(t.headers),r=t.stubs===void 0?void 0:JSON.stringify({stubs:t.stubs});r!==void 0&&n.set(`content-type`,`application/json`);let i=await fetch(createClientUrl(e.host,EVE_SESSION_ROUTE_PATH),{body:r,headers:n,method:`POST`,redirect:e.redirect,signal:t.signal??null});if(!i.ok){let e=await i.text();throw new ClientError(i.status,e,i.headers)}return i}function isSessionNotReady(e){return e instanceof ClientError&&e.status===409&&e.code===`session_not_ready`}async function postTurn(e,t,n,r,i){let a=createMessageBody(n,r);if(a===null)throw Error(r?`Creating a session requires a non-empty message.`:`A session turn requires a non-empty message or inputResponses.`);i!==void 0&&(a.stubs=i);let o=await e.resolveHeaders(n.headers);o.set(`content-type`,`application/json`);let s=await fetch(createClientUrl(e.host,t),{body:JSON.stringify(a),headers:o,method:`POST`,redirect:e.redirect,signal:n.signal??null});if(!s.ok){let e=await s.text();throw createClientError(s.status,e,s.headers)}return s}async function readAcceptedMessage(e,t){let n=await e.json(),r=(typeof n.sessionId==`string`?n.sessionId:void 0)??e.headers.get(EVE_SESSION_ID_HEADER)?.trim()??t;if(!r)throw Error(`Message route did not return a session id.`);return{sessionId:r,deliveryId:typeof n.deliveryId==`string`&&n.deliveryId.length>0?n.deliveryId:void 0}}function createMessageBody(e,t){let n={};e.message!==void 0&&(n.message=e.message),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses),!t&&e.message!==void 0&&e.turnPolicy!==void 0&&(n.turnPolicy=e.turnPolicy),e.clientContext!==void 0&&(n.clientContext=e.clientContext);let r=serializeOutputSchema(e.outputSchema);return r!==void 0&&(n.outputSchema=r),t&&n.message===void 0||n.message===void 0&&n.inputResponses===void 0?null:n}export{ClientSession,followClientSession};
1
+ import{EVE_SESSION_ROUTE_PATH,createEveSessionRoutePath,createEveSessionStreamRoutePath}from"#protocol/routes.js";import{ClientError,createClientError}from"#client/client-error.js";import{TurnSegment}from"#client/session-utils.js";import{EVE_SESSION_ID_HEADER}from"#protocol/message.js";import{followStreamIterable,sleep}from"#client/open-stream.js";import{createClientUrl}from"#client/url.js";import{throwIfAborted}from"#client/abort-signal.js";import{MessageResponse}from"#client/message-response.js";import{ClientAgentSession}from"#client/agent-session.js";import{cancelClientSession,clearClientSession,compactClientSession,prewarmClientSession,resetClientSession}from"#client/session-controls.js";import{serializeOutputSchema}from"#tools/schema.js";const followSession=Symbol(`followClientSession`);var ClientSession=class ClientSession{#e;#t;constructor(e,t){this.#e=e,this.#t=t}static async create(e,t){let n=Date.now(),r=await postTurn(e,EVE_SESSION_ROUTE_PATH,t,!0,t.stubs),i=Date.now(),{sessionId:a,deliveryId:o}=await readAcceptedMessage(r),s=new ClientSession(e,{sessionId:a,streamIndex:0}),c={deliveryId:o,startedAt:n,notReadyMs:0,acceptedAt:i};return{response:s.#r(r,t,0,void 0,c),session:s}}static async prewarm(e,t={}){let{sessionId:n}=await readAcceptedMessage(await postCreateSession(e,t));return new ClientSession(e,{sessionId:n,streamIndex:0})}get state(){return this.#t}async snapshot(e){throwIfAborted(e?.signal);let t=[];for await(let n of this.#s({follow:!1,signal:e?.signal,startIndex:0}))t.push(n);return throwIfAborted(e?.signal),{events:t,session:{sessionId:this.#t.sessionId,streamIndex:t.length}}}async send(e,t={}){return await this.#n({...t,message:e},!0)}async respond(e,t={}){if(e.length===0)throw Error(`ClientSession.respond() requires at least one input response.`);return await this.#n({...t,inputResponses:e},!1)}async#n(e,t){let n=this.#t.streamIndex,r=createEveSessionRoutePath(this.#t.sessionId),{response:i,timing:a}=await postSessionSend(this.#e,r,e,t),{sessionId:o,deliveryId:s}=await readAcceptedMessage(i,this.#t.sessionId);if(o!==this.#t.sessionId)throw Error(`Message route returned a different session id.`);if(e.message!==void 0&&s===void 0)throw Error(`Message route did not return a delivery id. Update the server before sending with this client.`);return this.#r(i,e,n,e.message===void 0?void 0:s,{...a,deliveryId:s})}async prewarm(e){return await prewarmClientSession({context:this.#e,sessionId:this.#t.sessionId,signal:e?.signal})}async cancel(e){return await cancelClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}async clear(){return await clearClientSession({context:this.#e,sessionId:this.#t.sessionId})}async compact(){return await compactClientSession({context:this.#e,sessionId:this.#t.sessionId})}async reset(e){return await resetClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}stream(e){if(e?.follow===!1&&(e.startIndex??this.#t.streamIndex)<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);return this.#a(e)}agent(e){return new ClientAgentSession(this.#e,e)}[followSession](e){return this.#a({...e,keepAlive:!0})}#r(e,t,n,r,i){return e.body?.cancel().catch(()=>{}),new MessageResponse({cancelTurn:async e=>await this.cancel({turnId:e}),createStream:e=>this.#i(n,t,r,e),deliveryId:r,receipt:i,resumesTurn:t.inputResponses!==void 0,sessionId:this.#t.sessionId})}async*#i(e,t,n,r){let i=0,a=n===void 0,o=!1,s=new TurnSegment({followCallbacks:!0});try{for await(let c of r??this.#s({headers:t.headers,keepAlive:!0,signal:t.signal,startIndex:e,streamReconnectPolicy:t.streamReconnectPolicy})){if(i+=1,n!==void 0){let e=c.meta?.deliveryIds?.includes(n)===!0,t=c.type===`session.failed`||c.type===`session.completed`;if(!e&&t&&(!a||c.type===`session.completed`))throw Error(`The session ended before the accepted message reached its turn boundary.`);if(!a&&!e)continue;let r=c.meta?.deliveryIds!==void 0;if(!t&&r&&!e)continue;a=!0}if(o=s.observe(c),yield c,o)break}if(n!==void 0&&!o&&!t.signal?.aborted)throw Error(`The response stream ended before the accepted message reached its turn boundary.`)}finally{this.#o(e+i)}}async*#a(e){let t=e?.startIndex??this.#t.streamIndex,n=0;for await(let r of this.#s({follow:e?.follow,headers:e?.headers,keepAlive:e?.keepAlive,onCaughtUp:e?.onCaughtUp,resolveHeaders:e?.resolveHeaders,resolveReconnectPolicy:e?.resolveReconnectPolicy,signal:e?.signal,startIndex:t,streamReconnectPolicy:e?.streamReconnectPolicy}))n+=1,t>=0&&this.#o(t+n),yield r}#o(e){this.#t={sessionId:this.#t.sessionId,streamIndex:Math.max(this.#t.streamIndex,e)}}#s(e){return followStreamIterable({onCaughtUp:e.onCaughtUp,follow:e.follow,host:this.#e.host,keepAlive:e.keepAlive,resolveHeaders:()=>this.#e.resolveHeaders(e.resolveHeaders?.()??e.headers),path:createEveSessionStreamRoutePath(this.#t.sessionId),redirect:this.#e.redirect,signal:e.signal,startIndex:e.startIndex,streamReconnectPolicy:e.streamReconnectPolicy,resolveReconnectPolicy:e.resolveReconnectPolicy})}};function followClientSession(e,t){return e[followSession](t)}async function postSessionSend(e,t,n,r){let i=Date.now(),a=i+2e4,o=250;for(;;){let s=Date.now();try{return{response:await postTurn(e,t,n,!1),timing:{startedAt:i,notReadyMs:s-i,acceptedAt:Date.now()}}}catch(e){if(!r||!isSessionNotReady(e))throw e;let t=a-Date.now();if(t<=0)throw e;await sleep(Math.min(o,t),n.signal)}throwIfAborted(n.signal),o=Math.min(o*2,2e3)}}async function postCreateSession(e,t){let n=await e.resolveHeaders(t.headers),r=t.stubs===void 0?void 0:JSON.stringify({stubs:t.stubs});r!==void 0&&n.set(`content-type`,`application/json`);let i=await fetch(createClientUrl(e.host,EVE_SESSION_ROUTE_PATH),{body:r,headers:n,method:`POST`,redirect:e.redirect,signal:t.signal??null});if(!i.ok){let e=await i.text();throw new ClientError(i.status,e,i.headers)}return i}function isSessionNotReady(e){return e instanceof ClientError&&e.status===409&&e.code===`session_not_ready`}async function postTurn(e,t,n,r,i){let a=createMessageBody(n,r);if(a===null)throw Error(r?`Creating a session requires a non-empty message.`:`A session turn requires a non-empty message or inputResponses.`);i!==void 0&&(a.stubs=i);let o=await e.resolveHeaders(n.headers);o.set(`content-type`,`application/json`);let s=await fetch(createClientUrl(e.host,t),{body:JSON.stringify(a),headers:o,method:`POST`,redirect:e.redirect,signal:n.signal??null});if(!s.ok){let e=await s.text();throw createClientError(s.status,e,s.headers)}return s}async function readAcceptedMessage(e,t){let n=await e.json(),r=(typeof n.sessionId==`string`?n.sessionId:void 0)??e.headers.get(EVE_SESSION_ID_HEADER)?.trim()??t;if(!r)throw Error(`Message route did not return a session id.`);return{sessionId:r,deliveryId:typeof n.deliveryId==`string`&&n.deliveryId.length>0?n.deliveryId:void 0}}function createMessageBody(e,t){let n={};e.message!==void 0&&(n.message=e.message),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses),!t&&e.message!==void 0&&e.turnPolicy!==void 0&&(n.turnPolicy=e.turnPolicy),e.clientContext!==void 0&&(n.clientContext=e.clientContext);let r=serializeOutputSchema(e.outputSchema);return r!==void 0&&(n.outputSchema=r),t&&n.message===void 0||n.message===void 0&&n.inputResponses===void 0?null:n}export{ClientSession,followClientSession};
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "moduleFingerprints": {
3
- "@eve/catalog": "c1311c1420a1d2c475448db7956763f0eafbda990efe6c050d39fa9ee8b68a58",
3
+ "@eve/catalog": "29b7529f6044427c750e4c27fe91da792014c60c660db31b7ca1fff0afe7f603",
4
4
  "just-secrets": "1ce67d437d0bb06df02e4e99180a3c5f5edf0010314010226e97b96d462bba5d",
5
5
  "@vercel/agent-runs": "94231f05d03adf6e62c1c56a941d763e7ed8a25a7c2f3c17a920f68225319325",
6
6
  "@workflow/world-local": "a10e78551f65fc607cf75261a569d852c40bc9cfac13a7fb6e15c88bf1ccf429"
@@ -61,7 +61,7 @@
61
61
  "zod": "4.5.4",
62
62
  "zod-validation-error": "5.0.0"
63
63
  },
64
- "scriptHash": "e2d7091001b88f60679e1c4e5f30a7bf18dc36281ca6edcc8a77a41dfd4614d7",
64
+ "scriptHash": "b350dbbe6a6621651989fdd64f1028d7339f90c15bb60f8fa0afc90e97d33db3",
65
65
  "toolVersions": {
66
66
  "rolldown": "1.2.9",
67
67
  "typescript": "7.0.2"