diff --git a/core/src/main/java/com/google/adk/tools/AgentTool.java b/core/src/main/java/com/google/adk/tools/AgentTool.java index 66d4a2700..5e8798d0e 100644 --- a/core/src/main/java/com/google/adk/tools/AgentTool.java +++ b/core/src/main/java/com/google/adk/tools/AgentTool.java @@ -31,6 +31,7 @@ import com.google.adk.runner.Runner; import com.google.adk.sessions.State; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.genai.types.Content; @@ -131,8 +132,14 @@ private Optional getOutputSchema(BaseAgent agent) { @Override public Optional declaration() { + + // The genai FunctionDeclaration builder uses Optional.of() internally, which NPEs on a null + // description. Coerce null to an empty string. This matches the Python, Go, and Kotlin ports, + // which send an empty description when the agent has none. + String desc = Strings.nullToEmpty(this.description()); + FunctionDeclaration.Builder builder = - FunctionDeclaration.builder().description(this.description()).name(this.name()); + FunctionDeclaration.builder().description(desc).name(this.name()); Optional agentInputSchema = getInputSchema(agent); diff --git a/core/src/test/java/com/google/adk/tools/AgentToolTest.java b/core/src/test/java/com/google/adk/tools/AgentToolTest.java index b37db6611..755cebc46 100644 --- a/core/src/test/java/com/google/adk/tools/AgentToolTest.java +++ b/core/src/test/java/com/google/adk/tools/AgentToolTest.java @@ -43,6 +43,7 @@ import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; import java.util.Map; +import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Before; import org.junit.Test; @@ -882,4 +883,21 @@ private ToolContext createToolContext(BaseAgent agent) { .build()) .build(); } + + @Test + public void declaration_withNullDescription_usesEmptyDescription() { + // Create an agent with a name but NO description + LlmAgent testAgent = + LlmAgent.builder() + .name("TestAgent") + // .description() is intentionally left out + .build(); + + AgentTool tool = AgentTool.create(testAgent); + Optional declaration = tool.declaration(); + assertThat(declaration).isPresent(); + assertThat(declaration.get().name()).hasValue("TestAgent"); + // Matches the Python, Go, and Kotlin ports: a missing description becomes an empty string. + assertThat(declaration.get().description()).hasValue(""); + } }