@core-ai/openai 0.12.0 → 0.13.1

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,3 +1,110 @@
1
+ // src/model-capabilities.ts
2
+ import {
3
+ stripModelDateSuffix
4
+ } from "@core-ai/core-ai";
5
+ var STANDARD_EFFORTS = [
6
+ "low",
7
+ "medium",
8
+ "high"
9
+ ];
10
+ var MAX_EFFORTS = [
11
+ "low",
12
+ "medium",
13
+ "high",
14
+ "max"
15
+ ];
16
+ var MINIMAL_EFFORTS = [
17
+ "minimal",
18
+ "low",
19
+ "medium",
20
+ "high"
21
+ ];
22
+ var PRO_EFFORTS = [
23
+ "medium",
24
+ "high",
25
+ "max"
26
+ ];
27
+ var HIGH_EFFORT = ["high"];
28
+ function createCapabilities(supportedEfforts, restrictsSamplingParams) {
29
+ return {
30
+ reasoning: {
31
+ supported: true,
32
+ supportedEfforts,
33
+ restrictsSamplingParams
34
+ }
35
+ };
36
+ }
37
+ var DEFAULT_CAPABILITIES = createCapabilities(STANDARD_EFFORTS, false);
38
+ var SAMPLING_RESTRICTED_STANDARD_CAPABILITIES = createCapabilities(
39
+ STANDARD_EFFORTS,
40
+ true
41
+ );
42
+ var GPT_5_MAX_REASONING_CAPABILITIES = createCapabilities(MAX_EFFORTS, true);
43
+ var GPT_5_MINIMAL_REASONING_CAPABILITIES = createCapabilities(
44
+ MINIMAL_EFFORTS,
45
+ true
46
+ );
47
+ var GPT_5_PRO_REASONING_CAPABILITIES = createCapabilities(PRO_EFFORTS, true);
48
+ var GPT_5_HIGH_REASONING_CAPABILITIES = createCapabilities(HIGH_EFFORT, true);
49
+ var NO_REASONING_EFFORT_CAPABILITIES = {
50
+ reasoning: {
51
+ supported: false,
52
+ supportedEfforts: [],
53
+ restrictsSamplingParams: false
54
+ }
55
+ };
56
+ var O_SERIES_MAX_REASONING_CAPABILITIES = createCapabilities(
57
+ MAX_EFFORTS,
58
+ false
59
+ );
60
+ var MODEL_CAPABILITIES = {
61
+ "gpt-5.6-sol": GPT_5_MAX_REASONING_CAPABILITIES,
62
+ "gpt-5.6-terra": SAMPLING_RESTRICTED_STANDARD_CAPABILITIES,
63
+ "gpt-5.6-luna": GPT_5_MINIMAL_REASONING_CAPABILITIES,
64
+ "gpt-5.5": GPT_5_MAX_REASONING_CAPABILITIES,
65
+ "gpt-5.5-pro": GPT_5_PRO_REASONING_CAPABILITIES,
66
+ "gpt-5.4": GPT_5_MAX_REASONING_CAPABILITIES,
67
+ "gpt-5.4-pro": GPT_5_PRO_REASONING_CAPABILITIES,
68
+ "gpt-5.4-mini": GPT_5_MAX_REASONING_CAPABILITIES,
69
+ "gpt-5.4-nano": GPT_5_MAX_REASONING_CAPABILITIES,
70
+ "gpt-5.3-codex": GPT_5_MAX_REASONING_CAPABILITIES,
71
+ "gpt-5.2": GPT_5_MAX_REASONING_CAPABILITIES,
72
+ "gpt-5.2-codex": GPT_5_MAX_REASONING_CAPABILITIES,
73
+ "gpt-5.2-pro": GPT_5_MAX_REASONING_CAPABILITIES,
74
+ "gpt-5.1-codex": GPT_5_MAX_REASONING_CAPABILITIES,
75
+ "gpt-5.1-codex-max": GPT_5_MAX_REASONING_CAPABILITIES,
76
+ "gpt-5.1-codex-mini": GPT_5_MAX_REASONING_CAPABILITIES,
77
+ "gpt-5.1": SAMPLING_RESTRICTED_STANDARD_CAPABILITIES,
78
+ "gpt-5": GPT_5_MINIMAL_REASONING_CAPABILITIES,
79
+ "gpt-5-mini": GPT_5_MINIMAL_REASONING_CAPABILITIES,
80
+ "gpt-5-nano": GPT_5_MINIMAL_REASONING_CAPABILITIES,
81
+ "gpt-5-pro": GPT_5_HIGH_REASONING_CAPABILITIES,
82
+ "gpt-5-codex": GPT_5_MAX_REASONING_CAPABILITIES,
83
+ "o3-pro": O_SERIES_MAX_REASONING_CAPABILITIES,
84
+ o3: DEFAULT_CAPABILITIES,
85
+ "o3-mini": DEFAULT_CAPABILITIES,
86
+ "o4-mini": DEFAULT_CAPABILITIES,
87
+ o1: DEFAULT_CAPABILITIES,
88
+ "o1-mini": NO_REASONING_EFFORT_CAPABILITIES
89
+ };
90
+ var OPENAI_REASONING_EFFORT_MAP = {
91
+ minimal: "minimal",
92
+ low: "low",
93
+ medium: "medium",
94
+ high: "high",
95
+ max: "xhigh"
96
+ };
97
+ function getOpenAIModelCapabilities(modelId) {
98
+ const normalizedModelId = normalizeModelId(modelId);
99
+ return MODEL_CAPABILITIES[normalizedModelId] ?? DEFAULT_CAPABILITIES;
100
+ }
101
+ function normalizeModelId(modelId) {
102
+ return stripModelDateSuffix(modelId);
103
+ }
104
+ function toOpenAIReasoningEffort(effort) {
105
+ return OPENAI_REASONING_EFFORT_MAP[effort];
106
+ }
107
+
1
108
  // src/provider-options.ts
2
109
  import { z } from "zod";
3
110
  var openaiResponsesGenerateProviderOptionsSchema = z.object({
@@ -400,155 +507,6 @@ function createOpenAIProvider(options, createChatModel) {
400
507
  };
401
508
  }
402
509
 
403
- // src/model-capabilities.ts
404
- import { stripModelDateSuffix } from "@core-ai/core-ai";
405
- var DEFAULT_CAPABILITIES = {
406
- reasoning: {
407
- supportsEffort: true,
408
- supportedRange: ["low", "medium", "high"],
409
- restrictsSamplingParams: false
410
- }
411
- };
412
- var GPT_5_MAX_REASONING_CAPABILITIES = {
413
- reasoning: {
414
- supportsEffort: true,
415
- supportedRange: ["low", "medium", "high", "max"],
416
- restrictsSamplingParams: true
417
- }
418
- };
419
- var GPT_5_MINIMAL_REASONING_CAPABILITIES = {
420
- reasoning: {
421
- supportsEffort: true,
422
- supportedRange: ["minimal", "low", "medium", "high"],
423
- restrictsSamplingParams: true
424
- }
425
- };
426
- var GPT_5_PRO_REASONING_CAPABILITIES = {
427
- reasoning: {
428
- supportsEffort: true,
429
- supportedRange: ["medium", "high", "max"],
430
- restrictsSamplingParams: true
431
- }
432
- };
433
- var GPT_5_HIGH_REASONING_CAPABILITIES = {
434
- reasoning: {
435
- supportsEffort: true,
436
- supportedRange: ["high"],
437
- restrictsSamplingParams: true
438
- }
439
- };
440
- var NO_REASONING_EFFORT_CAPABILITIES = {
441
- reasoning: {
442
- supportsEffort: false,
443
- supportedRange: [],
444
- restrictsSamplingParams: false
445
- }
446
- };
447
- var O_SERIES_MAX_REASONING_CAPABILITIES = {
448
- reasoning: {
449
- supportsEffort: true,
450
- supportedRange: ["low", "medium", "high", "max"],
451
- restrictsSamplingParams: false
452
- }
453
- };
454
- var MODEL_CAPABILITIES = {
455
- "gpt-5.5": GPT_5_MAX_REASONING_CAPABILITIES,
456
- "gpt-5.5-pro": GPT_5_PRO_REASONING_CAPABILITIES,
457
- "gpt-5.4": GPT_5_MAX_REASONING_CAPABILITIES,
458
- "gpt-5.4-pro": GPT_5_PRO_REASONING_CAPABILITIES,
459
- "gpt-5.4-mini": GPT_5_MAX_REASONING_CAPABILITIES,
460
- "gpt-5.4-nano": GPT_5_MAX_REASONING_CAPABILITIES,
461
- "gpt-5.3-codex": GPT_5_MAX_REASONING_CAPABILITIES,
462
- "gpt-5.2": GPT_5_MAX_REASONING_CAPABILITIES,
463
- "gpt-5.2-codex": GPT_5_MAX_REASONING_CAPABILITIES,
464
- "gpt-5.2-pro": GPT_5_MAX_REASONING_CAPABILITIES,
465
- "gpt-5.1-codex": GPT_5_MAX_REASONING_CAPABILITIES,
466
- "gpt-5.1-codex-max": GPT_5_MAX_REASONING_CAPABILITIES,
467
- "gpt-5.1-codex-mini": GPT_5_MAX_REASONING_CAPABILITIES,
468
- "gpt-5.1": {
469
- reasoning: {
470
- supportsEffort: true,
471
- supportedRange: ["low", "medium", "high"],
472
- restrictsSamplingParams: true
473
- }
474
- },
475
- "gpt-5": GPT_5_MINIMAL_REASONING_CAPABILITIES,
476
- "gpt-5-mini": GPT_5_MINIMAL_REASONING_CAPABILITIES,
477
- "gpt-5-nano": GPT_5_MINIMAL_REASONING_CAPABILITIES,
478
- "gpt-5-pro": GPT_5_HIGH_REASONING_CAPABILITIES,
479
- "gpt-5-codex": GPT_5_MAX_REASONING_CAPABILITIES,
480
- "o3-pro": O_SERIES_MAX_REASONING_CAPABILITIES,
481
- o3: {
482
- reasoning: {
483
- supportsEffort: true,
484
- supportedRange: ["low", "medium", "high"],
485
- restrictsSamplingParams: false
486
- }
487
- },
488
- "o3-mini": {
489
- reasoning: {
490
- supportsEffort: true,
491
- supportedRange: ["low", "medium", "high"],
492
- restrictsSamplingParams: false
493
- }
494
- },
495
- "o4-mini": {
496
- reasoning: {
497
- supportsEffort: true,
498
- supportedRange: ["low", "medium", "high"],
499
- restrictsSamplingParams: false
500
- }
501
- },
502
- o1: {
503
- reasoning: {
504
- supportsEffort: true,
505
- supportedRange: ["low", "medium", "high"],
506
- restrictsSamplingParams: false
507
- }
508
- },
509
- "o1-mini": NO_REASONING_EFFORT_CAPABILITIES
510
- };
511
- var EFFORT_RANK = {
512
- minimal: 0,
513
- low: 1,
514
- medium: 2,
515
- high: 3,
516
- max: 4
517
- };
518
- var OPENAI_REASONING_EFFORT_MAP = {
519
- minimal: "minimal",
520
- low: "low",
521
- medium: "medium",
522
- high: "high",
523
- max: "xhigh"
524
- };
525
- function getOpenAIModelCapabilities(modelId) {
526
- const normalizedModelId = normalizeModelId(modelId);
527
- return MODEL_CAPABILITIES[normalizedModelId] ?? DEFAULT_CAPABILITIES;
528
- }
529
- function normalizeModelId(modelId) {
530
- return stripModelDateSuffix(modelId);
531
- }
532
- function clampReasoningEffort(effort, supportedRange) {
533
- if (supportedRange.length === 0 || supportedRange.includes(effort)) {
534
- return effort;
535
- }
536
- const targetRank = EFFORT_RANK[effort];
537
- let best = supportedRange[0] ?? effort;
538
- let bestDistance = Math.abs(EFFORT_RANK[best] - targetRank);
539
- for (const candidate of supportedRange) {
540
- const distance = Math.abs(EFFORT_RANK[candidate] - targetRank);
541
- if (distance < bestDistance) {
542
- best = candidate;
543
- bestDistance = distance;
544
- }
545
- }
546
- return best;
547
- }
548
- function toOpenAIReasoningEffort(effort) {
549
- return OPENAI_REASONING_EFFORT_MAP[effort];
550
- }
551
-
552
510
  // src/shared/utils.ts
553
511
  import { ValidationError } from "@core-ai/core-ai";
554
512
  function safeParseJsonObject(json) {
@@ -588,7 +546,6 @@ function validateOpenAIReasoningConfig(modelId, options) {
588
546
 
589
547
  export {
590
548
  getOpenAIModelCapabilities,
591
- clampReasoningEffort,
592
549
  toOpenAIReasoningEffort,
593
550
  convertTools,
594
551
  convertToolChoice,
package/dist/compat.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import {
2
- clampReasoningEffort,
3
2
  convertToolChoice,
4
3
  convertTools,
5
4
  createOpenAIProvider,
@@ -15,7 +14,7 @@ import {
15
14
  transformStructuredOutputStream,
16
15
  validateOpenAIReasoningConfig,
17
16
  wrapOpenAIError
18
- } from "./chunk-RPCZTXZS.js";
17
+ } from "./chunk-7MAEB5C7.js";
19
18
 
20
19
  // src/compat/provider.ts
21
20
  import OpenAI from "openai";
@@ -24,6 +23,7 @@ import OpenAI from "openai";
24
23
  import { createObjectStream, createChatStream } from "@core-ai/core-ai";
25
24
 
26
25
  // src/compat/chat-adapter.ts
26
+ import { clampReasoningEffort } from "@core-ai/core-ai";
27
27
  function convertMessages(messages) {
28
28
  return messages.map(convertMessage);
29
29
  }
@@ -327,12 +327,12 @@ function mapReasoningToRequestFields(modelId, options) {
327
327
  return {};
328
328
  }
329
329
  const capabilities = getOpenAIModelCapabilities(modelId);
330
- if (!capabilities.reasoning.supportsEffort) {
330
+ if (!capabilities.reasoning.supported) {
331
331
  return {};
332
332
  }
333
333
  const clampedEffort = clampReasoningEffort(
334
334
  options.reasoning.effort,
335
- capabilities.reasoning.supportedRange
335
+ capabilities.reasoning.supportedEfforts
336
336
  );
337
337
  return {
338
338
  reasoning_effort: toOpenAIReasoningEffort(clampedEffort)
@@ -400,6 +400,7 @@ function createOpenAICompatChatModel(client, modelId, providerId = "openai") {
400
400
  return {
401
401
  provider,
402
402
  modelId,
403
+ capabilities: getOpenAIModelCapabilities(modelId),
403
404
  generate: generateChat,
404
405
  stream: streamChat,
405
406
  async generateObject(options) {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { O as OpenAIProvider$1, a as OpenAIProviderBaseOptions } from './provider-options-DzqvHoId.js';
2
2
  export { b as OpenAICompatGenerateProviderOptions, c as OpenAICompatRequestOptions, e as OpenAIEmbedProviderOptions, f as OpenAIImageProviderOptions, g as OpenAIResponsesGenerateProviderOptions, h as OpenAIResponsesProviderOptions, o as openaiCompatGenerateProviderOptionsSchema, d as openaiCompatProviderOptionsSchema, i as openaiEmbedProviderOptionsSchema, j as openaiImageProviderOptionsSchema, k as openaiResponsesGenerateProviderOptionsSchema, l as openaiResponsesProviderOptionsSchema } from './provider-options-DzqvHoId.js';
3
+ import { ModelCapabilities } from '@core-ai/core-ai';
3
4
  import 'openai';
4
- import '@core-ai/core-ai';
5
5
  import 'zod';
6
6
 
7
7
  type OpenAIProviderOptions = OpenAIProviderBaseOptions;
@@ -12,4 +12,7 @@ type OpenAIReasoningMetadata = {
12
12
  encryptedContent?: string;
13
13
  };
14
14
 
15
- export { type OpenAIProvider, type OpenAIProviderOptions, type OpenAIReasoningMetadata, createOpenAI };
15
+ type OpenAIModelCapabilities = ModelCapabilities;
16
+ declare function getOpenAIModelCapabilities(modelId: string): OpenAIModelCapabilities;
17
+
18
+ export { type OpenAIModelCapabilities, type OpenAIProvider, type OpenAIProviderOptions, type OpenAIReasoningMetadata, createOpenAI, getOpenAIModelCapabilities };
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import {
2
- clampReasoningEffort,
3
2
  convertToolChoice,
4
3
  convertTools,
5
4
  createOpenAIProvider,
@@ -19,13 +18,13 @@ import {
19
18
  transformStructuredOutputStream,
20
19
  validateOpenAIReasoningConfig,
21
20
  wrapOpenAIError
22
- } from "./chunk-RPCZTXZS.js";
21
+ } from "./chunk-7MAEB5C7.js";
23
22
 
24
23
  // src/chat-model.ts
25
24
  import { createObjectStream, createChatStream } from "@core-ai/core-ai";
26
25
 
27
26
  // src/chat-adapter.ts
28
- import { getProviderMetadata } from "@core-ai/core-ai";
27
+ import { getProviderMetadata, clampReasoningEffort } from "@core-ai/core-ai";
29
28
  var ENCRYPTED_REASONING_INCLUDE = "reasoning.encrypted_content";
30
29
  var REASONING_SUMMARY_SEPARATOR = "\n\n";
31
30
  function convertMessages(messages) {
@@ -162,7 +161,7 @@ function createRequest(modelId, options, stream) {
162
161
  ...stream ? { stream: true } : {},
163
162
  ...mapOpenAIProviderOptionsToRequestFields(openaiOptions)
164
163
  };
165
- if (options.reasoning) {
164
+ if (options.reasoning && getOpenAIModelCapabilities(modelId).reasoning.supported) {
166
165
  request.include = mergeInclude(request.include, [
167
166
  ENCRYPTED_REASONING_INCLUDE
168
167
  ]);
@@ -287,11 +286,7 @@ function getTextContent(parts) {
287
286
  return getJoinedPartText(parts, "text", "");
288
287
  }
289
288
  function getReasoningText(parts) {
290
- return getJoinedPartText(
291
- parts,
292
- "reasoning",
293
- REASONING_SUMMARY_SEPARATOR
294
- );
289
+ return getJoinedPartText(parts, "reasoning", REASONING_SUMMARY_SEPARATOR);
295
290
  }
296
291
  function getJoinedPartText(parts, type, separator) {
297
292
  const text = parts.flatMap(
@@ -377,7 +372,9 @@ async function* transformStream(stream) {
377
372
  let reasoningStarted = false;
378
373
  let latestReasoningSummaryPart;
379
374
  const upsertBufferedToolCall = (outputIndex, getNextToolCall) => {
380
- const nextToolCall = getNextToolCall(bufferedToolCalls.get(outputIndex));
375
+ const nextToolCall = getNextToolCall(
376
+ bufferedToolCalls.get(outputIndex)
377
+ );
381
378
  bufferedToolCalls.set(outputIndex, nextToolCall);
382
379
  return nextToolCall;
383
380
  };
@@ -467,14 +464,11 @@ async function* transformStream(stream) {
467
464
  const toolCallId = event.item.call_id;
468
465
  const toolCallName = event.item.name;
469
466
  const toolCallArguments = event.item.arguments;
470
- upsertBufferedToolCall(
471
- event.output_index,
472
- () => ({
473
- id: toolCallId,
474
- name: toolCallName,
475
- arguments: toolCallArguments
476
- })
477
- );
467
+ upsertBufferedToolCall(event.output_index, () => ({
468
+ id: toolCallId,
469
+ name: toolCallName,
470
+ arguments: toolCallArguments
471
+ }));
478
472
  const shouldStartToolCall = !startedToolCalls.has(toolCallId);
479
473
  if (shouldStartToolCall) {
480
474
  startedToolCalls.add(toolCallId);
@@ -495,7 +489,9 @@ async function* transformStream(stream) {
495
489
  arguments: `${bufferedToolCall?.arguments ?? ""}${event.delta}`
496
490
  })
497
491
  );
498
- const shouldStartToolCall = !startedToolCalls.has(currentToolCall.id);
492
+ const shouldStartToolCall = !startedToolCalls.has(
493
+ currentToolCall.id
494
+ );
499
495
  if (shouldStartToolCall) {
500
496
  startedToolCalls.add(currentToolCall.id);
501
497
  yield {
@@ -535,13 +531,11 @@ async function* transformStream(stream) {
535
531
  yield reasoningStartEvent;
536
532
  }
537
533
  }
538
- const reasoningEndEvent2 = getNextReasoningEndEvent(
539
- {
540
- openai: {
541
- ...encryptedContent ? { encryptedContent } : {}
542
- }
534
+ const reasoningEndEvent2 = getNextReasoningEndEvent({
535
+ openai: {
536
+ ...encryptedContent ? { encryptedContent } : {}
543
537
  }
544
- );
538
+ });
545
539
  if (reasoningEndEvent2) {
546
540
  yield reasoningEndEvent2;
547
541
  }
@@ -627,15 +621,18 @@ function mapReasoningToRequestFields(modelId, options) {
627
621
  return {};
628
622
  }
629
623
  const capabilities = getOpenAIModelCapabilities(modelId);
630
- const effort = capabilities.reasoning.supportsEffort ? toOpenAIReasoningEffort(
624
+ if (!capabilities.reasoning.supported) {
625
+ return {};
626
+ }
627
+ const effort = toOpenAIReasoningEffort(
631
628
  clampReasoningEffort(
632
629
  options.reasoning.effort,
633
- capabilities.reasoning.supportedRange
630
+ capabilities.reasoning.supportedEfforts
634
631
  )
635
- ) : void 0;
632
+ );
636
633
  return {
637
634
  reasoning: {
638
- ...effort ? { effort } : {},
635
+ effort,
639
636
  summary: "auto"
640
637
  }
641
638
  };
@@ -682,6 +679,7 @@ function createOpenAIChatModel(client, modelId) {
682
679
  return {
683
680
  provider,
684
681
  modelId,
682
+ capabilities: getOpenAIModelCapabilities(modelId),
685
683
  generate: generateChat,
686
684
  stream: streamChat,
687
685
  async generateObject(options) {
@@ -725,6 +723,7 @@ function createOpenAI(options = {}) {
725
723
  }
726
724
  export {
727
725
  createOpenAI,
726
+ getOpenAIModelCapabilities,
728
727
  openaiCompatGenerateProviderOptionsSchema,
729
728
  openaiCompatProviderOptionsSchema,
730
729
  openaiEmbedProviderOptionsSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@core-ai/openai",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "OpenAI provider package for @core-ai/core-ai",
5
5
  "license": "MIT",
6
6
  "author": "Omnifact (https://omnifact.ai)",
@@ -50,8 +50,8 @@
50
50
  "test:watch": "vitest"
51
51
  },
52
52
  "dependencies": {
53
- "@core-ai/core-ai": "^0.12.0",
54
- "openai": "^6.1.0"
53
+ "@core-ai/core-ai": "^0.13.1",
54
+ "openai": "^6.46.0"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "zod": "^4.0.0"