Skip to content

[improvement] Support typed output declarations on AgentNode for DataFlowEdge wiring #146

Open

Description

@groganz

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:

  1. Use OutputMessageNode JSON envelopes for data passing (fragile, untyped).
  2. Replace AgentNode + A2A with FlowExecutionStep + 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 found

Reproduction

  1. Create a child flow (child_agent_a) with EndNode declaring a typed output dataRefA: string.
  2. Serve the child via A2AServer.serve_agent(...).
  3. In a parent flow, declare an AgentNode referencing child_agent_a (as A2AAgent) and a DataFlowEdge from child_agent_a.outputs.dataRefA → next_node.inputs.dataRefA.
  4. AgentSpecLoader.load_json(parent_spec) raises because the A2AAgent has no output_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

  1. groganz commented on May 11, 2026

    @groganz
    Author

    Cross-linking oracle/agent-spec#184 — the typed-payload gap on InputMessageNode at the spec level mirrors the typed-output gap reported here for AgentNode. 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) and InputMessageNode (typed HITL gates).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions