From c59b96642b242c91fb8b198ac2122ab91d78a0de Mon Sep 17 00:00:00 2001 From: Google Team Member Date: Mon, 26 Jan 2026 06:25:03 -0800 Subject: [PATCH] feat: Improving validation in LlmAgent PiperOrigin-RevId: 861164205 --- .../java/com/google/adk/agents/LlmAgent.java | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/google/adk/agents/LlmAgent.java b/core/src/main/java/com/google/adk/agents/LlmAgent.java index 78ebe757..bd2a2dbf 100644 --- a/core/src/main/java/com/google/adk/agents/LlmAgent.java +++ b/core/src/main/java/com/google/adk/agents/LlmAgent.java @@ -16,6 +16,7 @@ package com.google.adk.agents; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.ImmutableList.toImmutableList; import static java.util.stream.Collectors.joining; @@ -54,7 +55,6 @@ import com.google.adk.models.Model; import com.google.adk.tools.BaseTool; import com.google.adk.tools.BaseToolset; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.genai.types.Content; @@ -155,7 +155,7 @@ protected LlmAgent(Builder builder) { this.llmFlow = determineLlmFlow(); // Validate name not empty. - Preconditions.checkArgument(!this.name().isEmpty(), "Agent name cannot be empty."); + checkArgument(!this.name().isEmpty(), "Agent name cannot be empty."); } /** Returns a {@link Builder} for {@link LlmAgent}. */ @@ -613,21 +613,29 @@ private static ImmutableList convertCallbacks( } protected void validate() { - this.disallowTransferToParent = - this.disallowTransferToParent != null && this.disallowTransferToParent; - this.disallowTransferToPeers = - this.disallowTransferToPeers != null && this.disallowTransferToPeers; + if (this.generateContentConfig != null) { + checkArgument( + this.generateContentConfig.tools().isEmpty(), + "All tools must be set via LlmAgent.builder().tools()."); + checkArgument( + this.generateContentConfig.systemInstruction().isEmpty(), + "System instruction must be set via LlmAgent.builder().instruction()."); + checkArgument( + this.generateContentConfig.responseSchema().isEmpty(), + "Response schema must be set via LlmAgent.builder().outputSchema()."); + } if (this.outputSchema != null) { - if (!this.disallowTransferToParent || !this.disallowTransferToPeers) { + if (Objects.equals(this.disallowTransferToParent, false) + || Objects.equals(this.disallowTransferToPeers, false)) { logger.warn( "Invalid config for agent {}: outputSchema cannot co-exist with agent transfer" + " configurations. Setting disallowTransferToParent=true and" + " disallowTransferToPeers=true.", this.name); - this.disallowTransferToParent = true; - this.disallowTransferToPeers = true; } + this.disallowTransferToParent = true; + this.disallowTransferToPeers = true; if (this.subAgents != null && !this.subAgents.isEmpty()) { throw new IllegalArgumentException( @@ -642,6 +650,11 @@ protected void validate() { + this.name + ": if outputSchema is set, tools must be empty."); } + } else { + this.disallowTransferToParent = + this.disallowTransferToParent != null && this.disallowTransferToParent; + this.disallowTransferToPeers = + this.disallowTransferToPeers != null && this.disallowTransferToPeers; } } @@ -670,6 +683,10 @@ private void maybeSaveOutputToState(Event event) { .map(part -> part.text().orElse("")) .collect(joining()); + if (rawResult.isBlank()) { + return; + } + Optional outputSchema = outputSchema(); if (outputSchema.isPresent()) { try {