Instrument Proactive - #399
Conversation
There was a problem hiding this comment.
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.pywith 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 supportsNone(viaor attributes.UNKNOWN) and the new tests callProactiveStoreConversation(None). Please either update the type tostr | 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_FOUNDis sometimes set to a boolean and sometimes toattributes.UNKNOWN(a string). Mixing attribute value types for the same key can cause exporter/backend issues and makes querying harder. Consider omittingCONVERSATION_FOUNDwhen_found is None(only set it aftershare()), 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_COUNTis set to anintwhen members exist, but toattributes.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 makingMEMBERS_COUNTconsistently 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.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
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 asUNKNOWN, which prevents distinguishing “0 members” from “missing members”. Ifproactive.members.countis intended to be a count, consider expecting0here and usingUNKNOWNonly whenparameters/membersis 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
…into users/robrandao/instrument-proactive
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:
spansmodule (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.proactive/telemetry/constants.pyto standardize span identification.CONVERSATION_FOUNDandMEMBERS_COUNTintelemetry/attributes.pyto support richer span data. [1] [2]Integration with Proactive Operations:
proactive.pylogic to wrap all key operations (store_conversation,get_conversation,delete_conversation,send_activity,continue_conversation, andcreate_conversation) with the new telemetry spans, ensuring each operation is tracked and relevant attributes are recorded. [1] [2] [3] [4] [5] [6] [7] [8]get_conversationspan to record whether the conversation was found, using the newCONVERSATION_FOUNDattribute.Minor Improvements and Test Adjustments:
proactive.pyfor clarity.