Skip to content

Commit fd3bd52

Browse files
committed
demo(workflow): ADK Web wrapper for RFC google#93 authored workflows
A discoverable `root_agent` (a Workflow) that exposes the google#93 flow in ADK Web: the model authors a typed WorkflowSpec, ADK validates it against the capability registry, freezes spec+hash to session state, and executes it on the real engine via the google#92 supervisor — each step surfaced as a chat message so the authored plan, validation, capabilities, frozen hash, and final output are all visible in the ADK Web chat / State / Events surfaces. adk web contributing/samples/workflows/authored_workflow_demo Load-or-author: if a frozen spec already exists in the session it is REUSED (planner not re-invoked) and replayed — so the resume/reproducibility claim is real, verified by a CI-safe no-LLM test (test_demo_agent.py: import + name + registry + spec validation + reuse-path-with-stub-registry). Reuses the authored_workflow_spike/ stack; model from env (default gemini-2.5-flash; gemini-3.5-flash needs location=global); no hardcoded project. README is the ~7-min recording script. pyink/isort/mdformat clean; 4 demo tests pass.
1 parent da4f7aa commit fd3bd52

5 files changed

Lines changed: 639 additions & 0 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Demo narrative — model-authored typed Workflows (RFC #93)
2+
3+
A beat-by-beat narration for the ~7-minute recording, with a **real transcript**
4+
captured on Vertex `gemini-3.5-flash`. Pair this with the run commands in
5+
`README.md`. Bottom line: *ADK Web sells the product fit; pytest/CI sells the
6+
correctness.*
7+
8+
## Thesis (say this first, ~20s)
9+
10+
> "#92 gives ADK a supervised concurrent executor. #93 lets a model **author** a
11+
> typed `WorkflowSpec` — a plan as *data, not code* — that ADK validates against
12+
> a capability allow-list, freezes, and executes reproducibly. Watch the model
13+
> write a plan, ADK validate it, run it, and then **replay the exact same frozen
14+
> plan** without re-invoking the model."
15+
16+
## Beat 1 — author (ADK Web chat)
17+
18+
Send: **"Plan and run a codebase security review."** The chat streams:
19+
20+
```
21+
🧭 Model-authored Workflow — planning a security audit over 4 files using only
22+
registered capabilities (reviewer, triager, formatter).
23+
24+
📋 Authored plan (fan_out → step → step):
25+
{
26+
"goal": "Audit files and format the report",
27+
"steps": [
28+
{"kind": "fan_out", "id": "review_files", "over": {"source":"task","path":"files"}, "capability": "reviewer"},
29+
{"kind": "step", "id": "triage_findings", "input": {"source":"step","step":"review_files"}, "capability": "triager"},
30+
{"kind": "step", "id": "format_report", "input": {"source":"step","step":"triage_findings"}, "capability": "formatter"}
31+
],
32+
"output": {"source": "step", "step": "format_report"}
33+
}
34+
```
35+
36+
> "The model emitted a *typed plan*, not code — a fan-out of `reviewer` over the
37+
> files, then `triager`, then `formatter`, with explicit data bindings between
38+
> steps."
39+
40+
## Beat 2 — validate (capability allow-list)
41+
42+
```
43+
✅ Validation passed. Capabilities referenced (all registered):
44+
['formatter', 'reviewer', 'triager'].
45+
```
46+
47+
> "Validation confirms every capability the plan names is in the registry. The
48+
> model can only compose pre-approved capabilities — no arbitrary calls, no code
49+
> execution. That's the security model: capability allow-listing, not a sandbox."
50+
51+
## Beat 3 — freeze (State tab)
52+
53+
```
54+
🔒 Frozen spec persisted to session state — hash 206fb4d3a27b.
55+
Re-send the prompt: it replays this exact plan, not a new one.
56+
```
57+
58+
> "Open the **State** tab: `authored_workflow:frozen_spec` and `…_hash`. The plan
59+
> is now durable data you can store, diff, and audit."
60+
61+
## Beat 4 — execute (Events / trace tab)
62+
63+
```
64+
📄 Audit result: Identified 4 vulnerabilities: 1 critical (command injection),
65+
2 high (hardcoded credentials and SQL injection), and 1 medium (division by zero).
66+
```
67+
68+
> "Open **Events**: ADK runs the plan on the real engine via the #92 supervisor —
69+
> the `reviewer` fan-out over the 4 files, then `triager`, then `formatter`. The
70+
> findings are real: a CRITICAL `os.system` injection, HIGH hardcoded creds and
71+
> SQL injection, and a MEDIUM divide-by-zero."
72+
73+
## Beat 5 — reproduce (re-send the same prompt)
74+
75+
```
76+
♻️ Reusing frozen plan from session state — hash 206fb4d3a27b.
77+
The model is NOT re-invoked; the exact prior plan is replayed.
78+
✅ Validation passed. ...
79+
📄 Audit result: ...
80+
```
81+
82+
> "Send the same prompt again — **same hash, model not re-invoked**. The frozen
83+
> plan is replayed. That's the reproducibility guarantee: authoring is a
84+
> one-time, auditable step; execution is deterministic replay."
85+
86+
**Verified outputs (this capture):**
87+
88+
| Run | `reused` | `hash` |
89+
| ----------- | -------- | -------------- |
90+
| 1 (author) | `false` | `206fb4d3a27b` |
91+
| 2 (re-send) | `true` | `206fb4d3a27b` |
92+
93+
Same hash, `reused` flips to `true` — the model is not called the second time.
94+
95+
## Close (~20s)
96+
97+
> "So: a model authored a typed, validated, capability-bounded plan; ADK executed
98+
> it on the real engine; and a re-send replayed the exact frozen plan. The
99+
> deterministic test suites — 11 (#92) + 10 (#93) + 4 (demo) — lock all of this
100+
> in CI, including a no-LLM test of this reuse path."
101+
102+
## Proof commands (terminal, ~60s)
103+
104+
```bash
105+
pytest contributing/samples/workflows/dynamic_supervisor_spike/test_dynamic_supervisor_spike.py -q # 11
106+
pytest contributing/samples/workflows/authored_workflow_spike/test_authoring.py -q # 10
107+
pytest contributing/samples/workflows/authored_workflow_demo/test_demo_agent.py -q # 4
108+
```
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# ADK Web demo — model-authored typed Workflows (RFC #93)
2+
3+
A ~7-minute demo: a model authors a typed `WorkflowSpec`, ADK validates it
4+
against a capability registry, freezes it to session state, and executes it on
5+
the real ADK engine via the #92 supervisor — all visible in ADK Web's chat,
6+
state, and event surfaces. **ADK Web sells the product fit; pytest/CI sells the
7+
correctness.**
8+
9+
## 0. Configure a model (no hardcoded project)
10+
11+
```bash
12+
export GOOGLE_GENAI_USE_VERTEXAI=1
13+
export GOOGLE_CLOUD_PROJECT=<your-project>
14+
export GOOGLE_CLOUD_LOCATION=global # gemini-3.5-flash serves from `global`
15+
export SPIKE_GEMINI_MODEL=gemini-3.5-flash # or any flash model you can access
16+
```
17+
18+
## 1. Thesis (20s)
19+
20+
- **#92** is the supervised concurrent executor (`DynamicNodeSupervisor` + `ctx.pipeline`).
21+
- **#93** is the model-authored typed `WorkflowSpec` layer.
22+
- The demo: a model authors a *validated* plan, then ADK executes that *frozen* plan reproducibly.
23+
24+
## 2. ADK Web walkthrough (3–5 min)
25+
26+
```bash
27+
adk web contributing/samples/workflows/authored_workflow_demo \
28+
--port 8000 --session_service_uri "sqlite:///demo_sessions.db"
29+
```
30+
31+
Open the UI, pick `security_audit_planner`, and send:
32+
33+
```text
34+
Plan and run a codebase security review.
35+
```
36+
37+
Point at the ADK-native evidence as it streams:
38+
39+
1. **Authored `WorkflowSpec`** — the chat shows the JSON plan (`fan_out → step → step`).
40+
1. **Validation** — "Validation passed" + the capability list (all registered).
41+
1. **Frozen spec + hash** — open the **State** tab: `authored_workflow:frozen_spec` and `…_hash`.
42+
1. **Execution** — the **Events / trace** view shows the `reviewer` fan-out, then `triager`, then `formatter` node runs.
43+
1. **Final output** — the triaged audit (e.g. 3 HIGH + 1 MEDIUM across `auth.py`/`db.py`/`net.py`/`math.py`).
44+
45+
(Re-send the same prompt to show resume reuses the frozen spec — same hash, not re-authored.)
46+
47+
## 3. Shape sweep — not a one-off (1–2 min)
48+
49+
```bash
50+
SPIKE_LIVE=1 pytest \
51+
contributing/samples/workflows/authored_workflow_spike/test_live_planner_sweep.py -q -s
52+
```
53+
54+
Proof points: multi-stage `fan_out → step → step`; branch `step → branch`; loop `loop_until`.
55+
56+
## 4. Correctness proof (60s)
57+
58+
```bash
59+
pytest contributing/samples/workflows/dynamic_supervisor_spike/test_dynamic_supervisor_spike.py -q # 11
60+
pytest contributing/samples/workflows/authored_workflow_spike/test_authoring.py -q # 10
61+
pytest contributing/samples/workflows/authored_workflow_demo/test_demo_agent.py -q # 4
62+
```
63+
64+
- Deterministic suites: #92 **11** + #93 **10** + demo **4** = **25** (incl. a no-LLM reuse-path test).
65+
- PR #3 CI green except the documented fork-only `agent-triage` token job.
66+
67+
## Recording notes
68+
69+
- macOS `Cmd+Shift+5` or Loom; browser at 110–125% zoom, terminal font 16+.
70+
- Hide project IDs / env vars. Keep it under ~7 minutes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from . import agent # noqa: F401

0 commit comments

Comments
 (0)