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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions core/src/main/java/com/google/adk/runner/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -518,18 +518,9 @@ protected Flowable<Event> runAsyncImpl(
runConfig.saveInputBlobsAsArtifacts(),
stateDelta))
.flatMapPublisher(
event -> {
// Get the updated session after the message and state delta are
// applied
return this.sessionService
.getSession(
session.appName(), session.userId(), session.id(), Optional.empty())
.flatMapPublisher(
updatedSession ->
runAgentWithUpdatedSession(
initialContext, updatedSession, event, rootAgent))
.compose(Tracing.<Event>withContext(capturedContext));
});
event ->
runAgentWithUpdatedSession(initialContext, session, event, rootAgent)
.compose(Tracing.<Event>withContext(capturedContext)));
})
.doOnError(
throwable -> {
Expand Down
40 changes: 39 additions & 1 deletion core/src/test/java/com/google/adk/runner/RunnerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -763,8 +763,11 @@ public void runAsync_concurrentCalls_staleRead() throws Exception {
.firstOrError()
.doOnSuccess(
event -> {
s.events().add(e);
if (e.actions() != null && e.actions().stateDelta() != null) {
s.state().putAll(e.actions().stateDelta());
}
List<Event> newEvents = new ArrayList<>(s.events());
newEvents.add(e);
Session updated =
Session.builder(s.id())
.appName(s.appName())
Expand Down Expand Up @@ -1193,6 +1196,41 @@ public void runAsync_pureMockSessionService_multiStepLlmAgent_appendsExactlyOnce
verify(pureMockSessionService, times(expectedAppendCount)).appendEvent(any(), any());
}

@Test
public void runAsync_bypassesRedundantGetSession() {
BaseSessionService mockSessionService = mock(BaseSessionService.class);
Session backingSession = Session.builder("session-id").appName("test").userId("user").build();

when(mockSessionService.getSession(anyString(), anyString(), anyString(), any()))
.thenReturn(Maybe.just(backingSession));
when(mockSessionService.appendEvent(any(), any()))
.thenReturn(Single.just(Event.builder().id("sentinel").author("user").build()));

BaseAgent mockAgent = mock(BaseAgent.class);
when(mockAgent.runAsync(any()))
.thenReturn(Flowable.just(Event.builder().id("agent-event").author("agent").build()));

Runner spyRunner =
Runner.builder()
.app(
App.builder()
.name("test")
.rootAgent(mockAgent)
.plugins(ImmutableList.of(plugin))
.build())
.sessionService(mockSessionService)
.build();

List<Event> unused =
spyRunner
.runAsync("user", backingSession.id(), createContent("from user"))
.toList()
.blockingGet();

// Verify getSession was only called once (at the start of runAsync)
verify(mockSessionService, times(1)).getSession(anyString(), anyString(), anyString(), any());
}

@Test
public void runAsync_withSessionKey_success() {
var events =
Expand Down