microsoft-agents-a365-observability-core 0.1.0.dev30__py3-none-any.whl → 0.2.1.dev0__py3-none-any.whl
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/core/__init__.py +2 -1
- microsoft_agents_a365/observability/core/agent_details.py +7 -4
- microsoft_agents_a365/observability/core/config.py +71 -26
- microsoft_agents_a365/observability/core/constants.py +5 -2
- microsoft_agents_a365/observability/core/execute_tool_scope.py +15 -1
- microsoft_agents_a365/observability/core/execution_type.py +2 -1
- microsoft_agents_a365/observability/core/exporters/__init__.py +8 -0
- microsoft_agents_a365/observability/core/exporters/agent365_exporter.py +55 -7
- microsoft_agents_a365/observability/core/exporters/agent365_exporter_options.py +39 -0
- microsoft_agents_a365/observability/core/exporters/utils.py +133 -1
- microsoft_agents_a365/observability/core/inference_call_details.py +2 -1
- microsoft_agents_a365/observability/core/inference_operation_type.py +2 -1
- microsoft_agents_a365/observability/core/inference_scope.py +9 -0
- microsoft_agents_a365/observability/core/invoke_agent_details.py +2 -1
- microsoft_agents_a365/observability/core/invoke_agent_scope.py +12 -3
- microsoft_agents_a365/observability/core/middleware/__init__.py +2 -1
- microsoft_agents_a365/observability/core/middleware/baggage_builder.py +52 -28
- microsoft_agents_a365/observability/core/models/operation_source.py +21 -0
- microsoft_agents_a365/observability/core/opentelemetry_scope.py +2 -1
- microsoft_agents_a365/observability/core/request.py +2 -2
- microsoft_agents_a365/observability/core/source_metadata.py +2 -1
- microsoft_agents_a365/observability/core/tenant_details.py +2 -1
- microsoft_agents_a365/observability/core/tool_call_details.py +2 -1
- microsoft_agents_a365/observability/core/tool_type.py +2 -1
- microsoft_agents_a365/observability/core/trace_processor/__init__.py +2 -1
- microsoft_agents_a365/observability/core/trace_processor/span_processor.py +13 -3
- microsoft_agents_a365/observability/core/trace_processor/util.py +10 -5
- microsoft_agents_a365/observability/core/utils.py +53 -4
- {microsoft_agents_a365_observability_core-0.1.0.dev30.dist-info → microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info}/METADATA +3 -3
- microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info/RECORD +35 -0
- {microsoft_agents_a365_observability_core-0.1.0.dev30.dist-info → microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info}/WHEEL +1 -1
- {microsoft_agents_a365_observability_core-0.1.0.dev30.dist-info → microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info}/top_level.txt +1 -0
- microsoft_agents_a365/observability/core/middleware/turn_context_baggage.py +0 -193
- microsoft_agents_a365_observability_core-0.1.0.dev30.dist-info/RECORD +0 -33
|
@@ -5,6 +5,8 @@ from typing import List
|
|
|
5
5
|
|
|
6
6
|
from .agent_details import AgentDetails
|
|
7
7
|
from .constants import (
|
|
8
|
+
GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY,
|
|
9
|
+
GEN_AI_EXECUTION_SOURCE_NAME_KEY,
|
|
8
10
|
GEN_AI_INPUT_MESSAGES_KEY,
|
|
9
11
|
GEN_AI_OPERATION_NAME_KEY,
|
|
10
12
|
GEN_AI_OUTPUT_MESSAGES_KEY,
|
|
@@ -90,6 +92,13 @@ class InferenceScope(OpenTelemetryScope):
|
|
|
90
92
|
)
|
|
91
93
|
self.set_tag_maybe(GEN_AI_RESPONSE_ID_KEY, details.responseId)
|
|
92
94
|
|
|
95
|
+
# Set request metadata if provided
|
|
96
|
+
if request and request.source_metadata:
|
|
97
|
+
self.set_tag_maybe(GEN_AI_EXECUTION_SOURCE_NAME_KEY, request.source_metadata.name)
|
|
98
|
+
self.set_tag_maybe(
|
|
99
|
+
GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY, request.source_metadata.description
|
|
100
|
+
)
|
|
101
|
+
|
|
93
102
|
def record_input_messages(self, messages: List[str]) -> None:
|
|
94
103
|
"""Records the input messages for telemetry tracking.
|
|
95
104
|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
# Invoke agent scope for tracing agent invocation.
|
|
5
5
|
|
|
6
|
+
import logging
|
|
7
|
+
|
|
6
8
|
from .agent_details import AgentDetails
|
|
7
9
|
from .constants import (
|
|
8
10
|
GEN_AI_CALLER_AGENT_APPLICATION_ID_KEY,
|
|
@@ -10,6 +12,7 @@ from .constants import (
|
|
|
10
12
|
GEN_AI_CALLER_AGENT_NAME_KEY,
|
|
11
13
|
GEN_AI_CALLER_AGENT_TENANT_ID_KEY,
|
|
12
14
|
GEN_AI_CALLER_AGENT_UPN_KEY,
|
|
15
|
+
GEN_AI_CALLER_AGENT_USER_CLIENT_IP,
|
|
13
16
|
GEN_AI_CALLER_AGENT_USER_ID_KEY,
|
|
14
17
|
GEN_AI_CALLER_ID_KEY,
|
|
15
18
|
GEN_AI_CALLER_NAME_KEY,
|
|
@@ -17,7 +20,6 @@ from .constants import (
|
|
|
17
20
|
GEN_AI_CALLER_UPN_KEY,
|
|
18
21
|
GEN_AI_CALLER_USER_ID_KEY,
|
|
19
22
|
GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY,
|
|
20
|
-
GEN_AI_EXECUTION_SOURCE_ID_KEY,
|
|
21
23
|
GEN_AI_EXECUTION_SOURCE_NAME_KEY,
|
|
22
24
|
GEN_AI_EXECUTION_TYPE_KEY,
|
|
23
25
|
GEN_AI_INPUT_MESSAGES_KEY,
|
|
@@ -32,7 +34,9 @@ from .models.caller_details import CallerDetails
|
|
|
32
34
|
from .opentelemetry_scope import OpenTelemetryScope
|
|
33
35
|
from .request import Request
|
|
34
36
|
from .tenant_details import TenantDetails
|
|
35
|
-
from .utils import safe_json_dumps
|
|
37
|
+
from .utils import safe_json_dumps, validate_and_normalize_ip
|
|
38
|
+
|
|
39
|
+
logger = logging.getLogger(__name__)
|
|
36
40
|
|
|
37
41
|
|
|
38
42
|
class InvokeAgentScope(OpenTelemetryScope):
|
|
@@ -111,7 +115,6 @@ class InvokeAgentScope(OpenTelemetryScope):
|
|
|
111
115
|
# Set request metadata if provided
|
|
112
116
|
if request:
|
|
113
117
|
if request.source_metadata:
|
|
114
|
-
self.set_tag_maybe(GEN_AI_EXECUTION_SOURCE_ID_KEY, request.source_metadata.id)
|
|
115
118
|
self.set_tag_maybe(GEN_AI_EXECUTION_SOURCE_NAME_KEY, request.source_metadata.name)
|
|
116
119
|
self.set_tag_maybe(
|
|
117
120
|
GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY, request.source_metadata.description
|
|
@@ -121,6 +124,7 @@ class InvokeAgentScope(OpenTelemetryScope):
|
|
|
121
124
|
GEN_AI_EXECUTION_TYPE_KEY,
|
|
122
125
|
request.execution_type.value if request.execution_type else None,
|
|
123
126
|
)
|
|
127
|
+
self.set_tag_maybe(GEN_AI_INPUT_MESSAGES_KEY, safe_json_dumps([request.content]))
|
|
124
128
|
|
|
125
129
|
# Set caller details tags
|
|
126
130
|
if caller_details:
|
|
@@ -140,6 +144,11 @@ class InvokeAgentScope(OpenTelemetryScope):
|
|
|
140
144
|
self.set_tag_maybe(GEN_AI_CALLER_AGENT_USER_ID_KEY, caller_agent_details.agent_auid)
|
|
141
145
|
self.set_tag_maybe(GEN_AI_CALLER_AGENT_UPN_KEY, caller_agent_details.agent_upn)
|
|
142
146
|
self.set_tag_maybe(GEN_AI_CALLER_AGENT_TENANT_ID_KEY, caller_agent_details.tenant_id)
|
|
147
|
+
# Validate and set caller agent client IP
|
|
148
|
+
self.set_tag_maybe(
|
|
149
|
+
GEN_AI_CALLER_AGENT_USER_CLIENT_IP,
|
|
150
|
+
validate_and_normalize_ip(caller_agent_details.agent_client_ip),
|
|
151
|
+
)
|
|
143
152
|
|
|
144
153
|
def record_response(self, response: str) -> None:
|
|
145
154
|
"""Record response information for telemetry tracking.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
# Copyright (c) Microsoft
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
2
3
|
|
|
3
4
|
# Per request baggage builder for OpenTelemetry context propagation.
|
|
4
5
|
|
|
6
|
+
import logging
|
|
5
7
|
from typing import Any
|
|
6
8
|
|
|
7
9
|
from opentelemetry import baggage, context
|
|
@@ -14,19 +16,24 @@ from ..constants import (
|
|
|
14
16
|
GEN_AI_AGENT_ID_KEY,
|
|
15
17
|
GEN_AI_AGENT_NAME_KEY,
|
|
16
18
|
GEN_AI_AGENT_UPN_KEY,
|
|
19
|
+
GEN_AI_CALLER_CLIENT_IP_KEY,
|
|
17
20
|
GEN_AI_CALLER_ID_KEY,
|
|
18
21
|
GEN_AI_CALLER_NAME_KEY,
|
|
19
22
|
GEN_AI_CALLER_UPN_KEY,
|
|
20
23
|
GEN_AI_CONVERSATION_ID_KEY,
|
|
21
24
|
GEN_AI_CONVERSATION_ITEM_LINK_KEY,
|
|
22
25
|
GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY,
|
|
23
|
-
GEN_AI_EXECUTION_SOURCE_ID_KEY,
|
|
24
26
|
GEN_AI_EXECUTION_SOURCE_NAME_KEY,
|
|
25
27
|
HIRING_MANAGER_ID_KEY,
|
|
26
28
|
OPERATION_SOURCE_KEY,
|
|
29
|
+
SESSION_DESCRIPTION_KEY,
|
|
30
|
+
SESSION_ID_KEY,
|
|
27
31
|
TENANT_ID_KEY,
|
|
28
32
|
)
|
|
29
|
-
from .
|
|
33
|
+
from ..models.operation_source import OperationSource
|
|
34
|
+
from ..utils import deprecated, validate_and_normalize_ip
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
30
37
|
|
|
31
38
|
|
|
32
39
|
class BaggageBuilder:
|
|
@@ -36,30 +43,35 @@ class BaggageBuilder:
|
|
|
36
43
|
propagated in the OpenTelemetry context.
|
|
37
44
|
|
|
38
45
|
Example:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
.. code-block:: python
|
|
47
|
+
|
|
48
|
+
builder = (BaggageBuilder()
|
|
49
|
+
.tenant_id("tenant-123")
|
|
50
|
+
.agent_id("agent-456")
|
|
51
|
+
.correlation_id("corr-789"))
|
|
52
|
+
|
|
53
|
+
with builder.build():
|
|
54
|
+
# Baggage is set in this context
|
|
55
|
+
pass
|
|
56
|
+
# Baggage is restored after exiting the context
|
|
47
57
|
"""
|
|
48
58
|
|
|
49
59
|
def __init__(self):
|
|
50
60
|
"""Initialize the baggage builder."""
|
|
51
61
|
self._pairs: dict[str, str] = {}
|
|
52
62
|
|
|
53
|
-
def operation_source(self, value:
|
|
63
|
+
def operation_source(self, value: OperationSource | None) -> "BaggageBuilder":
|
|
54
64
|
"""Set the operation source baggage value.
|
|
55
65
|
|
|
56
66
|
Args:
|
|
57
|
-
value: The operation source value
|
|
67
|
+
value: The operation source enum value
|
|
58
68
|
|
|
59
69
|
Returns:
|
|
60
70
|
Self for method chaining
|
|
61
71
|
"""
|
|
62
|
-
|
|
72
|
+
# Convert enum to string value for baggage storage
|
|
73
|
+
str_value = value.value if value is not None else None
|
|
74
|
+
self._set(OPERATION_SOURCE_KEY, str_value)
|
|
63
75
|
return self
|
|
64
76
|
|
|
65
77
|
def tenant_id(self, value: str | None) -> "BaggageBuilder":
|
|
@@ -178,6 +190,11 @@ class BaggageBuilder:
|
|
|
178
190
|
self._set(GEN_AI_CALLER_UPN_KEY, value)
|
|
179
191
|
return self
|
|
180
192
|
|
|
193
|
+
def caller_client_ip(self, value: str | None) -> "BaggageBuilder":
|
|
194
|
+
"""Set the caller client IP baggage value."""
|
|
195
|
+
self._set(GEN_AI_CALLER_CLIENT_IP_KEY, validate_and_normalize_ip(value))
|
|
196
|
+
return self
|
|
197
|
+
|
|
181
198
|
def conversation_id(self, value: str | None) -> "BaggageBuilder":
|
|
182
199
|
"""Set the conversation ID baggage value."""
|
|
183
200
|
self._set(GEN_AI_CONVERSATION_ID_KEY, value)
|
|
@@ -188,28 +205,35 @@ class BaggageBuilder:
|
|
|
188
205
|
self._set(GEN_AI_CONVERSATION_ITEM_LINK_KEY, value)
|
|
189
206
|
return self
|
|
190
207
|
|
|
191
|
-
|
|
192
|
-
"""Set the execution source metadata ID (e.g., channel ID)."""
|
|
193
|
-
self._set(GEN_AI_EXECUTION_SOURCE_ID_KEY, value)
|
|
194
|
-
return self
|
|
195
|
-
|
|
208
|
+
@deprecated("Use channel_name() instead")
|
|
196
209
|
def source_metadata_name(self, value: str | None) -> "BaggageBuilder":
|
|
197
210
|
"""Set the execution source metadata name (e.g., channel name)."""
|
|
198
|
-
self.
|
|
199
|
-
return self
|
|
211
|
+
return self.channel_name(value)
|
|
200
212
|
|
|
213
|
+
@deprecated("Use channel_links() instead")
|
|
201
214
|
def source_metadata_description(self, value: str | None) -> "BaggageBuilder":
|
|
202
215
|
"""Set the execution source metadata description (e.g., channel description)."""
|
|
203
|
-
self.
|
|
216
|
+
return self.channel_links(value)
|
|
217
|
+
|
|
218
|
+
def session_id(self, value: str | None) -> "BaggageBuilder":
|
|
219
|
+
"""Set the session ID baggage value."""
|
|
220
|
+
self._set(SESSION_ID_KEY, value)
|
|
204
221
|
return self
|
|
205
222
|
|
|
206
|
-
def
|
|
207
|
-
"""
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
"""
|
|
223
|
+
def session_description(self, value: str | None) -> "BaggageBuilder":
|
|
224
|
+
"""Set the session description baggage value."""
|
|
225
|
+
self._set(SESSION_DESCRIPTION_KEY, value)
|
|
226
|
+
return self
|
|
211
227
|
|
|
212
|
-
|
|
228
|
+
def channel_name(self, value: str | None) -> "BaggageBuilder":
|
|
229
|
+
"""Sets the channel name baggage value (e.g., 'Teams', 'msteams')."""
|
|
230
|
+
self._set(GEN_AI_EXECUTION_SOURCE_NAME_KEY, value)
|
|
231
|
+
return self
|
|
232
|
+
|
|
233
|
+
def channel_links(self, value: str | None) -> "BaggageBuilder":
|
|
234
|
+
"""Sets the channel link baggage value. (e.g., channel links or description)."""
|
|
235
|
+
self._set(GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY, value)
|
|
236
|
+
return self
|
|
213
237
|
|
|
214
238
|
def set_pairs(self, pairs: Any) -> "BaggageBuilder":
|
|
215
239
|
"""
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
"""Operation source enumeration for Agent365 SDK."""
|
|
5
|
+
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OperationSource(Enum):
|
|
10
|
+
"""
|
|
11
|
+
Enumeration representing the source of an operation.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
SDK = "SDK"
|
|
15
|
+
"""Operation executed by SDK."""
|
|
16
|
+
|
|
17
|
+
GATEWAY = "Gateway"
|
|
18
|
+
"""Operation executed by Gateway."""
|
|
19
|
+
|
|
20
|
+
MCP_SERVER = "MCPServer"
|
|
21
|
+
"""Operation executed by MCP Server."""
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# Copyright (c) Microsoft
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
2
3
|
|
|
3
4
|
# Request class.
|
|
4
5
|
|
|
@@ -16,4 +17,3 @@ class Request:
|
|
|
16
17
|
execution_type: ExecutionType
|
|
17
18
|
session_id: str | None = None
|
|
18
19
|
source_metadata: SourceMetadata | None = None
|
|
19
|
-
payload: str | None = None
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
2
3
|
|
|
3
|
-
Span processor for copying OpenTelemetry baggage entries onto spans.
|
|
4
|
+
"""Span processor for copying OpenTelemetry baggage entries onto spans.
|
|
4
5
|
|
|
5
6
|
This implementation assumes `opentelemetry.baggage.get_all` is available with the
|
|
6
7
|
signature `get_all(context: Context | None) -> Mapping[str, object]`.
|
|
@@ -16,7 +17,8 @@ For every new span:
|
|
|
16
17
|
from opentelemetry import baggage, context
|
|
17
18
|
from opentelemetry.sdk.trace import SpanProcessor as BaseSpanProcessor
|
|
18
19
|
|
|
19
|
-
from ..constants import GEN_AI_OPERATION_NAME_KEY, INVOKE_AGENT_OPERATION_NAME
|
|
20
|
+
from ..constants import GEN_AI_OPERATION_NAME_KEY, INVOKE_AGENT_OPERATION_NAME, OPERATION_SOURCE_KEY
|
|
21
|
+
from ..models.operation_source import OperationSource
|
|
20
22
|
from .util import COMMON_ATTRIBUTES, INVOKE_AGENT_ATTRIBUTES
|
|
21
23
|
|
|
22
24
|
|
|
@@ -41,6 +43,14 @@ class SpanProcessor(BaseSpanProcessor):
|
|
|
41
43
|
except Exception:
|
|
42
44
|
baggage_map = {}
|
|
43
45
|
|
|
46
|
+
# Set operation source - coalesce baggage value with SDK default
|
|
47
|
+
if OPERATION_SOURCE_KEY not in existing:
|
|
48
|
+
operation_source = baggage_map.get(OPERATION_SOURCE_KEY) or OperationSource.SDK.value
|
|
49
|
+
try:
|
|
50
|
+
span.set_attribute(OPERATION_SOURCE_KEY, operation_source)
|
|
51
|
+
except Exception:
|
|
52
|
+
pass
|
|
53
|
+
|
|
44
54
|
operation_name = existing.get(GEN_AI_OPERATION_NAME_KEY)
|
|
45
55
|
is_invoke_agent = False
|
|
46
56
|
if operation_name == INVOKE_AGENT_OPERATION_NAME:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# Copyright (c) Microsoft
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
2
3
|
|
|
3
4
|
from .. import constants as consts
|
|
4
5
|
|
|
@@ -19,6 +20,14 @@ COMMON_ATTRIBUTES = [
|
|
|
19
20
|
consts.GEN_AI_AGENT_BLUEPRINT_ID_KEY, # gen_ai.agent.applicationid
|
|
20
21
|
consts.GEN_AI_AGENT_AUID_KEY,
|
|
21
22
|
consts.GEN_AI_AGENT_TYPE_KEY,
|
|
23
|
+
consts.OPERATION_SOURCE_KEY, # operation.source
|
|
24
|
+
consts.SESSION_ID_KEY,
|
|
25
|
+
consts.SESSION_DESCRIPTION_KEY,
|
|
26
|
+
consts.HIRING_MANAGER_ID_KEY,
|
|
27
|
+
consts.GEN_AI_CALLER_CLIENT_IP_KEY, # gen_ai.caller.client.ip
|
|
28
|
+
# Execution context
|
|
29
|
+
consts.GEN_AI_EXECUTION_SOURCE_NAME_KEY, # gen_ai.channel.name
|
|
30
|
+
consts.GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY, # gen_ai.channel.link
|
|
22
31
|
]
|
|
23
32
|
|
|
24
33
|
# Invoke Agent–specific attributes
|
|
@@ -36,9 +45,5 @@ INVOKE_AGENT_ATTRIBUTES = [
|
|
|
36
45
|
consts.GEN_AI_CALLER_AGENT_UPN_KEY, # gen_ai.caller.agent.upn
|
|
37
46
|
consts.GEN_AI_CALLER_AGENT_TENANT_ID_KEY, # gen_ai.caller.agent.tenantid
|
|
38
47
|
consts.GEN_AI_CALLER_AGENT_APPLICATION_ID_KEY, # gen_ai.caller.agent.applicationid
|
|
39
|
-
# Execution context
|
|
40
48
|
consts.GEN_AI_EXECUTION_TYPE_KEY, # gen_ai.execution.type
|
|
41
|
-
consts.GEN_AI_EXECUTION_SOURCE_ID_KEY, # gen_ai.execution.sourceMetadata.id
|
|
42
|
-
consts.GEN_AI_EXECUTION_SOURCE_NAME_KEY, # gen_ai.execution.sourceMetadata.name
|
|
43
|
-
consts.GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY, # gen_ai.execution.sourceMetadata.description
|
|
44
49
|
]
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
# Copyright (c) Microsoft
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
2
3
|
|
|
3
4
|
import datetime
|
|
5
|
+
import functools
|
|
4
6
|
import json
|
|
5
7
|
import logging
|
|
6
8
|
import traceback
|
|
9
|
+
import warnings
|
|
7
10
|
from collections.abc import Callable, Hashable, Iterable, Iterator, Mapping
|
|
8
11
|
from enum import Enum
|
|
12
|
+
from ipaddress import AddressValueError, ip_address
|
|
9
13
|
from threading import RLock
|
|
10
14
|
from typing import Any, Generic, TypeVar, cast
|
|
11
15
|
|
|
12
|
-
from opentelemetry.semconv.
|
|
16
|
+
from opentelemetry.semconv.attributes.exception_attributes import (
|
|
17
|
+
EXCEPTION_MESSAGE,
|
|
18
|
+
EXCEPTION_STACKTRACE,
|
|
19
|
+
)
|
|
13
20
|
from opentelemetry.trace import Span
|
|
14
21
|
from opentelemetry.util.types import AttributeValue
|
|
15
22
|
from wrapt import ObjectProxy
|
|
@@ -69,10 +76,10 @@ def record_exception(span: Span, error: BaseException) -> None:
|
|
|
69
76
|
exception_message = repr(error)
|
|
70
77
|
attributes: dict[str, AttributeValue] = {
|
|
71
78
|
ERROR_TYPE_KEY: exception_type,
|
|
72
|
-
|
|
79
|
+
EXCEPTION_MESSAGE: exception_message,
|
|
73
80
|
}
|
|
74
81
|
try:
|
|
75
|
-
attributes[
|
|
82
|
+
attributes[EXCEPTION_STACKTRACE] = traceback.format_exc()
|
|
76
83
|
except Exception:
|
|
77
84
|
logger.exception("Failed to record exception stacktrace.")
|
|
78
85
|
span.add_event(name="exception", attributes=attributes)
|
|
@@ -149,3 +156,45 @@ def extract_model_name(span_name: str) -> str | None:
|
|
|
149
156
|
return model_name.strip()
|
|
150
157
|
|
|
151
158
|
return None
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def deprecated(reason: str):
|
|
162
|
+
"""Decorator to mark functions as deprecated."""
|
|
163
|
+
|
|
164
|
+
def decorator(func):
|
|
165
|
+
@functools.wraps(func)
|
|
166
|
+
def wrapper(*args, **kwargs):
|
|
167
|
+
warnings.warn(
|
|
168
|
+
f"{func.__name__}() is deprecated. {reason}",
|
|
169
|
+
category=DeprecationWarning,
|
|
170
|
+
stacklevel=2,
|
|
171
|
+
)
|
|
172
|
+
return func(*args, **kwargs)
|
|
173
|
+
|
|
174
|
+
return wrapper
|
|
175
|
+
|
|
176
|
+
return decorator
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def validate_and_normalize_ip(ip_string: str | None) -> str | None:
|
|
180
|
+
"""Validate and normalize an IP address string.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
ip_string: The IP address string to validate (IPv4 or IPv6)
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
The normalized IP address string if valid, None if invalid or None input
|
|
187
|
+
|
|
188
|
+
Logs:
|
|
189
|
+
Error message if the IP address is invalid
|
|
190
|
+
"""
|
|
191
|
+
if ip_string is None:
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
# Validate and normalize IP address
|
|
196
|
+
ip_obj = ip_address(ip_string)
|
|
197
|
+
return str(ip_obj)
|
|
198
|
+
except (ValueError, AddressValueError):
|
|
199
|
+
logger.error(f"Invalid IP address: '{ip_string}'")
|
|
200
|
+
return None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: microsoft-agents-a365-observability-core
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.2.1.dev0
|
|
4
4
|
Summary: Telemetry, tracing, and monitoring components for AI agents
|
|
5
5
|
Author-email: Microsoft <support@microsoft.com>
|
|
6
6
|
License: MIT
|
|
@@ -64,7 +64,7 @@ For usage examples and detailed documentation, see the [Observability documentat
|
|
|
64
64
|
For issues, questions, or feedback:
|
|
65
65
|
|
|
66
66
|
- File issues in the [GitHub Issues](https://github.com/microsoft/Agent365-python/issues) section
|
|
67
|
-
- See the [main documentation](
|
|
67
|
+
- See the [main documentation](../../README.md) for more information
|
|
68
68
|
|
|
69
69
|
## Trademarks
|
|
70
70
|
|
|
@@ -74,5 +74,5 @@ For issues, questions, or feedback:
|
|
|
74
74
|
|
|
75
75
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
76
76
|
|
|
77
|
-
Licensed under the MIT License - see the [LICENSE](
|
|
77
|
+
Licensed under the MIT License - see the [LICENSE](../../LICENSE.md) file for details.
|
|
78
78
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
microsoft_agents_a365/observability/core/__init__.py,sha256=r613vGLepo9ttTRmq3_EQz3hfDd4Ukp3v8AVS-6Uf_o,1762
|
|
2
|
+
microsoft_agents_a365/observability/core/agent_details.py,sha256=7x4tqcocig1hz4T6eCRZy7fSF2gOCpM0pvE6Q3Txww0,1210
|
|
3
|
+
microsoft_agents_a365/observability/core/config.py,sha256=YhnQaJr-SVNJLGM_HvYvaAfwXn-h9KinbNNZeXG9w90,11751
|
|
4
|
+
microsoft_agents_a365/observability/core/constants.py,sha256=suvJc4JgB9o3eeDVyiJDk0kjFVkjeDrl6u43XsvPWBc,4747
|
|
5
|
+
microsoft_agents_a365/observability/core/execute_tool_scope.py,sha256=XgramOBLhpilR5VjFsigdDCqYkDkG0D6CIrwN5xgeJw,3654
|
|
6
|
+
microsoft_agents_a365/observability/core/execution_type.py,sha256=qnNGmo9-Tlb3PBTK3pen2QIAm2hlQiKl8vRuMPWHtk8,328
|
|
7
|
+
microsoft_agents_a365/observability/core/inference_call_details.py,sha256=VZGB7ybr3BT7YZbjRU92YCpsDyvoicILoWPejKiI1rM,508
|
|
8
|
+
microsoft_agents_a365/observability/core/inference_operation_type.py,sha256=6FKl9lxSBgPptwD7TZ4znrd8t6R9nD1rq1QPACfVsqY,298
|
|
9
|
+
microsoft_agents_a365/observability/core/inference_scope.py,sha256=fca5AdPw5PvHSNkLgUpJGsZWxG5c-BDUFLnRKjpAEuo,5382
|
|
10
|
+
microsoft_agents_a365/observability/core/invoke_agent_details.py,sha256=ED0pjtlQAl-wCO9vJqXv-xghCwVFn_c8FCSz_vpEa_s,414
|
|
11
|
+
microsoft_agents_a365/observability/core/invoke_agent_scope.py,sha256=A2syvvT9lUE1x7M1Ns7DuXY0J4STMiOBe7kGmPpyLmQ,6917
|
|
12
|
+
microsoft_agents_a365/observability/core/opentelemetry_scope.py,sha256=J2vetCZnVRgVgc7wlKzmL5FbGf5LdbWaf1ryxt8rBC0,9759
|
|
13
|
+
microsoft_agents_a365/observability/core/request.py,sha256=FVO8cjNSAp_5NnOmz4XuXkKJNl5NOYBHZAIDRo6mjcc,424
|
|
14
|
+
microsoft_agents_a365/observability/core/source_metadata.py,sha256=BgAyyA17sZtHSDH1aPQAm1BEtQ3G5zpbKZinjew_leo,346
|
|
15
|
+
microsoft_agents_a365/observability/core/tenant_details.py,sha256=VoJIUeEIIHRvr2trzRz5BE8QWkLTt6Z4NVVI2MbyBeQ,243
|
|
16
|
+
microsoft_agents_a365/observability/core/tool_call_details.py,sha256=D7wrDYjr2-65Ddx2LwK2P5bSghqq7ehdhUUToUiW-SI,480
|
|
17
|
+
microsoft_agents_a365/observability/core/tool_type.py,sha256=Jg021SlX-Vwz2WdHffcgJFm9Ys3zr1LRJNf4KYaZ6S4,296
|
|
18
|
+
microsoft_agents_a365/observability/core/utils.py,sha256=fnZBCEsD-1FlxpJ5hcbwovrEK4baeSKOyKJADSD3n3Q,6063
|
|
19
|
+
microsoft_agents_a365/observability/core/exporters/__init__.py,sha256=UEaMJYkbTViVAUVQTFSf1BUvni1pNTcDwriKzOzvGFU,296
|
|
20
|
+
microsoft_agents_a365/observability/core/exporters/agent365_exporter.py,sha256=Q8ylOrgBF2gNB_KAn8QdtJu8E3aiC6kUUomCgNLqgb4,13490
|
|
21
|
+
microsoft_agents_a365/observability/core/exporters/agent365_exporter_options.py,sha256=f-p11ZQfxtDIiK-kVPDfebBgT83onxdE29IQryYoAPk,1648
|
|
22
|
+
microsoft_agents_a365/observability/core/exporters/utils.py,sha256=tICuOuWfgUKL1dHoGuyG5_xNOrREPTXFE-RJZehpVT4,6989
|
|
23
|
+
microsoft_agents_a365/observability/core/middleware/__init__.py,sha256=KNH2QjJBIGhn1xf_r3HdOVYUw9ngKEcy0HV9eHuTaqk,202
|
|
24
|
+
microsoft_agents_a365/observability/core/middleware/baggage_builder.py,sha256=KaTb8n0D8dbjS-qph3o160VUEn4kYy8YdaFvGMd5Vck,10505
|
|
25
|
+
microsoft_agents_a365/observability/core/models/__init__.py,sha256=aCOr6sEsQpv9z4cJgWFA4qOs4xJqclqYYnxOVcxiK2Q,75
|
|
26
|
+
microsoft_agents_a365/observability/core/models/agent_type.py,sha256=ZazwwMAQRrYzzN3Ytz69F6thV4R6nemA6JrK-70fyt0,560
|
|
27
|
+
microsoft_agents_a365/observability/core/models/caller_details.py,sha256=8oaRKeGNteZq_RAQShhfUBs0iO-Sr9yjfk13Mv-xSjA,674
|
|
28
|
+
microsoft_agents_a365/observability/core/models/operation_source.py,sha256=HJp-SNR-lNSPIgoLlF6DMMlijtu4ZGhnqSyu58lIgnk,448
|
|
29
|
+
microsoft_agents_a365/observability/core/trace_processor/__init__.py,sha256=0QDkZgvgGekJVcZXjubSqipYhCGMZaAAxLSanyR76pg,219
|
|
30
|
+
microsoft_agents_a365/observability/core/trace_processor/span_processor.py,sha256=O_DLuLR-6sV9VmkYfMzUF3s6n1OLrtK5qkD6csen73g,2980
|
|
31
|
+
microsoft_agents_a365/observability/core/trace_processor/util.py,sha256=h5oOFAGIY6x9WtgfErPetblSkWZsQZjOgbwoR_tL-7k,2364
|
|
32
|
+
microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info/METADATA,sha256=mCXs-XGApLHUEkD7f17jKeJSHwXC4Um4U6eeV5Hnbyw,3871
|
|
33
|
+
microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
34
|
+
microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info/top_level.txt,sha256=m90AvzRnjbL6fpi20mzOj6HUVkR2LWuf2JuXm4LL9LU,27
|
|
35
|
+
microsoft_agents_a365_observability_core-0.2.1.dev0.dist-info/RECORD,,
|