From 5dfc000c9019b4d11a33b35c71c2a04d1f657bf2 Mon Sep 17 00:00:00 2001 From: Google Team Member Date: Thu, 5 Feb 2026 12:21:38 -0800 Subject: [PATCH] feat: Adding validation to BaseAgent PiperOrigin-RevId: 866059790 --- .../java/com/google/adk/agents/BaseAgent.java | 51 +++++++++++++++++-- .../com/google/adk/agents/BaseAgentTest.java | 11 ++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/adk/agents/BaseAgent.java b/core/src/main/java/com/google/adk/agents/BaseAgent.java index e7af0d1e..0db4dabb 100644 --- a/core/src/main/java/com/google/adk/agents/BaseAgent.java +++ b/core/src/main/java/com/google/adk/agents/BaseAgent.java @@ -35,6 +35,7 @@ import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.Single; +import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.function.Function; @@ -90,13 +91,16 @@ public BaseAgent( this.name = name; this.description = description; this.parentAgent = null; - this.subAgents = subAgents == null ? ImmutableList.of() : ImmutableList.copyOf(subAgents); + this.subAgents = (subAgents != null) ? ImmutableList.copyOf(subAgents) : ImmutableList.of(); + validateSubAgents(this.name, this.subAgents); this.beforeAgentCallback = - beforeAgentCallback == null - ? ImmutableList.of() - : ImmutableList.copyOf(beforeAgentCallback); + (beforeAgentCallback != null) + ? ImmutableList.copyOf(beforeAgentCallback) + : ImmutableList.of(); this.afterAgentCallback = - afterAgentCallback == null ? ImmutableList.of() : ImmutableList.copyOf(afterAgentCallback); + (afterAgentCallback != null) + ? ImmutableList.copyOf(afterAgentCallback) + : ImmutableList.of(); // Establish parent relationships for all sub-agents if needed. for (BaseAgent subAgent : this.subAgents) { @@ -104,6 +108,13 @@ public BaseAgent( } } + /** + * Validates the agent name. + * + * @param name The agent name to validate. + * @throws IllegalArgumentException if the agent name is null, empty, or does not match the + * identifier pattern. + */ private static void validateAgentName(String name) { if (isNullOrEmpty(name)) { throw new IllegalArgumentException("Agent name cannot be null or empty."); @@ -118,6 +129,36 @@ private static void validateAgentName(String name) { } } + /** + * Validates the sub-agents. + * + * @param name The name of the parent agent. + * @param subAgents The list of sub-agents to validate. + * @throws IllegalArgumentException if the sub-agents have duplicate names. + */ + private static void validateSubAgents( + String name, @Nullable List subAgents) { + if (subAgents == null) { + return; + } + HashSet subAgentNames = new HashSet<>(); + HashSet duplicateSubAgentNames = new HashSet<>(); + for (BaseAgent subAgent : subAgents) { + String subAgentName = subAgent.name(); + // NOTE: Mocked agents have null names because BaseAgent.name() is a final method that + // cannot be mocked. + if (subAgentName != null && !subAgentNames.add(subAgentName)) { + duplicateSubAgentNames.add(subAgentName); + } + } + if (!duplicateSubAgentNames.isEmpty()) { + throw new IllegalArgumentException( + format( + "Agent named '%s' has sub-agents with duplicate names: %s. Sub-agents: %s", + name, duplicateSubAgentNames, subAgents)); + } + } + /** * Gets the agent's unique name. * diff --git a/core/src/test/java/com/google/adk/agents/BaseAgentTest.java b/core/src/test/java/com/google/adk/agents/BaseAgentTest.java index 4afce04e..d435e90c 100644 --- a/core/src/test/java/com/google/adk/agents/BaseAgentTest.java +++ b/core/src/test/java/com/google/adk/agents/BaseAgentTest.java @@ -351,4 +351,15 @@ public void constructor_userName_throwsIllegalArgumentException() { IllegalArgumentException.class, () -> new TestBaseAgent("user", "description", null, null, null)); } + + @Test + public void constructor_duplicateSubAgentNames_throwsIllegalArgumentException() { + TestBaseAgent subAgent1 = new TestBaseAgent("subAgent", "subAgent1", null, null, null); + TestBaseAgent subAgent2 = new TestBaseAgent("subAgent", "subAgent2", null, null, null); + assertThrows( + IllegalArgumentException.class, + () -> + new TestBaseAgent( + "agent", "description", null, ImmutableList.of(subAgent1, subAgent2), null, null)); + } }