Concept
A returnable handoff setsRETURN: true on a HANDOFF route. The target agent becomes the child. The calling agent becomes the parent and waits. The child talks to the customer until it returns control.
RETURN: false is the default. A route with no RETURN line is permanent. Write RETURN: true in lowercase. Values such as True or "true" read as false. EXPECT_RETURN is an alias for RETURN.
Use a returnable handoff for a gate or a short job. See Switch the active agent for how
HANDOFF changes the active agent. See Permanent handoff when the target keeps the conversation. See Use handoff instead of delegate to choose between HANDOFF and DELEGATE.
How the child returns
The child returns in one of three ways.What the parent does after the return
ON_RETURN sets the parent behavior. It has these keys.
Without
ON_RETURN, a return that forwards a customer message replays that message. Otherwise the parent resumes and does not replay.
Only mapped fields come back. A child field with no value is skipped. The parent must be allowed to write each MAP and SET target. If one target is not writable, the runtime applies none of the return effects. See Resume after a child or human agent completes for resume detail.
Minimal working example
The supervisor sends every request toIncome_Capture_Agent until annual_income is set. The child gathers the value and completes. MAP copies the value to the supervisor. The supervisor then hands off for good.
annual_income has one source: the GATHER field in the child. Offer_Agent is a short stand-in for your real specialist.
How it works
annual_income IS NOT SETis true. The runtime checks this condition before the model runs. The supervisor hands off to the child.- The supervisor waits. The child asks for the income and the customer answers.
COMPLETEfires. The child returns.MAPcopiesannual_incometo the supervisor.resume_intentreplays the original customer message. The depth limit is one level.annual_income IS SETis true. The second route sends the conversation toOffer_Agent, and that route is permanent.
ON_FAILURE runs when the handoff fails before the child accepts it. The options are continue, ESCALATE, and RESPOND "message". The default is continue. It does not run when the child later fails on its own.
HISTORY sets how much conversation the child receives. The default is full. Other values are auto, none, summary_only, and a last_n block. auto uses summary_only when SUMMARY has text. Otherwise it passes the last five messages.
PASS lists the parent variables the child receives. SUMMARY states the reason for the handoff.
Use IS SET and IS NOT SET for empty variables. The check != "" is true when the value is missing. A // in a WHEN outside quotes starts a comment.
Common variations
Continue without a replay
Useaction: continue when the parent must not route again. SET adds a parent assignment after MAP. income_note is a parent MEMORY variable. Replace the first HANDOFF entry with this entry.
income_note in the supervisor MEMORY. Without the SET line, the compiler reports W801 for income_note.
Choose the replay message and use the CONTEXT block
CONTEXT groups pass, summary, and history. Keys inside CONTEXT must be lowercase. Uppercase keys inside CONTEXT are ignored. Write a last_n history as an indented block. A one-line { mode: last_n } is ignored and falls back to full.
Name a return handler
A handler reuses return behavior across routes. A handler cannot combineRESPOND with RESUME_INTENT. The compiler reports HANDOFF_ON_RETURN_ACTION_AND_HANDLER. Add MAP on the route, or no value returns.
Let the child hand back to the waiting parent
A child that cannot serve a request hands off to its waiting parent. Add aHANDOFF to the parent in the child. Add it to Income_Capture_Agent in the minimal example.
recursion. A route to a waiting parent is allowed.
Return to the supervisor when the topic changes
A reasoning child can return to the supervisor when the customer changes topic.EXECUTION.pipeline.parentReturn tunes this. minConfidence sets the match threshold, from 0 to 1. ignoreAmbiguous ignores ambiguous matches. The default for ignoreAmbiguous is false. A supervisor setting overrides the project setting. Add this block to the supervisor in the minimal example.
Verification
- Validate the project. Every
TOtarget must exist. AMAPsource that the child does not declare givesUNKNOWN_HANDOFF_RETURN_FIELD. - Start a new session and send “I want a loan offer”. Expect
Income_Capture_Agentto ask for the income. Thehandoffevent showsreturnExpected: trueandreasonCode: handoff_return_expected. - Send an income. Expect a
handoff_return_handlerevent withmappedFields: ["annual_income"]. Expect aresume_intentevent next. - Expect a second
handoffevent toOffer_AgentwithreturnExpected: falseandreasonCode: handoff_permanent. - Read each
handoff_completedevent. It hasoutcome,durationMs, and, on a failure,causeandcode. It can also havesiblingIntentMs, the time a queued sibling request ran inside the attempt. That time is not indurationMs.
Production readiness checklist
- Every
TOtarget exists. Replace the stand-in agents with real agents. - Every
MAPnames a child field that the child sets and a parent variable the routes read. - The child has a
COMPLETEcondition or the built-in return action, so it cannot hold the conversation forever. - Each route sets
ON_FAILUREon purpose. - Each
PASSlist holds only what the child needs. - Tests cover a new session, a returning customer with the value set, an unanswered gate, a child that hands back, and a refused route.
- Trace checks cover
handoff,handoff_return_handler,resume_intent, andhandoff_completed.