Skip to content

Commit 8aeee2b

Browse files
google-genai-botcopybara-github
authored andcommitted
feat: add ParallelAgent.fromConfig()
PiperOrigin-RevId: 834310422
1 parent b7e47b0 commit 8aeee2b

File tree

3 files changed

+155
-0
lines changed

3 files changed

+155
-0
lines changed

core/src/main/java/com/google/adk/agents/ConfigAgentUtils.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ private static Class<? extends BaseAgentConfig> getConfigClassForAgent(
220220
return SequentialAgentConfig.class;
221221
}
222222

223+
if (agentClass == ParallelAgent.class) {
224+
return ParallelAgentConfig.class;
225+
}
226+
223227
// TODO: Add more agent class to config class mappings as needed
224228
// Example:
225229
// if (agentClass == CustomAgent.class) {

core/src/main/java/com/google/adk/agents/ParallelAgent.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,20 @@
1717
package com.google.adk.agents;
1818

1919
import static com.google.common.base.Strings.isNullOrEmpty;
20+
import static com.google.common.base.Strings.nullToEmpty;
2021

22+
import com.google.adk.agents.ConfigAgentUtils.ConfigurationException;
2123
import com.google.adk.events.Event;
24+
import com.google.adk.utils.ComponentRegistry;
2225
import com.google.common.collect.ImmutableList;
2326
import com.google.errorprone.annotations.CanIgnoreReturnValue;
2427
import io.reactivex.rxjava3.core.Flowable;
2528
import java.util.ArrayList;
2629
import java.util.List;
30+
import java.util.function.Consumer;
31+
import javax.annotation.Nullable;
32+
import org.slf4j.Logger;
33+
import org.slf4j.LoggerFactory;
2734

2835
/**
2936
* A shell agent that runs its sub-agents in parallel in isolated manner.
@@ -34,6 +41,8 @@
3441
*/
3542
public class ParallelAgent extends BaseAgent {
3643

44+
private static final Logger logger = LoggerFactory.getLogger(ParallelAgent.class);
45+
3746
/**
3847
* Constructor for ParallelAgent.
3948
*
@@ -120,6 +129,82 @@ public static Builder builder() {
120129
return new Builder();
121130
}
122131

132+
/**
133+
* Creates a ParallelAgent from configuration.
134+
*
135+
* @param config the agent configuration
136+
* @param configAbsPath The absolute path to the agent config file.
137+
* @return the configured ParallelAgent
138+
* @throws ConfigurationException if the configuration is invalid
139+
*/
140+
public static ParallelAgent fromConfig(ParallelAgentConfig config, String configAbsPath)
141+
throws ConfigurationException {
142+
logger.debug("Creating ParallelAgent from config: {}", config.name());
143+
144+
// Validate required fields
145+
if (config.name() == null || config.name().trim().isEmpty()) {
146+
throw new ConfigurationException("Agent name is required");
147+
}
148+
149+
// Create builder with required fields
150+
Builder builder =
151+
ParallelAgent.builder().name(config.name()).description(nullToEmpty(config.description()));
152+
153+
// Resolve and add subagents using the utility class
154+
if (config.subAgents() != null && !config.subAgents().isEmpty()) {
155+
ImmutableList<BaseAgent> subAgents =
156+
ConfigAgentUtils.resolveSubAgents(config.subAgents(), configAbsPath);
157+
builder.subAgents(subAgents);
158+
}
159+
160+
// Resolve callbacks if configured
161+
setCallbacksFromConfig(config, builder);
162+
163+
// Build and return the agent
164+
ParallelAgent agent = builder.build();
165+
logger.info(
166+
"Successfully created ParallelAgent: {} with {} subagents",
167+
agent.name(),
168+
agent.subAgents() != null ? agent.subAgents().size() : 0);
169+
170+
return agent;
171+
}
172+
173+
private static void setCallbacksFromConfig(ParallelAgentConfig config, Builder builder)
174+
throws ConfigurationException {
175+
setCallbackFromConfig(
176+
config.beforeAgentCallbacks(),
177+
Callbacks.BeforeAgentCallbackBase.class,
178+
"before_agent_callback",
179+
builder::beforeAgentCallback);
180+
setCallbackFromConfig(
181+
config.afterAgentCallbacks(),
182+
Callbacks.AfterAgentCallbackBase.class,
183+
"after_agent_callback",
184+
builder::afterAgentCallback);
185+
}
186+
187+
private static <T> void setCallbackFromConfig(
188+
@Nullable List<ParallelAgentConfig.CallbackRef> refs,
189+
Class<T> callbackBaseClass,
190+
String callbackTypeName,
191+
Consumer<ImmutableList<T>> builderSetter)
192+
throws ConfigurationException {
193+
if (refs != null) {
194+
ImmutableList.Builder<T> list = ImmutableList.builder();
195+
for (ParallelAgentConfig.CallbackRef ref : refs) {
196+
list.add(
197+
ComponentRegistry.getInstance()
198+
.get(ref.name(), callbackBaseClass)
199+
.orElseThrow(
200+
() ->
201+
new ConfigurationException(
202+
"Invalid " + callbackTypeName + ": " + ref.name())));
203+
}
204+
builderSetter.accept(list.build());
205+
}
206+
}
207+
123208
/**
124209
* Sets the branch for the current agent in the invocation context.
125210
*
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.adk.agents;
17+
18+
import java.util.List;
19+
20+
/** Configuration for ParallelAgent. */
21+
public class ParallelAgentConfig extends BaseAgentConfig {
22+
23+
// Callback configuration (names resolved via ComponentRegistry)
24+
private List<CallbackRef> beforeAgentCallbacks;
25+
private List<CallbackRef> afterAgentCallbacks;
26+
27+
/** Reference to a callback stored in the ComponentRegistry. */
28+
public static class CallbackRef {
29+
private String name;
30+
31+
public CallbackRef() {}
32+
33+
public CallbackRef(String name) {
34+
this.name = name;
35+
}
36+
37+
public String name() {
38+
return name;
39+
}
40+
41+
public void setName(String name) {
42+
this.name = name;
43+
}
44+
}
45+
46+
public ParallelAgentConfig() {
47+
super();
48+
setAgentClass("ParallelAgent");
49+
}
50+
51+
public List<CallbackRef> beforeAgentCallbacks() {
52+
return beforeAgentCallbacks;
53+
}
54+
55+
public void setBeforeAgentCallbacks(List<CallbackRef> beforeAgentCallbacks) {
56+
this.beforeAgentCallbacks = beforeAgentCallbacks;
57+
}
58+
59+
public List<CallbackRef> afterAgentCallbacks() {
60+
return afterAgentCallbacks;
61+
}
62+
63+
public void setAfterAgentCallbacks(List<CallbackRef> afterAgentCallbacks) {
64+
this.afterAgentCallbacks = afterAgentCallbacks;
65+
}
66+
}

0 commit comments

Comments
 (0)