ai 7.0.134 → 7.0.136

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 (39) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/index.d.ts +234 -7
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +616 -57
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +6 -2
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +1 -1
  9. package/docs/03-agents/04-loop-control.mdx +2 -0
  10. package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +2 -2
  11. package/docs/03-ai-sdk-core/17-mcp-events.mdx +6 -2
  12. package/docs/03-ai-sdk-core/25-settings.mdx +4 -2
  13. package/docs/03-ai-sdk-core/30-embeddings.mdx +27 -0
  14. package/docs/03-ai-sdk-core/32-decisions.mdx +3 -2
  15. package/docs/04-ai-sdk-ui/21-transport.mdx +73 -0
  16. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +2 -2
  17. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +2 -2
  18. package/docs/07-reference/01-ai-sdk-core/05-embed.mdx +14 -0
  19. package/docs/07-reference/01-ai-sdk-core/06-embed-many.mdx +14 -0
  20. package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +5 -5
  21. package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +2 -2
  22. package/docs/07-reference/01-ai-sdk-core/24-mcp-events.mdx +123 -5
  23. package/docs/07-reference/02-ai-sdk-ui/51-websocket-chat-transport.mdx +393 -0
  24. package/docs/07-reference/02-ai-sdk-ui/index.mdx +6 -0
  25. package/package.json +12 -12
  26. package/src/agent/default-stop-condition.ts +33 -0
  27. package/src/agent/tool-loop-agent.ts +2 -2
  28. package/src/embed/embed-events.ts +6 -0
  29. package/src/embed/embed-many.ts +18 -0
  30. package/src/embed/embed.ts +16 -0
  31. package/src/embed/validate-embedding-dimensions.ts +14 -0
  32. package/src/generate-text/stream-text.ts +31 -24
  33. package/src/prompt/request-options.ts +2 -2
  34. package/src/ui/chat-transport.ts +16 -0
  35. package/src/ui/chat.ts +123 -34
  36. package/src/ui/index.ts +13 -0
  37. package/src/ui/process-ui-message-stream.ts +6 -2
  38. package/src/ui/websocket-chat-transport.ts +987 -0
  39. package/src/util/serial-job-executor.ts +22 -5
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { GatewayAuthenticationError, GatewayError, createGateway, gateway, gateway as gateway$1 } from "@ai-sdk/gateway";
3
- import { DEFAULT_MAX_DOWNLOAD_SIZE, DelayedPromise, DownloadError, DownloadError as DownloadError$1, EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL, EXPERIMENTAL_EMBEDDING_MODEL_PROVIDER_OPTIONS_TRANSFORMER, asArray, asSchema, asSchema as asSchema$1, cancelResponseBody, convertBase64ToUint8Array, convertUint8ArrayToBase64, createIdGenerator, createIdGenerator as createIdGenerator$1, delay, detectMediaType, dynamicTool, executeTool, experimental_getToolCaller, experimental_toolCaller, fetchUntrustedUrl, filterNullable, generateId, generateId as generateId$1, getErrorMessage, getRuntimeEnvironmentUserAgent, isAbortError, isBuffer, isExecutableTool, isFullMediaType, isNonNullable, isProviderReference, isProviderStreamError, isUrlSupported, jsonSchema, jsonSchema as jsonSchema$1, lazySchema, normalizeHeaders, parseJsonEventStream, parseJsonEventStream as parseJsonEventStream$1, readResponseWithSizeLimit, resolve, retryWithExponentialBackoff, safeParseJSON, safeValidateTypes, tool, tool as tool$1, validateTypes, withUserAgentSuffix, zodSchema, zodSchema as zodSchema$1 } from "@ai-sdk/provider-utils";
3
+ import { DEFAULT_MAX_DOWNLOAD_SIZE, DelayedPromise, DownloadError, DownloadError as DownloadError$1, EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL, EXPERIMENTAL_EMBEDDING_MODEL_PROVIDER_OPTIONS_TRANSFORMER, asArray, asSchema, asSchema as asSchema$1, cancelResponseBody, convertBase64ToUint8Array, convertUint8ArrayToBase64, createIdGenerator, createIdGenerator as createIdGenerator$1, delay, detectMediaType, dynamicTool, executeTool, experimental_getToolCaller, experimental_toolCaller, fetchUntrustedUrl, filterNullable, generateId, generateId as generateId$1, getErrorMessage, getRuntimeEnvironmentUserAgent, getWebSocketConstructor, isAbortError, isBuffer, isExecutableTool, isFullMediaType, isNonNullable, isProviderReference, isProviderStreamError, isUrlSupported, jsonSchema, jsonSchema as jsonSchema$1, lazySchema, normalizeHeaders, parseJsonEventStream, parseJsonEventStream as parseJsonEventStream$1, readResponseWithSizeLimit, readWebSocketMessageText, resolve, retryWithExponentialBackoff, safeParseJSON, safeValidateTypes, toWebSocketUrl, tool, tool as tool$1, validateTypes, waitForWebSocketBufferDrain, withUserAgentSuffix, zodSchema, zodSchema as zodSchema$1 } from "@ai-sdk/provider-utils";
4
4
  import { AISDKError, AISDKError as AISDKError$1, APICallError, APICallError as APICallError$1, EmptyResponseBodyError, EmptyResponseBodyError as EmptyResponseBodyError$1, Experimental_DecisionRefusalError, Experimental_DecisionRefusalError as Experimental_DecisionRefusalError$1, Experimental_DecisionUnsupportedQuestionTypeError, Experimental_DecisionUnsupportedQuestionTypeError as Experimental_DecisionUnsupportedQuestionTypeError$1, InvalidArgumentError as InvalidArgumentError$1, InvalidPromptError, InvalidPromptError as InvalidPromptError$1, InvalidResponseDataError, InvalidResponseDataError as InvalidResponseDataError$1, JSONParseError, JSONParseError as JSONParseError$1, LoadAPIKeyError, LoadSettingError, NoContentGeneratedError, NoSuchModelError, NoSuchModelError as NoSuchModelError$1, NoSuchProviderReferenceError, TooManyEmbeddingValuesForCallError, TypeValidationError, TypeValidationError as TypeValidationError$1, UnsupportedFunctionalityError, UnsupportedFunctionalityError as UnsupportedFunctionalityError$1, getErrorMessage as getErrorMessage$1, isJSONArray, isJSONObject } from "@ai-sdk/provider";
5
5
  import { array, boolean, custom, discriminatedUnion, enum as enum$1, instanceof as instanceof$1, lazy, literal, looseObject, never, null as null$1, number, object, record, string, union, unknown } from "zod/v4";
6
6
  //#region src/error/invalid-argument-error.ts
@@ -1174,7 +1174,7 @@ function cloneValue(value) {
1174
1174
  }
1175
1175
  //#endregion
1176
1176
  //#region src/version.ts
1177
- const VERSION = "7.0.134";
1177
+ const VERSION = "7.0.136";
1178
1178
  //#endregion
1179
1179
  //#region src/util/download/download.ts
1180
1180
  /**
@@ -6603,7 +6603,7 @@ function createStreamingUIMessageState({ lastMessage, messageId }) {
6603
6603
  partialToolCalls
6604
6604
  };
6605
6605
  }
6606
- function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas, runUpdateMessageJob, onError, onToolCall, onData, resetStateOnMessageIdChange = false }) {
6606
+ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas, runUpdateMessageJob, onError, onToolCall, onData, resetStateOnMessageIdChange = false, resetStateOnFirstMessageStart = false }) {
6607
6607
  return stream.pipeThrough(new TransformStream({ async transform(chunk, controller) {
6608
6608
  await runUpdateMessageJob(async ({ state, write }) => {
6609
6609
  function getCurrentStepParts() {
@@ -7069,7 +7069,7 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
7069
7069
  break;
7070
7070
  }
7071
7071
  case "start":
7072
- if (resetStateOnMessageIdChange && chunk.messageId != null && chunk.messageId !== state.message.id) Object.assign(state, createStreamingUIMessageState({
7072
+ if (chunk.messageId != null && (resetStateOnFirstMessageStart || resetStateOnMessageIdChange && chunk.messageId !== state.message.id)) Object.assign(state, createStreamingUIMessageState({
7073
7073
  lastMessage: void 0,
7074
7074
  messageId: chunk.messageId
7075
7075
  }), { finishReason: void 0 });
@@ -9511,6 +9511,7 @@ var DefaultStreamTextResult = class {
9511
9511
  let chunkTimeoutId = void 0;
9512
9512
  function resetChunkTimeout() {
9513
9513
  if (chunkTimeoutId != null) clearTimeout(chunkTimeoutId);
9514
+ if (abortSignal?.aborted) return;
9514
9515
  chunkTimeoutId = setAbortTimeout({
9515
9516
  abortController: chunkAbortController,
9516
9517
  label: "Chunk",
@@ -9523,13 +9524,16 @@ var DefaultStreamTextResult = class {
9523
9524
  chunkTimeoutId = void 0;
9524
9525
  }
9525
9526
  }
9527
+ function clearModelOutputTimeouts() {
9528
+ clearFirstChunkTimeout();
9529
+ clearChunkTimeout();
9530
+ }
9526
9531
  function clearStepTimeout() {
9527
9532
  if (stepTimeoutId != null) clearTimeout(stepTimeoutId);
9528
9533
  }
9529
9534
  function clearStepTimeouts() {
9530
9535
  clearStepTimeout();
9531
- clearFirstChunkTimeout();
9532
- clearChunkTimeout();
9536
+ clearModelOutputTimeouts();
9533
9537
  }
9534
9538
  function cleanupStepTimeouts() {
9535
9539
  abortSignal?.removeEventListener("abort", cleanupStepTimeouts);
@@ -9664,7 +9668,6 @@ var DefaultStreamTextResult = class {
9664
9668
  let automaticStreamRetryCount = 0;
9665
9669
  let callbackStreamRetryCount = 0;
9666
9670
  let bufferedAttemptParts = [];
9667
- const outputChunksHandledBeforeBuffering = /* @__PURE__ */ new WeakSet();
9668
9671
  const openTextParts = /* @__PURE__ */ new Set();
9669
9672
  const openReasoningParts = /* @__PURE__ */ new Set();
9670
9673
  let enqueueStreamRetryAttemptBoundary = false;
@@ -9703,28 +9706,36 @@ var DefaultStreamTextResult = class {
9703
9706
  openReasoningParts.clear();
9704
9707
  };
9705
9708
  while (true) {
9706
- const { done, value } = await languageModelStreamReader.read();
9709
+ let result;
9710
+ try {
9711
+ result = await languageModelStreamReader.read();
9712
+ } catch (error) {
9713
+ clearModelOutputTimeouts();
9714
+ throw error;
9715
+ }
9716
+ const { done, value } = result;
9707
9717
  if (enqueueStreamRetryAttemptBoundary) {
9708
9718
  controller.enqueue(createStreamRetryAttemptBoundaryPart({ warnings: !done && value.type === "model-call-start" ? value.warnings : [] }));
9709
9719
  enqueueStreamRetryAttemptBoundary = false;
9710
9720
  }
9711
9721
  if (done) {
9722
+ clearModelOutputTimeouts();
9712
9723
  flushBufferedAttemptParts();
9713
9724
  controller.close();
9714
9725
  return;
9715
9726
  }
9716
9727
  const isToolPart = value.type === "tool-input-start" || value.type === "tool-input-delta" || value.type === "tool-input-end" || value.type === "tool-call" || value.type === "tool-approval-request" || value.type === "tool-approval-response" || value.type === "tool-result" || value.type === "tool-error";
9717
9728
  if (value.type === "model-call-end") {
9729
+ clearModelOutputTimeouts();
9718
9730
  flushBufferedAttemptParts();
9719
9731
  enqueueAttemptPart(value);
9720
9732
  return;
9721
9733
  }
9734
+ if (isOutputChunk(value)) {
9735
+ clearFirstChunkTimeout();
9736
+ resetChunkTimeout();
9737
+ }
9722
9738
  if (shouldBufferToolParts && value.type !== "error" && (isToolPart || bufferedAttemptParts.length > 0)) {
9723
- if (isOutputChunk(value)) {
9724
- clearFirstChunkTimeout();
9725
- resetChunkTimeout();
9726
- outputChunksHandledBeforeBuffering.add(value);
9727
- }
9728
9739
  bufferedAttemptParts.push(value);
9729
9740
  continue;
9730
9741
  }
@@ -9732,6 +9743,7 @@ var DefaultStreamTextResult = class {
9732
9743
  enqueueAttemptPart(value);
9733
9744
  return;
9734
9745
  }
9746
+ clearModelOutputTimeouts();
9735
9747
  await notify({
9736
9748
  event: { chunk: value },
9737
9749
  callbacks: onChunk
@@ -9769,10 +9781,12 @@ var DefaultStreamTextResult = class {
9769
9781
  request = retryLanguageModelCall.request;
9770
9782
  response = retryLanguageModelCall.response;
9771
9783
  languageModelStreamReader = retryLanguageModelCall.stream.getReader();
9784
+ startFirstChunkTimeout();
9772
9785
  enqueueStreamRetryAttemptBoundary = true;
9773
9786
  }
9774
9787
  },
9775
9788
  cancel(reason) {
9789
+ clearModelOutputTimeouts();
9776
9790
  return languageModelStreamReader.cancel(reason);
9777
9791
  }
9778
9792
  });
@@ -9875,12 +9889,7 @@ var DefaultStreamTextResult = class {
9875
9889
  });
9876
9890
  }
9877
9891
  const chunkType = chunk.type;
9878
- if (isOutputChunk(chunk)) {
9879
- const timeoutHandledBeforeBuffering = outputChunksHandledBeforeBuffering.has(chunk);
9880
- if (!hasReceivedOutputChunk && !timeoutHandledBeforeBuffering) clearFirstChunkTimeout();
9881
- hasReceivedOutputChunk = true;
9882
- if (!timeoutHandledBeforeBuffering) resetChunkTimeout();
9883
- }
9892
+ if (isOutputChunk(chunk)) hasReceivedOutputChunk = true;
9884
9893
  switch (chunkType) {
9885
9894
  case "file":
9886
9895
  case "custom":
@@ -10310,6 +10319,27 @@ var DefaultStreamTextResult = class {
10310
10319
  }
10311
10320
  };
10312
10321
  //#endregion
10322
+ //#region src/agent/default-stop-condition.ts
10323
+ /**
10324
+ * Stop conditions are only evaluated when the tool loop can otherwise continue,
10325
+ * so logging here avoids warning when a call finishes naturally at the limit.
10326
+ */
10327
+ function createDefaultStopCondition(stepCount) {
10328
+ return ({ steps }) => {
10329
+ if (steps.length !== stepCount) return false;
10330
+ const { provider, modelId } = steps[steps.length - 1].model;
10331
+ logWarnings({
10332
+ provider,
10333
+ model: modelId,
10334
+ warnings: [{
10335
+ type: "other",
10336
+ message: `The tool loop stopped because it reached the default stopWhen condition, isStepCount(${stepCount}). To allow more steps, set stopWhen to isStepCount(...) with a higher limit or provide a custom stop condition. Learn more: https://ai-sdk.dev/docs/agents/loop-control`
10337
+ }]
10338
+ });
10339
+ return true;
10340
+ };
10341
+ }
10342
+ //#endregion
10313
10343
  //#region src/agent/tool-loop-agent.ts
10314
10344
  /**
10315
10345
  * A tool loop agent is an agent that runs tools in a loop. In each step,
@@ -10358,7 +10388,7 @@ var ToolLoopAgent = class {
10358
10388
  const { onStart: _settingsStableOnStart, experimental_onStart: _settingsExperimentalOnStart, onStepStart: _settingsStableOnStepStart, experimental_onStepStart: _settingsExperimentalOnStepStart, onToolExecutionStart: _settingsOnToolExecutionStart, onToolExecutionEnd: _settingsOnToolExecutionEnd, onStepEnd: _settingsOnStepEnd, onStepFinish: _settingsOnStepFinish, onFinish: _settingsOnFinish, onEnd: _settingsOnEnd, ...settingsWithoutCallbacks } = this.settings;
10359
10389
  const baseCallArgs = {
10360
10390
  ...settingsWithoutCallbacks,
10361
- stopWhen: this.settings.stopWhen ?? isStepCount(20),
10391
+ stopWhen: this.settings.stopWhen ?? createDefaultStopCondition(20),
10362
10392
  ...options
10363
10393
  };
10364
10394
  const { instructions, allowSystemInMessages, messages, prompt, runtimeContext, ...callArgs } = await this.settings.prepareCall?.(baseCallArgs) ?? baseCallArgs;
@@ -12184,6 +12214,15 @@ function createRestrictedTelemetryDispatcher$2({ telemetry }) {
12184
12214
  };
12185
12215
  }
12186
12216
  //#endregion
12217
+ //#region src/embed/validate-embedding-dimensions.ts
12218
+ function validateEmbeddingDimensions(dimensions) {
12219
+ if (dimensions !== void 0 && (!Number.isInteger(dimensions) || dimensions <= 0)) throw new InvalidArgumentError({
12220
+ parameter: "dimensions",
12221
+ value: dimensions,
12222
+ message: "dimensions must be a positive integer"
12223
+ });
12224
+ }
12225
+ //#endregion
12187
12226
  //#region src/embed/embed.ts
12188
12227
  const originalGenerateCallId$6 = createIdGenerator$1({
12189
12228
  prefix: "call",
@@ -12195,6 +12234,8 @@ const originalGenerateCallId$6 = createIdGenerator$1({
12195
12234
  * @param model - The embedding model to use.
12196
12235
  * @param value - The value that should be embedded.
12197
12236
  *
12237
+ * @param dimensions - Requested output dimensions. Must be a positive integer. Requires provider support.
12238
+ *
12198
12239
  * @param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2.
12199
12240
  * @param abortSignal - An optional abort signal that can be used to cancel the call.
12200
12241
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
@@ -12208,7 +12249,8 @@ const originalGenerateCallId$6 = createIdGenerator$1({
12208
12249
  *
12209
12250
  * @returns A result object that contains the embedding, the value, and additional information.
12210
12251
  */
12211
- async function embed({ model: modelArg, value, providerOptions, maxRetries: maxRetriesArg, abortSignal, headers, experimental_telemetry, telemetry = experimental_telemetry, runtimeContext = {}, onStart, experimental_onStart, onEnd, experimental_onEnd, _internal: { generateCallId = originalGenerateCallId$6 } = {} }) {
12252
+ async function embed({ model: modelArg, value, dimensions, providerOptions, maxRetries: maxRetriesArg, abortSignal, headers, experimental_telemetry, telemetry = experimental_telemetry, runtimeContext = {}, onStart, experimental_onStart, onEnd, experimental_onEnd, _internal: { generateCallId = originalGenerateCallId$6 } = {} }) {
12253
+ validateEmbeddingDimensions(dimensions);
12212
12254
  const model = resolveEmbeddingModel(modelArg);
12213
12255
  const { maxRetries, retry } = prepareRetries({
12214
12256
  maxRetries: maxRetriesArg,
@@ -12227,6 +12269,7 @@ async function embed({ model: modelArg, value, providerOptions, maxRetries: maxR
12227
12269
  provider: model.provider,
12228
12270
  modelId: model.modelId,
12229
12271
  value,
12272
+ dimensions,
12230
12273
  maxRetries,
12231
12274
  headers: headersWithUserAgent,
12232
12275
  providerOptions
@@ -12249,12 +12292,14 @@ async function embed({ model: modelArg, value, providerOptions, maxRetries: maxR
12249
12292
  operationId: "ai.embed.doEmbed",
12250
12293
  provider: model.provider,
12251
12294
  modelId: model.modelId,
12252
- values: [value]
12295
+ values: [value],
12296
+ dimensions
12253
12297
  },
12254
12298
  callbacks: [telemetryDispatcher.onEmbedStart]
12255
12299
  });
12256
12300
  const modelResponse = await model.doEmbed({
12257
12301
  values: [value],
12302
+ dimensions,
12258
12303
  abortSignal,
12259
12304
  headers: headersWithUserAgent,
12260
12305
  providerOptions
@@ -12383,6 +12428,8 @@ const originalGenerateCallId$5 = createIdGenerator$1({
12383
12428
  * @param model - The embedding model to use.
12384
12429
  * @param values - The values that should be embedded.
12385
12430
  *
12431
+ * @param dimensions - Requested output dimensions. Must be a positive integer. Requires provider support.
12432
+ *
12386
12433
  * @param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2.
12387
12434
  * @param abortSignal - An optional abort signal that can be used to cancel the call.
12388
12435
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
@@ -12400,7 +12447,8 @@ const originalGenerateCallId$5 = createIdGenerator$1({
12400
12447
  *
12401
12448
  * @returns A result object that contains the embeddings, the value, and additional information.
12402
12449
  */
12403
- async function embedMany({ model: modelArg, values, maxParallelCalls = Infinity, maxRetries: maxRetriesArg, abortSignal, headers, providerOptions, experimental_telemetry, telemetry = experimental_telemetry, runtimeContext = {}, onStart, experimental_onStart, onEnd, experimental_onEnd, _internal: { generateCallId = originalGenerateCallId$5 } = {} }) {
12450
+ async function embedMany({ model: modelArg, values, dimensions, maxParallelCalls = Infinity, maxRetries: maxRetriesArg, abortSignal, headers, providerOptions, experimental_telemetry, telemetry = experimental_telemetry, runtimeContext = {}, onStart, experimental_onStart, onEnd, experimental_onEnd, _internal: { generateCallId = originalGenerateCallId$5 } = {} }) {
12451
+ validateEmbeddingDimensions(dimensions);
12404
12452
  const model = resolveEmbeddingModel(modelArg);
12405
12453
  const { maxRetries, retry } = prepareRetries({
12406
12454
  maxRetries: maxRetriesArg,
@@ -12419,6 +12467,7 @@ async function embedMany({ model: modelArg, values, maxParallelCalls = Infinity,
12419
12467
  provider: model.provider,
12420
12468
  modelId: model.modelId,
12421
12469
  value: values,
12470
+ dimensions,
12422
12471
  maxRetries,
12423
12472
  headers: headersWithUserAgent,
12424
12473
  providerOptions
@@ -12449,12 +12498,14 @@ async function embedMany({ model: modelArg, values, maxParallelCalls = Infinity,
12449
12498
  operationId: "ai.embedMany.doEmbed",
12450
12499
  provider: model.provider,
12451
12500
  modelId: model.modelId,
12452
- values
12501
+ values,
12502
+ dimensions
12453
12503
  },
12454
12504
  callbacks: [telemetryDispatcher.onEmbedStart]
12455
12505
  });
12456
12506
  const modelResponse = await model.doEmbed({
12457
12507
  values,
12508
+ dimensions,
12458
12509
  abortSignal,
12459
12510
  headers: headersWithUserAgent,
12460
12511
  providerOptions
@@ -12548,12 +12599,14 @@ async function embedMany({ model: modelArg, values, maxParallelCalls = Infinity,
12548
12599
  operationId: "ai.embedMany.doEmbed",
12549
12600
  provider: model.provider,
12550
12601
  modelId: model.modelId,
12551
- values: chunk
12602
+ values: chunk,
12603
+ dimensions
12552
12604
  },
12553
12605
  callbacks: [telemetryDispatcher.onEmbedStart]
12554
12606
  });
12555
12607
  const modelResponse = await model.doEmbed({
12556
12608
  values: chunk,
12609
+ dimensions,
12557
12610
  abortSignal,
12558
12611
  headers: headersWithUserAgent,
12559
12612
  providerOptions: chunkProviderOptions
@@ -12733,7 +12786,7 @@ function createRestrictedTelemetryDispatcher$1({ telemetry }) {
12733
12786
  //#endregion
12734
12787
  //#region src/decide/validate-decision.ts
12735
12788
  const tolerance = 1e-6;
12736
- function isRecord(value) {
12789
+ function isRecord$1(value) {
12737
12790
  if (value == null || typeof value !== "object" || Array.isArray(value)) return false;
12738
12791
  const prototype = Object.getPrototypeOf(value);
12739
12792
  return prototype === Object.prototype || prototype === null;
@@ -12741,7 +12794,7 @@ function isRecord(value) {
12741
12794
  function isJSON(value, ancestors = /* @__PURE__ */ new Set()) {
12742
12795
  if (value === null || typeof value === "string" || typeof value === "boolean") return true;
12743
12796
  if (typeof value === "number") return Number.isFinite(value);
12744
- if (typeof value !== "object" || !Array.isArray(value) && !isRecord(value)) return false;
12797
+ if (typeof value !== "object" || !Array.isArray(value) && !isRecord$1(value)) return false;
12745
12798
  if (ancestors.has(value)) return false;
12746
12799
  ancestors.add(value);
12747
12800
  const valid = Object.getOwnPropertySymbols(value).length === 0 && (Array.isArray(value) ? Array.from(value).every((item) => isJSON(item, ancestors)) : Object.values(value).every((item) => isJSON(item, ancestors)));
@@ -12749,7 +12802,7 @@ function isJSON(value, ancestors = /* @__PURE__ */ new Set()) {
12749
12802
  return valid;
12750
12803
  }
12751
12804
  function isInput(value) {
12752
- return (typeof value === "string" || Array.isArray(value) || isRecord(value)) && isJSON(value);
12805
+ return (typeof value === "string" || Array.isArray(value) || isRecord$1(value)) && isJSON(value);
12753
12806
  }
12754
12807
  function invalidInput(parameter, value, message) {
12755
12808
  throw new InvalidArgumentError({
@@ -12760,29 +12813,29 @@ function invalidInput(parameter, value, message) {
12760
12813
  }
12761
12814
  function validateDecisionInput({ state, questions }) {
12762
12815
  if (!(Array.isArray(state) ? Array.from(state).every((part) => {
12763
- if (!isRecord(part)) return false;
12816
+ if (!isRecord$1(part)) return false;
12764
12817
  switch (part.type) {
12765
12818
  case "text": return textPartSchema.safeParse(part).success;
12766
12819
  case "file": return filePartSchema.safeParse(part).success;
12767
12820
  case "json": return isJSON(part.value);
12768
12821
  default: return false;
12769
12822
  }
12770
- }) : (typeof state === "string" || isRecord(state)) && isJSON(state))) invalidInput("state", state, "must be a string, JSON object, or array of text, file, or json parts");
12771
- if (!isRecord(questions) || Object.keys(questions).length === 0) invalidInput("questions", questions, "must be a nonempty question map");
12823
+ }) : (typeof state === "string" || isRecord$1(state)) && isJSON(state))) invalidInput("state", state, "must be a string, JSON object, or array of text, file, or json parts");
12824
+ if (!isRecord$1(questions) || Object.keys(questions).length === 0) invalidInput("questions", questions, "must be a nonempty question map");
12772
12825
  for (const [id, question] of Object.entries(questions)) {
12773
12826
  const parameter = `questions.${id}`;
12774
- if (!isRecord(question) || !isInput(question.instructions)) invalidInput(parameter, question, "instructions must be a JSON-compatible string, object, or array");
12827
+ if (!isRecord$1(question) || !isInput(question.instructions)) invalidInput(parameter, question, "instructions must be a JSON-compatible string, object, or array");
12775
12828
  const criteria = question.criteria;
12776
12829
  switch (question.type) {
12777
12830
  case "choice":
12778
- if (!isRecord(criteria) || Object.keys(criteria).length === 0) invalidInput(parameter, question, "choice criteria must be a nonempty option map");
12831
+ if (!isRecord$1(criteria) || Object.keys(criteria).length === 0) invalidInput(parameter, question, "choice criteria must be a nonempty option map");
12779
12832
  break;
12780
12833
  case "score":
12781
12834
  if (!Array.isArray(criteria) || criteria.length < 2) invalidInput(parameter, question, "score criteria must contain at least two ordered levels");
12782
12835
  break;
12783
12836
  case "boolean":
12784
12837
  if (criteria === void 0) continue;
12785
- if (!isRecord(criteria) || Object.keys(criteria).some((key) => key !== "true" && key !== "false")) invalidInput(parameter, question, "boolean criteria may only describe true and false");
12838
+ if (!isRecord$1(criteria) || Object.keys(criteria).some((key) => key !== "true" && key !== "false")) invalidInput(parameter, question, "boolean criteria may only describe true and false");
12786
12839
  break;
12787
12840
  default: invalidInput(parameter, question, "question type must be choice, score, or boolean");
12788
12841
  }
@@ -12802,7 +12855,7 @@ function hasExactKeys(value, keys) {
12802
12855
  return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
12803
12856
  }
12804
12857
  function validateDistribution(value, keys, answers, id, roundingError) {
12805
- if (!isRecord(value) || !hasExactKeys(value, keys) || !Object.values(value).every(isProbability)) invalidAnswer(answers, `Question "${id}" must have a complete distribution of finite probabilities in [0, 1].`);
12858
+ if (!isRecord$1(value) || !hasExactKeys(value, keys) || !Object.values(value).every(isProbability)) invalidAnswer(answers, `Question "${id}" must have a complete distribution of finite probabilities in [0, 1].`);
12806
12859
  const sum = Object.values(value).reduce((total, probability) => total + probability, 0);
12807
12860
  if (Math.abs(sum - 1) > tolerance + keys.length * roundingError) invalidAnswer(answers, `Question "${id}" probabilities must sum to 1 within the declared rounding precision.`);
12808
12861
  }
@@ -12814,11 +12867,11 @@ function validateDecisionAnswers({ questions, answers, rounding }) {
12814
12867
  }
12815
12868
  const probabilityError = roundingError(rounding?.probabilityDecimals);
12816
12869
  const scoreError = roundingError(rounding?.scoreDecimals);
12817
- if (!isRecord(answers) || !hasExactKeys(answers, Object.keys(questions))) invalidAnswer(answers, "Decision must return exactly one answer for every question.");
12870
+ if (!isRecord$1(answers) || !hasExactKeys(answers, Object.keys(questions))) invalidAnswer(answers, "Decision must return exactly one answer for every question.");
12818
12871
  for (const [id, question] of Object.entries(questions)) {
12819
12872
  const answer = answers[id];
12820
- if (isRecord(answer) && answer.type === "refusal") continue;
12821
- if (!isRecord(answer) || answer.type !== question.type) invalidAnswer(answers, `Question "${id}" returned an answer with the wrong type.`);
12873
+ if (isRecord$1(answer) && answer.type === "refusal") continue;
12874
+ if (!isRecord$1(answer) || answer.type !== question.type) invalidAnswer(answers, `Question "${id}" returned an answer with the wrong type.`);
12822
12875
  switch (question.type) {
12823
12876
  case "choice":
12824
12877
  if (typeof answer.choice !== "string" || !Object.hasOwn(question.criteria, answer.choice)) invalidAnswer(answers, `Question "${id}" selected an unknown option.`);
@@ -13721,15 +13774,20 @@ var SerialJobExecutor = class {
13721
13774
  constructor() {
13722
13775
  this.queue = [];
13723
13776
  this.isProcessing = false;
13777
+ this.idleWaiters = [];
13724
13778
  }
13725
13779
  async processQueue() {
13726
13780
  if (this.isProcessing) return;
13727
13781
  this.isProcessing = true;
13728
- while (this.queue.length > 0) {
13729
- await this.queue[0]();
13730
- this.queue.shift();
13782
+ try {
13783
+ while (this.queue.length > 0) {
13784
+ await this.queue[0]();
13785
+ this.queue.shift();
13786
+ }
13787
+ } finally {
13788
+ this.isProcessing = false;
13789
+ for (const resolve of this.idleWaiters.splice(0)) resolve();
13731
13790
  }
13732
- this.isProcessing = false;
13733
13791
  }
13734
13792
  async run(job) {
13735
13793
  return new Promise((resolve, reject) => {
@@ -13744,6 +13802,12 @@ var SerialJobExecutor = class {
13744
13802
  this.processQueue();
13745
13803
  });
13746
13804
  }
13805
+ async waitForIdle() {
13806
+ if (!this.isProcessing && this.queue.length === 0) return;
13807
+ await new Promise((resolve) => {
13808
+ this.idleWaiters.push(resolve);
13809
+ });
13810
+ }
13747
13811
  };
13748
13812
  //#endregion
13749
13813
  //#region src/util/simulate-readable-stream.ts
@@ -19677,6 +19741,8 @@ var AbstractChat = class {
19677
19741
  this.activeResumeRequest = void 0;
19678
19742
  this.resumableStreamState = void 0;
19679
19743
  this.jobExecutor = new SerialJobExecutor();
19744
+ this.activeStopCount = 0;
19745
+ this.stopGeneration = 0;
19680
19746
  this.sendMessage = async (message, options) => {
19681
19747
  if (message == null) {
19682
19748
  let messageId = this.pendingApprovalMessageId;
@@ -19793,15 +19859,16 @@ var AbstractChat = class {
19793
19859
  this.pendingApprovalMessageId = message.id;
19794
19860
  }
19795
19861
  if (this.activeResponse) this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(updatePart);
19796
- if (this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
19797
- if (await this.shouldSendAutomatically()) {
19862
+ if (messageIndex !== -1 && this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
19863
+ const shouldSend = await this.shouldSendAutomatically();
19864
+ if (shouldSend) this.runAutomaticRequest(() => {
19798
19865
  const messageId = messageIndex === -1 ? this.lastMessage?.id : messages[messageIndex].id;
19799
- this.makeRequestForToolApproval({
19866
+ return this.makeRequestForToolApproval({
19800
19867
  messageId,
19801
19868
  messageIndex,
19802
19869
  ...options
19803
19870
  });
19804
- }
19871
+ }, shouldSend);
19805
19872
  }
19806
19873
  });
19807
19874
  this.addToolOutput = async ({ state, toolCallId, output, errorText, options }) => this.jobExecutor.run(async () => {
@@ -19836,18 +19903,33 @@ var AbstractChat = class {
19836
19903
  });
19837
19904
  if (this.activeResponse) this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(updatePart);
19838
19905
  if (this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
19839
- if (await this.shouldSendAutomatically()) this.makeRequest({
19906
+ const shouldSend = await this.shouldSendAutomatically();
19907
+ if (shouldSend) this.runAutomaticRequest(() => this.makeRequest({
19840
19908
  trigger: "submit-message",
19841
19909
  messageId: this.lastMessage?.id,
19842
19910
  ...options
19843
- });
19911
+ }), shouldSend);
19844
19912
  }
19845
19913
  });
19846
19914
  this.addToolResult = this.addToolOutput;
19847
19915
  this.stop = async () => {
19848
- for (const controller of this.pendingMessagePreparations) controller.abort();
19849
- this.activeResumeRequest?.abortController.abort();
19850
- this.activeResponse?.abortController.abort();
19916
+ this.activeStopCount++;
19917
+ this.stopGeneration++;
19918
+ try {
19919
+ const activeResumeRequest = this.activeResumeRequest;
19920
+ const activeResponse = this.activeResponse;
19921
+ for (const controller of this.pendingMessagePreparations) controller.abort();
19922
+ activeResumeRequest?.abortController.abort();
19923
+ activeResponse?.abortController.abort();
19924
+ await Promise.all([activeResumeRequest?.completionPromise, activeResponse?.completionPromise]);
19925
+ await this.jobExecutor.waitForIdle();
19926
+ } finally {
19927
+ this.activeStopCount--;
19928
+ }
19929
+ };
19930
+ this.dispose = async () => {
19931
+ await this.stop();
19932
+ this.transport.close?.();
19851
19933
  };
19852
19934
  this.id = id;
19853
19935
  this.transport = transport;
@@ -19898,6 +19980,13 @@ var AbstractChat = class {
19898
19980
  if (result && typeof result === "object" && "then" in result) return await result;
19899
19981
  return result;
19900
19982
  }
19983
+ async runAutomaticRequest(request, shouldSend) {
19984
+ const stopGeneration = this.stopGeneration;
19985
+ const startedWhileStopping = this.activeStopCount > 0;
19986
+ if (!(shouldSend ?? await this.shouldSendAutomatically())) return;
19987
+ if (startedWhileStopping || stopGeneration !== this.stopGeneration || this.activeStopCount > 0) return;
19988
+ await request();
19989
+ }
19901
19990
  async makeRequestForToolApproval({ messageId, messageIndex, ...options }) {
19902
19991
  const consumesPendingApproval = messageId != null && messageId === this.pendingApprovalMessageId;
19903
19992
  if (consumesPendingApproval) this.pendingApprovalMessageId = void 0;
@@ -19908,10 +19997,24 @@ var AbstractChat = class {
19908
19997
  });
19909
19998
  if (consumesPendingApproval && this.status === "error" && this.pendingApprovalMessageId == null) this.pendingApprovalMessageId = this.state.messages[messageIndex]?.id ?? messageId;
19910
19999
  }
19911
- async makeRequest({ trigger, metadata, headers, body, messageId }) {
20000
+ async makeRequest(options) {
20001
+ const completion = createResolvablePromise();
20002
+ try {
20003
+ await this.makeRequestImpl({
20004
+ ...options,
20005
+ completionPromise: completion.promise
20006
+ });
20007
+ } finally {
20008
+ completion.resolve();
20009
+ }
20010
+ }
20011
+ async makeRequestImpl({ trigger, metadata, headers, body, messageId, completionPromise }) {
19912
20012
  if (trigger !== "resume-stream") this.resumableStreamState = void 0;
19913
20013
  const abortController = new AbortController();
19914
- const activeResumeRequest = trigger === "resume-stream" ? { abortController } : void 0;
20014
+ const activeResumeRequest = trigger === "resume-stream" ? {
20015
+ abortController,
20016
+ completionPromise
20017
+ } : void 0;
19915
20018
  if (activeResumeRequest) {
19916
20019
  this.activeResumeRequest?.abortController.abort();
19917
20020
  this.activeResumeRequest = activeResumeRequest;
@@ -19982,7 +20085,8 @@ var AbstractChat = class {
19982
20085
  lastMessage: trigger === "resume-stream" ? resumableResponseMessage : trigger === "regenerate-message" ? void 0 : this.state.snapshot(responseMessage),
19983
20086
  messageId: this.generateId()
19984
20087
  }),
19985
- abortController
20088
+ abortController,
20089
+ completionPromise
19986
20090
  };
19987
20091
  activeResponse = response;
19988
20092
  response.abortController.signal.addEventListener("abort", () => {
@@ -20018,6 +20122,7 @@ var AbstractChat = class {
20018
20122
  stream: processUIMessageStream({
20019
20123
  stream,
20020
20124
  resetStateOnMessageIdChange: trigger === "resume-stream",
20125
+ resetStateOnFirstMessageStart: trigger === "resume-stream" && this.transport.resumeStreamIsReplay,
20021
20126
  onToolCall: this.onToolCall,
20022
20127
  onData: this.onData,
20023
20128
  messageMetadataSchema: this.messageMetadataSchema,
@@ -20080,13 +20185,13 @@ var AbstractChat = class {
20080
20185
  clearActiveResumeRequest();
20081
20186
  }
20082
20187
  }
20083
- if (!isError && await this.shouldSendAutomatically()) await this.makeRequest({
20188
+ if (!isAbort && !isError) await this.runAutomaticRequest(() => this.makeRequest({
20084
20189
  trigger: "submit-message",
20085
20190
  messageId: this.lastMessage?.id,
20086
20191
  metadata,
20087
20192
  headers,
20088
20193
  body
20089
- });
20194
+ }));
20090
20195
  }
20091
20196
  };
20092
20197
  //#endregion
@@ -20221,6 +20326,460 @@ var TextStreamChatTransport = class extends HttpChatTransport {
20221
20326
  }
20222
20327
  };
20223
20328
  //#endregion
20329
+ //#region src/ui/websocket-chat-transport.ts
20330
+ const WEBSOCKET_OPEN_STATE = 1;
20331
+ function createAbortError(signal) {
20332
+ const reason = signal?.reason;
20333
+ if (reason instanceof Error) return reason;
20334
+ const error = /* @__PURE__ */ new Error("The WebSocket chat request was aborted.");
20335
+ error.name = "AbortError";
20336
+ return error;
20337
+ }
20338
+ function asError(error) {
20339
+ return error instanceof Error ? error : new Error(String(error));
20340
+ }
20341
+ function isRecord(value) {
20342
+ return value != null && typeof value === "object" && !Array.isArray(value);
20343
+ }
20344
+ function isStringRecord(value) {
20345
+ return isRecord(value) && Object.values(value).every((item) => typeof item === "string");
20346
+ }
20347
+ function isSequence(value) {
20348
+ return Number.isSafeInteger(value) && value >= 0;
20349
+ }
20350
+ /**
20351
+ * Validates an untrusted client-to-server WebSocket chat frame.
20352
+ */
20353
+ async function safeValidateWebSocketChatTransportRequest({ value }) {
20354
+ try {
20355
+ if (!isRecord(value) || typeof value.type !== "string") throw new Error("Invalid WebSocket chat request frame.");
20356
+ if (value.type === "abort") {
20357
+ if (typeof value.requestId !== "string") throw new Error("Invalid WebSocket chat abort request.");
20358
+ return {
20359
+ success: true,
20360
+ data: value
20361
+ };
20362
+ }
20363
+ if (typeof value.requestId !== "string" || typeof value.id !== "string" || !isStringRecord(value.headers) || !isRecord(value.body)) throw new Error("Invalid WebSocket chat request frame.");
20364
+ if (value.type === "resume") {
20365
+ if (value.lastSequence !== void 0 && !isSequence(value.lastSequence)) throw new Error("Invalid WebSocket chat resume sequence.");
20366
+ return {
20367
+ success: true,
20368
+ data: value
20369
+ };
20370
+ }
20371
+ if (value.type !== "send" || !["submit-message", "regenerate-message"].includes(value.trigger) || value.messageId !== void 0 && typeof value.messageId !== "string") throw new Error("Invalid WebSocket chat send request.");
20372
+ const messages = await safeValidateUIMessages({ messages: value.messages });
20373
+ if (!messages.success) throw new Error("Invalid UI messages in WebSocket chat request.", { cause: messages.error });
20374
+ return {
20375
+ success: true,
20376
+ data: {
20377
+ ...value,
20378
+ messages: messages.data
20379
+ }
20380
+ };
20381
+ } catch (error) {
20382
+ return {
20383
+ success: false,
20384
+ error: asError(error)
20385
+ };
20386
+ }
20387
+ }
20388
+ /**
20389
+ * A `ChatTransport` that multiplexes correlated UI message streams over one
20390
+ * persistent WebSocket connection.
20391
+ *
20392
+ * The server must implement the protocol represented by
20393
+ * `WebSocketChatTransportRequest` and `WebSocketChatTransportResponse`.
20394
+ */
20395
+ var WebSocketChatTransport = class {
20396
+ constructor(options) {
20397
+ this.resumeStreamIsReplay = true;
20398
+ this.activeRequests = /* @__PURE__ */ new Map();
20399
+ this.sendQueue = Promise.resolve();
20400
+ this.url = options.url;
20401
+ this.protocols = options.protocols;
20402
+ this.params = options.params;
20403
+ this.headers = options.headers;
20404
+ this.body = options.body;
20405
+ this.webSocket = options.webSocket;
20406
+ this.prepareSendMessagesRequest = options.prepareSendMessagesRequest;
20407
+ this.prepareReconnectToStreamRequest = options.prepareReconnectToStreamRequest;
20408
+ }
20409
+ async sendMessages({ abortSignal, ...options }) {
20410
+ this.throwIfAborted(abortSignal);
20411
+ const [resolvedHeaders, resolvedBody] = await Promise.all([resolve(this.headers), resolve(this.body)]);
20412
+ this.throwIfAborted(abortSignal);
20413
+ const headers = {
20414
+ ...normalizeHeaders(resolvedHeaders),
20415
+ ...normalizeHeaders(options.headers)
20416
+ };
20417
+ const body = {
20418
+ ...resolvedBody,
20419
+ ...options.body
20420
+ };
20421
+ const preparedRequest = await this.prepareSendMessagesRequest?.({
20422
+ id: options.chatId,
20423
+ messages: options.messages,
20424
+ requestMetadata: options.metadata,
20425
+ body,
20426
+ headers,
20427
+ trigger: options.trigger,
20428
+ messageId: options.messageId
20429
+ });
20430
+ this.throwIfAborted(abortSignal);
20431
+ const socket = await this.getSocket(abortSignal);
20432
+ const requestId = generateId$1();
20433
+ const request = this.createActiveRequest({
20434
+ requestId,
20435
+ kind: "send",
20436
+ lastSequence: -1,
20437
+ abortSignal
20438
+ });
20439
+ const frame = {
20440
+ type: "send",
20441
+ requestId,
20442
+ id: options.chatId,
20443
+ trigger: options.trigger,
20444
+ messageId: options.messageId,
20445
+ messages: preparedRequest?.messages ?? options.messages,
20446
+ headers: preparedRequest?.headers == null ? headers : normalizeHeaders(preparedRequest.headers),
20447
+ body: preparedRequest?.body ?? body,
20448
+ metadata: options.metadata
20449
+ };
20450
+ try {
20451
+ await this.sendFrame(socket, frame, abortSignal);
20452
+ return request.stream;
20453
+ } catch (error) {
20454
+ const requestError = asError(error);
20455
+ this.failRequest(request, requestError);
20456
+ throw requestError;
20457
+ }
20458
+ }
20459
+ async reconnectToStream(options) {
20460
+ this.throwIfAborted(options.abortSignal);
20461
+ const [resolvedHeaders, resolvedBody] = await Promise.all([resolve(this.headers), resolve(this.body)]);
20462
+ this.throwIfAborted(options.abortSignal);
20463
+ const headers = {
20464
+ ...normalizeHeaders(resolvedHeaders),
20465
+ ...normalizeHeaders(options.headers)
20466
+ };
20467
+ const body = {
20468
+ ...resolvedBody,
20469
+ ...options.body
20470
+ };
20471
+ const preparedRequest = await this.prepareReconnectToStreamRequest?.({
20472
+ id: options.chatId,
20473
+ requestMetadata: options.metadata,
20474
+ body,
20475
+ headers
20476
+ });
20477
+ this.throwIfAborted(options.abortSignal);
20478
+ const socket = await this.getSocket(options.abortSignal);
20479
+ const requestId = generateId$1();
20480
+ let resolveResponse;
20481
+ let rejectResponse;
20482
+ const responsePromise = new Promise((resolve, reject) => {
20483
+ resolveResponse = resolve;
20484
+ rejectResponse = reject;
20485
+ });
20486
+ responsePromise.catch(() => {});
20487
+ const request = this.createActiveRequest({
20488
+ requestId,
20489
+ kind: "resume",
20490
+ lastSequence: -1,
20491
+ abortSignal: options.abortSignal,
20492
+ resolveResponse,
20493
+ rejectResponse
20494
+ });
20495
+ const frame = {
20496
+ type: "resume",
20497
+ requestId,
20498
+ id: options.chatId,
20499
+ lastSequence: void 0,
20500
+ headers: preparedRequest?.headers == null ? headers : normalizeHeaders(preparedRequest.headers),
20501
+ body: preparedRequest?.body ?? body,
20502
+ metadata: options.metadata
20503
+ };
20504
+ try {
20505
+ await this.sendFrame(socket, frame, options.abortSignal);
20506
+ } catch (error) {
20507
+ const requestError = asError(error);
20508
+ request.responseSettled = true;
20509
+ this.failRequest(request, requestError);
20510
+ throw requestError;
20511
+ }
20512
+ return responsePromise;
20513
+ }
20514
+ /**
20515
+ * Closes the current connection and errors any active response streams.
20516
+ * A later request opens a new connection.
20517
+ */
20518
+ close() {
20519
+ const error = /* @__PURE__ */ new Error("WebSocket chat transport was closed.");
20520
+ const connection = this.connection;
20521
+ this.connection = void 0;
20522
+ this.failAllRequests(error);
20523
+ if (connection != null) {
20524
+ this.rejectConnection(connection, error);
20525
+ try {
20526
+ connection.socket?.close(1e3, "Client closed transport");
20527
+ } catch {}
20528
+ }
20529
+ }
20530
+ throwIfAborted(abortSignal) {
20531
+ if (abortSignal?.aborted) throw createAbortError(abortSignal);
20532
+ }
20533
+ async getSocket(abortSignal) {
20534
+ const existingSocket = this.connection?.socket;
20535
+ if (existingSocket?.readyState === WEBSOCKET_OPEN_STATE) return existingSocket;
20536
+ if (this.connection == null) {
20537
+ let resolveConnection;
20538
+ let rejectConnection;
20539
+ const connection = {
20540
+ promise: new Promise((resolve, reject) => {
20541
+ resolveConnection = resolve;
20542
+ rejectConnection = reject;
20543
+ }),
20544
+ resolve: resolveConnection,
20545
+ reject: rejectConnection,
20546
+ settled: false
20547
+ };
20548
+ this.connection = connection;
20549
+ this.initializeConnection(connection);
20550
+ }
20551
+ const connection = this.connection;
20552
+ if (connection == null) throw new Error("Failed to initialize WebSocket connection.");
20553
+ return this.waitForConnection(connection.promise, abortSignal);
20554
+ }
20555
+ async initializeConnection(connection) {
20556
+ try {
20557
+ const params = await resolve(this.params);
20558
+ if (this.connection !== connection) return;
20559
+ const url = this.buildUrl(params);
20560
+ const socket = new (getWebSocketConstructor(this.webSocket))(url, this.protocols);
20561
+ connection.socket = socket;
20562
+ let messageTail = Promise.resolve();
20563
+ socket.onopen = () => {
20564
+ if (this.connection !== connection) return;
20565
+ this.resolveConnection(connection, socket);
20566
+ };
20567
+ socket.onmessage = (event) => {
20568
+ messageTail = messageTail.then(() => readWebSocketMessageText(event.data)).then((text) => this.handleResponseFrame(connection, text)).catch((error) => {
20569
+ this.terminateConnection(connection, asError(error));
20570
+ });
20571
+ };
20572
+ socket.onerror = () => {
20573
+ this.terminateConnection(connection, /* @__PURE__ */ new TypeError("WebSocket chat network connection failed."));
20574
+ };
20575
+ socket.onclose = (event) => {
20576
+ messageTail = messageTail.then(() => {
20577
+ if (this.connection !== connection) return;
20578
+ const closeEvent = event;
20579
+ const code = typeof closeEvent?.code === "number" ? closeEvent.code : void 0;
20580
+ const reason = typeof closeEvent?.reason === "string" && closeEvent.reason !== "" ? `: ${closeEvent.reason}` : "";
20581
+ this.terminateConnection(connection, /* @__PURE__ */ new TypeError(`WebSocket chat network connection closed${code == null ? "" : ` (code ${code}${reason})`}.`), false);
20582
+ }).catch((error) => {
20583
+ this.terminateConnection(connection, asError(error));
20584
+ });
20585
+ };
20586
+ } catch (error) {
20587
+ this.terminateConnection(connection, asError(error), false);
20588
+ }
20589
+ }
20590
+ buildUrl(params) {
20591
+ let url;
20592
+ try {
20593
+ const baseUrl = typeof globalThis.location === "undefined" ? void 0 : globalThis.location.href;
20594
+ url = new URL(this.url, baseUrl);
20595
+ url = toWebSocketUrl(url);
20596
+ } catch {
20597
+ throw new Error("Invalid WebSocket chat URL. Use an absolute URL outside the browser.");
20598
+ }
20599
+ if (!["ws:", "wss:"].includes(url.protocol) || url.hostname === "") throw new Error("Invalid WebSocket chat URL. Expected ws:// or wss://.");
20600
+ if (url.hash !== "") throw new Error("Invalid WebSocket chat URL. Fragments are not allowed.");
20601
+ for (const [key, value] of Object.entries(params ?? {})) url.searchParams.set(key, value);
20602
+ return url;
20603
+ }
20604
+ waitForConnection(promise, abortSignal) {
20605
+ if (abortSignal == null) return promise;
20606
+ if (abortSignal.aborted) return Promise.reject(createAbortError(abortSignal));
20607
+ return new Promise((resolve, reject) => {
20608
+ const onAbort = () => {
20609
+ reject(createAbortError(abortSignal));
20610
+ };
20611
+ abortSignal.addEventListener("abort", onAbort, { once: true });
20612
+ promise.then((socket) => {
20613
+ abortSignal.removeEventListener("abort", onAbort);
20614
+ resolve(socket);
20615
+ }, (error) => {
20616
+ abortSignal.removeEventListener("abort", onAbort);
20617
+ reject(error);
20618
+ });
20619
+ });
20620
+ }
20621
+ resolveConnection(connection, socket) {
20622
+ if (connection.settled) return;
20623
+ connection.settled = true;
20624
+ connection.resolve(socket);
20625
+ }
20626
+ rejectConnection(connection, error) {
20627
+ if (connection.settled) return;
20628
+ connection.settled = true;
20629
+ connection.reject(error);
20630
+ }
20631
+ terminateConnection(connection, error, closeSocket = true) {
20632
+ if (this.connection !== connection) return;
20633
+ this.connection = void 0;
20634
+ this.rejectConnection(connection, error);
20635
+ this.failAllRequests(error);
20636
+ if (closeSocket) try {
20637
+ connection.socket?.close(1011, "WebSocket chat transport error");
20638
+ } catch {}
20639
+ }
20640
+ createActiveRequest({ requestId, kind, lastSequence, abortSignal, resolveResponse, rejectResponse }) {
20641
+ let controller;
20642
+ const request = {
20643
+ requestId,
20644
+ kind,
20645
+ lastSequence,
20646
+ stream: new ReadableStream({
20647
+ start(streamController) {
20648
+ controller = streamController;
20649
+ },
20650
+ cancel: () => {
20651
+ this.abortRequest(requestId, false);
20652
+ }
20653
+ }),
20654
+ controller,
20655
+ responseSettled: false,
20656
+ resolveResponse,
20657
+ rejectResponse,
20658
+ abortSignal
20659
+ };
20660
+ this.activeRequests.set(requestId, request);
20661
+ if (abortSignal != null) {
20662
+ const abortListener = () => {
20663
+ this.abortRequest(requestId, true);
20664
+ };
20665
+ request.abortListener = abortListener;
20666
+ abortSignal.addEventListener("abort", abortListener, { once: true });
20667
+ if (abortSignal.aborted) abortListener();
20668
+ }
20669
+ return request;
20670
+ }
20671
+ abortRequest(requestId, closeStream) {
20672
+ const request = this.activeRequests.get(requestId);
20673
+ if (request == null) return;
20674
+ const error = createAbortError(request.abortSignal);
20675
+ if (request.kind === "resume" && !request.responseSettled) {
20676
+ request.responseSettled = true;
20677
+ request.rejectResponse?.(error);
20678
+ }
20679
+ this.cleanupRequest(request);
20680
+ if (closeStream) try {
20681
+ request.controller.close();
20682
+ } catch {}
20683
+ const socket = this.connection?.socket;
20684
+ if (socket?.readyState === WEBSOCKET_OPEN_STATE) this.sendFrame(socket, {
20685
+ type: "abort",
20686
+ requestId
20687
+ }).catch(() => {});
20688
+ }
20689
+ cleanupRequest(request) {
20690
+ this.activeRequests.delete(request.requestId);
20691
+ if (request.abortListener != null) {
20692
+ request.abortSignal?.removeEventListener("abort", request.abortListener);
20693
+ request.abortListener = void 0;
20694
+ }
20695
+ }
20696
+ failRequest(request, error) {
20697
+ if (!this.activeRequests.has(request.requestId)) return;
20698
+ if (request.kind === "resume" && !request.responseSettled) {
20699
+ request.responseSettled = true;
20700
+ request.rejectResponse?.(error);
20701
+ }
20702
+ this.cleanupRequest(request);
20703
+ try {
20704
+ request.controller.error(error);
20705
+ } catch {}
20706
+ }
20707
+ failAllRequests(error) {
20708
+ for (const request of [...this.activeRequests.values()]) this.failRequest(request, error);
20709
+ }
20710
+ resolveResumeStream(request) {
20711
+ if (request.kind !== "resume" || request.responseSettled) return;
20712
+ request.responseSettled = true;
20713
+ request.resolveResponse?.(request.stream);
20714
+ }
20715
+ async validateResponseChunk(value) {
20716
+ const chunk = await safeValidateTypes({
20717
+ value,
20718
+ schema: uiMessageChunkSchema
20719
+ });
20720
+ if (!chunk.success) throw new Error("Invalid UI message chunk in WebSocket response.");
20721
+ return chunk.value;
20722
+ }
20723
+ async handleResponseFrame(connection, text) {
20724
+ if (this.connection !== connection) return;
20725
+ const parsed = await safeParseJSON({ text });
20726
+ if (!parsed.success || !isRecord(parsed.value)) throw new Error("Invalid WebSocket chat response frame.");
20727
+ const type = parsed.value.type;
20728
+ const requestId = parsed.value.requestId;
20729
+ if (typeof type !== "string" || typeof requestId !== "string") throw new Error("Invalid WebSocket chat response frame.");
20730
+ const request = this.activeRequests.get(requestId);
20731
+ if (request == null) return;
20732
+ switch (type) {
20733
+ case "start":
20734
+ this.resolveResumeStream(request);
20735
+ return;
20736
+ case "chunk": {
20737
+ if (!isSequence(parsed.value.sequence)) throw new Error("Invalid WebSocket chat chunk sequence.");
20738
+ if (parsed.value.sequence <= request.lastSequence) return;
20739
+ if (parsed.value.sequence !== request.lastSequence + 1) throw new Error("Out-of-order WebSocket chat chunk sequence.");
20740
+ const chunk = await this.validateResponseChunk(parsed.value.chunk);
20741
+ if (this.activeRequests.get(requestId) !== request) return;
20742
+ this.resolveResumeStream(request);
20743
+ try {
20744
+ request.controller.enqueue(chunk);
20745
+ } catch {
20746
+ return;
20747
+ }
20748
+ request.lastSequence = parsed.value.sequence;
20749
+ return;
20750
+ }
20751
+ case "end":
20752
+ this.resolveResumeStream(request);
20753
+ this.cleanupRequest(request);
20754
+ request.controller.close();
20755
+ return;
20756
+ case "no-active":
20757
+ if (request.kind === "resume" && !request.responseSettled) {
20758
+ request.responseSettled = true;
20759
+ request.resolveResponse?.(null);
20760
+ }
20761
+ this.cleanupRequest(request);
20762
+ request.controller.close();
20763
+ return;
20764
+ case "error":
20765
+ if (parsed.value.errorText !== void 0 && typeof parsed.value.errorText !== "string") throw new Error("Invalid WebSocket chat error response.");
20766
+ this.failRequest(request, new Error(parsed.value.errorText ?? "WebSocket chat server returned an error."));
20767
+ return;
20768
+ default: throw new Error(`Unknown WebSocket chat response type: ${type}.`);
20769
+ }
20770
+ }
20771
+ async sendFrame(socket, frame, abortSignal) {
20772
+ const send = this.sendQueue.then(async () => {
20773
+ await waitForWebSocketBufferDrain(socket, { abortSignal });
20774
+ this.throwIfAborted(abortSignal);
20775
+ if (this.connection?.socket !== socket || socket.readyState !== WEBSOCKET_OPEN_STATE) throw new TypeError("WebSocket chat network connection is not open.");
20776
+ socket.send(JSON.stringify(frame));
20777
+ });
20778
+ this.sendQueue = send.catch(() => {});
20779
+ return send;
20780
+ }
20781
+ };
20782
+ //#endregion
20224
20783
  //#region src/upload-file/upload-file.ts
20225
20784
  /**
20226
20785
  * Uploads a file using a files API interface.
@@ -20321,6 +20880,6 @@ async function uploadSkill({ api, files, displayTitle, providerOptions }) {
20321
20880
  });
20322
20881
  }
20323
20882
  //#endregion
20324
- export { AISDKError, AI_SDK_TELEMETRY_TRACING_CHANNEL, APICallError, AbstractChat, DefaultChatTransport, DefaultGeneratedFile, DirectChatTransport, DownloadError, EmptyResponseBodyError, AbstractRealtimeSession as Experimental_AbstractRealtimeSession, ToolLoopAgent as Experimental_Agent, ToolLoopAgent, Experimental_DecisionRefusalError, Experimental_DecisionUnsupportedQuestionTypeError, Experimental_EvaluationUnsupportedQuestionTypeError, HttpChatTransport, InvalidArgumentError, InvalidDataContentError, InvalidMessageRoleError, InvalidPromptError, InvalidResponseDataError, InvalidStreamPartError, InvalidToolApprovalError, InvalidToolApprovalSignatureError, InvalidToolInputError, JSONParseError, JsonToSseTransformStream, LoadAPIKeyError, LoadSettingError, MessageConversionError, MissingToolResultsError, NoContentGeneratedError, NoImageGeneratedError, NoObjectGeneratedError, NoOutputGeneratedError, NoSpeechGeneratedError, NoSuchModelError, NoSuchProviderError, NoSuchProviderReferenceError, NoSuchToolError, NoTranscriptGeneratedError, NoTranslationGeneratedError, NoVideoGeneratedError, output_exports as Output, RetryError, SerialJobExecutor, StreamProviderError, TextStreamChatTransport, TooManyEmbeddingValuesForCallError, ToolCallNotFoundForApprovalError, ToolCallRepairError, ToolChoiceViolationError, TypeValidationError, UIMessageStreamError, UI_MESSAGE_STREAM_HEADERS, UnsupportedFunctionalityError, UnsupportedModelVersionError, addToolInputExamplesMiddleware, asSchema, assistantModelMessageSchema, callCompletionApi, consumeStream, convertDataContentToBase64String, convertFileListToFileUIParts, convertToModelMessages, cosineSimilarity, createAgentUIStream, createAgentUIStreamResponse, createDownload, createGateway, createIdGenerator, createProviderRegistry, createTextStreamResponse, createUIMessageStream, createUIMessageStreamResponse, customProvider, defaultEmbeddingSettingsMiddleware, defaultInstructionsMiddleware, defaultSettingsMiddleware, detectToolDrift, dynamicTool, embed, embedMany, cancelBatch as experimental_cancelBatch, experimental_createProviderRegistry, decide as experimental_decide, decodeRealtimeAudio as experimental_decodeRealtimeAudio, encodeRealtimeAudio as experimental_encodeRealtimeAudio, experimental_evaluate, filterActiveTools as experimental_filterActiveTools, experimental_generateSpeech, experimental_generateVideo, getBatchResults as experimental_getBatchResults, getBatchStatus as experimental_getBatchStatus, getRealtimeToolDefinitions as experimental_getRealtimeToolDefinitions, experimental_getVideoStatus, listBatches as experimental_listBatches, resampleAudio as experimental_resampleAudio, startBatch as experimental_startBatch, experimental_startVideo, streamLanguageModelCall as experimental_streamLanguageModelCall, streamTranscribe as experimental_streamTranscribe, streamTranslate as experimental_streamTranslate, experimental_toolCaller, experimental_transcribe, extractJsonMiddleware, extractReasoningMiddleware, fingerprintTools, gateway, generateId, generateImage, generateObject, generateSpeech, generateText, getChunkTimeoutMs, getFirstChunkTimeoutMs, getStaticToolName, getStepTimeoutMs, getTextFromDataUrl, getToolName, getToolOrDynamicToolName, getToolTimeoutMs, getTotalTimeoutMs, hasToolCall, isCustomContentUIPart, isDataUIPart, isDeepEqualData, isDynamicToolUIPart, isFileUIPart, isLoopFinished, isReasoningFileUIPart, isReasoningUIPart, isStaticToolUIPart, isStepCount, isStepCount as stepCountIs, isTextUIPart, isToolOutputErrorUIPart, isToolUIPart, jsonSchema, lastAssistantMessageIsCompleteWithApprovalResponses, lastAssistantMessageIsCompleteWithToolCalls, modelMessageSchema, parseJsonEventStream, parsePartialJson, pipeAgentUIStreamToResponse, pipeTextStreamToResponse, pipeUIMessageStreamToResponse, pruneMessages, readUIMessageStream, registerTelemetry, rerank, safeValidateUIMessages, simulateReadableStream, simulateStreamingMiddleware, smoothStream, streamObject, streamText, systemModelMessageSchema, toTextStream, toUIMessageChunk, toUIMessageStream, tool, toolModelMessageSchema, toolSearch, transcribe, uiMessageChunkSchema, uploadFile, uploadSkill, userModelMessageSchema, validateUIMessages, wrapEmbeddingModel, wrapImageModel, wrapLanguageModel, wrapProvider, zodSchema };
20883
+ export { AISDKError, AI_SDK_TELEMETRY_TRACING_CHANNEL, APICallError, AbstractChat, DefaultChatTransport, DefaultGeneratedFile, DirectChatTransport, DownloadError, EmptyResponseBodyError, AbstractRealtimeSession as Experimental_AbstractRealtimeSession, ToolLoopAgent as Experimental_Agent, ToolLoopAgent, Experimental_DecisionRefusalError, Experimental_DecisionUnsupportedQuestionTypeError, Experimental_EvaluationUnsupportedQuestionTypeError, HttpChatTransport, InvalidArgumentError, InvalidDataContentError, InvalidMessageRoleError, InvalidPromptError, InvalidResponseDataError, InvalidStreamPartError, InvalidToolApprovalError, InvalidToolApprovalSignatureError, InvalidToolInputError, JSONParseError, JsonToSseTransformStream, LoadAPIKeyError, LoadSettingError, MessageConversionError, MissingToolResultsError, NoContentGeneratedError, NoImageGeneratedError, NoObjectGeneratedError, NoOutputGeneratedError, NoSpeechGeneratedError, NoSuchModelError, NoSuchProviderError, NoSuchProviderReferenceError, NoSuchToolError, NoTranscriptGeneratedError, NoTranslationGeneratedError, NoVideoGeneratedError, output_exports as Output, RetryError, SerialJobExecutor, StreamProviderError, TextStreamChatTransport, TooManyEmbeddingValuesForCallError, ToolCallNotFoundForApprovalError, ToolCallRepairError, ToolChoiceViolationError, TypeValidationError, UIMessageStreamError, UI_MESSAGE_STREAM_HEADERS, UnsupportedFunctionalityError, UnsupportedModelVersionError, WebSocketChatTransport, addToolInputExamplesMiddleware, asSchema, assistantModelMessageSchema, callCompletionApi, consumeStream, convertDataContentToBase64String, convertFileListToFileUIParts, convertToModelMessages, cosineSimilarity, createAgentUIStream, createAgentUIStreamResponse, createDownload, createGateway, createIdGenerator, createProviderRegistry, createTextStreamResponse, createUIMessageStream, createUIMessageStreamResponse, customProvider, defaultEmbeddingSettingsMiddleware, defaultInstructionsMiddleware, defaultSettingsMiddleware, detectToolDrift, dynamicTool, embed, embedMany, cancelBatch as experimental_cancelBatch, experimental_createProviderRegistry, decide as experimental_decide, decodeRealtimeAudio as experimental_decodeRealtimeAudio, encodeRealtimeAudio as experimental_encodeRealtimeAudio, experimental_evaluate, filterActiveTools as experimental_filterActiveTools, experimental_generateSpeech, experimental_generateVideo, getBatchResults as experimental_getBatchResults, getBatchStatus as experimental_getBatchStatus, getRealtimeToolDefinitions as experimental_getRealtimeToolDefinitions, experimental_getVideoStatus, listBatches as experimental_listBatches, resampleAudio as experimental_resampleAudio, startBatch as experimental_startBatch, experimental_startVideo, streamLanguageModelCall as experimental_streamLanguageModelCall, streamTranscribe as experimental_streamTranscribe, streamTranslate as experimental_streamTranslate, experimental_toolCaller, experimental_transcribe, extractJsonMiddleware, extractReasoningMiddleware, fingerprintTools, gateway, generateId, generateImage, generateObject, generateSpeech, generateText, getChunkTimeoutMs, getFirstChunkTimeoutMs, getStaticToolName, getStepTimeoutMs, getTextFromDataUrl, getToolName, getToolOrDynamicToolName, getToolTimeoutMs, getTotalTimeoutMs, hasToolCall, isCustomContentUIPart, isDataUIPart, isDeepEqualData, isDynamicToolUIPart, isFileUIPart, isLoopFinished, isReasoningFileUIPart, isReasoningUIPart, isStaticToolUIPart, isStepCount, isStepCount as stepCountIs, isTextUIPart, isToolOutputErrorUIPart, isToolUIPart, jsonSchema, lastAssistantMessageIsCompleteWithApprovalResponses, lastAssistantMessageIsCompleteWithToolCalls, modelMessageSchema, parseJsonEventStream, parsePartialJson, pipeAgentUIStreamToResponse, pipeTextStreamToResponse, pipeUIMessageStreamToResponse, pruneMessages, readUIMessageStream, registerTelemetry, rerank, safeValidateUIMessages, safeValidateWebSocketChatTransportRequest, simulateReadableStream, simulateStreamingMiddleware, smoothStream, streamObject, streamText, systemModelMessageSchema, toTextStream, toUIMessageChunk, toUIMessageStream, tool, toolModelMessageSchema, toolSearch, transcribe, uiMessageChunkSchema, uploadFile, uploadSkill, userModelMessageSchema, validateUIMessages, wrapEmbeddingModel, wrapImageModel, wrapLanguageModel, wrapProvider, zodSchema };
20325
20884
 
20326
20885
  //# sourceMappingURL=index.js.map