The site rendered one language under two names. Tab labels were split 137 `TypeScript` / 53 `Typescript`, with three pages carrying both spellings at once (custom-agents.md 7/7, patterns.md 1/7, function-tools.md 4/1), and the language-support badges were split 67/18 the same way. Because pymdownx.tabbed slugifies tab labels to lowercase, both variants rendered and linked fine, so no link check or build warning ever flagged it -- it was visible only to readers, as two names for one SDK. Every user-visible occurrence is normalized to `TypeScript`, plus the two inconsistencies that turned up while doing it. 80 changed lines, accounted for exactly: 53 tab label === "Typescript" -> === "TypeScript" 18 badge span lst-typescript">Typescript -> TypeScript 3 prose mention cloud-run.md, mcp-tools.md, workflows/patterns.md 2 api-reference/index.md card heading and link text 1 badge div attr title="...Python and Typescript." 1 mkdocs.yml nav Typescript ADK -> TypeScript ADK 1 code fence ```javascript -> ```typescript on a .ts include 1 artifacts/index.md closing summary sentence --- 80 The first six rows are pure casing: 78 lines that differ from their originals by nothing but `Typescript` -> `TypeScript`. The last two are not, and are the reason this is not a `sed`: llm-agents.md:872 fenced `--8<-- ".../capital_agent.ts"` as ```javascript. It was the only javascript-fenced `.ts` include in docs/ (the other 189 TypeScript fences are correct), and it cost that one snippet its TypeScript highlighting. artifacts/index.md:1084 closed the page by naming languages and got the list wrong. It described reaching the artifact methods "using Python's context objects or directly interacting with the `BaseArtifactService` in Java" -- a two-language enumeration at the end of a page that carries Python, TypeScript, Go, Java and Kotlin tabs (11/10/10/10/11), and one that contradicts :556, which correctly names four of them. The enumeration is dropped rather than extended: the sentence now describes the two ways to reach these methods -- through the context object, or through `BaseArtifactService` -- which is what the page actually teaches and does not rot when a sixth language is added. docs/api-reference/index.md is included even though the rest of docs/api-reference/ is generated output that must not be touched. That tree holds 3,140 generated HTML files and exactly one hand-authored page: this one. It is Markdown, it is the only api-reference entry mkdocs.yml lists as `.md` rather than `index.html` (:272, :441), it uses Material `grid cards` and `:fontawesome-*:` shortcodes, and it carries a `CONTRIBUTORS:` note citing issues #1716 and #1717. Its TypeScript card already said "TypeScript" twice in its body text while its heading and link text said "Typescript"; those two are now consistent with the body. No generated file is modified. Not in this change: the broken `SseConnectionParams` sample in mcp-tools.md (docs-ts/p6c-mcp-ts-sample) and the `@google/adk` example version bumps (docs-ts/p6b-example-versions). Only the casing of the prose line above that sample is touched here. Verified: `mkdocs build` exits 0 with an empty warning set on both main and this branch, and the two warning sets are identical. A rendered before/after diff of the whole site shows every `__tabbed_*` id, every tab radio id and every heading anchor unchanged. Zero `=== "Typescript"` and zero `lst-typescript">Typescript` remain anywhere in the repo. Co-authored-by: Amaad Martin <amaadmartin@google.com>
4.1 KiB
Loop template workflow agent
The LoopAgent class is a template workflow agent that executes its sub-agents in a loop for a specified number of iterations or until a termination condition is met. Use the LoopAgent when your workflow involves repetition or iterative refinement, such as revising code or a document. As with other templated workflows, the execution of a LoopAgent object is not controlled by an AI model, and is deterministic in how it executes its sub-agents. The sub-agents within the defined loop may or may not utilize AI models, but the overall execution of those sub-agents is ultimately managed by the LoopAgent object you define.
!!! note "Alternative: graph-based workflows"
Starting in ADK 2.0 for Python and Go, templated workflows have been superseded
by more flexible workflow structures, including
[graph-based workflows](/graphs/) and
[dynamic workflows](/graphs/dynamic/).
Example scenario
You want to build an agent that can generate images of food, but sometimes when
you want to generate a specific number of items, such as bananas, the agent
generates a different number of those items in the image, such as an image of 7
bananas. You have two tools: Generate Image, Count Food Items. If your goal
is to keep generating images until it either correctly generates the specified
number of items, or after a certain number of iterations, you can build your
agent using a LoopAgent workflow.
How it Works
When the LoopAgent's Run Async method is called, it performs the following actions:
-
Sub-Agent Execution: It iterates through the Sub Agents list in order. For each sub-agent, it calls the agent's
Run Asyncmethod. -
Termination Check:
Crucially, the
LoopAgentitself does not inherently decide when to stop looping. You must implement a termination mechanism to prevent infinite loops. Common strategies include:- Max Iterations: Set a maximum number of iterations in the
LoopAgent. The loop will terminate after that many iterations. - Escalation from sub-agent: Design one or more sub-agents to evaluate a condition (e.g., "Is the document quality good enough?", "Has a consensus been reached?"). If the condition is met, the sub-agent can signal termination (e.g., by raising a custom event, setting a flag in a shared context, or returning a specific value).
- Max Iterations: Set a maximum number of iterations in the
Full Example: Iterative Document Improvement
Imagine a scenario where you want to iteratively improve a document:
-
Writer Agent: An
LlmAgentthat generates or refines a draft on a topic. -
Critic Agent: An
LlmAgentthat critiques the draft, identifying areas for improvement.LoopAgent(sub_agents=[WriterAgent, CriticAgent], max_iterations=5)
In this setup, the LoopAgent would manage the iterative process. The CriticAgent could be designed to return a "STOP" signal when the document reaches a satisfactory quality level, preventing further iterations. Alternatively, the max iterations parameter could be used to limit the process to a fixed number of cycles, or external logic could be implemented to make stop decisions. The loop would run at most five times, ensuring the iterative refinement doesn't continue indefinitely.
???+ "Full Code"
=== "Python"
```py
--8<-- "examples/python/snippets/agents/workflow-agents/loop_agent_doc_improv_agent.py:init"
```
=== "TypeScript"
```typescript
--8<-- "examples/typescript/snippets/agents/workflow-agents/loop_agent_doc_improv_agent.ts:init"
```
=== "Go"
```go
--8<-- "examples/go/snippets/agents/workflow-agents/loop/main.go:init"
```
=== "Java"
```java
--8<-- "examples/java/snippets/src/main/java/agents/workflow/LoopAgentExample.java:init"
```
