-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat(genai): add thinking samples #10160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jdomingr
wants to merge
7
commits into
GoogleCloudPlatform:main
Choose a base branch
from
jdomingr:genai-sdk-thinking-samples
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
2ae0919
feat: add new genAI thinking with text sample
2a1028d
feat: add new GenAI sdk thinking with budget sample
5771f64
feat: add new GenAI sdk thinking with thoughts sample
e855135
feat(genai): add test for ThinkingIncludeThoughts sample
b7417c7
refactor: change the way of getting the first candidate for an stream…
410c1a6
refactor: change gemini model and change example responses
2a7ba90
refactor: apply code review suggestions and change filenames to match…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
genai/snippets/src/main/java/genai/thinking/ThinkingBudgetWithText.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] |
107 changes: 107 additions & 0 deletions
107
genai/snippets/src/main/java/genai/thinking/ThinkingIncludeThoughtsWithText.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
99
genai/snippets/src/main/java/genai/thinking/ThinkingWithText.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
jdomingr marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
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
82
genai/snippets/src/test/java/genai/thinking/ThinkingIT.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
jdomingr marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.