@ai-sdk/openai-compatible 2.0.73 → 2.0.74

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @ai-sdk/openai-compatible
2
2
 
3
+ ## 2.0.74
4
+
5
+ ### Patch Changes
6
+
7
+ - 6d44462: Support text and thinking parts in array-based chat completion content while ignoring unknown part types.
8
+ - Updated dependencies [cc23556]
9
+ - @ai-sdk/provider-utils@4.0.50
10
+
3
11
  ## 2.0.73
4
12
 
5
13
  ### Patch Changes
package/dist/index.js CHANGED
@@ -588,10 +588,7 @@ var OpenAICompatibleChatLanguageModel = class {
588
588
  });
589
589
  const choice = responseBody.choices[0];
590
590
  const content = [];
591
- const text = choice.message.content;
592
- if (text != null && text.length > 0) {
593
- content.push({ type: "text", text });
594
- }
591
+ content.push(...convertOpenAICompatibleContent(choice.message.content));
595
592
  const reasoning = (_a = choice.message.reasoning_content) != null ? _a : choice.message.reasoning;
596
593
  if (reasoning != null && reasoning.length > 0) {
597
594
  content.push({
@@ -725,8 +722,11 @@ var OpenAICompatibleChatLanguageModel = class {
725
722
  return;
726
723
  }
727
724
  const delta = choice.delta;
728
- const reasoningContent = (_b = delta.reasoning_content) != null ? _b : delta.reasoning;
729
- if (reasoningContent) {
725
+ const enqueueReasoningDelta = (reasoningDelta) => {
726
+ if (isActiveText) {
727
+ controller.enqueue({ type: "text-end", id: "txt-0" });
728
+ isActiveText = false;
729
+ }
730
730
  if (!isActiveReasoning) {
731
731
  controller.enqueue({
732
732
  type: "reasoning-start",
@@ -737,10 +737,10 @@ var OpenAICompatibleChatLanguageModel = class {
737
737
  controller.enqueue({
738
738
  type: "reasoning-delta",
739
739
  id: "reasoning-0",
740
- delta: reasoningContent
740
+ delta: reasoningDelta
741
741
  });
742
- }
743
- if (delta.content) {
742
+ };
743
+ const enqueueTextDelta = (textDelta) => {
744
744
  if (isActiveReasoning) {
745
745
  controller.enqueue({
746
746
  type: "reasoning-end",
@@ -755,8 +755,21 @@ var OpenAICompatibleChatLanguageModel = class {
755
755
  controller.enqueue({
756
756
  type: "text-delta",
757
757
  id: "txt-0",
758
- delta: delta.content
758
+ delta: textDelta
759
759
  });
760
+ };
761
+ const reasoningContent = (_b = delta.reasoning_content) != null ? _b : delta.reasoning;
762
+ if (reasoningContent) {
763
+ enqueueReasoningDelta(reasoningContent);
764
+ }
765
+ for (const contentPart of convertOpenAICompatibleContent(
766
+ delta.content
767
+ )) {
768
+ if (contentPart.type === "reasoning") {
769
+ enqueueReasoningDelta(contentPart.text);
770
+ } else {
771
+ enqueueTextDelta(contentPart.text);
772
+ }
760
773
  }
761
774
  if (delta.tool_calls != null) {
762
775
  if (isActiveReasoning) {
@@ -958,6 +971,38 @@ var openaiCompatibleTokenUsageSchema = import_v43.z.looseObject({
958
971
  rejected_prediction_tokens: import_v43.z.number().nullish()
959
972
  }).nullish()
960
973
  }).nullish();
974
+ var openAICompatibleContentSchema = import_v43.z.union([
975
+ import_v43.z.string(),
976
+ import_v43.z.array(
977
+ import_v43.z.looseObject({
978
+ type: import_v43.z.string()
979
+ })
980
+ )
981
+ ]).nullish();
982
+ function convertOpenAICompatibleContent(content) {
983
+ if (content == null) {
984
+ return [];
985
+ }
986
+ if (typeof content === "string") {
987
+ return content.length > 0 ? [{ type: "text", text: content }] : [];
988
+ }
989
+ const result = [];
990
+ for (const part of content) {
991
+ if (part.type === "text" && typeof part.text === "string") {
992
+ if (part.text.length > 0) {
993
+ result.push({ type: "text", text: part.text });
994
+ }
995
+ } else if (part.type === "thinking" && Array.isArray(part.thinking)) {
996
+ const reasoningText = part.thinking.filter(
997
+ (chunk) => chunk != null && typeof chunk === "object" && "type" in chunk && chunk.type === "text" && "text" in chunk && typeof chunk.text === "string"
998
+ ).map((chunk) => chunk.text).join("");
999
+ if (reasoningText.length > 0) {
1000
+ result.push({ type: "reasoning", text: reasoningText });
1001
+ }
1002
+ }
1003
+ }
1004
+ return result;
1005
+ }
961
1006
  var OpenAICompatibleChatResponseSchema = import_v43.z.looseObject({
962
1007
  id: import_v43.z.string().nullish(),
963
1008
  created: import_v43.z.number().nullish(),
@@ -966,7 +1011,7 @@ var OpenAICompatibleChatResponseSchema = import_v43.z.looseObject({
966
1011
  import_v43.z.object({
967
1012
  message: import_v43.z.object({
968
1013
  role: import_v43.z.literal("assistant").nullish(),
969
- content: import_v43.z.string().nullish(),
1014
+ content: openAICompatibleContentSchema,
970
1015
  reasoning_content: import_v43.z.string().nullish(),
971
1016
  reasoning: import_v43.z.string().nullish(),
972
1017
  tool_calls: import_v43.z.array(
@@ -998,7 +1043,7 @@ var chunkBaseSchema = import_v43.z.looseObject({
998
1043
  import_v43.z.object({
999
1044
  delta: import_v43.z.object({
1000
1045
  role: import_v43.z.enum(["assistant", ""]).nullish(),
1001
- content: import_v43.z.string().nullish(),
1046
+ content: openAICompatibleContentSchema,
1002
1047
  // Most openai-compatible models set `reasoning_content`, but some
1003
1048
  // providers serving `gpt-oss` set `reasoning`. See #7866
1004
1049
  reasoning_content: import_v43.z.string().nullish(),
@@ -1725,7 +1770,7 @@ async function fileToBlob(file) {
1725
1770
  var import_provider_utils6 = require("@ai-sdk/provider-utils");
1726
1771
 
1727
1772
  // src/version.ts
1728
- var VERSION = true ? "2.0.73" : "0.0.0-test";
1773
+ var VERSION = true ? "2.0.74" : "0.0.0-test";
1729
1774
 
1730
1775
  // src/openai-compatible-provider.ts
1731
1776
  function createOpenAICompatible(options) {