chore: import upstream snapshot with attribution
Continuous Integration / Pre-commit Linter (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.10) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.11) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.12) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.12) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.12) (push) Has been cancelled
Copybara PR Handler / close-imported-pr (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / Pre-commit Linter (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.10) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.11) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.12) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.12) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.12) (push) Has been cancelled
Copybara PR Handler / close-imported-pr (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.14) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# ADK Workflow Request Input Rerun Sample
|
||||
|
||||
## Overview
|
||||
|
||||
This sample demonstrates an alternative way to handle a **Human-in-the-Loop** workflow in **ADK Workflows** using the `RequestInput` event combined with the `@node(rerun_on_resume=True)` decorator.
|
||||
|
||||
Like the standard `request_input` sample, this workflow simulates a customer support scenario where an AI drafts an email and a human reviews it. The key difference lies in *how* the human input is processed when the workflow resumes.
|
||||
|
||||
### `request_input` vs `request_input_rerun`
|
||||
|
||||
- **Standard (`request_input`):** The workflow pauses after a node yields `RequestInput`. When the user provides input and execution resumes, the input is automatically passed as the argument to the **next node** in the edge definition. This requires two separate nodes: one to request the input and one to handle it.
|
||||
- **Rerun (`request_input_rerun`):** The node yielding `RequestInput` is decorated with `@node(rerun_on_resume=True)`. When execution resumes, the workflow **re-runs the exact same node** that asked for the input. The node can then access the provided input via the execution `Context`.
|
||||
|
||||
This allows you to combine the requesting and handling of human input into a single, cohesive node.
|
||||
|
||||
## Sample Inputs
|
||||
|
||||
- `The delivery was a week late`
|
||||
|
||||
- `I received the wrong item`
|
||||
|
||||
- `My account was charged twice`
|
||||
|
||||
## Graph
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
START --> draft_email
|
||||
draft_email --> human_review[human_review <br/>reruns on resume]
|
||||
human_review -->|revise| draft_email
|
||||
human_review -->|approved| send_email
|
||||
human_review -->|rejected| END_rejected[END rejected]
|
||||
```
|
||||
|
||||
## How To
|
||||
|
||||
1. Decorate the node that needs human input with `@node(rerun_on_resume=True)`. Ensure the function signature includes the workflow `Context`.
|
||||
|
||||
```python
|
||||
from google.adk.workflow import node
|
||||
from google.adk import Context
|
||||
|
||||
@node(rerun_on_resume=True)
|
||||
def human_review(draft: str, ctx: Context):
|
||||
# ...
|
||||
```
|
||||
|
||||
1. Inside the node, check if you are being resumed by looking for the `interrupt_id` in `ctx.resume_inputs`.
|
||||
|
||||
```python
|
||||
resume_input = ctx.resume_inputs.get('human_review')
|
||||
```
|
||||
|
||||
1. If `resume_input` is missing (i.e., this is the first time the node is executing), yield the `RequestInput` event to pause the workflow. Include an explicit `interrupt_id`.
|
||||
|
||||
```python
|
||||
if not resume_input:
|
||||
yield RequestInput(
|
||||
interrupt_id="human_review",
|
||||
message="Please review the draft...",
|
||||
)
|
||||
return # Important: Stop execution of this node for now
|
||||
```
|
||||
|
||||
1. If `resume_input` is present (i.e., the workflow was resumed with user input), process the input and yield the appropriate routing events.
|
||||
|
||||
```python
|
||||
if resume_input == "reject":
|
||||
yield Event(route="rejected")
|
||||
elif resume_input == "approve":
|
||||
yield Event(route="approved")
|
||||
else:
|
||||
yield Event(state={"feedback": resume_input}, route="revise")
|
||||
```
|
||||
|
||||
1. The edge definition is much simpler because the single `human_review` node handles everything:
|
||||
|
||||
```python
|
||||
Workflow(
|
||||
name="request_input",
|
||||
edges=[
|
||||
("START", process_input, draft_email, human_review),
|
||||
(human_review, {"revise": draft_email, "approved": send_email}),
|
||||
],
|
||||
)
|
||||
```
|
||||
Reference in New Issue
Block a user