@sentry/junior-dashboard 0.266.0 → 0.268.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +85 -12
- package/dist/client.js +94 -64
- package/dist/index.js +85 -12
- package/dist/tailwind.css +1 -1
- package/package.json +11 -5
- package/src/app.ts +0 -2
- package/src/auth.ts +4 -7
- package/src/client/App.tsx +55 -53
- package/src/client/components/DetailsPanel.tsx +12 -13
- package/src/client/components/Drawer.tsx +46 -23
- package/src/client/components/ImageAttachment.tsx +1 -1
- package/src/client/components/ParticipantAvatarStack.tsx +6 -2
- package/src/client/components/README.md +15 -2
- package/src/client/components/UserInputForm.tsx +283 -0
- package/src/client/components/layout/DashboardHeader.tsx +13 -0
- package/src/client/components/ui/alert.tsx +1 -1
- package/src/client/components/ui/button-group.tsx +59 -0
- package/src/client/components/ui/button.tsx +11 -1
- package/src/client/components/ui/dialog.tsx +29 -35
- package/src/client/components/ui/drawer.tsx +140 -0
- package/src/client/components/ui/empty.tsx +30 -1
- package/src/client/components/ui/separator.tsx +22 -0
- package/src/client/components/ui/useSheet.ts +5 -1
- package/src/client/conversations/ComposerImages.tsx +66 -14
- package/src/client/conversations/ConversationComposer.tsx +84 -12
- package/src/client/conversations/ConversationDetails.tsx +3 -27
- package/src/client/conversations/ConversationEventDetails.tsx +26 -10
- package/src/client/conversations/ConversationHomeList.tsx +6 -0
- package/src/client/conversations/ConversationListStatusIcon.tsx +15 -1
- package/src/client/conversations/ConversationPage.tsx +160 -2
- package/src/client/conversations/ConversationSidebar.tsx +6 -0
- package/src/client/conversations/ConversationTranscript.tsx +48 -16
- package/src/client/conversations/ConversationWorkspace.tsx +4 -0
- package/src/client/conversations/DetailsList.tsx +33 -0
- package/src/client/conversations/EventDetails.tsx +46 -19
- package/src/client/conversations/ForkConversationButton.tsx +79 -73
- package/src/client/conversations/PendingMailboxStack.tsx +310 -112
- package/src/client/conversations/README.md +30 -13
- package/src/client/conversations/SubagentTranscriptDrawer.tsx +19 -22
- package/src/client/conversations/TranscriptActivityGroup.tsx +27 -19
- package/src/client/conversations/TranscriptAttachment.tsx +39 -4
- package/src/client/conversations/TranscriptAutomationTriggerView.tsx +14 -19
- package/src/client/conversations/TranscriptFailureView.tsx +10 -13
- package/src/client/conversations/TranscriptMarkdown.tsx +232 -436
- package/src/client/conversations/TranscriptMessageContextView.tsx +12 -1
- package/src/client/conversations/TranscriptMessageView.tsx +10 -1
- package/src/client/conversations/TranscriptSummary.tsx +5 -31
- package/src/client/conversations/TranscriptToolView.tsx +13 -1
- package/src/client/conversations/TranscriptTurnContextView.tsx +174 -161
- package/src/client/conversations/TranscriptView.tsx +7 -3
- package/src/client/conversations/UserInputRequestCard.tsx +39 -0
- package/src/client/conversations/conversationOutbox.ts +46 -0
- package/src/client/conversations/eventTime.ts +13 -1
- package/src/client/conversations/eventTranscript.ts +12 -5
- package/src/client/conversations/queries.ts +127 -26
- package/src/client/conversations/transcriptMarkdownLinks.ts +5 -367
- package/src/client/conversations/turnContext.ts +15 -0
- package/src/client/conversations/userInputRequest.ts +56 -0
- package/src/client/format.ts +31 -8
- package/src/client/pages/SettingsPage.tsx +103 -3
- package/src/client/pages/automations/{AutomationLifecycle.tsx → AutomationActions.tsx} +60 -69
- package/src/client/pages/automations/AutomationDraftChanges.tsx +171 -0
- package/src/client/pages/automations/AutomationEditor.tsx +182 -156
- package/src/client/pages/automations/AutomationEventFields.tsx +119 -45
- package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +1 -1
- package/src/client/pages/automations/AutomationFormSection.tsx +20 -2
- package/src/client/pages/automations/AutomationOutcomeFields.tsx +1 -1
- package/src/client/pages/automations/AutomationOverview.tsx +238 -0
- package/src/client/pages/automations/AutomationPage.tsx +343 -0
- package/src/client/pages/automations/AutomationRecentRuns.tsx +3 -2
- package/src/client/pages/automations/AutomationRow.tsx +11 -13
- package/src/client/pages/automations/AutomationRunDetails.tsx +4 -2
- package/src/client/pages/automations/{AutomationExecutionsPage.tsx → AutomationRunsTab.tsx} +94 -103
- package/src/client/pages/automations/AutomationStatus.tsx +164 -108
- package/src/client/pages/automations/AutomationVersionsTab.tsx +518 -0
- package/src/client/pages/automations/AutomationsPage.tsx +10 -98
- package/src/client/pages/automations/AutomationsPageLayout.tsx +5 -23
- package/src/client/pages/automations/README.md +56 -46
- package/src/client/pages/code/RepositorySections.tsx +1 -0
- package/src/client/pages/code/RepositoryTabs.tsx +3 -0
- package/src/client/primaryNav.ts +15 -2
- package/src/client/review-desk/ConversationReviewBar.tsx +62 -0
- package/src/client/review-desk/ReviewDeskPage.tsx +277 -0
- package/src/client/review-desk/ReviewItemActions.tsx +165 -0
- package/src/client/review-desk/ReviewItemCard.tsx +47 -0
- package/src/client/review-desk/ReviewItemDetail.tsx +115 -0
- package/src/client/review-desk/queries.ts +164 -0
- package/src/client/review-desk/reviewItemFormat.ts +61 -0
- package/src/client/types.ts +3 -0
- package/src/mock-reporting/fixtures.ts +54 -2
- package/src/mock-reporting/routes.ts +20 -0
- package/src/shell.ts +3 -0
- package/src/client/conversations/transcriptStyles.ts +0 -10
- package/src/client/pages/automations/AutomationDetails.tsx +0 -193
- package/src/client/pages/automations/AutomationEditPage.tsx +0 -176
- package/src/client/pages/automations/AutomationVersionsPage.tsx +0 -390
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { Bot, ExternalLink } from "lucide-react";
|
|
2
|
+
import { Bot, CircleAlert, ExternalLink } from "lucide-react";
|
|
3
3
|
import { Link } from "react-router";
|
|
4
4
|
|
|
5
5
|
import { useConversationData } from "./queries";
|
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
} from "../format";
|
|
12
12
|
import { buildConversationMarkdown } from "../markdownExport";
|
|
13
13
|
import { Drawer } from "../components/Drawer";
|
|
14
|
+
import { EmptyTelemetry } from "../components/EmptyTelemetry";
|
|
15
|
+
import { Alert, AlertDescription, AlertTitle } from "../components/ui/alert";
|
|
14
16
|
import { SearchInput } from "../components/SearchInput";
|
|
15
17
|
import { StatusChip } from "../components/StatusChip";
|
|
16
18
|
import { subagentStatusTone } from "./ConversationChildAgents";
|
|
@@ -22,7 +24,6 @@ import {
|
|
|
22
24
|
import { Transcript } from "./TranscriptView";
|
|
23
25
|
import { TranscriptLoading } from "./TranscriptLoading";
|
|
24
26
|
import type { TranscriptViewMode } from "./transcriptRenderModel";
|
|
25
|
-
import { transcriptEmptyClass } from "./transcriptStyles";
|
|
26
27
|
|
|
27
28
|
/** One child Conversation to show, with what its parent already knows. */
|
|
28
29
|
export interface SubagentTranscriptTarget {
|
|
@@ -108,6 +109,8 @@ function SubagentTranscriptDrawerContent(props: {
|
|
|
108
109
|
</>
|
|
109
110
|
}
|
|
110
111
|
closeLabel="Close subagent transcript"
|
|
112
|
+
// The event log owns its row insets and sticky toolbar, like the page.
|
|
113
|
+
flush={view === "raw"}
|
|
111
114
|
header={
|
|
112
115
|
<>
|
|
113
116
|
<div className="flex min-w-0 items-center gap-2">
|
|
@@ -178,9 +181,19 @@ function SubagentTranscriptDrawerContent(props: {
|
|
|
178
181
|
{query.isPending ? (
|
|
179
182
|
<TranscriptLoading />
|
|
180
183
|
) : query.error && !detail ? (
|
|
181
|
-
<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
<Alert
|
|
185
|
+
className="gap-1 px-4 py-3 has-[>svg]:gap-x-3"
|
|
186
|
+
variant="destructive"
|
|
187
|
+
>
|
|
188
|
+
<CircleAlert aria-hidden="true" />
|
|
189
|
+
<AlertTitle className="font-display text-base font-semibold leading-tight">
|
|
190
|
+
Conversation failed to load.
|
|
191
|
+
</AlertTitle>
|
|
192
|
+
<AlertDescription className="leading-relaxed">
|
|
193
|
+
Junior could not get this child conversation. Use Open conversation
|
|
194
|
+
to view it on its own page.
|
|
195
|
+
</AlertDescription>
|
|
196
|
+
</Alert>
|
|
184
197
|
) : detail ? (
|
|
185
198
|
<Transcript
|
|
186
199
|
hasPreviousPage={query.hasPreviousPage}
|
|
@@ -194,7 +207,7 @@ function SubagentTranscriptDrawerContent(props: {
|
|
|
194
207
|
view={view}
|
|
195
208
|
/>
|
|
196
209
|
) : (
|
|
197
|
-
<
|
|
210
|
+
<EmptyTelemetry>Conversation unavailable.</EmptyTelemetry>
|
|
198
211
|
)}
|
|
199
212
|
</Drawer>
|
|
200
213
|
);
|
|
@@ -209,19 +222,3 @@ function statusLabel(
|
|
|
209
222
|
}
|
|
210
223
|
return detailStatus ?? status;
|
|
211
224
|
}
|
|
212
|
-
|
|
213
|
-
function DrawerEmptyState(props: {
|
|
214
|
-
children: string;
|
|
215
|
-
tone?: "default" | "error";
|
|
216
|
-
}) {
|
|
217
|
-
const isError = props.tone === "error";
|
|
218
|
-
return (
|
|
219
|
-
<div
|
|
220
|
-
className={transcriptEmptyClass(isError ? "error" : "default")}
|
|
221
|
-
data-tone={props.tone ?? "default"}
|
|
222
|
-
role={isError ? "alert" : undefined}
|
|
223
|
-
>
|
|
224
|
-
{props.children}
|
|
225
|
-
</div>
|
|
226
|
-
);
|
|
227
|
-
}
|
|
@@ -2,17 +2,19 @@ import { Fragment, useState, type ReactNode } from "react";
|
|
|
2
2
|
import { ChevronRight } from "lucide-react";
|
|
3
3
|
|
|
4
4
|
import { ShimmerText } from "../components/ShimmerText";
|
|
5
|
+
import { Collapsible, CollapsibleContent } from "../components/ui/collapsible";
|
|
5
6
|
import {
|
|
6
7
|
Tooltip,
|
|
7
8
|
TooltipContent,
|
|
8
9
|
TooltipTrigger,
|
|
9
10
|
} from "../components/ui/tooltip";
|
|
10
11
|
import { formatMs } from "../format";
|
|
12
|
+
import { reviewItemIdFromToolCall } from "../review-desk/reviewItemFormat";
|
|
11
13
|
import type { RenderedTranscriptEntry } from "./transcriptRenderModel";
|
|
12
14
|
import { cn } from "../styles";
|
|
13
15
|
import { useTranscriptSearch } from "./transcriptSearch";
|
|
14
16
|
import { TranscriptActivityNesting } from "./TranscriptRailEvent";
|
|
15
|
-
import {
|
|
17
|
+
import { TranscriptSummaryTrigger } from "./TranscriptSummary";
|
|
16
18
|
|
|
17
19
|
function countLabel(count: number, singular: string, plural: string): string {
|
|
18
20
|
return count === 1 ? singular : `${count} ${plural}`;
|
|
@@ -28,6 +30,10 @@ export function isCollapsibleActivityEntry(
|
|
|
28
30
|
// Child agent rows stay in the main view, like their result events.
|
|
29
31
|
if (entry.kind === "subagent") return false;
|
|
30
32
|
if (entry.kind === "message") return false;
|
|
33
|
+
// A review card stays visible where the agent added the item.
|
|
34
|
+
if (entry.kind === "tool" && reviewItemIdFromToolCall(entry.part)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
31
37
|
return true;
|
|
32
38
|
}
|
|
33
39
|
|
|
@@ -172,17 +178,17 @@ export function TranscriptActivityGroup(props: {
|
|
|
172
178
|
const open = activityGroupOpen(userOpen);
|
|
173
179
|
|
|
174
180
|
return (
|
|
175
|
-
<
|
|
176
|
-
|
|
181
|
+
<Collapsible
|
|
182
|
+
className="min-w-0 py-0.5"
|
|
183
|
+
onOpenChange={setUserOpen}
|
|
184
|
+
open={open}
|
|
185
|
+
>
|
|
186
|
+
<TranscriptSummaryTrigger
|
|
177
187
|
flush
|
|
178
188
|
className={cn(
|
|
179
|
-
"flex items-center gap-1 text-
|
|
189
|
+
"group/activity-run flex items-center gap-1 text-xs leading-tight text-dashboard-text-muted",
|
|
180
190
|
live && "text-dashboard-accent-text/80",
|
|
181
191
|
)}
|
|
182
|
-
onClick={(event) => {
|
|
183
|
-
event.preventDefault();
|
|
184
|
-
setUserOpen(!open);
|
|
185
|
-
}}
|
|
186
192
|
>
|
|
187
193
|
<Tooltip>
|
|
188
194
|
<TooltipTrigger
|
|
@@ -190,24 +196,26 @@ export function TranscriptActivityGroup(props: {
|
|
|
190
196
|
<span className="inline-flex min-w-0 max-w-full items-center gap-1" />
|
|
191
197
|
}
|
|
192
198
|
>
|
|
193
|
-
<span className="min-w-0 truncate
|
|
194
|
-
<ShimmerText active={live}>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
<ShimmerText active={live}>Hide {label}</ShimmerText>
|
|
199
|
+
<span className="min-w-0 truncate">
|
|
200
|
+
<ShimmerText active={live}>
|
|
201
|
+
{open ? `Hide ${label}` : label}
|
|
202
|
+
</ShimmerText>
|
|
198
203
|
</span>
|
|
199
204
|
<ChevronRight
|
|
200
205
|
aria-hidden="true"
|
|
201
|
-
className="size-3 shrink-0 opacity-55 transition-transform group-
|
|
206
|
+
className="size-3 shrink-0 opacity-55 transition-transform group-aria-expanded/activity-run:rotate-90"
|
|
202
207
|
strokeWidth={2.2}
|
|
203
208
|
/>
|
|
204
209
|
</TooltipTrigger>
|
|
205
210
|
<TooltipContent>{summary}</TooltipContent>
|
|
206
211
|
</Tooltip>
|
|
207
|
-
</
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
+
</TranscriptSummaryTrigger>
|
|
213
|
+
{/* Closed rows stay in the page, so browser find can open the group. */}
|
|
214
|
+
<CollapsibleContent hiddenUntilFound>
|
|
215
|
+
<TranscriptActivityNesting.Provider value>
|
|
216
|
+
<div className="mt-1.5 grid min-w-0 gap-1">{rows}</div>
|
|
217
|
+
</TranscriptActivityNesting.Provider>
|
|
218
|
+
</CollapsibleContent>
|
|
219
|
+
</Collapsible>
|
|
212
220
|
);
|
|
213
221
|
}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
INPUT_IMAGE_TYPES,
|
|
3
|
+
type InputImage,
|
|
3
4
|
type MessageAttachment,
|
|
4
5
|
} from "@sentry/junior/api/schema";
|
|
5
6
|
import { FileText } from "lucide-react";
|
|
6
7
|
import { ImageAttachment } from "../components/ImageAttachment";
|
|
7
8
|
import { HighlightText, useTranscriptSearch } from "./transcriptSearch";
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
/** Build a data URL that previews an image before the server stores it. */
|
|
11
|
+
export function inputImageSrc(image: InputImage): string {
|
|
12
|
+
return `data:${image.contentType};base64,${image.data}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Build the private read route for one stored conversation attachment. */
|
|
16
|
+
export function conversationAttachmentUrl(
|
|
17
|
+
conversationId: string,
|
|
18
|
+
attachmentId: string,
|
|
19
|
+
): string {
|
|
10
20
|
return `/api/conversations/${encodeURIComponent(conversationId)}/attachments/${encodeURIComponent(attachmentId)}`;
|
|
11
21
|
}
|
|
12
22
|
|
|
@@ -35,13 +45,38 @@ export function TranscriptAttachments(props: {
|
|
|
35
45
|
);
|
|
36
46
|
}
|
|
37
47
|
|
|
48
|
+
/** Show the images of a send before the server stores them. */
|
|
49
|
+
export function TranscriptLocalImages(props: { images: InputImage[] }) {
|
|
50
|
+
return (
|
|
51
|
+
<div className="flex min-w-0 flex-wrap items-start gap-2">
|
|
52
|
+
{props.images.map((image, index) => (
|
|
53
|
+
<ImageAttachment
|
|
54
|
+
filename={image.filename}
|
|
55
|
+
imageClassName={TRANSCRIPT_IMAGE_CLASS}
|
|
56
|
+
key={`${image.filename}:${index}`}
|
|
57
|
+
src={inputImageSrc(image)}
|
|
58
|
+
triggerClassName={TRANSCRIPT_IMAGE_TRIGGER_CLASS}
|
|
59
|
+
/>
|
|
60
|
+
))}
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const TRANSCRIPT_IMAGE_CLASS =
|
|
66
|
+
"max-h-48 w-auto max-w-full h-auto rounded-lg object-contain";
|
|
67
|
+
const TRANSCRIPT_IMAGE_TRIGGER_CLASS =
|
|
68
|
+
"block min-w-0 max-w-full flex-none rounded-lg border border-dashboard-border bg-dashboard-fill-faint transition-colors hover:border-dashboard-border-interactive hover:bg-dashboard-fill-hover focus-visible:outline-2 focus-visible:outline-dashboard-focus";
|
|
69
|
+
|
|
38
70
|
/** Render one stored user or assistant attachment using the private read route. */
|
|
39
71
|
function TranscriptAttachment(props: {
|
|
40
72
|
attachment: MessageAttachment;
|
|
41
73
|
conversationId: string;
|
|
42
74
|
}) {
|
|
43
75
|
const search = useTranscriptSearch();
|
|
44
|
-
const href =
|
|
76
|
+
const href = conversationAttachmentUrl(
|
|
77
|
+
props.conversationId,
|
|
78
|
+
props.attachment.id,
|
|
79
|
+
);
|
|
45
80
|
const size = formatAttachmentBytes(props.attachment.bytes);
|
|
46
81
|
const inline = INPUT_IMAGE_TYPES.some(
|
|
47
82
|
(type) => type === props.attachment.contentType,
|
|
@@ -53,10 +88,10 @@ function TranscriptAttachment(props: {
|
|
|
53
88
|
<ImageAttachment
|
|
54
89
|
context={meta}
|
|
55
90
|
filename={props.attachment.filename}
|
|
56
|
-
imageClassName=
|
|
91
|
+
imageClassName={TRANSCRIPT_IMAGE_CLASS}
|
|
57
92
|
loading="lazy"
|
|
58
93
|
src={href}
|
|
59
|
-
triggerClassName=
|
|
94
|
+
triggerClassName={TRANSCRIPT_IMAGE_TRIGGER_CLASS}
|
|
60
95
|
/>
|
|
61
96
|
);
|
|
62
97
|
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { ArrowRight, ChevronRight } from "lucide-react";
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from "react";
|
|
3
3
|
import type { ConversationDetailReport } from "@sentry/junior/api/schema";
|
|
4
4
|
|
|
5
5
|
import { buttonVariants } from "../components/ui/button";
|
|
6
|
+
import {
|
|
7
|
+
Collapsible,
|
|
8
|
+
CollapsibleContent,
|
|
9
|
+
CollapsibleTrigger,
|
|
10
|
+
} from "../components/ui/collapsible";
|
|
6
11
|
import { Link } from "react-router";
|
|
7
12
|
import { ObjectIcon } from "../components/ObjectIcon";
|
|
8
13
|
import { automationPath, formatRelativeTime } from "../format";
|
|
@@ -49,7 +54,6 @@ export function TranscriptAutomationTriggerView(props: {
|
|
|
49
54
|
(part) => part.type === "text" && part.redacted,
|
|
50
55
|
);
|
|
51
56
|
const [open, setOpen] = useState(false);
|
|
52
|
-
const promptId = useId();
|
|
53
57
|
const automationId = props.sourceTask.id?.trim();
|
|
54
58
|
const name = props.sourceTask.title?.trim() || "Automation";
|
|
55
59
|
const details = [
|
|
@@ -86,30 +90,21 @@ export function TranscriptAutomationTriggerView(props: {
|
|
|
86
90
|
</p>
|
|
87
91
|
) : null}
|
|
88
92
|
{text ? (
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
aria-controls={promptId}
|
|
92
|
-
aria-expanded={open}
|
|
93
|
-
className="-mx-1 inline-flex cursor-pointer items-center gap-1 rounded-sm border-0 bg-transparent px-1 py-0.5 font-sans text-xs font-medium text-dashboard-text-muted transition-colors hover:text-dashboard-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-dashboard-focus"
|
|
94
|
-
onClick={() => setOpen((value) => !value)}
|
|
95
|
-
type="button"
|
|
96
|
-
>
|
|
93
|
+
<Collapsible className="min-w-0" onOpenChange={setOpen} open={open}>
|
|
94
|
+
<CollapsibleTrigger className="group -mx-1 inline-flex cursor-pointer items-center gap-1 rounded-sm border-0 bg-transparent px-1 py-0.5 font-sans text-xs font-medium text-dashboard-text-muted transition-colors hover:text-dashboard-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-dashboard-focus">
|
|
97
95
|
<ChevronRight
|
|
98
96
|
aria-hidden="true"
|
|
99
|
-
className=
|
|
97
|
+
className="size-3 transition-transform group-aria-expanded:rotate-90 motion-reduce:transition-none"
|
|
100
98
|
strokeWidth={2.2}
|
|
101
99
|
/>
|
|
102
100
|
{open ? "Hide prompt" : "Show prompt"}
|
|
103
|
-
</
|
|
104
|
-
|
|
105
|
-
<pre
|
|
106
|
-
className="mt-2 max-h-80 overflow-auto whitespace-pre-wrap break-words rounded-lg border border-dashboard-border-subtle bg-dashboard-bg px-3 py-2 font-mono text-xs leading-relaxed text-dashboard-text-muted"
|
|
107
|
-
id={promptId}
|
|
108
|
-
>
|
|
101
|
+
</CollapsibleTrigger>
|
|
102
|
+
<CollapsibleContent>
|
|
103
|
+
<pre className="mt-2 max-h-80 overflow-auto whitespace-pre-wrap break-words rounded-lg border border-dashboard-border-subtle bg-dashboard-bg px-3 py-2 font-mono text-xs leading-relaxed text-dashboard-text-muted">
|
|
109
104
|
<HighlightText text={text} />
|
|
110
105
|
</pre>
|
|
111
|
-
|
|
112
|
-
</
|
|
106
|
+
</CollapsibleContent>
|
|
107
|
+
</Collapsible>
|
|
113
108
|
) : redacted ? (
|
|
114
109
|
<RedactedMarker />
|
|
115
110
|
) : null}
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
ConversationTurnFailureReason,
|
|
5
5
|
} from "@sentry/junior/api/schema";
|
|
6
6
|
|
|
7
|
+
import { Alert, AlertDescription, AlertTitle } from "../components/ui/alert";
|
|
7
8
|
import { formatMessageTimestamp } from "../format";
|
|
8
9
|
import {
|
|
9
10
|
transcriptFailureDescription,
|
|
@@ -35,25 +36,21 @@ export function TranscriptFailureView(props: {
|
|
|
35
36
|
) : null;
|
|
36
37
|
|
|
37
38
|
return (
|
|
38
|
-
<
|
|
39
|
-
className="
|
|
39
|
+
<Alert
|
|
40
|
+
className="min-w-0 gap-3 rounded-lg border-0 bg-rose-300/[0.1] px-4 py-3 text-rose-100 *:[svg]:row-span-1 has-[>svg]:grid-cols-[auto_minmax(0,1fr)_auto] has-[>svg]:gap-x-3 max-md:has-[>svg]:grid-cols-[auto_minmax(0,1fr)] *:[svg]:text-rose-300"
|
|
40
41
|
data-transcript-failure={props.failureCode}
|
|
41
42
|
data-transcript-failure-event-id={props.eventId}
|
|
42
43
|
data-transcript-failure-reason={props.failureReason}
|
|
43
|
-
|
|
44
|
+
variant="destructive"
|
|
44
45
|
>
|
|
45
|
-
<CircleAlert
|
|
46
|
-
aria-hidden="true"
|
|
47
|
-
className="mt-0.5 text-rose-300"
|
|
48
|
-
size={16}
|
|
49
|
-
/>
|
|
46
|
+
<CircleAlert aria-hidden="true" size={16} />
|
|
50
47
|
<div className="min-w-0">
|
|
51
|
-
<
|
|
48
|
+
<AlertTitle className="font-display text-base font-semibold leading-tight">
|
|
52
49
|
{transcriptFailureTitle(props.failureCode, props.failureReason)}
|
|
53
|
-
</
|
|
54
|
-
<
|
|
50
|
+
</AlertTitle>
|
|
51
|
+
<AlertDescription className="mt-1 leading-relaxed text-rose-100/70">
|
|
55
52
|
{transcriptFailureDescription(props.failureCode, props.failureReason)}
|
|
56
|
-
</
|
|
53
|
+
</AlertDescription>
|
|
57
54
|
{eventReference ? (
|
|
58
55
|
<div className="mt-2 text-xs leading-relaxed text-rose-100/65">
|
|
59
56
|
Reference: {eventReference}
|
|
@@ -65,6 +62,6 @@ export function TranscriptFailureView(props: {
|
|
|
65
62
|
{timestamp}
|
|
66
63
|
</span>
|
|
67
64
|
) : null}
|
|
68
|
-
</
|
|
65
|
+
</Alert>
|
|
69
66
|
);
|
|
70
67
|
}
|