microsoft-agents-a365-observability-extensions-semantic-kernel 0.2.1.dev7__py3-none-any.whl → 0.2.1.dev9__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/extensions/semantickernel/span_enricher.py +75 -0
- microsoft_agents_a365/observability/extensions/semantickernel/span_processor.py +39 -5
- microsoft_agents_a365/observability/extensions/semantickernel/trace_instrumentor.py +36 -12
- microsoft_agents_a365/observability/extensions/semantickernel/utils.py +37 -0
- {microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info → microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info}/METADATA +1 -1
- microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info/RECORD +9 -0
- microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info/RECORD +0 -7
- {microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info → microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info}/WHEEL +0 -0
- {microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info → microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
"""Span enricher for Semantic Kernel."""
|
|
5
|
+
|
|
6
|
+
from microsoft_agents_a365.observability.core.constants import (
|
|
7
|
+
EXECUTE_TOOL_OPERATION_NAME,
|
|
8
|
+
GEN_AI_INPUT_MESSAGES_KEY,
|
|
9
|
+
GEN_AI_OUTPUT_MESSAGES_KEY,
|
|
10
|
+
GEN_AI_TOOL_ARGS_KEY,
|
|
11
|
+
GEN_AI_TOOL_CALL_RESULT_KEY,
|
|
12
|
+
INVOKE_AGENT_OPERATION_NAME,
|
|
13
|
+
)
|
|
14
|
+
from microsoft_agents_a365.observability.core.exporters.enriched_span import EnrichedReadableSpan
|
|
15
|
+
from opentelemetry.sdk.trace import ReadableSpan
|
|
16
|
+
|
|
17
|
+
from .utils import extract_content_as_string_list
|
|
18
|
+
|
|
19
|
+
# Semantic Kernel specific attribute keys
|
|
20
|
+
SK_TOOL_CALL_ARGUMENTS_KEY = "gen_ai.tool.call.arguments"
|
|
21
|
+
SK_TOOL_CALL_RESULT_KEY = "gen_ai.tool.call.result"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def enrich_semantic_kernel_span(span: ReadableSpan) -> ReadableSpan:
|
|
25
|
+
"""
|
|
26
|
+
Enricher function for Semantic Kernel spans.
|
|
27
|
+
|
|
28
|
+
Transforms SK-specific attributes to standard gen_ai attributes
|
|
29
|
+
before the span is exported. Enrichment is applied based on span type:
|
|
30
|
+
- invoke_agent spans: Extract only content from input/output messages
|
|
31
|
+
- execute_tool spans: Map tool arguments and results to standard keys
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
span: The ReadableSpan to enrich.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
The enriched span (wrapped if attributes were added), or the
|
|
38
|
+
original span if no enrichment was needed.
|
|
39
|
+
"""
|
|
40
|
+
extra_attributes = {}
|
|
41
|
+
attributes = span.attributes or {}
|
|
42
|
+
|
|
43
|
+
# Only extract content for invoke_agent spans
|
|
44
|
+
if span.name.startswith(INVOKE_AGENT_OPERATION_NAME):
|
|
45
|
+
# Transform SK-specific agent invocation attributes to standard gen_ai attributes
|
|
46
|
+
# Extract only the content from the full message objects
|
|
47
|
+
# Support both gen_ai.agent.invocation_input and gen_ai.input_messages as sources
|
|
48
|
+
input_messages = attributes.get("gen_ai.agent.invocation_input") or attributes.get(
|
|
49
|
+
GEN_AI_INPUT_MESSAGES_KEY
|
|
50
|
+
)
|
|
51
|
+
if input_messages:
|
|
52
|
+
extra_attributes[GEN_AI_INPUT_MESSAGES_KEY] = extract_content_as_string_list(
|
|
53
|
+
input_messages
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
output_messages = attributes.get("gen_ai.agent.invocation_output") or attributes.get(
|
|
57
|
+
GEN_AI_OUTPUT_MESSAGES_KEY
|
|
58
|
+
)
|
|
59
|
+
if output_messages:
|
|
60
|
+
extra_attributes[GEN_AI_OUTPUT_MESSAGES_KEY] = extract_content_as_string_list(
|
|
61
|
+
output_messages
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Map tool attributes for execute_tool spans
|
|
65
|
+
elif span.name.startswith(EXECUTE_TOOL_OPERATION_NAME):
|
|
66
|
+
if SK_TOOL_CALL_ARGUMENTS_KEY in attributes:
|
|
67
|
+
extra_attributes[GEN_AI_TOOL_ARGS_KEY] = attributes[SK_TOOL_CALL_ARGUMENTS_KEY]
|
|
68
|
+
|
|
69
|
+
if SK_TOOL_CALL_RESULT_KEY in attributes:
|
|
70
|
+
extra_attributes[GEN_AI_TOOL_CALL_RESULT_KEY] = attributes[SK_TOOL_CALL_RESULT_KEY]
|
|
71
|
+
|
|
72
|
+
if extra_attributes:
|
|
73
|
+
return EnrichedReadableSpan(span, extra_attributes)
|
|
74
|
+
|
|
75
|
+
return span
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
# Copyright (c) Microsoft Corporation.
|
|
2
2
|
# Licensed under the MIT License.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
from microsoft_agents_a365.observability.core.constants import (
|
|
5
|
+
GEN_AI_EXECUTION_TYPE_KEY,
|
|
6
|
+
GEN_AI_OPERATION_NAME_KEY,
|
|
7
|
+
INVOKE_AGENT_OPERATION_NAME,
|
|
8
|
+
)
|
|
9
|
+
from microsoft_agents_a365.observability.core.execution_type import ExecutionType
|
|
7
10
|
from microsoft_agents_a365.observability.core.inference_operation_type import InferenceOperationType
|
|
8
11
|
from microsoft_agents_a365.observability.core.utils import extract_model_name
|
|
12
|
+
from opentelemetry import context as context_api
|
|
13
|
+
from opentelemetry.sdk.trace import ReadableSpan, Span
|
|
9
14
|
from opentelemetry.sdk.trace.export import SpanProcessor
|
|
10
15
|
|
|
11
16
|
|
|
@@ -15,13 +20,42 @@ class SemanticKernelSpanProcessor(SpanProcessor):
|
|
|
15
20
|
"""
|
|
16
21
|
|
|
17
22
|
def __init__(self, service_name: str | None = None):
|
|
23
|
+
"""
|
|
24
|
+
Initialize the Semantic Kernel span processor.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
service_name: Optional service name for span enrichment.
|
|
28
|
+
"""
|
|
18
29
|
self.service_name = service_name
|
|
19
30
|
|
|
20
|
-
def on_start(self, span, parent_context):
|
|
31
|
+
def on_start(self, span: Span, parent_context: context_api.Context | None) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Modify span while it's still writable.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
span: The span that is starting (writable).
|
|
37
|
+
parent_context: The parent context of the span.
|
|
38
|
+
"""
|
|
21
39
|
if span.name.startswith("chat."):
|
|
22
40
|
span.set_attribute(GEN_AI_OPERATION_NAME_KEY, InferenceOperationType.CHAT.value.lower())
|
|
23
41
|
model_name = extract_model_name(span.name)
|
|
24
42
|
span.update_name(f"{InferenceOperationType.CHAT.value.lower()} {model_name}")
|
|
25
43
|
|
|
26
|
-
|
|
44
|
+
if span.name.startswith(INVOKE_AGENT_OPERATION_NAME):
|
|
45
|
+
span.set_attribute(
|
|
46
|
+
GEN_AI_EXECUTION_TYPE_KEY, ExecutionType.HUMAN_TO_AGENT.value.lower()
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def on_end(self, span: ReadableSpan) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Called when a span ends.
|
|
52
|
+
"""
|
|
27
53
|
pass
|
|
54
|
+
|
|
55
|
+
def shutdown(self) -> None:
|
|
56
|
+
"""Shutdown the processor."""
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
def force_flush(self, timeout_millis: int = 30000) -> bool:
|
|
60
|
+
"""Force flush any pending spans."""
|
|
61
|
+
return True
|
|
@@ -6,30 +6,35 @@ from __future__ import annotations
|
|
|
6
6
|
from collections.abc import Collection
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
-
from microsoft_agents_a365.observability.core.config import
|
|
9
|
+
from microsoft_agents_a365.observability.core.config import (
|
|
10
|
+
get_tracer_provider,
|
|
11
|
+
is_configured,
|
|
12
|
+
)
|
|
13
|
+
from microsoft_agents_a365.observability.core.exporters.enriching_span_processor import (
|
|
14
|
+
register_span_enricher,
|
|
15
|
+
unregister_span_enricher,
|
|
16
|
+
)
|
|
10
17
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
11
18
|
|
|
19
|
+
from microsoft_agents_a365.observability.extensions.semantickernel.span_enricher import (
|
|
20
|
+
enrich_semantic_kernel_span,
|
|
21
|
+
)
|
|
12
22
|
from microsoft_agents_a365.observability.extensions.semantickernel.span_processor import (
|
|
13
23
|
SemanticKernelSpanProcessor,
|
|
14
24
|
)
|
|
15
25
|
|
|
16
|
-
# -----------------------------
|
|
17
|
-
# 3) The Instrumentor class
|
|
18
|
-
# -----------------------------
|
|
19
26
|
_instruments = ("semantic-kernel >= 1.0.0",)
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
class SemanticKernelInstrumentor(BaseInstrumentor):
|
|
23
30
|
"""
|
|
24
|
-
Instruments Semantic Kernel
|
|
25
|
-
• Installs your custom OTel SpanProcessor
|
|
26
|
-
• (Optionally) attaches an SK function-invocation filter to enrich spans
|
|
31
|
+
Instruments Semantic Kernel with Agent365 observability.
|
|
27
32
|
"""
|
|
28
33
|
|
|
29
34
|
def __init__(self):
|
|
30
35
|
if not is_configured():
|
|
31
36
|
raise RuntimeError(
|
|
32
|
-
"Microsoft Agent 365
|
|
37
|
+
"Microsoft Agent 365 is not initialized. Call configure() before instrumenting."
|
|
33
38
|
)
|
|
34
39
|
super().__init__()
|
|
35
40
|
|
|
@@ -38,13 +43,32 @@ class SemanticKernelInstrumentor(BaseInstrumentor):
|
|
|
38
43
|
|
|
39
44
|
def _instrument(self, **kwargs: Any) -> None:
|
|
40
45
|
"""
|
|
41
|
-
|
|
42
|
-
"""
|
|
46
|
+
Instrument Semantic Kernel.
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
Args:
|
|
49
|
+
**kwargs: Optional configuration parameters.
|
|
50
|
+
"""
|
|
45
51
|
provider = get_tracer_provider()
|
|
52
|
+
|
|
53
|
+
# Add processor for on_start modifications (rename spans, add attributes)
|
|
46
54
|
self._processor = SemanticKernelSpanProcessor()
|
|
47
55
|
provider.add_span_processor(self._processor)
|
|
48
56
|
|
|
57
|
+
# Register enricher for on_end modifications
|
|
58
|
+
# This enricher runs before the span is exported, allowing us to
|
|
59
|
+
# transform SK-specific attributes to standard gen_ai attributes
|
|
60
|
+
register_span_enricher(enrich_semantic_kernel_span)
|
|
61
|
+
|
|
49
62
|
def _uninstrument(self, **kwargs: Any) -> None:
|
|
50
|
-
|
|
63
|
+
"""
|
|
64
|
+
Remove Semantic Kernel instrumentation.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
**kwargs: Optional configuration parameters.
|
|
68
|
+
"""
|
|
69
|
+
# Unregister the enricher
|
|
70
|
+
unregister_span_enricher()
|
|
71
|
+
|
|
72
|
+
# Shutdown the processor
|
|
73
|
+
if hasattr(self, "_processor"):
|
|
74
|
+
self._processor.shutdown()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
"""Utility functions for Semantic Kernel observability extensions."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def extract_content_as_string_list(messages_json: str) -> str:
|
|
12
|
+
"""Extract content values from messages JSON and return as JSON string list.
|
|
13
|
+
|
|
14
|
+
Transforms from: [{"role": "user", "content": "Hello"}]
|
|
15
|
+
To: ["Hello"]
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
messages_json: JSON string like '[{"role": "user", "content": "Hello"}]'
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
JSON string containing only the content values as an array,
|
|
22
|
+
or the original string if parsing fails.
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
messages = json.loads(messages_json)
|
|
26
|
+
if isinstance(messages, list):
|
|
27
|
+
contents = []
|
|
28
|
+
for msg in messages:
|
|
29
|
+
if isinstance(msg, dict) and "content" in msg:
|
|
30
|
+
contents.append(msg["content"])
|
|
31
|
+
elif isinstance(msg, str):
|
|
32
|
+
contents.append(msg)
|
|
33
|
+
return json.dumps(contents)
|
|
34
|
+
return messages_json
|
|
35
|
+
except (json.JSONDecodeError, TypeError):
|
|
36
|
+
# If parsing fails, return as-is
|
|
37
|
+
return messages_json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: microsoft-agents-a365-observability-extensions-semantic-kernel
|
|
3
|
-
Version: 0.2.1.
|
|
3
|
+
Version: 0.2.1.dev9
|
|
4
4
|
Summary: Semantic Kernel observability and tracing extensions for Microsoft Agent 365
|
|
5
5
|
Author-email: Microsoft <support@microsoft.com>
|
|
6
6
|
License: MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
microsoft_agents_a365/observability/extensions/semantickernel/__init__.py,sha256=ftH5IKh1CBMvS1AYGEh6md7b7NX_80ZoIORUElbKBg4,74
|
|
2
|
+
microsoft_agents_a365/observability/extensions/semantickernel/span_enricher.py,sha256=OTeTffta2QcI57nNwLUhtftucZ6Ctoe4AG7ETvy6w9c,2872
|
|
3
|
+
microsoft_agents_a365/observability/extensions/semantickernel/span_processor.py,sha256=_pbNx_qc_PhQq79A37JozVr-FqwrvRJL_wV1a2OFHmw,2122
|
|
4
|
+
microsoft_agents_a365/observability/extensions/semantickernel/trace_instrumentor.py,sha256=KaGekkBMYY2jZcbuB46tSWGbCiu0a394eZKnQDlEXto,2306
|
|
5
|
+
microsoft_agents_a365/observability/extensions/semantickernel/utils.py,sha256=RdV0hlCnPD_i0g-CXKmN0qD5bybDhPHIiGPHjrMDNgY,1185
|
|
6
|
+
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info/METADATA,sha256=kxbSpbqbQ8RUTha_eTvVtT9qXMp4NomEWjkyHlfIpyQ,3713
|
|
7
|
+
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
8
|
+
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info/top_level.txt,sha256=G3c2_4sy5_EM_BWO67SbK2tKj4G8XFn-QXRbh8g9Lgk,22
|
|
9
|
+
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev9.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
microsoft_agents_a365/observability/extensions/semantickernel/__init__.py,sha256=ftH5IKh1CBMvS1AYGEh6md7b7NX_80ZoIORUElbKBg4,74
|
|
2
|
-
microsoft_agents_a365/observability/extensions/semantickernel/span_processor.py,sha256=OFlXRbHY4YjM3FnvIaIzjMFCMf-xRnxuni6eIGNbdpg,993
|
|
3
|
-
microsoft_agents_a365/observability/extensions/semantickernel/trace_instrumentor.py,sha256=avsopF76V_n5L6aAcbILlQTJ8af-PmKBYxGu3DCxDko,1551
|
|
4
|
-
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info/METADATA,sha256=_tA9X4o8E1hNBt6IsKqzkP0F8Kp6p7z8KWZb-hhgWkU,3713
|
|
5
|
-
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
6
|
-
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info/top_level.txt,sha256=G3c2_4sy5_EM_BWO67SbK2tKj4G8XFn-QXRbh8g9Lgk,22
|
|
7
|
-
microsoft_agents_a365_observability_extensions_semantic_kernel-0.2.1.dev7.dist-info/RECORD,,
|
|
File without changes
|