Files
google--adk-python/tests/integration
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
..
2026-01-20 14:50:09 -08:00
2026-01-20 14:50:09 -08:00
2026-01-20 14:50:09 -08:00
2025-04-17 21:47:59 +00:00