CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-google-genai--google-genai

Java idiomatic SDK for the Gemini Developer APIs and Vertex AI APIs

Overview
Eval results
Files

tools-functions.mddocs/

Tools and Function Calling

Use tools like Google Search, code execution, and custom function calling with automatic or manual execution.

Core Imports

import com.google.genai.types.Tool;
import com.google.genai.types.FunctionDeclaration;
import com.google.genai.types.FunctionCall;
import com.google.genai.types.FunctionResponse;
import com.google.genai.types.ToolConfig;
import com.google.genai.types.FunctionCallingConfig;
import com.google.genai.types.AutomaticFunctionCallingConfig;
import com.google.genai.types.Schema;
import com.google.genai.types.GoogleSearch;
import com.google.genai.types.CodeExecution;
import java.lang.reflect.Method;

Tool Type

package com.google.genai.types;

public final class Tool {
  public static Builder builder();

  public Optional<List<FunctionDeclaration>> functionDeclarations();
  public Optional<GoogleSearchRetrieval> googleSearchRetrieval();
  public Optional<GoogleSearch> googleSearch();
  public Optional<GoogleMaps> googleMaps();
  public Optional<CodeExecution> codeExecution();
  public Optional<FileSearch> fileSearch();
  public Optional<ComputerUse> computerUse();
  public Optional<Retrieval> retrieval();
  public Optional<UrlContext> urlContext();
}

Function Declaration

package com.google.genai.types;

public final class FunctionDeclaration {
  public static Builder builder();

  public Optional<String> name();
  public Optional<String> description();
  public Optional<Schema> parameters();
}

Tool Configuration

package com.google.genai.types;

public final class ToolConfig {
  public static Builder builder();

  public Optional<FunctionCallingConfig> functionCallingConfig();
  public Optional<RetrievalConfig> retrievalConfig();
}
package com.google.genai.types;

public final class FunctionCallingConfig {
  public static Builder builder();

  public Optional<String> mode();
  public Optional<List<String>> allowedFunctionNames();
  public Optional<Boolean> streamFunctionCallArguments();
}
package com.google.genai.types;

public final class AutomaticFunctionCallingConfig {
  public static Builder builder();

  public Optional<Boolean> disable();
  public Optional<Integer> maxRemoteCalls();
  public Optional<Boolean> appendHistory();
}

Automatic Function Calling

Step 1: Enable Parameter Names

Add to pom.xml:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.14.0</version>
  <configuration>
    <compilerArgs>
      <arg>-parameters</arg>
    </compilerArgs>
  </configuration>
</plugin>

Step 2: Define Function

public class WeatherService {
    public static String getCurrentWeather(String location, String unit) {
        // Implementation
        return "The weather in " + location + " is sunny, 72 degrees " + unit;
    }
}

Step 3: Use with Generation

import java.lang.reflect.Method;

Method weatherMethod = WeatherService.class.getMethod(
    "getCurrentWeather", String.class, String.class);

GenerateContentConfig config = GenerateContentConfig.builder()
    .tools(Tool.builder()
        .functions(weatherMethod)
        .build())
    .build();

GenerateContentResponse response = client.models.generateContent(
    "gemini-2.0-flash",
    "What's the weather in Vancouver?",
    config
);

System.out.println("Response: " + response.text());
System.out.println("Function calling history: " +
    response.automaticFunctionCallingHistory().orElse(null));

Multiple Functions

public class ToolBox {
    public static String getCurrentWeather(String location) {
        return "Sunny, 75°F";
    }

    public static int add(int a, int b) {
        return a + b;
    }

    public static String searchWeb(String query) {
        return "Search results for: " + query;
    }
}

// Load all methods
Method weatherMethod = ToolBox.class.getMethod("getCurrentWeather", String.class);
Method addMethod = ToolBox.class.getMethod("add", int.class, int.class);
Method searchMethod = ToolBox.class.getMethod("searchWeb", String.class);

Tool tool = Tool.builder()
    .functions(weatherMethod, addMethod, searchMethod)
    .build();

GenerateContentConfig config = GenerateContentConfig.builder()
    .tools(tool)
    .build();

Manual Function Calling

Define Function Declaration

FunctionDeclaration function = FunctionDeclaration.builder()
    .name("getCurrentWeather")
    .description("Get the current weather in a location")
    .parameters(Schema.builder()
        .type(Type.Known.OBJECT)
        .properties(ImmutableMap.of(
            "location", Schema.builder()
                .type(Type.Known.STRING)
                .description("The city and state, e.g. San Francisco, CA")
                .build(),
            "unit", Schema.builder()
                .type(Type.Known.STRING)
                .enum_(ImmutableList.of("celsius", "fahrenheit"))
                .build()
        ))
        .required(ImmutableList.of("location"))
        .build())
    .build();

Tool tool = Tool.builder()
    .functionDeclarations(ImmutableList.of(function))
    .build();

Use in Generation

GenerateContentConfig config = GenerateContentConfig.builder()
    .tools(tool)
    .build();

GenerateContentResponse response = client.models.generateContent(
    "gemini-2.0-flash",
    "What's the weather in Boston?",
    config
);

// Process function call
response.candidates().ifPresent(candidates -> {
    if (!candidates.isEmpty()) {
        Content content = candidates.get(0).content().orElse(null);
        if (content != null && content.parts().isPresent()) {
            for (Part part : content.parts().get()) {
                part.functionCall().ifPresent(functionCall -> {
                    // Execute function
                    String functionName = functionCall.name().orElse("");
                    JsonNode args = functionCall.args().orElse(null);

                    // Call your function
                    String result = executeFunction(functionName, args);

                    // Send result back
                    sendFunctionResponse(functionCall, result);
                });
            }
        }
    }
});

Send Function Response

private void sendFunctionResponse(FunctionCall call, String result) {
    FunctionResponse response = FunctionResponse.builder()
        .name(call.name().orElse(""))
        .response(objectMapper.valueToTree(ImmutableMap.of("result", result)))
        .id(call.id().orElse(null))
        .build();

    Content responseContent = Content.fromParts(
        Part.fromFunctionResponse(response)
    );

    GenerateContentResponse finalResponse = client.models.generateContent(
        "gemini-2.0-flash",
        responseContent,
        null
    );

    System.out.println(finalResponse.text());
}

Google Search Tool

import com.google.genai.types.GoogleSearch;

Tool searchTool = Tool.builder()
    .googleSearch(GoogleSearch.builder().build())
    .build();

GenerateContentConfig config = GenerateContentConfig.builder()
    .tools(searchTool)
    .build();

GenerateContentResponse response = client.models.generateContent(
    "gemini-2.0-flash",
    "What are the latest developments in quantum computing?",
    config
);

Code Execution Tool

import com.google.genai.types.CodeExecution;

Tool codeExecTool = Tool.builder()
    .codeExecution(CodeExecution.builder().build())
    .build();

GenerateContentConfig config = GenerateContentConfig.builder()
    .tools(codeExecTool)
    .build();

GenerateContentResponse response = client.models.generateContent(
    "gemini-2.0-flash",
    "Calculate the first 10 fibonacci numbers",
    config
);

Function Calling Modes

import com.google.genai.types.FunctionCallingMode;

// AUTO: Model decides when to call functions
ToolConfig autoConfig = ToolConfig.builder()
    .functionCallingConfig(FunctionCallingConfig.builder()
        .mode(FunctionCallingMode.Known.AUTO)
        .build())
    .build();

// ANY: Model must call at least one function
ToolConfig anyConfig = ToolConfig.builder()
    .functionCallingConfig(FunctionCallingConfig.builder()
        .mode(FunctionCallingMode.Known.ANY)
        .build())
    .build();

// NONE: Model cannot call functions
ToolConfig noneConfig = ToolConfig.builder()
    .functionCallingConfig(FunctionCallingConfig.builder()
        .mode(FunctionCallingMode.Known.NONE)
        .build())
    .build();

GenerateContentConfig config = GenerateContentConfig.builder()
    .tools(tool)
    .toolConfig(autoConfig)
    .build();

Restrict Functions

// Only allow specific functions
ToolConfig config = ToolConfig.builder()
    .functionCallingConfig(FunctionCallingConfig.builder()
        .mode(FunctionCallingMode.Known.ANY)
        .allowedFunctionNames(ImmutableList.of("getCurrentWeather", "searchWeb"))
        .build())
    .build();

GenerateContentConfig genConfig = GenerateContentConfig.builder()
    .tools(tool)
    .toolConfig(config)
    .build();

Configure Automatic Function Calling

// Customize automatic function calling behavior
AutomaticFunctionCallingConfig afcConfig = AutomaticFunctionCallingConfig.builder()
    .maxRemoteCalls(5) // Limit remote calls
    .appendHistory(true) // Include in history
    .build();

GenerateContentConfig config = GenerateContentConfig.builder()
    .tools(tool)
    .automaticFunctionCalling(afcConfig)
    .build();

// Or disable AFC
AutomaticFunctionCallingConfig disableAFC = AutomaticFunctionCallingConfig.builder()
    .disable(true)
    .build();

GenerateContentConfig manualConfig = GenerateContentConfig.builder()
    .tools(tool)
    .automaticFunctionCalling(disableAFC)
    .build();

Multi-Turn Function Calling

List<Content> conversationHistory = new ArrayList<>();

// Initial query
conversationHistory.add(Content.builder()
    .role("user")
    .parts(ImmutableList.of(Part.fromText("What's the weather in Paris and Berlin?")))
    .build());

GenerateContentResponse response1 = client.models.generateContent(
    "gemini-2.0-flash",
    conversationHistory,
    config
);

// Process function calls and add to history
response1.candidates().ifPresent(candidates -> {
    Content modelResponse = candidates.get(0).content().orElse(null);
    if (modelResponse != null) {
        conversationHistory.add(modelResponse);

        // Execute function calls and add responses
        for (Part part : modelResponse.parts().orElse(ImmutableList.of())) {
            part.functionCall().ifPresent(call -> {
                String result = executeFunct(call);
                conversationHistory.add(Content.fromParts(
                    Part.fromFunctionResponse(FunctionResponse.builder()
                        .name(call.name().orElse(""))
                        .response(objectMapper.valueToTree(result))
                        .build())
                ));
            });
        }
    }
});

// Continue conversation
GenerateContentResponse finalResponse = client.models.generateContent(
    "gemini-2.0-flash",
    conversationHistory,
    config
);

Best Practices

Type-Safe Function Parameters

public static class WeatherParams {
    public String location;
    public String unit;
}

public static String getCurrentWeather(WeatherParams params) {
    return "Weather in " + params.location + ": sunny";
}

Error Handling in Functions

public static String safeFunction(String input) {
    try {
        // Function logic
        return performOperation(input);
    } catch (Exception e) {
        return "Error: " + e.getMessage();
    }
}

Validate Function Results

FunctionCall call = /* ... */;
String result = executeFunction(call);

// Validate result before sending
if (result == null || result.isEmpty()) {
    result = "Function returned no result";
}

FunctionResponse response = FunctionResponse.builder()
    .name(call.name().orElse(""))
    .response(objectMapper.valueToTree(ImmutableMap.of("result", result)))
    .build();

Install with Tessl CLI

npx tessl i tessl/maven-com-google-genai--google-genai

docs

batch-operations.md

caching.md

chat-sessions.md

client-configuration.md

content-generation.md

embeddings-tokens.md

error-handling.md

file-search-stores.md

files-management.md

image-operations.md

index.md

live-sessions.md

model-tuning.md

operations.md

tools-functions.md

types-reference.md

video-generation.md

tile.json