@ai-sdk/openai 4.0.65 → 4.0.66

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.
@@ -123,6 +123,13 @@ type OpenAIConfig = {
123
123
  * @see https://github.com/vercel/ai/issues/20180
124
124
  */
125
125
  explicitMessageItemType?: boolean;
126
+ /**
127
+ * Whether the provider supports the
128
+ * `web_search_call.action.sources` Responses API include value.
129
+ *
130
+ * Defaults to `true`.
131
+ */
132
+ supportsWebSearchSourcesInclude?: boolean;
126
133
  /**
127
134
  * This is soft-deprecated. Use provider references (e.g. `{ openai: 'file-abc123' }`)
128
135
  * in file part data instead. File ID prefixes used to identify file IDs
@@ -909,9 +909,119 @@ var openaiLanguageModelChatOptions = lazySchema2(
909
909
  );
910
910
 
911
911
  // src/chat/openai-chat-prepare-tools.ts
912
+ import {
913
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError3
914
+ } from "@ai-sdk/provider";
915
+
916
+ // src/normalize-openai-json-schema.ts
912
917
  import {
913
918
  UnsupportedFunctionalityError as UnsupportedFunctionalityError2
914
919
  } from "@ai-sdk/provider";
920
+ function normalizeOpenAIJsonSchema(schema) {
921
+ let removedPropertyNames = false;
922
+ const normalizedSchema = normalizeSchema(schema);
923
+ return {
924
+ schema: normalizedSchema,
925
+ warnings: removedPropertyNames ? [
926
+ {
927
+ type: "compatibility",
928
+ feature: "JSON Schema propertyNames",
929
+ details: "OpenAI does not support JSON Schema propertyNames. It was removed before sending the schema, so OpenAI will not enforce property-name constraints."
930
+ }
931
+ ] : []
932
+ };
933
+ function normalizeSchema(schema2) {
934
+ const propertyNames = schema2.propertyNames;
935
+ if (propertyNames != null) {
936
+ if (typeof propertyNames === "boolean" || propertyNames.type !== "string") {
937
+ throw new UnsupportedFunctionalityError2({
938
+ functionality: "JSON Schema propertyNames that does not use a string schema"
939
+ });
940
+ }
941
+ removedPropertyNames = true;
942
+ }
943
+ const normalizedSchema2 = { ...schema2 };
944
+ delete normalizedSchema2.propertyNames;
945
+ if (normalizedSchema2.properties != null) {
946
+ normalizedSchema2.properties = normalizeSchemaRecord(
947
+ normalizedSchema2.properties
948
+ );
949
+ }
950
+ if (normalizedSchema2.patternProperties != null) {
951
+ normalizedSchema2.patternProperties = normalizeSchemaRecord(
952
+ normalizedSchema2.patternProperties
953
+ );
954
+ }
955
+ if (normalizedSchema2.additionalProperties != null) {
956
+ normalizedSchema2.additionalProperties = normalizeDefinition(
957
+ normalizedSchema2.additionalProperties
958
+ );
959
+ }
960
+ if (normalizedSchema2.additionalItems != null) {
961
+ normalizedSchema2.additionalItems = normalizeDefinition(
962
+ normalizedSchema2.additionalItems
963
+ );
964
+ }
965
+ if (normalizedSchema2.items != null) {
966
+ normalizedSchema2.items = Array.isArray(normalizedSchema2.items) ? normalizedSchema2.items.map(normalizeDefinition) : normalizeDefinition(normalizedSchema2.items);
967
+ }
968
+ if (normalizedSchema2.contains != null) {
969
+ normalizedSchema2.contains = normalizeDefinition(
970
+ normalizedSchema2.contains
971
+ );
972
+ }
973
+ if (normalizedSchema2.not != null) {
974
+ normalizedSchema2.not = normalizeDefinition(normalizedSchema2.not);
975
+ }
976
+ if (normalizedSchema2.allOf != null) {
977
+ normalizedSchema2.allOf = normalizedSchema2.allOf.map(normalizeDefinition);
978
+ }
979
+ if (normalizedSchema2.anyOf != null) {
980
+ normalizedSchema2.anyOf = normalizedSchema2.anyOf.map(normalizeDefinition);
981
+ }
982
+ if (normalizedSchema2.oneOf != null) {
983
+ normalizedSchema2.oneOf = normalizedSchema2.oneOf.map(normalizeDefinition);
984
+ }
985
+ if (normalizedSchema2.definitions != null) {
986
+ normalizedSchema2.definitions = normalizeSchemaRecord(
987
+ normalizedSchema2.definitions
988
+ );
989
+ }
990
+ if (normalizedSchema2.$defs != null) {
991
+ normalizedSchema2.$defs = normalizeSchemaRecord(normalizedSchema2.$defs);
992
+ }
993
+ if (normalizedSchema2.dependencies != null) {
994
+ normalizedSchema2.dependencies = Object.fromEntries(
995
+ Object.entries(normalizedSchema2.dependencies).map(
996
+ ([key, dependency]) => [
997
+ key,
998
+ Array.isArray(dependency) ? dependency : normalizeDefinition(dependency)
999
+ ]
1000
+ )
1001
+ );
1002
+ }
1003
+ for (const keyword of ["if", "then", "else"]) {
1004
+ const conditionalSchema = normalizedSchema2[keyword];
1005
+ if (conditionalSchema != null) {
1006
+ normalizedSchema2[keyword] = normalizeDefinition(conditionalSchema);
1007
+ }
1008
+ }
1009
+ return normalizedSchema2;
1010
+ }
1011
+ function normalizeSchemaRecord(schemas) {
1012
+ return Object.fromEntries(
1013
+ Object.entries(schemas).map(([key, schema2]) => [
1014
+ key,
1015
+ normalizeDefinition(schema2)
1016
+ ])
1017
+ );
1018
+ }
1019
+ function normalizeDefinition(definition) {
1020
+ return typeof definition === "boolean" ? definition : normalizeSchema(definition);
1021
+ }
1022
+ }
1023
+
1024
+ // src/chat/openai-chat-prepare-tools.ts
915
1025
  function prepareChatTools({
916
1026
  tools,
917
1027
  toolChoice
@@ -924,17 +1034,22 @@ function prepareChatTools({
924
1034
  const openaiTools = [];
925
1035
  for (const tool of tools) {
926
1036
  switch (tool.type) {
927
- case "function":
1037
+ case "function": {
1038
+ const normalizedInputSchema = normalizeOpenAIJsonSchema(
1039
+ tool.inputSchema
1040
+ );
1041
+ toolWarnings.push(...normalizedInputSchema.warnings);
928
1042
  openaiTools.push({
929
1043
  type: "function",
930
1044
  function: {
931
1045
  name: tool.name,
932
1046
  description: tool.description,
933
- parameters: tool.inputSchema,
1047
+ parameters: normalizedInputSchema.schema,
934
1048
  ...tool.strict != null ? { strict: tool.strict } : {}
935
1049
  }
936
1050
  });
937
1051
  break;
1052
+ }
938
1053
  default:
939
1054
  toolWarnings.push({
940
1055
  type: "unsupported",
@@ -965,7 +1080,7 @@ function prepareChatTools({
965
1080
  };
966
1081
  default: {
967
1082
  const _exhaustiveCheck = type;
968
- throw new UnsupportedFunctionalityError2({
1083
+ throw new UnsupportedFunctionalityError3({
969
1084
  functionality: `tool choice type: ${_exhaustiveCheck}`
970
1085
  });
971
1086
  }
@@ -1041,6 +1156,10 @@ var OpenAIChatLanguageModel = class _OpenAIChatLanguageModel {
1041
1156
  );
1042
1157
  warnings.push(...messageWarnings);
1043
1158
  const strictJsonSchema = (_e = openaiOptions.strictJsonSchema) != null ? _e : true;
1159
+ const normalizedResponseFormatSchema = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? normalizeOpenAIJsonSchema(responseFormat.schema) : void 0;
1160
+ if (normalizedResponseFormatSchema != null) {
1161
+ warnings.push(...normalizedResponseFormatSchema.warnings);
1162
+ }
1044
1163
  const baseArgs = {
1045
1164
  // model id:
1046
1165
  model: this.modelId,
@@ -1056,10 +1175,10 @@ var OpenAIChatLanguageModel = class _OpenAIChatLanguageModel {
1056
1175
  top_p: topP,
1057
1176
  frequency_penalty: frequencyPenalty,
1058
1177
  presence_penalty: presencePenalty,
1059
- response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
1178
+ response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? normalizedResponseFormatSchema != null ? {
1060
1179
  type: "json_schema",
1061
1180
  json_schema: {
1062
- schema: responseFormat.schema,
1181
+ schema: normalizedResponseFormatSchema.schema,
1063
1182
  strict: strictJsonSchema,
1064
1183
  name: (_f = responseFormat.name) != null ? _f : "response",
1065
1184
  description: responseFormat.description
@@ -1476,7 +1595,7 @@ function convertOpenAICompletionUsage(usage) {
1476
1595
  // src/completion/convert-to-openai-completion-prompt.ts
1477
1596
  import {
1478
1597
  InvalidPromptError,
1479
- UnsupportedFunctionalityError as UnsupportedFunctionalityError3
1598
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError4
1480
1599
  } from "@ai-sdk/provider";
1481
1600
  function convertToOpenAICompletionPrompt({
1482
1601
  prompt,
@@ -1519,7 +1638,7 @@ ${userMessage}
1519
1638
  return part.text;
1520
1639
  }
1521
1640
  case "tool-call": {
1522
- throw new UnsupportedFunctionalityError3({
1641
+ throw new UnsupportedFunctionalityError4({
1523
1642
  functionality: "tool-call messages"
1524
1643
  });
1525
1644
  }
@@ -1532,7 +1651,7 @@ ${assistantMessage}
1532
1651
  break;
1533
1652
  }
1534
1653
  case "tool": {
1535
- throw new UnsupportedFunctionalityError3({
1654
+ throw new UnsupportedFunctionalityError4({
1536
1655
  functionality: "tool messages"
1537
1656
  });
1538
1657
  }
@@ -2424,7 +2543,7 @@ async function fileToBlob(file) {
2424
2543
 
2425
2544
  // src/transcription/openai-transcription-model.ts
2426
2545
  import {
2427
- UnsupportedFunctionalityError as UnsupportedFunctionalityError4
2546
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError5
2428
2547
  } from "@ai-sdk/provider";
2429
2548
  import {
2430
2549
  combineHeaders as combineHeaders5,
@@ -2714,7 +2833,7 @@ var OpenAITranscriptionModel = class _OpenAITranscriptionModel {
2714
2833
  async doGenerate(options) {
2715
2834
  var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2716
2835
  if (isRealtimeTranscriptionModelId(this.modelId)) {
2717
- throw new UnsupportedFunctionalityError4({
2836
+ throw new UnsupportedFunctionalityError5({
2718
2837
  functionality: `non-streaming transcription with ${this.modelId}`
2719
2838
  });
2720
2839
  }
@@ -2781,7 +2900,7 @@ var OpenAITranscriptionModel = class _OpenAITranscriptionModel {
2781
2900
  async doStream(options) {
2782
2901
  var _a2, _b, _c, _d, _e, _f, _g;
2783
2902
  if (!isRealtimeTranscriptionModelId(this.modelId)) {
2784
- throw new UnsupportedFunctionalityError4({
2903
+ throw new UnsupportedFunctionalityError5({
2785
2904
  functionality: `streaming transcription with ${this.modelId}`
2786
2905
  });
2787
2906
  }
@@ -3226,7 +3345,7 @@ function convertOpenAIResponsesUsage(usage) {
3226
3345
 
3227
3346
  // src/responses/convert-to-openai-responses-input.ts
3228
3347
  import {
3229
- UnsupportedFunctionalityError as UnsupportedFunctionalityError5
3348
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError6
3230
3349
  } from "@ai-sdk/provider";
3231
3350
  import {
3232
3351
  convertToBase64 as convertToBase643,
@@ -4006,7 +4125,7 @@ async function convertToOpenAIResponsesInput({
4006
4125
  };
4007
4126
  }
4008
4127
  case "text": {
4009
- throw new UnsupportedFunctionalityError5({
4128
+ throw new UnsupportedFunctionalityError6({
4010
4129
  functionality: "text file parts"
4011
4130
  });
4012
4131
  }
@@ -4036,7 +4155,7 @@ async function convertToOpenAIResponsesInput({
4036
4155
  }
4037
4156
  const fullMediaType = resolveFullMediaType2({ part });
4038
4157
  if (fullMediaType !== "application/pdf" && !passThroughUnsupportedFiles) {
4039
- throw new UnsupportedFunctionalityError5({
4158
+ throw new UnsupportedFunctionalityError6({
4040
4159
  functionality: `file part media type ${fullMediaType}`
4041
4160
  });
4042
4161
  }
@@ -4772,7 +4891,7 @@ ${text}`,
4772
4891
  }
4773
4892
  const resultCaller = (_P = (_O = part.providerOptions) == null ? void 0 : _O[providerOptionsName]) == null ? void 0 : _P.caller;
4774
4893
  if (output.type === "execution-denied" && ((resultCaller == null ? void 0 : resultCaller.type) === "program" || programmaticToolCallIds.has(part.toolCallId))) {
4775
- throw new UnsupportedFunctionalityError5({
4894
+ throw new UnsupportedFunctionalityError6({
4776
4895
  functionality: "execution-denied results for programmatic tool calls"
4777
4896
  });
4778
4897
  }
@@ -5996,6 +6115,14 @@ var openaiLanguageModelResponsesOptionsSchema = lazySchema19(
5996
6115
  "message.output_text.logprobs"
5997
6116
  ])
5998
6117
  ).nullish(),
6118
+ /**
6119
+ * Whether to automatically include web search action sources in the
6120
+ * response. Disable this for OpenAI-compatible providers that do not
6121
+ * support the `web_search_call.action.sources` include value.
6122
+ *
6123
+ * Defaults to `true`.
6124
+ */
6125
+ includeWebSearchSources: z21.boolean().optional(),
5999
6126
  /**
6000
6127
  * Instructions for the model.
6001
6128
  * They can be used to change the system or developer message when continuing a conversation using the `previousResponseId` option.
@@ -6195,7 +6322,7 @@ var openaiLanguageModelResponsesOptionsSchema = lazySchema19(
6195
6322
 
6196
6323
  // src/responses/openai-responses-prepare-tools.ts
6197
6324
  import {
6198
- UnsupportedFunctionalityError as UnsupportedFunctionalityError6
6325
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError7
6199
6326
  } from "@ai-sdk/provider";
6200
6327
  import {
6201
6328
  resolveProviderReference as resolveProviderReference3,
@@ -6599,6 +6726,7 @@ async function prepareResponsesTools({
6599
6726
  const openaiFunctionTool = prepareFunctionTool({
6600
6727
  tool,
6601
6728
  options: openaiOptions,
6729
+ toolWarnings,
6602
6730
  async: resolveAsyncToolOption({
6603
6731
  value: openaiOptions == null ? void 0 : openaiOptions.async,
6604
6732
  supportsAsyncToolCalling,
@@ -6621,7 +6749,7 @@ async function prepareResponsesTools({
6621
6749
  namespaceTools.set(namespace.name, namespaceTool);
6622
6750
  openaiTools.push(namespaceTool);
6623
6751
  } else if (namespaceTool.description !== namespace.description) {
6624
- throw new UnsupportedFunctionalityError6({
6752
+ throw new UnsupportedFunctionalityError7({
6625
6753
  functionality: `conflicting descriptions for OpenAI tool namespace "${namespace.name}"`
6626
6754
  });
6627
6755
  }
@@ -6888,7 +7016,7 @@ async function prepareResponsesTools({
6888
7016
  allowedToolEntries.push(resolution.entry);
6889
7017
  }
6890
7018
  if (allowedToolEntries.length === 0) {
6891
- throw new UnsupportedFunctionalityError6({
7019
+ throw new UnsupportedFunctionalityError7({
6892
7020
  functionality: `allowedTools with only tools that cannot be allow-listed (${droppedToolNames.join(
6893
7021
  ", "
6894
7022
  )})`
@@ -6923,7 +7051,7 @@ async function prepareResponsesTools({
6923
7051
  }
6924
7052
  default: {
6925
7053
  const _exhaustiveCheck = type;
6926
- throw new UnsupportedFunctionalityError6({
7054
+ throw new UnsupportedFunctionalityError7({
6927
7055
  functionality: `tool choice type: ${_exhaustiveCheck}`
6928
7056
  });
6929
7057
  }
@@ -6979,19 +7107,27 @@ function toAllowedToolResolution(tool) {
6979
7107
  function prepareFunctionTool({
6980
7108
  tool,
6981
7109
  options,
7110
+ toolWarnings,
6982
7111
  async
6983
7112
  }) {
7113
+ var _a2;
6984
7114
  const deferLoading = options == null ? void 0 : options.deferLoading;
7115
+ const normalizedInputSchema = normalizeOpenAIJsonSchema(tool.inputSchema);
7116
+ const normalizedOutputSchema = (options == null ? void 0 : options.outputSchema) != null ? normalizeOpenAIJsonSchema(options.outputSchema) : void 0;
7117
+ toolWarnings.push(
7118
+ ...normalizedInputSchema.warnings,
7119
+ ...(_a2 = normalizedOutputSchema == null ? void 0 : normalizedOutputSchema.warnings) != null ? _a2 : []
7120
+ );
6985
7121
  return {
6986
7122
  type: "function",
6987
7123
  name: tool.name,
6988
7124
  description: tool.description,
6989
- parameters: tool.inputSchema,
7125
+ parameters: normalizedInputSchema.schema,
6990
7126
  ...async != null ? { async } : {},
6991
7127
  ...tool.strict != null ? { strict: tool.strict } : {},
6992
7128
  ...deferLoading != null ? { defer_loading: deferLoading } : {},
6993
7129
  ...(options == null ? void 0 : options.allowedCallers) != null ? { allowed_callers: options.allowedCallers } : {},
6994
- ...(options == null ? void 0 : options.outputSchema) != null ? { output_schema: options.outputSchema } : {}
7130
+ ...(options == null ? void 0 : options.outputSchema) != null ? { output_schema: normalizedOutputSchema == null ? void 0 : normalizedOutputSchema.schema } : {}
6995
7131
  };
6996
7132
  }
6997
7133
  function resolveAsyncToolOption({
@@ -7314,6 +7450,10 @@ var OpenAIResponsesLanguageModel = class _OpenAIResponsesLanguageModel {
7314
7450
  input.push({ type: "compaction_trigger" });
7315
7451
  }
7316
7452
  const strictJsonSchema = (_g = openaiOptions == null ? void 0 : openaiOptions.strictJsonSchema) != null ? _g : true;
7453
+ const normalizedResponseFormatSchema = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? normalizeOpenAIJsonSchema(responseFormat.schema) : void 0;
7454
+ if (normalizedResponseFormatSchema != null) {
7455
+ warnings.push(...normalizedResponseFormatSchema.warnings);
7456
+ }
7317
7457
  let include = openaiOptions == null ? void 0 : openaiOptions.include;
7318
7458
  function addInclude(key) {
7319
7459
  if (include == null) {
@@ -7336,7 +7476,7 @@ var OpenAIResponsesLanguageModel = class _OpenAIResponsesLanguageModel {
7336
7476
  const webSearchToolName = (_h = tools == null ? void 0 : tools.find(
7337
7477
  (tool) => tool.type === "provider" && (tool.id === "openai.web_search" || tool.id === "openai.web_search_preview")
7338
7478
  )) == null ? void 0 : _h.name;
7339
- if (webSearchToolName) {
7479
+ if (webSearchToolName && config.supportsWebSearchSourcesInclude !== false && (openaiOptions == null ? void 0 : openaiOptions.includeWebSearchSources) !== false) {
7340
7480
  addInclude("web_search_call.action.sources");
7341
7481
  }
7342
7482
  if (hasOpenAITool("openai.code_interpreter")) {
@@ -7355,12 +7495,12 @@ var OpenAIResponsesLanguageModel = class _OpenAIResponsesLanguageModel {
7355
7495
  ...((responseFormat == null ? void 0 : responseFormat.type) === "json" || (openaiOptions == null ? void 0 : openaiOptions.textVerbosity)) && {
7356
7496
  text: {
7357
7497
  ...(responseFormat == null ? void 0 : responseFormat.type) === "json" && {
7358
- format: responseFormat.schema != null ? {
7498
+ format: normalizedResponseFormatSchema != null ? {
7359
7499
  type: "json_schema",
7360
7500
  strict: strictJsonSchema,
7361
7501
  name: (_i = responseFormat.name) != null ? _i : "response",
7362
7502
  description: responseFormat.description,
7363
- schema: responseFormat.schema
7503
+ schema: normalizedResponseFormatSchema.schema
7364
7504
  } : { type: "json_object" }
7365
7505
  },
7366
7506
  ...(openaiOptions == null ? void 0 : openaiOptions.textVerbosity) && {