@ai-sdk/google 2.0.0-alpha.9 → 2.0.0-beta.2

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
@@ -248,9 +248,7 @@ function isEmptyObjectSchema(jsonSchema) {
248
248
  import {
249
249
  UnsupportedFunctionalityError
250
250
  } from "@ai-sdk/provider";
251
- import {
252
- convertToBase64
253
- } from "@ai-sdk/provider-utils";
251
+ import { convertToBase64 } from "@ai-sdk/provider-utils";
254
252
  function convertToGoogleGenerativeAIMessages(prompt) {
255
253
  const systemInstructionParts = [];
256
254
  const contents = [];
@@ -328,7 +326,7 @@ function convertToGoogleGenerativeAIMessages(prompt) {
328
326
  return {
329
327
  functionCall: {
330
328
  name: part.toolName,
331
- args: part.args
329
+ args: part.input
332
330
  }
333
331
  };
334
332
  }
@@ -346,7 +344,7 @@ function convertToGoogleGenerativeAIMessages(prompt) {
346
344
  name: part.toolName,
347
345
  response: {
348
346
  name: part.toolName,
349
- content: part.result
347
+ content: part.output.value
350
348
  }
351
349
  }
352
350
  }))
@@ -382,7 +380,8 @@ var dynamicRetrievalConfig = z4.object({
382
380
  var googleGenerativeAIProviderOptions = z4.object({
383
381
  responseModalities: z4.array(z4.enum(["TEXT", "IMAGE"])).optional(),
384
382
  thinkingConfig: z4.object({
385
- thinkingBudget: z4.number().optional()
383
+ thinkingBudget: z4.number().optional(),
384
+ includeThoughts: z4.boolean().optional()
386
385
  }).optional(),
387
386
  /**
388
387
  Optional.
@@ -488,7 +487,7 @@ function prepareTools({
488
487
  functionDeclarations.push({
489
488
  name: tool.name,
490
489
  description: (_a = tool.description) != null ? _a : "",
491
- parameters: convertJSONSchemaToOpenAPISchema(tool.parameters)
490
+ parameters: convertJSONSchemaToOpenAPISchema(tool.inputSchema)
492
491
  });
493
492
  }
494
493
  }
@@ -595,14 +594,27 @@ var GoogleGenerativeAILanguageModel = class {
595
594
  toolChoice,
596
595
  providerOptions
597
596
  }) {
598
- var _a, _b;
597
+ var _a, _b, _c;
599
598
  const warnings = [];
600
599
  const googleOptions = await parseProviderOptions2({
601
600
  provider: "google",
602
601
  providerOptions,
603
602
  schema: googleGenerativeAIProviderOptions
604
603
  });
604
+ if (((_a = googleOptions == null ? void 0 : googleOptions.thinkingConfig) == null ? void 0 : _a.includeThoughts) === true && !this.config.provider.startsWith("google.vertex.")) {
605
+ warnings.push({
606
+ type: "other",
607
+ message: `The 'includeThoughts' option is only supported with the Google Vertex provider and might not be supported or could behave unexpectedly with the current Google provider (${this.config.provider}).`
608
+ });
609
+ }
605
610
  const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(prompt);
611
+ const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
612
+ if (isGemmaModel && systemInstruction && systemInstruction.parts.length > 0) {
613
+ warnings.push({
614
+ type: "other",
615
+ message: `GEMMA models do not support system instructions. System messages will be ignored. Consider including instructions in the first user message instead.`
616
+ });
617
+ }
606
618
  const {
607
619
  tools: googleTools,
608
620
  toolConfig: googleToolConfig,
@@ -610,7 +622,7 @@ var GoogleGenerativeAILanguageModel = class {
610
622
  } = prepareTools({
611
623
  tools,
612
624
  toolChoice,
613
- useSearchGrounding: (_a = googleOptions == null ? void 0 : googleOptions.useSearchGrounding) != null ? _a : false,
625
+ useSearchGrounding: (_b = googleOptions == null ? void 0 : googleOptions.useSearchGrounding) != null ? _b : false,
614
626
  dynamicRetrievalConfig: googleOptions == null ? void 0 : googleOptions.dynamicRetrievalConfig,
615
627
  modelId: this.modelId
616
628
  });
@@ -631,7 +643,7 @@ var GoogleGenerativeAILanguageModel = class {
631
643
  responseSchema: (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && // Google GenAI does not support all OpenAPI Schema features,
632
644
  // so this is needed as an escape hatch:
633
645
  // TODO convert into provider option
634
- ((_b = googleOptions == null ? void 0 : googleOptions.structuredOutputs) != null ? _b : true) ? convertJSONSchemaToOpenAPISchema(responseFormat.schema) : void 0,
646
+ ((_c = googleOptions == null ? void 0 : googleOptions.structuredOutputs) != null ? _c : true) ? convertJSONSchemaToOpenAPISchema(responseFormat.schema) : void 0,
635
647
  ...(googleOptions == null ? void 0 : googleOptions.audioTimestamp) && {
636
648
  audioTimestamp: googleOptions.audioTimestamp
637
649
  },
@@ -640,7 +652,7 @@ var GoogleGenerativeAILanguageModel = class {
640
652
  thinkingConfig: googleOptions == null ? void 0 : googleOptions.thinkingConfig
641
653
  },
642
654
  contents,
643
- systemInstruction,
655
+ systemInstruction: isGemmaModel ? void 0 : systemInstruction,
644
656
  safetySettings: googleOptions == null ? void 0 : googleOptions.safetySettings,
645
657
  tools: googleTools,
646
658
  toolConfig: googleToolConfig,
@@ -675,16 +687,20 @@ var GoogleGenerativeAILanguageModel = class {
675
687
  const candidate = response.candidates[0];
676
688
  const content = [];
677
689
  const parts = candidate.content == null || typeof candidate.content !== "object" || !("parts" in candidate.content) ? [] : (_a = candidate.content.parts) != null ? _a : [];
690
+ const usageMetadata = response.usageMetadata;
678
691
  for (const part of parts) {
679
- if ("text" in part && part.text.length > 0) {
680
- content.push({ type: "text", text: part.text });
692
+ if ("text" in part && part.text != null && part.text.length > 0) {
693
+ if (part.thought === true) {
694
+ content.push({ type: "reasoning", text: part.text });
695
+ } else {
696
+ content.push({ type: "text", text: part.text });
697
+ }
681
698
  } else if ("functionCall" in part) {
682
699
  content.push({
683
700
  type: "tool-call",
684
- toolCallType: "function",
685
701
  toolCallId: this.config.generateId(),
686
702
  toolName: part.functionCall.name,
687
- args: JSON.stringify(part.functionCall.args)
703
+ input: JSON.stringify(part.functionCall.args)
688
704
  });
689
705
  } else if ("inlineData" in part) {
690
706
  content.push({
@@ -701,7 +717,6 @@ var GoogleGenerativeAILanguageModel = class {
701
717
  for (const source of sources) {
702
718
  content.push(source);
703
719
  }
704
- const usageMetadata = response.usageMetadata;
705
720
  return {
706
721
  content,
707
722
  finishReason: mapGoogleGenerativeAIFinishReason({
@@ -757,6 +772,9 @@ var GoogleGenerativeAILanguageModel = class {
757
772
  let providerMetadata = void 0;
758
773
  const generateId2 = this.config.generateId;
759
774
  let hasToolCalls = false;
775
+ let currentTextBlockId = null;
776
+ let currentReasoningBlockId = null;
777
+ let blockCounter = 0;
760
778
  return {
761
779
  stream: response.pipeThrough(
762
780
  new TransformStream({
@@ -764,7 +782,10 @@ var GoogleGenerativeAILanguageModel = class {
764
782
  controller.enqueue({ type: "stream-start", warnings });
765
783
  },
766
784
  transform(chunk, controller) {
767
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
785
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
786
+ if (options.includeRawChunks) {
787
+ controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
788
+ }
768
789
  if (!chunk.success) {
769
790
  controller.enqueue({ type: "error", error: chunk.error });
770
791
  return;
@@ -784,9 +805,51 @@ var GoogleGenerativeAILanguageModel = class {
784
805
  }
785
806
  const content = candidate.content;
786
807
  if (content != null) {
787
- const deltaText = getTextFromParts(content.parts);
788
- if (deltaText != null) {
789
- controller.enqueue(deltaText);
808
+ const parts = (_g = content.parts) != null ? _g : [];
809
+ for (const part of parts) {
810
+ if ("text" in part && part.text != null && part.text.length > 0) {
811
+ if (part.thought === true) {
812
+ if (currentTextBlockId !== null) {
813
+ controller.enqueue({
814
+ type: "text-end",
815
+ id: currentTextBlockId
816
+ });
817
+ currentTextBlockId = null;
818
+ }
819
+ if (currentReasoningBlockId === null) {
820
+ currentReasoningBlockId = String(blockCounter++);
821
+ controller.enqueue({
822
+ type: "reasoning-start",
823
+ id: currentReasoningBlockId
824
+ });
825
+ }
826
+ controller.enqueue({
827
+ type: "reasoning-delta",
828
+ id: currentReasoningBlockId,
829
+ delta: part.text
830
+ });
831
+ } else {
832
+ if (currentReasoningBlockId !== null) {
833
+ controller.enqueue({
834
+ type: "reasoning-end",
835
+ id: currentReasoningBlockId
836
+ });
837
+ currentReasoningBlockId = null;
838
+ }
839
+ if (currentTextBlockId === null) {
840
+ currentTextBlockId = String(blockCounter++);
841
+ controller.enqueue({
842
+ type: "text-start",
843
+ id: currentTextBlockId
844
+ });
845
+ }
846
+ controller.enqueue({
847
+ type: "text-delta",
848
+ id: currentTextBlockId,
849
+ delta: part.text
850
+ });
851
+ }
852
+ }
790
853
  }
791
854
  const inlineDataParts = getInlineDataParts(content.parts);
792
855
  if (inlineDataParts != null) {
@@ -805,18 +868,24 @@ var GoogleGenerativeAILanguageModel = class {
805
868
  if (toolCallDeltas != null) {
806
869
  for (const toolCall of toolCallDeltas) {
807
870
  controller.enqueue({
808
- type: "tool-call-delta",
809
- toolCallType: "function",
810
- toolCallId: toolCall.toolCallId,
811
- toolName: toolCall.toolName,
812
- argsTextDelta: toolCall.args
871
+ type: "tool-input-start",
872
+ id: toolCall.toolCallId,
873
+ toolName: toolCall.toolName
874
+ });
875
+ controller.enqueue({
876
+ type: "tool-input-delta",
877
+ id: toolCall.toolCallId,
878
+ delta: toolCall.args
879
+ });
880
+ controller.enqueue({
881
+ type: "tool-input-end",
882
+ id: toolCall.toolCallId
813
883
  });
814
884
  controller.enqueue({
815
885
  type: "tool-call",
816
- toolCallType: "function",
817
886
  toolCallId: toolCall.toolCallId,
818
887
  toolName: toolCall.toolName,
819
- args: toolCall.args
888
+ input: toolCall.args
820
889
  });
821
890
  hasToolCalls = true;
822
891
  }
@@ -827,22 +896,34 @@ var GoogleGenerativeAILanguageModel = class {
827
896
  finishReason: candidate.finishReason,
828
897
  hasToolCalls
829
898
  });
830
- const sources = (_g = extractSources({
899
+ const sources = (_h = extractSources({
831
900
  groundingMetadata: candidate.groundingMetadata,
832
901
  generateId: generateId2
833
- })) != null ? _g : [];
902
+ })) != null ? _h : [];
834
903
  for (const source of sources) {
835
904
  controller.enqueue(source);
836
905
  }
837
906
  providerMetadata = {
838
907
  google: {
839
- groundingMetadata: (_h = candidate.groundingMetadata) != null ? _h : null,
840
- safetyRatings: (_i = candidate.safetyRatings) != null ? _i : null
908
+ groundingMetadata: (_i = candidate.groundingMetadata) != null ? _i : null,
909
+ safetyRatings: (_j = candidate.safetyRatings) != null ? _j : null
841
910
  }
842
911
  };
843
912
  }
844
913
  },
845
914
  flush(controller) {
915
+ if (currentTextBlockId !== null) {
916
+ controller.enqueue({
917
+ type: "text-end",
918
+ id: currentTextBlockId
919
+ });
920
+ }
921
+ if (currentReasoningBlockId !== null) {
922
+ controller.enqueue({
923
+ type: "reasoning-end",
924
+ id: currentReasoningBlockId
925
+ });
926
+ }
846
927
  controller.enqueue({
847
928
  type: "finish",
848
929
  finishReason,
@@ -866,19 +947,11 @@ function getToolCallsFromParts({
866
947
  );
867
948
  return functionCallParts == null || functionCallParts.length === 0 ? void 0 : functionCallParts.map((part) => ({
868
949
  type: "tool-call",
869
- toolCallType: "function",
870
950
  toolCallId: generateId2(),
871
951
  toolName: part.functionCall.name,
872
952
  args: JSON.stringify(part.functionCall.args)
873
953
  }));
874
954
  }
875
- function getTextFromParts(parts) {
876
- const textParts = parts == null ? void 0 : parts.filter((part) => "text" in part);
877
- return textParts == null || textParts.length === 0 ? void 0 : {
878
- type: "text",
879
- text: textParts.map((part) => part.text).join("")
880
- };
881
- }
882
955
  function getInlineDataParts(parts) {
883
956
  return parts == null ? void 0 : parts.filter(
884
957
  (part) => "inlineData" in part
@@ -900,12 +973,9 @@ function extractSources({
900
973
  }));
901
974
  }
902
975
  var contentSchema = z5.object({
903
- role: z5.string(),
904
976
  parts: z5.array(
905
977
  z5.union([
906
- z5.object({
907
- text: z5.string()
908
- }),
978
+ // note: order matters since text can be fully empty
909
979
  z5.object({
910
980
  functionCall: z5.object({
911
981
  name: z5.string(),
@@ -917,6 +987,10 @@ var contentSchema = z5.object({
917
987
  mimeType: z5.string(),
918
988
  data: z5.string()
919
989
  })
990
+ }),
991
+ z5.object({
992
+ text: z5.string().nullish(),
993
+ thought: z5.boolean().nullish()
920
994
  })
921
995
  ])
922
996
  ).nullish()