@ai-sdk/openai 3.0.33 → 3.0.35

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,28 @@
1
1
  # @ai-sdk/openai
2
2
 
3
+ ## 3.0.35
4
+
5
+ ### Patch Changes
6
+
7
+ - 5e18272: fix(openai): include reasoning parts without itemId when encrypted_content is present
8
+
9
+ When `providerOptions.openai.itemId` is absent on a reasoning content part,
10
+ the converter now uses `encrypted_content` as a fallback instead of silently
11
+ skipping the part with a warning. The OpenAI Responses API accepts reasoning
12
+ items without an `id` when `encrypted_content` is supplied, enabling
13
+ multi-turn reasoning even when item IDs are stripped from provider options.
14
+
15
+ Also makes the `id` field optional on the `OpenAIResponsesReasoning` type to
16
+ reflect that the API does not require it.
17
+
18
+ Fixes #12853
19
+
20
+ ## 3.0.34
21
+
22
+ ### Patch Changes
23
+
24
+ - 66a374c: Support `phase` parameter on Responses API message items. The `phase` field (`'commentary'` or `'final_answer'`) is returned by models like `gpt-5.3-codex` on assistant message output items and must be preserved when sending follow-up requests. The phase value is available in `providerMetadata.openai.phase` on text parts and is automatically included on assistant messages sent back to the API.
25
+
3
26
  ## 3.0.33
4
27
 
5
28
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -220,6 +220,7 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazySchema<{
220
220
  item: {
221
221
  type: "message";
222
222
  id: string;
223
+ phase?: "commentary" | "final_answer" | null | undefined;
223
224
  } | {
224
225
  type: "reasoning";
225
226
  id: string;
@@ -315,6 +316,7 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazySchema<{
315
316
  item: {
316
317
  type: "message";
317
318
  id: string;
319
+ phase?: "commentary" | "final_answer" | null | undefined;
318
320
  } | {
319
321
  type: "reasoning";
320
322
  id: string;
@@ -1027,6 +1029,7 @@ type OpenaiResponsesProviderMetadata = {
1027
1029
  };
1028
1030
  type ResponsesTextProviderMetadata = {
1029
1031
  itemId: string;
1032
+ phase?: 'commentary' | 'final_answer' | null;
1030
1033
  annotations?: Array<ResponsesOutputTextAnnotationProviderMetadata>;
1031
1034
  };
1032
1035
  type OpenaiResponsesTextProviderMetadata = {
package/dist/index.d.ts CHANGED
@@ -220,6 +220,7 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazySchema<{
220
220
  item: {
221
221
  type: "message";
222
222
  id: string;
223
+ phase?: "commentary" | "final_answer" | null | undefined;
223
224
  } | {
224
225
  type: "reasoning";
225
226
  id: string;
@@ -315,6 +316,7 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazySchema<{
315
316
  item: {
316
317
  type: "message";
317
318
  id: string;
319
+ phase?: "commentary" | "final_answer" | null | undefined;
318
320
  } | {
319
321
  type: "reasoning";
320
322
  id: string;
@@ -1027,6 +1029,7 @@ type OpenaiResponsesProviderMetadata = {
1027
1029
  };
1028
1030
  type ResponsesTextProviderMetadata = {
1029
1031
  itemId: string;
1032
+ phase?: 'commentary' | 'final_answer' | null;
1030
1033
  annotations?: Array<ResponsesOutputTextAnnotationProviderMetadata>;
1031
1034
  };
1032
1035
  type OpenaiResponsesTextProviderMetadata = {
package/dist/index.js CHANGED
@@ -1753,6 +1753,7 @@ var modelMaxImagesPerCall = {
1753
1753
  "chatgpt-image-latest": 10
1754
1754
  };
1755
1755
  var defaultResponseFormatPrefixes = [
1756
+ "chatgpt-image-",
1756
1757
  "gpt-image-1-mini",
1757
1758
  "gpt-image-1.5",
1758
1759
  "gpt-image-1"
@@ -2574,7 +2575,7 @@ async function convertToOpenAIResponsesInput({
2574
2575
  hasShellTool = false,
2575
2576
  hasApplyPatchTool = false
2576
2577
  }) {
2577
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
2578
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
2578
2579
  const input = [];
2579
2580
  const warnings = [];
2580
2581
  const processedApprovalIds = /* @__PURE__ */ new Set();
@@ -2655,7 +2656,9 @@ async function convertToOpenAIResponsesInput({
2655
2656
  for (const part of content) {
2656
2657
  switch (part.type) {
2657
2658
  case "text": {
2658
- const id = (_b = (_a = part.providerOptions) == null ? void 0 : _a[providerOptionsName]) == null ? void 0 : _b.itemId;
2659
+ const providerOpts = (_a = part.providerOptions) == null ? void 0 : _a[providerOptionsName];
2660
+ const id = providerOpts == null ? void 0 : providerOpts.itemId;
2661
+ const phase = providerOpts == null ? void 0 : providerOpts.phase;
2659
2662
  if (hasConversation && id != null) {
2660
2663
  break;
2661
2664
  }
@@ -2666,12 +2669,13 @@ async function convertToOpenAIResponsesInput({
2666
2669
  input.push({
2667
2670
  role: "assistant",
2668
2671
  content: [{ type: "output_text", text: part.text }],
2669
- id
2672
+ id,
2673
+ ...phase != null && { phase }
2670
2674
  });
2671
2675
  break;
2672
2676
  }
2673
2677
  case "tool-call": {
2674
- const id = (_g = (_d = (_c = part.providerOptions) == null ? void 0 : _c[providerOptionsName]) == null ? void 0 : _d.itemId) != null ? _g : (_f = (_e = part.providerMetadata) == null ? void 0 : _e[providerOptionsName]) == null ? void 0 : _f.itemId;
2678
+ const id = (_f = (_c = (_b = part.providerOptions) == null ? void 0 : _b[providerOptionsName]) == null ? void 0 : _c.itemId) != null ? _f : (_e = (_d = part.providerMetadata) == null ? void 0 : _d[providerOptionsName]) == null ? void 0 : _e.itemId;
2675
2679
  if (hasConversation && id != null) {
2676
2680
  break;
2677
2681
  }
@@ -2782,7 +2786,7 @@ async function convertToOpenAIResponsesInput({
2782
2786
  break;
2783
2787
  }
2784
2788
  if (store) {
2785
- const itemId = (_j = (_i = (_h = part.providerOptions) == null ? void 0 : _h[providerOptionsName]) == null ? void 0 : _i.itemId) != null ? _j : part.toolCallId;
2789
+ const itemId = (_i = (_h = (_g = part.providerOptions) == null ? void 0 : _g[providerOptionsName]) == null ? void 0 : _h.itemId) != null ? _i : part.toolCallId;
2786
2790
  input.push({ type: "item_reference", id: itemId });
2787
2791
  } else {
2788
2792
  warnings.push({
@@ -2842,10 +2846,26 @@ async function convertToOpenAIResponsesInput({
2842
2846
  }
2843
2847
  }
2844
2848
  } else {
2845
- warnings.push({
2846
- type: "other",
2847
- message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${JSON.stringify(part)}.`
2848
- });
2849
+ const encryptedContent = providerOptions == null ? void 0 : providerOptions.reasoningEncryptedContent;
2850
+ if (encryptedContent != null) {
2851
+ const summaryParts = [];
2852
+ if (part.text.length > 0) {
2853
+ summaryParts.push({
2854
+ type: "summary_text",
2855
+ text: part.text
2856
+ });
2857
+ }
2858
+ input.push({
2859
+ type: "reasoning",
2860
+ encrypted_content: encryptedContent,
2861
+ summary: summaryParts
2862
+ });
2863
+ } else {
2864
+ warnings.push({
2865
+ type: "other",
2866
+ message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${JSON.stringify(part)}.`
2867
+ });
2868
+ }
2849
2869
  }
2850
2870
  break;
2851
2871
  }
@@ -2876,7 +2896,7 @@ async function convertToOpenAIResponsesInput({
2876
2896
  }
2877
2897
  const output = part.output;
2878
2898
  if (output.type === "execution-denied") {
2879
- const approvalId = (_l = (_k = output.providerOptions) == null ? void 0 : _k.openai) == null ? void 0 : _l.approvalId;
2899
+ const approvalId = (_k = (_j = output.providerOptions) == null ? void 0 : _j.openai) == null ? void 0 : _k.approvalId;
2880
2900
  if (approvalId) {
2881
2901
  continue;
2882
2902
  }
@@ -2935,7 +2955,7 @@ async function convertToOpenAIResponsesInput({
2935
2955
  contentValue = output.value;
2936
2956
  break;
2937
2957
  case "execution-denied":
2938
- contentValue = (_m = output.reason) != null ? _m : "Tool execution denied.";
2958
+ contentValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
2939
2959
  break;
2940
2960
  case "json":
2941
2961
  case "error-json":
@@ -3068,7 +3088,8 @@ var openaiResponsesChunkSchema = (0, import_provider_utils24.lazySchema)(
3068
3088
  item: import_v419.z.discriminatedUnion("type", [
3069
3089
  import_v419.z.object({
3070
3090
  type: import_v419.z.literal("message"),
3071
- id: import_v419.z.string()
3091
+ id: import_v419.z.string(),
3092
+ phase: import_v419.z.enum(["commentary", "final_answer"]).nullish()
3072
3093
  }),
3073
3094
  import_v419.z.object({
3074
3095
  type: import_v419.z.literal("reasoning"),
@@ -3185,7 +3206,8 @@ var openaiResponsesChunkSchema = (0, import_provider_utils24.lazySchema)(
3185
3206
  item: import_v419.z.discriminatedUnion("type", [
3186
3207
  import_v419.z.object({
3187
3208
  type: import_v419.z.literal("message"),
3188
- id: import_v419.z.string()
3209
+ id: import_v419.z.string(),
3210
+ phase: import_v419.z.enum(["commentary", "final_answer"]).nullish()
3189
3211
  }),
3190
3212
  import_v419.z.object({
3191
3213
  type: import_v419.z.literal("reasoning"),
@@ -3497,6 +3519,7 @@ var openaiResponsesResponseSchema = (0, import_provider_utils24.lazySchema)(
3497
3519
  type: import_v419.z.literal("message"),
3498
3520
  role: import_v419.z.literal("assistant"),
3499
3521
  id: import_v419.z.string(),
3522
+ phase: import_v419.z.enum(["commentary", "final_answer"]).nullish(),
3500
3523
  content: import_v419.z.array(
3501
3524
  import_v419.z.object({
3502
3525
  type: import_v419.z.literal("output_text"),
@@ -4629,6 +4652,7 @@ var OpenAIResponsesLanguageModel = class {
4629
4652
  }
4630
4653
  const providerMetadata2 = {
4631
4654
  itemId: part.id,
4655
+ ...part.phase != null && { phase: part.phase },
4632
4656
  ...contentPart.annotations.length > 0 && {
4633
4657
  annotations: contentPart.annotations
4634
4658
  }
@@ -4943,6 +4967,7 @@ var OpenAIResponsesLanguageModel = class {
4943
4967
  let responseId = null;
4944
4968
  const ongoingToolCalls = {};
4945
4969
  const ongoingAnnotations = [];
4970
+ let activeMessagePhase;
4946
4971
  let hasFunctionCall = false;
4947
4972
  const activeReasoning = {};
4948
4973
  let serviceTier;
@@ -4953,7 +4978,7 @@ var OpenAIResponsesLanguageModel = class {
4953
4978
  controller.enqueue({ type: "stream-start", warnings });
4954
4979
  },
4955
4980
  transform(chunk, controller) {
4956
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D;
4981
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F;
4957
4982
  if (options.includeRawChunks) {
4958
4983
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
4959
4984
  }
@@ -5094,12 +5119,16 @@ var OpenAIResponsesLanguageModel = class {
5094
5119
  } else if (value.item.type === "shell_call_output") {
5095
5120
  } else if (value.item.type === "message") {
5096
5121
  ongoingAnnotations.splice(0, ongoingAnnotations.length);
5122
+ activeMessagePhase = (_a = value.item.phase) != null ? _a : void 0;
5097
5123
  controller.enqueue({
5098
5124
  type: "text-start",
5099
5125
  id: value.item.id,
5100
5126
  providerMetadata: {
5101
5127
  [providerOptionsName]: {
5102
- itemId: value.item.id
5128
+ itemId: value.item.id,
5129
+ ...value.item.phase != null && {
5130
+ phase: value.item.phase
5131
+ }
5103
5132
  }
5104
5133
  }
5105
5134
  });
@@ -5114,19 +5143,22 @@ var OpenAIResponsesLanguageModel = class {
5114
5143
  providerMetadata: {
5115
5144
  [providerOptionsName]: {
5116
5145
  itemId: value.item.id,
5117
- reasoningEncryptedContent: (_a = value.item.encrypted_content) != null ? _a : null
5146
+ reasoningEncryptedContent: (_b = value.item.encrypted_content) != null ? _b : null
5118
5147
  }
5119
5148
  }
5120
5149
  });
5121
5150
  }
5122
5151
  } else if (isResponseOutputItemDoneChunk(value)) {
5123
5152
  if (value.item.type === "message") {
5153
+ const phase = (_c = value.item.phase) != null ? _c : activeMessagePhase;
5154
+ activeMessagePhase = void 0;
5124
5155
  controller.enqueue({
5125
5156
  type: "text-end",
5126
5157
  id: value.item.id,
5127
5158
  providerMetadata: {
5128
5159
  [providerOptionsName]: {
5129
5160
  itemId: value.item.id,
5161
+ ...phase != null && { phase },
5130
5162
  ...ongoingAnnotations.length > 0 && {
5131
5163
  annotations: ongoingAnnotations
5132
5164
  }
@@ -5191,13 +5223,13 @@ var OpenAIResponsesLanguageModel = class {
5191
5223
  toolName: toolNameMapping.toCustomToolName("file_search"),
5192
5224
  result: {
5193
5225
  queries: value.item.queries,
5194
- results: (_c = (_b = value.item.results) == null ? void 0 : _b.map((result) => ({
5226
+ results: (_e = (_d = value.item.results) == null ? void 0 : _d.map((result) => ({
5195
5227
  attributes: result.attributes,
5196
5228
  fileId: result.file_id,
5197
5229
  filename: result.filename,
5198
5230
  score: result.score,
5199
5231
  text: result.text
5200
- }))) != null ? _c : null
5232
+ }))) != null ? _e : null
5201
5233
  }
5202
5234
  });
5203
5235
  } else if (value.item.type === "code_interpreter_call") {
@@ -5221,10 +5253,10 @@ var OpenAIResponsesLanguageModel = class {
5221
5253
  });
5222
5254
  } else if (value.item.type === "mcp_call") {
5223
5255
  ongoingToolCalls[value.output_index] = void 0;
5224
- const approvalRequestId = (_d = value.item.approval_request_id) != null ? _d : void 0;
5225
- const aliasedToolCallId = approvalRequestId != null ? (_f = (_e = approvalRequestIdToDummyToolCallIdFromStream.get(
5256
+ const approvalRequestId = (_f = value.item.approval_request_id) != null ? _f : void 0;
5257
+ const aliasedToolCallId = approvalRequestId != null ? (_h = (_g = approvalRequestIdToDummyToolCallIdFromStream.get(
5226
5258
  approvalRequestId
5227
- )) != null ? _e : approvalRequestIdToDummyToolCallIdFromPrompt[approvalRequestId]) != null ? _f : value.item.id : value.item.id;
5259
+ )) != null ? _g : approvalRequestIdToDummyToolCallIdFromPrompt[approvalRequestId]) != null ? _h : value.item.id : value.item.id;
5228
5260
  const toolName = `mcp.${value.item.name}`;
5229
5261
  controller.enqueue({
5230
5262
  type: "tool-call",
@@ -5294,8 +5326,8 @@ var OpenAIResponsesLanguageModel = class {
5294
5326
  ongoingToolCalls[value.output_index] = void 0;
5295
5327
  } else if (value.item.type === "mcp_approval_request") {
5296
5328
  ongoingToolCalls[value.output_index] = void 0;
5297
- const dummyToolCallId = (_i = (_h = (_g = self.config).generateId) == null ? void 0 : _h.call(_g)) != null ? _i : (0, import_provider_utils27.generateId)();
5298
- const approvalRequestId = (_j = value.item.approval_request_id) != null ? _j : value.item.id;
5329
+ const dummyToolCallId = (_k = (_j = (_i = self.config).generateId) == null ? void 0 : _j.call(_i)) != null ? _k : (0, import_provider_utils27.generateId)();
5330
+ const approvalRequestId = (_l = value.item.approval_request_id) != null ? _l : value.item.id;
5299
5331
  approvalRequestIdToDummyToolCallIdFromStream.set(
5300
5332
  approvalRequestId,
5301
5333
  dummyToolCallId
@@ -5384,7 +5416,7 @@ var OpenAIResponsesLanguageModel = class {
5384
5416
  providerMetadata: {
5385
5417
  [providerOptionsName]: {
5386
5418
  itemId: value.item.id,
5387
- reasoningEncryptedContent: (_k = value.item.encrypted_content) != null ? _k : null
5419
+ reasoningEncryptedContent: (_m = value.item.encrypted_content) != null ? _m : null
5388
5420
  }
5389
5421
  }
5390
5422
  });
@@ -5488,7 +5520,7 @@ var OpenAIResponsesLanguageModel = class {
5488
5520
  id: value.item_id,
5489
5521
  delta: value.delta
5490
5522
  });
5491
- if (((_m = (_l = options.providerOptions) == null ? void 0 : _l[providerOptionsName]) == null ? void 0 : _m.logprobs) && value.logprobs) {
5523
+ if (((_o = (_n = options.providerOptions) == null ? void 0 : _n[providerOptionsName]) == null ? void 0 : _o.logprobs) && value.logprobs) {
5492
5524
  logprobs.push(value.logprobs);
5493
5525
  }
5494
5526
  } else if (value.type === "response.reasoning_summary_part.added") {
@@ -5517,7 +5549,7 @@ var OpenAIResponsesLanguageModel = class {
5517
5549
  providerMetadata: {
5518
5550
  [providerOptionsName]: {
5519
5551
  itemId: value.item_id,
5520
- reasoningEncryptedContent: (_o = (_n = activeReasoning[value.item_id]) == null ? void 0 : _n.encryptedContent) != null ? _o : null
5552
+ reasoningEncryptedContent: (_q = (_p = activeReasoning[value.item_id]) == null ? void 0 : _p.encryptedContent) != null ? _q : null
5521
5553
  }
5522
5554
  }
5523
5555
  });
@@ -5551,10 +5583,10 @@ var OpenAIResponsesLanguageModel = class {
5551
5583
  } else if (isResponseFinishedChunk(value)) {
5552
5584
  finishReason = {
5553
5585
  unified: mapOpenAIResponseFinishReason({
5554
- finishReason: (_p = value.response.incomplete_details) == null ? void 0 : _p.reason,
5586
+ finishReason: (_r = value.response.incomplete_details) == null ? void 0 : _r.reason,
5555
5587
  hasFunctionCall
5556
5588
  }),
5557
- raw: (_r = (_q = value.response.incomplete_details) == null ? void 0 : _q.reason) != null ? _r : void 0
5589
+ raw: (_t = (_s = value.response.incomplete_details) == null ? void 0 : _s.reason) != null ? _t : void 0
5558
5590
  };
5559
5591
  usage = value.response.usage;
5560
5592
  if (typeof value.response.service_tier === "string") {
@@ -5566,7 +5598,7 @@ var OpenAIResponsesLanguageModel = class {
5566
5598
  controller.enqueue({
5567
5599
  type: "source",
5568
5600
  sourceType: "url",
5569
- id: (_u = (_t = (_s = self.config).generateId) == null ? void 0 : _t.call(_s)) != null ? _u : (0, import_provider_utils27.generateId)(),
5601
+ id: (_w = (_v = (_u = self.config).generateId) == null ? void 0 : _v.call(_u)) != null ? _w : (0, import_provider_utils27.generateId)(),
5570
5602
  url: value.annotation.url,
5571
5603
  title: value.annotation.title
5572
5604
  });
@@ -5574,7 +5606,7 @@ var OpenAIResponsesLanguageModel = class {
5574
5606
  controller.enqueue({
5575
5607
  type: "source",
5576
5608
  sourceType: "document",
5577
- id: (_x = (_w = (_v = self.config).generateId) == null ? void 0 : _w.call(_v)) != null ? _x : (0, import_provider_utils27.generateId)(),
5609
+ id: (_z = (_y = (_x = self.config).generateId) == null ? void 0 : _y.call(_x)) != null ? _z : (0, import_provider_utils27.generateId)(),
5578
5610
  mediaType: "text/plain",
5579
5611
  title: value.annotation.filename,
5580
5612
  filename: value.annotation.filename,
@@ -5590,7 +5622,7 @@ var OpenAIResponsesLanguageModel = class {
5590
5622
  controller.enqueue({
5591
5623
  type: "source",
5592
5624
  sourceType: "document",
5593
- id: (_A = (_z = (_y = self.config).generateId) == null ? void 0 : _z.call(_y)) != null ? _A : (0, import_provider_utils27.generateId)(),
5625
+ id: (_C = (_B = (_A = self.config).generateId) == null ? void 0 : _B.call(_A)) != null ? _C : (0, import_provider_utils27.generateId)(),
5594
5626
  mediaType: "text/plain",
5595
5627
  title: value.annotation.filename,
5596
5628
  filename: value.annotation.filename,
@@ -5606,7 +5638,7 @@ var OpenAIResponsesLanguageModel = class {
5606
5638
  controller.enqueue({
5607
5639
  type: "source",
5608
5640
  sourceType: "document",
5609
- id: (_D = (_C = (_B = self.config).generateId) == null ? void 0 : _C.call(_B)) != null ? _D : (0, import_provider_utils27.generateId)(),
5641
+ id: (_F = (_E = (_D = self.config).generateId) == null ? void 0 : _E.call(_D)) != null ? _F : (0, import_provider_utils27.generateId)(),
5610
5642
  mediaType: "application/octet-stream",
5611
5643
  title: value.annotation.file_id,
5612
5644
  filename: value.annotation.file_id,
@@ -6065,7 +6097,7 @@ var OpenAITranscriptionModel = class {
6065
6097
  };
6066
6098
 
6067
6099
  // src/version.ts
6068
- var VERSION = true ? "3.0.33" : "0.0.0-test";
6100
+ var VERSION = true ? "3.0.35" : "0.0.0-test";
6069
6101
 
6070
6102
  // src/openai-provider.ts
6071
6103
  function createOpenAI(options = {}) {