Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.google.genai.types.Part;
import com.google.genai.types.SafetySetting;
import com.google.genai.types.Schema;
import com.google.genai.types.ServiceTier;
import com.google.genai.types.ThinkingConfig;
import com.google.genai.types.ThinkingLevel;
import com.google.genai.types.Tool;
Expand Down Expand Up @@ -771,6 +772,9 @@ GeminiRequest createGeminiRequest(Prompt prompt) {
if (requestOptions.getPresencePenalty() != null) {
configBuilder.presencePenalty(requestOptions.getPresencePenalty().floatValue());
}
if (requestOptions.getServiceTier() != null) {
configBuilder.serviceTier(mapToGenAiServiceTier(requestOptions.getServiceTier()));
}

// Build thinking config if any thinking option is set
if (requestOptions.getThinkingBudget() != null || requestOptions.getIncludeThoughts() != null
Expand Down Expand Up @@ -903,6 +907,14 @@ private static ThinkingLevel mapToGenAiThinkingLevel(GoogleGenAiThinkingLevel le
};
}

private static ServiceTier mapToGenAiServiceTier(GoogleGenAiServiceTier tier) {
return switch (tier) {
case FLEX -> new ServiceTier(ServiceTier.Known.FLEX);
case STANDARD -> new ServiceTier(ServiceTier.Known.STANDARD);
case PRIORITY -> new ServiceTier(ServiceTier.Known.PRIORITY);
};
}

/**
* Checks if the model name indicates a Gemini 3 Pro model.
* @param modelName the model name to check
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ public class GoogleGenAiChatOptions implements ToolCallingChatOptions, Structure
*/
private GoogleGenAiThinkingLevel thinkingLevel;

/**
* Optional. The service tier to use for the request.
* STANDARD = used by default, FLEX = cost-optimized tier (higher latency), PRIORITY = higher reliability
* but premium price.
*/
private GoogleGenAiServiceTier serviceTier;

/**
* Optional. Whether to include extended usage metadata in responses.
* When true, includes thinking tokens, cached content, tool-use tokens, and modality details.
Expand Down Expand Up @@ -216,8 +223,9 @@ protected GoogleGenAiChatOptions(String model, Double frequencyPenalty, Integer
Boolean internalToolExecutionEnabled, @Nullable List<ToolCallback> toolCallbacks,
@Nullable Set<String> toolNames, @Nullable Map<String, Object> toolContext, Integer candidateCount,
String responseMimeType, String responseSchema, Integer thinkingBudget, Boolean includeThoughts,
GoogleGenAiThinkingLevel thinkingLevel, Boolean includeExtendedUsageMetadata, String cachedContentName,
Boolean useCachedContent, Integer autoCacheThreshold, Duration autoCacheTtl, Boolean googleSearchRetrieval,
GoogleGenAiThinkingLevel thinkingLevel, GoogleGenAiServiceTier serviceTier,
Boolean includeExtendedUsageMetadata, String cachedContentName, Boolean useCachedContent,
Integer autoCacheThreshold, Duration autoCacheTtl, Boolean googleSearchRetrieval,
Boolean includeServerSideToolInvocations, List<GoogleGenAiSafetySetting> safetySettings,
Map<String, String> labels) {
this.model = model;
Expand All @@ -238,6 +246,7 @@ protected GoogleGenAiChatOptions(String model, Double frequencyPenalty, Integer
this.thinkingBudget = thinkingBudget;
this.includeThoughts = includeThoughts;
this.thinkingLevel = thinkingLevel;
this.serviceTier = serviceTier;
this.includeExtendedUsageMetadata = includeExtendedUsageMetadata;
this.cachedContentName = cachedContentName;
this.useCachedContent = useCachedContent;
Expand Down Expand Up @@ -420,6 +429,14 @@ public void setThinkingLevel(GoogleGenAiThinkingLevel thinkingLevel) {
this.thinkingLevel = thinkingLevel;
}

public GoogleGenAiServiceTier getServiceTier() {
return this.serviceTier;
}

public void setServiceTier(GoogleGenAiServiceTier serviceTier) {
this.serviceTier = serviceTier;
}

public Boolean getIncludeExtendedUsageMetadata() {
return this.includeExtendedUsageMetadata;
}
Expand Down Expand Up @@ -532,7 +549,7 @@ public boolean equals(Object o) {
&& Objects.equals(this.presencePenalty, that.presencePenalty)
&& Objects.equals(this.thinkingBudget, that.thinkingBudget)
&& Objects.equals(this.includeThoughts, that.includeThoughts)
&& this.thinkingLevel == that.thinkingLevel
&& this.thinkingLevel == that.thinkingLevel && this.serviceTier == that.serviceTier
&& Objects.equals(this.maxOutputTokens, that.maxOutputTokens) && Objects.equals(this.model, that.model)
&& Objects.equals(this.responseMimeType, that.responseMimeType)
&& Objects.equals(this.responseSchema, that.responseSchema)
Expand All @@ -547,9 +564,10 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(this.stopSequences, this.temperature, this.topP, this.topK, this.candidateCount,
this.frequencyPenalty, this.presencePenalty, this.thinkingBudget, this.includeThoughts,
this.thinkingLevel, this.maxOutputTokens, this.model, this.responseMimeType, this.responseSchema,
this.toolCallbacks, this.toolNames, this.googleSearchRetrieval, this.includeServerSideToolInvocations,
this.safetySettings, this.internalToolExecutionEnabled, this.toolContext, this.labels);
this.thinkingLevel, this.serviceTier, this.maxOutputTokens, this.model, this.responseMimeType,
this.responseSchema, this.toolCallbacks, this.toolNames, this.googleSearchRetrieval,
this.includeServerSideToolInvocations, this.safetySettings, this.internalToolExecutionEnabled,
this.toolContext, this.labels);
}

@Override
Expand All @@ -563,7 +581,7 @@ public String toString() {
+ this.toolCallbacks + ", toolNames=" + this.toolNames + ", googleSearchRetrieval="
+ this.googleSearchRetrieval + ", includeServerSideToolInvocations="
+ this.includeServerSideToolInvocations + ", safetySettings=" + this.safetySettings + ", labels="
+ this.labels + '}';
+ this.labels + ", serviceTier=" + this.serviceTier + '}';
}

@Override
Expand Down Expand Up @@ -604,7 +622,8 @@ public Builder mutate() {
.googleSearchRetrieval(this.googleSearchRetrieval)
.includeServerSideToolInvocations(this.includeServerSideToolInvocations)
.safetySettings(this.safetySettings)
.labels(this.labels);
.labels(this.labels)
.serviceTier(this.serviceTier);
}

public enum TransportType {
Expand Down Expand Up @@ -648,6 +667,8 @@ public B clone() {

protected @Nullable GoogleGenAiThinkingLevel thinkingLevel;

protected @Nullable GoogleGenAiServiceTier serviceTier;

protected @Nullable Boolean includeExtendedUsageMetadata;

protected @Nullable String cachedContentName;
Expand Down Expand Up @@ -767,6 +788,11 @@ public B autoCacheTtl(@Nullable Duration autoCacheTtl) {
return self();
}

public B serviceTier(@Nullable GoogleGenAiServiceTier serviceTier) {
this.serviceTier = serviceTier;
return self();
}

public B combineWith(ChatOptions.Builder<?> other) {
super.combineWith(other);
if (other instanceof AbstractBuilder<?> that) {
Expand All @@ -788,6 +814,9 @@ public B combineWith(ChatOptions.Builder<?> other) {
if (that.thinkingLevel != null) {
this.thinkingLevel = that.thinkingLevel;
}
if (that.serviceTier != null) {
this.serviceTier = that.serviceTier;
}
if (that.includeExtendedUsageMetadata != null) {
this.includeExtendedUsageMetadata = that.includeExtendedUsageMetadata;
}
Expand Down Expand Up @@ -825,7 +854,7 @@ public GoogleGenAiChatOptions build() {
this.stopSequences, this.temperature, this.topK, this.topP, this.internalToolExecutionEnabled,
this.toolCallbacks, this.toolNames, this.toolContext, this.candidateCount, this.responseMimeType,
this.responseSchema, this.thinkingBudget, this.includeThoughts, this.thinkingLevel,
this.includeExtendedUsageMetadata, this.cachedContentName, this.useCachedContent,
this.serviceTier, this.includeExtendedUsageMetadata, this.cachedContentName, this.useCachedContent,
this.autoCacheThreshold, this.autoCacheTtl, this.googleSearchRetrieval,
this.includeServerSideToolInvocations, this.safetySettings, this.labels);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2023-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.ai.google.genai;

import org.jspecify.annotations.NullMarked;

/**
* Service Tier for the Google GenAI Chat API.
*
* @author Enrico Molino
* @since 2.0.0
*/
@NullMarked
public enum GoogleGenAiServiceTier {

FLEX, STANDARD, PRIORITY

}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
<djl.version>0.32.0</djl.version>
<onnxruntime.version>1.19.2</onnxruntime.version>
<com.google.cloud.version>26.72.0</com.google.cloud.version>
<com.google.genai.version>1.44.0</com.google.genai.version>
<com.google.genai.version>1.51.0</com.google.genai.version>
<ibm.sdk.version>9.20.0</ibm.sdk.version>
<jsonschema.version>5.0.0</jsonschema.version>
<swagger-annotations.version>2.2.38</swagger-annotations.version>
Expand Down