@ai-sdk/google 4.0.0-beta.13 → 4.0.0-beta.14

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.
@@ -17,7 +17,10 @@ import {
17
17
  FetchFunction,
18
18
  generateId,
19
19
  InferSchema,
20
+ isCustomReasoning,
20
21
  lazySchema,
22
+ mapReasoningToProviderBudget,
23
+ mapReasoningToProviderEffort,
21
24
  parseProviderOptions,
22
25
  ParseResult,
23
26
  postJsonToApi,
@@ -96,6 +99,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
96
99
  seed,
97
100
  tools,
98
101
  toolChoice,
102
+ reasoning,
99
103
  providerOptions,
100
104
  }: LanguageModelV4CallOptions) {
101
105
  const warnings: SharedV4Warning[] = [];
@@ -151,6 +155,16 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
151
155
  modelId: this.modelId,
152
156
  });
153
157
 
158
+ const resolvedThinking = resolveThinkingConfig({
159
+ reasoning,
160
+ modelId: this.modelId,
161
+ warnings,
162
+ });
163
+ const thinkingConfig =
164
+ googleOptions?.thinkingConfig || resolvedThinking
165
+ ? { ...resolvedThinking, ...googleOptions?.thinkingConfig }
166
+ : undefined;
167
+
154
168
  return {
155
169
  args: {
156
170
  generationConfig: {
@@ -182,7 +196,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
182
196
 
183
197
  // provider options:
184
198
  responseModalities: googleOptions?.responseModalities,
185
- thinkingConfig: googleOptions?.thinkingConfig,
199
+ thinkingConfig,
186
200
  ...(googleOptions?.mediaResolution && {
187
201
  mediaResolution: googleOptions.mediaResolution,
188
202
  }),
@@ -706,6 +720,109 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
706
720
  }
707
721
  }
708
722
 
723
+ function isGemini3Model(modelId: string): boolean {
724
+ return /gemini-3[\.\-]/i.test(modelId) || /gemini-3$/i.test(modelId);
725
+ }
726
+
727
+ function getMaxOutputTokensForGemini25Model(): number {
728
+ return 65536;
729
+ }
730
+
731
+ function getMaxThinkingTokensForGemini25Model(modelId: string): number {
732
+ const id = modelId.toLowerCase();
733
+ if (id.includes('2.5-pro') || id.includes('gemini-3-pro-image')) {
734
+ return 32768;
735
+ }
736
+ return 24576;
737
+ }
738
+
739
+ type GoogleThinkingConfig = NonNullable<
740
+ InferSchema<typeof googleLanguageModelOptions>['thinkingConfig']
741
+ >;
742
+
743
+ function resolveThinkingConfig({
744
+ reasoning,
745
+ modelId,
746
+ warnings,
747
+ }: {
748
+ reasoning: LanguageModelV4CallOptions['reasoning'];
749
+ modelId: string;
750
+ warnings: SharedV4Warning[];
751
+ }): Omit<GoogleThinkingConfig, 'includeThoughts'> | undefined {
752
+ if (!isCustomReasoning(reasoning)) {
753
+ return undefined;
754
+ }
755
+
756
+ if (isGemini3Model(modelId) && !modelId.includes('gemini-3-pro-image')) {
757
+ return resolveGemini3ThinkingConfig({ reasoning, warnings });
758
+ }
759
+
760
+ return resolveGemini25ThinkingConfig({ reasoning, modelId, warnings });
761
+ }
762
+
763
+ function resolveGemini3ThinkingConfig({
764
+ reasoning,
765
+ warnings,
766
+ }: {
767
+ reasoning: Exclude<
768
+ LanguageModelV4CallOptions['reasoning'],
769
+ 'provider-default' | undefined
770
+ >;
771
+ warnings: SharedV4Warning[];
772
+ }): Pick<GoogleThinkingConfig, 'thinkingLevel'> | undefined {
773
+ if (reasoning === 'none') {
774
+ // It's not possible to fully disable thinking with Gemini 3.
775
+ return { thinkingLevel: 'minimal' };
776
+ }
777
+
778
+ const thinkingLevel = mapReasoningToProviderEffort({
779
+ reasoning,
780
+ effortMap: {
781
+ minimal: 'minimal',
782
+ low: 'low',
783
+ medium: 'medium',
784
+ high: 'high',
785
+ xhigh: 'high',
786
+ },
787
+ warnings,
788
+ });
789
+
790
+ if (thinkingLevel == null) {
791
+ return undefined;
792
+ }
793
+
794
+ return { thinkingLevel };
795
+ }
796
+
797
+ function resolveGemini25ThinkingConfig({
798
+ reasoning,
799
+ modelId,
800
+ warnings,
801
+ }: {
802
+ reasoning: Exclude<
803
+ LanguageModelV4CallOptions['reasoning'],
804
+ 'provider-default' | undefined
805
+ >;
806
+ modelId: string;
807
+ warnings: SharedV4Warning[];
808
+ }): Pick<GoogleThinkingConfig, 'thinkingBudget'> | undefined {
809
+ if (reasoning === 'none') {
810
+ return { thinkingBudget: 0 };
811
+ }
812
+
813
+ const thinkingBudget = mapReasoningToProviderBudget({
814
+ reasoning,
815
+ maxOutputTokens: getMaxOutputTokensForGemini25Model(),
816
+ maxReasoningBudget: getMaxThinkingTokensForGemini25Model(modelId),
817
+ minReasoningBudget: 0,
818
+ warnings,
819
+ });
820
+ if (thinkingBudget == null) {
821
+ return undefined;
822
+ }
823
+ return { thinkingBudget };
824
+ }
825
+
709
826
  function getToolCallsFromParts({
710
827
  parts,
711
828
  generateId,