【WIP】feat: support pydantic-ai#189
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds an initial LoongSuite instrumentation package for Pydantic AI, including span normalization, metric recording, capability hooks, package metadata, tests, and tox entries.
Changes:
- Adds
loongsuite-instrumentation-pydantic-aipackage with instrumentor, span processor, and Pydantic AI capability integration. - Adds unit tests and test requirements for span normalization/metrics and ReAct step span wrapping.
- Adds tox test/lint environments for the new instrumentation.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
tox.ini |
Adds test/lint envs and commands for pydantic-ai instrumentation. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/tests/test_span_processor.py |
Adds unit tests and fakes for span processing/capability behavior. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/tests/requirements.latest.txt |
Adds latest test dependencies. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/src/opentelemetry/instrumentation/pydantic_ai/version.py |
Adds package version. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/src/opentelemetry/instrumentation/pydantic_ai/span_processor.py |
Adds span normalization and GenAI/ARMS metric recording. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/src/opentelemetry/instrumentation/pydantic_ai/package.py |
Declares instrumented Pydantic AI dependency. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/src/opentelemetry/instrumentation/pydantic_ai/capability.py |
Adds Pydantic AI capability hooks for agent/model/tool/node spans. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/src/opentelemetry/instrumentation/pydantic_ai/__init__.py |
Adds PydanticAIInstrumentor and global instrumentation setup/restore logic. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/src/opentelemetry/__init__.py |
Adds namespace package initializer. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/README.rst |
Adds package usage documentation. |
instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai/pyproject.toml |
Adds package metadata, dependencies, and entry point. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| -e util/opentelemetry-util-genai | ||
| -e instrumentation-loongsuite/loongsuite-instrumentation-pydantic-ai |
| ; instrumentation-pydantic-ai | ||
| py3{10,11,12,13,14}-test-instrumentation-pydantic-ai-latest | ||
| lint-instrumentation-pydantic-ai | ||
|
|
| agent and embedding instrumentation defaults and register the LoongSuite span | ||
| processor. Add ``LoongSuiteInstrumentationCapability`` to agents that need | ||
| ReAct STEP spans: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from opentelemetry.instrumentation.pydantic_ai import ( | ||
| LoongSuiteInstrumentationCapability, | ||
| PydanticAIInstrumentor, | ||
| ) | ||
| from pydantic_ai import Agent | ||
|
|
||
| PydanticAIInstrumentor().instrument() | ||
| agent = Agent( | ||
| "openai:gpt-4o-mini", | ||
| capabilities=[LoongSuiteInstrumentationCapability()], | ||
| ) |
| from opentelemetry.instrumentation.pydantic_ai.capability import ( | ||
| LoongSuiteInstrumentationCapability, | ||
| ) |
| lint-instrumentation-openai_agents-v2 | ||
|
|
||
| ; instrumentation-pydantic-ai | ||
| py3{10,11,12,13,14}-test-instrumentation-pydantic-ai-latest |
ralf0131
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Adapts pydantic-ai's native OTel instrumentation capability to LoongSuite GenAI semantic conventions: a PydanticAIInstrumentor that registers a LoongSuiteSpanProcessor + enables pydantic-ai defaults, and a LoongSuiteInstrumentationCapability that emits ReAct STEP spans. Well-scoped and tests cover the metrics + normalization paths.
Note: PR is marked [WIP]; focusing on design-level feedback.
Findings
- [Warning]
span_processor.py—_replace_readable_span_attributesmutatesspan._attributesdirectly inon_end.ReadableSpan._attributesis an OTel SDK private/immutable field (immutabledict), and the mutation only takes effect for exporters if this processor runs before the exporting processor. This relies on SDK internals and processor ordering, both of which can change across SDK upgrades. Prefer deriving the normalized attributes without touching a private attribute, or normalize onon_start/ before the span ends. - [Warning] Provider-LLM double-count suppression (
_is_provider_llm_span/_remember_provider_llm_trace) assumes the provider LLM span'son_endruns before the framework LLM span'son_end. For the typical nested case (provider span is inner → ends first) this works and is what the test exercises, but it's order-dependent: if the spans are not strictly nested, or processing order changes, the framework LLM metrics can be emitted in addition to the provider's → double counting. Consider de-duplicating by request/response id (e.g. sharedgen_ai.response.id) rather than relying on end-ordering. - [Info]
capability.py_is_model_request_nodeusestype(node).__name__ == "ModelRequestNode"— string-based type matching silently breaks if pydantic-ai renames the class. Preferisinstance(guarding the import) or duck-typing on the attributes you actually consume. - [Info]
__init__.py_restore_pydantic_ai_defaultspassesself._previous_agent_instrument or Falsetoinstrument_all; if a previously-capturedInstrumentationSettingsis falsy for any reason the restore silently drops it. Minor, but worth an explicitis Nonecheck. - [Info]
opentelemetry-util-genaiis unpinned while the sibling deps use~=; pin it for reproducibility.
Suggestions
For the suppression, recording the provider response id and skipping framework LLM metrics when an id is already seen is more robust than trace-id end-ordering.
Cross-repo Note
No shared API with loongsuite-pilot; no cross-repo change needed.
Automated review by github-manager-bot
Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
Does This PR Require a Core Repo Change?
Checklist:
See contributing.md for styleguide, changelog guidelines, and more.