diff --git a/pom.xml b/pom.xml
index afb900088..66ce647fa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
2.3.21
2.2.0
1.11.0
- 1.4.0
+ 1.5.0
3.7.0
2.35.1
3.27.7
diff --git a/tokt/src/main/kotlin/com/google/adk/tokt/JavaAdkToKt.kt b/tokt/src/main/kotlin/com/google/adk/tokt/JavaAdkToKt.kt
index 24af4a6ab..7628b46cd 100644
--- a/tokt/src/main/kotlin/com/google/adk/tokt/JavaAdkToKt.kt
+++ b/tokt/src/main/kotlin/com/google/adk/tokt/JavaAdkToKt.kt
@@ -141,7 +141,8 @@ object JavaAdkToKt {
* Java view of a Kotlin service is unwrapped to that Kotlin service, with no `dispatcher` hop.
* Resumption and rewinds work across the adapter if the Java service, like
* `InMemorySessionService`, returns the fields they read unchanged: `EventActions.agentState`,
- * `rewindBeforeInvocationId`, and a workflow node's output, node info, and routes.
+ * `rewindBeforeInvocationId`, `Event.isolationScope`, and a workflow node's output, node info,
+ * and routes.
*/
@JvmStatic
@JvmOverloads
diff --git a/tokt/src/main/kotlin/com/google/adk/tokt/codecs/EventCodec.kt b/tokt/src/main/kotlin/com/google/adk/tokt/codecs/EventCodec.kt
index 59fc574cb..efb57146f 100644
--- a/tokt/src/main/kotlin/com/google/adk/tokt/codecs/EventCodec.kt
+++ b/tokt/src/main/kotlin/com/google/adk/tokt/codecs/EventCodec.kt
@@ -36,7 +36,7 @@ import kotlin.jvm.optionals.getOrNull
* `errorCode`, `finishReason`), the token `usageMetadata` ([UsageMetadataCodec]),
* `groundingMetadata` ([GroundingMetadataCodec]) and context `cacheMetadata`
* ([CacheMetadataCodec]), a workflow node's `output` and `nodeInfo` ([WorkflowCodec]), long-running
- * tool ids, and the timestamp.
+ * tool ids, the timestamp, and the `isolationScope`.
*/
internal object EventCodec {
@@ -49,6 +49,7 @@ internal object EventCodec {
.actions(eventActionsToJava(event.actions))
event.invocationId?.let { builder.invocationId(it) }
event.branch?.let { builder.branch(it) }
+ event.isolationScope?.let { builder.isolationScope(it) }
event.content?.let { builder.content(ContentCodec.toJava(it)) }
if (event.longRunningToolIds.isNotEmpty()) builder.longRunningToolIds(event.longRunningToolIds)
// Streaming/error signals are set only when meaningful, so ordinary events keep the Java
@@ -101,6 +102,7 @@ internal object EventCodec {
route = javaActions.route().getOrNull()?.map { WorkflowCodec.routeFromJava(it) },
),
branch = event.branch().getOrNull(),
+ isolationScope = event.isolationScope().getOrNull(),
partial = event.partial().getOrNull() ?: false,
turnComplete = event.turnComplete().getOrNull() ?: false,
interrupted = event.interrupted().getOrNull() ?: false,
diff --git a/tokt/src/test/kotlin/com/google/adk/tokt/KtRunnerInteropTest.kt b/tokt/src/test/kotlin/com/google/adk/tokt/KtRunnerInteropTest.kt
index d47b1f9a8..a9aec4db6 100644
--- a/tokt/src/test/kotlin/com/google/adk/tokt/KtRunnerInteropTest.kt
+++ b/tokt/src/test/kotlin/com/google/adk/tokt/KtRunnerInteropTest.kt
@@ -4383,6 +4383,21 @@ class KtRunnerInteropTest {
assertEquals(listOf(fingerprintOnly, active), stored)
}
+ @Test
+ fun asKtSessionService_isolationScope_survivesTheJavaStore() = runBlocking {
+ // A task agent resumes from events in its own scope, so the scope must survive storage.
+ val sessions = JavaAdkToKt.asKtSessionService(JavaInMemorySessionService())
+ val key = KtSessionKey("app", "u", "s")
+ val session = sessions.createSession(key)
+
+ val unusedScoped =
+ sessions.appendEvent(session, KtEvent(author = "task", isolationScope = "task-1"))
+ val unusedUnscoped = sessions.appendEvent(session, KtEvent(author = "user"))
+
+ val stored = assertNotNull(sessions.getSession(key)).events.map { it.isolationScope }
+ assertEquals(listOf("task-1", null), stored)
+ }
+
@Test
fun eventCodec_workflowFields_roundTripThroughTheJavaEvent() {
// Java code reads these fields too, so a Kotlin Content in the output crosses as a genai one.