🏷️ fix: Scope Tool-Output Redaction to Tool Calls, Not Label Evidence - #574
Merged
Merged
Conversation
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 breaks
A Langfuse tool-output redaction policy (
toolOutputTracing.redactedToolNamesorenabled: false) exists to redact the named tools' outputs on their tool-call observations. The three label calls also apply it to the evidence they send the label model, and with any active policy they drop every piece of free-form evidence besides:generateActivityLabel{}without a model call.generateActivityPhaseLabel{}.generateReasoningLabelbuildReasoningLabelPromptreturns'', so no reasoning label is produced.A deployment that redacts one tool it rarely calls therefore loses every phase title and reasoning label and gets thinner activity labels, on every run and whether or not Langfuse is exporting.
Change
The label calls no longer resolve or apply the tool-output redaction policy. Each builds its prompt from the full evidence:
Removed with it:
freeFormSuppressedearly return ingenerateActivityLabelgenerateActivityPhaseLabel, which only chose the policies to unionA call still returns
{}when the full evidence produces an empty prompt.What stays redacted
Tool-call observations.
src/langfuse.tsand thetoolOutputTracingpipeline are unchanged: matching tools' outputs are still replaced on their tool spans, and tool-message values in traced generation inputs are still redacted by the existing value walker. The Langfuse-callback tests that assert this through the real export path (for example "promotes trusted ToolMessage artifact metadata before redacting callback output") pass unchanged.What changes for hosts
Label calls are traced as their own generations. Their traced input is the prompt the label model received, so it now contains the tool outputs, reasoning and commentary the label was written from, including the output of tools the policy names. The policy governs tool-call observations only.
The label model also receives that evidence. A host that sends labels to a different provider than its agents and relied on this policy to keep tool output away from that provider needs a different control.
buildActivityLabelPrompt,buildActivityPhaseLabelPromptandbuildReasoningLabelPromptkeep their optionalredactionparameter for hosts that call them directly.Tests
activity-label-redaction-scope.test.ts(new): under a run-levelrun_select_querypolicy, an activity label receives the tool output, reasoning and previous headers; a reasoning-only block is labeled; a labels-only phase is titled from its child labels and commentary; a reasoning label is produced. All four fail againstmain.activity-phase-label.test.tsandreasoning-label.test.ts: three cases that asserted the label model saw redacted or no evidence now assert it sees the full evidence.The full suite passes apart from three provider suites that need live credentials (
llm/anthropic,llm/google,llm/vertexai): 278 suites, 5973 tests.tsc --noEmitand ESLint are clean on the changed files.Built into a LibreChat checkout that sets a
run_select_query/run_tools_with_bashredaction policy with phase labels enabled, this turns theactivity-fold.spec.tse2e suite from 2 failed to 2 passed with the policy still in place.Supersedes #573.