@ai-sdk/openai 2.0.139 → 2.0.141
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 +37 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +249 -77
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +256 -78
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +2 -0
- package/dist/internal/index.d.ts +2 -0
- package/dist/internal/index.js +248 -76
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +255 -77
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @ai-sdk/openai
|
|
2
2
|
|
|
3
|
+
## 2.0.141
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6b6433f: fix(openai): surface Chat Completions refusals as text content
|
|
8
|
+
|
|
9
|
+
The Chat Completions model ignored `message.refusal` (non-streaming) and `delta.refusal` (streaming). When the model refused to answer, `content` was `null`, so the AI SDK returned empty text with a `stop` finish reason and silently dropped the refusal. Refusal text is now emitted as text content in both `generateText` and `streamText` results, and it is emitted in addition to content when the API returns both. A refusal with a `stop` finish reason is now reported as a `content-filter` finish reason, matching the Anthropic provider and the Responses API.
|
|
10
|
+
|
|
11
|
+
- ce27f15: fix(openai,openai-compatible): surface refusal logprobs and openai-compatible refusals
|
|
12
|
+
|
|
13
|
+
`@ai-sdk/openai`: Chat Completions responses that contain a refusal can return `logprobs.refusal` next to `logprobs.content`. The provider previously read only `logprobs.content`, so `providerMetadata.openai.logprobs` was empty or missing for refusals. Refusal logprobs are now included in emission order (content logprobs followed by refusal logprobs) in both `generateText` and `streamText`.
|
|
14
|
+
|
|
15
|
+
Streaming logprobs are now collected across all chunks in `streamText`: previously only the logprobs of the last streamed chunk were reported. This applies to content logprobs as well, so `providerMetadata.openai.logprobs` now contains the logprobs of every streamed token instead of only the last chunk's tokens. Explicitly empty logprobs (`logprobs: { content: [], refusal: null }`) are reported as an empty array, as before.
|
|
16
|
+
|
|
17
|
+
A refusal that arrives in the same streamed chunk as the `finish_reason` is now taken into account: such a response is reported with a `content-filter` finish reason instead of `stop`.
|
|
18
|
+
|
|
19
|
+
`@ai-sdk/openai-compatible`: Chat Completions responses that carry `message.refusal` (non-streaming) or `delta.refusal` (streaming) were ignored, so providers such as OpenAI served through `createOpenAICompatible` lost the refusal text and reported an empty `stop` response. Refusals are now returned as text content after any content text, and a non-empty refusal with a `stop` finish reason is reported as a `content-filter` finish reason. This also applies when the refusal and the finish reason arrive in the same streamed chunk. Non-string refusals (for example `refusal: false` from servers that use booleans) are ignored instead of failing the response.
|
|
20
|
+
|
|
21
|
+
- 0e51536: fix(openai): handle refusal content parts in the Responses API
|
|
22
|
+
|
|
23
|
+
The Responses API returns a `refusal` content part instead of `output_text` when the model declines a request. The response schema rejected these parts, so non-streaming calls failed with an `APICallError` ("Invalid JSON response"), and streamed `response.refusal.delta` / `response.refusal.done` events were dropped, producing empty text. Refusal content parts and stream events are now parsed: the refusal explanation is surfaced as text and the finish reason is mapped to `content-filter`. When the response also contains a client-side function call, the finish reason stays `tool-calls` so the tools are still executed.
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [49c554d]
|
|
26
|
+
- Updated dependencies [b753c03]
|
|
27
|
+
- @ai-sdk/provider-utils@3.0.45
|
|
28
|
+
|
|
29
|
+
## 2.0.140
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- 0a069bd: fix(openai): preserve valid JSON string tool arguments and serialize BigInt and cycles in tool calls and results, retaining malformed argument replay fallbacks
|
|
34
|
+
- 0a069bd: Forward `languages` and `keywords` transcription hints as repeated multipart fields instead of silently dropping them.
|
|
35
|
+
- Updated dependencies [0a069bd]
|
|
36
|
+
- Updated dependencies [0a069bd]
|
|
37
|
+
- Updated dependencies [0a069bd]
|
|
38
|
+
- @ai-sdk/provider-utils@3.0.44
|
|
39
|
+
|
|
3
40
|
## 2.0.139
|
|
4
41
|
|
|
5
42
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -202,6 +202,18 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazyValidator<{
|
|
|
202
202
|
logprob: number;
|
|
203
203
|
}[];
|
|
204
204
|
}[] | null | undefined;
|
|
205
|
+
} | {
|
|
206
|
+
type: "response.refusal.delta";
|
|
207
|
+
item_id: string;
|
|
208
|
+
delta: string;
|
|
209
|
+
output_index?: number | null | undefined;
|
|
210
|
+
content_index?: number | null | undefined;
|
|
211
|
+
} | {
|
|
212
|
+
type: "response.refusal.done";
|
|
213
|
+
item_id: string;
|
|
214
|
+
refusal: string;
|
|
215
|
+
output_index?: number | null | undefined;
|
|
216
|
+
content_index?: number | null | undefined;
|
|
205
217
|
} | {
|
|
206
218
|
type: "response.completed" | "response.incomplete";
|
|
207
219
|
response: {
|
package/dist/index.d.ts
CHANGED
|
@@ -202,6 +202,18 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazyValidator<{
|
|
|
202
202
|
logprob: number;
|
|
203
203
|
}[];
|
|
204
204
|
}[] | null | undefined;
|
|
205
|
+
} | {
|
|
206
|
+
type: "response.refusal.delta";
|
|
207
|
+
item_id: string;
|
|
208
|
+
delta: string;
|
|
209
|
+
output_index?: number | null | undefined;
|
|
210
|
+
content_index?: number | null | undefined;
|
|
211
|
+
} | {
|
|
212
|
+
type: "response.refusal.done";
|
|
213
|
+
item_id: string;
|
|
214
|
+
refusal: string;
|
|
215
|
+
output_index?: number | null | undefined;
|
|
216
|
+
content_index?: number | null | undefined;
|
|
205
217
|
} | {
|
|
206
218
|
type: "response.completed" | "response.incomplete";
|
|
207
219
|
response: {
|
package/dist/index.js
CHANGED
|
@@ -100,7 +100,18 @@ function getGptVersion(modelId) {
|
|
|
100
100
|
var import_provider = require("@ai-sdk/provider");
|
|
101
101
|
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
102
102
|
function serializeToolCallArguments(input) {
|
|
103
|
-
|
|
103
|
+
if (typeof input === "string") {
|
|
104
|
+
try {
|
|
105
|
+
const parsed = (0, import_provider_utils2.secureJsonParse)(input);
|
|
106
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
107
|
+
return "{}";
|
|
108
|
+
}
|
|
109
|
+
return input;
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return "{}";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return (0, import_provider_utils2.stringifyWithBigIntAndCycles)(
|
|
104
115
|
typeof input === "object" && input !== null && !Array.isArray(input) ? input : {}
|
|
105
116
|
);
|
|
106
117
|
}
|
|
@@ -323,7 +334,7 @@ function convertToOpenAIChatMessages({
|
|
|
323
334
|
case "content":
|
|
324
335
|
case "json":
|
|
325
336
|
case "error-json":
|
|
326
|
-
contentValue =
|
|
337
|
+
contentValue = (0, import_provider_utils2.stringifyWithBigIntAndCycles)(output.value);
|
|
327
338
|
break;
|
|
328
339
|
}
|
|
329
340
|
messages.push({
|
|
@@ -363,10 +374,13 @@ function getResponseMetadata({
|
|
|
363
374
|
}
|
|
364
375
|
|
|
365
376
|
// src/chat/map-openai-finish-reason.ts
|
|
366
|
-
function mapOpenAIFinishReason(
|
|
377
|
+
function mapOpenAIFinishReason({
|
|
378
|
+
finishReason,
|
|
379
|
+
hasRefusal = false
|
|
380
|
+
}) {
|
|
367
381
|
switch (finishReason) {
|
|
368
382
|
case "stop":
|
|
369
|
-
return "stop";
|
|
383
|
+
return hasRefusal ? "content-filter" : "stop";
|
|
370
384
|
case "length":
|
|
371
385
|
return "length";
|
|
372
386
|
case "content_filter":
|
|
@@ -393,6 +407,8 @@ var openaiChatResponseSchema = (0, import_provider_utils3.lazyValidator)(
|
|
|
393
407
|
message: import_v42.z.object({
|
|
394
408
|
role: import_v42.z.literal("assistant").nullish(),
|
|
395
409
|
content: import_v42.z.string().nullish(),
|
|
410
|
+
// set instead of `content` when the model refuses to answer:
|
|
411
|
+
refusal: import_v42.z.string().nullish(),
|
|
396
412
|
audio: import_v42.z.object({
|
|
397
413
|
transcript: import_v42.z.string().nullish()
|
|
398
414
|
}).nullish(),
|
|
@@ -431,6 +447,20 @@ var openaiChatResponseSchema = (0, import_provider_utils3.lazyValidator)(
|
|
|
431
447
|
})
|
|
432
448
|
)
|
|
433
449
|
})
|
|
450
|
+
).nullish(),
|
|
451
|
+
// logprobs of the refusal tokens (set instead of `content` when
|
|
452
|
+
// the model refuses to answer):
|
|
453
|
+
refusal: import_v42.z.array(
|
|
454
|
+
import_v42.z.object({
|
|
455
|
+
token: import_v42.z.string(),
|
|
456
|
+
logprob: import_v42.z.number(),
|
|
457
|
+
top_logprobs: import_v42.z.array(
|
|
458
|
+
import_v42.z.object({
|
|
459
|
+
token: import_v42.z.string(),
|
|
460
|
+
logprob: import_v42.z.number()
|
|
461
|
+
})
|
|
462
|
+
)
|
|
463
|
+
})
|
|
434
464
|
).nullish()
|
|
435
465
|
}).nullish(),
|
|
436
466
|
finish_reason: import_v42.z.string().nullish()
|
|
@@ -465,6 +495,8 @@ var openaiChatChunkSchema = (0, import_provider_utils3.lazyValidator)(
|
|
|
465
495
|
delta: import_v42.z.object({
|
|
466
496
|
role: import_v42.z.enum(["assistant"]).nullish(),
|
|
467
497
|
content: import_v42.z.string().nullish(),
|
|
498
|
+
// set instead of `content` when the model refuses to answer:
|
|
499
|
+
refusal: import_v42.z.string().nullish(),
|
|
468
500
|
tool_calls: import_v42.z.array(
|
|
469
501
|
import_v42.z.object({
|
|
470
502
|
index: import_v42.z.number(),
|
|
@@ -500,6 +532,20 @@ var openaiChatChunkSchema = (0, import_provider_utils3.lazyValidator)(
|
|
|
500
532
|
})
|
|
501
533
|
)
|
|
502
534
|
})
|
|
535
|
+
).nullish(),
|
|
536
|
+
// logprobs of the refusal tokens (set instead of `content` when
|
|
537
|
+
// the model refuses to answer):
|
|
538
|
+
refusal: import_v42.z.array(
|
|
539
|
+
import_v42.z.object({
|
|
540
|
+
token: import_v42.z.string(),
|
|
541
|
+
logprob: import_v42.z.number(),
|
|
542
|
+
top_logprobs: import_v42.z.array(
|
|
543
|
+
import_v42.z.object({
|
|
544
|
+
token: import_v42.z.string(),
|
|
545
|
+
logprob: import_v42.z.number()
|
|
546
|
+
})
|
|
547
|
+
)
|
|
548
|
+
})
|
|
503
549
|
).nullish()
|
|
504
550
|
}).nullish(),
|
|
505
551
|
finish_reason: import_v42.z.string().nullish(),
|
|
@@ -931,7 +977,7 @@ var OpenAIChatLanguageModel = class {
|
|
|
931
977
|
};
|
|
932
978
|
}
|
|
933
979
|
async doGenerate(options) {
|
|
934
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
980
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
935
981
|
const { args: body, warnings } = await this.getArgs(options);
|
|
936
982
|
const {
|
|
937
983
|
responseHeaders,
|
|
@@ -963,6 +1009,11 @@ var OpenAIChatLanguageModel = class {
|
|
|
963
1009
|
if (text != null && text.length > 0) {
|
|
964
1010
|
content.push({ type: "text", text });
|
|
965
1011
|
}
|
|
1012
|
+
const refusal = choice.message.refusal;
|
|
1013
|
+
const hasRefusal = refusal != null && refusal.length > 0;
|
|
1014
|
+
if (hasRefusal) {
|
|
1015
|
+
content.push({ type: "text", text: refusal });
|
|
1016
|
+
}
|
|
966
1017
|
for (const toolCall of (_b = choice.message.tool_calls) != null ? _b : []) {
|
|
967
1018
|
content.push({
|
|
968
1019
|
type: "tool-call",
|
|
@@ -994,18 +1045,26 @@ var OpenAIChatLanguageModel = class {
|
|
|
994
1045
|
cacheWriteTokens: promptTokenDetails.cache_write_tokens
|
|
995
1046
|
};
|
|
996
1047
|
}
|
|
997
|
-
|
|
998
|
-
|
|
1048
|
+
const contentLogprobs = (_g = choice.logprobs) == null ? void 0 : _g.content;
|
|
1049
|
+
const refusalLogprobs = (_h = choice.logprobs) == null ? void 0 : _h.refusal;
|
|
1050
|
+
if (contentLogprobs != null || refusalLogprobs != null) {
|
|
1051
|
+
providerMetadata.openai.logprobs = [
|
|
1052
|
+
...contentLogprobs != null ? contentLogprobs : [],
|
|
1053
|
+
...refusalLogprobs != null ? refusalLogprobs : []
|
|
1054
|
+
];
|
|
999
1055
|
}
|
|
1000
1056
|
return {
|
|
1001
1057
|
content,
|
|
1002
|
-
finishReason: mapOpenAIFinishReason(
|
|
1058
|
+
finishReason: mapOpenAIFinishReason({
|
|
1059
|
+
finishReason: choice.finish_reason,
|
|
1060
|
+
hasRefusal
|
|
1061
|
+
}),
|
|
1003
1062
|
usage: {
|
|
1004
|
-
inputTokens: (
|
|
1005
|
-
outputTokens: (
|
|
1006
|
-
totalTokens: (
|
|
1007
|
-
reasoningTokens: (
|
|
1008
|
-
cachedInputTokens: (
|
|
1063
|
+
inputTokens: (_j = (_i = response.usage) == null ? void 0 : _i.prompt_tokens) != null ? _j : void 0,
|
|
1064
|
+
outputTokens: (_l = (_k = response.usage) == null ? void 0 : _k.completion_tokens) != null ? _l : void 0,
|
|
1065
|
+
totalTokens: (_n = (_m = response.usage) == null ? void 0 : _m.total_tokens) != null ? _n : void 0,
|
|
1066
|
+
reasoningTokens: (_o = completionTokenDetails == null ? void 0 : completionTokenDetails.reasoning_tokens) != null ? _o : void 0,
|
|
1067
|
+
cachedInputTokens: (_p = promptTokenDetails == null ? void 0 : promptTokenDetails.cached_tokens) != null ? _p : void 0
|
|
1009
1068
|
},
|
|
1010
1069
|
request: { body },
|
|
1011
1070
|
response: {
|
|
@@ -1049,6 +1108,10 @@ var OpenAIChatLanguageModel = class {
|
|
|
1049
1108
|
};
|
|
1050
1109
|
let metadataExtracted = false;
|
|
1051
1110
|
let isActiveText = false;
|
|
1111
|
+
let hasRefusal = false;
|
|
1112
|
+
let rawFinishReason = void 0;
|
|
1113
|
+
let hasLogprobs = false;
|
|
1114
|
+
const streamedLogprobs = [];
|
|
1052
1115
|
const providerMetadata = { openai: {} };
|
|
1053
1116
|
return {
|
|
1054
1117
|
stream: response.pipeThrough(
|
|
@@ -1061,18 +1124,20 @@ var OpenAIChatLanguageModel = class {
|
|
|
1061
1124
|
controller.enqueue({ type: "stream-start", warnings });
|
|
1062
1125
|
},
|
|
1063
1126
|
transform(chunk, controller) {
|
|
1064
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l
|
|
1127
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
1065
1128
|
if (options.includeRawChunks) {
|
|
1066
1129
|
controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
|
|
1067
1130
|
}
|
|
1068
1131
|
if (!chunk.success) {
|
|
1069
1132
|
finishReason = "error";
|
|
1133
|
+
rawFinishReason = void 0;
|
|
1070
1134
|
controller.enqueue({ type: "error", error: chunk.error });
|
|
1071
1135
|
return;
|
|
1072
1136
|
}
|
|
1073
1137
|
const value = chunk.value;
|
|
1074
1138
|
if ("error" in value) {
|
|
1075
1139
|
finishReason = "error";
|
|
1140
|
+
rawFinishReason = void 0;
|
|
1076
1141
|
controller.enqueue({ type: "error", error: value.error });
|
|
1077
1142
|
return;
|
|
1078
1143
|
}
|
|
@@ -1106,16 +1171,35 @@ var OpenAIChatLanguageModel = class {
|
|
|
1106
1171
|
}
|
|
1107
1172
|
const choice = value.choices[0];
|
|
1108
1173
|
if ((choice == null ? void 0 : choice.finish_reason) != null) {
|
|
1109
|
-
|
|
1174
|
+
rawFinishReason = choice.finish_reason;
|
|
1110
1175
|
}
|
|
1111
|
-
if ((
|
|
1112
|
-
|
|
1176
|
+
if ((choice == null ? void 0 : choice.logprobs) != null) {
|
|
1177
|
+
const contentLogprobs = choice.logprobs.content;
|
|
1178
|
+
const refusalLogprobs = choice.logprobs.refusal;
|
|
1179
|
+
if (contentLogprobs != null || refusalLogprobs != null) {
|
|
1180
|
+
hasLogprobs = true;
|
|
1181
|
+
streamedLogprobs.push(
|
|
1182
|
+
...contentLogprobs != null ? contentLogprobs : [],
|
|
1183
|
+
...refusalLogprobs != null ? refusalLogprobs : []
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1113
1186
|
}
|
|
1114
1187
|
if ((choice == null ? void 0 : choice.delta) == null) {
|
|
1115
1188
|
return;
|
|
1116
1189
|
}
|
|
1117
1190
|
const delta = choice.delta;
|
|
1118
|
-
|
|
1191
|
+
const textDeltas = [];
|
|
1192
|
+
if (delta.content != null && delta.content.length > 0) {
|
|
1193
|
+
textDeltas.push(delta.content);
|
|
1194
|
+
}
|
|
1195
|
+
if (delta.refusal != null && delta.refusal.length > 0) {
|
|
1196
|
+
hasRefusal = true;
|
|
1197
|
+
textDeltas.push(delta.refusal);
|
|
1198
|
+
}
|
|
1199
|
+
if (textDeltas.length === 0 && delta.content === "") {
|
|
1200
|
+
textDeltas.push(delta.content);
|
|
1201
|
+
}
|
|
1202
|
+
for (const textDelta of textDeltas) {
|
|
1119
1203
|
if (!isActiveText) {
|
|
1120
1204
|
controller.enqueue({ type: "text-start", id: "0" });
|
|
1121
1205
|
isActiveText = true;
|
|
@@ -1123,7 +1207,7 @@ var OpenAIChatLanguageModel = class {
|
|
|
1123
1207
|
controller.enqueue({
|
|
1124
1208
|
type: "text-delta",
|
|
1125
1209
|
id: "0",
|
|
1126
|
-
delta:
|
|
1210
|
+
delta: textDelta
|
|
1127
1211
|
});
|
|
1128
1212
|
}
|
|
1129
1213
|
if (delta.tool_calls != null) {
|
|
@@ -1148,6 +1232,15 @@ var OpenAIChatLanguageModel = class {
|
|
|
1148
1232
|
controller.enqueue({ type: "text-end", id: "0" });
|
|
1149
1233
|
}
|
|
1150
1234
|
toolCallTracker.flush();
|
|
1235
|
+
if (rawFinishReason != null) {
|
|
1236
|
+
finishReason = mapOpenAIFinishReason({
|
|
1237
|
+
finishReason: rawFinishReason,
|
|
1238
|
+
hasRefusal
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
if (hasLogprobs) {
|
|
1242
|
+
providerMetadata.openai.logprobs = streamedLogprobs;
|
|
1243
|
+
}
|
|
1151
1244
|
controller.enqueue({
|
|
1152
1245
|
type: "finish",
|
|
1153
1246
|
finishReason,
|
|
@@ -2764,7 +2857,7 @@ async function convertToOpenAIResponsesInput({
|
|
|
2764
2857
|
type: "function_call",
|
|
2765
2858
|
call_id: part.toolCallId,
|
|
2766
2859
|
name: part.toolName,
|
|
2767
|
-
arguments:
|
|
2860
|
+
arguments: serializeToolCallArguments2(part.input),
|
|
2768
2861
|
...isAsync != null && { async: isAsync },
|
|
2769
2862
|
id: canUseItemId ? id : void 0
|
|
2770
2863
|
});
|
|
@@ -2826,7 +2919,7 @@ async function convertToOpenAIResponsesInput({
|
|
|
2826
2919
|
} else if (reasoningMessage !== void 0) {
|
|
2827
2920
|
warnings.push({
|
|
2828
2921
|
type: "other",
|
|
2829
|
-
message: `Cannot append empty reasoning part to existing reasoning sequence. Skipping reasoning part: ${
|
|
2922
|
+
message: `Cannot append empty reasoning part to existing reasoning sequence. Skipping reasoning part: ${(0, import_provider_utils22.stringifyWithBigIntAndCycles)(part)}.`
|
|
2830
2923
|
});
|
|
2831
2924
|
}
|
|
2832
2925
|
if (reasoningMessage === void 0) {
|
|
@@ -2847,7 +2940,7 @@ async function convertToOpenAIResponsesInput({
|
|
|
2847
2940
|
} else {
|
|
2848
2941
|
warnings.push({
|
|
2849
2942
|
type: "other",
|
|
2850
|
-
message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${
|
|
2943
|
+
message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${(0, import_provider_utils22.stringifyWithBigIntAndCycles)(part)}.`
|
|
2851
2944
|
});
|
|
2852
2945
|
}
|
|
2853
2946
|
break;
|
|
@@ -2888,10 +2981,10 @@ async function convertToOpenAIResponsesInput({
|
|
|
2888
2981
|
break;
|
|
2889
2982
|
case "json":
|
|
2890
2983
|
case "error-json":
|
|
2891
|
-
contentValue = promptCacheBreakpoint == null ?
|
|
2984
|
+
contentValue = promptCacheBreakpoint == null ? (0, import_provider_utils22.stringifyWithBigIntAndCycles)(output.value) : [
|
|
2892
2985
|
{
|
|
2893
2986
|
type: "input_text",
|
|
2894
|
-
text:
|
|
2987
|
+
text: (0, import_provider_utils22.stringifyWithBigIntAndCycles)(output.value),
|
|
2895
2988
|
prompt_cache_breakpoint: promptCacheBreakpoint
|
|
2896
2989
|
}
|
|
2897
2990
|
];
|
|
@@ -2964,16 +3057,29 @@ var openaiResponsesReasoningProviderOptionsSchema = (0, import_provider_utils22.
|
|
|
2964
3057
|
})
|
|
2965
3058
|
)
|
|
2966
3059
|
);
|
|
3060
|
+
function serializeToolCallArguments2(input) {
|
|
3061
|
+
if (typeof input === "string") {
|
|
3062
|
+
try {
|
|
3063
|
+
(0, import_provider_utils22.secureJsonParse)(input);
|
|
3064
|
+
return input;
|
|
3065
|
+
} catch (e) {
|
|
3066
|
+
return (0, import_provider_utils22.stringifyWithBigIntAndCycles)(input);
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
return (0, import_provider_utils22.stringifyWithBigIntAndCycles)(input === void 0 ? {} : input);
|
|
3070
|
+
}
|
|
2967
3071
|
|
|
2968
3072
|
// src/responses/map-openai-responses-finish-reason.ts
|
|
2969
3073
|
function mapOpenAIResponseFinishReason({
|
|
2970
3074
|
finishReason,
|
|
2971
|
-
hasFunctionCall
|
|
3075
|
+
hasFunctionCall,
|
|
3076
|
+
hasRefusal = false
|
|
2972
3077
|
}) {
|
|
2973
3078
|
switch (finishReason) {
|
|
2974
3079
|
case void 0:
|
|
2975
3080
|
case null:
|
|
2976
|
-
|
|
3081
|
+
if (hasFunctionCall) return "tool-calls";
|
|
3082
|
+
return hasRefusal ? "content-filter" : "stop";
|
|
2977
3083
|
case "max_output_tokens":
|
|
2978
3084
|
return "length";
|
|
2979
3085
|
case "content_filter":
|
|
@@ -3006,6 +3112,20 @@ var openaiResponsesChunkSchema = (0, import_provider_utils23.lazyValidator)(
|
|
|
3006
3112
|
})
|
|
3007
3113
|
).nullish()
|
|
3008
3114
|
}),
|
|
3115
|
+
import_v418.z.object({
|
|
3116
|
+
type: import_v418.z.literal("response.refusal.delta"),
|
|
3117
|
+
item_id: import_v418.z.string(),
|
|
3118
|
+
output_index: import_v418.z.number().nullish(),
|
|
3119
|
+
content_index: import_v418.z.number().nullish(),
|
|
3120
|
+
delta: import_v418.z.string()
|
|
3121
|
+
}),
|
|
3122
|
+
import_v418.z.object({
|
|
3123
|
+
type: import_v418.z.literal("response.refusal.done"),
|
|
3124
|
+
item_id: import_v418.z.string(),
|
|
3125
|
+
output_index: import_v418.z.number().nullish(),
|
|
3126
|
+
content_index: import_v418.z.number().nullish(),
|
|
3127
|
+
refusal: import_v418.z.string()
|
|
3128
|
+
}),
|
|
3009
3129
|
import_v418.z.object({
|
|
3010
3130
|
type: import_v418.z.enum(["response.completed", "response.incomplete"]),
|
|
3011
3131
|
response: import_v418.z.object({
|
|
@@ -3292,57 +3412,64 @@ var openaiResponsesResponseSchema = (0, import_provider_utils23.lazyValidator)(
|
|
|
3292
3412
|
role: import_v418.z.literal("assistant"),
|
|
3293
3413
|
id: import_v418.z.string(),
|
|
3294
3414
|
phase: import_v418.z.enum(["commentary", "final_answer"]).nullish(),
|
|
3415
|
+
// the API returns either text or a refusal as content parts:
|
|
3295
3416
|
content: import_v418.z.array(
|
|
3296
|
-
import_v418.z.
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
import_v418.z.
|
|
3301
|
-
token: import_v418.z.string(),
|
|
3302
|
-
logprob: import_v418.z.number(),
|
|
3303
|
-
top_logprobs: import_v418.z.array(
|
|
3304
|
-
import_v418.z.object({
|
|
3305
|
-
token: import_v418.z.string(),
|
|
3306
|
-
logprob: import_v418.z.number()
|
|
3307
|
-
})
|
|
3308
|
-
)
|
|
3309
|
-
})
|
|
3310
|
-
).nullish(),
|
|
3311
|
-
annotations: import_v418.z.array(
|
|
3312
|
-
import_v418.z.discriminatedUnion("type", [
|
|
3313
|
-
import_v418.z.object({
|
|
3314
|
-
type: import_v418.z.literal("url_citation"),
|
|
3315
|
-
start_index: import_v418.z.number(),
|
|
3316
|
-
end_index: import_v418.z.number(),
|
|
3317
|
-
url: import_v418.z.string(),
|
|
3318
|
-
title: import_v418.z.string()
|
|
3319
|
-
}),
|
|
3320
|
-
import_v418.z.object({
|
|
3321
|
-
type: import_v418.z.literal("file_citation"),
|
|
3322
|
-
file_id: import_v418.z.string(),
|
|
3323
|
-
filename: import_v418.z.string().nullish(),
|
|
3324
|
-
index: import_v418.z.number().nullish(),
|
|
3325
|
-
start_index: import_v418.z.number().nullish(),
|
|
3326
|
-
end_index: import_v418.z.number().nullish(),
|
|
3327
|
-
quote: import_v418.z.string().nullish()
|
|
3328
|
-
}),
|
|
3329
|
-
import_v418.z.object({
|
|
3330
|
-
type: import_v418.z.literal("container_file_citation"),
|
|
3331
|
-
container_id: import_v418.z.string(),
|
|
3332
|
-
file_id: import_v418.z.string(),
|
|
3333
|
-
filename: import_v418.z.string().nullish(),
|
|
3334
|
-
start_index: import_v418.z.number().nullish(),
|
|
3335
|
-
end_index: import_v418.z.number().nullish(),
|
|
3336
|
-
index: import_v418.z.number().nullish()
|
|
3337
|
-
}),
|
|
3417
|
+
import_v418.z.discriminatedUnion("type", [
|
|
3418
|
+
import_v418.z.object({
|
|
3419
|
+
type: import_v418.z.literal("output_text"),
|
|
3420
|
+
text: import_v418.z.string(),
|
|
3421
|
+
logprobs: import_v418.z.array(
|
|
3338
3422
|
import_v418.z.object({
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3423
|
+
token: import_v418.z.string(),
|
|
3424
|
+
logprob: import_v418.z.number(),
|
|
3425
|
+
top_logprobs: import_v418.z.array(
|
|
3426
|
+
import_v418.z.object({
|
|
3427
|
+
token: import_v418.z.string(),
|
|
3428
|
+
logprob: import_v418.z.number()
|
|
3429
|
+
})
|
|
3430
|
+
)
|
|
3342
3431
|
})
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3432
|
+
).nullish(),
|
|
3433
|
+
annotations: import_v418.z.array(
|
|
3434
|
+
import_v418.z.discriminatedUnion("type", [
|
|
3435
|
+
import_v418.z.object({
|
|
3436
|
+
type: import_v418.z.literal("url_citation"),
|
|
3437
|
+
start_index: import_v418.z.number(),
|
|
3438
|
+
end_index: import_v418.z.number(),
|
|
3439
|
+
url: import_v418.z.string(),
|
|
3440
|
+
title: import_v418.z.string()
|
|
3441
|
+
}),
|
|
3442
|
+
import_v418.z.object({
|
|
3443
|
+
type: import_v418.z.literal("file_citation"),
|
|
3444
|
+
file_id: import_v418.z.string(),
|
|
3445
|
+
filename: import_v418.z.string().nullish(),
|
|
3446
|
+
index: import_v418.z.number().nullish(),
|
|
3447
|
+
start_index: import_v418.z.number().nullish(),
|
|
3448
|
+
end_index: import_v418.z.number().nullish(),
|
|
3449
|
+
quote: import_v418.z.string().nullish()
|
|
3450
|
+
}),
|
|
3451
|
+
import_v418.z.object({
|
|
3452
|
+
type: import_v418.z.literal("container_file_citation"),
|
|
3453
|
+
container_id: import_v418.z.string(),
|
|
3454
|
+
file_id: import_v418.z.string(),
|
|
3455
|
+
filename: import_v418.z.string().nullish(),
|
|
3456
|
+
start_index: import_v418.z.number().nullish(),
|
|
3457
|
+
end_index: import_v418.z.number().nullish(),
|
|
3458
|
+
index: import_v418.z.number().nullish()
|
|
3459
|
+
}),
|
|
3460
|
+
import_v418.z.object({
|
|
3461
|
+
type: import_v418.z.literal("file_path"),
|
|
3462
|
+
file_id: import_v418.z.string(),
|
|
3463
|
+
index: import_v418.z.number().nullish()
|
|
3464
|
+
})
|
|
3465
|
+
])
|
|
3466
|
+
)
|
|
3467
|
+
}),
|
|
3468
|
+
import_v418.z.object({
|
|
3469
|
+
type: import_v418.z.literal("refusal"),
|
|
3470
|
+
refusal: import_v418.z.string()
|
|
3471
|
+
})
|
|
3472
|
+
])
|
|
3346
3473
|
)
|
|
3347
3474
|
}),
|
|
3348
3475
|
import_v418.z.object({
|
|
@@ -4004,6 +4131,7 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
4004
4131
|
const content = [];
|
|
4005
4132
|
const logprobs = [];
|
|
4006
4133
|
let hasFunctionCall = false;
|
|
4134
|
+
let hasRefusal = false;
|
|
4007
4135
|
for (const part of response.output) {
|
|
4008
4136
|
switch (part.type) {
|
|
4009
4137
|
case "reasoning": {
|
|
@@ -4061,6 +4189,20 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
4061
4189
|
}
|
|
4062
4190
|
case "message": {
|
|
4063
4191
|
for (const contentPart of part.content) {
|
|
4192
|
+
if (contentPart.type === "refusal") {
|
|
4193
|
+
hasRefusal = true;
|
|
4194
|
+
content.push({
|
|
4195
|
+
type: "text",
|
|
4196
|
+
text: contentPart.refusal,
|
|
4197
|
+
providerMetadata: {
|
|
4198
|
+
[providerKey]: {
|
|
4199
|
+
itemId: part.id,
|
|
4200
|
+
...part.phase != null && { phase: part.phase }
|
|
4201
|
+
}
|
|
4202
|
+
}
|
|
4203
|
+
});
|
|
4204
|
+
continue;
|
|
4205
|
+
}
|
|
4064
4206
|
if (((_c = (_b = options.providerOptions) == null ? void 0 : _b.openai) == null ? void 0 : _c.logprobs) && contentPart.logprobs) {
|
|
4065
4207
|
logprobs.push(contentPart.logprobs);
|
|
4066
4208
|
}
|
|
@@ -4261,7 +4403,8 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
4261
4403
|
content,
|
|
4262
4404
|
finishReason: mapOpenAIResponseFinishReason({
|
|
4263
4405
|
finishReason: (_y = response.incomplete_details) == null ? void 0 : _y.reason,
|
|
4264
|
-
hasFunctionCall
|
|
4406
|
+
hasFunctionCall,
|
|
4407
|
+
hasRefusal
|
|
4265
4408
|
}),
|
|
4266
4409
|
usage: {
|
|
4267
4410
|
inputTokens: usage.input_tokens,
|
|
@@ -4320,6 +4463,7 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
4320
4463
|
const ongoingAnnotations = [];
|
|
4321
4464
|
let activeMessagePhase;
|
|
4322
4465
|
let hasFunctionCall = false;
|
|
4466
|
+
let hasRefusal = false;
|
|
4323
4467
|
const activeReasoning = {};
|
|
4324
4468
|
let serviceTier;
|
|
4325
4469
|
let reasoningContext;
|
|
@@ -4661,6 +4805,15 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
4661
4805
|
if (((_h = (_g = options.providerOptions) == null ? void 0 : _g.openai) == null ? void 0 : _h.logprobs) && value.logprobs) {
|
|
4662
4806
|
logprobs.push(value.logprobs);
|
|
4663
4807
|
}
|
|
4808
|
+
} else if (isRefusalDeltaChunk(value)) {
|
|
4809
|
+
hasRefusal = true;
|
|
4810
|
+
controller.enqueue({
|
|
4811
|
+
type: "text-delta",
|
|
4812
|
+
id: value.item_id,
|
|
4813
|
+
delta: value.delta
|
|
4814
|
+
});
|
|
4815
|
+
} else if (isRefusalDoneChunk(value)) {
|
|
4816
|
+
hasRefusal = true;
|
|
4664
4817
|
} else if (value.type === "response.reasoning_summary_part.added") {
|
|
4665
4818
|
if (value.summary_index > 0) {
|
|
4666
4819
|
const activeReasoningPart = activeReasoning[value.item_id];
|
|
@@ -4717,7 +4870,8 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
4717
4870
|
} else if (isResponseFinishedChunk(value)) {
|
|
4718
4871
|
finishReason = mapOpenAIResponseFinishReason({
|
|
4719
4872
|
finishReason: (_k = value.response.incomplete_details) == null ? void 0 : _k.reason,
|
|
4720
|
-
hasFunctionCall
|
|
4873
|
+
hasFunctionCall,
|
|
4874
|
+
hasRefusal
|
|
4721
4875
|
});
|
|
4722
4876
|
usage.inputTokens = value.response.usage.input_tokens;
|
|
4723
4877
|
usage.outputTokens = value.response.usage.output_tokens;
|
|
@@ -4794,6 +4948,12 @@ var OpenAIResponsesLanguageModel = class {
|
|
|
4794
4948
|
};
|
|
4795
4949
|
}
|
|
4796
4950
|
};
|
|
4951
|
+
function isRefusalDeltaChunk(chunk) {
|
|
4952
|
+
return chunk.type === "response.refusal.delta";
|
|
4953
|
+
}
|
|
4954
|
+
function isRefusalDoneChunk(chunk) {
|
|
4955
|
+
return chunk.type === "response.refusal.done";
|
|
4956
|
+
}
|
|
4797
4957
|
function isTextDeltaChunk(chunk) {
|
|
4798
4958
|
return chunk.type === "response.output_text.delta";
|
|
4799
4959
|
}
|
|
@@ -5045,6 +5205,16 @@ var openAITranscriptionProviderOptions = (0, import_provider_utils29.lazyValidat
|
|
|
5045
5205
|
* The language of the input audio in ISO-639-1 format.
|
|
5046
5206
|
*/
|
|
5047
5207
|
language: import_v421.z.string().optional(),
|
|
5208
|
+
/**
|
|
5209
|
+
* Expected languages for REST transcription, e.g. with gpt-transcribe.
|
|
5210
|
+
* Use this instead of language. The API validates model support.
|
|
5211
|
+
*/
|
|
5212
|
+
languages: import_v421.z.array(import_v421.z.string()).optional(),
|
|
5213
|
+
/**
|
|
5214
|
+
* Vocabulary hints for REST transcription, e.g. names or technical terms.
|
|
5215
|
+
* The API validates model support.
|
|
5216
|
+
*/
|
|
5217
|
+
keywords: import_v421.z.array(import_v421.z.string()).optional(),
|
|
5048
5218
|
/**
|
|
5049
5219
|
* An optional text to guide the model's style or continue a previous audio segment.
|
|
5050
5220
|
*/
|
|
@@ -5156,6 +5326,8 @@ var OpenAITranscriptionModel = class {
|
|
|
5156
5326
|
const transcriptionModelOptions = {
|
|
5157
5327
|
include: openAIOptions.include,
|
|
5158
5328
|
language: openAIOptions.language,
|
|
5329
|
+
languages: openAIOptions.languages,
|
|
5330
|
+
keywords: openAIOptions.keywords,
|
|
5159
5331
|
prompt: openAIOptions.prompt,
|
|
5160
5332
|
// https://platform.openai.com/docs/api-reference/audio/createTranscription#audio_createtranscription-response_format
|
|
5161
5333
|
// prefer verbose_json to get segments for models that support it
|
|
@@ -5232,7 +5404,7 @@ var OpenAITranscriptionModel = class {
|
|
|
5232
5404
|
};
|
|
5233
5405
|
|
|
5234
5406
|
// src/version.ts
|
|
5235
|
-
var VERSION = true ? "2.0.
|
|
5407
|
+
var VERSION = true ? "2.0.141" : "0.0.0-test";
|
|
5236
5408
|
|
|
5237
5409
|
// src/openai-provider.ts
|
|
5238
5410
|
function createOpenAI(options = {}) {
|