diff --git a/core/pom.xml b/core/pom.xml
index fe65715f3..7d2032c7e 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1,4 +1,4 @@
-
+
4.0.0
-
com.google.adk
google-adk-parent
- 0.4.1-SNAPSHOT
+ 0.4.1-SNAPSHOT
+
-
google-adk
Agent Development Kit
Agent Development Kit: an open-source, code-first toolkit designed to simplify building, evaluating, and deploying advanced AI agents anywhere.
-
-
-
com.anthropic
@@ -201,6 +197,15 @@
maven-compiler-plugin
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.40
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextActiveStreamingToolsTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextActiveStreamingToolsTest.java
new file mode 100644
index 000000000..43e24ce9b
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextActiveStreamingToolsTest.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=activeStreamingTools_c4cc5030aa
+ROOST_METHOD_SIG_HASH=activeStreamingTools_398f84db97
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"Scenario 1: Return Empty Map When No Active Streaming Tools Have Been Added
+
+Details:
+ TestName: activeStreamingToolsReturnsEmptyMapOnNewContext
+ Description: Verifies that a newly built InvocationContext returns an empty (but non-null) map
+ from activeStreamingTools() when no tools have been added to it. This confirms
+ that the underlying ConcurrentHashMap is initialized as empty by default.
+
+Execution:
+ Arrange: Build an InvocationContext using InvocationContext.builder() with the required fields
+ (sessionService, artifactService, memoryService, pluginManager, invocationId, agent,
+ session, userContent, runConfig, endInvocation) without adding any entries to
+ activeStreamingTools.
+ Act: Call activeStreamingTools() on the newly created InvocationContext instance.
+ Assert: Assert that the returned map is not null.
+ Assert that the returned map is empty (size == 0).
+
+Validation:
+ The assertion confirms that the ConcurrentHashMap backing activeStreamingTools is properly
+ initialized at construction time and defaults to an empty state. This is critical for ensuring
+ that code consuming the map does not encounter a NullPointerException and can safely check
+ for active streaming tools without error on a fresh invocation context.
+
+*/
+
+// ********RoostGPT********
+
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class InvocationContextActiveStreamingToolsTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private RunConfig mockRunConfig;
+
+ @Mock
+ private ActiveStreamingTool mockActiveTool1;
+
+ @Mock
+ private ActiveStreamingTool mockActiveTool2;
+
+ private InvocationContext invocationContext;
+
+ @BeforeEach
+ void setUp() {
+ when(mockSession.appName()).thenReturn("testApp");
+ when(mockSession.userId()).thenReturn("testUser");
+ invocationContext =
+ InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .endInvocation(false)
+ .build();
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsReturnsEmptyMapOnNewContext() {
+ // Arrange
+ InvocationContext freshContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .invocationId("fresh-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .endInvocation(false)
+ .build();
+ // Act
+ Map result = freshContext.activeStreamingTools();
+ // Assert
+ assertNotNull(result, "activeStreamingTools map should not be null");
+ assertTrue(result.isEmpty(), "activeStreamingTools map should be empty on a new context");
+ assertEquals(0, result.size(), "activeStreamingTools map size should be 0");
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsReturnsNonNullMap() {
+ // Act
+ Map result = invocationContext.activeStreamingTools();
+ // Assert
+ assertNotNull(result, "activeStreamingTools() should never return null");
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsReturnsMapWithAddedEntries() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ // Act
+ Map result = invocationContext.activeStreamingTools();
+ // Assert
+ assertNotNull(result);
+ assertEquals(1, result.size());
+ assertTrue(result.containsKey("tool1"));
+ assertEquals(mockActiveTool1, result.get("tool1"));
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsReturnsLiveReferenceAllowingMutations() {
+ // Arrange
+ Map result = invocationContext.activeStreamingTools();
+ assertTrue(result.isEmpty());
+ // Act - mutate through the returned reference
+ result.put("tool1", mockActiveTool1);
+ // Assert - re-fetch and check mutation is reflected
+ Map resultAfterMutation = invocationContext.activeStreamingTools();
+ assertEquals(1, resultAfterMutation.size());
+ assertTrue(resultAfterMutation.containsKey("tool1"));
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsReturnsSameReferenceOnMultipleCalls() {
+ // Act
+ Map firstCall = invocationContext.activeStreamingTools();
+ Map secondCall = invocationContext.activeStreamingTools();
+ // Assert
+ assertSame(firstCall, secondCall,
+ "Multiple calls to activeStreamingTools() should return the same map instance");
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsSupportsMultipleEntries() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ invocationContext.activeStreamingTools().put("tool2", mockActiveTool2);
+ // Act
+ Map result = invocationContext.activeStreamingTools();
+ // Assert
+ assertEquals(2, result.size());
+ assertTrue(result.containsKey("tool1"));
+ assertTrue(result.containsKey("tool2"));
+ assertEquals(mockActiveTool1, result.get("tool1"));
+ assertEquals(mockActiveTool2, result.get("tool2"));
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsSupportsRemoveEntry() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ invocationContext.activeStreamingTools().put("tool2", mockActiveTool2);
+ assertEquals(2, invocationContext.activeStreamingTools().size());
+ // Act
+ invocationContext.activeStreamingTools().remove("tool1");
+ // Assert
+ Map result = invocationContext.activeStreamingTools();
+ assertEquals(1, result.size());
+ assertFalse(result.containsKey("tool1"));
+ assertTrue(result.containsKey("tool2"));
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsIsCopiedCorrectlyViaCopyOf() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ // Act
+ InvocationContext copiedContext = InvocationContext.copyOf(invocationContext);
+ Map copiedTools = copiedContext.activeStreamingTools();
+ // Assert
+ assertNotNull(copiedTools);
+ assertEquals(1, copiedTools.size());
+ assertTrue(copiedTools.containsKey("tool1"));
+ assertEquals(mockActiveTool1, copiedTools.get("tool1"));
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsInCopiedContextIsIndependentFromOriginal() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ InvocationContext copiedContext = InvocationContext.copyOf(invocationContext);
+ // Act - mutate the copy's map
+ copiedContext.activeStreamingTools().put("tool2", mockActiveTool2);
+ // Assert - original should not have tool2
+ Map originalTools = invocationContext.activeStreamingTools();
+ Map copiedTools = copiedContext.activeStreamingTools();
+ assertEquals(1, originalTools.size());
+ assertFalse(originalTools.containsKey("tool2"));
+ assertEquals(2, copiedTools.size());
+ assertTrue(copiedTools.containsKey("tool1"));
+ assertTrue(copiedTools.containsKey("tool2"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void activeStreamingToolsOnContextWithEmptyCopyOfOriginalEmpty() {
+ // Arrange - original has no streaming tools
+ InvocationContext originalContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("original-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ Map result = copiedContext.activeStreamingTools();
+ // Assert
+ assertNotNull(result);
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ @Tag("boundary")
+ void activeStreamingToolsMapSupportsOverwriteOfExistingKey() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ assertEquals(mockActiveTool1, invocationContext.activeStreamingTools().get("tool1"));
+ // Act - overwrite the key with a new tool
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool2);
+ // Assert
+ Map result = invocationContext.activeStreamingTools();
+ assertEquals(1, result.size());
+ assertEquals(mockActiveTool2, result.get("tool1"), "Overwritten key should map to the new value");
+ }
+
+ @Test
+ @Tag("boundary")
+ void activeStreamingToolsMapClearsAllEntries() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ invocationContext.activeStreamingTools().put("tool2", mockActiveTool2);
+ assertEquals(2, invocationContext.activeStreamingTools().size());
+ // Act
+ invocationContext.activeStreamingTools().clear();
+ // Assert
+ Map result = invocationContext.activeStreamingTools();
+ assertNotNull(result);
+ assertTrue(result.isEmpty());
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsReturnedMapContainsKeyCheck() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("existingTool", mockActiveTool1);
+ // Act
+ Map result = invocationContext.activeStreamingTools();
+ // Assert
+ assertTrue(result.containsKey("existingTool"));
+ assertFalse(result.containsKey("nonExistentTool"));
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsMapContainsValueCheck() {
+ // Arrange
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ // Act
+ Map result = invocationContext.activeStreamingTools();
+ // Assert
+ assertTrue(result.containsValue(mockActiveTool1));
+ assertFalse(result.containsValue(mockActiveTool2));
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsWithLiveRequestQueueContext() {
+ // Arrange
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext liveContext = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, liveRequestQueue, mockRunConfig);
+ // Act
+ Map result = liveContext.activeStreamingTools();
+ // Assert
+ assertNotNull(result);
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ @Tag("valid")
+ void activeStreamingToolsWithCreateStaticMethod() {
+ // Arrange
+ Content userContent = Content.fromParts();
+ InvocationContext createdContext = InvocationContext.create(mockSessionService, mockArtifactService,
+ "static-create-invocation-id", mockAgent, mockSession, userContent, mockRunConfig);
+ // Act
+ Map result = createdContext.activeStreamingTools();
+ // Assert
+ assertNotNull(result);
+ assertTrue(result.isEmpty());
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ @Tag("integration")
+ void activeStreamingToolsIntegrationWithCopyAndMutate() {
+ // Arrange - setup original context with tools
+ invocationContext.activeStreamingTools().put("tool1", mockActiveTool1);
+ invocationContext.activeStreamingTools().put("tool2", mockActiveTool2);
+ // Act - copy the context
+ InvocationContext copiedContext = InvocationContext.copyOf(invocationContext);
+ // Mutate original after copying
+ invocationContext.activeStreamingTools().remove("tool1");
+ // Assert original reflects mutation
+ assertEquals(1, invocationContext.activeStreamingTools().size());
+ assertFalse(invocationContext.activeStreamingTools().containsKey("tool1"));
+ // Assert copy is unchanged from when it was copied
+ assertEquals(2, copiedContext.activeStreamingTools().size());
+ assertTrue(copiedContext.activeStreamingTools().containsKey("tool1"));
+ assertTrue(copiedContext.activeStreamingTools().containsKey("tool2"));
+ }
+
+ @Test
+ @Tag("integration")
+ void activeStreamingToolsEqualsConsidersMapContents() {
+ // Arrange
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("same-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("same-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ // Act - both contexts have empty activeStreamingTools initially
+ boolean equalsBeforeModification = context1.equals(context2);
+ // Modify context1's activeStreamingTools
+ context1.activeStreamingTools().put("tool1", mockActiveTool1);
+ boolean equalsAfterModification = context1.equals(context2);
+ // Assert
+ assertTrue(equalsBeforeModification, "Contexts with empty streaming tools maps should be equal");
+ assertFalse(equalsAfterModification, "Contexts with different streaming tools maps should not be equal");
+ }
+
+}
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextArtifactServiceTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextArtifactServiceTest.java
new file mode 100644
index 000000000..c606e24bd
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextArtifactServiceTest.java
@@ -0,0 +1,584 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=artifactService_d673c8a05b
+ROOST_METHOD_SIG_HASH=artifactService_769a3f8842
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCreateWithUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCreateWithNullUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.userContent()).isEmpty();
+}
+"
+ "@Test
+public void testCreateWithLiveRequestQueue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).hasValue(liveRequestQueue);
+
+ assertThat(context.invocationId()).startsWith("e-");
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).isEmpty();
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"
+ "@Test
+public void testGetters() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testSetAgent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ BaseAgent newMockAgent = mock(BaseAgent.class);
+ context.agent(newMockAgent);
+ assertThat(context.agent()).isEqualTo(newMockAgent);
+}
+"
+ "@Test
+public void testEquals_sameObject() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(context)).isTrue();
+}
+"
+ "@Test
+public void testEquals_null() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(null)).isFalse();
+}
+"
+ "@Test
+public void testEquals_sameValues() {
+ InvocationContext context1 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext context2 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context1.equals(context2)).isTrue();
+
+ assertThat(context2.equals(context1)).isTrue();
+}
+"
+ "@Test
+public void testEquals_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffAgent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(
+ mock(BaseAgent.class)).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithUserContentEmpty = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithLiveQueuePresent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(contextWithDiffSessionService)).isFalse();
+ assertThat(context.equals(contextWithDiffInvocationId)).isFalse();
+ assertThat(context.equals(contextWithDiffAgent)).isFalse();
+ assertThat(context.equals(contextWithUserContentEmpty)).isFalse();
+ assertThat(context.equals(contextWithLiveQueuePresent)).isFalse();
+}
+"
+ "@Test
+public void testHashCode_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotEqualTo(contextWithDiffSessionService);
+ assertThat(context).isNotEqualTo(contextWithDiffInvocationId);
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ assertThat(context.isResumable()).isFalse();
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsResumable_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ assertThat(context.isResumable()).isTrue();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoLongRunningToolIds_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoFunctionCalls_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoMatchingFunctionCallId_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc2"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndMatchingFunctionCallId_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isTrue();
+}
+"Scenario 1: Verify That artifactService() Returns the Correct Artifact Service Instance Set via Builder
+
+Details:
+ TestName: artifactServiceReturnsCorrectInstanceSetViaBuilder
+ Description: Verifies that when an InvocationContext is constructed using the builder with a specific
+ BaseArtifactService mock, the artifactService() method returns exactly that same instance.
+Execution:
+ Arrange: Create a mock of BaseArtifactService. Build an InvocationContext using the builder,
+ passing the mock artifact service, along with all other required fields such as
+ mockSessionService, mockMemoryService, mockAgent, session, and runConfig.
+ Act: Call artifactService() on the constructed InvocationContext instance.
+ Assert: Assert that the returned value is equal to (and the same instance as) the mock
+ BaseArtifactService that was provided to the builder.
+Validation:
+ Confirms that the artifactService() getter faithfully returns the value injected through the builder,
+ without modification or wrapping. This is fundamental to ensuring that downstream components using
+ the InvocationContext receive the expected artifact service dependency.
+
+*/
+
+// ********RoostGPT********
+
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextArtifactServiceTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private RunConfig mockRunConfig;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private ResumabilityConfig mockResumabilityConfig;
+
+ private static final String TEST_INVOCATION_ID = "e-test-invocation-id";
+
+ private static final String TEST_APP_NAME = "testApp";
+
+ private static final String TEST_USER_ID = "testUser";
+
+ @BeforeEach
+ void setUp() {
+ lenient().when(mockSession.appName()).thenReturn(TEST_APP_NAME);
+ lenient().when(mockSession.userId()).thenReturn(TEST_USER_ID);
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceReturnsCorrectInstanceSetViaBuilder() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ BaseArtifactService result = context.artifactService();
+ assertNotNull(result);
+ assertSame(mockArtifactService, result);
+ assertEquals(mockArtifactService, result);
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceReturnsNullWhenNotSetInBuilder() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ BaseArtifactService result = context.artifactService();
+ assertNull(result);
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceReturnsSameInstanceAfterCopyOf() {
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext copied = InvocationContext.copyOf(original);
+ assertSame(mockArtifactService, copied.artifactService());
+ assertEquals(original.artifactService(), copied.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceReturnsDifferentInstanceWhenDifferentMockUsed() {
+ BaseArtifactService anotherMockArtifactService = mock(BaseArtifactService.class);
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(anotherMockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ assertSame(mockArtifactService, context1.artifactService());
+ assertSame(anotherMockArtifactService, context2.artifactService());
+ assertNotSame(context1.artifactService(), context2.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceReturnedFromCreateFactoryMethod() {
+ Content userContent = mock(Content.class);
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ TEST_INVOCATION_ID, mockAgent, mockSession, userContent, mockRunConfig);
+ assertSame(mockArtifactService, context.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceReturnedFromCreateFactoryMethodWithLiveRequestQueue() {
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, liveRequestQueue, mockRunConfig);
+ assertSame(mockArtifactService, context.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceReturnedFromCreateFactoryMethodWithNullUserContent() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ TEST_INVOCATION_ID, mockAgent, mockSession, null, mockRunConfig);
+ assertSame(mockArtifactService, context.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceRemainsConsistentAcrossMultipleCalls() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ BaseArtifactService firstCall = context.artifactService();
+ BaseArtifactService secondCall = context.artifactService();
+ BaseArtifactService thirdCall = context.artifactService();
+ assertSame(firstCall, secondCall);
+ assertSame(secondCall, thirdCall);
+ assertSame(mockArtifactService, firstCall);
+ }
+
+ @Test
+ @Tag("integration")
+ void artifactServiceRemainsUnchangedAfterModifyingOtherFields() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ context.setEndInvocation(true);
+ context.branch("newBranch");
+ context.agent(mock(BaseAgent.class));
+ assertSame(mockArtifactService, context.artifactService());
+ }
+
+ @Test
+ @Tag("integration")
+ void artifactServiceFromCopiedContextIsIndependentOfOriginalModifications() {
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext copied = InvocationContext.copyOf(original);
+ copied.setEndInvocation(true);
+ copied.branch("modifiedBranch");
+ assertSame(mockArtifactService, original.artifactService());
+ assertSame(mockArtifactService, copied.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceIsIncludedInEquality() {
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(context1.artifactService(), context2.artifactService());
+ }
+
+ @Test
+ @Tag("invalid")
+ void artifactServiceDiffersWhenDifferentInstancesUsed() {
+ BaseArtifactService differentArtifactService = mock(BaseArtifactService.class);
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(differentArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ assertNotEquals(context1.artifactService(), context2.artifactService());
+ assertNotSame(context1.artifactService(), context2.artifactService());
+ }
+
+ @Test
+ @Tag("boundary")
+ void artifactServiceWithNullSessionService() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(null)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ assertSame(mockArtifactService, context.artifactService());
+ assertNull(context.sessionService());
+ }
+
+ @Test
+ @Tag("boundary")
+ void artifactServiceWithNullArtifactService() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(null)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ assertNull(context.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceIncludedInHashCode() {
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(context1.hashCode(), context2.hashCode());
+ }
+
+ @Test
+ @Tag("valid")
+ void artifactServiceWithAllOptionalFieldsPopulated() {
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .liveRequestQueue(Optional.of(liveRequestQueue))
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .branch("testBranch")
+ .endInvocation(false)
+ .build();
+ assertSame(mockArtifactService, context.artifactService());
+ }
+
+ @Test
+ @Tag("integration")
+ void artifactServicePreservedWhenCopyingWithAllFields() {
+ BaseArtifactService specificMock = mock(BaseArtifactService.class);
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(specificMock)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(TEST_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .branch("originalBranch")
+ .endInvocation(false)
+ .build();
+ InvocationContext copy = InvocationContext.copyOf(original);
+ assertSame(specificMock, copy.artifactService());
+ assertSame(original.artifactService(), copy.artifactService());
+ }
+
+}
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextBranchTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextBranchTest.java
new file mode 100644
index 000000000..c1f2835f6
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextBranchTest.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=branch_25309d7017
+ROOST_METHOD_SIG_HASH=branch_5237016f3f
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/ParallelAgentTest.java
+Tests:
+ "@Test
+public void runAsync_subAgentsExecuteInParallel_eventsOrderedByCompletion() {
+ String agent1Name = "test_agent_1_delayed";
+ String agent2Name = "test_agent_2_fast";
+ String parallelAgentName = "test_parallel_agent";
+ TestingAgent agent1 = new TestingAgent(agent1Name, "Delayed Agent", 500);
+ TestingAgent agent2 = new TestingAgent(agent2Name, "Fast Agent", 0);
+ ParallelAgent parallelAgent = ParallelAgent.builder().name(parallelAgentName).subAgents(agent1, agent2).build();
+ InvocationContext invocationContext = createInvocationContext(parallelAgent);
+ List events = parallelAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).hasSize(2);
+
+ Event firstEvent = events.get(0);
+ assertThat(firstEvent.author()).isEqualTo(agent2Name);
+ assertThat(firstEvent.content().get().parts().get().get(0).text()).hasValue("Hello, async " + agent2Name + "!");
+ assertThat(firstEvent.branch().get()).endsWith(agent2Name);
+
+ Event secondEvent = events.get(1);
+ assertThat(secondEvent.author()).isEqualTo(agent1Name);
+ assertThat(secondEvent.content().get().parts().get().get(0).text()).hasValue("Hello, async " + agent1Name + "!");
+ assertThat(secondEvent.branch().get()).endsWith(agent1Name);
+}
+"Scenario 1: Setting a Valid Non-Null Branch String
+
+Details:
+ TestName: branchIsSetToNonNullValue
+ Description: Verifies that calling branch() with a valid non-null string correctly stores the value
+ as a non-empty Optional in the InvocationContext's branch field.
+
+Execution:
+ Arrange: Build an InvocationContext using InvocationContext.builder() with required fields
+ (sessionService, artifactService, session, agent). Do not set a branch during construction.
+ Act: Call invocationContext.branch("feature-branch-1") on the constructed context.
+ Assert: Call invocationContext.branch() and assert that the returned Optional is present and
+ contains the value "feature-branch-1".
+
+Validation:
+ Verifies that a non-null branch string is wrapped in Optional.of() and stored correctly.
+ This is essential to correctly track conversation branch forks during agent invocation routing.
+
+*/
+
+// ********RoostGPT********
+
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.events.Event;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.models.LlmCallsLimitExceededException;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.*;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
+import com.google.genai.types.FunctionCall;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextBranchTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ private RunConfig defaultRunConfig;
+
+ @BeforeEach
+ void setUp() {
+ defaultRunConfig = RunConfig.builder().build();
+ when(mockSession.appName()).thenReturn("testApp");
+ when(mockSession.userId()).thenReturn("testUser");
+ }
+
+ private InvocationContext buildDefaultContext() {
+ return InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(defaultRunConfig)
+ .build();
+ }
+
+ // Scenario 1: Setting a Valid Non-Null Branch String
+ @Test
+ @Tag("valid")
+ void branchIsSetToNonNullValue() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("feature-branch-1");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals("feature-branch-1", branch.get(), "Branch value should match");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchIsSetToNullValue() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch(null);
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertFalse(branch.isPresent(), "Branch should be empty when null is set");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchIsSetToEmptyString() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present even for empty string");
+ assertEquals("", branch.get(), "Branch value should be empty string");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchOverwritesPreviousBranchValue() {
+ // Arrange
+ InvocationContext invocationContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(defaultRunConfig)
+ .branch("initial-branch")
+ .build();
+ // Act
+ invocationContext.branch("updated-branch");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals("updated-branch", branch.get(), "Branch should be updated to new value");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchOverwritesWithNull() {
+ // Arrange
+ InvocationContext invocationContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(defaultRunConfig)
+ .branch("initial-branch")
+ .build();
+ // Act
+ invocationContext.branch(null);
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertFalse(branch.isPresent(), "Branch should be empty after setting null");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchWithDotSeparatedPath() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("parent.child.grandchild");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals("parent.child.grandchild", branch.get(), "Branch should support dot-separated paths");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchWithSpecialCharacters() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ String specialBranch = "branch-with_special.chars/test";
+ // Act
+ invocationContext.branch(specialBranch);
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals(specialBranch, branch.get(), "Branch should preserve special characters");
+ }
+
+ @Test
+ @Tag("boundary")
+ void branchWithVeryLongString() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ String longBranch = "a".repeat(1000);
+ // Act
+ invocationContext.branch(longBranch);
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals(longBranch, branch.get(), "Branch should store long strings correctly");
+ assertEquals(1000, branch.get().length(), "Branch length should be 1000");
+ }
+
+ @Test
+ @Tag("boundary")
+ void branchWithSingleCharacter() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("a");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals("a", branch.get(), "Branch should store single character");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchGetReturnsOptionalNotNull() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("test-branch");
+ // Assert
+ assertNotNull(invocationContext.branch(), "Branch Optional itself should never be null");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchGetReturnsOptionalEmptyWhenNotSet() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertNotNull(branch, "Branch Optional should not be null even when not set");
+ assertFalse(branch.isPresent(), "Branch should be empty when not explicitly set");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchSetMultipleTimesRetainsLastValue() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("first-branch");
+ invocationContext.branch("second-branch");
+ invocationContext.branch("third-branch");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals("third-branch", branch.get(), "Branch should retain the last set value");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchSetThenNullThenNewValue() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("first-branch");
+ invocationContext.branch(null);
+ invocationContext.branch("new-branch");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals("new-branch", branch.get(), "Branch should have the latest non-null value");
+ }
+
+ @Test
+ @Tag("integration")
+ void branchIsPreservedAfterCopyOf() {
+ // Arrange
+ InvocationContext original = buildDefaultContext();
+ original.branch("original-branch");
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertTrue(copy.branch().isPresent(), "Copied context should have branch present");
+ assertEquals("original-branch", copy.branch().get(), "Copied context should preserve branch value");
+ }
+
+ @Test
+ @Tag("integration")
+ void branchChangeInCopyDoesNotAffectOriginal() {
+ // Arrange
+ InvocationContext original = buildDefaultContext();
+ original.branch("original-branch");
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Act
+ copy.branch("modified-branch");
+ // Assert
+ assertTrue(original.branch().isPresent(), "Original branch should still be present");
+ assertEquals("original-branch", original.branch().get(), "Original branch should not be modified");
+ assertEquals("modified-branch", copy.branch().get(), "Copy branch should reflect updated value");
+ }
+
+ @Test
+ @Tag("integration")
+ void branchNullPreservedAfterCopyOf() {
+ // Arrange
+ InvocationContext original = buildDefaultContext();
+ original.branch(null);
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertFalse(copy.branch().isPresent(), "Copied context with null branch should have empty Optional");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchBuilderSetAndThenBranchMethodOverrides() {
+ // Arrange
+ InvocationContext invocationContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(defaultRunConfig)
+ .branch("builder-branch")
+ .build();
+ // Act
+ invocationContext.branch("method-branch");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present");
+ assertEquals("method-branch", branch.get(), "Branch set via method should override builder branch");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchReturnsOptionalOfNullableSemantics() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act - set non-null, then verify Optional semantics
+ invocationContext.branch("some-branch");
+ Optional presentBranch = invocationContext.branch();
+ // Act - set null, then verify Optional.empty semantics
+ invocationContext.branch(null);
+ Optional emptyBranch = invocationContext.branch();
+ // Assert
+ assertTrue(presentBranch.isPresent(), "Non-null branch should produce present Optional");
+ assertFalse(emptyBranch.isPresent(), "Null branch should produce empty Optional");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchWithWhitespaceString() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch(" ");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present for whitespace string");
+ assertEquals(" ", branch.get(), "Branch should preserve whitespace string as-is");
+ }
+
+ @Test
+ @Tag("valid")
+ void branchWithNumericString() {
+ // Arrange
+ InvocationContext invocationContext = buildDefaultContext();
+ // Act
+ invocationContext.branch("12345");
+ // Assert
+ Optional branch = invocationContext.branch();
+ assertTrue(branch.isPresent(), "Branch should be present for numeric string");
+ assertEquals("12345", branch.get(), "Branch should store numeric string correctly");
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextBuilderTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextBuilderTest.java
new file mode 100644
index 000000000..bd7c8ae8c
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextBuilderTest.java
@@ -0,0 +1,1612 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=builder_2187989d2f
+ROOST_METHOD_SIG_HASH=builder_80041265ae
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/ParallelAgentTest.java
+Tests:
+ "@Test
+public void runAsync_subAgentsExecuteInParallel_eventsOrderedByCompletion() {
+ String agent1Name = "test_agent_1_delayed";
+ String agent2Name = "test_agent_2_fast";
+ String parallelAgentName = "test_parallel_agent";
+ TestingAgent agent1 = new TestingAgent(agent1Name, "Delayed Agent", 500);
+ TestingAgent agent2 = new TestingAgent(agent2Name, "Fast Agent", 0);
+ ParallelAgent parallelAgent = ParallelAgent.builder().name(parallelAgentName).subAgents(agent1, agent2).build();
+ InvocationContext invocationContext = createInvocationContext(parallelAgent);
+ List events = parallelAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).hasSize(2);
+
+ Event firstEvent = events.get(0);
+ assertThat(firstEvent.author()).isEqualTo(agent2Name);
+ assertThat(firstEvent.content().get().parts().get().get(0).text()).hasValue("Hello, async " + agent2Name + "!");
+ assertThat(firstEvent.branch().get()).endsWith(agent2Name);
+
+ Event secondEvent = events.get(1);
+ assertThat(secondEvent.author()).isEqualTo(agent1Name);
+ assertThat(secondEvent.content().get().parts().get().get(0).text()).hasValue("Hello, async " + agent1Name + "!");
+ assertThat(secondEvent.branch().get()).endsWith(agent1Name);
+}
+"
+ "@Test
+public void runAsync_noSubAgents_returnsEmptyFlowable() {
+ String parallelAgentName = "empty_parallel_agent";
+ ParallelAgent parallelAgent = ParallelAgent.builder().name(parallelAgentName).subAgents(ImmutableList.of()).build();
+ InvocationContext invocationContext = createInvocationContext(parallelAgent);
+ List events = parallelAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).isEmpty();
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/CallbacksTest.java
+Tests:
+ "@Test
+public void testRun_withBeforeModelCallback_returnsResponseFromCallback() {
+ Content realContent = Content.fromParts(Part.fromText("Real LLM response"));
+ Content callbackContent = Content.fromParts(Part.fromText("Callback response"));
+ TestLlm testLlm = createTestLlm(createLlmResponse(realContent));
+ LlmAgent agent = createTestAgentBuilder(testLlm).beforeModelCallback((context, request) -> Maybe.just(LlmResponse.builder().content(callbackContent).build())).build();
+ InvocationContext invocationContext = createInvocationContext(agent);
+ List events = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(testLlm.getRequests()).isEmpty();
+ assertThat(events).hasSize(1);
+ assertThat(getOnlyElement(events).content()).hasValue(callbackContent);
+}
+"
+ "@Test
+public void testRun_withBeforeModelCallback_usesModifiedRequestFromCallback() {
+ TestLlm testLlm = createTestLlm(createLlmResponse(Content.builder().build()));
+ LlmAgent agent = createTestAgentBuilder(testLlm).beforeModelCallback((context, requestBuilder) -> {
+ requestBuilder.contents(ImmutableList.of(Content.fromParts(Part.fromText("Modified request"))));
+ return Maybe.empty();
+ }).build();
+ InvocationContext invocationContext = createInvocationContext(agent);
+ List unused = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(testLlm.getRequests()).hasSize(1);
+ assertThat(testLlm.getRequests().get(0).contents()).containsExactly(Content.fromParts(Part.fromText("Modified request")));
+}
+"
+ "@Test
+public void testRun_withAfterModelCallback_returnsResponseFromCallback() {
+ Part textPartFromModel = Part.fromText("Real LLM response");
+ Part textPartFromCallback = Part.fromText("Callback response");
+ TestLlm testLlm = createTestLlm(createLlmResponse(Content.fromParts(textPartFromModel)));
+ LlmAgent agent = createTestAgentBuilder(testLlm).afterModelCallback((context, response) -> Maybe.just(addPartToResponse(response, textPartFromCallback))).build();
+ InvocationContext invocationContext = createInvocationContext(agent);
+ List events = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).hasSize(1);
+ assertThat(getOnlyElement(events).content()).hasValue(Content.builder().parts(ImmutableList.of(textPartFromModel, textPartFromCallback)).build());
+}
+"
+ "@Test
+public void testRun_withChainedModelCallbacks_mixOfSyncAndAsync_returnsBeforeCallbackResponse() {
+ Content originalLlmResponseContent = Content.fromParts(Part.fromText("Original LLM response"));
+ Content contentFromSecondBeforeCallback = Content.fromParts(Part.fromText("Response from second beforeModelCallback"));
+ Content contentFromSecondAfterCallback = Content.fromParts(Part.fromText("Response from second afterModelCallback"));
+ TestLlm testLlm = createTestLlm(createLlmResponse(originalLlmResponseContent));
+ LlmAgent agent = createTestAgentBuilder(testLlm).beforeModelCallback(ImmutableList.of((Callbacks.BeforeModelCallbackSync) (context, request) -> Optional.empty(), (Callbacks.BeforeModelCallback) (context, request) -> Maybe.just(LlmResponse.builder().content(contentFromSecondBeforeCallback).build()))).afterModelCallback(ImmutableList.of((Callbacks.AfterModelCallbackSync) (context, response) -> Optional.empty(), (Callbacks.AfterModelCallback) (context, response) -> Maybe.just(LlmResponse.builder().content(contentFromSecondAfterCallback).build()))).build();
+ InvocationContext invocationContext = createInvocationContext(agent);
+ List events = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(testLlm.getRequests()).isEmpty();
+ assertThat(events).hasSize(1);
+ assertThat(getOnlyElement(events).content()).hasValue(contentFromSecondBeforeCallback);
+}
+"
+ "@Test
+public void testRun_withChainedModelCallbacks_mixOfSyncAndAsync_returnsAfterCallbackResponse() {
+ Content originalLlmResponseContent = Content.fromParts(Part.fromText("Original LLM response"));
+ Content contentFromSecondAfterCallback = Content.fromParts(Part.fromText("Response from second afterModelCallback"));
+ TestLlm testLlm = createTestLlm(createLlmResponse(originalLlmResponseContent));
+ LlmAgent agent = createTestAgentBuilder(testLlm).beforeModelCallback(ImmutableList.of((Callbacks.BeforeModelCallbackSync) (context, request) -> Optional.empty(), (Callbacks.BeforeModelCallback) (context, request) -> Maybe.empty())).afterModelCallback(ImmutableList.of((Callbacks.AfterModelCallbackSync) (context, response) -> Optional.empty(), (Callbacks.AfterModelCallback) (context, response) -> Maybe.just(LlmResponse.builder().content(contentFromSecondAfterCallback).build()))).build();
+ InvocationContext invocationContext = createInvocationContext(agent);
+ List events = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(testLlm.getRequests()).isNotEmpty();
+ assertThat(events).hasSize(1);
+ assertThat(getOnlyElement(events).content()).hasValue(contentFromSecondAfterCallback);
+}
+"
+ "@Test
+private static LlmResponse addPartToResponse(LlmResponse response, Part part) {
+ return LlmResponse.builder().content(Content.builder().parts(ImmutableList.builder().addAll(response.content().flatMap(Content::parts).orElse(ImmutableList.of())).add(part).build()).build()).build();
+}
+"
+ "@Test
+public void handleFunctionCalls_withBeforeToolCallback_returnsBeforeToolCallbackResult() {
+ ImmutableMap beforeToolCallbackResult = ImmutableMap.of("before_tool_callback_result", "value");
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).beforeToolCallback((invocationContext1, tool, args, toolContext) -> Maybe.just(beforeToolCallbackResult)).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.FailingEchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(beforeToolCallbackResult).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withBeforeToolCallbackThatReturnsNull_returnsToolResult() {
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).beforeToolCallback((invocationContext1, tool, args, toolContext) -> Maybe.empty()).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.EchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(ImmutableMap.of("result", ImmutableMap.of("key", "value"))).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withBeforeToolCallbackSync_returnsBeforeToolCallbackResult() {
+ ImmutableMap beforeToolCallbackResult = ImmutableMap.of("before_tool_callback_result", "value");
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).beforeToolCallbackSync((invocationContext1, tool, args, toolContext) -> Optional.of(beforeToolCallbackResult)).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.FailingEchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(beforeToolCallbackResult).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withBeforeToolCallbackSyncThatReturnsNull_returnsToolResult() {
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).beforeToolCallbackSync((invocationContext1, tool, args, toolContext) -> Optional.empty()).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.EchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(ImmutableMap.of("result", ImmutableMap.of("key", "value"))).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withAfterToolCallback_returnsAfterToolCallbackResult() {
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).afterToolCallback((invocationContext1, tool, args, toolContext, response) -> Maybe.just(ImmutableMap.of("after_tool_callback_result", response))).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.EchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(ImmutableMap.of("after_tool_callback_result", ImmutableMap.of("result", ImmutableMap.of("key", "value")))).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withAfterToolCallbackThatReturnsNull_returnsToolResult() {
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).afterToolCallback((invocationContext1, tool, args, toolContext, response) -> Maybe.empty()).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.EchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(ImmutableMap.of("result", ImmutableMap.of("key", "value"))).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withAfterToolCallbackSync_returnsAfterToolCallbackResult() {
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).afterToolCallbackSync((invocationContext1, tool, args, toolContext, response) -> Optional.of(ImmutableMap.of("after_tool_callback_result", response))).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.EchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(ImmutableMap.of("after_tool_callback_result", ImmutableMap.of("result", ImmutableMap.of("key", "value")))).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withAfterToolCallbackSyncThatReturnsNull_returnsToolResult() {
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).afterToolCallbackSync((invocationContext1, tool, args, toolContext, response) -> Optional.empty()).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.EchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(ImmutableMap.of("result", ImmutableMap.of("key", "value"))).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withBeforeAndAfterToolCallback_returnsAfterToolCallbackResultAppliedToBeforeToolCallbackResult() {
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).beforeToolCallback((invocationContext1, tool, args, toolContext) -> Maybe.just(ImmutableMap.of("before_tool_callback_result", "value"))).afterToolCallback((invocationContext1, tool, args, toolContext, response) -> Maybe.just(ImmutableMap.of("after_tool_callback_result", response))).build());
+ Event event = createEvent("event").toBuilder().content(Content.fromParts(Part.fromText("..."), Part.builder().functionCall(FunctionCall.builder().id("function_call_id").name("echo_tool").args(ImmutableMap.of("key", "value")).build()).build())).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, event, ImmutableMap.of("echo_tool", new TestUtils.FailingEchoTool())).blockingGet();
+ assertThat(functionResponseEvent).isNotNull();
+ assertThat(functionResponseEvent.content().get().parts().get()).containsExactly(Part.builder().functionResponse(FunctionResponse.builder().id("function_call_id").name("echo_tool").response(ImmutableMap.of("after_tool_callback_result", ImmutableMap.of("before_tool_callback_result", "value"))).build()).build());
+}
+"
+ "@Test
+public void handleFunctionCalls_withChainedToolCallbacks_overridesResultAndPassesContext() {
+ ImmutableMap originalToolInputArgs = ImmutableMap.of("input_key", "input_value");
+ ImmutableMap stateAddedByBc2 = ImmutableMap.of("bc2_state_key", "bc2_state_value");
+ ImmutableMap responseFromAc2 = ImmutableMap.of("ac2_response_key", "ac2_response_value");
+ Callbacks.BeforeToolCallbackSync bc1 = (invCtx, toolName, args, currentToolCtx) -> Optional.empty();
+ Callbacks.BeforeToolCallbackSync bc2 = (invCtx, toolName, args, currentToolCtx) -> {
+ currentToolCtx.state().putAll(stateAddedByBc2);
+ return Optional.empty();
+ };
+ TestUtils.EchoTool echoTool = new TestUtils.EchoTool();
+ Callbacks.AfterToolCallbackSync ac1 = (invCtx, toolName, args, currentToolCtx, responseFromTool) -> Optional.empty();
+ Callbacks.AfterToolCallbackSync ac2 = (invCtx, toolName, args, currentToolCtx, responseFromTool) -> Optional.of(responseFromAc2);
+ InvocationContext invocationContext = createInvocationContext(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).beforeToolCallback(ImmutableList.of(bc1, bc2)).afterToolCallback(ImmutableList.of(ac1, ac2)).build());
+ Event eventWithFunctionCall = createEvent("event").toBuilder().content(createFunctionCallContent("fc_id_minimal", "echo_tool", originalToolInputArgs)).build();
+ Event functionResponseEvent = Functions.handleFunctionCalls(invocationContext, eventWithFunctionCall, ImmutableMap.of("echo_tool", echoTool)).blockingGet();
+ assertThat(getFunctionResponse(functionResponseEvent)).isEqualTo(responseFromAc2);
+ assertThat(invocationContext.session().state()).containsExactlyEntriesIn(stateAddedByBc2);
+}
+"
+ "@Test
+public void agentRunAsync_withToolCallbacks_inspectsArgsAndReturnsResponse() {
+ TestUtils.EchoTool echoTool = new TestUtils.EchoTool();
+ String toolName = echoTool.declaration().get().name().get();
+ ImmutableMap functionArgs = ImmutableMap.of("message", "hello");
+ Content llmFunctionCallContent = Content.builder().role("model").parts(ImmutableList.of(Part.fromFunctionCall(toolName, functionArgs))).build();
+ Content llmTextContent = Content.builder().role("model").parts(ImmutableList.of(Part.fromText("hi there"))).build();
+ TestLlm testLlm = createTestLlm(createLlmResponse(llmFunctionCallContent), createLlmResponse(llmTextContent));
+ ImmutableMap responseFromAfterToolCallback = ImmutableMap.of("final_wrapper", "wrapped_value_from_after_callback");
+ Callbacks.BeforeToolCallback beforeToolCb = (invCtx, tName, args, toolCtx) -> {
+ assertThat(args).isEqualTo(functionArgs);
+ return Maybe.empty();
+ };
+ Callbacks.AfterToolCallback afterToolCb = (invCtx, tName, args, toolCtx, toolResponse) -> {
+ assertThat(args).isEqualTo(functionArgs);
+ assertThat(toolResponse).isEqualTo(ImmutableMap.of("result", functionArgs));
+ return Maybe.just(responseFromAfterToolCallback);
+ };
+ LlmAgent agent = createTestAgentBuilder(testLlm).tools(ImmutableList.of(echoTool)).beforeToolCallback(beforeToolCb).afterToolCallback(afterToolCb).build();
+ InvocationContext invocationContext = createInvocationContext(agent);
+ List events = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(testLlm.getRequests()).hasSize(2);
+ assertThat(events).hasSize(3);
+ var functionCall = getFunctionCall(events.get(0));
+ assertThat(functionCall.args().get()).isEqualTo(functionArgs);
+ assertThat(functionCall.name()).hasValue(toolName);
+ var functionResponse = getFunctionResponse(events.get(1));
+ assertThat(functionResponse).isEqualTo(responseFromAfterToolCallback);
+ assertThat(events.get(2).content()).hasValue(llmTextContent);
+}
+"
+ "@Test
+private static Content createFunctionCallContent(String functionCallId, String toolName, Map args) {
+ return Content.builder().role("model").parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name(toolName).id(functionCallId).args(args).build()).build())).build();
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InstructionTest.java
+Tests:
+ "@Test
+public void testCanonicalInstruction_staticInstruction() {
+ String instruction = "Test static instruction";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).instruction(instruction).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction);
+}
+"
+ "@Test
+public void testCanonicalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).instruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+ "@Test
+public void testCanonicalGlobalInstruction_staticInstruction() {
+ String instruction = "Test static global instruction";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).globalInstruction(instruction).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalGlobalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction);
+}
+"
+ "@Test
+public void testCanonicalGlobalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider global instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).globalInstruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalGlobalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/LlmAgentTest.java
+Tests:
+ "@Test
+public void build_withOutputSchemaAndTools_throwsIllegalArgumentException() {
+ BaseTool tool = new BaseTool("test_tool", "test_description") {
+
+ @Override
+ public Optional declaration() {
+ return Optional.empty();
+ }
+ };
+ Schema outputSchema = Schema.builder().type("OBJECT").properties(ImmutableMap.of("status", Schema.builder().type("STRING").build())).required(ImmutableList.of("status")).build();
+
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () ->
+ LlmAgent.builder().name("agent with invalid tool config").outputSchema(
+ outputSchema).tools(
+ ImmutableList.of(tool)).
+ build());
+ assertThat(exception).hasMessageThat().contains("Invalid config for agent agent with invalid tool config: if outputSchema is set, tools" + " must be empty");
+}
+"
+ "@Test
+public void build_withOutputSchemaAndSubAgents_throwsIllegalArgumentException() {
+ ImmutableList subAgents = ImmutableList.of(createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).name("test_sub_agent").description("test_sub_agent_description").build());
+ Schema outputSchema = Schema.builder().type("OBJECT").properties(ImmutableMap.of("status", Schema.builder().type("STRING").build())).required(ImmutableList.of("status")).build();
+
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () ->
+ LlmAgent.builder().name("agent with invalid tool config").outputSchema(
+ outputSchema).subAgents(
+ subAgents).
+ build());
+ assertThat(exception).hasMessageThat().contains("Invalid config for agent agent with invalid tool config: if outputSchema is set," + " subAgents must be empty to disable agent transfer.");
+}
+"
+ "@Test
+public void testBuild_withNullInstruction_setsInstructionToEmptyString() {
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).instruction((String) null).build();
+ assertThat(agent.instruction()).isEqualTo(new Instruction.Static(""));
+}
+"
+ "@Test
+public void testCanonicalInstruction_acceptsPlainString() {
+ String instruction = "Test static instruction";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).instruction(instruction).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction);
+}
+"
+ "@Test
+public void testCanonicalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).instruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+ "@Test
+public void testBuild_withNullGlobalInstruction_setsGlobalInstructionToEmptyString() {
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).globalInstruction((String) null).build();
+ assertThat(agent.globalInstruction()).isEqualTo(new Instruction.Static(""));
+}
+"
+ "@Test
+public void testCanonicalGlobalInstruction_acceptsPlainString() {
+ String instruction = "Test static global instruction";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).globalInstruction(instruction).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalGlobalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction);
+}
+"
+ "@Test
+public void testCanonicalGlobalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider global instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).globalInstruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalGlobalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+ "@Test
+public void resolveModel_withModelName_resolvesFromRegistry() {
+ String modelName = "test-model";
+ TestLlm testLlm = createTestLlm(LlmResponse.builder().build());
+ LlmRegistry.registerLlm(modelName, (name) -> testLlm);
+ LlmAgent agent = createTestAgentBuilder(testLlm).model(modelName).build();
+ Model resolvedModel = agent.resolvedModel();
+ assertThat(resolvedModel.modelName()).hasValue(modelName);
+ assertThat(resolvedModel.model()).hasValue(testLlm);
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/BaseAgentTest.java
+Tests:
+ "@Test
+public void runAsync_beforeAgentCallbackReturnsContent_endsInvocationAndSkipsRunAsyncImplAndAfterCallback() {
+ AtomicBoolean runAsyncImplCalled = new AtomicBoolean(false);
+ AtomicBoolean afterAgentCallbackCalled = new AtomicBoolean(false);
+ Content callbackContent = Content.fromParts(Part.fromText("before_callback_output"));
+ Callbacks.BeforeAgentCallback beforeCallback = (callbackContext) -> Maybe.just(callbackContent);
+ Callbacks.AfterAgentCallback afterCallback = (callbackContext) -> {
+ afterAgentCallbackCalled.set(true);
+ return Maybe.empty();
+ };
+ TestBaseAgent agent = new TestBaseAgent(TEST_AGENT_NAME, TEST_AGENT_DESCRIPTION, ImmutableList.of(beforeCallback), ImmutableList.of(afterCallback), () -> Flowable.defer(() -> {
+ runAsyncImplCalled.set(true);
+ return Flowable.just(Event.builder().content(Content.fromParts(Part.fromText("main_output"))).build());
+ }));
+ InvocationContext invocationContext = TestUtils.createInvocationContext(agent);
+ List results = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).content()).hasValue(callbackContent);
+ assertThat(runAsyncImplCalled.get()).isFalse();
+ assertThat(afterAgentCallbackCalled.get()).isFalse();
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/LoopAgentTest.java
+Tests:
+ "@Test
+public void runAsync_withNoAgents_returnsEmptyEvents() {
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of()).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ List events = loopAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).isEmpty();
+}
+"
+ "@Test
+public void runAsync_withSingleAgent_singleIteration_returnsEvents() {
+ Event event1 = createEvent("event1");
+ Event event2 = createEvent("event2");
+ TestBaseAgent subAgent = createSubAgent("subAgent", Flowable.just(event1, event2));
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of(subAgent)).maxIterations(1).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ List events = loopAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).containsExactly(event1, event2).inOrder();
+}
+"
+ "@Test
+public void runAsync_withSingleAgent_multipleIterations_returnsEvents() {
+ Event event1 = createEvent("event1");
+ Event event2 = createEvent("event2");
+ Event event3 = createEvent("event3");
+ Event event4 = createEvent("event4");
+ TestBaseAgent subAgent = createSubAgent("subAgent", Flowable.just(event1, event2), Flowable.just(event3, event4));
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of(subAgent)).maxIterations(2).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ List events = loopAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).containsExactly(event1, event2, event3, event4).inOrder();
+}
+"
+ "@Test
+public void runAsync_withMultipleAgents_loopsAndReturnsEvents() {
+ Event event1 = createEvent("event1");
+ Event event2 = createEvent("event2");
+ Event event3 = createEvent("event3");
+ Event event4 = createEvent("event4");
+ TestBaseAgent subAgent1 = createSubAgent("subAgent1", Flowable.just(event1), Flowable.just(event3));
+ TestBaseAgent subAgent2 = createSubAgent("subAgent2", Flowable.just(event2), Flowable.just(event4));
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of(subAgent1, subAgent2)).maxIterations(2).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ List events = loopAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).containsExactly(event1, event2, event3, event4).inOrder();
+}
+"
+ "@Test
+public void runAsync_withEscalateAction_returnsEventsUpToEscalateAndStops() {
+ Event event1 = createEvent("event1");
+ Event escalateEvent2 = createEscalateEvent("escalate2");
+ Event event3 = createEvent("event3");
+ Event event4 = createEvent("event4");
+ Flowable subAgent1Events = Flowable.just(event1, escalateEvent2, event3);
+ Flowable subAgent2Events = Flowable.just(event4);
+ TestBaseAgent subAgent1 = createSubAgent("subAgent1", subAgent1Events);
+ TestBaseAgent subAgent2 = createSubAgent("subAgent2", subAgent2Events);
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of(subAgent1, subAgent2)).maxIterations(1).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ List events = loopAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).containsExactly(event1, escalateEvent2).inOrder();
+}
+"
+ "@Test
+public void runAsync_withEscalateAction_loopsAndReturnsEventsUpToEscalateAndStops() {
+ Event event1 = createEvent("event1");
+ Event event2 = createEvent("event2");
+ Event event3 = createEvent("event3");
+ Event event4 = createEvent("event4");
+ Event escalateEvent5 = createEscalateEvent("escalate5");
+ Event escalateEvent6 = createEscalateEvent("escalate6");
+ TestBaseAgent subAgent1 = createSubAgent("subAgent1", Flowable.just(event1, event2), Flowable.just(event4));
+ TestBaseAgent subAgent2 = createSubAgent("subAgent2", Flowable.just(event3), Flowable.just(escalateEvent5, escalateEvent6));
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of(subAgent1, subAgent2)).maxIterations(3).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ List events = loopAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).containsExactly(event1, event2, event3, event4, escalateEvent5).inOrder();
+}
+"
+ "@Test
+public void runAsync_withNoMaxIterations_keepsLooping() {
+ Event event1 = createEvent("event1");
+ Event event2 = createEvent("event2");
+ TestBaseAgent subAgent = createSubAgent("subAgent", () -> Flowable.just(event1, event2));
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of(subAgent)).maxIterations(Optional.empty()).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ Iterable result = loopAgent.runAsync(invocationContext).blockingIterable();
+ Iterable first10Events = Iterables.limit(result, 10);
+ assertThat(first10Events).containsExactly(event1, event2, event1, event2, event1, event2, event1, event2, event1, event2).inOrder();
+}
+"
+ "@Test
+public void runAsync_withEndInvocationInSubAgentCallback_stopsSubAgentButLoopContinues() {
+ AtomicInteger normalAgentRunCount = new AtomicInteger(0);
+ TestBaseAgent normalAgent = createSubAgent("NormalAgent", () -> {
+ int count = normalAgentRunCount.incrementAndGet();
+ return Flowable.just(createEvent("Normal Agent Run " + count));
+ });
+ AtomicInteger subAgent2CallbackCount = new AtomicInteger(0);
+ AtomicInteger subAgent2RunCount = new AtomicInteger(0);
+ BeforeAgentCallback subAgent2BeforeCallback = (callbackContext) -> {
+ int callbackCount = subAgent2CallbackCount.incrementAndGet();
+ if (callbackCount > 1) {
+ return Maybe.just(Content.fromParts(Part.fromText("Exit Callback Triggered After " + callbackCount + " Runs")));
+ }
+ return Maybe.empty();
+ };
+ TestBaseAgent earlyExitAgent = new TestBaseAgent("EarlyExitAgent", "An agent that exits early after its callback is called once", () -> {
+ int count = subAgent2RunCount.incrementAndGet();
+ return Flowable.just(createEvent("Early Exit Agent Run " + count));
+ },
+ ImmutableList.of(),
+ ImmutableList.of(subAgent2BeforeCallback),
+ ImmutableList.of());
+ LoopAgent loopAgent = LoopAgent.builder().name("loopAgent").subAgents(ImmutableList.of(normalAgent, earlyExitAgent)).maxIterations(3).build();
+ InvocationContext invocationContext = createInvocationContext(loopAgent);
+ List events = loopAgent.runAsync(invocationContext).toList().blockingGet();
+ ImmutableList eventTexts = events.stream().filter(e -> e.content().isPresent()).map(e -> e.content().get().text()).collect(toImmutableList());
+ assertThat(eventTexts).containsExactly("content for event Normal Agent Run 1", "content for event Early Exit Agent Run 1", "content for event Normal Agent Run 2", "Exit Callback Triggered After 2 Runs", "content for event Normal Agent Run 3", "Exit Callback Triggered After 3 Runs").inOrder();
+ assertThat(normalAgentRunCount.get()).isEqualTo(3);
+ assertThat(subAgent2RunCount.get()).isEqualTo(1);
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/RunConfigTest.java
+Tests:
+ "@Test
+public void testBuilderWithVariousValues() {
+ SpeechConfig speechConfig = SpeechConfig.builder().build();
+ AudioTranscriptionConfig audioTranscriptionConfig = AudioTranscriptionConfig.builder().build();
+ RunConfig runConfig = RunConfig.builder().setSpeechConfig(speechConfig).setResponseModalities(ImmutableList.of(new Modality(Modality.Known.TEXT))).setSaveInputBlobsAsArtifacts(true).setStreamingMode(RunConfig.StreamingMode.SSE).setOutputAudioTranscription(audioTranscriptionConfig).setInputAudioTranscription(audioTranscriptionConfig).setMaxLlmCalls(10).build();
+ assertThat(runConfig.speechConfig()).isEqualTo(speechConfig);
+ assertThat(runConfig.responseModalities()).containsExactly(new Modality(Modality.Known.TEXT));
+ assertThat(runConfig.saveInputBlobsAsArtifacts()).isTrue();
+ assertThat(runConfig.streamingMode()).isEqualTo(RunConfig.StreamingMode.SSE);
+ assertThat(runConfig.outputAudioTranscription()).isEqualTo(audioTranscriptionConfig);
+ assertThat(runConfig.inputAudioTranscription()).isEqualTo(audioTranscriptionConfig);
+ assertThat(runConfig.maxLlmCalls()).isEqualTo(10);
+}
+"
+ "@Test
+public void testBuilderDefaults() {
+ RunConfig runConfig = RunConfig.builder().build();
+ assertThat(runConfig.speechConfig()).isNull();
+ assertThat(runConfig.responseModalities()).isEmpty();
+ assertThat(runConfig.saveInputBlobsAsArtifacts()).isFalse();
+ assertThat(runConfig.streamingMode()).isEqualTo(RunConfig.StreamingMode.NONE);
+ assertThat(runConfig.outputAudioTranscription()).isNull();
+ assertThat(runConfig.inputAudioTranscription()).isNull();
+ assertThat(runConfig.maxLlmCalls()).isEqualTo(500);
+}
+"
+ "@Test
+public void testMaxLlmCalls_negativeValueAllowedInSetterButLoggedAndBuilt() {
+ RunConfig runConfig = RunConfig.builder().setMaxLlmCalls(-1).build();
+ assertThat(runConfig.maxLlmCalls()).isEqualTo(-1);
+}
+"
+ "@Test
+public void testBuilderWithDifferentValues() {
+ SpeechConfig speechConfig = SpeechConfig.builder().build();
+ AudioTranscriptionConfig audioTranscriptionConfig = AudioTranscriptionConfig.builder().build();
+ RunConfig runConfig = RunConfig.builder().setSpeechConfig(speechConfig).setResponseModalities(ImmutableList.of(new Modality(Modality.Known.AUDIO))).setSaveInputBlobsAsArtifacts(true).setStreamingMode(RunConfig.StreamingMode.BIDI).setOutputAudioTranscription(audioTranscriptionConfig).setInputAudioTranscription(audioTranscriptionConfig).setMaxLlmCalls(20).build();
+ assertThat(runConfig.speechConfig()).isEqualTo(speechConfig);
+ assertThat(runConfig.responseModalities()).containsExactly(new Modality(Modality.Known.AUDIO));
+ assertThat(runConfig.saveInputBlobsAsArtifacts()).isTrue();
+ assertThat(runConfig.streamingMode()).isEqualTo(RunConfig.StreamingMode.BIDI);
+ assertThat(runConfig.outputAudioTranscription()).isEqualTo(audioTranscriptionConfig);
+ assertThat(runConfig.inputAudioTranscription()).isEqualTo(audioTranscriptionConfig);
+ assertThat(runConfig.maxLlmCalls()).isEqualTo(20);
+}
+"
+ "@Test
+public void testInputAudioTranscriptionOnly() {
+ AudioTranscriptionConfig inputTranscriptionConfig = AudioTranscriptionConfig.builder().build();
+ RunConfig runConfig = RunConfig.builder().setStreamingMode(RunConfig.StreamingMode.BIDI).setResponseModalities(ImmutableList.of(new Modality(Modality.Known.AUDIO))).setInputAudioTranscription(inputTranscriptionConfig).build();
+ assertThat(runConfig.inputAudioTranscription()).isEqualTo(inputTranscriptionConfig);
+ assertThat(runConfig.outputAudioTranscription()).isNull();
+ assertThat(runConfig.streamingMode()).isEqualTo(RunConfig.StreamingMode.BIDI);
+ assertThat(runConfig.responseModalities()).containsExactly(new Modality(Modality.Known.AUDIO));
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/SequentialAgentTest.java
+Tests:
+ "@Test
+public void runAsync_withNoSubAgents_returnsEmptyEvents() {
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgent").subAgents(ImmutableList.of()).build();
+ InvocationContext invocationContext = createInvocationContext(sequentialAgent);
+ List events = sequentialAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).isEmpty();
+}
+"
+ "@Test
+public void runAsync_withSingleSubAgent_returnsEventsFromSubAgent() {
+ Event event1 = createEvent("event1").toBuilder().author("subAgent").build();
+ TestBaseAgent subAgent = createSubAgent("subAgent", event1);
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgent").subAgents(ImmutableList.of(subAgent)).build();
+ InvocationContext invocationContext = createInvocationContext(sequentialAgent);
+ List events = sequentialAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).containsExactly(event1);
+ assertThat(events.get(0).author()).isEqualTo("subAgent");
+}
+"
+ "@Test
+public void runAsync_withSingleLlmSubAgent_returnsEventsFromSubAgent() {
+ Content modelContent = Content.fromParts(Part.fromText("Real LLM response"));
+ TestLlm testLlm = createTestLlm(createLlmResponse(modelContent));
+ LlmAgent subAgent = createTestAgent(testLlm);
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgent").subAgents(ImmutableList.of(subAgent)).build();
+ InvocationContext invocationContext = createInvocationContext(sequentialAgent);
+ List events = sequentialAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).hasSize(1);
+ assertThat(getOnlyElement(events).content()).hasValue(modelContent);
+}
+"
+ "@Test
+public void runAsync_withMultipleSubAgents_returnsConcatenatedEventsInOrder() {
+ Event event1 = createEvent("event1");
+ Event event2 = createEvent("event2");
+ Event event3 = createEvent("event3");
+ TestBaseAgent subAgent1 = createSubAgent("subAgent", event1.toBuilder().author("subAgent").build(), event2.toBuilder().author("subAgent").build());
+ TestBaseAgent subAgent2 = createSubAgent("subAgent2", event3.toBuilder().author("subAgent2").build());
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgent").subAgents(ImmutableList.of(subAgent1, subAgent2)).build();
+ InvocationContext invocationContext = createInvocationContext(sequentialAgent);
+ List events = sequentialAgent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).hasSize(3);
+ assertThat(events.get(0).id()).isEqualTo("event1");
+ assertThat(events.get(0).author()).isEqualTo("subAgent");
+ assertThat(events.get(1).id()).isEqualTo("event2");
+ assertThat(events.get(1).author()).isEqualTo("subAgent");
+ assertThat(events.get(2).id()).isEqualTo("event3");
+ assertThat(events.get(2).author()).isEqualTo("subAgent2");
+}
+"
+ "@Test
+public void runAsync_propagatesInvocationContextToSubAgents() {
+ TestBaseAgent subAgent = createSubAgent("subAgent");
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgent").subAgents(ImmutableList.of(subAgent)).build();
+ InvocationContext parentContext = createInvocationContext(sequentialAgent);
+ List unused = sequentialAgent.runAsync(parentContext).toList().blockingGet();
+ InvocationContext capturedContext = subAgent.getLastInvocationContext();
+ assertThat(capturedContext).isNotNull();
+ assertThat(capturedContext.invocationId()).isEqualTo(parentContext.invocationId());
+ assertThat(capturedContext.session()).isEqualTo(parentContext.session());
+ assertThat(capturedContext.agent()).isEqualTo(subAgent);
+ assertThat(subAgent.getInvocationCount()).isEqualTo(1);
+}
+"
+ "@Test
+public void runLive_withNoSubAgents_returnsEmptyEvents() {
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgent").subAgents(ImmutableList.of()).build();
+ InvocationContext invocationContext = createInvocationContext(sequentialAgent);
+ List events = sequentialAgent.runLive(invocationContext).toList().blockingGet();
+ assertThat(events).isEmpty();
+}
+"
+ "@Test
+public void runLive_withSingleSubAgent_returnsEventsFromSubAgent() {
+ Event event1 = createEvent("event1_live").toBuilder().author("subAgent_live").build();
+ TestBaseAgent subAgent = createSubAgent("subAgent_live", event1);
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgentLive").subAgents(ImmutableList.of(subAgent)).build();
+ InvocationContext invocationContext = createInvocationContext(sequentialAgent);
+ List events = sequentialAgent.runLive(invocationContext).toList().blockingGet();
+ assertThat(events).containsExactly(event1);
+ assertThat(events.get(0).author()).isEqualTo("subAgent_live");
+}
+"
+ "@Test
+public void runLive_withMultipleSubAgents_returnsConcatenatedEventsInOrder() {
+ Event event1 = createEvent("event1_live");
+ Event event2 = createEvent("event2_live");
+ Event event3 = createEvent("event3_live");
+ TestBaseAgent subAgent1 = createSubAgent("subAgent_live", event1.toBuilder().author("subAgent_live").build(), event2.toBuilder().author("subAgent_live").build());
+ TestBaseAgent subAgent2 = createSubAgent("subAgent2_live", event3.toBuilder().author("subAgent2_live").build());
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgentLive").subAgents(ImmutableList.of(subAgent1, subAgent2)).build();
+ InvocationContext invocationContext = createInvocationContext(sequentialAgent);
+ List events = sequentialAgent.runLive(invocationContext).toList().blockingGet();
+ assertThat(events).hasSize(3);
+ assertThat(events.get(0).id()).isEqualTo("event1_live");
+ assertThat(events.get(0).author()).isEqualTo("subAgent_live");
+ assertThat(events.get(1).id()).isEqualTo("event2_live");
+ assertThat(events.get(1).author()).isEqualTo("subAgent_live");
+ assertThat(events.get(2).id()).isEqualTo("event3_live");
+ assertThat(events.get(2).author()).isEqualTo("subAgent2_live");
+}
+"
+ "@Test
+public void runLive_propagatesInvocationContextToSubAgents() {
+ TestBaseAgent subAgent = createSubAgent("subAgent_live");
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgentLive").subAgents(ImmutableList.of(subAgent)).build();
+ InvocationContext parentContext = createInvocationContext(sequentialAgent);
+ List unused = sequentialAgent.runLive(parentContext).toList().blockingGet();
+ InvocationContext capturedContext = subAgent.getLastInvocationContext();
+ assertThat(capturedContext).isNotNull();
+ assertThat(capturedContext.invocationId()).isEqualTo(parentContext.invocationId());
+ assertThat(capturedContext.session()).isEqualTo(parentContext.session());
+ assertThat(capturedContext.agent()).isEqualTo(subAgent);
+ assertThat(subAgent.getInvocationCount()).isEqualTo(1);
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/ConfigAgentUtilsTest.java
+Tests:
+ "@Test
+public void fromConfig_withExamplesList_appendsExamplesInFlow() throws IOException, ConfigurationException {
+
+ ComponentRegistry originalRegistry = ComponentRegistry.getInstance();
+ class TestRegistry extends ComponentRegistry {
+
+ TestRegistry() {
+ super();
+ }
+ }
+ ComponentRegistry testRegistry = new TestRegistry();
+ Example example = Example.builder().input(Content.fromParts(Part.fromText("qin"))).output(ImmutableList.of(Content.fromParts(Part.fromText("qout")))).build();
+ testRegistry.register("multi_agent_llm_config.example_tool", ExampleTool.builder().addExample(example).build());
+ ComponentRegistry.setInstance(testRegistry);
+ File configFile = tempFolder.newFile("with_examples.yaml");
+ Files.writeString(configFile.toPath(), """
+ name: examples_agent
+ description: Agent with examples configured via tool
+ instruction: You are a test agent
+ agent_class: LlmAgent
+ model: gemini-2.0-flash
+ tools:
+ - name: multi_agent_llm_config.example_tool
+ """);
+ String configPath = configFile.getAbsolutePath();
+ BaseAgent agent;
+ try {
+ agent = ConfigAgentUtils.fromConfig(configPath);
+ } finally {
+ ComponentRegistry.setInstance(originalRegistry);
+ }
+ assertThat(agent).isInstanceOf(LlmAgent.class);
+ LlmAgent llmAgent = (LlmAgent) agent;
+
+ LlmRequest.Builder requestBuilder = LlmRequest.builder().model("gemini-2.0-flash");
+ InvocationContext context = TestUtils.createInvocationContext(agent);
+ llmAgent.canonicalTools(new ReadonlyContext(context)).concatMapCompletable(tool -> tool.processLlmRequest(requestBuilder, ToolContext.builder(context).build())).blockingAwait();
+ LlmRequest updated = requestBuilder.build();
+
+ assertThat(updated.getSystemInstructions()).isNotEmpty();
+}
+"
+ "@Test
+public void resolveSubAgents_withCode_resolvesSuccessfully() throws IOException, ConfigurationException {
+
+ LlmAgent testAgent = LlmAgent.builder().name("test_agent").description("Test agent for code resolution").instruction("Test instruction").build();
+
+ ComponentRegistry.getInstance().register("sub_agents_config.test_agent.agent", testAgent);
+ File mainAgentFile = tempFolder.newFile("main_agent.yaml");
+ Files.writeString(mainAgentFile.toPath(), """
+ agent_class: LlmAgent
+ name: main_agent
+ description: Main agent with code subagent
+ instruction: You are a main agent
+ sub_agents:
+ - code: sub_agents_config.test_agent.agent
+ """);
+ BaseAgent mainAgent = ConfigAgentUtils.fromConfig(mainAgentFile.getAbsolutePath());
+ assertThat(mainAgent).isNotNull();
+ assertThat(mainAgent.subAgents()).hasSize(1);
+ BaseAgent subAgent = mainAgent.subAgents().get(0);
+ assertThat(subAgent).isInstanceOf(LlmAgent.class);
+ assertThat(subAgent.name()).isEqualTo("test_agent");
+ assertThat(subAgent.description()).isEqualTo("Test agent for code resolution");
+}
+"
+ "@Test
+public void resolveSubAgents_withLifeAgentUsingCode_resolvesSuccessfully() throws IOException, ConfigurationException {
+
+ LlmAgent lifeAgent = LlmAgent.builder().name("life_agent").description("Life agent").instruction("You are a life agent. You are responsible for answering questions about life.").build();
+
+ ComponentRegistry.getInstance().register("sub_agents_config.life_agent.agent", lifeAgent);
+ File mainAgentFile = tempFolder.newFile("root_agent.yaml");
+ Files.writeString(mainAgentFile.toPath(), """
+ name: root_agent
+ model: gemini-2.0-flash
+ description: Root agent
+ instruction: |
+ If the user query is about life, you should route it to the life sub-agent.
+ If the user query is about work, you should route it to the work sub-agent.
+ If the user query is about anything else, you should answer it yourself.
+ sub_agents:
+ - code: sub_agents_config.life_agent.agent
+ """);
+ BaseAgent rootAgent = ConfigAgentUtils.fromConfig(mainAgentFile.getAbsolutePath());
+ assertThat(rootAgent).isNotNull();
+ assertThat(rootAgent.name()).isEqualTo("root_agent");
+ assertThat(rootAgent.description()).isEqualTo("Root agent");
+ assertThat(rootAgent).isInstanceOf(LlmAgent.class);
+
+ assertThat(rootAgent.subAgents()).hasSize(1);
+ BaseAgent subAgent = rootAgent.subAgents().get(0);
+ assertThat(subAgent).isInstanceOf(LlmAgent.class);
+ assertThat(subAgent.name()).isEqualTo("life_agent");
+ assertThat(subAgent.description()).isEqualTo("Life agent");
+ LlmAgent llmSubAgent = (LlmAgent) subAgent;
+ assertThat(llmSubAgent.instruction().toString()).contains("You are a life agent. You are responsible for answering questions about life.");
+}
+"
+ "@Test
+public void testLlmAgentConfigAccessors() {
+ LlmAgentConfig config = new LlmAgentConfig();
+ assertThat(config.agentClass()).isEqualTo("LlmAgent");
+ config.setModel("test-model");
+ assertThat(config.model()).isEqualTo("test-model");
+ config.setInstruction("test instruction");
+ assertThat(config.instruction()).isEqualTo("test instruction");
+ config.setDisallowTransferToParent(true);
+ assertThat(config.disallowTransferToParent()).isTrue();
+ config.setDisallowTransferToPeers(false);
+ assertThat(config.disallowTransferToPeers()).isFalse();
+ config.setOutputKey("test-output-key");
+ assertThat(config.outputKey()).isEqualTo("test-output-key");
+ config.setIncludeContents(LlmAgent.IncludeContents.NONE);
+ assertThat(config.includeContents()).isEqualTo(LlmAgent.IncludeContents.NONE);
+ GenerateContentConfig contentConfig = GenerateContentConfig.builder().temperature(0.8f).build();
+ config.setGenerateContentConfig(contentConfig);
+ assertThat(config.generateContentConfig()).isEqualTo(contentConfig);
+ List beforeAgentCallbacks = new ArrayList<>();
+ beforeAgentCallbacks.add(new LlmAgentConfig.CallbackRef("callback1"));
+ config.setBeforeAgentCallbacks(beforeAgentCallbacks);
+ assertThat(config.beforeAgentCallbacks()).hasSize(1);
+ assertThat(config.beforeAgentCallbacks().get(0).name()).isEqualTo("callback1");
+ List afterAgentCallbacks = new ArrayList<>();
+ afterAgentCallbacks.add(new LlmAgentConfig.CallbackRef("callback2"));
+ config.setAfterAgentCallbacks(afterAgentCallbacks);
+ assertThat(config.afterAgentCallbacks()).hasSize(1);
+ assertThat(config.afterAgentCallbacks().get(0).name()).isEqualTo("callback2");
+ List beforeModelCallbacks = new ArrayList<>();
+ beforeModelCallbacks.add(new LlmAgentConfig.CallbackRef("callback3"));
+ config.setBeforeModelCallbacks(beforeModelCallbacks);
+ assertThat(config.beforeModelCallbacks()).hasSize(1);
+ assertThat(config.beforeModelCallbacks().get(0).name()).isEqualTo("callback3");
+ List afterModelCallbacks = new ArrayList<>();
+ afterModelCallbacks.add(new LlmAgentConfig.CallbackRef("callback4"));
+ config.setAfterModelCallbacks(afterModelCallbacks);
+ assertThat(config.afterModelCallbacks()).hasSize(1);
+ assertThat(config.afterModelCallbacks().get(0).name()).isEqualTo("callback4");
+ List beforeToolCallbacks = new ArrayList<>();
+ beforeToolCallbacks.add(new LlmAgentConfig.CallbackRef("callback5"));
+ config.setBeforeToolCallbacks(beforeToolCallbacks);
+ assertThat(config.beforeToolCallbacks()).hasSize(1);
+ assertThat(config.beforeToolCallbacks().get(0).name()).isEqualTo("callback5");
+ List afterToolCallbacks = new ArrayList<>();
+ afterToolCallbacks.add(new LlmAgentConfig.CallbackRef("callback6"));
+ config.setAfterToolCallbacks(afterToolCallbacks);
+ assertThat(config.afterToolCallbacks()).hasSize(1);
+ assertThat(config.afterToolCallbacks().get(0).name()).isEqualTo("callback6");
+ List tools = new ArrayList<>();
+ BaseTool.ToolConfig toolConfig = new BaseTool.ToolConfig();
+ toolConfig.setName("test-tool");
+ tools.add(toolConfig);
+ config.setTools(tools);
+ assertThat(config.tools()).hasSize(1);
+ assertThat(config.tools().get(0).name()).isEqualTo("test-tool");
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/AgentWithMemoryTest.java
+Tests:
+ "@Test
+public void agentRemembersUserNameWithMemoryTool() throws Exception {
+ String userId = "test-user";
+ String agentName = "test-agent";
+ Part functionCall = Part.builder().functionCall(FunctionCall.builder().name("loadMemory").args(ImmutableMap.of("query", "what is my name?")).build()).build();
+ TestLlm testLlm = new TestLlm(ImmutableList.of(LlmResponse.builder().content(Content.builder().parts(Part.fromText("OK, I'll remember that.")).role("model").build()).build(), LlmResponse.builder().content(Content.builder().role("model").parts(ImmutableList.of(functionCall)).build()).build(), LlmResponse.builder().content(Content.builder().
+
+ parts(Part.fromText("Your name is James.")).role("model").build()).build()));
+ LlmAgent agent = LlmAgent.builder().name(agentName).model(testLlm).tools(ImmutableList.of(new LoadMemoryTool())).build();
+ InMemoryRunner runner = new InMemoryRunner(agent);
+ String sessionId = runner.sessionService().createSession(agentName, userId).blockingGet().id();
+ Content firstMessage = Content.fromParts(Part.fromText("My name is James"));
+ var unused = runner.runAsync(userId, sessionId, firstMessage, RunConfig.builder().build()).toList().blockingGet();
+
+ Session updatedSession = runner.sessionService().getSession("test-agent", userId, sessionId, Optional.empty()).blockingGet();
+
+ runner.memoryService().addSessionToMemory(updatedSession).blockingAwait();
+ Content secondMessage = Content.fromParts(Part.fromText("what is my name?"));
+ unused = runner.runAsync(userId, updatedSession.id(), secondMessage, RunConfig.builder().build()).toList().blockingGet();
+
+ LlmRequest lastRequest = testLlm.getLastRequest();
+ Content functionResponseContent = Iterables.getLast(lastRequest.contents());
+ Optional functionResponsePart = functionResponseContent.parts().get().stream().filter(p -> p.functionResponse().isPresent()).findFirst();
+ assertThat(functionResponsePart).isPresent();
+ FunctionResponse functionResponse = functionResponsePart.get().functionResponse().get();
+ assertThat(functionResponse.name()).hasValue("loadMemory");
+ assertThat(functionResponse.response().get().toString()).contains("My name is James");
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void setUp() {
+ MockitoAnnotations.openMocks(this);
+ liveRequestQueue = new LiveRequestQueue();
+ session = Session.builder("test-session-id").build();
+ userContent = Content.builder().build();
+ runConfig = RunConfig.builder().build();
+ testInvocationId = "test-invocation-id";
+ activeStreamingTools = new HashMap<>();
+ activeStreamingTools.put("test-tool", new ActiveStreamingTool(new LiveRequestQueue()));
+}
+"
+ "@Test
+public void testCreateWithUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCreateWithNullUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.userContent()).isEmpty();
+}
+"
+ "@Test
+public void testCreateWithLiveRequestQueue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).hasValue(liveRequestQueue);
+
+ assertThat(context.invocationId()).startsWith("e-");
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).isEmpty();
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"
+ "@Test
+public void testGetters() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testSetAgent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ BaseAgent newMockAgent = mock(BaseAgent.class);
+ context.agent(newMockAgent);
+ assertThat(context.agent()).isEqualTo(newMockAgent);
+}
+"
+ "@Test
+public void testEquals_sameObject() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(context)).isTrue();
+}
+"
+ "@Test
+public void testEquals_null() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(null)).isFalse();
+}
+"
+ "@Test
+public void testEquals_sameValues() {
+ InvocationContext context1 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext context2 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context1.equals(context2)).isTrue();
+
+ assertThat(context2.equals(context1)).isTrue();
+}
+"
+ "@Test
+public void testEquals_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffAgent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(
+ mock(BaseAgent.class)).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithUserContentEmpty = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithLiveQueuePresent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(contextWithDiffSessionService)).isFalse();
+ assertThat(context.equals(contextWithDiffInvocationId)).isFalse();
+ assertThat(context.equals(contextWithDiffAgent)).isFalse();
+ assertThat(context.equals(contextWithUserContentEmpty)).isFalse();
+ assertThat(context.equals(contextWithLiveQueuePresent)).isFalse();
+}
+"
+ "@Test
+public void testHashCode_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotEqualTo(contextWithDiffSessionService);
+ assertThat(context).isNotEqualTo(contextWithDiffInvocationId);
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ assertThat(context.isResumable()).isFalse();
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsResumable_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ assertThat(context.isResumable()).isTrue();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoLongRunningToolIds_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoFunctionCalls_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoMatchingFunctionCallId_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc2"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndMatchingFunctionCallId_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isTrue();
+}
+"Scenario 1: Builder Returns a Non-Null Builder Instance
+
+Details:
+ TestName: builderReturnsNonNullInstance
+ Description: Verifies that the static builder() method returns a non-null Builder instance,
+ confirming that the factory method is properly instantiating the Builder class.
+Execution:
+ Arrange: No setup required; the builder() method is a static factory method with no parameters.
+ Act: Invoke InvocationContext.builder() to obtain a Builder instance.
+ Assert: Assert that the returned Builder instance is not null.
+Validation:
+ The assertion verifies that the builder() method always returns a valid, non-null Builder object.
+ This is foundational to all builder-based construction of InvocationContext; if the builder is
+ null, no InvocationContext can be created. This test ensures the factory method initializes
+ correctly.
+
+*/
+
+// ********RoostGPT********
+
+```java
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.events.Event;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.models.LlmCallsLimitExceededException;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.*;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
+import com.google.genai.types.FunctionCall;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextBuilderTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ private RunConfig runConfig;
+
+ @BeforeEach
+ public void setUp() {
+ runConfig = RunConfig.builder().build();
+ when(mockSession.appName()).thenReturn("testApp");
+ when(mockSession.userId()).thenReturn("testUser");
+ when(mockAgent.name()).thenReturn("testAgent");
+ }
+
+ // =========================================================================
+ // Scenario 1: Builder Returns a Non-Null Builder Instance
+ // =========================================================================
+ @Test
+ @Tag("valid")
+ public void builderReturnsNonNullInstance() {
+ // Act
+ InvocationContext.Builder builder = InvocationContext.builder();
+ // Assert
+ assertNotNull(builder, "builder() should return a non-null Builder instance");
+ }
+
+ // =========================================================================
+ // Additional Builder Tests
+ // =========================================================================
+ @Test
+ @Tag("valid")
+ public void builderReturnsNewInstanceEachTime() {
+ // Act
+ InvocationContext.Builder builder1 = InvocationContext.builder();
+ InvocationContext.Builder builder2 = InvocationContext.builder();
+ // Assert
+ assertNotNull(builder1);
+ assertNotNull(builder2);
+ assertNotSame(builder1, builder2, "Each call to builder() should return a distinct Builder instance");
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderCanBuildMinimalInvocationContext() {
+ // Arrange
+ String invocationId = "e-test-invocation-id";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context, "Builder.build() should return a non-null InvocationContext");
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderSessionServiceIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-session-service-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderArtifactServiceIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-artifact-service-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockArtifactService, context.artifactService());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderMemoryServiceIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-memory-service-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockMemoryService, context.memoryService());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderPluginManagerIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-plugin-manager-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .pluginManager(mockPluginManager)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockPluginManager, context.pluginManager());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderInvocationIdIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-invocation-id-12345";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(invocationId, context.invocationId());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderAgentIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-agent-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockAgent, context.agent());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderSessionIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-session-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockSession, context.session());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderUserContentIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-user-content-test";
+ Content userContent = Content.builder().role("user").build();
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.of(userContent))
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertTrue(context.userContent().isPresent());
+ assertEquals(userContent, context.userContent().get());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderUserContentAbsentWhenNotSet() {
+ // Arrange
+ String invocationId = "e-user-content-absent-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertFalse(context.userContent().isPresent());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderRunConfigIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-run-config-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertEquals(runConfig, context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderEndInvocationDefaultFalse() {
+ // Arrange
+ String invocationId = "e-end-invocation-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertFalse(context.endInvocation());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderEndInvocationSetToTrue() {
+ // Arrange
+ String invocationId = "e-end-invocation-true-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .endInvocation(true)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertTrue(context.endInvocation());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderBranchIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-branch-test";
+ String branchValue = "main-branch";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .branch(branchValue)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertTrue(context.branch().isPresent());
+ assertEquals(branchValue, context.branch().get());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderBranchIsSetViaOptional() {
+ // Arrange
+ String invocationId = "e-branch-optional-test";
+ String branchValue = "optional-branch";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .branch(Optional.of(branchValue))
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertTrue(context.branch().isPresent());
+ assertEquals(branchValue, context.branch().get());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderLiveRequestQueueIsSetCorrectly() {
+ // Arrange
+ String invocationId = "e-live-request-queue-test";
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .liveRequestQueue(Optional.of(liveRequestQueue))
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertTrue(context.liveRequestQueue().isPresent());
+ assertEquals(liveRequestQueue, context.liveRequestQueue().get());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderLiveRequestQueueAbsentByDefault() {
+ // Arrange
+ String invocationId = "e-live-request-queue-absent-test";
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .liveRequestQueue(Optional.empty())
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertFalse(context.liveRequestQueue().isPresent());
+ }
+
+ @Test
+ @Tag("valid")
+ public void builderLiveRequestQueueSetDirectly() {
+ // Arrange
+ String invocationId = "e-live-request-queue-direct-test";
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ // Act
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(invocationId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(runConfig)
+ .liveRequestQueue(liveRequestQueue)
+ .build();
+ // Assert
+ assertNotNull(context);
+ assertTrue(context.liveRequestQueue().isPresent());
+ assertEquals(liveRequestQueue, context.liveRequestQueue().get());
+ }
+
+@Test
+ @Tag("valid")
+ public void builderResumabilityConfigIsSetCorrectly() {
+ // Arrange
+ String invocation
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextCopyOfTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextCopyOfTest.java
new file mode 100644
index 000000000..6368aecbf
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextCopyOfTest.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=copyOf_49f0784c6e
+ROOST_METHOD_SIG_HASH=copyOf_2c012f0957
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"Scenario 1: Copy of Context with Minimal Required Fields Only
+
+Details:
+ TestName: copyOfWithMinimalRequiredFields
+ Description: Verifies that copyOf correctly creates a new InvocationContext when only the
+ minimal required fields (sessionService, artifactService, invocationId, agent,
+ session) are set, while optional fields retain their defaults.
+Execution:
+ Arrange: Build an InvocationContext using the builder with only sessionService,
+ artifactService, invocationId, agent, and session set. Leave memoryService,
+ pluginManager, liveRequestQueue, userContent, runConfig, branch, endInvocation,
+ and resumabilityConfig at their defaults.
+ Act: Call InvocationContext.copyOf(originalContext).
+ Assert: Assert that the returned context is not null, is not the same instance as the
+ original, and that sessionService(), artifactService(), invocationId(), agent(),
+ and session() all match the original. Assert that userContent() equals
+ Optional.empty(), liveRequestQueue() equals Optional.empty(), and
+ endInvocation() is false.
+Validation:
+ Verifies that copyOf handles the minimal-field scenario without errors, and that default
+ values for optional fields are correctly propagated into the new context. This is important
+ to ensure robustness when not all optional fields are explicitly set during context creation.
+
+*/
+
+// ********RoostGPT********
+
+```java
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.events.Event;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.models.LlmCallsLimitExceededException;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import io.reactivex.rxjava3.core.Flowable;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.*;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
+import com.google.genai.types.FunctionCall;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@ExtendWith(MockitoExtension.class)
+class InvocationContextCopyOfTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private ResumabilityConfig mockResumabilityConfig;
+
+ private BaseAgent mockAgent;
+
+ private RunConfig defaultRunConfig;
+
+ @BeforeEach
+ void setUp() {
+ mockAgent = new BaseAgent("testAgent", "A test agent", null, null, null) {
+ @Override
+ protected Flowable runAsyncImpl(InvocationContext invocationContext) {
+ return Flowable.empty();
+ }
+
+ @Override
+ protected Flowable runLiveImpl(InvocationContext invocationContext) {
+ return Flowable.empty();
+ }
+ };
+ defaultRunConfig = RunConfig.builder().build();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 1: Copy of Context with Minimal Required Fields Only
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfWithMinimalRequiredFields() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertNotSame(original, copy);
+ assertSame(mockSessionService, copy.sessionService());
+ assertSame(mockArtifactService, copy.artifactService());
+ assertEquals("inv-001", copy.invocationId());
+ assertSame(mockAgent, copy.agent());
+ assertSame(mockSession, copy.session());
+ assertEquals(Optional.empty(), copy.userContent());
+ assertEquals(Optional.empty(), copy.liveRequestQueue());
+ assertFalse(copy.endInvocation());
+ assertNull(copy.memoryService());
+ assertNull(copy.pluginManager());
+ assertNull(copy.runConfig());
+ assertEquals(Optional.empty(), copy.branch());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 2: Copy of Context with All Fields Set
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfWithAllFieldsSet() {
+ // Arrange
+ Content userContent = Content.newBuilder().build();
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ ResumabilityConfig resumabilityConfig = mock(ResumabilityConfig.class);
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .invocationId("inv-full-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(userContent)
+ .runConfig(defaultRunConfig)
+ .liveRequestQueue(Optional.of(liveRequestQueue))
+ .branch("main-branch")
+ .endInvocation(true)
+ .resumabilityConfig(resumabilityConfig)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertNotSame(original, copy);
+ assertSame(mockSessionService, copy.sessionService());
+ assertSame(mockArtifactService, copy.artifactService());
+ assertSame(mockMemoryService, copy.memoryService());
+ assertSame(mockPluginManager, copy.pluginManager());
+ assertEquals("inv-full-001", copy.invocationId());
+ assertSame(mockAgent, copy.agent());
+ assertSame(mockSession, copy.session());
+ assertTrue(copy.userContent().isPresent());
+ assertSame(userContent, copy.userContent().get());
+ assertSame(defaultRunConfig, copy.runConfig());
+ assertTrue(copy.liveRequestQueue().isPresent());
+ assertSame(liveRequestQueue, copy.liveRequestQueue().get());
+ assertTrue(copy.branch().isPresent());
+ assertEquals("main-branch", copy.branch().get());
+ assertTrue(copy.endInvocation());
+ assertSame(resumabilityConfig, copy.resumabilityConfig());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 3: Copy preserves activeStreamingTools
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfPreservesActiveStreamingTools() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-streaming-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .build();
+ ActiveStreamingTool mockTool1 = mock(ActiveStreamingTool.class);
+ ActiveStreamingTool mockTool2 = mock(ActiveStreamingTool.class);
+ original.activeStreamingTools().put("tool1", mockTool1);
+ original.activeStreamingTools().put("tool2", mockTool2);
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertNotSame(original, copy);
+ assertEquals(2, copy.activeStreamingTools().size());
+ assertSame(mockTool1, copy.activeStreamingTools().get("tool1"));
+ assertSame(mockTool2, copy.activeStreamingTools().get("tool2"));
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 4: Copy returns a distinct instance (not same reference)
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfReturnsDistinctInstance() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-distinct-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertNotSame(original, copy);
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 5: Copy of context with endInvocation = false propagates correctly
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfWithEndInvocationFalse() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-end-false-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .endInvocation(false)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertFalse(copy.endInvocation());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 6: Copy of context with endInvocation = true propagates correctly
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfWithEndInvocationTrue() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-end-true-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .endInvocation(true)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertTrue(copy.endInvocation());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 7: Mutations to copy do not affect original
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfMutationDoesNotAffectOriginal() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-mutation-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .endInvocation(false)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ copy.setEndInvocation(true);
+ copy.branch("new-branch");
+ // Assert
+ assertFalse(original.endInvocation());
+ assertEquals(Optional.empty(), original.branch());
+ assertTrue(copy.endInvocation());
+ assertEquals(Optional.of("new-branch"), copy.branch());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 8: Mutations to activeStreamingTools in copy do not affect original
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfActiveStreamingToolsMutationDoesNotAffectOriginal() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-tool-mutation-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .build();
+ ActiveStreamingTool mockTool = mock(ActiveStreamingTool.class);
+ original.activeStreamingTools().put("tool1", mockTool);
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ ActiveStreamingTool mockTool2 = mock(ActiveStreamingTool.class);
+ copy.activeStreamingTools().put("tool2", mockTool2);
+ // Assert
+ assertEquals(1, original.activeStreamingTools().size());
+ assertTrue(original.activeStreamingTools().containsKey("tool1"));
+ assertFalse(original.activeStreamingTools().containsKey("tool2"));
+ assertEquals(2, copy.activeStreamingTools().size());
+ assertTrue(copy.activeStreamingTools().containsKey("tool1"));
+ assertTrue(copy.activeStreamingTools().containsKey("tool2"));
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 9: Copy of context with empty activeStreamingTools
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("boundary")
+ void copyOfWithEmptyActiveStreamingTools() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-empty-tools-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertNotNull(copy.activeStreamingTools());
+ assertTrue(copy.activeStreamingTools().isEmpty());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 10: Copy of context preserves branch value
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfPreservesBranchValue() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-branch-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .branch("parent.child.grandchild")
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertTrue(copy.branch().isPresent());
+ assertEquals("parent.child.grandchild", copy.branch().get());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 11: Copy of context with Optional.empty branch
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("boundary")
+ void copyOfWithEmptyBranch() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-no-branch-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .branch(Optional.empty())
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertFalse(copy.branch().isPresent());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 12: Copy of context preserves invocationId exactly
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void copyOfPreservesInvocationId() {
+ // Arrange
+ String specificId = "e-" + "12345678-1234-1234-1234-123456789012";
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(specificId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertEquals(specificId, copy.invocationId());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 13: Copy of context with null optional fields (userContent = empty)
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("boundary")
+ void copyOfWithNullUserContent() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-null-content-001")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ // Assert
+ assertNotNull(copy);
+ assertFalse(copy.userContent().isPresent());
+ }
+
+// -------------------------------------------------------------------------
+// Scenario 14: Copy of context preserves runConfig
+// -------------------------------------------------------------------------
+@Test
+ @Tag("valid")
+ void copyOfPreservesRunConfig() {
+ // Arrange
+ RunConfig runConfig = RunConfig.builder().setMaxLlmCalls(10).build();
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockA
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextCreate891Test.java b/core/src/test/java/com/google/adk/agents/InvocationContextCreate891Test.java
new file mode 100644
index 000000000..7dd143b5c
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextCreate891Test.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=create_6e6963ca78
+ROOST_METHOD_SIG_HASH=create_ac1179ff57
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/ToolResolverTest.java
+Tests:
+ "@Test
+public void testResolveToolInstance_fromRegistry() throws Exception {
+ FunctionTool testTool = FunctionTool.create(TestToolWithMethods.class, "method1");
+ testRegistry.register("test.tool.instance", testTool);
+ BaseTool resolved = ToolResolver.resolveToolInstance("test.tool.instance");
+ assertThat(resolved).isEqualTo(testTool);
+}
+"
+ "@Test
+public void testResolveTools_mixedTypes() throws Exception {
+
+ FunctionTool registeredTool = FunctionTool.create(TestToolWithMethods.class, "method1");
+ testRegistry.register("registered.tool", registeredTool);
+ ImmutableList toolConfigs = ImmutableList.of(
+ createToolConfig("registered.tool", null),
+ createToolConfig(TestToolWithDefaultConstructor.class.getName(), null), createToolConfig(TestToolWithStaticField.class.getName() + ".INSTANCE",
+ null));
+ ImmutableList resolved = ToolResolver.resolveTools(toolConfigs, "/test/path");
+ assertThat(resolved).hasSize(3);
+ assertThat(resolved.get(0)).isEqualTo(registeredTool);
+ assertThat(resolved.get(1)).isInstanceOf(TestToolWithDefaultConstructor.class);
+ assertThat(resolved.get(2)).isInstanceOf(TestToolWithStaticField.class);
+}
+"Scenario 1: Create InvocationContext with All Valid Non-Null Parameters
+
+Details:
+ TestName: createWithAllValidNonNullParameters
+ Description: Verifies that calling the create method with all valid, non-null parameters produces a fully populated InvocationContext instance where each field is correctly assigned.
+
+Execution:
+ Arrange:
+ - Create a mock or stub instance of BaseSessionService.
+ - Create a mock or stub instance of BaseArtifactService.
+ - Create a mock or stub instance of BaseAgent.
+ - Create a mock or stub instance of Session.
+ - Create a mock or stub instance of LiveRequestQueue.
+ - Create a RunConfig instance using RunConfig.builder().build().
+ Act:
+ - Call InvocationContext.create(sessionService, artifactService, agent, session, liveRequestQueue, runConfig).
+ Assert:
+ - Assert that the returned InvocationContext is not null.
+ - Assert that context.sessionService() equals the provided sessionService.
+ - Assert that context.artifactService() equals the provided artifactService.
+ - Assert that context.agent() equals the provided agent.
+ - Assert that context.session() equals the provided session.
+ - Assert that context.liveRequestQueue() is equal to Optional.of(liveRequestQueue).
+ - Assert that context.runConfig() equals the provided runConfig.
+
+Validation:
+ This test ensures that when all parameters are provided and non-null, the factory method correctly delegates to the builder and produces an InvocationContext with every field set to the expected value. It validates the fundamental happy-path behavior of the create method.
+
+*/
+
+// ********RoostGPT********
+
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import java.util.Optional;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextCreate891Test {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private LiveRequestQueue mockLiveRequestQueue;
+
+ private RunConfig runConfig;
+
+ @BeforeEach
+ void setUp() {
+ runConfig = RunConfig.builder().build();
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithAllValidNonNullParameters() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(mockAgent, context.agent());
+ assertEquals(mockSession, context.session());
+ assertEquals(Optional.of(mockLiveRequestQueue), context.liveRequestQueue());
+ assertEquals(runConfig, context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithNullLiveRequestQueueResultsInEmptyOptional() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, null, runConfig);
+ assertNotNull(context);
+ assertNotNull(context.liveRequestQueue());
+ assertFalse(context.liveRequestQueue().isPresent());
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(mockAgent, context.agent());
+ assertEquals(mockSession, context.session());
+ assertEquals(runConfig, context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithNullSessionServiceReturnsContextWithNullSessionService() {
+ InvocationContext context = InvocationContext.create(null, mockArtifactService, mockAgent, mockSession,
+ mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertNull(context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(mockAgent, context.agent());
+ assertEquals(mockSession, context.session());
+ assertEquals(Optional.of(mockLiveRequestQueue), context.liveRequestQueue());
+ assertEquals(runConfig, context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithNullArtifactServiceReturnsContextWithNullArtifactService() {
+ InvocationContext context = InvocationContext.create(mockSessionService, null, mockAgent, mockSession,
+ mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ assertNull(context.artifactService());
+ assertEquals(mockAgent, context.agent());
+ assertEquals(mockSession, context.session());
+ assertEquals(Optional.of(mockLiveRequestQueue), context.liveRequestQueue());
+ assertEquals(runConfig, context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithNullAgentReturnsContextWithNullAgent() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, null, mockSession,
+ mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertNull(context.agent());
+ assertEquals(mockSession, context.session());
+ assertEquals(Optional.of(mockLiveRequestQueue), context.liveRequestQueue());
+ assertEquals(runConfig, context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithNullSessionReturnsContextWithNullSession() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent, null,
+ mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(mockAgent, context.agent());
+ assertNull(context.session());
+ assertEquals(Optional.of(mockLiveRequestQueue), context.liveRequestQueue());
+ assertEquals(runConfig, context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithNullRunConfigReturnsContextWithNullRunConfig() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, null);
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(mockAgent, context.agent());
+ assertEquals(mockSession, context.session());
+ assertEquals(Optional.of(mockLiveRequestQueue), context.liveRequestQueue());
+ assertNull(context.runConfig());
+ }
+
+ @Test
+ @Tag("invalid")
+ void createWithAllNullParametersReturnsContextWithNullFields() {
+ InvocationContext context = InvocationContext.create(null, null, null, null, null, null);
+ assertNotNull(context);
+ assertNull(context.sessionService());
+ assertNull(context.artifactService());
+ assertNull(context.agent());
+ assertNull(context.session());
+ assertFalse(context.liveRequestQueue().isPresent());
+ assertNull(context.runConfig());
+ }
+
+ @Test
+ @Tag("valid")
+ void createDoesNotSetInvocationIdWhenNotProvided() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertNull(context.invocationId());
+ }
+
+ @Test
+ @Tag("valid")
+ void createSetsLiveRequestQueueAsOptionalPresent() {
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, liveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertTrue(context.liveRequestQueue().isPresent());
+ assertEquals(liveRequestQueue, context.liveRequestQueue().get());
+ }
+
+ @Test
+ @Tag("valid")
+ void createDefaultsEndInvocationToFalse() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertFalse(context.endInvocation());
+ }
+
+ @Test
+ @Tag("valid")
+ void createDefaultsBranchToEmptyOptional() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertNotNull(context.branch());
+ assertFalse(context.branch().isPresent());
+ }
+
+ @Test
+ @Tag("valid")
+ void createUserContentIsEmptyOptionalByDefault() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertNotNull(context.userContent());
+ assertFalse(context.userContent().isPresent());
+ }
+
+ @Test
+ @Tag("valid")
+ void createActiveStreamingToolsIsEmptyByDefault() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertNotNull(context.activeStreamingTools());
+ assertTrue(context.activeStreamingTools().isEmpty());
+ }
+
+ @Test
+ @Tag("valid")
+ void createReturnsDistinctInstancesOnMultipleCalls() {
+ InvocationContext context1 = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ InvocationContext context2 = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context1);
+ assertNotNull(context2);
+ assertNotSame(context1, context2);
+ }
+
+ @Test
+ @Tag("valid")
+ void createMemoryServiceIsNullByDefault() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertNull(context.memoryService());
+ }
+
+ @Test
+ @Tag("valid")
+ void createPluginManagerIsNullByDefault() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertNull(context.pluginManager());
+ }
+
+ @Test
+ @Tag("valid")
+ void createWithRunConfigMaxLlmCallsSet() {
+ RunConfig customRunConfig = RunConfig.builder().setMaxLlmCalls(100).build();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, customRunConfig);
+ assertNotNull(context);
+ assertNotNull(context.runConfig());
+ assertEquals(100, context.runConfig().maxLlmCalls());
+ }
+
+ @Test
+ @Tag("integration")
+ void createContextCanBeUsedWithCopyOf() {
+ InvocationContext original = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ InvocationContext copy = InvocationContext.copyOf(original);
+ assertNotNull(copy);
+ assertEquals(original.sessionService(), copy.sessionService());
+ assertEquals(original.artifactService(), copy.artifactService());
+ assertEquals(original.agent(), copy.agent());
+ assertEquals(original.session(), copy.session());
+ assertEquals(original.liveRequestQueue(), copy.liveRequestQueue());
+ assertEquals(original.runConfig(), copy.runConfig());
+ assertEquals(original.endInvocation(), copy.endInvocation());
+ }
+
+ @Test
+ @Tag("integration")
+ void createContextEqualsAnotherContextWithSameParameters() {
+ InvocationContext context1 = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ InvocationContext context2 = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertEquals(context1, context2);
+ }
+
+ @Test
+ @Tag("integration")
+ void createContextSetEndInvocationAfterCreation() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertFalse(context.endInvocation());
+ context.setEndInvocation(true);
+ assertTrue(context.endInvocation());
+ }
+
+ @Test
+ @Tag("integration")
+ void createContextSetAgentAfterCreation() {
+ BaseAgent anotherAgent = mock(BaseAgent.class);
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, runConfig);
+ assertEquals(mockAgent, context.agent());
+ context.agent(anotherAgent);
+ assertEquals(anotherAgent, context.agent());
+ }
+
+ @Test
+ @Tag("boundary")
+ void createWithNewLiveRequestQueueInstance() {
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, liveRequestQueue, runConfig);
+ assertNotNull(context);
+ assertTrue(context.liveRequestQueue().isPresent());
+ assertSame(liveRequestQueue, context.liveRequestQueue().get());
+ }
+
+ @Test
+ @Tag("boundary")
+ void createWithRunConfigZeroMaxLlmCalls() {
+ RunConfig customRunConfig = RunConfig.builder().setMaxLlmCalls(0).build();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, customRunConfig);
+ assertNotNull(context);
+ assertNotNull(context.runConfig());
+ assertEquals(0, context.runConfig().maxLlmCalls());
+ }
+
+ @Test
+ @Tag("boundary")
+ void createWithRunConfigMaxIntMaxLlmCalls() {
+ RunConfig customRunConfig = RunConfig.builder().setMaxLlmCalls(Integer.MAX_VALUE).build();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, mockLiveRequestQueue, customRunConfig);
+ assertNotNull(context);
+ assertNotNull(context.runConfig());
+ assertEquals(Integer.MAX_VALUE, context.runConfig().maxLlmCalls());
+ }
+
+}
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextCreateTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextCreateTest.java
new file mode 100644
index 000000000..ddbc422f3
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextCreateTest.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=create_a8299eaa31
+ROOST_METHOD_SIG_HASH=create_95f62994c3
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/ToolResolverTest.java
+Tests:
+ "@Test
+public void testResolveToolInstance_fromRegistry() throws Exception {
+ FunctionTool testTool = FunctionTool.create(TestToolWithMethods.class, "method1");
+ testRegistry.register("test.tool.instance", testTool);
+ BaseTool resolved = ToolResolver.resolveToolInstance("test.tool.instance");
+ assertThat(resolved).isEqualTo(testTool);
+}
+"
+ "@Test
+public void testResolveTools_mixedTypes() throws Exception {
+
+ FunctionTool registeredTool = FunctionTool.create(TestToolWithMethods.class, "method1");
+ testRegistry.register("registered.tool", registeredTool);
+ ImmutableList toolConfigs = ImmutableList.of(
+ createToolConfig("registered.tool", null),
+ createToolConfig(TestToolWithDefaultConstructor.class.getName(), null), createToolConfig(TestToolWithStaticField.class.getName() + ".INSTANCE",
+ null));
+ ImmutableList resolved = ToolResolver.resolveTools(toolConfigs, "/test/path");
+ assertThat(resolved).hasSize(3);
+ assertThat(resolved.get(0)).isEqualTo(registeredTool);
+ assertThat(resolved.get(1)).isInstanceOf(TestToolWithDefaultConstructor.class);
+ assertThat(resolved.get(2)).isInstanceOf(TestToolWithStaticField.class);
+}
+"Scenario 1: Create InvocationContext With All Valid Non-Null Parameters
+
+Details:
+ TestName: createWithAllValidNonNullParameters
+ Description: Verifies that the `create` method successfully constructs an `InvocationContext` when all parameters,
+ including a non-null `userContent`, are provided with valid values. This confirms that each field
+ is correctly assigned through the builder chain.
+Execution:
+ Arrange:
+ - Create a mock of `BaseSessionService`.
+ - Create a mock of `BaseArtifactService`.
+ - Create a mock of `BaseAgent`.
+ - Create a mock of `Session`.
+ - Create a mock of `Content` (non-null userContent).
+ - Create a mock of `RunConfig`.
+ - Define a non-empty `invocationId` string (e.g., "test-invocation-id-001").
+ Act:
+ - Call `InvocationContext.create(sessionService, artifactService, invocationId, agent, session, userContent, runConfig)`.
+ Assert:
+ - Assert that the returned `InvocationContext` object is not null.
+ - Assert that `context.sessionService()` equals the provided `sessionService` mock.
+ - Assert that `context.artifactService()` equals the provided `artifactService` mock.
+ - Assert that `context.invocationId()` equals "test-invocation-id-001".
+ - Assert that `context.agent()` equals the provided `agent` mock.
+ - Assert that `context.session()` equals the provided `session` mock.
+ - Assert that `context.userContent()` is present and equals the provided `userContent` mock.
+ - Assert that `context.runConfig()` equals the provided `runConfig` mock.
+Validation:
+ This test validates the primary happy-path scenario, ensuring that the factory method correctly
+ delegates all provided parameters to the underlying builder and that the resulting context
+ accurately reflects all supplied values. This is fundamental to the correct initialization of
+ an invocation lifecycle.
+
+*/
+
+// ********RoostGPT********
+
+```java
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.*;
+import com.google.adk.events.Event;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.models.LlmCallsLimitExceededException;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
+import com.google.genai.types.FunctionCall;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextCreateTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private Content mockUserContent;
+
+ @Mock
+ private RunConfig mockRunConfig;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ private static final String VALID_INVOCATION_ID = "test-invocation-id-001";
+
+ @BeforeEach
+ void setUp() {
+ // Common setup if needed
+ }
+
+ // ===== Scenario 1: Create InvocationContext With All Valid Non-Null Parameters =====
+ @Test
+ @Tag("valid")
+ void createWithAllValidNonNullParameters() {
+ // Arrange
+ String invocationId = VALID_INVOCATION_ID;
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, invocationId,
+ mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(invocationId, context.invocationId());
+ assertEquals(mockAgent, context.agent());
+ assertEquals(mockSession, context.session());
+ assertTrue(context.userContent().isPresent());
+ assertEquals(mockUserContent, context.userContent().get());
+ assertEquals(mockRunConfig, context.runConfig());
+ }
+
+ // ===== Scenario 2: Create InvocationContext With Null UserContent =====
+ @Test
+ @Tag("valid")
+ void createWithNullUserContentResultsInEmptyOptional() {
+ // Arrange
+ String invocationId = "test-invocation-null-content";
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, invocationId,
+ mockAgent, mockSession, null, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertFalse(context.userContent().isPresent());
+ assertEquals(invocationId, context.invocationId());
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(mockAgent, context.agent());
+ assertEquals(mockSession, context.session());
+ assertEquals(mockRunConfig, context.runConfig());
+ }
+
+ // ===== Scenario 3: Create InvocationContext With Null SessionService =====
+ @Test
+ @Tag("valid")
+ void createWithNullSessionService() {
+ // Arrange
+ String invocationId = "test-invocation-null-session-service";
+ // Act
+ InvocationContext context = InvocationContext.create(null, mockArtifactService, invocationId, mockAgent,
+ mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertNull(context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ assertEquals(invocationId, context.invocationId());
+ }
+
+ // ===== Scenario 4: Create InvocationContext With Null ArtifactService =====
+ @Test
+ @Tag("valid")
+ void createWithNullArtifactService() {
+ // Arrange
+ String invocationId = "test-invocation-null-artifact-service";
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, null, invocationId, mockAgent,
+ mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertEquals(mockSessionService, context.sessionService());
+ assertNull(context.artifactService());
+ assertEquals(invocationId, context.invocationId());
+ }
+
+ // ===== Scenario 5: Create InvocationContext With Empty InvocationId =====
+ @Test
+ @Tag("boundary")
+ void createWithEmptyInvocationId() {
+ // Arrange
+ String emptyInvocationId = "";
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, emptyInvocationId,
+ mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertEquals("", context.invocationId());
+ assertEquals(mockSessionService, context.sessionService());
+ assertEquals(mockArtifactService, context.artifactService());
+ }
+
+ // ===== Scenario 6: Create InvocationContext With Null InvocationId =====
+ @Test
+ @Tag("boundary")
+ void createWithNullInvocationId() {
+ // Arrange - null invocationId
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, null, mockAgent,
+ mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertNull(context.invocationId());
+ }
+
+ // ===== Scenario 7: Create InvocationContext With Null Agent =====
+ @Test
+ @Tag("valid")
+ void createWithNullAgent() {
+ // Arrange
+ String invocationId = "test-invocation-null-agent";
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, invocationId,
+ null, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertNull(context.agent());
+ assertEquals(invocationId, context.invocationId());
+ }
+
+ // ===== Scenario 8: Create InvocationContext With Null Session =====
+ @Test
+ @Tag("valid")
+ void createWithNullSession() {
+ // Arrange
+ String invocationId = "test-invocation-null-session";
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, invocationId,
+ mockAgent, null, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertNull(context.session());
+ assertEquals(invocationId, context.invocationId());
+ }
+
+ // ===== Scenario 9: Create InvocationContext With Null RunConfig =====
+ @Test
+ @Tag("valid")
+ void createWithNullRunConfig() {
+ // Arrange
+ String invocationId = "test-invocation-null-runconfig";
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, invocationId,
+ mockAgent, mockSession, mockUserContent, null);
+ // Assert
+ assertNotNull(context);
+ assertNull(context.runConfig());
+ assertEquals(invocationId, context.invocationId());
+ }
+
+ // ===== Scenario 10: Create InvocationContext With All Null Parameters =====
+ @Test
+ @Tag("boundary")
+ void createWithAllNullParameters() {
+ // Act
+ InvocationContext context = InvocationContext.create(null, null, null, null, null, null, null);
+ // Assert
+ assertNotNull(context);
+ assertNull(context.sessionService());
+ assertNull(context.artifactService());
+ assertNull(context.invocationId());
+ assertNull(context.agent());
+ assertNull(context.session());
+ assertFalse(context.userContent().isPresent());
+ assertNull(context.runConfig());
+ }
+
+ // ===== Scenario 11: Create InvocationContext Returns Non-Null Object =====
+ @Test
+ @Tag("valid")
+ void createReturnsNonNullObject() {
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ VALID_INVOCATION_ID, mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context, "The create method must not return null");
+ }
+
+ // ===== Scenario 12: Create InvocationContext Verifies UserContent Is Wrapped In
+ // Optional =====
+ @Test
+ @Tag("valid")
+ void createUserContentIsWrappedInOptional() {
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ VALID_INVOCATION_ID, mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context.userContent());
+ assertTrue(context.userContent() instanceof Optional);
+ assertTrue(context.userContent().isPresent());
+ assertSame(mockUserContent, context.userContent().get());
+ }
+
+ // ===== Scenario 13: Create Two InvocationContexts Are Independent =====
+ @Test
+ @Tag("valid")
+ void createTwoContextsAreIndependent() {
+ // Arrange
+ BaseSessionService anotherSessionService = mock(BaseSessionService.class);
+ String invocationId1 = "invocation-001";
+ String invocationId2 = "invocation-002";
+ // Act
+ InvocationContext context1 = InvocationContext.create(mockSessionService, mockArtifactService, invocationId1,
+ mockAgent, mockSession, mockUserContent, mockRunConfig);
+ InvocationContext context2 = InvocationContext.create(anotherSessionService, mockArtifactService, invocationId2,
+ mockAgent, mockSession, null, mockRunConfig);
+ // Assert
+ assertNotEquals(context1.invocationId(), context2.invocationId());
+ assertNotEquals(context1.sessionService(), context2.sessionService());
+ assertTrue(context1.userContent().isPresent());
+ assertFalse(context2.userContent().isPresent());
+ }
+
+ // ===== Scenario 14: Create InvocationContext Has Default endInvocation False =====
+ @Test
+ @Tag("valid")
+ void createDefaultEndInvocationIsFalse() {
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ VALID_INVOCATION_ID, mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertFalse(context.endInvocation(), "Default endInvocation should be false");
+ }
+
+ // ===== Scenario 15: Create InvocationContext Has Empty Branch By Default =====
+ @Test
+ @Tag("valid")
+ void createDefaultBranchIsEmpty() {
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ VALID_INVOCATION_ID, mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context.branch());
+ assertFalse(context.branch().isPresent(), "Default branch should be empty");
+ }
+
+ // ===== Scenario 16: Create InvocationContext Has Empty LiveRequestQueue By Default
+ // =====
+ @Test
+ @Tag("valid")
+ void createDefaultLiveRequestQueueIsEmpty() {
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ VALID_INVOCATION_ID, mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context.liveRequestQueue());
+ assertFalse(context.liveRequestQueue().isPresent(), "Default liveRequestQueue should be empty");
+ }
+
+ // ===== Scenario 17: Create InvocationContext Has Empty ActiveStreamingTools By
+ // Default =====
+ @Test
+ @Tag("valid")
+ void createDefaultActiveStreamingToolsIsEmpty() {
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ VALID_INVOCATION_ID, mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context.activeStreamingTools());
+ assertTrue(context.activeStreamingTools().isEmpty(), "Default activeStreamingTools should be empty");
+ }
+
+ // ===== Scenario 18: Create InvocationContext With Long InvocationId =====
+ @Test
+ @Tag("boundary")
+ void createWithVeryLongInvocationId() {
+ // Arrange
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 1000; i++) {
+ sb.append("x");
+ }
+ String longInvocationId = sb.toString();
+ // Act
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, longInvocationId,
+ mockAgent, mockSession, mockUserContent, mockRunConfig);
+ // Assert
+ assertNotNull(context);
+ assertEquals(longInvocationId, context.invocationId());
+ assertEquals(1000, context.invocationId().length());
+ }
+
+ // ===== Scenario 19: Create InvocationContext Invocation Id With Special Characters
+ // =====
+ @Test
+ @Tag("boundary")
+ void createWithSpecialCharactersInInvocationId() {
+ // Arrange
+ String specialInvocationId = "e-" + java.util.UUID.randomUUID().toString();
+ // Act
+ InvocationContext context = InvocationContext.create(
+ mockSessionService,
+ mockArtifactService,
+ specialInvocationId,
+ mockAgent,
+ mockSession,
+ mockUserContent,
+ mockRunConfig
+ );
+ // Assert
+ assertNotNull(context);
+ assertEquals(specialInvocationId, context.invocationId());
+ assertTrue(context.invocationId().startsWith("e-"));
+ }
+
+// ===== Scenario 20: Create Two Separate Calls Return Different Instances =====
+@Test
+ @Tag("valid")
+ void createReturnsDifferentInstancesOnMultipleCalls() {
+ // Act
+ InvocationContext context1 = InvocationContext.create(
+ mockSessionService,
+ mockArtifactService,
+ VALID_INVOCATION_ID,
+ mockAgent,
+ mockSession,
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextInvocationIdTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextInvocationIdTest.java
new file mode 100644
index 000000000..ec953f645
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextInvocationIdTest.java
@@ -0,0 +1,708 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=invocationId_b0959abc16
+ROOST_METHOD_SIG_HASH=invocationId_6cd6fb05e4
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/CallbacksTest.java
+Tests:
+ "@Test
+public void testRun_withModelCallbacks_receivesCorrectContext() {
+ Content realContent = Content.fromParts(Part.fromText("Real LLM response"));
+ TestLlm testLlm = createTestLlm(createLlmResponse(realContent));
+ LlmAgent agent = createTestAgentBuilder(testLlm).beforeModelCallback((callbackContext, request) -> {
+ assertThat(callbackContext.invocationId()).isNotEmpty();
+ assertThat(callbackContext.agentName()).isEqualTo("test agent");
+ return Maybe.empty();
+ }).afterModelCallback((callbackContext, response) -> {
+ assertThat(callbackContext.invocationId()).isNotEmpty();
+ assertThat(callbackContext.agentName()).isEqualTo("test agent");
+ assertThat(response.content()).hasValue(realContent);
+ return Maybe.empty();
+ }).build();
+ InvocationContext invocationContext = createInvocationContext(agent);
+ List events = agent.runAsync(invocationContext).toList().blockingGet();
+ assertThat(events).hasSize(1);
+ assertThat(getOnlyElement(events).content()).hasValue(realContent);
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InstructionTest.java
+Tests:
+ "@Test
+public void testCanonicalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).instruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+ "@Test
+public void testCanonicalGlobalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider global instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).globalInstruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalGlobalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/LlmAgentTest.java
+Tests:
+ "@Test
+public void testCanonicalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).instruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+ "@Test
+public void testCanonicalGlobalInstruction_providerInstructionInjectsContext() {
+ String instruction = "Test provider global instruction for invocation: ";
+ LlmAgent agent = createTestAgentBuilder(createTestLlm(LlmResponse.builder().build())).globalInstruction(new Instruction.Provider(context -> Single.just(instruction + context.invocationId()))).build();
+ ReadonlyContext invocationContext = new ReadonlyContext(createInvocationContext(agent));
+ String canonicalInstruction = agent.canonicalGlobalInstruction(invocationContext).blockingGet().getKey();
+ assertThat(canonicalInstruction).isEqualTo(instruction + invocationContext.invocationId());
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/SequentialAgentTest.java
+Tests:
+ "@Test
+public void runAsync_propagatesInvocationContextToSubAgents() {
+ TestBaseAgent subAgent = createSubAgent("subAgent");
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgent").subAgents(ImmutableList.of(subAgent)).build();
+ InvocationContext parentContext = createInvocationContext(sequentialAgent);
+ List unused = sequentialAgent.runAsync(parentContext).toList().blockingGet();
+ InvocationContext capturedContext = subAgent.getLastInvocationContext();
+ assertThat(capturedContext).isNotNull();
+ assertThat(capturedContext.invocationId()).isEqualTo(parentContext.invocationId());
+ assertThat(capturedContext.session()).isEqualTo(parentContext.session());
+ assertThat(capturedContext.agent()).isEqualTo(subAgent);
+ assertThat(subAgent.getInvocationCount()).isEqualTo(1);
+}
+"
+ "@Test
+public void runLive_propagatesInvocationContextToSubAgents() {
+ TestBaseAgent subAgent = createSubAgent("subAgent_live");
+ SequentialAgent sequentialAgent = SequentialAgent.builder().name("seqAgentLive").subAgents(ImmutableList.of(subAgent)).build();
+ InvocationContext parentContext = createInvocationContext(sequentialAgent);
+ List unused = sequentialAgent.runLive(parentContext).toList().blockingGet();
+ InvocationContext capturedContext = subAgent.getLastInvocationContext();
+ assertThat(capturedContext).isNotNull();
+ assertThat(capturedContext.invocationId()).isEqualTo(parentContext.invocationId());
+ assertThat(capturedContext.session()).isEqualTo(parentContext.session());
+ assertThat(capturedContext.agent()).isEqualTo(subAgent);
+ assertThat(subAgent.getInvocationCount()).isEqualTo(1);
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCreateWithUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCreateWithNullUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.userContent()).isEmpty();
+}
+"
+ "@Test
+public void testCreateWithLiveRequestQueue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).hasValue(liveRequestQueue);
+
+ assertThat(context.invocationId()).startsWith("e-");
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).isEmpty();
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"
+ "@Test
+public void testGetters() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testSetAgent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ BaseAgent newMockAgent = mock(BaseAgent.class);
+ context.agent(newMockAgent);
+ assertThat(context.agent()).isEqualTo(newMockAgent);
+}
+"
+ "@Test
+public void testEquals_sameObject() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(context)).isTrue();
+}
+"
+ "@Test
+public void testEquals_null() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(null)).isFalse();
+}
+"
+ "@Test
+public void testEquals_sameValues() {
+ InvocationContext context1 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext context2 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context1.equals(context2)).isTrue();
+
+ assertThat(context2.equals(context1)).isTrue();
+}
+"
+ "@Test
+public void testEquals_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffAgent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(
+ mock(BaseAgent.class)).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithUserContentEmpty = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithLiveQueuePresent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(contextWithDiffSessionService)).isFalse();
+ assertThat(context.equals(contextWithDiffInvocationId)).isFalse();
+ assertThat(context.equals(contextWithDiffAgent)).isFalse();
+ assertThat(context.equals(contextWithUserContentEmpty)).isFalse();
+ assertThat(context.equals(contextWithLiveQueuePresent)).isFalse();
+}
+"
+ "@Test
+public void testHashCode_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotEqualTo(contextWithDiffSessionService);
+ assertThat(context).isNotEqualTo(contextWithDiffInvocationId);
+}
+"Scenario 1: Return the Explicitly Set Invocation ID
+
+Details:
+ TestName: invocationIdReturnsExplicitlySetValue
+ Description: Verifies that the invocationId() method returns the exact invocation ID string
+ that was explicitly provided to the builder via the invocationId() builder method.
+Execution:
+ Arrange: Build an InvocationContext using InvocationContext.builder() with a known, specific
+ invocation ID string (e.g., "test-invocation-id-123") set via .invocationId("test-invocation-id-123"),
+ along with all other required fields (sessionService, artifactService, agent, session, etc.).
+ Act: Call invocationId() on the built InvocationContext instance.
+ Assert: Assert that the returned value equals the exact string "test-invocation-id-123".
+Validation:
+ Confirms that the invocationId field is properly stored during construction and returned without
+ modification by the getter. This is fundamental to ensuring correct tracking of agent invocations
+ throughout the system.
+
+*/
+
+// ********RoostGPT********
+
+```java
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.events.Event;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.models.LlmCallsLimitExceededException;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.*;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
+import com.google.genai.types.FunctionCall;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextInvocationIdTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private RunConfig mockRunConfig;
+
+ @BeforeEach
+ void setUp() {
+ when(mockSession.appName()).thenReturn("testApp");
+ when(mockSession.userId()).thenReturn("testUser");
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdReturnsExplicitlySetValue() {
+ String expectedId = "test-invocation-id-123";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ String actualId = context.invocationId();
+ assertEquals(expectedId, actualId);
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdReturnsCorrectValueWhenSetViaCreateMethod() {
+ String expectedId = "create-method-invocation-id";
+ Content userContent = Content.builder().build();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, expectedId,
+ mockAgent, mockSession, userContent, mockRunConfig);
+ String actualId = context.invocationId();
+ assertEquals(expectedId, actualId);
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdIsNotNullWhenExplicitlySet() {
+ String expectedId = "non-null-invocation-id";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertNotNull(context.invocationId());
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdReturnsSameReferenceAfterMultipleCalls() {
+ String expectedId = "stable-invocation-id-456";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ String firstCall = context.invocationId();
+ String secondCall = context.invocationId();
+ String thirdCall = context.invocationId();
+ assertEquals(firstCall, secondCall);
+ assertEquals(secondCall, thirdCall);
+ assertEquals(expectedId, firstCall);
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdPreservedInCopyOf() {
+ String expectedId = "copy-of-invocation-id-789";
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext copy = InvocationContext.copyOf(original);
+ assertEquals(expectedId, copy.invocationId());
+ assertEquals(original.invocationId(), copy.invocationId());
+ }
+
+ @Test
+ @Tag("boundary")
+ void invocationIdWithEmptyString() {
+ String emptyId = "";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(emptyId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ String actualId = context.invocationId();
+ assertEquals(emptyId, actualId);
+ assertNotNull(actualId);
+ assertTrue(actualId.isEmpty());
+ }
+
+ @Test
+ @Tag("boundary")
+ void invocationIdWithVeryLongString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 1000; i++) {
+ sb.append("a");
+ }
+ String longId = sb.toString();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(longId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(longId, context.invocationId());
+ assertEquals(1000, context.invocationId().length());
+ }
+
+ @Test
+ @Tag("boundary")
+ void invocationIdWithSpecialCharacters() {
+ String specialId = "e-!@#$%^&*()-_=+[]{}|;':\",./<>?";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(specialId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(specialId, context.invocationId());
+ }
+
+ @Test
+ @Tag("boundary")
+ void invocationIdWithUuidFormat() {
+ String uuidId = "e-" + java.util.UUID.randomUUID().toString();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(uuidId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertNotNull(context.invocationId());
+ assertTrue(context.invocationId().startsWith("e-"));
+ assertEquals(uuidId, context.invocationId());
+ }
+
+ @Test
+ @Tag("valid")
+ void newInvocationContextIdGeneratesValidId() {
+ String generatedId = InvocationContext.newInvocationContextId();
+ assertNotNull(generatedId);
+ assertTrue(generatedId.startsWith("e-"));
+ assertTrue(generatedId.length() > 2);
+ }
+
+ @Test
+ @Tag("valid")
+ void newInvocationContextIdGeneratesUniqueIds() {
+ String id1 = InvocationContext.newInvocationContextId();
+ String id2 = InvocationContext.newInvocationContextId();
+ String id3 = InvocationContext.newInvocationContextId();
+ assertNotEquals(id1, id2);
+ assertNotEquals(id2, id3);
+ assertNotEquals(id1, id3);
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdUsedInNewInvocationContextIdFormat() {
+ String generatedId = InvocationContext.newInvocationContextId();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(generatedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(generatedId, context.invocationId());
+ assertTrue(context.invocationId().startsWith("e-"));
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdNotAffectedByOtherFieldChanges() {
+ String expectedId = "immutable-invocation-id";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ context.setEndInvocation(true);
+ context.agent(mockAgent);
+ context.branch("new-branch");
+ assertEquals(expectedId, context.invocationId());
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdWithNumericString() {
+ String numericId = "1234567890";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(numericId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(numericId, context.invocationId());
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdWithWhitespace() {
+ String whitespaceId = " invocation id with spaces ";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(whitespaceId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(whitespaceId, context.invocationId());
+ }
+
+ @Test
+ @Tag("integration")
+ void invocationIdConsistentAcrossEqualsAndHashCode() {
+ String expectedId = "equality-test-invocation-id";
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(context1.invocationId(), context2.invocationId());
+ assertEquals(context1, context2);
+ assertEquals(context1.hashCode(), context2.hashCode());
+ }
+
+ @Test
+ @Tag("integration")
+ void invocationIdDifferentContextsHaveDifferentIds() {
+ String id1 = "first-invocation-id";
+ String id2 = "second-invocation-id";
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(id1)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(id2)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertNotEquals(context1.invocationId(), context2.invocationId());
+ assertNotEquals(context1, context2);
+ }
+
+ @Test
+ @Tag("integration")
+ void invocationIdReturnedCorrectlyWithAllFieldsPopulated() {
+ String expectedId = "full-context-invocation-id";
+ Content userContent = Content.builder().build();
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.of(userContent))
+ .runConfig(mockRunConfig)
+ .branch("test-branch")
+ .endInvocation(false)
+ .build();
+ assertEquals(expectedId, context.invocationId());
+ }
+
+ @Test
+ @Tag("valid")
+ void invocationIdReturnedCorrectlyWithNullOptionalFields() {
+ String expectedId = "minimal-context-invocation-id";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(null)
+ .artifactService(null)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(expectedId, context.invocationId());
+ }
+
+ @Test
+ @Tag("boundary")
+ void invocationIdWithSingleCharacter() {
+ String singleCharId = "x";
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(singleCharId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ assertEquals(singleCharId, context.invocationId());
+ assertEquals(1, context.invocationId().length());
+ }
+
+@Test
+ @Tag("valid")
+ void invocationIdPreservedAfterCopyAndModification() {
+ String expectedId = "original-copy-test-id";
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId(expectedId)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext copy = InvocationContext
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextLiveRequestQueueTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextLiveRequestQueueTest.java
new file mode 100644
index 000000000..507ceb5de
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextLiveRequestQueueTest.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=liveRequestQueue_752dd14d55
+ROOST_METHOD_SIG_HASH=liveRequestQueue_66d4c7a2b5
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCreateWithUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCreateWithLiveRequestQueue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).hasValue(liveRequestQueue);
+
+ assertThat(context.invocationId()).startsWith("e-");
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).isEmpty();
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"
+ "@Test
+public void testGetters() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testEquals_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffAgent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(
+ mock(BaseAgent.class)).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithUserContentEmpty = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithLiveQueuePresent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(contextWithDiffSessionService)).isFalse();
+ assertThat(context.equals(contextWithDiffInvocationId)).isFalse();
+ assertThat(context.equals(contextWithDiffAgent)).isFalse();
+ assertThat(context.equals(contextWithUserContentEmpty)).isFalse();
+ assertThat(context.equals(contextWithLiveQueuePresent)).isFalse();
+}
+"Scenario 1: liveRequestQueue Returns Empty Optional When Not Set During Build
+
+Details:
+ TestName: liveRequestQueueReturnsEmptyOptionalWhenNotProvided
+ Description: Verifies that when an InvocationContext is built without explicitly setting a
+ liveRequestQueue, the liveRequestQueue() method returns an empty Optional.
+ This is the default behavior per the Builder class default field initialization.
+Execution:
+ Arrange: Build an InvocationContext using the builder without calling liveRequestQueue(...),
+ providing only the mandatory fields (sessionService, artifactService, agent, session,
+ userContent, runConfig).
+ Act: Call liveRequestQueue() on the built InvocationContext instance.
+ Assert: assertThat(context.liveRequestQueue()).isEmpty();
+Validation:
+ The assertion confirms that the default value of liveRequestQueue in the builder is
+ Optional.empty(), and the getter faithfully returns that value. This is important because
+ non-live (standard) invocations must not expose a queue, ensuring the application logic
+ can safely distinguish between live and non-live modes.
+
+*/
+
+// ********RoostGPT********
+
+```java
+package com.google.adk.agents;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.events.Event;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.models.LlmCallsLimitExceededException;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.*;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
+import com.google.genai.types.FunctionCall;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextLiveRequestQueueTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private RunConfig mockRunConfig;
+
+ @Mock
+ private Content mockContent;
+
+ @BeforeEach
+ void setUp() {
+ when(mockSession.appName()).thenReturn("testApp");
+ when(mockSession.userId()).thenReturn("testUser");
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 1: liveRequestQueue returns empty Optional when not set during build
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueReturnsEmptyOptionalWhenNotProvided() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.ofNullable(mockContent))
+ .runConfig(mockRunConfig)
+ .build();
+ assertThat(context.liveRequestQueue()).isEmpty();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 2: liveRequestQueue returns present Optional when set via builder
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueReturnsPresentOptionalWhenProvided() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(Optional.of(queue))
+ .build();
+ assertThat(context.liveRequestQueue()).isPresent();
+ assertThat(context.liveRequestQueue().get()).isSameInstanceAs(queue);
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 3: liveRequestQueue returns present Optional when set directly
+ // via builder overload accepting LiveRequestQueue (not Optional)
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueReturnsPresentOptionalWhenProvidedDirectly() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(queue)
+ .build();
+ assertThat(context.liveRequestQueue()).isPresent();
+ assertThat(context.liveRequestQueue().get()).isSameInstanceAs(queue);
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 4: liveRequestQueue returns empty Optional when created via
+ // the static create(...) factory that accepts Content
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueReturnsEmptyOptionalWhenCreatedViaContentFactory() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ "test-invocation-id", mockAgent, mockSession, mockContent, mockRunConfig);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 5: liveRequestQueue returns present Optional when created via
+ // the static create(...) factory that accepts LiveRequestQueue
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueReturnsPresentOptionalWhenCreatedViaLiveFactory() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, queue, mockRunConfig);
+ assertThat(context.liveRequestQueue()).isPresent();
+ assertThat(context.liveRequestQueue().get()).isSameInstanceAs(queue);
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 6: liveRequestQueue returns empty Optional when null is passed
+ // to the live factory (liveRequestQueue is Optional.ofNullable)
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("boundary")
+ void liveRequestQueueReturnsEmptyOptionalWhenNullPassedToLiveFactory() {
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, null, mockRunConfig);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 7: liveRequestQueue is preserved after copyOf
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueIsPreservedAfterCopyOf() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(queue)
+ .build();
+ InvocationContext copy = InvocationContext.copyOf(original);
+ assertThat(copy.liveRequestQueue()).isPresent();
+ assertThat(copy.liveRequestQueue().get()).isSameInstanceAs(queue);
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 8: liveRequestQueue empty Optional is preserved after copyOf
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueEmptyIsPreservedAfterCopyOf() {
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext copy = InvocationContext.copyOf(original);
+ assertThat(copy.liveRequestQueue()).isEmpty();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 9: liveRequestQueue getter returns consistent value on repeated calls
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void liveRequestQueueReturnsSameValueOnRepeatedCalls() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(queue)
+ .build();
+ Optional first = context.liveRequestQueue();
+ Optional second = context.liveRequestQueue();
+ assertThat(first).isEqualTo(second);
+ assertThat(first.get()).isSameInstanceAs(second.get());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 10: liveRequestQueue is empty Optional when set to Optional.empty()
+ // explicitly in builder
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("boundary")
+ void liveRequestQueueReturnsEmptyWhenBuilderSetToEmptyOptional() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(Optional.empty())
+ .build();
+ assertThat(context.liveRequestQueue()).isEmpty();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 11: equals() respects liveRequestQueue presence
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void equalsReturnsTrueWhenBothContextsHaveSameLiveRequestQueue() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(Optional.of(queue))
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(Optional.of(queue))
+ .build();
+ assertThat(context1).isEqualTo(context2);
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 12: equals() distinguishes contexts with and without liveRequestQueue
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void equalsReturnsFalseWhenOnlyOneContextHasLiveRequestQueue() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext contextWithQueue = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(Optional.of(queue))
+ .build();
+ InvocationContext contextWithoutQueue = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .build();
+ assertThat(contextWithQueue).isNotEqualTo(contextWithoutQueue);
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 13: hashCode is consistent between contexts with same liveRequestQueue
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ void hashCodeIsConsistentForContextsWithSameLiveRequestQueue() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(Optional.of(queue))
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("inv-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(Optional.of(queue))
+ .build();
+ assertThat(context1.hashCode()).isEqualTo(context2.hashCode());
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 14: liveRequestQueue is not null (always returns Optional, never null)
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("boundary")
+ void liveRequestQueueGetterNeverReturnsNull() {
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .build();
+ assertThat(context.liveRequestQueue()).isNotNull();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 15: liveRequestQueue with queue can send content
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("integration")
+ void liveRequestQueueCanSendContentWhenPresent() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ Content dummyContent = Content.newBuilder().build();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .invocationId("test-invocation-id")
+ .agent(mockAgent)
+ .session(mockSession)
+ .runConfig(mockRunConfig)
+ .liveRequestQueue(queue)
+ .build();
+ assertThat(context.liveRequestQueue()).isPresent();
+ LiveRequestQueue retrievedQueue = context.liveRequestQueue().get();
+ assertDoesNotThrow(() -> retrievedQueue.content(dummyContent));
+ assertThat(retrievedQueue).isNotNull();
+ }
+
+ // -------------------------------------------------------------------------
+ // Scenario 16: liveRequestQueue built via deprecated constructor reflects value
+ // -------------------------------------------------------------------------
+ @Test
+ @Tag("valid")
+ @SuppressWarnings("deprecation")
+ void liveRequestQueueReturnsPresentOptionalWhenCreatedViaDeprecatedConstructor() {
+ LiveRequestQueue queue = new LiveRequestQueue();
+ InvocationContext context = new InvocationContext(
+ mockSessionService,
+ mockArtifactService,
+ mockMemoryService,
+ mockPluginManager,
+ Optional.of(queue),
+ Optional.of("branch"),
+ "invocation-id",
+ mockAgent,
+ mockSession,
+ Optional.of(mockContent),
+ mockRunConfig,
+ false);
+ assertThat(context.liveRequestQueue()).isPresent();
+ assertThat(context.liveRequestQueue().get()).isSameInstanceAs(queue);
+ }
+
+// -------------------------------------------------------------------------
+// Scenario 17: liveRequestQueue empty Optional when deprecated constructor
+// receives empty Optional
+// -------------------------------------------------------------------------
+@Test
+ @Tag("boundary")
+ @SuppressWarnings("deprecation")
+ void liveRequestQueueReturnsEmptyOptionalWhenDeprecatedConstructorReceivesEmptyOptional() {
+ InvocationContext context = new InvocationContext(
+ mockSessionService,
+ mockArtifactService,
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextMemoryServiceTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextMemoryServiceTest.java
new file mode 100644
index 000000000..bb17975f2
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextMemoryServiceTest.java
@@ -0,0 +1,593 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=memoryService_1115878a43
+ROOST_METHOD_SIG_HASH=memoryService_b8500b83f5
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/AgentWithMemoryTest.java
+Tests:
+ "@Test
+public void agentRemembersUserNameWithMemoryTool() throws Exception {
+ String userId = "test-user";
+ String agentName = "test-agent";
+ Part functionCall = Part.builder().functionCall(FunctionCall.builder().name("loadMemory").args(ImmutableMap.of("query", "what is my name?")).build()).build();
+ TestLlm testLlm = new TestLlm(ImmutableList.of(LlmResponse.builder().content(Content.builder().parts(Part.fromText("OK, I'll remember that.")).role("model").build()).build(), LlmResponse.builder().content(Content.builder().role("model").parts(ImmutableList.of(functionCall)).build()).build(), LlmResponse.builder().content(Content.builder().
+
+ parts(Part.fromText("Your name is James.")).role("model").build()).build()));
+ LlmAgent agent = LlmAgent.builder().name(agentName).model(testLlm).tools(ImmutableList.of(new LoadMemoryTool())).build();
+ InMemoryRunner runner = new InMemoryRunner(agent);
+ String sessionId = runner.sessionService().createSession(agentName, userId).blockingGet().id();
+ Content firstMessage = Content.fromParts(Part.fromText("My name is James"));
+ var unused = runner.runAsync(userId, sessionId, firstMessage, RunConfig.builder().build()).toList().blockingGet();
+
+ Session updatedSession = runner.sessionService().getSession("test-agent", userId, sessionId, Optional.empty()).blockingGet();
+
+ runner.memoryService().addSessionToMemory(updatedSession).blockingAwait();
+ Content secondMessage = Content.fromParts(Part.fromText("what is my name?"));
+ unused = runner.runAsync(userId, updatedSession.id(), secondMessage, RunConfig.builder().build()).toList().blockingGet();
+
+ LlmRequest lastRequest = testLlm.getLastRequest();
+ Content functionResponseContent = Iterables.getLast(lastRequest.contents());
+ Optional functionResponsePart = functionResponseContent.parts().get().stream().filter(p -> p.functionResponse().isPresent()).findFirst();
+ assertThat(functionResponsePart).isPresent();
+ FunctionResponse functionResponse = functionResponsePart.get().functionResponse().get();
+ assertThat(functionResponse.name()).hasValue("loadMemory");
+ assertThat(functionResponse.response().get().toString()).contains("My name is James");
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCreateWithUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCreateWithNullUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.userContent()).isEmpty();
+}
+"
+ "@Test
+public void testCreateWithLiveRequestQueue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).hasValue(liveRequestQueue);
+
+ assertThat(context.invocationId()).startsWith("e-");
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).isEmpty();
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"
+ "@Test
+public void testGetters() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testSetAgent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ BaseAgent newMockAgent = mock(BaseAgent.class);
+ context.agent(newMockAgent);
+ assertThat(context.agent()).isEqualTo(newMockAgent);
+}
+"
+ "@Test
+public void testEquals_sameObject() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(context)).isTrue();
+}
+"
+ "@Test
+public void testEquals_null() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(null)).isFalse();
+}
+"
+ "@Test
+public void testEquals_sameValues() {
+ InvocationContext context1 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext context2 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context1.equals(context2)).isTrue();
+
+ assertThat(context2.equals(context1)).isTrue();
+}
+"
+ "@Test
+public void testEquals_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffAgent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(
+ mock(BaseAgent.class)).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithUserContentEmpty = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithLiveQueuePresent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(contextWithDiffSessionService)).isFalse();
+ assertThat(context.equals(contextWithDiffInvocationId)).isFalse();
+ assertThat(context.equals(contextWithDiffAgent)).isFalse();
+ assertThat(context.equals(contextWithUserContentEmpty)).isFalse();
+ assertThat(context.equals(contextWithLiveQueuePresent)).isFalse();
+}
+"
+ "@Test
+public void testHashCode_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotEqualTo(contextWithDiffSessionService);
+ assertThat(context).isNotEqualTo(contextWithDiffInvocationId);
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ assertThat(context.isResumable()).isFalse();
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsResumable_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ assertThat(context.isResumable()).isTrue();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoLongRunningToolIds_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoFunctionCalls_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoMatchingFunctionCallId_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc2"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndMatchingFunctionCallId_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isTrue();
+}
+"Scenario 1: Return the Memory Service Instance When Set with a Valid Mock
+
+Details:
+ TestName: memoryServiceReturnsCorrectInstanceWhenSetWithMock
+ Description: Verifies that the memoryService() method returns the exact same BaseMemoryService instance
+ that was provided during the construction of the InvocationContext via the builder.
+Execution:
+ Arrange: Create a mock instance of BaseMemoryService. Build an InvocationContext using the builder,
+ providing the mock memory service, along with the required sessionService, artifactService,
+ agent, and session fields.
+ Act: Call memoryService() on the built InvocationContext instance.
+ Assert: Assert that the returned value is equal to (and the same instance as) the mock
+ BaseMemoryService that was set during construction.
+Validation:
+ This test ensures that the getter correctly returns the field value set at construction time without
+ any transformation or modification. It is fundamental to confirm that the internal field assignment
+ in the constructor works correctly and the getter exposes it properly.
+
+*/
+
+// ********RoostGPT********
+
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextMemoryServiceTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private RunConfig mockRunConfig;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private ResumabilityConfig mockResumabilityConfig;
+
+ @BeforeEach
+ void setUp() {
+ when(mockSession.appName()).thenReturn("testApp");
+ when(mockSession.userId()).thenReturn("testUser");
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceReturnsCorrectInstanceWhenSetWithMock() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseMemoryService result = context.memoryService();
+ // Assert
+ assertSame(mockMemoryService, result);
+ assertEquals(mockMemoryService, result);
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceReturnsNullWhenNotSet() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseMemoryService result = context.memoryService();
+ // Assert
+ assertNull(result);
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceReturnsSameReferenceAfterMultipleCalls() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseMemoryService firstCall = context.memoryService();
+ BaseMemoryService secondCall = context.memoryService();
+ BaseMemoryService thirdCall = context.memoryService();
+ // Assert
+ assertSame(firstCall, secondCall);
+ assertSame(secondCall, thirdCall);
+ assertSame(mockMemoryService, firstCall);
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceReturnsDifferentInstancesForDifferentContexts() {
+ // Arrange
+ BaseMemoryService mockMemoryService1 = mock(BaseMemoryService.class);
+ BaseMemoryService mockMemoryService2 = mock(BaseMemoryService.class);
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService1)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("invocation-id-1")
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService2)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("invocation-id-2")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseMemoryService result1 = context1.memoryService();
+ BaseMemoryService result2 = context2.memoryService();
+ // Assert
+ assertSame(mockMemoryService1, result1);
+ assertSame(mockMemoryService2, result2);
+ assertNotSame(result1, result2);
+ }
+
+ @Test
+ @Tag("integration")
+ void memoryServicePreservedAfterCopyOf() {
+ // Arrange
+ InvocationContext originalContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ // Assert
+ assertSame(mockMemoryService, copiedContext.memoryService());
+ assertEquals(originalContext.memoryService(), copiedContext.memoryService());
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceReturnedFromContextCreatedViaStaticFactory() {
+ // Arrange
+ Content userContent = Content.fromParts();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ "test-invocation-id", mockAgent, mockSession, userContent, mockRunConfig);
+ // Act
+ BaseMemoryService result = context.memoryService();
+ // Assert
+ // When using the static factory create(), memoryService is not set, so it should
+ // be null
+ assertNull(result);
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceSetViaBuilderReturnedCorrectly() {
+ // Arrange
+ BaseMemoryService specificMemoryService = mock(BaseMemoryService.class);
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(specificMemoryService)
+ .pluginManager(mockPluginManager)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("detailed-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseMemoryService result = context.memoryService();
+ // Assert
+ assertNotNull(result);
+ assertSame(specificMemoryService, result);
+ }
+
+ @Test
+ @Tag("boundary")
+ void memoryServiceNullWhenCopyOfContextWithNoMemoryService() {
+ // Arrange
+ InvocationContext originalContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ // Assert
+ assertNull(originalContext.memoryService());
+ assertNull(copiedContext.memoryService());
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceReturnedCorrectlyWithAllFieldsSet() {
+ // Arrange
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .liveRequestQueue(Optional.of(liveRequestQueue))
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("full-invocation-id")
+ .runConfig(mockRunConfig)
+ .branch("test-branch")
+ .build();
+ // Act
+ BaseMemoryService result = context.memoryService();
+ // Assert
+ assertNotNull(result);
+ assertSame(mockMemoryService, result);
+ }
+
+ @Test
+ @Tag("integration")
+ void memoryServiceUnchangedAfterModifyingOtherFields() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act: Modify other fields that have setters
+ context.branch("new-branch");
+ context.setEndInvocation(true);
+ BaseAgent anotherAgent = mock(BaseAgent.class);
+ context.agent(anotherAgent);
+ BaseMemoryService result = context.memoryService();
+ // Assert
+ assertSame(mockMemoryService, result);
+ }
+
+ @Test
+ @Tag("valid")
+ void memoryServiceNotInteractedWithDuringRetrieval() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ context.memoryService();
+ // Assert: The memory service mock should have had no interactions when just
+ // retrieved
+ verifyNoInteractions(mockMemoryService);
+ }
+
+ @Test
+ @Tag("integration")
+ void memoryServiceConsistentBetweenOriginalAndCopiedContext() {
+ // Arrange
+ InvocationContext originalContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("test-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ // Act
+ BaseMemoryService originalMemoryService = originalContext.memoryService();
+ BaseMemoryService copiedMemoryService = copiedContext.memoryService();
+ // Assert
+ assertSame(originalMemoryService, copiedMemoryService);
+ assertSame(mockMemoryService, originalMemoryService);
+ assertSame(mockMemoryService, copiedMemoryService);
+ }
+
+ @Test
+ @Tag("boundary")
+ void memoryServiceWithDeprecatedConstructorReturnsCorrectInstance() {
+ // Arrange
+ String invocationId = "deprecated-constructor-invocation-id";
+ @SuppressWarnings("deprecation")
+ InvocationContext context = new InvocationContext(mockSessionService, mockArtifactService, mockMemoryService,
+ mockPluginManager, Optional.empty(), Optional.empty(), invocationId, mockAgent, mockSession,
+ Optional.empty(), mockRunConfig, false);
+ // Act
+ BaseMemoryService result = context.memoryService();
+ // Assert
+ assertNotNull(result);
+ assertSame(mockMemoryService, result);
+ }
+
+}
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextPluginManagerTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextPluginManagerTest.java
new file mode 100644
index 000000000..e85c06d31
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextPluginManagerTest.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=pluginManager_009a0b1a05
+ROOST_METHOD_SIG_HASH=pluginManager_3452d016c7
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCreateWithUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCreateWithNullUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.userContent()).isEmpty();
+}
+"
+ "@Test
+public void testCreateWithLiveRequestQueue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).hasValue(liveRequestQueue);
+
+ assertThat(context.invocationId()).startsWith("e-");
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).isEmpty();
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"
+ "@Test
+public void testGetters() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testSetAgent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ BaseAgent newMockAgent = mock(BaseAgent.class);
+ context.agent(newMockAgent);
+ assertThat(context.agent()).isEqualTo(newMockAgent);
+}
+"
+ "@Test
+public void testEquals_sameObject() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(context)).isTrue();
+}
+"
+ "@Test
+public void testEquals_null() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(null)).isFalse();
+}
+"
+ "@Test
+public void testEquals_sameValues() {
+ InvocationContext context1 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext context2 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context1.equals(context2)).isTrue();
+
+ assertThat(context2.equals(context1)).isTrue();
+}
+"
+ "@Test
+public void testEquals_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffAgent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(
+ mock(BaseAgent.class)).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithUserContentEmpty = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithLiveQueuePresent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(contextWithDiffSessionService)).isFalse();
+ assertThat(context.equals(contextWithDiffInvocationId)).isFalse();
+ assertThat(context.equals(contextWithDiffAgent)).isFalse();
+ assertThat(context.equals(contextWithUserContentEmpty)).isFalse();
+ assertThat(context.equals(contextWithLiveQueuePresent)).isFalse();
+}
+"
+ "@Test
+public void testHashCode_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotEqualTo(contextWithDiffSessionService);
+ assertThat(context).isNotEqualTo(contextWithDiffInvocationId);
+}
+"Scenario 1: Verify that pluginManager() returns the exact PluginManager instance set during construction via builder
+
+Details:
+ TestName: pluginManagerReturnsExplicitlySetPluginManagerInstance
+ Description: This test verifies that when an explicit PluginManager instance is provided to the builder, the pluginManager() method returns that exact same instance without any modification or wrapping.
+
+Execution:
+ Arrange:
+ - Create a new PluginManager instance (e.g., explicitPluginManager = new PluginManager()).
+ - Build an InvocationContext using the builder, supplying all required fields (sessionService, artifactService, memoryService, agent, session, runConfig) and set pluginManager to explicitPluginManager.
+ Act:
+ - Call context.pluginManager() on the constructed InvocationContext.
+ Assert:
+ - Assert that the returned value is the same instance as explicitPluginManager using assertThat(context.pluginManager()).isSameInstanceAs(explicitPluginManager).
+
+Validation:
+ This assertion confirms that pluginManager() is a straightforward accessor returning the stored reference without any transformation. This is critical because consumers of the plugin system expect to operate on the same PluginManager instance they configured, ensuring consistent behavior across the invocation lifecycle.
+
+
+Scenario 2: Verify that pluginManager() returns the default PluginManager when none is explicitly provided to the builder
+
+Details:
+ TestName: pluginManagerReturnsDefaultPluginManagerWhenNotExplicitlySet
+ Description: This test verifies that when no pluginManager is explicitly supplied to the builder, the builder uses a default-constructed PluginManager and the pluginManager() method returns a non-null instance.
+
+Execution:
+ Arrange:
+ - Build an InvocationContext using the builder without calling .pluginManager(...), providing only the minimum required fields (sessionService, artifactService, agent, session, userContent, runConfig).
+ Act:
+ - Call context.pluginManager() on the constructed InvocationContext.
+ Assert:
+ - Assert that the returned PluginManager is not null using assertThat(context.pluginManager()).isNotNull().
+
+Validation:
+ The builder initializes pluginManager to new PluginManager() by default. This scenario confirms that the default initialization works correctly and that pluginManager() never returns null even when the caller does not explicitly configure one, preventing NullPointerExceptions in downstream plugin-dependent logic.
+
+
+Scenario 3: Verify that pluginManager() returns a non-null value when a custom PluginManager is set
+
+Details:
+ TestName: pluginManagerIsNotNullWhenCustomInstanceIsProvided
+ Description: This test verifies that the result of pluginManager() is always non-null when a valid PluginManager is passed through the builder.
+
+Execution:
+ Arrange:
+ - Instantiate a PluginManager (e.g., customPluginManager = new PluginManager()).
+ - Build an InvocationContext supplying all required fields and .pluginManager(customPluginManager).
+ Act:
+ - Call context.pluginManager().
+ Assert:
+ - Assert that the returned value is not null: assertThat(context.pluginManager()).isNotNull().
+
+Validation:
+ This ensures a basic contract: any explicitly set PluginManager is preserved and accessible. Non-null guarantees are fundamental for any code that relies on pluginManager() to register or query plugins during an agent invocation.
+
+
+Scenario 4: Verify that pluginManager() returns the correct PluginManager after a copyOf operation
+
+Details:
+ TestName: pluginManagerIsPreservedAfterCopyOf
+ Description: This test verifies that after creating a shallow copy of an InvocationContext using InvocationContext.copyOf(), the pluginManager() on the copied context returns the same PluginManager instance as the original.
+
+Execution:
+ Arrange:
+ - Create a PluginManager instance (e.g., originalPluginManager = new PluginManager()).
+ - Build an original InvocationContext with the above PluginManager and all required fields.
+ - Call InvocationContext.copyOf(originalContext) to produce a copiedContext.
+ Act:
+ - Call copiedContext.pluginManager().
+ Assert:
+ - Assert that copiedContext.pluginManager() returns the same instance as originalContext.pluginManager() using assertThat(copiedContext.pluginManager()).isSameInstanceAs(originalContext.pluginManager()).
+
+Validation:
+ The copyOf() method performs a shallow copy, meaning the PluginManager reference should not be duplicated. This test confirms that plugin state is shared correctly between original and copied contexts, which is important in agent delegation and sub-agent invocation scenarios where the same plugin registry should be accessible.
+
+
+Scenario 5: Verify that two independently built InvocationContext instances with different PluginManager instances return their respective PluginManager objects
+
+Details:
+ TestName: pluginManagerReturnsDifferentInstancesForDifferentContexts
+ Description: This test verifies that two separate InvocationContext instances built with different PluginManager instances each independently return their own PluginManager through pluginManager(), with no cross-contamination.
+
+Execution:
+ Arrange:
+ - Create two distinct PluginManager instances: pluginManager1 = new PluginManager() and pluginManager2 = new PluginManager().
+ - Build context1 with pluginManager1 and all required fields.
+ - Build context2 with pluginManager2 and all required fields (same other parameters).
+ Act:
+ - Call context1.pluginManager() and context2.pluginManager().
+ Assert:
+ - Assert that context1.pluginManager() is the same instance as pluginManager1.
+ - Assert that context2.pluginManager() is the same instance as pluginManager2.
+ - Assert that context1.pluginManager() is not the same instance as context2.pluginManager().
+
+Validation:
+ This scenario ensures that PluginManager instances are correctly scoped to their owning InvocationContext. If two invocations share or bleed plugin state, it could lead to interference between different agent runs. Confirming isolation here is important for correctness in multi-invocation or concurrent scenarios.
+
+
+Scenario 6: Verify that pluginManager() participates correctly in equals() comparison when PluginManagers are different
+
+Details:
+ TestName: pluginManagerInequalityReflectedInContextEquality
+ Description: This test verifies that two InvocationContext instances built with different PluginManager instances are not considered equal, demonstrating that pluginManager() value participates in the equals() logic of InvocationContext.
+
+Execution:
+ Arrange:
+ - Create two distinct PluginManager instances: pluginManagerA = new PluginManager() and pluginManagerB = new PluginManager().
+ - Build contextA using pluginManagerA with all identical required fields.
+ - Build contextB using pluginManagerB with all identical required fields.
+ Act:
+ - Call contextA.equals(contextB).
+ Assert:
+ - Assert that contextA.equals(contextB) is false: assertThat(contextA.equals(contextB)).isFalse().
+
+Validation:
+ The equals() method of InvocationContext includes pluginManager in its comparison. This test confirms that differing PluginManager instances cause two otherwise identical contexts to be unequal, ensuring that the field is properly considered in identity and comparison operations used throughout the framework.
+
+
+Scenario 7: Verify that pluginManager() participates correctly in equals() when the same PluginManager instance is shared
+
+Details:
+ TestName: pluginManagerEqualityReflectedInContextEquality
+ Description: This test verifies that two InvocationContext instances built with the same PluginManager instance (and all other identical fields) are considered equal, demonstrating consistent pluginManager equality behavior.
+
+Execution:
+ Arrange:
+ - Create a single PluginManager instance: sharedPluginManager = new PluginManager().
+ - Build contextX with sharedPluginManager and all required fields (specific, fixed invocationId).
+ - Build contextY with the same sharedPluginManager and the same required fields.
+ Act:
+ - Call contextX.equals(contextY).
+ Assert:
+ - Assert that contextX.equals(contextY) is true: assertThat(contextX.equals(contextY)).isTrue().
+
+Validation:
+ This ensures that the pluginManager field does not introduce spurious inequality when the same instance is shared. This is significant in scenarios where a single PluginManager is used across multiple contexts (e.g., in sub-agent delegation), and correct equality checks depend on this consistency.
+
+
+Scenario 8: Verify that pluginManager() is consistent across multiple successive calls on the same InvocationContext
+
+Details:
+ TestName: pluginManagerReturnsSameInstanceOnRepeatedCalls
+ Description: This test verifies that calling pluginManager() multiple times on the same InvocationContext always returns the exact same PluginManager instance, confirming the method is idempotent and referentially stable.
+
+Execution:
+ Arrange:
+ - Create a PluginManager instance: stablePluginManager = new PluginManager().
+ - Build an InvocationContext with stablePluginManager and all required fields.
+ Act:
+ - Call context.pluginManager() three times, storing each result (result1, result2, result3).
+ Assert:
+ - Assert that result1, result2, and result3 are all the same instance as stablePluginManager.
+ - Assert that result1 == result2 == result3 using isSameInstanceAs().
+
+Validation:
+ Idempotency of accessor methods is a fundamental contract in Java. Since pluginManager is a final field with no mutation path, successive calls must return the same reference. This test guards against accidental wrapping, lazy initialization errors, or any future refactoring that could break referential stability.
+
+*/
+
+// ********RoostGPT********
+
+package com.google.adk.agents;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.genai.types.Content;
+import java.util.Optional;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextPluginManagerTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ private RunConfig defaultRunConfig;
+
+ private static final String FIXED_INVOCATION_ID = "e-test-invocation-id";
+
+ @BeforeEach
+ void setUp() {
+ defaultRunConfig = RunConfig.builder().build();
+ }
+
+ private InvocationContext.Builder buildBaseContext() {
+ return InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(FIXED_INVOCATION_ID)
+ .runConfig(defaultRunConfig);
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerReturnsExplicitlySetPluginManagerInstance() {
+ // Arrange
+ PluginManager explicitPluginManager = new PluginManager();
+ InvocationContext context = buildBaseContext().pluginManager(explicitPluginManager).build();
+ // Act
+ PluginManager result = context.pluginManager();
+ // Assert
+ assertThat(result).isSameInstanceAs(explicitPluginManager);
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerReturnsDefaultPluginManagerWhenNotExplicitlySet() {
+ // Arrange
+ InvocationContext context = buildBaseContext().build();
+ // Act
+ PluginManager result = context.pluginManager();
+ // Assert
+ assertThat(result).isNotNull();
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerIsNotNullWhenCustomInstanceIsProvided() {
+ // Arrange
+ PluginManager customPluginManager = new PluginManager();
+ InvocationContext context = buildBaseContext().pluginManager(customPluginManager).build();
+ // Act
+ PluginManager result = context.pluginManager();
+ // Assert
+ assertThat(result).isNotNull();
+ }
+
+ @Test
+ @Tag("integration")
+ void pluginManagerIsPreservedAfterCopyOf() {
+ // Arrange
+ PluginManager originalPluginManager = new PluginManager();
+ InvocationContext originalContext = buildBaseContext().pluginManager(originalPluginManager).build();
+ // Act
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ // Assert
+ assertThat(copiedContext.pluginManager()).isSameInstanceAs(originalContext.pluginManager());
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerReturnsDifferentInstancesForDifferentContexts() {
+ // Arrange
+ PluginManager pluginManager1 = new PluginManager();
+ PluginManager pluginManager2 = new PluginManager();
+ InvocationContext context1 = buildBaseContext().pluginManager(pluginManager1)
+ .invocationId("e-invocation-1")
+ .build();
+ InvocationContext context2 = buildBaseContext().pluginManager(pluginManager2)
+ .invocationId("e-invocation-2")
+ .build();
+ // Act
+ PluginManager result1 = context1.pluginManager();
+ PluginManager result2 = context2.pluginManager();
+ // Assert
+ assertThat(result1).isSameInstanceAs(pluginManager1);
+ assertThat(result2).isSameInstanceAs(pluginManager2);
+ assertThat(result1).isNotSameInstanceAs(result2);
+ }
+
+ @Test
+ @Tag("invalid")
+ void pluginManagerInequalityReflectedInContextEquality() {
+ // Arrange
+ PluginManager pluginManagerA = new PluginManager();
+ PluginManager pluginManagerB = new PluginManager();
+ InvocationContext contextA = buildBaseContext().pluginManager(pluginManagerA).build();
+ InvocationContext contextB = buildBaseContext().pluginManager(pluginManagerB).build();
+ // Act & Assert
+ assertThat(contextA.equals(contextB)).isFalse();
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerEqualityReflectedInContextEquality() {
+ // Arrange
+ PluginManager sharedPluginManager = new PluginManager();
+ InvocationContext contextX = buildBaseContext().pluginManager(sharedPluginManager)
+ .invocationId(FIXED_INVOCATION_ID)
+ .build();
+ InvocationContext contextY = buildBaseContext().pluginManager(sharedPluginManager)
+ .invocationId(FIXED_INVOCATION_ID)
+ .build();
+ // Act & Assert
+ assertThat(contextX.equals(contextY)).isTrue();
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerReturnsSameInstanceOnRepeatedCalls() {
+ // Arrange
+ PluginManager stablePluginManager = new PluginManager();
+ InvocationContext context = buildBaseContext().pluginManager(stablePluginManager).build();
+ // Act
+ PluginManager result1 = context.pluginManager();
+ PluginManager result2 = context.pluginManager();
+ PluginManager result3 = context.pluginManager();
+ // Assert
+ assertThat(result1).isSameInstanceAs(stablePluginManager);
+ assertThat(result2).isSameInstanceAs(stablePluginManager);
+ assertThat(result3).isSameInstanceAs(stablePluginManager);
+ assertThat(result1).isSameInstanceAs(result2);
+ assertThat(result2).isSameInstanceAs(result3);
+ }
+
+ @Test
+ @Tag("boundary")
+ void pluginManagerIsNotNullWhenContextCreatedWithStaticCreateMethod() {
+ // Arrange
+ Content userContent = Content.newBuilder().build();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ FIXED_INVOCATION_ID, mockAgent, mockSession, userContent, defaultRunConfig);
+ // Act
+ PluginManager result = context.pluginManager();
+ // Assert
+ assertThat(result).isNotNull();
+ }
+
+ @Test
+ @Tag("boundary")
+ void pluginManagerIsNotNullWhenContextCreatedWithLiveRequestQueue() {
+ // Arrange
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, liveRequestQueue, defaultRunConfig);
+ // Act
+ PluginManager result = context.pluginManager();
+ // Assert
+ assertThat(result).isNotNull();
+ }
+
+ @Test
+ @Tag("integration")
+ void pluginManagerIsPreservedAfterCopyOfWithNullUserContent() {
+ // Arrange
+ PluginManager originalPluginManager = new PluginManager();
+ InvocationContext originalContext = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(originalPluginManager)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(FIXED_INVOCATION_ID)
+ .userContent(Optional.empty())
+ .runConfig(defaultRunConfig)
+ .build();
+ // Act
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ PluginManager result = copiedContext.pluginManager();
+ // Assert
+ assertThat(result).isSameInstanceAs(originalPluginManager);
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerHashCodeIsConsistentWithSameInstance() {
+ // Arrange
+ PluginManager sharedPluginManager = new PluginManager();
+ InvocationContext contextA = buildBaseContext().pluginManager(sharedPluginManager)
+ .invocationId(FIXED_INVOCATION_ID)
+ .build();
+ InvocationContext contextB = buildBaseContext().pluginManager(sharedPluginManager)
+ .invocationId(FIXED_INVOCATION_ID)
+ .build();
+ // Act & Assert
+ assertThat(contextA.hashCode()).isEqualTo(contextB.hashCode());
+ }
+
+ @Test
+ @Tag("valid")
+ void pluginManagerInstanceIsIndependentFromMemoryAndArtifactServices() {
+ // Arrange
+ PluginManager explicitPluginManager = new PluginManager();
+ InvocationContext context = buildBaseContext().pluginManager(explicitPluginManager).build();
+ // Act
+ PluginManager pluginManagerResult = context.pluginManager();
+ BaseMemoryService memoryServiceResult = context.memoryService();
+ BaseArtifactService artifactServiceResult = context.artifactService();
+ // Assert
+ assertThat(pluginManagerResult).isSameInstanceAs(explicitPluginManager);
+ assertThat(pluginManagerResult).isNotSameInstanceAs(memoryServiceResult);
+ assertThat(pluginManagerResult).isNotSameInstanceAs(artifactServiceResult);
+ }
+
+ @Test
+ @Tag("boundary")
+ void pluginManagerDefaultInstanceIsCreatedWhenBuilderHasNoPluginManagerSet() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(FIXED_INVOCATION_ID)
+ .runConfig(defaultRunConfig)
+ .build();
+ // Act
+ PluginManager result = context.pluginManager();
+ // Assert
+ assertThat(result).isNotNull();
+ assertThat(result).isInstanceOf(PluginManager.class);
+ }
+
+}
diff --git a/core/src/test/java/com/google/adk/agents/InvocationContextSessionServiceTest.java b/core/src/test/java/com/google/adk/agents/InvocationContextSessionServiceTest.java
new file mode 100644
index 000000000..8e36a3beb
--- /dev/null
+++ b/core/src/test/java/com/google/adk/agents/InvocationContextSessionServiceTest.java
@@ -0,0 +1,668 @@
+/*
+ * Copyright 2025 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.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test june-java-unit using AI Type AWS Bedrock Runtime AI and AI Model global.anthropic.claude-sonnet-4-6
+
+ROOST_METHOD_HASH=sessionService_c04b1de6f8
+ROOST_METHOD_SIG_HASH=sessionService_1fa67a6550
+
+Here are your existing test cases which we found out and are not considered for test generation:
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/AgentWithMemoryTest.java
+Tests:
+ "@Test
+public void agentRemembersUserNameWithMemoryTool() throws Exception {
+ String userId = "test-user";
+ String agentName = "test-agent";
+ Part functionCall = Part.builder().functionCall(FunctionCall.builder().name("loadMemory").args(ImmutableMap.of("query", "what is my name?")).build()).build();
+ TestLlm testLlm = new TestLlm(ImmutableList.of(LlmResponse.builder().content(Content.builder().parts(Part.fromText("OK, I'll remember that.")).role("model").build()).build(), LlmResponse.builder().content(Content.builder().role("model").parts(ImmutableList.of(functionCall)).build()).build(), LlmResponse.builder().content(Content.builder().
+
+ parts(Part.fromText("Your name is James.")).role("model").build()).build()));
+ LlmAgent agent = LlmAgent.builder().name(agentName).model(testLlm).tools(ImmutableList.of(new LoadMemoryTool())).build();
+ InMemoryRunner runner = new InMemoryRunner(agent);
+ String sessionId = runner.sessionService().createSession(agentName, userId).blockingGet().id();
+ Content firstMessage = Content.fromParts(Part.fromText("My name is James"));
+ var unused = runner.runAsync(userId, sessionId, firstMessage, RunConfig.builder().build()).toList().blockingGet();
+
+ Session updatedSession = runner.sessionService().getSession("test-agent", userId, sessionId, Optional.empty()).blockingGet();
+
+ runner.memoryService().addSessionToMemory(updatedSession).blockingAwait();
+ Content secondMessage = Content.fromParts(Part.fromText("what is my name?"));
+ unused = runner.runAsync(userId, updatedSession.id(), secondMessage, RunConfig.builder().build()).toList().blockingGet();
+
+ LlmRequest lastRequest = testLlm.getLastRequest();
+ Content functionResponseContent = Iterables.getLast(lastRequest.contents());
+ Optional functionResponsePart = functionResponseContent.parts().get().stream().filter(p -> p.functionResponse().isPresent()).findFirst();
+ assertThat(functionResponsePart).isPresent();
+ FunctionResponse functionResponse = functionResponsePart.get().functionResponse().get();
+ assertThat(functionResponse.name()).hasValue("loadMemory");
+ assertThat(functionResponse.response().get().toString()).contains("My name is James");
+}
+"
+
+File Path: /var/tmp/Roost/RoostGPT/june-java-unit/1782282926/source/adk-java/core/src/test/java/com/google/adk/agents/InvocationContextTest.java
+Tests:
+ "@Test
+public void testCreateWithUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCreateWithNullUserContent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.userContent()).isEmpty();
+}
+"
+ "@Test
+public void testCreateWithLiveRequestQueue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotNull();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).hasValue(liveRequestQueue);
+
+ assertThat(context.invocationId()).startsWith("e-");
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).isEmpty();
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testCopyOf() {
+ InvocationContext originalContext = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ originalContext.activeStreamingTools().putAll(activeStreamingTools);
+ InvocationContext copiedContext = InvocationContext.copyOf(originalContext);
+ assertThat(copiedContext).isNotNull();
+ assertThat(copiedContext).isNotSameInstanceAs(originalContext);
+ assertThat(copiedContext.sessionService()).isEqualTo(originalContext.sessionService());
+ assertThat(copiedContext.artifactService()).isEqualTo(originalContext.artifactService());
+ assertThat(copiedContext.memoryService()).isEqualTo(originalContext.memoryService());
+ assertThat(copiedContext.liveRequestQueue()).isEqualTo(originalContext.liveRequestQueue());
+ assertThat(copiedContext.invocationId()).isEqualTo(originalContext.invocationId());
+ assertThat(copiedContext.agent()).isEqualTo(originalContext.agent());
+ assertThat(copiedContext.session()).isEqualTo(originalContext.session());
+ assertThat(copiedContext.userContent()).isEqualTo(originalContext.userContent());
+ assertThat(copiedContext.runConfig()).isEqualTo(originalContext.runConfig());
+ assertThat(copiedContext.endInvocation()).isEqualTo(originalContext.endInvocation());
+ assertThat(copiedContext.activeStreamingTools()).isEqualTo(originalContext.activeStreamingTools());
+}
+"
+ "@Test
+public void testGetters() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.sessionService()).isEqualTo(mockSessionService);
+ assertThat(context.artifactService()).isEqualTo(mockArtifactService);
+ assertThat(context.memoryService()).isEqualTo(mockMemoryService);
+ assertThat(context.liveRequestQueue()).isEmpty();
+ assertThat(context.invocationId()).isEqualTo(testInvocationId);
+ assertThat(context.agent()).isEqualTo(mockAgent);
+ assertThat(context.session()).isEqualTo(session);
+ assertThat(context.userContent()).hasValue(userContent);
+ assertThat(context.runConfig()).isEqualTo(runConfig);
+ assertThat(context.endInvocation()).isFalse();
+}
+"
+ "@Test
+public void testSetAgent() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ BaseAgent newMockAgent = mock(BaseAgent.class);
+ context.agent(newMockAgent);
+ assertThat(context.agent()).isEqualTo(newMockAgent);
+}
+"
+ "@Test
+public void testEquals_sameObject() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(context)).isTrue();
+}
+"
+ "@Test
+public void testEquals_null() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(null)).isFalse();
+}
+"
+ "@Test
+public void testEquals_sameValues() {
+ InvocationContext context1 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext context2 = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context1.equals(context2)).isTrue();
+
+ assertThat(context2.equals(context1)).isTrue();
+}
+"
+ "@Test
+public void testEquals_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffAgent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(
+ mock(BaseAgent.class)).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithUserContentEmpty = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithLiveQueuePresent = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).liveRequestQueue(liveRequestQueue).agent(mockAgent).session(session).userContent(Optional.empty()).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context.equals(contextWithDiffSessionService)).isFalse();
+ assertThat(context.equals(contextWithDiffInvocationId)).isFalse();
+ assertThat(context.equals(contextWithDiffAgent)).isFalse();
+ assertThat(context.equals(contextWithUserContentEmpty)).isFalse();
+ assertThat(context.equals(contextWithLiveQueuePresent)).isFalse();
+}
+"
+ "@Test
+public void testHashCode_differentValues() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+
+ InvocationContext contextWithDiffSessionService = InvocationContext.builder().sessionService(
+ mock(BaseSessionService.class)).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(testInvocationId).agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ InvocationContext contextWithDiffInvocationId = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).pluginManager(pluginManager).invocationId(
+ "another-id").agent(mockAgent).session(session).userContent(Optional.of(userContent)).runConfig(runConfig).endInvocation(false).build();
+ assertThat(context).isNotEqualTo(contextWithDiffSessionService);
+ assertThat(context).isNotEqualTo(contextWithDiffInvocationId);
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ assertThat(context.isResumable()).isFalse();
+}
+"
+ "@Test
+public void isResumable_whenResumabilityConfigIsResumable_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ assertThat(context.isResumable()).isTrue();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenNotResumable_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(false)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoLongRunningToolIds_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoFunctionCalls_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndNoMatchingFunctionCallId_isFalse() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc2"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isFalse();
+}
+"
+ "@Test
+public void shouldPauseInvocation_whenResumableAndMatchingFunctionCallId_isTrue() {
+ InvocationContext context = InvocationContext.builder().sessionService(mockSessionService).artifactService(mockArtifactService).memoryService(mockMemoryService).agent(mockAgent).session(session).resumabilityConfig(new ResumabilityConfig(true)).build();
+ Event event = Event.builder().longRunningToolIds(Optional.of(ImmutableSet.of("fc1"))).content(Content.builder().parts(ImmutableList.of(Part.builder().functionCall(FunctionCall.builder().name("tool1").id("fc1").build()).build())).build()).build();
+ assertThat(context.shouldPauseInvocation(event)).isTrue();
+}
+"Scenario 1: Session Service Returns the Correctly Injected Instance
+
+Details:
+ TestName: sessionServiceReturnsInjectedInstance
+ Description: Verifies that the sessionService() method returns the exact same BaseSessionService
+ instance that was provided during the construction of InvocationContext via the builder.
+ This validates that the internal field is properly assigned and retrieved without
+ modification.
+Execution:
+ Arrange: Create a mock of BaseSessionService. Build an InvocationContext using the builder,
+ providing the mock as the sessionService, along with the other required fields
+ (artifactService, memoryService, agent, session).
+ Act: Call sessionService() on the constructed InvocationContext instance.
+ Assert: Assert that the returned value is the same instance (reference equality) as the mock
+ BaseSessionService provided during construction.
+Validation:
+ The assertion verifies that sessionService() performs a direct field return without any
+ transformation or wrapping. This is critical because other components (e.g., memory tools,
+ artifact handlers) depend on receiving the exact service instance to perform operations like
+ session creation, retrieval, and update.
+
+*/
+
+// ********RoostGPT********
+
+```java
+package com.google.adk.agents;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.events.Event;
+import com.google.adk.flows.llmflows.ResumabilityConfig;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.models.LlmCallsLimitExceededException;
+import com.google.adk.plugins.PluginManager;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.Session;
+import com.google.common.collect.ImmutableSet;
+import com.google.genai.types.Content;
+import com.google.genai.types.FunctionCall;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.junit.jupiter.api.*;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@ExtendWith(MockitoExtension.class)
+public class InvocationContextSessionServiceTest {
+
+ @Mock
+ private BaseSessionService mockSessionService;
+
+ @Mock
+ private BaseArtifactService mockArtifactService;
+
+ @Mock
+ private BaseMemoryService mockMemoryService;
+
+ @Mock
+ private BaseAgent mockAgent;
+
+ @Mock
+ private Session mockSession;
+
+ @Mock
+ private PluginManager mockPluginManager;
+
+ @Mock
+ private RunConfig mockRunConfig;
+
+ private static final String DUMMY_INVOCATION_ID = "e-test-invocation-id-12345";
+
+ private static final String DUMMY_APP_NAME = "testApp";
+
+ private static final String DUMMY_USER_ID = "testUser";
+
+ private static final String DUMMY_SESSION_ID = "testSession";
+
+ @BeforeEach
+ void setUp() {
+ lenient().when(mockSession.appName()).thenReturn(DUMMY_APP_NAME);
+ lenient().when(mockSession.userId()).thenReturn(DUMMY_USER_ID);
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceReturnsInjectedInstance() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertSame(mockSessionService, result,
+ "sessionService() should return the exact same instance provided during construction");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceReturnsNullWhenNotSet() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertNull(result, "sessionService() should return null when no sessionService was provided");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceReturnsSameReferenceAfterCopyOf() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ InvocationContext copy = InvocationContext.copyOf(original);
+ BaseSessionService result = copy.sessionService();
+ // Assert
+ assertSame(mockSessionService, result, "copyOf() should preserve the same sessionService reference");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceReturnsSameInstanceViaStaticCreateWithUserContent() {
+ // Arrange
+ Content dummyContent = Content.builder().build();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService,
+ DUMMY_INVOCATION_ID, mockAgent, mockSession, dummyContent, mockRunConfig);
+ // Act
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertSame(mockSessionService, result, "create() with userContent should assign the correct sessionService");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceReturnsSameInstanceViaStaticCreateWithLiveRequestQueue() {
+ // Arrange
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ InvocationContext context = InvocationContext.create(mockSessionService, mockArtifactService, mockAgent,
+ mockSession, liveRequestQueue, mockRunConfig);
+ // Act
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertSame(mockSessionService, result,
+ "create() with liveRequestQueue should assign the correct sessionService");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceReturnedIsNotNull_WhenProvided() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertNotNull(result, "sessionService() should not return null when sessionService was provided");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceReturnsSameInstanceAcrossMultipleCalls() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseSessionService firstCall = context.sessionService();
+ BaseSessionService secondCall = context.sessionService();
+ BaseSessionService thirdCall = context.sessionService();
+ // Assert
+ assertSame(firstCall, secondCall, "Repeated calls should return the same instance");
+ assertSame(secondCall, thirdCall, "Repeated calls should return the same instance");
+ assertSame(mockSessionService, firstCall, "Should be the same as the mock provided");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceIsIndependentAcrossDifferentContextInstances() {
+ // Arrange
+ BaseSessionService mockSessionService1 = mock(BaseSessionService.class);
+ BaseSessionService mockSessionService2 = mock(BaseSessionService.class);
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService1)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService2)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId("e-other-invocation-id")
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseSessionService result1 = context1.sessionService();
+ BaseSessionService result2 = context2.sessionService();
+ // Assert
+ assertSame(mockSessionService1, result1, "context1 should return its own sessionService");
+ assertSame(mockSessionService2, result2, "context2 should return its own sessionService");
+ assertNotSame(result1, result2, "Two different contexts should return different sessionService instances");
+ }
+
+ @Test
+ @Tag("integration")
+ void sessionServiceReturnedCanBeUsedForFurtherOperations() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseSessionService returnedService = context.sessionService();
+ // Assert
+ assertNotNull(returnedService, "Returned service should not be null");
+ assertSame(mockSessionService, returnedService, "Returned service should be the same mock instance");
+ // Verifies the returned service is usable (not wrapped or proxied unexpectedly)
+ assertInstanceOf(BaseSessionService.class, returnedService, "Returned service should be a BaseSessionService");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServicePreservedWithAllOptionalFieldsSet() {
+ // Arrange
+ LiveRequestQueue liveRequestQueue = new LiveRequestQueue();
+ ResumabilityConfig resumabilityConfig = mock(ResumabilityConfig.class);
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .pluginManager(mockPluginManager)
+ .liveRequestQueue(Optional.of(liveRequestQueue))
+ .branch(Optional.of("testBranch"))
+ .invocationId(DUMMY_INVOCATION_ID)
+ .agent(mockAgent)
+ .session(mockSession)
+ .userContent(Optional.empty())
+ .runConfig(mockRunConfig)
+ .endInvocation(false)
+ .resumabilityConfig(resumabilityConfig)
+ .build();
+ // Act
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertSame(mockSessionService, result,
+ "sessionService should be correctly set even when all optional fields are provided");
+ }
+
+ @Test
+ @Tag("integration")
+ void sessionServicePreservedAfterCopyOfWithModifiedBranch() {
+ // Arrange
+ InvocationContext original = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .memoryService(mockMemoryService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext copy = InvocationContext.copyOf(original);
+ copy.branch("modifiedBranch");
+ // Act
+ BaseSessionService resultFromCopy = copy.sessionService();
+ BaseSessionService resultFromOriginal = original.sessionService();
+ // Assert
+ assertSame(mockSessionService, resultFromCopy,
+ "Copy should return the same sessionService after branch modification");
+ assertSame(mockSessionService, resultFromOriginal, "Original should still return the same sessionService");
+ assertSame(resultFromOriginal, resultFromCopy,
+ "Both original and copy should return the same sessionService instance");
+ }
+
+ @Test
+ @Tag("boundary")
+ void sessionServiceWithOnlyRequiredFieldsProvided() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .session(mockSession)
+ .build();
+ // Act
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertSame(mockSessionService, result,
+ "sessionService should be correctly returned even when built with only required fields");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceEqualsCheckIncludesSessionService() {
+ // Arrange
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act
+ BaseSessionService result1 = context1.sessionService();
+ BaseSessionService result2 = context2.sessionService();
+ // Assert
+ assertSame(result1, result2, "Both contexts with same sessionService should return the same service instance");
+ assertEquals(context1, context2, "Contexts with same fields including sessionService should be equal");
+ }
+
+ @Test
+ @Tag("valid")
+ void sessionServiceDifferenceBreaksEquality() {
+ // Arrange
+ BaseSessionService anotherMockSessionService = mock(BaseSessionService.class);
+ InvocationContext context1 = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ InvocationContext context2 = InvocationContext.builder()
+ .sessionService(anotherMockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act & Assert
+ assertNotSame(context1.sessionService(), context2.sessionService(),
+ "Different sessionServices should not be same instance");
+ assertNotEquals(context1, context2, "Contexts with different sessionServices should not be equal");
+ }
+
+ @Test
+ @Tag("boundary")
+ void sessionServiceNotAlteredBySettingOtherFields() {
+ // Arrange
+ InvocationContext context = InvocationContext.builder()
+ .sessionService(mockSessionService)
+ .artifactService(mockArtifactService)
+ .agent(mockAgent)
+ .session(mockSession)
+ .invocationId(DUMMY_INVOCATION_ID)
+ .runConfig(mockRunConfig)
+ .build();
+ // Act - modify mutable fields
+ context.setEndInvocation(true);
+ context.branch("newBranch");
+ context.agent(mock(BaseAgent.class));
+ BaseSessionService result = context.sessionService();
+ // Assert
+ assertSame(mockSessionService, result,
+ "sessionService should remain unchanged after modifying other mutable fields");
+ }
+
+@Test
+ @Tag("valid")
+ void sessionServiceReturnedFromDeprecatedConstructor() {
+ // Arrange
+ @SuppressWarnings("deprecation")
+ InvocationContext context = new InvocationContext(
+ mockSessionService,
+ mockArtifactService,
+ mockMem
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6009c7316..24fd6ece6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,4 @@
-
+
-
+
4.0.0
-
com.google.adk
google-adk-parent
- 0.4.1-SNAPSHOT
+ 0.4.1-SNAPSHOT
+
pom
-
Google Agent Development Kit Maven Parent POM
https://github.com/google/adk-java
Google Agent Development Kit (ADK) for Java
-
core
dev
@@ -39,12 +35,10 @@
a2a
a2a/webservice
-
17
${java.version}
UTF-8
-
1.11.0
3.4.1
1.49.0
@@ -73,7 +67,6 @@
3.9.0
5.4.3
-
@@ -112,7 +105,6 @@
pom
import
-
com.anthropic
@@ -274,9 +266,21 @@
assertj-core
${assertj.version}
+
+ org.mockito
+ mockito-junit-jupiter
+ 2.23.4
+ test
+
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ 0.0.40
+
+
-
@@ -324,8 +328,7 @@
plain
-
+
**/*Test.java
@@ -469,6 +472,36 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.2.5
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ 3.2.5
+
+ testReport
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 2.1
+
+ testReport
+
+
+
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.40
+
+
@@ -528,7 +561,6 @@
-
The Apache License, Version 2.0
@@ -558,4 +590,19 @@
https://central.sonatype.com/repository/maven-snapshots/
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 2.23.4
+ test
+
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ 0.0.40
+
+
+
\ No newline at end of file