diff --git a/docs/sessions/memory.md b/docs/sessions/memory.md index 629672bd60..e62704542f 100644 --- a/docs/sessions/memory.md +++ b/docs/sessions/memory.md @@ -598,6 +598,26 @@ 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 +
+ +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" +``` + +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. */