@ai-sdk/openai 2.0.12 → 2.0.14

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,19 @@
1
1
  # @ai-sdk/openai
2
2
 
3
+ ## 2.0.14
4
+
5
+ ### Patch Changes
6
+
7
+ - 7f47105: fix(provider/openai): support file_citation annotations in responses api
8
+
9
+ ## 2.0.13
10
+
11
+ ### Patch Changes
12
+
13
+ - ddc9d99: Implements `logprobs` for OpenAI `providerOptions` and `providerMetaData` in `OpenAIResponsesLanguageModel`
14
+
15
+ You can now set `providerOptions.openai.logprobs` when using `generateText()` and retrieve logprobs from the response via `result.providerMetadata?.openai`
16
+
3
17
  ## 2.0.12
4
18
 
5
19
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -161,6 +161,7 @@ declare const openaiResponsesProviderOptionsSchema: z.ZodObject<{
161
161
  include: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodEnum<{
162
162
  "reasoning.encrypted_content": "reasoning.encrypted_content";
163
163
  "file_search_call.results": "file_search_call.results";
164
+ "message.output_text.logprobs": "message.output_text.logprobs";
164
165
  }>>>>;
165
166
  textVerbosity: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
166
167
  low: "low";
@@ -169,6 +170,7 @@ declare const openaiResponsesProviderOptionsSchema: z.ZodObject<{
169
170
  }>>>;
170
171
  promptCacheKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
171
172
  safetyIdentifier: z.ZodOptional<z.ZodNullable<z.ZodString>>;
173
+ logprobs: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber]>>;
172
174
  }, z.core.$strip>;
173
175
  type OpenAIResponsesProviderOptions = z.infer<typeof openaiResponsesProviderOptionsSchema>;
174
176
 
package/dist/index.d.ts CHANGED
@@ -161,6 +161,7 @@ declare const openaiResponsesProviderOptionsSchema: z.ZodObject<{
161
161
  include: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodEnum<{
162
162
  "reasoning.encrypted_content": "reasoning.encrypted_content";
163
163
  "file_search_call.results": "file_search_call.results";
164
+ "message.output_text.logprobs": "message.output_text.logprobs";
164
165
  }>>>>;
165
166
  textVerbosity: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
166
167
  low: "low";
@@ -169,6 +170,7 @@ declare const openaiResponsesProviderOptionsSchema: z.ZodObject<{
169
170
  }>>>;
170
171
  promptCacheKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
171
172
  safetyIdentifier: z.ZodOptional<z.ZodNullable<z.ZodString>>;
173
+ logprobs: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber]>>;
172
174
  }, z.core.$strip>;
173
175
  type OpenAIResponsesProviderOptions = z.infer<typeof openaiResponsesProviderOptionsSchema>;
174
176
 
package/dist/index.js CHANGED
@@ -2127,6 +2127,19 @@ function prepareResponsesTools({
2127
2127
  }
2128
2128
 
2129
2129
  // src/responses/openai-responses-language-model.ts
2130
+ var TOP_LOGPROBS_MAX = 20;
2131
+ var LOGPROBS_SCHEMA = import_v413.z.array(
2132
+ import_v413.z.object({
2133
+ token: import_v413.z.string(),
2134
+ logprob: import_v413.z.number(),
2135
+ top_logprobs: import_v413.z.array(
2136
+ import_v413.z.object({
2137
+ token: import_v413.z.string(),
2138
+ logprob: import_v413.z.number()
2139
+ })
2140
+ )
2141
+ })
2142
+ );
2130
2143
  var OpenAIResponsesLanguageModel = class {
2131
2144
  constructor(modelId, config) {
2132
2145
  this.specificationVersion = "v2";
@@ -2190,6 +2203,8 @@ var OpenAIResponsesLanguageModel = class {
2190
2203
  schema: openaiResponsesProviderOptionsSchema
2191
2204
  });
2192
2205
  const strictJsonSchema = (_a = openaiOptions == null ? void 0 : openaiOptions.strictJsonSchema) != null ? _a : false;
2206
+ const topLogprobs = typeof (openaiOptions == null ? void 0 : openaiOptions.logprobs) === "number" ? openaiOptions == null ? void 0 : openaiOptions.logprobs : (openaiOptions == null ? void 0 : openaiOptions.logprobs) === true ? TOP_LOGPROBS_MAX : void 0;
2207
+ const openaiOptionsInclude = topLogprobs ? Array.isArray(openaiOptions == null ? void 0 : openaiOptions.include) ? [...openaiOptions == null ? void 0 : openaiOptions.include, "message.output_text.logprobs"] : ["message.output_text.logprobs"] : openaiOptions == null ? void 0 : openaiOptions.include;
2193
2208
  const baseArgs = {
2194
2209
  model: this.modelId,
2195
2210
  input: messages,
@@ -2220,9 +2235,10 @@ var OpenAIResponsesLanguageModel = class {
2220
2235
  user: openaiOptions == null ? void 0 : openaiOptions.user,
2221
2236
  instructions: openaiOptions == null ? void 0 : openaiOptions.instructions,
2222
2237
  service_tier: openaiOptions == null ? void 0 : openaiOptions.serviceTier,
2223
- include: openaiOptions == null ? void 0 : openaiOptions.include,
2238
+ include: openaiOptionsInclude,
2224
2239
  prompt_cache_key: openaiOptions == null ? void 0 : openaiOptions.promptCacheKey,
2225
2240
  safety_identifier: openaiOptions == null ? void 0 : openaiOptions.safetyIdentifier,
2241
+ top_logprobs: topLogprobs,
2226
2242
  // model-specific settings:
2227
2243
  ...modelConfig.isReasoningModel && ((openaiOptions == null ? void 0 : openaiOptions.reasoningEffort) != null || (openaiOptions == null ? void 0 : openaiOptions.reasoningSummary) != null) && {
2228
2244
  reasoning: {
@@ -2306,7 +2322,7 @@ var OpenAIResponsesLanguageModel = class {
2306
2322
  };
2307
2323
  }
2308
2324
  async doGenerate(options) {
2309
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2325
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
2310
2326
  const { args: body, warnings } = await this.getArgs(options);
2311
2327
  const url = this.config.url({
2312
2328
  path: "/responses",
@@ -2340,14 +2356,24 @@ var OpenAIResponsesLanguageModel = class {
2340
2356
  import_v413.z.object({
2341
2357
  type: import_v413.z.literal("output_text"),
2342
2358
  text: import_v413.z.string(),
2359
+ logprobs: LOGPROBS_SCHEMA.nullish(),
2343
2360
  annotations: import_v413.z.array(
2344
- import_v413.z.object({
2345
- type: import_v413.z.literal("url_citation"),
2346
- start_index: import_v413.z.number(),
2347
- end_index: import_v413.z.number(),
2348
- url: import_v413.z.string(),
2349
- title: import_v413.z.string()
2350
- })
2361
+ import_v413.z.discriminatedUnion("type", [
2362
+ import_v413.z.object({
2363
+ type: import_v413.z.literal("url_citation"),
2364
+ start_index: import_v413.z.number(),
2365
+ end_index: import_v413.z.number(),
2366
+ url: import_v413.z.string(),
2367
+ title: import_v413.z.string()
2368
+ }),
2369
+ import_v413.z.object({
2370
+ type: import_v413.z.literal("file_citation"),
2371
+ start_index: import_v413.z.number(),
2372
+ end_index: import_v413.z.number(),
2373
+ file_id: import_v413.z.string(),
2374
+ quote: import_v413.z.string()
2375
+ })
2376
+ ])
2351
2377
  )
2352
2378
  })
2353
2379
  )
@@ -2417,6 +2443,7 @@ var OpenAIResponsesLanguageModel = class {
2417
2443
  });
2418
2444
  }
2419
2445
  const content = [];
2446
+ const logprobs = [];
2420
2447
  for (const part of response.output) {
2421
2448
  switch (part.type) {
2422
2449
  case "reasoning": {
@@ -2439,6 +2466,9 @@ var OpenAIResponsesLanguageModel = class {
2439
2466
  }
2440
2467
  case "message": {
2441
2468
  for (const contentPart of part.content) {
2469
+ if (((_c = (_b = options.providerOptions) == null ? void 0 : _b.openai) == null ? void 0 : _c.logprobs) && contentPart.logprobs) {
2470
+ logprobs.push(contentPart.logprobs);
2471
+ }
2442
2472
  content.push({
2443
2473
  type: "text",
2444
2474
  text: contentPart.text,
@@ -2449,13 +2479,24 @@ var OpenAIResponsesLanguageModel = class {
2449
2479
  }
2450
2480
  });
2451
2481
  for (const annotation of contentPart.annotations) {
2452
- content.push({
2453
- type: "source",
2454
- sourceType: "url",
2455
- id: (_d = (_c = (_b = this.config).generateId) == null ? void 0 : _c.call(_b)) != null ? _d : (0, import_provider_utils12.generateId)(),
2456
- url: annotation.url,
2457
- title: annotation.title
2458
- });
2482
+ if (annotation.type === "url_citation") {
2483
+ content.push({
2484
+ type: "source",
2485
+ sourceType: "url",
2486
+ id: (_f = (_e = (_d = this.config).generateId) == null ? void 0 : _e.call(_d)) != null ? _f : (0, import_provider_utils12.generateId)(),
2487
+ url: annotation.url,
2488
+ title: annotation.title
2489
+ });
2490
+ } else if (annotation.type === "file_citation") {
2491
+ content.push({
2492
+ type: "source",
2493
+ sourceType: "document",
2494
+ id: (_i = (_h = (_g = this.config).generateId) == null ? void 0 : _h.call(_g)) != null ? _i : (0, import_provider_utils12.generateId)(),
2495
+ mediaType: "text/plain",
2496
+ title: annotation.quote,
2497
+ filename: annotation.file_id
2498
+ });
2499
+ }
2459
2500
  }
2460
2501
  }
2461
2502
  break;
@@ -2535,18 +2576,24 @@ var OpenAIResponsesLanguageModel = class {
2535
2576
  }
2536
2577
  }
2537
2578
  }
2579
+ const providerMetadata = {
2580
+ openai: { responseId: response.id }
2581
+ };
2582
+ if (logprobs.length > 0) {
2583
+ providerMetadata.openai.logprobs = logprobs;
2584
+ }
2538
2585
  return {
2539
2586
  content,
2540
2587
  finishReason: mapOpenAIResponseFinishReason({
2541
- finishReason: (_e = response.incomplete_details) == null ? void 0 : _e.reason,
2588
+ finishReason: (_j = response.incomplete_details) == null ? void 0 : _j.reason,
2542
2589
  hasToolCalls: content.some((part) => part.type === "tool-call")
2543
2590
  }),
2544
2591
  usage: {
2545
2592
  inputTokens: response.usage.input_tokens,
2546
2593
  outputTokens: response.usage.output_tokens,
2547
2594
  totalTokens: response.usage.input_tokens + response.usage.output_tokens,
2548
- reasoningTokens: (_g = (_f = response.usage.output_tokens_details) == null ? void 0 : _f.reasoning_tokens) != null ? _g : void 0,
2549
- cachedInputTokens: (_i = (_h = response.usage.input_tokens_details) == null ? void 0 : _h.cached_tokens) != null ? _i : void 0
2595
+ reasoningTokens: (_l = (_k = response.usage.output_tokens_details) == null ? void 0 : _k.reasoning_tokens) != null ? _l : void 0,
2596
+ cachedInputTokens: (_n = (_m = response.usage.input_tokens_details) == null ? void 0 : _m.cached_tokens) != null ? _n : void 0
2550
2597
  },
2551
2598
  request: { body },
2552
2599
  response: {
@@ -2556,11 +2603,7 @@ var OpenAIResponsesLanguageModel = class {
2556
2603
  headers: responseHeaders,
2557
2604
  body: rawResponse
2558
2605
  },
2559
- providerMetadata: {
2560
- openai: {
2561
- responseId: response.id
2562
- }
2563
- },
2606
+ providerMetadata,
2564
2607
  warnings
2565
2608
  };
2566
2609
  }
@@ -2590,6 +2633,7 @@ var OpenAIResponsesLanguageModel = class {
2590
2633
  outputTokens: void 0,
2591
2634
  totalTokens: void 0
2592
2635
  };
2636
+ const logprobs = [];
2593
2637
  let responseId = null;
2594
2638
  const ongoingToolCalls = {};
2595
2639
  let hasToolCalls = false;
@@ -2601,7 +2645,7 @@ var OpenAIResponsesLanguageModel = class {
2601
2645
  controller.enqueue({ type: "stream-start", warnings });
2602
2646
  },
2603
2647
  transform(chunk, controller) {
2604
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
2648
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
2605
2649
  if (options.includeRawChunks) {
2606
2650
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
2607
2651
  }
@@ -2815,6 +2859,9 @@ var OpenAIResponsesLanguageModel = class {
2815
2859
  id: value.item_id,
2816
2860
  delta: value.delta
2817
2861
  });
2862
+ if (value.logprobs) {
2863
+ logprobs.push(value.logprobs);
2864
+ }
2818
2865
  } else if (isResponseReasoningSummaryPartAddedChunk(value)) {
2819
2866
  if (value.summary_index > 0) {
2820
2867
  (_c = activeReasoning[value.item_id]) == null ? void 0 : _c.summaryParts.push(
@@ -2853,27 +2900,42 @@ var OpenAIResponsesLanguageModel = class {
2853
2900
  usage.reasoningTokens = (_h = (_g = value.response.usage.output_tokens_details) == null ? void 0 : _g.reasoning_tokens) != null ? _h : void 0;
2854
2901
  usage.cachedInputTokens = (_j = (_i = value.response.usage.input_tokens_details) == null ? void 0 : _i.cached_tokens) != null ? _j : void 0;
2855
2902
  } else if (isResponseAnnotationAddedChunk(value)) {
2856
- controller.enqueue({
2857
- type: "source",
2858
- sourceType: "url",
2859
- id: (_m = (_l = (_k = self.config).generateId) == null ? void 0 : _l.call(_k)) != null ? _m : (0, import_provider_utils12.generateId)(),
2860
- url: value.annotation.url,
2861
- title: value.annotation.title
2862
- });
2903
+ if (value.annotation.type === "url_citation") {
2904
+ controller.enqueue({
2905
+ type: "source",
2906
+ sourceType: "url",
2907
+ id: (_m = (_l = (_k = self.config).generateId) == null ? void 0 : _l.call(_k)) != null ? _m : (0, import_provider_utils12.generateId)(),
2908
+ url: value.annotation.url,
2909
+ title: value.annotation.title
2910
+ });
2911
+ } else if (value.annotation.type === "file_citation") {
2912
+ controller.enqueue({
2913
+ type: "source",
2914
+ sourceType: "document",
2915
+ id: (_p = (_o = (_n = self.config).generateId) == null ? void 0 : _o.call(_n)) != null ? _p : (0, import_provider_utils12.generateId)(),
2916
+ mediaType: "text/plain",
2917
+ title: value.annotation.quote,
2918
+ filename: value.annotation.file_id
2919
+ });
2920
+ }
2863
2921
  } else if (isErrorChunk(value)) {
2864
2922
  controller.enqueue({ type: "error", error: value });
2865
2923
  }
2866
2924
  },
2867
2925
  flush(controller) {
2926
+ const providerMetadata = {
2927
+ openai: {
2928
+ responseId
2929
+ }
2930
+ };
2931
+ if (logprobs.length > 0) {
2932
+ providerMetadata.openai.logprobs = logprobs;
2933
+ }
2868
2934
  controller.enqueue({
2869
2935
  type: "finish",
2870
2936
  finishReason,
2871
2937
  usage,
2872
- providerMetadata: {
2873
- openai: {
2874
- responseId
2875
- }
2876
- }
2938
+ providerMetadata
2877
2939
  });
2878
2940
  }
2879
2941
  })
@@ -2892,7 +2954,8 @@ var usageSchema2 = import_v413.z.object({
2892
2954
  var textDeltaChunkSchema = import_v413.z.object({
2893
2955
  type: import_v413.z.literal("response.output_text.delta"),
2894
2956
  item_id: import_v413.z.string(),
2895
- delta: import_v413.z.string()
2957
+ delta: import_v413.z.string(),
2958
+ logprobs: LOGPROBS_SCHEMA.nullish()
2896
2959
  });
2897
2960
  var errorChunkSchema = import_v413.z.object({
2898
2961
  type: import_v413.z.literal("error"),
@@ -3021,11 +3084,18 @@ var responseFunctionCallArgumentsDeltaSchema = import_v413.z.object({
3021
3084
  });
3022
3085
  var responseAnnotationAddedSchema = import_v413.z.object({
3023
3086
  type: import_v413.z.literal("response.output_text.annotation.added"),
3024
- annotation: import_v413.z.object({
3025
- type: import_v413.z.literal("url_citation"),
3026
- url: import_v413.z.string(),
3027
- title: import_v413.z.string()
3028
- })
3087
+ annotation: import_v413.z.discriminatedUnion("type", [
3088
+ import_v413.z.object({
3089
+ type: import_v413.z.literal("url_citation"),
3090
+ url: import_v413.z.string(),
3091
+ title: import_v413.z.string()
3092
+ }),
3093
+ import_v413.z.object({
3094
+ type: import_v413.z.literal("file_citation"),
3095
+ file_id: import_v413.z.string(),
3096
+ quote: import_v413.z.string()
3097
+ })
3098
+ ])
3029
3099
  });
3030
3100
  var responseReasoningSummaryPartAddedSchema = import_v413.z.object({
3031
3101
  type: import_v413.z.literal("response.reasoning_summary_part.added"),
@@ -3133,10 +3203,29 @@ var openaiResponsesProviderOptionsSchema = import_v413.z.object({
3133
3203
  instructions: import_v413.z.string().nullish(),
3134
3204
  reasoningSummary: import_v413.z.string().nullish(),
3135
3205
  serviceTier: import_v413.z.enum(["auto", "flex", "priority"]).nullish(),
3136
- include: import_v413.z.array(import_v413.z.enum(["reasoning.encrypted_content", "file_search_call.results"])).nullish(),
3206
+ include: import_v413.z.array(
3207
+ import_v413.z.enum([
3208
+ "reasoning.encrypted_content",
3209
+ "file_search_call.results",
3210
+ "message.output_text.logprobs"
3211
+ ])
3212
+ ).nullish(),
3137
3213
  textVerbosity: import_v413.z.enum(["low", "medium", "high"]).nullish(),
3138
3214
  promptCacheKey: import_v413.z.string().nullish(),
3139
- safetyIdentifier: import_v413.z.string().nullish()
3215
+ safetyIdentifier: import_v413.z.string().nullish(),
3216
+ /**
3217
+ * Return the log probabilities of the tokens.
3218
+ *
3219
+ * Setting to true will return the log probabilities of the tokens that
3220
+ * were generated.
3221
+ *
3222
+ * Setting to a number will return the log probabilities of the top n
3223
+ * tokens that were generated.
3224
+ *
3225
+ * @see https://platform.openai.com/docs/api-reference/responses/create
3226
+ * @see https://cookbook.openai.com/examples/using_logprobs
3227
+ */
3228
+ logprobs: import_v413.z.union([import_v413.z.boolean(), import_v413.z.number().min(1).max(TOP_LOGPROBS_MAX)]).optional()
3140
3229
  });
3141
3230
 
3142
3231
  // src/speech/openai-speech-model.ts