FIX Recover chat drafts after target processing failures - #2474
Merged
Roman Lutz (romanlutz) merged 12 commits intoSep 16, 2026
Merged
Roman Lutz (romanlutz) merged 12 commits into
Roman Lutz (romanlutz) merged 12 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Scope chat message assertions to the message list so retained in-flight drafts do not create ambiguous text locators. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Adrian Gavrila (adrian-gavrila)
approved these changes
Sep 9, 2026
Adrian Gavrila (adrian-gavrila)
left a comment
Contributor
There was a problem hiding this comment.
Looks good overall! A couple of recovery-related things that I thought might warrant attention. These aren't blocking if you disagree so I am approving with comments.
Keep persisted attachment data types when restoring failed drafts, and invalidate older same-conversation loads around sends so they cannot replace a newer processing outcome. Preserve an already-loaded transcript when a refresh fails. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Preserve draft recovery alongside manual scoring and backend media persistence. Align browser fixtures with the merged response contract. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Reconcile cached drafts with authoritative failed turns, retain scoring evidence while redacting diagnostics, and provide original media references to converter previews. Add regression coverage for refresh outcomes, preserved live drafts, score rendering and exports, and restored media conversion and sending. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Keep recovery history before the first processing failure while preserving the latest draft. Gate sends on conversation readiness and scope rejected sends to their original transcript. Restore media converter inputs with recovered drafts before asynchronous file reads finish. Add focused unit and real-backend browser regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Clarify that the metadata reports the latest target response's recorded error and turn numbers, not attack success. Rename the helper, DTO, API field, and consumers together without changing recovery behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Roman Lutz (romanlutz)
deleted the
romanlutz-fix-chat-target-recovery
branch
September 16, 2026 17:11
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.
Description
PyRIT can persist a failed user turn and an assistant error piece while returning HTTP 200 from the message endpoint. The chat frontend previously treated that resolved request as target success, cleared the composer, and left users without a safe recovery path.
This change reports the latest real target response's error category and associated request/response turns in
target_response_status. This metadata does not evaluate whether the attack achieved its objective;response_error="none"means no response piece reported an error.For retryable
processingfailures, the chat preserves the submitted text, attachments, and converter intent and offers Edit in clean conversation instead of automatically resending. Multi-turn targets retain the contiguous history before the first request that hit a processing error, while single-turn targets start a fresh conversation. This avoids duplicating persisted turns or replaying diagnostic text into future target context.Blocked and safety responses remain non-retryable, rejected HTTP or network sends restore the draft in place, and stale send or recovery completions cannot overwrite newer edits or navigation. Processing diagnostics are also removed from chat content and conversation previews, and internal attachment recovery values are excluded from JSON exports.
The backend's authoritative persisted-error and HTTP-200 behavior remains unchanged.
Before and after
processing-error-before-after-updated.webm
Tests and Documentation