Builds OpenTelemetry span attribute maps from LangChain telemetry metadata, following a subset of the GenAI Semantic Conventions (v1.40+).
Attribute key constants are defined as string literals because the Hex
opentelemetry_semantic_conventions package lags behind the latest spec.
Coverage
This integration emits the following semantic-convention attributes:
gen_ai.operation.name,gen_ai.provider.name,gen_ai.output.type("json"when the model requests structured output, else"text")gen_ai.request.model,gen_ai.response.modelserver.address,server.port(derived from the model's request endpoint)- Request parameters (when the model sets them):
gen_ai.request.temperature,gen_ai.request.max_tokens,gen_ai.request.top_p,gen_ai.request.top_k,gen_ai.request.frequency_penalty,gen_ai.request.presence_penalty,gen_ai.request.seed,gen_ai.request.choice.count,gen_ai.request.stream,gen_ai.request.stop_sequences,gen_ai.request.reasoning.level gen_ai.usage.input_tokens,gen_ai.usage.output_tokens, and — best-effort from the provider-specificTokenUsage.raw—gen_ai.usage.cache_read.input_tokens,gen_ai.usage.cache_creation.input_tokens,gen_ai.usage.reasoning.output_tokensgen_ai.response.finish_reasons(best-effort fromMessage.status)gen_ai.input.messages,gen_ai.output.messages(opt-in — seeConfig)gen_ai.tool.name,gen_ai.tool.call.id,gen_ai.tool.type,gen_ai.tool.description,gen_ai.tool.call.arguments/gen_ai.tool.call.result(opt-in)gen_ai.agent.name,gen_ai.conversation.id(fromcustom_context)error.type(on failed operations)
It does not currently emit gen_ai.response.id or a distinct
gen_ai.response.model (LangChain keeps no response id and normalizes the
response model to the requested one). Treat the output as a useful subset
rather than full conformance.
Streaming time-to-first-token is captured, but by
LangChain.OpenTelemetry.SpanHandler (as a gen_ai.response.time_to_first_token
attribute and a gen_ai.first_token span event) rather than here, because it is
derived from a streaming lifecycle event rather than the call metadata this
module maps.
Summary
Functions
Builds attributes for a chain execution event.
Builds attributes for a chain execution stop event.
Extracts Langfuse-specific attributes from a custom_context map.
Builds attributes for an LLM call start event.
Builds attributes for an LLM call stop event (token usage and response model).
Returns the gen_ai.operation.name attribute key.
Builds attributes for a tool call start event.
Builds attributes for a tool call stop event.
Functions
Builds attributes for a chain execution event.
Sets gen_ai.conversation.id from custom_context (a :conversation_id key,
falling back to :langfuse_session_id — the same session concept) and also
extracts Langfuse-specific attributes from custom_context when present.
@spec chain_stop(map(), LangChain.OpenTelemetry.Config.t()) :: [{String.t(), term()}]
Builds attributes for a chain execution stop event.
Extracts the first user message as input and the last assistant message as output so they appear on the trace-level span in Langfuse (and other OTEL backends).
Extracts Langfuse-specific attributes from a custom_context map.
Supported keys:
:langfuse_trace_name->langfuse.trace.name:langfuse_user_id->langfuse.user.id:langfuse_session_id->langfuse.session.id:langfuse_tags->langfuse.trace.tags:langfuse_metadata->langfuse.trace.metadata.*(flattened)
@spec llm_call_start(map(), LangChain.OpenTelemetry.Config.t()) :: [ {String.t(), term()} ]
Builds attributes for an LLM call start event.
Returns operation name, output type, model, provider, and request-parameter
attributes (gen_ai.request.*, sourced from metadata[:request_options]).
Input message capture is handled separately by the prompt event handler in
SpanHandler.
@spec llm_call_stop(map(), LangChain.OpenTelemetry.Config.t()) :: [ {String.t(), term()} ]
Builds attributes for an LLM call stop event (token usage and response model).
When config.capture_output_messages is true and metadata[:result] contains
a message, serializes output messages into gen_ai.output.messages.
Returns the gen_ai.operation.name attribute key.
@spec tool_call(map(), LangChain.OpenTelemetry.Config.t()) :: [{String.t(), term()}]
Builds attributes for a tool call start event.
When config.capture_tool_arguments is true and metadata[:arguments] is present,
serializes arguments into gen_ai.tool.call.arguments.
@spec tool_call_stop(map(), LangChain.OpenTelemetry.Config.t()) :: [ {String.t(), term()} ]
Builds attributes for a tool call stop event.
When config.capture_tool_results is true and metadata[:tool_result] is present,
extracts the result content into gen_ai.tool.call.result.