From 88b62a3359f85b23d2bc1f5a1caf993902b1d357 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Fri, 24 Apr 2026 20:13:10 +0200 Subject: [PATCH] fix(site/src/pages/AgentsPage): add copy buttons to raw attempts (#24705) --- .../DebugPanel/DebugAttemptAccordion.tsx | 26 ++++++++++--------- .../DebugPanel/DebugPanel.stories.tsx | 13 ++++++++++ .../DebugPanel/DebugPanelPrimitives.tsx | 5 +--- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugAttemptAccordion.tsx b/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugAttemptAccordion.tsx index c1c6ecf739..d75636ab86 100644 --- a/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugAttemptAccordion.tsx +++ b/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugAttemptAccordion.tsx @@ -9,7 +9,7 @@ import { import { cn } from "#/utils/cn"; import { DATE_FORMAT, formatDateTime, humanDuration } from "#/utils/time"; import { - DebugCodeBlock, + CopyableCodeBlock, DebugDataSection, EmptyHelper, } from "./DebugPanelPrimitives"; @@ -27,24 +27,23 @@ interface DebugAttemptAccordionProps { interface JsonBlockProps { value: unknown; - fallbackCopy: string; + emptyMessage: string; + copyLabel: string; } -const JsonBlock: FC = ({ value, fallbackCopy }) => { +const JsonBlock: FC = ({ value, emptyMessage, copyLabel }) => { if ( value === null || value === undefined || (typeof value === "string" && value.length === 0) || (typeof value === "object" && Object.keys(value as object).length === 0) ) { - return ; + return ; } - if (typeof value === "string") { - return ; - } + const code = safeJsonStringify(value); - return ; + return ; }; const getAttemptTimingLabel = (attempt: NormalizedAttempt): string => { @@ -79,7 +78,7 @@ export const DebugAttemptAccordion: FC = ({ Unable to parse raw attempts. Showing the original payload exactly as it was captured.

- + ); } @@ -161,19 +160,22 @@ export const DebugAttemptAccordion: FC = ({ diff --git a/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanel.stories.tsx b/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanel.stories.tsx index e97b41b4e4..6d9930ab70 100644 --- a/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanel.stories.tsx +++ b/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanel.stories.tsx @@ -786,6 +786,19 @@ export const MultiStepRunWithRetries: Story = { expect(canvas.getByText(/Attempt 2/)).toBeVisible(); expect(canvas.getByText(/Attempt 3/)).toBeVisible(); }); + + await user.click(canvas.getByRole("button", { name: /Attempt 1/i })); + await waitFor(() => { + expect( + canvas.getByRole("button", { name: /Copy raw request JSON/i }), + ).toBeVisible(); + expect( + canvas.getByRole("button", { name: /Copy raw response JSON/i }), + ).toBeVisible(); + expect( + canvas.getByRole("button", { name: /Copy raw attempt error/i }), + ).toBeVisible(); + }); }, }; diff --git a/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanelPrimitives.tsx b/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanelPrimitives.tsx index 1ea40266e3..9f0b00c014 100644 --- a/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanelPrimitives.tsx +++ b/site/src/pages/AgentsPage/components/RightPanel/DebugPanel/DebugPanelPrimitives.tsx @@ -33,10 +33,7 @@ interface DebugCodeBlockProps { className?: string; } -export const DebugCodeBlock: FC = ({ - code, - className, -}) => { +const DebugCodeBlock: FC = ({ code, className }) => { return (