Skip to content

Instrument Proactive - #399

Merged
Rodrigo Brandão (rodrigobr-msft) merged 8 commits into
mainfrom
users/robrandao/instrument-proactive
May 19, 2026
Merged

Instrument Proactive#399
Rodrigo Brandão (rodrigobr-msft) merged 8 commits into
mainfrom
users/robrandao/instrument-proactive

Conversation

@rodrigobr-msft

Copy link
Copy Markdown
Contributor

This pull request adds detailed OpenTelemetry-based telemetry spans to the proactive conversation handling logic in the Microsoft Agents Hosting Core. The main focus is on tracking and correlating key operations (store, get, delete, send activity, continue, and create conversation) with rich contextual attributes, improving observability and diagnostics for proactive scenarios. The changes also introduce new constants and attributes to support these spans. Some minor formatting and test improvements are included as well.

Telemetry and Observability Enhancements:

  • Introduced a new spans module (proactive/telemetry/spans.py) implementing custom span wrappers for each proactive operation (store, get, delete, send activity, continue, create conversation), capturing relevant attributes for each operation.
  • Added new constants for span names in proactive/telemetry/constants.py to standardize span identification.
  • Extended telemetry attribute definitions with CONVERSATION_FOUND and MEMBERS_COUNT in telemetry/attributes.py to support richer span data. [1] [2]

Integration with Proactive Operations:

  • Updated the main proactive.py logic to wrap all key operations (store_conversation, get_conversation, delete_conversation, send_activity, continue_conversation, and create_conversation) with the new telemetry spans, ensuring each operation is tracked and relevant attributes are recorded. [1] [2] [3] [4] [5] [6] [7] [8]
  • Enhanced the get_conversation span to record whether the conversation was found, using the new CONVERSATION_FOUND attribute.

Minor Improvements and Test Adjustments:

  • Minor code formatting improvements and explicit line breaks in test files for better readability and consistency. [1] [2] [3] [4] [5] [6] [7] [8] [9]
  • Type annotation cleanup in proactive.py for clarity.

Copilot AI review requested due to automatic review settings May 18, 2026 15:01

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 instruments the Hosting Core proactive messaging flow with OpenTelemetry spans, adding standardized span names and attributes to improve correlation/diagnostics for proactive storage, retrieval, deletion, send/continue, and conversation creation.

Changes:

  • Added dedicated proactive telemetry span wrappers and span-name constants for each proactive operation.
  • Wrapped key proactive operations in proactive.py with the new spans and added richer attributes (e.g., conversation-found, members-count).
  • Added proactive span unit tests and did minor test formatting cleanups.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/hosting_core/telemetry/test_proactive_spans.py New unit tests for proactive span wrappers and their attributes.
tests/hosting_core/app/proactive/test_proactive.py Minor formatting adjustments in proactive tests.
tests/hosting_core/app/proactive/test_create_conversation_options.py Minor formatting adjustments.
tests/hosting_core/app/proactive/test_conversation.py Minor formatting adjustments.
tests/hosting_core/app/proactive/test_conversation_reference_builder.py Minor formatting adjustments.
tests/hosting_core/app/proactive/test_conversation_builder.py Minor formatting adjustments.
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/telemetry/attributes.py Adds CONVERSATION_FOUND and MEMBERS_COUNT telemetry attribute keys.
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/spans.py New proactive span wrapper implementations and attribute mapping.
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/constants.py New standardized proactive span name constants.
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/proactive.py Wraps proactive operations with the new spans and shares relevant attributes (e.g., found/not found).
Comments suppressed due to low confidence (3)

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/spans.py:27

  • The constructor is annotated as conversation_id: str, but the implementation explicitly supports None (via or attributes.UNKNOWN) and the new tests call ProactiveStoreConversation(None). Please either update the type to str | None (and propagate to similar wrappers) or enforce non-None inputs and adjust tests accordingly.
    def __init__(self, conversation_id: str):
        """Initializes the ProactiveStoreConversation SpanWrapper.

        :param conversation_id: The ID of the conversation being stored, used to extract attributes for the span
        """
        super().__init__(constants.SPAN_STORE_CONVERSATION)
        self._conversation_id = conversation_id

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/spans.py:52

  • CONVERSATION_FOUND is sometimes set to a boolean and sometimes to attributes.UNKNOWN (a string). Mixing attribute value types for the same key can cause exporter/backend issues and makes querying harder. Consider omitting CONVERSATION_FOUND when _found is None (only set it after share()), or otherwise keep the attribute type stable.
    def _get_attributes(self) -> AttributeMap:
        return {
            attributes.CONVERSATION_ID: self._conversation_id or attributes.UNKNOWN,
            attributes.CONVERSATION_FOUND: (
                self._found if self._found is not None else attributes.UNKNOWN
            ),
        }

libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/proactive/telemetry/spans.py:137

  • MEMBERS_COUNT is set to an int when members exist, but to attributes.UNKNOWN (string) otherwise, which mixes attribute types for the same key. Also, an empty members list currently maps to UNKNOWN rather than 0, losing valid information. Consider making MEMBERS_COUNT consistently numeric (e.g., 0 for empty list) and omitting it (or using a numeric sentinel) only when members are truly unavailable.
        super().__init__(constants.SPAN_CREATE_CONVERSATION)
        self._channel_id = options.channel_id
        self._members_count: str | int = (
            len(options.parameters.members)
            if options.parameters and options.parameters.members
            else attributes.UNKNOWN
        )

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/hosting_core/telemetry/test_proactive_spans.py Outdated
Copilot AI review requested due to automatic review settings May 18, 2026 15:40
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

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 10 out of 11 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

tests/hosting_core/telemetry/test_proactive_spans.py:323

  • This test codifies that an empty members=[] should be reported as UNKNOWN, which prevents distinguishing “0 members” from “missing members”. If proactive.members.count is intended to be a count, consider expecting 0 here and using UNKNOWN only when parameters/members is absent.
def test_create_conversation_members_count_unknown_when_empty_members(test_exporter):
    """An empty list is treated the same as missing — the `and members` clause
    in ProactiveCreateConversation short-circuits to UNKNOWN."""
    with ProactiveCreateConversation(_make_create_options(members=[])):
        pass

    span = test_exporter.get_finished_spans()[0]
    assert span.attributes[attributes.MEMBERS_COUNT] == attributes.UNKNOWN

Comment thread tests/hosting_core/telemetry/test_proactive_spans.py Outdated
@rodrigobr-msft Rodrigo Brandão (rodrigobr-msft) linked an issue May 18, 2026 that may be closed by this pull request

@axelsrz Axel Suárez (axelsrz) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

:shipit:

@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) merged commit d7e2e67 into main May 19, 2026
11 checks passed
@rodrigobr-msft
Rodrigo Brandão (rodrigobr-msft) deleted the users/robrandao/instrument-proactive branch May 19, 2026 17:33
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.

Instrumentation for Proactive in Python

3 participants