Span linking in Proactive scenarios - #534
Span linking in Proactive scenarios#534Rodrigo Brandão (rodrigobr-msft) wants to merge 8 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to improve observability in proactive messaging by enabling OpenTelemetry span linking across “store conversation” and later proactive operations (send/continue), and adds a custom HTTP client factory for the Teams hosting package.
Changes:
- Add support for passing OpenTelemetry
linkswhen starting spans, and expose that capability throughSimpleSpanWrapper. - Persist a serialized
SpanContexton storedConversationobjects and plumb it into proactive span wrappers for correlation. - Tighten typing in a few core areas (
Self, union types) and add a Teams HTTP client helper that pins TLS CA handling viacertifi.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| libraries/microsoft-agents-hosting-msteams/microsoft_agents/hosting/msteams/_http_client.py | New Teams HTTP client factory using httpx with a certifi-based SSL context. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/telemetry/core/type_defs.py | Telemetry type defs updated (imports). |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/telemetry/core/simple_span_wrapper.py | Adds link parameter and forwards OTEL links into span creation. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/telemetry/core/base_span_wrapper.py | Improves typing of context-manager lifecycle methods using Self. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/telemetry/core/_agents_telemetry.py | Extends start_as_current_span to accept OTEL links. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/spans.py | Proactive span wrappers accept an optional SpanContext link. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/_utils.py | Adds SpanContext (de)serialization helpers for storage. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/proactive.py | Captures span context during store_conversation and attempts to link later proactive spans. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/proactive_options.py | Makes storage required (API change). |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/create_conversation_options.py | Updates type annotations (non-Optional unions). |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/conversation.py | Persists serialized span context on Conversation for later linking. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/_utils.py | Adds a helper intended to link spans to conversation references. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/agent_application.py | Adjusts proactive attribute typing. |
Suppressed comments (1)
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/proactive.py:272
- Same issue as
send_activity:Conversationhas no_span_contextattribute. Useconversation._get_span_context()so the proactive continuation span is linked correctly and doesn’t raiseAttributeError.
with spans.ProactiveContinueConversation(
conversation_id,
continuation,
link=conversation._span_context):
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.
Suppressed comments (5)
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/agent_application.py:84
_proactiveis annotated as non-optional but is only set whenoptions.proactiveis provided. If proactive options are not configured, accessingself._proactive(e.g., in theproactiveproperty) will raiseAttributeErrorbecause the instance never gets the attribute.
Either keep it optional (and give it a default) or eagerly initialize it to None so the property can raise the intended ApplicationError.
_adapter: ChannelServiceAdapter | None = None
_adaptive_card: AdaptiveCard
_auth: Authorization
_proactive: Proactive
_internal_before_turn: list[Callable[[TurnContext, StateT], Awaitable[bool]]]
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/conversation.py:6
- Unused import
functools(not referenced in this module). This will trigger lint warnings and makes the module look like it relies on something it doesn't.
import functools
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/telemetry/core/type_defs.py:5
Linkis imported but never used in this module. It will raise an unused-import lint warning.
from opentelemetry.util.types import AttributeValue
from opentelemetry.trace import Span, Link
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/proactive_options.py:20
- This docstring says
storageis a requiredStorage, but the field is optional (Storage | None = None). Keeping the docstring accurate helps API consumers understand when they must provide storage vs when the application will fill it in.
:param storage: The storage instance used to persist and retrieve conversations.
:type storage: :class:`microsoft_agents.hosting.core.storage.Storage`
:param fail_on_unsigned_in_connections: If ``True`` (the default), a
libraries/microsoft-agents-hosting-msteams/microsoft_agents/hosting/msteams/_http_client.py:34
- This new helper module appears to be unused: there are no references/imports of
_create_http_clientanywhere undermicrosoft_agents.hosting.msteams, so this code is currently dead and won't be exercised by tests.
Either wire it into the Teams extension where the HTTP client is created, or remove it from this PR to avoid accumulating unused code.
def _create_http_client(options: ClientOptions | None = None) -> Client:
options = options or ClientOptions()
client = object.__new__(Client)
client._options = options
client._token = options.token
client._interceptors = list(options.interceptors or [])
client.http = httpx.AsyncClient(
base_url=httpx.URL(options.base_url) if options.base_url else "",
headers=options.headers,
timeout=options.timeout,
verify=_get_ssl_context(),
)
client._update_event_hooks()
return client
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Suppressed comments (1)
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/conversation.py:6
functoolsis imported but never used in this module. Please remove it to avoid unused-import warnings.
from typing import TYPE_CHECKING
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.
Suppressed comments (1)
changelog.md:17
- Typo in changelog entry: "throught" should be "through".
- Support for linking with OpenTelemetry span creation throught the `SimpleSpanWrapper` constructor.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.
Suppressed comments (1)
changelog.md:17
- Typo in changelog entry: "throught" should be "through".
- Support for linking with OpenTelemetry span creation throught the `SimpleSpanWrapper` constructor.
This pull request introduces distributed tracing support for proactive operations, improves type annotations and consistency across builder classes, and adds internal APIs for telemetry context propagation. The changes enhance observability and reliability for proactive scenarios, while also improving code clarity and type safety.
Distributed Tracing and Telemetry Support
SpanContextin theConversationclass for telemetry linking. This includes new internal APIs for setting and retrieving span context, and ensures context is persisted and restored with conversation state. [1] [2] [3] [4] [5] [6]Type Annotation and Consistency Improvements
ConversationBuilderandConversationReferenceBuilderclasses to use modern Python type annotations (e.g.,str | Noneinstead ofOptional[str]) for all internal fields and method signatures, improving type clarity and consistency. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]Builder Construction Robustness
ConversationBuilder.build()to enforce that all required identifiers (channel, conversation, agent, and user) are present, raising aValueErrorif any are missing. This prevents incomplete or invalid conversation references from being constructed.Code Quality and Documentation
Conversationclass, clarifying usage and expected types for developers. [1] [2] [3] [4] [5] [6]Changelog Updates
changelog.mdto reflect the addition of distributed tracing and OpenTelemetry span creation support, improving release documentation for developers. [1] [2]