Skip to content

Commit 8dd710c

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix-thought-signature-pruning
2 parents c8080ea + 8addc44 commit 8dd710c

187 files changed

Lines changed: 10758 additions & 705 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.

.github/workflows/analyze-releases-for-adk-docs-updates.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ jobs:
4545

4646
steps:
4747
- name: Checkout repository
48-
uses: actions/checkout@v6
48+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
4949

5050
- name: Set up Python
51-
uses: actions/setup-python@v6
51+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
5252
with:
5353
python-version: '3.11'
5454

5555
- name: Load adk-bot SSH Private Key
56-
uses: webfactory/ssh-agent@v0.9.1
56+
uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
5757
with:
5858
ssh-private-key: ${{ secrets.ADK_BOT_SSH_PRIVATE_KEY }}
5959

@@ -64,7 +64,7 @@ jobs:
6464
6565
- name: Restore session DB from cache
6666
if: ${{ github.event.inputs.resume == 'true' }}
67-
uses: actions/cache/restore@v4
67+
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
6868
with:
6969
path: contributing/samples/adk_team/adk_documentation/adk_release_analyzer/sessions.db
7070
key: analyzer-session-db-${{ github.run_id }}-${{ github.run_attempt }}
@@ -102,7 +102,7 @@ jobs:
102102
103103
- name: Save session DB to cache
104104
if: always()
105-
uses: actions/cache/save@v4
105+
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
106106
with:
107107
path: contributing/samples/adk_team/adk_documentation/adk_release_analyzer/sessions.db
108108
key: analyzer-session-db-${{ github.run_id }}-${{ github.run_attempt }}

.github/workflows/release-finalize.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
echo "manifest_file=.github/.release-please-manifest.json" >> $GITHUB_OUTPUT
6060
fi
6161
62-
- uses: actions/checkout@v6
62+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
6363
if: steps.check.outputs.is_release_pr == 'true'
6464
with:
6565
ref: ${{ github.event.pull_request.base.ref }}

.github/workflows/release-update-adk-web.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636

3737
steps:
3838
- name: Checkout repository
39-
uses: actions/checkout@v6
39+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
4040
with:
4141
persist-credentials: false
4242

@@ -78,7 +78,7 @@ jobs:
7878
echo "email=$(echo "$USER_JSON" | jq -r '.id')+$(echo "$USER_JSON" | jq -r '.login')@users.noreply.github.com" >> $GITHUB_OUTPUT
7979
8080
- name: Create Pull Request
81-
uses: peter-evans/create-pull-request@v6
81+
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6
8282
with:
8383
token: ${{ secrets.RELEASE_PAT }}
8484
commit-message: "Update compiled adk web files from ${{ github.event.inputs.adk_web_repo }}@${{ github.event.inputs.adk_web_tag || 'latest' }}"

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,11 @@ repos:
7272
exclude: (?i)SKILL\.md$
7373
additional_dependencies:
7474
- mdformat-gfm
75+
- repo: https://github.com/codespell-project/codespell
76+
rev: v2.4.2
77+
hooks:
78+
- id: codespell
79+
# Configuration (skip globs, ignored words) lives in the
80+
# [tool.codespell] table in pyproject.toml.
81+
additional_dependencies:
82+
- tomli
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# ADK evaluation samples
2+
3+
## Overview
4+
5+
A family of single-concept samples that each show one way to evaluate the *same*
6+
shared home-automation agent with the `adk eval` CLI. Every sample points `adk eval` at one agent and differs only in its eval data and criteria, so you can
7+
compare evaluation techniques (deterministic reference matching, custom metrics,
8+
LLM-as-a-judge, rubrics, and user simulation) side by side.
9+
10+
## The shared agent
11+
12+
`home_automation_agent/` is a small agent that controls smart-home devices and
13+
temperatures. Its five tools (`get_device_info`, `set_device_info`,
14+
`get_temperature`, `set_temperature`, `list_devices`) are deterministic, backed by
15+
in-memory state, so eval trajectories are reproducible. The module exposes
16+
`reset_data()`, which `adk eval` calls to reset that state between eval cases.
17+
18+
Every sample evaluates this same agent. `adk eval` takes the agent path and the
19+
eval-set path as two separate arguments, so each sub-sample folder holds only
20+
eval data and its criteria config, never a copy of the agent code.
21+
22+
## How evaluation runs
23+
24+
`adk eval` runs in two phases: (1) live inference, where it actually runs the
25+
agent against each eval input to produce responses and tool calls, and then (2)
26+
scoring, where it compares that output against the case's criteria. Because phase 1
27+
runs the real agent, a model credential is required for every sample, even the
28+
deterministic ones. Provide a Gemini API key in `home_automation_agent/.env`,
29+
or configure Vertex.
30+
Samples that use an LLM judge or a user simulator make additional model calls, but
31+
they resolve through the same model registry and credentials.
32+
33+
Because live responses vary from run to run, the deterministic, reference-based
34+
criteria use lenient response thresholds (e.g. `response_match_score` at
35+
`0.5`) so that harmless phrasing differences don't fail an otherwise-correct
36+
answer.
37+
38+
## Samples
39+
40+
| Sample | Concept | Criteria |
41+
| ------------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------- |
42+
| [`basic_criteria`](./basic_criteria/) | Deterministic, reference-based scoring | `tool_trajectory_avg_score`, `response_match_score` |
43+
| [`test_file_vs_evalset`](./test_file_vs_evalset/) | `.test.json` vs `.evalset.json` conventions | `tool_trajectory_avg_score`, `response_match_score` |
44+
| [`custom_metric`](./custom_metric/) | Write your own metric | `temperature_safety_score` (custom) |
45+
| [`llm_judge_match`](./llm_judge_match/) | LLM-judged semantic match | `final_response_match_v2` |
46+
| [`rubric_criteria`](./rubric_criteria/) | LLM-judged quality via rubrics | `rubric_based_final_response_quality_v1`, `rubric_based_tool_use_quality_v1` |
47+
| [`user_simulation`](./user_simulation/) | Dynamically simulated user turns | `hallucinations_v1`, `per_turn_user_simulator_quality_v1` |
48+
49+
## Graph
50+
51+
```mermaid
52+
graph TD
53+
A[home_automation_agent] --> B(get_device_info)
54+
A --> C(set_device_info)
55+
A --> D(get_temperature)
56+
A --> E(set_temperature)
57+
A --> F(list_devices)
58+
```
59+
60+
## Related Guides
61+
62+
- Evaluation overview: https://adk.dev/evaluate/
63+
- Evaluation criteria reference: https://adk.dev/evaluate/criteria/
64+
- User simulation guide: https://adk.dev/evaluate/user-sim/
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Basic evaluation criteria
2+
3+
## Overview
4+
5+
Evaluates the shared home-automation agent with the two deterministic,
6+
reference-based criteria:
7+
8+
- `tool_trajectory_avg_score`: does the agent call the right tools with the
9+
right args? Each expected tool call (name + args) is compared against what the
10+
agent actually did.
11+
- `response_match_score`: ROUGE-1 word overlap between the agent's final
12+
response and a reference answer.
13+
14+
Both criteria are computed locally with no judge model, so this sample needs only
15+
a model credential for the agent's own inference (a Gemini API key or Vertex).
16+
17+
## Sample Inputs
18+
19+
The eval set (`home_automation.evalset.json`) contains two single-turn cases:
20+
21+
- `Turn off device_2.`
22+
- `What is the temperature in the Living Room?`
23+
24+
## How To
25+
26+
Run the sample from the workspace root:
27+
28+
```bash
29+
adk eval contributing/samples/evaluation/home_automation_agent \
30+
contributing/samples/evaluation/basic_criteria/home_automation.evalset.json \
31+
--config_file_path contributing/samples/evaluation/basic_criteria/eval_config.json \
32+
--print_detailed_results
33+
```
34+
35+
`adk eval` takes the agent folder and the eval-set file as two separate
36+
arguments, so this folder holds only eval data (`home_automation.evalset.json`),
37+
the criteria config (`eval_config.json`), and this README, with no agent code.
38+
39+
### `match_type` for tool trajectory
40+
41+
`tool_trajectory_avg_score` has a `match_type` (set to `EXACT` here in
42+
`eval_config.json`) that controls how the expected and actual tool calls are
43+
compared:
44+
45+
- `EXACT`: the actual tool calls must match the expected calls one-for-one, in
46+
the same order, with identical args. Use this when the trajectory is fully
47+
deterministic (as in this sample).
48+
- `IN_ORDER`: the expected calls must appear in the given order, but extra
49+
actual calls in between are tolerated. Useful when the agent may take
50+
additional, harmless steps.
51+
- `ANY_ORDER`: the expected calls must all appear, but order does not matter.
52+
Useful when the agent may reorder independent tool calls.
53+
54+
The `threshold` is `1.0`, so every expected call must match for the case to pass.
55+
56+
### Why `response_match_score` uses a `0.6` threshold
57+
58+
`adk eval` runs live inference, so the exact wording of the agent's final
59+
response varies from run to run (for example, "I have turned off device_2." vs
60+
"device_2 has been switched off."). `response_match_score` is a ROUGE-1 score,
61+
which measures word overlap rather than exact-string equality, so it tolerates
62+
this phrasing variation. The `0.6` threshold requires the response to share most
63+
of its wording with the reference while still allowing some rewording. Raise it
64+
toward `1.0` for stricter wording, lower it to tolerate more paraphrasing.
65+
66+
### Expectations captured from a real run
67+
68+
The expected `tool_uses` (tool names and args) in `home_automation.evalset.json`
69+
were captured from an actual `adk eval` run of the agent: run with
70+
`--print_detailed_results`, read the printed Actual-vs-Expected, then set the
71+
expected values to match what the agent really produced. The reference
72+
`final_response` for each case is an independently written natural answer (not a
73+
copy of the model output), which is exactly what ROUGE-1 is designed to tolerate.
74+
75+
## Related Guides
76+
77+
- Evaluation overview: https://adk.dev/evaluate/
78+
- Evaluation criteria reference: https://adk.dev/evaluate/criteria/
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"criteria": {
3+
"tool_trajectory_avg_score": {
4+
"threshold": 1.0,
5+
"match_type": "EXACT"
6+
},
7+
"response_match_score": 0.6
8+
}
9+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"eval_set_id": "basic_criteria",
3+
"name": "Basic deterministic criteria",
4+
"description": "Single-turn cases scored by tool trajectory and ROUGE-1.",
5+
"eval_cases": [
6+
{
7+
"eval_id": "turn_off_bedroom_device",
8+
"conversation": [
9+
{
10+
"invocation_id": "basic-1",
11+
"user_content": {
12+
"parts": [{"text": "Turn off device_2."}],
13+
"role": "user"
14+
},
15+
"final_response": {
16+
"parts": [{"text": "device_2 is now turned off."}],
17+
"role": "model"
18+
},
19+
"intermediate_data": {
20+
"tool_uses": [
21+
{"name": "set_device_info",
22+
"args": {"device_id": "device_2", "status": "OFF"}}
23+
],
24+
"intermediate_responses": []
25+
}
26+
}
27+
],
28+
"session_input": {
29+
"app_name": "home_automation_agent",
30+
"user_id": "user",
31+
"state": {}
32+
}
33+
},
34+
{
35+
"eval_id": "get_living_room_temperature",
36+
"conversation": [
37+
{
38+
"invocation_id": "basic-2",
39+
"user_content": {
40+
"parts": [{"text": "What is the temperature in the Living Room?"}],
41+
"role": "user"
42+
},
43+
"final_response": {
44+
"parts": [{"text": "The Living Room is 22 degrees Celsius."}],
45+
"role": "model"
46+
},
47+
"intermediate_data": {
48+
"tool_uses": [
49+
{"name": "get_temperature", "args": {"location": "Living Room"}}
50+
],
51+
"intermediate_responses": []
52+
}
53+
}
54+
],
55+
"session_input": {
56+
"app_name": "home_automation_agent",
57+
"user_id": "user",
58+
"state": {}
59+
}
60+
}
61+
]
62+
}

0 commit comments

Comments
 (0)