Skip to content

FIX Recover chat drafts after target processing failures - #2474

Merged
Roman Lutz (romanlutz) merged 12 commits into
microsoft:mainfrom
romanlutz:romanlutz-fix-chat-target-recovery
Sep 16, 2026
Merged

Roman Lutz (romanlutz) merged 12 commits into
microsoft:mainfrom
romanlutz:romanlutz-fix-chat-target-recovery

Conversation

@romanlutz

@romanlutz Roman Lutz (romanlutz) commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

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 processing failures, 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

  • Added focused Jest coverage for processing, blocked, successful, rejected, persisted-reload, single-turn, multi-turn, and race scenarios.
  • Added Playwright coverage for HTTP-200 processing failures and clean-conversation recovery, including real-backend regressions for consecutive failures, conversation-loading races, and restored media converters.
  • Added backend tests for response-status metadata, the persisted-error HTTP-200 contract, and safe error previews.
  • Latest focused validation: 132 ChatWindow Jest tests, 267 backend tests, and 39 Chromium tests, including four real-backend cases. Frontend ESLint, TypeScript type-check, production build, backend Ruff, and backend type-check passed.
  • Updated API model descriptions to distinguish response status from attack success. JupyText: N/A; no notebook changes.

Copilot AI and others added 3 commits August 23, 2026 20:12
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
@hannahwestra25 hannahwestra25 self-assigned this Aug 24, 2026
Comment thread frontend/src/components/Chat/ChatWindow.tsx Outdated
Comment thread frontend/src/components/Chat/ChatWindow.tsx Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4a69a7e6-c349-4549-9179-3058526d25dc
Comment thread frontend/src/components/Chat/ChatWindow.tsx Outdated
Comment thread frontend/src/components/Chat/ChatWindow.tsx Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread frontend/src/utils/messageMapper.ts
Comment thread frontend/src/components/Chat/ChatWindow.tsx Outdated
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
@romanlutz
Roman Lutz (romanlutz) added this pull request to the merge queue Sep 16, 2026
Merged via the queue into microsoft:main with commit 40c8919 Sep 16, 2026
49 checks passed
@romanlutz
Roman Lutz (romanlutz) deleted the romanlutz-fix-chat-target-recovery branch September 16, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants