@depup/ai-sdk__openai 3.0.41-depup.0
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 +3101 -0
- package/LICENSE +13 -0
- package/README.md +25 -0
- package/changes.json +5 -0
- package/dist/index.d.mts +1107 -0
- package/dist/index.d.ts +1107 -0
- package/dist/index.js +6408 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6493 -0
- package/dist/index.mjs.map +1 -0
- package/dist/internal/index.d.mts +1137 -0
- package/dist/internal/index.d.ts +1137 -0
- package/dist/internal/index.js +6256 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/internal/index.mjs +6306 -0
- package/dist/internal/index.mjs.map +1 -0
- package/docs/03-openai.mdx +2396 -0
- package/internal.d.ts +1 -0
- package/package.json +96 -0
- package/src/chat/convert-openai-chat-usage.ts +57 -0
- package/src/chat/convert-to-openai-chat-messages.ts +225 -0
- package/src/chat/get-response-metadata.ts +15 -0
- package/src/chat/map-openai-finish-reason.ts +19 -0
- package/src/chat/openai-chat-api.ts +198 -0
- package/src/chat/openai-chat-language-model.ts +703 -0
- package/src/chat/openai-chat-options.ts +192 -0
- package/src/chat/openai-chat-prepare-tools.ts +84 -0
- package/src/chat/openai-chat-prompt.ts +70 -0
- package/src/completion/convert-openai-completion-usage.ts +46 -0
- package/src/completion/convert-to-openai-completion-prompt.ts +93 -0
- package/src/completion/get-response-metadata.ts +15 -0
- package/src/completion/map-openai-finish-reason.ts +19 -0
- package/src/completion/openai-completion-api.ts +81 -0
- package/src/completion/openai-completion-language-model.ts +336 -0
- package/src/completion/openai-completion-options.ts +61 -0
- package/src/embedding/openai-embedding-api.ts +13 -0
- package/src/embedding/openai-embedding-model.ts +95 -0
- package/src/embedding/openai-embedding-options.ts +30 -0
- package/src/image/openai-image-api.ts +35 -0
- package/src/image/openai-image-model.ts +349 -0
- package/src/image/openai-image-options.ts +31 -0
- package/src/index.ts +23 -0
- package/src/internal/index.ts +19 -0
- package/src/openai-config.ts +18 -0
- package/src/openai-error.ts +22 -0
- package/src/openai-language-model-capabilities.ts +52 -0
- package/src/openai-provider.ts +270 -0
- package/src/openai-tools.ts +126 -0
- package/src/responses/convert-openai-responses-usage.ts +53 -0
- package/src/responses/convert-to-openai-responses-input.ts +735 -0
- package/src/responses/map-openai-responses-finish-reason.ts +22 -0
- package/src/responses/openai-responses-api.ts +1260 -0
- package/src/responses/openai-responses-language-model.ts +2098 -0
- package/src/responses/openai-responses-options.ts +299 -0
- package/src/responses/openai-responses-prepare-tools.ts +408 -0
- package/src/responses/openai-responses-provider-metadata.ts +62 -0
- package/src/speech/openai-speech-api.ts +38 -0
- package/src/speech/openai-speech-model.ts +137 -0
- package/src/speech/openai-speech-options.ts +26 -0
- package/src/tool/apply-patch.ts +141 -0
- package/src/tool/code-interpreter.ts +104 -0
- package/src/tool/custom.ts +64 -0
- package/src/tool/file-search.ts +145 -0
- package/src/tool/image-generation.ts +126 -0
- package/src/tool/local-shell.ts +72 -0
- package/src/tool/mcp.ts +125 -0
- package/src/tool/shell.ts +203 -0
- package/src/tool/web-search-preview.ts +141 -0
- package/src/tool/web-search.ts +181 -0
- package/src/transcription/openai-transcription-api.ts +37 -0
- package/src/transcription/openai-transcription-model.ts +232 -0
- package/src/transcription/openai-transcription-options.ts +53 -0
- package/src/transcription/transcription-test.mp3 +0 -0
- package/src/version.ts +6 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createProviderToolFactoryWithOutputSchema,
|
|
3
|
+
lazySchema,
|
|
4
|
+
zodSchema,
|
|
5
|
+
} from '@ai-sdk/provider-utils';
|
|
6
|
+
import { z } from 'zod/v4';
|
|
7
|
+
|
|
8
|
+
export const webSearchPreviewArgsSchema = lazySchema(() =>
|
|
9
|
+
zodSchema(
|
|
10
|
+
z.object({
|
|
11
|
+
searchContextSize: z.enum(['low', 'medium', 'high']).optional(),
|
|
12
|
+
userLocation: z
|
|
13
|
+
.object({
|
|
14
|
+
type: z.literal('approximate'),
|
|
15
|
+
country: z.string().optional(),
|
|
16
|
+
city: z.string().optional(),
|
|
17
|
+
region: z.string().optional(),
|
|
18
|
+
timezone: z.string().optional(),
|
|
19
|
+
})
|
|
20
|
+
.optional(),
|
|
21
|
+
}),
|
|
22
|
+
),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const webSearchPreviewInputSchema = lazySchema(() =>
|
|
26
|
+
zodSchema(z.object({})),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const webSearchPreviewOutputSchema = lazySchema(() =>
|
|
30
|
+
zodSchema(
|
|
31
|
+
z.object({
|
|
32
|
+
action: z
|
|
33
|
+
.discriminatedUnion('type', [
|
|
34
|
+
z.object({
|
|
35
|
+
type: z.literal('search'),
|
|
36
|
+
query: z.string().optional(),
|
|
37
|
+
}),
|
|
38
|
+
z.object({
|
|
39
|
+
type: z.literal('openPage'),
|
|
40
|
+
url: z.string().nullish(),
|
|
41
|
+
}),
|
|
42
|
+
z.object({
|
|
43
|
+
type: z.literal('findInPage'),
|
|
44
|
+
url: z.string().nullish(),
|
|
45
|
+
pattern: z.string().nullish(),
|
|
46
|
+
}),
|
|
47
|
+
])
|
|
48
|
+
.optional(),
|
|
49
|
+
}),
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
export const webSearchPreview = createProviderToolFactoryWithOutputSchema<
|
|
54
|
+
{
|
|
55
|
+
// Web search preview doesn't take input parameters - it's controlled by the prompt
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
/**
|
|
59
|
+
* An object describing the specific action taken in this web search call.
|
|
60
|
+
* Includes details on how the model used the web (search, open_page, find_in_page).
|
|
61
|
+
*/
|
|
62
|
+
action?:
|
|
63
|
+
| {
|
|
64
|
+
/**
|
|
65
|
+
* Action type "search" - Performs a web search query.
|
|
66
|
+
*/
|
|
67
|
+
type: 'search';
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The search query.
|
|
71
|
+
*/
|
|
72
|
+
query?: string;
|
|
73
|
+
}
|
|
74
|
+
| {
|
|
75
|
+
/**
|
|
76
|
+
* Action type "openPage" - Opens a specific URL from search results.
|
|
77
|
+
*/
|
|
78
|
+
type: 'openPage';
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The URL opened by the model.
|
|
82
|
+
*/
|
|
83
|
+
url?: string | null;
|
|
84
|
+
}
|
|
85
|
+
| {
|
|
86
|
+
/**
|
|
87
|
+
* Action type "findInPage": Searches for a pattern within a loaded page.
|
|
88
|
+
*/
|
|
89
|
+
type: 'findInPage';
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The URL of the page searched for the pattern.
|
|
93
|
+
*/
|
|
94
|
+
url?: string | null;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The pattern or text to search for within the page.
|
|
98
|
+
*/
|
|
99
|
+
pattern?: string | null;
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
/**
|
|
104
|
+
* Search context size to use for the web search.
|
|
105
|
+
* - high: Most comprehensive context, highest cost, slower response
|
|
106
|
+
* - medium: Balanced context, cost, and latency (default)
|
|
107
|
+
* - low: Least context, lowest cost, fastest response
|
|
108
|
+
*/
|
|
109
|
+
searchContextSize?: 'low' | 'medium' | 'high';
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* User location information to provide geographically relevant search results.
|
|
113
|
+
*/
|
|
114
|
+
userLocation?: {
|
|
115
|
+
/**
|
|
116
|
+
* Type of location (always 'approximate')
|
|
117
|
+
*/
|
|
118
|
+
type: 'approximate';
|
|
119
|
+
/**
|
|
120
|
+
* Two-letter ISO country code (e.g., 'US', 'GB')
|
|
121
|
+
*/
|
|
122
|
+
country?: string;
|
|
123
|
+
/**
|
|
124
|
+
* City name (free text, e.g., 'Minneapolis')
|
|
125
|
+
*/
|
|
126
|
+
city?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Region name (free text, e.g., 'Minnesota')
|
|
129
|
+
*/
|
|
130
|
+
region?: string;
|
|
131
|
+
/**
|
|
132
|
+
* IANA timezone (e.g., 'America/Chicago')
|
|
133
|
+
*/
|
|
134
|
+
timezone?: string;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
>({
|
|
138
|
+
id: 'openai.web_search_preview',
|
|
139
|
+
inputSchema: webSearchPreviewInputSchema,
|
|
140
|
+
outputSchema: webSearchPreviewOutputSchema,
|
|
141
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createProviderToolFactoryWithOutputSchema,
|
|
3
|
+
lazySchema,
|
|
4
|
+
zodSchema,
|
|
5
|
+
} from '@ai-sdk/provider-utils';
|
|
6
|
+
import { z } from 'zod/v4';
|
|
7
|
+
|
|
8
|
+
export const webSearchArgsSchema = lazySchema(() =>
|
|
9
|
+
zodSchema(
|
|
10
|
+
z.object({
|
|
11
|
+
externalWebAccess: z.boolean().optional(),
|
|
12
|
+
filters: z
|
|
13
|
+
.object({ allowedDomains: z.array(z.string()).optional() })
|
|
14
|
+
.optional(),
|
|
15
|
+
searchContextSize: z.enum(['low', 'medium', 'high']).optional(),
|
|
16
|
+
userLocation: z
|
|
17
|
+
.object({
|
|
18
|
+
type: z.literal('approximate'),
|
|
19
|
+
country: z.string().optional(),
|
|
20
|
+
city: z.string().optional(),
|
|
21
|
+
region: z.string().optional(),
|
|
22
|
+
timezone: z.string().optional(),
|
|
23
|
+
})
|
|
24
|
+
.optional(),
|
|
25
|
+
}),
|
|
26
|
+
),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const webSearchInputSchema = lazySchema(() => zodSchema(z.object({})));
|
|
30
|
+
|
|
31
|
+
export const webSearchOutputSchema = lazySchema(() =>
|
|
32
|
+
zodSchema(
|
|
33
|
+
z.object({
|
|
34
|
+
action: z
|
|
35
|
+
.discriminatedUnion('type', [
|
|
36
|
+
z.object({
|
|
37
|
+
type: z.literal('search'),
|
|
38
|
+
query: z.string().optional(),
|
|
39
|
+
}),
|
|
40
|
+
z.object({
|
|
41
|
+
type: z.literal('openPage'),
|
|
42
|
+
url: z.string().nullish(),
|
|
43
|
+
}),
|
|
44
|
+
z.object({
|
|
45
|
+
type: z.literal('findInPage'),
|
|
46
|
+
url: z.string().nullish(),
|
|
47
|
+
pattern: z.string().nullish(),
|
|
48
|
+
}),
|
|
49
|
+
])
|
|
50
|
+
.optional(),
|
|
51
|
+
sources: z
|
|
52
|
+
.array(
|
|
53
|
+
z.discriminatedUnion('type', [
|
|
54
|
+
z.object({ type: z.literal('url'), url: z.string() }),
|
|
55
|
+
z.object({ type: z.literal('api'), name: z.string() }),
|
|
56
|
+
]),
|
|
57
|
+
)
|
|
58
|
+
.optional(),
|
|
59
|
+
}),
|
|
60
|
+
),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export const webSearchToolFactory = createProviderToolFactoryWithOutputSchema<
|
|
64
|
+
{
|
|
65
|
+
// Web search doesn't take input parameters - it's controlled by the prompt
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
/**
|
|
69
|
+
* An object describing the specific action taken in this web search call.
|
|
70
|
+
* Includes details on how the model used the web (search, open_page, find_in_page).
|
|
71
|
+
*/
|
|
72
|
+
action?:
|
|
73
|
+
| {
|
|
74
|
+
/**
|
|
75
|
+
* Action type "search" - Performs a web search query.
|
|
76
|
+
*/
|
|
77
|
+
type: 'search';
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The search query.
|
|
81
|
+
*/
|
|
82
|
+
query?: string;
|
|
83
|
+
}
|
|
84
|
+
| {
|
|
85
|
+
/**
|
|
86
|
+
* Action type "openPage" - Opens a specific URL from search results.
|
|
87
|
+
*/
|
|
88
|
+
type: 'openPage';
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The URL opened by the model.
|
|
92
|
+
*/
|
|
93
|
+
url?: string | null;
|
|
94
|
+
}
|
|
95
|
+
| {
|
|
96
|
+
/**
|
|
97
|
+
* Action type "findInPage": Searches for a pattern within a loaded page.
|
|
98
|
+
*/
|
|
99
|
+
type: 'findInPage';
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The URL of the page searched for the pattern.
|
|
103
|
+
*/
|
|
104
|
+
url?: string | null;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The pattern or text to search for within the page.
|
|
108
|
+
*/
|
|
109
|
+
pattern?: string | null;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Optional sources cited by the model for the web search call.
|
|
114
|
+
*/
|
|
115
|
+
sources?: Array<
|
|
116
|
+
{ type: 'url'; url: string } | { type: 'api'; name: string }
|
|
117
|
+
>;
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
/**
|
|
121
|
+
* Whether to use external web access for fetching live content.
|
|
122
|
+
* - true: Fetch live web content (default)
|
|
123
|
+
* - false: Use cached/indexed results
|
|
124
|
+
*/
|
|
125
|
+
externalWebAccess?: boolean;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Filters for the search.
|
|
129
|
+
*/
|
|
130
|
+
filters?: {
|
|
131
|
+
/**
|
|
132
|
+
* Allowed domains for the search.
|
|
133
|
+
* If not provided, all domains are allowed.
|
|
134
|
+
* Subdomains of the provided domains are allowed as well.
|
|
135
|
+
*/
|
|
136
|
+
allowedDomains?: string[];
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Search context size to use for the web search.
|
|
141
|
+
* - high: Most comprehensive context, highest cost, slower response
|
|
142
|
+
* - medium: Balanced context, cost, and latency (default)
|
|
143
|
+
* - low: Least context, lowest cost, fastest response
|
|
144
|
+
*/
|
|
145
|
+
searchContextSize?: 'low' | 'medium' | 'high';
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* User location information to provide geographically relevant search results.
|
|
149
|
+
*/
|
|
150
|
+
userLocation?: {
|
|
151
|
+
/**
|
|
152
|
+
* Type of location (always 'approximate')
|
|
153
|
+
*/
|
|
154
|
+
type: 'approximate';
|
|
155
|
+
/**
|
|
156
|
+
* Two-letter ISO country code (e.g., 'US', 'GB')
|
|
157
|
+
*/
|
|
158
|
+
country?: string;
|
|
159
|
+
/**
|
|
160
|
+
* City name (free text, e.g., 'Minneapolis')
|
|
161
|
+
*/
|
|
162
|
+
city?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Region name (free text, e.g., 'Minnesota')
|
|
165
|
+
*/
|
|
166
|
+
region?: string;
|
|
167
|
+
/**
|
|
168
|
+
* IANA timezone (e.g., 'America/Chicago')
|
|
169
|
+
*/
|
|
170
|
+
timezone?: string;
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
>({
|
|
174
|
+
id: 'openai.web_search',
|
|
175
|
+
inputSchema: webSearchInputSchema,
|
|
176
|
+
outputSchema: webSearchOutputSchema,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
export const webSearch = (
|
|
180
|
+
args: Parameters<typeof webSearchToolFactory>[0] = {}, // default
|
|
181
|
+
) => webSearchToolFactory(args);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
3
|
+
|
|
4
|
+
export const openaiTranscriptionResponseSchema = lazySchema(() =>
|
|
5
|
+
zodSchema(
|
|
6
|
+
z.object({
|
|
7
|
+
text: z.string(),
|
|
8
|
+
language: z.string().nullish(),
|
|
9
|
+
duration: z.number().nullish(),
|
|
10
|
+
words: z
|
|
11
|
+
.array(
|
|
12
|
+
z.object({
|
|
13
|
+
word: z.string(),
|
|
14
|
+
start: z.number(),
|
|
15
|
+
end: z.number(),
|
|
16
|
+
}),
|
|
17
|
+
)
|
|
18
|
+
.nullish(),
|
|
19
|
+
segments: z
|
|
20
|
+
.array(
|
|
21
|
+
z.object({
|
|
22
|
+
id: z.number(),
|
|
23
|
+
seek: z.number(),
|
|
24
|
+
start: z.number(),
|
|
25
|
+
end: z.number(),
|
|
26
|
+
text: z.string(),
|
|
27
|
+
tokens: z.array(z.number()),
|
|
28
|
+
temperature: z.number(),
|
|
29
|
+
avg_logprob: z.number(),
|
|
30
|
+
compression_ratio: z.number(),
|
|
31
|
+
no_speech_prob: z.number(),
|
|
32
|
+
}),
|
|
33
|
+
)
|
|
34
|
+
.nullish(),
|
|
35
|
+
}),
|
|
36
|
+
),
|
|
37
|
+
);
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TranscriptionModelV3,
|
|
3
|
+
TranscriptionModelV3CallOptions,
|
|
4
|
+
SharedV3Warning,
|
|
5
|
+
} from '@ai-sdk/provider';
|
|
6
|
+
import {
|
|
7
|
+
combineHeaders,
|
|
8
|
+
convertBase64ToUint8Array,
|
|
9
|
+
createJsonResponseHandler,
|
|
10
|
+
mediaTypeToExtension,
|
|
11
|
+
parseProviderOptions,
|
|
12
|
+
postFormDataToApi,
|
|
13
|
+
} from '@ai-sdk/provider-utils';
|
|
14
|
+
import { OpenAIConfig } from '../openai-config';
|
|
15
|
+
import { openaiFailedResponseHandler } from '../openai-error';
|
|
16
|
+
import { openaiTranscriptionResponseSchema } from './openai-transcription-api';
|
|
17
|
+
import {
|
|
18
|
+
OpenAITranscriptionModelId,
|
|
19
|
+
openAITranscriptionModelOptions,
|
|
20
|
+
OpenAITranscriptionModelOptions,
|
|
21
|
+
} from './openai-transcription-options';
|
|
22
|
+
|
|
23
|
+
export type OpenAITranscriptionCallOptions = Omit<
|
|
24
|
+
TranscriptionModelV3CallOptions,
|
|
25
|
+
'providerOptions'
|
|
26
|
+
> & {
|
|
27
|
+
providerOptions?: {
|
|
28
|
+
openai?: OpenAITranscriptionModelOptions;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
interface OpenAITranscriptionModelConfig extends OpenAIConfig {
|
|
33
|
+
_internal?: {
|
|
34
|
+
currentDate?: () => Date;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// https://platform.openai.com/docs/guides/speech-to-text#supported-languages
|
|
39
|
+
const languageMap = {
|
|
40
|
+
afrikaans: 'af',
|
|
41
|
+
arabic: 'ar',
|
|
42
|
+
armenian: 'hy',
|
|
43
|
+
azerbaijani: 'az',
|
|
44
|
+
belarusian: 'be',
|
|
45
|
+
bosnian: 'bs',
|
|
46
|
+
bulgarian: 'bg',
|
|
47
|
+
catalan: 'ca',
|
|
48
|
+
chinese: 'zh',
|
|
49
|
+
croatian: 'hr',
|
|
50
|
+
czech: 'cs',
|
|
51
|
+
danish: 'da',
|
|
52
|
+
dutch: 'nl',
|
|
53
|
+
english: 'en',
|
|
54
|
+
estonian: 'et',
|
|
55
|
+
finnish: 'fi',
|
|
56
|
+
french: 'fr',
|
|
57
|
+
galician: 'gl',
|
|
58
|
+
german: 'de',
|
|
59
|
+
greek: 'el',
|
|
60
|
+
hebrew: 'he',
|
|
61
|
+
hindi: 'hi',
|
|
62
|
+
hungarian: 'hu',
|
|
63
|
+
icelandic: 'is',
|
|
64
|
+
indonesian: 'id',
|
|
65
|
+
italian: 'it',
|
|
66
|
+
japanese: 'ja',
|
|
67
|
+
kannada: 'kn',
|
|
68
|
+
kazakh: 'kk',
|
|
69
|
+
korean: 'ko',
|
|
70
|
+
latvian: 'lv',
|
|
71
|
+
lithuanian: 'lt',
|
|
72
|
+
macedonian: 'mk',
|
|
73
|
+
malay: 'ms',
|
|
74
|
+
marathi: 'mr',
|
|
75
|
+
maori: 'mi',
|
|
76
|
+
nepali: 'ne',
|
|
77
|
+
norwegian: 'no',
|
|
78
|
+
persian: 'fa',
|
|
79
|
+
polish: 'pl',
|
|
80
|
+
portuguese: 'pt',
|
|
81
|
+
romanian: 'ro',
|
|
82
|
+
russian: 'ru',
|
|
83
|
+
serbian: 'sr',
|
|
84
|
+
slovak: 'sk',
|
|
85
|
+
slovenian: 'sl',
|
|
86
|
+
spanish: 'es',
|
|
87
|
+
swahili: 'sw',
|
|
88
|
+
swedish: 'sv',
|
|
89
|
+
tagalog: 'tl',
|
|
90
|
+
tamil: 'ta',
|
|
91
|
+
thai: 'th',
|
|
92
|
+
turkish: 'tr',
|
|
93
|
+
ukrainian: 'uk',
|
|
94
|
+
urdu: 'ur',
|
|
95
|
+
vietnamese: 'vi',
|
|
96
|
+
welsh: 'cy',
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export class OpenAITranscriptionModel implements TranscriptionModelV3 {
|
|
100
|
+
readonly specificationVersion = 'v3';
|
|
101
|
+
|
|
102
|
+
get provider(): string {
|
|
103
|
+
return this.config.provider;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
constructor(
|
|
107
|
+
readonly modelId: OpenAITranscriptionModelId,
|
|
108
|
+
private readonly config: OpenAITranscriptionModelConfig,
|
|
109
|
+
) {}
|
|
110
|
+
|
|
111
|
+
private async getArgs({
|
|
112
|
+
audio,
|
|
113
|
+
mediaType,
|
|
114
|
+
providerOptions,
|
|
115
|
+
}: OpenAITranscriptionCallOptions) {
|
|
116
|
+
const warnings: SharedV3Warning[] = [];
|
|
117
|
+
|
|
118
|
+
// Parse provider options
|
|
119
|
+
const openAIOptions = await parseProviderOptions({
|
|
120
|
+
provider: 'openai',
|
|
121
|
+
providerOptions,
|
|
122
|
+
schema: openAITranscriptionModelOptions,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Create form data with base fields
|
|
126
|
+
const formData = new FormData();
|
|
127
|
+
const blob =
|
|
128
|
+
audio instanceof Uint8Array
|
|
129
|
+
? new Blob([audio])
|
|
130
|
+
: new Blob([convertBase64ToUint8Array(audio)]);
|
|
131
|
+
|
|
132
|
+
formData.append('model', this.modelId);
|
|
133
|
+
const fileExtension = mediaTypeToExtension(mediaType);
|
|
134
|
+
formData.append(
|
|
135
|
+
'file',
|
|
136
|
+
new File([blob], 'audio', { type: mediaType }),
|
|
137
|
+
`audio.${fileExtension}`,
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Add provider-specific options
|
|
141
|
+
if (openAIOptions) {
|
|
142
|
+
const transcriptionModelOptions = {
|
|
143
|
+
include: openAIOptions.include,
|
|
144
|
+
language: openAIOptions.language,
|
|
145
|
+
prompt: openAIOptions.prompt,
|
|
146
|
+
// https://platform.openai.com/docs/api-reference/audio/createTranscription#audio_createtranscription-response_format
|
|
147
|
+
// prefer verbose_json to get segments for models that support it
|
|
148
|
+
response_format: [
|
|
149
|
+
'gpt-4o-transcribe',
|
|
150
|
+
'gpt-4o-mini-transcribe',
|
|
151
|
+
].includes(this.modelId)
|
|
152
|
+
? 'json'
|
|
153
|
+
: 'verbose_json',
|
|
154
|
+
temperature: openAIOptions.temperature,
|
|
155
|
+
timestamp_granularities: openAIOptions.timestampGranularities,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
for (const [key, value] of Object.entries(transcriptionModelOptions)) {
|
|
159
|
+
if (value != null) {
|
|
160
|
+
if (Array.isArray(value)) {
|
|
161
|
+
for (const item of value) {
|
|
162
|
+
formData.append(`${key}[]`, String(item));
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
formData.append(key, String(value));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
formData,
|
|
173
|
+
warnings,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async doGenerate(
|
|
178
|
+
options: OpenAITranscriptionCallOptions,
|
|
179
|
+
): Promise<Awaited<ReturnType<TranscriptionModelV3['doGenerate']>>> {
|
|
180
|
+
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
181
|
+
const { formData, warnings } = await this.getArgs(options);
|
|
182
|
+
|
|
183
|
+
const {
|
|
184
|
+
value: response,
|
|
185
|
+
responseHeaders,
|
|
186
|
+
rawValue: rawResponse,
|
|
187
|
+
} = await postFormDataToApi({
|
|
188
|
+
url: this.config.url({
|
|
189
|
+
path: '/audio/transcriptions',
|
|
190
|
+
modelId: this.modelId,
|
|
191
|
+
}),
|
|
192
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
193
|
+
formData,
|
|
194
|
+
failedResponseHandler: openaiFailedResponseHandler,
|
|
195
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
196
|
+
openaiTranscriptionResponseSchema,
|
|
197
|
+
),
|
|
198
|
+
abortSignal: options.abortSignal,
|
|
199
|
+
fetch: this.config.fetch,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const language =
|
|
203
|
+
response.language != null && response.language in languageMap
|
|
204
|
+
? languageMap[response.language as keyof typeof languageMap]
|
|
205
|
+
: undefined;
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
text: response.text,
|
|
209
|
+
segments:
|
|
210
|
+
response.segments?.map(segment => ({
|
|
211
|
+
text: segment.text,
|
|
212
|
+
startSecond: segment.start,
|
|
213
|
+
endSecond: segment.end,
|
|
214
|
+
})) ??
|
|
215
|
+
response.words?.map(word => ({
|
|
216
|
+
text: word.word,
|
|
217
|
+
startSecond: word.start,
|
|
218
|
+
endSecond: word.end,
|
|
219
|
+
})) ??
|
|
220
|
+
[],
|
|
221
|
+
language,
|
|
222
|
+
durationInSeconds: response.duration ?? undefined,
|
|
223
|
+
warnings,
|
|
224
|
+
response: {
|
|
225
|
+
timestamp: currentDate,
|
|
226
|
+
modelId: this.modelId,
|
|
227
|
+
headers: responseHeaders,
|
|
228
|
+
body: rawResponse,
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { InferSchema, lazySchema, zodSchema } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
3
|
+
|
|
4
|
+
export type OpenAITranscriptionModelId =
|
|
5
|
+
| 'whisper-1'
|
|
6
|
+
| 'gpt-4o-mini-transcribe'
|
|
7
|
+
| 'gpt-4o-mini-transcribe-2025-03-20'
|
|
8
|
+
| 'gpt-4o-mini-transcribe-2025-12-15'
|
|
9
|
+
| 'gpt-4o-transcribe'
|
|
10
|
+
| 'gpt-4o-transcribe-diarize'
|
|
11
|
+
| (string & {});
|
|
12
|
+
|
|
13
|
+
// https://platform.openai.com/docs/api-reference/audio/createTranscription
|
|
14
|
+
export const openAITranscriptionModelOptions = lazySchema(() =>
|
|
15
|
+
zodSchema(
|
|
16
|
+
z.object({
|
|
17
|
+
/**
|
|
18
|
+
* Additional information to include in the transcription response.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
include: z.array(z.string()).optional(),
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The language of the input audio in ISO-639-1 format.
|
|
25
|
+
*/
|
|
26
|
+
language: z.string().optional(),
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An optional text to guide the model's style or continue a previous audio segment.
|
|
30
|
+
*/
|
|
31
|
+
prompt: z.string().optional(),
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The sampling temperature, between 0 and 1.
|
|
35
|
+
* @default 0
|
|
36
|
+
*/
|
|
37
|
+
temperature: z.number().min(0).max(1).default(0).optional(),
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The timestamp granularities to populate for this transcription.
|
|
41
|
+
* @default ['segment']
|
|
42
|
+
*/
|
|
43
|
+
timestampGranularities: z
|
|
44
|
+
.array(z.enum(['word', 'segment']))
|
|
45
|
+
.default(['segment'])
|
|
46
|
+
.optional(),
|
|
47
|
+
}),
|
|
48
|
+
),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
export type OpenAITranscriptionModelOptions = InferSchema<
|
|
52
|
+
typeof openAITranscriptionModelOptions
|
|
53
|
+
>;
|
|
Binary file
|