createLangfuseSpanProcessor()
Export PAI OpenTelemetry spans to Langfuse.
import { createLangfuseSpanProcessor } from "@pai/langfuse";
import { createPaiOpenTelemetry } from "@pai/observability";
const langfuse = createLangfuseSpanProcessor("env");
export const telemetry = createPaiOpenTelemetry({
serviceName: "assistant-api",
spanProcessors: langfuse ? [langfuse] : [],
});For "env", set PAI_LANGFUSE_PUBLIC_KEY and PAI_LANGFUSE_SECRET_KEY. PAI_LANGFUSE_BASE_URL defaults to http://localhost:7320.
Import
import { createLangfuseSpanProcessor } from "@pai/langfuse";Signature
function createLangfuseSpanProcessor(
input?: PaiLangfuseSpanProcessorOptions,
): SpanProcessor | undefined;Returns undefined when env credentials are missing.
Trace content
The top-level run supplies the trace name, session, and run metadata. Enable
recordRunInputs and recordRunOutputs in createPaiOpenTelemetry to show the
customer's message and final answer in the trace summary. Subagent tasks and
answers appear on their own run observations.
Token usage and cost
Model observations report provider token counts even when content capture is
disabled. Langfuse receives non-overlapping usage buckets: input for ordinary
input, input_cached_tokens for cache reads, input_cache_creation for cache
writes, and output for all output tokens, including reasoning. Reasoning usage
is also available as gen_ai.usage.reasoning.output_tokens metadata; it is
already included in output and must not be added again.
Reported zeroes are preserved, and unreported counts are omitted. Langfuse calculates costs using its configured model prices, so the model definition must price the corresponding usage buckets. Usage is recorded per model step rather than duplicated on run or tool observations.
Span mapper
mapPaiSpanToLangfuseAttributes(span) maps one OpenTelemetry ReadableSpan to
Langfuse attributes. It returns observation input, output, and model usage for the span;
trace-wide fields are returned only for a non-delegated pai.run.execute span.
Model usage is serialized as langfuse.observation.usage_details; an existing
explicit value takes precedence over the mapped counts.
import { mapPaiSpanToLangfuseAttributes } from "@pai/langfuse";
const attributes = mapPaiSpanToLangfuseAttributes(span);Parameters
input?: PaiLangfuseSpanProcessorOptions
"env" | false | config object. "env" reads PAI_LANGFUSE_*. false
disables export.
Defaults to env.
enabled?: boolean
baseUrl?: string
endpoint?: string
publicKey?: string
secretKey?: string
timeoutMillis?: number
scheduledDelayMillis?: number
exportTimeoutMillis?: number
Returns
A SpanProcessor | undefined.
undefined when env credentials are missing. Pass in
createPaiOpenTelemetry({ spanProcessors }).