Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
@@ -0,0 +1,79 @@
/*
* Copyright 2025 Google LLC
*
* 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
*
* http://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 genai.thinking;

// [START googlegenaisdk_thinking_budget_with_txt]

import com.google.genai.Client;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.HttpOptions;
import com.google.genai.types.ThinkingConfig;

public class ThinkingBudgetWithText {

public static void main(String[] args) {
// TODO(developer): Replace these variables before running the sample.
String modelId = "gemini-2.5-flash";
generateContent(modelId);
}

// Generates text controlling the thinking budget
public static String generateContent(String modelId) {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try (Client client =
Client.builder()
.location("global")
.vertexAI(true)
.httpOptions(HttpOptions.builder().apiVersion("v1").build())
.build()) {

GenerateContentConfig contentConfig =
GenerateContentConfig.builder()
.thinkingConfig(ThinkingConfig.builder().thinkingBudget(1024).build())
.build();

GenerateContentResponse response =
client.models.generateContent(modelId, "solve x^2 + 4x + 4 = 0", contentConfig);

System.out.println(response.text());
// Example response:
// To solve the equation $x^2 + 4x + 4 = 0$, we can use several methods:
//
// **Method 1: Factoring (Recognizing a Perfect Square Trinomial)**
//
// Notice that the left side of the equation is a perfect square trinomial. It fits the form
// $a^2 + 2ab + b^2 = (a+b)^2$...
// ...
// The solution is $x = -2$.

response
.usageMetadata()
.ifPresent(
metadata -> {
System.out.println("Token count for thinking: " + metadata.thoughtsTokenCount());
System.out.println("Total token count: " + metadata.totalTokenCount());
});
// Example response:
// Token count for thinking: Optional[885]
// Total token count: Optional[1468]
return response.text();
}
}
}
// [END googlegenaisdk_thinking_budget_with_txt]
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright 2025 Google LLC
*
* 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
*
* http://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 genai.thinking;

// [START googlegenaisdk_thinking_includethoughts_with_txt]

import com.google.genai.Client;
import com.google.genai.types.Candidate;
import com.google.genai.types.Content;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.HttpOptions;
import com.google.genai.types.ThinkingConfig;

public class ThinkingIncludeThoughtsWithText {

public static void main(String[] args) {
// TODO(developer): Replace these variables before running the sample.
String modelId = "gemini-2.5-flash";
generateContent(modelId);
}

// Generates text including thoughts in the response
public static String generateContent(String modelId) {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try (Client client =
Client.builder()
.location("global")
.vertexAI(true)
.httpOptions(HttpOptions.builder().apiVersion("v1").build())
.build()) {

GenerateContentConfig contentConfig =
GenerateContentConfig.builder()
.thinkingConfig(ThinkingConfig.builder().includeThoughts(true).build())
.build();

GenerateContentResponse response =
client.models.generateContent(modelId, "solve x^2 + 4x + 4 = 0", contentConfig);

System.out.println(response.text());
// Example response:
// To solve the equation $x^2 + 4x + 4 = 0$, we can use several methods:
// ...
// **Solution:**
// The solution to the equation $x^2 + 4x + 4 = 0$ is $x = -2$.

// Get parts of the response and print thoughts
response
.candidates()
.flatMap(candidates -> candidates.stream().findFirst())
.flatMap(Candidate::content)
.flatMap(Content::parts)
.ifPresent(
parts -> {
parts.forEach(
part -> {
if (part.thought().orElse(false)) {
part.text().ifPresent(System.out::println);
}
});
});
// Example response:
// Alright, here's how I'd approach this problem. I'm looking at the quadratic equation $x^2 +
// 4x + 4 = 0$. Immediately, I recognize a few potential solution paths, the beauty of
// quadratic equations is the multiple ways to solve them.
//
// First, **factoring** seems promising. I mentally scan the expression and see if it can be
// easily factored, and sure enough, it screams "perfect square trinomial." $x^2$ is clearly a
// perfect square, and so is $4$. The middle term, $4x$, fits the pattern $2ab$ with $a = x$
// and $b = 2$. So, I can rewrite the equation as $(x+2)^2 = 0$. Taking the square root of
// both sides, I get $x+2 = 0$, and therefore $x = -2$. Done.
//
// But, just to be thorough and ensure I haven't missed anything, I should also check the
// **quadratic formula**. I have to, of course, apply the standard formula: $x = \frac{-b \pm
// \sqrt{b^2 - 4ac}}{2a}$. Here, $a = 1$, $b = 4$, and $c = 4$. Plugging those values in, I
// get $x = \frac{-4 \pm \sqrt{16 - 16}}{2}$, which simplifies to $x = \frac{-4}{2}$, meaning
// $x = -2$. Perfect.
//
// And finally, as a sanity check, I'll briefly consider **completing the square**. Well, in
// this case, I've already essentially done it! The equation is already set up in a perfect
// square form. The constant term is, effectively, $(4/2)^2 = 4$. Therefore, I can directly
// proceed to the factored form and solve for x.
//
// So, all three methods, factoring, the quadratic formula and completing the square, yield
// the same result: $x = -2$. The fact that the discriminant, $b^2 - 4ac$, equals 0 tells me
// that there's only one real solution, a repeated root, which is exactly what I found.
return response.text();
}
}
}
// [END googlegenaisdk_thinking_includethoughts_with_txt]
99 changes: 99 additions & 0 deletions genai/snippets/src/main/java/genai/thinking/ThinkingWithText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2025 Google LLC
*
* 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
*
* http://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 genai.thinking;

// [START googlegenaisdk_thinking_with_txt]

import com.google.genai.Client;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.HttpOptions;

public class ThinkingWithText {

public static void main(String[] args) {
// TODO(developer): Replace these variables before running the sample.
String modelId = "gemini-2.5-flash";
generateContent(modelId);
}

// Generates text with text input
public static String generateContent(String modelId) {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try (Client client =
Client.builder()
.location("global")
.vertexAI(true)
.httpOptions(HttpOptions.builder().apiVersion("v1").build())
.build()) {

GenerateContentResponse response =
client.models.generateContent(modelId, "solve x^2 + 4x + 4 = 0", null);

System.out.println(response.text());
// Example response:
// To solve the equation $x^2 + 4x + 4 = 0$, we can use several methods:
//
// **Method 1: Factoring (Recognizing a Perfect Square Trinomial)**
//
// Observe the structure of the equation: it is a quadratic trinomial.
// We look for two numbers that multiply to $c$ (4) and add up to $b$ (4).
// These numbers are 2 and 2 ($2 \times 2 = 4$ and $2 + 2 = 4$).
//
// So, the quadratic expression can be factored as $(x+2)(x+2)$.
// This is equivalent to $(x+2)^2$.
//
// Now, the equation becomes:
// $(x+2)^2 = 0$
//
// To solve for $x$, take the square root of both sides:
// $\sqrt{(x+2)^2} = \sqrt{0}$
// $x+2 = 0$
//
// Subtract 2 from both sides:
// $x = -2$
//
// This is the only solution, as the quadratic has a repeated root (or a root with
// multiplicity 2).
//
// **Method 2: Using the Quadratic Formula**
//
// The quadratic formula solves for $x$ in an equation of the form $ax^2 + bx + c = 0$:
// $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$
//
// In our equation, $x^2 + 4x + 4 = 0$, we have:
// $a = 1$
// $b = 4$
// $c = 4$
//
// Substitute these values into the formula:
// $x = \frac{-4 \pm \sqrt{4^2 - 4(1)(4)}}{2(1)}$
// $x = \frac{-4 \pm \sqrt{16 - 16}}{2}$
// $x = \frac{-4 \pm \sqrt{0}}{2}$
// $x = \frac{-4 \pm 0}{2}$
// $x = \frac{-4}{2}$
// $x = -2$
//
// Both methods yield the same solution.
//
// **Solution:**
// The solution to the equation $x^2 + 4x + 4 = 0$ is $x = -2$.
return response.text();
}
}
}
// [END googlegenaisdk_thinking_with_txt]
82 changes: 82 additions & 0 deletions genai/snippets/src/test/java/genai/thinking/ThinkingIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2025 Google LLC
*
* 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
*
* http://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 genai.thinking;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class ThinkingIT {

private static final String GEMINI_FLASH = "gemini-2.5-flash";
private ByteArrayOutputStream bout;
private PrintStream out;

// Check if the required environment variables are set.
public static void requireEnvVar(String envVarName) {
assertWithMessage(String.format("Missing environment variable '%s' ", envVarName))
.that(System.getenv(envVarName))
.isNotEmpty();
}

@BeforeClass
public static void checkRequirements() {
requireEnvVar("GOOGLE_CLOUD_PROJECT");
}

@Before
public void setUp() {
bout = new ByteArrayOutputStream();
out = new PrintStream(bout);
System.setOut(out);
}

@After
public void tearDown() {
System.setOut(null);
bout.reset();
}

@Test
public void testThinkingWithText() {
String response = ThinkingWithText.generateContent(GEMINI_FLASH);
assertThat(response).isNotEmpty();
}

@Test
public void testThinkingBudgetWithText() {
String response = ThinkingBudgetWithText.generateContent(GEMINI_FLASH);
assertThat(response).isNotEmpty();
assertThat(bout.toString()).contains("Token count for thinking: ");
assertThat(bout.toString()).contains("Total token count: ");
}

@Test
public void testThinkingIncludeThoughtsWithText() {
String response = ThinkingIncludeThoughtsWithText.generateContent(GEMINI_FLASH);
assertThat(response).isNotEmpty();
}
}