Skip to content

Commit 46fb8c6

Browse files
Poggeccicopybara-github
authored andcommitted
feat!: Integrate Memory Service into ADK runtime
PiperOrigin-RevId: 788611035
1 parent f7fd470 commit 46fb8c6

File tree

19 files changed

+677
-221
lines changed

19 files changed

+677
-221
lines changed

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

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818

1919
import com.google.adk.artifacts.BaseArtifactService;
2020
import com.google.adk.exceptions.LlmCallsLimitExceededException;
21+
import com.google.adk.memory.BaseMemoryService;
2122
import com.google.adk.sessions.BaseSessionService;
2223
import com.google.adk.sessions.Session;
24+
import com.google.errorprone.annotations.InlineMe;
2325
import com.google.genai.types.Content;
2426
import java.util.Map;
2527
import java.util.Objects;
@@ -33,6 +35,7 @@ public class InvocationContext {
3335

3436
private final BaseSessionService sessionService;
3537
private final BaseArtifactService artifactService;
38+
private final BaseMemoryService memoryService;
3639
private final Optional<LiveRequestQueue> liveRequestQueue;
3740
private final Map<String, ActiveStreamingTool> activeStreamingTools = new ConcurrentHashMap<>();
3841

@@ -46,9 +49,10 @@ public class InvocationContext {
4649
private boolean endInvocation;
4750
private final InvocationCostManager invocationCostManager = new InvocationCostManager();
4851

49-
private InvocationContext(
52+
public InvocationContext(
5053
BaseSessionService sessionService,
5154
BaseArtifactService artifactService,
55+
BaseMemoryService memoryService,
5256
Optional<LiveRequestQueue> liveRequestQueue,
5357
Optional<String> branch,
5458
String invocationId,
@@ -59,6 +63,7 @@ private InvocationContext(
5963
boolean endInvocation) {
6064
this.sessionService = sessionService;
6165
this.artifactService = artifactService;
66+
this.memoryService = memoryService;
6267
this.liveRequestQueue = liveRequestQueue;
6368
this.branch = branch;
6469
this.invocationId = invocationId;
@@ -69,6 +74,16 @@ private InvocationContext(
6974
this.endInvocation = endInvocation;
7075
}
7176

77+
/**
78+
* @deprecated Use the {@link #InvocationContext} constructor directly instead
79+
*/
80+
@InlineMe(
81+
replacement =
82+
"new InvocationContext(sessionService, artifactService, null, Optional.empty(),"
83+
+ " Optional.empty(), invocationId, agent, session, Optional.ofNullable(userContent),"
84+
+ " runConfig, false)",
85+
imports = {"com.google.adk.agents.InvocationContext", "java.util.Optional"})
86+
@Deprecated
7287
public static InvocationContext create(
7388
BaseSessionService sessionService,
7489
BaseArtifactService artifactService,
@@ -80,7 +95,8 @@ public static InvocationContext create(
8095
return new InvocationContext(
8196
sessionService,
8297
artifactService,
83-
Optional.empty(),
98+
/* memoryService= */ null,
99+
/* liveRequestQueue= */ Optional.empty(),
84100
/* branch= */ Optional.empty(),
85101
invocationId,
86102
agent,
@@ -90,6 +106,17 @@ public static InvocationContext create(
90106
false);
91107
}
92108

109+
/**
110+
* @deprecated Use the {@link #InvocationContext} constructor directly instead
111+
*/
112+
@InlineMe(
113+
replacement =
114+
"new InvocationContext(sessionService, artifactService, null,"
115+
+ " Optional.ofNullable(liveRequestQueue), Optional.empty(),"
116+
+ " InvocationContext.newInvocationContextId(), agent, session, Optional.empty(),"
117+
+ " runConfig, false)",
118+
imports = {"com.google.adk.agents.InvocationContext", "java.util.Optional"})
119+
@Deprecated
93120
public static InvocationContext create(
94121
BaseSessionService sessionService,
95122
BaseArtifactService artifactService,
@@ -100,6 +127,7 @@ public static InvocationContext create(
100127
return new InvocationContext(
101128
sessionService,
102129
artifactService,
130+
/* memoryService= */ null,
103131
Optional.ofNullable(liveRequestQueue),
104132
/* branch= */ Optional.empty(),
105133
InvocationContext.newInvocationContextId(),
@@ -115,6 +143,7 @@ public static InvocationContext copyOf(InvocationContext other) {
115143
new InvocationContext(
116144
other.sessionService,
117145
other.artifactService,
146+
other.memoryService,
118147
other.liveRequestQueue,
119148
other.branch,
120149
other.invocationId,
@@ -135,6 +164,10 @@ public BaseArtifactService artifactService() {
135164
return artifactService;
136165
}
137166

167+
public BaseMemoryService memoryService() {
168+
return memoryService;
169+
}
170+
138171
public Map<String, ActiveStreamingTool> activeStreamingTools() {
139172
return activeStreamingTools;
140173
}
@@ -226,6 +259,7 @@ public boolean equals(Object o) {
226259
return endInvocation == that.endInvocation
227260
&& Objects.equals(sessionService, that.sessionService)
228261
&& Objects.equals(artifactService, that.artifactService)
262+
&& Objects.equals(memoryService, that.memoryService)
229263
&& Objects.equals(liveRequestQueue, that.liveRequestQueue)
230264
&& Objects.equals(activeStreamingTools, that.activeStreamingTools)
231265
&& Objects.equals(branch, that.branch)
@@ -241,6 +275,7 @@ public int hashCode() {
241275
return Objects.hash(
242276
sessionService,
243277
artifactService,
278+
memoryService,
244279
liveRequestQueue,
245280
activeStreamingTools,
246281
branch,

core/src/main/java/com/google/adk/memory/InMemoryMemoryService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ public Single<SearchMemoryResponse> searchMemory(String appName, String userId,
118118
if (!Collections.disjoint(wordsInQuery, wordsInEvent)) {
119119
MemoryEntry memory =
120120
MemoryEntry.builder()
121-
.setContent(event.content().get())
122-
.setAuthor(event.author())
123-
.setTimestamp(formatTimestamp(event.timestamp()))
121+
.content(event.content().get())
122+
.author(event.author())
123+
.timestamp(formatTimestamp(event.timestamp()))
124124
.build();
125125
matchingMemories.add(memory);
126126
}

core/src/main/java/com/google/adk/memory/MemoryEntry.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,26 @@
1616

1717
package com.google.adk.memory;
1818

19+
import com.fasterxml.jackson.annotation.JsonCreator;
20+
import com.fasterxml.jackson.annotation.JsonProperty;
21+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
1922
import com.google.auto.value.AutoValue;
2023
import com.google.genai.types.Content;
2124
import java.time.Instant;
2225
import javax.annotation.Nullable;
2326

2427
/** Represents one memory entry. */
2528
@AutoValue
29+
@JsonDeserialize(builder = MemoryEntry.Builder.class)
2630
public abstract class MemoryEntry {
2731

2832
/** Returns the main content of the memory. */
33+
@JsonProperty("content")
2934
public abstract Content content();
3035

3136
/** Returns the author of the memory, or null if not set. */
3237
@Nullable
38+
@JsonProperty("author")
3339
public abstract String author();
3440

3541
/**
@@ -56,27 +62,35 @@ public static Builder builder() {
5662
@AutoValue.Builder
5763
public abstract static class Builder {
5864

65+
@JsonCreator
66+
static Builder create() {
67+
return new AutoValue_MemoryEntry.Builder();
68+
}
69+
5970
/**
6071
* Sets the main content of the memory.
6172
*
6273
* <p>This is a required field.
6374
*/
64-
public abstract Builder setContent(Content content);
75+
@JsonProperty("content")
76+
public abstract Builder content(Content content);
6577

6678
/** Sets the author of the memory. */
67-
public abstract Builder setAuthor(@Nullable String author);
79+
@JsonProperty("author")
80+
public abstract Builder author(@Nullable String author);
6881

6982
/** Sets the timestamp when the original content of this memory happened. */
70-
public abstract Builder setTimestamp(@Nullable String timestamp);
83+
@JsonProperty("timestamp")
84+
public abstract Builder timestamp(@Nullable String timestamp);
7185

7286
/**
7387
* A convenience method to set the timestamp from an {@link Instant} object, formatted as an ISO
7488
* 8601 string.
7589
*
7690
* @param instant The timestamp as an Instant object.
7791
*/
78-
public Builder setTimestamp(Instant instant) {
79-
return setTimestamp(instant.toString());
92+
public Builder timestamp(Instant instant) {
93+
return timestamp(instant.toString());
8094
}
8195

8296
/** Builds the immutable {@link MemoryEntry} object. */

core/src/main/java/com/google/adk/runner/InMemoryRunner.java

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

1919
import com.google.adk.agents.BaseAgent;
2020
import com.google.adk.artifacts.InMemoryArtifactService;
21+
import com.google.adk.memory.InMemoryMemoryService;
2122
import com.google.adk.sessions.InMemorySessionService;
2223

2324
/** The class for the in-memory GenAi runner, using in-memory artifact and session services. */
@@ -30,6 +31,11 @@ public InMemoryRunner(BaseAgent agent) {
3031
}
3132

3233
public InMemoryRunner(BaseAgent agent, String appName) {
33-
super(agent, appName, new InMemoryArtifactService(), new InMemorySessionService());
34+
super(
35+
agent,
36+
appName,
37+
new InMemoryArtifactService(),
38+
new InMemorySessionService(),
39+
new InMemoryMemoryService());
3440
}
3541
}

core/src/main/java/com/google/adk/runner/Runner.java

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@
2525
import com.google.adk.agents.RunConfig;
2626
import com.google.adk.artifacts.BaseArtifactService;
2727
import com.google.adk.events.Event;
28+
import com.google.adk.memory.BaseMemoryService;
2829
import com.google.adk.sessions.BaseSessionService;
2930
import com.google.adk.sessions.Session;
3031
import com.google.adk.tools.BaseTool;
3132
import com.google.adk.tools.FunctionTool;
3233
import com.google.adk.utils.CollectionUtils;
3334
import com.google.common.collect.ImmutableList;
35+
import com.google.errorprone.annotations.InlineMe;
3436
import com.google.genai.types.AudioTranscriptionConfig;
3537
import com.google.genai.types.Content;
3638
import com.google.genai.types.Modality;
@@ -53,17 +55,36 @@ public class Runner {
5355
private final String appName;
5456
private final BaseArtifactService artifactService;
5557
private final BaseSessionService sessionService;
58+
private final BaseMemoryService memoryService;
5659

5760
/** Creates a new {@code Runner}. */
5861
public Runner(
5962
BaseAgent agent,
6063
String appName,
6164
BaseArtifactService artifactService,
62-
BaseSessionService sessionService) {
65+
BaseSessionService sessionService,
66+
BaseMemoryService memoryService) {
6367
this.agent = agent;
6468
this.appName = appName;
6569
this.artifactService = artifactService;
6670
this.sessionService = sessionService;
71+
this.memoryService = memoryService;
72+
}
73+
74+
/**
75+
* Creates a new {@code Runner}.
76+
*
77+
* @deprecated Use the constructor with {@code BaseMemoryService} instead even if with a null if
78+
* you don't need the memory service.
79+
*/
80+
@InlineMe(replacement = "this(agent, appName, artifactService, sessionService, null)")
81+
@Deprecated
82+
public Runner(
83+
BaseAgent agent,
84+
String appName,
85+
BaseArtifactService artifactService,
86+
BaseSessionService sessionService) {
87+
this(agent, appName, artifactService, sessionService, null);
6788
}
6889

6990
public BaseAgent agent() {
@@ -82,6 +103,10 @@ public BaseSessionService sessionService() {
82103
return this.sessionService;
83104
}
84105

106+
public BaseMemoryService memoryService() {
107+
return this.memoryService;
108+
}
109+
85110
/**
86111
* Appends a new user message to the session history.
87112
*
@@ -185,13 +210,10 @@ public Flowable<Event> runAsync(Session session, Content newMessage, RunConfig r
185210
sess -> {
186211
BaseAgent rootAgent = this.agent;
187212
InvocationContext invocationContext =
188-
InvocationContext.create(
189-
this.sessionService,
190-
this.artifactService,
191-
InvocationContext.newInvocationContextId(),
192-
rootAgent,
213+
newInvocationContext(
193214
sess,
194-
newMessage,
215+
Optional.of(newMessage),
216+
/* liveRequestQueue= */ Optional.empty(),
195217
runConfig);
196218

197219
if (newMessage != null) {
@@ -240,7 +262,8 @@ private InvocationContext newInvocationContextForLive(
240262
}
241263
}
242264
}
243-
return newInvocationContext(session, liveRequestQueue, runConfigBuilder.build());
265+
return newInvocationContext(
266+
session, /* newMessage= */ Optional.empty(), liveRequestQueue, runConfigBuilder.build());
244267
}
245268

246269
/**
@@ -249,16 +272,24 @@ private InvocationContext newInvocationContextForLive(
249272
* @return a new {@link InvocationContext}.
250273
*/
251274
private InvocationContext newInvocationContext(
252-
Session session, Optional<LiveRequestQueue> liveRequestQueue, RunConfig runConfig) {
275+
Session session,
276+
Optional<Content> newMessage,
277+
Optional<LiveRequestQueue> liveRequestQueue,
278+
RunConfig runConfig) {
253279
BaseAgent rootAgent = this.agent;
254280
InvocationContext invocationContext =
255-
InvocationContext.create(
281+
new InvocationContext(
256282
this.sessionService,
257283
this.artifactService,
284+
this.memoryService,
285+
liveRequestQueue,
286+
/* branch= */ Optional.empty(),
287+
InvocationContext.newInvocationContextId(),
258288
rootAgent,
259289
session,
260-
liveRequestQueue.orElse(null),
261-
runConfig);
290+
newMessage,
291+
runConfig,
292+
/* endInvocation= */ false);
262293
invocationContext.agent(this.findAgentToRun(session, rootAgent));
263294
return invocationContext;
264295
}

0 commit comments

Comments
 (0)