55 Commits

Author SHA1 Message Date
nikkie babb11c83c feat(eval): support custom metrics in AgentEvaluator
Merge https://github.com/google/adk-python/pull/4344

**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: #4343

**Problem:**
`AgentEvaluator.evaluate` did not register custom metrics from `EvalConfig`, so custom metrics worked in `adk eval` but not in pytest-based evals.

**Solution:**
Align `AgentEvaluator` with the CLI eval flow by registering custom metrics via a per-run metric registry and a shared default `MetricInfo` helper. The per-run registry is a fork of `DEFAULT_METRIC_EVALUATOR_REGISTRY` (new `MetricEvaluatorRegistry.fork()`), so the custom metrics declared by one eval config never leak into another run.

### Testing Plan

Add unit coverage for the registration behavior and a lightweight integration example that uses a custom metric.

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

```
% pytest tests/unittests/evaluation tests/unittests/cli

614 passed, 308 warnings in 12.74s
```

**Manual End-to-End (E2E) Tests:**

```
% pytest tests/integration/test_with_test_file.py::test_with_custom_metric

tests/integration/test_with_test_file.py .                               [100%]

1 passed, 12 warnings in 3.57s
```

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

This change keeps `AgentEvaluator` behavior consistent with `adk eval` while avoiding CLI-layer dependencies.

`fork()` returns an isolated copy seeded with the source registry's contents, rather than a bare `MetricEvaluatorRegistry()`. The seeding is what keeps this backwards compatible: registering an `Evaluator` subclass on `DEFAULT_METRIC_EVALUATOR_REGISTRY` is the only way to plug one in, since an eval config can only name a scoring function. Callers who do that today (including ones replacing the evaluator behind a standard metric name) would otherwise silently fall back to the stock evaluator, with no error and a different score. Covered by `test_evaluate_eval_set_keeps_evaluators_from_the_default_registry`.

Co-authored-by: Yi Liu <yiliuly@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4344 from ftnext:agent-evaluator-support-custom-metric 3c844a9817d16954c683b164a88a86a82e8f9cf1
PiperOrigin-RevId: 966416454
2026-08-18 00:17:15 -07:00
nikkie 76027ddb2f feat(evaluation): add optional eval set result persistence to AgentEvaluator
Merge https://github.com/google/adk-python/pull/4414

**Please ensure you have read the [contribution guide](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Related: #4410
- Fixes: #2602

**Problem:**
`AgentEvaluator.evaluate()` did not support built-in eval set result persistence, making it harder to reuse the same workflow as CLI/Web paths that already use `EvalSetResultsManager`.
Also, introducing new parameters in the middle of method signatures would break positional-argument compatibility for existing users.

**Solution:**
This PR adds optional eval result persistence to `AgentEvaluator` while preserving backward compatibility:

- Add optional parameters to `AgentEvaluator.evaluate()` and `AgentEvaluator.evaluate_eval_set()`:
  - `app_name: Optional[str] = None`
  - `eval_set_results_manager: Optional[EvalSetResultsManager] = None`
- Persist results per eval set (a single save aggregating all `EvalCaseResult`s), aligning `AgentEvaluator` with existing CLI/Web/API (`LocalEvalService`) persistence behavior.
- Resolve `app_name` from explicit input first, then derive from `agent_module` (including `.agent` suffix handling).
- Save results before failure assertion so failed eval runs still leave artifacts for inspection.
- Keep existing positional argument behavior by appending new parameters at the end of public method signatures.
- Add/extend tests to verify:
  - explicit and derived `app_name`
  - save-on-failure behavior
  - argument propagation from `evaluate()` to `evaluate_eval_set()`
  - positional-argument backward compatibility
- Add an integration usage example for `app_name` omission with `LocalEvalSetResultsManager`.
- For multi-run evals, all runs and eval cases are aggregated into a single result file per eval set (each run contributes one `EvalCaseResult`).

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

```
% pytest tests/unittests/evaluation

======================== 357 passed, 169 warnings in 9.68s =========================
```

**Manual End-to-End (E2E) Tests:**

```
% pytest tests/integration/test_with_test_file.py::test_with_single_test_file_saves_eval_set_result

======================== 1 passed, 14 warnings in 5.24s ========================
```

Verify a result file is created under: `<tmp_path>/<derived_app_name>/.adk/eval_history/*.evalset_result.json` (e.g., 1 file containing 2 `EvalCaseResult`s when num_runs=2 on a single-case eval fixture).
This is helpful for debugging failed integration tests.

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

### Additional context

- This PR intentionally preserves public API positional compatibility by appending new optional parameters at the tail of method signatures.
- A generated local eval result JSON file may exist in the working tree from manual verification and is intentionally not part of the code change.

Co-authored-by: Yi Liu <yiliuly@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4414 from ftnext:agent-evaluator-save-evalset-result 873973e549c0a4b25b83e1ef81e1b4148ab4e379
PiperOrigin-RevId: 962597058
2026-08-10 23:52:52 -07:00
George Weale 1026d2da4c test: use a plain-text corpus for the file retrieval fixture
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 959715205
2026-08-05 09:51:21 -07:00
Fede Kamelhar 625ef1aa69 feat(integrations): add OCI Generative AI provider
Adds OCIGenAILlm under integrations/oci/, for Google Gemini and other models
hosted on Oracle Cloud Infrastructure Generative AI. Optional install:
pip install google-adk[oci]. LLMRegistry auto-routing and the
google.adk.models import surface are preserved.

The OpenAI-compatible transport from the source PR (OCIGenAIOpenAILlm) is
not taken. It reimplemented the message, tool and response conversion plus
the streaming loop that OpenAILlm already provides; the right form is a
small subclass overriding the OpenAI client, which cannot live in
integrations/ while OpenAILlm is still experimental. It can land separately
once that settles.

The OCI client is now built once per instance rather than per request, so a
call no longer re-reads the OCI config from disk.

Merge https://github.com/google/adk-python/pull/5285

Closes #5069

Co-authored-by: George Weale <gweale@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/5285 from fede-kamel:feat/oci-generative-ai 0230acc0a93b7e43014f2ef3a8b89de463a50bd8
PiperOrigin-RevId: 955453382
2026-07-28 13:56:27 -07:00
Haran Rajkumar 0a62d39ff9 chore(agents): tag ManagedAgent traffic with a +managed_agent version suffix
ManagedAgent and Gemini(use_interactions_api=True) both reach the Interactions
API and surface identically as tool_name=google-adk in Google's usage pipeline,
with no way to tell them apart. Thread an optional framework_label through
merge_tracking_headers / get_tracking_headers / get_client_labels /
_get_default_labels, and have ManagedAgent emit google-adk/<version>+managed_agent
on the per-request extra_headers it sends to interactions.create, so its traffic
is distinguishable via the tool_version dimension while tool_name stays
google-adk. The suffix is applied on the request-time header path because that is
what reaches the Interactions wire (the per-request extra_headers override the
genai client's construction-time headers; verified by live capture). An explicit
framework_label takes precedence over the Agent Engine (+remote_reasoning_engine)
suffix; all other callers of merge_tracking_headers keep the no-arg default and
are unchanged. Follow-up to the ManagedAgent tracking-headers change.

Co-authored-by: Haran Rajkumar <haranrk@google.com>
PiperOrigin-RevId: 947239702
2026-07-13 14:19:30 -07:00
Haran Rajkumar cc444b6cbf docs(samples): add ManagedAgent remote MCP (Maps Grounding Lite) sample
Add a runnable sample wiring `ManagedAgent` to the Maps Grounding Lite MCP
server via `RemoteMcpServer`, with a `header_provider` callback that reads
`GOOGLE_MAPS_API_KEY` and sends it as the `X-Goog-Api-Key` header. Demonstrates
server-side remote MCP execution with runtime header minting.

Co-authored-by: Haran Rajkumar <haranrk@google.com>
PiperOrigin-RevId: 947137422
2026-07-13 11:07:40 -07:00
Haran Rajkumar 2e2ec09a76 feat(agents): support remote MCP servers for ManagedAgent with runtime header callbacks
Add `RemoteMcpServer`, a server-side remote MCP tool for `ManagedAgent`. The
Managed Agents / Interactions API runs the MCP server itself, so ADK only
forwards the server URL and headers as an `MCPServerParam` and never opens an
MCP session. A `header_provider` callback (the same contract as the `LlmAgent`
`McpToolset.header_provider`) mints auth headers at request time, driven by the
runner, and is merged over any static headers so a fresh token can be generated
per turn.

Only remote (HTTP/streamable) MCP servers are supported; raw
`types.Tool.mcp_servers` remains rejected. Includes a live integration test
against Maps Grounding Lite, scoped to the Gemini Developer API backend; the
Vertex Interactions endpoint does not yet accept the `mcp_server` tool param
(consistent with google-genai documenting `types.Tool.mcp_servers` as
unsupported on Vertex AI).

Co-authored-by: Haran Rajkumar <haranrk@google.com>
PiperOrigin-RevId: 945306712
2026-07-09 14:07:52 -07:00
Haran Rajkumar 527e3c1089 docs(samples): Add ManagedAgent code-execution sample
Add a runnable sample under contributing/samples/managed_agent/code_execution
showing how to use ManagedAgent with the server-side code execution tool. Since
ManagedAgent has no code_executor field, code execution is enabled by passing the
raw types.Tool(code_execution=types.ToolCodeExecution()) config in tools. The
sample exposes a root_agent in agent.py and ships a README plus a matching
single-turn live integration test that verifies a code-executed prime-sum
computation.

Co-authored-by: Haran Rajkumar <haranrk@google.com>
PiperOrigin-RevId: 943548907
2026-07-06 16:15:37 -07:00
Haran Rajkumar cf91b8443f feat(agents): add ManagedAgent backed by the Managed Agents API
Add ManagedAgent(BaseAgent), which drives the Managed Agents interactions.create
API directly. This first cut supports server-side tools only (ADK built-in tools
and raw types.Tool configs); client-executed tools (FunctionTool/callables) and
MCP are rejected with NotImplementedError. Multi-turn chaining reuses
previous_interaction_id and recovers the sandbox environment across turns.

Co-authored-by: Haran Rajkumar <haranrk@google.com>
PiperOrigin-RevId: 943406685
2026-07-06 11:38:04 -07:00
doughayden 883ff98aef fix(flows): terminate invocation at tool-level EUC
Merge https://github.com/google/adk-python/pull/5638

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: #5637

This change adds `invocation_context.end_invocation = True` after the auth event yield in `_postprocess_handle_function_calls_async`, mirroring the existing termination signal in `_resolve_toolset_auth`. Tool-level auth now terminates symmetrically with toolset-level auth at the EUC, instead of continuing for one more LLM call.

### Testing Plan

**Unit Tests:**

- [x] I have added or updated unit tests for my change.
- [x] All unit tests pass locally.

Three existing tests in `test_functions_request_euc.py` had assertions tied to the trailing post-EUC LLM call:

- `test_function_request_euc`: adds `assert len(mock_model.requests) == 1` to anchor the new termination behavior.
- `test_function_get_auth_response`: `events[-3]` → `events[-2]` for the auth event lookup, since the auth event is now second-to-last.
- `test_function_get_auth_response_partial`: same `events[-3]` → `events[-2]` change, plus the two `len(mock_model.requests)` assertions drop by 1 (3 → 2 and 4 → 3).

```
$ pytest tests/unittests/flows/llm_flows/test_functions_request_euc.py
======================== 3 passed, 17 warnings in 1.31s ========================

$ pytest tests/unittests/
=============== 5695 passed, 2308 warnings in 122.89s (0:02:02) ================
```

**Manual End-to-End (E2E) Tests:**

A self-contained Runner-based reproduction is at https://github.com/doughayden/adk-issue-examples/tree/main/04-tool_level_auth_continuation. The agent definition (`agent.py`) wires up an `OpenAPIToolset` against a local OAuth2 test server. `main.py` constructs an `InMemoryRunner`, applies the workaround for #5327 (`get_auth_config = lambda: None`) at runtime to land on the tool-level auth path, and sends a tool-triggering prompt. The `--apply-fix` flag monkey-patches the proposed fix to demonstrate the resolution end-to-end.

Without the fix:

```
👤 User: What's the weather in San Francisco?
🌤️  Weather Assistant event stream:

    [function_call] get_weather by WeatherAssistant
    [auth_event] adk_request_credential by WeatherAssistant
    [function_response] get_weather by WeatherAssistant
    [post_euc_text] WeatherAssistant: "I'm sorry, I cannot retrieve the weather for San Francisco at the moment. It ..."

Event counts:
    function_calls: 1
    auth_events: 1
    function_responses: 1
    text_events: 1
    post_euc_text_events: 1

 Bug reproduced: 1 text event(s) after the EUC (agent loop continued past adk_request_credential).
```

With the fix:

```
👤 User: What's the weather in San Francisco?
🌤️  Weather Assistant event stream:

    [function_call] get_weather by WeatherAssistant
    [auth_event] adk_request_credential by WeatherAssistant
    [function_response] get_weather by WeatherAssistant

Event counts:
    function_calls: 1
    auth_events: 1
    function_responses: 1
    text_events: 0
    post_euc_text_events: 0

 Fix verified: no LLM events after the EUC.
```

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

### Additional context

**Alternative considered:**

A reorder of the yields (yield `auth_event` last so `last_event.is_final_response()` returns True) would also fix the loop termination in a single iteration without needing the flag. I went with `end_invocation = True` to preserve the observable event order and to match the existing pattern in `_resolve_toolset_auth`. Happy to switch if maintainers prefer the reorder.

**Related:**

The same yield site at lines 1126-1130 also produces `tool_confirmation_event` for HITL with the same `long_running_tool_ids` shape and the same termination gap. This PR scopes to `auth_event` only. Happy to open a follow-up PR with the same fix for `tool_confirmation_event` if the team agrees with the approach here.

Co-authored-by: George Weale <gweale@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/5638 from doughayden:fix/tool-level-auth-terminates-at-euc 0a04d30aae4a284c8234218ac4e82e1f723bc9c1
PiperOrigin-RevId: 932731604
2026-06-15 16:28:59 -07:00
Google Team Member dc6fbd8fae refactor: Implement the auth provider using Agent Identity Credentials service
PiperOrigin-RevId: 931503059
2026-06-12 22:31:23 -07:00
Google Team Member c423fcd987 refactor: Move the IamConnectorCredential service depedency to a seperate file
PiperOrigin-RevId: 931088283
2026-06-12 05:03:07 -07:00
Haran Rajkumar 4100a24021 chore: replace vertexai with enterprise in samples and docs
Co-authored-by: Haran Rajkumar <haranrk@google.com>
PiperOrigin-RevId: 930146494
2026-06-10 16:34:15 -07:00
George Weale 020683bb7b chore: internal changes
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 929293376
2026-06-09 11:03:49 -07:00
George Weale 68785f53cf chore: edit docs
Change-Id: I47379cb495725595571ae5274ad34d8201ba1ca3
2026-05-22 11:41:51 -07:00
George Weale a4f394e139 chore: edit files
Change-Id: I4e3e3e9f1846520f3fda86cc83453b30bdd336ef
2026-05-22 10:47:37 -07:00
Sasha Sobran 162279358c chore: switch main to v2.0.0 GA (transition to v2)
Co-authored-by: Bo Yang <ybo@google.com>
Co-authored-by: Wei Sun (Jack) <weisun@google.com>
Co-authored-by: George Weale <gweale@google.com>
Co-authored-by: Swapnil Agarwal <swapnilag@google.com>
Co-authored-by: Xuan Yang <xygoogle@google.com>
Co-authored-by: Shangjie Chen <deanchen@google.com>
Co-authored-by: Yifan Wang <wanyif@google.com>
Co-authored-by: Kathy Wu <wukathy@google.com>
2026-05-19 02:01:33 +00:00
Google Team Member 2343973531 fix: Fix misplaced pytest decorator on helper dataclass in 2LO integration tests
PiperOrigin-RevId: 907996031
2026-04-30 00:18:08 -07:00
Google Team Member ed8b31ce5f chore: migrate from gemini-1.* and gemini-2.0* to gemini-2.5-*
`gemini-1.*` and `gemini-2.0*` models are respectively deprecated and scheduled for shutdown on June 1, 2026. `gemini-2.5*` models are their successors.
No regressions in unit tests:
```
========================================================================================== 5583 passed, 2237 warnings in 84.91s (0:01:24) ===========================================================================================
```

PiperOrigin-RevId: 907663315
2026-04-29 10:34:22 -07:00
Google Team Member ad937fe1b8 fix: Fix GcpAuthProvider to return capitalized Bearer scheme
PiperOrigin-RevId: 906864805
2026-04-28 03:36:19 -07:00
Shangjie Chen 2565cc6872 chore: Format using pre-commit, resolving pyink, isort, trailing space, empty lines
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 904736532
2026-04-23 18:34:14 -07:00
Morgan Roux 110aecf7e0 chore: Replace old model gemini-2.0 references by 2.5
Merge https://github.com/google/adk-python/pull/4705

### Link to Issue or Description of Change

- Closes: #4666

**Problem:**
Gemini-2.0-flash model is still used in integration tests, but disabled for new users

**Solution:**
Replace all occurrences of Gemini-2.0-flash by Gemini-2.5-flash, in integration tests and docstrings.
Because gemini-2.0 is still enabled for some users, this PR doesn't clean the model from unit tests.

### Testing Plan
Run already existing unittests and integration tests

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4705 from morganroux:fix/issues/4666 3c390a2ed3abb7b2fc7bd99cfb801e8a2b1f5343
PiperOrigin-RevId: 900973552
2026-04-16 16:49:22 -07:00
Google Team Member 0acee3175a chore: Update dependencies and release configuration for the Agent Identity feature
PiperOrigin-RevId: 898786239
2026-04-12 22:51:19 -07:00
Google Team Member 9199189e57 feat(eval): Add ADK CLI for eval_set generation
PiperOrigin-RevId: 895946363
2026-04-07 09:43:35 -07:00
Google Team Member 0ad4de7350 ADK changes
PiperOrigin-RevId: 881782296
2026-03-10 21:48:28 -07:00
Google Team Member 36e76b98b3 ADK changes
PiperOrigin-RevId: 878768583
2026-03-04 18:48:47 -08:00
Kathy Wu ab4b9526fc chore: Move spanner tools to integration folder
Added a deprecation warning in the old tools/spanner/__init__.py

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 878742289
2026-03-04 17:24:31 -08:00
Sasha Sobran e6da417292 fix: propagate grounding and citation metadata in streaming responses
Co-authored-by: Sasha Sobran <asobran@google.com>
PiperOrigin-RevId: 868324488
2026-02-10 14:36:21 -08:00
Didier Durand 80ff067c6b docs: fixing typo in multiple files
Merge https://github.com/google/adk-python/pull/3944

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):** N/A

**2. Or, if no issue exists, describe the change:** fixing various typos in multiple files: see commit diffs for details

**Problem:**

Discovered typos while reading ADK repo

**Solution:**

Submitted this PR to fix them

### Testing Plan

N/A: changes only in comments, .md and docstrings.

**Unit Tests:**

- [N/A ] I have added or updated unit tests for my change.
- [X] All unit tests pass locally.

_Please include a summary of passed `pytest` results._

**Manual End-to-End (E2E) Tests:**

N/A

### Checklist

- [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [X] I have performed a self-review of my own code.
- [N/A] I have commented my code, particularly in hard-to-understand areas.
- [N/A] I have added tests that prove my fix is effective or that my feature works.
- [X] New and existing unit tests pass locally with my changes.
- [N/A] I have manually tested my changes end-to-end.
- [N/A] Any dependent changes have been merged and published in downstream modules.

### Additional context

N/A

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3944 from didier-durand:fix-typos-a 02378a488d9a87ac9b6b7397fe9ad7c393faf16a
PiperOrigin-RevId: 868245940
2026-02-10 11:38:22 -08:00
George Weale 2367901ec5 chore: Upgrade to headers to 2026
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 858763407
2026-01-20 14:50:09 -08:00
Josh Soref d672349ddf chore: Fix spelling in tests
Merge https://github.com/google/adk-python/pull/3402

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

### Testing Plan

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/19056081305/attempts/1#summary-54426435973

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/19056081446/attempts/1#summary-54426436321

**Unit Tests:**

- [ ] I have added or updated unit tests for my change.
- [ ] All unit tests pass locally.

_Please include a summary of passed `pytest` results._

**Manual End-to-End (E2E) Tests:**

_Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix._

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] I have added tests that prove my fix is effective or that my feature works.
- [ ] New and existing unit tests pass locally with my changes.
- [ ] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

### Additional context

- https://github.com/google/adk-python/pull/3382#issuecomment-3488654110

Co-authored-by: Liang Wu <wuliang@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3402 from jsoref:spelling-tests 3cf0439d0584e4557179c25596aadf3b5b7c3fa8
PiperOrigin-RevId: 829035089
2025-11-06 11:21:59 -08:00
Josh Soref aa1233608a chore: Fix spelling
Merge https://github.com/google/adk-python/pull/2447

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/16840838898/attempts/1#summary-47711379253

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/16840839269/attempts/1#summary-47711380479

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

I've included a couple of changes to make CI happy. Personally, I object to CI being in a state of "random drive by person who adds a blank line in the middle of a file must fix all the preexisting bugs in the file", but that appears to be the state for this repository.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2447 from jsoref:spelling d85398e7fd154d124d477c6af6181481a01f34e0
PiperOrigin-RevId: 827629615
2025-11-03 13:33:53 -08:00
Ankur Sharma 955632ce2c feat:Allow agent evaluation from modules ending in ".agent"
PiperOrigin-RevId: 822888194
2025-10-22 23:11:48 -07:00
Google Team Member 86097afe49 feat: Update AgentEvaluator to handle async ADK agent definitions
AgentEvaluator should recognize root_agent and get_agent_async as valid structures for ADK agent definitions.

PiperOrigin-RevId: 819976635
2025-10-16 13:06:31 -07:00
Douglas Reid 2b5acb98f5 feat(models): add support for gemma model via gemini api
Merge https://github.com/google/adk-python/pull/2857

Adds support for invoking Gemma models via the Gemini API endpoint. To support agentic function, callbacks are added which can extract and transform function calls and responses into user and model messages in the history.

This change is intended to allow developers to explore the use of Gemma models for agentic purposes without requiring local deployment of the models. This should ease the burden of experimentation and testing for developers.

A basic "hello world" style agent example is provided to demonstrate proper functioning of Gemma 3 models inside an Agent container, using the dice roll + prime check framework of similar examples for other models.

## Testing

### Testing Plan
- add and run integration and unit tests
- manual run of example `multi_tool_agent` from quickstart using new `Gemma` model
- manual run of `hello_world_gemma` agent

### Automated Test Results:
| Test Command | Results |
|----------------|---------|
| pytest ./tests/unittests | 4386 passed, 2849 warnings in 58.43s |
| pytest ./tests/unittests/models/test_google_llm.py | 100 passed, 4 warnings in 5.83s |
| pytest ./tests/integration/models/test_google_llm.py | 5 passed, 2 warnings in 3.73s |

### Manual Testing

Here is a log of `multi_tool_agent` run with locally-built wheel and using Gemma model.
```
❯ adk run multi_tool_agent
Log setup complete: /var/folders/bg/_133c0ds2kb7cn699cpmmh_h0061bp/T/agents_log/agent.20250904_152617.log
To access latest log: tail -F /var/folders/bg/_133c0ds2kb7cn699cpmmh_h0061bp/T/agents_log/agent.latest.log
/Users/<redacted>/venvs/adk-quickstart/lib/python3.11/site-packages/google/adk/cli/cli.py:143: UserWarning: [EXPERIMENTAL] InMemoryCredentialService: This feature is experimental and may change or be removed in future versions without notice. It may introduce breaking changes at any time.
  credential_service = InMemoryCredentialService()
/Users/<redacted>/venvs/adk-quickstart/lib/python3.11/site-packages/google/adk/auth/credential_service/in_memory_credential_service.py:33: UserWarning: [EXPERIMENTAL] BaseCredentialService: This feature is experimental and may change or be removed in future versions without notice. It may introduce breaking changes at any time.
  super().__init__()
Running agent weather_time_agent, type exit to exit.
[user]: what's the weather like today?
[weather_time_agent]: Which city are you asking about?

[user]: new york
[weather_time_agent]: OK. The weather in New York is sunny with a temperature of 25 degrees Celsius (77 degrees Fahrenheit).
```

And here is a snippet of a log generated with DEBUG level logging of the `hello_world_gemma` sample. It demonstrates how function calls are extracted and inserted based on Gemma model interactions:

```
...
2025-09-04 15:32:41,708 - DEBUG - google_llm.py:138 -
LLM Request:
-----------------------------------------------------------
System Instruction:
None
-----------------------------------------------------------
Contents:
{"parts":[{"text":"\n      You roll dice and answer questions about the outcome of the dice rolls.\n      You can roll dice of different sizes...\n"}],"role":"user"}
{"parts":[{"text":"Hi, introduce yourself."}],"role":"user"}
{"parts":[{"text":"Hello! I am data_processing_agent, a hello world agent that can roll many-sided dice and check if numbers are prime. I'm ready to assist you with those tasks. Let's begin!\n\n\n\n"}],"role":"model"}
{"parts":[{"text":"Roll a die with 100 sides and check if it is prime"}],"role":"user"}
{"parts":[{"text":"{\"args\":{\"sides\":100},\"name\":\"roll_die\"}"}],"role":"model"}
{"parts":[{"text":"Invoking tool `roll_die` produced: `{\"result\": 82}`."}],"role":"user"}
{"parts":[{"text":"{\"args\":{\"nums\":[82]},\"name\":\"check_prime\"}"}],"role":"model"}
{"parts":[{"text":"Invoking tool `check_prime` produced: `{\"result\": \"No prime numbers found.\"}`."}],"role":"user"}
{"parts":[{"text":"The die roll was 82, and it is not a prime number.\n\n\n\n"}],"role":"model"}
{"parts":[{"text":"Roll it again."}],"role":"user"}
-----------------------------------------------------------
Functions:

-----------------------------------------------------------

2025-09-04 15:32:41,708 - INFO - models.py:8165 - AFC is enabled with max remote calls: 10.
2025-09-04 15:32:42,693 - INFO - google_llm.py:180 - Response received from the model.
2025-09-04 15:32:42,693 - DEBUG - google_llm.py:181 -
LLM Response:
-----------------------------------------------------------
Text:
{"args":{"sides":100},"name":"roll_die"}
-----------------------------------------------------------
...
```
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2857 from douglas-reid:add-gemma-via-api e6d015f6a9ccbcf20ef7a7af8e4bbe1e9a5936b6
PiperOrigin-RevId: 816451001
2025-10-07 17:38:35 -07:00
Ankur Sharma 65554d6621 chore: Update AgentEvaluator to use EvalConfig
We updated the one of the public methods on AgentEvaluator to take in eval metric configurations using a more formal EvalConfig data model.

We also mark "criteria" field on the method as deprecated.

Updated some integration test cases.

PiperOrigin-RevId: 814314134
2025-10-02 13:43:44 -07:00
Google Team Member 103e88e95f test: Add evaluation for BigQuery tools
We should treat this as the first step towards building a robust eval story for BQ tools.

PiperOrigin-RevId: 807247053
2025-09-15 08:16:33 -07:00
Wei Sun (Jack) a360bc2542 docs: Clean up docs in sample
PiperOrigin-RevId: 798284758
2025-08-22 11:36:58 -07:00
Xiang (Sean) Zhou 927c75f0ee chore: Replace imports by importing from actual module instead of from package (__init__.py)
PiperOrigin-RevId: 786342250
2025-07-23 10:49:43 -07:00
Ankur Sharma 0bd05df471 feat: Add Safety evaluator metric
We add a new metric for evaluating safety of Agent's response to ADK Eval. We delegate the actual implementation to Vertex Gen AI Eval SDK, so using this metric will require GCP project.

As a part of this change, we created (refactored) a simple Facade for vertex gen ai eval sdk.

PiperOrigin-RevId: 778580406
2025-07-02 11:30:31 -07:00
Ankur Sharma 04de3e197d fix: Adding detailed information on each metric evaluation
Additionally, few other small changes.
*   Updated a test fixture to support the latest eval data schema. Somehow I missed doing that previously.
*   Updated the `evaluation_generator.py` to use `run_async`, instead of `run`.
*   Also, raise an informed error when dependencies required eval are not installed.
*   Also, changed the behavior of AgentEvaluator.evaluate method to run all the evals, instead of failing at the first eval metric failure.

PiperOrigin-RevId: 775919127
2025-06-25 18:32:02 -07:00
Genquan Duan f33e0903b2 feat: Add ADK examples for litellm with add_function_to_prompt
Add examples for for https://github.com/google/adk-python/issues/1273

PiperOrigin-RevId: 775352677
2025-06-24 13:08:44 -07:00
Liang Wu e384fa4ad7 chore: fix previously skipped isort issue
PiperOrigin-RevId: 772224853
2025-06-16 16:57:46 -07:00
Google Team Member aafa80bd85 fix: stream in litellm + adk and add corresponding integration tests
Fixes https://github.com/google/adk-python/issues/1368

PiperOrigin-RevId: 772218385
2025-06-16 16:37:14 -07:00
Google Team Member 8e285874da feat: Add integration tests for litellm with and without turn on add_function_to_prompt
Add experiments for https://github.com/google/adk-python/issues/1273

PiperOrigin-RevId: 771145715
2025-06-13 10:37:09 -07:00
Wei Sun (Jack) a09781142a chore: Removes LlmAgent.examples field, which was already abandoned before 0.1 version
For context: tools/example_tool.py was created to replace LlmAgent.example

Also removes relevant usage in tests.

PiperOrigin-RevId: 768193042
2025-06-06 13:17:10 -07:00
Selcuk Gun 41b33d4a0a Move public_utils to utils in tests
Renamed conflicting utils.py as testing_utils.py

PiperOrigin-RevId: 761715808
2025-05-21 16:35:11 -07:00
Xiang (Sean) Zhou 3f117391a5 refactor: remote remote agent as there is no use case and it's not implemented properly
PiperOrigin-RevId: 760652423
2025-05-19 09:24:37 -07:00
Wei Sun (Jack) 729001fc0b chore: logger = logging.getLogger(__name__) --> logger = logging.getLogger('google_adk.' + __name__)
PiperOrigin-RevId: 760019467
2025-05-17 09:47:55 -07:00
Ankur Sharma 1c23556225 Updated test cases to use the new EvalSet schema to store test data. Also, added a utility to help migrate existing tests files to the new schema.
Also, migrated existing test files to the new schema and deleted test session files as they are no longer needed.

PiperOrigin-RevId: 759318735
2025-05-15 15:10:06 -07:00