ai 7.0.162 → 7.0.164
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/CHANGELOG.md +78 -0
- package/dist/index.d.ts +166 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +539 -112
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +43 -10
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +209 -24
- package/dist/internal/index.js.map +1 -1
- package/dist/test/index.d.ts +3 -1
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +2 -1
- package/dist/test/index.js.map +1 -1
- package/docs/02-foundations/02-providers-and-models.mdx +2 -0
- package/docs/03-agents/04-loop-control.mdx +34 -0
- package/docs/03-agents/06-memory.mdx +42 -0
- package/docs/03-ai-sdk-core/05-generating-text.mdx +1 -0
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +12 -0
- package/docs/03-ai-sdk-core/36-realtime.mdx +74 -1
- package/docs/03-ai-sdk-core/36-transcription.mdx +51 -4
- package/docs/03-ai-sdk-core/40-middleware.mdx +7 -2
- package/docs/03-ai-sdk-core/60-telemetry.mdx +37 -4
- package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +13 -0
- package/docs/06-advanced/04-caching.mdx +13 -4
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +33 -28
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +58 -1
- package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +17 -2
- package/docs/07-reference/01-ai-sdk-core/13-generate-video.mdx +8 -1
- package/docs/07-reference/01-ai-sdk-core/31-ui-message.mdx +23 -0
- package/docs/07-reference/02-ai-sdk-ui/05-use-realtime.mdx +37 -8
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +1 -49
- package/docs/08-migration-guides/23-migration-guide-7-0.mdx +36 -34
- package/package.json +12 -12
- package/src/generate-object/generate-object.ts +2 -1
- package/src/generate-object/stream-object.ts +7 -3
- package/src/generate-text/generate-text.ts +23 -3
- package/src/generate-text/is-output-chunk.ts +1 -0
- package/src/generate-text/language-model-events.ts +3 -0
- package/src/generate-text/output.ts +90 -37
- package/src/generate-text/smooth-stream.ts +5 -0
- package/src/generate-text/steering.ts +5 -4
- package/src/generate-text/stream-language-model-call.ts +16 -1
- package/src/generate-text/stream-text-result.ts +29 -1
- package/src/generate-text/stream-text.ts +25 -1
- package/src/generate-text/to-response-messages.ts +6 -2
- package/src/generate-video/generate-video-result.ts +11 -2
- package/src/generate-video/generate-video.ts +26 -2
- package/src/model/as-transcription-model-v4.ts +25 -0
- package/src/prompt/convert-to-language-model-prompt.ts +86 -14
- package/src/realtime/index.ts +3 -0
- package/src/realtime/realtime-attempt.ts +1 -0
- package/src/realtime/realtime-session.ts +142 -21
- package/src/telemetry/create-telemetry-dispatcher.ts +8 -1
- package/src/telemetry/filter-telemetry-event.ts +165 -0
- package/src/telemetry/get-request-origin.ts +25 -0
- package/src/telemetry/tracing-channel-publisher.ts +19 -4
- package/src/test/mock-transcription-model-v4.ts +4 -0
- package/src/transcribe/transcribe-result.ts +20 -0
- package/src/transcribe/transcribe.ts +107 -20
- package/src/transcribe/transcription-events.ts +28 -8
- package/src/types/language-model-request-metadata.ts +3 -0
- package/src/types/realtime-model.ts +9 -0
- package/src/ui/convert-to-model-messages.ts +36 -28
- package/src/ui/index.ts +1 -0
- package/src/ui/process-ui-message-stream.ts +10 -0
- package/src/ui/ui-messages.ts +20 -0
- package/src/ui/validate-ui-messages.ts +21 -0
- package/src/ui-message-stream/to-ui-message-chunk.ts +72 -1
- package/src/ui-message-stream/ui-message-chunks.ts +31 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
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, convertAsyncIteratorToReadableStream, 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, isArrayBuffer, isBuffer, isExecutableTool, isFullMediaType, isNonNullable, isProviderReference, isProviderStreamError, isUint8Array, 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";
|
|
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, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertUint8ArrayToBase64, createIdGenerator, createIdGenerator as createIdGenerator$1, delay, detectMediaType, dynamicTool, executeTool, experimental_getToolCaller, experimental_toolCaller, fetchUntrustedUrl, filterNullable, generateId, generateId as generateId$1, getErrorMessage, getRuntimeEnvironmentUserAgent, getTopLevelMediaType, getWebSocketConstructor, isAbortError, isArrayBuffer, isBuffer, isExecutableTool, isFullMediaType, isNonNullable, isProviderReference, isProviderStreamError, isUint8Array, 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, 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
|
+
//#region src/telemetry/get-request-origin.ts
|
|
7
|
+
/** Remove credentials, paths, queries, and fragments before emitting telemetry. */
|
|
8
|
+
function getRequestOrigin(url) {
|
|
9
|
+
if (url == null) return void 0;
|
|
10
|
+
try {
|
|
11
|
+
const endpoint = new URL(url);
|
|
12
|
+
return endpoint.protocol === "http:" || endpoint.protocol === "https:" ? endpoint.origin : void 0;
|
|
13
|
+
} catch {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Preserve request metadata while keeping unknown or sensitive URL fields out of results. */
|
|
18
|
+
function sanitizeRequestMetadata(request) {
|
|
19
|
+
if (request == null || !("url" in request)) return request;
|
|
20
|
+
const { url, ...rest } = request;
|
|
21
|
+
const origin = getRequestOrigin(url);
|
|
22
|
+
return {
|
|
23
|
+
...rest,
|
|
24
|
+
...origin != null ? { url: origin } : {}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
6
28
|
//#region src/error/invalid-argument-error.ts
|
|
7
29
|
const name$23 = "AI_InvalidArgumentError";
|
|
8
30
|
const marker$23 = `vercel.ai.error.${name$23}`;
|
|
@@ -937,6 +959,18 @@ function asTranscriptionModelV4(model) {
|
|
|
937
959
|
const v3Model = model.specificationVersion === "v2" ? asTranscriptionModelV3(model) : model;
|
|
938
960
|
return new Proxy(v3Model, { get(target, prop) {
|
|
939
961
|
if (prop === "specificationVersion") return "v4";
|
|
962
|
+
if (prop === "doGenerate") return async ({ timestampGranularities, ...options }) => {
|
|
963
|
+
const result = await target.doGenerate.call(model, options);
|
|
964
|
+
if (!timestampGranularities?.length) return result;
|
|
965
|
+
return {
|
|
966
|
+
...result,
|
|
967
|
+
warnings: [...result.warnings, {
|
|
968
|
+
type: "unsupported",
|
|
969
|
+
feature: "timestampGranularities",
|
|
970
|
+
details: `Shared timestamp granularities are not supported by ${model.specificationVersion} transcription models.`
|
|
971
|
+
}]
|
|
972
|
+
};
|
|
973
|
+
};
|
|
940
974
|
return target[prop];
|
|
941
975
|
} });
|
|
942
976
|
}
|
|
@@ -1207,7 +1241,7 @@ function cloneValue(value, seen) {
|
|
|
1207
1241
|
}
|
|
1208
1242
|
//#endregion
|
|
1209
1243
|
//#region src/version.ts
|
|
1210
|
-
const VERSION = "7.0.
|
|
1244
|
+
const VERSION = "7.0.164";
|
|
1211
1245
|
//#endregion
|
|
1212
1246
|
//#region src/util/download/download.ts
|
|
1213
1247
|
/**
|
|
@@ -1670,12 +1704,18 @@ async function downloadAssets(messages, download, supportedUrls) {
|
|
|
1670
1704
|
if (message.role === "tool") for (const part of message.content) {
|
|
1671
1705
|
if (part.type !== "tool-result") continue;
|
|
1672
1706
|
if (part.output.type !== "content") continue;
|
|
1673
|
-
for (const contentPart of part.output.value)
|
|
1707
|
+
for (const contentPart of part.output.value) {
|
|
1708
|
+
const filePart = getDownloadableFilePart(contentPart);
|
|
1709
|
+
if (filePart != null) downloadableFiles.push(filePart);
|
|
1710
|
+
}
|
|
1674
1711
|
}
|
|
1675
1712
|
if (message.role === "assistant" && Array.isArray(message.content)) for (const part of message.content) {
|
|
1676
1713
|
if (part.type !== "tool-result") continue;
|
|
1677
1714
|
if (part.output.type !== "content") continue;
|
|
1678
|
-
for (const contentPart of part.output.value)
|
|
1715
|
+
for (const contentPart of part.output.value) {
|
|
1716
|
+
const filePart = getDownloadableFilePart(contentPart);
|
|
1717
|
+
if (filePart != null) downloadableFiles.push(filePart);
|
|
1718
|
+
}
|
|
1679
1719
|
}
|
|
1680
1720
|
}
|
|
1681
1721
|
const plannedDownloads = downloadableFiles.map((part) => {
|
|
@@ -1700,6 +1740,57 @@ async function downloadAssets(messages, download, supportedUrls) {
|
|
|
1700
1740
|
}]).filter((file) => file != null));
|
|
1701
1741
|
}
|
|
1702
1742
|
/**
|
|
1743
|
+
* Resolves the tool result content parts that point at a remote file to the
|
|
1744
|
+
* tagged file shape, including the deprecated `file-url` and `image-url`
|
|
1745
|
+
* types, so that they are downloaded and inlined exactly like their `file`
|
|
1746
|
+
* replacement. Returns `undefined` for content that is already inline or
|
|
1747
|
+
* provider-referenced.
|
|
1748
|
+
*/
|
|
1749
|
+
function getDownloadableFilePart(contentPart) {
|
|
1750
|
+
switch (contentPart.type) {
|
|
1751
|
+
case "file": return contentPart;
|
|
1752
|
+
case "file-url": return {
|
|
1753
|
+
type: "file",
|
|
1754
|
+
data: {
|
|
1755
|
+
type: "url",
|
|
1756
|
+
url: new URL(contentPart.url)
|
|
1757
|
+
},
|
|
1758
|
+
mediaType: contentPart.mediaType ?? getMediaTypeFromUrl(contentPart.url),
|
|
1759
|
+
providerOptions: contentPart.providerOptions
|
|
1760
|
+
};
|
|
1761
|
+
case "image-url": return {
|
|
1762
|
+
type: "file",
|
|
1763
|
+
data: {
|
|
1764
|
+
type: "url",
|
|
1765
|
+
url: new URL(contentPart.url)
|
|
1766
|
+
},
|
|
1767
|
+
mediaType: "image",
|
|
1768
|
+
providerOptions: contentPart.providerOptions
|
|
1769
|
+
};
|
|
1770
|
+
default: return;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
/**
|
|
1774
|
+
* Resolves file data and media type for a remote tool result content part: the downloaded
|
|
1775
|
+
* bytes when the asset was fetched, otherwise the URL reference. `originalUrl`
|
|
1776
|
+
* is preserved when the URL string does not round-trip through `URL`.
|
|
1777
|
+
*/
|
|
1778
|
+
function resolveDownloadedFile({ url, originalUrl, downloadedAssets, mediaType }) {
|
|
1779
|
+
const convertedPart = convertPartToLanguageModelPart({
|
|
1780
|
+
type: "file",
|
|
1781
|
+
data: {
|
|
1782
|
+
type: "url",
|
|
1783
|
+
url,
|
|
1784
|
+
...url.toString() !== originalUrl ? { originalUrl } : {}
|
|
1785
|
+
},
|
|
1786
|
+
mediaType
|
|
1787
|
+
}, downloadedAssets);
|
|
1788
|
+
return {
|
|
1789
|
+
data: convertedPart.data,
|
|
1790
|
+
mediaType: convertedPart.mediaType
|
|
1791
|
+
};
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1703
1794
|
* Convert part of a user message to a LanguageModelV4Part.
|
|
1704
1795
|
*
|
|
1705
1796
|
* @param part - The part to convert.
|
|
@@ -1784,12 +1875,12 @@ function mapToolResultOutput({ output, provider, warnings = [], downloadedAssets
|
|
|
1784
1875
|
});
|
|
1785
1876
|
return {
|
|
1786
1877
|
type: "file",
|
|
1787
|
-
|
|
1788
|
-
type: "url",
|
|
1878
|
+
...resolveDownloadedFile({
|
|
1789
1879
|
url,
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1880
|
+
originalUrl: item.url,
|
|
1881
|
+
downloadedAssets,
|
|
1882
|
+
mediaType
|
|
1883
|
+
}),
|
|
1793
1884
|
providerOptions: item.providerOptions
|
|
1794
1885
|
};
|
|
1795
1886
|
}
|
|
@@ -1850,12 +1941,12 @@ function mapToolResultOutput({ output, provider, warnings = [], downloadedAssets
|
|
|
1850
1941
|
});
|
|
1851
1942
|
return {
|
|
1852
1943
|
type: "file",
|
|
1853
|
-
|
|
1854
|
-
type: "url",
|
|
1944
|
+
...resolveDownloadedFile({
|
|
1855
1945
|
url,
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1946
|
+
originalUrl: item.url,
|
|
1947
|
+
downloadedAssets,
|
|
1948
|
+
mediaType: "image"
|
|
1949
|
+
}),
|
|
1859
1950
|
providerOptions: item.providerOptions
|
|
1860
1951
|
};
|
|
1861
1952
|
}
|
|
@@ -3401,17 +3492,7 @@ const text = () => ({
|
|
|
3401
3492
|
},
|
|
3402
3493
|
createElementStreamTransform() {}
|
|
3403
3494
|
});
|
|
3404
|
-
|
|
3405
|
-
* Output specification for typed object generation using schemas.
|
|
3406
|
-
* When the model generates a text response, it will return an object that matches the schema.
|
|
3407
|
-
*
|
|
3408
|
-
* @param schema - The schema of the object to generate.
|
|
3409
|
-
* @param name - Optional name of the output that should be generated. Used by some providers for additional LLM guidance, e.g. via tool or schema name.
|
|
3410
|
-
* @param description - Optional description of the output that should be generated. Used by some providers for additional LLM guidance, e.g. via tool or schema description.
|
|
3411
|
-
*
|
|
3412
|
-
* @returns An output specification for generating objects with the specified schema.
|
|
3413
|
-
*/
|
|
3414
|
-
const object$1 = ({ schema: inputSchema, name, description }) => {
|
|
3495
|
+
function object$1({ schema: inputSchema, name, description }) {
|
|
3415
3496
|
const schema = asSchema$1(inputSchema);
|
|
3416
3497
|
return {
|
|
3417
3498
|
name: "object",
|
|
@@ -3456,20 +3537,8 @@ const object$1 = ({ schema: inputSchema, name, description }) => {
|
|
|
3456
3537
|
},
|
|
3457
3538
|
createElementStreamTransform() {}
|
|
3458
3539
|
};
|
|
3459
|
-
}
|
|
3460
|
-
|
|
3461
|
-
* Output specification for array generation.
|
|
3462
|
-
* When the model generates a text response, it will return an array of elements.
|
|
3463
|
-
*
|
|
3464
|
-
* @param element - The schema of the array elements to generate.
|
|
3465
|
-
* @param minItems - Optional minimum number of elements to generate.
|
|
3466
|
-
* @param maxItems - Optional maximum number of elements to generate.
|
|
3467
|
-
* @param name - Optional name of the output that should be generated. Used by some providers for additional LLM guidance, e.g. via tool or schema name.
|
|
3468
|
-
* @param description - Optional description of the output that should be generated. Used by some providers for additional LLM guidance, e.g. via tool or schema description.
|
|
3469
|
-
*
|
|
3470
|
-
* @returns An output specification for generating an array of elements.
|
|
3471
|
-
*/
|
|
3472
|
-
const array$1 = ({ element: inputElementSchema, minItems, maxItems, name, description }) => {
|
|
3540
|
+
}
|
|
3541
|
+
function array$1({ element: inputElementSchema, minItems, maxItems, name, description }) {
|
|
3473
3542
|
validateArrayBound({
|
|
3474
3543
|
name: "minItems",
|
|
3475
3544
|
value: minItems
|
|
@@ -3599,7 +3668,7 @@ const array$1 = ({ element: inputElementSchema, minItems, maxItems, name, descri
|
|
|
3599
3668
|
} });
|
|
3600
3669
|
}
|
|
3601
3670
|
};
|
|
3602
|
-
}
|
|
3671
|
+
}
|
|
3603
3672
|
function validateArrayBound({ name, value }) {
|
|
3604
3673
|
if (value == null) return;
|
|
3605
3674
|
if (!Number.isInteger(value)) throw new InvalidArgumentError({
|
|
@@ -4064,7 +4133,7 @@ function loadBuiltinModule(id) {
|
|
|
4064
4133
|
* if tracing itself throws, and prevents falling back by calling `execute` a
|
|
4065
4134
|
* second time.
|
|
4066
4135
|
*/
|
|
4067
|
-
async function runWithTracingChannelSpan(message, execute) {
|
|
4136
|
+
async function runWithTracingChannelSpan(message, execute, recordResult = true) {
|
|
4068
4137
|
const tracingChannel = (await loadDiagnosticsChannel())?.tracingChannel?.(AI_SDK_TELEMETRY_TRACING_CHANNEL);
|
|
4069
4138
|
if (tracingChannel == null || tracingChannel.hasSubscribers === false) return await execute();
|
|
4070
4139
|
let executePromise;
|
|
@@ -4087,10 +4156,13 @@ async function runWithTracingChannelSpan(message, execute) {
|
|
|
4087
4156
|
hasExecutionError = true;
|
|
4088
4157
|
throw error;
|
|
4089
4158
|
});
|
|
4090
|
-
return executePromise
|
|
4159
|
+
return recordResult ? executePromise : executePromise.then(() => void 0, () => {
|
|
4160
|
+
throw new Error("AI SDK operation failed");
|
|
4161
|
+
});
|
|
4091
4162
|
};
|
|
4092
4163
|
try {
|
|
4093
|
-
|
|
4164
|
+
await tracingChannel.tracePromise(tracedExecute, message);
|
|
4165
|
+
return executionResult;
|
|
4094
4166
|
} catch {
|
|
4095
4167
|
if (hasExecutionError) throw executionError;
|
|
4096
4168
|
if (hasExecutionResult) return executionResult;
|
|
@@ -4102,7 +4174,7 @@ async function runWithTracingChannelSpan(message, execute) {
|
|
|
4102
4174
|
* Opens a long-lived tracing-channel span context and returns a runner that can
|
|
4103
4175
|
* re-enter that context later without changing stream setup timing.
|
|
4104
4176
|
*/
|
|
4105
|
-
function openTelemetryChannelSpanContext({ message, completion }) {
|
|
4177
|
+
function openTelemetryChannelSpanContext({ message, completion, recordResult = true }) {
|
|
4106
4178
|
if (!isNodeRuntime()) {
|
|
4107
4179
|
Promise.resolve(completion).catch(() => {});
|
|
4108
4180
|
return;
|
|
@@ -4126,10 +4198,10 @@ function openTelemetryChannelSpanContext({ message, completion }) {
|
|
|
4126
4198
|
if (asyncEndPublished) return;
|
|
4127
4199
|
asyncEndPublished = true;
|
|
4128
4200
|
if (error !== void 0) {
|
|
4129
|
-
context.error = error;
|
|
4201
|
+
context.error = recordResult ? error : /* @__PURE__ */ new Error("AI SDK operation failed");
|
|
4130
4202
|
safePublish(() => tracingChannel.error.publish(context));
|
|
4131
4203
|
}
|
|
4132
|
-
if (result !== void 0) context.result = result;
|
|
4204
|
+
if (recordResult && result !== void 0) context.result = result;
|
|
4133
4205
|
safePublish(() => tracingChannel.asyncEnd.publish(context));
|
|
4134
4206
|
};
|
|
4135
4207
|
safePublish(() => {
|
|
@@ -4154,6 +4226,116 @@ function getGlobalTelemetryIntegrations() {
|
|
|
4154
4226
|
return globalThis.AI_SDK_TELEMETRY_INTEGRATIONS ?? [];
|
|
4155
4227
|
}
|
|
4156
4228
|
//#endregion
|
|
4229
|
+
//#region src/telemetry/filter-telemetry-event.ts
|
|
4230
|
+
/**
|
|
4231
|
+
* Filters SDK-owned content fields on a copy. Only descend into SDK event
|
|
4232
|
+
* containers; user context has its own inclusion policy.
|
|
4233
|
+
*/
|
|
4234
|
+
function filterTelemetryEvent(event, telemetry) {
|
|
4235
|
+
const hideInputs = telemetry.recordInputs === false;
|
|
4236
|
+
const hideOutputs = telemetry.recordOutputs === false;
|
|
4237
|
+
if (!hideInputs && !hideOutputs || event == null || typeof event !== "object") return event;
|
|
4238
|
+
const filtered = Object.assign(Object.create(Object.getPrototypeOf(event)), event);
|
|
4239
|
+
const replace = (fields) => {
|
|
4240
|
+
for (const [key, value] of Object.entries(fields)) if (Object.hasOwn(event, key)) filtered[key] = value;
|
|
4241
|
+
};
|
|
4242
|
+
const isSpeech = filtered.operationId === "ai.generateSpeech";
|
|
4243
|
+
if (hideInputs) {
|
|
4244
|
+
replace({
|
|
4245
|
+
instructions: void 0,
|
|
4246
|
+
system: void 0,
|
|
4247
|
+
prompt: void 0,
|
|
4248
|
+
messages: [],
|
|
4249
|
+
promptMessages: [],
|
|
4250
|
+
experimental_steeringMessages: [],
|
|
4251
|
+
tools: void 0,
|
|
4252
|
+
stepTools: void 0,
|
|
4253
|
+
schema: void 0,
|
|
4254
|
+
schemaName: void 0,
|
|
4255
|
+
schemaDescription: void 0,
|
|
4256
|
+
...typeof filtered.output === "object" ? { output: void 0 } : {},
|
|
4257
|
+
providerOptions: {},
|
|
4258
|
+
value: "",
|
|
4259
|
+
values: [],
|
|
4260
|
+
query: "",
|
|
4261
|
+
documents: [],
|
|
4262
|
+
state: Array.isArray(filtered.state) ? [] : typeof filtered.state === "string" ? "" : {},
|
|
4263
|
+
questions: {},
|
|
4264
|
+
...isSpeech ? { text: "" } : {}
|
|
4265
|
+
});
|
|
4266
|
+
if (filtered.toolCall != null) filtered.toolCall = {
|
|
4267
|
+
...filtered.toolCall,
|
|
4268
|
+
input: void 0
|
|
4269
|
+
};
|
|
4270
|
+
if (filtered.toolOutput != null) filtered.toolOutput = {
|
|
4271
|
+
...filtered.toolOutput,
|
|
4272
|
+
input: void 0
|
|
4273
|
+
};
|
|
4274
|
+
if (Array.isArray(filtered.ranking)) filtered.ranking = filtered.ranking.map((entry) => "document" in entry ? {
|
|
4275
|
+
...entry,
|
|
4276
|
+
document: typeof entry.document === "string" ? "" : {}
|
|
4277
|
+
} : entry);
|
|
4278
|
+
}
|
|
4279
|
+
if (hideOutputs) {
|
|
4280
|
+
replace({
|
|
4281
|
+
content: [],
|
|
4282
|
+
...!isSpeech ? { text: "" } : {},
|
|
4283
|
+
reasoning: Array.isArray(filtered.reasoning) ? [] : void 0,
|
|
4284
|
+
reasoningText: void 0,
|
|
4285
|
+
files: [],
|
|
4286
|
+
sources: [],
|
|
4287
|
+
toolCalls: [],
|
|
4288
|
+
staticToolCalls: [],
|
|
4289
|
+
dynamicToolCalls: [],
|
|
4290
|
+
toolResults: [],
|
|
4291
|
+
staticToolResults: [],
|
|
4292
|
+
dynamicToolResults: [],
|
|
4293
|
+
responseMessages: [],
|
|
4294
|
+
object: void 0,
|
|
4295
|
+
objectText: "",
|
|
4296
|
+
embedding: [],
|
|
4297
|
+
embeddings: [],
|
|
4298
|
+
ranking: [],
|
|
4299
|
+
answers: {},
|
|
4300
|
+
segments: []
|
|
4301
|
+
});
|
|
4302
|
+
if (filtered.toolOutput != null) filtered.toolOutput = {
|
|
4303
|
+
...filtered.toolOutput,
|
|
4304
|
+
output: void 0,
|
|
4305
|
+
error: void 0
|
|
4306
|
+
};
|
|
4307
|
+
}
|
|
4308
|
+
replace({
|
|
4309
|
+
providerMetadata: void 0,
|
|
4310
|
+
error: filtered.error == null ? filtered.error : /* @__PURE__ */ new Error("AI SDK operation failed")
|
|
4311
|
+
});
|
|
4312
|
+
for (const key of ["toolCall", "toolOutput"]) {
|
|
4313
|
+
const toolEvent = filtered[key];
|
|
4314
|
+
if (toolEvent != null && typeof toolEvent === "object") filtered[key] = {
|
|
4315
|
+
...toolEvent,
|
|
4316
|
+
providerMetadata: void 0,
|
|
4317
|
+
..."error" in toolEvent ? { error: toolEvent.error == null ? toolEvent.error : /* @__PURE__ */ new Error("AI SDK operation failed") } : {}
|
|
4318
|
+
};
|
|
4319
|
+
}
|
|
4320
|
+
for (const key of ["request", "response"]) {
|
|
4321
|
+
const filterMetadata = (metadata) => {
|
|
4322
|
+
if (metadata == null || typeof metadata !== "object") return metadata;
|
|
4323
|
+
const filteredMetadata = { ...metadata };
|
|
4324
|
+
delete filteredMetadata.body;
|
|
4325
|
+
if (key === "request" ? hideInputs : hideOutputs) {
|
|
4326
|
+
if ("messages" in metadata) filteredMetadata.messages = [];
|
|
4327
|
+
if ("instructions" in metadata) filteredMetadata.instructions = void 0;
|
|
4328
|
+
}
|
|
4329
|
+
return filteredMetadata;
|
|
4330
|
+
};
|
|
4331
|
+
const metadata = filtered[key];
|
|
4332
|
+
if (metadata != null) filtered[key] = Array.isArray(metadata) ? metadata.map(filterMetadata) : filterMetadata(metadata);
|
|
4333
|
+
}
|
|
4334
|
+
if (Array.isArray(filtered.steps)) filtered.steps = filtered.steps.map((step) => filterTelemetryEvent(step, telemetry));
|
|
4335
|
+
if (Object.hasOwn(event, "finalStep")) filtered.finalStep = filterTelemetryEvent(filtered.finalStep, telemetry);
|
|
4336
|
+
return filtered;
|
|
4337
|
+
}
|
|
4338
|
+
//#endregion
|
|
4157
4339
|
//#region src/telemetry/create-telemetry-dispatcher.ts
|
|
4158
4340
|
function augmentEvent(event, telemetry, filterContext = false) {
|
|
4159
4341
|
const augmentedEvent = Object.assign(Object.create(Object.getPrototypeOf(event)), event, {
|
|
@@ -4177,7 +4359,7 @@ function augmentEvent(event, telemetry, filterContext = false) {
|
|
|
4177
4359
|
includeToolsContext: telemetry.includeToolsContext
|
|
4178
4360
|
});
|
|
4179
4361
|
}
|
|
4180
|
-
return augmentedEvent;
|
|
4362
|
+
return filterTelemetryEvent(augmentedEvent, telemetry);
|
|
4181
4363
|
}
|
|
4182
4364
|
/**
|
|
4183
4365
|
* Creates a telemetry dispatcher that sends telemetry events
|
|
@@ -4203,6 +4385,7 @@ function createTelemetryDispatcher({ telemetry }) {
|
|
|
4203
4385
|
includeRuntimeContext: telemetry?.includeRuntimeContext,
|
|
4204
4386
|
includeToolsContext: telemetry?.includeToolsContext
|
|
4205
4387
|
};
|
|
4388
|
+
const recordResult = telemetry?.recordInputs !== false && telemetry?.recordOutputs !== false;
|
|
4206
4389
|
const mergeTelemetryCallback = (key, deprecatedKey) => {
|
|
4207
4390
|
const integrationCallbacks = integrations.map((integration) => {
|
|
4208
4391
|
const callback = integration[key] ?? (deprecatedKey == null ? void 0 : integration[deprecatedKey]);
|
|
@@ -4222,13 +4405,14 @@ function createTelemetryDispatcher({ telemetry }) {
|
|
|
4222
4405
|
runInTracingChannelSpan: async ({ type, event, execute }) => await runWithTracingChannelSpan({
|
|
4223
4406
|
type,
|
|
4224
4407
|
event: augmentEvent(event, telemetryMetadata, true)
|
|
4225
|
-
}, execute),
|
|
4408
|
+
}, execute, recordResult),
|
|
4226
4409
|
startTracingChannelContext: ({ type, event, completion }) => openTelemetryChannelSpanContext({
|
|
4227
4410
|
message: {
|
|
4228
4411
|
type,
|
|
4229
4412
|
event: augmentEvent(event, telemetryMetadata, true)
|
|
4230
4413
|
},
|
|
4231
|
-
completion
|
|
4414
|
+
completion,
|
|
4415
|
+
recordResult
|
|
4232
4416
|
}),
|
|
4233
4417
|
onStart: mergeTelemetryCallback("onStart"),
|
|
4234
4418
|
onStepStart: mergeTelemetryCallback("onStepStart"),
|
|
@@ -4270,7 +4454,7 @@ function createTelemetryDispatcher({ telemetry }) {
|
|
|
4270
4454
|
return await runWithTracingChannelSpan({
|
|
4271
4455
|
type: "languageModelCall",
|
|
4272
4456
|
event: augmentedEvent
|
|
4273
|
-
}, wrappedExecute);
|
|
4457
|
+
}, wrappedExecute, recordResult);
|
|
4274
4458
|
},
|
|
4275
4459
|
/**
|
|
4276
4460
|
* Composes all `executeTool` wrappers around the original tool execution.
|
|
@@ -4559,7 +4743,10 @@ var DefaultSteering = class {
|
|
|
4559
4743
|
message,
|
|
4560
4744
|
sentMessages
|
|
4561
4745
|
})) {
|
|
4562
|
-
delivered.push(
|
|
4746
|
+
delivered.push({
|
|
4747
|
+
id,
|
|
4748
|
+
message
|
|
4749
|
+
});
|
|
4563
4750
|
resolve({
|
|
4564
4751
|
type: "delivered",
|
|
4565
4752
|
id,
|
|
@@ -4722,7 +4909,7 @@ async function toResponseMessages({ content: inputContent, tools }) {
|
|
|
4722
4909
|
for (const part of inputContent) {
|
|
4723
4910
|
if (part.type === "source") continue;
|
|
4724
4911
|
if ((part.type === "tool-result" || part.type === "tool-error") && !part.providerExecuted) continue;
|
|
4725
|
-
if (part.type === "text" && part.text.length === 0) continue;
|
|
4912
|
+
if (part.type === "text" && part.text.length === 0 && part.providerMetadata == null) continue;
|
|
4726
4913
|
switch (part.type) {
|
|
4727
4914
|
case "text":
|
|
4728
4915
|
content.push({
|
|
@@ -5472,10 +5659,10 @@ async function generateTextInternal({ model: modelArg, tools, toolChoice, instru
|
|
|
5472
5659
|
messages: prepareStepResult?.messages ?? stepInputMessages,
|
|
5473
5660
|
toolCallerMessages
|
|
5474
5661
|
});
|
|
5475
|
-
const deliveredSteeringMessages = steeringRun?.resolveTakenMessages({
|
|
5662
|
+
const deliveredSteeringMessages = (steeringRun?.resolveTakenMessages({
|
|
5476
5663
|
stepNumber,
|
|
5477
5664
|
sentMessages: stepMessages
|
|
5478
|
-
}) ?? [];
|
|
5665
|
+
}) ?? []).map(({ message }) => message);
|
|
5479
5666
|
const promptMessages = await convertToLanguageModelPrompt({
|
|
5480
5667
|
prompt: {
|
|
5481
5668
|
instructions: stepInstructions,
|
|
@@ -5557,6 +5744,7 @@ async function generateTextInternal({ model: modelArg, tools, toolChoice, instru
|
|
|
5557
5744
|
};
|
|
5558
5745
|
return {
|
|
5559
5746
|
...result,
|
|
5747
|
+
...result.request != null ? { request: sanitizeRequestMetadata(result.request) } : {},
|
|
5560
5748
|
response: responseData
|
|
5561
5749
|
};
|
|
5562
5750
|
});
|
|
@@ -5594,6 +5782,7 @@ async function generateTextInternal({ model: modelArg, tools, toolChoice, instru
|
|
|
5594
5782
|
usage: stepUsage,
|
|
5595
5783
|
content: modelCallContent,
|
|
5596
5784
|
responseId: currentModelResponse.response.id,
|
|
5785
|
+
...currentModelResponse.request?.url != null ? { request: { url: getRequestOrigin(currentModelResponse.request.url) } } : {},
|
|
5597
5786
|
...currentModelResponse.providerMetadata != null ? { providerMetadata: currentModelResponse.providerMetadata } : {},
|
|
5598
5787
|
performance: {
|
|
5599
5788
|
responseTimeMs,
|
|
@@ -6435,6 +6624,22 @@ const uiMessageChunkSchema = lazySchema(() => zodSchema$1(z.union([
|
|
|
6435
6624
|
mediaType: z.string(),
|
|
6436
6625
|
providerMetadata: providerMetadataSchema.optional()
|
|
6437
6626
|
}),
|
|
6627
|
+
z.looseObject({
|
|
6628
|
+
type: z.literal("steering-message"),
|
|
6629
|
+
id: z.string(),
|
|
6630
|
+
parts: z.array(z.union([z.looseObject({
|
|
6631
|
+
type: z.literal("text"),
|
|
6632
|
+
text: z.string(),
|
|
6633
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
6634
|
+
}), z.looseObject({
|
|
6635
|
+
type: z.literal("file"),
|
|
6636
|
+
mediaType: z.string(),
|
|
6637
|
+
url: z.string(),
|
|
6638
|
+
filename: z.string().optional(),
|
|
6639
|
+
providerReference: z.record(z.string(), z.string()).optional(),
|
|
6640
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
6641
|
+
})]))
|
|
6642
|
+
}),
|
|
6438
6643
|
z.looseObject({
|
|
6439
6644
|
type: z.custom((value) => typeof value === "string" && value.startsWith("data-"), { message: "Type must start with \"data-\"" }),
|
|
6440
6645
|
id: z.string().optional(),
|
|
@@ -7078,6 +7283,14 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
7078
7283
|
write();
|
|
7079
7284
|
break;
|
|
7080
7285
|
}
|
|
7286
|
+
case "steering-message":
|
|
7287
|
+
state.message.parts.push({
|
|
7288
|
+
type: "steering-message",
|
|
7289
|
+
id: chunk.id,
|
|
7290
|
+
parts: chunk.parts
|
|
7291
|
+
});
|
|
7292
|
+
write();
|
|
7293
|
+
break;
|
|
7081
7294
|
case "start-step":
|
|
7082
7295
|
state.message.parts.push({ type: "step-start" });
|
|
7083
7296
|
break;
|
|
@@ -7425,6 +7638,11 @@ function toUIMessageChunk(part, { tools, sendReasoning = true, sendSources = fal
|
|
|
7425
7638
|
type: "error",
|
|
7426
7639
|
errorText: onError(part.error)
|
|
7427
7640
|
};
|
|
7641
|
+
case "steering-message": return {
|
|
7642
|
+
type: "steering-message",
|
|
7643
|
+
id: part.id,
|
|
7644
|
+
parts: convertUserMessageToUIParts(part.message)
|
|
7645
|
+
};
|
|
7428
7646
|
case "start-step": return { type: "start-step" };
|
|
7429
7647
|
case "finish-step": return { type: "finish-step" };
|
|
7430
7648
|
case "start":
|
|
@@ -7443,10 +7661,53 @@ function toUIMessageChunk(part, { tools, sendReasoning = true, sendSources = fal
|
|
|
7443
7661
|
};
|
|
7444
7662
|
case "abort": return part;
|
|
7445
7663
|
case "tool-input-end":
|
|
7664
|
+
case "ping":
|
|
7446
7665
|
case "raw": return;
|
|
7447
7666
|
default: throw new Error(`Unknown chunk type: ${partType}`);
|
|
7448
7667
|
}
|
|
7449
7668
|
}
|
|
7669
|
+
function convertUserMessageToUIParts(message) {
|
|
7670
|
+
if (typeof message.content === "string") return [{
|
|
7671
|
+
type: "text",
|
|
7672
|
+
text: message.content
|
|
7673
|
+
}];
|
|
7674
|
+
return message.content.map((part) => {
|
|
7675
|
+
const providerMetadata = part.providerOptions != null ? { providerMetadata: part.providerOptions } : {};
|
|
7676
|
+
if (part.type === "text") return {
|
|
7677
|
+
type: "text",
|
|
7678
|
+
text: part.text,
|
|
7679
|
+
...providerMetadata
|
|
7680
|
+
};
|
|
7681
|
+
const { data, mediaType: dataUrlMediaType } = convertToLanguageModelV4FilePart(part.type === "image" ? part.image : part.data);
|
|
7682
|
+
const mediaType = dataUrlMediaType ?? part.mediaType ?? "image";
|
|
7683
|
+
const filename = part.type === "file" ? part.filename : void 0;
|
|
7684
|
+
const file = {
|
|
7685
|
+
type: "file",
|
|
7686
|
+
mediaType,
|
|
7687
|
+
...filename != null ? { filename } : {},
|
|
7688
|
+
...providerMetadata
|
|
7689
|
+
};
|
|
7690
|
+
switch (data.type) {
|
|
7691
|
+
case "url": return {
|
|
7692
|
+
...file,
|
|
7693
|
+
url: data.url.toString()
|
|
7694
|
+
};
|
|
7695
|
+
case "data": return {
|
|
7696
|
+
...file,
|
|
7697
|
+
url: `data:${mediaType};base64,${convertDataContentToBase64String(data.data)}`
|
|
7698
|
+
};
|
|
7699
|
+
case "text": return {
|
|
7700
|
+
...file,
|
|
7701
|
+
url: `data:${mediaType};base64,${convertUint8ArrayToBase64(new TextEncoder().encode(data.text))}`
|
|
7702
|
+
};
|
|
7703
|
+
case "reference": return {
|
|
7704
|
+
...file,
|
|
7705
|
+
url: "",
|
|
7706
|
+
providerReference: data.reference
|
|
7707
|
+
};
|
|
7708
|
+
}
|
|
7709
|
+
});
|
|
7710
|
+
}
|
|
7450
7711
|
//#endregion
|
|
7451
7712
|
//#region src/ui-message-stream/to-ui-message-stream.ts
|
|
7452
7713
|
/**
|
|
@@ -7979,6 +8240,7 @@ const isOutputChunkType = {
|
|
|
7979
8240
|
"model-call-response-metadata": false,
|
|
7980
8241
|
"model-call-end": false,
|
|
7981
8242
|
error: false,
|
|
8243
|
+
ping: false,
|
|
7982
8244
|
raw: false
|
|
7983
8245
|
};
|
|
7984
8246
|
function isOutputChunk$1(chunk) {
|
|
@@ -8284,7 +8546,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8284
8546
|
callbacks: onLanguageModelCallStart
|
|
8285
8547
|
});
|
|
8286
8548
|
const callStartTimestampMs = now$3();
|
|
8287
|
-
const { stream: languageModelStream, response, request } = await executeLanguageModelCallInTelemetryContext({
|
|
8549
|
+
const { stream: languageModelStream, response, request: rawRequest } = await executeLanguageModelCallInTelemetryContext({
|
|
8288
8550
|
...languageModelCallStartEvent,
|
|
8289
8551
|
execute: async () => await resolvedModel.doStream({
|
|
8290
8552
|
...callSettings,
|
|
@@ -8298,6 +8560,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8298
8560
|
includeRawChunks
|
|
8299
8561
|
})
|
|
8300
8562
|
});
|
|
8563
|
+
const request = sanitizeRequestMetadata(rawRequest);
|
|
8301
8564
|
return {
|
|
8302
8565
|
stream: createAsyncIterableStream(languageModelStream.pipeThrough(createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
|
|
8303
8566
|
tools,
|
|
@@ -8313,6 +8576,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8313
8576
|
generateId,
|
|
8314
8577
|
now: now$3,
|
|
8315
8578
|
callStartTimestampMs,
|
|
8579
|
+
request,
|
|
8316
8580
|
onLanguageModelCallEnd,
|
|
8317
8581
|
collectContent
|
|
8318
8582
|
}))),
|
|
@@ -8320,7 +8584,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8320
8584
|
request
|
|
8321
8585
|
};
|
|
8322
8586
|
}
|
|
8323
|
-
function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({ tools, instructions, messages, repairToolCall, refineToolInput, abortSignal, callId, provider, modelId, toolChoice, generateId, now, callStartTimestampMs, onLanguageModelCallEnd, collectContent }) {
|
|
8587
|
+
function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({ tools, instructions, messages, repairToolCall, refineToolInput, abortSignal, callId, provider, modelId, toolChoice, generateId, now, callStartTimestampMs, request, onLanguageModelCallEnd, collectContent }) {
|
|
8324
8588
|
const toolCallsByToolCallId = /* @__PURE__ */ new Map();
|
|
8325
8589
|
const modelCallContent = [];
|
|
8326
8590
|
const rawModelCallContent = [];
|
|
@@ -8498,6 +8762,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({ too
|
|
|
8498
8762
|
usage,
|
|
8499
8763
|
content: modelCallContent,
|
|
8500
8764
|
responseId,
|
|
8765
|
+
...request?.url != null ? { request: { url: getRequestOrigin(request.url) } } : {},
|
|
8501
8766
|
...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {},
|
|
8502
8767
|
performance
|
|
8503
8768
|
},
|
|
@@ -9792,10 +10057,20 @@ var DefaultStreamTextResult = class {
|
|
|
9792
10057
|
toolCallerMessages
|
|
9793
10058
|
});
|
|
9794
10059
|
currentStepMessages = stepMessages;
|
|
9795
|
-
|
|
10060
|
+
const deliveredSteeringMessages = steeringRun?.resolveTakenMessages({
|
|
9796
10061
|
stepNumber: currentStep,
|
|
9797
10062
|
sentMessages: stepMessages
|
|
9798
10063
|
}) ?? [];
|
|
10064
|
+
currentStepSteeringMessages = deliveredSteeringMessages.map(({ message }) => message);
|
|
10065
|
+
if (deliveredSteeringMessages.length > 0) self.addStream(new ReadableStream({ start(controller) {
|
|
10066
|
+
for (const { id, message } of deliveredSteeringMessages) controller.enqueue({
|
|
10067
|
+
type: "steering-message",
|
|
10068
|
+
id,
|
|
10069
|
+
message,
|
|
10070
|
+
stepNumber: currentStep
|
|
10071
|
+
});
|
|
10072
|
+
controller.close();
|
|
10073
|
+
} }));
|
|
9799
10074
|
const stepInstructions = prepareStepResult?.instructions ?? prepareStepResult?.system ?? instructionsForNextStep;
|
|
9800
10075
|
instructionsForNextStep = stepInstructions;
|
|
9801
10076
|
const stepProviderOptions = mergeObjects(providerOptions, prepareStepResult?.providerOptions);
|
|
@@ -9940,7 +10215,7 @@ var DefaultStreamTextResult = class {
|
|
|
9940
10215
|
clearFirstChunkTimeout();
|
|
9941
10216
|
resetChunkTimeout();
|
|
9942
10217
|
}
|
|
9943
|
-
if (shouldBufferToolParts && value.type !== "error" && (isToolPart || bufferedAttemptParts.length > 0)) {
|
|
10218
|
+
if (shouldBufferToolParts && value.type !== "error" && value.type !== "ping" && (isToolPart || bufferedAttemptParts.length > 0)) {
|
|
9944
10219
|
bufferedAttemptParts.push(value);
|
|
9945
10220
|
continue;
|
|
9946
10221
|
}
|
|
@@ -10105,6 +10380,7 @@ var DefaultStreamTextResult = class {
|
|
|
10105
10380
|
case "tool-input-end":
|
|
10106
10381
|
case "tool-input-delta":
|
|
10107
10382
|
case "tool-approval-request":
|
|
10383
|
+
case "ping":
|
|
10108
10384
|
case "tool-output-denied":
|
|
10109
10385
|
enqueueStepPart(controller, chunk);
|
|
10110
10386
|
break;
|
|
@@ -11043,24 +11319,7 @@ async function convertToModelMessages(messages, options) {
|
|
|
11043
11319
|
modelMessages.push({
|
|
11044
11320
|
role: "user",
|
|
11045
11321
|
content: message.parts.map((part) => {
|
|
11046
|
-
if (isTextUIPart(part)) return
|
|
11047
|
-
type: "text",
|
|
11048
|
-
text: part.text,
|
|
11049
|
-
...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
|
|
11050
|
-
};
|
|
11051
|
-
if (isFileUIPart(part)) return {
|
|
11052
|
-
type: "file",
|
|
11053
|
-
mediaType: part.mediaType,
|
|
11054
|
-
filename: part.filename,
|
|
11055
|
-
data: part.providerReference != null ? {
|
|
11056
|
-
type: "reference",
|
|
11057
|
-
reference: part.providerReference
|
|
11058
|
-
} : {
|
|
11059
|
-
type: "url",
|
|
11060
|
-
url: new URL(part.url)
|
|
11061
|
-
},
|
|
11062
|
-
...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
|
|
11063
|
-
};
|
|
11322
|
+
if (isTextUIPart(part) || isFileUIPart(part)) return convertUserContentUIPart(part);
|
|
11064
11323
|
if (isDataUIPart(part)) return options?.convertDataPart?.(part);
|
|
11065
11324
|
}).filter(isNonNullable)
|
|
11066
11325
|
});
|
|
@@ -11216,6 +11475,13 @@ async function convertToModelMessages(messages, options) {
|
|
|
11216
11475
|
}
|
|
11217
11476
|
for (const part of message.parts) if (isCustomContentUIPart(part) || isTextUIPart(part) || isReasoningUIPart(part) || isReasoningFileUIPart(part) || isFileUIPart(part) || isToolUIPart(part) || isDataUIPart(part)) block.push(part);
|
|
11218
11477
|
else if (part.type === "step-start") await processBlock();
|
|
11478
|
+
else if (part.type === "steering-message") {
|
|
11479
|
+
await processBlock();
|
|
11480
|
+
modelMessages.push({
|
|
11481
|
+
role: "user",
|
|
11482
|
+
content: part.parts.map(convertUserContentUIPart)
|
|
11483
|
+
});
|
|
11484
|
+
}
|
|
11219
11485
|
await processBlock();
|
|
11220
11486
|
break;
|
|
11221
11487
|
}
|
|
@@ -11230,6 +11496,26 @@ async function convertToModelMessages(messages, options) {
|
|
|
11230
11496
|
}
|
|
11231
11497
|
return modelMessages;
|
|
11232
11498
|
}
|
|
11499
|
+
function convertUserContentUIPart(part) {
|
|
11500
|
+
if (part.type === "text") return {
|
|
11501
|
+
type: "text",
|
|
11502
|
+
text: part.text,
|
|
11503
|
+
...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
|
|
11504
|
+
};
|
|
11505
|
+
return {
|
|
11506
|
+
type: "file",
|
|
11507
|
+
mediaType: part.mediaType,
|
|
11508
|
+
filename: part.filename,
|
|
11509
|
+
data: part.providerReference != null ? {
|
|
11510
|
+
type: "reference",
|
|
11511
|
+
reference: part.providerReference
|
|
11512
|
+
} : {
|
|
11513
|
+
type: "url",
|
|
11514
|
+
url: new URL(part.url)
|
|
11515
|
+
},
|
|
11516
|
+
...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
|
|
11517
|
+
};
|
|
11518
|
+
}
|
|
11233
11519
|
//#endregion
|
|
11234
11520
|
//#region src/ui/validate-ui-messages.ts
|
|
11235
11521
|
const toolMetadataSchema = z.record(z.string(), jsonValueSchema.optional());
|
|
@@ -11322,6 +11608,22 @@ const uiMessagesSchema = lazySchema(() => {
|
|
|
11322
11608
|
url: z.string(),
|
|
11323
11609
|
providerMetadata: providerMetadataSchema.optional()
|
|
11324
11610
|
}),
|
|
11611
|
+
z.object({
|
|
11612
|
+
type: z.literal("steering-message"),
|
|
11613
|
+
id: z.string(),
|
|
11614
|
+
parts: z.array(z.union([z.object({
|
|
11615
|
+
type: z.literal("text"),
|
|
11616
|
+
text: z.string(),
|
|
11617
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
11618
|
+
}), z.object({
|
|
11619
|
+
type: z.literal("file"),
|
|
11620
|
+
mediaType: z.string(),
|
|
11621
|
+
filename: z.string().optional(),
|
|
11622
|
+
url: z.string(),
|
|
11623
|
+
providerReference: providerReferenceSchema$1.optional(),
|
|
11624
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
11625
|
+
})]))
|
|
11626
|
+
}),
|
|
11325
11627
|
z.object({ type: z.literal("step-start") }),
|
|
11326
11628
|
z.object({
|
|
11327
11629
|
type: z.string().startsWith("data-"),
|
|
@@ -13864,7 +14166,7 @@ async function generateObject(options) {
|
|
|
13864
14166
|
const usage = asLanguageModelUsage(generateResult.usage);
|
|
13865
14167
|
const warnings = generateResult.warnings;
|
|
13866
14168
|
const resultProviderMetadata = generateResult.providerMetadata;
|
|
13867
|
-
const request = generateResult.request ?? {};
|
|
14169
|
+
const request = sanitizeRequestMetadata(generateResult.request) ?? {};
|
|
13868
14170
|
const response = responseData;
|
|
13869
14171
|
logWarnings({
|
|
13870
14172
|
warnings,
|
|
@@ -14323,7 +14625,8 @@ var DefaultStreamObjectResult = class {
|
|
|
14323
14625
|
}
|
|
14324
14626
|
} };
|
|
14325
14627
|
const startTimestampMs = now();
|
|
14326
|
-
const { stream, response, request } = await retry(() => model.doStream(callOptions));
|
|
14628
|
+
const { stream, response, request: rawRequest } = await retry(() => model.doStream(callOptions));
|
|
14629
|
+
const request = sanitizeRequestMetadata(rawRequest);
|
|
14327
14630
|
self._request.resolve(request ?? {});
|
|
14328
14631
|
let warnings;
|
|
14329
14632
|
let usage = createNullLanguageModelUsage();
|
|
@@ -15254,6 +15557,10 @@ function smoothStream({ delayInMs = 10, chunking = "word", _internal: { delay: d
|
|
|
15254
15557
|
}
|
|
15255
15558
|
}
|
|
15256
15559
|
return new TransformStream({ async transform(chunk, controller) {
|
|
15560
|
+
if (chunk.type === "ping") {
|
|
15561
|
+
controller.enqueue(chunk);
|
|
15562
|
+
return;
|
|
15563
|
+
}
|
|
15257
15564
|
if (chunk.type !== "text-delta" && chunk.type !== "reasoning-delta") {
|
|
15258
15565
|
flushBuffer(controller);
|
|
15259
15566
|
controller.enqueue(chunk);
|
|
@@ -15424,10 +15731,14 @@ async function experimental_generateVideo({ model: modelArg, prompt: promptArg,
|
|
|
15424
15731
|
return retry(() => model.doGenerate(callOptions));
|
|
15425
15732
|
}));
|
|
15426
15733
|
const videos = [];
|
|
15734
|
+
let uploadedVideos = 0;
|
|
15427
15735
|
const responses = [];
|
|
15428
15736
|
const providerMetadata = {};
|
|
15429
15737
|
for (const result of results) {
|
|
15430
15738
|
for (const videoData of result.videos) switch (videoData.type) {
|
|
15739
|
+
case "uploaded":
|
|
15740
|
+
uploadedVideos++;
|
|
15741
|
+
break;
|
|
15431
15742
|
case "url": {
|
|
15432
15743
|
const { data, mediaType: downloadedMediaType } = await downloadFn({
|
|
15433
15744
|
url: new URL(videoData.url),
|
|
@@ -15471,19 +15782,30 @@ async function experimental_generateVideo({ model: modelArg, prompt: promptArg,
|
|
|
15471
15782
|
});
|
|
15472
15783
|
if (result.providerMetadata != null) mergeProviderMetadata(providerMetadata, result.providerMetadata);
|
|
15473
15784
|
}
|
|
15474
|
-
if (videos.length === 0) throw new NoVideoGeneratedError({ responses });
|
|
15785
|
+
if (videos.length === 0 && uploadedVideos === 0) throw new NoVideoGeneratedError({ responses });
|
|
15475
15786
|
if (warnings.length > 0) logWarnings({
|
|
15476
15787
|
warnings,
|
|
15477
15788
|
provider: model.provider,
|
|
15478
15789
|
model: model.modelId
|
|
15479
15790
|
});
|
|
15480
|
-
|
|
15791
|
+
const result = {
|
|
15481
15792
|
video: videos[0],
|
|
15482
15793
|
videos,
|
|
15794
|
+
uploadedVideos,
|
|
15483
15795
|
warnings,
|
|
15484
15796
|
responses,
|
|
15485
15797
|
providerMetadata
|
|
15486
15798
|
};
|
|
15799
|
+
if (videos.length === 0) Object.defineProperty(result, "video", {
|
|
15800
|
+
enumerable: false,
|
|
15801
|
+
get() {
|
|
15802
|
+
throw new NoVideoGeneratedError({
|
|
15803
|
+
message: "Videos were delivered to the upload destination. Use uploadedVideos instead of video.",
|
|
15804
|
+
responses
|
|
15805
|
+
});
|
|
15806
|
+
}
|
|
15807
|
+
});
|
|
15808
|
+
return result;
|
|
15487
15809
|
}
|
|
15488
15810
|
async function executeStartStatusFlow({ model, callOptions, poll: pollConfig, webhook: webhookFactory, maxRetries, retry }) {
|
|
15489
15811
|
const earlyWarnings = [];
|
|
@@ -18039,6 +18361,7 @@ var BrowserRealtimeWebRTC = class {
|
|
|
18039
18361
|
var RealtimeAttempt = class {
|
|
18040
18362
|
constructor() {
|
|
18041
18363
|
this.abort = new AbortController();
|
|
18364
|
+
this.reportedTransportErrors = /* @__PURE__ */ new WeakSet();
|
|
18042
18365
|
this.timers = /* @__PURE__ */ new Map();
|
|
18043
18366
|
this.active = true;
|
|
18044
18367
|
this.ready = false;
|
|
@@ -18544,9 +18867,13 @@ var AbstractRealtimeSession = class {
|
|
|
18544
18867
|
}
|
|
18545
18868
|
validateConnection() {
|
|
18546
18869
|
const { model, api } = this.options;
|
|
18547
|
-
if ((!this.continuous || api.session != null) && this.options.maxPlaybackBufferSeconds != null) throw new Error("maxPlaybackBufferSeconds is supported only for continuous PCM sessions");
|
|
18548
|
-
const connection = api.session != null ? "webrtc" : api.token != null ? "client-secret-websocket" : "server-websocket";
|
|
18549
|
-
if (!(model.capabilities?.connections ?? ["client-secret-websocket"]).includes(connection) || model.capabilities?.transports != null && !model.capabilities.transports.includes(api.session != null ? "webrtc" : "websocket")) throw new Error(`Realtime model does not support ${connection}`);
|
|
18870
|
+
if ((!this.continuous || api.session != null || api.provider != null) && this.options.maxPlaybackBufferSeconds != null) throw new Error("maxPlaybackBufferSeconds is supported only for continuous PCM sessions");
|
|
18871
|
+
const connection = api.provider != null ? "provider" : api.session != null ? "webrtc" : api.token != null ? "client-secret-websocket" : "server-websocket";
|
|
18872
|
+
if (!(model.capabilities?.connections ?? ["client-secret-websocket"]).includes(connection) || api.provider == null && model.capabilities?.transports != null && !model.capabilities.transports.includes(api.session != null ? "webrtc" : "websocket")) throw new Error(`Realtime model does not support ${connection}`);
|
|
18873
|
+
if (api.provider != null) {
|
|
18874
|
+
if (model.createTransport == null) throw new Error("Realtime model does not support a provider transport");
|
|
18875
|
+
return;
|
|
18876
|
+
}
|
|
18550
18877
|
if (api.session != null) {
|
|
18551
18878
|
if (model.getWebRTCConfig == null) throw new Error("Realtime model does not support WebRTC configuration");
|
|
18552
18879
|
return;
|
|
@@ -18570,7 +18897,7 @@ var AbstractRealtimeSession = class {
|
|
|
18570
18897
|
if (connectOptions?.capture === false) this.stopAudioCapture();
|
|
18571
18898
|
if (!current()) return;
|
|
18572
18899
|
if (connectOptions?.stream != null && connectOptions.stream !== this.suppliedStream) {
|
|
18573
|
-
if (this.captureRequested && !this.sessionLifecycle && !this.continuous && api.session == null) this.startAudioCapture(connectOptions.stream);
|
|
18900
|
+
if (this.captureRequested && !this.sessionLifecycle && !this.continuous && api.session == null && api.provider == null) this.startAudioCapture(connectOptions.stream);
|
|
18574
18901
|
else this.suppliedStream = connectOptions.stream;
|
|
18575
18902
|
}
|
|
18576
18903
|
if (!current()) return;
|
|
@@ -18592,7 +18919,7 @@ var AbstractRealtimeSession = class {
|
|
|
18592
18919
|
attempt.timer("startup", this.options.startupTimeoutMs ?? 3e4, () => {
|
|
18593
18920
|
if (current()) this.fail(/* @__PURE__ */ new Error("Realtime session startup timed out"));
|
|
18594
18921
|
});
|
|
18595
|
-
const reportedTransportErrors =
|
|
18922
|
+
const reportedTransportErrors = attempt.reportedTransportErrors;
|
|
18596
18923
|
const callbacks = {
|
|
18597
18924
|
model,
|
|
18598
18925
|
onEvent: async (event) => {
|
|
@@ -18600,7 +18927,7 @@ var AbstractRealtimeSession = class {
|
|
|
18600
18927
|
try {
|
|
18601
18928
|
await this.handleServerEvent(event, attempt);
|
|
18602
18929
|
} catch (error) {
|
|
18603
|
-
if (current()) this.fail(error, (this.rtc ?? this.pcm ?? this.transport)?.finish());
|
|
18930
|
+
if (current()) this.fail(error, (this.providerTransport ?? this.rtc ?? this.pcm ?? this.transport)?.finish());
|
|
18604
18931
|
}
|
|
18605
18932
|
},
|
|
18606
18933
|
onError: (error) => {
|
|
@@ -18628,6 +18955,13 @@ var AbstractRealtimeSession = class {
|
|
|
18628
18955
|
onClose: (error) => {
|
|
18629
18956
|
if (!current()) return;
|
|
18630
18957
|
const finalizationConfirmed = model.capabilities?.finalization === "session-close" && this.state.session?.finalization === "confirmed";
|
|
18958
|
+
if (api.provider != null && attempt.closing) {
|
|
18959
|
+
if (error != null && !finalizationConfirmed && !reportedTransportErrors.has(error)) {
|
|
18960
|
+
reportedTransportErrors.add(error);
|
|
18961
|
+
this.reportError(error, attempt);
|
|
18962
|
+
}
|
|
18963
|
+
return;
|
|
18964
|
+
}
|
|
18631
18965
|
if (error != null && !finalizationConfirmed) this.fail(error, void 0, !reportedTransportErrors.has(error));
|
|
18632
18966
|
else if (!attempt.ready && !finalizationConfirmed) this.fail(/* @__PURE__ */ new Error("Realtime connection closed before becoming ready"));
|
|
18633
18967
|
else this.disconnect();
|
|
@@ -18645,7 +18979,21 @@ var AbstractRealtimeSession = class {
|
|
|
18645
18979
|
});
|
|
18646
18980
|
}
|
|
18647
18981
|
};
|
|
18648
|
-
if (api.
|
|
18982
|
+
if (api.provider != null) {
|
|
18983
|
+
const transport = model.createTransport(callbacks);
|
|
18984
|
+
if (!current()) {
|
|
18985
|
+
transport.dispose();
|
|
18986
|
+
return;
|
|
18987
|
+
}
|
|
18988
|
+
this.providerTransport = transport;
|
|
18989
|
+
await transport.connect({
|
|
18990
|
+
api: api.provider,
|
|
18991
|
+
sessionConfig,
|
|
18992
|
+
stream: connectOptions?.stream,
|
|
18993
|
+
capture: connectOptions?.capture,
|
|
18994
|
+
abortSignal: attempt.abort.signal
|
|
18995
|
+
});
|
|
18996
|
+
} else if (api.session != null) {
|
|
18649
18997
|
this.rtc = new BrowserRealtimeWebRTC({
|
|
18650
18998
|
...callbacks,
|
|
18651
18999
|
disconnectTimeoutMs: this.options.rtcDisconnectTimeoutMs
|
|
@@ -18761,8 +19109,12 @@ var AbstractRealtimeSession = class {
|
|
|
18761
19109
|
closeFailed(attempt, error) {
|
|
18762
19110
|
if (this.attempt !== attempt || !attempt.active || attempt.transportClosing) return;
|
|
18763
19111
|
attempt.clearTimer("close");
|
|
18764
|
-
const transport = this.rtc ?? this.pcm ?? this.transport;
|
|
19112
|
+
const transport = this.providerTransport ?? this.rtc ?? this.pcm ?? this.transport;
|
|
18765
19113
|
this.drainAttempt(attempt, transport?.finish());
|
|
19114
|
+
if (error instanceof Error) {
|
|
19115
|
+
if (attempt.reportedTransportErrors.has(error)) return;
|
|
19116
|
+
attempt.reportedTransportErrors.add(error);
|
|
19117
|
+
}
|
|
18766
19118
|
this.reportError(error, attempt);
|
|
18767
19119
|
}
|
|
18768
19120
|
disconnect() {
|
|
@@ -18774,16 +19126,19 @@ var AbstractRealtimeSession = class {
|
|
|
18774
19126
|
const audio = this.audio;
|
|
18775
19127
|
const pcm = this.pcm;
|
|
18776
19128
|
const rtc = this.rtc;
|
|
19129
|
+
const providerTransport = this.providerTransport;
|
|
18777
19130
|
this.transport = void 0;
|
|
18778
19131
|
this.audio = void 0;
|
|
18779
19132
|
this.pcm = void 0;
|
|
18780
19133
|
this.rtc = void 0;
|
|
19134
|
+
this.providerTransport = void 0;
|
|
18781
19135
|
this.commands = void 0;
|
|
18782
19136
|
attempt?.retire();
|
|
18783
19137
|
transport?.dispose();
|
|
18784
19138
|
audio?.dispose();
|
|
18785
19139
|
pcm?.dispose();
|
|
18786
19140
|
rtc?.dispose();
|
|
19141
|
+
providerTransport?.dispose();
|
|
18787
19142
|
if (this.attempt !== attempt) return;
|
|
18788
19143
|
const session = this.state.session;
|
|
18789
19144
|
this.applyState({
|
|
@@ -18797,10 +19152,27 @@ var AbstractRealtimeSession = class {
|
|
|
18797
19152
|
} } : {}
|
|
18798
19153
|
});
|
|
18799
19154
|
}
|
|
18800
|
-
/** Wait for
|
|
19155
|
+
/** Wait for provider cleanup or supported session-close finalization. */
|
|
18801
19156
|
close(options) {
|
|
18802
19157
|
const attempt = this.attempt;
|
|
18803
19158
|
if (attempt?.closePromise != null) return attempt.closePromise;
|
|
19159
|
+
const providerTransport = this.providerTransport;
|
|
19160
|
+
if (providerTransport != null && attempt?.active) {
|
|
19161
|
+
const promise = attempt.beginClose();
|
|
19162
|
+
attempt.clearTimer("startup");
|
|
19163
|
+
this.applyState({
|
|
19164
|
+
...this.state,
|
|
19165
|
+
status: "closing"
|
|
19166
|
+
});
|
|
19167
|
+
if (this.attempt !== attempt || !attempt.active) return promise;
|
|
19168
|
+
this.stopAudioCapture();
|
|
19169
|
+
if (this.attempt !== attempt || !attempt.active) return promise;
|
|
19170
|
+
attempt.timer("close", this.options.closeTimeoutMs ?? 15e3, () => {
|
|
19171
|
+
if (this.attempt === attempt && attempt.active) this.fail(/* @__PURE__ */ new Error("Realtime provider session cleanup timed out"));
|
|
19172
|
+
});
|
|
19173
|
+
providerTransport.close().then(() => this.finishAttempt(attempt), (error) => this.closeFailed(attempt, error));
|
|
19174
|
+
return promise;
|
|
19175
|
+
}
|
|
18804
19176
|
if (this.state.status !== "connected" || this.options.model.capabilities?.finalization !== "session-close" || attempt == null) {
|
|
18805
19177
|
this.disconnect();
|
|
18806
19178
|
return Promise.resolve();
|
|
@@ -18827,8 +19199,16 @@ var AbstractRealtimeSession = class {
|
|
|
18827
19199
|
return promise;
|
|
18828
19200
|
}
|
|
18829
19201
|
sendTransport(event, guard, automaticAudio = false) {
|
|
18830
|
-
const transport = this.rtc ?? this.pcm ?? this.transport;
|
|
19202
|
+
const transport = this.providerTransport ?? this.rtc ?? this.pcm ?? this.transport;
|
|
18831
19203
|
if (transport == null) throw new Error("Realtime connection is not open");
|
|
19204
|
+
if (transport === this.providerTransport) {
|
|
19205
|
+
const attempt = this.attempt;
|
|
19206
|
+
const sent = transport.sendEvent(event, guard);
|
|
19207
|
+
sent.catch((error) => {
|
|
19208
|
+
if (attempt?.active && this.attempt === attempt) this.reportError(error, attempt);
|
|
19209
|
+
});
|
|
19210
|
+
return sent;
|
|
19211
|
+
}
|
|
18832
19212
|
if (transport === this.transport) return this.transport.sendEvent(event, guard, automaticAudio);
|
|
18833
19213
|
return transport.sendEvent(event, guard);
|
|
18834
19214
|
}
|
|
@@ -18914,14 +19294,14 @@ var AbstractRealtimeSession = class {
|
|
|
18914
19294
|
this.maybeRequestToolResponse();
|
|
18915
19295
|
}
|
|
18916
19296
|
maybeRequestToolResponse() {
|
|
18917
|
-
if (this.state.status !== "connected" || this.attempt?.closing || !this.responseToolCallsClosed || this.toolCallsInResponse.size === 0 || [...this.toolCallsInResponse].some((id) => !this.submittedToolOutputs.has(id))) return;
|
|
19297
|
+
if (this.providerTransport != null || this.state.status !== "connected" || this.attempt?.closing || !this.responseToolCallsClosed || this.toolCallsInResponse.size === 0 || [...this.toolCallsInResponse].some((id) => !this.submittedToolOutputs.has(id))) return;
|
|
18918
19298
|
this.sendEvent({ type: "response-create" });
|
|
18919
19299
|
this.toolCallsInResponse.clear();
|
|
18920
19300
|
this.submittedToolOutputs.clear();
|
|
18921
19301
|
this.responseToolCallsClosed = false;
|
|
18922
19302
|
}
|
|
18923
19303
|
startAudioCapture(stream) {
|
|
18924
|
-
const legacy = !this.sessionLifecycle && !this.continuous && this.options.api.session == null;
|
|
19304
|
+
const legacy = !this.sessionLifecycle && !this.continuous && this.options.api.session == null && this.options.api.provider == null;
|
|
18925
19305
|
if (!legacy && this.state.status !== "connected") throw new Error("Realtime session is not accepting capture");
|
|
18926
19306
|
if (this.attempt?.active && (this.attempt.closing || this.attempt.cause != null)) throw new Error("Realtime session is not accepting capture");
|
|
18927
19307
|
this.suppliedStream = stream;
|
|
@@ -18940,6 +19320,7 @@ var AbstractRealtimeSession = class {
|
|
|
18940
19320
|
const accepting = () => !this.attempt?.closing && this.attempt?.cause == null && (this.state.status === "connected" || !this.sessionLifecycle && this.state.status === "connecting");
|
|
18941
19321
|
if (!accepting()) throw new Error("Realtime session is not accepting capture");
|
|
18942
19322
|
this.captureRequested = true;
|
|
19323
|
+
if (this.providerTransport != null) return this.providerTransport.startCapture(this.suppliedStream);
|
|
18943
19324
|
if (this.rtc != null) return this.rtc.startCapture(this.suppliedStream);
|
|
18944
19325
|
if (this.pcm != null) return this.pcm.resumeCapture(this.suppliedStream);
|
|
18945
19326
|
const audio = this.audio;
|
|
@@ -18961,7 +19342,11 @@ var AbstractRealtimeSession = class {
|
|
|
18961
19342
|
const pcm = this.pcm;
|
|
18962
19343
|
const audio = this.audio;
|
|
18963
19344
|
const rtc = this.rtc;
|
|
19345
|
+
const providerTransport = this.providerTransport;
|
|
18964
19346
|
const attempt = this.attempt;
|
|
19347
|
+
if (providerTransport != null) providerTransport.stopCapture().catch((error) => {
|
|
19348
|
+
if (attempt?.active && this.attempt === attempt) this.reportError(error, attempt);
|
|
19349
|
+
});
|
|
18965
19350
|
if (rtc != null) rtc.stopCapture().catch((error) => {
|
|
18966
19351
|
if (attempt?.active && this.attempt === attempt) this.reportError(error, attempt);
|
|
18967
19352
|
});
|
|
@@ -18969,10 +19354,10 @@ var AbstractRealtimeSession = class {
|
|
|
18969
19354
|
audio?.stopCapture();
|
|
18970
19355
|
}
|
|
18971
19356
|
stopPlayback() {
|
|
18972
|
-
(this.rtc ?? this.pcm ?? this.audio)?.stopPlayback();
|
|
19357
|
+
(this.providerTransport ?? this.rtc ?? this.pcm ?? this.audio)?.stopPlayback();
|
|
18973
19358
|
}
|
|
18974
19359
|
async resumePlayback() {
|
|
18975
|
-
await (this.rtc ?? this.pcm ?? this.audio)?.resumePlayback();
|
|
19360
|
+
await (this.providerTransport ?? this.rtc ?? this.pcm ?? this.audio)?.resumePlayback();
|
|
18976
19361
|
}
|
|
18977
19362
|
dispose() {
|
|
18978
19363
|
this.disconnect();
|
|
@@ -19705,7 +20090,7 @@ const originalGenerateCallId$1 = createIdGenerator$1({
|
|
|
19705
20090
|
* @returns A result object that contains the generated transcript.
|
|
19706
20091
|
*/
|
|
19707
20092
|
const defaultDownload = createDownload();
|
|
19708
|
-
async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxRetriesArg, abortSignal, headers, telemetry, download: downloadFn = defaultDownload, _internal: { generateCallId = originalGenerateCallId$1 } = {} }) {
|
|
20093
|
+
async function transcribe({ model, audio, providerOptions = {}, timestampGranularities, maxRetries: maxRetriesArg, abortSignal, headers, telemetry, download: downloadFn = defaultDownload, _internal: { generateCallId = originalGenerateCallId$1 } = {} }) {
|
|
19709
20094
|
const resolvedModel = resolveTranscriptionModel(model);
|
|
19710
20095
|
if (!resolvedModel) throw new Error("Model could not be resolved");
|
|
19711
20096
|
const { maxRetries, retry } = prepareRetries({
|
|
@@ -19728,7 +20113,8 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19728
20113
|
inputAudioFormat: void 0,
|
|
19729
20114
|
maxRetries,
|
|
19730
20115
|
headers,
|
|
19731
|
-
providerOptions
|
|
20116
|
+
providerOptions,
|
|
20117
|
+
timestampGranularities
|
|
19732
20118
|
});
|
|
19733
20119
|
const executeWithStartEvent = async ({ startEvent, execute }) => await runInTracingChannelSpan({
|
|
19734
20120
|
type: "transcribe",
|
|
@@ -19747,12 +20133,15 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19747
20133
|
let downloadedMediaType;
|
|
19748
20134
|
try {
|
|
19749
20135
|
if (audio instanceof URL) {
|
|
19750
|
-
|
|
19751
|
-
|
|
19752
|
-
|
|
19753
|
-
|
|
19754
|
-
|
|
19755
|
-
|
|
20136
|
+
if (resolvedModel.doGenerateFromUrl != null && downloadFn === defaultDownload && (audio.protocol === "https:" || audio.protocol === "http:")) audioData = audio;
|
|
20137
|
+
else {
|
|
20138
|
+
const downloadResult = await downloadFn({
|
|
20139
|
+
url: audio,
|
|
20140
|
+
abortSignal
|
|
20141
|
+
});
|
|
20142
|
+
audioData = downloadResult.data;
|
|
20143
|
+
downloadedMediaType = downloadResult.mediaType;
|
|
20144
|
+
}
|
|
19756
20145
|
} else audioData = convertDataContentToUint8Array(audio);
|
|
19757
20146
|
} catch (error) {
|
|
19758
20147
|
preparationFailed = true;
|
|
@@ -19779,25 +20168,49 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19779
20168
|
throw error;
|
|
19780
20169
|
}
|
|
19781
20170
|
}
|
|
19782
|
-
|
|
20171
|
+
let mediaType = audioData instanceof URL ? void 0 : getAudioMediaType(downloadedMediaType) ?? detectMediaType({
|
|
19783
20172
|
data: audioData,
|
|
19784
20173
|
topLevelType: "audio"
|
|
19785
20174
|
}) ?? "audio/wav";
|
|
20175
|
+
let byteLength = audioData instanceof URL ? void 0 : audioData.byteLength;
|
|
19786
20176
|
const startEvent = createStartEvent({
|
|
19787
|
-
byteLength
|
|
20177
|
+
byteLength,
|
|
19788
20178
|
mediaType
|
|
19789
20179
|
});
|
|
19790
20180
|
try {
|
|
19791
20181
|
return await executeWithStartEvent({
|
|
19792
20182
|
startEvent,
|
|
19793
20183
|
execute: async () => {
|
|
19794
|
-
const result = await retry(() =>
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
|
|
20184
|
+
const result = await retry(async () => {
|
|
20185
|
+
const callOptions = {
|
|
20186
|
+
abortSignal,
|
|
20187
|
+
headers: headersWithUserAgent,
|
|
20188
|
+
providerOptions,
|
|
20189
|
+
...timestampGranularities != null ? { timestampGranularities } : {}
|
|
20190
|
+
};
|
|
20191
|
+
if (audioData instanceof URL) {
|
|
20192
|
+
const nativeResult = await resolvedModel.doGenerateFromUrl?.({
|
|
20193
|
+
...callOptions,
|
|
20194
|
+
audio: audioData
|
|
20195
|
+
});
|
|
20196
|
+
if (nativeResult != null) return nativeResult;
|
|
20197
|
+
const downloaded = await downloadFn({
|
|
20198
|
+
url: audioData,
|
|
20199
|
+
abortSignal
|
|
20200
|
+
});
|
|
20201
|
+
audioData = downloaded.data;
|
|
20202
|
+
mediaType = getAudioMediaType(downloaded.mediaType) ?? detectMediaType({
|
|
20203
|
+
data: audioData,
|
|
20204
|
+
topLevelType: "audio"
|
|
20205
|
+
}) ?? "audio/wav";
|
|
20206
|
+
byteLength = audioData.byteLength;
|
|
20207
|
+
}
|
|
20208
|
+
return resolvedModel.doGenerate({
|
|
20209
|
+
...callOptions,
|
|
20210
|
+
audio: audioData,
|
|
20211
|
+
mediaType: mediaType ?? "audio/wav"
|
|
20212
|
+
});
|
|
20213
|
+
});
|
|
19801
20214
|
logWarnings({
|
|
19802
20215
|
warnings: result.warnings,
|
|
19803
20216
|
provider: resolvedModel.provider,
|
|
@@ -19811,11 +20224,12 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19811
20224
|
provider: resolvedModel.provider,
|
|
19812
20225
|
modelId: resolvedModel.modelId,
|
|
19813
20226
|
audio: {
|
|
19814
|
-
byteLength
|
|
20227
|
+
byteLength,
|
|
19815
20228
|
mediaType
|
|
19816
20229
|
},
|
|
19817
20230
|
text: result.text,
|
|
19818
20231
|
segments: result.segments,
|
|
20232
|
+
words: result.words,
|
|
19819
20233
|
language: result.language,
|
|
19820
20234
|
durationInSeconds: result.durationInSeconds,
|
|
19821
20235
|
usage: result.usage,
|
|
@@ -19828,6 +20242,7 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19828
20242
|
return new DefaultTranscriptionResult({
|
|
19829
20243
|
text: result.text,
|
|
19830
20244
|
segments: result.segments,
|
|
20245
|
+
words: result.words,
|
|
19831
20246
|
language: result.language,
|
|
19832
20247
|
durationInSeconds: result.durationInSeconds,
|
|
19833
20248
|
warnings: result.warnings,
|
|
@@ -19844,10 +20259,22 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19844
20259
|
throw error;
|
|
19845
20260
|
}
|
|
19846
20261
|
}
|
|
20262
|
+
/**
|
|
20263
|
+
* Normalizes a downloaded `Content-Type` header value and returns it only
|
|
20264
|
+
* when it is a full `audio/<subtype>` media type. Generic or mislabeled types
|
|
20265
|
+
* (e.g. `application/octet-stream`, `binary/octet-stream`, `text/plain`)
|
|
20266
|
+
* return `undefined` so that the media type is detected from the audio bytes
|
|
20267
|
+
* instead.
|
|
20268
|
+
*/
|
|
20269
|
+
function getAudioMediaType(contentType) {
|
|
20270
|
+
const mediaType = contentType?.split(";")[0].trim().toLowerCase();
|
|
20271
|
+
return mediaType != null && getTopLevelMediaType(mediaType) === "audio" && isFullMediaType(mediaType) ? mediaType : void 0;
|
|
20272
|
+
}
|
|
19847
20273
|
var DefaultTranscriptionResult = class {
|
|
19848
20274
|
constructor(options) {
|
|
19849
20275
|
this.text = options.text;
|
|
19850
20276
|
this.segments = options.segments;
|
|
20277
|
+
this.words = options.words;
|
|
19851
20278
|
this.language = options.language;
|
|
19852
20279
|
this.durationInSeconds = options.durationInSeconds;
|
|
19853
20280
|
this.warnings = options.warnings;
|