@ai-sdk/openai 2.0.140 → 2.0.142

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 CHANGED
@@ -1,5 +1,38 @@
1
1
  # @ai-sdk/openai
2
2
 
3
+ ## 2.0.142
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [c31e0a2]
8
+ - @ai-sdk/provider-utils@3.0.46
9
+
10
+ ## 2.0.141
11
+
12
+ ### Patch Changes
13
+
14
+ - 6b6433f: fix(openai): surface Chat Completions refusals as text content
15
+
16
+ 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.
17
+
18
+ - ce27f15: fix(openai,openai-compatible): surface refusal logprobs and openai-compatible refusals
19
+
20
+ `@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`.
21
+
22
+ 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.
23
+
24
+ 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`.
25
+
26
+ `@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.
27
+
28
+ - 0e51536: fix(openai): handle refusal content parts in the Responses API
29
+
30
+ 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.
31
+
32
+ - Updated dependencies [49c554d]
33
+ - Updated dependencies [b753c03]
34
+ - @ai-sdk/provider-utils@3.0.45
35
+
3
36
  ## 2.0.140
4
37
 
5
38
  ### 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
@@ -374,10 +374,13 @@ function getResponseMetadata({
374
374
  }
375
375
 
376
376
  // src/chat/map-openai-finish-reason.ts
377
- function mapOpenAIFinishReason(finishReason) {
377
+ function mapOpenAIFinishReason({
378
+ finishReason,
379
+ hasRefusal = false
380
+ }) {
378
381
  switch (finishReason) {
379
382
  case "stop":
380
- return "stop";
383
+ return hasRefusal ? "content-filter" : "stop";
381
384
  case "length":
382
385
  return "length";
383
386
  case "content_filter":
@@ -404,6 +407,8 @@ var openaiChatResponseSchema = (0, import_provider_utils3.lazyValidator)(
404
407
  message: import_v42.z.object({
405
408
  role: import_v42.z.literal("assistant").nullish(),
406
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(),
407
412
  audio: import_v42.z.object({
408
413
  transcript: import_v42.z.string().nullish()
409
414
  }).nullish(),
@@ -442,6 +447,20 @@ var openaiChatResponseSchema = (0, import_provider_utils3.lazyValidator)(
442
447
  })
443
448
  )
444
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
+ })
445
464
  ).nullish()
446
465
  }).nullish(),
447
466
  finish_reason: import_v42.z.string().nullish()
@@ -476,6 +495,8 @@ var openaiChatChunkSchema = (0, import_provider_utils3.lazyValidator)(
476
495
  delta: import_v42.z.object({
477
496
  role: import_v42.z.enum(["assistant"]).nullish(),
478
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(),
479
500
  tool_calls: import_v42.z.array(
480
501
  import_v42.z.object({
481
502
  index: import_v42.z.number(),
@@ -511,6 +532,20 @@ var openaiChatChunkSchema = (0, import_provider_utils3.lazyValidator)(
511
532
  })
512
533
  )
513
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
+ })
514
549
  ).nullish()
515
550
  }).nullish(),
516
551
  finish_reason: import_v42.z.string().nullish(),
@@ -942,7 +977,7 @@ var OpenAIChatLanguageModel = class {
942
977
  };
943
978
  }
944
979
  async doGenerate(options) {
945
- 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;
946
981
  const { args: body, warnings } = await this.getArgs(options);
947
982
  const {
948
983
  responseHeaders,
@@ -974,6 +1009,11 @@ var OpenAIChatLanguageModel = class {
974
1009
  if (text != null && text.length > 0) {
975
1010
  content.push({ type: "text", text });
976
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
+ }
977
1017
  for (const toolCall of (_b = choice.message.tool_calls) != null ? _b : []) {
978
1018
  content.push({
979
1019
  type: "tool-call",
@@ -1005,18 +1045,26 @@ var OpenAIChatLanguageModel = class {
1005
1045
  cacheWriteTokens: promptTokenDetails.cache_write_tokens
1006
1046
  };
1007
1047
  }
1008
- if (((_g = choice.logprobs) == null ? void 0 : _g.content) != null) {
1009
- providerMetadata.openai.logprobs = choice.logprobs.content;
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
+ ];
1010
1055
  }
1011
1056
  return {
1012
1057
  content,
1013
- finishReason: mapOpenAIFinishReason(choice.finish_reason),
1058
+ finishReason: mapOpenAIFinishReason({
1059
+ finishReason: choice.finish_reason,
1060
+ hasRefusal
1061
+ }),
1014
1062
  usage: {
1015
- inputTokens: (_i = (_h = response.usage) == null ? void 0 : _h.prompt_tokens) != null ? _i : void 0,
1016
- outputTokens: (_k = (_j = response.usage) == null ? void 0 : _j.completion_tokens) != null ? _k : void 0,
1017
- totalTokens: (_m = (_l = response.usage) == null ? void 0 : _l.total_tokens) != null ? _m : void 0,
1018
- reasoningTokens: (_n = completionTokenDetails == null ? void 0 : completionTokenDetails.reasoning_tokens) != null ? _n : void 0,
1019
- cachedInputTokens: (_o = promptTokenDetails == null ? void 0 : promptTokenDetails.cached_tokens) != null ? _o : void 0
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
1020
1068
  },
1021
1069
  request: { body },
1022
1070
  response: {
@@ -1060,6 +1108,10 @@ var OpenAIChatLanguageModel = class {
1060
1108
  };
1061
1109
  let metadataExtracted = false;
1062
1110
  let isActiveText = false;
1111
+ let hasRefusal = false;
1112
+ let rawFinishReason = void 0;
1113
+ let hasLogprobs = false;
1114
+ const streamedLogprobs = [];
1063
1115
  const providerMetadata = { openai: {} };
1064
1116
  return {
1065
1117
  stream: response.pipeThrough(
@@ -1072,18 +1124,20 @@ var OpenAIChatLanguageModel = class {
1072
1124
  controller.enqueue({ type: "stream-start", warnings });
1073
1125
  },
1074
1126
  transform(chunk, controller) {
1075
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
1127
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1076
1128
  if (options.includeRawChunks) {
1077
1129
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
1078
1130
  }
1079
1131
  if (!chunk.success) {
1080
1132
  finishReason = "error";
1133
+ rawFinishReason = void 0;
1081
1134
  controller.enqueue({ type: "error", error: chunk.error });
1082
1135
  return;
1083
1136
  }
1084
1137
  const value = chunk.value;
1085
1138
  if ("error" in value) {
1086
1139
  finishReason = "error";
1140
+ rawFinishReason = void 0;
1087
1141
  controller.enqueue({ type: "error", error: value.error });
1088
1142
  return;
1089
1143
  }
@@ -1117,16 +1171,35 @@ var OpenAIChatLanguageModel = class {
1117
1171
  }
1118
1172
  const choice = value.choices[0];
1119
1173
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
1120
- finishReason = mapOpenAIFinishReason(choice.finish_reason);
1174
+ rawFinishReason = choice.finish_reason;
1121
1175
  }
1122
- if (((_m = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _m.content) != null) {
1123
- providerMetadata.openai.logprobs = choice.logprobs.content;
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
+ }
1124
1186
  }
1125
1187
  if ((choice == null ? void 0 : choice.delta) == null) {
1126
1188
  return;
1127
1189
  }
1128
1190
  const delta = choice.delta;
1129
- if (delta.content != null) {
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) {
1130
1203
  if (!isActiveText) {
1131
1204
  controller.enqueue({ type: "text-start", id: "0" });
1132
1205
  isActiveText = true;
@@ -1134,7 +1207,7 @@ var OpenAIChatLanguageModel = class {
1134
1207
  controller.enqueue({
1135
1208
  type: "text-delta",
1136
1209
  id: "0",
1137
- delta: delta.content
1210
+ delta: textDelta
1138
1211
  });
1139
1212
  }
1140
1213
  if (delta.tool_calls != null) {
@@ -1159,6 +1232,15 @@ var OpenAIChatLanguageModel = class {
1159
1232
  controller.enqueue({ type: "text-end", id: "0" });
1160
1233
  }
1161
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
+ }
1162
1244
  controller.enqueue({
1163
1245
  type: "finish",
1164
1246
  finishReason,
@@ -2990,12 +3072,14 @@ function serializeToolCallArguments2(input) {
2990
3072
  // src/responses/map-openai-responses-finish-reason.ts
2991
3073
  function mapOpenAIResponseFinishReason({
2992
3074
  finishReason,
2993
- hasFunctionCall
3075
+ hasFunctionCall,
3076
+ hasRefusal = false
2994
3077
  }) {
2995
3078
  switch (finishReason) {
2996
3079
  case void 0:
2997
3080
  case null:
2998
- return hasFunctionCall ? "tool-calls" : "stop";
3081
+ if (hasFunctionCall) return "tool-calls";
3082
+ return hasRefusal ? "content-filter" : "stop";
2999
3083
  case "max_output_tokens":
3000
3084
  return "length";
3001
3085
  case "content_filter":
@@ -3028,6 +3112,20 @@ var openaiResponsesChunkSchema = (0, import_provider_utils23.lazyValidator)(
3028
3112
  })
3029
3113
  ).nullish()
3030
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
+ }),
3031
3129
  import_v418.z.object({
3032
3130
  type: import_v418.z.enum(["response.completed", "response.incomplete"]),
3033
3131
  response: import_v418.z.object({
@@ -3314,57 +3412,64 @@ var openaiResponsesResponseSchema = (0, import_provider_utils23.lazyValidator)(
3314
3412
  role: import_v418.z.literal("assistant"),
3315
3413
  id: import_v418.z.string(),
3316
3414
  phase: import_v418.z.enum(["commentary", "final_answer"]).nullish(),
3415
+ // the API returns either text or a refusal as content parts:
3317
3416
  content: import_v418.z.array(
3318
- import_v418.z.object({
3319
- type: import_v418.z.literal("output_text"),
3320
- text: import_v418.z.string(),
3321
- logprobs: import_v418.z.array(
3322
- import_v418.z.object({
3323
- token: import_v418.z.string(),
3324
- logprob: import_v418.z.number(),
3325
- top_logprobs: import_v418.z.array(
3326
- import_v418.z.object({
3327
- token: import_v418.z.string(),
3328
- logprob: import_v418.z.number()
3329
- })
3330
- )
3331
- })
3332
- ).nullish(),
3333
- annotations: import_v418.z.array(
3334
- import_v418.z.discriminatedUnion("type", [
3335
- import_v418.z.object({
3336
- type: import_v418.z.literal("url_citation"),
3337
- start_index: import_v418.z.number(),
3338
- end_index: import_v418.z.number(),
3339
- url: import_v418.z.string(),
3340
- title: import_v418.z.string()
3341
- }),
3342
- import_v418.z.object({
3343
- type: import_v418.z.literal("file_citation"),
3344
- file_id: import_v418.z.string(),
3345
- filename: import_v418.z.string().nullish(),
3346
- index: import_v418.z.number().nullish(),
3347
- start_index: import_v418.z.number().nullish(),
3348
- end_index: import_v418.z.number().nullish(),
3349
- quote: import_v418.z.string().nullish()
3350
- }),
3351
- import_v418.z.object({
3352
- type: import_v418.z.literal("container_file_citation"),
3353
- container_id: import_v418.z.string(),
3354
- file_id: import_v418.z.string(),
3355
- filename: import_v418.z.string().nullish(),
3356
- start_index: import_v418.z.number().nullish(),
3357
- end_index: import_v418.z.number().nullish(),
3358
- index: import_v418.z.number().nullish()
3359
- }),
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(
3360
3422
  import_v418.z.object({
3361
- type: import_v418.z.literal("file_path"),
3362
- file_id: import_v418.z.string(),
3363
- index: import_v418.z.number().nullish()
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
+ )
3364
3431
  })
3365
- ])
3366
- )
3367
- })
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
+ ])
3368
3473
  )
3369
3474
  }),
3370
3475
  import_v418.z.object({
@@ -4026,6 +4131,7 @@ var OpenAIResponsesLanguageModel = class {
4026
4131
  const content = [];
4027
4132
  const logprobs = [];
4028
4133
  let hasFunctionCall = false;
4134
+ let hasRefusal = false;
4029
4135
  for (const part of response.output) {
4030
4136
  switch (part.type) {
4031
4137
  case "reasoning": {
@@ -4083,6 +4189,20 @@ var OpenAIResponsesLanguageModel = class {
4083
4189
  }
4084
4190
  case "message": {
4085
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
+ }
4086
4206
  if (((_c = (_b = options.providerOptions) == null ? void 0 : _b.openai) == null ? void 0 : _c.logprobs) && contentPart.logprobs) {
4087
4207
  logprobs.push(contentPart.logprobs);
4088
4208
  }
@@ -4283,7 +4403,8 @@ var OpenAIResponsesLanguageModel = class {
4283
4403
  content,
4284
4404
  finishReason: mapOpenAIResponseFinishReason({
4285
4405
  finishReason: (_y = response.incomplete_details) == null ? void 0 : _y.reason,
4286
- hasFunctionCall
4406
+ hasFunctionCall,
4407
+ hasRefusal
4287
4408
  }),
4288
4409
  usage: {
4289
4410
  inputTokens: usage.input_tokens,
@@ -4342,6 +4463,7 @@ var OpenAIResponsesLanguageModel = class {
4342
4463
  const ongoingAnnotations = [];
4343
4464
  let activeMessagePhase;
4344
4465
  let hasFunctionCall = false;
4466
+ let hasRefusal = false;
4345
4467
  const activeReasoning = {};
4346
4468
  let serviceTier;
4347
4469
  let reasoningContext;
@@ -4683,6 +4805,15 @@ var OpenAIResponsesLanguageModel = class {
4683
4805
  if (((_h = (_g = options.providerOptions) == null ? void 0 : _g.openai) == null ? void 0 : _h.logprobs) && value.logprobs) {
4684
4806
  logprobs.push(value.logprobs);
4685
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;
4686
4817
  } else if (value.type === "response.reasoning_summary_part.added") {
4687
4818
  if (value.summary_index > 0) {
4688
4819
  const activeReasoningPart = activeReasoning[value.item_id];
@@ -4739,7 +4870,8 @@ var OpenAIResponsesLanguageModel = class {
4739
4870
  } else if (isResponseFinishedChunk(value)) {
4740
4871
  finishReason = mapOpenAIResponseFinishReason({
4741
4872
  finishReason: (_k = value.response.incomplete_details) == null ? void 0 : _k.reason,
4742
- hasFunctionCall
4873
+ hasFunctionCall,
4874
+ hasRefusal
4743
4875
  });
4744
4876
  usage.inputTokens = value.response.usage.input_tokens;
4745
4877
  usage.outputTokens = value.response.usage.output_tokens;
@@ -4816,6 +4948,12 @@ var OpenAIResponsesLanguageModel = class {
4816
4948
  };
4817
4949
  }
4818
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
+ }
4819
4957
  function isTextDeltaChunk(chunk) {
4820
4958
  return chunk.type === "response.output_text.delta";
4821
4959
  }
@@ -5266,7 +5404,7 @@ var OpenAITranscriptionModel = class {
5266
5404
  };
5267
5405
 
5268
5406
  // src/version.ts
5269
- var VERSION = true ? "2.0.140" : "0.0.0-test";
5407
+ var VERSION = true ? "2.0.142" : "0.0.0-test";
5270
5408
 
5271
5409
  // src/openai-provider.ts
5272
5410
  function createOpenAI(options = {}) {