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.
- {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/PKG-INFO +1 -1
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/README.md +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/pyproject.toml +0 -0
- {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/setup.cfg +0 -0
- {microsoft_agents_a365_observability_hosting-0.2.1.dev42 → microsoft_agents_a365_observability_hosting-0.2.1.dev44}/setup.py +0 -0
|
@@ -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
|
|
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
|
-
"
|
|
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
|
|
6
|
+
from .output_logging_middleware import A365_PARENT_TRACEPARENT_KEY, OutputLoggingMiddleware
|
|
7
7
|
|
|
8
8
|
__all__ = [
|
|
9
9
|
"BaggageMiddleware",
|
|
10
10
|
"OutputLoggingMiddleware",
|
|
11
|
-
"
|
|
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
|
-
|
|
35
|
-
|
|
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
|
|
86
|
+
def _derive_channel(
|
|
86
87
|
context: TurnContext,
|
|
87
88
|
) -> dict[str, str | None]:
|
|
88
|
-
"""Derive
|
|
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, "
|
|
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:`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
179
|
-
|
|
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
|
|
185
|
+
"[OutputLoggingMiddleware] No traceparent in turn_state under "
|
|
182
186
|
"'%s'. OutputScope will not be linked to a parent.",
|
|
183
|
-
|
|
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
|
-
|
|
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,
|
|
197
|
-
output_scope.set_tag_maybe(CHANNEL_LINK_KEY,
|
|
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(
|
|
201
|
-
output_scope.set_tag_maybe(
|
|
202
|
-
output_scope.set_tag_maybe(
|
|
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
|
|
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(
|
|
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
|
|
42
|
-
yield
|
|
43
|
-
yield
|
|
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
|
|
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
|
|
77
|
+
def get_channel_pairs(activity: Activity) -> Iterator[tuple[str, Any]]:
|
|
78
78
|
"""
|
|
79
|
-
Generate
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|