Skip to content

feat(replay): Add AI Summary tab for replay details [INTERNAL] #93224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 18, 2025

Conversation

billyvg
Copy link
Member

@billyvg billyvg commented Jun 10, 2025

A new "AI Summary" tab was added to the Replay Details page for internal testing only. It is only visible to the Replay team. This will not be the final design.

image

  • The TabKey enum in static/app/utils/replays/hooks/useActiveReplayTab.tsx was updated to include AI_SUMMARY, and it was added to supportedVideoTabs for mobile compatibility.
  • In static/app/views/replays/detail/layout/focusTabs.tsx, the getReplayTabs function was modified to conditionally render the "AI Summary" tab based on the organizations:replay-ai-summaries feature flag, positioning it before the Breadcrumbs tab.
  • A new AISummary component was created in static/app/views/replays/detail/aiSummary/index.tsx. This component:
    • Makes a POST request to /organizations/{organization_slug}/replays/summary/ on initial load.
    • Displays a LoadingIndicator while the request is in flight.
    • Shows an error message if the request fails.
    • Renders the summary content upon successful completion.
  • The static/app/views/replays/detail/layout/focusArea.tsx file was updated to import and render the new AISummary component when the AI_SUMMARY tab is active.

Closes REPLAY-388

@billyvg
Copy link
Member Author

billyvg commented Jun 10, 2025

AI Summary Tab Implementation for Replay Details

Overview

Added a new "AI Summary" tab to the Replay Details page that is visible only when the organizations:replay-ai-summaries feature flag is enabled. The tab is positioned before the Breadcrumbs tab and makes a POST request to /organizations/{organization_slug}/replays/summary/ to fetch AI-generated summaries.

Changes Made

1. Updated TabKey Enum

File: static/app/utils/replays/hooks/useActiveReplayTab.tsx

  • Added AI_SUMMARY = 'ai-summary' to the TabKey enum
  • Added TabKey.AI_SUMMARY to the supportedVideoTabs array to ensure it works for mobile replays

2. Updated FocusTabs Component

File: static/app/views/replays/detail/layout/focusTabs.tsx

  • Added feature flag check for replay-ai-summaries in the getReplayTabs function
  • The AI Summary tab appears before Breadcrumbs when the feature flag is enabled
  • Added proper TypeScript typing for the Organization parameter

3. Updated FocusArea Component

File: static/app/views/replays/detail/layout/focusArea.tsx

  • Added case for TabKey.AI_SUMMARY to render the new AISummary component
  • Imported the new AISummary component

4. Created AISummary Component

File: static/app/views/replays/detail/aiSummary/index.tsx

  • Loading State: Shows <LoadingIndicator> while the API request is in flight
  • Error State: Shows error alert if the request fails
  • Success State: Displays the summary text from the API response
  • API Integration: Uses Sentry's useApiQuery() hook with proper query key configuration for POST requests
  • Caching: Implements 5-minute stale time for efficient caching
  • Conditional Fetching: Only makes requests when replay record is available
  • Feature Flag: Only accessible when organizations:replay-ai-summaries is enabled
  • Styling: Consistent with other replay detail tabs using styled components

API Integration Details

Query Key Structure

function createAISummaryQueryKey(orgSlug: string, replayId: string): ApiQueryKey {
  return [
    `/organizations/${orgSlug}/replays/summary/`,
    {
      method: 'POST',
      data: {
        replayId,
      },
    },
  ];
}

useApiQuery Configuration

const {data, isLoading, isError} = useApiQuery<SummaryResponse>(
  createAISummaryQueryKey(organization.slug, replayRecord?.id ?? ''),
  {
    staleTime: 5 * 60 * 1000, // 5 minutes
    enabled: Boolean(replayRecord?.id),
  }
);

Endpoint

POST /organizations/{organization_slug}/replays/summary/

Request Body

{
  "replayId": "replay-id-here"
}

Expected Response

{
  "summary": "AI-generated summary text here"
}

Benefits of useApiQuery Implementation

  1. Automatic Caching: Built-in caching with 5-minute stale time prevents unnecessary requests
  2. Request Deduplication: Multiple components requesting the same data will share a single request
  3. Background Refetching: Automatic background updates when data becomes stale
  4. Conditional Fetching: Only makes requests when replay record is available
  5. Error Handling: Built-in error states and retry logic
  6. Loading States: Automatic loading state management
  7. TypeScript Safety: Full type safety with TypeScript generics

User Experience

  1. Feature Flag Disabled: AI Summary tab is completely hidden
  2. Feature Flag Enabled: AI Summary tab appears as the first tab before Breadcrumbs
  3. First Load: Shows loading indicator while fetching summary
  4. Success: Displays the summary text with proper formatting
  5. Error: Shows user-friendly error message
  6. No Data: Shows informational message when no summary is available
  7. Subsequent Visits: Cached data loads instantly within 5-minute window

Testing

The implementation includes:

  • Data test ID: replay-details-ai-summary-tab for automated testing
  • Proper error handling for API failures
  • Loading states for better UX
  • Feature flag integration for gradual rollout
  • Conditional fetching to prevent unnecessary requests

Dependencies

  • Feature flag: organizations:replay-ai-summaries (already defined in src/sentry/features/temporary.py)
  • API endpoint: /organizations/{organization_slug}/replays/summary/ (needs backend implementation)
  • Components: Uses existing Sentry UI components (LoadingIndicator, Alert, etc.)
  • Query Client: Uses Sentry's useApiQuery hook for data fetching and caching

@billyvg billyvg force-pushed the cursor/add-summary-tab-to-replay-details-4ae6 branch from 8293b30 to 4fc16dc Compare June 18, 2025 21:17
@getsentry getsentry deleted a comment from github-actions bot Jun 18, 2025
@billyvg billyvg removed the Scope: Backend Automatically applied to PRs that change backend components label Jun 18, 2025
@billyvg billyvg marked this pull request as ready for review June 18, 2025 21:24
@billyvg billyvg requested a review from a team as a code owner June 18, 2025 21:24
@billyvg billyvg changed the title Add AI Summary tab for replay details with feature flag support feat(replay): Add AI Summary tab for replay details [INTERNAL] Jun 18, 2025
@billyvg billyvg requested a review from michellewzhang June 18, 2025 21:31
<span>{title}</span>

<ReplayTimestamp>
<TimestampButton
Copy link
Member

Choose a reason for hiding this comment

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

SCR-20250618-nwxe

i'm getting some wonky timestamps locally and no breadcrumbs as a result

Copy link
Member

@michellewzhang michellewzhang Jun 18, 2025

Choose a reason for hiding this comment

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

seems like the LLM returned the timestamp in proper ms format already so we don't need to multiply by 1000?

SCR-20250618-nxpr

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we have to prompt to have it return the correct timestamp because my results are coming back in seconds vs ms.

Copy link
Member

Choose a reason for hiding this comment

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

ah yeah, that's probably a good call.

Copy link
Member

Choose a reason for hiding this comment

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

should we prompt it to return in MS?

white-space: pre-wrap;
`;

const ChapterList = styled('div')``;
Copy link
Member

Choose a reason for hiding this comment

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

extra style

Copy link
Member

@michellewzhang michellewzhang left a comment

Choose a reason for hiding this comment

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

looks good! when the breadcrumbs are expanded the scroll can get janky but that's fine for now

@billyvg billyvg enabled auto-merge (squash) June 18, 2025 23:00
@billyvg billyvg merged commit 7cc0623 into master Jun 18, 2025
45 checks passed
@billyvg billyvg deleted the cursor/add-summary-tab-to-replay-details-4ae6 branch June 18, 2025 23:03
andrewshie-sentry pushed a commit that referenced this pull request Jun 19, 2025
A new "AI Summary" tab was added to the Replay Details page for internal
testing only. It is only visible to the Replay team. This will not be
the final design.


![image](https://github.com/user-attachments/assets/7719aa52-1100-4548-ae97-9ebff845bcfa)


* The `TabKey` enum in
`static/app/utils/replays/hooks/useActiveReplayTab.tsx` was updated to
include `AI_SUMMARY`, and it was added to `supportedVideoTabs` for
mobile compatibility.
* In `static/app/views/replays/detail/layout/focusTabs.tsx`, the
`getReplayTabs` function was modified to conditionally render the "AI
Summary" tab based on the `organizations:replay-ai-summaries` feature
flag, positioning it before the `Breadcrumbs` tab.
* A new `AISummary` component was created in
`static/app/views/replays/detail/aiSummary/index.tsx`. This component:
* Makes a POST request to
`/organizations/{organization_slug}/replays/summary/` on initial load.
    *   Displays a `LoadingIndicator` while the request is in flight.
    *   Shows an error message if the request fails.
    *   Renders the `summary` content upon successful completion.
* The `static/app/views/replays/detail/layout/focusArea.tsx` file was
updated to import and render the new `AISummary` component when the
`AI_SUMMARY` tab is active.

Closes REPLAY-388

---------

Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
Co-authored-by: Michelle Zhang <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants