fix(langfuse): default base URL to localhost; reap stale per-turn trace state - #45326
Open
rdguidry wants to merge 1 commit into
Open
fix(langfuse): default base URL to localhost; reap stale per-turn trace state#45326rdguidry wants to merge 1 commit into
rdguidry wants to merge 1 commit into
Conversation
… state Two fixes to the Langfuse observability plugin: - Default HERMES_LANGFUSE_BASE_URL to http://localhost:3000 instead of https://cloud.langfuse.com. With keys set but no base URL, the old default silently shipped trace payloads (inputs, tool results) to Langfuse Cloud — the wrong failure mode for self-hosted deployments. Cloud users set the URL explicitly. - Reap orphaned TraceState entries. A turn that errors between pre_llm_request and the final post_llm_call never reaches _finish_trace, leaking its TraceState (and unended spans) for the life of the process. _reap_stale_traces() now flushes entries idle longer than 30 minutes at the start of each turn. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tonydwb
approved these changes
Jun 13, 2026
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Clean, well-scoped fix/feature with comprehensive tests. No issues found.
- Logic is correct and focused
- Tests cover the new behavior
- No security concerns
- Good error handling
Reviewed by Hermes Agent
Contributor
|
Thanks for the focused Langfuse work. The cloud-fallback premise remains on current main ( Problems
Suggested changes
Automated hermes-sweeper review. |
This was referenced Jul 27, 2026
This was referenced Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Two independent fixes to the Langfuse observability plugin:
1. Default
HERMES_LANGFUSE_BASE_URLtohttp://localhost:3000With credentials set but no base URL, the plugin currently defaults to
https://cloud.langfuse.com— meaning a self-hosted deployment that forgets the URL silently ships trace payloads (user inputs, assistant outputs, tool results) to a third-party cloud. That is the wrong failure mode: a missing URL on a cloud setup fails loudly (401s on flush, no traces appear), while a missing URL on a self-hosted setup leaks data invisibly.Defaulting to localhost inverts that: misconfiguration now fails closed (connection refused, traces dropped, fail-open semantics preserved) instead of leaking. Cloud users set the URL explicitly — which the README and
hermes toolsflow already instruct. Happy to flip this to requiring an explicit base URL (no default at all) if maintainers prefer that over a localhost default.2. Reap orphaned
TraceStateentriesA turn that errors between
pre_llm_requestand the finalpost_llm_callnever reaches_finish_trace, so itsTraceState(root span, generation/tool observation handles) stays in the module-level_TRACE_STATEdict for the life of the process — a slow leak in long-running gateway deployments, and the spans are never ended.TraceStatealready trackslast_updated_at; this PR adds_reap_stale_traces(), called at the start of each turn from bothon_pre_llm_callandon_pre_llm_request, which flushes entries idle longer than 30 minutes through the existing_finish_tracepath (ends all observations, ends the root span, flushes the client).Note: this is complementary to #45048 / #43677, which close contexts at normal finish and interpreter exit — this handles turns that died mid-flight while the process keeps running.
Testing
scripts/run_tests.sh tests/plugins/test_langfuse_plugin.py— all 41 tests pass. Also running in production on a self-hosted Langfuse v3 deployment (gateway + Telegram platform) since this was written.🤖 Generated with Claude Code