Skip to main content
Back to how-to guides Use this pattern when a child agent collects or computes values and the parent agent must use them after the child finishes.

Concept

A child agent runs in its own scope. When it finishes, nothing comes back unless you map it. The mapping names each child field and the parent variable that receives it. Two constructs return values. They use the same child_field: parent_variable shape. Choose by who talks to the customer. A child that asks the customer questions is a returnable HANDOFF. A hidden call that returns a result is a DELEGATE. See When to use HANDOFF instead of DELEGATE. Only mapped fields come back. A child field that you do not map stays in the child.

Minimal working example

A refill agent needs a delivery postcode before it can confirm the request. A delivery agent talks to the customer and collects it. MAP copies the postcode to the parent. SET records that delivery is confirmed. The delivery agent is a short stand-in in the same project. Replace it with your real agent. agents/refill-request-agent.agent.abl
agents/delivery-agent.agent.abl
Variable sources:
  • delivery_postcode in the child is a GATHER field. MAP copies it to the parent variable of the same name.
  • delivery_confirmed is set by the SET line after MAP runs.

How it works

  1. The parent routes to the child. RETURN: true makes the parent wait.
  2. The child talks to the customer and gathers its field.
  3. The child’s COMPLETE rule fires. The child returns control.
  4. The runtime applies MAP: it reads each child field and writes it to the parent variable. A child field with no value is skipped.
  5. The runtime applies SET assignments.
  6. The action decides what the parent does next. continue resumes the parent without routing again. resume_intent replays the customer’s request through the parent routes.
Rules for MAP:
  • Write child_field: parent_variable. The child field is on the left.
  • The child must declare or produce the child field. Otherwise the compiler reports UNKNOWN_HANDOFF_RETURN_FIELD as an error. The check runs for local children with RETURN: true.
  • The parent must be allowed to write each target. If one target is not writable, the runtime applies none of the return effects. See Transfer control to another agent and return later.
  • ON_RETURN without RETURN: true is unreachable. The compiler warns with HANDOFF_ON_RETURN_WITHOUT_RETURN.
Rules for RETURNS on a delegate:
  • Write child_field: parent_variable. The runtime looks for the child field in the result, then in the JSON response, then in the delegate’s session values, then in its state context.
  • A field that has no value is skipped.
  • If RETURNS is declared and no field maps, the delegate fails and the ON_FAILURE path runs.
  • An empty string never overwrites a parent variable that holds a value. Return null to clear one on purpose.
  • The compiler warns with UNKNOWN_DELEGATE_RETURN_FIELD when the child does not declare the field.
  • The full result also lands in the variable that USE_RESULT names. The default is delegate_result.

Common variations

Map a delegate result

A delegate returns two values to the caller.
This is a section snippet. It needs the caller MEMORY fields and the Refund_Checker agent from Delegate and map the result.

Map several fields and replay the request

Add more MAP lines and use resume_intent when the parent must route again with the new values.
This is an illustrative fragment. delivery_window must be a child field and preferred_window a parent variable.

Reuse return behavior with a handler

Define a named handler in RETURN_HANDLERS when several routes share the same return behavior. A handler cannot combine RESPOND with RESUME_INTENT. See Transfer control to another agent and return later.

Remote children

A remote child can also return values. The remote agent sends an A2A data part with a returnValues object, and MAP reads its keys. The compiler does not check MAP fields for a remote target, so a wrong key is skipped without an error. See Preserve context when calling remote agents.

Verification

  1. Run the validator on both files. Expect no errors and no warnings.
  2. Send “Refill my prescription.”
  3. Expect a handoff trace event to Delivery_Agent with returnExpected: true.
  4. Answer the postcode. Expect the child to complete.
  5. Expect a handoff_return_handler trace event. mappedFields must list delivery_postcode.
  6. Expect the parent reply “Your refill ships to” followed by your postcode.
  7. Change the MAP child field to a name the child does not declare. Expect UNKNOWN_HANDOFF_RETURN_FIELD. Revert the change.

Production readiness checklist

  • Every MAP and RETURNS entry names a child field that the child sets on every successful path.
  • Every parent variable is declared in MEMORY, and the parent reads it.
  • The parent can write every MAP and SET target.
  • A failure path exists for the child. See Transfer control to another agent and return later.
  • Tests cover a child that returns every field, a child that returns some fields, and a child that never completes.
  • Trace checks confirm mappedFields on every return.

Common mistakes

Troubleshooting

Related articles: