feat: Annotate active OTel spans with AI SDK metrics and config metadata#108
Draft
feat: Annotate active OTel spans with AI SDK metrics and config metadata#108
Conversation
Every tracker method (track_duration, track_tokens, track_success, etc.) now writes the same metrics onto the active OpenTelemetry span in addition to firing LD analytics events. This gives users correlated LLM observability data in their tracing backend without any extra code. Key additions: - `LDAIObserveConfig` dataclass — controls span annotation behaviour (`annotate_spans`, `create_span_if_none`), passed to `LDAIClient`. - `observe.py` — span annotation helpers, baggage helpers, and `LDAIBaggageSpanProcessor` for propagating AI Config metadata through OTel context (useful with auto-instrumented LLM libraries). - `LDAIClient.config_scope()` — context manager that evaluates an AI Config and scopes its metadata as OTel baggage for the duration of the block, so downstream spans inherit AI Config identity. - `opentelemetry-api` added as an optional dependency (`pip install launchdarkly-server-sdk-ai[otel]`). All OTel code is guarded behind availability checks — zero impact when the package is not installed. - Both `LDAIConfigTracker` and `AIGraphTracker` annotate spans for every metric they track: duration, tokens, TTFT, success/error, feedback, eval scores, judge responses, graph invocation, handoffs, etc. Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds OpenTelemetry span annotation to the LaunchDarkly AI SDK so that every metric tracked by
LDAIConfigTrackerandAIGraphTrackeris also written as attributes on the active OTel span. This gives users correlated LLM observability data in the tracing backend without any extra integration code.What's included
LDAIObserveConfig— a developer-facing dataclass that controls how the SDK writes to spans:annotate_spans(defaultTrue) — toggle all span annotation on/offcreate_span_if_none(defaultTrue) — create an internalld.ai.completionspan when no OTel span is activeobserve.py— the core observability module containing:annotate_span_with_tokens,annotate_span_with_duration,annotate_span_success,annotate_span_with_feedback,annotate_span_with_judge_response, etc.)_span_scope()context manager — ensures a recording span exists for a block of codeset_ai_config_baggage,detach_ai_config_baggage) for OTel context propagationLDAIBaggageSpanProcessor— aSpanProcessorthat copies AI Config metadata from OTel baggage onto every new span, enabling auto-instrumented LLM libraries (e.g. OpenLLMetry) to carry LD metadataLDAIClient.config_scope()— a context manager that evaluates an AI Config and scopes its metadata as OTel baggage for the duration of the block, so any spans created inside (including by auto-instrumentation) inherit AI Config identity attributesTracker span annotation — both
LDAIConfigTrackerandAIGraphTrackernow annotate spans for every metric:ld.ai_config.key,ld.ai_config.variation_key,ld.ai_config.version,ld.ai_config.model,ld.ai_config.provideropentelemetry-apiadded as an optional dependency — install viapip install launchdarkly-server-sdk-ai[otel]. All OTel code is guarded behindtry/except ImportErrorchecks so there is zero impact when the package is not installed.Span attribute naming convention
ld.ai_config.key,ld.ai_config.variation_key,ld.ai_config.model,ld.ai_config.providerld.ai.metrics.tokens.total,ld.ai.metrics.duration_ms,ld.ai.metrics.time_to_first_token_msOKorERRORld.ai.metrics.feedback.kindld.ai.judge.<metric>.score,ld.ai.judge.<metric>.reasoningld.ai.graph.latency,ld.ai.graph.tokens.total,ld.ai.graph.pathTest plan
config_scope()propagates baggage to auto-instrumented spansLDAIBaggageSpanProcessorcopies baggage to span attributesopentelemetry-apiis not installedLDAIObserveConfig(annotate_spans=False)disables all span writesLDAIObserveConfig(create_span_if_none=False)does not create internal spansMade with Cursor