-
-
Notifications
You must be signed in to change notification settings - Fork 80.3k
[Feature] textTransforms should apply output replacements to toolcall_delta / toolcall_end events #97761
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.This issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.Issue affects a taxonomy feature currently scored M4/M5.no-staleExclude from stale automationExclude from stale automation
Description
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.This issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.Issue affects a taxonomy feature currently scored M4/M5.no-staleExclude from stale automationExclude from stale automation
Type
Fields
No fields configured for issues without a type.
Problem
ProviderPlugin.textTransformssupports bidirectional text replacement —inputreplacements mask text before it reaches the LLM, andoutputreplacements restore text in the response stream. This works correctly for:text_delta(streaming text chunks) ✅text_end(final text content) ✅partial(thinking/reasoning blocks) ✅message(full message objects) ✅error(error messages) ✅However,
toolcall_deltaandtoolcall_endevents are not processed by output replacements. This means any transformed tokens in tool call arguments are passed verbatim to tool execution without being restored.Impact
This is critical for PII anonymization and any text transform use case where the LLM generates tool calls that include transformed content:
PII masking: Entity names are correctly encoded before reaching the LLM (e.g.,
"John Smith"→"[PER_001]"). The LLM then generates tool calls (e.g.,send_message,create_card) using the encoded tokens. Sincetoolcall_delta/toolcall_endevents bypass output transforms, the tool executes with[PER_001]instead of"John Smith"— resulting in encoded tokens appearing in external systems (Slack, Google Chat, email, etc.).Any output transform: The same gap applies to any plugin using
textTransforms.outputwhere the LLM's response includes tool calls with transformed text.Reproduction
textTransforms:[MASKED]instead ofJohn SmithRoot Cause
In
plugin-text-transforms(transformAssistantEventText), the function handlestext_delta,text_end,partial,message, anderrorevent types, but does not handletoolcall_deltaortoolcall_end:Proposed Fix
Add output transform handling for tool call argument strings:
This is ~4 lines in
transformAssistantEventTextand follows the exact same pattern as the existingtext_delta/text_endhandlers.Environment
textTransformson provider definitionAdditional Context
The
textTransformssystem is otherwise excellent — provider-level transforms correctly survive registry swaps during agent turns, and the bidirectional input/output contract works perfectly for all non-tool-call response events. This is the only remaining gap in the pipeline.