@core-ai/openai 0.18.0 → 0.20.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,16 +1383,34 @@ 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
+ // Also the ownership key for encrypted reasoning metadata — Azure
1399
+ // (`azure-openai`) must not share the `openai` namespace.
1400
+ providerId: adapterOptions.providerId ?? DEFAULT_PROVIDER_ID
1401
+ };
1402
+ }
1287
1403
  var ENCRYPTED_REASONING_INCLUDE = "reasoning.encrypted_content";
1288
1404
  var REASONING_SUMMARY_SEPARATOR = "\n\n";
1405
+ var RESPONSES_AUDIO_REJECTION = "OpenAI Responses does not accept audio input; use provider.chat.chatModel() with an audio-capable Chat Completions model";
1289
1406
  function convertMessages2(messages, options = {}) {
1290
1407
  const includeReasoning = options.includeReasoning ?? true;
1408
+ const providerId = options.providerId ?? DEFAULT_PROVIDER_ID;
1291
1409
  return messages.flatMap(
1292
- (message) => convertMessage2(message, includeReasoning)
1410
+ (message) => convertMessage2(message, includeReasoning, providerId)
1293
1411
  );
1294
1412
  }
1295
- function convertMessage2(message, includeReasoning) {
1413
+ function convertMessage2(message, includeReasoning, providerId) {
1296
1414
  if (message.role === "system") {
1297
1415
  return [
1298
1416
  {
@@ -1310,7 +1428,11 @@ function convertMessage2(message, includeReasoning) {
1310
1428
  ];
1311
1429
  }
1312
1430
  if (message.role === "assistant") {
1313
- return convertAssistantMessage(message.parts, includeReasoning);
1431
+ return convertAssistantMessage(
1432
+ message.parts,
1433
+ includeReasoning,
1434
+ providerId
1435
+ );
1314
1436
  }
1315
1437
  return [
1316
1438
  {
@@ -1320,7 +1442,7 @@ function convertMessage2(message, includeReasoning) {
1320
1442
  }
1321
1443
  ];
1322
1444
  }
1323
- function convertAssistantMessage(parts, includeReasoning) {
1445
+ function convertAssistantMessage(parts, includeReasoning, providerId) {
1324
1446
  const items = [];
1325
1447
  const textParts = [];
1326
1448
  const flushTextBuffer = () => {
@@ -1341,7 +1463,7 @@ function convertAssistantMessage(parts, includeReasoning) {
1341
1463
  if (part.type === "reasoning") {
1342
1464
  if (!includeReasoning || getProviderMetadata2(
1343
1465
  part.providerMetadata,
1344
- "openai"
1466
+ providerId
1345
1467
  ) == null) {
1346
1468
  if (part.text.length > 0) {
1347
1469
  textParts.push(`<thinking>${part.text}</thinking>`);
@@ -1349,7 +1471,10 @@ function convertAssistantMessage(parts, includeReasoning) {
1349
1471
  continue;
1350
1472
  }
1351
1473
  flushTextBuffer();
1352
- const encryptedContent = getEncryptedReasoningContent(part);
1474
+ const encryptedContent = getEncryptedReasoningContent(
1475
+ part,
1476
+ providerId
1477
+ );
1353
1478
  items.push({
1354
1479
  type: "reasoning",
1355
1480
  summary: [
@@ -1373,13 +1498,20 @@ function convertAssistantMessage(parts, includeReasoning) {
1373
1498
  flushTextBuffer();
1374
1499
  return items;
1375
1500
  }
1376
- function getEncryptedReasoningContent(part) {
1501
+ function getEncryptedReasoningContent(part, providerId) {
1377
1502
  const { encryptedContent } = getProviderMetadata2(
1378
1503
  part.providerMetadata,
1379
- "openai"
1504
+ providerId
1380
1505
  ) ?? {};
1381
1506
  return typeof encryptedContent === "string" && encryptedContent.length > 0 ? encryptedContent : void 0;
1382
1507
  }
1508
+ function createReasoningProviderMetadata(providerId, encryptedContent) {
1509
+ return {
1510
+ [providerId]: {
1511
+ ...encryptedContent ? { encryptedContent } : {}
1512
+ }
1513
+ };
1514
+ }
1383
1515
  function convertUserContentPart2(part) {
1384
1516
  if (part.type === "text") {
1385
1517
  return {
@@ -1394,58 +1526,80 @@ function convertUserContentPart2(part) {
1394
1526
  image_url: imageUrl
1395
1527
  };
1396
1528
  }
1529
+ if (part.type === "audio") {
1530
+ throw new ValidationError3(RESPONSES_AUDIO_REJECTION);
1531
+ }
1397
1532
  return {
1398
1533
  type: "input_file",
1399
1534
  file_data: part.data,
1400
1535
  ...part.filename ? { filename: part.filename } : {}
1401
1536
  };
1402
1537
  }
1403
- function createGenerateRequest2(modelId, options) {
1538
+ function createGenerateRequest2(modelId, options, adapterOptions = {}) {
1404
1539
  return createRequest2(
1405
1540
  modelId,
1406
1541
  options,
1407
- false
1542
+ false,
1543
+ adapterOptions
1408
1544
  );
1409
1545
  }
1410
- function createStreamRequest2(modelId, options) {
1546
+ function createStreamRequest2(modelId, options, adapterOptions = {}) {
1411
1547
  return createRequest2(
1412
1548
  modelId,
1413
1549
  options,
1414
- true
1550
+ true,
1551
+ adapterOptions
1415
1552
  );
1416
1553
  }
1417
- function createRequest2(modelId, options, stream) {
1554
+ function createRequest2(modelId, options, stream, adapterOptions) {
1555
+ const resolved = resolveAdapterOptions(modelId, adapterOptions);
1418
1556
  const openaiOptions = parseOpenAIResponsesGenerateProviderOptions(
1419
1557
  options.providerOptions
1420
1558
  );
1421
1559
  const request = {
1422
- ...createRequestBase2(modelId, options),
1560
+ ...createRequestBase2(modelId, options, resolved),
1423
1561
  ...stream ? { stream: true } : {},
1424
1562
  ...options.structuredOutputFormat ? { text: { format: options.structuredOutputFormat } } : {},
1425
1563
  ...mapOpenAIProviderOptionsToRequestFields2(openaiOptions)
1426
1564
  };
1427
- if (options.reasoning && getOpenAIModelCapabilities(modelId).reasoning.mode !== "unsupported") {
1565
+ if (options.reasoning && resolved.capabilities.reasoning.mode !== "unsupported") {
1428
1566
  request.include = mergeInclude(request.include, [
1429
1567
  ENCRYPTED_REASONING_INCLUDE
1430
1568
  ]);
1431
1569
  }
1432
1570
  return request;
1433
1571
  }
1434
- function createRequestBase2(modelId, options) {
1435
- validateOpenAIReasoningConfig(modelId, options);
1436
- const capabilities = getOpenAIModelCapabilities(modelId);
1572
+ function createRequestBase2(modelId, options, { capabilities, providerId }) {
1573
+ validateReasoningConfig(modelId, options, capabilities, providerId);
1574
+ validateResponsesInputModalities({
1575
+ messages: options.messages,
1576
+ capabilities,
1577
+ modelId,
1578
+ providerId
1579
+ });
1437
1580
  return {
1438
1581
  model: modelId,
1439
1582
  store: false,
1440
1583
  input: convertMessages2(options.messages, {
1441
- includeReasoning: capabilities.reasoning.mode !== "unsupported"
1584
+ includeReasoning: capabilities.reasoning.mode !== "unsupported",
1585
+ providerId
1442
1586
  }),
1443
1587
  ...options.tools && Object.keys(options.tools).length > 0 ? { tools: convertResponseTools(options.tools) } : {},
1444
1588
  ...options.toolChoice ? { tool_choice: convertResponseToolChoice(options.toolChoice) } : {},
1445
- ...mapReasoningToRequestFields2(modelId, options),
1589
+ ...mapReasoningToRequestFields2(options, capabilities),
1446
1590
  ...mapSamplingToRequestFields2(options)
1447
1591
  };
1448
1592
  }
1593
+ function validateResponsesInputModalities(options) {
1594
+ try {
1595
+ validateInputModalities2(options);
1596
+ } catch (error) {
1597
+ if (error instanceof UnsupportedInputModalityError && error.unsupportedModalities.includes("audio")) {
1598
+ error.message = `${error.message}. ${RESPONSES_AUDIO_REJECTION}`;
1599
+ }
1600
+ throw error;
1601
+ }
1602
+ }
1449
1603
  function convertResponseTools(tools) {
1450
1604
  return convertTools(tools).map((tool) => ({
1451
1605
  type: "function",
@@ -1489,11 +1643,12 @@ function mapOpenAIProviderOptionsToRequestFields2(options) {
1489
1643
  ...options?.user !== void 0 ? { user: options.user } : {}
1490
1644
  };
1491
1645
  }
1492
- function mapGenerateResponse2(response) {
1646
+ function mapGenerateResponse2(response, adapterOptions = {}) {
1647
+ const providerId = adapterOptions.providerId ?? DEFAULT_PROVIDER_ID;
1493
1648
  const parts = [];
1494
1649
  for (const item of response.output) {
1495
1650
  if (isReasoningItem(item)) {
1496
- const reasoningPart = mapReasoningPart(item);
1651
+ const reasoningPart = mapReasoningPart(item, providerId);
1497
1652
  if (reasoningPart) {
1498
1653
  parts.push(reasoningPart);
1499
1654
  }
@@ -1526,7 +1681,7 @@ function mapGenerateResponse2(response) {
1526
1681
  usage: mapUsage(response.usage)
1527
1682
  };
1528
1683
  }
1529
- function mapReasoningPart(item) {
1684
+ function mapReasoningPart(item, providerId) {
1530
1685
  const text = getReasoningSummaryText(item.summary);
1531
1686
  const encryptedContent = typeof item.encrypted_content === "string" && item.encrypted_content.length > 0 ? item.encrypted_content : void 0;
1532
1687
  if (text.length === 0 && !encryptedContent) {
@@ -1535,9 +1690,10 @@ function mapReasoningPart(item) {
1535
1690
  return {
1536
1691
  type: "reasoning",
1537
1692
  text,
1538
- providerMetadata: {
1539
- openai: { ...encryptedContent ? { encryptedContent } : {} }
1540
- }
1693
+ providerMetadata: createReasoningProviderMetadata(
1694
+ providerId,
1695
+ encryptedContent
1696
+ )
1541
1697
  };
1542
1698
  }
1543
1699
  function getReasoningSummaryText(summary) {
@@ -1628,7 +1784,9 @@ function getReasoningEndTransition(reasoningStarted, providerMetadata) {
1628
1784
  }
1629
1785
  };
1630
1786
  }
1631
- async function* transformStream2(stream) {
1787
+ async function* transformStream2(stream, adapterOptions = {}) {
1788
+ const providerId = adapterOptions.providerId ?? DEFAULT_PROVIDER_ID;
1789
+ const emptyReasoningMetadata = createReasoningProviderMetadata(providerId);
1632
1790
  const bufferedToolCalls = /* @__PURE__ */ new Map();
1633
1791
  const emittedToolCalls = /* @__PURE__ */ new Set();
1634
1792
  const startedToolCalls = /* @__PURE__ */ new Set();
@@ -1734,7 +1892,9 @@ async function* transformStream2(stream) {
1734
1892
  continue;
1735
1893
  }
1736
1894
  if (event.type === "response.output_text.delta") {
1737
- const reasoningEndEvent2 = getNextReasoningEndEvent({ openai: {} });
1895
+ const reasoningEndEvent2 = getNextReasoningEndEvent(
1896
+ emptyReasoningMetadata
1897
+ );
1738
1898
  if (reasoningEndEvent2) {
1739
1899
  yield reasoningEndEvent2;
1740
1900
  }
@@ -1823,11 +1983,9 @@ async function* transformStream2(stream) {
1823
1983
  yield reasoningStartEvent;
1824
1984
  }
1825
1985
  }
1826
- const reasoningEndEvent2 = getNextReasoningEndEvent({
1827
- openai: {
1828
- ...encryptedContent ? { encryptedContent } : {}
1829
- }
1830
- });
1986
+ const reasoningEndEvent2 = getNextReasoningEndEvent(
1987
+ createReasoningProviderMetadata(providerId, encryptedContent)
1988
+ );
1831
1989
  if (reasoningEndEvent2) {
1832
1990
  yield reasoningEndEvent2;
1833
1991
  }
@@ -1866,7 +2024,9 @@ async function* transformStream2(stream) {
1866
2024
  if (event.type === "response.completed") {
1867
2025
  latestResponse = event.response;
1868
2026
  yield* closeText();
1869
- const reasoningEndEvent2 = getNextReasoningEndEvent({ openai: {} });
2027
+ const reasoningEndEvent2 = getNextReasoningEndEvent(
2028
+ emptyReasoningMetadata
2029
+ );
1870
2030
  if (reasoningEndEvent2) {
1871
2031
  yield reasoningEndEvent2;
1872
2032
  }
@@ -1895,9 +2055,7 @@ async function* transformStream2(stream) {
1895
2055
  return;
1896
2056
  }
1897
2057
  }
1898
- const reasoningEndEvent = getNextReasoningEndEvent({
1899
- openai: {}
1900
- });
2058
+ const reasoningEndEvent = getNextReasoningEndEvent(emptyReasoningMetadata);
1901
2059
  yield* closeText();
1902
2060
  if (reasoningEndEvent) {
1903
2061
  yield reasoningEndEvent;
@@ -1911,11 +2069,10 @@ async function* transformStream2(stream) {
1911
2069
  usage
1912
2070
  };
1913
2071
  }
1914
- function mapReasoningToRequestFields2(modelId, options) {
2072
+ function mapReasoningToRequestFields2(options, capabilities) {
1915
2073
  if (!options.reasoning) {
1916
2074
  return {};
1917
2075
  }
1918
- const capabilities = getOpenAIModelCapabilities(modelId);
1919
2076
  if (capabilities.reasoning.mode === "unsupported") {
1920
2077
  return {};
1921
2078
  }
@@ -1943,8 +2100,9 @@ function isReasoningItem(item) {
1943
2100
  }
1944
2101
 
1945
2102
  // src/chat-model.ts
1946
- function createOpenAIChatModel(client, modelId, capabilities, providerId = "openai") {
2103
+ function createOpenAIChatModel(client, modelId, capabilities, providerId = DEFAULT_PROVIDER_ID) {
1947
2104
  const provider = providerId;
2105
+ const adapterOptions = { capabilities, providerId };
1948
2106
  async function callOpenAIResponsesApi(request, signal) {
1949
2107
  try {
1950
2108
  return await client.responses.create(request, {
@@ -1955,18 +2113,19 @@ function createOpenAIChatModel(client, modelId, capabilities, providerId = "open
1955
2113
  }
1956
2114
  }
1957
2115
  async function generateChat(options) {
1958
- const request = createGenerateRequest2(modelId, options);
2116
+ const request = createGenerateRequest2(modelId, options, adapterOptions);
1959
2117
  const response = await callOpenAIResponsesApi(
1960
2118
  request,
1961
2119
  options.signal
1962
2120
  );
1963
- return mapGenerateResponse2(response);
2121
+ return mapGenerateResponse2(response, { providerId: provider });
1964
2122
  }
1965
2123
  async function streamChat(options) {
1966
- const request = createStreamRequest2(modelId, options);
2124
+ const request = createStreamRequest2(modelId, options, adapterOptions);
1967
2125
  return createChatStream2(
1968
2126
  async () => transformStream2(
1969
- await callOpenAIResponsesApi(request, options.signal)
2127
+ await callOpenAIResponsesApi(request, options.signal),
2128
+ { providerId: provider }
1970
2129
  ),
1971
2130
  { signal: options.signal }
1972
2131
  );
@@ -2110,7 +2269,12 @@ function createOpenAIProvider(options, factoryOptions = {}) {
2110
2269
  factoryOptions.modelCapabilities,
2111
2270
  modelId
2112
2271
  ) ?? getOpenAIModelCapabilities(modelId);
2113
- return createOpenAIChatModel(client, modelId, capabilities, providerId);
2272
+ return createOpenAIChatModel(
2273
+ client,
2274
+ modelId,
2275
+ toOpenAIResponsesCapabilities(capabilities),
2276
+ providerId
2277
+ );
2114
2278
  };
2115
2279
  const createChatCompletionsModel = (modelId) => {
2116
2280
  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-MKAXZHMO.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-MKAXZHMO.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.20.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.20.0",
54
54
  "openai": "^6.46.0"
55
55
  },
56
56
  "peerDependencies": {