refactor: replace boolean endInvocation flag with atomic.Bool to enable cross-context state propagation#1135
refactor: replace boolean endInvocation flag with atomic.Bool to enable cross-context state propagation#1135hanorik wants to merge 2 commits into
Conversation
karolpiotrowicz
left a comment
There was a problem hiding this comment.
Thanks for this — the value-copy propagation bug is real, and the red→green tests (TestSubAgentCallbackEndInvocationPropagated, TestSequentialAgent_SubAgentEndInvocationPropagated) capture it well. I reproduced it locally: both new tests fail on main and pass with this change, the full go test -race ./... suite is green (one unrelated remoteagent timing flake), and there's no public API change. Keeping EndInvocationPtr() off the public interface via a type assertion is a nice touch.
I left a few inline notes. The main things I'd like to see before merge:
- Live path isn't covered —
sequentialAgent.RunLivedoesn't have theEnded()short-circuit thatRunnow has (inline). - ParallelAgent semantics need a deliberate decision — sharing one flag across siblings changes isolation behavior (inline).
initEndInvocationisn't thread-safe — worth eager-initializing (inline).- Test coverage —
loopagent,parallelagent(shared atomic), andworkflow/agent_node.goare changed but untested; could you add cases for those? - Rebase on
main— the branch predates therunner.NewInMemoryaddition, so an API diff against currentmainlooks misleadingly like a removal; a rebase clears it. (It also sets up the small follow-up that #370 describes.)
Overall the core mechanism and the sequential propagation are solid — nice work.
…le cross-context state propagation
5dce794 to
19ab0e0
Compare
|
Also added missing test coverage. |
4bc0961 to
51eb2fe
Compare
wolo-lab
left a comment
There was a problem hiding this comment.
The fix looks good.
There's one thing worrying me. adk-python decided explicitly not to fix it: google/adk-python#1452.
Submitting this fix will introduce the difference in behavior between adks. Let me sync with them first.
Fixes an issue where
EndInvocation()called inside sub-agent callbacks or child nodes did not propagate to parent/sibling contexts becauseEndInvocationwas stored as a value-copiedbool.Changes
EndInvocation boolwith*atomic.BoolacrossInvocationContextimplementations (agentandinternal/context).EndInvocationPtr() *atomic.Boolso derived child contexts (WithContext,WithICDelta,parallelagent,workflow.AgentNode) share the same underlying atomic flag.sequentialagentandloopagentto checkctx.Ended()and stop execution when a sub-agent ends the invocation.Testing Plan
sequentialagent,agent, andinternal/contextpackages verifying thatEndInvocation()propagates across child/sub-agent contexts.go test -race ./....