feat: use GenAI util for Google ADK spans#199
Conversation
a535875 to
a705b63
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the LoongSuite Google ADK instrumentation to route AGENT, LLM, and TOOL span lifecycles through the shared opentelemetry-util-genai utilities, improving correctness for streaming responses, concurrent invocations, and GenAI semantic convention attributes (including gen_ai.span.kind). It also adds a local otel-gui smoke script, refreshes docs, and expands integration tests around concurrency and runner finalization.
Changes:
- Refactor the Google ADK plugin to use GenAI util invocation objects/handler for span lifecycle, streaming output accumulation, and span-kind attributes.
- Add new test coverage for streaming TTFT, concurrent LLM/tool/agent callbacks, and runner span finalization on root “final” events.
- Update README + changelog and add an
otelgui_smoke.pyexample for local trace verification.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| instrumentation-loongsuite/loongsuite-instrumentation-google-adk/src/opentelemetry/instrumentation/google_adk/internal/_plugin.py | Refactors span lifecycle management to GenAI util patterns; adds streaming + concurrency handling helpers. |
| instrumentation-loongsuite/loongsuite-instrumentation-google-adk/tests/test_plugin_integration.py | Expands tests for gen_ai.span.kind, runner finalization, streaming TTFT, and concurrency isolation. |
| instrumentation-loongsuite/loongsuite-instrumentation-google-adk/tests/test_integration.py | Adds metric datapoint helper and strengthens metrics assertions; removes a weak/placeholder error-span test. |
| instrumentation-loongsuite/loongsuite-instrumentation-google-adk/examples/otelgui_smoke.py | Adds a standalone smoke scenario script for non-streaming, streaming, and concurrent runs. |
| instrumentation-loongsuite/loongsuite-instrumentation-google-adk/README.md | Updates env var guidance for GenAI semconv opt-in and message capture modes; documents smoke scenarios. |
| instrumentation-loongsuite/loongsuite-instrumentation-google-adk/pyproject.toml | Aligns opentelemetry-util-genai dependency declaration with other packages. |
| instrumentation-loongsuite/loongsuite-instrumentation-google-adk/CHANGELOG.md | Documents the span lifecycle/attribute changes and streaming/concurrency fixes. |
Comments suppressed due to low confidence (1)
instrumentation-loongsuite/loongsuite-instrumentation-google-adk/src/opentelemetry/instrumentation/google_adk/internal/_plugin.py:816
_resolve_model_namedeclaresrequest_key: str, but callers pass therequest_keyreturned from_find_active_llm_invocation, which can beNone. The current implementation happens to guardrequest_keyusage, but the annotation/docstring should be updated toOptional[str]to reflect actual call sites and avoid type-checking confusion.
def _resolve_model_name(
self,
llm_response: LlmResponse,
request_key: str,
invocation: LLMInvocation,
) -> str:
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self._handler.start_llm(invocation) | ||
| self._detach_current_context(invocation) | ||
|
|
||
| # Store invocation for later use | ||
| session_id = callback_context._invocation_context.session.id | ||
| request_key = f"llm_{id(llm_request)}_{session_id}" | ||
| request_key = self._llm_key(callback_context, llm_request) | ||
| self._active_llm_invocations[request_key] = invocation | ||
| _ACTIVE_LLM_REQUEST_KEY.set(request_key) |
| if invocation.context_token is None: | ||
| return | ||
| try: | ||
| otel_context.detach(invocation.context_token) |
Description
This PR updates the LoongSuite Google ADK instrumentation to construct GenAI spans through the shared GenAI util lifecycle, preserving streaming state, concurrent invocations, response metadata, and
gen_ai.span.kindattributes for agent/tool/LLM spans. It also adds a local otel-gui smoke example covering non-streaming, streaming, and concurrent Google ADK calls, updates documentation, and expands tests for callback concurrency and runner span finalization.Fixes # (N/A)
Type of change
How Has This Been Tested?
tox -e precommitOTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_ONLY python -m tox -c tox-loongsuite.ini -e py312-test-loongsuite-instrumentation-google-adk-latestOTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_ONLY python -m tox -c tox-loongsuite.ini -e py39-test-loongsuite-instrumentation-google-adk-latestpython -m tox -c tox-loongsuite.ini -e lint-loongsuite-instrumentation-google-adkpython instrumentation-loongsuite/loongsuite-instrumentation-google-adk/examples/otelgui_smoke.py --scenario allDoes This PR Require a Core Repo Change?
Checklist:
See contributing.md for styleguide, changelog guidelines, and more.