@ai-sdk/openai-compatible 2.0.79 → 2.0.80

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.80
4
+
5
+ ### Patch Changes
6
+
7
+ - 29dc427: fix(provider-utils): preserve streamed tool calls with unreliable IDs and indices
8
+ - Updated dependencies [29dc427]
9
+ - @ai-sdk/provider-utils@4.0.56
10
+
3
11
  ## 2.0.79
4
12
 
5
13
  ### Patch Changes
package/dist/index.js CHANGED
@@ -672,12 +672,55 @@ var OpenAICompatibleChatLanguageModel = class {
672
672
  abortSignal: options.abortSignal,
673
673
  fetch: this.config.fetch
674
674
  });
675
- const toolCalls = [];
675
+ const providerOptionsName = metadataKey;
676
+ let toolCallTracker;
676
677
  const pendingToolCalls = /* @__PURE__ */ new Map();
678
+ const forwardedToolCallIndices = /* @__PURE__ */ new Set();
679
+ const processToolCallDelta = (toolCallDelta) => {
680
+ var _a2, _b, _c, _d, _e;
681
+ const index = toolCallDelta.index;
682
+ if (index == null || forwardedToolCallIndices.has(index)) {
683
+ toolCallTracker.processDelta(toolCallDelta);
684
+ return;
685
+ }
686
+ let pending = pendingToolCalls.get(index);
687
+ if (pending == null) {
688
+ pending = {
689
+ id: (_a2 = toolCallDelta.id) != null ? _a2 : null,
690
+ bufferedArguments: "",
691
+ extraContent: (_b = toolCallDelta.extra_content) != null ? _b : null
692
+ };
693
+ pendingToolCalls.set(index, pending);
694
+ } else {
695
+ if (pending.id == null && toolCallDelta.id != null) {
696
+ pending.id = toolCallDelta.id;
697
+ }
698
+ if (pending.extraContent == null && toolCallDelta.extra_content != null) {
699
+ pending.extraContent = toolCallDelta.extra_content;
700
+ }
701
+ }
702
+ const argumentsDelta = (_c = toolCallDelta.function) == null ? void 0 : _c.arguments;
703
+ if (argumentsDelta != null) {
704
+ pending.bufferedArguments += argumentsDelta;
705
+ }
706
+ const name = (_d = toolCallDelta.function) == null ? void 0 : _d.name;
707
+ if (name != null) {
708
+ toolCallTracker.processDelta({
709
+ index,
710
+ id: pending.id,
711
+ function: {
712
+ name,
713
+ arguments: pending.bufferedArguments
714
+ },
715
+ extra_content: (_e = pending.extraContent) != null ? _e : void 0
716
+ });
717
+ pendingToolCalls.delete(index);
718
+ forwardedToolCallIndices.add(index);
719
+ }
720
+ };
677
721
  let finishReason;
678
722
  let usage = void 0;
679
723
  let isFirstChunk = true;
680
- const providerOptionsName = metadataKey;
681
724
  let isActiveReasoning = false;
682
725
  let isActiveText = false;
683
726
  const convertUsage = (usage2) => this.convertUsage(usage2);
@@ -685,10 +728,22 @@ var OpenAICompatibleChatLanguageModel = class {
685
728
  stream: response.pipeThrough(
686
729
  new TransformStream({
687
730
  start(controller) {
731
+ toolCallTracker = new import_provider_utils2.StreamingToolCallTracker(
732
+ controller,
733
+ {
734
+ generateId: import_provider_utils2.generateId,
735
+ extractMetadata: (delta) => {
736
+ var _a2, _b;
737
+ const thoughtSignature = (_b = (_a2 = delta.extra_content) == null ? void 0 : _a2.google) == null ? void 0 : _b.thought_signature;
738
+ return thoughtSignature ? { [providerOptionsName]: { thoughtSignature } } : void 0;
739
+ },
740
+ buildToolCallProviderMetadata: (metadata) => metadata
741
+ }
742
+ );
688
743
  controller.enqueue({ type: "stream-start", warnings });
689
744
  },
690
745
  transform(chunk, controller) {
691
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
746
+ var _a2, _b;
692
747
  if (options.includeRawChunks) {
693
748
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
694
749
  }
@@ -786,113 +841,12 @@ var OpenAICompatibleChatLanguageModel = class {
786
841
  isActiveReasoning = false;
787
842
  }
788
843
  for (const toolCallDelta of delta.tool_calls) {
789
- const index = (_c = toolCallDelta.index) != null ? _c : toolCalls.length;
790
- if (toolCalls[index] == null) {
791
- if (toolCallDelta.index != null) {
792
- let pending = pendingToolCalls.get(index);
793
- if (pending == null) {
794
- pending = {
795
- id: (_d = toolCallDelta.id) != null ? _d : null,
796
- bufferedArguments: "",
797
- thoughtSignature: (_g = (_f = (_e = toolCallDelta.extra_content) == null ? void 0 : _e.google) == null ? void 0 : _f.thought_signature) != null ? _g : void 0
798
- };
799
- pendingToolCalls.set(index, pending);
800
- } else {
801
- if (pending.id == null && toolCallDelta.id != null) {
802
- pending.id = toolCallDelta.id;
803
- }
804
- if (pending.thoughtSignature == null && ((_i = (_h = toolCallDelta.extra_content) == null ? void 0 : _h.google) == null ? void 0 : _i.thought_signature) != null) {
805
- pending.thoughtSignature = toolCallDelta.extra_content.google.thought_signature;
806
- }
807
- }
808
- const argumentsDelta = (_j = toolCallDelta.function) == null ? void 0 : _j.arguments;
809
- if (argumentsDelta != null) {
810
- pending.bufferedArguments += argumentsDelta;
811
- }
812
- const name = (_k = toolCallDelta.function) == null ? void 0 : _k.name;
813
- if (name == null) {
814
- continue;
815
- }
816
- pendingToolCalls.delete(index);
817
- if (pending.id == null) {
818
- throw new import_provider3.InvalidResponseDataError({
819
- data: toolCallDelta,
820
- message: `Expected 'id' to be a string.`
821
- });
822
- }
823
- controller.enqueue({
824
- type: "tool-input-start",
825
- id: pending.id,
826
- toolName: name
827
- });
828
- toolCalls[index] = {
829
- id: pending.id,
830
- type: "function",
831
- function: {
832
- name,
833
- arguments: pending.bufferedArguments
834
- },
835
- hasFinished: false,
836
- thoughtSignature: pending.thoughtSignature
837
- };
838
- } else {
839
- if (toolCallDelta.id == null) {
840
- throw new import_provider3.InvalidResponseDataError({
841
- data: toolCallDelta,
842
- message: `Expected 'id' to be a string.`
843
- });
844
- }
845
- if (((_l = toolCallDelta.function) == null ? void 0 : _l.name) == null) {
846
- throw new import_provider3.InvalidResponseDataError({
847
- data: toolCallDelta,
848
- message: `Expected 'function.name' to be a string.`
849
- });
850
- }
851
- controller.enqueue({
852
- type: "tool-input-start",
853
- id: toolCallDelta.id,
854
- toolName: toolCallDelta.function.name
855
- });
856
- toolCalls[index] = {
857
- id: toolCallDelta.id,
858
- type: "function",
859
- function: {
860
- name: toolCallDelta.function.name,
861
- arguments: (_m = toolCallDelta.function.arguments) != null ? _m : ""
862
- },
863
- hasFinished: false,
864
- thoughtSignature: (_p = (_o = (_n = toolCallDelta.extra_content) == null ? void 0 : _n.google) == null ? void 0 : _o.thought_signature) != null ? _p : void 0
865
- };
866
- }
867
- const toolCall2 = toolCalls[index];
868
- if (((_q = toolCall2.function) == null ? void 0 : _q.name) != null && ((_r = toolCall2.function) == null ? void 0 : _r.arguments) != null) {
869
- if (toolCall2.function.arguments.length > 0) {
870
- controller.enqueue({
871
- type: "tool-input-delta",
872
- id: toolCall2.id,
873
- delta: toolCall2.function.arguments
874
- });
875
- }
876
- }
877
- continue;
878
- }
879
- const toolCall = toolCalls[index];
880
- if (toolCall.hasFinished) {
881
- continue;
882
- }
883
- if (((_s = toolCallDelta.function) == null ? void 0 : _s.arguments) != null) {
884
- toolCall.function.arguments += (_u = (_t = toolCallDelta.function) == null ? void 0 : _t.arguments) != null ? _u : "";
885
- }
886
- controller.enqueue({
887
- type: "tool-input-delta",
888
- id: toolCall.id,
889
- delta: (_v = toolCallDelta.function.arguments) != null ? _v : ""
890
- });
844
+ processToolCallDelta(toolCallDelta);
891
845
  }
892
846
  }
893
847
  },
894
848
  flush(controller) {
895
- var _a2, _b, _c, _d, _e;
849
+ var _a2, _b, _c, _d;
896
850
  if (isActiveReasoning) {
897
851
  controller.enqueue({ type: "reasoning-end", id: "reasoning-0" });
898
852
  }
@@ -900,36 +854,14 @@ var OpenAICompatibleChatLanguageModel = class {
900
854
  controller.enqueue({ type: "text-end", id: "txt-0" });
901
855
  }
902
856
  for (const [index, pending] of pendingToolCalls) {
903
- throw new import_provider3.InvalidResponseDataError({
904
- data: {
905
- index,
906
- id: pending.id,
907
- function: { arguments: pending.bufferedArguments }
908
- },
909
- message: `Expected 'function.name' to be a string.`
910
- });
911
- }
912
- for (const toolCall of toolCalls.filter(
913
- (toolCall2) => !toolCall2.hasFinished
914
- )) {
915
- controller.enqueue({
916
- type: "tool-input-end",
917
- id: toolCall.id
918
- });
919
- controller.enqueue({
920
- type: "tool-call",
921
- toolCallId: (_a2 = toolCall.id) != null ? _a2 : (0, import_provider_utils2.generateId)(),
922
- toolName: toolCall.function.name,
923
- input: toolCall.function.arguments,
924
- ...toolCall.thoughtSignature ? {
925
- providerMetadata: {
926
- [providerOptionsName]: {
927
- thoughtSignature: toolCall.thoughtSignature
928
- }
929
- }
930
- } : {}
857
+ toolCallTracker.processDelta({
858
+ index,
859
+ id: pending.id,
860
+ function: { arguments: pending.bufferedArguments }
931
861
  });
932
862
  }
863
+ pendingToolCalls.clear();
864
+ toolCallTracker.flush();
933
865
  if (finishReason == null) {
934
866
  finishReason = { unified: "error", raw: void 0 };
935
867
  controller.enqueue({
@@ -944,11 +876,11 @@ var OpenAICompatibleChatLanguageModel = class {
944
876
  [providerOptionsName]: {},
945
877
  ...metadataExtractor == null ? void 0 : metadataExtractor.buildMetadata()
946
878
  };
947
- if (((_b = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _b.accepted_prediction_tokens) != null) {
948
- providerMetadata[providerOptionsName].acceptedPredictionTokens = (_c = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _c.accepted_prediction_tokens;
879
+ if (((_a2 = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _a2.accepted_prediction_tokens) != null) {
880
+ providerMetadata[providerOptionsName].acceptedPredictionTokens = (_b = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _b.accepted_prediction_tokens;
949
881
  }
950
- if (((_d = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _d.rejected_prediction_tokens) != null) {
951
- providerMetadata[providerOptionsName].rejectedPredictionTokens = (_e = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _e.rejected_prediction_tokens;
882
+ if (((_c = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _c.rejected_prediction_tokens) != null) {
883
+ providerMetadata[providerOptionsName].rejectedPredictionTokens = (_d = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _d.rejected_prediction_tokens;
952
884
  }
953
885
  controller.enqueue({
954
886
  type: "finish",
@@ -1776,7 +1708,7 @@ async function fileToBlob(file) {
1776
1708
  var import_provider_utils6 = require("@ai-sdk/provider-utils");
1777
1709
 
1778
1710
  // src/version.ts
1779
- var VERSION = true ? "2.0.79" : "0.0.0-test";
1711
+ var VERSION = true ? "2.0.80" : "0.0.0-test";
1780
1712
 
1781
1713
  // src/openai-compatible-provider.ts
1782
1714
  function createOpenAICompatible(options) {