google / google/adk-python

Playground eval history: clicking failed eval result crashes with 'e is not iterable' in formatToolUses

Đang mở
#4,657 3 bình luận 0 reaction 3 người được giao Được @GWeale nhận Xem trên GitHub
needs review web
Ngôn ngữ chính
Python
Star
21.5k
Fork
4k
Merge trung bình
1 ngày 14 giờ
Pull request đã merge (30 ngày)
37

Mô tả

## Describe the bug

When viewing eval results in the ADK playground web UI, clicking on a **failed** eval case result (to view the session details) crashes with a JavaScript error. Clicking on **passed** eval results works correctly.

**Error from browser console:**

```
Uncaught TypeError: e is not iterable
at t.formatToolUses (main-QQBY56NS.js:4105:21033)
at t.addEvalFieldsToBotEvent (main-QQBY56NS.js:4105:21654)
at t.addEvalCaseResultToEvents (main-QQBY56NS.js:4105:21447)
```

## Root cause

In the eval tab component, `addEvalFieldsToBotEvent` calls `formatToolUses` when a metric has `evalStatus === 2` (fail) and the metric name is `tool_trajectory_avg_score`:

```javascript
// addEvalFieldsToBotEvent calls:
e.actualInvocationToolUses = this.formatToolUses(A.actualInvocation.intermediateData.toolUses)
e.expectedInvocationToolUses = this.formatToolUses(A.expectedInvocation.intermediateData.toolUses)
```

`formatToolUses` iterates its argument with `for...of` but does not guard against `null`/`undefined`:

```javascript
formatToolUses(e) {
let A = [];
for (let i of e) // crashes if e is null/undefined
A.push({name: i.name, args: i.args});
return A;
}
```

When eval cases don't include `tool_uses` in their `intermediate_data` (or when `intermediateData.toolUses` is serialized as `null`), `expectedInvocation.intermediateData.toolUses` is `null`, causing the crash.

This code path is only reached for **failed** evals because the `tool_trajectory_avg_score` status check (`evalStatus === 2`) only triggers for failures. Passed evals never enter this branch.

## Steps to reproduce

1. Create a minimal agent that uses `AgentTool`:

```python
from google.adk.agents import Agent, SequentialAgent
from google.adk.tools.agent_tool import AgentTool

sub_agent = Agent(name="sub", model="gemini-2.5-flash", instruction="Say hello")
workflow = SequentialAgent(name="workflow", sub_agents=[sub_agent])
root_agent = Agent(
name="my_agent",
model="gemini-2.5-flash",
instruction="Use workflow tool to respond.",
tools=[AgentTool(agent=workflow)],
)
```

2. Create an evalset file (`my_eval.evalset.json`) **without** expected `tool_uses`:

```json
{
"eval_set_id": "my_eval",
"eval_cases": [
{
"eval_id": "simple_test",
"conversation": [
{
"user_content": {
"parts": [{"text": "Hello"}]
}
}
],
"session_input": {
"app_name": "my_agent",
"user_id": "test_user",
"state": {}
}
}
]
}
```

3. Start the playground: `adk web ./agents/ --port 8501`
4. Go to the Eval tab, select `my_eval`, select the test case, run with `tool_trajectory_avg_score` metric
5. After the eval completes, go to the History section
6. Click on the result button for a **FAIL** entry -- the UI crashes with the error above

## Expected behavior

Clicking on failed eval results should display the session details, same as for passed results.

## Suggested fix

Add a null guard in `formatToolUses`:

```javascript
formatToolUses(e) {
if (!e) return [];
let A = [];
for (let i of e) A.push({name: i.name, args: i.args});
return A;
}
```

## Environment

- `google-adk` version: 1.25.1
- Python: 3.13
- Browser: Chrome (latest)
- OS: macOS

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.