@ai-sdk/openai 2.0.49 → 2.0.51

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,17 @@
1
1
  # @ai-sdk/openai
2
2
 
3
+ ## 2.0.51
4
+
5
+ ### Patch Changes
6
+
7
+ - cad5c1d: fix(provider/openai): fix web search tool input types
8
+
9
+ ## 2.0.50
10
+
11
+ ### Patch Changes
12
+
13
+ - c336b43: feat(provider/openai): send assistant text and tool call parts as reference ids when store: true
14
+
3
15
  ## 2.0.49
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -28,7 +28,44 @@ type OpenAIEmbeddingModelId = 'text-embedding-3-small' | 'text-embedding-3-large
28
28
 
29
29
  type OpenAIImageModelId = 'dall-e-3' | 'dall-e-2' | 'gpt-image-1' | 'gpt-image-1-mini' | (string & {});
30
30
 
31
- declare const webSearchToolFactory: _ai_sdk_provider_utils.ProviderDefinedToolFactory<{}, {
31
+ declare const webSearchToolFactory: _ai_sdk_provider_utils.ProviderDefinedToolFactoryWithOutputSchema<{}, {
32
+ /**
33
+ * An object describing the specific action taken in this web search call.
34
+ * Includes details on how the model used the web (search, open_page, find).
35
+ */
36
+ action: {
37
+ /**
38
+ * Action type "search" - Performs a web search query.
39
+ */
40
+ type: "search";
41
+ /**
42
+ * The search query.
43
+ */
44
+ query?: string;
45
+ } | {
46
+ /**
47
+ * Action type "openPage" - Opens a specific URL from search results.
48
+ */
49
+ type: "openPage";
50
+ /**
51
+ * The URL opened by the model.
52
+ */
53
+ url: string;
54
+ } | {
55
+ /**
56
+ * Action type "find": Searches for a pattern within a loaded page.
57
+ */
58
+ type: "find";
59
+ /**
60
+ * The URL of the page searched for the pattern.
61
+ */
62
+ url: string;
63
+ /**
64
+ * The pattern or text to search for within the page.
65
+ */
66
+ pattern: string;
67
+ };
68
+ }, {
32
69
  /**
33
70
  * Filters for the search.
34
71
  */
@@ -221,7 +258,19 @@ declare const openaiTools: {
221
258
  *
222
259
  * @deprecated Use `webSearch` instead.
223
260
  */
224
- webSearchPreview: _ai_sdk_provider_utils.ProviderDefinedToolFactory<{}, {
261
+ webSearchPreview: _ai_sdk_provider_utils.ProviderDefinedToolFactoryWithOutputSchema<{}, {
262
+ action: {
263
+ type: "search";
264
+ query?: string;
265
+ } | {
266
+ type: "openPage";
267
+ url: string;
268
+ } | {
269
+ type: "find";
270
+ url: string;
271
+ pattern: string;
272
+ };
273
+ }, {
225
274
  searchContextSize?: "low" | "medium" | "high";
226
275
  userLocation?: {
227
276
  type: "approximate";
@@ -241,7 +290,19 @@ declare const openaiTools: {
241
290
  * @param searchContextSize - The search context size to use for the web search.
242
291
  * @param userLocation - The user location to use for the web search.
243
292
  */
244
- webSearch: (args?: Parameters<typeof webSearchToolFactory>[0]) => _ai_sdk_provider_utils.Tool<{}, unknown>;
293
+ webSearch: (args?: Parameters<typeof webSearchToolFactory>[0]) => _ai_sdk_provider_utils.Tool<{}, {
294
+ action: {
295
+ type: "search";
296
+ query?: string;
297
+ } | {
298
+ type: "openPage";
299
+ url: string;
300
+ } | {
301
+ type: "find";
302
+ url: string;
303
+ pattern: string;
304
+ };
305
+ }>;
245
306
  };
246
307
 
247
308
  type OpenAIResponsesModelId = 'chatgpt-4o-latest' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo' | 'gpt-4-0613' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo' | 'gpt-4.1-2025-04-14' | 'gpt-4.1-mini-2025-04-14' | 'gpt-4.1-mini' | 'gpt-4.1-nano-2025-04-14' | 'gpt-4.1-nano' | 'gpt-4.1' | 'gpt-4' | 'gpt-4o-2024-05-13' | 'gpt-4o-2024-08-06' | 'gpt-4o-2024-11-20' | 'gpt-4o-mini-2024-07-18' | 'gpt-4o-mini' | 'gpt-4o' | 'gpt-5-2025-08-07' | 'gpt-5-chat-latest' | 'gpt-5-codex' | 'gpt-5-mini-2025-08-07' | 'gpt-5-mini' | 'gpt-5-nano-2025-08-07' | 'gpt-5-nano' | 'gpt-5-pro-2025-10-06' | 'gpt-5-pro' | 'gpt-5' | 'o1-2024-12-17' | 'o1' | 'o3-2025-04-16' | 'o3-mini-2025-01-31' | 'o3-mini' | 'o3' | (string & {});
package/dist/index.d.ts CHANGED
@@ -28,7 +28,44 @@ type OpenAIEmbeddingModelId = 'text-embedding-3-small' | 'text-embedding-3-large
28
28
 
29
29
  type OpenAIImageModelId = 'dall-e-3' | 'dall-e-2' | 'gpt-image-1' | 'gpt-image-1-mini' | (string & {});
30
30
 
31
- declare const webSearchToolFactory: _ai_sdk_provider_utils.ProviderDefinedToolFactory<{}, {
31
+ declare const webSearchToolFactory: _ai_sdk_provider_utils.ProviderDefinedToolFactoryWithOutputSchema<{}, {
32
+ /**
33
+ * An object describing the specific action taken in this web search call.
34
+ * Includes details on how the model used the web (search, open_page, find).
35
+ */
36
+ action: {
37
+ /**
38
+ * Action type "search" - Performs a web search query.
39
+ */
40
+ type: "search";
41
+ /**
42
+ * The search query.
43
+ */
44
+ query?: string;
45
+ } | {
46
+ /**
47
+ * Action type "openPage" - Opens a specific URL from search results.
48
+ */
49
+ type: "openPage";
50
+ /**
51
+ * The URL opened by the model.
52
+ */
53
+ url: string;
54
+ } | {
55
+ /**
56
+ * Action type "find": Searches for a pattern within a loaded page.
57
+ */
58
+ type: "find";
59
+ /**
60
+ * The URL of the page searched for the pattern.
61
+ */
62
+ url: string;
63
+ /**
64
+ * The pattern or text to search for within the page.
65
+ */
66
+ pattern: string;
67
+ };
68
+ }, {
32
69
  /**
33
70
  * Filters for the search.
34
71
  */
@@ -221,7 +258,19 @@ declare const openaiTools: {
221
258
  *
222
259
  * @deprecated Use `webSearch` instead.
223
260
  */
224
- webSearchPreview: _ai_sdk_provider_utils.ProviderDefinedToolFactory<{}, {
261
+ webSearchPreview: _ai_sdk_provider_utils.ProviderDefinedToolFactoryWithOutputSchema<{}, {
262
+ action: {
263
+ type: "search";
264
+ query?: string;
265
+ } | {
266
+ type: "openPage";
267
+ url: string;
268
+ } | {
269
+ type: "find";
270
+ url: string;
271
+ pattern: string;
272
+ };
273
+ }, {
225
274
  searchContextSize?: "low" | "medium" | "high";
226
275
  userLocation?: {
227
276
  type: "approximate";
@@ -241,7 +290,19 @@ declare const openaiTools: {
241
290
  * @param searchContextSize - The search context size to use for the web search.
242
291
  * @param userLocation - The user location to use for the web search.
243
292
  */
244
- webSearch: (args?: Parameters<typeof webSearchToolFactory>[0]) => _ai_sdk_provider_utils.Tool<{}, unknown>;
293
+ webSearch: (args?: Parameters<typeof webSearchToolFactory>[0]) => _ai_sdk_provider_utils.Tool<{}, {
294
+ action: {
295
+ type: "search";
296
+ query?: string;
297
+ } | {
298
+ type: "openPage";
299
+ url: string;
300
+ } | {
301
+ type: "find";
302
+ url: string;
303
+ pattern: string;
304
+ };
305
+ }>;
245
306
  };
246
307
 
247
308
  type OpenAIResponsesModelId = 'chatgpt-4o-latest' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo' | 'gpt-4-0613' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo' | 'gpt-4.1-2025-04-14' | 'gpt-4.1-mini-2025-04-14' | 'gpt-4.1-mini' | 'gpt-4.1-nano-2025-04-14' | 'gpt-4.1-nano' | 'gpt-4.1' | 'gpt-4' | 'gpt-4o-2024-05-13' | 'gpt-4o-2024-08-06' | 'gpt-4o-2024-11-20' | 'gpt-4o-mini-2024-07-18' | 'gpt-4o-mini' | 'gpt-4o' | 'gpt-5-2025-08-07' | 'gpt-5-chat-latest' | 'gpt-5-codex' | 'gpt-5-mini-2025-08-07' | 'gpt-5-mini' | 'gpt-5-nano-2025-08-07' | 'gpt-5-nano' | 'gpt-5-pro-2025-10-06' | 'gpt-5-pro' | 'gpt-5' | 'o1-2024-12-17' | 'o1' | 'o3-2025-04-16' | 'o3-mini-2025-01-31' | 'o3-mini' | 'o3' | (string & {});
package/dist/index.js CHANGED
@@ -1916,9 +1916,7 @@ var import_v413 = require("zod/v4");
1916
1916
  var webSearchArgsSchema = (0, import_provider_utils18.lazySchema)(
1917
1917
  () => (0, import_provider_utils18.zodSchema)(
1918
1918
  import_v413.z.object({
1919
- filters: import_v413.z.object({
1920
- allowedDomains: import_v413.z.array(import_v413.z.string()).optional()
1921
- }).optional(),
1919
+ filters: import_v413.z.object({ allowedDomains: import_v413.z.array(import_v413.z.string()).optional() }).optional(),
1922
1920
  searchContextSize: import_v413.z.enum(["low", "medium", "high"]).optional(),
1923
1921
  userLocation: import_v413.z.object({
1924
1922
  type: import_v413.z.literal("approximate"),
@@ -1930,16 +1928,17 @@ var webSearchArgsSchema = (0, import_provider_utils18.lazySchema)(
1930
1928
  })
1931
1929
  )
1932
1930
  );
1933
- var webSearchInputSchema = (0, import_provider_utils18.lazySchema)(
1931
+ var webSearchInputSchema = (0, import_provider_utils18.lazySchema)(() => (0, import_provider_utils18.zodSchema)(import_v413.z.object({})));
1932
+ var webSearchOutputSchema = (0, import_provider_utils18.lazySchema)(
1934
1933
  () => (0, import_provider_utils18.zodSchema)(
1935
1934
  import_v413.z.object({
1936
1935
  action: import_v413.z.discriminatedUnion("type", [
1937
1936
  import_v413.z.object({
1938
1937
  type: import_v413.z.literal("search"),
1939
- query: import_v413.z.string().nullish()
1938
+ query: import_v413.z.string().optional()
1940
1939
  }),
1941
1940
  import_v413.z.object({
1942
- type: import_v413.z.literal("open_page"),
1941
+ type: import_v413.z.literal("openPage"),
1943
1942
  url: import_v413.z.string()
1944
1943
  }),
1945
1944
  import_v413.z.object({
@@ -1947,18 +1946,17 @@ var webSearchInputSchema = (0, import_provider_utils18.lazySchema)(
1947
1946
  url: import_v413.z.string(),
1948
1947
  pattern: import_v413.z.string()
1949
1948
  })
1950
- ]).nullish()
1949
+ ])
1951
1950
  })
1952
1951
  )
1953
1952
  );
1954
- var webSearchToolFactory = (0, import_provider_utils18.createProviderDefinedToolFactory)({
1953
+ var webSearchToolFactory = (0, import_provider_utils18.createProviderDefinedToolFactoryWithOutputSchema)({
1955
1954
  id: "openai.web_search",
1956
1955
  name: "web_search",
1957
- inputSchema: webSearchInputSchema
1956
+ inputSchema: webSearchInputSchema,
1957
+ outputSchema: webSearchOutputSchema
1958
1958
  });
1959
- var webSearch = (args = {}) => {
1960
- return webSearchToolFactory(args);
1961
- };
1959
+ var webSearch = (args = {}) => webSearchToolFactory(args);
1962
1960
 
1963
1961
  // src/tool/web-search-preview.ts
1964
1962
  var import_provider_utils19 = require("@ai-sdk/provider-utils");
@@ -1966,51 +1964,30 @@ var import_v414 = require("zod/v4");
1966
1964
  var webSearchPreviewArgsSchema = (0, import_provider_utils19.lazySchema)(
1967
1965
  () => (0, import_provider_utils19.zodSchema)(
1968
1966
  import_v414.z.object({
1969
- /**
1970
- * Search context size to use for the web search.
1971
- * - high: Most comprehensive context, highest cost, slower response
1972
- * - medium: Balanced context, cost, and latency (default)
1973
- * - low: Least context, lowest cost, fastest response
1974
- */
1975
1967
  searchContextSize: import_v414.z.enum(["low", "medium", "high"]).optional(),
1976
- /**
1977
- * User location information to provide geographically relevant search results.
1978
- */
1979
1968
  userLocation: import_v414.z.object({
1980
- /**
1981
- * Type of location (always 'approximate')
1982
- */
1983
1969
  type: import_v414.z.literal("approximate"),
1984
- /**
1985
- * Two-letter ISO country code (e.g., 'US', 'GB')
1986
- */
1987
1970
  country: import_v414.z.string().optional(),
1988
- /**
1989
- * City name (free text, e.g., 'Minneapolis')
1990
- */
1991
1971
  city: import_v414.z.string().optional(),
1992
- /**
1993
- * Region name (free text, e.g., 'Minnesota')
1994
- */
1995
1972
  region: import_v414.z.string().optional(),
1996
- /**
1997
- * IANA timezone (e.g., 'America/Chicago')
1998
- */
1999
1973
  timezone: import_v414.z.string().optional()
2000
1974
  }).optional()
2001
1975
  })
2002
1976
  )
2003
1977
  );
2004
1978
  var webSearchPreviewInputSchema = (0, import_provider_utils19.lazySchema)(
1979
+ () => (0, import_provider_utils19.zodSchema)(import_v414.z.object({}))
1980
+ );
1981
+ var webSearchPreviewOutputSchema = (0, import_provider_utils19.lazySchema)(
2005
1982
  () => (0, import_provider_utils19.zodSchema)(
2006
1983
  import_v414.z.object({
2007
1984
  action: import_v414.z.discriminatedUnion("type", [
2008
1985
  import_v414.z.object({
2009
1986
  type: import_v414.z.literal("search"),
2010
- query: import_v414.z.string().nullish()
1987
+ query: import_v414.z.string().optional()
2011
1988
  }),
2012
1989
  import_v414.z.object({
2013
- type: import_v414.z.literal("open_page"),
1990
+ type: import_v414.z.literal("openPage"),
2014
1991
  url: import_v414.z.string()
2015
1992
  }),
2016
1993
  import_v414.z.object({
@@ -2018,14 +1995,15 @@ var webSearchPreviewInputSchema = (0, import_provider_utils19.lazySchema)(
2018
1995
  url: import_v414.z.string(),
2019
1996
  pattern: import_v414.z.string()
2020
1997
  })
2021
- ]).nullish()
1998
+ ])
2022
1999
  })
2023
2000
  )
2024
2001
  );
2025
- var webSearchPreview = (0, import_provider_utils19.createProviderDefinedToolFactory)({
2002
+ var webSearchPreview = (0, import_provider_utils19.createProviderDefinedToolFactoryWithOutputSchema)({
2026
2003
  id: "openai.web_search_preview",
2027
2004
  name: "web_search_preview",
2028
- inputSchema: webSearchPreviewInputSchema
2005
+ inputSchema: webSearchPreviewInputSchema,
2006
+ outputSchema: webSearchPreviewOutputSchema
2029
2007
  });
2030
2008
 
2031
2009
  // src/openai-tools.ts
@@ -2120,7 +2098,7 @@ async function convertToOpenAIResponsesInput({
2120
2098
  store,
2121
2099
  hasLocalShellTool = false
2122
2100
  }) {
2123
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2101
+ var _a, _b, _c, _d;
2124
2102
  const input = [];
2125
2103
  const warnings = [];
2126
2104
  for (const { role, content } of prompt) {
@@ -2201,10 +2179,15 @@ async function convertToOpenAIResponsesInput({
2201
2179
  for (const part of content) {
2202
2180
  switch (part.type) {
2203
2181
  case "text": {
2182
+ const id = (_b = (_a = part.providerOptions) == null ? void 0 : _a.openai) == null ? void 0 : _b.itemId;
2183
+ if (store && id != null) {
2184
+ input.push({ type: "item_reference", id });
2185
+ break;
2186
+ }
2204
2187
  input.push({
2205
2188
  role: "assistant",
2206
2189
  content: [{ type: "output_text", text: part.text }],
2207
- id: (_c = (_b = (_a = part.providerOptions) == null ? void 0 : _a.openai) == null ? void 0 : _b.itemId) != null ? _c : void 0
2190
+ id
2208
2191
  });
2209
2192
  break;
2210
2193
  }
@@ -2213,6 +2196,11 @@ async function convertToOpenAIResponsesInput({
2213
2196
  if (part.providerExecuted) {
2214
2197
  break;
2215
2198
  }
2199
+ const id = (_d = (_c = part.providerOptions) == null ? void 0 : _c.openai) == null ? void 0 : _d.itemId;
2200
+ if (store && id != null) {
2201
+ input.push({ type: "item_reference", id });
2202
+ break;
2203
+ }
2216
2204
  if (hasLocalShellTool && part.toolName === "local_shell") {
2217
2205
  const parsedInput = await (0, import_provider_utils20.validateTypes)({
2218
2206
  value: part.input,
@@ -2221,7 +2209,7 @@ async function convertToOpenAIResponsesInput({
2221
2209
  input.push({
2222
2210
  type: "local_shell_call",
2223
2211
  call_id: part.toolCallId,
2224
- id: (_f = (_e = (_d = part.providerOptions) == null ? void 0 : _d.openai) == null ? void 0 : _e.itemId) != null ? _f : void 0,
2212
+ id,
2225
2213
  action: {
2226
2214
  type: "exec",
2227
2215
  command: parsedInput.action.command,
@@ -2238,7 +2226,7 @@ async function convertToOpenAIResponsesInput({
2238
2226
  call_id: part.toolCallId,
2239
2227
  name: part.toolName,
2240
2228
  arguments: JSON.stringify(part.input),
2241
- id: (_i = (_h = (_g = part.providerOptions) == null ? void 0 : _g.openai) == null ? void 0 : _h.itemId) != null ? _i : void 0
2229
+ id
2242
2230
  });
2243
2231
  break;
2244
2232
  }
@@ -2461,11 +2449,7 @@ var openaiResponsesChunkSchema = (0, import_provider_utils21.lazyValidator)(
2461
2449
  import_v416.z.object({
2462
2450
  type: import_v416.z.literal("web_search_call"),
2463
2451
  id: import_v416.z.string(),
2464
- status: import_v416.z.string(),
2465
- action: import_v416.z.object({
2466
- type: import_v416.z.literal("search"),
2467
- query: import_v416.z.string().optional()
2468
- }).nullish()
2452
+ status: import_v416.z.string()
2469
2453
  }),
2470
2454
  import_v416.z.object({
2471
2455
  type: import_v416.z.literal("computer_call"),
@@ -2551,7 +2535,7 @@ var openaiResponsesChunkSchema = (0, import_provider_utils21.lazyValidator)(
2551
2535
  url: import_v416.z.string(),
2552
2536
  pattern: import_v416.z.string()
2553
2537
  })
2554
- ]).nullish()
2538
+ ])
2555
2539
  }),
2556
2540
  import_v416.z.object({
2557
2541
  type: import_v416.z.literal("file_search_call"),
@@ -2732,7 +2716,7 @@ var openaiResponsesResponseSchema = (0, import_provider_utils21.lazyValidator)(
2732
2716
  url: import_v416.z.string(),
2733
2717
  pattern: import_v416.z.string()
2734
2718
  })
2735
- ]).nullish()
2719
+ ])
2736
2720
  }),
2737
2721
  import_v416.z.object({
2738
2722
  type: import_v416.z.literal("file_search_call"),
@@ -3430,14 +3414,14 @@ var OpenAIResponsesLanguageModel = class {
3430
3414
  type: "tool-call",
3431
3415
  toolCallId: part.id,
3432
3416
  toolName: webSearchToolName != null ? webSearchToolName : "web_search",
3433
- input: JSON.stringify({ action: part.action }),
3417
+ input: JSON.stringify({}),
3434
3418
  providerExecuted: true
3435
3419
  });
3436
3420
  content.push({
3437
3421
  type: "tool-result",
3438
3422
  toolCallId: part.id,
3439
3423
  toolName: webSearchToolName != null ? webSearchToolName : "web_search",
3440
- result: { status: part.status },
3424
+ result: mapWebSearchOutput(part.action),
3441
3425
  providerExecuted: true
3442
3426
  });
3443
3427
  break;
@@ -3621,6 +3605,17 @@ var OpenAIResponsesLanguageModel = class {
3621
3605
  toolName: webSearchToolName != null ? webSearchToolName : "web_search",
3622
3606
  providerExecuted: true
3623
3607
  });
3608
+ controller.enqueue({
3609
+ type: "tool-input-end",
3610
+ id: value.item.id
3611
+ });
3612
+ controller.enqueue({
3613
+ type: "tool-call",
3614
+ toolCallId: value.item.id,
3615
+ toolName: "web_search",
3616
+ input: JSON.stringify({}),
3617
+ providerExecuted: true
3618
+ });
3624
3619
  } else if (value.item.type === "computer_call") {
3625
3620
  ongoingToolCalls[value.output_index] = {
3626
3621
  toolName: "computer_use",
@@ -3714,22 +3709,11 @@ var OpenAIResponsesLanguageModel = class {
3714
3709
  });
3715
3710
  } else if (value.item.type === "web_search_call") {
3716
3711
  ongoingToolCalls[value.output_index] = void 0;
3717
- controller.enqueue({
3718
- type: "tool-input-end",
3719
- id: value.item.id
3720
- });
3721
- controller.enqueue({
3722
- type: "tool-call",
3723
- toolCallId: value.item.id,
3724
- toolName: "web_search",
3725
- input: JSON.stringify({ action: value.item.action }),
3726
- providerExecuted: true
3727
- });
3728
3712
  controller.enqueue({
3729
3713
  type: "tool-result",
3730
3714
  toolCallId: value.item.id,
3731
3715
  toolName: "web_search",
3732
- result: { status: value.item.status },
3716
+ result: mapWebSearchOutput(value.item.action),
3733
3717
  providerExecuted: true
3734
3718
  });
3735
3719
  } else if (value.item.type === "computer_call") {
@@ -4060,6 +4044,19 @@ function getResponsesModelConfig(modelId) {
4060
4044
  isReasoningModel: false
4061
4045
  };
4062
4046
  }
4047
+ function mapWebSearchOutput(action) {
4048
+ var _a;
4049
+ switch (action.type) {
4050
+ case "search":
4051
+ return { action: { type: "search", query: (_a = action.query) != null ? _a : void 0 } };
4052
+ case "open_page":
4053
+ return { action: { type: "openPage", url: action.url } };
4054
+ case "find":
4055
+ return {
4056
+ action: { type: "find", url: action.url, pattern: action.pattern }
4057
+ };
4058
+ }
4059
+ }
4063
4060
 
4064
4061
  // src/speech/openai-speech-model.ts
4065
4062
  var import_provider_utils26 = require("@ai-sdk/provider-utils");
@@ -4414,7 +4411,7 @@ var OpenAITranscriptionModel = class {
4414
4411
  };
4415
4412
 
4416
4413
  // src/version.ts
4417
- var VERSION = true ? "2.0.49" : "0.0.0-test";
4414
+ var VERSION = true ? "2.0.51" : "0.0.0-test";
4418
4415
 
4419
4416
  // src/openai-provider.ts
4420
4417
  function createOpenAI(options = {}) {