thread_id / user_id, typed nested generations/tools/spans, and real wall-clock timing. Standalone LLM/tool/retriever callbacks finalize their own owned trace. Missing-parent events never overwrite concurrent trace state.
You do not need to wrap LangChain calls in lemma.trace(). Pass the callback handler through LangChain’s callbacks option, then flush() to send the trace. In a long-lived process, open traces that stay idle past open_trace_ttl (default 2 hours) are finalized and sent so handler state cannot grow without bound. Last activity is the latest of the root open time, child ends, and in-flight run starts, so a long agent loop that still emits callbacks is not evicted. The sweep runs from every on_*_start callback at most once per eviction_interval (default 5 minutes). Lemma sends the partial owned trace, the same payload flush() would, rather than dropping abandoned runs. Pass open_trace_ttl=None to disable. A complete docs-chat agent using this integration lives in examples/langchain (TypeScript) and examples/python/langchain (Python). See Runnable examples.
TypeScript
Install LangChain and the Lemma SDK:langChain() as a callback handler:
Python
Install the optional extra:langchain() as a callback handler:
What Lemma records
Promote identity from configurable metadata/tag keys (
threadIdKey / thread_id_key, userIdKey / user_id_key). Defaults also check conversation_id, session_id, and resourceId.
Prompts, tool inputs, outputs, model output text, and error messages are always recorded. Redact secrets and sensitive user data before they reach the chain.