fix(streaming): aggregate model info per invocation, not per session - #205
fix(streaming): aggregate model info per invocation, not per session#205LeonxLJX wants to merge 5 commits into
Conversation
_extract_model_info_from_trace walked trace.all_spans for every invocation, so each invocation reported the session-wide token/model aggregates and any summation triple-counted usage. The converter now records the LLM spans each invocation was built from (ConversionResult.invocation_llm_spans, kept in lockstep through ADK/GenAI conversion and deduplication) and ws_server aggregates only those spans per invocation. Fixes agentevals-dev#204
krisztianfekete
left a comment
There was a problem hiding this comment.
Thanks, added a few comments, please check them out!
- Multi-turn: when turn count matches LLM span count, map turn n to span n; otherwise attribute all spans to the first turn (empty for the rest) so session totals stay honest instead of every turn reporting all spans. - Dedup: merge dropped duplicate invocations' LLM spans into the survivor so their token spend is not discarded; always return the (invocations, spans) tuple and updated the test call sites accordingly. - ws_server: drop the dead \if trace\ guard (convert_traces is 1:1 with traces), log loudly on invocation_llm_spans index drift, remove the unused Trace import, and stop re-filtering LLM spans (a generate_content-only trace would otherwise be dropped to nothing even with usage metadata). The model info aggregator is now a @staticmethod. - find_adk_llm_spans_in returns both call_llm and generate_content spans so a provider generate_content span's temperature/model no longer vanish. - Tests: drive a real TraceSession through _extract_invocations instead of calling the aggregator on hand-picked spans; pin the nested sub-agent double-count limitation; add a dedup span-merge test.
|
Thanks for the thorough review @krisztianfekete! I've pushed
Test run on the touched areas: 249 passed (remaining full-suite failures are pre-existing env issues — API keys / installed-distribution version — unrelated to this change). |
- Add strict=True to zip() in genai_converter.py (B905) - Rename unused trace_idx to _trace_idx in ws_server.py (B007) - Run ruff format on genai_converter.py, test_genai_converter.py, test_model_info.py
- Restore 'call_llm_spans or generate_content_spans' return order as krisztianfekete requested (the combined list doesn't help because generate_content spans never carry ADK llm_request/llm_response attrs) - Fix garbled arrow characters in test_genai_converter.py docstring
|
Thanks again for the thorough review @krisztianfekete — I've gone back through all of your points. Summary of where each one landed, so nothing is implicit: Addressed in code
Deliberately not fixed — would like your call
Test quality
Ready for another look whenever you have time. |
Fixes #204
_extract_model_info_from_tracewalkedtrace.all_spansfor every invocation, so each invocation in a session reported the same session-wide token/model/provider aggregates, and anything summing them triple-counted usage.What changed
ConversionResultnow carriesinvocation_llm_spans— the LLM spans each invocation was built from, kept in lockstep through ADK conversion, GenAI single-turn conversion, and deduplication.ws_server._extract_model_info_from_trace→_extract_model_info_from_llm_spans: aggregates only the spans belonging to that invocation.Verification
tests/test_model_info.py(converter span tracking + per-invocation token aggregation + empty-span edge case).maintoo).Verified live with the zero-code examples: each invocation now reports its own
in= / out=numbers instead of the session aggregate.