@ai-sdk/openai 3.0.135 → 3.0.137

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
@@ -370,9 +370,24 @@ function convertOpenAIChatUsage(usage) {
370
370
  import {
371
371
  UnsupportedFunctionalityError
372
372
  } from "@ai-sdk/provider";
373
- import { convertToBase64 } from "@ai-sdk/provider-utils";
373
+ import {
374
+ secureJsonParse,
375
+ stringifyWithBigIntAndCycles,
376
+ convertToBase64
377
+ } from "@ai-sdk/provider-utils";
374
378
  function serializeToolCallArguments(input) {
375
- return JSON.stringify(
379
+ if (typeof input === "string") {
380
+ try {
381
+ const parsed = secureJsonParse(input);
382
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
383
+ return "{}";
384
+ }
385
+ return input;
386
+ } catch (e) {
387
+ return "{}";
388
+ }
389
+ }
390
+ return stringifyWithBigIntAndCycles(
376
391
  typeof input === "object" && input !== null && !Array.isArray(input) ? input : {}
377
392
  );
378
393
  }
@@ -600,7 +615,7 @@ function convertToOpenAIChatMessages({
600
615
  case "content":
601
616
  case "json":
602
617
  case "error-json":
603
- contentValue = JSON.stringify(output.value);
618
+ contentValue = stringifyWithBigIntAndCycles(output.value);
604
619
  break;
605
620
  }
606
621
  messages.push({
@@ -2081,6 +2096,9 @@ var OpenAIEmbeddingModel = class {
2081
2096
  };
2082
2097
 
2083
2098
  // src/image/openai-image-model.ts
2099
+ import {
2100
+ InvalidArgumentError
2101
+ } from "@ai-sdk/provider";
2084
2102
  import {
2085
2103
  combineHeaders as combineHeaders4,
2086
2104
  convertBase64ToUint8Array,
@@ -2135,6 +2153,8 @@ var modelMaxImagesPerCall = {
2135
2153
  "gpt-image-1-mini": 10,
2136
2154
  "gpt-image-1.5": 10,
2137
2155
  "gpt-image-2": 10,
2156
+ "gpt-image-2.6-flare": 10,
2157
+ "gpt-image-2.6-sunburst": 10,
2138
2158
  "gpt-image-2.5-flare": 10,
2139
2159
  "gpt-image-2.5-flare-2026-09-08": 10,
2140
2160
  "gpt-image-2.5-sunburst": 10,
@@ -2170,6 +2190,11 @@ var baseImageModelOptionsObject = () => z9.object({
2170
2190
  * Format in which the generated image(s) are returned.
2171
2191
  */
2172
2192
  outputFormat: z9.enum(["png", "jpeg", "webp"]).optional(),
2193
+ /**
2194
+ * How much detail the model puts into the image. Supported by GPT Image
2195
+ * 2.6 models. The API defaults to `high`.
2196
+ */
2197
+ complexity: z9.enum(["low", "medium", "high"]).optional(),
2173
2198
  /**
2174
2199
  * Compression level (0-100) for the generated image(s). Applies to the
2175
2200
  * `jpeg` and `webp` output formats.
@@ -2179,7 +2204,13 @@ var baseImageModelOptionsObject = () => z9.object({
2179
2204
  * A unique identifier representing your end-user, which can help OpenAI
2180
2205
  * to monitor and detect abuse.
2181
2206
  */
2182
- user: z9.string().optional()
2207
+ user: z9.string().optional(),
2208
+ /**
2209
+ * A stable identifier used to help detect users of your application that
2210
+ * may be violating OpenAI's usage policies. Should be a hashed username
2211
+ * or email address.
2212
+ */
2213
+ safetyIdentifier: z9.string().max(128).optional()
2183
2214
  });
2184
2215
  var openaiImageModelOptions = lazySchema9(
2185
2216
  () => zodSchema9(baseImageModelOptionsObject())
@@ -2193,6 +2224,22 @@ var openaiImageModelGenerationOptions = lazySchema9(
2193
2224
  * looking images.
2194
2225
  */
2195
2226
  style: z9.enum(["vivid", "natural"]).optional(),
2227
+ /**
2228
+ * Format in which the generated image(s) are returned. `gif` produces
2229
+ * an animated GIF and is supported by GPT Image 2.6 models.
2230
+ */
2231
+ outputFormat: z9.enum(["png", "jpeg", "webp", "gif"]).optional(),
2232
+ /**
2233
+ * Number of frames (2-64) of an animated GIF. Only applies to the `gif`
2234
+ * output format. The API defaults to 9.
2235
+ */
2236
+ frameCount: z9.number().int().min(2).max(64).optional(),
2237
+ /**
2238
+ * Duration of each frame in milliseconds (20-2000) of an animated GIF.
2239
+ * The API rounds it to the nearest 10 ms. Only applies to the `gif`
2240
+ * output format. The API defaults to 200.
2241
+ */
2242
+ frameDurationMs: z9.number().int().min(20).max(2e3).optional(),
2196
2243
  /**
2197
2244
  * Content moderation level for the generated image(s). `low` applies
2198
2245
  * less restrictive filtering.
@@ -2207,7 +2254,14 @@ var openaiImageModelEditOptions = lazySchema9(
2207
2254
  /**
2208
2255
  * Fidelity of the output image(s) to the input image(s).
2209
2256
  */
2210
- inputFidelity: z9.enum(["high", "low"]).optional()
2257
+ inputFidelity: z9.enum(["high", "low"]).optional(),
2258
+ /**
2259
+ * A transparent PNG overlaid on the first input image to mark up the
2260
+ * regions to change, as an HTTPS URL or a base64 data URL. It must match
2261
+ * the dimensions of the first image. Supported by GPT Image 2.5 and 2.6
2262
+ * models. Cannot be combined with a `mask`.
2263
+ */
2264
+ markup: z9.string().optional()
2211
2265
  })
2212
2266
  )
2213
2267
  );
@@ -2256,6 +2310,12 @@ var OpenAIImageModel = class {
2256
2310
  providerOptions,
2257
2311
  schema: openaiImageModelEditOptions
2258
2312
  })) != null ? _d : {};
2313
+ if (mask != null && openaiOptions2.markup != null) {
2314
+ throw new InvalidArgumentError({
2315
+ argument: "providerOptions.openai.markup",
2316
+ message: "`markup` cannot be combined with `mask`."
2317
+ });
2318
+ }
2259
2319
  const { value: response2, responseHeaders: responseHeaders2 } = await postFormDataToApi({
2260
2320
  url: this.config.url({
2261
2321
  path: "/images/edits",
@@ -2280,14 +2340,17 @@ var OpenAIImageModel = class {
2280
2340
  )
2281
2341
  ),
2282
2342
  mask: mask != null ? await fileToBlob(mask) : void 0,
2343
+ markup: openaiOptions2.markup != null ? await markupToBlob(openaiOptions2.markup) : void 0,
2283
2344
  n,
2284
2345
  size,
2285
2346
  quality: openaiOptions2.quality,
2286
2347
  background: openaiOptions2.background,
2287
2348
  output_format: openaiOptions2.outputFormat,
2288
2349
  output_compression: openaiOptions2.outputCompression,
2350
+ complexity: openaiOptions2.complexity,
2289
2351
  input_fidelity: openaiOptions2.inputFidelity,
2290
- user: openaiOptions2.user
2352
+ user: openaiOptions2.user,
2353
+ safety_identifier: openaiOptions2.safetyIdentifier
2291
2354
  }),
2292
2355
  failedResponseHandler: openaiFailedResponseHandler,
2293
2356
  successfulResponseHandler: createJsonResponseHandler4(
@@ -2353,7 +2416,11 @@ var OpenAIImageModel = class {
2353
2416
  moderation: openaiOptions.moderation,
2354
2417
  output_format: openaiOptions.outputFormat,
2355
2418
  output_compression: openaiOptions.outputCompression,
2419
+ complexity: openaiOptions.complexity,
2420
+ frame_count: openaiOptions.frameCount,
2421
+ frame_duration_ms: openaiOptions.frameDurationMs,
2356
2422
  user: openaiOptions.user,
2423
+ safety_identifier: openaiOptions.safetyIdentifier,
2357
2424
  ...!hasDefaultResponseFormat(this.modelId) ? { response_format: "b64_json" } : {}
2358
2425
  },
2359
2426
  failedResponseHandler: openaiFailedResponseHandler,
@@ -2416,6 +2483,21 @@ function distributeTokenDetails(details, index, total) {
2416
2483
  }
2417
2484
  return result;
2418
2485
  }
2486
+ async function markupToBlob(markup) {
2487
+ const dataUrl = /^data:([^;,]*)(;base64)?,(.*)$/s.exec(markup);
2488
+ if (dataUrl == null) {
2489
+ return downloadBlob(markup);
2490
+ }
2491
+ if (dataUrl[2] == null) {
2492
+ throw new InvalidArgumentError({
2493
+ argument: "providerOptions.openai.markup",
2494
+ message: "`markup` data URLs must be base64 encoded."
2495
+ });
2496
+ }
2497
+ return new Blob([convertBase64ToUint8Array(dataUrl[3])], {
2498
+ type: dataUrl[1] || "image/png"
2499
+ });
2500
+ }
2419
2501
  async function fileToBlob(file) {
2420
2502
  if (!file) return void 0;
2421
2503
  if (file.type === "url") {
@@ -3174,6 +3256,8 @@ import {
3174
3256
  UnsupportedFunctionalityError as UnsupportedFunctionalityError4
3175
3257
  } from "@ai-sdk/provider";
3176
3258
  import {
3259
+ secureJsonParse as secureJsonParse2,
3260
+ stringifyWithBigIntAndCycles as stringifyWithBigIntAndCycles2,
3177
3261
  lazySchema as lazySchema22,
3178
3262
  zodSchema as zodSchema22,
3179
3263
  convertToBase64 as convertToBase642,
@@ -3571,7 +3655,15 @@ async function expandParallelToolCall({
3571
3655
 
3572
3656
  // src/responses/convert-to-openai-responses-input.ts
3573
3657
  function serializeToolCallArguments2(input) {
3574
- return JSON.stringify(input === void 0 ? {} : input);
3658
+ if (typeof input === "string") {
3659
+ try {
3660
+ secureJsonParse2(input);
3661
+ return input;
3662
+ } catch (e) {
3663
+ return stringifyWithBigIntAndCycles2(input);
3664
+ }
3665
+ }
3666
+ return stringifyWithBigIntAndCycles2(input === void 0 ? {} : input);
3575
3667
  }
3576
3668
  async function convertWebSearchToolResultOutput({
3577
3669
  output,
@@ -3649,7 +3741,7 @@ async function convertFunctionToolResultOutput({
3649
3741
  }
3650
3742
  case "json":
3651
3743
  case "error-json":
3652
- return convertScalarOutput(JSON.stringify(output.value));
3744
+ return convertScalarOutput(stringifyWithBigIntAndCycles2(output.value));
3653
3745
  case "content":
3654
3746
  return output.value.map((item) => {
3655
3747
  var _a3, _b, _c, _d, _e, _f, _g;
@@ -4152,7 +4244,7 @@ async function convertToOpenAIResponsesInput({
4152
4244
  type: "custom_tool_call",
4153
4245
  call_id: part.toolCallId,
4154
4246
  name: resolvedToolName,
4155
- input: typeof part.input === "string" ? part.input : JSON.stringify(part.input),
4247
+ input: typeof part.input === "string" ? part.input : stringifyWithBigIntAndCycles2(part.input),
4156
4248
  ...isAsync != null && { async: isAsync },
4157
4249
  id
4158
4250
  });
@@ -4278,7 +4370,7 @@ async function convertToOpenAIResponsesInput({
4278
4370
  } else if (reasoningMessage !== void 0) {
4279
4371
  warnings.push({
4280
4372
  type: "other",
4281
- message: `Cannot append empty reasoning part to existing reasoning sequence. Skipping reasoning part: ${JSON.stringify(part)}.`
4373
+ message: `Cannot append empty reasoning part to existing reasoning sequence. Skipping reasoning part: ${stringifyWithBigIntAndCycles2(part)}.`
4282
4374
  });
4283
4375
  }
4284
4376
  if (reasoningMessage === void 0) {
@@ -4314,7 +4406,7 @@ async function convertToOpenAIResponsesInput({
4314
4406
  } else {
4315
4407
  warnings.push({
4316
4408
  type: "other",
4317
- message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${JSON.stringify(part)}.`
4409
+ message: `Non-OpenAI reasoning parts are not supported. Skipping reasoning part: ${stringifyWithBigIntAndCycles2(part)}.`
4318
4410
  });
4319
4411
  }
4320
4412
  }
@@ -4380,7 +4472,7 @@ async function convertToOpenAIResponsesInput({
4380
4472
  })
4381
4473
  );
4382
4474
  const serializedToolOutputs = toolOutputs.map(
4383
- ({ output: output2 }) => typeof output2 === "string" ? output2 : JSON.stringify(output2)
4475
+ ({ output: output2 }) => typeof output2 === "string" ? output2 : stringifyWithBigIntAndCycles2(output2)
4384
4476
  );
4385
4477
  const hasPromptCacheBreakpoint = toolOutputs.some(
4386
4478
  ({ promptCacheBreakpoint }) => promptCacheBreakpoint != null
@@ -4496,7 +4588,9 @@ ${text}`,
4496
4588
  break;
4497
4589
  case "json":
4498
4590
  case "error-json":
4499
- outputValue = convertScalarOutput(JSON.stringify(output.value));
4591
+ outputValue = convertScalarOutput(
4592
+ stringifyWithBigIntAndCycles2(output.value)
4593
+ );
4500
4594
  break;
4501
4595
  case "content":
4502
4596
  outputValue = output.value.map((item) => {
@@ -8286,6 +8380,16 @@ var openAITranscriptionModelOptions = lazySchema26(
8286
8380
  * The language of the input audio in ISO-639-1 format.
8287
8381
  */
8288
8382
  language: z26.string().optional(),
8383
+ /**
8384
+ * Expected languages for REST transcription, e.g. with gpt-transcribe.
8385
+ * Use this instead of language. The API validates model support.
8386
+ */
8387
+ languages: z26.array(z26.string()).optional(),
8388
+ /**
8389
+ * Vocabulary hints for REST transcription, e.g. names or technical terms.
8390
+ * The API validates model support.
8391
+ */
8392
+ keywords: z26.array(z26.string()).optional(),
8289
8393
  /**
8290
8394
  * An optional text to guide the model's style or continue a previous audio segment.
8291
8395
  */
@@ -8397,6 +8501,8 @@ var OpenAITranscriptionModel = class {
8397
8501
  const transcriptionModelOptions = {
8398
8502
  include: openAIOptions.include,
8399
8503
  language: openAIOptions.language,
8504
+ languages: openAIOptions.languages,
8505
+ keywords: openAIOptions.keywords,
8400
8506
  prompt: openAIOptions.prompt,
8401
8507
  // https://platform.openai.com/docs/api-reference/audio/createTranscription#audio_createtranscription-response_format
8402
8508
  // prefer verbose_json to get segments for models that support it
@@ -8473,7 +8579,7 @@ var OpenAITranscriptionModel = class {
8473
8579
  };
8474
8580
 
8475
8581
  // src/version.ts
8476
- var VERSION = true ? "3.0.135" : "0.0.0-test";
8582
+ var VERSION = true ? "3.0.137" : "0.0.0-test";
8477
8583
 
8478
8584
  // src/openai-provider.ts
8479
8585
  function createOpenAI(options = {}) {