Conversation
Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com>
Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com>
…for Python Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
Updates the Python observability libraries/tests to support the new A365 telemetry schema attribute names (migrating gen_ai.* -> microsoft.* where applicable), remove deprecated constants, and add new SDK/service attributes.
Changes:
- Renamed channel/caller/tenant/session and other attributes to the new schema keys, removing deprecated telemetry constants throughout core/hosting/extensions.
- Added telemetry SDK attributes (
telemetry.sdk.*) and new model fields (ServiceEndpoint,provider_name,agent_platform_id, etc.). - Updated OpenAI/AgentFramework trace processors and test assertions to use
gen_ai.provider.nameand new tool call result attribute keys.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/observability/hosting/scope_helpers/test_scope_helper_utils.py | Updates tests to assert new channel attribute keys and removes deprecated caller tenant assertion. |
| tests/observability/hosting/scope_helpers/test_populate_invoke_agent_scope.py | Updates scope population tests to validate new channel name key. |
| tests/observability/extensions/openai/integration/test_openai_trace_processor.py | Migrates LLM span detection from gen_ai.system to gen_ai.provider.name. |
| tests/observability/extensions/agentframework/integration/test_agentframework_trace_processor.py | Migrates LLM span detection from gen_ai.system to gen_ai.provider.name. |
| tests/observability/core/test_span_processor.py | Reworks span processor test to validate baggage propagation for tenant/agent IDs (removes operation source). |
| tests/observability/core/test_invoke_agent_scope.py | Updates tests for channel keys and remodels caller/caller-agent details per new schema fields. |
| tests/observability/core/test_inference_scope.py | Updates inference scope tests to assert new channel keys. |
| tests/observability/core/test_execute_tool_scope.py | Updates execute tool scope tests to assert new channel keys. |
| tests/observability/core/test_baggage_builder.py | Updates baggage builder tests for removed deprecated keys and new channel key names. |
| libraries/.../hosting/scope_helpers/utils.py | Migrates helper output to new channel keys and removes deprecated caller tenant pair. |
| libraries/.../hosting/middleware/output_logging_middleware.py | Migrates span tags to new channel keys and removes deprecated caller tenant tagging. |
| libraries/.../extensions/openai/utils.py | Removes deprecated attributes (gen_ai.system, response id) and remaps tool output to gen_ai.tool.call.result. |
| libraries/.../extensions/openai/trace_processor.py | Sets gen_ai.provider.name on span start instead of deprecated gen_ai.system. |
| libraries/.../core/trace_processor/util.py | Updates attribute allowlists to the new constants and channel keys. |
| libraries/.../core/trace_processor/span_processor.py | Removes deprecated operation source defaulting logic. |
| libraries/.../core/opentelemetry_scope.py | Adds telemetry.sdk.*, service/provider/platform tags, and remaps response recording attribute. |
| libraries/.../core/models/caller_details.py | Updates caller data model (removes tenant/user id; adds client IP). |
| libraries/.../core/middleware/baggage_builder.py | Removes deprecated baggage setters and migrates channel baggage keys. |
| libraries/.../core/invoke_agent_scope.py | Migrates request/channel tagging and remodels caller/caller-agent fields (client IP, platform id). |
| libraries/.../core/inference_scope.py | Adds thought process + endpoint tagging; updates token attributes to numeric; migrates channel keys. |
| libraries/.../core/inference_call_details.py | Adds ServiceEndpoint and new thoughtProcess/endpoint fields. |
| libraries/.../core/constants.py | Applies schema rename, removes deprecated constants, and adds telemetry SDK/service constants. |
| libraries/.../core/agent_details.py | Updates agent data model (platform id/provider/service instead of type/client ip). |
| libraries/.../core/init.py | Exports new ServiceEndpoint type from the public package surface. |
You can also share your feedback on Copilot code review. Take the survey.
| if details.endpoint.port: | ||
| self.set_tag_maybe(SERVER_PORT_KEY, str(details.endpoint.port)) |
There was a problem hiding this comment.
server.port should be recorded as an integer attribute (OpenTelemetry semconv expects an int), but this converts it to str(...). Also, if details.endpoint.port: will skip valid ports like 0; use an explicit is not None check and set the numeric value.
| if details.endpoint.port: | |
| self.set_tag_maybe(SERVER_PORT_KEY, str(details.endpoint.port)) | |
| if details.endpoint.port is not None: | |
| self.set_tag_maybe(SERVER_PORT_KEY, details.endpoint.port) |
| """ | ||
| if self._span and self._is_telemetry_enabled(): | ||
| self._span.set_attribute(GEN_AI_EVENT_CONTENT, response) | ||
| self._span.set_attribute(GEN_AI_OUTPUT_MESSAGES_KEY, response) |
There was a problem hiding this comment.
gen_ai.output.messages is used elsewhere as a serialized array of message objects (e.g., safe_json_dumps([...]) in the OpenAI extension). Setting it directly to a raw response string makes the attribute shape inconsistent across spans. Consider serializing into the same structure (or using a different attribute intended for raw text) to keep schema consistency.
| @staticmethod | ||
| def _get_sdk_version() -> str: | ||
| """Get the SDK version from package metadata. | ||
|
|
||
| Returns: | ||
| The SDK version string, or "0.0.0-unknown" if not found | ||
| """ | ||
| try: | ||
| from importlib.metadata import version | ||
|
|
||
| return version("microsoft-agents-a365-observability-core") | ||
| except Exception: | ||
| return "0.0.0-unknown" |
There was a problem hiding this comment.
_get_sdk_version() will run an importlib.metadata lookup each time a scope/span is created. Consider caching the resolved version (e.g., with a module-level constant or functools.lru_cache) to avoid repeated metadata resolution overhead.
| # Set telemetry SDK attributes | ||
| self._span.set_attribute(TELEMETRY_SDK_NAME_KEY, TELEMETRY_SDK_NAME_VALUE) | ||
| self._span.set_attribute(TELEMETRY_SDK_LANGUAGE_KEY, TELEMETRY_SDK_LANGUAGE_VALUE) | ||
| self._span.set_attribute(TELEMETRY_SDK_VERSION_KEY, self._get_sdk_version()) |
There was a problem hiding this comment.
This introduces new always-on attributes (telemetry.sdk.*) and new optional tags (gen_ai.provider.name, service.name) on spans, but the updated tests shown don’t assert these behaviors. Add/extend existing scope/span tests to validate these attributes are set (and that optional ones are omitted when not provided) to prevent regressions during future schema changes.
| # Set provider name dynamically from agent details | ||
| self.set_tag_maybe(GEN_AI_PROVIDER_NAME_KEY, agent_details.provider_name) | ||
| # Set service name from agent details if available | ||
| self.set_tag_maybe(SERVICE_NAME_KEY, agent_details.service_name) |
There was a problem hiding this comment.
This introduces new always-on attributes (telemetry.sdk.*) and new optional tags (gen_ai.provider.name, service.name) on spans, but the updated tests shown don’t assert these behaviors. Add/extend existing scope/span tests to validate these attributes are set (and that optional ones are omitted when not provided) to prevent regressions during future schema changes.
Implements A365 telemetry schema attribute name migration matching nodejs PR #207. Migrates
gen_ai.*attributes tomicrosoft.*namespace and removes deprecated telemetry constants.Attribute Renames
gen_ai.caller.*→microsoft.caller.*gen_ai.agent.user.*→microsoft.agent.user.*gen_ai.caller.agent.*→microsoft.a365.caller.agent.*session.id→microsoft.session.id,tenant.id→microsoft.tenant.idgen_ai.channel.*→microsoft.channel.*gen_ai.event.content→gen_ai.tool.call.resultgen_ai.agent.thought.process→microsoft.a365.agent.thought.processRemoved Constants
gen_ai.system/gen_ai.system.value— replaced with dynamicgen_ai.provider.namegen_ai.response.id,gen_ai.agent.type,gen_ai.caller.agent.typecorrelation.id,hiring.manager.id,operation.sourcegen_ai.caller.tenantid,gen_ai.caller.agent.tenantidgen_ai.caller.agent.user.client.ipAdded
telemetry.sdk.name,telemetry.sdk.language,telemetry.sdk.versionservice.name,microsoft.a365.agent.platform.idData Model Changes
AgentDetails: Removed
agent_type,agent_client_ip; addedprovider_name,agent_platform_id,service_nameCallerDetails: Removed
caller_user_id,tenant_id; addedcaller_client_ipInferenceCallDetails: Removed
responseId; addedthoughtProcess,endpoint: ServiceEndpoint✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.