@sentry/junior-dashboard 0.61.0 → 0.63.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.d.ts +1 -0
- package/dist/app.js +44 -37
- package/dist/assets.d.ts +2 -0
- package/dist/client/api.d.ts +1 -1
- package/dist/client/components/Metric.d.ts +22 -0
- package/dist/client/components/TelemetryMetrics.d.ts +24 -0
- package/dist/client/components/TranscriptText.d.ts +1 -0
- package/dist/client/components/transcriptRenderModel.d.ts +24 -8
- package/dist/client/format.d.ts +65 -13
- package/dist/client/toolInvocations.d.ts +7 -0
- package/dist/client/types.d.ts +17 -100
- package/dist/client.js +59 -55992
- package/dist/handler.js +44 -37
- package/dist/index.d.ts +8 -0
- package/dist/index.js +564 -0
- package/dist/nitro.d.ts +6 -1
- package/dist/tailwind.css +1 -1
- package/dist/url.d.ts +13 -0
- package/package.json +8 -5
- package/src/app.ts +24 -16
- package/src/assets.ts +2 -0
- package/src/auth.ts +2 -35
- package/src/client/components/ConversationRowStats.tsx +3 -2
- package/src/client/components/Metric.tsx +159 -0
- package/src/client/components/TelemetryMetrics.tsx +124 -0
- package/src/client/components/ToolFrame.tsx +3 -3
- package/src/client/components/TranscriptText.tsx +5 -2
- package/src/client/components/TranscriptToolView.tsx +9 -7
- package/src/client/components/TranscriptTurn.tsx +435 -84
- package/src/client/components/TurnDurationChart.tsx +229 -78
- package/src/client/components/transcriptRenderModel.ts +66 -22
- package/src/client/format.ts +369 -103
- package/src/client/pages/ConversationPage.tsx +77 -38
- package/src/client/toolInvocations.ts +16 -0
- package/src/client/types.ts +34 -90
- package/src/index.ts +74 -0
- package/src/nitro.ts +6 -1
- package/src/url.ts +68 -0
package/dist/assets.d.ts
ADDED
package/dist/client/api.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ export declare const client: QueryClient;
|
|
|
5
5
|
/** Poll the dashboard summary feed used by command center and conversation lists. */
|
|
6
6
|
export declare function useDashboardData(): import("@tanstack/react-query").UseQueryResult<NoInfer<DashboardData>, Error>;
|
|
7
7
|
/** Poll one conversation transcript while preserving route-level disabled state. */
|
|
8
|
-
export declare function useConversationData(conversationId: string | undefined): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
8
|
+
export declare function useConversationData(conversationId: string | undefined): import("@tanstack/react-query").UseQueryResult<NoInfer<import("@sentry/junior/reporting").DashboardConversationReport>, Error>;
|
|
9
9
|
/** Read one conversation transcript payload for dashboard-local detail views. */
|
|
10
10
|
export declare function readConversationData(conversationId: string): Promise<ConversationDetailFeed>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export type MetricTooltipLine = {
|
|
3
|
+
label?: string;
|
|
4
|
+
labelStyle?: "code";
|
|
5
|
+
value: string;
|
|
6
|
+
};
|
|
7
|
+
export type MetricListItem = {
|
|
8
|
+
content: ReactNode;
|
|
9
|
+
key: string;
|
|
10
|
+
};
|
|
11
|
+
/** Render compact metadata text with an optional styled hover/focus tooltip. */
|
|
12
|
+
export declare function MetricValue(props: {
|
|
13
|
+
align?: "left" | "right";
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
tooltip?: MetricTooltipLine[];
|
|
17
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
/** Render inline metadata with consistent dot spacing across dashboard headers. */
|
|
19
|
+
export declare function MetricList(props: {
|
|
20
|
+
className?: string;
|
|
21
|
+
items: MetricListItem[];
|
|
22
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type MessageSummary, type TokenUsageSummary, type ToolCallSummary } from "../format";
|
|
2
|
+
/** Render total token usage with a hoverable breakdown. */
|
|
3
|
+
export declare function TokenMetric(props: {
|
|
4
|
+
align?: "left" | "right";
|
|
5
|
+
summary: TokenUsageSummary | undefined;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
/** Render a duration value with start/end timestamps in the tooltip. */
|
|
8
|
+
export declare function DurationMetric(props: {
|
|
9
|
+
align?: "left" | "right";
|
|
10
|
+
endedAt?: string;
|
|
11
|
+
label: string;
|
|
12
|
+
startedAt?: string;
|
|
13
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
14
|
+
/** Render a tool-call count with top tool names, counts, and matched duration. */
|
|
15
|
+
export declare function ToolCallsMetric(props: {
|
|
16
|
+
align?: "left" | "right";
|
|
17
|
+
loading?: boolean;
|
|
18
|
+
summary: ToolCallSummary | undefined;
|
|
19
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
20
|
+
/** Render a conversational message count. */
|
|
21
|
+
export declare function MessagesMetric(props: {
|
|
22
|
+
loading?: boolean;
|
|
23
|
+
summary: MessageSummary | undefined;
|
|
24
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,22 +1,38 @@
|
|
|
1
1
|
import type { TranscriptMessage, TranscriptPart } from "../types";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
part: TranscriptPart;
|
|
5
|
-
} | {
|
|
2
|
+
type RenderedToolPart = {
|
|
3
|
+
call: TranscriptPart;
|
|
6
4
|
kind: "tool";
|
|
7
|
-
call?: TranscriptPart;
|
|
8
5
|
result?: TranscriptPart;
|
|
6
|
+
} | {
|
|
7
|
+
call?: undefined;
|
|
8
|
+
kind: "tool";
|
|
9
|
+
result: TranscriptPart;
|
|
9
10
|
};
|
|
11
|
+
export type RenderedTranscriptPart = {
|
|
12
|
+
kind: "part";
|
|
13
|
+
part: TranscriptPart;
|
|
14
|
+
} | RenderedToolPart;
|
|
10
15
|
type RenderedTranscriptEntry = {
|
|
11
16
|
kind: "message";
|
|
12
17
|
message: TranscriptMessage;
|
|
13
|
-
} | RenderedToolEntry;
|
|
18
|
+
} | RenderedThinkingEntry | RenderedToolEntry;
|
|
19
|
+
type RenderedThinkingEntry = {
|
|
20
|
+
kind: "thinking";
|
|
21
|
+
part: TranscriptPart;
|
|
22
|
+
timestamp?: number;
|
|
23
|
+
};
|
|
14
24
|
type RenderedToolEntry = {
|
|
15
|
-
call
|
|
25
|
+
call: TranscriptPart;
|
|
16
26
|
kind: "tool";
|
|
17
27
|
result?: TranscriptPart;
|
|
18
28
|
resultTimestamp?: number;
|
|
19
29
|
timestamp?: number;
|
|
30
|
+
} | {
|
|
31
|
+
call?: undefined;
|
|
32
|
+
kind: "tool";
|
|
33
|
+
result: TranscriptPart;
|
|
34
|
+
resultTimestamp?: number;
|
|
35
|
+
timestamp?: never;
|
|
20
36
|
};
|
|
21
37
|
export type TranscriptViewMode = "raw" | "rich";
|
|
22
38
|
/** Group inline transcript parts so matching tool calls/results render together. */
|
|
@@ -26,5 +42,5 @@ export declare function groupTranscriptMessages(messages: TranscriptMessage[]):
|
|
|
26
42
|
/** Build the plain-text clipboard/raw view for one transcript message. */
|
|
27
43
|
export declare function messageRawText(message: TranscriptMessage): string;
|
|
28
44
|
/** Count rendered rows so structured transcript expansion opens the newest node. */
|
|
29
|
-
export declare function countRenderedTranscriptChildren(part: RenderedTranscriptPart): number;
|
|
45
|
+
export declare function countRenderedTranscriptChildren(part: RenderedTranscriptPart, role?: string): number;
|
|
30
46
|
export {};
|
package/dist/client/format.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export declare function formatTime(value: string | undefined): string;
|
|
|
10
10
|
export declare function formatRelativeTime(value: string | undefined): string;
|
|
11
11
|
/** Format millisecond durations for compact transcript metadata. */
|
|
12
12
|
export declare function formatMs(value: number | undefined): string;
|
|
13
|
+
/** Format chart duration ticks without long labels wrapping on the Y axis. */
|
|
14
|
+
export declare function formatDurationTick(value: number | undefined): string;
|
|
13
15
|
/** Format aggregate runtime across turn summaries when duration data exists. */
|
|
14
16
|
export declare function formatDurationTotal(durations: Array<number | undefined>): string;
|
|
15
17
|
/** Format transcript event timestamps independently from turn start offsets. */
|
|
@@ -18,16 +20,53 @@ export declare function formatMessageTimestamp(value: number | undefined): strin
|
|
|
18
20
|
export declare function formatMessageOffset(turn: ConversationTurn, value: number | undefined): string | undefined;
|
|
19
21
|
/** Format byte counts in lowercase compact units for transcript metadata. */
|
|
20
22
|
export declare function formatBytes(value: number | undefined): string;
|
|
23
|
+
/** Normalized role category for transcript messages. */
|
|
24
|
+
export type TranscriptRoleKind = "assistant" | "other" | "system" | "tool" | "user";
|
|
25
|
+
/** Normalize a raw transcript role string to a canonical kind. */
|
|
26
|
+
export declare function transcriptRoleKind(role: string): TranscriptRoleKind;
|
|
21
27
|
/** Count visible or redacted message records for a turn. */
|
|
22
28
|
export declare function turnMessageCount(turn: ConversationTurn): number;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
export type ToolCallSummaryItem = {
|
|
30
|
+
count: number;
|
|
31
|
+
name: string;
|
|
32
|
+
totalDurationMs?: number;
|
|
33
|
+
};
|
|
34
|
+
export type ToolCallSummary = {
|
|
35
|
+
items: ToolCallSummaryItem[];
|
|
36
|
+
total: number;
|
|
37
|
+
};
|
|
38
|
+
/** Summarize tool calls and matched result durations from transcript metadata. */
|
|
39
|
+
export declare function summarizeToolCalls(turns: ConversationTurn[], limit?: number): ToolCallSummary;
|
|
40
|
+
export type MessageSummaryItem = {
|
|
41
|
+
author: string;
|
|
42
|
+
bytes: number;
|
|
43
|
+
};
|
|
44
|
+
export type MessageSummary = {
|
|
45
|
+
items: MessageSummaryItem[];
|
|
46
|
+
total: number;
|
|
47
|
+
};
|
|
48
|
+
/** Summarize conversational messages by author and serialized size. */
|
|
49
|
+
export declare function summarizeMessages(turns: ConversationTurn[]): MessageSummary;
|
|
50
|
+
/** Format raw counts with the dashboard's compact number rules. */
|
|
51
|
+
export declare function formatCompactNumber(value: number | undefined): string;
|
|
52
|
+
export type TokenUsageSummary = {
|
|
53
|
+
cachedInputTokens?: number;
|
|
54
|
+
cacheCreationTokens?: number;
|
|
55
|
+
inputTokens?: number;
|
|
56
|
+
outputTokens?: number;
|
|
57
|
+
providerTotalTokens?: number;
|
|
58
|
+
totalTokens: number;
|
|
59
|
+
};
|
|
60
|
+
/** Summarize token usage without double-counting provider total fields. */
|
|
61
|
+
export declare function summarizeUsage(usages: Array<TurnUsage | undefined>): TokenUsageSummary | undefined;
|
|
62
|
+
/** Format a summarized token counter for compact metadata. */
|
|
63
|
+
export declare function formatTokenSummary(summary: TokenUsageSummary | undefined): string;
|
|
27
64
|
/** Format the aggregate token count across conversation turns. */
|
|
28
65
|
export declare function formatUsageTotal(usages: Array<TurnUsage | undefined>): string;
|
|
29
|
-
/**
|
|
30
|
-
export declare function
|
|
66
|
+
/** Keep turn duration displays aligned on elapsed transcript time. */
|
|
67
|
+
export declare function turnElapsedDurationMs(turn: Pick<ConversationTurn, "completedAt" | "lastSeenAt" | "startedAt">): number | undefined;
|
|
68
|
+
/** Format elapsed turn time for chart dots and transcript metadata. */
|
|
69
|
+
export declare function formatTurnDuration(turn: Pick<ConversationTurn, "completedAt" | "lastSeenAt" | "startedAt">): string;
|
|
31
70
|
/** Format a conversation span from first turn start to latest activity. */
|
|
32
71
|
export declare function formatConversationDuration(conversation: Conversation): string;
|
|
33
72
|
/** Resolve the owning conversation id for a turn/session summary. */
|
|
@@ -35,11 +74,13 @@ export declare function conversationIdForSession(session: Session): string;
|
|
|
35
74
|
/** Choose the safe display title already prepared by the reporting API. */
|
|
36
75
|
export declare function conversationDisplayTitle(conversation: Conversation | undefined): string;
|
|
37
76
|
/** Prefer stable requester identifiers while keeping Slack ids as a last resort. */
|
|
38
|
-
export declare function requesterLabel(requester: RequesterIdentity | undefined
|
|
77
|
+
export declare function requesterLabel(requester: RequesterIdentity | undefined): string | undefined;
|
|
78
|
+
/** Derive the conversation owner label from structured requester identity. */
|
|
79
|
+
export declare function conversationRequesterLabel(conversation: Conversation | undefined): string | undefined;
|
|
39
80
|
/** Format the owner and permalink id line shared by conversation rows and headers. */
|
|
40
81
|
export declare function conversationIdentityMeta(conversation: Conversation | undefined, conversationId: string | undefined): string;
|
|
41
82
|
/** Convert Slack channel ids and names into user-facing location labels. */
|
|
42
|
-
export declare function slackLocationLabel(input: Pick<Session, "channel" | "channelName"
|
|
83
|
+
export declare function slackLocationLabel(input: Pick<Session, "channel" | "channelName">, options?: {
|
|
43
84
|
includeId?: boolean;
|
|
44
85
|
}): string | undefined;
|
|
45
86
|
/** Collapse raw turn states into the dashboard's visual status language. */
|
|
@@ -59,13 +100,24 @@ export declare function detectLanguage(text: string): BundledLanguage;
|
|
|
59
100
|
*/
|
|
60
101
|
export declare function detectOutputLanguage(text: string): BundledLanguage;
|
|
61
102
|
/**
|
|
62
|
-
* Decide whether a
|
|
63
|
-
*
|
|
64
|
-
*
|
|
103
|
+
* Decide whether a block can use the interactive markup renderer.
|
|
104
|
+
* Only xml/html language blocks qualify; fenced is tracked as metadata but
|
|
105
|
+
* does not gate eligibility — caller controls whether XML detection runs.
|
|
65
106
|
*/
|
|
66
107
|
export declare function canRenderStructuredMarkup(block: CodeBlock): boolean;
|
|
67
|
-
/**
|
|
68
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Parse markdown into renderable code blocks while preserving plain text blocks.
|
|
110
|
+
*
|
|
111
|
+
* `outputOnly` (default `false`): when `true`, prose sections use
|
|
112
|
+
* `detectOutputLanguage` (json or markdown only — no xml/html heuristics).
|
|
113
|
+
* Use `outputOnly: true` for LLM-generated text (assistant messages) to
|
|
114
|
+
* prevent Slack autolinks and HTML snippets from triggering the XML tree
|
|
115
|
+
* renderer. Leave `false` (default) for user/system messages that may
|
|
116
|
+
* contain genuine XML runtime context.
|
|
117
|
+
*/
|
|
118
|
+
export declare function parseMarkdownBlocks(text: string, opts?: {
|
|
119
|
+
outputOnly?: boolean;
|
|
120
|
+
}): CodeBlock[];
|
|
69
121
|
/** Parse XML/HTML-ish fragments for the collapsible transcript renderer. */
|
|
70
122
|
export declare function parseMarkupNodes(code: string, language: BundledLanguage): MarkupNode[];
|
|
71
123
|
/** Group recent turn summaries into conversation rows. */
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type ToolInvocationRef = {
|
|
2
|
+
id?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
};
|
|
5
|
+
/** Match tool call/result refs without inferring relationships from missing metadata. */
|
|
6
|
+
export declare function sameToolInvocation(left: ToolInvocationRef, right: ToolInvocationRef): boolean;
|
|
7
|
+
export {};
|
package/dist/client/types.d.ts
CHANGED
|
@@ -1,117 +1,34 @@
|
|
|
1
1
|
import type { BundledLanguage } from "shiki/bundle/web";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
15
|
-
export type Plugin = {
|
|
16
|
-
name: string;
|
|
17
|
-
};
|
|
18
|
-
export type Skill = {
|
|
19
|
-
name: string;
|
|
20
|
-
pluginProvider?: string;
|
|
21
|
-
};
|
|
22
|
-
export type RequesterIdentity = {
|
|
23
|
-
email?: string;
|
|
24
|
-
fullName?: string;
|
|
25
|
-
slackUserId?: string;
|
|
26
|
-
slackUserName?: string;
|
|
27
|
-
};
|
|
28
|
-
export type TurnUsage = {
|
|
29
|
-
cachedInputTokens?: number;
|
|
30
|
-
cacheCreationTokens?: number;
|
|
31
|
-
inputTokens?: number;
|
|
32
|
-
outputTokens?: number;
|
|
33
|
-
totalTokens?: number;
|
|
34
|
-
};
|
|
35
|
-
export type Session = {
|
|
36
|
-
channel?: string;
|
|
37
|
-
channelName?: string;
|
|
38
|
-
conversationId?: string;
|
|
39
|
-
conversationTitle?: string;
|
|
40
|
-
cumulativeDurationMs?: number;
|
|
41
|
-
cumulativeUsage?: TurnUsage;
|
|
42
|
-
id: string;
|
|
43
|
-
lastProgressAt?: string;
|
|
44
|
-
lastSeenAt?: string;
|
|
45
|
-
requester?: string;
|
|
46
|
-
requesterIdentity?: RequesterIdentity;
|
|
47
|
-
sentryConversationUrl?: string;
|
|
48
|
-
sentryTraceUrl?: string;
|
|
49
|
-
startedAt?: string;
|
|
50
|
-
status: string;
|
|
51
|
-
surface?: string;
|
|
52
|
-
title?: string;
|
|
53
|
-
traceId?: string;
|
|
54
|
-
};
|
|
55
|
-
export type TranscriptPart = {
|
|
56
|
-
bytes?: number;
|
|
57
|
-
chars?: number;
|
|
58
|
-
id?: string;
|
|
59
|
-
input?: unknown;
|
|
60
|
-
inputKeys?: string[];
|
|
61
|
-
inputSizeBytes?: number;
|
|
62
|
-
inputSizeChars?: number;
|
|
63
|
-
inputType?: string;
|
|
64
|
-
name?: string;
|
|
65
|
-
output?: unknown;
|
|
66
|
-
outputKeys?: string[];
|
|
67
|
-
outputSizeBytes?: number;
|
|
68
|
-
outputSizeChars?: number;
|
|
69
|
-
outputType?: string;
|
|
70
|
-
redacted?: boolean;
|
|
71
|
-
text?: string;
|
|
72
|
-
type: string;
|
|
73
|
-
};
|
|
74
|
-
export type TranscriptMessage = {
|
|
75
|
-
parts: TranscriptPart[];
|
|
76
|
-
role: string;
|
|
77
|
-
timestamp?: number;
|
|
78
|
-
};
|
|
79
|
-
export type ConversationTurn = Session & {
|
|
80
|
-
transcript: TranscriptMessage[];
|
|
81
|
-
transcriptAvailable: boolean;
|
|
82
|
-
transcriptMetadata?: TranscriptMessage[];
|
|
83
|
-
transcriptMessageCount?: number;
|
|
84
|
-
transcriptRedacted?: boolean;
|
|
85
|
-
transcriptRedactionReason?: "non_public_conversation";
|
|
86
|
-
};
|
|
87
|
-
export type ConversationDetailFeed = {
|
|
88
|
-
conversationId: string;
|
|
89
|
-
generatedAt: string;
|
|
90
|
-
turns: ConversationTurn[];
|
|
91
|
-
};
|
|
2
|
+
import type { DashboardConversationReport, DashboardRequesterIdentity, DashboardSessionFeed, DashboardSessionReport, DashboardTurnReport, DashboardTurnUsage, HealthReport, PluginReport, RuntimeInfoReport, SkillReport } from "@sentry/junior/reporting";
|
|
3
|
+
export type Health = HealthReport;
|
|
4
|
+
export type Runtime = RuntimeInfoReport;
|
|
5
|
+
export type Plugin = PluginReport;
|
|
6
|
+
export type Skill = SkillReport;
|
|
7
|
+
export type RequesterIdentity = DashboardRequesterIdentity;
|
|
8
|
+
export type TurnUsage = DashboardTurnUsage;
|
|
9
|
+
export type Session = DashboardSessionReport;
|
|
10
|
+
export type TranscriptPart = DashboardTurnReport["transcript"][number]["parts"][number];
|
|
11
|
+
export type TranscriptMessage = DashboardTurnReport["transcript"][number];
|
|
12
|
+
export type ConversationTurn = DashboardTurnReport;
|
|
13
|
+
export type ConversationDetailFeed = DashboardConversationReport;
|
|
92
14
|
export type Conversation = {
|
|
93
15
|
channel?: string;
|
|
94
16
|
channelName?: string;
|
|
95
17
|
conversationTitle?: string;
|
|
96
18
|
id: string;
|
|
97
|
-
lastProgressAt
|
|
98
|
-
lastSeenAt
|
|
99
|
-
requester?: string;
|
|
19
|
+
lastProgressAt: string;
|
|
20
|
+
lastSeenAt: string;
|
|
100
21
|
requesterIdentity?: RequesterIdentity;
|
|
101
22
|
sentryConversationUrl?: string;
|
|
102
23
|
sentryTraceUrl?: string;
|
|
103
|
-
startedAt
|
|
24
|
+
startedAt: string;
|
|
104
25
|
status: Session["status"];
|
|
105
|
-
surface
|
|
26
|
+
surface: Session["surface"];
|
|
106
27
|
title: string;
|
|
107
28
|
traceId?: string;
|
|
108
29
|
turns: Session[];
|
|
109
30
|
};
|
|
110
|
-
export type SessionFeed =
|
|
111
|
-
generatedAt?: string;
|
|
112
|
-
sessions: Session[];
|
|
113
|
-
source: string;
|
|
114
|
-
};
|
|
31
|
+
export type SessionFeed = DashboardSessionFeed;
|
|
115
32
|
export type Identity = {
|
|
116
33
|
user: {
|
|
117
34
|
email?: string;
|