Span linking in Proactive scenarios - #534
Span linking in Proactive scenarios#534Rodrigo Brandão (rodrigobr-msft) wants to merge 11 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.
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 (2)
changelog.md:17
- Spelling/grammar: "throught" should be "through", and the sentence is a bit unclear. Consider rephrasing for readability in the release notes.
- Support for linking with OpenTelemetry span creation throught the `SimpleSpanWrapper` constructor.
changelog.md:22
- The horizontal rule (
---) is currently placed before two bullet items, leaving those bullets outside any section heading and making the markdown structure confusing. Move the rule to after the final bullet of the v1.4.0 section (immediately before the v1.3.0 header).
---
- Simplified the anonymous identity scenarios when using `ClaimsIdentity`. Added a new property `ClaimsIdentity.allow_anonymous` and deprecated the `ClaimsIdentity.is_authenticated` flag.
- In the construction of the inbound `Activity` instance, raw `Entity` JSON is automatically deserialized into known derived `Entity` classes such as `ProductInfo`, `Mention`, `AIEntity`, and more.
This pull request introduces distributed tracing support for proactive operations, enhances telemetry integration, and makes several improvements to the proactive conversation and builder APIs. The most significant changes are the addition of span linking for proactive conversations, new integration tests for telemetry, and stricter requirements in the conversation builder. There are also minor improvements to type annotations and documentation.
Distributed Tracing and Telemetry Enhancements:
SimpleSpanWrapperconstructor. [1] [2]Conversationclass now serializes and deserializes span context for telemetry linking, with new internal methods_set_span_contextand_get_span_context, and persists span context in storage. [1] [2] [3]Testing Improvements:
test_proactive_span_linking.pyto verify that continuation spans are correctly linked to the latest store span, ensuring accurate distributed tracing.Proactive Conversation Builder Improvements:
ConversationBuildernow requiresagent_idanduser_id(in addition tochannel_idandconversation_id) when building a conversation, raising an error if any are missing.Optional[str]withstr | None. [1] [2] [3] [4] [5] [6] [7]Other Codebase Improvements:
These changes collectively improve observability, reliability, and type safety for proactive operations and telemetry in the codebase.