Skip to content

Span linking in Proactive scenarios - #534

Merged
Rodrigo Brandão (rodrigobr-msft) merged 18 commits into
mainfrom
users/robrandao/proactive-updates
Aug 21, 2026
Merged

Span linking in Proactive scenarios#534
Rodrigo Brandão (rodrigobr-msft) merged 18 commits into
mainfrom
users/robrandao/proactive-updates

Conversation

@rodrigobr-msft

@rodrigobr-msft Rodrigo Brandão (rodrigobr-msft) commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

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:

  • Added distributed tracing support for proactive operations, including span linking between storing and continuing conversations, and support for OpenTelemetry span creation via the SimpleSpanWrapper constructor. [1] [2]
  • The Conversation class now serializes and deserializes span context for telemetry linking, with new internal methods _set_span_context and _get_span_context, and persists span context in storage. [1] [2] [3]

Testing Improvements:

  • Added new integration tests for proactive span linking in test_proactive_span_linking.py to verify that continuation spans are correctly linked to the latest store span, ensuring accurate distributed tracing.
  • Updated test imports and structure for telemetry integration tests, including moving and renaming files for better organization. [1] [2]

Proactive Conversation Builder Improvements:

  • The ConversationBuilder now requires agent_id and user_id (in addition to channel_id and conversation_id) when building a conversation, raising an error if any are missing.
  • Improved type annotations throughout the builder for clarity, replacing Optional[str] with str | None. [1] [2] [3] [4] [5] [6] [7]
  • Refactored agent and user construction in the builder to ensure required fields and cleaner instantiation.

Other Codebase Improvements:

  • Minor code cleanup and import adjustments in proactive conversation and reference builder modules. [1] [2]

These changes collectively improve observability, reliability, and type safety for proactive operations and telemetry in the codebase.

Copilot AI lite review requested due to automatic review settings August 10, 2026 22:10
@rodrigobr-msft Rodrigo Brandão (rodrigobr-msft) linked an issue Aug 10, 2026 that may be closed by this pull request

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 links when starting spans, and expose that capability through SimpleSpanWrapper.
  • Persist a serialized SpanContext on stored Conversation objects 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 via certifi.

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: Conversation has no _span_context attribute. Use conversation._get_span_context() so the proactive continuation span is linked correctly and doesn’t raise AttributeError.
        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.

Copilot AI review requested due to automatic review settings August 11, 2026 17:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • _proactive is annotated as non-optional but is only set when options.proactive is provided. If proactive options are not configured, accessing self._proactive (e.g., in the proactive property) will raise AttributeError because 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

  • Link is 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 storage is a required Storage, 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_client anywhere under microsoft_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

Comment thread tests/hosting_core/telemetry/test_proactive_utils.py
Copilot AI review requested due to automatic review settings August 11, 2026 18:03
@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) marked this pull request as ready for review August 11, 2026 18:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • functools is imported but never used in this module. Please remove it to avoid unused-import warnings.
from typing import TYPE_CHECKING

Copilot AI review requested due to automatic review settings August 11, 2026 18:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings August 11, 2026 18:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot AI review requested due to automatic review settings August 11, 2026 18:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 18, 2026 18:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 19, 2026 18:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated no new comments.

Suppressed comments (2)

changelog.md:52

  • There are two consecutive Markdown horizontal rules (---) here, which creates an empty section break and looks like an accidental duplicate. Removing the extra rule will keep the release notes formatting clean.
---

---

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/proactive.py:69

  • This change drops the StateT generic from the app type, reducing static type-safety for Proactive[StateT] (e.g., handlers and turn-state factory typing). Keeping AgentApplication[StateT] preserves the intended generic relationship.
    def __init__(
        self,
        app: AgentApplication,
        options: ProactiveOptions,
    ) -> None:

Copilot AI review requested due to automatic review settings August 20, 2026 19:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/_utils.py:38

  • _dump_span_context() stores trace_state as a list of tuples via trace_state.items(). When this dict is persisted through JSON serializers (e.g., BlobStorage uses json.dumps/json.loads), those tuples round-trip back as lists, so _deserialize_span_context() should normalize data["trace_state"] into the expected key/value pair structure before constructing TraceState to avoid type/validation issues.
    data = {
        "trace_id": str(span_context.trace_id),
        "span_id": str(span_context.span_id),
        "trace_flags": int(span_context.trace_flags),
        "trace_state": list(span_context.trace_state.items()),
    }

changelog.md:54

  • There are two consecutive section separators (---) between the v1.4.0 and v1.3.0 sections. This looks accidental and will render as an extra empty horizontal rule in the changelog.
---

---

Copilot AI review requested due to automatic review settings August 20, 2026 20:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

changelog.md:53

  • There are two consecutive horizontal-rule separators here (--- twice), which creates an empty section break in the rendered changelog. Remove the extra separator (or replace it with the intended heading/content) to keep the release notes structure consistent.
---

---

Copilot AI review requested due to automatic review settings August 20, 2026 21:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated no new comments.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/proactive.py:380

  • _on_turn() now attempts OAuth sign-in whenever token_handlers is provided, but it no longer guards against self._app._auth being unset. In unit tests (and potentially in custom constructions) Proactive is instantiated with an app mock where _auth is None, so this will raise AttributeError instead of skipping/handling auth. Consider restoring the previous guard (e.g., if token_handlers and self._app._auth:) or raising a clearer error when auth is required but not configured.
        if token_handlers:
            for handler_id in token_handlers:
                result = await self._app._auth._start_or_continue_sign_in(
                    context, state, handler_id
                )

Copilot AI review requested due to automatic review settings August 21, 2026 16:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 24 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/proactive.py:380

  • _on_turn() now runs the OAuth token pre-check whenever token_handlers is provided, but it unconditionally calls self._app._auth._start_or_continue_sign_in(...). If the hosting AgentApplication (or test double) has _auth unset/None, this will raise AttributeError instead of skipping the check or failing with a clear error. Consider restoring a guard (e.g., if token_handlers and self._app._auth:) or raising a RuntimeError/ApplicationError with an actionable message when token_handlers is provided but auth isn’t configured.
        if token_handlers:
            for handler_id in token_handlers:
                result = await self._app._auth._start_or_continue_sign_in(
                    context, state, handler_id
                )

@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) merged commit 8ff0ac3 into main Aug 21, 2026
11 checks passed
@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) deleted the users/robrandao/proactive-updates branch August 21, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support span links in OTEL layer

3 participants