.agents/skills/llmobs-integration/references/reference-implementations.md
Working examples of LLMObs plugins in dd-trace-js.
Location: packages/dd-trace/src/llmobs/plugins/base.js
The abstract base class leaf plugins extend. Composite roots such as ai/index.js extend CompositePlugin
instead.
Key methods:
start(ctx) - Registers span, captures contextgetLLMObsSpanRegisterOptions(ctx) - Abstract, must implementsetLLMObsTags(ctx) - Abstract, must implementend(ctx) - Restores context after the wrapped call returnsasyncEnd(ctx) - Calls setLLMObsTags after the operation settlesTagger methods (accessed via this._tagger):
tagLLMIO, tagEmbeddingIO, tagRetrievalIO, tagTextIOtagMetadata, tagMetrics, tagSpanTags, tagPrompt, tagToolDefinitions, tagModelNameLocation: packages/dd-trace/src/llmobs/plugins/openai/index.js
Category: LLM API Client
Characteristics:
messages: [{role, content}])usage.prompt_tokens, usage.completion_tokens)choices[0].message)Good for: Learning basic plugin structure
Location: packages/dd-trace/src/llmobs/plugins/anthropic/ (index.js + util.js)
Category: LLM API Client
Characteristics:
content: [{type: 'text', text: '...'}])usage.input_tokens, usage.output_tokens)Good for: Handling non-standard message formats
Location: packages/dd-trace/src/llmobs/plugins/genai/ (index.js + util.js)
Category: LLM API Client
Characteristics:
contents: [{role, parts: [{text}]}])candidates[0].content.parts)Good for: Complex nested structures, role normalization
Location: packages/dd-trace/src/llmobs/plugins/ai/ (ddTelemetry.js + vercelTelemetry.js behind a
CompositePlugin)
Category: Multi-Provider Framework
Characteristics:
Good for: Provider abstraction patterns
Location: packages/dd-trace/src/llmobs/plugins/langgraph/
Category: Pure Orchestration
Characteristics:
invoke, stream)LangChain is a separate hybrid plugin (packages/dd-trace/src/llmobs/plugins/langchain/). It emits workflow,
llm, embedding, tool, and retrieval spans. Provider-backed cases run over the VCR proxy.
Good for: Workflow instrumentation, non-LLM span kinds
| Plugin | Category | Format Complexity | Special Features |
|---|---|---|---|
| OpenAI | LLM Client | Simple | Standard reference |
| Anthropic | LLM Client | Medium | Nested content arrays |
| Google GenAI | LLM Client | Complex | Multi-level nesting, role normalization |
| Vercel AI SDK | Multi-Provider | Medium | Provider abstraction |
| LangGraph | Orchestration | Simple | Workflow spans, state management |
Per-provider request, response and token-field shapes live in message-extraction.md.
Pattern: Accumulate deltas from chunk.choices[0].delta.content
Pattern: Accumulate from chunk.delta.text or chunk.content_block.text
Use the contract the instrumentation already publishes. Anthropic and GenAI append chunks to the operation's ctx
and build ctx.result when the chunk channel reports done; OpenAI's instrumentation builds the result before
publishing asyncEnd. The plugin tags that final result instead of maintaining a second request-keyed buffer.
Some plugins integrate LLMObs with tracing plugins using CompositePlugin. The plugin class exposes a
static plugins mapping, either as a field or a getter.
See packages/datadog-plugin-google-genai/src/index.js for a reference implementation.
Test files demonstrate expected span structure and assertions:
Locations:
packages/dd-trace/test/llmobs/plugins/openai/openaiv4.spec.jspackages/dd-trace/test/llmobs/plugins/anthropic/index.spec.jspackages/dd-trace/test/llmobs/plugins/google-genai/index.spec.jspackages/dd-trace/test/llmobs/plugins/langgraph/index.spec.jsStart from base.js for the abstract methods, then the plugin above whose message format is closest to the
one you are adding.