Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Avoid enriching non-MAF spans that use overlapping GenAI operation names.
- Preserve parent-child context for legacy Microsoft Agent Framework streaming
agent spans.
- Stop exporting process-cumulative GenAI ObservableGauges and use Microsoft
Agent Framework's native metric instruments instead.
- Keep non-streaming MAF spans current for nested work and scope Robin provider
suppression to the active LLM call when that optional integration is present.

## Version 0.7.0 (2026-07-03)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ through ``opentelemetry-util-genai`` before spans are ended:
recording. This ensures exporter snapshots include
``gen_ai.span.kind``, ``gen_ai.operation.name``, normalized provider names,
token usage, finish reasons, and streaming TTFT where MAF exposes enough
data.
data. Non-streaming spans remain current for the wrapped call, and nested
Robin provider instrumentation is suppressed when its optional context key
is available.
* ``MAFSemanticProcessor`` remains as a compatibility layer for MAF workflow,
MCP, private-prefix attribute normalization, and the in-process ARMS gauges.
Successful spans keep the OpenTelemetry default ``UNSET`` status; failed
spans keep MAF's ``ERROR`` status.
MCP, and private-prefix attribute normalization. Metrics come from MAF's
native counter and histogram instruments; this package does not export
process-cumulative ObservableGauges. Successful spans keep the OpenTelemetry
default ``UNSET`` status; failed spans keep MAF's ``ERROR`` status.
* ``react_step_patch`` (opt-in via ``ARMS_MAF_REACT_STEP_ENABLED=true``)
wraps ``FunctionInvocationLayer.get_response`` so that each LLM round-trip
inside the ReAct loop emits one ``react step`` span via
Expand Down Expand Up @@ -56,6 +59,4 @@ Env Default Description
``ARMS_MAF_INSTRUMENTATION_ENABLED`` ``true`` Master switch; ``false`` disables instrumentation.
``ARMS_MAF_SENSITIVE_DATA_ENABLED`` ``false`` Capture inputs/outputs (linked to MAF's sensitive-data option).
``ARMS_MAF_REACT_STEP_ENABLED`` ``false`` Emit ``react step`` spans for non-streaming ReAct tool loops.
``ARMS_MAF_METRICS_ENABLED`` ``true`` Aggregate ARMS GenAI gauges in-process.
``ARMS_MAF_SLOW_THRESHOLD_MS`` ``1000`` Slow-call threshold in ms.
====================================== ========== ==============================================================
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
with ``force=True`` so a sticky user-disable does not block us), bridges MAF's
native span helpers through ``opentelemetry-util-genai`` finish helpers, and
registers :class:`~.span_processor.MAFSemanticProcessor` for workflow/MCP
normalization plus metrics aggregation.
normalization. Microsoft Agent Framework's native counter and histogram
instruments remain the metric source.

The optional ReAct step patch (``ARMS_MAF_REACT_STEP_ENABLED=true``) wraps the
``FunctionInvocationLayer.get_response`` ReAct loop with
Expand All @@ -42,9 +43,7 @@
from opentelemetry.trace import get_tracer_provider

from .config import (
get_slow_threshold_ms,
is_instrumentation_enabled,
is_metrics_enabled,
is_react_step_enabled,
is_sensitive_data_enabled,
)
Expand Down Expand Up @@ -116,20 +115,19 @@ def _instrument(self, **kwargs: Any) -> None:
# invocation finish helpers. This keeps MAF's span lifetime and
# streaming cleanup behavior, but writes AGENT/LLM/TOOL semantic
# attributes before span.end() creates the exporter snapshot.
apply_util_genai_bridge()
apply_util_genai_bridge(
tracer_provider=tracer_provider,
meter_provider=meter_provider,
)

# 3) Register the semantic SpanProcessor. MAF uses the standard OTel
# TracerProvider (it does not have its own multi-processor), so
# ``add_span_processor`` is the right hook.
processor = MAFSemanticProcessor(
meter_provider=meter_provider,
slow_threshold_ms=get_slow_threshold_ms(),
metrics_enabled=is_metrics_enabled(default=True),
capture_sensitive_data=sensitive,
)
processor = MAFSemanticProcessor(capture_sensitive_data=sensitive)
try:
tracer_provider.add_span_processor(processor)
except Exception as exc:
revert_util_genai_bridge()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Info] Good defensive rollback — if add_span_processor fails, calling revert_util_genai_bridge() and _remove_span_processor() prevents leaving the instrumentation in a partial state where the bridge is installed but the processor is not. Solid error handling.

logger.warning("add_span_processor failed: %s", exc)
raise

Expand Down
Loading
Loading