ai 7.0.161 → 7.0.163
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 +79 -0
- package/dist/index.d.ts +210 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +551 -114
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +87 -10
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +221 -26
- 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-agents/06-tool-approvals.mdx +2 -0
- package/docs/03-ai-sdk-core/05-generating-text.mdx +1 -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 +85 -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-text/validate-tool-approvals.ts +21 -3
- 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/index.ts +6 -1
- package/src/telemetry/telemetry.ts +62 -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.163";
|
|
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({
|
|
@@ -4973,9 +5160,19 @@ async function validateApprovedToolApprovals({ approvedToolApprovals, tools, too
|
|
|
4973
5160
|
const approved = [];
|
|
4974
5161
|
const denied = [];
|
|
4975
5162
|
const invalid = [];
|
|
4976
|
-
for (const
|
|
5163
|
+
for (const collectedApproval of approvedToolApprovals) {
|
|
5164
|
+
const tool = getOwn(tools, collectedApproval.toolCall.toolName);
|
|
5165
|
+
const { toolMetadata: _toolMetadata, dynamic: _dynamic, ...toolCallFromHistory } = collectedApproval.toolCall;
|
|
5166
|
+
const approval = {
|
|
5167
|
+
...collectedApproval,
|
|
5168
|
+
toolCall: {
|
|
5169
|
+
...toolCallFromHistory,
|
|
5170
|
+
...tool?.metadata != null ? { toolMetadata: tool.metadata } : {},
|
|
5171
|
+
...tool?.type === "dynamic" ? { dynamic: true } : {},
|
|
5172
|
+
title: tool?.title
|
|
5173
|
+
}
|
|
5174
|
+
};
|
|
4977
5175
|
const { approvalRequest, toolCall } = approval;
|
|
4978
|
-
const tool = getOwn(tools, toolCall.toolName);
|
|
4979
5176
|
if (toolApprovalSecret != null) {
|
|
4980
5177
|
if (approvalRequest.signature == null) throw new InvalidToolApprovalSignatureError({
|
|
4981
5178
|
approvalId: approvalRequest.approvalId,
|
|
@@ -5462,10 +5659,10 @@ async function generateTextInternal({ model: modelArg, tools, toolChoice, instru
|
|
|
5462
5659
|
messages: prepareStepResult?.messages ?? stepInputMessages,
|
|
5463
5660
|
toolCallerMessages
|
|
5464
5661
|
});
|
|
5465
|
-
const deliveredSteeringMessages = steeringRun?.resolveTakenMessages({
|
|
5662
|
+
const deliveredSteeringMessages = (steeringRun?.resolveTakenMessages({
|
|
5466
5663
|
stepNumber,
|
|
5467
5664
|
sentMessages: stepMessages
|
|
5468
|
-
}) ?? [];
|
|
5665
|
+
}) ?? []).map(({ message }) => message);
|
|
5469
5666
|
const promptMessages = await convertToLanguageModelPrompt({
|
|
5470
5667
|
prompt: {
|
|
5471
5668
|
instructions: stepInstructions,
|
|
@@ -5547,6 +5744,7 @@ async function generateTextInternal({ model: modelArg, tools, toolChoice, instru
|
|
|
5547
5744
|
};
|
|
5548
5745
|
return {
|
|
5549
5746
|
...result,
|
|
5747
|
+
...result.request != null ? { request: sanitizeRequestMetadata(result.request) } : {},
|
|
5550
5748
|
response: responseData
|
|
5551
5749
|
};
|
|
5552
5750
|
});
|
|
@@ -5584,6 +5782,7 @@ async function generateTextInternal({ model: modelArg, tools, toolChoice, instru
|
|
|
5584
5782
|
usage: stepUsage,
|
|
5585
5783
|
content: modelCallContent,
|
|
5586
5784
|
responseId: currentModelResponse.response.id,
|
|
5785
|
+
...currentModelResponse.request?.url != null ? { request: { url: getRequestOrigin(currentModelResponse.request.url) } } : {},
|
|
5587
5786
|
...currentModelResponse.providerMetadata != null ? { providerMetadata: currentModelResponse.providerMetadata } : {},
|
|
5588
5787
|
performance: {
|
|
5589
5788
|
responseTimeMs,
|
|
@@ -6425,6 +6624,22 @@ const uiMessageChunkSchema = lazySchema(() => zodSchema$1(z.union([
|
|
|
6425
6624
|
mediaType: z.string(),
|
|
6426
6625
|
providerMetadata: providerMetadataSchema.optional()
|
|
6427
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
|
+
}),
|
|
6428
6643
|
z.looseObject({
|
|
6429
6644
|
type: z.custom((value) => typeof value === "string" && value.startsWith("data-"), { message: "Type must start with \"data-\"" }),
|
|
6430
6645
|
id: z.string().optional(),
|
|
@@ -7068,6 +7283,14 @@ function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas
|
|
|
7068
7283
|
write();
|
|
7069
7284
|
break;
|
|
7070
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;
|
|
7071
7294
|
case "start-step":
|
|
7072
7295
|
state.message.parts.push({ type: "step-start" });
|
|
7073
7296
|
break;
|
|
@@ -7415,6 +7638,11 @@ function toUIMessageChunk(part, { tools, sendReasoning = true, sendSources = fal
|
|
|
7415
7638
|
type: "error",
|
|
7416
7639
|
errorText: onError(part.error)
|
|
7417
7640
|
};
|
|
7641
|
+
case "steering-message": return {
|
|
7642
|
+
type: "steering-message",
|
|
7643
|
+
id: part.id,
|
|
7644
|
+
parts: convertUserMessageToUIParts(part.message)
|
|
7645
|
+
};
|
|
7418
7646
|
case "start-step": return { type: "start-step" };
|
|
7419
7647
|
case "finish-step": return { type: "finish-step" };
|
|
7420
7648
|
case "start":
|
|
@@ -7433,10 +7661,53 @@ function toUIMessageChunk(part, { tools, sendReasoning = true, sendSources = fal
|
|
|
7433
7661
|
};
|
|
7434
7662
|
case "abort": return part;
|
|
7435
7663
|
case "tool-input-end":
|
|
7664
|
+
case "ping":
|
|
7436
7665
|
case "raw": return;
|
|
7437
7666
|
default: throw new Error(`Unknown chunk type: ${partType}`);
|
|
7438
7667
|
}
|
|
7439
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
|
+
}
|
|
7440
7711
|
//#endregion
|
|
7441
7712
|
//#region src/ui-message-stream/to-ui-message-stream.ts
|
|
7442
7713
|
/**
|
|
@@ -7969,6 +8240,7 @@ const isOutputChunkType = {
|
|
|
7969
8240
|
"model-call-response-metadata": false,
|
|
7970
8241
|
"model-call-end": false,
|
|
7971
8242
|
error: false,
|
|
8243
|
+
ping: false,
|
|
7972
8244
|
raw: false
|
|
7973
8245
|
};
|
|
7974
8246
|
function isOutputChunk$1(chunk) {
|
|
@@ -8274,7 +8546,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8274
8546
|
callbacks: onLanguageModelCallStart
|
|
8275
8547
|
});
|
|
8276
8548
|
const callStartTimestampMs = now$3();
|
|
8277
|
-
const { stream: languageModelStream, response, request } = await executeLanguageModelCallInTelemetryContext({
|
|
8549
|
+
const { stream: languageModelStream, response, request: rawRequest } = await executeLanguageModelCallInTelemetryContext({
|
|
8278
8550
|
...languageModelCallStartEvent,
|
|
8279
8551
|
execute: async () => await resolvedModel.doStream({
|
|
8280
8552
|
...callSettings,
|
|
@@ -8288,6 +8560,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8288
8560
|
includeRawChunks
|
|
8289
8561
|
})
|
|
8290
8562
|
});
|
|
8563
|
+
const request = sanitizeRequestMetadata(rawRequest);
|
|
8291
8564
|
return {
|
|
8292
8565
|
stream: createAsyncIterableStream(languageModelStream.pipeThrough(createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
|
|
8293
8566
|
tools,
|
|
@@ -8303,6 +8576,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8303
8576
|
generateId,
|
|
8304
8577
|
now: now$3,
|
|
8305
8578
|
callStartTimestampMs,
|
|
8579
|
+
request,
|
|
8306
8580
|
onLanguageModelCallEnd,
|
|
8307
8581
|
collectContent
|
|
8308
8582
|
}))),
|
|
@@ -8310,7 +8584,7 @@ async function streamLanguageModelCall({ model, tools, toolOrder, output, toolCh
|
|
|
8310
8584
|
request
|
|
8311
8585
|
};
|
|
8312
8586
|
}
|
|
8313
|
-
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 }) {
|
|
8314
8588
|
const toolCallsByToolCallId = /* @__PURE__ */ new Map();
|
|
8315
8589
|
const modelCallContent = [];
|
|
8316
8590
|
const rawModelCallContent = [];
|
|
@@ -8488,6 +8762,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({ too
|
|
|
8488
8762
|
usage,
|
|
8489
8763
|
content: modelCallContent,
|
|
8490
8764
|
responseId,
|
|
8765
|
+
...request?.url != null ? { request: { url: getRequestOrigin(request.url) } } : {},
|
|
8491
8766
|
...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {},
|
|
8492
8767
|
performance
|
|
8493
8768
|
},
|
|
@@ -9782,10 +10057,20 @@ var DefaultStreamTextResult = class {
|
|
|
9782
10057
|
toolCallerMessages
|
|
9783
10058
|
});
|
|
9784
10059
|
currentStepMessages = stepMessages;
|
|
9785
|
-
|
|
10060
|
+
const deliveredSteeringMessages = steeringRun?.resolveTakenMessages({
|
|
9786
10061
|
stepNumber: currentStep,
|
|
9787
10062
|
sentMessages: stepMessages
|
|
9788
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
|
+
} }));
|
|
9789
10074
|
const stepInstructions = prepareStepResult?.instructions ?? prepareStepResult?.system ?? instructionsForNextStep;
|
|
9790
10075
|
instructionsForNextStep = stepInstructions;
|
|
9791
10076
|
const stepProviderOptions = mergeObjects(providerOptions, prepareStepResult?.providerOptions);
|
|
@@ -9930,7 +10215,7 @@ var DefaultStreamTextResult = class {
|
|
|
9930
10215
|
clearFirstChunkTimeout();
|
|
9931
10216
|
resetChunkTimeout();
|
|
9932
10217
|
}
|
|
9933
|
-
if (shouldBufferToolParts && value.type !== "error" && (isToolPart || bufferedAttemptParts.length > 0)) {
|
|
10218
|
+
if (shouldBufferToolParts && value.type !== "error" && value.type !== "ping" && (isToolPart || bufferedAttemptParts.length > 0)) {
|
|
9934
10219
|
bufferedAttemptParts.push(value);
|
|
9935
10220
|
continue;
|
|
9936
10221
|
}
|
|
@@ -10095,6 +10380,7 @@ var DefaultStreamTextResult = class {
|
|
|
10095
10380
|
case "tool-input-end":
|
|
10096
10381
|
case "tool-input-delta":
|
|
10097
10382
|
case "tool-approval-request":
|
|
10383
|
+
case "ping":
|
|
10098
10384
|
case "tool-output-denied":
|
|
10099
10385
|
enqueueStepPart(controller, chunk);
|
|
10100
10386
|
break;
|
|
@@ -11033,24 +11319,7 @@ async function convertToModelMessages(messages, options) {
|
|
|
11033
11319
|
modelMessages.push({
|
|
11034
11320
|
role: "user",
|
|
11035
11321
|
content: message.parts.map((part) => {
|
|
11036
|
-
if (isTextUIPart(part)) return
|
|
11037
|
-
type: "text",
|
|
11038
|
-
text: part.text,
|
|
11039
|
-
...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
|
|
11040
|
-
};
|
|
11041
|
-
if (isFileUIPart(part)) return {
|
|
11042
|
-
type: "file",
|
|
11043
|
-
mediaType: part.mediaType,
|
|
11044
|
-
filename: part.filename,
|
|
11045
|
-
data: part.providerReference != null ? {
|
|
11046
|
-
type: "reference",
|
|
11047
|
-
reference: part.providerReference
|
|
11048
|
-
} : {
|
|
11049
|
-
type: "url",
|
|
11050
|
-
url: new URL(part.url)
|
|
11051
|
-
},
|
|
11052
|
-
...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
|
|
11053
|
-
};
|
|
11322
|
+
if (isTextUIPart(part) || isFileUIPart(part)) return convertUserContentUIPart(part);
|
|
11054
11323
|
if (isDataUIPart(part)) return options?.convertDataPart?.(part);
|
|
11055
11324
|
}).filter(isNonNullable)
|
|
11056
11325
|
});
|
|
@@ -11206,6 +11475,13 @@ async function convertToModelMessages(messages, options) {
|
|
|
11206
11475
|
}
|
|
11207
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);
|
|
11208
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
|
+
}
|
|
11209
11485
|
await processBlock();
|
|
11210
11486
|
break;
|
|
11211
11487
|
}
|
|
@@ -11220,6 +11496,26 @@ async function convertToModelMessages(messages, options) {
|
|
|
11220
11496
|
}
|
|
11221
11497
|
return modelMessages;
|
|
11222
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
|
+
}
|
|
11223
11519
|
//#endregion
|
|
11224
11520
|
//#region src/ui/validate-ui-messages.ts
|
|
11225
11521
|
const toolMetadataSchema = z.record(z.string(), jsonValueSchema.optional());
|
|
@@ -11312,6 +11608,22 @@ const uiMessagesSchema = lazySchema(() => {
|
|
|
11312
11608
|
url: z.string(),
|
|
11313
11609
|
providerMetadata: providerMetadataSchema.optional()
|
|
11314
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
|
+
}),
|
|
11315
11627
|
z.object({ type: z.literal("step-start") }),
|
|
11316
11628
|
z.object({
|
|
11317
11629
|
type: z.string().startsWith("data-"),
|
|
@@ -13854,7 +14166,7 @@ async function generateObject(options) {
|
|
|
13854
14166
|
const usage = asLanguageModelUsage(generateResult.usage);
|
|
13855
14167
|
const warnings = generateResult.warnings;
|
|
13856
14168
|
const resultProviderMetadata = generateResult.providerMetadata;
|
|
13857
|
-
const request = generateResult.request ?? {};
|
|
14169
|
+
const request = sanitizeRequestMetadata(generateResult.request) ?? {};
|
|
13858
14170
|
const response = responseData;
|
|
13859
14171
|
logWarnings({
|
|
13860
14172
|
warnings,
|
|
@@ -14313,7 +14625,8 @@ var DefaultStreamObjectResult = class {
|
|
|
14313
14625
|
}
|
|
14314
14626
|
} };
|
|
14315
14627
|
const startTimestampMs = now();
|
|
14316
|
-
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);
|
|
14317
14630
|
self._request.resolve(request ?? {});
|
|
14318
14631
|
let warnings;
|
|
14319
14632
|
let usage = createNullLanguageModelUsage();
|
|
@@ -15244,6 +15557,10 @@ function smoothStream({ delayInMs = 10, chunking = "word", _internal: { delay: d
|
|
|
15244
15557
|
}
|
|
15245
15558
|
}
|
|
15246
15559
|
return new TransformStream({ async transform(chunk, controller) {
|
|
15560
|
+
if (chunk.type === "ping") {
|
|
15561
|
+
controller.enqueue(chunk);
|
|
15562
|
+
return;
|
|
15563
|
+
}
|
|
15247
15564
|
if (chunk.type !== "text-delta" && chunk.type !== "reasoning-delta") {
|
|
15248
15565
|
flushBuffer(controller);
|
|
15249
15566
|
controller.enqueue(chunk);
|
|
@@ -15414,10 +15731,14 @@ async function experimental_generateVideo({ model: modelArg, prompt: promptArg,
|
|
|
15414
15731
|
return retry(() => model.doGenerate(callOptions));
|
|
15415
15732
|
}));
|
|
15416
15733
|
const videos = [];
|
|
15734
|
+
let uploadedVideos = 0;
|
|
15417
15735
|
const responses = [];
|
|
15418
15736
|
const providerMetadata = {};
|
|
15419
15737
|
for (const result of results) {
|
|
15420
15738
|
for (const videoData of result.videos) switch (videoData.type) {
|
|
15739
|
+
case "uploaded":
|
|
15740
|
+
uploadedVideos++;
|
|
15741
|
+
break;
|
|
15421
15742
|
case "url": {
|
|
15422
15743
|
const { data, mediaType: downloadedMediaType } = await downloadFn({
|
|
15423
15744
|
url: new URL(videoData.url),
|
|
@@ -15461,19 +15782,30 @@ async function experimental_generateVideo({ model: modelArg, prompt: promptArg,
|
|
|
15461
15782
|
});
|
|
15462
15783
|
if (result.providerMetadata != null) mergeProviderMetadata(providerMetadata, result.providerMetadata);
|
|
15463
15784
|
}
|
|
15464
|
-
if (videos.length === 0) throw new NoVideoGeneratedError({ responses });
|
|
15785
|
+
if (videos.length === 0 && uploadedVideos === 0) throw new NoVideoGeneratedError({ responses });
|
|
15465
15786
|
if (warnings.length > 0) logWarnings({
|
|
15466
15787
|
warnings,
|
|
15467
15788
|
provider: model.provider,
|
|
15468
15789
|
model: model.modelId
|
|
15469
15790
|
});
|
|
15470
|
-
|
|
15791
|
+
const result = {
|
|
15471
15792
|
video: videos[0],
|
|
15472
15793
|
videos,
|
|
15794
|
+
uploadedVideos,
|
|
15473
15795
|
warnings,
|
|
15474
15796
|
responses,
|
|
15475
15797
|
providerMetadata
|
|
15476
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;
|
|
15477
15809
|
}
|
|
15478
15810
|
async function executeStartStatusFlow({ model, callOptions, poll: pollConfig, webhook: webhookFactory, maxRetries, retry }) {
|
|
15479
15811
|
const earlyWarnings = [];
|
|
@@ -18029,6 +18361,7 @@ var BrowserRealtimeWebRTC = class {
|
|
|
18029
18361
|
var RealtimeAttempt = class {
|
|
18030
18362
|
constructor() {
|
|
18031
18363
|
this.abort = new AbortController();
|
|
18364
|
+
this.reportedTransportErrors = /* @__PURE__ */ new WeakSet();
|
|
18032
18365
|
this.timers = /* @__PURE__ */ new Map();
|
|
18033
18366
|
this.active = true;
|
|
18034
18367
|
this.ready = false;
|
|
@@ -18534,9 +18867,13 @@ var AbstractRealtimeSession = class {
|
|
|
18534
18867
|
}
|
|
18535
18868
|
validateConnection() {
|
|
18536
18869
|
const { model, api } = this.options;
|
|
18537
|
-
if ((!this.continuous || api.session != null) && this.options.maxPlaybackBufferSeconds != null) throw new Error("maxPlaybackBufferSeconds is supported only for continuous PCM sessions");
|
|
18538
|
-
const connection = api.session != null ? "webrtc" : api.token != null ? "client-secret-websocket" : "server-websocket";
|
|
18539
|
-
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
|
+
}
|
|
18540
18877
|
if (api.session != null) {
|
|
18541
18878
|
if (model.getWebRTCConfig == null) throw new Error("Realtime model does not support WebRTC configuration");
|
|
18542
18879
|
return;
|
|
@@ -18560,7 +18897,7 @@ var AbstractRealtimeSession = class {
|
|
|
18560
18897
|
if (connectOptions?.capture === false) this.stopAudioCapture();
|
|
18561
18898
|
if (!current()) return;
|
|
18562
18899
|
if (connectOptions?.stream != null && connectOptions.stream !== this.suppliedStream) {
|
|
18563
|
-
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);
|
|
18564
18901
|
else this.suppliedStream = connectOptions.stream;
|
|
18565
18902
|
}
|
|
18566
18903
|
if (!current()) return;
|
|
@@ -18582,7 +18919,7 @@ var AbstractRealtimeSession = class {
|
|
|
18582
18919
|
attempt.timer("startup", this.options.startupTimeoutMs ?? 3e4, () => {
|
|
18583
18920
|
if (current()) this.fail(/* @__PURE__ */ new Error("Realtime session startup timed out"));
|
|
18584
18921
|
});
|
|
18585
|
-
const reportedTransportErrors =
|
|
18922
|
+
const reportedTransportErrors = attempt.reportedTransportErrors;
|
|
18586
18923
|
const callbacks = {
|
|
18587
18924
|
model,
|
|
18588
18925
|
onEvent: async (event) => {
|
|
@@ -18590,7 +18927,7 @@ var AbstractRealtimeSession = class {
|
|
|
18590
18927
|
try {
|
|
18591
18928
|
await this.handleServerEvent(event, attempt);
|
|
18592
18929
|
} catch (error) {
|
|
18593
|
-
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());
|
|
18594
18931
|
}
|
|
18595
18932
|
},
|
|
18596
18933
|
onError: (error) => {
|
|
@@ -18618,6 +18955,13 @@ var AbstractRealtimeSession = class {
|
|
|
18618
18955
|
onClose: (error) => {
|
|
18619
18956
|
if (!current()) return;
|
|
18620
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
|
+
}
|
|
18621
18965
|
if (error != null && !finalizationConfirmed) this.fail(error, void 0, !reportedTransportErrors.has(error));
|
|
18622
18966
|
else if (!attempt.ready && !finalizationConfirmed) this.fail(/* @__PURE__ */ new Error("Realtime connection closed before becoming ready"));
|
|
18623
18967
|
else this.disconnect();
|
|
@@ -18635,7 +18979,21 @@ var AbstractRealtimeSession = class {
|
|
|
18635
18979
|
});
|
|
18636
18980
|
}
|
|
18637
18981
|
};
|
|
18638
|
-
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) {
|
|
18639
18997
|
this.rtc = new BrowserRealtimeWebRTC({
|
|
18640
18998
|
...callbacks,
|
|
18641
18999
|
disconnectTimeoutMs: this.options.rtcDisconnectTimeoutMs
|
|
@@ -18751,8 +19109,12 @@ var AbstractRealtimeSession = class {
|
|
|
18751
19109
|
closeFailed(attempt, error) {
|
|
18752
19110
|
if (this.attempt !== attempt || !attempt.active || attempt.transportClosing) return;
|
|
18753
19111
|
attempt.clearTimer("close");
|
|
18754
|
-
const transport = this.rtc ?? this.pcm ?? this.transport;
|
|
19112
|
+
const transport = this.providerTransport ?? this.rtc ?? this.pcm ?? this.transport;
|
|
18755
19113
|
this.drainAttempt(attempt, transport?.finish());
|
|
19114
|
+
if (error instanceof Error) {
|
|
19115
|
+
if (attempt.reportedTransportErrors.has(error)) return;
|
|
19116
|
+
attempt.reportedTransportErrors.add(error);
|
|
19117
|
+
}
|
|
18756
19118
|
this.reportError(error, attempt);
|
|
18757
19119
|
}
|
|
18758
19120
|
disconnect() {
|
|
@@ -18764,16 +19126,19 @@ var AbstractRealtimeSession = class {
|
|
|
18764
19126
|
const audio = this.audio;
|
|
18765
19127
|
const pcm = this.pcm;
|
|
18766
19128
|
const rtc = this.rtc;
|
|
19129
|
+
const providerTransport = this.providerTransport;
|
|
18767
19130
|
this.transport = void 0;
|
|
18768
19131
|
this.audio = void 0;
|
|
18769
19132
|
this.pcm = void 0;
|
|
18770
19133
|
this.rtc = void 0;
|
|
19134
|
+
this.providerTransport = void 0;
|
|
18771
19135
|
this.commands = void 0;
|
|
18772
19136
|
attempt?.retire();
|
|
18773
19137
|
transport?.dispose();
|
|
18774
19138
|
audio?.dispose();
|
|
18775
19139
|
pcm?.dispose();
|
|
18776
19140
|
rtc?.dispose();
|
|
19141
|
+
providerTransport?.dispose();
|
|
18777
19142
|
if (this.attempt !== attempt) return;
|
|
18778
19143
|
const session = this.state.session;
|
|
18779
19144
|
this.applyState({
|
|
@@ -18787,10 +19152,27 @@ var AbstractRealtimeSession = class {
|
|
|
18787
19152
|
} } : {}
|
|
18788
19153
|
});
|
|
18789
19154
|
}
|
|
18790
|
-
/** Wait for
|
|
19155
|
+
/** Wait for provider cleanup or supported session-close finalization. */
|
|
18791
19156
|
close(options) {
|
|
18792
19157
|
const attempt = this.attempt;
|
|
18793
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
|
+
}
|
|
18794
19176
|
if (this.state.status !== "connected" || this.options.model.capabilities?.finalization !== "session-close" || attempt == null) {
|
|
18795
19177
|
this.disconnect();
|
|
18796
19178
|
return Promise.resolve();
|
|
@@ -18817,8 +19199,16 @@ var AbstractRealtimeSession = class {
|
|
|
18817
19199
|
return promise;
|
|
18818
19200
|
}
|
|
18819
19201
|
sendTransport(event, guard, automaticAudio = false) {
|
|
18820
|
-
const transport = this.rtc ?? this.pcm ?? this.transport;
|
|
19202
|
+
const transport = this.providerTransport ?? this.rtc ?? this.pcm ?? this.transport;
|
|
18821
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
|
+
}
|
|
18822
19212
|
if (transport === this.transport) return this.transport.sendEvent(event, guard, automaticAudio);
|
|
18823
19213
|
return transport.sendEvent(event, guard);
|
|
18824
19214
|
}
|
|
@@ -18904,14 +19294,14 @@ var AbstractRealtimeSession = class {
|
|
|
18904
19294
|
this.maybeRequestToolResponse();
|
|
18905
19295
|
}
|
|
18906
19296
|
maybeRequestToolResponse() {
|
|
18907
|
-
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;
|
|
18908
19298
|
this.sendEvent({ type: "response-create" });
|
|
18909
19299
|
this.toolCallsInResponse.clear();
|
|
18910
19300
|
this.submittedToolOutputs.clear();
|
|
18911
19301
|
this.responseToolCallsClosed = false;
|
|
18912
19302
|
}
|
|
18913
19303
|
startAudioCapture(stream) {
|
|
18914
|
-
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;
|
|
18915
19305
|
if (!legacy && this.state.status !== "connected") throw new Error("Realtime session is not accepting capture");
|
|
18916
19306
|
if (this.attempt?.active && (this.attempt.closing || this.attempt.cause != null)) throw new Error("Realtime session is not accepting capture");
|
|
18917
19307
|
this.suppliedStream = stream;
|
|
@@ -18930,6 +19320,7 @@ var AbstractRealtimeSession = class {
|
|
|
18930
19320
|
const accepting = () => !this.attempt?.closing && this.attempt?.cause == null && (this.state.status === "connected" || !this.sessionLifecycle && this.state.status === "connecting");
|
|
18931
19321
|
if (!accepting()) throw new Error("Realtime session is not accepting capture");
|
|
18932
19322
|
this.captureRequested = true;
|
|
19323
|
+
if (this.providerTransport != null) return this.providerTransport.startCapture(this.suppliedStream);
|
|
18933
19324
|
if (this.rtc != null) return this.rtc.startCapture(this.suppliedStream);
|
|
18934
19325
|
if (this.pcm != null) return this.pcm.resumeCapture(this.suppliedStream);
|
|
18935
19326
|
const audio = this.audio;
|
|
@@ -18951,7 +19342,11 @@ var AbstractRealtimeSession = class {
|
|
|
18951
19342
|
const pcm = this.pcm;
|
|
18952
19343
|
const audio = this.audio;
|
|
18953
19344
|
const rtc = this.rtc;
|
|
19345
|
+
const providerTransport = this.providerTransport;
|
|
18954
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
|
+
});
|
|
18955
19350
|
if (rtc != null) rtc.stopCapture().catch((error) => {
|
|
18956
19351
|
if (attempt?.active && this.attempt === attempt) this.reportError(error, attempt);
|
|
18957
19352
|
});
|
|
@@ -18959,10 +19354,10 @@ var AbstractRealtimeSession = class {
|
|
|
18959
19354
|
audio?.stopCapture();
|
|
18960
19355
|
}
|
|
18961
19356
|
stopPlayback() {
|
|
18962
|
-
(this.rtc ?? this.pcm ?? this.audio)?.stopPlayback();
|
|
19357
|
+
(this.providerTransport ?? this.rtc ?? this.pcm ?? this.audio)?.stopPlayback();
|
|
18963
19358
|
}
|
|
18964
19359
|
async resumePlayback() {
|
|
18965
|
-
await (this.rtc ?? this.pcm ?? this.audio)?.resumePlayback();
|
|
19360
|
+
await (this.providerTransport ?? this.rtc ?? this.pcm ?? this.audio)?.resumePlayback();
|
|
18966
19361
|
}
|
|
18967
19362
|
dispose() {
|
|
18968
19363
|
this.disconnect();
|
|
@@ -19695,7 +20090,7 @@ const originalGenerateCallId$1 = createIdGenerator$1({
|
|
|
19695
20090
|
* @returns A result object that contains the generated transcript.
|
|
19696
20091
|
*/
|
|
19697
20092
|
const defaultDownload = createDownload();
|
|
19698
|
-
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 } = {} }) {
|
|
19699
20094
|
const resolvedModel = resolveTranscriptionModel(model);
|
|
19700
20095
|
if (!resolvedModel) throw new Error("Model could not be resolved");
|
|
19701
20096
|
const { maxRetries, retry } = prepareRetries({
|
|
@@ -19718,7 +20113,8 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19718
20113
|
inputAudioFormat: void 0,
|
|
19719
20114
|
maxRetries,
|
|
19720
20115
|
headers,
|
|
19721
|
-
providerOptions
|
|
20116
|
+
providerOptions,
|
|
20117
|
+
timestampGranularities
|
|
19722
20118
|
});
|
|
19723
20119
|
const executeWithStartEvent = async ({ startEvent, execute }) => await runInTracingChannelSpan({
|
|
19724
20120
|
type: "transcribe",
|
|
@@ -19737,12 +20133,15 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19737
20133
|
let downloadedMediaType;
|
|
19738
20134
|
try {
|
|
19739
20135
|
if (audio instanceof URL) {
|
|
19740
|
-
|
|
19741
|
-
|
|
19742
|
-
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
|
|
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
|
+
}
|
|
19746
20145
|
} else audioData = convertDataContentToUint8Array(audio);
|
|
19747
20146
|
} catch (error) {
|
|
19748
20147
|
preparationFailed = true;
|
|
@@ -19769,25 +20168,49 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19769
20168
|
throw error;
|
|
19770
20169
|
}
|
|
19771
20170
|
}
|
|
19772
|
-
|
|
20171
|
+
let mediaType = audioData instanceof URL ? void 0 : getAudioMediaType(downloadedMediaType) ?? detectMediaType({
|
|
19773
20172
|
data: audioData,
|
|
19774
20173
|
topLevelType: "audio"
|
|
19775
20174
|
}) ?? "audio/wav";
|
|
20175
|
+
let byteLength = audioData instanceof URL ? void 0 : audioData.byteLength;
|
|
19776
20176
|
const startEvent = createStartEvent({
|
|
19777
|
-
byteLength
|
|
20177
|
+
byteLength,
|
|
19778
20178
|
mediaType
|
|
19779
20179
|
});
|
|
19780
20180
|
try {
|
|
19781
20181
|
return await executeWithStartEvent({
|
|
19782
20182
|
startEvent,
|
|
19783
20183
|
execute: async () => {
|
|
19784
|
-
const result = await retry(() =>
|
|
19785
|
-
|
|
19786
|
-
|
|
19787
|
-
|
|
19788
|
-
|
|
19789
|
-
|
|
19790
|
-
|
|
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
|
+
});
|
|
19791
20214
|
logWarnings({
|
|
19792
20215
|
warnings: result.warnings,
|
|
19793
20216
|
provider: resolvedModel.provider,
|
|
@@ -19801,11 +20224,12 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19801
20224
|
provider: resolvedModel.provider,
|
|
19802
20225
|
modelId: resolvedModel.modelId,
|
|
19803
20226
|
audio: {
|
|
19804
|
-
byteLength
|
|
20227
|
+
byteLength,
|
|
19805
20228
|
mediaType
|
|
19806
20229
|
},
|
|
19807
20230
|
text: result.text,
|
|
19808
20231
|
segments: result.segments,
|
|
20232
|
+
words: result.words,
|
|
19809
20233
|
language: result.language,
|
|
19810
20234
|
durationInSeconds: result.durationInSeconds,
|
|
19811
20235
|
usage: result.usage,
|
|
@@ -19818,6 +20242,7 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19818
20242
|
return new DefaultTranscriptionResult({
|
|
19819
20243
|
text: result.text,
|
|
19820
20244
|
segments: result.segments,
|
|
20245
|
+
words: result.words,
|
|
19821
20246
|
language: result.language,
|
|
19822
20247
|
durationInSeconds: result.durationInSeconds,
|
|
19823
20248
|
warnings: result.warnings,
|
|
@@ -19834,10 +20259,22 @@ async function transcribe({ model, audio, providerOptions = {}, maxRetries: maxR
|
|
|
19834
20259
|
throw error;
|
|
19835
20260
|
}
|
|
19836
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
|
+
}
|
|
19837
20273
|
var DefaultTranscriptionResult = class {
|
|
19838
20274
|
constructor(options) {
|
|
19839
20275
|
this.text = options.text;
|
|
19840
20276
|
this.segments = options.segments;
|
|
20277
|
+
this.words = options.words;
|
|
19841
20278
|
this.language = options.language;
|
|
19842
20279
|
this.durationInSeconds = options.durationInSeconds;
|
|
19843
20280
|
this.warnings = options.warnings;
|