feat(workflow): derive node output from message via NodeInfo.MessageAsOutput#966
Merged
Conversation
e825441 to
13a85af
Compare
9 tasks
wolo-lab
added a commit
that referenced
this pull request
Jun 5, 2026
…ution Add NodeInfo.OutputFor: the node paths an event's Output counts for — the emitter plus any WithUseAsOutput delegating ancestors. A delegating child's single event is stamped OutputFor=[child, parent, ...] and flows up, and the parent no longer re-emits a duplicate terminal output event (full suppression, matching adk-python's _output_delegated + output_for). Resume attributes a descendant's output to its delegating ancestors via OutputFor. Every output event records OutputFor (own path minimum), mirroring adk-python _enrich_event. Built on the temp integration branch (#960 + #920 + #966); rebase onto v2 once those merge.
3f8bec4 to
843dfca
Compare
13a85af to
749072a
Compare
wolo-lab
added a commit
that referenced
this pull request
Jun 5, 2026
…ution Add NodeInfo.OutputFor: the node paths an event's Output counts for — the emitter plus any WithUseAsOutput delegating ancestors. A delegating child's single event is stamped OutputFor=[child, parent, ...] and flows up, and the parent no longer re-emits a duplicate terminal output event (full suppression, matching adk-python's _output_delegated + output_for). Resume attributes a descendant's output to its delegating ancestors via OutputFor. Every output event records OutputFor (own path minimum), mirroring adk-python _enrich_event. Built on the temp integration branch (#960 + #920 + #966); rebase onto v2 once those merge.
843dfca to
94e6366
Compare
749072a to
b0d4a1b
Compare
wolo-lab
added a commit
that referenced
this pull request
Jun 8, 2026
…ution Add NodeInfo.OutputFor: the node paths an event's Output counts for — the emitter plus any WithUseAsOutput delegating ancestors. A delegating child's single event is stamped OutputFor=[child, parent, ...] and flows up, and the parent no longer re-emits a duplicate terminal output event (full suppression, matching adk-python's _output_delegated + output_for). Resume attributes a descendant's output to its delegating ancestors via OutputFor. Every output event records OutputFor (own path minimum), mirroring adk-python _enrich_event. Built on the temp integration branch (#960 + #920 + #966); rebase onto v2 once those merge.
94e6366 to
558781b
Compare
b0d4a1b to
ba7d347
Compare
wolo-lab
added a commit
that referenced
this pull request
Jun 8, 2026
…ution Add NodeInfo.OutputFor: the node paths an event's Output counts for — the emitter plus any WithUseAsOutput delegating ancestors. A delegating child's single event is stamped OutputFor=[child, parent, ...] and flows up, and the parent no longer re-emits a duplicate terminal output event (full suppression, matching adk-python's _output_delegated + output_for). Resume attributes a descendant's output to its delegating ancestors via OutputFor. Every output event records OutputFor (own path minimum), mirroring adk-python _enrich_event. Built on the temp integration branch (#960 + #920 + #966); rebase onto v2 once those merge.
wolo-lab
added a commit
that referenced
this pull request
Jun 8, 2026
…ution Add NodeInfo.OutputFor: the node paths an event's Output counts for — the emitter plus any WithUseAsOutput delegating ancestors. A delegating child's single event is stamped OutputFor=[child, parent, ...] and flows up, and the parent no longer re-emits a duplicate terminal output event (full suppression, matching adk-python's _output_delegated + output_for). Resume attributes a descendant's output to its delegating ancestors via OutputFor. Every output event records OutputFor (own path minimum), mirroring adk-python _enrich_event. Built on the temp integration branch (#960 + #920 + #966); rebase onto v2 once those merge.
ba7d347 to
6024efc
Compare
wolo-lab
added a commit
that referenced
this pull request
Jun 8, 2026
…ution Add NodeInfo.OutputFor: the node paths an event's Output counts for — the emitter plus any WithUseAsOutput delegating ancestors. A delegating child's single event is stamped OutputFor=[child, parent, ...] and flows up, and the parent no longer re-emits a duplicate terminal output event (full suppression, matching adk-python's _output_delegated + output_for). Resume attributes a descendant's output to its delegating ancestors via OutputFor. Every output event records OutputFor (own path minimum), mirroring adk-python _enrich_event. Built on the temp integration branch (#960 + #920 + #966); rebase onto v2 once those merge.
…sOutput Add NodeInfo.MessageAsOutput: when set and Event.Output is nil, readers derive the node's output from the event's model text. The static and dynamic schedulers both honor it (Output wins, message text is the fallback), mirroring adk-python's _track_event_in_context. Empty text is a valid output, matching python; AgentNode's own empty-text-skips behavior is unchanged. This lets a delegated child whose message IS its output (e.g. an LlmAgent node) promote its text to the parent via WithUseAsOutput, and feeds it to a successor on a normal handoff.
6024efc to
f620edd
Compare
Complete the MessageAsOutput feature to match adk-python's single mechanism, where a node sets Event.Output and NodeInfo.MessageAsOutput together: - Producer: synthesizeAgentOutput now stamps NodeInfo.MessageAsOutput when it derives output from model text (mirrors process_llm_agent_output), so the flag is present in history. - Resume reader: collectNodeOutputs derives a node's output from the model message when an event is flagged MessageAsOutput and carries no explicit Output (mirrors _reconstruct_node_states' use_message_as_output), so a message-as-output node recovers its output on resume. Previously the flag was only read (live, via childEventOutput) but never produced and never consumed on resume.
dpasiukevich
approved these changes
Jun 9, 2026
wolo-lab
added a commit
that referenced
this pull request
Jun 9, 2026
Resolves conflicts from v2's #966 (MessageAsOutput) and #987 (isolation_scope) landing while this OutputFor stack was in review. Conflict resolutions (keep this branch's OutputFor delegation model): - session.go: keep NodeInfo.OutputFor field; drop v2's stale TODO note. - dynamic_scheduler.go: keep full-suppression (stamp OutputFor on the child event) over v2's drop-and-re-emit-on-parent approach. - persistence.go: keep OutputFor-based resume attribution to ancestors. - persistence_test.go / run_node_test.go: keep the OutputFor tests and drop v2's duplicate parent-re-emit variants.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A workflow node's output normally lives in
Event.Output. But anLlmAgentnode in chat mode emits its answer as message content with noseparate
Outputvalue — so anything consuming that node's output (asuccessor on a handoff, or a
WithUseAsOutputdelegation) would see nooutput. adk-python solves this with
node_info.message_as_output;adk-go had no equivalent.
Solution
Add
NodeInfo.MessageAsOutput. When set andEvent.Outputis nil,readers derive the node's output from the event's model text. This mirrors
adk-python's
_track_event_in_context(explicitOutputwins; messagetext is the fallback).