Await-Condition Steps
Use an await_condition step when a workflow must pause until an expected outcome arrives from an agent session, review, or authorized callback.
Configuration
- key: await_executor
name: Await Executor
kind: await_condition
needs: [launch_executor]
waitsFor:
kind: workflow_input
expected: [executor_completed, executor_blocked]
authorizedHandles: ["${workflow.inputs.executorHandle}"]
sourceSessionUlid: "${steps.launch_executor.outputs.sessionUlid}"
outputs:
outcome: "$.normalized.input.outcome"| Field | Required | Purpose |
|---|---|---|
waitsFor.kind | Yes | Use workflow_input for authored waits |
waitsFor.expected | Yes | Outcomes this step accepts |
waitsFor.authorizedHandles | Callback mode | Agents or operators allowed to satisfy a callback-authorized wait |
waitsFor.sourceSessionUlid | Depends on mode | Recommended for callback mode; required for an exact-turn join |
waitsFor.sourceTurnClientRequestId | Exact-turn mode | Binds the wait to one turn from the same detached producer |
outputs | No | Named accepted values for later steps |
Keep expected outcomes narrow and non-empty. Strict validation rejects an empty list. Callback-authorized waits need at least one authorized handle; exact-turn waits derive authority from the detached producer and must not add authorizedHandles.
Bind the wait to its source
For agent work, map the session identity from the launch step and use it as sourceSessionUlid. For review work, use the reviewer session identity and expect only review verdicts:
waitsFor:
kind: workflow_input
expected: [review_approved, review_changes_requested]
authorizedHandles: ["${workflow.inputs.reviewerHandle}"]
sourceSessionUlid: "${steps.launch_review.outputs.reviewerSessionUlid}"This prevents unrelated sessions or reviews from advancing the workflow.
Join one detached turn
Use an exact-turn wait when a Session or Review step dispatches work with detached: true. Export both identifiers from that producer, then bind the wait to the same pair:
- key: launch_executor
name: Launch Executor
kind: session
detached: true
session:
action: launch_task
taskKey: "${workflow.inputs.taskKey}"
agentHandle: "${workflow.inputs.executorHandle}"
launcherConfigKey: "${workflow.inputs.launcherConfigKey}"
outputs:
sessionUlid: "$.normalized.session.sessionUlid"
turnClientRequestId: "$.normalized.session.turnClientRequestId"
- key: await_executor
name: Await Executor
kind: await_condition
needs: [launch_executor]
waitsFor:
kind: workflow_input
expected: [executor_completed, executor_blocked]
sourceSessionUlid: "${steps.launch_executor.outputs.sessionUlid}"
sourceTurnClientRequestId: "${steps.launch_executor.outputs.turnClientRequestId}"
outputs:
outcome: "$.normalized.input.outcome"Both values must come from the same detached producer. Do not add callback-authority fields to an exact-turn wait.
Interpret structured session output
Put a session-output gate on the producing Session or Review step when that step starts and waits, or on a Session input step. An await_condition cannot carry gates. See Session Steps for the supported placement and example.
Review-backed waits rely on published review evidence; do not use an agent’s JSON response to manufacture a review verdict.
Outputs and routing
Map the accepted outcome:
outputs:
outcome: "$.normalized.input.outcome"Later steps can route on ${steps.await_executor.outputs.outcome} with when checks or an Outcome route.
In Valdr UI
The run inspector shows what the step is waiting for, its linked session or review, accepted evidence, and any available operator action. The Workflow Builder exposes expected outcomes, authorized handles, source-session selection, and output mappings.
Next step
Use a Outcome route to route the accepted outcome, or a Human-Gate Step when the next transition requires an operator decision.