Skip to content

symfonic.observability.otel.framework_bridge

framework_bridge

Bridges FrameworkObservabilityHook events into OTEL spans.

Implements the FrameworkObservabilityHook protocol (src/symfonic/agent/observability.py) and forwards each event into the tracer's recorder. Each method is wrapped in a try/except so a bridge bug never crashes the engine's memory pipeline.

CONTAINS opentelemetry imports transitively via OTelTracer. Loaded only through OTelExporter.build().

FrameworkBridge

FrameworkBridge(tracer: OTelTracer)

Translate FrameworkObservabilityHook callbacks into spans.

Source code in src/symfonic/observability/otel/framework_bridge.py
def __init__(self, tracer: OTelTracer) -> None:
    self._tracer = tracer

on_consolidation_complete async

on_consolidation_complete(
    tenant_id: str, operations_count: int, latency_ms: float
) -> None

Emit symfonic.consolidation carrying the reported latency.

Source code in src/symfonic/observability/otel/framework_bridge.py
async def on_consolidation_complete(
    self,
    tenant_id: str,
    operations_count: int,
    latency_ms: float,
) -> None:
    """Emit ``symfonic.consolidation`` carrying the reported latency."""
    try:
        self._tracer.recorder.record_consolidation(
            tenant_id=tenant_id,
            operations_count=operations_count,
            latency_ms=latency_ms,
        )
    except Exception:
        logger.exception(
            "OTel framework bridge on_consolidation_complete raised; suppressing",
        )

on_hydration_complete async

on_hydration_complete(
    tenant_id: str,
    query: str,
    entries_count: int,
    latency_ms: float,
) -> None

Emit symfonic.hydration carrying the reported latency.

Source code in src/symfonic/observability/otel/framework_bridge.py
async def on_hydration_complete(
    self,
    tenant_id: str,
    query: str,
    entries_count: int,
    latency_ms: float,
) -> None:
    """Emit ``symfonic.hydration`` carrying the reported latency."""
    try:
        self._tracer.recorder.record_hydration(
            tenant_id=tenant_id,
            query=query,
            entries_count=entries_count,
            latency_ms=latency_ms,
        )
    except Exception:
        logger.exception(
            "OTel framework bridge on_hydration_complete raised; suppressing",
        )

on_routing_complete async

on_routing_complete(
    tenant_id: str,
    query: str,
    tools_selected: list[str],
    latency_ms: float,
) -> None

Emit symfonic.tool_routing carrying the reported latency.

Source code in src/symfonic/observability/otel/framework_bridge.py
async def on_routing_complete(
    self,
    tenant_id: str,
    query: str,
    tools_selected: list[str],
    latency_ms: float,
) -> None:
    """Emit ``symfonic.tool_routing`` carrying the reported latency."""
    try:
        self._tracer.recorder.record_routing(
            tenant_id=tenant_id,
            query=query,
            tools_selected=tools_selected,
            latency_ms=latency_ms,
        )
    except Exception:
        logger.exception(
            "OTel framework bridge on_routing_complete raised; suppressing",
        )

on_token_budget_computed async

on_token_budget_computed(
    tenant_id: str,
    total_tool_tokens: int,
    filtered_tool_tokens: int,
    savings_pct: float,
) -> None

Emit symfonic.token_budget carrying budget telemetry.

Source code in src/symfonic/observability/otel/framework_bridge.py
async def on_token_budget_computed(
    self,
    tenant_id: str,
    total_tool_tokens: int,
    filtered_tool_tokens: int,
    savings_pct: float,
) -> None:
    """Emit ``symfonic.token_budget`` carrying budget telemetry."""
    try:
        self._tracer.recorder.record_token_budget(
            tenant_id=tenant_id,
            total_tool_tokens=total_tool_tokens,
            filtered_tool_tokens=filtered_tool_tokens,
            savings_pct=savings_pct,
        )
    except Exception:
        logger.exception(
            "OTel framework bridge on_token_budget_computed raised; suppressing",
        )