Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ share your patches and improvements with the project.

Before you contribute, please take a moment to review the following:

### 1. Sign our Contributor License Agreement
### 1. Sign our Contributor License Agreement { #sign-our-contributor-license-agreement }

Contributions to this project must be accompanied by a
[Contributor License Agreement](https://cla.developers.google.com/about) (CLA).
Expand All @@ -21,7 +21,7 @@ was for a different project), you probably don't need to do it again.
Visit <https://cla.developers.google.com/> to see your current agreements or to
sign a new one.

### 2. Review Community Guidelines
### 2. Review Community Guidelines { #review-community-guidelines }

We adhere to [Google's Open Source Community Guidelines](https://opensource.google/conduct/).
Please familiarize yourself with these guidelines to ensure a positive and
Expand Down
8 changes: 4 additions & 4 deletions docs/a2a/quickstart-consuming.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The A2A Basic sample consists of:

In the a2a_basic example, you will first need to expose the `check_prime_agent` via an A2A server, so that the local root agent can use it.

### 1. Getting the Sample Code
### 1. Getting the Sample Code { #getting-the-sample-code }

First, make sure you have the necessary dependencies installed:

Expand Down Expand Up @@ -68,7 +68,7 @@ a2a_basic/
- **`agent.json`**: Agent card of the A2A agent
- **`check_prime(nums: list[int])`**: Prime number checking algorithm

### 2. Start the Remote Prime Agent server
### 2. Start the Remote Prime Agent server { #start-the-remote-prime-agent-server }

To show how your ADK agent can consume a remote agent via A2A, you'll first need to start a remote agent server, which will host the prime agent (under `check_prime_agent`).

Expand Down Expand Up @@ -96,7 +96,7 @@ INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
```

### 3. Look out for the required agent card (`agent.json`) of the remote agent
### 3. Look out for the required agent card (`agent.json`) of the remote agent { #look-out-for-the-required-agent-card-agent-json-of-the-remote-agent }

A2A Protocol requires that each agent must have an agent card that describes what it does.

Expand Down Expand Up @@ -129,7 +129,7 @@ In the sample, the `check_prime_agent` already has an agent card provided:

In ADK, you can use a `to_a2a(root_agent)` wrapper which automatically generates an agent card for you. If you're interested in learning more about how to expose your existing agent so others can use it, then please look at the [A2A Quickstart (Exposing)](quickstart-exposing.md) tutorial.

### 4. Run the Main (Consuming) Agent
### 4. Run the Main (Consuming) Agent { #run-the-main-consuming-agent }

```bash
# In a separate terminal, run the adk web server
Expand Down
8 changes: 4 additions & 4 deletions docs/a2a/quickstart-exposing.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The `to_a2a()` function will even auto-generate an agent card in-memory behind-t

Now let's dive into the sample code.

### 1. Getting the Sample Code
### 1. Getting the Sample Code { #getting-the-sample-code }

First, make sure you have the necessary dependencies installed:

Expand Down Expand Up @@ -103,7 +103,7 @@ a2a_root/
- **`root_agent`**: The main agent with comprehensive instructions
- **`a2a_app`**: The A2A application created using `to_a2a()` utility

### 2. Start the Remote A2A Agent server
### 2. Start the Remote A2A Agent server { #start-the-remote-a2a-agent-server }

You can now start the remote agent server, which will host the `a2a_app` within the hello_world agent:

Expand All @@ -125,7 +125,7 @@ INFO: Application startup complete.
INFO: Uvicorn running on http://localhost:8001 (Press CTRL+C to quit)
```

### 3. Check that your remote agent is running
### 3. Check that your remote agent is running { #check-that-your-remote-agent-is-running }

You can check that your agent is up and running by visiting the agent card that was auto-generated earlier as part of your `to_a2a()` function in `a2a_root/remote_a2a/hello_world/agent.py`:

Expand All @@ -137,7 +137,7 @@ You should see the contents of the agent card, which should look like:
{"capabilities":{},"defaultInputModes":["text/plain"],"defaultOutputModes":["text/plain"],"description":"hello world agent that can roll a dice of 8 sides and check prime numbers.","name":"hello_world_agent","protocolVersion":"0.2.6","skills":[{"description":"hello world agent that can roll a dice of 8 sides and check prime numbers. \n I roll dice and answer questions about the outcome of the dice rolls.\n I can roll dice of different sizes.\n I can use multiple tools in parallel by calling functions in parallel(in one request and in one round).\n It is ok to discuss previous dice roles, and comment on the dice rolls.\n When I are asked to roll a die, I must call the roll_die tool with the number of sides. Be sure to pass in an integer. Do not pass in a string.\n I should never roll a die on my own.\n When checking prime numbers, call the check_prime tool with a list of integers. Be sure to pass in a list of integers. I should never pass in a string.\n I should not check prime numbers before calling the tool.\n When I are asked to roll a die and check prime numbers, I should always make the following two function calls:\n 1. I should first call the roll_die tool to get a roll. Wait for the function response before calling the check_prime tool.\n 2. After I get the function response from roll_die tool, I should call the check_prime tool with the roll_die result.\n 2.1 If user asks I to check primes based on previous rolls, make sure I include the previous rolls in the list.\n 3. When I respond, I must include the roll_die result from step 1.\n I should always perform the previous 3 steps when asking for a roll and checking prime numbers.\n I should not rely on the previous history on prime results.\n ","id":"hello_world_agent","name":"model","tags":["llm"]},{"description":"Roll a die and return the rolled result.\n\nArgs:\n sides: The integer number of sides the die has.\n tool_context: the tool context\nReturns:\n An integer of the result of rolling the die.","id":"hello_world_agent-roll_die","name":"roll_die","tags":["llm","tools"]},{"description":"Check if a given list of numbers are prime.\n\nArgs:\n nums: The list of numbers to check.\n\nReturns:\n A str indicating which number is prime.","id":"hello_world_agent-check_prime","name":"check_prime","tags":["llm","tools"]}],"supportsAuthenticatedExtendedCard":false,"url":"http://localhost:8001","version":"0.0.1"}
```

### 4. Run the Main (Consuming) Agent
### 4. Run the Main (Consuming) Agent { #run-the-main-consuming-agent }

Now that your remote agent is running, you can launch the dev UI and select "a2a_root" as your agent.

Expand Down
8 changes: 4 additions & 4 deletions docs/agents/custom-agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Let's illustrate the power of custom agents with an example pattern: a multi-sta

---

### Part 1: Simplified custom agent Initialization
### Part 1: Simplified custom agent Initialization { #part-1-simplified-custom-agent-initialization }

=== "Python"

Expand All @@ -160,7 +160,7 @@ Let's illustrate the power of custom agents with an example pattern: a multi-sta
```
---

### Part 2: Defining the Custom Execution Logic
### Part 2: Defining the Custom Execution Logic { #part-2-defining-the-custom-execution-logic }

=== "Python"

Expand Down Expand Up @@ -193,7 +193,7 @@ Let's illustrate the power of custom agents with an example pattern: a multi-sta

---

### Part 3: Defining the LLM Sub-Agents
### Part 3: Defining the LLM Sub-Agents { #part-3-defining-the-llm-sub-agents }

These are standard `LlmAgent` definitions, responsible for specific tasks. Their `output key` parameter is crucial for placing results into the `session.state` where other agents or the custom orchestrator can access them.

Expand All @@ -214,7 +214,7 @@ These are standard `LlmAgent` definitions, responsible for specific tasks. Their

---

### Part 4: Instantiating and Running the custom agent
### Part 4: Instantiating and Running the custom agent { #part-4-instantiating-and-running-the-custom-agent }

Finally, you instantiate your `StoryFlowAgent` and use the `Runner` as usual.

Expand Down
10 changes: 5 additions & 5 deletions docs/agents/multi-agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ You can compose various types of agents derived from `BaseAgent` to build these

The following sections detail the core ADK primitives—such as agent hierarchy, workflow agents, and interaction mechanisms—that enable you to construct and manage these multi-agent systems effectively.

## 1. ADK Primitives for Agent Composition
## 1. ADK Primitives for Agent Composition { #adk-primitives-for-agent-composition }

ADK provides core building blocks—primitives—that enable you to structure and manage interactions within your multi-agent system.

!!! Note
The specific parameters or method names for the primitives may vary slightly by SDK language (e.g., `sub_agents` in Python, `subAgents` in Java). Refer to the language-specific API documentation for details.

### 1.1. Agent Hierarchy (Parent agent, Sub Agents)
### 1.1. Agent Hierarchy (Parent agent, Sub Agents) { #agent-hierarchy-parent-agent-sub-agents }

The foundation for structuring multi-agent systems is the parent-child relationship defined in `BaseAgent`.

Expand Down Expand Up @@ -77,7 +77,7 @@ The foundation for structuring multi-agent systems is the parent-child relations
// assert taskDoer.parentAgent().equals(coordinator);
```

### 1.2. Workflow Agents as Orchestrators
### 1.2. Workflow Agents as Orchestrators { #workflow-agents-as-orchestrators }

ADK includes specialized agents derived from `BaseAgent` that don't perform tasks themselves but orchestrate the execution flow of their `sub_agents`.

Expand Down Expand Up @@ -223,7 +223,7 @@ ADK includes specialized agents derived from `BaseAgent` that don't perform task
// until Checker escalates (state.get("status") == "completed") or 10 iterations pass.
```

### 1.3. Interaction & Communication Mechanisms
### 1.3. Interaction & Communication Mechanisms { #interaction-communication-mechanisms }

Agents within a system often need to exchange data or trigger actions in one another. ADK facilitates this through:

Expand Down Expand Up @@ -444,7 +444,7 @@ Allows an [`LlmAgent`](llm-agents.md) to treat another `BaseAgent` instance as a

These primitives provide the flexibility to design multi-agent interactions ranging from tightly coupled sequential workflows to dynamic, LLM-driven delegation networks.

## 2. Common Multi-Agent Patterns using ADK Primitives
## 2. Common Multi-Agent Patterns using ADK Primitives { #common-multi-agent-patterns-using-adk-primitives }

By combining ADK's composition primitives, you can implement various established patterns for multi-agent collaboration.

Expand Down
16 changes: 8 additions & 8 deletions docs/callbacks/design-patterns-and-best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ Callbacks offer powerful hooks into the agent lifecycle. Here are common design

These patterns demonstrate typical ways to enhance or control agent behavior using callbacks:

### 1. Guardrails & Policy Enforcement
### 1. Guardrails & Policy Enforcement { #guardrails-policy-enforcement }

* **Pattern:** Intercept requests before they reach the LLM or tools to enforce rules.
* **How:** Use `before_model_callback` to inspect the `LlmRequest` prompt or `before_tool_callback` to inspect tool arguments. If a policy violation is detected (e.g., forbidden topics, profanity), return a predefined response (`LlmResponse` or `dict`/ `Map`) to block the operation and optionally update `context.state` to log the violation.
* **Example:** A `before_model_callback` checks `llm_request.contents` for sensitive keywords and returns a standard "Cannot process this request" `LlmResponse` if found, preventing the LLM call.

### 2. Dynamic State Management
### 2. Dynamic State Management { #dynamic-state-management }

* **Pattern:** Read from and write to session state within callbacks to make agent behavior context-aware and pass data between steps.
* **How:** Access `callback_context.state` or `tool_context.state`. Modifications (`state['key'] = value`) are automatically tracked in the subsequent `Event.actions.state_delta` for persistence by the `SessionService`.
* **Example:** An `after_tool_callback` saves a `transaction_id` from the tool's result to `tool_context.state['last_transaction_id']`. A later `before_agent_callback` might read `state['user_tier']` to customize the agent's greeting.

### 3. Logging and Monitoring
### 3. Logging and Monitoring { #logging-and-monitoring }

* **Pattern:** Add detailed logging at specific lifecycle points for observability and debugging.
* **How:** Implement callbacks (e.g., `before_agent_callback`, `after_tool_callback`, `after_model_callback`) to print or send structured logs containing information like agent name, tool name, invocation ID, and relevant data from the context or arguments.
* **Example:** Log messages like `INFO: [Invocation: e-123] Before Tool: search_api - Args: {'query': 'ADK'}`.

### 4. Caching
### 4. Caching { #caching }

* **Pattern:** Avoid redundant LLM calls or tool executions by caching results.
* **How:** In `before_model_callback` or `before_tool_callback`, generate a cache key based on the request/arguments. Check `context.state` (or an external cache) for this key. If found, return the cached `LlmResponse` or result directly, skipping the actual operation. If not found, allow the operation to proceed and use the corresponding `after_` callback (`after_model_callback`, `after_tool_callback`) to store the new result in the cache using the key.
* **Example:** `before_tool_callback` for `get_stock_price(symbol)` checks `state[f"cache:stock:{symbol}"]`. If present, returns the cached price; otherwise, allows the API call and `after_tool_callback` saves the result to the state key.

### 5. Request/Response Modification
### 5. Request/Response Modification { #request-response-modification }

* **Pattern:** Alter data just before it's sent to the LLM/tool or just after it's received.
* **How:**
Expand All @@ -40,21 +40,21 @@ These patterns demonstrate typical ways to enhance or control agent behavior usi
* `after_tool_callback`: Modify the `tool_response` dictionary (or Map in Java).
* **Example:** `before_model_callback` appends "User language preference: Spanish" to `llm_request.config.system_instruction` if `context.state['lang'] == 'es'`.

### 6. Conditional Skipping of Steps
### 6. Conditional Skipping of Steps { #conditional-skipping-of-steps }

* **Pattern:** Prevent standard operations (agent run, LLM call, tool execution) based on certain conditions.
* **How:** Return a value from a `before_` callback (`Content` from `before_agent_callback`, `LlmResponse` from `before_model_callback`, `dict` from `before_tool_callback`). The framework interprets this returned value as the result for that step, skipping the normal execution.
* **Example:** `before_tool_callback` checks `tool_context.state['api_quota_exceeded']`. If `True`, it returns `{'error': 'API quota exceeded'}`, preventing the actual tool function from running.

### 7. Tool-Specific Actions (Authentication & Summarization Control)
### 7. Tool-Specific Actions (Authentication & Summarization Control) { #tool-specific-actions-authentication-summarization-control }

* **Pattern:** Handle actions specific to the tool lifecycle, primarily authentication and controlling LLM summarization of tool results.
* **How:** Use `ToolContext` within tool callbacks (`before_tool_callback`, `after_tool_callback`).
* **Authentication:** Call `tool_context.request_credential(auth_config)` in `before_tool_callback` if credentials are required but not found (e.g., via `tool_context.get_auth_response` or state check). This initiates the auth flow.
* **Summarization:** Set `tool_context.actions.skip_summarization = True` if the raw dictionary output of the tool should be passed back to the LLM or potentially displayed directly, bypassing the default LLM summarization step.
* **Example:** A `before_tool_callback` for a secure API checks for an auth token in state; if missing, it calls `request_credential`. An `after_tool_callback` for a tool returning structured JSON might set `skip_summarization = True`.

### 8. Artifact Handling
### 8. Artifact Handling { #artifact-handling }

* **Pattern:** Save or load session-related files or large data blobs during the agent lifecycle.
* **How:** Use `callback_context.save_artifact` / `await tool_context.save_artifact` to store data (e.g., generated reports, logs, intermediate data). Use `load_artifact` to retrieve previously stored artifacts. Changes are tracked via `Event.actions.artifact_delta`.
Expand Down
16 changes: 8 additions & 8 deletions docs/contributing-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ Thank you for your interest in contributing to the Agent Development Kit (ADK)!

This guide provides information on how to get involved.

## 1. [`google/adk-python`](https://github.com/google/adk-python)
## 1. [`google/adk-python`](https://github.com/google/adk-python) { #google-adk-python }

Contains the core Python library source code.

## 2. [`google/adk-java`](https://github.com/google/adk-java)
## 2. [`google/adk-java`](https://github.com/google/adk-java) { #google-adk-java }

Contains the core Java library source code.

## 3. [`google/adk-docs`](https://github.com/google/adk-docs)
## 3. [`google/adk-docs`](https://github.com/google/adk-docs) { #google-adk-docs }

Contains the source for the documentation site you are currently reading.

## 4. [`google/adk-web`](https://github.com/google/adk-web)
## 4. [`google/adk-web`](https://github.com/google/adk-web) { #google-adk-web }

Contains the source for the `adk web` dev UI.

Expand Down Expand Up @@ -54,28 +54,28 @@ This is the primary place for:

There are several ways you can contribute to the ADK:

### 1. Reporting Issues (Bugs & Errors)
### 1. Reporting Issues (Bugs & Errors) { #reporting-issues-bugs-errors }

If you find a bug in the framework or an error in the documentation:

* **Framework Bugs:** Open an issue in [`google/adk-python`](https://github.com/google/adk-python/issues/new) or in [`google/adk-java`](https://github.com/google/adk-java/issues/new)
* **Documentation Errors:** [Open an issue in `google/adk-docs` (use bug template)](https://github.com/google/adk-docs/issues/new?template=bug_report.md)

### 2. Suggesting Enhancements
### 2. Suggesting Enhancements { #suggesting-enhancements }

Have an idea for a new feature or an improvement to an existing one?

* **Framework Enhancements:** Open an issue in [`google/adk-python`](https://github.com/google/adk-python/issues/new) or in [`google/adk-java`](https://github.com/google/adk-java/issues/new)
* **Documentation Enhancements:** [Open an issue in `google/adk-docs`](https://github.com/google/adk-docs/issues/new)

### 3. Improving Documentation
### 3. Improving Documentation { #improving-documentation }

Found a typo, unclear explanation, or missing information? Submit your changes directly:

* **How:** Submit a Pull Request (PR) with your suggested improvements.
* **Where:** [Create a Pull Request in `google/adk-docs`](https://github.com/google/adk-docs/pulls)

### 4. Writing Code
### 4. Writing Code { #writing-code }

Help fix bugs, implement new features or contribute code samples for the documentation:

Expand Down
Loading