From 86f31308c96c41b15db63f870a12f05319c3ef55 Mon Sep 17 00:00:00 2001 From: Damian Momot Date: Mon, 26 Oct 2026 05:29:23 -0700 Subject: [PATCH] feat: add Event.isolationScope PiperOrigin-RevId: 1007206276 --- .../java/com/google/adk/events/Event.java | 30 +++++++++++++++++++ .../java/com/google/adk/events/EventTest.java | 25 ++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/core/src/main/java/com/google/adk/events/Event.java b/core/src/main/java/com/google/adk/events/Event.java index f2bdaf3d7..6288964be 100644 --- a/core/src/main/java/com/google/adk/events/Event.java +++ b/core/src/main/java/com/google/adk/events/Event.java @@ -64,6 +64,7 @@ public class Event extends JsonBaseModel { private @Nullable Double avgLogprobs; private @Nullable Boolean interrupted; private @Nullable String branch; + private @Nullable String isolationScope; private @Nullable GroundingMetadata groundingMetadata; private @Nullable List customMetadata; private @Nullable String modelVersion; @@ -256,6 +257,22 @@ public void branch(@Nullable String branch) { this.branch = branch; } + /** + * Returns the isolated conversation this event belongs to, such as a delegated task, so an + * agent's model history can keep only events from its own scope. Returns empty when the event is + * not scoped. This field is internal to the framework and may change without notice. + */ + @Experimental + @JsonProperty("isolationScope") + public Optional isolationScope() { + return Optional.ofNullable(isolationScope); + } + + @Experimental + public void setIsolationScope(@Nullable String isolationScope) { + this.isolationScope = isolationScope; + } + /** The grounding metadata of the event. */ @JsonProperty("groundingMetadata") public Optional groundingMetadata() { @@ -480,6 +497,7 @@ public static class Builder { private @Nullable Double avgLogprobs; private @Nullable Boolean interrupted; private @Nullable String branch; + private @Nullable String isolationScope; private @Nullable GroundingMetadata groundingMetadata; private @Nullable List customMetadata; private @Nullable String modelVersion; @@ -626,6 +644,14 @@ Optional branch() { return Optional.ofNullable(branch); } + @Experimental + @CanIgnoreReturnValue + @JsonProperty("isolationScope") + public Builder isolationScope(@Nullable String value) { + this.isolationScope = value; + return this; + } + @CanIgnoreReturnValue @JsonProperty("groundingMetadata") public Builder groundingMetadata(@Nullable GroundingMetadata value) { @@ -704,6 +730,7 @@ public Event build() { event.setAvgLogprobs(avgLogprobs); event.setInterrupted(interrupted); event.branch(branch); + event.setIsolationScope(isolationScope); event.setGroundingMetadata(groundingMetadata); event.setCustomMetadata(customMetadata); event.setModelVersion(modelVersion); @@ -746,6 +773,7 @@ public Builder toBuilder() { .avgLogprobs(this.avgLogprobs) .interrupted(this.interrupted) .branch(this.branch) + .isolationScope(this.isolationScope) .groundingMetadata(this.groundingMetadata) .customMetadata(this.customMetadata) .modelVersion(this.modelVersion) @@ -781,6 +809,7 @@ public boolean equals(Object obj) { && Objects.equals(avgLogprobs, other.avgLogprobs) && Objects.equals(interrupted, other.interrupted) && Objects.equals(branch, other.branch) + && Objects.equals(isolationScope, other.isolationScope) && Objects.equals(groundingMetadata, other.groundingMetadata) && Objects.equals(customMetadata, other.customMetadata) && Objects.equals(modelVersion, other.modelVersion) @@ -814,6 +843,7 @@ public int hashCode() { avgLogprobs, interrupted, branch, + isolationScope, groundingMetadata, customMetadata, modelVersion, diff --git a/core/src/test/java/com/google/adk/events/EventTest.java b/core/src/test/java/com/google/adk/events/EventTest.java index 65fa9e80d..349118e6b 100644 --- a/core/src/test/java/com/google/adk/events/EventTest.java +++ b/core/src/test/java/com/google/adk/events/EventTest.java @@ -407,6 +407,31 @@ public void event_cacheMetadata_emptyByDefault() { assertThat(EVENT.toJson()).doesNotContain("cacheMetadata"); } + @Test + public void event_isolationScope_survivesJsonAndToBuilder() { + Event event = EVENT.toBuilder().isolationScope("wf@1/task@1").build(); + + assertThat(event.isolationScope()).hasValue("wf@1/task@1"); + assertThat(event.toBuilder().build()).isEqualTo(event); + assertThat(Event.fromJson(event.toJson())).isEqualTo(event); + assertThat(event).isNotEqualTo(EVENT); + assertThat(event.hashCode()).isNotEqualTo(EVENT.hashCode()); + } + + @Test + public void event_isolationScope_emptyByDefault() { + assertThat(EVENT.isolationScope()).isEmpty(); + assertThat(EVENT.toJson()).doesNotContain("isolationScope"); + } + + @Test + public void fromJson_readsIsolationScope() { + Event event = + Event.fromJson("{\"id\":\"event_id\",\"author\":\"agent\",\"isolationScope\":\"fc-1\"}"); + + assertThat(event.isolationScope()).hasValue("fc-1"); + } + @Test public void finalResponse_returnsTrueIfNoToolCalls() { Event event =