Skip to content

FEAT: GUI view existing scores#2189

Open
jbolor21 wants to merge 8 commits into
microsoft:mainfrom
jbolor21:jbolor/GUI_load_scores
Open

FEAT: GUI view existing scores#2189
jbolor21 wants to merge 8 commits into
microsoft:mainfrom
jbolor21:jbolor/GUI_load_scores

Conversation

@jbolor21

@jbolor21 jbolor21 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Description

Surfaces the attack objectives and scores from existing conversations in the DB into the GUI/CoPyRIT chat view.

Whats new:

  • Objective Header: the conversation objective is now shown in an inline banner above the conversation. Long objectives are truncated with a toggle to view the full objective.
  • Score value: a clickable chip is shown with the score value in the top ribbon
  • When you click on the score value, you can see all scorer information including the rationale, scorer type, etc
  • The chip color is color coded red for 'False', green for 'True' and grey for NA/neutral.
  • Refactored History table outcome icons/colors into a shared utils/attackOutcome helper so the chat and history views stay consistent

Screenshots:
(see the new objective and score)
image

Click on score for details:
image

Tests and Documentation

New unit tests for the score chip, objective header, and the color. Existing full frontend test suite passes.

@rlundeen2

Copy link
Copy Markdown
Contributor

Love this already but haven't reviewed in depth yet :)

Comment thread frontend/src/App.tsx Outdated
Comment thread frontend/src/utils/scoreColor.ts Outdated
Comment thread frontend/src/components/Chat/AttackVerdictChip.tsx Outdated
Comment thread frontend/src/components/Chat/ChatWindow.tsx Outdated

@behnam-o behnam-o left a comment

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.

agreed with other comments, approved as long as those are resolved.

Comment thread frontend/src/components/Chat/AttackVerdictChip.tsx Outdated
Comment thread frontend/src/components/History/AttackTable.tsx Outdated
Comment on lines +624 to +627
<AttackVerdictChip
outcome={outcome}
score={lastScore}
appliesToActiveConversation={activeConversationId === conversationId}

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.

I don't think we should render the verdict here at all when a related (non-main) conversation is active, rather than dimming it and adding a caveat. outcome/last_score are attack-level, computed on the main conversation's final turn — so putting a colored success/failure badge in the ribbon next to a different conversation's messages is misleading. Someone scanning the ribbon reads the badge color first; the "this is attack-level, not this conversation" note in the popover is easy to miss and only shows after a click.

The dimming + appliesToActiveConversation machinery is really working around the fact that this value doesn't belong on a related-conversation view. I'd gate it so the chip only shows on the main conversation (activeConversationId === conversationId) and drop the dimmed/attack-level-note branch entirely — simpler component, and no misleading state.

(If we do want related conversations to show their verdict eventually, the per-piece scores are already in the API — MessagePieceView.scores — so that'd be a separate, more accurate feature rather than surfacing the main conversation's score everywhere.)

[For attacks, it's not unreasonable to think that we might have an attack result page at some point, too. ]

Copilot AI review requested due to automatic review settings July 22, 2026 18:40

Copilot AI left a comment

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.

Pull request overview

This PR enhances the CoPyRIT GUI by surfacing persisted attack objectives and scoring details from stored conversations, enabling users to quickly understand an attack’s goal and outcome and to inspect scorer details directly from the chat/history UI.

Changes:

  • Backend: expose a scale_score computed field on ScoreView to surface the underlying float score for thresholded true/false scorers.
  • Frontend: add an objective header and a reusable verdict/score chip with a details popover; introduce shared outcome + score-color utilities to keep chat/history consistent.
  • Tests: add/extend unit tests across backend response contracts and frontend components/utils to validate rendering and color behavior.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/unit/backend/test_response_contracts.py Adds contract tests ensuring scale_score is serialized as expected.
pyrit/backend/models/attacks.py Adds ScoreView.scale_score computed field derived from score metadata.
frontend/src/utils/scoreColor.ts New utility to compute score badge colors based on outcome + score intensity.
frontend/src/utils/scoreColor.test.ts Unit tests for score normalization and color selection.
frontend/src/utils/attackOutcome.tsx New shared outcome icons/colors + resolver for history/chat consistency.
frontend/src/types/index.ts Extends shared types with AttackOutcome, ScoreView, and new AttackSummary fields (objective, last_score).
frontend/src/components/Home/Home.test.tsx Updates mocks to include required objective on AttackSummary.
frontend/src/components/History/AttackTable.tsx Replaces static outcome badge with shared AttackVerdictChip and score popover support.
frontend/src/components/History/AttackTable.test.tsx Adds tests asserting score-tinted outcome chip + popover behavior without row navigation.
frontend/src/components/History/AttackHistory.test.tsx Updates sample attack data to include objective.
frontend/src/components/Chat/ObjectiveHeader.tsx New component displaying the conversation objective with overflow-aware expand/collapse.
frontend/src/components/Chat/ObjectiveHeader.test.tsx Tests objective header rendering and overflow toggle behavior.
frontend/src/components/Chat/ObjectiveHeader.styles.ts Styling for the objective header banner and expanded/collapsed states.
frontend/src/components/Chat/ChatWindow.tsx Wires objective header and verdict chip into the chat window ribbon and layout.
frontend/src/components/Chat/AttackVerdictChip.tsx New verdict chip component: outcome-only badge or score-tinted interactive popover.
frontend/src/components/Chat/AttackVerdictChip.test.tsx Tests chip visibility, popover contents, and scale-score row behavior.
frontend/src/components/Chat/AttackVerdictChip.styles.ts Styling for chip layout and popover surface content.
frontend/src/App.tsx Threads objective/outcome/lastScore through loaded-attack state into ChatWindow.

Comment thread frontend/src/utils/attackOutcome.tsx
Copilot AI review requested due to automatic review settings July 22, 2026 18:50

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

frontend/src/utils/attackOutcome.tsx:17

  • OUTCOME_COLORS treats error as a warning state, but the error icon is currently colored with the red failure token. This makes error outcomes visually indistinguishable from failures and diverges from the amber/orange error hue used elsewhere (e.g. score badge tinting). Use the dark-orange warning token for the error icon.
  success: <CheckmarkCircleRegular style={{ color: tokens.colorPaletteGreenForeground1 }} />,
  failure: <DismissCircleRegular style={{ color: tokens.colorPaletteRedForeground1 }} />,
  error: <ErrorCircleRegular style={{ color: tokens.colorPaletteRedForeground1 }} />,
  undetermined: <QuestionCircleRegular style={{ color: tokens.colorNeutralForeground3 }} />,

Comment thread frontend/src/components/Chat/ObjectiveHeader.tsx Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 22, 2026 18:58

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

frontend/src/utils/attackOutcome.tsx:17

  • The shared outcome presentation uses a warning-colored badge for error (OUTCOME_COLORS maps error -> warning), but the error icon is still hard-coded to the red foreground token. This makes the error outcome visually inconsistent (and can reduce contrast on a warning/amber background). Use the dark-orange foreground token for the error icon to match the warning semantics and the amber hue used elsewhere.
export const OUTCOME_ICONS: Record<AttackOutcome, React.ReactElement> = {
  success: <CheckmarkCircleRegular style={{ color: tokens.colorPaletteGreenForeground1 }} />,
  failure: <DismissCircleRegular style={{ color: tokens.colorPaletteRedForeground1 }} />,
  error: <ErrorCircleRegular style={{ color: tokens.colorPaletteRedForeground1 }} />,
  undetermined: <QuestionCircleRegular style={{ color: tokens.colorNeutralForeground3 }} />,

Comment on lines +61 to +69
<Button
appearance="subtle"
className={styles.chip}
data-testid="attack-score-chip"
aria-label={`Verdict ${resolvedOutcome}, score ${score.score_value}`}
>
<Badge appearance="filled" size="medium" style={scoreBadgeStyle}>
{resolvedOutcome}
</Badge>
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.

5 participants