PAIPAI

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 }).

Learn more

On this page