Python: emit tool definitions individually for telemetry#6302
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR updates how tool definitions are recorded into span attributes so each tool is serialized independently, and adds a regression test to validate the new structure.
Changes:
- Add
_serialize_tool_definitions()helper to serialize tool definitions into a list of JSON strings. - Update the OTEL attribute mapping for
toolsto use the new serializer. - Add a unit test asserting a single tool produces a single, individually-serialized definition.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| python/packages/core/agent_framework/observability.py | Switch tool-definition span attribute serialization from a single JSON blob to per-tool JSON entries via a helper. |
| python/packages/core/tests/core/test_observability.py | Add a test verifying per-tool serialization behavior and JSON structure. |
| def _serialize_tool_definitions(tools: Any) -> list[str] | None: | ||
| from agent_framework._tools import _tools_to_dict | ||
|
|
||
| tools_dict = _tools_to_dict(tools) | ||
| if not tools_dict: | ||
| return None | ||
| return [json.dumps(tool_def, ensure_ascii=False) for tool_def in tools_dict] |
| def test_get_span_attributes_serializes_tool_definitions_individually(): | ||
| from agent_framework.observability import OtelAttr, _get_span_attributes | ||
|
|
||
| @tool | ||
| def lookup_weather(city: str) -> str: | ||
| return f"sunny in {city}" | ||
|
|
||
| attrs = _get_span_attributes(tools=[lookup_weather]) | ||
| definitions = attrs[OtelAttr.TOOL_DEFINITIONS] | ||
|
|
||
| assert isinstance(definitions, list) | ||
| assert len(definitions) == 1 | ||
| definition = json.loads(definitions[0]) | ||
| assert definition["function"]["name"] == "lookup_weather" |
|
Thank you for your contribution, @he-yufeng. To keep the review queue manageable, we currently limit community contributors to 10 open pull requests at a time. This PR would put you at 20 open pull requests, so we are closing it automatically. Please focus on getting your existing PRs reviewed, merged, or closed before opening another one. If a maintainer asked you to open this PR, they can apply the |
Summary
Fixes #6300.
The Python telemetry mapper now emits
gen_ai.tool.definitionsas a list of per-tool JSON strings instead of one JSON string containing the whole array. That matches the shape Aspire expects for its Tools tab and keeps the existing_tools_to_dictnormalization path.Validation
python -m pytest python\packages\core\tests\core\test_observability.py -q -k tool_definitionspython -m pytest python\packages\core\tests\core\test_observability.py -q -k get_span_attributespython -m ruff check python\packages\core\agent_framework\observability.py python\packages\core\tests\core\test_observability.pypython -m ruff format --check python\packages\core\agent_framework\observability.py python\packages\core\tests\core\test_observability.pypython -m mypy --config-file python\packages\core\pyproject.toml python\packages\core\agent_framework\observability.pygit diff --check