@veryfront/ext-llm-openai 0.1.987 → 0.1.988

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/README.md CHANGED
@@ -57,7 +57,7 @@ Any model accessible through the OpenAI Chat Completions, Responses, or Embeddin
57
57
 
58
58
  - **Flagship:** `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano`, `gpt-4o`, `gpt-4o-mini`
59
59
  - **Frontier:** `gpt-5`, `gpt-5-mini`, `gpt-5-nano`
60
- - **Reasoning:** `o3`, `o4-mini`, `o1`, `o1-mini`, `o3-mini` (sampling parameters are automatically dropped with warnings)
60
+ - **Reasoning:** `gpt-5.4-nano`, current `gpt-5`/`gpt-5.x` reasoning models, `o3`, `o4-mini`, `o1`, `o3-mini` (sampling parameters are automatically dropped with warnings)
61
61
  - **Embeddings:** `text-embedding-3-small`, `text-embedding-3-large`
62
62
  - **OpenAI-compatible:** Any third-party model reachable via an OpenAI-compatible endpoint (set `OPENAI_BASE_URL`)
63
63
 
@@ -74,7 +74,11 @@ The extension accepts configuration through `LLMProviderConfig` when creating ru
74
74
 
75
75
  ## Model-Specific Behavior
76
76
 
77
- ### Reasoning Models (o3, o4-mini, o1)
77
+ ### Reasoning Models (GPT-5.x, o3, o4-mini, o1)
78
+
79
+ Default reasoning params are applied only for native `openai` and `veryfront-cloud` providers.
80
+ OpenAI-compatible providers require explicit `reasoning` options. `gpt-5-chat-latest`,
81
+ `gpt-5.1`, `o1-mini`, and `o1-preview` are left unmodified by default.
78
82
 
79
83
  Reasoning models automatically:
80
84
 
@@ -1,10 +1,5 @@
1
1
  import type { OpenAICompatibleChatRequest, RuntimePromptMessage } from "veryfront/provider/shared";
2
- type ProviderReasoningEffort = "low" | "medium" | "high" | "max";
3
- type ProviderReasoningOption = {
4
- enabled?: boolean;
5
- effort?: ProviderReasoningEffort;
6
- budgetTokens?: number;
7
- };
2
+ import { type OpenAIProviderReasoningOption } from "./openai-reasoning-models.js";
8
3
  export type RuntimeToolDefinition = {
9
4
  type: "function";
10
5
  name: string;
@@ -32,7 +27,7 @@ export type OpenAICompatibleLanguageOptions = {
32
27
  providerOptions?: Record<string, unknown>;
33
28
  includeRawChunks?: boolean;
34
29
  abortSignal?: AbortSignal;
35
- reasoning?: ProviderReasoningOption;
30
+ reasoning?: OpenAIProviderReasoningOption;
36
31
  userId?: string;
37
32
  serviceTier?: "auto" | "default" | "flex" | "scale";
38
33
  parallelToolCalls?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"openai-chat-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-chat-request-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai-chat-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-chat-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EACL,KAAK,6BAA6B,EAGnC,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,qBAAqB,GAC7B;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB,GACC;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAEJ,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,6BAA6B,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EACX;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAChB;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAChB;QACA,IAAI,EAAE,aAAa,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACL,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAUF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,2BAA2B,CA4G7B"}
@@ -1,34 +1,17 @@
1
1
  import { readProviderOptions, toOpenAICompatibleMessages, toOpenAICompatibleTools, unwrapToolInputSchema, } from "veryfront/provider/shared";
2
- function isOpenAIReasoningModel(modelId) {
3
- return /^o[134](-|$)/.test(modelId);
4
- }
2
+ import { rejectsOpenAISamplingParams, resolveOpenAIReasoningConfig, } from "./openai-reasoning-models.js";
5
3
  function isNativeOpenAIModel(modelId) {
6
4
  return /^(gpt-|o[134](-|$)|chatgpt-)/.test(modelId);
7
5
  }
8
6
  function isFixedSamplingModel(modelId) {
9
7
  return /^kimi-k2\.5/.test(modelId);
10
8
  }
11
- function resolveOpenAIReasoningEffort(option) {
12
- if (!option || option.enabled !== true) {
13
- return undefined;
14
- }
15
- switch (option.effort) {
16
- case "low":
17
- return "low";
18
- case "high":
19
- case "max":
20
- return "high";
21
- case "medium":
22
- default:
23
- return "medium";
24
- }
25
- }
26
9
  export function buildOpenAIChatRequest(modelId, providerName, options, stream, warnings) {
27
- const isReasoningModel = isOpenAIReasoningModel(modelId);
28
- const reasoningEffort = resolveOpenAIReasoningEffort(options.reasoning);
29
- const reasoningEnabled = isReasoningModel || reasoningEffort !== undefined;
10
+ const reasoning = resolveOpenAIReasoningConfig(modelId, providerName, options.reasoning);
11
+ const reasoningEnabled = reasoning !== undefined;
12
+ const samplingRejected = rejectsOpenAISamplingParams(modelId);
30
13
  const fixedSampling = isFixedSamplingModel(modelId);
31
- const dropSamplingParams = reasoningEnabled || fixedSampling;
14
+ const dropSamplingParams = reasoningEnabled || samplingRejected || fixedSampling;
32
15
  // OpenAI Chat Completions has no top_k surface.
33
16
  if (options.topK !== undefined) {
34
17
  warnings.push({
@@ -38,7 +21,7 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
38
21
  details: "OpenAI Chat Completions does not expose top_k; the value was dropped.",
39
22
  });
40
23
  }
41
- // Reasoning models (o1 / o3 / o4) and models with fixed sampling params
24
+ // Reasoning models and models with fixed sampling params
42
25
  // reject sampling params outright. Emit warnings.
43
26
  if (dropSamplingParams) {
44
27
  const dropped = [
@@ -55,7 +38,9 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
55
38
  setting: key,
56
39
  details: fixedSampling
57
40
  ? `Dropped because this model uses fixed sampling parameters.`
58
- : `Dropped because OpenAI reasoning models reject ${openaiName}. Reasoning was active for this request.`,
41
+ : samplingRejected
42
+ ? `Dropped because this model rejects ${openaiName}.`
43
+ : `Dropped because reasoning was active for this request and OpenAI rejects ${openaiName} with reasoning.`,
59
44
  });
60
45
  }
61
46
  }
@@ -87,7 +72,7 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
87
72
  ...(!dropSamplingParams && options.frequencyPenalty !== undefined
88
73
  ? { frequency_penalty: options.frequencyPenalty }
89
74
  : {}),
90
- ...(reasoningEffort !== undefined ? { reasoning_effort: reasoningEffort } : {}),
75
+ ...(reasoning !== undefined ? { reasoning_effort: reasoning.effort } : {}),
91
76
  ...(typeof options.userId === "string" && options.userId.length > 0
92
77
  ? { user: options.userId }
93
78
  : {}),
@@ -0,0 +1,17 @@
1
+ export type OpenAIReasoningEffort = "low" | "medium" | "high";
2
+ export type OpenAIProviderReasoningEffort = OpenAIReasoningEffort | "max";
3
+ export type OpenAIProviderReasoningOption = {
4
+ enabled?: boolean;
5
+ effort?: OpenAIProviderReasoningEffort;
6
+ budgetTokens?: number;
7
+ };
8
+ export type ResolvedOpenAIReasoning = {
9
+ effort: OpenAIReasoningEffort;
10
+ source: "default" | "explicit";
11
+ };
12
+ export declare function getDefaultOpenAIReasoningEffort(modelId: string, providerName?: string): OpenAIReasoningEffort | undefined;
13
+ export declare function resolveOpenAIReasoningConfig(modelId: string, providerName: string, option: OpenAIProviderReasoningOption | undefined): ResolvedOpenAIReasoning | undefined;
14
+ export declare function shouldRequestOpenAIReasoningSummary(providerName: string, reasoning: ResolvedOpenAIReasoning): boolean;
15
+ export declare function isOpenAIReasoningModel(modelId: string, providerName?: string): boolean;
16
+ export declare function rejectsOpenAISamplingParams(modelId: string): boolean;
17
+ //# sourceMappingURL=openai-reasoning-models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-reasoning-models.d.ts","sourceRoot":"","sources":["../src/openai-reasoning-models.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,MAAM,MAAM,6BAA6B,GAAG,qBAAqB,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,6BAA6B,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC,CAAC;AA6BF,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,EACf,YAAY,SAAW,GACtB,qBAAqB,GAAG,SAAS,CA0BnC;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,6BAA6B,GAAG,SAAS,GAChD,uBAAuB,GAAG,SAAS,CAoBrC;AAED,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,uBAAuB,GACjC,OAAO,CAET;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,SAAW,GAAG,OAAO,CAExF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIpE"}
@@ -0,0 +1,70 @@
1
+ const DEFAULT_REASONING_EFFORT = "medium";
2
+ function supportsDefaultReasoningParams(providerName) {
3
+ return providerName === "openai" || providerName === "veryfront-cloud";
4
+ }
5
+ function isGpt5ChatSnapshot(modelId) {
6
+ return /^gpt-5-chat($|-)/.test(modelId);
7
+ }
8
+ function isGpt51(modelId) {
9
+ return /^gpt-5\.1($|-)/.test(modelId);
10
+ }
11
+ function isReasoningCapableGpt5(modelId) {
12
+ if (isGpt5ChatSnapshot(modelId) || isGpt51(modelId)) {
13
+ return false;
14
+ }
15
+ if (/^gpt-5(-|$)/.test(modelId)) {
16
+ return true;
17
+ }
18
+ const gpt5Version = /^gpt-5\.(\d+)(-|$)/.exec(modelId)?.[1];
19
+ return gpt5Version !== undefined && Number.parseInt(gpt5Version, 10) >= 2;
20
+ }
21
+ export function getDefaultOpenAIReasoningEffort(modelId, providerName = "openai") {
22
+ const normalized = modelId.toLowerCase();
23
+ const normalizedProvider = providerName.toLowerCase();
24
+ if (!supportsDefaultReasoningParams(normalizedProvider)) {
25
+ return undefined;
26
+ }
27
+ if (isGpt5ChatSnapshot(normalized)) {
28
+ return undefined;
29
+ }
30
+ // GPT-5.1 defaults upstream reasoning to none unless callers opt in explicitly.
31
+ if (isGpt51(normalized)) {
32
+ return undefined;
33
+ }
34
+ if (/^o1($|-\d)/.test(normalized) || /^o[34](-|$)/.test(normalized)) {
35
+ return DEFAULT_REASONING_EFFORT;
36
+ }
37
+ if (isReasoningCapableGpt5(normalized)) {
38
+ return DEFAULT_REASONING_EFFORT;
39
+ }
40
+ return undefined;
41
+ }
42
+ export function resolveOpenAIReasoningConfig(modelId, providerName, option) {
43
+ if (!option) {
44
+ const effort = getDefaultOpenAIReasoningEffort(modelId, providerName);
45
+ return effort === undefined ? undefined : { effort, source: "default" };
46
+ }
47
+ if (option.enabled !== true) {
48
+ return undefined;
49
+ }
50
+ switch (option.effort) {
51
+ case "low":
52
+ return { effort: "low", source: "explicit" };
53
+ case "high":
54
+ case "max":
55
+ return { effort: "high", source: "explicit" };
56
+ case "medium":
57
+ default:
58
+ return { effort: "medium", source: "explicit" };
59
+ }
60
+ }
61
+ export function shouldRequestOpenAIReasoningSummary(providerName, reasoning) {
62
+ return reasoning.source === "explicit" || providerName.toLowerCase() === "veryfront-cloud";
63
+ }
64
+ export function isOpenAIReasoningModel(modelId, providerName = "openai") {
65
+ return getDefaultOpenAIReasoningEffort(modelId, providerName) !== undefined;
66
+ }
67
+ export function rejectsOpenAISamplingParams(modelId) {
68
+ const normalized = modelId.toLowerCase();
69
+ return /^o[134]($|-)/.test(normalized) || isReasoningCapableGpt5(normalized);
70
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"openai-responses-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-responses-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,+BAA+B,EAEhC,MAAM,kCAAkC,CAAC;AAI1C,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAmKF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,sBAAsB,CAiFxB"}
1
+ {"version":3,"file":"openai-responses-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-responses-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,+BAA+B,EAEhC,MAAM,kCAAkC,CAAC;AAO1C,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AA6IF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,sBAAsB,CA0FxB"}
@@ -1,22 +1,5 @@
1
1
  import { readProviderOptions, stringifyJsonValue, unwrapToolInputSchema, } from "veryfront/provider/shared";
2
- function isOpenAIReasoningModel(modelId) {
3
- return /^o[134](-|$)/.test(modelId);
4
- }
5
- function resolveOpenAIReasoningEffort(option) {
6
- if (!option || option.enabled !== true) {
7
- return undefined;
8
- }
9
- switch (option.effort) {
10
- case "low":
11
- return "low";
12
- case "high":
13
- case "max":
14
- return "high";
15
- case "medium":
16
- default:
17
- return "medium";
18
- }
19
- }
2
+ import { rejectsOpenAISamplingParams, resolveOpenAIReasoningConfig, shouldRequestOpenAIReasoningSummary, } from "./openai-reasoning-models.js";
20
3
  function toSnakeCaseRecord(record) {
21
4
  return Object.fromEntries(Object.entries(record).map(([key, value]) => [
22
5
  key.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`),
@@ -142,9 +125,10 @@ function toOpenAIResponsesTools(tools) {
142
125
  return normalized.length > 0 ? normalized : undefined;
143
126
  }
144
127
  export function buildOpenAIResponsesRequest(modelId, providerName, options, stream, warnings) {
145
- const isReasoningModel = isOpenAIReasoningModel(modelId);
146
- const reasoningEffort = resolveOpenAIReasoningEffort(options.reasoning);
147
- const reasoningEnabled = isReasoningModel || reasoningEffort !== undefined;
128
+ const reasoning = resolveOpenAIReasoningConfig(modelId, providerName, options.reasoning);
129
+ const reasoningEnabled = reasoning !== undefined;
130
+ const samplingRejected = rejectsOpenAISamplingParams(modelId);
131
+ const dropSamplingParams = reasoningEnabled || samplingRejected;
148
132
  if (options.topK !== undefined) {
149
133
  warnings.push({
150
134
  type: "unsupported-setting",
@@ -153,7 +137,7 @@ export function buildOpenAIResponsesRequest(modelId, providerName, options, stre
153
137
  details: "OpenAI Responses API does not expose top_k; the value was dropped.",
154
138
  });
155
139
  }
156
- if (reasoningEnabled) {
140
+ if (dropSamplingParams) {
157
141
  const dropped = [
158
142
  ["temperature", "temperature"],
159
143
  ["topP", "top_p"],
@@ -166,7 +150,9 @@ export function buildOpenAIResponsesRequest(modelId, providerName, options, stre
166
150
  type: "unsupported-setting",
167
151
  provider: "openai",
168
152
  setting: key,
169
- details: `Dropped because OpenAI reasoning models reject ${openaiName}. Reasoning was active for this request.`,
153
+ details: samplingRejected
154
+ ? `Dropped because this model rejects ${openaiName}.`
155
+ : `Dropped because reasoning was active for this request and OpenAI rejects ${openaiName} with reasoning.`,
170
156
  });
171
157
  }
172
158
  }
@@ -181,14 +167,21 @@ export function buildOpenAIResponsesRequest(modelId, providerName, options, stre
181
167
  ...(options.maxOutputTokens !== undefined
182
168
  ? { max_output_tokens: options.maxOutputTokens }
183
169
  : {}),
184
- ...(!reasoningEnabled && options.temperature !== undefined
170
+ ...(!dropSamplingParams && options.temperature !== undefined
185
171
  ? { temperature: options.temperature }
186
172
  : {}),
187
- ...(!reasoningEnabled && options.topP !== undefined ? { top_p: options.topP } : {}),
173
+ ...(!dropSamplingParams && options.topP !== undefined ? { top_p: options.topP } : {}),
188
174
  ...(responsesTools ? { tools: responsesTools } : {}),
189
175
  ...(options.toolChoice !== undefined ? { tool_choice: options.toolChoice } : {}),
190
- ...(reasoningEffort !== undefined
191
- ? { reasoning: { effort: reasoningEffort, summary: "auto" } }
176
+ ...(reasoning !== undefined
177
+ ? {
178
+ reasoning: {
179
+ effort: reasoning.effort,
180
+ ...(shouldRequestOpenAIReasoningSummary(providerName, reasoning)
181
+ ? { summary: "auto" }
182
+ : {}),
183
+ },
184
+ }
192
185
  : {}),
193
186
  ...(typeof options.userId === "string" && options.userId.length > 0
194
187
  ? { user: options.userId }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veryfront/ext-llm-openai",
3
- "version": "0.1.987",
3
+ "version": "0.1.988",
4
4
  "description": "Veryfront first-party extension package for ext-llm-openai",
5
5
  "keywords": [
6
6
  "veryfront",
@@ -45,7 +45,7 @@
45
45
  "capabilities": []
46
46
  },
47
47
  "peerDependencies": {
48
- "veryfront": "^0.1.987"
48
+ "veryfront": "^0.1.988"
49
49
  },
50
50
  "type": "module",
51
51
  "types": "./esm/index.d.ts",
@@ -55,4 +55,4 @@
55
55
  "NOTICE",
56
56
  "README.md"
57
57
  ]
58
- }
58
+ }