microsoft-agents-a365-observability-hosting 0.2.1.dev42__tar.gz → 0.2.1.dev44__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/PKG-INFO +1 -1
  2. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/__init__.py +5 -2
  3. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/middleware/__init__.py +2 -2
  4. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/middleware/output_logging_middleware.py +26 -22
  5. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/scope_helpers/populate_baggage.py +2 -2
  6. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/scope_helpers/populate_invoke_agent_scope.py +2 -2
  7. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/scope_helpers/utils.py +11 -11
  8. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365_observability_hosting.egg-info/PKG-INFO +1 -1
  9. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/README.md +0 -0
  10. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/middleware/baggage_middleware.py +0 -0
  11. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/middleware/observability_hosting_manager.py +0 -0
  12. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/scope_helpers/__init__.py +0 -0
  13. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/token_cache_helpers/__init__.py +0 -0
  14. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365/observability/hosting/token_cache_helpers/agent_token_cache.py +0 -0
  15. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365_observability_hosting.egg-info/SOURCES.txt +0 -0
  16. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365_observability_hosting.egg-info/dependency_links.txt +0 -0
  17. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365_observability_hosting.egg-info/requires.txt +0 -0
  18. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/microsoft_agents_a365_observability_hosting.egg-info/top_level.txt +0 -0
  19. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/pyproject.toml +0 -0
  20. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/setup.cfg +0 -0
  21. {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-a365-observability-hosting
3
- Version: 0.2.1.dev42
3
+ Version: 0.2.1.dev44
4
4
  Summary: Hosting components for Agent 365 observability
5
5
  Author-email: Microsoft <support@microsoft.com>
6
6
  License: MIT
@@ -10,12 +10,15 @@ from .middleware.observability_hosting_manager import (
10
10
  ObservabilityHostingManager,
11
11
  ObservabilityHostingOptions,
12
12
  )
13
- from .middleware.output_logging_middleware import A365_PARENT_SPAN_KEY, OutputLoggingMiddleware
13
+ from .middleware.output_logging_middleware import (
14
+ A365_PARENT_TRACEPARENT_KEY,
15
+ OutputLoggingMiddleware,
16
+ )
14
17
 
15
18
  __all__ = [
16
19
  "BaggageMiddleware",
17
20
  "OutputLoggingMiddleware",
18
- "A365_PARENT_SPAN_KEY",
21
+ "A365_PARENT_TRACEPARENT_KEY",
19
22
  "ObservabilityHostingManager",
20
23
  "ObservabilityHostingOptions",
21
24
  ]
@@ -3,12 +3,12 @@
3
3
 
4
4
  from .baggage_middleware import BaggageMiddleware
5
5
  from .observability_hosting_manager import ObservabilityHostingManager, ObservabilityHostingOptions
6
- from .output_logging_middleware import A365_PARENT_SPAN_KEY, OutputLoggingMiddleware
6
+ from .output_logging_middleware import A365_PARENT_TRACEPARENT_KEY, OutputLoggingMiddleware
7
7
 
8
8
  __all__ = [
9
9
  "BaggageMiddleware",
10
10
  "OutputLoggingMiddleware",
11
- "A365_PARENT_SPAN_KEY",
11
+ "A365_PARENT_TRACEPARENT_KEY",
12
12
  "ObservabilityHostingManager",
13
13
  "ObservabilityHostingOptions",
14
14
  ]
@@ -14,16 +14,17 @@ from microsoft_agents_a365.observability.core.agent_details import AgentDetails
14
14
  from microsoft_agents_a365.observability.core.constants import (
15
15
  CHANNEL_LINK_KEY,
16
16
  CHANNEL_NAME_KEY,
17
- GEN_AI_CALLER_ID_KEY,
18
- GEN_AI_CALLER_NAME_KEY,
19
- GEN_AI_CALLER_UPN_KEY,
20
17
  GEN_AI_CONVERSATION_ID_KEY,
21
18
  GEN_AI_EXECUTION_TYPE_KEY,
19
+ USER_EMAIL_KEY,
20
+ USER_ID_KEY,
21
+ USER_NAME_KEY,
22
22
  )
23
23
  from microsoft_agents_a365.observability.core.models.caller_details import CallerDetails
24
24
  from microsoft_agents_a365.observability.core.models.response import Response
25
25
  from microsoft_agents_a365.observability.core.spans_scopes.output_scope import OutputScope
26
26
  from microsoft_agents_a365.observability.core.tenant_details import TenantDetails
27
+ from microsoft_agents_a365.observability.core.utils import extract_context_from_headers
27
28
 
28
29
  from ..scope_helpers.utils import (
29
30
  get_execution_type_pair,
@@ -31,8 +32,8 @@ from ..scope_helpers.utils import (
31
32
 
32
33
  logger = logging.getLogger(__name__)
33
34
 
34
- A365_PARENT_SPAN_KEY = "A365ParentSpanId"
35
- """TurnState key for the parent span reference."""
35
+ # TurnState key for the parent trace context (W3C traceparent string).
36
+ A365_PARENT_TRACEPARENT_KEY = "A365ParentTraceparent"
36
37
 
37
38
 
38
39
  def _derive_agent_details(context: TurnContext) -> AgentDetails | None:
@@ -82,10 +83,10 @@ def _derive_conversation_id(context: TurnContext) -> str | None:
82
83
  return conv.id if conv else None
83
84
 
84
85
 
85
- def _derive_source_metadata(
86
+ def _derive_channel(
86
87
  context: TurnContext,
87
88
  ) -> dict[str, str | None]:
88
- """Derive source metadata (channel name and description) from TurnContext."""
89
+ """Derive channel (name and link) from TurnContext."""
89
90
  channel_id = getattr(context.activity, "channel_id", None)
90
91
  channel_name: str | None = None
91
92
  sub_channel: str | None = None
@@ -95,7 +96,7 @@ def _derive_source_metadata(
95
96
  elif hasattr(channel_id, "channel"):
96
97
  channel_name = channel_id.channel
97
98
  sub_channel = channel_id.sub_channel
98
- return {"name": channel_name, "description": sub_channel}
99
+ return {"name": channel_name, "link": sub_channel}
99
100
 
100
101
 
101
102
  def _derive_execution_type(context: TurnContext) -> str | None:
@@ -109,7 +110,7 @@ def _derive_execution_type(context: TurnContext) -> str | None:
109
110
  class OutputLoggingMiddleware:
110
111
  """Middleware that creates :class:`OutputScope` spans for outgoing messages.
111
112
 
112
- Links to a parent span when :data:`A365_PARENT_SPAN_KEY` is set in
113
+ Links to a parent span when :data:`A365_PARENT_TRACEPARENT_KEY` is set in
113
114
  ``turn_state``.
114
115
 
115
116
  **Privacy note:** Outgoing message content is captured verbatim as span
@@ -130,7 +131,7 @@ class OutputLoggingMiddleware:
130
131
 
131
132
  caller_details = _derive_caller_details(context)
132
133
  conversation_id = _derive_conversation_id(context)
133
- source_metadata = _derive_source_metadata(context)
134
+ channel = _derive_channel(context)
134
135
  execution_type = _derive_execution_type(context)
135
136
 
136
137
  context.on_send_activities(
@@ -140,7 +141,7 @@ class OutputLoggingMiddleware:
140
141
  tenant_details,
141
142
  caller_details,
142
143
  conversation_id,
143
- source_metadata,
144
+ channel,
144
145
  execution_type,
145
146
  )
146
147
  )
@@ -154,7 +155,7 @@ class OutputLoggingMiddleware:
154
155
  tenant_details: TenantDetails,
155
156
  caller_details: CallerDetails | None,
156
157
  conversation_id: str | None,
157
- source_metadata: dict[str, str | None],
158
+ channel: dict[str, str | None],
158
159
  execution_type: str | None,
159
160
  ) -> Callable:
160
161
  """Create a send handler that wraps outgoing messages in OutputScope spans.
@@ -175,31 +176,34 @@ class OutputLoggingMiddleware:
175
176
  await send_next()
176
177
  return
177
178
 
178
- parent_id: str | None = turn_context.turn_state.get(A365_PARENT_SPAN_KEY)
179
- if not parent_id:
179
+ traceparent: str | None = turn_context.turn_state.get(A365_PARENT_TRACEPARENT_KEY)
180
+ parent_context = None
181
+ if traceparent:
182
+ parent_context = extract_context_from_headers({"traceparent": traceparent})
183
+ else:
180
184
  logger.warning(
181
- "[OutputLoggingMiddleware] No parent span ref in turn_state under "
185
+ "[OutputLoggingMiddleware] No traceparent in turn_state under "
182
186
  "'%s'. OutputScope will not be linked to a parent.",
183
- A365_PARENT_SPAN_KEY,
187
+ A365_PARENT_TRACEPARENT_KEY,
184
188
  )
185
189
 
186
190
  output_scope = OutputScope.start(
187
191
  agent_details=agent_details,
188
192
  tenant_details=tenant_details,
189
193
  response=Response(messages=messages),
190
- parent_id=parent_id,
194
+ parent_context=parent_context,
191
195
  )
192
196
 
193
197
  # Set additional attributes on the scope
194
198
  output_scope.set_tag_maybe(GEN_AI_CONVERSATION_ID_KEY, conversation_id)
195
199
  output_scope.set_tag_maybe(GEN_AI_EXECUTION_TYPE_KEY, execution_type)
196
- output_scope.set_tag_maybe(CHANNEL_NAME_KEY, source_metadata.get("name"))
197
- output_scope.set_tag_maybe(CHANNEL_LINK_KEY, source_metadata.get("description"))
200
+ output_scope.set_tag_maybe(CHANNEL_NAME_KEY, channel.get("name"))
201
+ output_scope.set_tag_maybe(CHANNEL_LINK_KEY, channel.get("link"))
198
202
 
199
203
  if caller_details:
200
- output_scope.set_tag_maybe(GEN_AI_CALLER_ID_KEY, caller_details.caller_id)
201
- output_scope.set_tag_maybe(GEN_AI_CALLER_UPN_KEY, caller_details.caller_upn)
202
- output_scope.set_tag_maybe(GEN_AI_CALLER_NAME_KEY, caller_details.caller_name)
204
+ output_scope.set_tag_maybe(USER_ID_KEY, caller_details.caller_id)
205
+ output_scope.set_tag_maybe(USER_EMAIL_KEY, caller_details.caller_upn)
206
+ output_scope.set_tag_maybe(USER_NAME_KEY, caller_details.caller_name)
203
207
 
204
208
  try:
205
209
  await send_next()
@@ -11,9 +11,9 @@ from microsoft_agents_a365.observability.core.middleware.baggage_builder import
11
11
 
12
12
  from .utils import (
13
13
  get_caller_pairs,
14
+ get_channel_pairs,
14
15
  get_conversation_pairs,
15
16
  get_execution_type_pair,
16
- get_source_metadata_pairs,
17
17
  get_target_agent_pairs,
18
18
  get_tenant_id_pair,
19
19
  )
@@ -27,7 +27,7 @@ def _iter_all_pairs(turn_context: TurnContext) -> Iterator[tuple[str, Any]]:
27
27
  yield from get_execution_type_pair(activity)
28
28
  yield from get_target_agent_pairs(activity)
29
29
  yield from get_tenant_id_pair(activity)
30
- yield from get_source_metadata_pairs(activity)
30
+ yield from get_channel_pairs(activity)
31
31
  yield from get_conversation_pairs(activity)
32
32
 
33
33
 
@@ -9,9 +9,9 @@ from microsoft_agents_a365.observability.core.invoke_agent_scope import InvokeAg
9
9
 
10
10
  from .utils import (
11
11
  get_caller_pairs,
12
+ get_channel_pairs,
12
13
  get_conversation_pairs,
13
14
  get_execution_type_pair,
14
- get_source_metadata_pairs,
15
15
  get_target_agent_pairs,
16
16
  get_tenant_id_pair,
17
17
  )
@@ -39,7 +39,7 @@ def populate(scope: InvokeAgentScope, turn_context: TurnContext) -> InvokeAgentS
39
39
  scope.record_attributes(get_execution_type_pair(activity))
40
40
  scope.record_attributes(get_target_agent_pairs(activity))
41
41
  scope.record_attributes(get_tenant_id_pair(activity))
42
- scope.record_attributes(get_source_metadata_pairs(activity))
42
+ scope.record_attributes(get_channel_pairs(activity))
43
43
  scope.record_attributes(get_conversation_pairs(activity))
44
44
 
45
45
  if activity.text:
@@ -9,16 +9,16 @@ from microsoft_agents_a365.observability.core.constants import (
9
9
  CHANNEL_NAME_KEY,
10
10
  GEN_AI_AGENT_AUID_KEY,
11
11
  GEN_AI_AGENT_DESCRIPTION_KEY,
12
+ GEN_AI_AGENT_EMAIL_KEY,
12
13
  GEN_AI_AGENT_ID_KEY,
13
14
  GEN_AI_AGENT_NAME_KEY,
14
- GEN_AI_AGENT_UPN_KEY,
15
- GEN_AI_CALLER_ID_KEY,
16
- GEN_AI_CALLER_NAME_KEY,
17
- GEN_AI_CALLER_UPN_KEY,
18
15
  GEN_AI_CONVERSATION_ID_KEY,
19
16
  GEN_AI_CONVERSATION_ITEM_LINK_KEY,
20
17
  GEN_AI_EXECUTION_TYPE_KEY,
21
18
  TENANT_ID_KEY,
19
+ USER_EMAIL_KEY,
20
+ USER_ID_KEY,
21
+ USER_NAME_KEY,
22
22
  )
23
23
  from microsoft_agents_a365.observability.core.execution_type import ExecutionType
24
24
 
@@ -38,9 +38,9 @@ def get_caller_pairs(activity: Activity) -> Iterator[tuple[str, Any]]:
38
38
  frm = activity.from_property
39
39
  if not frm:
40
40
  return
41
- yield GEN_AI_CALLER_ID_KEY, frm.aad_object_id
42
- yield GEN_AI_CALLER_NAME_KEY, frm.name
43
- yield GEN_AI_CALLER_UPN_KEY, frm.agentic_user_id
41
+ yield USER_ID_KEY, frm.aad_object_id
42
+ yield USER_NAME_KEY, frm.name
43
+ yield USER_EMAIL_KEY, frm.agentic_user_id
44
44
 
45
45
 
46
46
  def get_execution_type_pair(activity: Activity) -> Iterator[tuple[str, Any]]:
@@ -63,7 +63,7 @@ def get_target_agent_pairs(activity: Activity) -> Iterator[tuple[str, Any]]:
63
63
  yield GEN_AI_AGENT_ID_KEY, activity.get_agentic_instance_id()
64
64
  yield GEN_AI_AGENT_NAME_KEY, rec.name
65
65
  yield GEN_AI_AGENT_AUID_KEY, rec.aad_object_id
66
- yield GEN_AI_AGENT_UPN_KEY, activity.get_agentic_user()
66
+ yield GEN_AI_AGENT_EMAIL_KEY, activity.get_agentic_user()
67
67
  yield (
68
68
  GEN_AI_AGENT_DESCRIPTION_KEY,
69
69
  rec.role,
@@ -74,12 +74,12 @@ def get_tenant_id_pair(activity: Activity) -> Iterator[tuple[str, Any]]:
74
74
  yield TENANT_ID_KEY, activity.recipient.tenant_id
75
75
 
76
76
 
77
- def get_source_metadata_pairs(activity: Activity) -> Iterator[tuple[str, Any]]:
77
+ def get_channel_pairs(activity: Activity) -> Iterator[tuple[str, Any]]:
78
78
  """
79
- Generate source metadata pairs from activity, handling both string and ChannelId object cases.
79
+ Generate channel pairs from activity, handling both string and ChannelId object cases.
80
80
 
81
81
  :param activity: The activity object (Activity instance or dict)
82
- :return: Iterator of (key, value) tuples for source metadata
82
+ :return: Iterator of (key, value) tuples for channel information
83
83
  """
84
84
  # Handle channel_id (can be string or ChannelId object)
85
85
  channel_id = activity.channel_id
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-a365-observability-hosting
3
- Version: 0.2.1.dev42
3
+ Version: 0.2.1.dev44
4
4
  Summary: Hosting components for Agent 365 observability
5
5
  Author-email: Microsoft <support@microsoft.com>
6
6
  License: MIT