3434import com .google .genai .types .GenerateContentConfig ;
3535import com .google .genai .types .GenerateContentResponse ;
3636import com .google .genai .types .HttpOptions ;
37+ import com .google .genai .types .HttpRetryOptions ;
3738import com .google .genai .types .LiveConnectConfig ;
3839import com .google .genai .types .Part ;
3940import com .google .genai .types .PartialArg ;
@@ -76,20 +77,24 @@ private static OkHttpClient prepareHttpClient(@Nullable ExecutorService executor
7677 }
7778
7879 private static Client buildApiKeyClient (
79- String apiKey , @ Nullable ExecutorService executorService ) {
80+ String apiKey ,
81+ @ Nullable ExecutorService executorService ,
82+ @ Nullable HttpRetryOptions retryOptions ) {
8083 return Client .builder ()
8184 .apiKey (apiKey )
82- .httpOptions (HttpOptions . builder (). headers ( TRACKING_HEADERS ). build ( ))
85+ .httpOptions (buildHttpOptions ( retryOptions ))
8386 .clientOptions (
8487 ClientOptions .builder ().customHttpClient (prepareHttpClient (executorService )).build ())
8588 .build ();
8689 }
8790
8891 private static Client buildVertexClient (
89- VertexCredentials vertexCredentials , @ Nullable ExecutorService executorService ) {
92+ VertexCredentials vertexCredentials ,
93+ @ Nullable ExecutorService executorService ,
94+ @ Nullable HttpRetryOptions retryOptions ) {
9095 Client .Builder apiClientBuilder =
9196 Client .builder ()
92- .httpOptions (HttpOptions . builder (). headers ( TRACKING_HEADERS ). build ( ))
97+ .httpOptions (buildHttpOptions ( retryOptions ))
9398 .clientOptions (
9499 ClientOptions .builder ()
95100 .customHttpClient (prepareHttpClient (executorService ))
@@ -100,14 +105,24 @@ private static Client buildVertexClient(
100105 return apiClientBuilder .build ();
101106 }
102107
103- private static Client buildDefaultClient (@ Nullable ExecutorService executorService ) {
108+ private static Client buildDefaultClient (
109+ @ Nullable ExecutorService executorService , @ Nullable HttpRetryOptions retryOptions ) {
104110 return Client .builder ()
105- .httpOptions (HttpOptions . builder (). headers ( TRACKING_HEADERS ). build ( ))
111+ .httpOptions (buildHttpOptions ( retryOptions ))
106112 .clientOptions (
107113 ClientOptions .builder ().customHttpClient (prepareHttpClient (executorService )).build ())
108114 .build ();
109115 }
110116
117+ @ VisibleForTesting
118+ static HttpOptions buildHttpOptions (@ Nullable HttpRetryOptions retryOptions ) {
119+ HttpOptions .Builder httpOptionsBuilder = HttpOptions .builder ().headers (TRACKING_HEADERS );
120+ if (retryOptions != null ) {
121+ httpOptionsBuilder .retryOptions (retryOptions );
122+ }
123+ return httpOptionsBuilder .build ();
124+ }
125+
111126 static {
112127 String frameworkLabel = "google-adk/" + Version .JAVA_ADK_VERSION ;
113128 String languageLabel = "gl-java/" + JAVA_VERSION .value ();
@@ -121,15 +136,33 @@ private static Client buildDefaultClient(@Nullable ExecutorService executorServi
121136
122137 private final Client apiClient ;
123138
139+ private Gemini (Builder builder ) {
140+ super (builder .modelName );
141+ if (builder .apiClient != null ) {
142+ this .apiClient = builder .apiClient ;
143+ } else if (builder .apiKey != null ) {
144+ this .apiClient =
145+ buildApiKeyClient (builder .apiKey , builder .httpExecutorService , builder .retryOptions );
146+ } else if (builder .vertexCredentials != null ) {
147+ this .apiClient =
148+ buildVertexClient (
149+ builder .vertexCredentials , builder .httpExecutorService , builder .retryOptions );
150+ } else {
151+ this .apiClient = buildDefaultClient (builder .httpExecutorService , builder .retryOptions );
152+ }
153+ }
154+
124155 /**
125156 * Constructs a new Gemini instance.
126157 *
127158 * @param modelName The name of the Gemini model to use (e.g., "gemini-2.0-flash").
128159 * @param apiClient The genai {@link com.google.genai.Client} instance for making API calls.
129160 */
130161 public Gemini (String modelName , Client apiClient ) {
131- super (modelName );
132- this .apiClient = Objects .requireNonNull (apiClient , "apiClient cannot be null" );
162+ this (
163+ builder ()
164+ .modelName (modelName )
165+ .apiClient (Objects .requireNonNull (apiClient , "apiClient cannot be null" )));
133166 }
134167
135168 /**
@@ -139,27 +172,29 @@ public Gemini(String modelName, Client apiClient) {
139172 * @param apiKey The Google Gemini API key.
140173 */
141174 public Gemini (String modelName , String apiKey ) {
142- super (modelName );
143- Objects .requireNonNull (apiKey , "apiKey cannot be null" );
144- this .apiClient = buildApiKeyClient (apiKey , null );
175+ this (
176+ builder ()
177+ .modelName (modelName )
178+ .apiKey (Objects .requireNonNull (apiKey , "apiKey cannot be null" )));
145179 }
146180
147181 /**
148- * Constructs a new Gemini instance with a Google Gemini API key .
182+ * Constructs a new Gemini instance with Vertex AI credentials .
149183 *
150184 * @param modelName The name of the Gemini model to use (e.g., "gemini-2.0-flash").
151185 * @param vertexCredentials The Vertex AI credentials to access the Gemini model.
152186 */
153187 public Gemini (String modelName , VertexCredentials vertexCredentials ) {
154- super (modelName );
155- Objects .requireNonNull (vertexCredentials , "vertexCredentials cannot be null" );
156- this .apiClient = buildVertexClient (vertexCredentials , null );
188+ this (
189+ builder ()
190+ .modelName (modelName )
191+ .vertexCredentials (
192+ Objects .requireNonNull (vertexCredentials , "vertexCredentials cannot be null" )));
157193 }
158194
159195 /**
160- * Returns a new Builder instance for constructing Gemini objects. Note that when building a
161- * Gemini object, at least one of apiKey, vertexCredentials, or an explicit apiClient must be set.
162- * If multiple are set, the explicit apiClient will take precedence.
196+ * Returns a builder for configuring Gemini. An explicit client takes precedence over an API key
197+ * or Vertex credentials. If none are supplied, the client uses its default configuration.
163198 *
164199 * @return A new {@link Builder}.
165200 */
@@ -174,6 +209,7 @@ public static class Builder {
174209 private String apiKey ;
175210 private VertexCredentials vertexCredentials ;
176211 private ExecutorService httpExecutorService ;
212+ private HttpRetryOptions retryOptions ;
177213
178214 private Builder () {}
179215
@@ -245,6 +281,21 @@ public Builder httpExecutorService(ExecutorService httpExecutorService) {
245281 return this ;
246282 }
247283
284+ /**
285+ * Sets options for retrying transient HTTP failures through the Gemini client.
286+ *
287+ * <p>If an explicit {@link #apiClient(Client)} is supplied, its existing HTTP options take
288+ * precedence and these retry options are ignored.
289+ *
290+ * @param retryOptions The retry options to pass to the Google Gen AI client.
291+ * @return This builder.
292+ */
293+ @ CanIgnoreReturnValue
294+ public Builder retryOptions (HttpRetryOptions retryOptions ) {
295+ this .retryOptions = retryOptions ;
296+ return this ;
297+ }
298+
248299 /**
249300 * Builds the {@link Gemini} instance.
250301 *
@@ -253,16 +304,7 @@ public Builder httpExecutorService(ExecutorService httpExecutorService) {
253304 */
254305 public Gemini build () {
255306 Objects .requireNonNull (modelName , "modelName must be set." );
256-
257- if (apiClient != null ) {
258- return new Gemini (modelName , apiClient );
259- } else if (apiKey != null ) {
260- return new Gemini (modelName , buildApiKeyClient (apiKey , httpExecutorService ));
261- } else if (vertexCredentials != null ) {
262- return new Gemini (modelName , buildVertexClient (vertexCredentials , httpExecutorService ));
263- } else {
264- return new Gemini (modelName , buildDefaultClient (httpExecutorService ));
265- }
307+ return new Gemini (this );
266308 }
267309 }
268310
0 commit comments