A modern Java SDK for the Google Gemini Interactions API.
- Modern Java: Built with Java 17+, utilizing Records, Sealed Interfaces, and pattern matching.
- Easy to Use: Fluent Builder APIs for constructing requests.
- Multimodal: Native support for Text, Image, and Function Calling.
- Lightweight: Minimal dependencies (Jackson, Java Standard Library).
Add the dependency to your pom.xml:
<dependency>
<groupId>io.github.glaforge</groupId>
<artifactId>gemini-interactions-api-sdk</artifactId>
<version>0.4.4</version>
</dependency>import io.github.glaforge.gemini.interactions.GeminiInteractionsClient;
import io.github.glaforge.gemini.interactions.model.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
GeminiInteractionsClient client = GeminiInteractionsClient.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.build();ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("Why is the sky blue?")
.build();
Interaction response = client.create(request);
System.out.println(response.outputs().get(0));import io.github.glaforge.gemini.interactions.model.Interaction.Turn;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import io.github.glaforge.gemini.interactions.model.Content.*;
import static io.github.glaforge.gemini.interactions.model.Interaction.Role.*;
ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input(
new Turn(USER, "Hello!"),
new Turn(MODEL, "Hi! How can I help?"),
new Turn(USER, "Tell me a joke")
)
.build();
Interaction response = client.create(request);You can also continue a conversation by referencing the ID of a previous interaction. Ensure you set store(true) to persist the interaction context.
// 1. First turn (must set store=true)
ModelInteractionParams turn1 = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("Hello!")
.store(true)
.build();
Interaction response1 = client.create(turn1);
String id = response1.id();
System.out.println(response1.outputs().get(0));
// 2. Second turn (referencing previous ID)
ModelInteractionParams turn2 = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("Tell me a joke")
.previousInteractionId(id)
.store(true) // Optional if you want to extend further
.build();
Interaction response2 = client.create(turn2);
System.out.println(response2.outputs().get(0));import io.github.glaforge.gemini.interactions.model.Content.*;
ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input(
new TextContent("Describe this image"),
// Create an image from Base64 string
new ImageContent("BASE64_STRING...", "image/png")
)
.build();
Interaction response = client.create(request);import io.github.glaforge.gemini.interactions.model.Content.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import io.github.glaforge.gemini.interactions.model.Interaction.Modality;
ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-3-pro-image-preview")
.input("Create an infographic about blood, organs, and the circulatory system")
.responseModalities(Modality.IMAGE)
.build();
Interaction interaction = client.create(request);
interaction.outputs().forEach(content -> {
if (content instanceof ImageContent image) {
byte[] imageBytes = Base64.getDecoder().decode(image.data());
// Save imageBytes to a file
}
});import io.github.glaforge.gemini.interactions.model.Interaction;
import io.github.glaforge.gemini.interactions.model.Interaction.Status;
import io.github.glaforge.gemini.interactions.model.InteractionParams.AgentInteractionParams;
AgentInteractionParams request = AgentInteractionParams.builder()
.agent("deep-research-pro-preview-12-2025")
.input("Research the history of the Google TPUs")
.build();
Interaction interaction = client.create(request);
// Poll for completion
while (interaction.status() != Status.COMPLETED) {
Thread.sleep(1000);
interaction = client.get(interaction.id());
}
System.out.println(interaction.outputs());import io.github.glaforge.gemini.interactions.model.Content;
import io.github.glaforge.gemini.interactions.model.Content.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import io.github.glaforge.gemini.interactions.model.Tool;
import io.github.glaforge.gemini.interactions.model.Tool.Function;
// 1. Define the tool
Function weatherTool = Function.builder()
.name("get_weather")
.description("Get the current weather")
.parameters(
Map.of(
"type", "object",
"properties", Map.of(
"location", Map.of("type", "string")
),
"required", List.of("location")
)
.build();
// 2. Initial Request with Tools
ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("What is the weather in London?")
.tools(weatherTool)
.build();
Interaction interaction = client.create(request);
// 3. Handle Function Call
Content lastOutput = interaction.outputs().getLast();
if (lastOutput instanceof FunctionCallContent call) {
if ("get_weather".equals(call.name())) {
String location = (String) call.arguments().get("location");
// Execute local logic...
String weather = "Rainy, 15°C"; // Simulated result
// 4. Send Function Result
ModelInteractionParams continuation = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.previousInteractionId(interaction.id())
.input(new FunctionResultContent(
"function_result",
call.id(),
call.name(),
false,
Map.of("weather", weather)
))
.build();
Interaction finalResponse = client.create(continuation);
System.out.println(finalResponse.outputs().getLast());
}
}You can enforce the model to output a specific JSON structure using the responseFormat parameter.
You can pass a Map representing the JSON Schema directly.
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import java.util.Map;
import java.util.List;
ModelInteractionParams params = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("List 5 popular cookie recipes")
.responseMimeType("application/json")
.responseFormat(Map.of(
"type", "array",
"items", Map.of(
"type", "object",
"properties", Map.of(
"recipe_name", Map.of("type", "string")
)
)
))
.build();You can use the fluent Schema builder API provided by the SDK.
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import io.github.glaforge.gemini.schema.GSchema;
import static io.github.glaforge.gemini.schema.GSchema.*;
ModelInteractionParams params = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("List 5 popular cookie recipes")
.responseMimeType("application/json")
.responseFormat(
arr().items(
obj()
.prop("recipe_name", str())
.prop("ingredients", arr().items(str()))
)
)
.build();You can generate the schema directly from a Java class (Records or POJOs).
public record Recipe(String name, List<String> ingredients) {}
ModelInteractionParams params = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("List 5 popular cookie recipes")
.responseMimeType("application/json")
.responseFormat(GSchema.fromClass(Recipe.class))
.build();You can also parse an existing JSON Schema string.
String jsonSchema = """
{
"type": "array",
"items": { "type": "string" }
}
""";
ModelInteractionParams params = ModelInteractionParams.builder()
.model("gemini-2.5-flash")
.input("List 5 popular cookie recipes")
.responseMimeType("application/json")
.responseFormat(GSchema.fromJson(jsonSchema))
.build();Apache 2.0
This is not an official Google project.