Skip to content

Commit 857e7d4

Browse files
google-genai-botcopybara-github
authored andcommitted
feat: Add invocationContext() to ReadOnlyContext
When using callbacks, developers should be able to access the InvocationContext. From there, it allows them to access the Session, and from the Session also to access Events, etc. This would align with Python which allows to access the invocation context. PiperOrigin-RevId: 781590060
1 parent a211ac4 commit 857e7d4

File tree

9 files changed

+226
-250
lines changed

9 files changed

+226
-250
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.google.adk.events.EventActions;
2020
import com.google.adk.sessions.State;
21+
import com.google.genai.types.Content;
2122
import com.google.genai.types.Part;
2223
import io.reactivex.rxjava3.core.Maybe;
2324
import java.util.Optional;
@@ -46,6 +47,11 @@ public State state() {
4647
return state;
4748
}
4849

50+
/** Returns the user content that initiated this invocation. */
51+
public Optional<Content> userContent() {
52+
return invocationContext.userContent();
53+
}
54+
4955
/** Returns the EventActions associated with this context. */
5056
public EventActions eventActions() {
5157
return eventActions;

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

Lines changed: 10 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.google.adk.agents;
1818

19-
import static com.google.common.collect.ImmutableList.toImmutableList;
2019
import static java.util.stream.Collectors.joining;
2120

2221
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -48,7 +47,6 @@
4847
import com.google.adk.models.BaseLlm;
4948
import com.google.adk.models.Model;
5049
import com.google.adk.tools.BaseTool;
51-
import com.google.adk.tools.BaseToolset;
5250
import com.google.common.base.Preconditions;
5351
import com.google.common.collect.ImmutableList;
5452
import com.google.errorprone.annotations.CanIgnoreReturnValue;
@@ -58,7 +56,6 @@
5856
import io.reactivex.rxjava3.core.Flowable;
5957
import io.reactivex.rxjava3.core.Maybe;
6058
import io.reactivex.rxjava3.core.Single;
61-
import java.util.ArrayList;
6259
import java.util.List;
6360
import java.util.Map;
6461
import java.util.Optional;
@@ -84,7 +81,7 @@ public enum IncludeContents {
8481
private final Optional<Model> model;
8582
private final Instruction instruction;
8683
private final Instruction globalInstruction;
87-
private final List<Object> toolsUnion;
84+
private final List<BaseTool> tools;
8885
private final Optional<GenerateContentConfig> generateContentConfig;
8986
private final Optional<BaseExampleProvider> exampleProvider;
9087
private final IncludeContents includeContents;
@@ -133,7 +130,7 @@ protected LlmAgent(Builder builder) {
133130
this.outputSchema = Optional.ofNullable(builder.outputSchema);
134131
this.executor = Optional.ofNullable(builder.executor);
135132
this.outputKey = Optional.ofNullable(builder.outputKey);
136-
this.toolsUnion = builder.toolsUnion != null ? builder.toolsUnion : ImmutableList.of();
133+
this.tools = builder.tools != null ? builder.tools : ImmutableList.of();
137134

138135
this.llmFlow = determineLlmFlow();
139136

@@ -156,7 +153,7 @@ public static class Builder {
156153
private Instruction instruction;
157154
private Instruction globalInstruction;
158155
private ImmutableList<BaseAgent> subAgents;
159-
private ImmutableList<Object> toolsUnion;
156+
private ImmutableList<BaseTool> tools;
160157
private GenerateContentConfig generateContentConfig;
161158
private BaseExampleProvider exampleProvider;
162159
private IncludeContents includeContents;
@@ -237,14 +234,14 @@ public Builder subAgents(BaseAgent... subAgents) {
237234
}
238235

239236
@CanIgnoreReturnValue
240-
public Builder tools(List<?> tools) {
241-
this.toolsUnion = ImmutableList.copyOf(tools);
237+
public Builder tools(List<? extends BaseTool> tools) {
238+
this.tools = ImmutableList.copyOf(tools);
242239
return this;
243240
}
244241

245242
@CanIgnoreReturnValue
246-
public Builder tools(Object... tools) {
247-
this.toolsUnion = ImmutableList.copyOf(tools);
243+
public Builder tools(BaseTool... tools) {
244+
this.tools = ImmutableList.copyOf(tools);
248245
return this;
249246
}
250247

@@ -583,7 +580,7 @@ protected void validate() {
583580
+ ": if outputSchema is set, subAgents must be empty to disable agent"
584581
+ " transfer.");
585582
}
586-
if (this.toolsUnion != null && !this.toolsUnion.isEmpty()) {
583+
if (this.tools != null && !this.tools.isEmpty()) {
587584
throw new IllegalArgumentException(
588585
"Invalid config for agent "
589586
+ this.name
@@ -690,42 +687,6 @@ public Single<String> canonicalGlobalInstruction(ReadonlyContext context) {
690687
throw new IllegalStateException("Unknown Instruction subtype: " + instruction.getClass());
691688
}
692689

693-
/**
694-
* Constructs the list of tools for this agent based on the {@link #tools} field.
695-
*
696-
* <p>This method is only for use by Agent Development Kit.
697-
*
698-
* @param context The context to retrieve the session state.
699-
* @return The resolved list of tools as a {@link Single} wrapped list of {@link BaseTool}.
700-
*/
701-
public Single<List<BaseTool>> canonicalTools(Optional<ReadonlyContext> context) {
702-
List<Single<List<BaseTool>>> toolSingles = new ArrayList<>();
703-
for (Object toolOrToolset : toolsUnion) {
704-
if (toolOrToolset instanceof BaseTool baseTool) {
705-
toolSingles.add(Single.just(ImmutableList.of(baseTool)));
706-
} else if (toolOrToolset instanceof BaseToolset baseToolset) {
707-
toolSingles.add(baseToolset.getTools(context.orElse(null)));
708-
} else {
709-
throw new IllegalArgumentException(
710-
"Object in tools list is not of a supported type: "
711-
+ toolOrToolset.getClass().getName());
712-
}
713-
}
714-
return Single.concat(toolSingles)
715-
.toList()
716-
.map(listOfLists -> listOfLists.stream().flatMap(List::stream).collect(toImmutableList()));
717-
}
718-
719-
/** Overload of canonicalTools that defaults to an empty context. */
720-
public Single<List<BaseTool>> canonicalTools() {
721-
return canonicalTools(Optional.empty());
722-
}
723-
724-
/** Convenience overload of canonicalTools that accepts a non-optional ReadonlyContext. */
725-
public Single<List<BaseTool>> canonicalTools(ReadonlyContext context) {
726-
return canonicalTools(Optional.ofNullable(context));
727-
}
728-
729690
public Instruction instruction() {
730691
return instruction;
731692
}
@@ -758,8 +719,8 @@ public IncludeContents includeContents() {
758719
return includeContents;
759720
}
760721

761-
public List<Object> tools() {
762-
return toolsUnion;
722+
public List<BaseTool> tools() {
723+
return tools;
763724
}
764725

765726
public boolean disallowTransferToParent() {

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.google.adk.agents;
1818

1919
import com.google.common.collect.ImmutableMap;
20-
import com.google.genai.types.Content;
2120
import java.util.Map;
2221
import java.util.Optional;
2322

@@ -30,11 +29,6 @@ public ReadonlyContext(InvocationContext invocationContext) {
3029
this.invocationContext = invocationContext;
3130
}
3231

33-
/** Returns the user content that initiated this invocation. */
34-
public Optional<Content> userContent() {
35-
return invocationContext.userContent();
36-
}
37-
3832
/** Returns the ID of the current invocation. */
3933
public String invocationId() {
4034
return invocationContext.invocationId();
@@ -50,6 +44,11 @@ public String agentName() {
5044
return invocationContext.agent().name();
5145
}
5246

47+
/** Returns the invocation context. */
48+
public InvocationContext invocationContext() {
49+
return invocationContext;
50+
}
51+
5352
/**
5453
* Returns a read-only view of the state of the current session.
5554
*

core/src/main/java/com/google/adk/flows/llmflows/BaseLlmFlow.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.google.adk.agents.InvocationContext;
2525
import com.google.adk.agents.LiveRequest;
2626
import com.google.adk.agents.LlmAgent;
27-
import com.google.adk.agents.ReadonlyContext;
2827
import com.google.adk.agents.RunConfig.StreamingMode;
2928
import com.google.adk.events.Event;
3029
import com.google.adk.exceptions.LlmCallsLimitExceededException;
@@ -113,22 +112,20 @@ protected Single<RequestProcessingResult> preprocess(
113112
processedRequest -> {
114113
LlmRequest.Builder updatedRequestBuilder = processedRequest.toBuilder();
115114

116-
return agent
117-
.canonicalTools(new ReadonlyContext(context))
118-
.flatMapCompletable(
119-
tools ->
120-
Flowable.fromIterable(tools)
121-
.concatMapCompletable(
122-
tool ->
123-
tool.processLlmRequest(
124-
updatedRequestBuilder, ToolContext.builder(context).build())))
125-
.andThen(
126-
Single.fromCallable(
127-
() -> {
128-
Iterable<Event> combinedEvents = Iterables.concat(eventIterables);
129-
return RequestProcessingResult.create(
130-
updatedRequestBuilder.build(), combinedEvents);
131-
}));
115+
Completable toolProcessingCompletable =
116+
Flowable.fromIterable(agent.tools())
117+
.concatMapCompletable(
118+
tool ->
119+
tool.processLlmRequest(
120+
updatedRequestBuilder, ToolContext.builder(context).build()));
121+
122+
return toolProcessingCompletable.andThen(
123+
Single.fromCallable(
124+
() -> {
125+
Iterable<Event> combinedEvents = Iterables.concat(eventIterables);
126+
return RequestProcessingResult.create(
127+
updatedRequestBuilder.build(), combinedEvents);
128+
}));
132129
});
133130
}
134131

core/src/main/java/com/google/adk/tools/BaseToolset.java

Lines changed: 0 additions & 54 deletions
This file was deleted.

core/src/main/java/com/google/adk/tools/ToolPredicate.java

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)