🤖 feat: preserve failure status when redacting tool outputs in shared transcripts #2207
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 tool outputs are stripped for sharing (
output-redacted), failure information was lost — every redacted tool showed the same muted "redacted" status. This adds an optionalfailedboolean to the redacted schema so failed tools still render as failed (red X) even when their output content is redacted.Background
Follow-up to the
output-redactedfeature (PR #2202).stripToolPartOutputdrops the entireoutputobject (which contains{ success: false }or{ error: "..." }), and setsstate: "output-redacted". Downstream, the aggregator mapped that to a single"redacted"display status — no way to distinguish failed-then-redacted from succeeded-then-redacted.Implementation
Adds an optional
failed?: booleanfield to the redacted state, populated at strip time by inspecting the output before dropping it:src/common/orpc/schemas/message.tsfailed: z.boolean().optional()onNestedToolCallSchema+DynamicToolPartRedactedSchemasrc/common/utils/messages/transcriptShare.tsisFailedOutput()helper; wired intostripNestedToolCallOutputandstripToolPartOutputsrc/browser/utils/messages/StreamingMessageAggregator.ts"output-redacted"branch checkspart.failed→ picks"failed"vs"redacted"src/browser/components/tools/shared/toolUtils.tsxgetNestedToolStatusaccepts optionalfailedparamsrc/browser/components/tools/shared/NestedToolsContainer.tsxcall.failedthroughsrc/browser/components/tools/shared/codeExecutionTypes.tsfailed?: booleanonNestedToolCallinterfacesrc/common/types/message.tsfailed?: booleanon inline nested call typesrc/common/utils/messages/transcriptShare.test.tsNo rendering changes needed —
GenericToolCall,BashToolCall,ToolPrimitives, andgetStatusDisplayalready handle the"failed"status with the correct red X icon.Risks
Low. The
failedfield is optional, so existing persisted data without it parses fine (defaults toundefined→ treated as not-failed). No migration needed.Generated with
mux• Model:anthropic:claude-opus-4-6• Thinking:high• Cost:$2.93