ai 7.0.123 → 7.0.126

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 (35) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/index.d.ts +232 -34
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +415 -100
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +199 -8
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +9 -3
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +25 -0
  11. package/docs/03-ai-sdk-core/36-transcription.mdx +38 -1
  12. package/docs/03-ai-sdk-core/37-speech.mdx +23 -0
  13. package/docs/03-ai-sdk-core/60-telemetry.mdx +49 -1
  14. package/docs/07-reference/01-ai-sdk-core/11-stream-transcribe.mdx +7 -0
  15. package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +7 -0
  16. package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +7 -0
  17. package/docs/07-reference/01-ai-sdk-core/17-create-agent-ui-stream.mdx +7 -0
  18. package/docs/07-reference/01-ai-sdk-core/18-create-agent-ui-stream-response.mdx +7 -0
  19. package/docs/07-reference/01-ai-sdk-core/18-pipe-agent-ui-stream-to-response.mdx +7 -0
  20. package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +60 -3
  21. package/package.json +12 -12
  22. package/src/agent/create-agent-ui-stream-response.ts +16 -4
  23. package/src/agent/create-agent-ui-stream.ts +16 -2
  24. package/src/agent/pipe-agent-ui-stream-to-response.ts +16 -4
  25. package/src/generate-speech/generate-speech.ts +163 -38
  26. package/src/generate-speech/index.ts +4 -0
  27. package/src/generate-speech/speech-events.ts +91 -0
  28. package/src/telemetry/create-telemetry-dispatcher.ts +18 -5
  29. package/src/telemetry/telemetry.ts +38 -6
  30. package/src/telemetry/tracing-channel.ts +3 -0
  31. package/src/transcribe/index.ts +6 -0
  32. package/src/transcribe/stream-transcribe.ts +182 -31
  33. package/src/transcribe/transcribe.ts +186 -33
  34. package/src/transcribe/transcription-events.ts +111 -0
  35. package/src/ui/chat.ts +36 -5
package/dist/index.js CHANGED
@@ -1102,7 +1102,7 @@ function cloneValue(value) {
1102
1102
  }
1103
1103
  //#endregion
1104
1104
  //#region src/version.ts
1105
- const VERSION = "7.0.123";
1105
+ const VERSION = "7.0.126";
1106
1106
  //#endregion
1107
1107
  //#region src/util/download/download.ts
1108
1108
  /**
@@ -4356,11 +4356,15 @@ function createTelemetryDispatcher({ telemetry }) {
4356
4356
  includeToolsContext: telemetry?.includeToolsContext
4357
4357
  };
4358
4358
  const mergeTelemetryCallback = (key) => {
4359
- const mergedIntegrationCallback = mergeCallbacks(...integrations.map((integration) => integration[key]?.bind(integration)).filter(Boolean).map((callback) => ((event) => callback(augmentEvent(event, telemetryMetadata)))));
4359
+ const integrationCallbacks = integrations.map((integration) => integration[key]?.bind(integration)).filter(Boolean).map((callback) => ((event) => callback(augmentEvent(event, telemetryMetadata))));
4360
+ if (integrationCallbacks.length === 0) return;
4361
+ const mergedIntegrationCallback = mergeCallbacks(...integrationCallbacks);
4360
4362
  return async (event) => {
4361
4363
  await mergedIntegrationCallback(event);
4362
4364
  };
4363
4365
  };
4366
+ const onStepEnd = mergeTelemetryCallback("onStepEnd");
4367
+ const onStepFinish = mergeTelemetryCallback("onStepFinish");
4364
4368
  const executeLanguageModelCallWrappers = integrations.map((integration) => integration.executeLanguageModelCall?.bind(integration)).filter(Boolean);
4365
4369
  const executeToolWrappers = integrations.map((integration) => integration.executeTool?.bind(integration)).filter(Boolean);
4366
4370
  return {
@@ -4381,7 +4385,7 @@ function createTelemetryDispatcher({ telemetry }) {
4381
4385
  onLanguageModelCallEnd: mergeTelemetryCallback("onLanguageModelCallEnd"),
4382
4386
  onToolExecutionStart: mergeTelemetryCallback("onToolExecutionStart"),
4383
4387
  onToolExecutionEnd: mergeTelemetryCallback("onToolExecutionEnd"),
4384
- onStepEnd: mergeCallbacks(mergeTelemetryCallback("onStepEnd"), mergeTelemetryCallback("onStepFinish")),
4388
+ onStepEnd: onStepEnd == null && onStepFinish == null ? void 0 : mergeCallbacks(onStepEnd, onStepFinish),
4385
4389
  onObjectStepStart: mergeTelemetryCallback("onObjectStepStart"),
4386
4390
  onObjectStepEnd: mergeTelemetryCallback("onObjectStepEnd"),
4387
4391
  onEmbedStart: mergeTelemetryCallback("onEmbedStart"),
@@ -4392,6 +4396,8 @@ function createTelemetryDispatcher({ telemetry }) {
4392
4396
  experimental_onEvaluationModelCallStart: mergeTelemetryCallback("experimental_onEvaluationModelCallStart"),
4393
4397
  experimental_onEvaluationModelCallEnd: mergeTelemetryCallback("experimental_onEvaluationModelCallEnd"),
4394
4398
  experimental_onEvaluateEnd: mergeTelemetryCallback("experimental_onEvaluateEnd"),
4399
+ experimental_onStreamTranscriptionStart: mergeTelemetryCallback("experimental_onStreamTranscriptionStart"),
4400
+ experimental_onStreamTranscriptionEnd: mergeTelemetryCallback("experimental_onStreamTranscriptionEnd"),
4395
4401
  onEnd: mergeTelemetryCallback("onEnd"),
4396
4402
  onAbort: mergeTelemetryCallback("onAbort"),
4397
4403
  onError: mergeTelemetryCallback("onError"),
@@ -5041,7 +5047,7 @@ const originalGenerateId$4 = createIdGenerator$1({
5041
5047
  prefix: "aitxt",
5042
5048
  size: 24
5043
5049
  });
5044
- const originalGenerateCallId$6 = createIdGenerator$1({
5050
+ const originalGenerateCallId$9 = createIdGenerator$1({
5045
5051
  prefix: "call",
5046
5052
  size: 24
5047
5053
  });
@@ -5112,7 +5118,7 @@ const originalGenerateCallId$6 = createIdGenerator$1({
5112
5118
  * @returns
5113
5119
  * A result object that contains the generated text, the results of the tool calls, and additional information.
5114
5120
  */
5115
- async function generateText({ model: modelArg, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries: maxRetriesArg, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, providerOptions, activeTools, toolOrder, prepareStep, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_download: download, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { generateId = originalGenerateId$4, generateCallId = originalGenerateCallId$6, now: now$4 = now } = {}, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, onStepEnd, onStepFinish, onFinish, onEnd = onFinish, ...settings }) {
5121
+ async function generateText({ model: modelArg, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries: maxRetriesArg, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, providerOptions, activeTools, toolOrder, prepareStep, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_download: download, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { generateId = originalGenerateId$4, generateCallId = originalGenerateCallId$9, now: now$4 = now } = {}, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, onStepEnd, onStepFinish, onFinish, onEnd = onFinish, ...settings }) {
5116
5122
  include = {
5117
5123
  requestBody: include?.requestBody ?? false,
5118
5124
  requestMessages: include?.requestMessages ?? false,
@@ -7948,7 +7954,7 @@ const originalGenerateId$3 = createIdGenerator$1({
7948
7954
  prefix: "aitxt",
7949
7955
  size: 24
7950
7956
  });
7951
- const originalGenerateCallId$5 = createIdGenerator$1({
7957
+ const originalGenerateCallId$8 = createIdGenerator$1({
7952
7958
  prefix: "call",
7953
7959
  size: 24
7954
7960
  });
@@ -8001,7 +8007,7 @@ const originalGenerateCallId$5 = createIdGenerator$1({
8001
8007
  *
8002
8008
  * @returns A stream of model call parts together with request and response metadata when available.
8003
8009
  */
8004
- async function streamLanguageModelCall({ model, tools, toolOrder, output, toolChoice, prompt, system, instructions, messages, allowSystemInMessages, download, abortSignal, headers, includeRawChunks, providerOptions, repairToolCall, refineToolInput, executeLanguageModelCallInTelemetryContext = async ({ execute }) => await execute(), callId, toolsContext, experimental_sandbox: sandbox, _internal: { generateId = originalGenerateId$3, generateCallId = originalGenerateCallId$5, now: now$3 = now } = {}, onStart, onLanguageModelCallStart, onLanguageModelCallEnd, ...callSettings }) {
8010
+ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolChoice, prompt, system, instructions, messages, allowSystemInMessages, download, abortSignal, headers, includeRawChunks, providerOptions, repairToolCall, refineToolInput, executeLanguageModelCallInTelemetryContext = async ({ execute }) => await execute(), callId, toolsContext, experimental_sandbox: sandbox, _internal: { generateId = originalGenerateId$3, generateCallId = originalGenerateCallId$8, now: now$3 = now } = {}, onStart, onLanguageModelCallStart, onLanguageModelCallEnd, ...callSettings }) {
8005
8011
  const resolvedModel = resolveLanguageModel(model);
8006
8012
  const effectiveCallId = callId ?? generateCallId();
8007
8013
  const standardizedPrompt = await standardizePrompt({
@@ -8464,7 +8470,7 @@ const originalGenerateId$2 = createIdGenerator$1({
8464
8470
  prefix: "aitxt",
8465
8471
  size: 24
8466
8472
  });
8467
- const originalGenerateCallId$4 = createIdGenerator$1({
8473
+ const originalGenerateCallId$7 = createIdGenerator$1({
8468
8474
  prefix: "call",
8469
8475
  size: 24
8470
8476
  });
@@ -8574,7 +8580,7 @@ function isOutputChunk(chunk) {
8574
8580
  * @returns
8575
8581
  * A result object for accessing different stream types and additional information.
8576
8582
  */
8577
- function streamText({ model, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries, streamRetries, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, prepareStep, providerOptions, activeTools, toolOrder, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_transform: transform, experimental_download: download, includeRawChunks, onChunk, onError: onErrorArg, onFinish, onEnd = onFinish, onAbort, onStepEnd, onStepFinish, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { now: now$2 = now, generateId = originalGenerateId$2, generateCallId = originalGenerateCallId$4 } = {}, ...settings }) {
8583
+ function streamText({ model, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries, streamRetries, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, prepareStep, providerOptions, activeTools, toolOrder, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_transform: transform, experimental_download: download, includeRawChunks, onChunk, onError: onErrorArg, onFinish, onEnd = onFinish, onAbort, onStepEnd, onStepFinish, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { now: now$2 = now, generateId = originalGenerateId$2, generateCallId = originalGenerateCallId$7 } = {}, ...settings }) {
8578
8584
  const totalTimeoutMs = getTotalTimeoutMs(timeout);
8579
8585
  const stepTimeoutMs = getStepTimeoutMs(timeout);
8580
8586
  const firstChunkTimeoutMs = getFirstChunkTimeoutMs(timeout);
@@ -11198,6 +11204,7 @@ async function validateUIMessagesForAgent(options) {
11198
11204
  *
11199
11205
  * @param agent - The agent to run.
11200
11206
  * @param uiMessages - The input UI messages.
11207
+ * @param convertDataPart - Optional function to convert custom data parts to text or file model message parts.
11201
11208
  * @param abortSignal - The abort signal. Optional.
11202
11209
  * @param timeout - Timeout in milliseconds. Optional.
11203
11210
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
@@ -11208,12 +11215,15 @@ async function validateUIMessagesForAgent(options) {
11208
11215
  *
11209
11216
  * @returns The UI message stream.
11210
11217
  */
11211
- async function createAgentUIStream({ agent, uiMessages, options, abortSignal, timeout, experimental_sandbox: sandbox, experimental_transform, onStepEnd, onStepFinish, ...uiMessageStreamOptions }) {
11218
+ async function createAgentUIStream({ agent, uiMessages, convertDataPart, options, abortSignal, timeout, experimental_sandbox: sandbox, experimental_transform, onStepEnd, onStepFinish, ...uiMessageStreamOptions }) {
11212
11219
  const validatedMessages = await validateUIMessagesForAgent({
11213
11220
  messages: uiMessages,
11214
11221
  tools: agent.tools
11215
11222
  });
11216
- const modelMessages = await convertToModelMessages(validatedMessages, { tools: agent.tools });
11223
+ const modelMessages = await convertToModelMessages(validatedMessages, {
11224
+ tools: agent.tools,
11225
+ convertDataPart
11226
+ });
11217
11227
  const result = await agent.stream({
11218
11228
  prompt: modelMessages,
11219
11229
  options,
@@ -11238,6 +11248,7 @@ async function createAgentUIStream({ agent, uiMessages, options, abortSignal, ti
11238
11248
  *
11239
11249
  * @param agent - The agent to run.
11240
11250
  * @param uiMessages - The input UI messages.
11251
+ * @param convertDataPart - Optional function to convert custom data parts to text or file model message parts.
11241
11252
  * @param abortSignal - Abort signal. Optional.
11242
11253
  * @param timeout - Timeout in milliseconds. Optional.
11243
11254
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
@@ -11271,6 +11282,7 @@ async function createAgentUIStreamResponse({ headers, status, statusText, keepAl
11271
11282
  * @param response - The Node.js ServerResponse object to pipe to.
11272
11283
  * @param agent - The agent to run.
11273
11284
  * @param uiMessages - The input UI messages.
11285
+ * @param convertDataPart - Optional function to convert custom data parts to text or file model message parts.
11274
11286
  * @param abortSignal - Abort signal. Optional.
11275
11287
  * @param timeout - Timeout in milliseconds. Optional.
11276
11288
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
@@ -11992,7 +12004,7 @@ function createRestrictedTelemetryDispatcher$2({ telemetry }) {
11992
12004
  }
11993
12005
  //#endregion
11994
12006
  //#region src/embed/embed.ts
11995
- const originalGenerateCallId$3 = createIdGenerator$1({
12007
+ const originalGenerateCallId$6 = createIdGenerator$1({
11996
12008
  prefix: "call",
11997
12009
  size: 24
11998
12010
  });
@@ -12015,7 +12027,7 @@ const originalGenerateCallId$3 = createIdGenerator$1({
12015
12027
  *
12016
12028
  * @returns A result object that contains the embedding, the value, and additional information.
12017
12029
  */
12018
- 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$3 } = {} }) {
12030
+ 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 } = {} }) {
12019
12031
  const model = resolveEmbeddingModel(modelArg);
12020
12032
  const { maxRetries, retry } = prepareRetries({
12021
12033
  maxRetries: maxRetriesArg,
@@ -12175,7 +12187,7 @@ function splitArray(array, chunkSize) {
12175
12187
  }
12176
12188
  //#endregion
12177
12189
  //#region src/embed/embed-many.ts
12178
- const originalGenerateCallId$2 = createIdGenerator$1({
12190
+ const originalGenerateCallId$5 = createIdGenerator$1({
12179
12191
  prefix: "call",
12180
12192
  size: 24
12181
12193
  });
@@ -12207,7 +12219,7 @@ const originalGenerateCallId$2 = createIdGenerator$1({
12207
12219
  *
12208
12220
  * @returns A result object that contains the embeddings, the value, and additional information.
12209
12221
  */
12210
- 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$2 } = {} }) {
12222
+ 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 } = {} }) {
12211
12223
  const model = resolveEmbeddingModel(modelArg);
12212
12224
  const { maxRetries, retry } = prepareRetries({
12213
12225
  maxRetries: maxRetriesArg,
@@ -12611,12 +12623,12 @@ function validateEvaluationAnswers({ questions, answers, rounding }) {
12611
12623
  }
12612
12624
  //#endregion
12613
12625
  //#region src/evaluate/evaluate.ts
12614
- const originalGenerateCallId$1 = createIdGenerator$1({
12626
+ const originalGenerateCallId$4 = createIdGenerator$1({
12615
12627
  prefix: "call",
12616
12628
  size: 24
12617
12629
  });
12618
12630
  /** Evaluate typed questions against one shared state. Experimental. */
12619
- async function evaluate({ model: modelArg, state, questions, maxRetries, abortSignal, headers, providerOptions = {}, telemetry, runtimeContext = {}, onStart, onEnd, _internal: { generateCallId = originalGenerateCallId$1 } = {} }) {
12631
+ async function evaluate({ model: modelArg, state, questions, maxRetries, abortSignal, headers, providerOptions = {}, telemetry, runtimeContext = {}, onStart, onEnd, _internal: { generateCallId = originalGenerateCallId$4 } = {} }) {
12620
12632
  const model = resolveEvaluationModel(modelArg);
12621
12633
  validateEvaluationInput({
12622
12634
  state,
@@ -14071,6 +14083,10 @@ var DefaultGeneratedAudioFile = class extends DefaultGeneratedFile {
14071
14083
  };
14072
14084
  //#endregion
14073
14085
  //#region src/generate-speech/generate-speech.ts
14086
+ const originalGenerateCallId$3 = createIdGenerator$1({
14087
+ prefix: "call",
14088
+ size: 24
14089
+ });
14074
14090
  /**
14075
14091
  * Generates speech audio using a speech model.
14076
14092
  *
@@ -14086,48 +14102,126 @@ var DefaultGeneratedAudioFile = class extends DefaultGeneratedFile {
14086
14102
  * @param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2.
14087
14103
  * @param abortSignal - An optional abort signal that can be used to cancel the call.
14088
14104
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
14105
+ * @param telemetry - Optional telemetry configuration.
14089
14106
  *
14090
14107
  * @returns A result object that contains the generated audio data.
14091
14108
  */
14092
- async function generateSpeech({ model, text, voice, outputFormat, instructions, speed, language, providerOptions = {}, maxRetries: maxRetriesArg, abortSignal, headers }) {
14109
+ async function generateSpeech({ model, text, voice, outputFormat, instructions, speed, language, providerOptions = {}, maxRetries: maxRetriesArg, abortSignal, headers, telemetry, _internal: { generateCallId = originalGenerateCallId$3 } = {} }) {
14093
14110
  const resolvedModel = resolveSpeechModel(model);
14094
14111
  if (!resolvedModel) throw new Error("Model could not be resolved");
14095
14112
  const headersWithUserAgent = withUserAgentSuffix(headers ?? {}, `ai/${VERSION}`);
14096
- const { retry } = prepareRetries({
14113
+ const { maxRetries, retry } = prepareRetries({
14097
14114
  maxRetries: maxRetriesArg,
14098
14115
  abortSignal
14099
14116
  });
14100
- const result = await retry(() => resolvedModel.doGenerate({
14117
+ const callId = generateCallId();
14118
+ const telemetryDispatcher = createTelemetryDispatcher({ telemetry });
14119
+ const runInTracingChannelSpan = telemetryDispatcher.runInTracingChannelSpan ?? (async ({ execute }) => await execute());
14120
+ const startEvent = {
14121
+ callId,
14122
+ operationId: "ai.generateSpeech",
14123
+ provider: resolvedModel.provider,
14124
+ modelId: resolvedModel.modelId,
14101
14125
  text,
14102
14126
  voice,
14103
14127
  outputFormat,
14104
14128
  instructions,
14105
14129
  speed,
14106
14130
  language,
14107
- abortSignal,
14108
- headers: headersWithUserAgent,
14131
+ maxRetries,
14132
+ headers,
14109
14133
  providerOptions
14110
- }));
14111
- if (!result.audio || result.audio.length === 0) throw new NoSpeechGeneratedError({ responses: [result.response] });
14112
- logWarnings({
14113
- warnings: result.warnings,
14114
- provider: resolvedModel.provider,
14115
- model: resolvedModel.modelId
14116
- });
14117
- const detectedMediaType = detectMediaType({
14118
- data: result.audio,
14119
- topLevelType: "audio"
14120
- });
14121
- return new DefaultSpeechResult({
14122
- audio: new DefaultGeneratedAudioFile({
14123
- data: result.audio,
14124
- mediaType: detectedMediaType ?? getResponseAudioMediaType(result.response.headers) ?? getOutputFormatMediaType(outputFormat) ?? "audio/mp3"
14125
- }),
14126
- warnings: result.warnings,
14127
- responses: [result.response],
14128
- providerMetadata: result.providerMetadata
14134
+ };
14135
+ return await runInTracingChannelSpan({
14136
+ type: "generateSpeech",
14137
+ event: startEvent,
14138
+ execute: async () => {
14139
+ await notify({
14140
+ event: startEvent,
14141
+ callbacks: [telemetryDispatcher.onStart]
14142
+ });
14143
+ try {
14144
+ const result = await retry(() => resolvedModel.doGenerate({
14145
+ text,
14146
+ voice,
14147
+ outputFormat,
14148
+ instructions,
14149
+ speed,
14150
+ language,
14151
+ abortSignal,
14152
+ headers: headersWithUserAgent,
14153
+ providerOptions
14154
+ }));
14155
+ if (!result.audio || result.audio.length === 0) throw new NoSpeechGeneratedError({ responses: [result.response] });
14156
+ logWarnings({
14157
+ warnings: result.warnings,
14158
+ provider: resolvedModel.provider,
14159
+ model: resolvedModel.modelId
14160
+ });
14161
+ const detectedMediaType = detectMediaType({
14162
+ data: result.audio,
14163
+ topLevelType: "audio"
14164
+ });
14165
+ const audio = new DefaultGeneratedAudioFile({
14166
+ data: result.audio,
14167
+ mediaType: detectedMediaType ?? getResponseAudioMediaType(result.response.headers) ?? getOutputFormatMediaType(outputFormat) ?? "audio/mp3"
14168
+ });
14169
+ if (telemetryDispatcher.onEnd != null) await notify({
14170
+ event: {
14171
+ callId,
14172
+ operationId: "ai.generateSpeech",
14173
+ provider: resolvedModel.provider,
14174
+ modelId: resolvedModel.modelId,
14175
+ text,
14176
+ audio: {
14177
+ byteLength: getBase64OrBinaryByteLength(result.audio),
14178
+ mediaType: audio.mediaType,
14179
+ format: audio.format
14180
+ },
14181
+ usage: result.usage,
14182
+ warnings: result.warnings,
14183
+ providerMetadata: result.providerMetadata,
14184
+ response: getTelemetryResponseMetadata(result.response)
14185
+ },
14186
+ callbacks: [telemetryDispatcher.onEnd]
14187
+ });
14188
+ return new DefaultSpeechResult({
14189
+ audio,
14190
+ warnings: result.warnings,
14191
+ responses: [result.response],
14192
+ providerMetadata: result.providerMetadata
14193
+ });
14194
+ } catch (error) {
14195
+ await telemetryDispatcher.onError?.({
14196
+ callId,
14197
+ error
14198
+ });
14199
+ throw error;
14200
+ }
14201
+ }
14129
14202
  });
14130
14203
  }
14204
+ function getBase64OrBinaryByteLength(audio) {
14205
+ if (audio instanceof Uint8Array) return audio.byteLength;
14206
+ let characterCount = 0;
14207
+ let lastCharacter = "";
14208
+ let secondLastCharacter = "";
14209
+ for (const character of audio) {
14210
+ if (/\s/.test(character)) continue;
14211
+ characterCount++;
14212
+ secondLastCharacter = lastCharacter;
14213
+ lastCharacter = character;
14214
+ }
14215
+ const padding = lastCharacter === "=" ? secondLastCharacter === "=" ? 2 : 1 : 0;
14216
+ return Math.floor(characterCount * 3 / 4) - padding;
14217
+ }
14218
+ function getTelemetryResponseMetadata(response) {
14219
+ return {
14220
+ timestamp: response.timestamp,
14221
+ modelId: response.modelId,
14222
+ headers: response.headers
14223
+ };
14224
+ }
14131
14225
  function getResponseAudioMediaType(headers) {
14132
14226
  const mediaType = Object.entries(headers ?? {}).find(([name]) => name.toLowerCase() === "content-type")?.[1];
14133
14227
  if (mediaType == null) return;
@@ -18187,7 +18281,7 @@ function createRestrictedTelemetryDispatcher({ telemetry }) {
18187
18281
  }
18188
18282
  //#endregion
18189
18283
  //#region src/rerank/rerank.ts
18190
- const originalGenerateCallId = createIdGenerator$1({
18284
+ const originalGenerateCallId$2 = createIdGenerator$1({
18191
18285
  prefix: "call",
18192
18286
  size: 24
18193
18287
  });
@@ -18208,7 +18302,7 @@ const originalGenerateCallId = createIdGenerator$1({
18208
18302
  *
18209
18303
  * @returns A result object that contains the reranked documents, the reranked indices, and additional information.
18210
18304
  */
18211
- async function rerank({ model: modelArg, documents, query, topN, maxRetries: maxRetriesArg, abortSignal, headers, providerOptions, experimental_telemetry, telemetry = experimental_telemetry, runtimeContext = {}, onStart, experimental_onStart, onEnd, experimental_onEnd, _internal: { generateCallId = originalGenerateCallId } = {} }) {
18305
+ async function rerank({ model: modelArg, documents, query, topN, maxRetries: maxRetriesArg, abortSignal, headers, providerOptions, experimental_telemetry, telemetry = experimental_telemetry, runtimeContext = {}, onStart, experimental_onStart, onEnd, experimental_onEnd, _internal: { generateCallId = originalGenerateCallId$2 } = {} }) {
18212
18306
  const model = resolveRerankingModel(modelArg);
18213
18307
  const callId = generateCallId();
18214
18308
  const resolvedOnStart = onStart ?? experimental_onStart;
@@ -18415,6 +18509,10 @@ var DefaultRerankResult = class {
18415
18509
  };
18416
18510
  //#endregion
18417
18511
  //#region src/transcribe/transcribe.ts
18512
+ const originalGenerateCallId$1 = createIdGenerator$1({
18513
+ prefix: "call",
18514
+ size: 24
18515
+ });
18418
18516
  /**
18419
18517
  * Generates transcripts using a transcription model.
18420
18518
  *
@@ -18425,47 +18523,149 @@ var DefaultRerankResult = class {
18425
18523
  * @param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2.
18426
18524
  * @param abortSignal - An optional abort signal that can be used to cancel the call.
18427
18525
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
18526
+ * @param telemetry - Optional telemetry configuration.
18428
18527
  *
18429
18528
  * @returns A result object that contains the generated transcript.
18430
18529
  */
18431
18530
  const defaultDownload = createDownload();
18432
- async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxRetriesArg, abortSignal, headers, download: downloadFn = defaultDownload }) {
18531
+ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxRetriesArg, abortSignal, headers, telemetry, download: downloadFn = defaultDownload, _internal: { generateCallId = originalGenerateCallId$1 } = {} }) {
18433
18532
  const resolvedModel = resolveTranscriptionModel(model);
18434
18533
  if (!resolvedModel) throw new Error("Model could not be resolved");
18435
- const { retry } = prepareRetries({
18534
+ const { maxRetries, retry } = prepareRetries({
18436
18535
  maxRetries: maxRetriesArg,
18437
18536
  abortSignal
18438
18537
  });
18439
18538
  const headersWithUserAgent = withUserAgentSuffix(headers ?? {}, `ai/${VERSION}`);
18440
- const audioData = audio instanceof URL ? (await downloadFn({
18441
- url: audio,
18442
- abortSignal
18443
- })).data : convertDataContentToUint8Array(audio);
18444
- const result = await retry(() => resolvedModel.doGenerate({
18445
- audio: audioData,
18446
- abortSignal,
18447
- headers: headersWithUserAgent,
18448
- providerOptions,
18449
- mediaType: detectMediaType({
18450
- data: audioData,
18451
- topLevelType: "audio"
18452
- }) ?? "audio/wav"
18453
- }));
18454
- logWarnings({
18455
- warnings: result.warnings,
18539
+ const callId = generateCallId();
18540
+ const telemetryDispatcher = createTelemetryDispatcher({ telemetry });
18541
+ const runInTracingChannelSpan = telemetryDispatcher.runInTracingChannelSpan ?? (async ({ execute }) => await execute());
18542
+ const createStartEvent = ({ byteLength, mediaType }) => ({
18543
+ callId,
18544
+ operationId: "ai.transcribe",
18456
18545
  provider: resolvedModel.provider,
18457
- model: resolvedModel.modelId
18546
+ modelId: resolvedModel.modelId,
18547
+ audio: {
18548
+ byteLength,
18549
+ mediaType
18550
+ },
18551
+ inputAudioFormat: void 0,
18552
+ maxRetries,
18553
+ headers,
18554
+ providerOptions
18458
18555
  });
18459
- if (!result.text) throw new NoTranscriptGeneratedError({ responses: [result.response] });
18460
- return new DefaultTranscriptionResult({
18461
- text: result.text,
18462
- segments: result.segments,
18463
- language: result.language,
18464
- durationInSeconds: result.durationInSeconds,
18465
- warnings: result.warnings,
18466
- responses: [result.response],
18467
- providerMetadata: result.providerMetadata
18556
+ const executeWithStartEvent = async ({ startEvent, execute }) => await runInTracingChannelSpan({
18557
+ type: "transcribe",
18558
+ event: startEvent,
18559
+ execute: async () => {
18560
+ await notify({
18561
+ event: startEvent,
18562
+ callbacks: [telemetryDispatcher.onStart]
18563
+ });
18564
+ return await execute();
18565
+ }
18468
18566
  });
18567
+ let preparationError;
18568
+ let preparationFailed = false;
18569
+ let audioData;
18570
+ let downloadedMediaType;
18571
+ try {
18572
+ if (audio instanceof URL) {
18573
+ const downloadResult = await downloadFn({
18574
+ url: audio,
18575
+ abortSignal
18576
+ });
18577
+ audioData = downloadResult.data;
18578
+ downloadedMediaType = downloadResult.mediaType;
18579
+ } else audioData = convertDataContentToUint8Array(audio);
18580
+ } catch (error) {
18581
+ preparationFailed = true;
18582
+ preparationError = error;
18583
+ audioData = /* @__PURE__ */ new Uint8Array();
18584
+ }
18585
+ if (preparationFailed) {
18586
+ const startEvent = createStartEvent({
18587
+ byteLength: void 0,
18588
+ mediaType: void 0
18589
+ });
18590
+ try {
18591
+ return await executeWithStartEvent({
18592
+ startEvent,
18593
+ execute: () => {
18594
+ throw preparationError;
18595
+ }
18596
+ });
18597
+ } catch (error) {
18598
+ await telemetryDispatcher.onError?.({
18599
+ callId,
18600
+ error
18601
+ });
18602
+ throw error;
18603
+ }
18604
+ }
18605
+ const mediaType = downloadedMediaType ?? detectMediaType({
18606
+ data: audioData,
18607
+ topLevelType: "audio"
18608
+ }) ?? "audio/wav";
18609
+ const startEvent = createStartEvent({
18610
+ byteLength: audioData.byteLength,
18611
+ mediaType
18612
+ });
18613
+ try {
18614
+ return await executeWithStartEvent({
18615
+ startEvent,
18616
+ execute: async () => {
18617
+ const result = await retry(() => resolvedModel.doGenerate({
18618
+ audio: audioData,
18619
+ abortSignal,
18620
+ headers: headersWithUserAgent,
18621
+ providerOptions,
18622
+ mediaType
18623
+ }));
18624
+ logWarnings({
18625
+ warnings: result.warnings,
18626
+ provider: resolvedModel.provider,
18627
+ model: resolvedModel.modelId
18628
+ });
18629
+ if (!result.text) throw new NoTranscriptGeneratedError({ responses: [result.response] });
18630
+ await notify({
18631
+ event: {
18632
+ callId,
18633
+ operationId: "ai.transcribe",
18634
+ provider: resolvedModel.provider,
18635
+ modelId: resolvedModel.modelId,
18636
+ audio: {
18637
+ byteLength: audioData.byteLength,
18638
+ mediaType
18639
+ },
18640
+ text: result.text,
18641
+ segments: result.segments,
18642
+ language: result.language,
18643
+ durationInSeconds: result.durationInSeconds,
18644
+ usage: result.usage,
18645
+ warnings: result.warnings,
18646
+ providerMetadata: result.providerMetadata,
18647
+ response: result.response
18648
+ },
18649
+ callbacks: [telemetryDispatcher.onEnd]
18650
+ });
18651
+ return new DefaultTranscriptionResult({
18652
+ text: result.text,
18653
+ segments: result.segments,
18654
+ language: result.language,
18655
+ durationInSeconds: result.durationInSeconds,
18656
+ warnings: result.warnings,
18657
+ responses: [result.response],
18658
+ providerMetadata: result.providerMetadata
18659
+ });
18660
+ }
18661
+ });
18662
+ } catch (error) {
18663
+ await telemetryDispatcher.onError?.({
18664
+ callId,
18665
+ error
18666
+ });
18667
+ throw error;
18668
+ }
18469
18669
  }
18470
18670
  var DefaultTranscriptionResult = class {
18471
18671
  constructor(options) {
@@ -18480,6 +18680,10 @@ var DefaultTranscriptionResult = class {
18480
18680
  };
18481
18681
  //#endregion
18482
18682
  //#region src/transcribe/stream-transcribe.ts
18683
+ const originalGenerateCallId = createIdGenerator$1({
18684
+ prefix: "call",
18685
+ size: 24
18686
+ });
18483
18687
  /**
18484
18688
  * Streams transcripts using a transcription model.
18485
18689
  *
@@ -18489,10 +18693,11 @@ var DefaultTranscriptionResult = class {
18489
18693
  * @param providerOptions - Additional provider-specific options.
18490
18694
  * @param abortSignal - An optional abort signal that can be used to cancel the call.
18491
18695
  * @param headers - Additional HTTP/WebSocket headers to send when supported by the provider.
18696
+ * @param telemetry - Optional telemetry configuration.
18492
18697
  *
18493
18698
  * @returns A result object that contains the streaming transcript and final transcript metadata.
18494
18699
  */
18495
- function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}, abortSignal, headers, includeRawChunks, _internal: { currentDate = () => /* @__PURE__ */ new Date() } = {} }) {
18700
+ function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}, abortSignal, headers, includeRawChunks, telemetry, _internal: { currentDate = () => /* @__PURE__ */ new Date(), generateCallId = originalGenerateCallId } = {} }) {
18496
18701
  const resolvedModel = resolveTranscriptionModel(model);
18497
18702
  if (!resolvedModel) throw new Error("Model could not be resolved");
18498
18703
  const doStream = resolvedModel.doStream?.bind(resolvedModel);
@@ -18501,6 +18706,27 @@ function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}
18501
18706
  message: `The ${resolvedModel.provider} model "${resolvedModel.modelId}" does not support streaming transcription.` + (typeof model === "string" ? " String model IDs resolve through the global provider (AI Gateway by default). If that provider does not support streaming transcription, pass a provider model instance instead (e.g. openai.transcription('gpt-realtime-whisper')) or upgrade @ai-sdk/gateway to a version with streaming transcription support." : "")
18502
18707
  });
18503
18708
  const headersWithUserAgent = withUserAgentSuffix(headers ?? {}, `ai/${VERSION}`);
18709
+ const callId = generateCallId();
18710
+ const telemetryDispatcher = createTelemetryDispatcher({ telemetry });
18711
+ const runInTracingChannelSpan = telemetryDispatcher.runInTracingChannelSpan ?? (async ({ execute }) => await execute());
18712
+ let audioByteLength = 0;
18713
+ const countedAudio = telemetryDispatcher.experimental_onStreamTranscriptionEnd != null ? createByteCountingStream(audio, (byteLength) => {
18714
+ audioByteLength += byteLength;
18715
+ }) : audio;
18716
+ const startEvent = {
18717
+ callId,
18718
+ operationId: "ai.streamTranscribe",
18719
+ provider: resolvedModel.provider,
18720
+ modelId: resolvedModel.modelId,
18721
+ audio: {
18722
+ byteLength: void 0,
18723
+ mediaType: inputAudioFormat.type
18724
+ },
18725
+ inputAudioFormat,
18726
+ maxRetries: void 0,
18727
+ headers,
18728
+ providerOptions
18729
+ };
18504
18730
  const textPromise = new DelayedPromise();
18505
18731
  const segmentsPromise = new DelayedPromise();
18506
18732
  const languagePromise = new DelayedPromise();
@@ -18508,6 +18734,8 @@ function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}
18508
18734
  const warningsPromise = new DelayedPromise();
18509
18735
  const responsesPromise = new DelayedPromise();
18510
18736
  const providerMetadataPromise = new DelayedPromise();
18737
+ let warnings = [];
18738
+ let telemetrySettled = false;
18511
18739
  const rejectPendingPromises = (error) => {
18512
18740
  for (const promise of [
18513
18741
  textPromise,
@@ -18525,17 +18753,18 @@ function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}
18525
18753
  timestamp: startedAt,
18526
18754
  modelId: resolvedModel.modelId
18527
18755
  };
18528
- const resolveWarnings = (warnings) => {
18529
- warningsPromise.resolve(warnings);
18756
+ const resolveWarnings = (resolvedWarnings) => {
18757
+ warnings = resolvedWarnings;
18758
+ warningsPromise.resolve(resolvedWarnings);
18530
18759
  logWarnings({
18531
- warnings,
18760
+ warnings: resolvedWarnings,
18532
18761
  provider: resolvedModel.provider,
18533
18762
  model: resolvedModel.modelId
18534
18763
  });
18535
18764
  };
18536
18765
  const pipeAbortController = new AbortController();
18537
18766
  const transform = new TransformStream({
18538
- transform(value, controller) {
18767
+ async transform(value, controller) {
18539
18768
  switch (value.type) {
18540
18769
  case "stream-start":
18541
18770
  resolveWarnings(value.warnings);
@@ -18563,6 +18792,28 @@ function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}
18563
18792
  durationInSecondsPromise.resolve(value.durationInSeconds);
18564
18793
  responsesPromise.resolve([currentResponseMetadata()]);
18565
18794
  providerMetadataPromise.resolve(value.providerMetadata ?? {});
18795
+ telemetrySettled = true;
18796
+ if (telemetryDispatcher.experimental_onStreamTranscriptionEnd != null) await notify({
18797
+ event: {
18798
+ callId,
18799
+ operationId: "ai.streamTranscribe",
18800
+ provider: resolvedModel.provider,
18801
+ modelId: resolvedModel.modelId,
18802
+ audio: {
18803
+ byteLength: audioByteLength,
18804
+ mediaType: inputAudioFormat.type
18805
+ },
18806
+ text: value.text,
18807
+ segments: value.segments,
18808
+ language: value.language,
18809
+ durationInSeconds: value.durationInSeconds,
18810
+ usage: value.usage,
18811
+ warnings,
18812
+ providerMetadata: value.providerMetadata,
18813
+ response: currentResponseMetadata()
18814
+ },
18815
+ callbacks: [telemetryDispatcher.experimental_onStreamTranscriptionEnd]
18816
+ });
18566
18817
  }
18567
18818
  },
18568
18819
  flush() {
@@ -18572,25 +18823,40 @@ function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}
18572
18823
  pipeAbortController.abort(reason ?? /* @__PURE__ */ new Error("Transcription stream was cancelled."));
18573
18824
  }
18574
18825
  });
18575
- (async () => {
18576
- const result = await doStream({
18577
- audio,
18578
- inputAudioFormat,
18579
- providerOptions,
18580
- abortSignal: mergeAbortSignals(abortSignal, pipeAbortController.signal),
18581
- headers: headersWithUserAgent,
18582
- includeRawChunks
18583
- });
18584
- response = {
18585
- timestamp: result.response?.timestamp ?? startedAt,
18586
- modelId: result.response?.modelId ?? resolvedModel.modelId,
18587
- headers: result.response?.headers
18588
- };
18589
- await result.stream.pipeTo(transform.writable, { signal: pipeAbortController.signal });
18590
- })().catch((error) => {
18826
+ runInTracingChannelSpan({
18827
+ type: "streamTranscribe",
18828
+ event: startEvent,
18829
+ execute: async () => {
18830
+ await notify({
18831
+ event: startEvent,
18832
+ callbacks: [telemetryDispatcher.experimental_onStreamTranscriptionStart]
18833
+ });
18834
+ const result = await doStream({
18835
+ audio: countedAudio,
18836
+ inputAudioFormat,
18837
+ providerOptions,
18838
+ abortSignal: mergeAbortSignals(abortSignal, pipeAbortController.signal),
18839
+ headers: headersWithUserAgent,
18840
+ includeRawChunks
18841
+ });
18842
+ response = {
18843
+ timestamp: result.response?.timestamp ?? startedAt,
18844
+ modelId: result.response?.modelId ?? resolvedModel.modelId,
18845
+ headers: result.response?.headers
18846
+ };
18847
+ await result.stream.pipeTo(transform.writable, { signal: pipeAbortController.signal });
18848
+ }
18849
+ }).catch(async (error) => {
18591
18850
  const reason = error ?? /* @__PURE__ */ new Error("Transcription stream was cancelled or errored.");
18592
18851
  rejectPendingPromises(reason);
18593
- audio.cancel(reason).catch(() => {});
18852
+ if (!telemetrySettled) {
18853
+ telemetrySettled = true;
18854
+ await telemetryDispatcher.onError?.({
18855
+ callId,
18856
+ error: reason
18857
+ });
18858
+ }
18859
+ countedAudio.cancel(reason).catch(() => {});
18594
18860
  transform.writable.abort(reason).catch(() => {});
18595
18861
  });
18596
18862
  let streamOwner = "unclaimed";
@@ -18641,6 +18907,38 @@ function streamTranscribe({ model, audio, inputAudioFormat, providerOptions = {}
18641
18907
  }
18642
18908
  };
18643
18909
  }
18910
+ function createByteCountingStream(audio, onChunk) {
18911
+ let audioReader;
18912
+ return new ReadableStream({
18913
+ async pull(controller) {
18914
+ audioReader ??= audio.getReader();
18915
+ const { done, value } = await audioReader.read();
18916
+ if (done) {
18917
+ controller.close();
18918
+ return;
18919
+ }
18920
+ onChunk(typeof value === "string" ? getBase64ByteLength(value) : value.byteLength);
18921
+ controller.enqueue(value);
18922
+ },
18923
+ async cancel(reason) {
18924
+ if (audioReader != null) await audioReader.cancel(reason);
18925
+ else await audio.cancel(reason);
18926
+ }
18927
+ });
18928
+ }
18929
+ function getBase64ByteLength(value) {
18930
+ let characterCount = 0;
18931
+ let lastCharacter = "";
18932
+ let secondLastCharacter = "";
18933
+ for (const character of value) {
18934
+ if (/\s/.test(character)) continue;
18935
+ characterCount++;
18936
+ secondLastCharacter = lastCharacter;
18937
+ lastCharacter = character;
18938
+ }
18939
+ const padding = lastCharacter === "=" ? secondLastCharacter === "=" ? 2 : 1 : 0;
18940
+ return Math.floor(characterCount * 3 / 4) - padding;
18941
+ }
18644
18942
  //#endregion
18645
18943
  //#region src/transcribe/index.ts
18646
18944
  /**
@@ -19222,15 +19520,32 @@ var AbstractChat = class {
19222
19520
  }
19223
19521
  });
19224
19522
  });
19225
- this.addToolOutput = async ({ state = "output-available", toolCallId, output, errorText, options }) => this.jobExecutor.run(async () => {
19523
+ this.addToolOutput = async ({ state, toolCallId, output, errorText, options }) => this.jobExecutor.run(async () => {
19226
19524
  const messages = this.state.messages;
19227
19525
  const lastMessage = messages[messages.length - 1];
19228
- const updatePart = (part) => isToolUIPart(part) && part.toolCallId === toolCallId ? {
19229
- ...part,
19230
- state,
19231
- output,
19232
- errorText
19233
- } : part;
19526
+ const updatePart = (part) => {
19527
+ if (!isToolUIPart(part) || part.toolCallId !== toolCallId) return part;
19528
+ const { approval: existingApproval, ...toolPart } = part;
19529
+ const approval = existingApproval?.approved === true ? { approval: {
19530
+ ...existingApproval,
19531
+ approved: existingApproval.approved
19532
+ } } : {};
19533
+ return state === "output-error" ? {
19534
+ ...toolPart,
19535
+ ...approval,
19536
+ state,
19537
+ input: part.input,
19538
+ output: void 0,
19539
+ errorText
19540
+ } : {
19541
+ ...toolPart,
19542
+ ...approval,
19543
+ state: "output-available",
19544
+ input: part.input,
19545
+ output,
19546
+ errorText: void 0
19547
+ };
19548
+ };
19234
19549
  this.state.replaceMessage(messages.length - 1, {
19235
19550
  ...lastMessage,
19236
19551
  parts: lastMessage.parts.map(updatePart)