@ai-sdk/openai-compatible 3.0.0-beta.2 → 3.0.0-beta.21

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/dist/index.mjs CHANGED
@@ -8,12 +8,39 @@ import {
8
8
  createJsonErrorResponseHandler,
9
9
  createJsonResponseHandler,
10
10
  generateId,
11
+ isCustomReasoning,
11
12
  isParsableJson,
12
13
  parseProviderOptions,
13
14
  postJsonToApi
14
15
  } from "@ai-sdk/provider-utils";
15
16
  import { z as z3 } from "zod/v4";
16
17
 
18
+ // src/utils/to-camel-case.ts
19
+ function toCamelCase(str) {
20
+ return str.replace(/[_-]([a-z])/g, (g) => g[1].toUpperCase());
21
+ }
22
+ function resolveProviderOptionsKey(rawName, providerOptions) {
23
+ const camelName = toCamelCase(rawName);
24
+ if (camelName !== rawName && (providerOptions == null ? void 0 : providerOptions[camelName]) != null) {
25
+ return camelName;
26
+ }
27
+ return rawName;
28
+ }
29
+ function warnIfDeprecatedProviderOptionsKey({
30
+ rawName,
31
+ providerOptions,
32
+ warnings
33
+ }) {
34
+ const camelName = toCamelCase(rawName);
35
+ if (camelName !== rawName && (providerOptions == null ? void 0 : providerOptions[rawName]) != null) {
36
+ warnings.push({
37
+ type: "deprecated",
38
+ setting: `providerOptions key '${rawName}'`,
39
+ message: `Use '${camelName}' instead.`
40
+ });
41
+ }
42
+ }
43
+
17
44
  // src/openai-compatible-error.ts
18
45
  import { z } from "zod/v4";
19
46
  var openaiCompatibleErrorDataSchema = z.object({
@@ -77,7 +104,8 @@ import {
77
104
  } from "@ai-sdk/provider";
78
105
  import {
79
106
  convertBase64ToUint8Array,
80
- convertToBase64
107
+ convertToBase64,
108
+ isProviderReference
81
109
  } from "@ai-sdk/provider-utils";
82
110
  function getOpenAIMetadata(message) {
83
111
  var _a, _b;
@@ -123,6 +151,11 @@ function convertToOpenAICompatibleChatMessages(prompt) {
123
151
  return { type: "text", text: part.text, ...partMetadata };
124
152
  }
125
153
  case "file": {
154
+ if (isProviderReference(part.data)) {
155
+ throw new UnsupportedFunctionalityError({
156
+ functionality: "file parts with provider references"
157
+ });
158
+ }
126
159
  if (part.mediaType.startsWith("image/")) {
127
160
  const mediaType = part.mediaType === "image/*" ? "image/jpeg" : part.mediaType;
128
161
  return {
@@ -395,7 +428,7 @@ function prepareTools({
395
428
  var OpenAICompatibleChatLanguageModel = class {
396
429
  // type inferred via constructor
397
430
  constructor(modelId, config) {
398
- this.specificationVersion = "v3";
431
+ this.specificationVersion = "v4";
399
432
  var _a, _b;
400
433
  this.modelId = modelId;
401
434
  this.config = config;
@@ -428,6 +461,7 @@ var OpenAICompatibleChatLanguageModel = class {
428
461
  topK,
429
462
  frequencyPenalty,
430
463
  presencePenalty,
464
+ reasoning,
431
465
  providerOptions,
432
466
  stopSequences,
433
467
  responseFormat,
@@ -435,7 +469,7 @@ var OpenAICompatibleChatLanguageModel = class {
435
469
  toolChoice,
436
470
  tools
437
471
  }) {
438
- var _a, _b, _c, _d, _e;
472
+ var _a, _b, _c, _d, _e, _f;
439
473
  const warnings = [];
440
474
  const deprecatedOptions = await parseProviderOptions({
441
475
  provider: "openai-compatible",
@@ -444,10 +478,16 @@ var OpenAICompatibleChatLanguageModel = class {
444
478
  });
445
479
  if (deprecatedOptions != null) {
446
480
  warnings.push({
447
- type: "other",
448
- message: `The 'openai-compatible' key in providerOptions is deprecated. Use 'openaiCompatible' instead.`
481
+ type: "deprecated",
482
+ setting: "providerOptions key 'openai-compatible'",
483
+ message: "Use 'openaiCompatible' instead."
449
484
  });
450
485
  }
486
+ warnIfDeprecatedProviderOptionsKey({
487
+ rawName: this.providerOptionsName,
488
+ providerOptions,
489
+ warnings
490
+ });
451
491
  const compatibleOptions = Object.assign(
452
492
  deprecatedOptions != null ? deprecatedOptions : {},
453
493
  (_a = await parseProviderOptions({
@@ -459,9 +499,14 @@ var OpenAICompatibleChatLanguageModel = class {
459
499
  provider: this.providerOptionsName,
460
500
  providerOptions,
461
501
  schema: openaiCompatibleLanguageModelChatOptions
462
- })) != null ? _b : {}
502
+ })) != null ? _b : {},
503
+ (_c = await parseProviderOptions({
504
+ provider: toCamelCase(this.providerOptionsName),
505
+ providerOptions,
506
+ schema: openaiCompatibleLanguageModelChatOptions
507
+ })) != null ? _c : {}
463
508
  );
464
- const strictJsonSchema = (_c = compatibleOptions == null ? void 0 : compatibleOptions.strictJsonSchema) != null ? _c : true;
509
+ const strictJsonSchema = (_d = compatibleOptions == null ? void 0 : compatibleOptions.strictJsonSchema) != null ? _d : true;
465
510
  if (topK != null) {
466
511
  warnings.push({ type: "unsupported", feature: "topK" });
467
512
  }
@@ -480,7 +525,12 @@ var OpenAICompatibleChatLanguageModel = class {
480
525
  tools,
481
526
  toolChoice
482
527
  });
528
+ const metadataKey = resolveProviderOptionsKey(
529
+ this.providerOptionsName,
530
+ providerOptions
531
+ );
483
532
  return {
533
+ metadataKey,
484
534
  args: {
485
535
  // model id:
486
536
  model: this.modelId,
@@ -497,22 +547,23 @@ var OpenAICompatibleChatLanguageModel = class {
497
547
  json_schema: {
498
548
  schema: responseFormat.schema,
499
549
  strict: strictJsonSchema,
500
- name: (_d = responseFormat.name) != null ? _d : "response",
550
+ name: (_e = responseFormat.name) != null ? _e : "response",
501
551
  description: responseFormat.description
502
552
  }
503
553
  } : { type: "json_object" } : void 0,
504
554
  stop: stopSequences,
505
555
  seed,
506
556
  ...Object.fromEntries(
507
- Object.entries(
508
- (_e = providerOptions == null ? void 0 : providerOptions[this.providerOptionsName]) != null ? _e : {}
509
- ).filter(
557
+ Object.entries({
558
+ ...providerOptions == null ? void 0 : providerOptions[this.providerOptionsName],
559
+ ...providerOptions == null ? void 0 : providerOptions[toCamelCase(this.providerOptionsName)]
560
+ }).filter(
510
561
  ([key]) => !Object.keys(
511
562
  openaiCompatibleLanguageModelChatOptions.shape
512
563
  ).includes(key)
513
564
  )
514
565
  ),
515
- reasoning_effort: compatibleOptions.reasoningEffort,
566
+ reasoning_effort: (_f = compatibleOptions.reasoningEffort) != null ? _f : isCustomReasoning(reasoning) && reasoning !== "none" ? reasoning : void 0,
516
567
  verbosity: compatibleOptions.textVerbosity,
517
568
  // messages:
518
569
  messages: convertToOpenAICompatibleChatMessages(prompt),
@@ -525,7 +576,7 @@ var OpenAICompatibleChatLanguageModel = class {
525
576
  }
526
577
  async doGenerate(options) {
527
578
  var _a, _b, _c, _d, _e, _f, _g, _h;
528
- const { args, warnings } = await this.getArgs({ ...options });
579
+ const { args, warnings, metadataKey } = await this.getArgs({ ...options });
529
580
  const transformedBody = this.transformRequestBody(args);
530
581
  const body = JSON.stringify(transformedBody);
531
582
  const {
@@ -569,24 +620,24 @@ var OpenAICompatibleChatLanguageModel = class {
569
620
  input: toolCall.function.arguments,
570
621
  ...thoughtSignature ? {
571
622
  providerMetadata: {
572
- [this.providerOptionsName]: { thoughtSignature }
623
+ [metadataKey]: { thoughtSignature }
573
624
  }
574
625
  } : {}
575
626
  });
576
627
  }
577
628
  }
578
629
  const providerMetadata = {
579
- [this.providerOptionsName]: {},
630
+ [metadataKey]: {},
580
631
  ...await ((_f = (_e = this.config.metadataExtractor) == null ? void 0 : _e.extractMetadata) == null ? void 0 : _f.call(_e, {
581
632
  parsedBody: rawResponse
582
633
  }))
583
634
  };
584
635
  const completionTokenDetails = (_g = responseBody.usage) == null ? void 0 : _g.completion_tokens_details;
585
636
  if ((completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens) != null) {
586
- providerMetadata[this.providerOptionsName].acceptedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens;
637
+ providerMetadata[metadataKey].acceptedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens;
587
638
  }
588
639
  if ((completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens) != null) {
589
- providerMetadata[this.providerOptionsName].rejectedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens;
640
+ providerMetadata[metadataKey].rejectedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens;
590
641
  }
591
642
  return {
592
643
  content,
@@ -607,7 +658,9 @@ var OpenAICompatibleChatLanguageModel = class {
607
658
  }
608
659
  async doStream(options) {
609
660
  var _a;
610
- const { args, warnings } = await this.getArgs({ ...options });
661
+ const { args, warnings, metadataKey } = await this.getArgs({
662
+ ...options
663
+ });
611
664
  const body = this.transformRequestBody({
612
665
  ...args,
613
666
  stream: true,
@@ -636,7 +689,7 @@ var OpenAICompatibleChatLanguageModel = class {
636
689
  };
637
690
  let usage = void 0;
638
691
  let isFirstChunk = true;
639
- const providerOptionsName = this.providerOptionsName;
692
+ const providerOptionsName = metadataKey;
640
693
  let isActiveReasoning = false;
641
694
  let isActiveText = false;
642
695
  return {
@@ -1145,7 +1198,7 @@ var openaiCompatibleLanguageModelCompletionOptions = z4.object({
1145
1198
  var OpenAICompatibleCompletionLanguageModel = class {
1146
1199
  // type inferred via constructor
1147
1200
  constructor(modelId, config) {
1148
- this.specificationVersion = "v3";
1201
+ this.specificationVersion = "v4";
1149
1202
  var _a;
1150
1203
  this.modelId = modelId;
1151
1204
  this.config = config;
@@ -1180,13 +1233,25 @@ var OpenAICompatibleCompletionLanguageModel = class {
1180
1233
  tools,
1181
1234
  toolChoice
1182
1235
  }) {
1183
- var _a;
1236
+ var _a, _b;
1184
1237
  const warnings = [];
1185
- const completionOptions = (_a = await parseProviderOptions2({
1186
- provider: this.providerOptionsName,
1238
+ warnIfDeprecatedProviderOptionsKey({
1239
+ rawName: this.providerOptionsName,
1187
1240
  providerOptions,
1188
- schema: openaiCompatibleLanguageModelCompletionOptions
1189
- })) != null ? _a : {};
1241
+ warnings
1242
+ });
1243
+ const completionOptions = Object.assign(
1244
+ (_a = await parseProviderOptions2({
1245
+ provider: this.providerOptionsName,
1246
+ providerOptions,
1247
+ schema: openaiCompatibleLanguageModelCompletionOptions
1248
+ })) != null ? _a : {},
1249
+ (_b = await parseProviderOptions2({
1250
+ provider: toCamelCase(this.providerOptionsName),
1251
+ providerOptions,
1252
+ schema: openaiCompatibleLanguageModelCompletionOptions
1253
+ })) != null ? _b : {}
1254
+ );
1190
1255
  if (topK != null) {
1191
1256
  warnings.push({ type: "unsupported", feature: "topK" });
1192
1257
  }
@@ -1222,6 +1287,7 @@ var OpenAICompatibleCompletionLanguageModel = class {
1222
1287
  presence_penalty: presencePenalty,
1223
1288
  seed,
1224
1289
  ...providerOptions == null ? void 0 : providerOptions[this.providerOptionsName],
1290
+ ...providerOptions == null ? void 0 : providerOptions[toCamelCase(this.providerOptionsName)],
1225
1291
  // prompt:
1226
1292
  prompt: completionPrompt,
1227
1293
  // stop sequences:
@@ -1432,7 +1498,7 @@ var openaiCompatibleEmbeddingModelOptions = z6.object({
1432
1498
  // src/embedding/openai-compatible-embedding-model.ts
1433
1499
  var OpenAICompatibleEmbeddingModel = class {
1434
1500
  constructor(modelId, config) {
1435
- this.specificationVersion = "v3";
1501
+ this.specificationVersion = "v4";
1436
1502
  this.modelId = modelId;
1437
1503
  this.config = config;
1438
1504
  }
@@ -1465,10 +1531,16 @@ var OpenAICompatibleEmbeddingModel = class {
1465
1531
  });
1466
1532
  if (deprecatedOptions != null) {
1467
1533
  warnings.push({
1468
- type: "other",
1469
- message: `The 'openai-compatible' key in providerOptions is deprecated. Use 'openaiCompatible' instead.`
1534
+ type: "deprecated",
1535
+ setting: "providerOptions key 'openai-compatible'",
1536
+ message: "Use 'openaiCompatible' instead."
1470
1537
  });
1471
1538
  }
1539
+ warnIfDeprecatedProviderOptionsKey({
1540
+ rawName: this.providerOptionsName,
1541
+ providerOptions,
1542
+ warnings
1543
+ });
1472
1544
  const compatibleOptions = Object.assign(
1473
1545
  deprecatedOptions != null ? deprecatedOptions : {},
1474
1546
  (_a = await parseProviderOptions3({
@@ -1547,7 +1619,7 @@ var OpenAICompatibleImageModel = class {
1547
1619
  constructor(modelId, config) {
1548
1620
  this.modelId = modelId;
1549
1621
  this.config = config;
1550
- this.specificationVersion = "v3";
1622
+ this.specificationVersion = "v4";
1551
1623
  this.maxImagesPerCall = 10;
1552
1624
  }
1553
1625
  get provider() {
@@ -1559,8 +1631,12 @@ var OpenAICompatibleImageModel = class {
1559
1631
  get providerOptionsKey() {
1560
1632
  return this.config.provider.split(".")[0].trim();
1561
1633
  }
1562
- // TODO: deprecate non-camelCase keys and remove in future major version
1563
- getArgs(providerOptions) {
1634
+ getArgs(providerOptions, warnings) {
1635
+ warnIfDeprecatedProviderOptionsKey({
1636
+ rawName: this.providerOptionsKey,
1637
+ providerOptions,
1638
+ warnings
1639
+ });
1564
1640
  return {
1565
1641
  ...providerOptions[this.providerOptionsKey],
1566
1642
  ...providerOptions[toCamelCase(this.providerOptionsKey)]
@@ -1591,7 +1667,7 @@ var OpenAICompatibleImageModel = class {
1591
1667
  warnings.push({ type: "unsupported", feature: "seed" });
1592
1668
  }
1593
1669
  const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
1594
- const args = this.getArgs(providerOptions);
1670
+ const args = this.getArgs(providerOptions, warnings);
1595
1671
  if (files != null && files.length > 0) {
1596
1672
  const { value: response2, responseHeaders: responseHeaders2 } = await postFormDataToApi({
1597
1673
  url: this.config.url({
@@ -1671,9 +1747,6 @@ async function fileToBlob(file) {
1671
1747
  const data = file.data instanceof Uint8Array ? file.data : convertBase64ToUint8Array2(file.data);
1672
1748
  return new Blob([data], { type: file.mediaType });
1673
1749
  }
1674
- function toCamelCase(str) {
1675
- return str.replace(/[_-]([a-z])/g, (g) => g[1].toUpperCase());
1676
- }
1677
1750
 
1678
1751
  // src/openai-compatible-provider.ts
1679
1752
  import {
@@ -1682,7 +1755,7 @@ import {
1682
1755
  } from "@ai-sdk/provider-utils";
1683
1756
 
1684
1757
  // src/version.ts
1685
- var VERSION = true ? "3.0.0-beta.2" : "0.0.0-test";
1758
+ var VERSION = true ? "3.0.0-beta.21" : "0.0.0-test";
1686
1759
 
1687
1760
  // src/openai-compatible-provider.ts
1688
1761
  function createOpenAICompatible(options) {
@@ -1722,7 +1795,7 @@ function createOpenAICompatible(options) {
1722
1795
  });
1723
1796
  const createImageModel = (modelId) => new OpenAICompatibleImageModel(modelId, getCommonModelConfig("image"));
1724
1797
  const provider = (modelId) => createLanguageModel(modelId);
1725
- provider.specificationVersion = "v3";
1798
+ provider.specificationVersion = "v4";
1726
1799
  provider.languageModel = createLanguageModel;
1727
1800
  provider.chatModel = createChatModel;
1728
1801
  provider.completionModel = createCompletionModel;