ai 6.0.83 → 6.0.85

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.
@@ -10,7 +10,7 @@ import {
10
10
  audioMediaTypeSignatures,
11
11
  detectMediaType,
12
12
  } from '../util/detect-media-type';
13
- import { download } from '../util/download/download';
13
+ import { createDownload } from '../util/download/create-download';
14
14
  import { prepareRetries } from '../util/prepare-retries';
15
15
  import { TranscriptionResult } from './transcribe-result';
16
16
  import { VERSION } from '../version';
@@ -29,6 +29,8 @@ import { Warning } from '../types';
29
29
  *
30
30
  * @returns A result object that contains the generated transcript.
31
31
  */
32
+ const defaultDownload = createDownload();
33
+
32
34
  export async function transcribe({
33
35
  model,
34
36
  audio,
@@ -36,6 +38,7 @@ export async function transcribe({
36
38
  maxRetries: maxRetriesArg,
37
39
  abortSignal,
38
40
  headers,
41
+ download: downloadFn = defaultDownload,
39
42
  }: {
40
43
  /**
41
44
  * The transcription model to use.
@@ -80,6 +83,17 @@ export async function transcribe({
80
83
  * Only applicable for HTTP-based providers.
81
84
  */
82
85
  headers?: Record<string, string>;
86
+
87
+ /**
88
+ * Custom download function for fetching audio from URLs.
89
+ * Use `createDownload()` from `ai` to create a download function with custom size limits.
90
+ *
91
+ * @default createDownload() (2 GiB limit)
92
+ */
93
+ download?: (options: {
94
+ url: URL;
95
+ abortSignal?: AbortSignal;
96
+ }) => Promise<{ data: Uint8Array; mediaType: string | undefined }>;
83
97
  }): Promise<TranscriptionResult> {
84
98
  const resolvedModel = resolveTranscriptionModel(model);
85
99
  if (!resolvedModel) {
@@ -98,7 +112,7 @@ export async function transcribe({
98
112
 
99
113
  const audioData =
100
114
  audio instanceof URL
101
- ? (await download({ url: audio })).data
115
+ ? (await downloadFn({ url: audio, abortSignal })).data
102
116
  : convertDataContentToUint8Array(audio);
103
117
 
104
118
  const result = await retry(() =>
@@ -0,0 +1,13 @@
1
+ import { download as internalDownload } from './download';
2
+
3
+ /**
4
+ * Creates a download function with configurable options.
5
+ *
6
+ * @param options - Configuration options for the download function.
7
+ * @param options.maxBytes - Maximum allowed download size in bytes. Default: 2 GiB.
8
+ * @returns A download function that can be passed to `transcribe()` or `experimental_generateVideo()`.
9
+ */
10
+ export function createDownload(options?: { maxBytes?: number }) {
11
+ return ({ url, abortSignal }: { url: URL; abortSignal?: AbortSignal }) =>
12
+ internalDownload({ url, maxBytes: options?.maxBytes, abortSignal });
13
+ }
@@ -1,4 +1,8 @@
1
- import { DownloadError } from '@ai-sdk/provider-utils';
1
+ import {
2
+ DownloadError,
3
+ readResponseWithSizeLimit,
4
+ DEFAULT_MAX_DOWNLOAD_SIZE,
5
+ } from '@ai-sdk/provider-utils';
2
6
  import {
3
7
  withUserAgentSuffix,
4
8
  getRuntimeEnvironmentUserAgent,
@@ -9,11 +13,21 @@ import { VERSION } from '../../version';
9
13
  * Download a file from a URL.
10
14
  *
11
15
  * @param url - The URL to download from.
16
+ * @param maxBytes - Maximum allowed download size in bytes. Defaults to 100 MiB.
17
+ * @param abortSignal - An optional abort signal to cancel the download.
12
18
  * @returns The downloaded data and media type.
13
19
  *
14
- * @throws DownloadError if the download fails.
20
+ * @throws DownloadError if the download fails or exceeds maxBytes.
15
21
  */
16
- export const download = async ({ url }: { url: URL }) => {
22
+ export const download = async ({
23
+ url,
24
+ maxBytes,
25
+ abortSignal,
26
+ }: {
27
+ url: URL;
28
+ maxBytes?: number;
29
+ abortSignal?: AbortSignal;
30
+ }) => {
17
31
  const urlText = url.toString();
18
32
  try {
19
33
  const response = await fetch(urlText, {
@@ -22,6 +36,7 @@ export const download = async ({ url }: { url: URL }) => {
22
36
  `ai-sdk/${VERSION}`,
23
37
  getRuntimeEnvironmentUserAgent(),
24
38
  ),
39
+ signal: abortSignal,
25
40
  });
26
41
 
27
42
  if (!response.ok) {
@@ -32,8 +47,14 @@ export const download = async ({ url }: { url: URL }) => {
32
47
  });
33
48
  }
34
49
 
50
+ const data = await readResponseWithSizeLimit({
51
+ response,
52
+ url: urlText,
53
+ maxBytes: maxBytes ?? DEFAULT_MAX_DOWNLOAD_SIZE,
54
+ });
55
+
35
56
  return {
36
- data: new Uint8Array(await response.arrayBuffer()),
57
+ data,
37
58
  mediaType: response.headers.get('content-type') ?? undefined,
38
59
  };
39
60
  } catch (error) {
package/src/util/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export type { AsyncIterableStream } from './async-iterable-stream';
2
2
  export { consumeStream } from './consume-stream';
3
3
  export { cosineSimilarity } from './cosine-similarity';
4
+ export { createDownload } from './download/create-download';
4
5
  export { getTextFromDataUrl } from './data-url';
5
6
  export type { DeepPartial } from './deep-partial';
6
7
  export type { DownloadFunction as Experimental_DownloadFunction } from './download/download-function';