microsoft-agents-a365-observability-core 0.2.1.dev35__tar.gz → 0.2.1.dev36__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 (47) hide show
  1. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/PKG-INFO +1 -1
  2. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/__init__.py +5 -0
  3. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/config.py +39 -12
  4. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/__init__.py +2 -1
  5. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/agent365_exporter.py +0 -20
  6. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/enriched_span.py +10 -1
  7. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/enriching_span_processor.py +30 -0
  8. microsoft_agents_a365_observability_core-0.2.1.dev36/microsoft_agents_a365/observability/core/exporters/spectra_exporter_options.py +56 -0
  9. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/PKG-INFO +1 -1
  10. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/SOURCES.txt +1 -0
  11. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/README.md +0 -0
  12. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/agent_details.py +0 -0
  13. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/constants.py +0 -0
  14. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/execute_tool_scope.py +0 -0
  15. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/execution_type.py +0 -0
  16. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/agent365_exporter_options.py +0 -0
  17. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/utils.py +0 -0
  18. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_call_details.py +0 -0
  19. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_operation_type.py +0 -0
  20. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_scope.py +0 -0
  21. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/invoke_agent_details.py +0 -0
  22. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/invoke_agent_scope.py +0 -0
  23. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/middleware/__init__.py +0 -0
  24. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/middleware/baggage_builder.py +0 -0
  25. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/__init__.py +0 -0
  26. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/agent_type.py +0 -0
  27. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/caller_details.py +0 -0
  28. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/operation_source.py +0 -0
  29. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/response.py +0 -0
  30. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/opentelemetry_scope.py +0 -0
  31. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/request.py +0 -0
  32. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/source_metadata.py +0 -0
  33. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/spans_scopes/__init__.py +0 -0
  34. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/spans_scopes/output_scope.py +0 -0
  35. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tenant_details.py +0 -0
  36. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tool_call_details.py +0 -0
  37. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tool_type.py +0 -0
  38. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/__init__.py +0 -0
  39. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/span_processor.py +0 -0
  40. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/util.py +0 -0
  41. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/utils.py +0 -0
  42. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/dependency_links.txt +0 -0
  43. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/requires.txt +0 -0
  44. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/top_level.txt +0 -0
  45. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/pyproject.toml +0 -0
  46. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/setup.cfg +0 -0
  47. {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-a365-observability-core
3
- Version: 0.2.1.dev35
3
+ Version: 0.2.1.dev36
4
4
  Summary: Telemetry, tracing, and monitoring components for AI agents
5
5
  Author-email: Microsoft <support@microsoft.com>
6
6
  License: MIT
@@ -12,12 +12,14 @@ from .config import (
12
12
  )
13
13
  from .execute_tool_scope import ExecuteToolScope
14
14
  from .execution_type import ExecutionType
15
+ from .exporters.agent365_exporter_options import Agent365ExporterOptions
15
16
  from .exporters.enriched_span import EnrichedReadableSpan
16
17
  from .exporters.enriching_span_processor import (
17
18
  get_span_enricher,
18
19
  register_span_enricher,
19
20
  unregister_span_enricher,
20
21
  )
22
+ from .exporters.spectra_exporter_options import SpectraExporterOptions
21
23
  from .inference_call_details import InferenceCallDetails, ServiceEndpoint
22
24
  from .inference_operation_type import InferenceOperationType
23
25
  from .inference_scope import InferenceScope
@@ -38,6 +40,9 @@ __all__ = [
38
40
  "is_configured",
39
41
  "get_tracer",
40
42
  "get_tracer_provider",
43
+ # Exporter options
44
+ "Agent365ExporterOptions",
45
+ "SpectraExporterOptions",
41
46
  # Span enrichment
42
47
  "register_span_enricher",
43
48
  "unregister_span_enricher",
@@ -8,6 +8,9 @@ from collections.abc import Callable
8
8
  from typing import Any, Optional
9
9
 
10
10
  from opentelemetry import trace
11
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
12
+ OTLPSpanExporter as GrpcOTLPSpanExporter,
13
+ )
11
14
  from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
12
15
  from opentelemetry.sdk.resources import SERVICE_NAME, SERVICE_NAMESPACE, Resource
13
16
  from opentelemetry.sdk.trace import TracerProvider
@@ -18,6 +21,7 @@ from .exporters.agent365_exporter_options import Agent365ExporterOptions
18
21
  from .exporters.enriching_span_processor import (
19
22
  _EnrichingBatchSpanProcessor,
20
23
  )
24
+ from .exporters.spectra_exporter_options import SpectraExporterOptions
21
25
  from .exporters.utils import is_agent365_exporter_enabled
22
26
  from .trace_processor.span_processor import SpanProcessor
23
27
 
@@ -58,7 +62,7 @@ class TelemetryManager:
58
62
  logger_name: str = DEFAULT_LOGGER_NAME,
59
63
  token_resolver: Callable[[str, str], str | None] | None = None,
60
64
  cluster_category: str = "prod",
61
- exporter_options: Optional[Agent365ExporterOptions] = None,
65
+ exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
62
66
  suppress_invoke_agent_input: bool = False,
63
67
  **kwargs: Any,
64
68
  ) -> bool:
@@ -72,9 +76,10 @@ class TelemetryManager:
72
76
  Use exporter_options instead.
73
77
  :param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
74
78
  Use exporter_options instead.
75
- :param exporter_options: Agent365ExporterOptions instance for configuring the exporter.
76
- If provided, exporter_options takes precedence. If exporter_options is None, the token_resolver and cluster_category parameters are used as fallback/legacy support to construct a default Agent365ExporterOptions instance.
77
- :param suppress_invoke_agent_input: If True, suppress input messages for spans that are children of InvokeAgent spans.
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.
78
83
  :return: True if configuration succeeded, False otherwise.
79
84
  """
80
85
  try:
@@ -100,7 +105,7 @@ class TelemetryManager:
100
105
  logger_name: str,
101
106
  token_resolver: Callable[[str, str], str | None] | None = None,
102
107
  cluster_category: str = "prod",
103
- exporter_options: Optional[Agent365ExporterOptions] = None,
108
+ exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
104
109
  suppress_invoke_agent_input: bool = False,
105
110
  **kwargs: Any,
106
111
  ) -> bool:
@@ -156,25 +161,43 @@ class TelemetryManager:
156
161
  "max_export_batch_size": exporter_options.max_export_batch_size,
157
162
  }
158
163
 
159
- if is_agent365_exporter_enabled() and exporter_options.token_resolver is not None:
164
+ # Type-based exporter dispatch
165
+ if isinstance(exporter_options, SpectraExporterOptions):
166
+ # Spectra path — OTLP exporter to sidecar
167
+ # ENABLE_A365_OBSERVABILITY_EXPORTER is intentionally ignored.
168
+ if exporter_options.protocol == "grpc":
169
+ exporter = GrpcOTLPSpanExporter(
170
+ endpoint=exporter_options.endpoint,
171
+ insecure=exporter_options.insecure,
172
+ )
173
+ else:
174
+ exporter = OTLPSpanExporter(
175
+ endpoint=exporter_options.endpoint,
176
+ )
177
+
178
+ elif is_agent365_exporter_enabled() and exporter_options.token_resolver is not None:
160
179
  exporter = _Agent365Exporter(
161
180
  token_resolver=exporter_options.token_resolver,
162
181
  cluster_category=exporter_options.cluster_category,
163
182
  use_s2s_endpoint=exporter_options.use_s2s_endpoint,
164
- suppress_invoke_agent_input=suppress_invoke_agent_input,
165
183
  )
166
184
 
167
185
  else:
168
186
  exporter = ConsoleSpanExporter()
169
187
  self._logger.warning(
170
- "is_agent365_exporter_enabled() not enabled or token_resolver not set. Falling back to console exporter."
188
+ "is_agent365_exporter_enabled() not enabled or token_resolver not set."
189
+ " Falling back to console exporter."
171
190
  )
172
191
 
173
192
  # Add span processors
174
193
 
175
194
  # Create _EnrichingBatchSpanProcessor with optimized settings
176
195
  # This allows extensions to enrich spans before export
177
- batch_processor = _EnrichingBatchSpanProcessor(exporter, **batch_processor_kwargs)
196
+ batch_processor = _EnrichingBatchSpanProcessor(
197
+ exporter,
198
+ suppress_invoke_agent_input=suppress_invoke_agent_input,
199
+ **batch_processor_kwargs,
200
+ )
178
201
  agent_processor = SpanProcessor()
179
202
 
180
203
  tracer_provider.add_span_processor(batch_processor)
@@ -248,7 +271,8 @@ def configure(
248
271
  logger_name: str = DEFAULT_LOGGER_NAME,
249
272
  token_resolver: Callable[[str, str], str | None] | None = None,
250
273
  cluster_category: str = "prod",
251
- exporter_options: Optional[Agent365ExporterOptions] = None,
274
+ exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
275
+ suppress_invoke_agent_input: bool = False,
252
276
  **kwargs: Any,
253
277
  ) -> bool:
254
278
  """
@@ -261,8 +285,10 @@ def configure(
261
285
  Use exporter_options instead.
262
286
  :param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
263
287
  Use exporter_options instead.
264
- :param exporter_options: Agent365ExporterOptions instance for configuring the exporter.
265
- If provided, exporter_options takes precedence. If exporter_options is None, the token_resolver and cluster_category parameters are used as fallback/legacy support to construct a default Agent365ExporterOptions instance.
288
+ :param exporter_options: Exporter configuration. Pass Agent365ExporterOptions for A365 API
289
+ export, SpectraExporterOptions for Spectra Collector sidecar export, or None (default)
290
+ to construct Agent365ExporterOptions from legacy parameters.
291
+ :param suppress_invoke_agent_input: If True, suppress input messages for InvokeAgent spans.
266
292
  :return: True if configuration succeeded, False otherwise.
267
293
  """
268
294
  return _telemetry_manager.configure(
@@ -272,6 +298,7 @@ def configure(
272
298
  token_resolver,
273
299
  cluster_category,
274
300
  exporter_options,
301
+ suppress_invoke_agent_input,
275
302
  **kwargs,
276
303
  )
277
304
 
@@ -2,7 +2,8 @@
2
2
  # Licensed under the MIT License.
3
3
 
4
4
  from .agent365_exporter_options import Agent365ExporterOptions
5
+ from .spectra_exporter_options import SpectraExporterOptions
5
6
 
6
7
  # Agent365Exporter is not exported intentionally.
7
8
  # It should only be used internally by the observability core module.
8
- __all__ = ["Agent365ExporterOptions"]
9
+ __all__ = ["Agent365ExporterOptions", "SpectraExporterOptions"]
@@ -17,11 +17,6 @@ from opentelemetry.sdk.trace import ReadableSpan
17
17
  from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
18
18
  from opentelemetry.trace import StatusCode
19
19
 
20
- from ..constants import (
21
- GEN_AI_INPUT_MESSAGES_KEY,
22
- GEN_AI_OPERATION_NAME_KEY,
23
- INVOKE_AGENT_OPERATION_NAME,
24
- )
25
20
  from .utils import (
26
21
  build_export_url,
27
22
  get_validated_domain_override,
@@ -59,7 +54,6 @@ class _Agent365Exporter(SpanExporter):
59
54
  token_resolver: Callable[[str, str], str | None],
60
55
  cluster_category: str = "prod",
61
56
  use_s2s_endpoint: bool = False,
62
- suppress_invoke_agent_input: bool = False,
63
57
  ):
64
58
  if token_resolver is None:
65
59
  raise ValueError("token_resolver must be provided.")
@@ -69,7 +63,6 @@ class _Agent365Exporter(SpanExporter):
69
63
  self._token_resolver = token_resolver
70
64
  self._cluster_category = cluster_category
71
65
  self._use_s2s_endpoint = use_s2s_endpoint
72
- self._suppress_invoke_agent_input = suppress_invoke_agent_input
73
66
  # Read domain override once at initialization
74
67
  self._domain_override = get_validated_domain_override()
75
68
 
@@ -270,19 +263,6 @@ class _Agent365Exporter(SpanExporter):
270
263
  # attributes
271
264
  attrs = dict(sp.attributes or {})
272
265
 
273
- # Suppress input messages if configured and current span is an InvokeAgent span
274
- if self._suppress_invoke_agent_input:
275
- # Check if current span is an InvokeAgent span by:
276
- # 1. Span name starts with "invoke_agent"
277
- # 2. Has attribute gen_ai.operation.name set to INVOKE_AGENT_OPERATION_NAME
278
- operation_name = attrs.get(GEN_AI_OPERATION_NAME_KEY)
279
- if (
280
- sp.name.startswith(INVOKE_AGENT_OPERATION_NAME)
281
- and operation_name == INVOKE_AGENT_OPERATION_NAME
282
- ):
283
- # Remove input messages attribute
284
- attrs.pop(GEN_AI_INPUT_MESSAGES_KEY, None)
285
-
286
266
  # events
287
267
  events = []
288
268
  for ev in sp.events:
@@ -19,22 +19,31 @@ class EnrichedReadableSpan(ReadableSpan):
19
19
  the original span.
20
20
  """
21
21
 
22
- def __init__(self, span: ReadableSpan, extra_attributes: dict):
22
+ def __init__(
23
+ self,
24
+ span: ReadableSpan,
25
+ extra_attributes: dict,
26
+ excluded_attribute_keys: set[str] | None = None,
27
+ ):
23
28
  """
24
29
  Initialize the enriched span wrapper.
25
30
 
26
31
  Args:
27
32
  span: The original ReadableSpan to wrap.
28
33
  extra_attributes: Additional attributes to merge with the original.
34
+ excluded_attribute_keys: Attribute keys to remove after merging.
29
35
  """
30
36
  self._span = span
31
37
  self._extra_attributes = extra_attributes
38
+ self._excluded_attribute_keys = excluded_attribute_keys or set()
32
39
 
33
40
  @property
34
41
  def attributes(self) -> types.Attributes:
35
42
  """Return merged attributes from original span and extra attributes."""
36
43
  original = dict(self._span.attributes or {})
37
44
  original.update(self._extra_attributes)
45
+ for key in self._excluded_attribute_keys:
46
+ original.pop(key, None)
38
47
  return original
39
48
 
40
49
  @property
@@ -10,6 +10,13 @@ from collections.abc import Callable
10
10
  from opentelemetry.sdk.trace import ReadableSpan
11
11
  from opentelemetry.sdk.trace.export import BatchSpanProcessor
12
12
 
13
+ from ..constants import (
14
+ GEN_AI_INPUT_MESSAGES_KEY,
15
+ GEN_AI_OPERATION_NAME_KEY,
16
+ INVOKE_AGENT_OPERATION_NAME,
17
+ )
18
+ from .enriched_span import EnrichedReadableSpan
19
+
13
20
  logger = logging.getLogger(__name__)
14
21
 
15
22
  # Single span enricher - only one platform instrumentor should be active at a time
@@ -65,6 +72,15 @@ def get_span_enricher() -> Callable[[ReadableSpan], ReadableSpan] | None:
65
72
  class _EnrichingBatchSpanProcessor(BatchSpanProcessor):
66
73
  """BatchSpanProcessor that applies the registered enricher before batching."""
67
74
 
75
+ def __init__(
76
+ self,
77
+ *args: object,
78
+ suppress_invoke_agent_input: bool = False,
79
+ **kwargs: object,
80
+ ):
81
+ super().__init__(*args, **kwargs)
82
+ self._suppress_invoke_agent_input = suppress_invoke_agent_input
83
+
68
84
  def on_end(self, span: ReadableSpan) -> None:
69
85
  """Apply the span enricher and pass to parent for batching.
70
86
 
@@ -83,4 +99,18 @@ class _EnrichingBatchSpanProcessor(BatchSpanProcessor):
83
99
  enricher.__name__,
84
100
  )
85
101
 
102
+ # Apply input message suppression for InvokeAgent spans
103
+ if self._suppress_invoke_agent_input:
104
+ attrs = enriched_span.attributes or {}
105
+ operation_name = attrs.get(GEN_AI_OPERATION_NAME_KEY)
106
+ if (
107
+ enriched_span.name.startswith(INVOKE_AGENT_OPERATION_NAME)
108
+ and operation_name == INVOKE_AGENT_OPERATION_NAME
109
+ ):
110
+ enriched_span = EnrichedReadableSpan(
111
+ enriched_span,
112
+ extra_attributes={},
113
+ excluded_attribute_keys={GEN_AI_INPUT_MESSAGES_KEY},
114
+ )
115
+
86
116
  super().on_end(enriched_span)
@@ -0,0 +1,56 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ from typing import Literal
5
+
6
+
7
+ class SpectraExporterOptions:
8
+ """
9
+ Configuration for exporting traces to a Spectra Collector sidecar via OTLP.
10
+
11
+ Spectra Collector is deployed as a Kubernetes sidecar that accepts
12
+ standard OTLP telemetry on localhost. Defaults are tuned for this
13
+ deployment topology — most consumers should not need to override them.
14
+
15
+ Note: Batch processor fields (max_queue_size, scheduled_delay_ms, etc.)
16
+ are duplicated from Agent365ExporterOptions intentionally — these two
17
+ options classes have no shared base class per design decision C4.
18
+ """
19
+
20
+ _DEFAULT_GRPC_ENDPOINT = "http://localhost:4317"
21
+ _DEFAULT_HTTP_ENDPOINT = "http://localhost:4318"
22
+
23
+ def __init__(
24
+ self,
25
+ endpoint: str | None = None,
26
+ protocol: Literal["grpc", "http"] = "grpc",
27
+ insecure: bool = True,
28
+ max_queue_size: int = 2048,
29
+ scheduled_delay_ms: int = 5000,
30
+ exporter_timeout_ms: int = 30000,
31
+ max_export_batch_size: int = 512,
32
+ ):
33
+ """
34
+ Args:
35
+ endpoint: Spectra sidecar OTLP endpoint. Defaults to
36
+ http://localhost:4317 for gRPC or http://localhost:4318 for HTTP.
37
+ protocol: OTLP protocol — "grpc" or "http". Default: grpc.
38
+ insecure: Use insecure (no TLS) connection. Default: True (localhost sidecar).
39
+ max_queue_size: Batch processor queue size. Default: 2048.
40
+ scheduled_delay_ms: Export interval in milliseconds. Default: 5000.
41
+ exporter_timeout_ms: Export timeout in milliseconds. Default: 30000.
42
+ max_export_batch_size: Max spans per export batch. Default: 512.
43
+ """
44
+ if protocol not in ("grpc", "http"):
45
+ raise ValueError(f"protocol must be 'grpc' or 'http', got '{protocol}'")
46
+ if endpoint is None:
47
+ endpoint = (
48
+ self._DEFAULT_GRPC_ENDPOINT if protocol == "grpc" else self._DEFAULT_HTTP_ENDPOINT
49
+ )
50
+ self.endpoint = endpoint
51
+ self.protocol = protocol
52
+ self.insecure = insecure
53
+ self.max_queue_size = max_queue_size
54
+ self.scheduled_delay_ms = scheduled_delay_ms
55
+ self.exporter_timeout_ms = exporter_timeout_ms
56
+ self.max_export_batch_size = max_export_batch_size
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-a365-observability-core
3
- Version: 0.2.1.dev35
3
+ Version: 0.2.1.dev36
4
4
  Summary: Telemetry, tracing, and monitoring components for AI agents
5
5
  Author-email: Microsoft <support@microsoft.com>
6
6
  License: MIT
@@ -24,6 +24,7 @@ microsoft_agents_a365/observability/core/exporters/agent365_exporter.py
24
24
  microsoft_agents_a365/observability/core/exporters/agent365_exporter_options.py
25
25
  microsoft_agents_a365/observability/core/exporters/enriched_span.py
26
26
  microsoft_agents_a365/observability/core/exporters/enriching_span_processor.py
27
+ microsoft_agents_a365/observability/core/exporters/spectra_exporter_options.py
27
28
  microsoft_agents_a365/observability/core/exporters/utils.py
28
29
  microsoft_agents_a365/observability/core/middleware/__init__.py
29
30
  microsoft_agents_a365/observability/core/middleware/baggage_builder.py