Skip to main content

langfuse-memanto

Turn Langfuse observability signal into Memanto memories, live from your application.

Langfuse records what went wrong. Memanto remembers the lesson. This package connects them: failing spans become durable memories your agents can recall, instead of being re-learned on every run.

Install

pip install langfuse-memanto

That's the only install. memanto comes with it, and there is no server to run — memories go straight to the Memanto cloud API from your process.

Quick start — from nothing

You need one thing: a Memanto API key from memanto.ai.

export MOORCHEH_API_KEY="your-key"

Then two lines in your app:

from langfuse import Langfuse
from langfuse_memanto import attach

Langfuse()                      # your existing setup
attach(agent_id="my-agent")     # start capturing

That's the whole setup. No CLI, no config file, no decorators to add, no call sites to change. The agent is created and activated automatically on the first write, and every span your app already sends to Langfuse is now also inspected for failures.

Configuring capture in code

Anything you'd set with the CLI can be passed to attach() instead:

attach(
    agent_id="my-agent",
    capture=["errors", "slow", "costly"],
    latency_ms=5000,            # slower than 5s is an anomaly
    cost_usd=0.10,              # pricier than 10c is an anomaly
    group_by="metadata.error_code",   # if your messages group poorly
)

Bad settings fail loudly at attach() rather than silently capturing nothing.

Omit a setting and it falls back to the shared profile in ~/.memanto/migrate/langfuse/config.json — so a team can manage capture rules centrally with memanto migrate langfuse --save and individual services need only attach(agent_id=...). Use whichever fits; they compose.

To see what's actually in your Langfuse project before choosing thresholds:

memanto migrate langfuse --discover     # scores, latency spread, error labels
@observe()
def generate(prompt):
    raise ValueError("Model returned malformed output")

produces a memory:

Model returned malformed output in generate                     [error]
Langfuse recorded 12 failing 'generate' observations:
Model returned malformed output.
Seen 12x between 2026-08-06T18:28:52Z and 2026-08-06T18:31:38Z.
tags: langfuse, capture=errors, sig=c8b2fd9e4d19, op=generate

How it works

Langfuse's Python SDK is built on OpenTelemetry and attaches its own span processor to the global TracerProvider. This package attaches a second one, so it sees the same spans without calling the Langfuse API at all.

your app  ──▶  Langfuse SDK  ──▶  OTel TracerProvider  ──┬──▶  LangfuseSpanProcessor  ──▶  Langfuse
                                                         └──▶  MemantoLangfuseHandler ──▶  Memanto

One memory per signature, not per occurrence. A thousand identical failures become a single memory whose confidence reflects how often it happened — the same grouping memanto migrate langfuse performs, sharing the same code, so both paths write identical content.

Nothing runs on your hot path. on_end maps the span and appends it to a buffer; grouping and network I/O happen on a daemon thread. Every entry point swallows its own exceptions — a memory that fails to write will never break your application.

No duplicates with the CLI sync. Writes are recorded in the same ledger (~/.memanto/migrate/langfuse/state.json) under the same project::agent scope, so a later memanto migrate langfuse sees them as already written.

What can and cannot be captured live

Mode Live Why
errors The span carries its own level and status message
slow ✅ with an absolute latency_ms Timing is on the span; percentile budgets need a population to calibrate against
costly ⚠️ only if your app sets cost_details Langfuse otherwise computes cost server-side after ingestion, where a span processor cannot see it
low-score Langfuse scores are attached after a trace ends
success Same

Anything marked ❌ or ⚠️ is still captured by memanto migrate langfuse, which reads the enriched data back from the Langfuse API. The two paths share a ledger, so running both is safe.

The handler logs a warning at startup for any configured mode it cannot honour. For score-driven capture, run memanto migrate langfuse periodically — it and the live handler share a ledger, so they compose safely.

Configuration

Capture rules can come from attach() (above) or from ~/.memanto/migrate/langfuse/config.json, written by memanto migrate langfuse --save or the UI tile. Code wins where both are set.

Runtime settings are read from the environment:

Variable Required Default Description
MOORCHEH_API_KEY Yes Memanto API key. Never logged.
MEMANTO_LANGFUSE_AGENT_ID Yes* Agent that receives the memories. *Or pass agent_id=.
MEMANTO_LANGFUSE_PROJECT No default Which stored capture profile to use
MEMANTO_LANGFUSE_FLUSH_INTERVAL No 30 Seconds between background flushes
MEMANTO_LANGFUSE_MAX_BUFFER No 100 Flush early at this many pending spans
MEMANTO_LANGFUSE_MAX_CACHE No 2000 Bound on in-process signature memory
MEMANTO_LANGFUSE_AUTO_CREATE_AGENT No true Create + activate the agent on first write
MEMANTO_LANGFUSE_SESSION_HOURS No 24 Lifetime of the session the handler opens

Set auto_create_agent=False if agents are provisioned by your platform team and an app should fail rather than create one.

For more control:

from langfuse_memanto import MemantoLangfuseHandler

handler = MemantoLangfuseHandler(agent_id="my-agent", host="https://us.cloud.langfuse.com")
handler.attach()
...
handler.flush()           # write immediately
handler.stats()           # {'captured': 12, 'written': 2, 'dropped': 0, 'pending': 0}
handler.shutdown()        # flush and stop (also runs at exit)

Troubleshooting

No memories appear. Check handler.stats(). captured: 0 means no span matched your capture settings — confirm with memanto migrate langfuse --discover. captured > 0, written: 0 means the flush failed; enable logging:

import logging; logging.getLogger("langfuse_memanto").setLevel(logging.DEBUG)

attach() raises about the TracerProvider. Call it after Langfuse(). Before that, OpenTelemetry has only a ProxyTracerProvider, which cannot take a processor.

Langfuse Cloud US. Keys are region-scoped. Pass host="https://us.cloud.langfuse.com" and set LANGFUSE_HOST for the CLI.

Memories stop appearing after a while. A bounded buffer drops spans during a storm; stats()["dropped"] counts them. Lower MEMANTO_LANGFUSE_FLUSH_INTERVAL or raise MEMANTO_LANGFUSE_MAX_BUFFER.

Requirements

  • Python 3.10+
  • langfuse>=3 in your application (this package does not depend on it — it only needs the OpenTelemetry SDK that Langfuse brings)
  • A Memanto API key and an activated agent

License

MIT

Links

Download files

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

Source Distribution

langfuse_memanto-0.1.0.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

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

langfuse_memanto-0.1.0-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file langfuse_memanto-0.1.0.tar.gz.

File metadata

  • Download URL: langfuse_memanto-0.1.0.tar.gz
  • Upload date:
  • Size: 20.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for langfuse_memanto-0.1.0.tar.gz
Algorithm Hash digest
SHA256 029112cbd6af0d0f5e62cbb48ce2433470fb93115bc8d3f3f6df8e7468fc2eae
MD5 d3676a045fa92063652aebeb73a67d9e
BLAKE2b-256 01180dddbe873399a778e6f1ddf4195ad6b7fe4a174efa935781fe63f66e24b9

See more details on using hashes here.

File details

Details for the file langfuse_memanto-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for langfuse_memanto-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a31b024bd6dc34372c2cdbbb537a23c62a92a83fa82ad3d2a628faa60dc0089
MD5 a431a02b261f9255c02a37c7e9ed9031
BLAKE2b-256 7ba6e5c07fab0560bfa1d7cef8c90954529c84db0b817fc3769a0adac5370eee

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page