@ai-sdk/openai 3.0.136 → 3.0.138
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 +28 -0
- package/dist/index.d.mts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +290 -85
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +276 -69
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +23 -2
- package/dist/internal/index.d.ts +23 -2
- package/dist/internal/index.js +289 -84
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +275 -68
- package/dist/internal/index.mjs.map +1 -1
- package/docs/03-openai.mdx +92 -0
- package/package.json +3 -3
- package/src/chat/map-openai-finish-reason.ts +11 -4
- package/src/chat/openai-chat-api.ts +36 -0
- package/src/chat/openai-chat-language-model.ts +101 -12
- package/src/image/openai-image-model-options.ts +44 -0
- package/src/image/openai-image-model.ts +44 -4
- package/src/responses/map-openai-responses-finish-reason.ts +7 -1
- package/src/responses/openai-responses-api.ts +71 -48
- package/src/responses/openai-responses-language-model.ts +47 -0
|
@@ -681,6 +681,8 @@ const openaiResponsesModeledChunkTypes = new Set([
|
|
|
681
681
|
'response.output_item.done',
|
|
682
682
|
'response.output_text.annotation.added',
|
|
683
683
|
'response.output_text.delta',
|
|
684
|
+
'response.refusal.delta',
|
|
685
|
+
'response.refusal.done',
|
|
684
686
|
'response.reasoning_summary_part.added',
|
|
685
687
|
'response.reasoning_summary_part.done',
|
|
686
688
|
'response.reasoning_summary_text.delta',
|
|
@@ -756,6 +758,20 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
756
758
|
)
|
|
757
759
|
.nullish(),
|
|
758
760
|
}),
|
|
761
|
+
z.object({
|
|
762
|
+
type: z.literal('response.refusal.delta'),
|
|
763
|
+
item_id: z.string(),
|
|
764
|
+
output_index: z.number().nullish(),
|
|
765
|
+
content_index: z.number().nullish(),
|
|
766
|
+
delta: z.string(),
|
|
767
|
+
}),
|
|
768
|
+
z.object({
|
|
769
|
+
type: z.literal('response.refusal.done'),
|
|
770
|
+
item_id: z.string(),
|
|
771
|
+
output_index: z.number().nullish(),
|
|
772
|
+
content_index: z.number().nullish(),
|
|
773
|
+
refusal: z.string(),
|
|
774
|
+
}),
|
|
759
775
|
z.object({
|
|
760
776
|
type: z.enum(['response.completed', 'response.incomplete']),
|
|
761
777
|
response: z.object({
|
|
@@ -1330,55 +1346,62 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
|
|
|
1330
1346
|
role: z.literal('assistant'),
|
|
1331
1347
|
id: z.string(),
|
|
1332
1348
|
phase: z.enum(['commentary', 'final_answer']).nullish(),
|
|
1349
|
+
// the API returns either text or a refusal as content parts:
|
|
1333
1350
|
content: z.array(
|
|
1334
|
-
z.
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
z.
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
z.
|
|
1353
|
-
z.
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1351
|
+
z.discriminatedUnion('type', [
|
|
1352
|
+
z.object({
|
|
1353
|
+
type: z.literal('output_text'),
|
|
1354
|
+
text: z.string(),
|
|
1355
|
+
logprobs: z
|
|
1356
|
+
.array(
|
|
1357
|
+
z.object({
|
|
1358
|
+
token: z.string(),
|
|
1359
|
+
logprob: z.number(),
|
|
1360
|
+
top_logprobs: z.array(
|
|
1361
|
+
z.object({
|
|
1362
|
+
token: z.string(),
|
|
1363
|
+
logprob: z.number(),
|
|
1364
|
+
}),
|
|
1365
|
+
),
|
|
1366
|
+
}),
|
|
1367
|
+
)
|
|
1368
|
+
.nullish(),
|
|
1369
|
+
annotations: z.array(
|
|
1370
|
+
z.discriminatedUnion('type', [
|
|
1371
|
+
z.object({
|
|
1372
|
+
type: z.literal('url_citation'),
|
|
1373
|
+
start_index: z.number(),
|
|
1374
|
+
end_index: z.number(),
|
|
1375
|
+
url: z.string(),
|
|
1376
|
+
title: z.string(),
|
|
1377
|
+
}),
|
|
1378
|
+
z.object({
|
|
1379
|
+
type: z.literal('file_citation'),
|
|
1380
|
+
file_id: z.string(),
|
|
1381
|
+
filename: z.string(),
|
|
1382
|
+
index: z.number(),
|
|
1383
|
+
}),
|
|
1384
|
+
z.object({
|
|
1385
|
+
type: z.literal('container_file_citation'),
|
|
1386
|
+
container_id: z.string(),
|
|
1387
|
+
file_id: z.string(),
|
|
1388
|
+
filename: z.string(),
|
|
1389
|
+
start_index: z.number(),
|
|
1390
|
+
end_index: z.number(),
|
|
1391
|
+
}),
|
|
1392
|
+
z.object({
|
|
1393
|
+
type: z.literal('file_path'),
|
|
1394
|
+
file_id: z.string(),
|
|
1395
|
+
index: z.number(),
|
|
1396
|
+
}),
|
|
1397
|
+
]),
|
|
1398
|
+
),
|
|
1399
|
+
}),
|
|
1400
|
+
z.object({
|
|
1401
|
+
type: z.literal('refusal'),
|
|
1402
|
+
refusal: z.string(),
|
|
1403
|
+
}),
|
|
1404
|
+
]),
|
|
1382
1405
|
),
|
|
1383
1406
|
}),
|
|
1384
1407
|
z.object({
|
|
@@ -686,6 +686,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
686
686
|
let hasFunctionCall = false;
|
|
687
687
|
const hostedToolSearchCallIds: string[] = [];
|
|
688
688
|
|
|
689
|
+
// flag that checks if the model refused to answer:
|
|
690
|
+
let hasRefusal = false;
|
|
691
|
+
|
|
689
692
|
// map response content to content array (defined when there is no error)
|
|
690
693
|
for (const part of response.output!) {
|
|
691
694
|
switch (part.type) {
|
|
@@ -842,6 +845,23 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
842
845
|
|
|
843
846
|
case 'message': {
|
|
844
847
|
for (const contentPart of part.content) {
|
|
848
|
+
if (contentPart.type === 'refusal') {
|
|
849
|
+
hasRefusal = true;
|
|
850
|
+
|
|
851
|
+
content.push({
|
|
852
|
+
type: 'text',
|
|
853
|
+
text: contentPart.refusal,
|
|
854
|
+
providerMetadata: {
|
|
855
|
+
[providerOptionsName]: {
|
|
856
|
+
itemId: part.id,
|
|
857
|
+
...(part.phase != null && { phase: part.phase }),
|
|
858
|
+
} satisfies ResponsesTextProviderMetadata,
|
|
859
|
+
},
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
|
|
845
865
|
if (
|
|
846
866
|
options.providerOptions?.[providerOptionsName]?.logprobs &&
|
|
847
867
|
contentPart.logprobs
|
|
@@ -1200,6 +1220,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1200
1220
|
unified: mapOpenAIResponseFinishReason({
|
|
1201
1221
|
finishReason: response.incomplete_details?.reason,
|
|
1202
1222
|
hasFunctionCall,
|
|
1223
|
+
hasRefusal,
|
|
1203
1224
|
}),
|
|
1204
1225
|
raw: response.incomplete_details?.reason ?? undefined,
|
|
1205
1226
|
},
|
|
@@ -1320,6 +1341,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1320
1341
|
// flag that checks if there have been client-side tool calls (not executed by openai)
|
|
1321
1342
|
let hasFunctionCall = false;
|
|
1322
1343
|
|
|
1344
|
+
// flag that checks if the model refused to answer:
|
|
1345
|
+
let hasRefusal = false;
|
|
1346
|
+
|
|
1323
1347
|
const activeReasoning: Record<
|
|
1324
1348
|
string,
|
|
1325
1349
|
{
|
|
@@ -2265,6 +2289,16 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
2265
2289
|
) {
|
|
2266
2290
|
logprobs.push(value.logprobs);
|
|
2267
2291
|
}
|
|
2292
|
+
} else if (isRefusalDeltaChunk(value)) {
|
|
2293
|
+
hasRefusal = true;
|
|
2294
|
+
|
|
2295
|
+
controller.enqueue({
|
|
2296
|
+
type: 'text-delta',
|
|
2297
|
+
id: value.item_id,
|
|
2298
|
+
delta: value.delta,
|
|
2299
|
+
});
|
|
2300
|
+
} else if (isRefusalDoneChunk(value)) {
|
|
2301
|
+
hasRefusal = true;
|
|
2268
2302
|
} else if (value.type === 'response.reasoning_summary_part.added') {
|
|
2269
2303
|
// the first reasoning start is pushed in isResponseOutputItemAddedReasoningChunk
|
|
2270
2304
|
if (value.summary_index > 0) {
|
|
@@ -2350,6 +2384,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
2350
2384
|
unified: mapOpenAIResponseFinishReason({
|
|
2351
2385
|
finishReason: value.response.incomplete_details?.reason,
|
|
2352
2386
|
hasFunctionCall,
|
|
2387
|
+
hasRefusal,
|
|
2353
2388
|
}),
|
|
2354
2389
|
raw: value.response.incomplete_details?.reason ?? undefined,
|
|
2355
2390
|
};
|
|
@@ -2525,6 +2560,18 @@ function isTextDeltaChunk(
|
|
|
2525
2560
|
return chunk.type === 'response.output_text.delta';
|
|
2526
2561
|
}
|
|
2527
2562
|
|
|
2563
|
+
function isRefusalDeltaChunk(
|
|
2564
|
+
chunk: OpenAIResponsesChunk,
|
|
2565
|
+
): chunk is OpenAIResponsesChunk & { type: 'response.refusal.delta' } {
|
|
2566
|
+
return chunk.type === 'response.refusal.delta';
|
|
2567
|
+
}
|
|
2568
|
+
|
|
2569
|
+
function isRefusalDoneChunk(
|
|
2570
|
+
chunk: OpenAIResponsesChunk,
|
|
2571
|
+
): chunk is OpenAIResponsesChunk & { type: 'response.refusal.done' } {
|
|
2572
|
+
return chunk.type === 'response.refusal.done';
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2528
2575
|
function isOpenAIChatCompletionChunk(value: unknown): boolean {
|
|
2529
2576
|
const chunk = asRecord(value);
|
|
2530
2577
|
|