Commit f4aa037
authored
feat(scripts): add latency report and scope-aware quality eval (#156)
* Add latency report, scope-aware quality eval, and sample reports
- Rename trace_latency to latency_report for consistency with quality_report
- Add --report and --output-json flags to latency_report
- Add --session flag to quality_report for single-session evaluation
- Add --config flag for scope-aware eval with declined category
- Add sample_quality_report.md and sample_latency_report.md
- Update README with scope-aware eval docs and latency report section
- Add .env and example run artifacts to .gitignore
* Improve multi-turn support, A2A null handling, and scope evaluation
- get_user_input: return last user message (not first) for multi-turn alignment
- get_a2a_response: handle null/empty A2A content as "(no response)" instead of
falling through to earlier turns, preventing question/response mismatches
- Always include declined category in response_usefulness metrics — lets the
LLM judge correctly classify legitimate scope declines even without --config
- _load_agent_config: implement auto-discovery of eval/data/agent_context.json
(the docstring already described this behavior but the code returned None)
- Add Declined Sessions section to markdown report
- Add 14 new tests covering get_user_input and get_a2a_response
* Address PR #156 review: bug fixes, dead code removal, tests, logging
quality_report.py:
- B2: Replace stale config cache with dict keyed by config_path
- B3: Raise FileNotFoundError instead of sys.exit for missing config
- M3: Consistent get_a2a_response return shape (always tuple)
- M4: Comment explaining is_a2a=True for "(no response)" sessions
- M7: Remove duplicate import json as _json
- M9: Document that 'reason' field in --config is documentation-only
- L7: Store samples as None (not string) when unset
- Fail fast with clear error when --session-ids-file has no valid IDs
latency_report.py:
- H1: Remove dead parse_period() function and unused import re
- H4: Add _load_dotenv(), _configure_logging(), --env CLI flag
- M6: Document that stitch_a2a_traces mutates traces in place
- M10: Extract A2A noise events to module-level frozenset
- L2: Move Counter import and _script_dir to module level
- L3: Replace print() with logger.* for operational messages
- Second review: --output-json - sends human output to stderr
tests:
- H2: Add test_latency_report_helpers.py (26 tests for pure helpers)
- H3: Add TestBuildScopeContext (6 tests) and TestLoadAgentConfig (4 tests)
- M1: Remove unused import pytest from top level
- Update test_invalid_json_string for M3 consistent return shape
Formatting: pyink + isort applied via autoformat.sh
* Address second review: autoformat scripts/, new findings, polish
B1: Add scripts/ to autoformat.sh scope; run pyink+isort on both
scripts (now consistent 2-space indent throughout)
N1: Guard --sdk-tree + --output-json - (SDK trace.render() writes
directly to stdout, bypassing the stderr routing)
N4: Add test_cache_isolates_paths — proves two different config paths
return two different configs (regression guard for B2 fix)
N5: Include session ID in A2A JSON parse warning for debuggability
M2: Add docstring to get_eval_metrics documenting returned metrics
and the always-present declined category
M8: Qualify run_eval.py path in --session-ids-file help text
N3: Add --env example to README direct-Python usage section
L4: Complete latency_report.py module docstring with all flags
(--no-waterfall, --sdk-tree, --report, --output-json, --env)
79 tests pass, autoformat clean (pyink + isort).
* Address remaining review items: rebase, polish, cleanup
L1: Remove GFM trailing whitespace from sample markdown files
L6: Add comment about approximate alignment in waterfall markers
L8: Clarify --time-period help text in latency_report.py
L9: Scope .gitignore *.log to scripts/ and examples/ only
L10: Remove duplicate env validation from latency_report.sh
(Python script now handles validation with structured logging)
L11: Rebased onto origin/main (17 commits ahead, 0 behind)
79 tests pass, autoformat clean.
* Regenerate sample reports from live data
Ran both scripts against live BigQuery data to verify end-to-end:
- quality_report.py --limit 20 --report --samples 3
- latency_report.py --limit 3 --report
Sanitized project-specific details for the sample files.
Stripped GFM trailing whitespace (L1).
* Align --time-period default between quality and latency scripts
Change latency_report.py --time-period default from None to "all" to
match quality_report.py. Convert "all" back to None before building
the TraceFilter so runtime behavior is unchanged.
Also regenerate sample_latency_report.md from live data and add .adk/
to .gitignore.1 parent 917a8fa commit f4aa037
11 files changed
Lines changed: 2224 additions & 285 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
| 16 | + | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
18 | 20 | | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
19 | 28 | | |
20 | 29 | | |
21 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
5 | 10 | | |
6 | 11 | | |
7 | 12 | | |
| |||
56 | 61 | | |
57 | 62 | | |
58 | 63 | | |
| 64 | + | |
59 | 65 | | |
60 | 66 | | |
61 | 67 | | |
| |||
98 | 104 | | |
99 | 105 | | |
100 | 106 | | |
101 | | - | |
| 107 | + | |
102 | 108 | | |
103 | 109 | | |
104 | 110 | | |
105 | 111 | | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
106 | 159 | | |
107 | 160 | | |
108 | 161 | | |
| |||
111 | 164 | | |
112 | 165 | | |
113 | 166 | | |
114 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
0 commit comments