Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/main/java/com/google/adk/agents/BaseAgent.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ private static void validateAgentName(String name) {
throw new IllegalArgumentException(
format("Agent name '%s' does not match regex '%s'.", name, IDENTIFIER_REGEX));
}
if (name.equals("user")) {
if (name.equals(Role.USER)) {
throw new IllegalArgumentException(
"Agent name cannot be 'user'; reserved for end-user input.");
}
Expand Down
25 changes: 25 additions & 0 deletions core/src/main/java/com/google/adk/agents/Role.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.adk.agents;

/** Standard role names for {@code Content} and event authors. */
public final class Role {
/** The user interacting with the agent or model: a {@code Content} role and an event author. */
public static final String USER = "user";

private Role() {}
}
3 changes: 2 additions & 1 deletion core/src/main/java/com/google/adk/apps/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.ContextCacheConfig;
import com.google.adk.agents.Role;
import com.google.adk.plugins.Plugin;
import com.google.adk.summarizer.EventsCompactionConfig;
import com.google.common.collect.ImmutableList;
Expand Down Expand Up @@ -168,7 +169,7 @@ private static void validateAppName(String name) {
+ name
+ "': must be a valid identifier consisting of letters, digits, and underscores.");
}
if (name.equals("user")) {
if (name.equals(Role.USER)) {
throw new IllegalArgumentException("App name cannot be 'user'; reserved for end-user input.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.adk.JsonBaseModel;
import com.google.adk.agents.Role;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
Expand Down Expand Up @@ -114,7 +115,7 @@ public static Content convertCodeExecutionParts(
+ lastPart.codeExecutionResult().get().output()
+ executionResultDelimiters.get(1));
newParts.set(newParts.size() - 1, newPart);
return Content.builder().parts(newParts).role("user").build();
return Content.builder().parts(newParts).role(Role.USER).build();
}

return content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import com.google.adk.agents.InvocationContext;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.Role;
import com.google.adk.codeexecutors.BuiltInCodeExecutor;
import com.google.adk.codeexecutors.CodeExecutionUtils;
import com.google.adk.codeexecutors.CodeExecutionUtils.CodeExecutionInput;
Expand Down Expand Up @@ -347,7 +348,7 @@ private static List<File> extractAndReplaceInlineFiles(
for (int i = 0; i < llmRequest.contents().size(); i++) {
Content content = llmRequest.contents().get(i);
if (content.role().isEmpty()
|| !Objects.equals(content.role().get(), "user")
|| !Objects.equals(content.role().get(), Role.USER)
|| content.parts().isEmpty()) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.adk.JsonBaseModel;
import com.google.adk.agents.InvocationContext;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.Role;
import com.google.adk.events.Event;
import com.google.adk.events.EventCompaction;
import com.google.adk.models.LlmRequest;
Expand Down Expand Up @@ -112,7 +113,7 @@ private ImmutableList<Content> getCurrentTurnContents(
// Find the latest event that starts the current turn and process from there.
for (int i = events.size() - 1; i >= 0; i--) {
Event event = events.get(i);
if (event.author().equals("user") || isOtherAgentReply(agentName, event)) {
if (event.author().equals(Role.USER) || isOtherAgentReply(agentName, event)) {
return getContents(
currentBranch, events.subList(i, events.size()), agentName, groupFunctionResponses);
}
Expand Down Expand Up @@ -404,7 +405,7 @@ private static Event createCompactionEvent(Event event) {
private static boolean isOtherAgentReply(String agentName, Event event) {
return !agentName.isEmpty()
&& !event.author().equals(agentName)
&& !event.author().equals("user");
&& !event.author().equals(Role.USER);
}

/**
Expand Down Expand Up @@ -482,8 +483,8 @@ private static boolean isOtherAgentReply(String agentName, Event event) {
return null;
}

Content content = Content.builder().role("user").parts(parts).build();
return event.toBuilder().author("user").content(content).build();
Content content = Content.builder().role(Role.USER).parts(parts).build();
return event.toBuilder().author(Role.USER).content(content).build();
}

private static String convertMapToJson(Map<String, Object> struct) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.adk.agents.Callbacks.OnToolErrorCallback;
import com.google.adk.agents.InvocationContext;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.Role;
import com.google.adk.agents.RunConfig.ToolExecutionMode;
import com.google.adk.events.Event;
import com.google.adk.events.EventActions;
Expand Down Expand Up @@ -379,7 +380,7 @@ private static Maybe<Map<String, Object>> processFunctionLive(
result -> {
String resultText = "Function " + tool.name() + " returned: " + result;
Content updateContent =
Content.builder().role("user").parts(Part.fromText(resultText)).build();
Content.builder().role(Role.USER).parts(Part.fromText(resultText)).build();
invocationContext.liveRequestQueue().get().content(updateContent);
},
error -> logger.error("Error in streaming tool " + tool.name(), error.getCause()),
Expand Down Expand Up @@ -588,7 +589,7 @@ private static Optional<Event> mergeParallelFunctionResponseEvents(
.invocationId(baseEvent.invocationId())
.author(baseEvent.author())
.branch(baseEvent.branch().orElse(null))
.content(Content.builder().role("user").parts(mergedParts).build())
.content(Content.builder().role(Role.USER).parts(mergedParts).build())
.actions(mergedActionsBuilder.build())
.timestamp(baseEvent.timestamp())
.build());
Expand Down Expand Up @@ -739,7 +740,7 @@ private static Event buildResponseEvent(
.invocationId(invocationContext.invocationId())
.author(invocationContext.agent().name())
.branch(invocationContext.branch().orElse(null))
.content(Content.builder().role("user").parts(partFunctionResponse).build())
.content(Content.builder().role(Role.USER).parts(partFunctionResponse).build())
.actions(toolContext.eventActions())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.adk.JsonBaseModel;
import com.google.adk.agents.InvocationContext;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.Role;
import com.google.adk.events.Event;
import com.google.adk.events.ToolConfirmation;
import com.google.adk.models.LlmRequest;
Expand Down Expand Up @@ -169,7 +170,7 @@ private static Optional<ConfirmationResult> findMostRecentConfirmations(
// function responses.
for (int i = events.size() - 1; i >= 0; i--) {
Event event = events.get(i);
if (!Objects.equals(event.author(), "user") || event.functionResponses().isEmpty()) {
if (!Objects.equals(event.author(), Role.USER) || event.functionResponses().isEmpty()) {
continue;
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/com/google/adk/models/GeminiUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.adk.agents.Role;
import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand Down Expand Up @@ -202,11 +203,11 @@ private static Part removeClientFunctionCallIdFromPart(Part part) {
static List<Content> ensureModelResponse(List<Content> contents) {
// Last content must be from the user, otherwise the model won't respond.
if (contents.isEmpty()
|| !Ascii.equalsIgnoreCase(Iterables.getLast(contents).role().orElse(""), "user")) {
|| !Ascii.equalsIgnoreCase(Iterables.getLast(contents).role().orElse(""), Role.USER)) {
Content userContent =
Content.builder()
.parts(ImmutableList.of(Part.fromText(CONTINUE_OUTPUT_MESSAGE)))
.role("user")
.role(Role.USER)
.build();
return Stream.concat(contents.stream(), Stream.of(userContent)).collect(toImmutableList());
}
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/com/google/adk/models/LlmRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.adk.JsonBaseModel;
import com.google.adk.agents.Role;
import com.google.adk.tools.BaseTool;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
Expand Down Expand Up @@ -195,7 +196,7 @@ private Content addInstructions(
.map(text -> text + "\n\n" + instructions)
.orElse(instructions));

String role = currentSystemInstruction.flatMap(Content::role).orElse("user");
String role = currentSystemInstruction.flatMap(Content::role).orElse(Role.USER);

return Content.builder().parts(part).role(role).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.adk.JsonBaseModel;
import com.google.adk.agents.Role;
import com.google.adk.models.LlmRequest;
import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
Expand Down Expand Up @@ -377,7 +378,7 @@ private static Optional<Message> processSystemInstruction(
*/
private static List<Message> processContent(Content content) {
Message msg = new Message();
String role = content.role().orElse("user");
String role = content.role().orElse(Role.USER);
msg.role = role.equals("model") ? "assistant" : role;

List<ContentPart> contentParts = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.google.common.base.Preconditions.checkArgument;

import com.google.adk.agents.CallbackContext;
import com.google.adk.agents.Role;
import com.google.adk.models.LlmRequest;
import com.google.adk.models.LlmResponse;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
Expand Down Expand Up @@ -63,7 +64,6 @@
public class ContextFilterPlugin extends BasePlugin {
private static final Logger logger = LoggerFactory.getLogger(ContextFilterPlugin.class);
private static final String MODEL_ROLE = "model";
private static final String USER_ROLE = "user";

private final Optional<Integer> numInvocationsToKeep;
private final Optional<UnaryOperator<List<Content>>> customFilter;
Expand Down Expand Up @@ -159,7 +159,7 @@ private List<Content> trimContentsByInvocations(int numInvocations, List<Content
int finalSplitIndex = adjustIndexForToolCalls(candidateSplitIndex, contents);
// The Nth model turn can be preceded by user turns; expand window to include them.
while (finalSplitIndex > 0
&& hasRole(contents.get(finalSplitIndex - 1), USER_ROLE)
&& hasRole(contents.get(finalSplitIndex - 1), Role.USER)
&& !isFunctionResponse(contents.get(finalSplitIndex - 1))) {
finalSplitIndex--;
}
Expand All @@ -174,7 +174,7 @@ private int findNthModelTurnStartIndex(int numInvocations, List<Content> content
if (modelTurnsToFind == 0) {
int startIndex = i;
// Include all preceding user messages in the same turn.
while (startIndex > 0 && hasRole(contents.get(startIndex - 1), USER_ROLE)) {
while (startIndex > 0 && hasRole(contents.get(startIndex - 1), Role.USER)) {
startIndex--;
}
return startIndex;
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/com/google/adk/runner/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.adk.agents.InvocationContext;
import com.google.adk.agents.LiveRequestQueue;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.Role;
import com.google.adk.agents.RunConfig;
import com.google.adk.agents.SequentialAgent;
import com.google.adk.apps.App;
Expand Down Expand Up @@ -391,7 +392,7 @@ private Single<Event> appendNewMessageToSession(
Event.builder()
.id(Event.generateEventId())
.invocationId(invocationContext.invocationId())
.author("user")
.author(Role.USER)
.content(messageToAppend);

// Add state delta if provided
Expand Down Expand Up @@ -867,7 +868,7 @@ private BaseAgent findAgentToRun(Session session, BaseAgent rootAgent) {
if (author == null) {
continue;
}
if (author.equals("user")) {
if (author.equals(Role.USER)) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static java.util.stream.Collectors.joining;

import com.google.adk.JsonBaseModel;
import com.google.adk.agents.Role;
import com.google.adk.events.Event;
import com.google.adk.events.EventActions;
import com.google.adk.events.EventCompaction;
Expand Down Expand Up @@ -76,7 +77,7 @@ public Maybe<Event> summarizeEvents(List<Event> events) {
.contents(
ImmutableList.of(
Content.builder()
.role("user")
.role(Role.USER)
.parts(ImmutableList.of(Part.fromText(prompt)))
.build()))
.build();
Expand All @@ -101,7 +102,7 @@ public Maybe<Event> summarizeEvents(List<Event> events) {
compaction ->
Event.builder()
.id(Event.generateEventId())
.author("user")
.author(Role.USER)
.actions(EventActions.builder().compaction(compaction).build())
.invocationId(Event.generateEventId())
.build())));
Expand Down
Loading