@ai-sdk/openai 3.0.0-beta.104 → 3.0.0-beta.105

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/dist/index.mjs CHANGED
@@ -43,7 +43,7 @@ var openaiFailedResponseHandler = createJsonErrorResponseHandler({
43
43
  function getOpenAILanguageModelCapabilities(modelId) {
44
44
  const supportsFlexProcessing = modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
45
45
  const supportsPriorityProcessing = modelId.startsWith("gpt-4") || modelId.startsWith("gpt-5-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-nano") && !modelId.startsWith("gpt-5-chat") || modelId.startsWith("o3") || modelId.startsWith("o4-mini");
46
- const isReasoningModel = !(modelId.startsWith("gpt-3") || modelId.startsWith("gpt-4") || modelId.startsWith("chatgpt-4o") || modelId.startsWith("gpt-5-chat"));
46
+ const isReasoningModel = modelId.startsWith("o1") || modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("codex-mini") || modelId.startsWith("computer-use-preview") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
47
47
  const supportsNonReasoningParameters = modelId.startsWith("gpt-5.1") || modelId.startsWith("gpt-5.2");
48
48
  const systemMessageMode = isReasoningModel ? "developer" : "system";
49
49
  return {
@@ -545,7 +545,26 @@ var openaiChatLanguageModelOptions = lazySchema2(
545
545
  * username or email address, in order to avoid sending us any identifying
546
546
  * information.
547
547
  */
548
- safetyIdentifier: z3.string().optional()
548
+ safetyIdentifier: z3.string().optional(),
549
+ /**
550
+ * Override the system message mode for this model.
551
+ * - 'system': Use the 'system' role for system messages (default for most models)
552
+ * - 'developer': Use the 'developer' role for system messages (used by reasoning models)
553
+ * - 'remove': Remove system messages entirely
554
+ *
555
+ * If not specified, the mode is automatically determined based on the model.
556
+ */
557
+ systemMessageMode: z3.enum(["system", "developer", "remove"]).optional(),
558
+ /**
559
+ * Force treating this model as a reasoning model.
560
+ *
561
+ * This is useful for "stealth" reasoning models (e.g. via a custom baseURL)
562
+ * where the model ID is not recognized by the SDK's allowlist.
563
+ *
564
+ * When enabled, the SDK applies reasoning-model parameter compatibility rules
565
+ * and defaults `systemMessageMode` to `developer` unless overridden.
566
+ */
567
+ forceReasoning: z3.boolean().optional()
549
568
  })
550
569
  )
551
570
  );
@@ -642,7 +661,7 @@ var OpenAIChatLanguageModel = class {
642
661
  toolChoice,
643
662
  providerOptions
644
663
  }) {
645
- var _a, _b, _c;
664
+ var _a, _b, _c, _d, _e;
646
665
  const warnings = [];
647
666
  const openaiOptions = (_a = await parseProviderOptions({
648
667
  provider: "openai",
@@ -650,17 +669,18 @@ var OpenAIChatLanguageModel = class {
650
669
  schema: openaiChatLanguageModelOptions
651
670
  })) != null ? _a : {};
652
671
  const modelCapabilities = getOpenAILanguageModelCapabilities(this.modelId);
672
+ const isReasoningModel = (_b = openaiOptions.forceReasoning) != null ? _b : modelCapabilities.isReasoningModel;
653
673
  if (topK != null) {
654
674
  warnings.push({ type: "unsupported", feature: "topK" });
655
675
  }
656
676
  const { messages, warnings: messageWarnings } = convertToOpenAIChatMessages(
657
677
  {
658
678
  prompt,
659
- systemMessageMode: modelCapabilities.systemMessageMode
679
+ systemMessageMode: (_c = openaiOptions.systemMessageMode) != null ? _c : isReasoningModel ? "developer" : modelCapabilities.systemMessageMode
660
680
  }
661
681
  );
662
682
  warnings.push(...messageWarnings);
663
- const strictJsonSchema = (_b = openaiOptions.strictJsonSchema) != null ? _b : true;
683
+ const strictJsonSchema = (_d = openaiOptions.strictJsonSchema) != null ? _d : true;
664
684
  const baseArgs = {
665
685
  // model id:
666
686
  model: this.modelId,
@@ -681,7 +701,7 @@ var OpenAIChatLanguageModel = class {
681
701
  json_schema: {
682
702
  schema: responseFormat.schema,
683
703
  strict: strictJsonSchema,
684
- name: (_c = responseFormat.name) != null ? _c : "response",
704
+ name: (_e = responseFormat.name) != null ? _e : "response",
685
705
  description: responseFormat.description
686
706
  }
687
707
  } : { type: "json_object" } : void 0,
@@ -702,7 +722,7 @@ var OpenAIChatLanguageModel = class {
702
722
  // messages:
703
723
  messages
704
724
  };
705
- if (modelCapabilities.isReasoningModel) {
725
+ if (isReasoningModel) {
706
726
  if (openaiOptions.reasoningEffort !== "none" || !modelCapabilities.supportsNonReasoningParameters) {
707
727
  if (baseArgs.temperature != null) {
708
728
  baseArgs.temperature = void 0;
@@ -1678,7 +1698,11 @@ var OpenAIEmbeddingModel = class {
1678
1698
  // src/image/openai-image-model.ts
1679
1699
  import {
1680
1700
  combineHeaders as combineHeaders4,
1701
+ convertBase64ToUint8Array,
1702
+ convertToFormData,
1681
1703
  createJsonResponseHandler as createJsonResponseHandler4,
1704
+ downloadBlob,
1705
+ postFormDataToApi,
1682
1706
  postJsonToApi as postJsonToApi4
1683
1707
  } from "@ai-sdk/provider-utils";
1684
1708
 
@@ -1742,6 +1766,8 @@ var OpenAIImageModel = class {
1742
1766
  }
1743
1767
  async doGenerate({
1744
1768
  prompt,
1769
+ files,
1770
+ mask,
1745
1771
  n,
1746
1772
  size,
1747
1773
  aspectRatio,
@@ -1750,7 +1776,7 @@ var OpenAIImageModel = class {
1750
1776
  headers,
1751
1777
  abortSignal
1752
1778
  }) {
1753
- var _a, _b, _c, _d, _e, _f, _g;
1779
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1754
1780
  const warnings = [];
1755
1781
  if (aspectRatio != null) {
1756
1782
  warnings.push({
@@ -1763,6 +1789,72 @@ var OpenAIImageModel = class {
1763
1789
  warnings.push({ type: "unsupported", feature: "seed" });
1764
1790
  }
1765
1791
  const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
1792
+ if (files != null) {
1793
+ const { value: response2, responseHeaders: responseHeaders2 } = await postFormDataToApi({
1794
+ url: this.config.url({
1795
+ path: "/images/edits",
1796
+ modelId: this.modelId
1797
+ }),
1798
+ headers: combineHeaders4(this.config.headers(), headers),
1799
+ formData: convertToFormData({
1800
+ model: this.modelId,
1801
+ prompt,
1802
+ image: await Promise.all(
1803
+ files.map(
1804
+ (file) => file.type === "file" ? new Blob(
1805
+ [
1806
+ file.data instanceof Uint8Array ? new Blob([file.data], {
1807
+ type: file.mediaType
1808
+ }) : new Blob([convertBase64ToUint8Array(file.data)], {
1809
+ type: file.mediaType
1810
+ })
1811
+ ],
1812
+ { type: file.mediaType }
1813
+ ) : downloadBlob(file.url)
1814
+ )
1815
+ ),
1816
+ mask: mask != null ? await fileToBlob(mask) : void 0,
1817
+ n,
1818
+ size,
1819
+ ...(_d = providerOptions.openai) != null ? _d : {}
1820
+ }),
1821
+ failedResponseHandler: openaiFailedResponseHandler,
1822
+ successfulResponseHandler: createJsonResponseHandler4(
1823
+ openaiImageResponseSchema
1824
+ ),
1825
+ abortSignal,
1826
+ fetch: this.config.fetch
1827
+ });
1828
+ return {
1829
+ images: response2.data.map((item) => item.b64_json),
1830
+ warnings,
1831
+ usage: response2.usage != null ? {
1832
+ inputTokens: (_e = response2.usage.input_tokens) != null ? _e : void 0,
1833
+ outputTokens: (_f = response2.usage.output_tokens) != null ? _f : void 0,
1834
+ totalTokens: (_g = response2.usage.total_tokens) != null ? _g : void 0
1835
+ } : void 0,
1836
+ response: {
1837
+ timestamp: currentDate,
1838
+ modelId: this.modelId,
1839
+ headers: responseHeaders2
1840
+ },
1841
+ providerMetadata: {
1842
+ openai: {
1843
+ images: response2.data.map((item) => {
1844
+ var _a2, _b2, _c2, _d2, _e2;
1845
+ return {
1846
+ ...item.revised_prompt ? { revisedPrompt: item.revised_prompt } : {},
1847
+ created: (_a2 = response2.created) != null ? _a2 : void 0,
1848
+ size: (_b2 = response2.size) != null ? _b2 : void 0,
1849
+ quality: (_c2 = response2.quality) != null ? _c2 : void 0,
1850
+ background: (_d2 = response2.background) != null ? _d2 : void 0,
1851
+ outputFormat: (_e2 = response2.output_format) != null ? _e2 : void 0
1852
+ };
1853
+ })
1854
+ }
1855
+ }
1856
+ };
1857
+ }
1766
1858
  const { value: response, responseHeaders } = await postJsonToApi4({
1767
1859
  url: this.config.url({
1768
1860
  path: "/images/generations",
@@ -1774,7 +1866,7 @@ var OpenAIImageModel = class {
1774
1866
  prompt,
1775
1867
  n,
1776
1868
  size,
1777
- ...(_d = providerOptions.openai) != null ? _d : {},
1869
+ ...(_h = providerOptions.openai) != null ? _h : {},
1778
1870
  ...!hasDefaultResponseFormat.has(this.modelId) ? { response_format: "b64_json" } : {}
1779
1871
  },
1780
1872
  failedResponseHandler: openaiFailedResponseHandler,
@@ -1788,9 +1880,9 @@ var OpenAIImageModel = class {
1788
1880
  images: response.data.map((item) => item.b64_json),
1789
1881
  warnings,
1790
1882
  usage: response.usage != null ? {
1791
- inputTokens: (_e = response.usage.input_tokens) != null ? _e : void 0,
1792
- outputTokens: (_f = response.usage.output_tokens) != null ? _f : void 0,
1793
- totalTokens: (_g = response.usage.total_tokens) != null ? _g : void 0
1883
+ inputTokens: (_i = response.usage.input_tokens) != null ? _i : void 0,
1884
+ outputTokens: (_j = response.usage.output_tokens) != null ? _j : void 0,
1885
+ totalTokens: (_k = response.usage.total_tokens) != null ? _k : void 0
1794
1886
  } : void 0,
1795
1887
  response: {
1796
1888
  timestamp: currentDate,
@@ -1815,6 +1907,14 @@ var OpenAIImageModel = class {
1815
1907
  };
1816
1908
  }
1817
1909
  };
1910
+ async function fileToBlob(file) {
1911
+ if (!file) return void 0;
1912
+ if (file.type === "url") {
1913
+ return downloadBlob(file.url);
1914
+ }
1915
+ const data = file.data instanceof Uint8Array ? file.data : convertBase64ToUint8Array(file.data);
1916
+ return new Blob([data], { type: file.mediaType });
1917
+ }
1818
1918
 
1819
1919
  // src/tool/apply-patch.ts
1820
1920
  import {
@@ -3677,7 +3777,26 @@ var openaiResponsesProviderOptionsSchema = lazySchema18(
3677
3777
  * Defaults to `undefined`.
3678
3778
  * @see https://platform.openai.com/docs/guides/safety-best-practices/end-user-ids
3679
3779
  */
3680
- user: z20.string().nullish()
3780
+ user: z20.string().nullish(),
3781
+ /**
3782
+ * Override the system message mode for this model.
3783
+ * - 'system': Use the 'system' role for system messages (default for most models)
3784
+ * - 'developer': Use the 'developer' role for system messages (used by reasoning models)
3785
+ * - 'remove': Remove system messages entirely
3786
+ *
3787
+ * If not specified, the mode is automatically determined based on the model.
3788
+ */
3789
+ systemMessageMode: z20.enum(["system", "developer", "remove"]).optional(),
3790
+ /**
3791
+ * Force treating this model as a reasoning model.
3792
+ *
3793
+ * This is useful for "stealth" reasoning models (e.g. via a custom baseURL)
3794
+ * where the model ID is not recognized by the SDK's allowlist.
3795
+ *
3796
+ * When enabled, the SDK applies reasoning-model parameter compatibility rules
3797
+ * and defaults `systemMessageMode` to `developer` unless overridden.
3798
+ */
3799
+ forceReasoning: z20.boolean().optional()
3681
3800
  })
3682
3801
  )
3683
3802
  );
@@ -3890,7 +4009,7 @@ var OpenAIResponsesLanguageModel = class {
3890
4009
  toolChoice,
3891
4010
  responseFormat
3892
4011
  }) {
3893
- var _a, _b, _c, _d;
4012
+ var _a, _b, _c, _d, _e, _f;
3894
4013
  const warnings = [];
3895
4014
  const modelCapabilities = getOpenAILanguageModelCapabilities(this.modelId);
3896
4015
  if (topK != null) {
@@ -3913,6 +4032,7 @@ var OpenAIResponsesLanguageModel = class {
3913
4032
  providerOptions,
3914
4033
  schema: openaiResponsesProviderOptionsSchema
3915
4034
  });
4035
+ const isReasoningModel = (_a = openaiOptions == null ? void 0 : openaiOptions.forceReasoning) != null ? _a : modelCapabilities.isReasoningModel;
3916
4036
  if ((openaiOptions == null ? void 0 : openaiOptions.conversation) && (openaiOptions == null ? void 0 : openaiOptions.previousResponseId)) {
3917
4037
  warnings.push({
3918
4038
  type: "unsupported",
@@ -3937,15 +4057,15 @@ var OpenAIResponsesLanguageModel = class {
3937
4057
  const { input, warnings: inputWarnings } = await convertToOpenAIResponsesInput({
3938
4058
  prompt,
3939
4059
  toolNameMapping,
3940
- systemMessageMode: modelCapabilities.systemMessageMode,
4060
+ systemMessageMode: (_b = openaiOptions == null ? void 0 : openaiOptions.systemMessageMode) != null ? _b : isReasoningModel ? "developer" : modelCapabilities.systemMessageMode,
3941
4061
  fileIdPrefixes: this.config.fileIdPrefixes,
3942
- store: (_a = openaiOptions == null ? void 0 : openaiOptions.store) != null ? _a : true,
4062
+ store: (_c = openaiOptions == null ? void 0 : openaiOptions.store) != null ? _c : true,
3943
4063
  hasLocalShellTool: hasOpenAITool("openai.local_shell"),
3944
4064
  hasShellTool: hasOpenAITool("openai.shell"),
3945
4065
  hasApplyPatchTool: hasOpenAITool("openai.apply_patch")
3946
4066
  });
3947
4067
  warnings.push(...inputWarnings);
3948
- const strictJsonSchema = (_b = openaiOptions == null ? void 0 : openaiOptions.strictJsonSchema) != null ? _b : true;
4068
+ const strictJsonSchema = (_d = openaiOptions == null ? void 0 : openaiOptions.strictJsonSchema) != null ? _d : true;
3949
4069
  let include = openaiOptions == null ? void 0 : openaiOptions.include;
3950
4070
  function addInclude(key) {
3951
4071
  if (include == null) {
@@ -3961,9 +4081,9 @@ var OpenAIResponsesLanguageModel = class {
3961
4081
  if (topLogprobs) {
3962
4082
  addInclude("message.output_text.logprobs");
3963
4083
  }
3964
- const webSearchToolName = (_c = tools == null ? void 0 : tools.find(
4084
+ const webSearchToolName = (_e = tools == null ? void 0 : tools.find(
3965
4085
  (tool) => tool.type === "provider" && (tool.id === "openai.web_search" || tool.id === "openai.web_search_preview")
3966
- )) == null ? void 0 : _c.name;
4086
+ )) == null ? void 0 : _e.name;
3967
4087
  if (webSearchToolName) {
3968
4088
  addInclude("web_search_call.action.sources");
3969
4089
  }
@@ -3971,7 +4091,7 @@ var OpenAIResponsesLanguageModel = class {
3971
4091
  addInclude("code_interpreter_call.outputs");
3972
4092
  }
3973
4093
  const store = openaiOptions == null ? void 0 : openaiOptions.store;
3974
- if (store === false && modelCapabilities.isReasoningModel) {
4094
+ if (store === false && isReasoningModel) {
3975
4095
  addInclude("reasoning.encrypted_content");
3976
4096
  }
3977
4097
  const baseArgs = {
@@ -3986,7 +4106,7 @@ var OpenAIResponsesLanguageModel = class {
3986
4106
  format: responseFormat.schema != null ? {
3987
4107
  type: "json_schema",
3988
4108
  strict: strictJsonSchema,
3989
- name: (_d = responseFormat.name) != null ? _d : "response",
4109
+ name: (_f = responseFormat.name) != null ? _f : "response",
3990
4110
  description: responseFormat.description,
3991
4111
  schema: responseFormat.schema
3992
4112
  } : { type: "json_object" }
@@ -4013,7 +4133,7 @@ var OpenAIResponsesLanguageModel = class {
4013
4133
  top_logprobs: topLogprobs,
4014
4134
  truncation: openaiOptions == null ? void 0 : openaiOptions.truncation,
4015
4135
  // model-specific settings:
4016
- ...modelCapabilities.isReasoningModel && ((openaiOptions == null ? void 0 : openaiOptions.reasoningEffort) != null || (openaiOptions == null ? void 0 : openaiOptions.reasoningSummary) != null) && {
4136
+ ...isReasoningModel && ((openaiOptions == null ? void 0 : openaiOptions.reasoningEffort) != null || (openaiOptions == null ? void 0 : openaiOptions.reasoningSummary) != null) && {
4017
4137
  reasoning: {
4018
4138
  ...(openaiOptions == null ? void 0 : openaiOptions.reasoningEffort) != null && {
4019
4139
  effort: openaiOptions.reasoningEffort
@@ -4024,7 +4144,7 @@ var OpenAIResponsesLanguageModel = class {
4024
4144
  }
4025
4145
  }
4026
4146
  };
4027
- if (modelCapabilities.isReasoningModel) {
4147
+ if (isReasoningModel) {
4028
4148
  if (!((openaiOptions == null ? void 0 : openaiOptions.reasoningEffort) === "none" && modelCapabilities.supportsNonReasoningParameters)) {
4029
4149
  if (baseArgs.temperature != null) {
4030
4150
  baseArgs.temperature = void 0;
@@ -5332,11 +5452,11 @@ var OpenAISpeechModel = class {
5332
5452
  // src/transcription/openai-transcription-model.ts
5333
5453
  import {
5334
5454
  combineHeaders as combineHeaders7,
5335
- convertBase64ToUint8Array,
5455
+ convertBase64ToUint8Array as convertBase64ToUint8Array2,
5336
5456
  createJsonResponseHandler as createJsonResponseHandler6,
5337
5457
  mediaTypeToExtension,
5338
5458
  parseProviderOptions as parseProviderOptions7,
5339
- postFormDataToApi
5459
+ postFormDataToApi as postFormDataToApi2
5340
5460
  } from "@ai-sdk/provider-utils";
5341
5461
 
5342
5462
  // src/transcription/openai-transcription-api.ts
@@ -5486,7 +5606,7 @@ var OpenAITranscriptionModel = class {
5486
5606
  schema: openAITranscriptionProviderOptions
5487
5607
  });
5488
5608
  const formData = new FormData();
5489
- const blob = audio instanceof Uint8Array ? new Blob([audio]) : new Blob([convertBase64ToUint8Array(audio)]);
5609
+ const blob = audio instanceof Uint8Array ? new Blob([audio]) : new Blob([convertBase64ToUint8Array2(audio)]);
5490
5610
  formData.append("model", this.modelId);
5491
5611
  const fileExtension = mediaTypeToExtension(mediaType);
5492
5612
  formData.append(
@@ -5533,7 +5653,7 @@ var OpenAITranscriptionModel = class {
5533
5653
  value: response,
5534
5654
  responseHeaders,
5535
5655
  rawValue: rawResponse
5536
- } = await postFormDataToApi({
5656
+ } = await postFormDataToApi2({
5537
5657
  url: this.config.url({
5538
5658
  path: "/audio/transcriptions",
5539
5659
  modelId: this.modelId
@@ -5573,7 +5693,7 @@ var OpenAITranscriptionModel = class {
5573
5693
  };
5574
5694
 
5575
5695
  // src/version.ts
5576
- var VERSION = true ? "3.0.0-beta.104" : "0.0.0-test";
5696
+ var VERSION = true ? "3.0.0-beta.105" : "0.0.0-test";
5577
5697
 
5578
5698
  // src/openai-provider.ts
5579
5699
  function createOpenAI(options = {}) {