Repository navigation
Description
Summary
AgentNode (the Agent Spec representation of a child agent invocation) supports typed output declarations via the called agent's output_descriptors, and these can be wired into the parent flow with DataFlowEdge connections. However, the wayflowcore A2AAgent implementation hardcodes input_descriptors=[] and provides no output_descriptors, so a remote A2A child cannot expose typed outputs to the parent flow.
This forces parent flows to either:
- Use
OutputMessageNodeJSON envelopes for data passing (fragile, untyped). - Replace
AgentNode+ A2A withFlowExecutionStep+ a local subflow (works, but eliminates the cross-process boundary the user wanted in the first place).
Expected behaviour (per Agent Spec)
Agent Spec's flow model defines AgentNode outputs as the agent's declared outputs, wirable to other nodes via DataFlowEdge. This should hold whether the called agent is local (Agent) or remote (A2AAgent).
Actual behaviour
# wayflowcore/agentenvironment/_a2a_client.py (paraphrased)
class A2AAgent(...):
def __init__(self, ...):
# No output_descriptors parameter accepted.
# Parent flows that declare DataFlowEdge from an A2AAgent's AgentNode
# to another node fail at AgentSpecLoader.load_json with:
# ValueError: source 'child_agent_a.outputs.someField' not foundReproduction
- Create a child flow (
child_agent_a) withEndNodedeclaring a typed outputdataRefA: string. - Serve the child via
A2AServer.serve_agent(...). - In a parent flow, declare an
AgentNodereferencingchild_agent_a(asA2AAgent) and aDataFlowEdgefromchild_agent_a.outputs.dataRefA→next_node.inputs.dataRefA. AgentSpecLoader.load_json(parent_spec)raises because theA2AAgenthas nooutput_descriptors.
Suggested resolution
Either:
Option A (preferred): Allow A2AAgent.__init__ to accept output_descriptors (and input_descriptors) directly, and have the deserialization plugin populate them from the parent's AgentNode.outputs declaration. The runtime would NOT validate the descriptors against the remote agent (the remote is opaque); it would simply trust the parent's contract and validate the wire format on each call.
Option B: Document the limitation prominently and provide an alternative pattern (e.g. a DSL helper that synthesizes a typed wrapper around an A2A call).
Related
This is distinct from #141 (AgentExecutionStep.might_yield raises NotImplementedError for A2AAgent) and #142 (caller_input_mode=None due to elif ordering) — both concern startup compatibility. This issue concerns typed output declaration ergonomics for DataFlowEdge wiring at design time, not runtime startup.
Environment
wayflowcore[a2a]==26.1.1- Python 3.11
Activity
groganz commentedon May 11, 2026
Cross-linking oracle/agent-spec#184 — the typed-payload gap on
InputMessageNodeat the spec level mirrors the typed-output gap reported here forAgentNode. Both follow the same pattern: the spec supports typed wiring, the implementation collapses to untyped strings or empty descriptors, parent flows lose the type information.Worth resolving in coordination so the typed-DataFlowEdge story is consistent across both
AgentNode(remote child agents) andInputMessageNode(typed HITL gates).