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
70 changes: 39 additions & 31 deletions docs/sessions/session/rewind.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Rewind sessions for agents

<div class="language-support-tag">
<span class="lst-supported">Supported in ADK</span><span class="lst-python">Python v1.17.0</span>
<span class="lst-supported">Supported in ADK</span><span class="lst-python">Python v1.17.0</span><span class="lst-kotlin">Kotlin v0.3.0</span>
</div>

The ADK session Rewind feature allows you to revert a session to a previous
Expand All @@ -19,36 +19,44 @@ rewind a session by using the rewind method on a ***Runner*** instance,
specifying the user, session, and invocation id, as shown in the following code
snippet:

```python
# Create runner
runner = InMemoryRunner(
agent=agent.root_agent,
app_name=APP_NAME,
)

# Create a session
session = await runner.session_service.create_session(
app_name=APP_NAME, user_id=USER_ID
)
# call agent with wrapper function "call_agent_async()"
await call_agent_async(
runner, USER_ID, session.id, "set state color to red"
)
# ... more agent calls ...
events_list = await call_agent_async(
runner, USER_ID, session.id, "update state color to blue"
)

# get invocation id
rewind_invocation_id=events_list[1].invocation_id

# rewind invocations (state color: red)
await runner.rewind_async(
user_id=USER_ID,
session_id=session.id,
rewind_before_invocation_id=rewind_invocation_id,
)
```
=== "Python"

```python
# Create runner
runner = InMemoryRunner(
agent=agent.root_agent,
app_name=APP_NAME,
)

# Create a session
session = await runner.session_service.create_session(
app_name=APP_NAME, user_id=USER_ID
)
# call agent with wrapper function "call_agent_async()"
await call_agent_async(
runner, USER_ID, session.id, "set state color to red"
)
# ... more agent calls ...
events_list = await call_agent_async(
runner, USER_ID, session.id, "update state color to blue"
)

# get invocation id
rewind_invocation_id=events_list[1].invocation_id

# rewind invocations (state color: red)
await runner.rewind_async(
user_id=USER_ID,
session_id=session.id,
rewind_before_invocation_id=rewind_invocation_id,
)
```

=== "Kotlin"

```kotlin
--8<-- "examples/kotlin/snippets/sessions/RewindExample.kt:rewind_session"
```

When you call the ***rewind*** method, all ADK managed session-level resources
are restored to the state they were in *before* the request you specified with
Expand Down
69 changes: 69 additions & 0 deletions examples/kotlin/snippets/sessions/RewindExample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2026 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.
*/

package com.google.adk.kt.examples.sessions

import com.google.adk.kt.agents.BaseAgent
import com.google.adk.kt.events.Event
import com.google.adk.kt.runners.InMemoryRunner
import com.google.adk.kt.sessions.InMemorySessionService
import com.google.adk.kt.sessions.SessionKey
import com.google.adk.kt.types.Content
import com.google.adk.kt.types.Part
import com.google.adk.kt.types.Role
import kotlinx.coroutines.flow.toList

private const val APP_NAME = "rewind_app"
private const val USER_ID = "user123"

// --8<-- [start:rewind_session]
suspend fun rewindSession(rootAgent: BaseAgent) {
val sessionService = InMemorySessionService()
val runner =
InMemoryRunner(agent = rootAgent, appName = APP_NAME, sessionService = sessionService)

// Create a session. The service assigns the id, which is held on Session.key.
val session = sessionService.createSession(SessionKey(APP_NAME, USER_ID, id = null))
val sessionId = checkNotNull(session.key.id)

// Call the agent
callAgent(runner, sessionId, "set state color to red")
// ... more agent calls ...
val events = callAgent(runner, sessionId, "update state color to blue")

// Get the invocation id of the request to undo
val rewindInvocationId = events[1].invocationId ?: return

// Rewind invocations (state color: red)
runner.rewindAsync(
userId = USER_ID,
sessionId = sessionId,
rewindBeforeInvocationId = rewindInvocationId,
)
}

private suspend fun callAgent(
runner: InMemoryRunner,
sessionId: String,
query: String,
): List<Event> =
runner
.runAsync(
userId = USER_ID,
sessionId = sessionId,
newMessage = Content(role = Role.USER, parts = listOf(Part(text = query))),
).toList()
// --8<-- [end:rewind_session]
1 change: 1 addition & 0 deletions tools/kotlin-snippets/files_to_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ snippets/tools/overview/UserPreferenceTools.kt
snippets/tools/overview/CustomerSupport.kt
snippets/tools/overview/DocAnalysisTools.kt
snippets/tools/overview/OrderTools.kt
snippets/sessions/RewindExample.kt
Loading