Skip to main content

tai42-monitoring-langfuse

License: Apache 2.0

A Langfuse Monitoring backend for the TAI ecosystem. It implements both faces of the tai42_contract.monitoring contract: the writer (spans, events, LangChain/LangGraph callback handlers, context propagation, per-project scoping) and the reader (metrics totals, the runtime span window, and complete-trace reads) over a Langfuse server — cloud or self-hosted.

The TAI ecosystem

TAI is an open-source runtime for MCP tools, agents, and workflows. A Monitoring backend is the runtime's observability provider: the framework emits tool/hook/agent spans through the registered writer, and the /api/observability/* routes answer dashboards from the same backend's reader. This package is one such provider (Langfuse); any package can back the same contract, so this repo is this provider's own full doc home, and the documentation site covers the platform-level story:

Its only tai-* dependencies are tai42-contract (the Monitoring / MonitoringWriter / MonitoringReader protocols, the neutral data models, and the tai42_app handle) and tai42-kit (TaiBaseSettings and the settings cache). Beyond those it depends on the langfuse SDK, langchain, the OpenTelemetry API, and pydantic / pydantic-settings.

Install

Requires Python 3.13+. Install from PyPI into the environment that runs the server:

uv add tai42-monitoring-langfuse

Or from source — clone this repo and add it as an editable dependency; the tai42-* dependencies resolve in-tree from the workspace.

git clone https://github.com/tai42ai/tai42   # next to your app checkout
cd /path/to/your/app
uv add --editable ../tai42/plugins/monitoring-langfuse

Discovery

The runtime discovers this backend through the manifest's monitoring_module field: it imports every module under the named package, and the package's register module fires the @tai42_app.monitoring.register_monitoring decorator as a side-effect (there is no entry-point). The decorated zero-arg builder constructs the backend from the LANGFUSE_* environment and installs it as the process monitoring backend:

monitoring_module: tai42_monitoring_langfuse

Selecting the module but leaving the credentials unset raises at startup — a selected backend that cannot build is a loud failure, not a silent downgrade. To run without monitoring, omit monitoring_module entirely (the runtime falls back to its built-in no-op). A plain import tai42_monitoring_langfuse (library use) does not register anything.

Configuration

Settings are read from the LANGFUSE_ environment group (see LangfuseSettings):

Env var Default Purpose
LANGFUSE_PUBLIC_KEY Langfuse project public key (required)
LANGFUSE_SECRET_KEY Langfuse project secret key (required)
LANGFUSE_HOST Langfuse server URL (required)
LANGFUSE_TIMEOUT_SECONDS 30 SDK client timeout, also passed per read request
LANGFUSE_TRACING_ENVIRONMENT tai The source marker: stamps every write as the Langfuse environment and scopes every read to it

The source marker lets several deployments share one Langfuse project while each reads back only its own data. get_trace is the one unscoped read — a trace id is globally unique.

Multi-project scoping

One registered backend can hold several Langfuse projects. Monitoring.add_project(ProjectConfig(...)) registers an extra project, and writer.scope(public_key) binds it as the active project for a block — every emit and read inside the block targets it. Scoping to an unregistered key raises (a silently mis-scoped block could leak traces across projects). writer.disable() suppresses all emission within a block.

Behavior notes

  • Writer fail-safety (contract invariant): the emit methods and the Span handle catch + log, never raising into application code. record_span without a trace_id is the one raising precondition (a caller bug). The lifecycle/propagation methods (flush, shutdown, inject_context, get_monitoring_callbacks, scope, disable) propagate errors loudly.
  • Fork safety: writer.shutdown() fully evicts every cached SDK client (not just a flush), so a forked child rebuilds a clean client on first use.
  • Reader: async per the contract; the synchronous Langfuse API client is dispatched off the event loop, and list_traces hydrates trace bodies concurrently (bounded, order-preserving). A trace body that fails to load is kept in place with fetch_error set, never dropped. get_trace returns the trace or raises TraceNotFoundError; a transient failure (e.g. a timeout) propagates as-is — it is never mapped to "not found".
  • Metric sorts: list_traces ordered by total_cost / latency / total_tokens ranks globally through the Langfuse metrics API (trace.list cannot sort on aggregates) and requires from_timestamp + limit; unsupported filter clauses on that path raise MonitoringReadNotSupportedError naming the offending clauses.
  • Private SDK surface: the few capabilities the SDK has no public API for (project-scope contextvar, full client eviction, explicit-time span emission, trace attributes from a span handle) are concentrated in tai42_monitoring_langfuse.sdk_internals, documented as version-fragile against the pinned langfuse~=4.0.6.

Development

uv venv --python 3.13
uv pip install --no-sources --group dev --editable .
uv run --no-sync pytest --cov --cov-report=term-missing
uv run --no-sync ruff check .
uv run --no-sync ruff format --check .
uv run --no-sync pyright

Live integration tests (pytest -m integration) hit a real Langfuse server; they read LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY / LANGFUSE_HOST from the environment and skip cleanly when unset.

License

Apache-2.0. See LICENSE and NOTICE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tai42_monitoring_langfuse-1.0.1.tar.gz (46.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tai42_monitoring_langfuse-1.0.1-py3-none-any.whl (29.6 kB view details)

Uploaded Python 3

File details

Details for the file tai42_monitoring_langfuse-1.0.1.tar.gz.

File metadata

File hashes

Hashes for tai42_monitoring_langfuse-1.0.1.tar.gz
Algorithm Hash digest
SHA256 9c932a7575b5b9b6c5d110a6c5445bce38ed5d6ce2b76fea396bd1a8f5a1b3ec
MD5 75a36a89fc8eb3b1de8d1b77d9afa8ac
BLAKE2b-256 f4012e4095e237f36df39e119f7c30d4acf0645ad4bd51c972bcb1c5bb1cc53a

See more details on using hashes here.

File details

Details for the file tai42_monitoring_langfuse-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for tai42_monitoring_langfuse-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b3287001d4b8c5a083751ad8c0c31f84eb6a300c94ad841806555949fe792e34
MD5 691642ed9c3930c33f30a6f538623e58
BLAKE2b-256 86b3bc88c6ef8aa1c5835d3cc9712bd2a7059a29bce188902ae24958bcf074ee

See more details on using hashes here.

Release history Release notifications | RSS feed

2.2.0

2 files

2.1.2

2 files

2.1.1

2 files

2.1.0

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

This release

1.0.1 This release

2 files

1.0.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page