Skip to content

Commit d0c9bbd

Browse files
committed
chore: merge main into fix-windows-click-glob-expansion
2 parents 531bb85 + 6ccb837 commit d0c9bbd

1,056 files changed

Lines changed: 106037 additions & 25532 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/adk-agent-builder/SKILL.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,37 @@ description: Central hub for building, testing, and iterating on ADK agents. Tri
55

66
# ADK Agent Builder
77

8-
This file serves as a directory of specialized reference guides for developing agents with ADK. To avoid context pollution, read only the relevant reference file based on your current task.
8+
This file serves as a directory of specialized reference guides for developing
9+
agents with ADK. To avoid context pollution, read only the relevant reference
10+
file based on your current task.
911

1012
## Core Concepts Directory
1113

1214
Refer to these files for foundational knowledge:
15+
1316
- **Getting Started & Basic Agents**: [getting-started.md](references/getting-started.md)
1417
- Environment setup, API key configuration, and minimal agent definitions.
1518
- **Tool Catalog**: [tool-catalog.md](references/tool-catalog.md)
1619
- How to bind function tools, MCP tools, OpenAPI specs, and Google API tools.
1720
- **Agent Modes (Task / Single-Turn)**: [task-mode.md](references/task-mode.md)
1821
- Multi-turn structured delegation and autonomous single-turn execution patterns.
22+
- **Import Paths**: [import-paths.md](references/import-paths.md)
23+
- Canonical and verbose import paths for core components, tools, and
24+
events.
1925

2026
## Workflow & Graph Orchestration
2127

2228
Refer to these files when building complex graphs:
29+
2330
- **Function Nodes**: [function-nodes.md](references/function-nodes.md)
2431
- How to use functions as nodes, type resolution, and generators.
2532
- **Routing & Conditions**: [routing-and-conditions.md](references/routing-and-conditions.md)
2633
- Edge patterns, dict-based routing, self-loops, and conditional execution.
2734
- **LLM Agent Nodes**: [llm-agent-nodes.md](references/llm-agent-nodes.md)
2835
- How to use LLM agents as workflow nodes, task wrappers, and handling output schemas.
36+
- **Advanced Patterns**:
37+
[advanced-patterns.md](references/advanced-patterns.md)
38+
- Nested workflows, custom node types, and graph validation rules.
2939

3040
## Advanced Orchestration Patterns
3141

@@ -40,6 +50,14 @@ Refer to these files when building complex graphs:
4050

4151
- **State & Events**: [state-and-events.md](references/state-and-events.md)
4252
- Using context API, sharing global state, and yield event structures.
53+
- **Session & Memory**:
54+
[session-and-state.md](references/session-and-state.md)
55+
- Session state mutation, scope conventions, and database session
56+
services.
57+
- **Callbacks & Plugins**:
58+
[callbacks-and-plugins.md](references/callbacks-and-plugins.md)
59+
- Implementing callbacks, plugin manager integration, and override
60+
behavior.
4361
- **Multi-Agent Systems**: [multi-agent.md](references/multi-agent.md)
4462
- Hierarchical execution (e.g., `SequentialAgent`, `LoopAgent`, `ParallelAgent`).
4563
- **Testing Strategies**: [testing.md](references/testing.md)

.agents/skills/adk-architecture/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ description: ADK architectural knowledge — graph orchestration, resumption, ex
1111
- [Runner](references/interfaces/runner.md) — The public interface for executing workflows and agents. Documents entrance methods `run` and `run_async`.
1212
- [Agent](references/interfaces/agent.md) — Blueprint defining identity, instructions, and tools. Documents that `run` is the preferred entrance method.
1313
- [BaseAgent](references/interfaces/base-agent.md) — Base class for all agents. Defines the contract for subclassing with `_run_impl` as the primary override point.
14-
- [Event](references/interfaces/event.md) — Core data structure for state reconstruction and communication. Represents a conversation turn or action.
14+
- [Event](references/interfaces/event.md) — Core data structure for state reconstruction and communication. Represents a conversation turn, action, and state lifecycle immutability.
1515

1616
## Key Principles (references/principles/)
1717
- [API Principles](references/principles/api-principles.md) — stability, backward compatibility, and self-containment. Use when making design choices that affect the public API surface.

.agents/skills/adk-architecture/references/architecture/observability.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ execution flow).
3030
implicit "current span" context. In a concurrent asyncio.Task
3131
runtime, implicit context can be unreliable across concurrent
3232
nodes. All tracing operations (attributes, logs, child spans)
33-
should go through `ctx._span`.
33+
should go through `ctx._span`. When attaching or detaching OTel context explicitly (e.g., using `context.attach()` and `context.detach()`), **always pair them inside a `try...finally` block** to prevent context leaks across requests.
3434

3535
**Span lifecycle:**
3636

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Workflow Resumability: Model and Direction
2+
3+
This note describes how a `Workflow` node preserves and restores execution state
4+
across a human-in-the-loop pause, how that compares to peer agent frameworks,
5+
and the direction we are moving in. It complements `checkpoint-resume.md`, which
6+
covers the interrupt/resume lifecycle for a single node.
7+
8+
The first thing to be clear about: a `Workflow` reconstructs its progress from
9+
the session event stream on every run, so it resumes whether or not resumability
10+
is configured. The `is_resumable` flag does not switch resume on or off. What it
11+
switches on is **durability** — persisting loadable checkpoints and letting an
12+
invocation be continued across separate runner calls.
13+
14+
## Current model
15+
16+
### Resume is always on: reconstruction by event replay
17+
18+
On every run, the workflow scans the current invocation's session events and
19+
rebuilds its in-memory loop state (which nodes completed, their outputs, which
20+
are still waiting on interrupts). Completed nodes are fast-forwarded from their
21+
recovered output rather than re-executed; the interrupted node re-runs with the
22+
supplied responses.
23+
24+
This path (`_run_impl` -> `ReplayManager.scan_workflow_events`) has no
25+
`is_resumable` guard — the scan matches events purely by invocation id. The loop
26+
state is not persisted and there is no separate workflow checkpoint to load; the
27+
session event log is the source of truth. So within an invocation, a workflow is
28+
inherently replay-resumable, flag or no flag. This is exactly what deanchen
29+
means by "still resumable even when resumability is not set."
30+
31+
### What `is_resumable` actually adds: durability
32+
33+
`ResumabilityConfig.is_resumable` is a durability switch. When it is set:
34+
35+
1. **Cross-call resume.** The runner will continue an existing invocation
36+
without a fresh user message and set up a "resumed invocation" context,
37+
rehydrating the recorded agent state and end-of-agent markers from history.
38+
With the flag off, the runner requires a new message and starts a fresh
39+
invocation instead.
40+
2. **Checkpoint markers in the log.** Composite agents (`LlmAgent`,
41+
`SequentialAgent`, `LoopAgent`, `ParallelAgent`, and `LlmAgent`s wrapped as
42+
workflow nodes) write `agent_state` / `end_of_agent` events into the session
43+
only when the invocation is resumable. These make progress loadable across a
44+
process boundary.
45+
3. **Function-response routing.** Routing an incoming function response back to
46+
its originating invocation is enabled only when resumable.
47+
48+
The config's own definition is durability-shaped: pause an invocation on a
49+
long-running call, and resume it from the last event if it paused or failed
50+
midway, best-effort and at-least-once, with in-memory state lost. So the
51+
accurate statement is: the flag decides whether progress is persisted as
52+
loadable checkpoints and whether an invocation can be resumed across runner
53+
calls — not whether the workflow can resume. Resumability here is really
54+
durability.
55+
56+
### The `Workflow` node emits no checkpoint of its own
57+
58+
Today the `Workflow` node does not persist a node-status checkpoint (a `nodes`
59+
payload of statuses/outputs). It relies solely on event replay. The `nodes`
60+
shape exists only as an input to graph visualization, not as something the
61+
runtime writes during a run. The only checkpoint events on the workflow path
62+
come from wrapped composite agents emitting their own `agent_state`, and those
63+
are gated on the flag as above.
64+
65+
## How peer frameworks do it
66+
67+
Every mainstream agent framework persists a **state snapshot with a position
68+
cursor** and, on resume, **loads that snapshot** — none reconstruct by replaying
69+
the entire history.
70+
71+
Framework | Durable unit | Position cursor | Resume
72+
------------------------ | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------
73+
LangGraph (graph) | `StateSnapshot` per super-step in a pluggable checkpointer | `next` nodes + parent-pointer chain + per-task pending writes | re-invoke same thread id; load latest checkpoint, re-run only the interrupted node
74+
pydantic-graph (graph) | `NodeSnapshot{state, node, status}` via a state-persistence backend | the snapshot's `node` = next node to run; `status` created/pending/running/success | `iter_from_persistence()` loads the next `created` snapshot
75+
OpenAI Agents SDK (loop) | serialized `RunState` blob | run cursor inside the state; correlate by tool-call id | deserialize the state, apply approvals, resume the run
76+
Pydantic AI (loop) | message history + deferred-tool results | implicit in the transcript; correlate by tool-call id | new run over the prior message history
77+
78+
ADK's durable unit today is the event log itself, and resume is by replay over
79+
it. Two patterns from the peers are worth copying, both consistent across them:
80+
81+
- **A snapshot is the source of truth for resume.** The runtime writes a
82+
snapshot as it advances and reads the latest one to continue. Resume cost is
83+
bounded by the snapshot size, not by history length.
84+
- **Resume re-runs the paused unit from its start** (LangGraph and
85+
pydantic-graph both re-execute the whole node, not a saved program counter),
86+
which keeps the durable state small and pushes an idempotency contract onto
87+
the node author — the same at-least-once contract ADK already documents.
88+
89+
## Direction: persist a workflow checkpoint as the durable source of truth
90+
91+
Even with durability on, the `Workflow` node reloads by replaying the event
92+
history rather than loading a compact checkpoint. The direction — peer-aligned,
93+
and the one ADK's own composite agents already follow — is to persist a workflow
94+
checkpoint and load the latest one on resume:
95+
96+
- As the workflow advances, persist node statuses and outputs as a checkpoint
97+
(an `agent_state` payload), the way composite agents already persist theirs.
98+
- On resume, seed the loop state from the most recent checkpoint, then
99+
continue: re-run only the interrupted node and dispatch newly-ready
100+
successors.
101+
- This makes resume cost independent of history length and unifies the
102+
`Workflow` node with composite agents and with LangGraph / pydantic-graph /
103+
the OpenAI SDK.
104+
105+
This only applies when durability is on. Without `is_resumable` there is nothing
106+
to persist, and the workflow continues to resume within an invocation by replay
107+
as it does today.
108+
109+
## Open considerations
110+
111+
- **Payload completeness.** A workflow checkpoint must carry (or be able to
112+
recover) each completed node's output, run id, and branch — the equivalent
113+
of LangGraph's per-task pending writes — to fully replace event replay.
114+
- **Partial interrupt resolution.** A node with several interrupts may receive
115+
only some responses on a resume. The re-run-vs-wait behavior differs between
116+
an orchestrating node (re-run to dispatch the resolved branch) and a leaf
117+
node (wait for all), keyed on `rerun_on_resume`. This is decided in the
118+
shared replay-interception logic and should be settled before a load path
119+
relies on it.
120+
- **Versioning.** Long-lived paused runs can outlive a code change. A version
121+
marker on the checkpoint lets a resume route to a compatible code path (the
122+
OpenAI SDK makes this an explicit recommendation).
123+
- **Serialization.** Keep payloads JSON-serializable (Pydantic `model_dump`),
124+
so any persistence backend works and no code objects are serialized; node
125+
objects are rebound from the in-memory graph definition on resume.

.agents/skills/adk-architecture/references/interfaces/event.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,8 @@ The `Event` class represents a single event in the conversation history or workf
2323
- `get_function_calls()`: Returns function calls in the event.
2424
- `get_function_responses()`: Returns function responses in the event.
2525
- `is_final_response()`: Returns whether the event is the final response of an agent.
26+
27+
## State Lifecycle & Immutability
28+
- **Event Immutability**: Event history is immutable. Never assume that events are mutated or cleared after they are saved to a session.
29+
- **Signal & Action Persistence**: When checking if a signal or action is "pending" versus "resolved", do not rely on events being modified in place.
30+
- **Compaction Side-Effects**: Be aware that storing stateful flags on events (such as requested actions or transient status) can have permanent unintended effects on background compaction when those events age but remain in history.

.agents/skills/adk-sample-creator/SKILL.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Each sample should have a `README.md` with the following structure:
8989

9090
- **Overview**: What the sample does.
9191
- **Sample Inputs**: Examples of inputs to test with. Each prompt must be wrapped in backticks. If a prompt has an explanation, always add a blank line between the prompt and the explanation, and indent the explanation by two spaces.
92-
- **Graph**: Visualization of the graph flow (Mermaid recommended for workflows).
92+
- **Graph**: Visualization of the graph flow (Mermaid recommended). For Workflow root agents, visualize the graph flow of nodes. For agents that orchestrate tools or sub-agents (e.g., `LlmAgent`, `ManagedAgent`), visualize the topology of the agent and its tools/sub-agents instead of internal workflow nodes. Keep it a simple topology diagram (a few nodes and edges). Do **not** draw a request/response data-flow sequence (e.g., `user -> agent -> API -> tool -> ... -> user`); those are noisy and add little value over the topology.
9393
- **How To**: Explanation of key techniques used (e.g., `ctx.run_node`).
9494
- **Related Guides**: Links to relevant developer guides in `docs/guides/` that explain the concepts or classes used.
9595

@@ -112,11 +112,18 @@ Brief description.
112112

113113
## Graph
114114

115+
For Workflow root agents:
115116
```mermaid
116117
graph TD
117118
START --> MyNode
118119
```
119120

121+
For agents that orchestrate tools or sub-agents (`LlmAgent`, `ManagedAgent`, ...):
122+
```mermaid
123+
graph TD
124+
MyAgent[my_agent] -->|calls| MyTool(my_tool)
125+
```
126+
120127
## How To
121128

122129
Explain the details.

.agents/skills/adk-style/references/typing.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,7 @@ Use `isinstance()` for runtime type discrimination when handling polymorphic inp
4848
- Always include an `else` branch that raises `TypeError` or handles the unknown case.
4949
- Prefer `isinstance(x, SomeType)` over `type(x) is SomeType` — it handles subclasses correctly.
5050
- For checking multiple types: `isinstance(x, (TypeA, TypeB))`.
51+
52+
## No Asserts in Production Code
53+
54+
**Never use `assert` statements in production code.** They can be optimized away when Python runs with `-O` flags and provide poor error messages. Use specific exceptions like `ValueError`, `TypeError`, or `RuntimeError` instead.

0 commit comments

Comments
 (0)