ai 7.0.133 → 7.0.135

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.
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.133";
1177
+ const VERSION = "7.0.135";
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 });
@@ -10310,6 +10310,27 @@ var DefaultStreamTextResult = class {
10310
10310
  }
10311
10311
  };
10312
10312
  //#endregion
10313
+ //#region src/agent/default-stop-condition.ts
10314
+ /**
10315
+ * Stop conditions are only evaluated when the tool loop can otherwise continue,
10316
+ * so logging here avoids warning when a call finishes naturally at the limit.
10317
+ */
10318
+ function createDefaultStopCondition(stepCount) {
10319
+ return ({ steps }) => {
10320
+ if (steps.length !== stepCount) return false;
10321
+ const { provider, modelId } = steps[steps.length - 1].model;
10322
+ logWarnings({
10323
+ provider,
10324
+ model: modelId,
10325
+ warnings: [{
10326
+ type: "other",
10327
+ 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`
10328
+ }]
10329
+ });
10330
+ return true;
10331
+ };
10332
+ }
10333
+ //#endregion
10313
10334
  //#region src/agent/tool-loop-agent.ts
10314
10335
  /**
10315
10336
  * A tool loop agent is an agent that runs tools in a loop. In each step,
@@ -10358,7 +10379,7 @@ var ToolLoopAgent = class {
10358
10379
  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
10380
  const baseCallArgs = {
10360
10381
  ...settingsWithoutCallbacks,
10361
- stopWhen: this.settings.stopWhen ?? isStepCount(20),
10382
+ stopWhen: this.settings.stopWhen ?? createDefaultStopCondition(20),
10362
10383
  ...options
10363
10384
  };
10364
10385
  const { instructions, allowSystemInMessages, messages, prompt, runtimeContext, ...callArgs } = await this.settings.prepareCall?.(baseCallArgs) ?? baseCallArgs;
@@ -12184,6 +12205,15 @@ function createRestrictedTelemetryDispatcher$2({ telemetry }) {
12184
12205
  };
12185
12206
  }
12186
12207
  //#endregion
12208
+ //#region src/embed/validate-embedding-dimensions.ts
12209
+ function validateEmbeddingDimensions(dimensions) {
12210
+ if (dimensions !== void 0 && (!Number.isInteger(dimensions) || dimensions <= 0)) throw new InvalidArgumentError({
12211
+ parameter: "dimensions",
12212
+ value: dimensions,
12213
+ message: "dimensions must be a positive integer"
12214
+ });
12215
+ }
12216
+ //#endregion
12187
12217
  //#region src/embed/embed.ts
12188
12218
  const originalGenerateCallId$6 = createIdGenerator$1({
12189
12219
  prefix: "call",
@@ -12195,6 +12225,8 @@ const originalGenerateCallId$6 = createIdGenerator$1({
12195
12225
  * @param model - The embedding model to use.
12196
12226
  * @param value - The value that should be embedded.
12197
12227
  *
12228
+ * @param dimensions - Requested output dimensions. Must be a positive integer. Requires provider support.
12229
+ *
12198
12230
  * @param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2.
12199
12231
  * @param abortSignal - An optional abort signal that can be used to cancel the call.
12200
12232
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
@@ -12208,7 +12240,8 @@ const originalGenerateCallId$6 = createIdGenerator$1({
12208
12240
  *
12209
12241
  * @returns A result object that contains the embedding, the value, and additional information.
12210
12242
  */
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 } = {} }) {
12243
+ 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 } = {} }) {
12244
+ validateEmbeddingDimensions(dimensions);
12212
12245
  const model = resolveEmbeddingModel(modelArg);
12213
12246
  const { maxRetries, retry } = prepareRetries({
12214
12247
  maxRetries: maxRetriesArg,
@@ -12227,6 +12260,7 @@ async function embed({ model: modelArg, value, providerOptions, maxRetries: maxR
12227
12260
  provider: model.provider,
12228
12261
  modelId: model.modelId,
12229
12262
  value,
12263
+ dimensions,
12230
12264
  maxRetries,
12231
12265
  headers: headersWithUserAgent,
12232
12266
  providerOptions
@@ -12249,12 +12283,14 @@ async function embed({ model: modelArg, value, providerOptions, maxRetries: maxR
12249
12283
  operationId: "ai.embed.doEmbed",
12250
12284
  provider: model.provider,
12251
12285
  modelId: model.modelId,
12252
- values: [value]
12286
+ values: [value],
12287
+ dimensions
12253
12288
  },
12254
12289
  callbacks: [telemetryDispatcher.onEmbedStart]
12255
12290
  });
12256
12291
  const modelResponse = await model.doEmbed({
12257
12292
  values: [value],
12293
+ dimensions,
12258
12294
  abortSignal,
12259
12295
  headers: headersWithUserAgent,
12260
12296
  providerOptions
@@ -12383,6 +12419,8 @@ const originalGenerateCallId$5 = createIdGenerator$1({
12383
12419
  * @param model - The embedding model to use.
12384
12420
  * @param values - The values that should be embedded.
12385
12421
  *
12422
+ * @param dimensions - Requested output dimensions. Must be a positive integer. Requires provider support.
12423
+ *
12386
12424
  * @param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2.
12387
12425
  * @param abortSignal - An optional abort signal that can be used to cancel the call.
12388
12426
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
@@ -12400,7 +12438,8 @@ const originalGenerateCallId$5 = createIdGenerator$1({
12400
12438
  *
12401
12439
  * @returns A result object that contains the embeddings, the value, and additional information.
12402
12440
  */
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 } = {} }) {
12441
+ 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 } = {} }) {
12442
+ validateEmbeddingDimensions(dimensions);
12404
12443
  const model = resolveEmbeddingModel(modelArg);
12405
12444
  const { maxRetries, retry } = prepareRetries({
12406
12445
  maxRetries: maxRetriesArg,
@@ -12419,6 +12458,7 @@ async function embedMany({ model: modelArg, values, maxParallelCalls = Infinity,
12419
12458
  provider: model.provider,
12420
12459
  modelId: model.modelId,
12421
12460
  value: values,
12461
+ dimensions,
12422
12462
  maxRetries,
12423
12463
  headers: headersWithUserAgent,
12424
12464
  providerOptions
@@ -12449,12 +12489,14 @@ async function embedMany({ model: modelArg, values, maxParallelCalls = Infinity,
12449
12489
  operationId: "ai.embedMany.doEmbed",
12450
12490
  provider: model.provider,
12451
12491
  modelId: model.modelId,
12452
- values
12492
+ values,
12493
+ dimensions
12453
12494
  },
12454
12495
  callbacks: [telemetryDispatcher.onEmbedStart]
12455
12496
  });
12456
12497
  const modelResponse = await model.doEmbed({
12457
12498
  values,
12499
+ dimensions,
12458
12500
  abortSignal,
12459
12501
  headers: headersWithUserAgent,
12460
12502
  providerOptions
@@ -12548,12 +12590,14 @@ async function embedMany({ model: modelArg, values, maxParallelCalls = Infinity,
12548
12590
  operationId: "ai.embedMany.doEmbed",
12549
12591
  provider: model.provider,
12550
12592
  modelId: model.modelId,
12551
- values: chunk
12593
+ values: chunk,
12594
+ dimensions
12552
12595
  },
12553
12596
  callbacks: [telemetryDispatcher.onEmbedStart]
12554
12597
  });
12555
12598
  const modelResponse = await model.doEmbed({
12556
12599
  values: chunk,
12600
+ dimensions,
12557
12601
  abortSignal,
12558
12602
  headers: headersWithUserAgent,
12559
12603
  providerOptions: chunkProviderOptions
@@ -12733,7 +12777,7 @@ function createRestrictedTelemetryDispatcher$1({ telemetry }) {
12733
12777
  //#endregion
12734
12778
  //#region src/decide/validate-decision.ts
12735
12779
  const tolerance = 1e-6;
12736
- function isRecord(value) {
12780
+ function isRecord$1(value) {
12737
12781
  if (value == null || typeof value !== "object" || Array.isArray(value)) return false;
12738
12782
  const prototype = Object.getPrototypeOf(value);
12739
12783
  return prototype === Object.prototype || prototype === null;
@@ -12741,7 +12785,7 @@ function isRecord(value) {
12741
12785
  function isJSON(value, ancestors = /* @__PURE__ */ new Set()) {
12742
12786
  if (value === null || typeof value === "string" || typeof value === "boolean") return true;
12743
12787
  if (typeof value === "number") return Number.isFinite(value);
12744
- if (typeof value !== "object" || !Array.isArray(value) && !isRecord(value)) return false;
12788
+ if (typeof value !== "object" || !Array.isArray(value) && !isRecord$1(value)) return false;
12745
12789
  if (ancestors.has(value)) return false;
12746
12790
  ancestors.add(value);
12747
12791
  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 +12793,7 @@ function isJSON(value, ancestors = /* @__PURE__ */ new Set()) {
12749
12793
  return valid;
12750
12794
  }
12751
12795
  function isInput(value) {
12752
- return (typeof value === "string" || Array.isArray(value) || isRecord(value)) && isJSON(value);
12796
+ return (typeof value === "string" || Array.isArray(value) || isRecord$1(value)) && isJSON(value);
12753
12797
  }
12754
12798
  function invalidInput(parameter, value, message) {
12755
12799
  throw new InvalidArgumentError({
@@ -12760,29 +12804,29 @@ function invalidInput(parameter, value, message) {
12760
12804
  }
12761
12805
  function validateDecisionInput({ state, questions }) {
12762
12806
  if (!(Array.isArray(state) ? Array.from(state).every((part) => {
12763
- if (!isRecord(part)) return false;
12807
+ if (!isRecord$1(part)) return false;
12764
12808
  switch (part.type) {
12765
12809
  case "text": return textPartSchema.safeParse(part).success;
12766
12810
  case "file": return filePartSchema.safeParse(part).success;
12767
12811
  case "json": return isJSON(part.value);
12768
12812
  default: return false;
12769
12813
  }
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");
12814
+ }) : (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");
12815
+ if (!isRecord$1(questions) || Object.keys(questions).length === 0) invalidInput("questions", questions, "must be a nonempty question map");
12772
12816
  for (const [id, question] of Object.entries(questions)) {
12773
12817
  const parameter = `questions.${id}`;
12774
- if (!isRecord(question) || !isInput(question.instructions)) invalidInput(parameter, question, "instructions must be a JSON-compatible string, object, or array");
12818
+ if (!isRecord$1(question) || !isInput(question.instructions)) invalidInput(parameter, question, "instructions must be a JSON-compatible string, object, or array");
12775
12819
  const criteria = question.criteria;
12776
12820
  switch (question.type) {
12777
12821
  case "choice":
12778
- if (!isRecord(criteria) || Object.keys(criteria).length === 0) invalidInput(parameter, question, "choice criteria must be a nonempty option map");
12822
+ if (!isRecord$1(criteria) || Object.keys(criteria).length === 0) invalidInput(parameter, question, "choice criteria must be a nonempty option map");
12779
12823
  break;
12780
12824
  case "score":
12781
12825
  if (!Array.isArray(criteria) || criteria.length < 2) invalidInput(parameter, question, "score criteria must contain at least two ordered levels");
12782
12826
  break;
12783
12827
  case "boolean":
12784
12828
  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");
12829
+ 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
12830
  break;
12787
12831
  default: invalidInput(parameter, question, "question type must be choice, score, or boolean");
12788
12832
  }
@@ -12802,7 +12846,7 @@ function hasExactKeys(value, keys) {
12802
12846
  return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
12803
12847
  }
12804
12848
  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].`);
12849
+ 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
12850
  const sum = Object.values(value).reduce((total, probability) => total + probability, 0);
12807
12851
  if (Math.abs(sum - 1) > tolerance + keys.length * roundingError) invalidAnswer(answers, `Question "${id}" probabilities must sum to 1 within the declared rounding precision.`);
12808
12852
  }
@@ -12814,11 +12858,11 @@ function validateDecisionAnswers({ questions, answers, rounding }) {
12814
12858
  }
12815
12859
  const probabilityError = roundingError(rounding?.probabilityDecimals);
12816
12860
  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.");
12861
+ if (!isRecord$1(answers) || !hasExactKeys(answers, Object.keys(questions))) invalidAnswer(answers, "Decision must return exactly one answer for every question.");
12818
12862
  for (const [id, question] of Object.entries(questions)) {
12819
12863
  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.`);
12864
+ if (isRecord$1(answer) && answer.type === "refusal") continue;
12865
+ if (!isRecord$1(answer) || answer.type !== question.type) invalidAnswer(answers, `Question "${id}" returned an answer with the wrong type.`);
12822
12866
  switch (question.type) {
12823
12867
  case "choice":
12824
12868
  if (typeof answer.choice !== "string" || !Object.hasOwn(question.criteria, answer.choice)) invalidAnswer(answers, `Question "${id}" selected an unknown option.`);
@@ -13721,15 +13765,20 @@ var SerialJobExecutor = class {
13721
13765
  constructor() {
13722
13766
  this.queue = [];
13723
13767
  this.isProcessing = false;
13768
+ this.idleWaiters = [];
13724
13769
  }
13725
13770
  async processQueue() {
13726
13771
  if (this.isProcessing) return;
13727
13772
  this.isProcessing = true;
13728
- while (this.queue.length > 0) {
13729
- await this.queue[0]();
13730
- this.queue.shift();
13773
+ try {
13774
+ while (this.queue.length > 0) {
13775
+ await this.queue[0]();
13776
+ this.queue.shift();
13777
+ }
13778
+ } finally {
13779
+ this.isProcessing = false;
13780
+ for (const resolve of this.idleWaiters.splice(0)) resolve();
13731
13781
  }
13732
- this.isProcessing = false;
13733
13782
  }
13734
13783
  async run(job) {
13735
13784
  return new Promise((resolve, reject) => {
@@ -13744,6 +13793,12 @@ var SerialJobExecutor = class {
13744
13793
  this.processQueue();
13745
13794
  });
13746
13795
  }
13796
+ async waitForIdle() {
13797
+ if (!this.isProcessing && this.queue.length === 0) return;
13798
+ await new Promise((resolve) => {
13799
+ this.idleWaiters.push(resolve);
13800
+ });
13801
+ }
13747
13802
  };
13748
13803
  //#endregion
13749
13804
  //#region src/util/simulate-readable-stream.ts
@@ -19677,6 +19732,8 @@ var AbstractChat = class {
19677
19732
  this.activeResumeRequest = void 0;
19678
19733
  this.resumableStreamState = void 0;
19679
19734
  this.jobExecutor = new SerialJobExecutor();
19735
+ this.activeStopCount = 0;
19736
+ this.stopGeneration = 0;
19680
19737
  this.sendMessage = async (message, options) => {
19681
19738
  if (message == null) {
19682
19739
  let messageId = this.pendingApprovalMessageId;
@@ -19793,16 +19850,17 @@ var AbstractChat = class {
19793
19850
  this.pendingApprovalMessageId = message.id;
19794
19851
  }
19795
19852
  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) this.shouldSendAutomatically().then((shouldSend) => {
19797
- if (shouldSend) {
19853
+ if (messageIndex !== -1 && this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
19854
+ const shouldSend = await this.shouldSendAutomatically();
19855
+ if (shouldSend) this.runAutomaticRequest(() => {
19798
19856
  const messageId = messageIndex === -1 ? this.lastMessage?.id : messages[messageIndex].id;
19799
- this.makeRequestForToolApproval({
19857
+ return this.makeRequestForToolApproval({
19800
19858
  messageId,
19801
19859
  messageIndex,
19802
19860
  ...options
19803
19861
  });
19804
- }
19805
- });
19862
+ }, shouldSend);
19863
+ }
19806
19864
  });
19807
19865
  this.addToolOutput = async ({ state, toolCallId, output, errorText, options }) => this.jobExecutor.run(async () => {
19808
19866
  const messages = this.state.messages;
@@ -19835,19 +19893,34 @@ var AbstractChat = class {
19835
19893
  parts: lastMessage.parts.map(updatePart)
19836
19894
  });
19837
19895
  if (this.activeResponse) this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(updatePart);
19838
- if (this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) this.shouldSendAutomatically().then((shouldSend) => {
19839
- if (shouldSend) this.makeRequest({
19896
+ if (this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
19897
+ const shouldSend = await this.shouldSendAutomatically();
19898
+ if (shouldSend) this.runAutomaticRequest(() => this.makeRequest({
19840
19899
  trigger: "submit-message",
19841
19900
  messageId: this.lastMessage?.id,
19842
19901
  ...options
19843
- });
19844
- });
19902
+ }), shouldSend);
19903
+ }
19845
19904
  });
19846
19905
  this.addToolResult = this.addToolOutput;
19847
19906
  this.stop = async () => {
19848
- for (const controller of this.pendingMessagePreparations) controller.abort();
19849
- this.activeResumeRequest?.abortController.abort();
19850
- this.activeResponse?.abortController.abort();
19907
+ this.activeStopCount++;
19908
+ this.stopGeneration++;
19909
+ try {
19910
+ const activeResumeRequest = this.activeResumeRequest;
19911
+ const activeResponse = this.activeResponse;
19912
+ for (const controller of this.pendingMessagePreparations) controller.abort();
19913
+ activeResumeRequest?.abortController.abort();
19914
+ activeResponse?.abortController.abort();
19915
+ await Promise.all([activeResumeRequest?.completionPromise, activeResponse?.completionPromise]);
19916
+ await this.jobExecutor.waitForIdle();
19917
+ } finally {
19918
+ this.activeStopCount--;
19919
+ }
19920
+ };
19921
+ this.dispose = async () => {
19922
+ await this.stop();
19923
+ this.transport.close?.();
19851
19924
  };
19852
19925
  this.id = id;
19853
19926
  this.transport = transport;
@@ -19898,6 +19971,13 @@ var AbstractChat = class {
19898
19971
  if (result && typeof result === "object" && "then" in result) return await result;
19899
19972
  return result;
19900
19973
  }
19974
+ async runAutomaticRequest(request, shouldSend) {
19975
+ const stopGeneration = this.stopGeneration;
19976
+ const startedWhileStopping = this.activeStopCount > 0;
19977
+ if (!(shouldSend ?? await this.shouldSendAutomatically())) return;
19978
+ if (startedWhileStopping || stopGeneration !== this.stopGeneration || this.activeStopCount > 0) return;
19979
+ await request();
19980
+ }
19901
19981
  async makeRequestForToolApproval({ messageId, messageIndex, ...options }) {
19902
19982
  const consumesPendingApproval = messageId != null && messageId === this.pendingApprovalMessageId;
19903
19983
  if (consumesPendingApproval) this.pendingApprovalMessageId = void 0;
@@ -19908,10 +19988,24 @@ var AbstractChat = class {
19908
19988
  });
19909
19989
  if (consumesPendingApproval && this.status === "error" && this.pendingApprovalMessageId == null) this.pendingApprovalMessageId = this.state.messages[messageIndex]?.id ?? messageId;
19910
19990
  }
19911
- async makeRequest({ trigger, metadata, headers, body, messageId }) {
19991
+ async makeRequest(options) {
19992
+ const completion = createResolvablePromise();
19993
+ try {
19994
+ await this.makeRequestImpl({
19995
+ ...options,
19996
+ completionPromise: completion.promise
19997
+ });
19998
+ } finally {
19999
+ completion.resolve();
20000
+ }
20001
+ }
20002
+ async makeRequestImpl({ trigger, metadata, headers, body, messageId, completionPromise }) {
19912
20003
  if (trigger !== "resume-stream") this.resumableStreamState = void 0;
19913
20004
  const abortController = new AbortController();
19914
- const activeResumeRequest = trigger === "resume-stream" ? { abortController } : void 0;
20005
+ const activeResumeRequest = trigger === "resume-stream" ? {
20006
+ abortController,
20007
+ completionPromise
20008
+ } : void 0;
19915
20009
  if (activeResumeRequest) {
19916
20010
  this.activeResumeRequest?.abortController.abort();
19917
20011
  this.activeResumeRequest = activeResumeRequest;
@@ -19970,7 +20064,7 @@ var AbstractChat = class {
19970
20064
  const lastMessage = this.lastMessage;
19971
20065
  const responseMessageIndex = trigger === "submit-message" && messageId != null ? this.state.messages.findIndex((message) => message.id === messageId) : this.state.messages.length - 1;
19972
20066
  const responseMessage = responseMessageIndex === -1 ? lastMessage : this.state.messages[responseMessageIndex];
19973
- const resumableResponseMessage = trigger === "resume-stream" && responseMessage?.role === "assistant" && responseMessage.parts.some((part) => isToolUIPart(part) && (part.state === "input-streaming" || part.state === "approval-responded")) ? this.state.snapshot(responseMessage) : void 0;
20067
+ const resumableResponseMessage = trigger === "resume-stream" && responseMessage?.role === "assistant" && responseMessage.parts.some((part) => isToolUIPart(part) && (part.state === "input-streaming" || part.state === "input-available" && part.providerExecuted || part.state === "approval-responded")) ? this.state.snapshot(responseMessage) : void 0;
19974
20068
  const usesEarlierAssistantMessage = responseMessageIndex !== -1 && responseMessageIndex < this.state.messages.length - 1 && responseMessage?.role === "assistant";
19975
20069
  let isAbort = false;
19976
20070
  let isDisconnect = false;
@@ -19982,7 +20076,8 @@ var AbstractChat = class {
19982
20076
  lastMessage: trigger === "resume-stream" ? resumableResponseMessage : trigger === "regenerate-message" ? void 0 : this.state.snapshot(responseMessage),
19983
20077
  messageId: this.generateId()
19984
20078
  }),
19985
- abortController
20079
+ abortController,
20080
+ completionPromise
19986
20081
  };
19987
20082
  activeResponse = response;
19988
20083
  response.abortController.signal.addEventListener("abort", () => {
@@ -20018,6 +20113,7 @@ var AbstractChat = class {
20018
20113
  stream: processUIMessageStream({
20019
20114
  stream,
20020
20115
  resetStateOnMessageIdChange: trigger === "resume-stream",
20116
+ resetStateOnFirstMessageStart: trigger === "resume-stream" && this.transport.resumeStreamIsReplay,
20021
20117
  onToolCall: this.onToolCall,
20022
20118
  onData: this.onData,
20023
20119
  messageMetadataSchema: this.messageMetadataSchema,
@@ -20080,13 +20176,13 @@ var AbstractChat = class {
20080
20176
  clearActiveResumeRequest();
20081
20177
  }
20082
20178
  }
20083
- if (!isError && await this.shouldSendAutomatically()) await this.makeRequest({
20179
+ if (!isAbort && !isError) await this.runAutomaticRequest(() => this.makeRequest({
20084
20180
  trigger: "submit-message",
20085
20181
  messageId: this.lastMessage?.id,
20086
20182
  metadata,
20087
20183
  headers,
20088
20184
  body
20089
- });
20185
+ }));
20090
20186
  }
20091
20187
  };
20092
20188
  //#endregion
@@ -20221,6 +20317,460 @@ var TextStreamChatTransport = class extends HttpChatTransport {
20221
20317
  }
20222
20318
  };
20223
20319
  //#endregion
20320
+ //#region src/ui/websocket-chat-transport.ts
20321
+ const WEBSOCKET_OPEN_STATE = 1;
20322
+ function createAbortError(signal) {
20323
+ const reason = signal?.reason;
20324
+ if (reason instanceof Error) return reason;
20325
+ const error = /* @__PURE__ */ new Error("The WebSocket chat request was aborted.");
20326
+ error.name = "AbortError";
20327
+ return error;
20328
+ }
20329
+ function asError(error) {
20330
+ return error instanceof Error ? error : new Error(String(error));
20331
+ }
20332
+ function isRecord(value) {
20333
+ return value != null && typeof value === "object" && !Array.isArray(value);
20334
+ }
20335
+ function isStringRecord(value) {
20336
+ return isRecord(value) && Object.values(value).every((item) => typeof item === "string");
20337
+ }
20338
+ function isSequence(value) {
20339
+ return Number.isSafeInteger(value) && value >= 0;
20340
+ }
20341
+ /**
20342
+ * Validates an untrusted client-to-server WebSocket chat frame.
20343
+ */
20344
+ async function safeValidateWebSocketChatTransportRequest({ value }) {
20345
+ try {
20346
+ if (!isRecord(value) || typeof value.type !== "string") throw new Error("Invalid WebSocket chat request frame.");
20347
+ if (value.type === "abort") {
20348
+ if (typeof value.requestId !== "string") throw new Error("Invalid WebSocket chat abort request.");
20349
+ return {
20350
+ success: true,
20351
+ data: value
20352
+ };
20353
+ }
20354
+ if (typeof value.requestId !== "string" || typeof value.id !== "string" || !isStringRecord(value.headers) || !isRecord(value.body)) throw new Error("Invalid WebSocket chat request frame.");
20355
+ if (value.type === "resume") {
20356
+ if (value.lastSequence !== void 0 && !isSequence(value.lastSequence)) throw new Error("Invalid WebSocket chat resume sequence.");
20357
+ return {
20358
+ success: true,
20359
+ data: value
20360
+ };
20361
+ }
20362
+ 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.");
20363
+ const messages = await safeValidateUIMessages({ messages: value.messages });
20364
+ if (!messages.success) throw new Error("Invalid UI messages in WebSocket chat request.", { cause: messages.error });
20365
+ return {
20366
+ success: true,
20367
+ data: {
20368
+ ...value,
20369
+ messages: messages.data
20370
+ }
20371
+ };
20372
+ } catch (error) {
20373
+ return {
20374
+ success: false,
20375
+ error: asError(error)
20376
+ };
20377
+ }
20378
+ }
20379
+ /**
20380
+ * A `ChatTransport` that multiplexes correlated UI message streams over one
20381
+ * persistent WebSocket connection.
20382
+ *
20383
+ * The server must implement the protocol represented by
20384
+ * `WebSocketChatTransportRequest` and `WebSocketChatTransportResponse`.
20385
+ */
20386
+ var WebSocketChatTransport = class {
20387
+ constructor(options) {
20388
+ this.resumeStreamIsReplay = true;
20389
+ this.activeRequests = /* @__PURE__ */ new Map();
20390
+ this.sendQueue = Promise.resolve();
20391
+ this.url = options.url;
20392
+ this.protocols = options.protocols;
20393
+ this.params = options.params;
20394
+ this.headers = options.headers;
20395
+ this.body = options.body;
20396
+ this.webSocket = options.webSocket;
20397
+ this.prepareSendMessagesRequest = options.prepareSendMessagesRequest;
20398
+ this.prepareReconnectToStreamRequest = options.prepareReconnectToStreamRequest;
20399
+ }
20400
+ async sendMessages({ abortSignal, ...options }) {
20401
+ this.throwIfAborted(abortSignal);
20402
+ const [resolvedHeaders, resolvedBody] = await Promise.all([resolve(this.headers), resolve(this.body)]);
20403
+ this.throwIfAborted(abortSignal);
20404
+ const headers = {
20405
+ ...normalizeHeaders(resolvedHeaders),
20406
+ ...normalizeHeaders(options.headers)
20407
+ };
20408
+ const body = {
20409
+ ...resolvedBody,
20410
+ ...options.body
20411
+ };
20412
+ const preparedRequest = await this.prepareSendMessagesRequest?.({
20413
+ id: options.chatId,
20414
+ messages: options.messages,
20415
+ requestMetadata: options.metadata,
20416
+ body,
20417
+ headers,
20418
+ trigger: options.trigger,
20419
+ messageId: options.messageId
20420
+ });
20421
+ this.throwIfAborted(abortSignal);
20422
+ const socket = await this.getSocket(abortSignal);
20423
+ const requestId = generateId$1();
20424
+ const request = this.createActiveRequest({
20425
+ requestId,
20426
+ kind: "send",
20427
+ lastSequence: -1,
20428
+ abortSignal
20429
+ });
20430
+ const frame = {
20431
+ type: "send",
20432
+ requestId,
20433
+ id: options.chatId,
20434
+ trigger: options.trigger,
20435
+ messageId: options.messageId,
20436
+ messages: preparedRequest?.messages ?? options.messages,
20437
+ headers: preparedRequest?.headers == null ? headers : normalizeHeaders(preparedRequest.headers),
20438
+ body: preparedRequest?.body ?? body,
20439
+ metadata: options.metadata
20440
+ };
20441
+ try {
20442
+ await this.sendFrame(socket, frame, abortSignal);
20443
+ return request.stream;
20444
+ } catch (error) {
20445
+ const requestError = asError(error);
20446
+ this.failRequest(request, requestError);
20447
+ throw requestError;
20448
+ }
20449
+ }
20450
+ async reconnectToStream(options) {
20451
+ this.throwIfAborted(options.abortSignal);
20452
+ const [resolvedHeaders, resolvedBody] = await Promise.all([resolve(this.headers), resolve(this.body)]);
20453
+ this.throwIfAborted(options.abortSignal);
20454
+ const headers = {
20455
+ ...normalizeHeaders(resolvedHeaders),
20456
+ ...normalizeHeaders(options.headers)
20457
+ };
20458
+ const body = {
20459
+ ...resolvedBody,
20460
+ ...options.body
20461
+ };
20462
+ const preparedRequest = await this.prepareReconnectToStreamRequest?.({
20463
+ id: options.chatId,
20464
+ requestMetadata: options.metadata,
20465
+ body,
20466
+ headers
20467
+ });
20468
+ this.throwIfAborted(options.abortSignal);
20469
+ const socket = await this.getSocket(options.abortSignal);
20470
+ const requestId = generateId$1();
20471
+ let resolveResponse;
20472
+ let rejectResponse;
20473
+ const responsePromise = new Promise((resolve, reject) => {
20474
+ resolveResponse = resolve;
20475
+ rejectResponse = reject;
20476
+ });
20477
+ responsePromise.catch(() => {});
20478
+ const request = this.createActiveRequest({
20479
+ requestId,
20480
+ kind: "resume",
20481
+ lastSequence: -1,
20482
+ abortSignal: options.abortSignal,
20483
+ resolveResponse,
20484
+ rejectResponse
20485
+ });
20486
+ const frame = {
20487
+ type: "resume",
20488
+ requestId,
20489
+ id: options.chatId,
20490
+ lastSequence: void 0,
20491
+ headers: preparedRequest?.headers == null ? headers : normalizeHeaders(preparedRequest.headers),
20492
+ body: preparedRequest?.body ?? body,
20493
+ metadata: options.metadata
20494
+ };
20495
+ try {
20496
+ await this.sendFrame(socket, frame, options.abortSignal);
20497
+ } catch (error) {
20498
+ const requestError = asError(error);
20499
+ request.responseSettled = true;
20500
+ this.failRequest(request, requestError);
20501
+ throw requestError;
20502
+ }
20503
+ return responsePromise;
20504
+ }
20505
+ /**
20506
+ * Closes the current connection and errors any active response streams.
20507
+ * A later request opens a new connection.
20508
+ */
20509
+ close() {
20510
+ const error = /* @__PURE__ */ new Error("WebSocket chat transport was closed.");
20511
+ const connection = this.connection;
20512
+ this.connection = void 0;
20513
+ this.failAllRequests(error);
20514
+ if (connection != null) {
20515
+ this.rejectConnection(connection, error);
20516
+ try {
20517
+ connection.socket?.close(1e3, "Client closed transport");
20518
+ } catch {}
20519
+ }
20520
+ }
20521
+ throwIfAborted(abortSignal) {
20522
+ if (abortSignal?.aborted) throw createAbortError(abortSignal);
20523
+ }
20524
+ async getSocket(abortSignal) {
20525
+ const existingSocket = this.connection?.socket;
20526
+ if (existingSocket?.readyState === WEBSOCKET_OPEN_STATE) return existingSocket;
20527
+ if (this.connection == null) {
20528
+ let resolveConnection;
20529
+ let rejectConnection;
20530
+ const connection = {
20531
+ promise: new Promise((resolve, reject) => {
20532
+ resolveConnection = resolve;
20533
+ rejectConnection = reject;
20534
+ }),
20535
+ resolve: resolveConnection,
20536
+ reject: rejectConnection,
20537
+ settled: false
20538
+ };
20539
+ this.connection = connection;
20540
+ this.initializeConnection(connection);
20541
+ }
20542
+ const connection = this.connection;
20543
+ if (connection == null) throw new Error("Failed to initialize WebSocket connection.");
20544
+ return this.waitForConnection(connection.promise, abortSignal);
20545
+ }
20546
+ async initializeConnection(connection) {
20547
+ try {
20548
+ const params = await resolve(this.params);
20549
+ if (this.connection !== connection) return;
20550
+ const url = this.buildUrl(params);
20551
+ const socket = new (getWebSocketConstructor(this.webSocket))(url, this.protocols);
20552
+ connection.socket = socket;
20553
+ let messageTail = Promise.resolve();
20554
+ socket.onopen = () => {
20555
+ if (this.connection !== connection) return;
20556
+ this.resolveConnection(connection, socket);
20557
+ };
20558
+ socket.onmessage = (event) => {
20559
+ messageTail = messageTail.then(() => readWebSocketMessageText(event.data)).then((text) => this.handleResponseFrame(connection, text)).catch((error) => {
20560
+ this.terminateConnection(connection, asError(error));
20561
+ });
20562
+ };
20563
+ socket.onerror = () => {
20564
+ this.terminateConnection(connection, /* @__PURE__ */ new TypeError("WebSocket chat network connection failed."));
20565
+ };
20566
+ socket.onclose = (event) => {
20567
+ messageTail = messageTail.then(() => {
20568
+ if (this.connection !== connection) return;
20569
+ const closeEvent = event;
20570
+ const code = typeof closeEvent?.code === "number" ? closeEvent.code : void 0;
20571
+ const reason = typeof closeEvent?.reason === "string" && closeEvent.reason !== "" ? `: ${closeEvent.reason}` : "";
20572
+ this.terminateConnection(connection, /* @__PURE__ */ new TypeError(`WebSocket chat network connection closed${code == null ? "" : ` (code ${code}${reason})`}.`), false);
20573
+ }).catch((error) => {
20574
+ this.terminateConnection(connection, asError(error));
20575
+ });
20576
+ };
20577
+ } catch (error) {
20578
+ this.terminateConnection(connection, asError(error), false);
20579
+ }
20580
+ }
20581
+ buildUrl(params) {
20582
+ let url;
20583
+ try {
20584
+ const baseUrl = typeof globalThis.location === "undefined" ? void 0 : globalThis.location.href;
20585
+ url = new URL(this.url, baseUrl);
20586
+ url = toWebSocketUrl(url);
20587
+ } catch {
20588
+ throw new Error("Invalid WebSocket chat URL. Use an absolute URL outside the browser.");
20589
+ }
20590
+ if (!["ws:", "wss:"].includes(url.protocol) || url.hostname === "") throw new Error("Invalid WebSocket chat URL. Expected ws:// or wss://.");
20591
+ if (url.hash !== "") throw new Error("Invalid WebSocket chat URL. Fragments are not allowed.");
20592
+ for (const [key, value] of Object.entries(params ?? {})) url.searchParams.set(key, value);
20593
+ return url;
20594
+ }
20595
+ waitForConnection(promise, abortSignal) {
20596
+ if (abortSignal == null) return promise;
20597
+ if (abortSignal.aborted) return Promise.reject(createAbortError(abortSignal));
20598
+ return new Promise((resolve, reject) => {
20599
+ const onAbort = () => {
20600
+ reject(createAbortError(abortSignal));
20601
+ };
20602
+ abortSignal.addEventListener("abort", onAbort, { once: true });
20603
+ promise.then((socket) => {
20604
+ abortSignal.removeEventListener("abort", onAbort);
20605
+ resolve(socket);
20606
+ }, (error) => {
20607
+ abortSignal.removeEventListener("abort", onAbort);
20608
+ reject(error);
20609
+ });
20610
+ });
20611
+ }
20612
+ resolveConnection(connection, socket) {
20613
+ if (connection.settled) return;
20614
+ connection.settled = true;
20615
+ connection.resolve(socket);
20616
+ }
20617
+ rejectConnection(connection, error) {
20618
+ if (connection.settled) return;
20619
+ connection.settled = true;
20620
+ connection.reject(error);
20621
+ }
20622
+ terminateConnection(connection, error, closeSocket = true) {
20623
+ if (this.connection !== connection) return;
20624
+ this.connection = void 0;
20625
+ this.rejectConnection(connection, error);
20626
+ this.failAllRequests(error);
20627
+ if (closeSocket) try {
20628
+ connection.socket?.close(1011, "WebSocket chat transport error");
20629
+ } catch {}
20630
+ }
20631
+ createActiveRequest({ requestId, kind, lastSequence, abortSignal, resolveResponse, rejectResponse }) {
20632
+ let controller;
20633
+ const request = {
20634
+ requestId,
20635
+ kind,
20636
+ lastSequence,
20637
+ stream: new ReadableStream({
20638
+ start(streamController) {
20639
+ controller = streamController;
20640
+ },
20641
+ cancel: () => {
20642
+ this.abortRequest(requestId, false);
20643
+ }
20644
+ }),
20645
+ controller,
20646
+ responseSettled: false,
20647
+ resolveResponse,
20648
+ rejectResponse,
20649
+ abortSignal
20650
+ };
20651
+ this.activeRequests.set(requestId, request);
20652
+ if (abortSignal != null) {
20653
+ const abortListener = () => {
20654
+ this.abortRequest(requestId, true);
20655
+ };
20656
+ request.abortListener = abortListener;
20657
+ abortSignal.addEventListener("abort", abortListener, { once: true });
20658
+ if (abortSignal.aborted) abortListener();
20659
+ }
20660
+ return request;
20661
+ }
20662
+ abortRequest(requestId, closeStream) {
20663
+ const request = this.activeRequests.get(requestId);
20664
+ if (request == null) return;
20665
+ const error = createAbortError(request.abortSignal);
20666
+ if (request.kind === "resume" && !request.responseSettled) {
20667
+ request.responseSettled = true;
20668
+ request.rejectResponse?.(error);
20669
+ }
20670
+ this.cleanupRequest(request);
20671
+ if (closeStream) try {
20672
+ request.controller.close();
20673
+ } catch {}
20674
+ const socket = this.connection?.socket;
20675
+ if (socket?.readyState === WEBSOCKET_OPEN_STATE) this.sendFrame(socket, {
20676
+ type: "abort",
20677
+ requestId
20678
+ }).catch(() => {});
20679
+ }
20680
+ cleanupRequest(request) {
20681
+ this.activeRequests.delete(request.requestId);
20682
+ if (request.abortListener != null) {
20683
+ request.abortSignal?.removeEventListener("abort", request.abortListener);
20684
+ request.abortListener = void 0;
20685
+ }
20686
+ }
20687
+ failRequest(request, error) {
20688
+ if (!this.activeRequests.has(request.requestId)) return;
20689
+ if (request.kind === "resume" && !request.responseSettled) {
20690
+ request.responseSettled = true;
20691
+ request.rejectResponse?.(error);
20692
+ }
20693
+ this.cleanupRequest(request);
20694
+ try {
20695
+ request.controller.error(error);
20696
+ } catch {}
20697
+ }
20698
+ failAllRequests(error) {
20699
+ for (const request of [...this.activeRequests.values()]) this.failRequest(request, error);
20700
+ }
20701
+ resolveResumeStream(request) {
20702
+ if (request.kind !== "resume" || request.responseSettled) return;
20703
+ request.responseSettled = true;
20704
+ request.resolveResponse?.(request.stream);
20705
+ }
20706
+ async validateResponseChunk(value) {
20707
+ const chunk = await safeValidateTypes({
20708
+ value,
20709
+ schema: uiMessageChunkSchema
20710
+ });
20711
+ if (!chunk.success) throw new Error("Invalid UI message chunk in WebSocket response.");
20712
+ return chunk.value;
20713
+ }
20714
+ async handleResponseFrame(connection, text) {
20715
+ if (this.connection !== connection) return;
20716
+ const parsed = await safeParseJSON({ text });
20717
+ if (!parsed.success || !isRecord(parsed.value)) throw new Error("Invalid WebSocket chat response frame.");
20718
+ const type = parsed.value.type;
20719
+ const requestId = parsed.value.requestId;
20720
+ if (typeof type !== "string" || typeof requestId !== "string") throw new Error("Invalid WebSocket chat response frame.");
20721
+ const request = this.activeRequests.get(requestId);
20722
+ if (request == null) return;
20723
+ switch (type) {
20724
+ case "start":
20725
+ this.resolveResumeStream(request);
20726
+ return;
20727
+ case "chunk": {
20728
+ if (!isSequence(parsed.value.sequence)) throw new Error("Invalid WebSocket chat chunk sequence.");
20729
+ if (parsed.value.sequence <= request.lastSequence) return;
20730
+ if (parsed.value.sequence !== request.lastSequence + 1) throw new Error("Out-of-order WebSocket chat chunk sequence.");
20731
+ const chunk = await this.validateResponseChunk(parsed.value.chunk);
20732
+ if (this.activeRequests.get(requestId) !== request) return;
20733
+ this.resolveResumeStream(request);
20734
+ try {
20735
+ request.controller.enqueue(chunk);
20736
+ } catch {
20737
+ return;
20738
+ }
20739
+ request.lastSequence = parsed.value.sequence;
20740
+ return;
20741
+ }
20742
+ case "end":
20743
+ this.resolveResumeStream(request);
20744
+ this.cleanupRequest(request);
20745
+ request.controller.close();
20746
+ return;
20747
+ case "no-active":
20748
+ if (request.kind === "resume" && !request.responseSettled) {
20749
+ request.responseSettled = true;
20750
+ request.resolveResponse?.(null);
20751
+ }
20752
+ this.cleanupRequest(request);
20753
+ request.controller.close();
20754
+ return;
20755
+ case "error":
20756
+ if (parsed.value.errorText !== void 0 && typeof parsed.value.errorText !== "string") throw new Error("Invalid WebSocket chat error response.");
20757
+ this.failRequest(request, new Error(parsed.value.errorText ?? "WebSocket chat server returned an error."));
20758
+ return;
20759
+ default: throw new Error(`Unknown WebSocket chat response type: ${type}.`);
20760
+ }
20761
+ }
20762
+ async sendFrame(socket, frame, abortSignal) {
20763
+ const send = this.sendQueue.then(async () => {
20764
+ await waitForWebSocketBufferDrain(socket, { abortSignal });
20765
+ this.throwIfAborted(abortSignal);
20766
+ if (this.connection?.socket !== socket || socket.readyState !== WEBSOCKET_OPEN_STATE) throw new TypeError("WebSocket chat network connection is not open.");
20767
+ socket.send(JSON.stringify(frame));
20768
+ });
20769
+ this.sendQueue = send.catch(() => {});
20770
+ return send;
20771
+ }
20772
+ };
20773
+ //#endregion
20224
20774
  //#region src/upload-file/upload-file.ts
20225
20775
  /**
20226
20776
  * Uploads a file using a files API interface.
@@ -20321,6 +20871,6 @@ async function uploadSkill({ api, files, displayTitle, providerOptions }) {
20321
20871
  });
20322
20872
  }
20323
20873
  //#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 };
20874
+ 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
20875
 
20326
20876
  //# sourceMappingURL=index.js.map