@core-ai/openai 0.18.0 → 0.19.0

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.
@@ -1,7 +1,9 @@
1
1
  // src/model-capabilities.ts
2
2
  import {
3
3
  getRegisteredModelCapabilities,
4
+ MULTIMODAL_INPUT_MODALITIES,
4
5
  stripModelDateSuffix,
6
+ TEXT_ONLY_MODALITIES,
5
7
  UNKNOWN_MODEL
6
8
  } from "@core-ai/core-ai";
7
9
  var STANDARD_EFFORTS = [
@@ -27,7 +29,16 @@ var PRO_EFFORTS = [
27
29
  "max"
28
30
  ];
29
31
  var HIGH_EFFORT = ["high"];
30
- function createCapabilities(supportedEfforts, restrictsSamplingParams, maxTokensParameter = "max_completion_tokens") {
32
+ var OPENAI_AUDIO_INPUT_MODALITIES = {
33
+ input: ["text", "audio"],
34
+ output: ["text"]
35
+ };
36
+ function createCapabilities({
37
+ supportedEfforts,
38
+ restrictsSamplingParams,
39
+ maxTokensParameter = "max_completion_tokens",
40
+ modalities = MULTIMODAL_INPUT_MODALITIES
41
+ }) {
31
42
  return {
32
43
  reasoning: {
33
44
  mode: "optional",
@@ -35,29 +46,45 @@ function createCapabilities(supportedEfforts, restrictsSamplingParams, maxTokens
35
46
  restrictsSamplingParams,
36
47
  supportedToolChoices: ["auto", "none", "required", "tool"]
37
48
  },
49
+ modalities,
38
50
  chatCompletions: {
39
51
  maxTokensParameter
40
52
  }
41
53
  };
42
54
  }
43
- var DEFAULT_CAPABILITIES = createCapabilities(STANDARD_EFFORTS, false);
44
- var UNKNOWN_MODEL_CAPABILITIES = createCapabilities(
45
- STANDARD_EFFORTS,
46
- false,
47
- "max_tokens"
48
- );
49
- var SAMPLING_RESTRICTED_STANDARD_CAPABILITIES = createCapabilities(
50
- STANDARD_EFFORTS,
51
- true
52
- );
53
- var GPT_5_MAX_REASONING_CAPABILITIES = createCapabilities(MAX_EFFORTS, true);
54
- var GPT_5_MINIMAL_REASONING_CAPABILITIES = createCapabilities(
55
- MINIMAL_EFFORTS,
56
- true
57
- );
58
- var GPT_5_PRO_REASONING_CAPABILITIES = createCapabilities(PRO_EFFORTS, true);
59
- var GPT_5_HIGH_REASONING_CAPABILITIES = createCapabilities(HIGH_EFFORT, true);
60
- function createNoReasoningCapabilities(maxTokensParameter) {
55
+ var DEFAULT_CAPABILITIES = createCapabilities({
56
+ supportedEfforts: STANDARD_EFFORTS,
57
+ restrictsSamplingParams: false
58
+ });
59
+ var UNKNOWN_MODEL_CAPABILITIES = createCapabilities({
60
+ supportedEfforts: STANDARD_EFFORTS,
61
+ restrictsSamplingParams: false,
62
+ maxTokensParameter: "max_tokens"
63
+ });
64
+ var SAMPLING_RESTRICTED_STANDARD_CAPABILITIES = createCapabilities({
65
+ supportedEfforts: STANDARD_EFFORTS,
66
+ restrictsSamplingParams: true
67
+ });
68
+ var GPT_5_MAX_REASONING_CAPABILITIES = createCapabilities({
69
+ supportedEfforts: MAX_EFFORTS,
70
+ restrictsSamplingParams: true
71
+ });
72
+ var GPT_5_MINIMAL_REASONING_CAPABILITIES = createCapabilities({
73
+ supportedEfforts: MINIMAL_EFFORTS,
74
+ restrictsSamplingParams: true
75
+ });
76
+ var GPT_5_PRO_REASONING_CAPABILITIES = createCapabilities({
77
+ supportedEfforts: PRO_EFFORTS,
78
+ restrictsSamplingParams: true
79
+ });
80
+ var GPT_5_HIGH_REASONING_CAPABILITIES = createCapabilities({
81
+ supportedEfforts: HIGH_EFFORT,
82
+ restrictsSamplingParams: true
83
+ });
84
+ function createNoReasoningCapabilities({
85
+ maxTokensParameter,
86
+ modalities = MULTIMODAL_INPUT_MODALITIES
87
+ }) {
61
88
  return {
62
89
  reasoning: {
63
90
  mode: "unsupported",
@@ -65,19 +92,40 @@ function createNoReasoningCapabilities(maxTokensParameter) {
65
92
  restrictsSamplingParams: false,
66
93
  supportedToolChoices: ["auto", "none", "required", "tool"]
67
94
  },
95
+ modalities,
68
96
  chatCompletions: {
69
97
  maxTokensParameter
70
98
  }
71
99
  };
72
100
  }
73
- var NO_REASONING_CAPABILITIES = createNoReasoningCapabilities("max_tokens");
74
- var NO_REASONING_EFFORT_CAPABILITIES = createNoReasoningCapabilities(
75
- "max_completion_tokens"
76
- );
77
- var O_SERIES_MAX_REASONING_CAPABILITIES = createCapabilities(
78
- MAX_EFFORTS,
79
- false
80
- );
101
+ var NO_REASONING_CAPABILITIES = createNoReasoningCapabilities({
102
+ maxTokensParameter: "max_tokens"
103
+ });
104
+ var NO_REASONING_TEXT_ONLY_CAPABILITIES = createNoReasoningCapabilities({
105
+ maxTokensParameter: "max_tokens",
106
+ modalities: TEXT_ONLY_MODALITIES
107
+ });
108
+ var NO_REASONING_EFFORT_TEXT_ONLY_CAPABILITIES = createNoReasoningCapabilities({
109
+ maxTokensParameter: "max_completion_tokens",
110
+ modalities: TEXT_ONLY_MODALITIES
111
+ });
112
+ var AUDIO_CAPABILITIES = createNoReasoningCapabilities({
113
+ maxTokensParameter: "max_completion_tokens",
114
+ modalities: OPENAI_AUDIO_INPUT_MODALITIES
115
+ });
116
+ var GPT_4O_AUDIO_CAPABILITIES = createNoReasoningCapabilities({
117
+ maxTokensParameter: "max_tokens",
118
+ modalities: OPENAI_AUDIO_INPUT_MODALITIES
119
+ });
120
+ var O_SERIES_MAX_REASONING_CAPABILITIES = createCapabilities({
121
+ supportedEfforts: MAX_EFFORTS,
122
+ restrictsSamplingParams: false
123
+ });
124
+ var O_SERIES_TEXT_ONLY_CAPABILITIES = createCapabilities({
125
+ supportedEfforts: STANDARD_EFFORTS,
126
+ restrictsSamplingParams: false,
127
+ modalities: TEXT_ONLY_MODALITIES
128
+ });
81
129
  var OPENAI_MODEL_CAPABILITIES = {
82
130
  "gpt-5.6-sol": GPT_5_MAX_REASONING_CAPABILITIES,
83
131
  "gpt-5.6-terra": SAMPLING_RESTRICTED_STANDARD_CAPABILITIES,
@@ -103,17 +151,22 @@ var OPENAI_MODEL_CAPABILITIES = {
103
151
  "gpt-5-codex": GPT_5_MAX_REASONING_CAPABILITIES,
104
152
  "o3-pro": O_SERIES_MAX_REASONING_CAPABILITIES,
105
153
  o3: DEFAULT_CAPABILITIES,
106
- "o3-mini": DEFAULT_CAPABILITIES,
154
+ "o3-mini": O_SERIES_TEXT_ONLY_CAPABILITIES,
107
155
  "o4-mini": DEFAULT_CAPABILITIES,
108
156
  o1: DEFAULT_CAPABILITIES,
109
- "o1-mini": NO_REASONING_EFFORT_CAPABILITIES,
157
+ "o1-mini": NO_REASONING_EFFORT_TEXT_ONLY_CAPABILITIES,
110
158
  "gpt-4.1": NO_REASONING_CAPABILITIES,
111
159
  "gpt-4.1-mini": NO_REASONING_CAPABILITIES,
112
160
  "gpt-4.1-nano": NO_REASONING_CAPABILITIES,
113
161
  "gpt-4o": NO_REASONING_CAPABILITIES,
114
162
  "gpt-4o-mini": NO_REASONING_CAPABILITIES,
115
163
  "gpt-4-turbo": NO_REASONING_CAPABILITIES,
116
- "gpt-3.5-turbo": NO_REASONING_CAPABILITIES,
164
+ "gpt-3.5-turbo": NO_REASONING_TEXT_ONLY_CAPABILITIES,
165
+ "gpt-audio-1.5": AUDIO_CAPABILITIES,
166
+ "gpt-audio": AUDIO_CAPABILITIES,
167
+ "gpt-audio-mini": AUDIO_CAPABILITIES,
168
+ "gpt-4o-audio-preview": GPT_4O_AUDIO_CAPABILITIES,
169
+ "gpt-4o-mini-audio-preview": GPT_4O_AUDIO_CAPABILITIES,
117
170
  [UNKNOWN_MODEL]: UNKNOWN_MODEL_CAPABILITIES
118
171
  };
119
172
  var OPENAI_REASONING_EFFORT_MAP = {
@@ -126,6 +179,20 @@ var OPENAI_REASONING_EFFORT_MAP = {
126
179
  function getOpenAIModelCapabilities(modelId) {
127
180
  return getRegisteredModelCapabilities(OPENAI_MODEL_CAPABILITIES, modelId) ?? UNKNOWN_MODEL_CAPABILITIES;
128
181
  }
182
+ function toOpenAIResponsesCapabilities(capabilities) {
183
+ if (!capabilities.modalities.input.includes("audio")) {
184
+ return capabilities;
185
+ }
186
+ return {
187
+ ...capabilities,
188
+ modalities: {
189
+ input: capabilities.modalities.input.filter(
190
+ (modality) => modality !== "audio"
191
+ ),
192
+ output: capabilities.modalities.output
193
+ }
194
+ };
195
+ }
129
196
  function toOpenAIReasoningEffort(effort) {
130
197
  return OPENAI_REASONING_EFFORT_MAP[effort];
131
198
  }
@@ -207,7 +274,12 @@ var openaiCompatGenerateProviderOptionsSchema = openaiChatGenerateProviderOption
207
274
  import { createObjectStream, createChatStream } from "@core-ai/core-ai";
208
275
 
209
276
  // src/chat-completions/chat-adapter.ts
210
- import { clampReasoningEffort, getProviderMetadata } from "@core-ai/core-ai";
277
+ import {
278
+ clampReasoningEffort,
279
+ getProviderMetadata,
280
+ ValidationError as ValidationError2,
281
+ validateInputModalities
282
+ } from "@core-ai/core-ai";
211
283
 
212
284
  // src/shared/tools.ts
213
285
  import { zodSchemaToJsonSchema } from "@core-ai/core-ai";
@@ -246,14 +318,6 @@ function safeParseJsonObject(json) {
246
318
  return {};
247
319
  }
248
320
  }
249
- function validateOpenAIReasoningConfig(modelId, options) {
250
- validateReasoningConfig(
251
- modelId,
252
- options,
253
- getOpenAIModelCapabilities(modelId),
254
- "openai"
255
- );
256
- }
257
321
  function validateReasoningConfig(modelId, options, capabilities, providerId) {
258
322
  const reasoningEnabled = options.reasoning !== void 0 || capabilities.reasoning.mode === "always-on";
259
323
  if (!reasoningEnabled) {
@@ -311,7 +375,12 @@ function convertMessage(message, adapterOptions) {
311
375
  if (message.role === "user") {
312
376
  return {
313
377
  role: "user",
314
- content: typeof message.content === "string" ? message.content : message.content.map(convertUserContentPart)
378
+ content: typeof message.content === "string" ? message.content : message.content.map(
379
+ (part) => convertUserContentPart(
380
+ part,
381
+ adapterOptions.providerId
382
+ )
383
+ )
315
384
  };
316
385
  }
317
386
  if (message.role === "assistant") {
@@ -365,7 +434,7 @@ function convertMessage(message, adapterOptions) {
365
434
  content: message.content
366
435
  };
367
436
  }
368
- function convertUserContentPart(part) {
437
+ function convertUserContentPart(part, providerId) {
369
438
  if (part.type === "text") {
370
439
  return {
371
440
  type: "text",
@@ -381,6 +450,15 @@ function convertUserContentPart(part) {
381
450
  }
382
451
  };
383
452
  }
453
+ if (part.type === "audio") {
454
+ return {
455
+ type: "input_audio",
456
+ input_audio: {
457
+ data: part.source.data,
458
+ format: toOpenAIAudioFormat(part.source.mediaType, providerId)
459
+ }
460
+ };
461
+ }
384
462
  return {
385
463
  type: "file",
386
464
  file: {
@@ -389,6 +467,22 @@ function convertUserContentPart(part) {
389
467
  }
390
468
  };
391
469
  }
470
+ var AUDIO_FORMAT_BY_MEDIA_TYPE = {
471
+ "audio/wav": "wav",
472
+ "audio/mp3": "mp3",
473
+ "audio/mpeg": "mp3"
474
+ };
475
+ function toOpenAIAudioFormat(mediaType, providerId) {
476
+ const format = AUDIO_FORMAT_BY_MEDIA_TYPE[mediaType.toLowerCase()];
477
+ if (format === void 0) {
478
+ throw new ValidationError2(
479
+ `unsupported audio media type "${mediaType}"; OpenAI Chat Completions accepts audio/wav, audio/mp3, and audio/mpeg`,
480
+ void 0,
481
+ providerId
482
+ );
483
+ }
484
+ return format;
485
+ }
392
486
  function createGenerateRequest(modelId, options, adapterOptions) {
393
487
  return createRequest(modelId, options, false, adapterOptions);
394
488
  }
@@ -419,6 +513,12 @@ function createRequestBase(modelId, options, adapterOptions) {
419
513
  adapterOptions.capabilities,
420
514
  adapterOptions.providerId
421
515
  );
516
+ validateInputModalities({
517
+ messages: options.messages,
518
+ capabilities: adapterOptions.capabilities,
519
+ modelId,
520
+ providerId: adapterOptions.providerId
521
+ });
422
522
  const reasoningFields = mapReasoningToRequestFields(
423
523
  options,
424
524
  adapterOptions.capabilities
@@ -1283,9 +1383,24 @@ import {
1283
1383
  import { createObjectStream as createObjectStream2, createChatStream as createChatStream2 } from "@core-ai/core-ai";
1284
1384
 
1285
1385
  // src/chat-adapter.ts
1286
- import { getProviderMetadata as getProviderMetadata2, clampReasoningEffort as clampReasoningEffort2 } from "@core-ai/core-ai";
1386
+ import {
1387
+ getProviderMetadata as getProviderMetadata2,
1388
+ clampReasoningEffort as clampReasoningEffort2,
1389
+ UnsupportedInputModalityError,
1390
+ ValidationError as ValidationError3,
1391
+ validateInputModalities as validateInputModalities2
1392
+ } from "@core-ai/core-ai";
1393
+ var DEFAULT_PROVIDER_ID = "openai";
1394
+ function resolveAdapterOptions(modelId, adapterOptions) {
1395
+ const capabilities = adapterOptions.capabilities ?? getOpenAIModelCapabilities(modelId);
1396
+ return {
1397
+ capabilities: toOpenAIResponsesCapabilities(capabilities),
1398
+ providerId: adapterOptions.providerId ?? DEFAULT_PROVIDER_ID
1399
+ };
1400
+ }
1287
1401
  var ENCRYPTED_REASONING_INCLUDE = "reasoning.encrypted_content";
1288
1402
  var REASONING_SUMMARY_SEPARATOR = "\n\n";
1403
+ var RESPONSES_AUDIO_REJECTION = "OpenAI Responses does not accept audio input; use provider.chat.chatModel() with an audio-capable Chat Completions model";
1289
1404
  function convertMessages2(messages, options = {}) {
1290
1405
  const includeReasoning = options.includeReasoning ?? true;
1291
1406
  return messages.flatMap(
@@ -1394,46 +1509,57 @@ function convertUserContentPart2(part) {
1394
1509
  image_url: imageUrl
1395
1510
  };
1396
1511
  }
1512
+ if (part.type === "audio") {
1513
+ throw new ValidationError3(RESPONSES_AUDIO_REJECTION);
1514
+ }
1397
1515
  return {
1398
1516
  type: "input_file",
1399
1517
  file_data: part.data,
1400
1518
  ...part.filename ? { filename: part.filename } : {}
1401
1519
  };
1402
1520
  }
1403
- function createGenerateRequest2(modelId, options) {
1521
+ function createGenerateRequest2(modelId, options, adapterOptions = {}) {
1404
1522
  return createRequest2(
1405
1523
  modelId,
1406
1524
  options,
1407
- false
1525
+ false,
1526
+ adapterOptions
1408
1527
  );
1409
1528
  }
1410
- function createStreamRequest2(modelId, options) {
1529
+ function createStreamRequest2(modelId, options, adapterOptions = {}) {
1411
1530
  return createRequest2(
1412
1531
  modelId,
1413
1532
  options,
1414
- true
1533
+ true,
1534
+ adapterOptions
1415
1535
  );
1416
1536
  }
1417
- function createRequest2(modelId, options, stream) {
1537
+ function createRequest2(modelId, options, stream, adapterOptions) {
1538
+ const resolved = resolveAdapterOptions(modelId, adapterOptions);
1418
1539
  const openaiOptions = parseOpenAIResponsesGenerateProviderOptions(
1419
1540
  options.providerOptions
1420
1541
  );
1421
1542
  const request = {
1422
- ...createRequestBase2(modelId, options),
1543
+ ...createRequestBase2(modelId, options, resolved),
1423
1544
  ...stream ? { stream: true } : {},
1424
1545
  ...options.structuredOutputFormat ? { text: { format: options.structuredOutputFormat } } : {},
1425
1546
  ...mapOpenAIProviderOptionsToRequestFields2(openaiOptions)
1426
1547
  };
1427
- if (options.reasoning && getOpenAIModelCapabilities(modelId).reasoning.mode !== "unsupported") {
1548
+ if (options.reasoning && resolved.capabilities.reasoning.mode !== "unsupported") {
1428
1549
  request.include = mergeInclude(request.include, [
1429
1550
  ENCRYPTED_REASONING_INCLUDE
1430
1551
  ]);
1431
1552
  }
1432
1553
  return request;
1433
1554
  }
1434
- function createRequestBase2(modelId, options) {
1435
- validateOpenAIReasoningConfig(modelId, options);
1436
- const capabilities = getOpenAIModelCapabilities(modelId);
1555
+ function createRequestBase2(modelId, options, { capabilities, providerId }) {
1556
+ validateReasoningConfig(modelId, options, capabilities, providerId);
1557
+ validateResponsesInputModalities({
1558
+ messages: options.messages,
1559
+ capabilities,
1560
+ modelId,
1561
+ providerId
1562
+ });
1437
1563
  return {
1438
1564
  model: modelId,
1439
1565
  store: false,
@@ -1442,10 +1568,20 @@ function createRequestBase2(modelId, options) {
1442
1568
  }),
1443
1569
  ...options.tools && Object.keys(options.tools).length > 0 ? { tools: convertResponseTools(options.tools) } : {},
1444
1570
  ...options.toolChoice ? { tool_choice: convertResponseToolChoice(options.toolChoice) } : {},
1445
- ...mapReasoningToRequestFields2(modelId, options),
1571
+ ...mapReasoningToRequestFields2(options, capabilities),
1446
1572
  ...mapSamplingToRequestFields2(options)
1447
1573
  };
1448
1574
  }
1575
+ function validateResponsesInputModalities(options) {
1576
+ try {
1577
+ validateInputModalities2(options);
1578
+ } catch (error) {
1579
+ if (error instanceof UnsupportedInputModalityError && error.unsupportedModalities.includes("audio")) {
1580
+ error.message = `${error.message}. ${RESPONSES_AUDIO_REJECTION}`;
1581
+ }
1582
+ throw error;
1583
+ }
1584
+ }
1449
1585
  function convertResponseTools(tools) {
1450
1586
  return convertTools(tools).map((tool) => ({
1451
1587
  type: "function",
@@ -1911,11 +2047,10 @@ async function* transformStream2(stream) {
1911
2047
  usage
1912
2048
  };
1913
2049
  }
1914
- function mapReasoningToRequestFields2(modelId, options) {
2050
+ function mapReasoningToRequestFields2(options, capabilities) {
1915
2051
  if (!options.reasoning) {
1916
2052
  return {};
1917
2053
  }
1918
- const capabilities = getOpenAIModelCapabilities(modelId);
1919
2054
  if (capabilities.reasoning.mode === "unsupported") {
1920
2055
  return {};
1921
2056
  }
@@ -1943,8 +2078,9 @@ function isReasoningItem(item) {
1943
2078
  }
1944
2079
 
1945
2080
  // src/chat-model.ts
1946
- function createOpenAIChatModel(client, modelId, capabilities, providerId = "openai") {
2081
+ function createOpenAIChatModel(client, modelId, capabilities, providerId = DEFAULT_PROVIDER_ID) {
1947
2082
  const provider = providerId;
2083
+ const adapterOptions = { capabilities, providerId };
1948
2084
  async function callOpenAIResponsesApi(request, signal) {
1949
2085
  try {
1950
2086
  return await client.responses.create(request, {
@@ -1955,7 +2091,7 @@ function createOpenAIChatModel(client, modelId, capabilities, providerId = "open
1955
2091
  }
1956
2092
  }
1957
2093
  async function generateChat(options) {
1958
- const request = createGenerateRequest2(modelId, options);
2094
+ const request = createGenerateRequest2(modelId, options, adapterOptions);
1959
2095
  const response = await callOpenAIResponsesApi(
1960
2096
  request,
1961
2097
  options.signal
@@ -1963,7 +2099,7 @@ function createOpenAIChatModel(client, modelId, capabilities, providerId = "open
1963
2099
  return mapGenerateResponse2(response);
1964
2100
  }
1965
2101
  async function streamChat(options) {
1966
- const request = createStreamRequest2(modelId, options);
2102
+ const request = createStreamRequest2(modelId, options, adapterOptions);
1967
2103
  return createChatStream2(
1968
2104
  async () => transformStream2(
1969
2105
  await callOpenAIResponsesApi(request, options.signal)
@@ -2110,7 +2246,12 @@ function createOpenAIProvider(options, factoryOptions = {}) {
2110
2246
  factoryOptions.modelCapabilities,
2111
2247
  modelId
2112
2248
  ) ?? getOpenAIModelCapabilities(modelId);
2113
- return createOpenAIChatModel(client, modelId, capabilities, providerId);
2249
+ return createOpenAIChatModel(
2250
+ client,
2251
+ modelId,
2252
+ toOpenAIResponsesCapabilities(capabilities),
2253
+ providerId
2254
+ );
2114
2255
  };
2115
2256
  const createChatCompletionsModel = (modelId) => {
2116
2257
  const capabilities = getRegisteredModelCapabilities2(
package/dist/compat.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  getOpenAIModelCapabilities,
5
5
  openaiCompatGenerateProviderOptionsSchema,
6
6
  openaiCompatProviderOptionsSchema
7
- } from "./chunk-LVGNSX5F.js";
7
+ } from "./chunk-UGCMGRDL.js";
8
8
 
9
9
  // src/compat/provider.ts
10
10
  import OpenAI from "openai";
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  openaiImageProviderOptionsSchema,
11
11
  openaiResponsesGenerateProviderOptionsSchema,
12
12
  openaiResponsesProviderOptionsSchema
13
- } from "./chunk-LVGNSX5F.js";
13
+ } from "./chunk-UGCMGRDL.js";
14
14
 
15
15
  // src/provider.ts
16
16
  function createOpenAI(options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@core-ai/openai",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "OpenAI provider package for @core-ai/core-ai",
5
5
  "license": "MIT",
6
6
  "author": "Omnifact (https://omnifact.ai)",
@@ -50,7 +50,7 @@
50
50
  "test:watch": "vitest"
51
51
  },
52
52
  "dependencies": {
53
- "@core-ai/core-ai": "^0.18.0",
53
+ "@core-ai/core-ai": "^0.19.0",
54
54
  "openai": "^6.46.0"
55
55
  },
56
56
  "peerDependencies": {