fix(langfuse): include Anthropic system prompt in generation input - #32175
Closed
db-aeon wants to merge 1 commit into
Closed
fix(langfuse): include Anthropic system prompt in generation input#32175db-aeon wants to merge 1 commit into
db-aeon wants to merge 1 commit into
Conversation
Anthropic Messages API passes system via a separate `system` kwarg, so Langfuse LLM call observations only showed user/assistant messages. Pass `system_prompt` through pre_api_request and prepend it to the serialized generation input when it is not already in messages. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
Author
|
Human here: pretty self explanatory: system messages were not being displayed in the langfuse traces. Not sure if this is the best approach, but does work. |
Contributor
|
Thanks for tracing the provider-specific request shape. The premise is confirmed on current main: Suggested changes
Automated hermes-sweeper review. |
4 tasks
This was referenced Jul 27, 2026
This was referenced Aug 3, 2026
erosika
added a commit
to erosika/hermes-agent
that referenced
this pull request
Aug 10, 2026
Providers that move the system prompt out of messages made it vanish from traces: Anthropic Messages carries it as a separate system kwarg (str or content-block list) and the Responses/Codex API as top-level instructions, so generation inputs showed conversations without the agent's instructions, skills, or memory. conversation_loop now derives the system prompt as actually sent to the provider and forwards it to hooks; the plugin prepends a role: system entry when messages don't already carry one. Serialization routes through _capture_content so capture modes apply to system prompts too. Adopted from NousResearch#64292, which extends NousResearch#32175's Anthropic fix to the Codex/Responses path — thanks @FnExpress and @db-aeon. Co-authored-by: FnExpress <37214785+FnExpress@users.noreply.github.com> Co-authored-by: Dan Benyamin <db@project-aeon.com>
Contributor
kshitijk4poor
added a commit
that referenced
this pull request
Aug 13, 2026
… fan-out Salvaged from PR #83437 by @erosika, with adopted fixes from @bgodlin (#81054), @aldoeliacim (#82332), @nftpoetrist (#42326), @rodboev (#39653), @FnExpress (#64292, supersedes #32175 by @db-aeon), @Per0-1 (#61166), @NaMinhyeok (#64797), and @liuhao1024 (#43130). Widens the bundled Langfuse plugin from 6 to 11 hooks and fixes two attribution bugs. Also adopts shutdown/atexit lifecycle fixes and composes 8 prior community PRs with interaction-fix follow-ups. Model attribution: on_pre_llm_request and on_post_llm_call now prefer the wire value (request body model, response model) over the agent attribute, which goes stale after /model switch or provider fallback. Cost total: both cost paths now send a summed total alongside the per-type breakdown, since Langfuse does not derive calculatedTotalCost from cost_details keys. Subscription-included routes send no cost keys at all. New coverage: api_request_error closes failed generations with ERROR level; on_session_finalize/on_session_end close dangling traces for tool-only and interrupted turns; subagent_start/subagent_stop trace delegated children as spans; MoA advisor fan-out emits one generation per advisor priced at the advisor's own model. Capture modes: HERMES_LANGFUSE_CAPTURE=metadata|sanitized|full (default sanitized). Sanitized mode redacts secret patterns before truncation. Adopted lifecycle fixes: shutdown client at session finalize when reason=shutdown (not on session rotation); atexit finalizer ends open root spans for short-lived processes; root context manager exited to prevent interpreter-teardown TypeError; TOCTOU on _get_langfuse() fixed with lock; reasoning_content surfaced in traces; system prompt included in generation input for Anthropic/Codex/Bedrock; SDK v3 update_trace replaces set_trace_io. Closes #29482, #43129, #72661. Supersedes #81054, #82332, #42326, #39653, #64292, #32175, #61166, #64797, #43130. Partially addresses #67544 (capture modes + secret redaction; user_id remains open).
Collaborator
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.
Summary
When using Anthropic (and other providers that split
systemout ofmessages), Langfuse LLM call generation observations only showed user/assistant turns — the Hermes system prompt (skills, memory, context) was missing from the trace input.This change:
system_promptfromapi_kwargs["system"](with fallback when the first message isrole: system) through thepre_api_requesthook inagent/conversation_loop.pyrole: systemmessage to Langfuse generation input inplugins/observability/langfusesystem_prompt_charsmetadata when a system block is loggedWhy
Anthropic Messages API does not include the system prompt in
messages; Hermes already buildsapi_kwargs["system"]separately. The Langfuse plugin only serializedrequest_messages, so hosted traces looked like conversations without the agent instructions — making debugging prompt/cache behavior difficult.Test plan
pytest tests/plugins/test_langfuse_plugin.py(39 passed locally)observability/langfuse, runhermes chat -q "hello", open LLM call in Langfuse and confirmrole: systemappears first in generation inputMade with Cursor