Superseded runtime guide: use SSOT ompfuse. The local langfuse.ts remains a gated fallback only; do not enable both exporters.


Historical snapshot

The former standalone exporter is preserved only for incident comparison. Current credentials and setup belong to ompfuse in SSOT; it finalizes token usage on message_end and tracks subagents on the same trace tree.


๐Ÿ—๏ธ Architecture

graph TB
    subgraph OMP["OMP Runtime (Bun)"]
        subgraph Ext["langfuse.ts extension"]
            Events["Events<br>(pi.on)"]
            Queue["Queue<br>(batch)"]
            Post["POST /ingestion<br>(2s / 500 cap)"]

            Events --> Queue
            Queue --> Post
        end
    end

    Server[Langfuse Server]

    Post -->|HTTP| Server

    style OMP fill:#f9f9f9,stroke:#333,stroke-width:2px
    style Ext fill:#e1f5fe,stroke:#0288d1,stroke-width:1.5px
    style Events fill:#fff,stroke:#333
    style Queue fill:#fff,stroke:#333
    style Post fill:#fff,stroke:#333
    style Server fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px

Key design decisions:

  • ๐Ÿ“จ Batched โ€” events queue in memory, flush every 2s or at 500 events
  • ๐Ÿ”— Ordered โ€” flushes chain via promise to preserve event sequence
  • ๐Ÿ›ก๏ธ Fail-open โ€” all handlers wrapped in safeOn() try-catch + sendBatch try-catch; errors logged, never crash OMP
  • โฑ๏ธ 10s timeout โ€” slow Langfuse server canโ€™t hang your session
  • ๐Ÿ Graceful shutdown โ€” final flush is awaited before process exits
  • ๐Ÿ”’ Type-safe โ€” all event properties coerced with String()/Number() before use; no unsafe as casts

๐Ÿ“Š What Gets Traced

OMP Eventโ†’ LangfuseData Captured
๐ŸŽฌ session_startTrace omp-sessioncwd, model, hostname, tags, userId (profile)
๐Ÿ session_shutdownTrace updateturn count summary
๐Ÿ”„ turn_start/endSpan turnduration (ms), context tokens, context %
๐Ÿง  before_provider_requestGeneration llm-callmodel, provider, prompt input (redacted + 15k truncated)
๐Ÿง  message_endGeneration completefinal output, tokens (in/out), cache stats, cost, latency, stop reason
๐Ÿ”ง tool_callSpan tool:<name>input (redacted + truncated)
๐Ÿ”ง tool_resultSpan updateoutput (redacted + 4k), duration, error level
๐Ÿค– agent_start/endSpan agent:<type>subagent type, model, nesting hierarchy, duration
๐Ÿ“ฆ session_compactSpan compactionsummary, tokens before
โš ๏ธ auto_retry_startSpan auto-retryreason, attempt (WARNING level)
๐Ÿ“ ttsr_triggeredSpan ttsr-injectioninjected rule names
๐ŸŽฏ goal_updatedTrace updatesession title โ†’ trace name

Historical configuration

Legacy environment variables are intentionally not documented here. Configure the active package through ompfuse in SSOT.


๐Ÿท๏ธ Langfuse Dashboard Tips

Filtering traces

  • Tag omp โ€” always present on every trace
  • Tag provider:<name> โ€” filter by LLM provider (anthropic, google, etc.)
  • Tag model:<name> โ€” filter by model (claude-opus-4, gemini-pro, etc.)
  • Custom tags via LANGFUSE_TAGS=prod,gpu-node โ†’ tags prod, gpu-node

Understanding the trace tree

graph TD
    %% Define Styles
    classDef session style fill:#1f77b4,stroke:#115588,stroke-width:2px,color:#fff;
    classDef turn style fill:#aec7e8,stroke:#1f77b4,stroke-width:1.5px,color:#000;
    classDef leaf style fill:#f7f7f7,stroke:#ccc,stroke-width:1px,color:#333;
    classDef warning fill:#ffbb78,stroke:#ff7f0e,stroke-dasharray: 5 5,stroke-width:2px,color:#000;
    classDef system style fill:#c7c7c7,stroke:#7f7f7f,stroke-width:1px,color:#000;

    %% Nodes
    Session["omp-session (Trace)<br/><i>1 per OMP session</i>"]:::session

    Turn1["turn (Span)<br/><i>1 per userโ†”agent exchange</i>"]:::turn
    Turn2["turn (Span)"]:::turn
    Compaction["compaction (Span)<br/><i>context window compacted</i>"]:::system
    AutoRetry["โš ๏ธ auto-retry (Span)<br/><i>WARNING level</i>"]:::warning
    Ttsr["ttsr-injection (Span)<br/><i>rule injection event</i>"]:::system

    %% Children of Turn 1
    LLM1["llm-call (Generation)<br/><i>model request/response + tokens</i>"]:::leaf
    Read["tool:read (Span)<br/><i>tool with I/O</i>"]:::leaf
    Edit["tool:edit (Span)<br/><i>another tool</i>"]:::leaf
    Bash["tool:bash (Span)<br/><i>...</i>"]:::leaf
    AgentTask["agent:task (Span)<br/><i>subagent spawn</i>"]:::leaf

    %% Children of Turn 2
    LLM2["llm-call (Generation)"]:::leaf
    Search["tool:search (Span)"]:::leaf

    %% Hierarchy Connections
    Session --> Turn1
    Session --> Turn2
    Session --> Compaction
    Session --> AutoRetry
    Session --> Ttsr

    Turn1 --> LLM1
    Turn1 --> Read
    Turn1 --> Edit
    Turn1 --> Bash
    Turn1 --> AgentTask

    Turn2 --> LLM2
    Turn2 --> Search

Key metadata fields

  • durationMs โ€” on generations + tools + turns
  • contextTokens / contextPct โ€” on turns (how full is the context window?)
  • cacheRead / cacheWrite โ€” on generations (prompt cache hits)
  • totalCost โ€” on generations (if provider reports cost)
  • stopReason โ€” on generations (stop, length, toolUse, error)
  • hostname โ€” on trace (which machine ran this session)

๐Ÿ”’ Security

ConcernProtection
๐Ÿ”‘ API keys & credentialsAuto-redacted by regex before sending across all channels (LLM prompts, completions, and tool inputs/outputs). Matches both key-value pairs (api_key, secret, etc.) and raw keys (ghp_, sk-proj-, sk-lf-, sk-ant-, AIzaSy-).
๐Ÿ–ผ๏ธ Base64 imagesStripped entirely โ†’ [base64 image omitted]
โœ‚๏ธ Large payloadsDeep-truncated: LLM I/O โ†’ 15k, tool I/O โ†’ 8k/4k, summaries โ†’ 5k (performed after redaction to avoid leaking pattern prefixes)
๐Ÿ” Auth to LangfuseBasic Auth header from env vars (never logged)
๐Ÿ“ Batch limitLangfuseโ€™s 3.5 MB limit respected via truncation + queue cap

Historical troubleshooting

Diagnose the active exporter with the ompfuse SSOT. The only legacy decision is whether its explicit compatibility gate is enabled; never run both exporters.


๐Ÿ”ฎ Langfuse API Reference (what the extension uses)

EndpointMethodAuthPurpose
/api/public/ingestionPOSTBasic (pk:sk)Batch event ingestion

Event types sent

TypeWhen
trace-createSession start, goal change, session end (upsert)
generation-createLLM request start
generation-updateLLM response received
span-createTurn/tool/agent/compaction/retry/ttsr start
span-updateTurn/tool end

๐Ÿ“ Changelog

2026-06-20 โ€” 100% Perfection Refinement, Raw Token Redaction & Robust Telemetry Redaction

Security & Secret Redaction Hardening:

  • ๐Ÿ”’ Unified & Structural Secret Redaction โ€” Applied redactSecrets() consistently to all telemetry vectors (LLM prompt inputs, LLM completion outputs, and tool output text previews) before payload truncation. Implemented JSON-parsing inside redactSecrets() to detect and recursively redact stringified JSON payloads structurally, preventing regex escapes and ensuring robust schema-aware key redaction.
  • ๐Ÿ”‘ Raw Token Pattern Detection โ€” Implemented RAW_TOKEN_PATTERN to scan and redact raw API keys/tokens (ghp_, github_pat_, sk-lf-, pk-lf-, sk-ant-, sk-proj-, sk-, AIzaSy) across all string payloads, preventing token leakage even without key-value prefix anchors.
  • ๐Ÿงช Dynamic Environment Secrets Collection โ€” Added code to dynamically scan and harvest secrets from the environment (process.env) on initialization, filtering for values >= 8 characters. Deduplicated and sorted these needles by length descending to prevent substring redaction collisions.
  • ๐Ÿ—ƒ๏ธ Deep Metadata Redaction & Safety โ€” Enforced redactSecrets() across all trace and span metadata blocks (including error messages, environment dumps, model configurations, and process telemetry). Implemented optional chaining and explicit null-pointer guards inside metadata mapping and array filters, eliminating potential runtime TypeError crashes on malformed payload inputs.

Subagent Nesting & Out-of-Scope Architecture:

  • ๐Ÿ•ธ๏ธ OTel-based Subagent Nesting Path โ€” Identified that OMP runs subagents in-process sharing global process state (rather than isolated OS child processes). Thus, ad-hoc process.env mutations for trace propagation bleed and race on concurrent executions. Consequently, subagent span nesting has been declared out-of-scope for this event-based extension. Users requiring recursive multi-agent tracing should configure OMPโ€™s native OpenTelemetry (OTel) OTLP exporter to Langfuseโ€™s OTLP endpoint for correct, race-free trace hierarchies.

Tool Output Preview Hardening:

  • ๐Ÿ”ง Support for Raw String & Custom Tool Outputs โ€” Expanded the tool_result event handler to support raw string content and fallback stringification of non-string and non-array custom tool results (objects, numeric stats, booleans), ensuring custom tool outputs are properly captured and redacted in Langfuse.

2026-06-11 โ€” Architectural Improvements, Subagent Nesting & UI Configs

Subagent Nesting & Developer Profiles:

  • ๐Ÿค– Subagent Span Closing โ€” Added agent_end hook listener to cleanly close subagent execution spans. Implemented activeAgents stack to track nested subagent calls (e.g. task calling plan) to correctly reconstruct parent-child execution graphs.
  • ๐Ÿ‘ค Developer Profiles (userId) โ€” Added OS user/username metadata capture (process.env.USER) as userId to traces, enabling trace filtering by developer profile.

Bug Fixes & Config Enhancements:

  • ๐Ÿ› trace-update rejected by Langfuse API โ€” The Ingestion API does not support trace-update events, returning HTTP 400. Corrected to trace-create events which Langfuse handles as upserts (updates/inserts) on existing id matches.
  • ๐Ÿ› [object Object] tags & model names โ€” When ctx.model or event.model is an object at runtime, String(model) coercion produced "model:[object Object]". Added robust object-to-string extraction of the model id or name field.
  • ๐Ÿ›ก๏ธ JSON secrets redaction bypass โ€” Tool input secrets in JSON/object keys (like { api_key: "value" }) bypassed the regex-based redactSecrets() due to missing separator matches on object keys. Added KEY_REDACT_PATTERN to correctly match and redact secret fields in object schemas.
  • โš™๏ธ LANGFUSE_UI_INDICATOR โ€” Introduced a dedicated env toggle to control the TUI status line tracing indicator, decoupled from verbose debug logging.

2026-06-10 โ€” Robustness Hardening

Bug Fix:

  • ๐Ÿ› model.split is not a function โ€” ctx.model / event.model can be a non-string truthy value at runtime (object, number). Fixed by coercing with String() in buildTags() (line 237), before_provider_request (line 362โ€“363), and after_provider_response (line 414).

Hardening:

  • ๐Ÿ›ก๏ธ Fail-open handlers โ€” all 13 event handlers now wrapped via safeOn() with try-catch; a thrown error in any handler is logged and swallowed, never crashes OMP.
  • ๐Ÿ›ก๏ธ sendBatch try-catch โ€” JSON.stringify failures and uncaught fetch errors now caught inside sendBatch(), preventing chain breakage.
  • ๐Ÿ”ข Token coercion โ€” usage.input/output/cacheRead/cacheWrite now coerced via Number() || 0 to handle string or undefined values.
  • โฑ๏ธ Consistent timestamps โ€” agent_start handler now captures iso() once and reuses for both timestamp and startTime (was calling iso() twice, producing skewed values).
  • ๐Ÿท๏ธ Agent name coercion โ€” agent_start span name ev.agentType coerced via String() to prevent [object Object] tags.
  • ๐Ÿ“ buildTags signature โ€” parameter types widened from string to unknown to match actual runtime event shapes.

๐Ÿงฉ Langfuse Agent Skills (langfuse/skills)

Repo: github.com/langfuse/skills โ€” MIT ยท 160+ โญ

Official Agent Skills that teach AI coding assistants (Claude Code, Cursor, etc.) how to work with Langfuse. Separate from the OMP extension above โ€” these are agent-side skills for instrumentation, prompt management, and data access.

Available Skills

SkillDescription
langfuseQuery/manage traces, prompts, datasets, scores via API; documentation lookup; best-practice workflows

Installation

# Cursor Plugin
/add-plugin langfuse
 
# Skills CLI (no install required)
npx skills add langfuse/skills --skill "langfuse"
 
# Manual symlink
git clone https://github.com/langfuse/skills.git /path/to/langfuse-skills
ln -s /path/to/langfuse-skills/skills/langfuse /path/to/skills-directory/langfuse

Core Capabilities

  1. CLI Data Access โ€” npx langfuse-cli api __schema to discover resources; list/get any API entity (traces, prompts, datasets, scores, sessions)
  2. Documentation Access โ€” langfuse.com/llms.txt (full page index), append .md to any page path, or search via /api/search-docs?query=...
  3. Use-case References โ€” built-in guides for: instrumentation, prompt migration, user feedback capture, SDK upgrades, judge calibration, error analysis, CI/CD experiment gates

Prerequisites

These credentials configure Langfuse skills and the active ompfuse package:

export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
export LANGFUSE_BASE_URL=https://cloud.langfuse.com  # or us.cloud.langfuse.com / self-hosted

Auto-Allowed Tools

The skill auto-grants these (read-only, Langfuse-scoped):

  • WebFetch(domain:langfuse.com)
  • Bash(npx langfuse-cli api __schema/list/get/--help ...)

Plugin Manifests

Ships as plugins to two marketplaces (.claude-plugin/plugin.json + .cursor-plugin/plugin.json), versioned with semver and kept in lockstep.