From 69e19b17a2e8551a488bedd8a9eea67b26a2cf19 Mon Sep 17 00:00:00 2001 From: Shahin Saadati Date: Tue, 11 Aug 2026 13:40:56 -0700 Subject: [PATCH 1/2] Add Kotlin snippet for the CallbackContext memory-write helpers adk-kotlin 0.7.0 added addEventsToMemory and addMemory to CallbackContext, alongside the addSessionToMemory the page already shows in Kotlin. They cover the cases addSessionToMemory cannot: a chosen subset of events, and facts you construct yourself rather than letting the service derive them. Compiling changed the shape of this snippet. The obvious version read the current turn's events off context.invocationContext, but that property is internal -- CallbackContext exposes no way to reach the session. So addEventsToMemory takes events the caller already holds, and the snippet says so rather than quietly implying otherwise. Both helpers, and addSessionToMemory, throw IllegalStateException when the runner has no memory service. That is a runtime failure with nothing at compile time to warn you, so the page states it. Verified by running both paths: "Cannot add events to memory: memory service is not available." and "Cannot add memory: memory service is not available." Badged Kotlin v0.7.0, verified rather than assumed: neither helper exists on CallbackContext at v0.6.0. Appended to the existing MemoryExample.kt, already registered, so CI compiles and lints it. --- docs/sessions/memory.md | 19 ++++++++++++++ .../kotlin/snippets/sessions/MemoryExample.kt | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/docs/sessions/memory.md b/docs/sessions/memory.md index 027e8e089a..46edc19ff7 100644 --- a/docs/sessions/memory.md +++ b/docs/sessions/memory.md @@ -597,6 +597,25 @@ For example, you can automate this step with a callback: --8<-- "examples/kotlin/snippets/sessions/MemoryExample.kt:auto_save_callback" ``` +### Write specific events or facts from a callback + +
+ Supported in ADKKotlin v0.7.0 +
+ +`addSessionToMemory` saves the whole session. When you want finer control, +`CallbackContext` also offers `addEventsToMemory`, for a chosen subset of events, +and `addMemory`, for facts you construct yourself. Both accept optional +`customMetadata`, and both fill in the app, user and session from the current +invocation. + +```kotlin +--8<-- "examples/kotlin/snippets/sessions/MemoryExample.kt:callback_memory_writes" +``` + +All three throw `IllegalStateException` if the runner has no memory service +configured, so they fail at run time rather than at compile time. + ## Extend memory capabilities Memory services extended from `BaseMemoryService` support adding sessions and diff --git a/examples/kotlin/snippets/sessions/MemoryExample.kt b/examples/kotlin/snippets/sessions/MemoryExample.kt index 5c1c758ddb..994bd7ee1c 100644 --- a/examples/kotlin/snippets/sessions/MemoryExample.kt +++ b/examples/kotlin/snippets/sessions/MemoryExample.kt @@ -21,7 +21,9 @@ import com.google.adk.kt.agents.Instruction import com.google.adk.kt.agents.LlmAgent import com.google.adk.kt.callbacks.AfterAgentCallback import com.google.adk.kt.callbacks.CallbackChoice +import com.google.adk.kt.events.Event import com.google.adk.kt.memory.InMemoryMemoryService +import com.google.adk.kt.memory.MemoryEntry import com.google.adk.kt.memory.VertexAiMemoryBankService import com.google.adk.kt.memory.VertexAiRagMemoryService import com.google.adk.kt.models.Gemini @@ -260,6 +262,30 @@ fun agentWithCallback(model: Gemini) { } // --8<-- [end:auto_save_callback] +// --8<-- [start:callback_memory_writes] + +/** + * Saves a chosen set of events rather than the whole session, tagged so they can + * be filtered later. The events come from the caller: CallbackContext does not + * expose the session. + */ +suspend fun saveEventsToMemory( + context: CallbackContext, + events: List, +) { + // appName, userId and sessionId are taken from the invocation. Throws + // IllegalStateException if the runner has no memory service configured. + context.addEventsToMemory(events, customMetadata = mapOf("source" to "turn_callback")) +} + +/** Writes an explicit fact, instead of letting the service derive one from events. */ +suspend fun rememberPreferenceCallback(context: CallbackContext): CallbackChoice { + val preference = MemoryEntry(content = Content.fromText(Role.USER, "Prefers window seats.")) + context.addMemory(listOf(preference)) + return CallbackChoice.Continue(Unit) +} +// --8<-- [end:callback_memory_writes] + // --8<-- [start:memory_bank] /** Memory Bank keeps LLM-extracted memories in a Vertex AI Agent Engine. */ From b43d315acabca46534f0ba68325f5837732bc841 Mon Sep 17 00:00:00 2001 From: Shahin Saadati Date: Tue, 18 Aug 2026 11:07:47 -0700 Subject: [PATCH 2/2] docs: clarify CallbackContext memory methods and their default behavior --- docs/sessions/memory.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/sessions/memory.md b/docs/sessions/memory.md index 46edc19ff7..bc07e9984e 100644 --- a/docs/sessions/memory.md +++ b/docs/sessions/memory.md @@ -603,11 +603,12 @@ For example, you can automate this step with a callback: Supported in ADKKotlin v0.7.0 -`addSessionToMemory` saves the whole session. When you want finer control, -`CallbackContext` also offers `addEventsToMemory`, for a chosen subset of events, -and `addMemory`, for facts you construct yourself. Both accept optional -`customMetadata`, and both fill in the app, user and session from the current -invocation. +The `CallbackContext.addSessionToMemory` method is the default behavior for +memory and saves the whole session of your agent. When you want finer control, +`CallbackContext` also offers two more methods: `addEventsToMemory`, for a +chosen subset of events, and `addMemory`, for facts you construct yourself. +Both accept optional `customMetadata`, and both fill in the app, user and +session from the current invocation. ```kotlin --8<-- "examples/kotlin/snippets/sessions/MemoryExample.kt:callback_memory_writes"