@ai-sdk/openai 3.0.137 → 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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @ai-sdk/openai
2
2
 
3
+ ## 3.0.138
4
+
5
+ ### Patch Changes
6
+
7
+ - c6d995a: 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
+ - 98eb47b: 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
+ - c21fadf: 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
+
3
25
  ## 3.0.137
4
26
 
5
27
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -241,6 +241,18 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazySchema<{
241
241
  logprob: number;
242
242
  }[];
243
243
  }[] | null | undefined;
244
+ } | {
245
+ type: "response.refusal.delta";
246
+ item_id: string;
247
+ delta: string;
248
+ output_index?: number | null | undefined;
249
+ content_index?: number | null | undefined;
250
+ } | {
251
+ type: "response.refusal.done";
252
+ item_id: string;
253
+ refusal: string;
254
+ output_index?: number | null | undefined;
255
+ content_index?: number | null | undefined;
244
256
  } | {
245
257
  type: "response.completed" | "response.incomplete";
246
258
  response: {
package/dist/index.d.ts CHANGED
@@ -241,6 +241,18 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazySchema<{
241
241
  logprob: number;
242
242
  }[];
243
243
  }[] | null | undefined;
244
+ } | {
245
+ type: "response.refusal.delta";
246
+ item_id: string;
247
+ delta: string;
248
+ output_index?: number | null | undefined;
249
+ content_index?: number | null | undefined;
250
+ } | {
251
+ type: "response.refusal.done";
252
+ item_id: string;
253
+ refusal: string;
254
+ output_index?: number | null | undefined;
255
+ content_index?: number | null | undefined;
244
256
  } | {
245
257
  type: "response.completed" | "response.incomplete";
246
258
  response: {
package/dist/index.js CHANGED
@@ -658,10 +658,13 @@ function getResponseMetadata({
658
658
  }
659
659
 
660
660
  // src/chat/map-openai-finish-reason.ts
661
- function mapOpenAIFinishReason(finishReason) {
661
+ function mapOpenAIFinishReason({
662
+ finishReason,
663
+ hasRefusal = false
664
+ }) {
662
665
  switch (finishReason) {
663
666
  case "stop":
664
- return "stop";
667
+ return hasRefusal ? "content-filter" : "stop";
665
668
  case "length":
666
669
  return "length";
667
670
  case "content_filter":
@@ -688,6 +691,8 @@ var openaiChatResponseSchema = (0, import_provider_utils3.lazySchema)(
688
691
  message: import_v42.z.object({
689
692
  role: import_v42.z.literal("assistant").nullish(),
690
693
  content: import_v42.z.string().nullish(),
694
+ // set instead of `content` when the model refuses to answer:
695
+ refusal: import_v42.z.string().nullish(),
691
696
  audio: import_v42.z.object({
692
697
  transcript: import_v42.z.string().nullish()
693
698
  }).nullish(),
@@ -726,6 +731,20 @@ var openaiChatResponseSchema = (0, import_provider_utils3.lazySchema)(
726
731
  })
727
732
  )
728
733
  })
734
+ ).nullish(),
735
+ // logprobs of the refusal tokens (set instead of `content` when
736
+ // the model refuses to answer):
737
+ refusal: import_v42.z.array(
738
+ import_v42.z.object({
739
+ token: import_v42.z.string(),
740
+ logprob: import_v42.z.number(),
741
+ top_logprobs: import_v42.z.array(
742
+ import_v42.z.object({
743
+ token: import_v42.z.string(),
744
+ logprob: import_v42.z.number()
745
+ })
746
+ )
747
+ })
729
748
  ).nullish()
730
749
  }).nullish(),
731
750
  finish_reason: import_v42.z.string().nullish()
@@ -760,6 +779,8 @@ var openaiChatChunkSchema = (0, import_provider_utils3.lazySchema)(
760
779
  delta: import_v42.z.object({
761
780
  role: import_v42.z.enum(["assistant"]).nullish(),
762
781
  content: import_v42.z.string().nullish(),
782
+ // set instead of `content` when the model refuses to answer:
783
+ refusal: import_v42.z.string().nullish(),
763
784
  tool_calls: import_v42.z.array(
764
785
  import_v42.z.object({
765
786
  index: import_v42.z.number(),
@@ -795,6 +816,20 @@ var openaiChatChunkSchema = (0, import_provider_utils3.lazySchema)(
795
816
  })
796
817
  )
797
818
  })
819
+ ).nullish(),
820
+ // logprobs of the refusal tokens (set instead of `content` when
821
+ // the model refuses to answer):
822
+ refusal: import_v42.z.array(
823
+ import_v42.z.object({
824
+ token: import_v42.z.string(),
825
+ logprob: import_v42.z.number(),
826
+ top_logprobs: import_v42.z.array(
827
+ import_v42.z.object({
828
+ token: import_v42.z.string(),
829
+ logprob: import_v42.z.number()
830
+ })
831
+ )
832
+ })
798
833
  ).nullish()
799
834
  }).nullish(),
800
835
  finish_reason: import_v42.z.string().nullish(),
@@ -1231,7 +1266,7 @@ var OpenAIChatLanguageModel = class {
1231
1266
  };
1232
1267
  }
1233
1268
  async doGenerate(options) {
1234
- var _a2, _b, _c, _d, _e, _f, _g, _h;
1269
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
1235
1270
  const { args: body, warnings } = await this.getArgs(options);
1236
1271
  const {
1237
1272
  responseHeaders,
@@ -1263,6 +1298,11 @@ var OpenAIChatLanguageModel = class {
1263
1298
  if (text != null && text.length > 0) {
1264
1299
  content.push({ type: "text", text });
1265
1300
  }
1301
+ const refusal = choice.message.refusal;
1302
+ const hasRefusal = refusal != null && refusal.length > 0;
1303
+ if (hasRefusal) {
1304
+ content.push({ type: "text", text: refusal });
1305
+ }
1266
1306
  for (const toolCall of (_b = choice.message.tool_calls) != null ? _b : []) {
1267
1307
  content.push({
1268
1308
  type: "tool-call",
@@ -1289,14 +1329,22 @@ var OpenAIChatLanguageModel = class {
1289
1329
  if ((completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens) != null) {
1290
1330
  providerMetadata.openai.rejectedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens;
1291
1331
  }
1292
- if (((_g = choice.logprobs) == null ? void 0 : _g.content) != null) {
1293
- providerMetadata.openai.logprobs = choice.logprobs.content;
1332
+ const contentLogprobs = (_g = choice.logprobs) == null ? void 0 : _g.content;
1333
+ const refusalLogprobs = (_h = choice.logprobs) == null ? void 0 : _h.refusal;
1334
+ if (contentLogprobs != null || refusalLogprobs != null) {
1335
+ providerMetadata.openai.logprobs = [
1336
+ ...contentLogprobs != null ? contentLogprobs : [],
1337
+ ...refusalLogprobs != null ? refusalLogprobs : []
1338
+ ];
1294
1339
  }
1295
1340
  return {
1296
1341
  content,
1297
1342
  finishReason: {
1298
- unified: mapOpenAIFinishReason(choice.finish_reason),
1299
- raw: (_h = choice.finish_reason) != null ? _h : void 0
1343
+ unified: mapOpenAIFinishReason({
1344
+ finishReason: choice.finish_reason,
1345
+ hasRefusal
1346
+ }),
1347
+ raw: (_i = choice.finish_reason) != null ? _i : void 0
1300
1348
  },
1301
1349
  usage: convertOpenAIChatUsage(response.usage),
1302
1350
  request: { body },
@@ -1349,6 +1397,10 @@ var OpenAIChatLanguageModel = class {
1349
1397
  let usage = void 0;
1350
1398
  let metadataExtracted = false;
1351
1399
  let isActiveText = false;
1400
+ let hasRefusal = false;
1401
+ let rawFinishReason = void 0;
1402
+ let hasLogprobs = false;
1403
+ const streamedLogprobs = [];
1352
1404
  const providerMetadata = { openai: {} };
1353
1405
  const result = {
1354
1406
  stream: checkedResponse.pipeThrough(
@@ -1361,18 +1413,20 @@ var OpenAIChatLanguageModel = class {
1361
1413
  controller.enqueue({ type: "stream-start", warnings });
1362
1414
  },
1363
1415
  transform(chunk, controller) {
1364
- var _a2, _b, _c, _d, _e;
1416
+ var _a2, _b, _c, _d;
1365
1417
  if (options.includeRawChunks) {
1366
1418
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
1367
1419
  }
1368
1420
  if (!chunk.success) {
1369
1421
  finishReason = { unified: "error", raw: void 0 };
1422
+ rawFinishReason = void 0;
1370
1423
  controller.enqueue({ type: "error", error: chunk.error });
1371
1424
  return;
1372
1425
  }
1373
1426
  const value = chunk.value;
1374
1427
  if ("error" in value) {
1375
1428
  finishReason = { unified: "error", raw: void 0 };
1429
+ rawFinishReason = void 0;
1376
1430
  controller.enqueue({ type: "error", error: value.error });
1377
1431
  return;
1378
1432
  }
@@ -1397,19 +1451,35 @@ var OpenAIChatLanguageModel = class {
1397
1451
  }
1398
1452
  const choice = value.choices[0];
1399
1453
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
1400
- finishReason = {
1401
- unified: mapOpenAIFinishReason(choice.finish_reason),
1402
- raw: choice.finish_reason
1403
- };
1454
+ rawFinishReason = choice.finish_reason;
1404
1455
  }
1405
- if (((_e = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _e.content) != null) {
1406
- providerMetadata.openai.logprobs = choice.logprobs.content;
1456
+ if ((choice == null ? void 0 : choice.logprobs) != null) {
1457
+ const contentLogprobs = choice.logprobs.content;
1458
+ const refusalLogprobs = choice.logprobs.refusal;
1459
+ if (contentLogprobs != null || refusalLogprobs != null) {
1460
+ hasLogprobs = true;
1461
+ streamedLogprobs.push(
1462
+ ...contentLogprobs != null ? contentLogprobs : [],
1463
+ ...refusalLogprobs != null ? refusalLogprobs : []
1464
+ );
1465
+ }
1407
1466
  }
1408
1467
  if ((choice == null ? void 0 : choice.delta) == null) {
1409
1468
  return;
1410
1469
  }
1411
1470
  const delta = choice.delta;
1412
- if (delta.content != null) {
1471
+ const textDeltas = [];
1472
+ if (delta.content != null && delta.content.length > 0) {
1473
+ textDeltas.push(delta.content);
1474
+ }
1475
+ if (delta.refusal != null && delta.refusal.length > 0) {
1476
+ hasRefusal = true;
1477
+ textDeltas.push(delta.refusal);
1478
+ }
1479
+ if (textDeltas.length === 0 && delta.content === "") {
1480
+ textDeltas.push(delta.content);
1481
+ }
1482
+ for (const textDelta of textDeltas) {
1413
1483
  if (!isActiveText) {
1414
1484
  controller.enqueue({ type: "text-start", id: "0" });
1415
1485
  isActiveText = true;
@@ -1417,7 +1487,7 @@ var OpenAIChatLanguageModel = class {
1417
1487
  controller.enqueue({
1418
1488
  type: "text-delta",
1419
1489
  id: "0",
1420
- delta: delta.content
1490
+ delta: textDelta
1421
1491
  });
1422
1492
  }
1423
1493
  if (delta.tool_calls != null) {
@@ -1442,6 +1512,18 @@ var OpenAIChatLanguageModel = class {
1442
1512
  controller.enqueue({ type: "text-end", id: "0" });
1443
1513
  }
1444
1514
  toolCallTracker.flush();
1515
+ if (rawFinishReason != null) {
1516
+ finishReason = {
1517
+ unified: mapOpenAIFinishReason({
1518
+ finishReason: rawFinishReason,
1519
+ hasRefusal
1520
+ }),
1521
+ raw: rawFinishReason
1522
+ };
1523
+ }
1524
+ if (hasLogprobs) {
1525
+ providerMetadata.openai.logprobs = streamedLogprobs;
1526
+ }
1445
1527
  controller.enqueue({
1446
1528
  type: "finish",
1447
1529
  finishReason,
@@ -1463,7 +1545,7 @@ function isOpenAIChatOutputChunk(chunk) {
1463
1545
  }
1464
1546
  return chunk.choices.some((choice) => {
1465
1547
  const delta = choice.delta;
1466
- return (delta == null ? void 0 : delta.content) != null && delta.content.length > 0 || (delta == null ? void 0 : delta.tool_calls) != null && delta.tool_calls.length > 0 || (delta == null ? void 0 : delta.annotations) != null && delta.annotations.length > 0;
1548
+ return (delta == null ? void 0 : delta.content) != null && delta.content.length > 0 || (delta == null ? void 0 : delta.refusal) != null && delta.refusal.length > 0 || (delta == null ? void 0 : delta.tool_calls) != null && delta.tool_calls.length > 0 || (delta == null ? void 0 : delta.annotations) != null && delta.annotations.length > 0;
1467
1549
  });
1468
1550
  }
1469
1551
 
@@ -4593,12 +4675,14 @@ var openaiResponsesReasoningProviderOptionsSchema = (0, import_provider_utils28.
4593
4675
  // src/responses/map-openai-responses-finish-reason.ts
4594
4676
  function mapOpenAIResponseFinishReason({
4595
4677
  finishReason,
4596
- hasFunctionCall
4678
+ hasFunctionCall,
4679
+ hasRefusal = false
4597
4680
  }) {
4598
4681
  switch (finishReason) {
4599
4682
  case void 0:
4600
4683
  case null:
4601
- return hasFunctionCall ? "tool-calls" : "stop";
4684
+ if (hasFunctionCall) return "tool-calls";
4685
+ return hasRefusal ? "content-filter" : "stop";
4602
4686
  case "max_output_tokens":
4603
4687
  return "length";
4604
4688
  case "content_filter":
@@ -4705,6 +4789,8 @@ var openaiResponsesModeledChunkTypes = /* @__PURE__ */ new Set([
4705
4789
  "response.output_item.done",
4706
4790
  "response.output_text.annotation.added",
4707
4791
  "response.output_text.delta",
4792
+ "response.refusal.delta",
4793
+ "response.refusal.done",
4708
4794
  "response.reasoning_summary_part.added",
4709
4795
  "response.reasoning_summary_part.done",
4710
4796
  "response.reasoning_summary_text.delta"
@@ -4761,6 +4847,20 @@ var openaiResponsesChunkSchema = (0, import_provider_utils29.lazySchema)(
4761
4847
  })
4762
4848
  ).nullish()
4763
4849
  }),
4850
+ import_v423.z.object({
4851
+ type: import_v423.z.literal("response.refusal.delta"),
4852
+ item_id: import_v423.z.string(),
4853
+ output_index: import_v423.z.number().nullish(),
4854
+ content_index: import_v423.z.number().nullish(),
4855
+ delta: import_v423.z.string()
4856
+ }),
4857
+ import_v423.z.object({
4858
+ type: import_v423.z.literal("response.refusal.done"),
4859
+ item_id: import_v423.z.string(),
4860
+ output_index: import_v423.z.number().nullish(),
4861
+ content_index: import_v423.z.number().nullish(),
4862
+ refusal: import_v423.z.string()
4863
+ }),
4764
4864
  import_v423.z.object({
4765
4865
  type: import_v423.z.enum(["response.completed", "response.incomplete"]),
4766
4866
  response: import_v423.z.object({
@@ -5286,53 +5386,60 @@ var openaiResponsesResponseSchema = (0, import_provider_utils29.lazySchema)(
5286
5386
  role: import_v423.z.literal("assistant"),
5287
5387
  id: import_v423.z.string(),
5288
5388
  phase: import_v423.z.enum(["commentary", "final_answer"]).nullish(),
5389
+ // the API returns either text or a refusal as content parts:
5289
5390
  content: import_v423.z.array(
5290
- import_v423.z.object({
5291
- type: import_v423.z.literal("output_text"),
5292
- text: import_v423.z.string(),
5293
- logprobs: import_v423.z.array(
5294
- import_v423.z.object({
5295
- token: import_v423.z.string(),
5296
- logprob: import_v423.z.number(),
5297
- top_logprobs: import_v423.z.array(
5298
- import_v423.z.object({
5299
- token: import_v423.z.string(),
5300
- logprob: import_v423.z.number()
5301
- })
5302
- )
5303
- })
5304
- ).nullish(),
5305
- annotations: import_v423.z.array(
5306
- import_v423.z.discriminatedUnion("type", [
5307
- import_v423.z.object({
5308
- type: import_v423.z.literal("url_citation"),
5309
- start_index: import_v423.z.number(),
5310
- end_index: import_v423.z.number(),
5311
- url: import_v423.z.string(),
5312
- title: import_v423.z.string()
5313
- }),
5314
- import_v423.z.object({
5315
- type: import_v423.z.literal("file_citation"),
5316
- file_id: import_v423.z.string(),
5317
- filename: import_v423.z.string(),
5318
- index: import_v423.z.number()
5319
- }),
5320
- import_v423.z.object({
5321
- type: import_v423.z.literal("container_file_citation"),
5322
- container_id: import_v423.z.string(),
5323
- file_id: import_v423.z.string(),
5324
- filename: import_v423.z.string(),
5325
- start_index: import_v423.z.number(),
5326
- end_index: import_v423.z.number()
5327
- }),
5391
+ import_v423.z.discriminatedUnion("type", [
5392
+ import_v423.z.object({
5393
+ type: import_v423.z.literal("output_text"),
5394
+ text: import_v423.z.string(),
5395
+ logprobs: import_v423.z.array(
5328
5396
  import_v423.z.object({
5329
- type: import_v423.z.literal("file_path"),
5330
- file_id: import_v423.z.string(),
5331
- index: import_v423.z.number()
5397
+ token: import_v423.z.string(),
5398
+ logprob: import_v423.z.number(),
5399
+ top_logprobs: import_v423.z.array(
5400
+ import_v423.z.object({
5401
+ token: import_v423.z.string(),
5402
+ logprob: import_v423.z.number()
5403
+ })
5404
+ )
5332
5405
  })
5333
- ])
5334
- )
5335
- })
5406
+ ).nullish(),
5407
+ annotations: import_v423.z.array(
5408
+ import_v423.z.discriminatedUnion("type", [
5409
+ import_v423.z.object({
5410
+ type: import_v423.z.literal("url_citation"),
5411
+ start_index: import_v423.z.number(),
5412
+ end_index: import_v423.z.number(),
5413
+ url: import_v423.z.string(),
5414
+ title: import_v423.z.string()
5415
+ }),
5416
+ import_v423.z.object({
5417
+ type: import_v423.z.literal("file_citation"),
5418
+ file_id: import_v423.z.string(),
5419
+ filename: import_v423.z.string(),
5420
+ index: import_v423.z.number()
5421
+ }),
5422
+ import_v423.z.object({
5423
+ type: import_v423.z.literal("container_file_citation"),
5424
+ container_id: import_v423.z.string(),
5425
+ file_id: import_v423.z.string(),
5426
+ filename: import_v423.z.string(),
5427
+ start_index: import_v423.z.number(),
5428
+ end_index: import_v423.z.number()
5429
+ }),
5430
+ import_v423.z.object({
5431
+ type: import_v423.z.literal("file_path"),
5432
+ file_id: import_v423.z.string(),
5433
+ index: import_v423.z.number()
5434
+ })
5435
+ ])
5436
+ )
5437
+ }),
5438
+ import_v423.z.object({
5439
+ type: import_v423.z.literal("refusal"),
5440
+ refusal: import_v423.z.string()
5441
+ })
5442
+ ])
5336
5443
  )
5337
5444
  }),
5338
5445
  import_v423.z.object({
@@ -6467,6 +6574,7 @@ var OpenAIResponsesLanguageModel = class {
6467
6574
  )) != null ? _b : [];
6468
6575
  let hasFunctionCall = false;
6469
6576
  const hostedToolSearchCallIds = [];
6577
+ let hasRefusal = false;
6470
6578
  for (const part of response.output) {
6471
6579
  switch (part.type) {
6472
6580
  case "reasoning": {
@@ -6600,6 +6708,20 @@ var OpenAIResponsesLanguageModel = class {
6600
6708
  }
6601
6709
  case "message": {
6602
6710
  for (const contentPart of part.content) {
6711
+ if (contentPart.type === "refusal") {
6712
+ hasRefusal = true;
6713
+ content.push({
6714
+ type: "text",
6715
+ text: contentPart.refusal,
6716
+ providerMetadata: {
6717
+ [providerOptionsName]: {
6718
+ itemId: part.id,
6719
+ ...part.phase != null && { phase: part.phase }
6720
+ }
6721
+ }
6722
+ });
6723
+ continue;
6724
+ }
6603
6725
  if (((_h = (_g = options.providerOptions) == null ? void 0 : _g[providerOptionsName]) == null ? void 0 : _h.logprobs) && contentPart.logprobs) {
6604
6726
  logprobs.push(contentPart.logprobs);
6605
6727
  }
@@ -6899,7 +7021,8 @@ var OpenAIResponsesLanguageModel = class {
6899
7021
  finishReason: {
6900
7022
  unified: mapOpenAIResponseFinishReason({
6901
7023
  finishReason: (_C = response.incomplete_details) == null ? void 0 : _C.reason,
6902
- hasFunctionCall
7024
+ hasFunctionCall,
7025
+ hasRefusal
6903
7026
  }),
6904
7027
  raw: (_E = (_D = response.incomplete_details) == null ? void 0 : _D.reason) != null ? _E : void 0
6905
7028
  },
@@ -6970,6 +7093,7 @@ var OpenAIResponsesLanguageModel = class {
6970
7093
  const ongoingAnnotations = [];
6971
7094
  let activeMessagePhase;
6972
7095
  let hasFunctionCall = false;
7096
+ let hasRefusal = false;
6973
7097
  const activeReasoning = {};
6974
7098
  let serviceTier;
6975
7099
  let reasoningContext;
@@ -7743,6 +7867,15 @@ var OpenAIResponsesLanguageModel = class {
7743
7867
  if (((_u = (_t = options.providerOptions) == null ? void 0 : _t[providerOptionsName]) == null ? void 0 : _u.logprobs) && value.logprobs) {
7744
7868
  logprobs.push(value.logprobs);
7745
7869
  }
7870
+ } else if (isRefusalDeltaChunk(value)) {
7871
+ hasRefusal = true;
7872
+ controller.enqueue({
7873
+ type: "text-delta",
7874
+ id: value.item_id,
7875
+ delta: value.delta
7876
+ });
7877
+ } else if (isRefusalDoneChunk(value)) {
7878
+ hasRefusal = true;
7746
7879
  } else if (value.type === "response.reasoning_summary_part.added") {
7747
7880
  if (value.summary_index > 0) {
7748
7881
  const activeReasoningPart = activeReasoning[value.item_id];
@@ -7805,7 +7938,8 @@ var OpenAIResponsesLanguageModel = class {
7805
7938
  finishReason = {
7806
7939
  unified: mapOpenAIResponseFinishReason({
7807
7940
  finishReason: (_x = value.response.incomplete_details) == null ? void 0 : _x.reason,
7808
- hasFunctionCall
7941
+ hasFunctionCall,
7942
+ hasRefusal
7809
7943
  }),
7810
7944
  raw: (_z = (_y = value.response.incomplete_details) == null ? void 0 : _y.reason) != null ? _z : void 0
7811
7945
  };
@@ -7959,6 +8093,12 @@ var OpenAIResponsesLanguageModel = class {
7959
8093
  function isTextDeltaChunk(chunk) {
7960
8094
  return chunk.type === "response.output_text.delta";
7961
8095
  }
8096
+ function isRefusalDeltaChunk(chunk) {
8097
+ return chunk.type === "response.refusal.delta";
8098
+ }
8099
+ function isRefusalDoneChunk(chunk) {
8100
+ return chunk.type === "response.refusal.done";
8101
+ }
7962
8102
  function isOpenAIChatCompletionChunk(value) {
7963
8103
  const chunk = asRecord2(value);
7964
8104
  return chunk != null && Array.isArray(chunk.choices) && typeof chunk.type !== "string";
@@ -8438,7 +8578,7 @@ var OpenAITranscriptionModel = class {
8438
8578
  };
8439
8579
 
8440
8580
  // src/version.ts
8441
- var VERSION = true ? "3.0.137" : "0.0.0-test";
8581
+ var VERSION = true ? "3.0.138" : "0.0.0-test";
8442
8582
 
8443
8583
  // src/openai-provider.ts
8444
8584
  function createOpenAI(options = {}) {