@ai-sdk/openai 4.0.106 → 4.0.107
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 +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -16
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +42 -15
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +36 -0
- package/package.json +2 -2
- package/src/chat/convert-to-openai-chat-messages.ts +22 -3
- package/src/responses/convert-to-openai-responses-input.ts +29 -11
- package/src/transcription/openai-transcription-model-options.ts +12 -0
- package/src/transcription/openai-transcription-model.ts +4 -0
package/docs/03-openai.mdx
CHANGED
|
@@ -3543,6 +3543,32 @@ const result = await transcribe({
|
|
|
3543
3543
|
});
|
|
3544
3544
|
```
|
|
3545
3545
|
|
|
3546
|
+
For `gpt-transcribe`, use `languages` for expected languages and `keywords` for
|
|
3547
|
+
names, acronyms, and domain vocabulary. These hints are sent as repeated
|
|
3548
|
+
`languages[]` and `keywords[]` multipart fields:
|
|
3549
|
+
|
|
3550
|
+
```ts
|
|
3551
|
+
import { transcribe } from 'ai';
|
|
3552
|
+
import { openai, type OpenAITranscriptionModelOptions } from '@ai-sdk/openai';
|
|
3553
|
+
|
|
3554
|
+
const result = await transcribe({
|
|
3555
|
+
model: openai.transcription('gpt-transcribe'),
|
|
3556
|
+
audio: new Uint8Array([1, 2, 3, 4]),
|
|
3557
|
+
providerOptions: {
|
|
3558
|
+
openai: {
|
|
3559
|
+
languages: ['en', 'fr'],
|
|
3560
|
+
keywords: ['premium plan', 'AC-42'],
|
|
3561
|
+
prompt: 'A customer support call.',
|
|
3562
|
+
} satisfies OpenAITranscriptionModelOptions,
|
|
3563
|
+
},
|
|
3564
|
+
});
|
|
3565
|
+
```
|
|
3566
|
+
|
|
3567
|
+
Use `languages` instead of `language` with `gpt-transcribe`; do not send both.
|
|
3568
|
+
The API validates model support and language codes. These two options currently
|
|
3569
|
+
apply to REST transcription; the provider reports unsupported-option warnings
|
|
3570
|
+
if they are supplied to `experimental_streamTranscribe`.
|
|
3571
|
+
|
|
3546
3572
|
To get word-level timestamps, specify the granularity:
|
|
3547
3573
|
|
|
3548
3574
|
```ts highlight="8-9"
|
|
@@ -3592,6 +3618,16 @@ The following provider options are available:
|
|
|
3592
3618
|
For streaming with `gpt-transcribe` and `gpt-live-transcribe`, it is sent as a single-entry `languages` list.
|
|
3593
3619
|
Optional.
|
|
3594
3620
|
|
|
3621
|
+
- **languages** _string[]_
|
|
3622
|
+
Expected languages for REST transcription, such as `['en', 'fr']` for `gpt-transcribe`.
|
|
3623
|
+
Use this instead of `language`; do not send both. The API validates model support.
|
|
3624
|
+
Optional.
|
|
3625
|
+
|
|
3626
|
+
- **keywords** _string[]_
|
|
3627
|
+
Vocabulary hints for REST transcription, such as product names, acronyms, or technical terms.
|
|
3628
|
+
Supported by `gpt-transcribe`; the API validates support for other models.
|
|
3629
|
+
Optional.
|
|
3630
|
+
|
|
3595
3631
|
- **prompt** _string_
|
|
3596
3632
|
An optional text to guide the model's style or continue a previous audio segment. The prompt should match the audio language.
|
|
3597
3633
|
Optional.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/openai",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.107",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@ai-sdk/provider": "4.0.35",
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.73"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@ai-sdk/test-server": "2.0.4",
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
} from '@ai-sdk/provider';
|
|
7
7
|
import type { OpenAIChatPrompt } from './openai-chat-prompt';
|
|
8
8
|
import {
|
|
9
|
+
secureJsonParse,
|
|
10
|
+
stringifyWithBigIntAndCycles,
|
|
9
11
|
convertToBase64,
|
|
10
12
|
getTopLevelMediaType,
|
|
11
13
|
resolveFullMediaType,
|
|
@@ -13,7 +15,22 @@ import {
|
|
|
13
15
|
} from '@ai-sdk/provider-utils';
|
|
14
16
|
|
|
15
17
|
function serializeToolCallArguments(input: unknown): string {
|
|
16
|
-
|
|
18
|
+
if (typeof input === 'string') {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = secureJsonParse(input);
|
|
21
|
+
if (
|
|
22
|
+
typeof parsed !== 'object' ||
|
|
23
|
+
parsed === null ||
|
|
24
|
+
Array.isArray(parsed)
|
|
25
|
+
) {
|
|
26
|
+
return '{}';
|
|
27
|
+
}
|
|
28
|
+
return input;
|
|
29
|
+
} catch {
|
|
30
|
+
return '{}';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return stringifyWithBigIntAndCycles(
|
|
17
34
|
typeof input === 'object' && input !== null && !Array.isArray(input)
|
|
18
35
|
? input
|
|
19
36
|
: {},
|
|
@@ -326,14 +343,16 @@ export function convertToOpenAIChatMessages({
|
|
|
326
343
|
break;
|
|
327
344
|
case 'error-text':
|
|
328
345
|
case 'error-json':
|
|
329
|
-
contentValue =
|
|
346
|
+
contentValue = stringifyWithBigIntAndCycles({
|
|
347
|
+
error: output.value,
|
|
348
|
+
});
|
|
330
349
|
break;
|
|
331
350
|
case 'execution-denied':
|
|
332
351
|
contentValue = output.reason ?? 'Tool call execution denied.';
|
|
333
352
|
break;
|
|
334
353
|
case 'content':
|
|
335
354
|
case 'json':
|
|
336
|
-
contentValue =
|
|
355
|
+
contentValue = stringifyWithBigIntAndCycles(output.value);
|
|
337
356
|
break;
|
|
338
357
|
}
|
|
339
358
|
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
type SharedV4Warning,
|
|
9
9
|
} from '@ai-sdk/provider';
|
|
10
10
|
import {
|
|
11
|
+
secureJsonParse,
|
|
12
|
+
stringifyWithBigIntAndCycles,
|
|
11
13
|
lazySchema,
|
|
12
14
|
zodSchema,
|
|
13
15
|
type InferSchema,
|
|
@@ -62,7 +64,15 @@ import {
|
|
|
62
64
|
} from './expand-parallel-tool-call';
|
|
63
65
|
|
|
64
66
|
function serializeToolCallArguments(input: unknown): string {
|
|
65
|
-
|
|
67
|
+
if (typeof input === 'string') {
|
|
68
|
+
try {
|
|
69
|
+
secureJsonParse(input);
|
|
70
|
+
return input;
|
|
71
|
+
} catch {
|
|
72
|
+
return stringifyWithBigIntAndCycles(input);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return stringifyWithBigIntAndCycles(input === undefined ? {} : input);
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
function mapToolCaller(
|
|
@@ -172,19 +182,23 @@ async function convertFunctionToolResultOutput({
|
|
|
172
182
|
switch (output.type) {
|
|
173
183
|
case 'text':
|
|
174
184
|
return convertScalarOutput(
|
|
175
|
-
hasOutputSchema
|
|
185
|
+
hasOutputSchema
|
|
186
|
+
? stringifyWithBigIntAndCycles(output.value)
|
|
187
|
+
: output.value,
|
|
176
188
|
);
|
|
177
189
|
case 'error-text':
|
|
178
190
|
case 'error-json':
|
|
179
|
-
return convertScalarOutput(
|
|
191
|
+
return convertScalarOutput(
|
|
192
|
+
stringifyWithBigIntAndCycles({ error: output.value }),
|
|
193
|
+
);
|
|
180
194
|
case 'execution-denied': {
|
|
181
195
|
const reason = output.reason ?? 'Tool call execution denied.';
|
|
182
196
|
return convertScalarOutput(
|
|
183
|
-
hasOutputSchema ?
|
|
197
|
+
hasOutputSchema ? stringifyWithBigIntAndCycles(reason) : reason,
|
|
184
198
|
);
|
|
185
199
|
}
|
|
186
200
|
case 'json':
|
|
187
|
-
return convertScalarOutput(
|
|
201
|
+
return convertScalarOutput(stringifyWithBigIntAndCycles(output.value));
|
|
188
202
|
case 'content':
|
|
189
203
|
return output.value
|
|
190
204
|
.map(item => {
|
|
@@ -1074,7 +1088,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
1074
1088
|
input:
|
|
1075
1089
|
typeof part.input === 'string'
|
|
1076
1090
|
? part.input
|
|
1077
|
-
:
|
|
1091
|
+
: stringifyWithBigIntAndCycles(part.input),
|
|
1078
1092
|
...(isAsync != null && { async: isAsync }),
|
|
1079
1093
|
id,
|
|
1080
1094
|
});
|
|
@@ -1311,7 +1325,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
1311
1325
|
} else if (reasoningMessage !== undefined) {
|
|
1312
1326
|
warnings.push({
|
|
1313
1327
|
type: 'other',
|
|
1314
|
-
message: `Cannot append empty reasoning part to existing reasoning sequence. Skipping reasoning part: ${
|
|
1328
|
+
message: `Cannot append empty reasoning part to existing reasoning sequence. Skipping reasoning part: ${stringifyWithBigIntAndCycles(part)}.`,
|
|
1315
1329
|
});
|
|
1316
1330
|
}
|
|
1317
1331
|
|
|
@@ -1362,7 +1376,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
1362
1376
|
} else {
|
|
1363
1377
|
warnings.push({
|
|
1364
1378
|
type: 'other',
|
|
1365
|
-
message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${
|
|
1379
|
+
message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${stringifyWithBigIntAndCycles(part)}.`,
|
|
1366
1380
|
});
|
|
1367
1381
|
}
|
|
1368
1382
|
}
|
|
@@ -1480,7 +1494,9 @@ export async function convertToOpenAIResponsesInput({
|
|
|
1480
1494
|
}),
|
|
1481
1495
|
);
|
|
1482
1496
|
const serializedToolOutputs = toolOutputs.map(({ output }) =>
|
|
1483
|
-
typeof output === 'string'
|
|
1497
|
+
typeof output === 'string'
|
|
1498
|
+
? output
|
|
1499
|
+
: stringifyWithBigIntAndCycles(output),
|
|
1484
1500
|
);
|
|
1485
1501
|
const hasPromptCacheBreakpoint = toolOutputs.some(
|
|
1486
1502
|
({ promptCacheBreakpoint }) => promptCacheBreakpoint != null,
|
|
@@ -1663,7 +1679,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
1663
1679
|
case 'error-text':
|
|
1664
1680
|
case 'error-json':
|
|
1665
1681
|
outputValue = convertScalarOutput(
|
|
1666
|
-
|
|
1682
|
+
stringifyWithBigIntAndCycles({ error: output.value }),
|
|
1667
1683
|
);
|
|
1668
1684
|
break;
|
|
1669
1685
|
case 'execution-denied':
|
|
@@ -1672,7 +1688,9 @@ export async function convertToOpenAIResponsesInput({
|
|
|
1672
1688
|
);
|
|
1673
1689
|
break;
|
|
1674
1690
|
case 'json':
|
|
1675
|
-
outputValue = convertScalarOutput(
|
|
1691
|
+
outputValue = convertScalarOutput(
|
|
1692
|
+
stringifyWithBigIntAndCycles(output.value),
|
|
1693
|
+
);
|
|
1676
1694
|
break;
|
|
1677
1695
|
case 'content':
|
|
1678
1696
|
outputValue = output.value
|
|
@@ -32,6 +32,18 @@ export const openAITranscriptionModelOptions = lazySchema(() =>
|
|
|
32
32
|
*/
|
|
33
33
|
language: z.string().optional(),
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Expected languages for REST transcription, e.g. with gpt-transcribe.
|
|
37
|
+
* Use this instead of language. The API validates model support.
|
|
38
|
+
*/
|
|
39
|
+
languages: z.array(z.string()).optional(),
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Vocabulary hints for REST transcription, e.g. names or technical terms.
|
|
43
|
+
* The API validates model support.
|
|
44
|
+
*/
|
|
45
|
+
keywords: z.array(z.string()).optional(),
|
|
46
|
+
|
|
35
47
|
/**
|
|
36
48
|
* An optional text to guide the model's style or continue a previous audio segment.
|
|
37
49
|
*/
|
|
@@ -207,6 +207,8 @@ export class OpenAITranscriptionModel implements TranscriptionModelV4 {
|
|
|
207
207
|
response_format: responseFormat,
|
|
208
208
|
include: openAIOptions?.include,
|
|
209
209
|
language: openAIOptions?.language,
|
|
210
|
+
languages: openAIOptions?.languages,
|
|
211
|
+
keywords: openAIOptions?.keywords,
|
|
210
212
|
prompt: openAIOptions?.prompt,
|
|
211
213
|
temperature: openAIOptions?.temperature,
|
|
212
214
|
timestamp_granularities: timestampGranularities,
|
|
@@ -384,6 +386,8 @@ export class OpenAITranscriptionModel implements TranscriptionModelV4 {
|
|
|
384
386
|
const rawOpenAIOptions = options.providerOptions?.openai ?? {};
|
|
385
387
|
for (const option of [
|
|
386
388
|
'include',
|
|
389
|
+
'languages',
|
|
390
|
+
'keywords',
|
|
387
391
|
'prompt',
|
|
388
392
|
'temperature',
|
|
389
393
|
'timestampGranularities',
|