microsoft-opentelemetry 0.1.0a1__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.
Files changed (105) hide show
  1. microsoft/__init__.py +1 -0
  2. microsoft/agents/__init__.py +0 -0
  3. microsoft/agents/a365/__init__.py +0 -0
  4. microsoft/agents/a365/observability/__init__.py +19 -0
  5. microsoft/agents/a365/observability/constants.py +133 -0
  6. microsoft/agents/a365/observability/core/__init__.py +131 -0
  7. microsoft/agents/a365/observability/core/agent_details.py +44 -0
  8. microsoft/agents/a365/observability/core/channel.py +14 -0
  9. microsoft/agents/a365/observability/core/config.py +325 -0
  10. microsoft/agents/a365/observability/core/constants.py +111 -0
  11. microsoft/agents/a365/observability/core/execute_tool_scope.py +149 -0
  12. microsoft/agents/a365/observability/core/exporters/__init__.py +2 -0
  13. microsoft/agents/a365/observability/core/exporters/agent365_exporter.py +310 -0
  14. microsoft/agents/a365/observability/core/exporters/agent365_exporter_options.py +50 -0
  15. microsoft/agents/a365/observability/core/exporters/enriched_span.py +91 -0
  16. microsoft/agents/a365/observability/core/exporters/enriching_span_processor.py +109 -0
  17. microsoft/agents/a365/observability/core/exporters/span_processor.py +183 -0
  18. microsoft/agents/a365/observability/core/exporters/spectra_exporter_options.py +54 -0
  19. microsoft/agents/a365/observability/core/exporters/utils.py +498 -0
  20. microsoft/agents/a365/observability/core/inference_call_details.py +22 -0
  21. microsoft/agents/a365/observability/core/inference_operation_type.py +12 -0
  22. microsoft/agents/a365/observability/core/inference_scope.py +202 -0
  23. microsoft/agents/a365/observability/core/invoke_agent_details.py +15 -0
  24. microsoft/agents/a365/observability/core/invoke_agent_scope.py +207 -0
  25. microsoft/agents/a365/observability/core/message_utils.py +144 -0
  26. microsoft/agents/a365/observability/core/middleware/__init__.py +8 -0
  27. microsoft/agents/a365/observability/core/middleware/baggage_builder.py +306 -0
  28. microsoft/agents/a365/observability/core/models/__init__.py +2 -0
  29. microsoft/agents/a365/observability/core/models/agent_type.py +25 -0
  30. microsoft/agents/a365/observability/core/models/caller_details.py +25 -0
  31. microsoft/agents/a365/observability/core/models/messages.py +222 -0
  32. microsoft/agents/a365/observability/core/models/operation_source.py +21 -0
  33. microsoft/agents/a365/observability/core/models/response.py +28 -0
  34. microsoft/agents/a365/observability/core/models/service_endpoint.py +15 -0
  35. microsoft/agents/a365/observability/core/models/user_details.py +22 -0
  36. microsoft/agents/a365/observability/core/opentelemetry_scope.py +331 -0
  37. microsoft/agents/a365/observability/core/request.py +21 -0
  38. microsoft/agents/a365/observability/core/span_details.py +28 -0
  39. microsoft/agents/a365/observability/core/spans_scopes/__init__.py +2 -0
  40. microsoft/agents/a365/observability/core/spans_scopes/output_scope.py +128 -0
  41. microsoft/agents/a365/observability/core/tool_call_details.py +22 -0
  42. microsoft/agents/a365/observability/core/tool_type.py +14 -0
  43. microsoft/agents/a365/observability/core/trace_processor/__init__.py +14 -0
  44. microsoft/agents/a365/observability/core/trace_processor/span_processor.py +77 -0
  45. microsoft/agents/a365/observability/core/trace_processor/util.py +49 -0
  46. microsoft/agents/a365/observability/core/utils.py +248 -0
  47. microsoft/agents/a365/observability/hosting/__init__.py +24 -0
  48. microsoft/agents/a365/observability/hosting/middleware/__init__.py +20 -0
  49. microsoft/agents/a365/observability/hosting/middleware/baggage_middleware.py +46 -0
  50. microsoft/agents/a365/observability/hosting/middleware/observability_hosting_manager.py +100 -0
  51. microsoft/agents/a365/observability/hosting/middleware/output_logging_middleware.py +187 -0
  52. microsoft/agents/a365/observability/hosting/scope_helpers/__init__.py +2 -0
  53. microsoft/agents/a365/observability/hosting/scope_helpers/populate_baggage.py +43 -0
  54. microsoft/agents/a365/observability/hosting/scope_helpers/populate_invoke_agent_scope.py +48 -0
  55. microsoft/agents/a365/observability/hosting/scope_helpers/utils.py +98 -0
  56. microsoft/agents/a365/observability/hosting/token_cache_helpers/__init__.py +11 -0
  57. microsoft/agents/a365/observability/hosting/token_cache_helpers/agent_token_cache.py +138 -0
  58. microsoft/agents/a365/observability/runtime/__init__.py +20 -0
  59. microsoft/agents/a365/observability/runtime/environment_utils.py +62 -0
  60. microsoft/agents/a365/observability/runtime/operation_error.py +58 -0
  61. microsoft/agents/a365/observability/runtime/operation_result.py +97 -0
  62. microsoft/agents/a365/observability/runtime/power_platform_api_discovery.py +91 -0
  63. microsoft/agents/a365/observability/runtime/utility.py +247 -0
  64. microsoft/agents/a365/observability/runtime/version_utils.py +34 -0
  65. microsoft/genai/__init__.py +2 -0
  66. microsoft/genai/_langchain/__init__.py +11 -0
  67. microsoft/genai/_langchain/_tracer.py +524 -0
  68. microsoft/genai/_langchain/_tracer_instrumentor.py +166 -0
  69. microsoft/genai/_langchain/_utils.py +774 -0
  70. microsoft/opentelemetry/__init__.py +21 -0
  71. microsoft/opentelemetry/_azure_monitor/__init__.py +20 -0
  72. microsoft/opentelemetry/_azure_monitor/_autoinstrumentation/__init__.py +5 -0
  73. microsoft/opentelemetry/_azure_monitor/_autoinstrumentation/configurator.py +69 -0
  74. microsoft/opentelemetry/_azure_monitor/_autoinstrumentation/distro.py +65 -0
  75. microsoft/opentelemetry/_azure_monitor/_browser_sdk_loader/__init__.py +110 -0
  76. microsoft/opentelemetry/_azure_monitor/_browser_sdk_loader/_config.py +46 -0
  77. microsoft/opentelemetry/_azure_monitor/_browser_sdk_loader/django_middleware.py +159 -0
  78. microsoft/opentelemetry/_azure_monitor/_browser_sdk_loader/snippet_injector.py +460 -0
  79. microsoft/opentelemetry/_azure_monitor/_configure.py +392 -0
  80. microsoft/opentelemetry/_azure_monitor/_constants.py +91 -0
  81. microsoft/opentelemetry/_azure_monitor/_diagnostics/__init__.py +5 -0
  82. microsoft/opentelemetry/_azure_monitor/_diagnostics/diagnostic_logging.py +134 -0
  83. microsoft/opentelemetry/_azure_monitor/_diagnostics/status_logger.py +58 -0
  84. microsoft/opentelemetry/_azure_monitor/_types.py +25 -0
  85. microsoft/opentelemetry/_azure_monitor/_utils/__init__.py +74 -0
  86. microsoft/opentelemetry/_azure_monitor/_utils/configurations.py +396 -0
  87. microsoft/opentelemetry/_azure_monitor/_utils/instrumentation.py +156 -0
  88. microsoft/opentelemetry/_azure_monitor/_version.py +7 -0
  89. microsoft/opentelemetry/_azure_monitor/py.typed +7 -0
  90. microsoft/opentelemetry/_constants.py +69 -0
  91. microsoft/opentelemetry/_distro.py +324 -0
  92. microsoft/opentelemetry/_instrumentation.py +164 -0
  93. microsoft/opentelemetry/_otlp/__init__.py +17 -0
  94. microsoft/opentelemetry/_otlp/handler.py +96 -0
  95. microsoft/opentelemetry/_types.py +22 -0
  96. microsoft/opentelemetry/_utils.py +116 -0
  97. microsoft/opentelemetry/_version.py +7 -0
  98. microsoft/opentelemetry/py.typed +0 -0
  99. microsoft_opentelemetry-0.1.0a1.dist-info/METADATA +184 -0
  100. microsoft_opentelemetry-0.1.0a1.dist-info/RECORD +105 -0
  101. microsoft_opentelemetry-0.1.0a1.dist-info/WHEEL +5 -0
  102. microsoft_opentelemetry-0.1.0a1.dist-info/entry_points.txt +2 -0
  103. microsoft_opentelemetry-0.1.0a1.dist-info/licenses/LICENSE +21 -0
  104. microsoft_opentelemetry-0.1.0a1.dist-info/licenses/NOTICE.md +7 -0
  105. microsoft_opentelemetry-0.1.0a1.dist-info/top_level.txt +1 -0
microsoft/__init__.py ADDED
@@ -0,0 +1 @@
1
+ __path__ = __import__("pkgutil").extend_path(__path__, __name__)
File without changes
File without changes
@@ -0,0 +1,19 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+
7
+ """Agent365 exporter integration for the Microsoft OpenTelemetry Distro."""
8
+
9
+ from microsoft.agents.a365.observability.core.exporters.utils import ( # noqa: F401
10
+ A365Handlers,
11
+ create_a365_components,
12
+ is_a365_enabled,
13
+ )
14
+
15
+ __all__ = [
16
+ "A365Handlers",
17
+ "create_a365_components",
18
+ "is_a365_enabled",
19
+ ]
@@ -0,0 +1,133 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+
7
+ """Constants for Agent365 observability.
8
+
9
+ Superset of microsoft-agents-a365-observability-core constants plus
10
+ distro-specific environment variable constants.
11
+ """
12
+
13
+ # --- Span operation names ---
14
+ INVOKE_AGENT_OPERATION_NAME = "invoke_agent"
15
+ EXECUTE_TOOL_OPERATION_NAME = "execute_tool"
16
+ OUTPUT_MESSAGES_OPERATION_NAME = "output_messages"
17
+ CHAT_OPERATION_NAME = "chat"
18
+
19
+ # --- OpenTelemetry semantic conventions ---
20
+ ERROR_TYPE_KEY = "error.type"
21
+ ERROR_MESSAGE_KEY = "error.message"
22
+ AZ_NAMESPACE_KEY = "az.namespace"
23
+ AZURE_RP_NAMESPACE_VALUE = "Microsoft.CognitiveServices"
24
+ SOURCE_NAME = "Agent365Sdk"
25
+
26
+ # --- Feature switches ---
27
+ ENABLE_OPENTELEMETRY_SWITCH = "Azure.Experimental.EnableActivitySource"
28
+ TRACE_CONTENTS_SWITCH = "Azure.Experimental.TraceGenAIMessageContent"
29
+ TRACE_CONTENTS_ENVIRONMENT_VARIABLE = "AZURE_TRACING_GEN_AI_CONTENT_RECORDING_ENABLED"
30
+ ENABLE_OBSERVABILITY = "ENABLE_OBSERVABILITY"
31
+ ENABLE_A365_OBSERVABILITY = "ENABLE_A365_OBSERVABILITY"
32
+
33
+ # --- GenAI semantic conventions ---
34
+ GEN_AI_CLIENT_OPERATION_DURATION_METRIC_NAME = "gen_ai.client.operation.duration"
35
+ GEN_AI_CLIENT_TOKEN_USAGE_METRIC_NAME = "gen_ai.client.token.usage"
36
+ GEN_AI_OPERATION_NAME_KEY = "gen_ai.operation.name"
37
+ GEN_AI_REQUEST_MAX_TOKENS_KEY = "gen_ai.request.max_tokens"
38
+ GEN_AI_REQUEST_MODEL_KEY = "gen_ai.request.model"
39
+ GEN_AI_REQUEST_TEMPERATURE_KEY = "gen_ai.request.temperature"
40
+ GEN_AI_REQUEST_TOP_P_KEY = "gen_ai.request.top_p"
41
+ GEN_AI_RESPONSE_FINISH_REASONS_KEY = "gen_ai.response.finish_reasons"
42
+ GEN_AI_RESPONSE_MODEL_KEY = "gen_ai.response.model"
43
+ GEN_AI_RESPONSE_ID_KEY = "gen_ai.response.id"
44
+ GEN_AI_AGENT_ID_KEY = "gen_ai.agent.id"
45
+ GEN_AI_AGENT_NAME_KEY = "gen_ai.agent.name"
46
+ GEN_AI_AGENT_DESCRIPTION_KEY = "gen_ai.agent.description"
47
+ GEN_AI_AGENT_VERSION_KEY = "gen_ai.agent.version"
48
+ GEN_AI_AGENT_PLATFORM_ID_KEY = "microsoft.a365.agent.platform.id"
49
+ GEN_AI_AGENT_THOUGHT_PROCESS_KEY = "microsoft.a365.agent.thought.process"
50
+ GEN_AI_CONVERSATION_ID_KEY = "gen_ai.conversation.id"
51
+ GEN_AI_CONVERSATION_ITEM_LINK_KEY = "microsoft.conversation.item.link"
52
+ GEN_AI_TOKEN_TYPE_KEY = "gen_ai.token.type"
53
+ GEN_AI_USAGE_INPUT_TOKENS_KEY = "gen_ai.usage.input_tokens"
54
+ GEN_AI_USAGE_OUTPUT_TOKENS_KEY = "gen_ai.usage.output_tokens"
55
+ GEN_AI_CHOICE = "gen_ai.choice"
56
+ GEN_AI_PROVIDER_NAME_KEY = "gen_ai.provider.name"
57
+ GEN_AI_SYSTEM_INSTRUCTIONS_KEY = "gen_ai.system_instructions"
58
+ GEN_AI_INPUT_MESSAGES_KEY = "gen_ai.input.messages"
59
+ GEN_AI_OUTPUT_MESSAGES_KEY = "gen_ai.output.messages"
60
+
61
+ # --- Tool execution ---
62
+ GEN_AI_TOOL_CALL_ID_KEY = "gen_ai.tool.call.id"
63
+ GEN_AI_TOOL_NAME_KEY = "gen_ai.tool.name"
64
+ GEN_AI_TOOL_DESCRIPTION_KEY = "gen_ai.tool.description"
65
+ GEN_AI_TOOL_ARGS_KEY = "gen_ai.tool.call.arguments"
66
+ GEN_AI_TOOL_CALL_RESULT_KEY = "gen_ai.tool.call.result"
67
+ GEN_AI_TOOL_TYPE_KEY = "gen_ai.tool.type"
68
+
69
+ # --- Human caller ---
70
+ USER_ID_KEY = "user.id"
71
+ USER_NAME_KEY = "user.name"
72
+ USER_EMAIL_KEY = "user.email"
73
+ GEN_AI_CALLER_CLIENT_IP_KEY = "client.address"
74
+
75
+ # --- Agent-to-Agent caller ---
76
+ GEN_AI_CALLER_AGENT_USER_ID_KEY = "microsoft.a365.caller.agent.user.id"
77
+ GEN_AI_CALLER_AGENT_EMAIL_KEY = "microsoft.a365.caller.agent.user.email"
78
+ GEN_AI_CALLER_AGENT_NAME_KEY = "microsoft.a365.caller.agent.name"
79
+ GEN_AI_CALLER_AGENT_ID_KEY = "microsoft.a365.caller.agent.id"
80
+ GEN_AI_CALLER_AGENT_APPLICATION_ID_KEY = "microsoft.a365.caller.agent.blueprint.id"
81
+ GEN_AI_CALLER_AGENT_PLATFORM_ID_KEY = "microsoft.a365.caller.agent.platform.id"
82
+ GEN_AI_CALLER_AGENT_VERSION_KEY = "microsoft.a365.caller.agent.version"
83
+
84
+ # --- Agent-specific dimensions ---
85
+ AGENT_ID_KEY = "gen_ai.agent.id"
86
+ GEN_AI_TASK_ID_KEY = "gen_ai.task.id"
87
+ GEN_AI_ICON_URI_KEY = "gen_ai.agent365.icon_uri"
88
+ GEN_AI_EXECUTION_PAYLOAD_KEY = "gen_ai.execution.payload"
89
+ TENANT_ID_KEY = "microsoft.tenant.id"
90
+ GEN_AI_AGENT_AUID_KEY = "microsoft.agent.user.id"
91
+ GEN_AI_AGENT_EMAIL_KEY = "microsoft.agent.user.email"
92
+ GEN_AI_AGENT_BLUEPRINT_ID_KEY = "microsoft.a365.agent.blueprint.id"
93
+ SESSION_ID_KEY = "microsoft.session.id"
94
+ SESSION_DESCRIPTION_KEY = "microsoft.session.description"
95
+
96
+ # --- Error type constants ---
97
+ ERROR_TYPE_CANCELLED = "TaskCanceledException"
98
+
99
+ # --- OTel standard keys ---
100
+ SERVER_ADDRESS_KEY = "server.address"
101
+ SERVER_PORT_KEY = "server.port"
102
+ SERVICE_NAME_KEY = "service.name"
103
+
104
+ # --- Custom span keys ---
105
+ CUSTOM_PARENT_SPAN_ID_KEY = "custom.parent.span.id"
106
+ CUSTOM_SPAN_NAME_KEY = "custom.span.name"
107
+
108
+ # --- Channel ---
109
+ CHANNEL_NAME_KEY = "microsoft.channel.name"
110
+ CHANNEL_LINK_KEY = "microsoft.channel.link"
111
+
112
+ # --- Telemetry SDK attributes ---
113
+ TELEMETRY_SDK_NAME_KEY = "telemetry.sdk.name"
114
+ TELEMETRY_SDK_LANGUAGE_KEY = "telemetry.sdk.language"
115
+ TELEMETRY_SDK_VERSION_KEY = "telemetry.sdk.version"
116
+ TELEMETRY_SDK_NAME_VALUE = "A365ObservabilitySDK"
117
+ TELEMETRY_SDK_LANGUAGE_VALUE = "python"
118
+
119
+ # --- Distro environment variable names ---
120
+ ENABLE_A365_OBSERVABILITY_EXPORTER = "ENABLE_A365_OBSERVABILITY_EXPORTER"
121
+ A365_OBSERVABILITY_DOMAIN_OVERRIDE = "A365_OBSERVABILITY_DOMAIN_OVERRIDE"
122
+ A365_TENANT_ID_ENV = "A365_TENANT_ID"
123
+ A365_AGENT_ID_ENV = "A365_AGENT_ID"
124
+ A365_CLUSTER_CATEGORY_ENV = "A365_CLUSTER_CATEGORY"
125
+ A365_USE_S2S_ENDPOINT_ENV = "A365_USE_S2S_ENDPOINT"
126
+ A365_SUPPRESS_INVOKE_AGENT_INPUT_ENV = "A365_SUPPRESS_INVOKE_AGENT_INPUT"
127
+
128
+ # --- FIC (Federated Identity Credential) token flow env vars ---
129
+ A365_AGENT_APP_INSTANCE_ID_ENV = "A365_AGENT_APP_INSTANCE_ID"
130
+ A365_AGENTIC_USER_ID_ENV = "A365_AGENTIC_USER_ID"
131
+ A365_SERVICE_CLIENT_ID_ENV = "CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID"
132
+ A365_SERVICE_CLIENT_SECRET_ENV = "CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET"
133
+ A365_SERVICE_TENANT_ID_ENV = "CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID"
@@ -0,0 +1,131 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ # Microsoft Agent 365 Python SDK for OpenTelemetry tracing.
5
+
6
+ from microsoft.agents.a365.observability.core.agent_details import AgentDetails
7
+ from microsoft.agents.a365.observability.core.config import (
8
+ configure,
9
+ get_tracer,
10
+ get_tracer_provider,
11
+ is_configured,
12
+ )
13
+ from microsoft.agents.a365.observability.core.execute_tool_scope import ExecuteToolScope
14
+ from microsoft.agents.a365.observability.core.exporters.agent365_exporter_options import Agent365ExporterOptions
15
+ from microsoft.agents.a365.observability.core.exporters.enriched_span import EnrichedReadableSpan
16
+ from microsoft.agents.a365.observability.core.exporters.enriching_span_processor import (
17
+ get_span_enricher,
18
+ register_span_enricher,
19
+ unregister_span_enricher,
20
+ )
21
+ from microsoft.agents.a365.observability.core.exporters.spectra_exporter_options import SpectraExporterOptions
22
+ from microsoft.agents.a365.observability.core.inference_call_details import InferenceCallDetails
23
+ from microsoft.agents.a365.observability.core.models.service_endpoint import ServiceEndpoint
24
+ from microsoft.agents.a365.observability.core.inference_operation_type import InferenceOperationType
25
+ from microsoft.agents.a365.observability.core.inference_scope import InferenceScope
26
+ from microsoft.agents.a365.observability.core.invoke_agent_details import InvokeAgentScopeDetails
27
+ from microsoft.agents.a365.observability.core.invoke_agent_scope import InvokeAgentScope
28
+ from microsoft.agents.a365.observability.core.middleware.baggage_builder import BaggageBuilder
29
+ from microsoft.agents.a365.observability.core.models.caller_details import CallerDetails
30
+ from microsoft.agents.a365.observability.core.models.messages import (
31
+ BlobPart,
32
+ ChatMessage,
33
+ FilePart,
34
+ FinishReason,
35
+ GenericPart,
36
+ InputMessages,
37
+ InputMessagesParam,
38
+ MessagePart,
39
+ MessageRole,
40
+ Modality,
41
+ OutputMessage,
42
+ OutputMessages,
43
+ OutputMessagesParam,
44
+ ReasoningPart,
45
+ ServerToolCallPart,
46
+ ServerToolCallResponsePart,
47
+ TextPart,
48
+ ToolCallRequestPart,
49
+ ToolCallResponsePart,
50
+ UriPart,
51
+ )
52
+ from microsoft.agents.a365.observability.core.models.response import Response
53
+ from microsoft.agents.a365.observability.core.models.user_details import UserDetails
54
+ from microsoft.agents.a365.observability.core.opentelemetry_scope import OpenTelemetryScope
55
+ from microsoft.agents.a365.observability.core.request import Request
56
+ from microsoft.agents.a365.observability.core.channel import Channel
57
+ from microsoft.agents.a365.observability.core.span_details import SpanDetails
58
+ from microsoft.agents.a365.observability.core.spans_scopes.output_scope import OutputScope
59
+ from microsoft.agents.a365.observability.core.tool_call_details import ToolCallDetails
60
+ from microsoft.agents.a365.observability.core.tool_type import ToolType
61
+ from microsoft.agents.a365.observability.core.exporters.span_processor import A365SpanProcessor as SpanProcessor
62
+ from microsoft.agents.a365.observability.core.utils import extract_context_from_headers, get_traceparent
63
+
64
+ __all__ = [
65
+ # Main SDK functions
66
+ "configure",
67
+ "is_configured",
68
+ "get_tracer",
69
+ "get_tracer_provider",
70
+ # Exporter options
71
+ "Agent365ExporterOptions",
72
+ "SpectraExporterOptions",
73
+ # Span enrichment
74
+ "register_span_enricher",
75
+ "unregister_span_enricher",
76
+ "get_span_enricher",
77
+ "EnrichedReadableSpan",
78
+ # Span processor
79
+ "SpanProcessor",
80
+ # Base scope class
81
+ "OpenTelemetryScope",
82
+ # Specific scope classes
83
+ "ExecuteToolScope",
84
+ "InvokeAgentScope",
85
+ "InferenceScope",
86
+ "OutputScope",
87
+ # Middleware
88
+ "BaggageBuilder",
89
+ # Data classes
90
+ "InvokeAgentScopeDetails",
91
+ "AgentDetails",
92
+ "CallerDetails",
93
+ "UserDetails",
94
+ "ToolCallDetails",
95
+ "Channel",
96
+ "Request",
97
+ "Response",
98
+ "SpanDetails",
99
+ "InferenceCallDetails",
100
+ "ServiceEndpoint",
101
+ # Enums
102
+ "InferenceOperationType",
103
+ "ToolType",
104
+ # OTEL gen-ai message format types
105
+ "MessageRole",
106
+ "FinishReason",
107
+ "Modality",
108
+ "TextPart",
109
+ "ToolCallRequestPart",
110
+ "ToolCallResponsePart",
111
+ "ReasoningPart",
112
+ "BlobPart",
113
+ "FilePart",
114
+ "UriPart",
115
+ "ServerToolCallPart",
116
+ "ServerToolCallResponsePart",
117
+ "GenericPart",
118
+ "MessagePart",
119
+ "ChatMessage",
120
+ "OutputMessage",
121
+ "InputMessages",
122
+ "OutputMessages",
123
+ "InputMessagesParam",
124
+ "OutputMessagesParam",
125
+ # Utility functions
126
+ "extract_context_from_headers",
127
+ "get_traceparent",
128
+ ]
129
+
130
+ # This is a namespace package
131
+ __path__ = __import__("pkgutil").extend_path(__path__, __name__)
@@ -0,0 +1,44 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+ from typing import Optional
6
+
7
+
8
+ @dataclass
9
+ # pylint: disable=too-many-instance-attributes
10
+ class AgentDetails:
11
+ """Details about an AI agent in the system."""
12
+
13
+ agent_id: str
14
+ """The unique identifier for the AI agent."""
15
+
16
+ agent_name: Optional[str] = None
17
+ """The human-readable name of the AI agent."""
18
+
19
+ agent_description: Optional[str] = None
20
+ """A description of the AI agent's purpose or capabilities."""
21
+
22
+ agentic_user_id: Optional[str] = None
23
+ """Agentic User ID for the agent."""
24
+
25
+ agentic_user_email: Optional[str] = None
26
+ """Email address for the agentic user."""
27
+
28
+ agent_blueprint_id: Optional[str] = None
29
+ """Blueprint/Application ID for the agent."""
30
+
31
+ agent_platform_id: Optional[str] = None
32
+ """Platform ID for the agent."""
33
+
34
+ tenant_id: Optional[str] = None
35
+ """Tenant ID for the agent."""
36
+
37
+ icon_uri: Optional[str] = None
38
+ """Optional icon URI for the agent."""
39
+
40
+ provider_name: Optional[str] = None
41
+ """The provider name (e.g., openai, anthropic)."""
42
+
43
+ agent_version: Optional[str] = None
44
+ """Optional version of the agent (e.g., "1.0.0", "2025-05-01")."""
@@ -0,0 +1,14 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ # Channel class.
5
+
6
+ from dataclasses import dataclass
7
+
8
+
9
+ @dataclass
10
+ class Channel:
11
+ """Channel information for agent execution context."""
12
+
13
+ name: str | None = None
14
+ link: str | None = None
@@ -0,0 +1,325 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ import os
5
+ import logging
6
+ import threading
7
+ from collections.abc import Callable
8
+ from typing import Any, Optional
9
+
10
+ from opentelemetry import trace
11
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
12
+ OTLPSpanExporter as GrpcOTLPSpanExporter,
13
+ )
14
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
15
+ from opentelemetry.sdk.resources import SERVICE_NAME, SERVICE_NAMESPACE, Resource
16
+ from opentelemetry.sdk.trace import TracerProvider
17
+ from opentelemetry.sdk.trace.export import ConsoleSpanExporter
18
+
19
+ from microsoft.agents.a365.observability.core.exporters.agent365_exporter import _Agent365Exporter
20
+ from microsoft.agents.a365.observability.core.exporters.agent365_exporter_options import Agent365ExporterOptions
21
+ from microsoft.agents.a365.observability.core.exporters.enriching_span_processor import _EnrichingBatchSpanProcessor
22
+ from microsoft.agents.a365.observability.core.exporters.utils import is_agent365_exporter_enabled
23
+ from microsoft.agents.a365.observability.core.exporters.spectra_exporter_options import SpectraExporterOptions
24
+ from microsoft.agents.a365.observability.core.exporters.span_processor import A365SpanProcessor as SpanProcessor
25
+
26
+ # mypy: disable-error-code="no-untyped-def, assignment, attr-defined, arg-type"
27
+
28
+ DEFAULT_LOGGER_NAME = __name__
29
+
30
+ # pylint: disable=broad-exception-caught, too-many-instance-attributes
31
+ class TelemetryManager:
32
+ """
33
+ Thread-safe singleton manager for telemetry operations.
34
+
35
+ This class encapsulates all telemetry state and operations, providing
36
+ a clean interface for configuration, flushing, and shutdown without
37
+ relying on global variables.
38
+ """
39
+
40
+ _instance: Optional["TelemetryManager"] = None
41
+ _lock = threading.Lock()
42
+
43
+ def __new__(cls) -> "TelemetryManager":
44
+ if cls._instance is None:
45
+ with cls._lock:
46
+ if cls._instance is None:
47
+ cls._instance = super().__new__(cls)
48
+ cls._instance._initialized = False
49
+ return cls._instance
50
+
51
+ def __init__(self):
52
+ if not getattr(self, "_initialized", False):
53
+ self._tracer_provider: TracerProvider | None = None
54
+ self._span_processors: dict[str, Any] = {}
55
+ self._logger = logging.getLogger(__name__)
56
+ self._initialized = True
57
+
58
+ def configure(
59
+ self,
60
+ service_name: str,
61
+ service_namespace: str,
62
+ logger_name: str = DEFAULT_LOGGER_NAME,
63
+ token_resolver: Callable[[str, str], str | None] | None = None,
64
+ cluster_category: str = "prod",
65
+ exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
66
+ suppress_invoke_agent_input: bool = False,
67
+ **kwargs: Any,
68
+ ) -> bool:
69
+ """
70
+ Configure telemetry.
71
+
72
+ :param service_name: The name of the service.
73
+ :param service_namespace: The namespace of the service.
74
+ :param logger_name: The name of the logger to collect telemetry from.
75
+ :param token_resolver: (Deprecated) Callable that returns an auth token for a given agent + tenant.
76
+ Use exporter_options instead.
77
+ :param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
78
+ Use exporter_options instead.
79
+ :param exporter_options: Exporter configuration. Pass Agent365ExporterOptions for A365 API
80
+ export, SpectraExporterOptions for Spectra Collector sidecar export, or None (default)
81
+ to construct Agent365ExporterOptions from legacy parameters.
82
+ :param suppress_invoke_agent_input: If True, suppress input messages for InvokeAgent spans.
83
+ :return: True if configuration succeeded, False otherwise.
84
+ """
85
+ try:
86
+ with self._lock:
87
+ return self._configure_internal(
88
+ service_name,
89
+ service_namespace,
90
+ logger_name,
91
+ token_resolver,
92
+ cluster_category,
93
+ exporter_options,
94
+ suppress_invoke_agent_input,
95
+ **kwargs,
96
+ )
97
+ except Exception as e:
98
+ self._logger.error("Failed to configure telemetry: %s", e)
99
+ return False
100
+
101
+ def _configure_internal(
102
+ self,
103
+ service_name: str,
104
+ service_namespace: str,
105
+ logger_name: str,
106
+ token_resolver: Callable[[str, str], str | None] | None = None,
107
+ cluster_category: str = "prod",
108
+ exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
109
+ suppress_invoke_agent_input: bool = False,
110
+ **kwargs: Any,
111
+ ) -> bool:
112
+ """Internal configuration method - not thread-safe, must be called with lock."""
113
+
114
+ # Check if a365 observability is already configured
115
+ if self._tracer_provider is not None:
116
+ self._logger.warning("a365 observability already configured. Ignoring repeated configure() call.")
117
+ return True
118
+
119
+ # Create resource with service information
120
+ resource = Resource.create(
121
+ {
122
+ SERVICE_NAMESPACE: service_namespace,
123
+ SERVICE_NAME: service_name,
124
+ }
125
+ )
126
+
127
+ # Check if there's an existing TracerProvider (from app's OTEL setup)
128
+ tracer_provider = trace.get_tracer_provider()
129
+
130
+ # Determine if we should use existing provider or create new one
131
+ # Check if it's a real TracerProvider with a resource (not a proxy/no-op)
132
+ if getattr(tracer_provider, "resource", None):
133
+ # Use existing provider from application's OTEL setup
134
+ self._logger.info(
135
+ "Detected existing TracerProvider with resource. Adding a365 observability processors to it."
136
+ )
137
+ else:
138
+ # Create new TracerProvider with our resource
139
+ self._logger.info("Creating new TracerProvider for a365 observability.")
140
+ tracer_provider = TracerProvider(resource=resource)
141
+ trace.set_tracer_provider(tracer_provider)
142
+
143
+ # Store reference
144
+ self._tracer_provider = tracer_provider
145
+
146
+ # Use exporter_options if provided, otherwise create default options with legacy parameters
147
+ if exporter_options is None:
148
+ exporter_options = Agent365ExporterOptions(
149
+ cluster_category=cluster_category,
150
+ token_resolver=token_resolver,
151
+ )
152
+
153
+ # Extract configuration for BatchSpanProcessor
154
+ batch_processor_kwargs = {
155
+ "max_queue_size": exporter_options.max_queue_size,
156
+ "schedule_delay_millis": exporter_options.scheduled_delay_ms,
157
+ "export_timeout_millis": exporter_options.exporter_timeout_ms,
158
+ "max_export_batch_size": exporter_options.max_export_batch_size,
159
+ }
160
+
161
+ # Type-based exporter dispatch
162
+ if isinstance(exporter_options, SpectraExporterOptions):
163
+ # Spectra path — OTLP exporter to sidecar
164
+ # ENABLE_A365_OBSERVABILITY_EXPORTER is intentionally ignored.
165
+ if exporter_options.protocol == "grpc":
166
+ exporter = GrpcOTLPSpanExporter(
167
+ endpoint=exporter_options.endpoint,
168
+ insecure=exporter_options.insecure,
169
+ )
170
+ else:
171
+ exporter = OTLPSpanExporter(
172
+ endpoint=exporter_options.endpoint,
173
+ )
174
+
175
+ elif is_agent365_exporter_enabled() and exporter_options.token_resolver is not None:
176
+ exporter = _Agent365Exporter(
177
+ token_resolver=exporter_options.token_resolver,
178
+ cluster_category=exporter_options.cluster_category,
179
+ use_s2s_endpoint=exporter_options.use_s2s_endpoint,
180
+ )
181
+
182
+ else:
183
+ exporter = ConsoleSpanExporter()
184
+ self._logger.warning(
185
+ "is_agent365_exporter_enabled() not enabled or token_resolver not set."
186
+ " Falling back to console exporter."
187
+ )
188
+
189
+ # Add span processors
190
+
191
+ # Create _EnrichingBatchSpanProcessor with optimized settings
192
+ # This allows extensions to enrich spans before export
193
+ batch_processor = _EnrichingBatchSpanProcessor(
194
+ exporter,
195
+ suppress_invoke_agent_input=suppress_invoke_agent_input,
196
+ **batch_processor_kwargs,
197
+ )
198
+ agent_processor = SpanProcessor()
199
+
200
+ tracer_provider.add_span_processor(batch_processor)
201
+ tracer_provider.add_span_processor(agent_processor)
202
+
203
+ # Store references for cleanup
204
+ self._span_processors["batch"] = batch_processor
205
+ self._span_processors["agent"] = agent_processor
206
+
207
+ if os.environ.get("ENABLE_OTLP_EXPORTER", "").lower() == "true":
208
+ # The OTLPSpanExporter is auto configured from the environment variables
209
+ otlp_exporter = OTLPSpanExporter()
210
+ tracer_provider.add_span_processor(_EnrichingBatchSpanProcessor(otlp_exporter, **batch_processor_kwargs))
211
+
212
+ # Configure logging if logger_name is provided
213
+ if logger_name:
214
+ target_logger = logging.getLogger(logger_name)
215
+ target_logger.setLevel(logging.INFO)
216
+
217
+ return True
218
+
219
+ def is_configured(self) -> bool:
220
+ """Check if the telemetry manager is configured."""
221
+ return self._tracer_provider is not None
222
+
223
+ def get_tracer(self, name: str | None = None, version: str | None = None):
224
+ """
225
+ Return an OpenTelemetry Tracer tied to the TracerProvider configured by agent365.
226
+
227
+ If the telemetry manager is not configured yet, this returns the default
228
+ (no-op) tracer from OpenTelemetry and logs a warning. Callers should prefer
229
+ to call `configure(...)` during application startup so the tracer
230
+ returned is backed by the configured TracerProvider.
231
+
232
+ :param name: Optional tracer name. Defaults to 'microsoft.agents.a365.observability.core' when not provided.
233
+ :param version: Optional tracer version.
234
+ :return: An OpenTelemetry Tracer instance.
235
+ """
236
+ tracer_name = name or DEFAULT_LOGGER_NAME
237
+ if self._tracer_provider is None:
238
+ # Not configured — return whatever tracer OpenTelemetry provides (no-op)
239
+ self._logger.warning("agent365 telemetry not configured; returning a no-op tracer for '%s'", tracer_name)
240
+ return trace.get_tracer(tracer_name, version)
241
+
242
+ # Ensure global tracer provider is set (should already be by configure)
243
+ try:
244
+ return trace.get_tracer(tracer_name, version)
245
+ except Exception as e:
246
+ self._logger.error("Failed to get tracer '%s': %s", tracer_name, e)
247
+ return trace.get_tracer(tracer_name, version)
248
+
249
+ def get_tracer_provider(self):
250
+ """
251
+ Return the configured TracerProvider instance.
252
+ """
253
+ return self._tracer_provider
254
+
255
+
256
+ # Singleton instance
257
+ _telemetry_manager = TelemetryManager()
258
+
259
+
260
+ # Public API functions that delegate to the singleton manager
261
+ def configure(
262
+ service_name: str,
263
+ service_namespace: str,
264
+ logger_name: str = DEFAULT_LOGGER_NAME,
265
+ token_resolver: Callable[[str, str], str | None] | None = None,
266
+ cluster_category: str = "prod",
267
+ exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
268
+ suppress_invoke_agent_input: bool = False,
269
+ **kwargs: Any,
270
+ ) -> bool:
271
+ """
272
+ Configure telemetry with OpenTelemetry.
273
+
274
+ :param service_name: The name of the service.
275
+ :param service_namespace: The namespace of the service.
276
+ :param logger_name: The name of the logger to collect telemetry from.
277
+ :param token_resolver: (Deprecated) Callable that returns an auth token for a given agent + tenant.
278
+ Use exporter_options instead.
279
+ :param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
280
+ Use exporter_options instead.
281
+ :param exporter_options: Exporter configuration. Pass Agent365ExporterOptions for A365 API
282
+ export, SpectraExporterOptions for Spectra Collector sidecar export, or None (default)
283
+ to construct Agent365ExporterOptions from legacy parameters.
284
+ :param suppress_invoke_agent_input: If True, suppress input messages for InvokeAgent spans.
285
+ :return: True if configuration succeeded, False otherwise.
286
+ """
287
+ return _telemetry_manager.configure(
288
+ service_name,
289
+ service_namespace,
290
+ logger_name,
291
+ token_resolver,
292
+ cluster_category,
293
+ exporter_options,
294
+ suppress_invoke_agent_input,
295
+ **kwargs,
296
+ )
297
+
298
+
299
+ def is_configured() -> bool:
300
+ """
301
+ Check if telemetry is currently configured.
302
+
303
+ :return: True if telemetry is configured and ready to use, False otherwise
304
+ """
305
+ return _telemetry_manager.is_configured()
306
+
307
+
308
+ def get_tracer(name: str | None = None, version: str | None = None):
309
+ """
310
+ Return a tracer tied to the TracerProvider configured by the SDK.
311
+
312
+ :param name: Optional tracer name. If omitted, defaults to 'microsoft.agents.a365.observability.core'.
313
+ :param version: Optional tracer version.
314
+ :return: An OpenTelemetry Tracer (may be a no-op tracer if SDK isn't configured).
315
+ """
316
+ return _telemetry_manager.get_tracer(name, version)
317
+
318
+
319
+ def get_tracer_provider():
320
+ """
321
+ Return the TracerProvider configured by the SDK.
322
+
323
+ :return: Configured OpenTelemetry TracerProvider
324
+ """
325
+ return _telemetry_manager.get_tracer_provider()