@tonyclaw/agent-inspector 2.1.15 → 2.1.16
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/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-BcEd6V-V.js → CompareDrawer-Ccrrcx1j.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-DLqClc9A.js +106 -0
- package/.output/public/assets/{ReplayDialog-BNpC0548.js → ReplayDialog-C7axhr-l.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-Ds1uRLVB.js → RequestAnatomy-WOptg8j_.js} +1 -1
- package/.output/public/assets/{ResponseView-7KPVqKl5.js → ResponseView-CSAcxh_M.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-BHQT261s.js → StreamingChunkSequence-DJS5KhPx.js} +1 -1
- package/.output/public/assets/_sessionId-DUSalzKH.js +1 -0
- package/.output/public/assets/index-BPpA21dY.css +1 -0
- package/.output/public/assets/index-Bt0Az2I2.js +1 -0
- package/.output/public/assets/{index-DjKt8XKe.js → index-DMPNh46t.js} +1 -1
- package/.output/public/assets/{json-viewer-CkCu-rka.js → json-viewer-inX5QSa3.js} +1 -1
- package/.output/public/assets/{main-DpD1N0S8.js → main-aCAKYGSD.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +207 -171
- package/.output/server/{_sessionId-DF9Sy8cP.mjs → _sessionId-C0fhvQnn.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-BoxztaO7.mjs → CompareDrawer-CO-Ti5sg.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-CRBkqFlJ.mjs → ProxyViewerContainer-N4J7uBCX.mjs} +807 -386
- package/.output/server/_ssr/{ReplayDialog-Cc1dyDuK.mjs → ReplayDialog-J1VxC0In.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-CMGSsz5Z.mjs → RequestAnatomy-DBH-F3rq.mjs} +3 -3
- package/.output/server/_ssr/{ResponseView-Cp10DM1D.mjs → ResponseView-DLFwV7Hd.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-B1VGxy3A.mjs → StreamingChunkSequence-BywmuND0.mjs} +3 -3
- package/.output/server/_ssr/{index-47XVPghS.mjs → index-CStymIc0.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-zDE2rrmJ.mjs → json-viewer-DlQu0N1x.mjs} +3 -3
- package/.output/server/_ssr/{router-DVeuZFqI.mjs → router-CQ4Zxhmr.mjs} +112 -46
- package/.output/server/{_tanstack-start-manifest_v-Bp8JxtPW.mjs → _tanstack-start-manifest_v-BHeJBGfo.mjs} +1 -1
- package/.output/server/index.mjs +72 -72
- package/package.json +1 -1
- package/src/components/ProxyViewer.tsx +146 -105
- package/src/components/ProxyViewerContainer.tsx +77 -67
- package/src/components/alerts/AlertsDialog.tsx +2 -1
- package/src/components/clients/ClientLogo.tsx +1 -1
- package/src/components/groups/GroupsDialog.tsx +19 -1
- package/src/components/providers/ProviderCard.tsx +1 -1
- package/src/components/providers/ProviderForm.tsx +18 -18
- package/src/components/providers/ProviderLogo.tsx +6 -1
- package/src/components/providers/ProvidersPanel.tsx +6 -6
- package/src/components/providers/SettingsDialog.tsx +13 -6
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +6 -6
- package/src/components/proxy-viewer/ConversationGroup.tsx +43 -32
- package/src/components/proxy-viewer/ConversationGroupList.tsx +452 -89
- package/src/components/proxy-viewer/ConversationHeader.tsx +44 -32
- package/src/components/proxy-viewer/LogEntry.tsx +21 -17
- package/src/components/proxy-viewer/LogEntryHeader.tsx +38 -45
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +2 -2
- package/src/components/proxy-viewer/RequestToolsPanel.tsx +9 -9
- package/src/components/proxy-viewer/ThreadConnector.tsx +4 -4
- package/src/components/proxy-viewer/TurnGroup.tsx +16 -11
- package/src/components/proxy-viewer/TurnGroupList.tsx +3 -0
- package/src/components/proxy-viewer/viewerState.ts +0 -4
- package/src/components/ui/icon-trigger.ts +2 -0
- package/src/components/ui/transient-toast.tsx +104 -0
- package/src/lib/sessionInfoContract.ts +4 -0
- package/src/mcp/server.ts +71 -27
- package/src/mcp/toolHandlers.ts +23 -4
- package/src/proxy/formats/openai/alibabaProvider.ts +0 -4
- package/src/proxy/sessionInfo.ts +31 -2
- package/src/proxy/sessionSupervisor.ts +20 -1
- package/src/proxy/store.ts +1 -1
- package/src/routes/api/providers.$providerId.test.log.ts +8 -4
- package/styles/globals.css +180 -180
- package/.output/public/assets/ProxyViewerContainer-h851qWNp.js +0 -106
- package/.output/public/assets/_sessionId-DWePGjnS.js +0 -1
- package/.output/public/assets/index-CI1-G8ua.js +0 -1
- package/.output/public/assets/index-DdhFqPsI.css +0 -1
package/.output/server/_ssr/{ProxyViewerContainer-CRBkqFlJ.mjs → ProxyViewerContainer-N4J7uBCX.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
|
|
2
|
-
import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as GroupEvidenceExportResultSchema, o as DeleteInspectorGroupResponseSchema, v as createPendingProviderTestResults, w as ProviderTestResultsSchema, x as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, y as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema,
|
|
2
|
+
import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as GroupEvidenceExportResultSchema, o as DeleteInspectorGroupResponseSchema, v as createPendingProviderTestResults, w as ProviderTestResultsSchema, x as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, y as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, t as maskApiKey, q as providerHasContextMetadata, r as findProviderModelMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, z as resolveProviderContextWindow, j as getSessionPath, u as buildUpstreamUrl, K as KnowledgeCandidateSchema, B as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-CQ4Zxhmr.mjs";
|
|
3
3
|
import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
|
|
4
4
|
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
5
5
|
import { c as clsx } from "../_libs/clsx.mjs";
|
|
@@ -9,7 +9,7 @@ import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
|
9
9
|
import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
10
10
|
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
11
11
|
import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
|
|
12
|
-
import { I as Info,
|
|
12
|
+
import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, U as Upload, D as Download, F as FileBraces, c as Trash2, P as Plus, A as ArrowLeft, d as ChevronUp, e as Copy, f as ChevronsLeft, g as ChevronLeft, h as ChevronRight, i as ChevronsRight, j as Clapperboard, S as Siren, G as Gauge, L as LoaderCircle, R as RefreshCw, k as Layers, l as Settings, M as Monitor, m as Scan, n as CircleAlert, o as Terminal, p as ArrowUpRight, q as ArrowDownRight, r as Cpu, s as FolderOpen, B as Bell, t as Clock3, u as ShieldAlert, E as EyeOff, v as Eye, w as ExternalLink, x as RotateCw, y as Clock, z as Pencil, H as MessageSquare, Z as Zap, W as Wrench, J as Brain, K as Minus, N as CircleCheckBig, O as CircleQuestionMark, Q as Server, V as Lock, Y as Wifi, _ as WifiOff, $ as CircleX, a0 as ShieldCheck, a1 as Save, a2 as FileSearch, a3 as CloudUpload, a4 as OctagonAlert, a5 as Radio, a6 as Globe, a7 as FileTerminal, a8 as ChevronsUp, a9 as ChevronsDown, aa as FileDiff, ab as History, ac as RotateCcw, ad as Search, ae as GitCompareArrows, af as ArrowUp, ag as ArrowDown, ah as Ellipsis, ai as CodeXml, aj as Blocks, ak as MousePointerClick, al as FileText, am as Rows3, an as Columns2 } from "../_libs/lucide-react.mjs";
|
|
13
13
|
import { u as union, d as object, a as array, l as literal, b as string, n as number, c as boolean, _ as _enum } from "../_libs/zod.mjs";
|
|
14
14
|
import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
|
|
15
15
|
import { R as Root2$1, L as List, T as Trigger$2, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
|
|
@@ -862,7 +862,7 @@ function ClientLogo({
|
|
|
862
862
|
"span",
|
|
863
863
|
{
|
|
864
864
|
className: cn(
|
|
865
|
-
"inline-flex size-6 shrink-0 items-center justify-center rounded-md
|
|
865
|
+
"border border-border bg-muted/40 inline-flex size-6 shrink-0 items-center justify-center rounded-md p-1 text-cyan-100",
|
|
866
866
|
className
|
|
867
867
|
),
|
|
868
868
|
"aria-label": label,
|
|
@@ -890,12 +890,16 @@ const PROVIDER_MAP = {
|
|
|
890
890
|
"o3-": "openai",
|
|
891
891
|
"deepseek-": "deepseek",
|
|
892
892
|
MiniMax: "minimax",
|
|
893
|
-
qwen: "qwen"
|
|
894
|
-
"glm-": "zhipuai"
|
|
893
|
+
qwen: "qwen"
|
|
895
894
|
};
|
|
895
|
+
function isGlmModel(modelLower) {
|
|
896
|
+
const normalized = modelLower.replace(/[_\s]+/g, "-");
|
|
897
|
+
return normalized.split(/[/:@]/).some((segment2) => segment2.startsWith("glm-"));
|
|
898
|
+
}
|
|
896
899
|
function detectProvider(model) {
|
|
897
900
|
if (model === null) return "unknown";
|
|
898
901
|
const modelLower = model.toLowerCase();
|
|
902
|
+
if (isGlmModel(modelLower)) return "zhipuai";
|
|
899
903
|
for (const [prefix, provider] of Object.entries(PROVIDER_MAP)) {
|
|
900
904
|
if (modelLower.startsWith(prefix.toLowerCase())) {
|
|
901
905
|
return provider;
|
|
@@ -1016,7 +1020,7 @@ function ProviderLogoStack({
|
|
|
1016
1020
|
"span",
|
|
1017
1021
|
{
|
|
1018
1022
|
className: cn(
|
|
1019
|
-
"inline-flex size-6 shrink-0 items-center justify-center rounded-md
|
|
1023
|
+
"border border-border bg-muted/40 inline-flex size-6 shrink-0 items-center justify-center rounded-md",
|
|
1020
1024
|
index > 0 && "-ml-2"
|
|
1021
1025
|
),
|
|
1022
1026
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: item.provider, className: "size-4" })
|
|
@@ -1024,7 +1028,7 @@ function ProviderLogoStack({
|
|
|
1024
1028
|
) }),
|
|
1025
1029
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: item.tooltip })
|
|
1026
1030
|
] }, `${item.provider}-${String(index)}`)),
|
|
1027
|
-
overflowCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "-ml-2 inline-flex h-6 min-w-6 shrink-0 items-center justify-center rounded-md
|
|
1031
|
+
overflowCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "border border-border bg-muted/40 -ml-2 inline-flex h-6 min-w-6 shrink-0 items-center justify-center rounded-md px-1 font-mono text-[10px] text-muted-foreground", children: [
|
|
1028
1032
|
"+",
|
|
1029
1033
|
overflowCount
|
|
1030
1034
|
] })
|
|
@@ -1420,6 +1424,8 @@ function ConversationHeader({
|
|
|
1420
1424
|
userAgent,
|
|
1421
1425
|
clientPid,
|
|
1422
1426
|
clientProjectFolder,
|
|
1427
|
+
showClientIdentity = true,
|
|
1428
|
+
showProcessMetadata = true,
|
|
1423
1429
|
timeDisplayFormat,
|
|
1424
1430
|
onClear
|
|
1425
1431
|
}) {
|
|
@@ -1445,6 +1451,8 @@ function ConversationHeader({
|
|
|
1445
1451
|
const hasUserAgent = userAgent !== null && userAgent !== void 0 && userAgent !== "";
|
|
1446
1452
|
const clientDisplayLabel = detectedClientLabel ?? userAgent ?? null;
|
|
1447
1453
|
const clientTooltip = detectedClientLabel !== null && hasUserAgent ? `${detectedClientLabel} - ${userAgent}` : null;
|
|
1454
|
+
const isFallbackConversation = conversationId.startsWith("PID:") || conversationId.includes("|");
|
|
1455
|
+
const compactSessionLabel = conversationId.length > 24 ? conversationId.slice(0, 12) + "..." + conversationId.slice(-12) : conversationId;
|
|
1448
1456
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1449
1457
|
"div",
|
|
1450
1458
|
{
|
|
@@ -1453,10 +1461,10 @@ function ConversationHeader({
|
|
|
1453
1461
|
"data-nav-id": `conv-${conversationId}`,
|
|
1454
1462
|
"data-nav-action": expanded ? "collapse" : "expand",
|
|
1455
1463
|
className: cn(
|
|
1456
|
-
"flex items-center gap-3 px-3 py-2
|
|
1457
|
-
"hover:
|
|
1464
|
+
"border border-border bg-card shadow-sm flex cursor-pointer items-center gap-3 rounded-[8px] px-3 py-2 transition-colors",
|
|
1465
|
+
"hover:border-cyan-200/20",
|
|
1458
1466
|
"select-none",
|
|
1459
|
-
"
|
|
1467
|
+
"sticky top-0 z-10 mb-2",
|
|
1460
1468
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
1461
1469
|
),
|
|
1462
1470
|
onClick: onToggle,
|
|
@@ -1469,19 +1477,18 @@ function ConversationHeader({
|
|
|
1469
1477
|
},
|
|
1470
1478
|
children: [
|
|
1471
1479
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogoStack, { items: providerLogoItems, ariaLabel: "Models used in this session" }),
|
|
1472
|
-
|
|
1473
|
-
conversationId.startsWith("PID:") || conversationId.includes("|") ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
1480
|
+
isFallbackConversation && showProcessMetadata ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
1474
1481
|
clientPid !== null && clientPid !== void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1475
1482
|
"span",
|
|
1476
1483
|
{
|
|
1477
|
-
className: "
|
|
1484
|
+
className: "shrink-0 font-mono text-xs font-semibold text-violet-200",
|
|
1478
1485
|
title: `PID ${clientPid}`,
|
|
1479
1486
|
children: [
|
|
1480
1487
|
"PID ",
|
|
1481
1488
|
clientPid
|
|
1482
1489
|
]
|
|
1483
1490
|
}
|
|
1484
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "
|
|
1491
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 font-mono text-xs font-semibold text-violet-200", children: conversationId }),
|
|
1485
1492
|
clientProjectFolder !== null && clientProjectFolder !== void 0 && clientProjectFolder !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1486
1493
|
"span",
|
|
1487
1494
|
{
|
|
@@ -1494,15 +1501,15 @@ function ConversationHeader({
|
|
|
1494
1501
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1495
1502
|
"span",
|
|
1496
1503
|
{
|
|
1497
|
-
className: "
|
|
1504
|
+
className: "shrink-0 font-mono text-xs font-semibold text-violet-200",
|
|
1498
1505
|
title: conversationId,
|
|
1499
|
-
children:
|
|
1506
|
+
children: isFallbackConversation ? "sessionless" : compactSessionLabel
|
|
1500
1507
|
}
|
|
1501
1508
|
),
|
|
1502
|
-
clientPid !== null && clientPid !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1509
|
+
showProcessMetadata && clientPid !== null && clientPid !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1503
1510
|
"span",
|
|
1504
1511
|
{
|
|
1505
|
-
className: "
|
|
1512
|
+
className: "border border-border bg-muted/40 shrink-0 rounded px-1.5 py-0.5 font-mono text-xs tabular-nums text-muted-foreground",
|
|
1506
1513
|
title: `Client process ID ${clientPid}`,
|
|
1507
1514
|
children: [
|
|
1508
1515
|
"PID ",
|
|
@@ -1511,7 +1518,7 @@ function ConversationHeader({
|
|
|
1511
1518
|
}
|
|
1512
1519
|
)
|
|
1513
1520
|
] }),
|
|
1514
|
-
clientDisplayLabel !== null && clientDisplayLabel !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1521
|
+
showClientIdentity && clientDisplayLabel !== null && clientDisplayLabel !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1515
1522
|
"span",
|
|
1516
1523
|
{
|
|
1517
1524
|
className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0",
|
|
@@ -1555,7 +1562,7 @@ function ConversationHeader({
|
|
|
1555
1562
|
},
|
|
1556
1563
|
"aria-label": `Open session ${conversationId} in a new tab`,
|
|
1557
1564
|
title: "Open this session in a new tab",
|
|
1558
|
-
className: "
|
|
1565
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
|
|
1559
1566
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3.5" })
|
|
1560
1567
|
}
|
|
1561
1568
|
),
|
|
@@ -1566,10 +1573,18 @@ function ConversationHeader({
|
|
|
1566
1573
|
onClick: handleClearClick,
|
|
1567
1574
|
"aria-label": `Clear group (${totalCalls} request${totalCalls !== 1 ? "s" : ""})`,
|
|
1568
1575
|
title: "Clear this group",
|
|
1569
|
-
className: "
|
|
1576
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
|
|
1570
1577
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" })
|
|
1571
1578
|
}
|
|
1572
1579
|
),
|
|
1580
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1581
|
+
"span",
|
|
1582
|
+
{
|
|
1583
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-slate-200",
|
|
1584
|
+
"aria-hidden": "true",
|
|
1585
|
+
children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 shrink-0" }) : isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" })
|
|
1586
|
+
}
|
|
1587
|
+
),
|
|
1573
1588
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1574
1589
|
ConfirmDialog,
|
|
1575
1590
|
{
|
|
@@ -1589,10 +1604,10 @@ function ConversationHeader({
|
|
|
1589
1604
|
);
|
|
1590
1605
|
}
|
|
1591
1606
|
function getConversationId(log) {
|
|
1592
|
-
if (log.isTest === true) return "provider-test";
|
|
1593
1607
|
if (log.sessionId !== null && log.sessionId !== "" && log.sessionId !== void 0) {
|
|
1594
1608
|
return log.sessionId;
|
|
1595
1609
|
}
|
|
1610
|
+
if (log.isTest === true) return "provider-test";
|
|
1596
1611
|
const hasPid = log.clientPid !== null && log.clientPid !== void 0;
|
|
1597
1612
|
const hasFolder = log.clientProjectFolder !== null && log.clientProjectFolder !== void 0;
|
|
1598
1613
|
if (!hasPid && !hasFolder) return "default";
|
|
@@ -2269,27 +2284,27 @@ function useCopyFeedback(text) {
|
|
|
2269
2284
|
return { copied, copy };
|
|
2270
2285
|
}
|
|
2271
2286
|
const LazyCompareDrawer = reactExports.lazy(
|
|
2272
|
-
() => import("./CompareDrawer-
|
|
2287
|
+
() => import("./CompareDrawer-CO-Ti5sg.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
2273
2288
|
);
|
|
2274
2289
|
const LazyReplayDialog = reactExports.lazy(
|
|
2275
|
-
() => import("./ReplayDialog-
|
|
2290
|
+
() => import("./ReplayDialog-J1VxC0In.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
2276
2291
|
);
|
|
2277
2292
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
2278
|
-
() => import("./RequestAnatomy-
|
|
2293
|
+
() => import("./RequestAnatomy-DBH-F3rq.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
2279
2294
|
);
|
|
2280
2295
|
const LazyResponseView = reactExports.lazy(
|
|
2281
|
-
() => import("./ResponseView-
|
|
2296
|
+
() => import("./ResponseView-DLFwV7Hd.mjs").then((m) => ({ default: m.ResponseView }))
|
|
2282
2297
|
);
|
|
2283
2298
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
2284
|
-
() => import("./StreamingChunkSequence-
|
|
2299
|
+
() => import("./StreamingChunkSequence-BywmuND0.mjs").then((m) => ({
|
|
2285
2300
|
default: m.StreamingChunkSequence
|
|
2286
2301
|
}))
|
|
2287
2302
|
);
|
|
2288
2303
|
const LazyJsonViewer = reactExports.lazy(
|
|
2289
|
-
() => import("./json-viewer-
|
|
2304
|
+
() => import("./json-viewer-DlQu0N1x.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
2290
2305
|
);
|
|
2291
2306
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
2292
|
-
() => import("./json-viewer-
|
|
2307
|
+
() => import("./json-viewer-DlQu0N1x.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
2293
2308
|
);
|
|
2294
2309
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
2295
2310
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -2713,35 +2728,31 @@ function Badge({
|
|
|
2713
2728
|
);
|
|
2714
2729
|
}
|
|
2715
2730
|
const STATUS_BADGE_CLASSES = {
|
|
2716
|
-
success: "bg-
|
|
2731
|
+
success: "bg-slate-300/[0.08] text-slate-100 border-slate-300/20",
|
|
2717
2732
|
client_error: "bg-amber-300/[0.10] text-amber-100 border-amber-300/30",
|
|
2718
2733
|
server_error: "bg-rose-400/[0.10] text-rose-100 border-rose-300/30",
|
|
2719
2734
|
pending: "bg-cyan-300/[0.08] text-cyan-100 border-cyan-300/25"
|
|
2720
2735
|
};
|
|
2721
2736
|
const STATUS_CUE_CLASSES = {
|
|
2722
2737
|
success: {
|
|
2723
|
-
frame: "border-
|
|
2724
|
-
dot: "bg-
|
|
2725
|
-
rail: "bg-emerald-300/45 shadow-[0_0_22px_rgba(110,231,183,0.28)]"
|
|
2738
|
+
frame: "border-cyan-200/15 bg-white/[0.04] text-slate-100",
|
|
2739
|
+
dot: "bg-cyan-200/80 shadow-[0_0_14px_rgba(125,211,252,0.65)]"
|
|
2726
2740
|
},
|
|
2727
2741
|
client_error: {
|
|
2728
2742
|
frame: "border-amber-300/25 bg-amber-300/[0.08] text-amber-100",
|
|
2729
|
-
dot: "bg-amber-200 shadow-[0_0_14px_rgba(252,211,77,0.8)]"
|
|
2730
|
-
rail: "bg-amber-300/50 shadow-[0_0_22px_rgba(252,211,77,0.28)]"
|
|
2743
|
+
dot: "bg-amber-200 shadow-[0_0_14px_rgba(252,211,77,0.8)]"
|
|
2731
2744
|
},
|
|
2732
2745
|
server_error: {
|
|
2733
2746
|
frame: "border-rose-300/25 bg-rose-300/[0.08] text-rose-100",
|
|
2734
|
-
dot: "bg-rose-300 shadow-[0_0_14px_rgba(253,164,175,0.8)]"
|
|
2735
|
-
rail: "bg-rose-300/50 shadow-[0_0_22px_rgba(253,164,175,0.28)]"
|
|
2747
|
+
dot: "bg-rose-300 shadow-[0_0_14px_rgba(253,164,175,0.8)]"
|
|
2736
2748
|
},
|
|
2737
2749
|
pending: {
|
|
2738
2750
|
frame: "border-cyan-300/25 bg-cyan-300/[0.08] text-cyan-100",
|
|
2739
|
-
dot: "bg-cyan-200 shadow-[0_0_14px_rgba(103,232,249,0.8)]"
|
|
2740
|
-
rail: "bg-cyan-300/50 shadow-[0_0_22px_rgba(103,232,249,0.28)]"
|
|
2751
|
+
dot: "bg-cyan-200 shadow-[0_0_14px_rgba(103,232,249,0.8)]"
|
|
2741
2752
|
}
|
|
2742
2753
|
};
|
|
2743
|
-
const HEADER_ACTION_BUTTON_CLASS = "
|
|
2744
|
-
const TELEMETRY_CHIP_CLASS = "flex h-7 items-center gap-1 rounded-md
|
|
2754
|
+
const HEADER_ACTION_BUTTON_CLASS = "border border-input bg-background hover:bg-accent hover:text-accent-foreground size-8 text-muted-foreground shadow-none hover:text-cyan-100";
|
|
2755
|
+
const TELEMETRY_CHIP_CLASS = "border border-border bg-muted/40 flex h-7 items-center gap-1 rounded-md px-2 text-xs";
|
|
2745
2756
|
function formatElapsed$3(ms) {
|
|
2746
2757
|
if (ms < 1e3) return `${ms}ms`;
|
|
2747
2758
|
return `${(ms / 1e3).toFixed(1)}s`;
|
|
@@ -2768,7 +2779,7 @@ function CacheTrendIndicator({ trend }) {
|
|
|
2768
2779
|
const Icon2 = isUp ? ArrowUp : ArrowDown;
|
|
2769
2780
|
const sign = isUp ? "+" : "-";
|
|
2770
2781
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-0.5 text-muted-foreground tabular-nums", children: [
|
|
2771
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: isUp ? "size-3 text-
|
|
2782
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: isUp ? "size-3 text-cyan-300" : "size-3 text-rose-400" }),
|
|
2772
2783
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
|
|
2773
2784
|
sign,
|
|
2774
2785
|
formatTokens(trend.delta)
|
|
@@ -2787,6 +2798,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2787
2798
|
tabActions,
|
|
2788
2799
|
onReplay,
|
|
2789
2800
|
slowResponseThresholdSeconds = 0,
|
|
2801
|
+
showClientMetadata = true,
|
|
2790
2802
|
timeDisplayFormat
|
|
2791
2803
|
}) {
|
|
2792
2804
|
const statusCategory = getStatusCategory(log.responseStatus);
|
|
@@ -2812,8 +2824,8 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2812
2824
|
"data-nav-action": expanded ? "collapse" : "expand",
|
|
2813
2825
|
className: cn(
|
|
2814
2826
|
"group/header relative isolate flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 overflow-hidden px-3 py-2 cursor-pointer transition-[background-color,border-color,box-shadow]",
|
|
2815
|
-
expanded ? "bg-[
|
|
2816
|
-
"select-none before:pointer-events-none before:absolute before:inset-x-
|
|
2827
|
+
expanded ? "bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.10)]" : "bg-transparent hover:bg-white/[0.035]",
|
|
2828
|
+
"select-none before:pointer-events-none before:absolute before:inset-x-3 before:top-0 before:h-px before:bg-white/12",
|
|
2817
2829
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
2818
2830
|
),
|
|
2819
2831
|
onClick: onToggle,
|
|
@@ -2824,22 +2836,11 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2824
2836
|
}
|
|
2825
2837
|
},
|
|
2826
2838
|
children: [
|
|
2827
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2828
|
-
"span",
|
|
2829
|
-
{
|
|
2830
|
-
className: cn(
|
|
2831
|
-
"absolute left-0 top-2 bottom-2 w-0.5 rounded-r-full transition-colors",
|
|
2832
|
-
statusCue.rail
|
|
2833
|
-
),
|
|
2834
|
-
"aria-hidden": "true"
|
|
2835
|
-
}
|
|
2836
|
-
),
|
|
2837
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: ROW_CHEVRON_SLOT_CLASS, children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" }) }),
|
|
2838
2839
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2839
2840
|
"span",
|
|
2840
2841
|
{
|
|
2841
2842
|
className: cn(
|
|
2842
|
-
"inline-flex h-8 shrink-0 items-center gap-2 rounded-md
|
|
2843
|
+
"border border-border bg-muted/40 inline-flex h-8 shrink-0 items-center gap-2 rounded-md px-2 font-mono",
|
|
2843
2844
|
statusCue.frame
|
|
2844
2845
|
),
|
|
2845
2846
|
children: [
|
|
@@ -2851,7 +2852,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2851
2852
|
]
|
|
2852
2853
|
}
|
|
2853
2854
|
),
|
|
2854
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex h-7 items-center gap-1 rounded-md
|
|
2855
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "border border-border bg-muted/40 flex h-7 shrink-0 items-center gap-1 rounded-md px-2 text-xs text-muted-foreground", children: [
|
|
2855
2856
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
2856
2857
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", title: log.timestamp, children: formatTimestamp$2(log.timestamp, timeDisplayFormat) })
|
|
2857
2858
|
] }),
|
|
@@ -2920,7 +2921,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2920
2921
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Time to first streaming chunk" })
|
|
2921
2922
|
] }),
|
|
2922
2923
|
log.streaming && tokenRateLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2923
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-
|
|
2924
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-cyan-300"), children: [
|
|
2924
2925
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Gauge, { className: "size-3" }),
|
|
2925
2926
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: tokenRateLabel })
|
|
2926
2927
|
] }) }),
|
|
@@ -2938,7 +2939,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2938
2939
|
),
|
|
2939
2940
|
children: [
|
|
2940
2941
|
"IN ",
|
|
2941
|
-
log.inputTokens !== null ? formatTokens(log.inputTokens) : "
|
|
2942
|
+
log.inputTokens !== null ? formatTokens(log.inputTokens) : "n/a"
|
|
2942
2943
|
]
|
|
2943
2944
|
}
|
|
2944
2945
|
),
|
|
@@ -2952,7 +2953,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2952
2953
|
),
|
|
2953
2954
|
children: [
|
|
2954
2955
|
"OUT ",
|
|
2955
|
-
log.outputTokens !== null ? formatTokens(log.outputTokens) : "
|
|
2956
|
+
log.outputTokens !== null ? formatTokens(log.outputTokens) : "n/a"
|
|
2956
2957
|
]
|
|
2957
2958
|
}
|
|
2958
2959
|
)
|
|
@@ -2960,7 +2961,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2960
2961
|
] }),
|
|
2961
2962
|
log.cacheCreationInputTokens !== null && log.cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0"), children: [
|
|
2962
2963
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CacheTrendIndicator, { trend: cacheTrend?.creation ?? null }),
|
|
2963
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-
|
|
2964
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-cyan-300", children: [
|
|
2964
2965
|
"KV Cache +",
|
|
2965
2966
|
formatTokens(log.cacheCreationInputTokens)
|
|
2966
2967
|
] })
|
|
@@ -2991,7 +2992,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2991
2992
|
]
|
|
2992
2993
|
}
|
|
2993
2994
|
),
|
|
2994
|
-
(hasClientPid || hasClientProjectFolder) && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2995
|
+
showClientMetadata && (hasClientPid || hasClientProjectFolder) && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2995
2996
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "hidden shrink-0 text-purple-300 xl:flex"), children: [
|
|
2996
2997
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FileTerminal, { className: "size-3" }),
|
|
2997
2998
|
hasClientProjectFolder ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: log.clientProjectFolder }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
@@ -3074,7 +3075,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
3074
3075
|
className: HEADER_ACTION_BUTTON_CLASS,
|
|
3075
3076
|
onClick: action.onCopy,
|
|
3076
3077
|
"aria-label": action.copyCopied ? "Copied" : action.copyLabel,
|
|
3077
|
-
children: action.copyCopied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5 text-
|
|
3078
|
+
children: action.copyCopied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5 text-cyan-300" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
|
|
3078
3079
|
}
|
|
3079
3080
|
) }),
|
|
3080
3081
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: action.copyCopied ? "Copied to clipboard" : action.copyLabel })
|
|
@@ -3097,6 +3098,14 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
3097
3098
|
] })
|
|
3098
3099
|
]
|
|
3099
3100
|
}
|
|
3101
|
+
),
|
|
3102
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3103
|
+
"span",
|
|
3104
|
+
{
|
|
3105
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-slate-200",
|
|
3106
|
+
"aria-hidden": "true",
|
|
3107
|
+
children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" })
|
|
3108
|
+
}
|
|
3100
3109
|
)
|
|
3101
3110
|
]
|
|
3102
3111
|
}
|
|
@@ -3229,7 +3238,7 @@ function ToolRow({ tool, called }) {
|
|
|
3229
3238
|
const [open, setOpen] = reactExports.useState(false);
|
|
3230
3239
|
const nameCopy = useCopyFeedback(tool.name);
|
|
3231
3240
|
const hasDetails = tool.description !== null || tool.requiredParameters.length > 0 || tool.schema !== null;
|
|
3232
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
3241
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm rounded-[8px]", children: [
|
|
3233
3242
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2 px-2.5 py-2", children: [
|
|
3234
3243
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3235
3244
|
"button",
|
|
@@ -3264,17 +3273,17 @@ function ToolRow({ tool, called }) {
|
|
|
3264
3273
|
"button",
|
|
3265
3274
|
{
|
|
3266
3275
|
type: "button",
|
|
3267
|
-
className: "inline-flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:
|
|
3276
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
3268
3277
|
onClick: nameCopy.copy,
|
|
3269
3278
|
"aria-label": nameCopy.copied ? "Copied tool name" : "Copy tool name",
|
|
3270
3279
|
children: nameCopy.copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5 text-emerald-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
|
|
3271
3280
|
}
|
|
3272
3281
|
)
|
|
3273
3282
|
] }),
|
|
3274
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: open && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-white/[0.
|
|
3283
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: open && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-white/[0.025] px-2.5 py-2", children: [
|
|
3275
3284
|
tool.description !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs leading-relaxed text-muted-foreground", children: tool.description }),
|
|
3276
3285
|
/* @__PURE__ */ jsxRuntimeExports.jsx(RequiredParameters, { names: tool.requiredParameters }),
|
|
3277
|
-
tool.schema !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "max-h-64 rounded-
|
|
3286
|
+
tool.schema !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "border border-border bg-card shadow-sm max-h-64 rounded-[8px] p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3278
3287
|
reactExports.Suspense,
|
|
3279
3288
|
{
|
|
3280
3289
|
fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "Loading JSON..." }),
|
|
@@ -3304,7 +3313,7 @@ const RequestTools = reactExports.memo(function RequestTools2({
|
|
|
3304
3313
|
if (summary === null) return null;
|
|
3305
3314
|
const previewTools = summary.tools.slice(0, 6);
|
|
3306
3315
|
const hiddenPreviewCount = summary.tools.length - previewTools.length;
|
|
3307
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "
|
|
3316
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border border-border bg-card shadow-sm mb-3 overflow-hidden rounded-[8px]", children: [
|
|
3308
3317
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2 px-3 py-2", children: [
|
|
3309
3318
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
3310
3319
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-4 shrink-0 text-sky-300/80" }),
|
|
@@ -3348,7 +3357,7 @@ const RequestTools = reactExports.memo(function RequestTools2({
|
|
|
3348
3357
|
type: "button",
|
|
3349
3358
|
variant: "ghost",
|
|
3350
3359
|
size: "sm",
|
|
3351
|
-
className: "h-7
|
|
3360
|
+
className: "h-7 px-2 text-muted-foreground hover:text-cyan-100",
|
|
3352
3361
|
onClick: () => setExpanded((value) => !value),
|
|
3353
3362
|
"aria-expanded": expanded,
|
|
3354
3363
|
children: [
|
|
@@ -3358,7 +3367,7 @@ const RequestTools = reactExports.memo(function RequestTools2({
|
|
|
3358
3367
|
}
|
|
3359
3368
|
)
|
|
3360
3369
|
] }),
|
|
3361
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap gap-1.5 border-t border-white/10 bg-
|
|
3370
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap gap-1.5 border-t border-white/10 bg-white/[0.025] px-3 py-2", children: [
|
|
3362
3371
|
previewTools.map((tool) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3363
3372
|
Badge,
|
|
3364
3373
|
{
|
|
@@ -3376,8 +3385,8 @@ const RequestTools = reactExports.memo(function RequestTools2({
|
|
|
3376
3385
|
hiddenPreviewCount
|
|
3377
3386
|
] })
|
|
3378
3387
|
] }),
|
|
3379
|
-
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-black/
|
|
3380
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex h-8 items-center gap-2 rounded-md
|
|
3388
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-black/10 px-3 py-3", children: [
|
|
3389
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex h-8 items-center gap-2 rounded-md px-2 text-xs", children: [
|
|
3381
3390
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
3382
3391
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3383
3392
|
"input",
|
|
@@ -3582,7 +3591,7 @@ const FULL_LOG_HYDRATION_TIMEOUT_MS = 15e3;
|
|
|
3582
3591
|
const BODY_CHUNK_TIMEOUT_MS = 15e3;
|
|
3583
3592
|
const BODY_CHUNK_BYTES = 256 * 1024;
|
|
3584
3593
|
const CHUNKED_BODY_THRESHOLD_BYTES = 1024 * 1024;
|
|
3585
|
-
const TAB_TRIGGER_CLASS = "h-9 flex-none rounded-
|
|
3594
|
+
const TAB_TRIGGER_CLASS = "h-9 flex-none rounded-md border border-transparent bg-transparent px-3 text-xs font-semibold text-muted-foreground shadow-none transition-colors hover:border-white/10 hover:bg-white/[0.045] hover:text-foreground data-[state=active]:border-cyan-200/25 data-[state=active]:bg-cyan-300/[0.08] data-[state=active]:text-cyan-100 data-[state=active]:shadow-none";
|
|
3586
3595
|
function createEmptyBodyPreviewState(totalBytes = null) {
|
|
3587
3596
|
return {
|
|
3588
3597
|
status: "idle",
|
|
@@ -3633,7 +3642,7 @@ function ExpandedPanel({
|
|
|
3633
3642
|
"div",
|
|
3634
3643
|
{
|
|
3635
3644
|
className: cn(
|
|
3636
|
-
"inspector-scrollbar mx-3 mb-3 max-h-[72vh] overflow-auto rounded-
|
|
3645
|
+
"border border-border bg-card shadow-sm inspector-scrollbar mx-3 mb-3 max-h-[72vh] overflow-auto rounded-[8px] p-3",
|
|
3637
3646
|
className
|
|
3638
3647
|
),
|
|
3639
3648
|
children
|
|
@@ -3641,10 +3650,10 @@ function ExpandedPanel({
|
|
|
3641
3650
|
);
|
|
3642
3651
|
}
|
|
3643
3652
|
function EmptyState({ children }) {
|
|
3644
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "
|
|
3653
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-muted/40 rounded-md border-dashed px-3 py-5 text-center text-xs italic text-muted-foreground", children });
|
|
3645
3654
|
}
|
|
3646
3655
|
function RawTextBlock({ children }) {
|
|
3647
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "inspector-scrollbar max-h-[64vh] overflow-auto whitespace-pre-wrap break-words rounded-
|
|
3656
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "border border-border bg-card shadow-sm inspector-scrollbar max-h-[64vh] overflow-auto whitespace-pre-wrap break-words rounded-[8px] p-3 font-mono text-xs leading-relaxed text-muted-foreground", children });
|
|
3648
3657
|
}
|
|
3649
3658
|
const NOTICE_TONE_CLASSES = {
|
|
3650
3659
|
loading: "border-cyan-400/25 bg-cyan-400/[0.06] text-cyan-100",
|
|
@@ -3696,7 +3705,7 @@ function BodyPreviewNotice({
|
|
|
3696
3705
|
type: "button",
|
|
3697
3706
|
variant: "outline",
|
|
3698
3707
|
size: "sm",
|
|
3699
|
-
className: "
|
|
3708
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 text-xs text-cyan-100",
|
|
3700
3709
|
onClick: onLoadMore,
|
|
3701
3710
|
children: actionLabel
|
|
3702
3711
|
}
|
|
@@ -3711,12 +3720,12 @@ function HeaderRows({
|
|
|
3711
3720
|
}) {
|
|
3712
3721
|
const entries = headers === void 0 ? [] : Object.entries(headers).sort(([left], [right]) => left.localeCompare(right));
|
|
3713
3722
|
if (entries.length === 0) return /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: emptyLabel });
|
|
3714
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "
|
|
3723
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm overflow-hidden rounded-[8px] font-mono text-xs", children: entries.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3715
3724
|
"div",
|
|
3716
3725
|
{
|
|
3717
|
-
className: "grid min-w-0 grid-cols-[minmax(140px,0.32fr)_minmax(0,1fr)] border-b border-white/
|
|
3726
|
+
className: "grid min-w-0 grid-cols-[minmax(140px,0.32fr)_minmax(0,1fr)] border-b border-white/10 last:border-b-0",
|
|
3718
3727
|
children: [
|
|
3719
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 truncate border-r border-white/
|
|
3728
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 truncate border-r border-white/10 bg-white/[0.035] px-2.5 py-2 font-semibold text-cyan-200", children: key }),
|
|
3720
3729
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 truncate px-2.5 py-2 text-muted-foreground", title: value, children: value })
|
|
3721
3730
|
]
|
|
3722
3731
|
},
|
|
@@ -3735,7 +3744,7 @@ function DiffToggleButton({
|
|
|
3735
3744
|
size: "sm",
|
|
3736
3745
|
className: cn(
|
|
3737
3746
|
"h-8 border-white/10 text-xs shadow-none",
|
|
3738
|
-
active ? "bg-cyan-300 text-black hover:bg-cyan-200" : "
|
|
3747
|
+
active ? "bg-cyan-300 text-black hover:bg-cyan-200" : "border border-input bg-background hover:bg-accent hover:text-accent-foreground text-muted-foreground hover:text-cyan-100"
|
|
3739
3748
|
),
|
|
3740
3749
|
onClick,
|
|
3741
3750
|
"aria-pressed": active,
|
|
@@ -3775,7 +3784,8 @@ const LogEntry = reactExports.memo(function({
|
|
|
3775
3784
|
slowResponseThresholdSeconds,
|
|
3776
3785
|
timeDisplayFormat,
|
|
3777
3786
|
cacheTrend = null,
|
|
3778
|
-
onCompareWithPrevious
|
|
3787
|
+
onCompareWithPrevious,
|
|
3788
|
+
showClientMetadata = true
|
|
3779
3789
|
}) {
|
|
3780
3790
|
const [expanded, setExpanded] = reactExports.useState(false);
|
|
3781
3791
|
const [replayOpen, setReplayOpen] = reactExports.useState(false);
|
|
@@ -4072,8 +4082,8 @@ const LogEntry = reactExports.memo(function({
|
|
|
4072
4082
|
"div",
|
|
4073
4083
|
{
|
|
4074
4084
|
className: cn(
|
|
4075
|
-
"relative mb-2 overflow-hidden rounded-
|
|
4076
|
-
expanded ? "border-cyan-
|
|
4085
|
+
"border border-border bg-card shadow-sm relative mb-2 overflow-hidden rounded-[8px] transition-[background-color,border-color,box-shadow]",
|
|
4086
|
+
expanded ? "border-cyan-200/25 shadow-[0_24px_80px_rgba(0,0,0,0.36),0_0_0_1px_rgba(103,232,249,0.05),inset_0_1px_0_rgba(255,255,255,0.14)]" : "hover:border-cyan-200/18"
|
|
4077
4087
|
),
|
|
4078
4088
|
children: [
|
|
4079
4089
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -4081,7 +4091,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
4081
4091
|
{
|
|
4082
4092
|
className: cn(
|
|
4083
4093
|
"pointer-events-none absolute inset-y-3 left-1 w-px rounded-full",
|
|
4084
|
-
expanded ? "bg-cyan-
|
|
4094
|
+
expanded ? "bg-cyan-200/55 shadow-[0_0_20px_rgba(103,232,249,0.26)]" : "bg-white/12"
|
|
4085
4095
|
),
|
|
4086
4096
|
"aria-hidden": "true"
|
|
4087
4097
|
}
|
|
@@ -4104,6 +4114,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
4104
4114
|
onToggle: handleToggleExpanded,
|
|
4105
4115
|
cacheTrend,
|
|
4106
4116
|
slowResponseThresholdSeconds,
|
|
4117
|
+
showClientMetadata,
|
|
4107
4118
|
timeDisplayFormat,
|
|
4108
4119
|
activeTab,
|
|
4109
4120
|
tabActions,
|
|
@@ -4115,14 +4126,14 @@ const LogEntry = reactExports.memo(function({
|
|
|
4115
4126
|
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4116
4127
|
"div",
|
|
4117
4128
|
{
|
|
4118
|
-
className: "relative border-t border-
|
|
4129
|
+
className: "relative border-t border-white/10 bg-black/[0.18] pt-2",
|
|
4119
4130
|
onClick: (e) => e.stopPropagation(),
|
|
4120
4131
|
onKeyDown: (e) => e.stopPropagation(),
|
|
4121
4132
|
children: [
|
|
4122
4133
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4123
4134
|
"div",
|
|
4124
4135
|
{
|
|
4125
|
-
className: "pointer-events-none absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-
|
|
4136
|
+
className: "pointer-events-none absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-white/[0.05] to-transparent",
|
|
4126
4137
|
"aria-hidden": "true"
|
|
4127
4138
|
}
|
|
4128
4139
|
),
|
|
@@ -4131,7 +4142,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
4131
4142
|
TabsList,
|
|
4132
4143
|
{
|
|
4133
4144
|
variant: "line",
|
|
4134
|
-
className: "inspector-scrollbar relative mx-3 h-auto w-[calc(100%-1.5rem)] justify-start overflow-x-auto rounded-
|
|
4145
|
+
className: "border border-border bg-muted/40 inspector-scrollbar relative mx-3 h-auto w-[calc(100%-1.5rem)] justify-start overflow-x-auto rounded-[8px] p-1",
|
|
4135
4146
|
children: [
|
|
4136
4147
|
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-headers", children: "Raw Headers" }),
|
|
4137
4148
|
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "headers", children: "Headers" }),
|
|
@@ -4366,9 +4377,9 @@ function ThreadConnector({
|
|
|
4366
4377
|
FusedCrab,
|
|
4367
4378
|
{
|
|
4368
4379
|
className: cn(
|
|
4369
|
-
"size-3.5 text-
|
|
4380
|
+
"size-3.5 text-cyan-300/90",
|
|
4370
4381
|
"animate-crab-settle",
|
|
4371
|
-
"drop-shadow-[0_0_4px_rgba(
|
|
4382
|
+
"drop-shadow-[0_0_4px_rgba(103,232,249,0.35)]"
|
|
4372
4383
|
)
|
|
4373
4384
|
}
|
|
4374
4385
|
) }) : isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: boundaryTitle(stopReason), ...interactiveProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -4384,9 +4395,9 @@ function ThreadConnector({
|
|
|
4384
4395
|
Crab,
|
|
4385
4396
|
{
|
|
4386
4397
|
className: cn(
|
|
4387
|
-
"size-3.5 text-
|
|
4398
|
+
"size-3.5 text-cyan-300/85",
|
|
4388
4399
|
"animate-crab-appear",
|
|
4389
|
-
"drop-shadow-[0_0_4px_rgba(
|
|
4400
|
+
"drop-shadow-[0_0_4px_rgba(103,232,249,0.32)]"
|
|
4390
4401
|
)
|
|
4391
4402
|
}
|
|
4392
4403
|
) }) : isRunning ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Processing…", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: cn("size-3.5 text-amber-300/80", "animate-crab-crawl") }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: "size-3.5 text-muted-foreground/40" }) }),
|
|
@@ -4449,9 +4460,6 @@ function responseMayContainToolTrace(log, format) {
|
|
|
4449
4460
|
return false;
|
|
4450
4461
|
}
|
|
4451
4462
|
}
|
|
4452
|
-
function shouldRenderConversationContent(standalone, expanded) {
|
|
4453
|
-
return standalone || expanded;
|
|
4454
|
-
}
|
|
4455
4463
|
function isTurnCollapsible(entryCount, isComplete, isPending) {
|
|
4456
4464
|
return entryCount > 1 && isComplete && !isPending;
|
|
4457
4465
|
}
|
|
@@ -4681,7 +4689,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4681
4689
|
comparisonPredecessors,
|
|
4682
4690
|
turnIndex = 0,
|
|
4683
4691
|
timeDisplayFormat,
|
|
4684
|
-
pendingFocusRequest
|
|
4692
|
+
pendingFocusRequest,
|
|
4693
|
+
showLogClientMetadata = true
|
|
4685
4694
|
}) {
|
|
4686
4695
|
const lastIdx = entries.length - 1;
|
|
4687
4696
|
const lastStop = entries[lastIdx]?.stopReason ?? null;
|
|
@@ -4754,7 +4763,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4754
4763
|
}, [entries, lastIdx]);
|
|
4755
4764
|
const StartCrab = reactExports.useMemo(() => getCrabVariant(entries[0]?.log.id ?? 0), [entries]);
|
|
4756
4765
|
const EndCrab = reactExports.useMemo(() => getCrabVariant(entries[lastIdx]?.log.id ?? 0), [entries, lastIdx]);
|
|
4757
|
-
const bgClass = turnIndex % 2 === 0 ? "bg-[
|
|
4766
|
+
const bgClass = turnIndex % 2 === 0 ? "bg-white/[0.012]" : "bg-cyan-300/[0.012]";
|
|
4758
4767
|
const aggregateIsSlow = aggregate.maxElapsed !== null && slowResponseThresholdSeconds > 0 && aggregate.maxElapsed > slowResponseThresholdSeconds * 1e3;
|
|
4759
4768
|
const toolEventsByLogId = reactExports.useMemo(() => {
|
|
4760
4769
|
const events = /* @__PURE__ */ new Map();
|
|
@@ -4799,7 +4808,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4799
4808
|
"aria-label": collapsed ? void 0 : turnLabel,
|
|
4800
4809
|
"data-nav-id": collapsed ? void 0 : `turn-${String(firstLogId)}`,
|
|
4801
4810
|
className: cn(
|
|
4802
|
-
"
|
|
4811
|
+
"rounded-[8px] border transition-[border-color,box-shadow]",
|
|
4803
4812
|
isPending ? "border-amber-300/15 shadow-[0_0_0_1px_rgba(252,211,77,0.04)]" : "border-transparent",
|
|
4804
4813
|
!collapsed && "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
4805
4814
|
),
|
|
@@ -4829,7 +4838,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4829
4838
|
{
|
|
4830
4839
|
role: "button",
|
|
4831
4840
|
tabIndex: 0,
|
|
4832
|
-
title: "Start of turn
|
|
4841
|
+
title: "Start of turn - click to expand",
|
|
4833
4842
|
className: "cursor-pointer",
|
|
4834
4843
|
onClick: (e) => {
|
|
4835
4844
|
e.stopPropagation();
|
|
@@ -4845,8 +4854,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4845
4854
|
StartCrab,
|
|
4846
4855
|
{
|
|
4847
4856
|
className: cn(
|
|
4848
|
-
"size-3.5 text-
|
|
4849
|
-
"animate-crab-appear drop-shadow-[0_0_4px_rgba(
|
|
4857
|
+
"size-3.5 text-cyan-300/85",
|
|
4858
|
+
"animate-crab-appear drop-shadow-[0_0_4px_rgba(103,232,249,0.32)]"
|
|
4850
4859
|
)
|
|
4851
4860
|
}
|
|
4852
4861
|
)
|
|
@@ -4858,7 +4867,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4858
4867
|
{
|
|
4859
4868
|
role: "button",
|
|
4860
4869
|
tabIndex: 0,
|
|
4861
|
-
title: "End of Turn
|
|
4870
|
+
title: "End of Turn - click to expand",
|
|
4862
4871
|
className: "cursor-pointer",
|
|
4863
4872
|
onClick: (e) => {
|
|
4864
4873
|
e.stopPropagation();
|
|
@@ -4887,6 +4896,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4887
4896
|
{
|
|
4888
4897
|
className: cn(
|
|
4889
4898
|
"flex-1 min-w-0 mb-0.5 rounded-lg border border-cyan-300/10 py-1.5 px-3 flex items-center gap-3 text-xs shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]",
|
|
4899
|
+
"border border-border bg-card shadow-sm",
|
|
4890
4900
|
bgClass
|
|
4891
4901
|
),
|
|
4892
4902
|
children: [
|
|
@@ -4971,7 +4981,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4971
4981
|
onToggle: toggleCollapse
|
|
4972
4982
|
}
|
|
4973
4983
|
),
|
|
4974
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("flex-1 min-w-0 mb-0.5 rounded-
|
|
4984
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("flex-1 min-w-0 mb-0.5 rounded-[8px]", bgClass), children: [
|
|
4975
4985
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4976
4986
|
LogEntry,
|
|
4977
4987
|
{
|
|
@@ -4982,6 +4992,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4982
4992
|
slowResponseThresholdSeconds,
|
|
4983
4993
|
timeDisplayFormat,
|
|
4984
4994
|
cacheTrend: cacheTrends?.get(log.id) ?? null,
|
|
4995
|
+
showClientMetadata: showLogClientMetadata,
|
|
4985
4996
|
onCompareWithPrevious: comparisonPredecessors.has(log.id) ? onCompareWithPrevious : void 0
|
|
4986
4997
|
}
|
|
4987
4998
|
),
|
|
@@ -4995,7 +5006,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4995
5006
|
});
|
|
4996
5007
|
const VIRTUALIZE_TURN_THRESHOLD = 24;
|
|
4997
5008
|
const ESTIMATED_TURN_HEIGHT = 132;
|
|
4998
|
-
const VIRTUAL_OVERSCAN
|
|
5009
|
+
const VIRTUAL_OVERSCAN = 8;
|
|
4999
5010
|
function shouldVirtualizeTurnGroups(turnCount) {
|
|
5000
5011
|
return turnCount > VIRTUALIZE_TURN_THRESHOLD;
|
|
5001
5012
|
}
|
|
@@ -5023,7 +5034,8 @@ function renderTurnGroup(turnGroup, props, pendingFocusRequest) {
|
|
|
5023
5034
|
onCompareWithPrevious: props.onCompareWithPrevious,
|
|
5024
5035
|
comparisonPredecessors: props.comparisonPredecessors,
|
|
5025
5036
|
turnIndex: turnGroup.turnIndex,
|
|
5026
|
-
pendingFocusRequest
|
|
5037
|
+
pendingFocusRequest,
|
|
5038
|
+
showLogClientMetadata: props.showLogClientMetadata
|
|
5027
5039
|
},
|
|
5028
5040
|
turnGroup.turnIndex
|
|
5029
5041
|
);
|
|
@@ -5042,7 +5054,7 @@ function VirtualizedTurnGroupList(props) {
|
|
|
5042
5054
|
const virtualizer = useWindowVirtualizer({
|
|
5043
5055
|
count: turnGroups.length,
|
|
5044
5056
|
estimateSize: () => ESTIMATED_TURN_HEIGHT,
|
|
5045
|
-
overscan: VIRTUAL_OVERSCAN
|
|
5057
|
+
overscan: VIRTUAL_OVERSCAN,
|
|
5046
5058
|
getItemKey: (index) => turnGroups[index]?.turnIndex ?? index
|
|
5047
5059
|
});
|
|
5048
5060
|
const turnIndexByLogId = reactExports.useMemo(() => buildLogTurnIndex(turnGroups), [turnGroups]);
|
|
@@ -5350,7 +5362,7 @@ function CandidateItem({
|
|
|
5350
5362
|
if (saved) setEditing(false);
|
|
5351
5363
|
}, [candidate.id, draftContent, draftTags, draftTitle, draftType, onUpdateCandidate]);
|
|
5352
5364
|
if (editing) {
|
|
5353
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "
|
|
5365
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm rounded-[8px] px-2.5 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2", children: [
|
|
5354
5366
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5355
5367
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5356
5368
|
"select",
|
|
@@ -5363,7 +5375,7 @@ function CandidateItem({
|
|
|
5363
5375
|
);
|
|
5364
5376
|
if (parsed.success) setDraftType(parsed.data);
|
|
5365
5377
|
},
|
|
5366
|
-
className: "
|
|
5378
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
|
|
5367
5379
|
"aria-label": "Candidate type",
|
|
5368
5380
|
children: [
|
|
5369
5381
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "episode", children: "episode" }),
|
|
@@ -5379,7 +5391,7 @@ function CandidateItem({
|
|
|
5379
5391
|
value: draftTitle,
|
|
5380
5392
|
disabled: isUpdating,
|
|
5381
5393
|
onChange: (event) => setDraftTitle(event.currentTarget.value),
|
|
5382
|
-
className: "h-7 min-w-[220px] flex-1 rounded-md
|
|
5394
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 min-w-[220px] flex-1 rounded-md px-2 text-xs",
|
|
5383
5395
|
"aria-label": "Candidate title"
|
|
5384
5396
|
}
|
|
5385
5397
|
)
|
|
@@ -5390,7 +5402,7 @@ function CandidateItem({
|
|
|
5390
5402
|
value: draftContent,
|
|
5391
5403
|
disabled: isUpdating,
|
|
5392
5404
|
onChange: (event) => setDraftContent(event.currentTarget.value),
|
|
5393
|
-
className: "min-h-28 rounded-md
|
|
5405
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground min-h-28 rounded-md px-2 py-1.5 font-mono text-[11px] leading-relaxed",
|
|
5394
5406
|
"aria-label": "Candidate content"
|
|
5395
5407
|
}
|
|
5396
5408
|
),
|
|
@@ -5400,7 +5412,7 @@ function CandidateItem({
|
|
|
5400
5412
|
value: draftTags,
|
|
5401
5413
|
disabled: isUpdating,
|
|
5402
5414
|
onChange: (event) => setDraftTags(event.currentTarget.value),
|
|
5403
|
-
className: "
|
|
5415
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
|
|
5404
5416
|
"aria-label": "Candidate tags"
|
|
5405
5417
|
}
|
|
5406
5418
|
),
|
|
@@ -5734,7 +5746,7 @@ function AgentTraceSummary({
|
|
|
5734
5746
|
[]
|
|
5735
5747
|
);
|
|
5736
5748
|
if (logs.length === 0) return null;
|
|
5737
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "
|
|
5749
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border border-border bg-card shadow-sm mb-2 rounded-[8px] px-3 py-2", children: [
|
|
5738
5750
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2 text-xs", children: [
|
|
5739
5751
|
showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 font-semibold text-foreground", children: [
|
|
5740
5752
|
/* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3.5 text-blue-400" }),
|
|
@@ -5882,13 +5894,15 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
5882
5894
|
onCompareWithPrevious,
|
|
5883
5895
|
comparisonPredecessors,
|
|
5884
5896
|
onClearGroup,
|
|
5885
|
-
|
|
5886
|
-
|
|
5897
|
+
showClientIdentity = true,
|
|
5898
|
+
showProcessMetadata = true,
|
|
5899
|
+
showLogClientMetadata = true,
|
|
5900
|
+
defaultExpanded = false,
|
|
5887
5901
|
timeDisplayFormat,
|
|
5888
5902
|
expanded: controlledExpanded,
|
|
5889
5903
|
onExpandedChange
|
|
5890
5904
|
}) {
|
|
5891
|
-
const [internalExpanded, setInternalExpanded] = reactExports.useState(
|
|
5905
|
+
const [internalExpanded, setInternalExpanded] = reactExports.useState(defaultExpanded);
|
|
5892
5906
|
const expanded = controlledExpanded ?? internalExpanded;
|
|
5893
5907
|
const setExpanded = reactExports.useCallback(
|
|
5894
5908
|
(nextExpanded) => {
|
|
@@ -5900,18 +5914,20 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
5900
5914
|
},
|
|
5901
5915
|
[onExpandedChange]
|
|
5902
5916
|
);
|
|
5917
|
+
reactExports.useEffect(() => {
|
|
5918
|
+
if (!defaultExpanded || controlledExpanded !== void 0) return;
|
|
5919
|
+
setInternalExpanded(true);
|
|
5920
|
+
}, [controlledExpanded, defaultExpanded]);
|
|
5903
5921
|
const stats = reactExports.useMemo(() => computeStats(group.logs), [group.logs]);
|
|
5904
5922
|
const providers = reactExports.useMemo(() => collectProviders(group.logs), [group.logs]);
|
|
5905
5923
|
const startTime = group.logs[0]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
5906
5924
|
const endTime = group.logs[group.logs.length - 1]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
5907
5925
|
const isLoading = group.logs.some((log) => log.responseStatus === null);
|
|
5908
|
-
const showTraceRollupMetrics = standalone && !hasPinnedSessionContext;
|
|
5909
5926
|
const clientPid = reactExports.useMemo(() => getFirstClientPid(group.logs), [group.logs]);
|
|
5910
5927
|
const clientProjectFolder = reactExports.useMemo(() => getFirstClientProjectFolder(group.logs), [group.logs]);
|
|
5911
5928
|
const turnGroups = reactExports.useMemo(() => buildTurnGroups(group.logs), [group.logs]);
|
|
5912
5929
|
reactExports.useEffect(() => {
|
|
5913
5930
|
const handleLogFocusRequest = (event) => {
|
|
5914
|
-
if (standalone) return;
|
|
5915
5931
|
const request = readLogFocusRequest(event);
|
|
5916
5932
|
if (request === null) return;
|
|
5917
5933
|
if (!group.logs.some((log) => log.id === request.logId)) return;
|
|
@@ -5921,9 +5937,9 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
5921
5937
|
return () => {
|
|
5922
5938
|
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
5923
5939
|
};
|
|
5924
|
-
}, [group.logs, setExpanded
|
|
5940
|
+
}, [group.logs, setExpanded]);
|
|
5925
5941
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
|
|
5926
|
-
|
|
5942
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5927
5943
|
ConversationHeader,
|
|
5928
5944
|
{
|
|
5929
5945
|
conversationId: group.conversationId,
|
|
@@ -5939,18 +5955,20 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
5939
5955
|
userAgent: group.logs[0]?.userAgent ?? null,
|
|
5940
5956
|
clientPid,
|
|
5941
5957
|
clientProjectFolder,
|
|
5958
|
+
showClientIdentity,
|
|
5959
|
+
showProcessMetadata,
|
|
5942
5960
|
timeDisplayFormat,
|
|
5943
5961
|
onClear: () => onClearGroup(group.logs.map((l) => l.id))
|
|
5944
5962
|
}
|
|
5945
5963
|
),
|
|
5946
|
-
|
|
5964
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
5947
5965
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5948
5966
|
AgentTraceSummary,
|
|
5949
5967
|
{
|
|
5950
5968
|
logs: group.logs,
|
|
5951
5969
|
scopeId: group.conversationId,
|
|
5952
5970
|
slowResponseThresholdSeconds,
|
|
5953
|
-
showRollupMetrics:
|
|
5971
|
+
showRollupMetrics: false,
|
|
5954
5972
|
timeDisplayFormat
|
|
5955
5973
|
}
|
|
5956
5974
|
),
|
|
@@ -5964,7 +5982,8 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
5964
5982
|
timeDisplayFormat,
|
|
5965
5983
|
cacheTrends,
|
|
5966
5984
|
onCompareWithPrevious,
|
|
5967
|
-
comparisonPredecessors
|
|
5985
|
+
comparisonPredecessors,
|
|
5986
|
+
showLogClientMetadata
|
|
5968
5987
|
}
|
|
5969
5988
|
)
|
|
5970
5989
|
] })
|
|
@@ -6169,6 +6188,7 @@ function useAlertSummary() {
|
|
|
6169
6188
|
mutate: response.mutate
|
|
6170
6189
|
};
|
|
6171
6190
|
}
|
|
6191
|
+
const INSPECTOR_ICON_TRIGGER_CLASS = "relative size-8 rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/50";
|
|
6172
6192
|
const ALERT_CATEGORIES = [
|
|
6173
6193
|
"request-failure",
|
|
6174
6194
|
"request-timeout",
|
|
@@ -6529,7 +6549,7 @@ function AlertsDialog() {
|
|
|
6529
6549
|
type: "button",
|
|
6530
6550
|
variant: "ghost",
|
|
6531
6551
|
size: "icon",
|
|
6532
|
-
className:
|
|
6552
|
+
className: INSPECTOR_ICON_TRIGGER_CLASS,
|
|
6533
6553
|
"aria-label": "Alerts",
|
|
6534
6554
|
title: "Alerts",
|
|
6535
6555
|
children: [
|
|
@@ -6825,6 +6845,12 @@ function firstNonEmpty(...values) {
|
|
|
6825
6845
|
}
|
|
6826
6846
|
return "-";
|
|
6827
6847
|
}
|
|
6848
|
+
function firstOptionalText(...values) {
|
|
6849
|
+
for (const value of values) {
|
|
6850
|
+
if (value !== null && value !== void 0 && value.trim().length > 0) return value;
|
|
6851
|
+
}
|
|
6852
|
+
return null;
|
|
6853
|
+
}
|
|
6828
6854
|
function providerModel(member) {
|
|
6829
6855
|
const provider = member.provider;
|
|
6830
6856
|
const model = member.model;
|
|
@@ -6987,7 +7013,7 @@ function GroupsDialog() {
|
|
|
6987
7013
|
type: "button",
|
|
6988
7014
|
variant: "ghost",
|
|
6989
7015
|
size: "icon",
|
|
6990
|
-
className:
|
|
7016
|
+
className: INSPECTOR_ICON_TRIGGER_CLASS,
|
|
6991
7017
|
"aria-label": "Evaluation groups",
|
|
6992
7018
|
title: "Evaluation groups",
|
|
6993
7019
|
children: [
|
|
@@ -7426,6 +7452,14 @@ function MemberRow({
|
|
|
7426
7452
|
const tokens = session?.tokenUsage.total ?? null;
|
|
7427
7453
|
const firstChunkMs = log?.firstChunkMs ?? null;
|
|
7428
7454
|
const sessionLabel = firstNonEmpty(member.label, member.sessionId);
|
|
7455
|
+
const clientUserAgent = firstOptionalText(session?.clientUserAgent, log?.userAgent, member.agent);
|
|
7456
|
+
const clientProjectFolder = session?.clientProjectFolder ?? null;
|
|
7457
|
+
const clientApp = detectClientApp({
|
|
7458
|
+
userAgent: clientUserAgent,
|
|
7459
|
+
conversationId: member.sessionId,
|
|
7460
|
+
clientProjectFolder
|
|
7461
|
+
});
|
|
7462
|
+
const clientLabel2 = clientAppLabel(clientApp);
|
|
7429
7463
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border last:border-0 hover:bg-muted/20", children: [
|
|
7430
7464
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "max-w-56 px-3 py-2", children: [
|
|
7431
7465
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
@@ -7444,6 +7478,7 @@ function MemberRow({
|
|
|
7444
7478
|
children: isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5" })
|
|
7445
7479
|
}
|
|
7446
7480
|
),
|
|
7481
|
+
clientLabel2 !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: clientApp, className: "size-5" }),
|
|
7447
7482
|
canOpenLiveSession ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
7448
7483
|
"a",
|
|
7449
7484
|
{
|
|
@@ -8201,7 +8236,7 @@ function ProviderCard({
|
|
|
8201
8236
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
8202
8237
|
"div",
|
|
8203
8238
|
{
|
|
8204
|
-
className: `border
|
|
8239
|
+
className: `border border-border bg-card shadow-sm flex flex-col gap-3 rounded-[8px] p-4 transition-all duration-500 ${isHighlighted === true ? "ring-2 ring-primary shadow-md" : ""}`,
|
|
8205
8240
|
children: [
|
|
8206
8241
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
8207
8242
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
@@ -8501,7 +8536,7 @@ const MINIMAX_MODELS = [
|
|
|
8501
8536
|
"MiniMax M2.1-highspeed",
|
|
8502
8537
|
"MiniMax M2"
|
|
8503
8538
|
];
|
|
8504
|
-
const ALIBABA_MODELS = ["
|
|
8539
|
+
const ALIBABA_MODELS = ["qwen3.6-plus", "qwen3.7-max"];
|
|
8505
8540
|
const ZHIPU_MODELS = [
|
|
8506
8541
|
"glm-5.2",
|
|
8507
8542
|
"glm-5.1",
|
|
@@ -8625,7 +8660,7 @@ function EndpointUrlPreview({
|
|
|
8625
8660
|
}) {
|
|
8626
8661
|
const finalUrl = previewEndpointUrl(baseUrl, endpoint);
|
|
8627
8662
|
if (finalUrl === null) return null;
|
|
8628
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
8663
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2 text-xs", children: [
|
|
8629
8664
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground", children: "Final URL" }),
|
|
8630
8665
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "break-all font-mono text-foreground", children: finalUrl })
|
|
8631
8666
|
] });
|
|
@@ -8938,7 +8973,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8938
8973
|
),
|
|
8939
8974
|
className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
8940
8975
|
children: [
|
|
8941
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "
|
|
8976
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "Unspecified" }),
|
|
8942
8977
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "personal", children: "个人 (Personal)" }),
|
|
8943
8978
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "company", children: "公司 (Company)" })
|
|
8944
8979
|
]
|
|
@@ -8960,7 +8995,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8960
8995
|
}
|
|
8961
8996
|
),
|
|
8962
8997
|
errors.modelMetadataUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.modelMetadataUrl }),
|
|
8963
|
-
modelMetadataUrl.trim() === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "
|
|
8998
|
+
modelMetadataUrl.trim() === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2 text-xs text-muted-foreground", children: "Built-in limits cover DeepSeek v4 pro/flash, MiniMax M3/M2.7/M2.5/M2.1, and GLM coding models. Use a registry URL for private or custom model limits." }),
|
|
8964
8999
|
provider !== void 0 && !hasContextMetadata && modelMetadataUrl.trim() === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-amber-400", children: "This provider has no matching context metadata yet." }),
|
|
8965
9000
|
modelMetadataUrl.trim() !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Agent Inspector will refresh model limits from this JSON registry after save." })
|
|
8966
9001
|
] }),
|
|
@@ -9025,7 +9060,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9025
9060
|
ref: (el) => {
|
|
9026
9061
|
modelRowRefs.current[i] = el;
|
|
9027
9062
|
},
|
|
9028
|
-
className: "space-y-2 rounded-
|
|
9063
|
+
className: "border border-border bg-card shadow-sm space-y-2 rounded-[8px] p-2",
|
|
9029
9064
|
children: [
|
|
9030
9065
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9031
9066
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex-1", children: [
|
|
@@ -9050,7 +9085,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9050
9085
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" })
|
|
9051
9086
|
}
|
|
9052
9087
|
),
|
|
9053
|
-
openModelDropdown === i && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-0 right-0 top-full
|
|
9088
|
+
openModelDropdown === i && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-popover text-popover-foreground absolute left-0 right-0 top-full z-50 mt-1 max-h-48 overflow-y-auto rounded-md border shadow-md", children: suggestedModels.map((opt) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9054
9089
|
"button",
|
|
9055
9090
|
{
|
|
9056
9091
|
type: "button",
|
|
@@ -9058,7 +9093,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9058
9093
|
updateModel(i, opt);
|
|
9059
9094
|
setOpenModelDropdown(null);
|
|
9060
9095
|
},
|
|
9061
|
-
className: "w-full
|
|
9096
|
+
className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-white/[0.06]",
|
|
9062
9097
|
children: opt
|
|
9063
9098
|
},
|
|
9064
9099
|
opt
|
|
@@ -9180,7 +9215,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9180
9215
|
errors.models !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.models })
|
|
9181
9216
|
] }),
|
|
9182
9217
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9183
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1
|
|
9218
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 flex gap-1 rounded-[8px] p-1", children: [
|
|
9184
9219
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
9185
9220
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9186
9221
|
"button",
|
|
@@ -9210,7 +9245,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9210
9245
|
] }),
|
|
9211
9246
|
activeTab === "anthropic" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9212
9247
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-anthropic-base-url", className: "text-sm font-medium", children: "Anthropic Base URL" }),
|
|
9213
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md
|
|
9248
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9214
9249
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9215
9250
|
"input",
|
|
9216
9251
|
{
|
|
@@ -9222,10 +9257,10 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9222
9257
|
setAnthropicBaseUrl(e.target.value);
|
|
9223
9258
|
},
|
|
9224
9259
|
placeholder: "https://api.anthropic.com",
|
|
9225
|
-
className: "min-w-0 flex-1 bg-
|
|
9260
|
+
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9226
9261
|
}
|
|
9227
9262
|
),
|
|
9228
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-
|
|
9263
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: ANTHROPIC_MESSAGES_ENDPOINT })
|
|
9229
9264
|
] }),
|
|
9230
9265
|
errors.anthropicBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.anthropicBaseUrl }),
|
|
9231
9266
|
/* @__PURE__ */ jsxRuntimeExports.jsx(EndpointUrlPreview, { baseUrl: anthropicBaseUrl, endpoint: ANTHROPIC_MESSAGES_ENDPOINT }),
|
|
@@ -9234,7 +9269,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9234
9269
|
activeTab === "openai" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
9235
9270
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9236
9271
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-base-url", className: "text-sm font-medium", children: "OpenAI Chat Base URL" }),
|
|
9237
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md
|
|
9272
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9238
9273
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9239
9274
|
"input",
|
|
9240
9275
|
{
|
|
@@ -9246,10 +9281,10 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9246
9281
|
setOpenaiBaseUrl(e.target.value);
|
|
9247
9282
|
},
|
|
9248
9283
|
placeholder: "https://api.openai.com",
|
|
9249
|
-
className: "min-w-0 flex-1 bg-
|
|
9284
|
+
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9250
9285
|
}
|
|
9251
9286
|
),
|
|
9252
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-
|
|
9287
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_CHAT_COMPLETIONS_ENDPOINT })
|
|
9253
9288
|
] }),
|
|
9254
9289
|
errors.openaiBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiBaseUrl }),
|
|
9255
9290
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -9263,7 +9298,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9263
9298
|
] }),
|
|
9264
9299
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9265
9300
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-responses-base-url", className: "text-sm font-medium", children: "OpenAI Responses Base URL" }),
|
|
9266
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md
|
|
9301
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9267
9302
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9268
9303
|
"input",
|
|
9269
9304
|
{
|
|
@@ -9275,10 +9310,10 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9275
9310
|
setOpenaiResponsesBaseUrl(e.target.value);
|
|
9276
9311
|
},
|
|
9277
9312
|
placeholder: "https://api.openai.com",
|
|
9278
|
-
className: "min-w-0 flex-1 bg-
|
|
9313
|
+
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9279
9314
|
}
|
|
9280
9315
|
),
|
|
9281
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-
|
|
9316
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_RESPONSES_ENDPOINT })
|
|
9282
9317
|
] }),
|
|
9283
9318
|
errors.openaiResponsesBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiResponsesBaseUrl }),
|
|
9284
9319
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -9306,7 +9341,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9306
9341
|
),
|
|
9307
9342
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Optional API documentation URL. If not set, uses known provider docs." })
|
|
9308
9343
|
] }),
|
|
9309
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
9344
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-background/95 shadow-sm sticky bottom-0 flex justify-end gap-2 rounded-[8px] px-3 py-2", children: [
|
|
9310
9345
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "outline", onClick: onCancel, disabled: isSubmitting, children: "Cancel" }),
|
|
9311
9346
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? "Saving..." : provider ? "Update Provider" : "Add Provider" })
|
|
9312
9347
|
] })
|
|
@@ -9717,7 +9752,7 @@ function ProvidersPanel({
|
|
|
9717
9752
|
}
|
|
9718
9753
|
if (showForm || editingProvider) {
|
|
9719
9754
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
9720
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "
|
|
9755
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-background/95 shadow-sm sticky top-0 z-10 flex items-center justify-between rounded-[8px] px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: editingProvider ? "Edit Provider" : "Add New Provider" }) }),
|
|
9721
9756
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9722
9757
|
ProviderForm,
|
|
9723
9758
|
{
|
|
@@ -9732,7 +9767,7 @@ function ProvidersPanel({
|
|
|
9732
9767
|
] });
|
|
9733
9768
|
}
|
|
9734
9769
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
9735
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
9770
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-background/95 shadow-sm sticky top-0 z-10 flex items-center justify-between rounded-[8px] px-3 py-2", children: [
|
|
9736
9771
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: "Providers" }),
|
|
9737
9772
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9738
9773
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
@@ -9799,7 +9834,7 @@ function ProvidersPanel({
|
|
|
9799
9834
|
] })
|
|
9800
9835
|
] })
|
|
9801
9836
|
] }),
|
|
9802
|
-
configPath !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
9837
|
+
configPath !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm flex items-center gap-2 rounded-[8px] px-3 py-2 text-xs text-muted-foreground", children: [
|
|
9803
9838
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0", children: "Config:" }),
|
|
9804
9839
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono truncate", title: configPath, children: configPath }),
|
|
9805
9840
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
@@ -9822,18 +9857,18 @@ function ProvidersPanel({
|
|
|
9822
9857
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Copy config file path to clipboard" })
|
|
9823
9858
|
] }) })
|
|
9824
9859
|
] }),
|
|
9825
|
-
error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
9860
|
+
error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm flex items-center gap-2 rounded-[8px] px-3 py-2 text-sm text-destructive", children: [
|
|
9826
9861
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-4 shrink-0" }),
|
|
9827
9862
|
error
|
|
9828
9863
|
] }),
|
|
9829
|
-
providers.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
9864
|
+
providers.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm space-y-3 rounded-[8px] py-12 text-center", children: [
|
|
9830
9865
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: "No providers configured yet." }),
|
|
9831
9866
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: () => setShowForm(true), variant: "outline", size: "sm", children: [
|
|
9832
9867
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
|
|
9833
9868
|
"Add Your First Provider"
|
|
9834
9869
|
] })
|
|
9835
9870
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
|
|
9836
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-1
|
|
9871
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-muted/40 flex gap-1 rounded-[8px] p-1", children: ["all", "personal", "company"].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
9837
9872
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9838
9873
|
"button",
|
|
9839
9874
|
{
|
|
@@ -9930,10 +9965,20 @@ function SettingsDialog() {
|
|
|
9930
9965
|
[]
|
|
9931
9966
|
);
|
|
9932
9967
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open, onOpenChange: setOpen, children: [
|
|
9933
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9969
|
+
Button,
|
|
9970
|
+
{
|
|
9971
|
+
variant: "ghost",
|
|
9972
|
+
size: "icon",
|
|
9973
|
+
className: INSPECTOR_ICON_TRIGGER_CLASS,
|
|
9974
|
+
"aria-label": "Settings",
|
|
9975
|
+
title: "Settings",
|
|
9976
|
+
children: [
|
|
9977
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "size-4" }),
|
|
9978
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Settings" })
|
|
9979
|
+
]
|
|
9980
|
+
}
|
|
9981
|
+
) }),
|
|
9937
9982
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-2xl max-h-[80vh] overflow-hidden flex flex-col", children: [
|
|
9938
9983
|
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Settings" }) }),
|
|
9939
9984
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "flex-1 overflow-hidden", children: [
|
|
@@ -10064,14 +10109,14 @@ function StorageSettingsTab() {
|
|
|
10064
10109
|
onCopy: handleCopy
|
|
10065
10110
|
}
|
|
10066
10111
|
),
|
|
10067
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
10112
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
|
|
10068
10113
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "In-memory logs" }),
|
|
10069
10114
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
|
|
10070
10115
|
stats.memoryCount.toLocaleString(),
|
|
10071
10116
|
" loaded"
|
|
10072
10117
|
] })
|
|
10073
10118
|
] }),
|
|
10074
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
10119
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
|
|
10075
10120
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Log files" }),
|
|
10076
10121
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
|
|
10077
10122
|
stats.logFileCount.toLocaleString(),
|
|
@@ -10079,7 +10124,7 @@ function StorageSettingsTab() {
|
|
|
10079
10124
|
formatBytes(stats.logBytes)
|
|
10080
10125
|
] })
|
|
10081
10126
|
] }),
|
|
10082
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
10127
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
|
|
10083
10128
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Streaming chunks" }),
|
|
10084
10129
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
|
|
10085
10130
|
stats.chunkFileCount.toLocaleString(),
|
|
@@ -10087,7 +10132,7 @@ function StorageSettingsTab() {
|
|
|
10087
10132
|
formatBytes(stats.chunkBytes)
|
|
10088
10133
|
] })
|
|
10089
10134
|
] }),
|
|
10090
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
10135
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
|
|
10091
10136
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Session archives" }),
|
|
10092
10137
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
|
|
10093
10138
|
stats.sessionArchiveFileCount.toLocaleString(),
|
|
@@ -10108,7 +10153,7 @@ function CopyableSetupValue({
|
|
|
10108
10153
|
onCopy
|
|
10109
10154
|
}) {
|
|
10110
10155
|
const copied = copiedId === id;
|
|
10111
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
10156
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 min-w-0 rounded-md px-3 py-2", children: [
|
|
10112
10157
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: label }),
|
|
10113
10158
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
10114
10159
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "min-w-0 flex-1 truncate font-mono text-xs text-foreground", children: value }),
|
|
@@ -10610,107 +10655,370 @@ function compareField(previous, current) {
|
|
|
10610
10655
|
if (current < previous) return { direction: "down", delta: previous - current };
|
|
10611
10656
|
return null;
|
|
10612
10657
|
}
|
|
10613
|
-
|
|
10614
|
-
const
|
|
10615
|
-
const
|
|
10616
|
-
|
|
10617
|
-
|
|
10658
|
+
function firstUserAgent(logs) {
|
|
10659
|
+
for (const log of logs) {
|
|
10660
|
+
const userAgent = log.userAgent;
|
|
10661
|
+
if (userAgent !== null && userAgent !== void 0 && userAgent !== "") return userAgent;
|
|
10662
|
+
}
|
|
10663
|
+
return null;
|
|
10618
10664
|
}
|
|
10619
|
-
function
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
}
|
|
10624
|
-
|
|
10625
|
-
|
|
10665
|
+
function firstClientPid(logs) {
|
|
10666
|
+
for (const log of logs) {
|
|
10667
|
+
const clientPid = log.clientPid;
|
|
10668
|
+
if (clientPid !== null && clientPid !== void 0) return clientPid;
|
|
10669
|
+
}
|
|
10670
|
+
return null;
|
|
10671
|
+
}
|
|
10672
|
+
function firstClientProjectFolder(logs) {
|
|
10673
|
+
for (const log of logs) {
|
|
10674
|
+
const projectFolder = log.clientProjectFolder;
|
|
10675
|
+
if (projectFolder !== null && projectFolder !== void 0 && projectFolder !== "") {
|
|
10676
|
+
return projectFolder;
|
|
10677
|
+
}
|
|
10626
10678
|
}
|
|
10627
|
-
return
|
|
10679
|
+
return null;
|
|
10680
|
+
}
|
|
10681
|
+
function groupClient(group) {
|
|
10682
|
+
return detectClientApp({
|
|
10683
|
+
userAgent: firstUserAgent(group.logs),
|
|
10684
|
+
conversationId: group.conversationId,
|
|
10685
|
+
clientProjectFolder: firstClientProjectFolder(group.logs)
|
|
10686
|
+
});
|
|
10628
10687
|
}
|
|
10629
|
-
function
|
|
10688
|
+
function fallbackClientLabel(userAgent) {
|
|
10689
|
+
if (userAgent === null || userAgent === "") return "Unknown IDE";
|
|
10690
|
+
const firstToken = userAgent.split(/[ /;]/)[0] ?? "";
|
|
10691
|
+
if (firstToken === "") return "Unknown IDE";
|
|
10692
|
+
return firstToken;
|
|
10693
|
+
}
|
|
10694
|
+
function clientLabel(client, userAgent) {
|
|
10695
|
+
const knownLabel = clientAppLabel(client);
|
|
10696
|
+
if (knownLabel !== null) return knownLabel;
|
|
10697
|
+
return fallbackClientLabel(userAgent);
|
|
10698
|
+
}
|
|
10699
|
+
function bucketKey(value) {
|
|
10700
|
+
if (value === null || value === "") return "unknown";
|
|
10701
|
+
return String(value);
|
|
10702
|
+
}
|
|
10703
|
+
function ideKey(client, userAgent, projectFolder) {
|
|
10704
|
+
if (client !== "unknown") return client;
|
|
10705
|
+
return `unknown:${bucketKey(userAgent)}:${bucketKey(projectFolder)}`;
|
|
10706
|
+
}
|
|
10707
|
+
function processKey(clientPid, projectFolder) {
|
|
10708
|
+
return `${bucketKey(clientPid)}:${bucketKey(projectFolder)}`;
|
|
10709
|
+
}
|
|
10710
|
+
function sortLogsByTimestamp(logs) {
|
|
10711
|
+
return [...logs].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
10712
|
+
}
|
|
10713
|
+
function firstTimestamp(logs) {
|
|
10714
|
+
return sortLogsByTimestamp(logs)[0]?.timestamp ?? "";
|
|
10715
|
+
}
|
|
10716
|
+
function sortByFirstLogTime(items) {
|
|
10717
|
+
return [...items].sort((a, b) => firstTimestamp(a.logs).localeCompare(firstTimestamp(b.logs)));
|
|
10718
|
+
}
|
|
10719
|
+
function buildConversationHierarchy(groups) {
|
|
10720
|
+
const ideGroups = /* @__PURE__ */ new Map();
|
|
10721
|
+
for (const group of groups) {
|
|
10722
|
+
const userAgent = firstUserAgent(group.logs);
|
|
10723
|
+
const projectFolder = firstClientProjectFolder(group.logs);
|
|
10724
|
+
const client = groupClient(group);
|
|
10725
|
+
const currentIdeKey = ideKey(client, userAgent, projectFolder);
|
|
10726
|
+
let ideGroup = ideGroups.get(currentIdeKey);
|
|
10727
|
+
if (ideGroup === void 0) {
|
|
10728
|
+
ideGroup = {
|
|
10729
|
+
id: currentIdeKey,
|
|
10730
|
+
client,
|
|
10731
|
+
label: clientLabel(client, userAgent),
|
|
10732
|
+
userAgent,
|
|
10733
|
+
processes: /* @__PURE__ */ new Map(),
|
|
10734
|
+
logs: []
|
|
10735
|
+
};
|
|
10736
|
+
ideGroups.set(currentIdeKey, ideGroup);
|
|
10737
|
+
}
|
|
10738
|
+
ideGroup.logs.push(...group.logs);
|
|
10739
|
+
const clientPid = firstClientPid(group.logs);
|
|
10740
|
+
const currentProcessKey = `${currentIdeKey}:${processKey(clientPid, projectFolder)}`;
|
|
10741
|
+
let processGroup = ideGroup.processes.get(currentProcessKey);
|
|
10742
|
+
if (processGroup === void 0) {
|
|
10743
|
+
processGroup = {
|
|
10744
|
+
id: currentProcessKey,
|
|
10745
|
+
clientPid,
|
|
10746
|
+
clientProjectFolder: projectFolder,
|
|
10747
|
+
sessions: [],
|
|
10748
|
+
logs: []
|
|
10749
|
+
};
|
|
10750
|
+
ideGroup.processes.set(currentProcessKey, processGroup);
|
|
10751
|
+
}
|
|
10752
|
+
processGroup.sessions.push(group);
|
|
10753
|
+
processGroup.logs.push(...group.logs);
|
|
10754
|
+
}
|
|
10755
|
+
const hierarchy = [];
|
|
10756
|
+
for (const ideGroup of ideGroups.values()) {
|
|
10757
|
+
const processes = sortByFirstLogTime(
|
|
10758
|
+
[...ideGroup.processes.values()].map((processGroup) => ({
|
|
10759
|
+
id: processGroup.id,
|
|
10760
|
+
clientPid: processGroup.clientPid,
|
|
10761
|
+
clientProjectFolder: processGroup.clientProjectFolder,
|
|
10762
|
+
sessions: sortByFirstLogTime(processGroup.sessions),
|
|
10763
|
+
logs: sortLogsByTimestamp(processGroup.logs)
|
|
10764
|
+
}))
|
|
10765
|
+
);
|
|
10766
|
+
hierarchy.push({
|
|
10767
|
+
id: ideGroup.id,
|
|
10768
|
+
client: ideGroup.client,
|
|
10769
|
+
label: ideGroup.label,
|
|
10770
|
+
userAgent: ideGroup.userAgent,
|
|
10771
|
+
processes,
|
|
10772
|
+
logs: sortLogsByTimestamp(ideGroup.logs)
|
|
10773
|
+
});
|
|
10774
|
+
}
|
|
10775
|
+
return sortByFirstLogTime(hierarchy);
|
|
10776
|
+
}
|
|
10777
|
+
function formatTokenCount(count) {
|
|
10778
|
+
if (count <= 0) return "0";
|
|
10779
|
+
return formatTokens(count);
|
|
10780
|
+
}
|
|
10781
|
+
function tokenTotals(logs) {
|
|
10782
|
+
let inputTokens = 0;
|
|
10783
|
+
let outputTokens = 0;
|
|
10784
|
+
for (const log of logs) {
|
|
10785
|
+
if (log.inputTokens !== null && log.inputTokens !== void 0) inputTokens += log.inputTokens;
|
|
10786
|
+
if (log.outputTokens !== null && log.outputTokens !== void 0) {
|
|
10787
|
+
outputTokens += log.outputTokens;
|
|
10788
|
+
}
|
|
10789
|
+
}
|
|
10790
|
+
return { inputTokens, outputTokens };
|
|
10791
|
+
}
|
|
10792
|
+
function countSessions(processes) {
|
|
10793
|
+
let sessions = 0;
|
|
10794
|
+
for (const processGroup of processes) {
|
|
10795
|
+
sessions += processGroup.sessions.length;
|
|
10796
|
+
}
|
|
10797
|
+
return sessions;
|
|
10798
|
+
}
|
|
10799
|
+
function shortProjectPath(projectFolder) {
|
|
10800
|
+
if (projectFolder === null || projectFolder === "") return null;
|
|
10801
|
+
const parts = projectFolder.replaceAll("\\", "/").split("/").filter((part) => part !== "");
|
|
10802
|
+
const leaf = parts[parts.length - 1];
|
|
10803
|
+
if (leaf === void 0) return projectFolder;
|
|
10804
|
+
const parent = parts[parts.length - 2];
|
|
10805
|
+
if (parent === void 0) return leaf;
|
|
10806
|
+
return `${parent}/${leaf}`;
|
|
10807
|
+
}
|
|
10808
|
+
function SummaryChip({
|
|
10809
|
+
label,
|
|
10810
|
+
value,
|
|
10811
|
+
className
|
|
10812
|
+
}) {
|
|
10813
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10814
|
+
"span",
|
|
10815
|
+
{
|
|
10816
|
+
className: cn(
|
|
10817
|
+
"border border-border bg-muted/40 inline-flex h-7 items-center gap-1 rounded-md px-2 text-xs text-muted-foreground",
|
|
10818
|
+
className
|
|
10819
|
+
),
|
|
10820
|
+
children: [
|
|
10821
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] uppercase tracking-[0.12em] text-white/35", children: label }),
|
|
10822
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums text-slate-100", children: value })
|
|
10823
|
+
]
|
|
10824
|
+
}
|
|
10825
|
+
);
|
|
10826
|
+
}
|
|
10827
|
+
function ConversationGroupList({
|
|
10630
10828
|
groups,
|
|
10631
|
-
standalone,
|
|
10632
10829
|
...groupProps
|
|
10633
10830
|
}) {
|
|
10634
|
-
const
|
|
10635
|
-
|
|
10831
|
+
const hierarchy = reactExports.useMemo(() => buildConversationHierarchy(groups), [groups]);
|
|
10832
|
+
const [collapsedIdeIds, setCollapsedIdeIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
|
|
10833
|
+
const [collapsedProcessIds, setCollapsedProcessIds] = reactExports.useState(
|
|
10834
|
+
() => /* @__PURE__ */ new Set()
|
|
10636
10835
|
);
|
|
10637
|
-
const
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
|
|
10641
|
-
|
|
10642
|
-
});
|
|
10643
|
-
const setGroupExpanded = reactExports.useCallback((groupId, expanded) => {
|
|
10644
|
-
setExpandedByGroupId((previous) => {
|
|
10645
|
-
const next = new Map(previous);
|
|
10646
|
-
if (expanded) {
|
|
10647
|
-
next.set(groupId, true);
|
|
10836
|
+
const toggleIde = reactExports.useCallback((id) => {
|
|
10837
|
+
setCollapsedIdeIds((previous) => {
|
|
10838
|
+
const next = new Set(previous);
|
|
10839
|
+
if (next.has(id)) {
|
|
10840
|
+
next.delete(id);
|
|
10648
10841
|
} else {
|
|
10649
|
-
next.
|
|
10842
|
+
next.add(id);
|
|
10650
10843
|
}
|
|
10651
10844
|
return next;
|
|
10652
10845
|
});
|
|
10653
10846
|
}, []);
|
|
10654
|
-
const
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10847
|
+
const toggleProcess = reactExports.useCallback((id) => {
|
|
10848
|
+
setCollapsedProcessIds((previous) => {
|
|
10849
|
+
const next = new Set(previous);
|
|
10850
|
+
if (next.has(id)) {
|
|
10851
|
+
next.delete(id);
|
|
10852
|
+
} else {
|
|
10853
|
+
next.add(id);
|
|
10661
10854
|
}
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
}, [
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
const request = readLogFocusRequest(event);
|
|
10668
|
-
if (request === null) return;
|
|
10669
|
-
const index = indexByLogId.get(request.logId);
|
|
10670
|
-
if (index === void 0) return;
|
|
10671
|
-
const group = groups[index];
|
|
10672
|
-
if (group === void 0) return;
|
|
10673
|
-
setGroupExpanded(group.id, true);
|
|
10674
|
-
virtualizer.scrollToIndex(index, { align: "center" });
|
|
10675
|
-
};
|
|
10676
|
-
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
10677
|
-
return () => {
|
|
10678
|
-
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
10679
|
-
};
|
|
10680
|
-
}, [groups, indexByLogId, setGroupExpanded, virtualizer]);
|
|
10681
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10682
|
-
"div",
|
|
10855
|
+
return next;
|
|
10856
|
+
});
|
|
10857
|
+
}, []);
|
|
10858
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: hierarchy.map((ideGroup) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10859
|
+
IdeGroupSection,
|
|
10683
10860
|
{
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10861
|
+
group: ideGroup,
|
|
10862
|
+
collapsed: collapsedIdeIds.has(ideGroup.id),
|
|
10863
|
+
collapsedProcessIds,
|
|
10864
|
+
onToggleIde: () => toggleIde(ideGroup.id),
|
|
10865
|
+
onToggleProcess: toggleProcess,
|
|
10866
|
+
conversationProps: groupProps
|
|
10867
|
+
},
|
|
10868
|
+
ideGroup.id
|
|
10869
|
+
)) });
|
|
10870
|
+
}
|
|
10871
|
+
function IdeGroupSection({
|
|
10872
|
+
group,
|
|
10873
|
+
collapsed,
|
|
10874
|
+
collapsedProcessIds,
|
|
10875
|
+
onToggleIde,
|
|
10876
|
+
onToggleProcess,
|
|
10877
|
+
conversationProps
|
|
10878
|
+
}) {
|
|
10879
|
+
const totals = tokenTotals(group.logs);
|
|
10880
|
+
const sessionCount = countSessions(group.processes);
|
|
10881
|
+
const logCount = group.logs.length;
|
|
10882
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10883
|
+
"section",
|
|
10884
|
+
{
|
|
10885
|
+
className: cn("border border-border bg-card shadow-sm relative isolate rounded-[8px]"),
|
|
10886
|
+
"data-ide-group": group.id,
|
|
10887
|
+
children: [
|
|
10888
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10889
|
+
"button",
|
|
10692
10890
|
{
|
|
10693
|
-
"
|
|
10694
|
-
|
|
10695
|
-
|
|
10696
|
-
|
|
10697
|
-
children:
|
|
10698
|
-
|
|
10699
|
-
{
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
|
|
10891
|
+
type: "button",
|
|
10892
|
+
className: "flex w-full min-w-0 items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-white/[0.03] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300/45",
|
|
10893
|
+
onClick: onToggleIde,
|
|
10894
|
+
"aria-expanded": !collapsed,
|
|
10895
|
+
children: [
|
|
10896
|
+
group.client === "unknown" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-border bg-muted/40 inline-flex size-10 shrink-0 items-center justify-center rounded-[8px] text-slate-200", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Monitor, { className: "size-5" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: group.client, className: "size-10 rounded-[8px] text-cyan-100" }),
|
|
10897
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
10898
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
10899
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10900
|
+
"span",
|
|
10901
|
+
{
|
|
10902
|
+
className: "truncate text-sm font-semibold text-slate-50",
|
|
10903
|
+
title: group.userAgent ?? group.label,
|
|
10904
|
+
children: group.label
|
|
10905
|
+
}
|
|
10906
|
+
),
|
|
10907
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded border border-cyan-200/15 bg-cyan-300/[0.06] px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-[0.16em] text-cyan-100/75", children: "IDE" })
|
|
10908
|
+
] }),
|
|
10909
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
10910
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
10911
|
+
group.processes.length,
|
|
10912
|
+
" process",
|
|
10913
|
+
group.processes.length !== 1 ? "es" : ""
|
|
10914
|
+
] }),
|
|
10915
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
10916
|
+
sessionCount,
|
|
10917
|
+
" session",
|
|
10918
|
+
sessionCount !== 1 ? "s" : ""
|
|
10919
|
+
] }),
|
|
10920
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
10921
|
+
logCount,
|
|
10922
|
+
" log",
|
|
10923
|
+
logCount !== 1 ? "s" : ""
|
|
10924
|
+
] })
|
|
10925
|
+
] })
|
|
10926
|
+
] }),
|
|
10927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 items-center gap-2 md:flex", children: [
|
|
10928
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "IN", value: formatTokenCount(totals.inputTokens) }),
|
|
10929
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "OUT", value: formatTokenCount(totals.outputTokens) })
|
|
10930
|
+
] }),
|
|
10931
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-slate-200", children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }) })
|
|
10932
|
+
]
|
|
10933
|
+
}
|
|
10934
|
+
),
|
|
10935
|
+
!collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3 border-t border-white/10 px-3 pb-3 pt-3 sm:px-4", children: group.processes.map((processGroup) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10936
|
+
ProcessGroupSection,
|
|
10937
|
+
{
|
|
10938
|
+
group: processGroup,
|
|
10939
|
+
collapsed: collapsedProcessIds.has(processGroup.id),
|
|
10940
|
+
onToggle: () => onToggleProcess(processGroup.id),
|
|
10941
|
+
conversationProps
|
|
10707
10942
|
},
|
|
10708
|
-
|
|
10709
|
-
)
|
|
10710
|
-
|
|
10943
|
+
processGroup.id
|
|
10944
|
+
)) })
|
|
10945
|
+
]
|
|
10711
10946
|
}
|
|
10712
10947
|
);
|
|
10713
10948
|
}
|
|
10949
|
+
function ProcessGroupSection({
|
|
10950
|
+
group,
|
|
10951
|
+
collapsed,
|
|
10952
|
+
onToggle,
|
|
10953
|
+
conversationProps
|
|
10954
|
+
}) {
|
|
10955
|
+
const totals = tokenTotals(group.logs);
|
|
10956
|
+
const projectLabel = shortProjectPath(group.clientProjectFolder);
|
|
10957
|
+
const sessionCount = group.sessions.length;
|
|
10958
|
+
const logCount = group.logs.length;
|
|
10959
|
+
const processLabel = group.clientPid !== null && group.clientPid !== void 0 ? `PID ${group.clientPid}` : "process";
|
|
10960
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "relative pl-5", children: [
|
|
10961
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute bottom-0 left-2 top-0 w-px bg-white/12", "aria-hidden": "true" }),
|
|
10962
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm overflow-hidden rounded-[8px]", children: [
|
|
10963
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10964
|
+
"button",
|
|
10965
|
+
{
|
|
10966
|
+
type: "button",
|
|
10967
|
+
className: "flex w-full min-w-0 items-center gap-3 px-3 py-2.5 text-left transition-colors hover:bg-white/[0.035] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300/40",
|
|
10968
|
+
onClick: onToggle,
|
|
10969
|
+
"aria-expanded": !collapsed,
|
|
10970
|
+
children: [
|
|
10971
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-border bg-muted/40 inline-flex size-8 shrink-0 items-center justify-center rounded-md text-amber-100", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Cpu, { className: "size-4" }) }),
|
|
10972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
10973
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
10974
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs font-semibold tabular-nums text-slate-100", children: processLabel }),
|
|
10975
|
+
projectLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10976
|
+
"span",
|
|
10977
|
+
{
|
|
10978
|
+
className: "inline-flex min-w-0 items-center gap-1 text-xs text-muted-foreground",
|
|
10979
|
+
title: group.clientProjectFolder ?? projectLabel,
|
|
10980
|
+
children: [
|
|
10981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-3 shrink-0" }),
|
|
10982
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-mono", children: projectLabel })
|
|
10983
|
+
]
|
|
10984
|
+
}
|
|
10985
|
+
)
|
|
10986
|
+
] }),
|
|
10987
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
10988
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
10989
|
+
sessionCount,
|
|
10990
|
+
" session",
|
|
10991
|
+
sessionCount !== 1 ? "s" : ""
|
|
10992
|
+
] }),
|
|
10993
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
10994
|
+
logCount,
|
|
10995
|
+
" log",
|
|
10996
|
+
logCount !== 1 ? "s" : ""
|
|
10997
|
+
] })
|
|
10998
|
+
] })
|
|
10999
|
+
] }),
|
|
11000
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 items-center gap-2 md:flex", children: [
|
|
11001
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "IN", value: formatTokenCount(totals.inputTokens) }),
|
|
11002
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "OUT", value: formatTokenCount(totals.outputTokens) })
|
|
11003
|
+
] }),
|
|
11004
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-7 shrink-0 items-center justify-center rounded-md text-slate-200", children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }) })
|
|
11005
|
+
]
|
|
11006
|
+
}
|
|
11007
|
+
),
|
|
11008
|
+
!collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 border-t border-white/10 p-2 sm:p-3", children: group.sessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11009
|
+
ConversationGroup,
|
|
11010
|
+
{
|
|
11011
|
+
group: session,
|
|
11012
|
+
...conversationProps,
|
|
11013
|
+
showClientIdentity: false,
|
|
11014
|
+
showLogClientMetadata: false,
|
|
11015
|
+
showProcessMetadata: false
|
|
11016
|
+
},
|
|
11017
|
+
session.id
|
|
11018
|
+
)) })
|
|
11019
|
+
] })
|
|
11020
|
+
] });
|
|
11021
|
+
}
|
|
10714
11022
|
const NAV_ATTR = "data-nav-id";
|
|
10715
11023
|
const NAV_ACTION_ATTR = "data-nav-action";
|
|
10716
11024
|
function findNavItems(container) {
|
|
@@ -11874,13 +12182,13 @@ function slateStatusClass(status) {
|
|
|
11874
12182
|
case "watch":
|
|
11875
12183
|
return "border-amber-300/35 bg-amber-400/10 text-amber-100";
|
|
11876
12184
|
case "clear":
|
|
11877
|
-
return "border-
|
|
12185
|
+
return "border-slate-300/20 bg-slate-300/[0.08] text-slate-100";
|
|
11878
12186
|
}
|
|
11879
12187
|
}
|
|
11880
12188
|
function SessionOpeningSlate({ stats }) {
|
|
11881
12189
|
if (stats.requests === 0) return null;
|
|
11882
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "
|
|
11883
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "col-span-2 border-b border-
|
|
12190
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm mb-4 rounded-[8px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-0 md:grid-cols-[minmax(220px,1.2fr)_repeat(4,minmax(120px,1fr))]", children: [
|
|
12191
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "col-span-2 border-b border-white/10 px-4 py-3 md:col-span-1 md:border-b-0 md:border-r", children: [
|
|
11884
12192
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-[10px] font-semibold uppercase text-muted-foreground", children: [
|
|
11885
12193
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clapperboard, { className: "size-3.5 text-cyan-300" }),
|
|
11886
12194
|
"Opening Slate"
|
|
@@ -11888,7 +12196,7 @@ function SessionOpeningSlate({ stats }) {
|
|
|
11888
12196
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 min-w-0 truncate font-mono text-sm font-semibold text-foreground", children: stats.modelLabel }),
|
|
11889
12197
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: stats.timeRange ?? "Timeline pending" })
|
|
11890
12198
|
] }),
|
|
11891
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-b border-
|
|
12199
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-b border-white/10 px-4 py-3 md:border-b-0", children: [
|
|
11892
12200
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase text-muted-foreground", children: "Status" }),
|
|
11893
12201
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11894
12202
|
"div",
|
|
@@ -11901,11 +12209,11 @@ function SessionOpeningSlate({ stats }) {
|
|
|
11901
12209
|
}
|
|
11902
12210
|
)
|
|
11903
12211
|
] }),
|
|
11904
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-
|
|
12212
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-white/10 px-4 py-3 md:border-b-0 md:border-r", children: [
|
|
11905
12213
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase text-muted-foreground", children: "Requests" }),
|
|
11906
12214
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 font-mono text-xl font-semibold text-foreground", children: stats.requests })
|
|
11907
12215
|
] }),
|
|
11908
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-
|
|
12216
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-white/10 px-4 py-3 md:border-r", children: [
|
|
11909
12217
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-[10px] uppercase text-muted-foreground", children: [
|
|
11910
12218
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Siren, { className: "size-3 text-red-300" }),
|
|
11911
12219
|
"Failure"
|
|
@@ -11989,7 +12297,7 @@ function sessionRiskBarClass(risk) {
|
|
|
11989
12297
|
case "unknown":
|
|
11990
12298
|
return "bg-muted-foreground/50";
|
|
11991
12299
|
case "ok":
|
|
11992
|
-
return "bg-
|
|
12300
|
+
return "bg-cyan-300";
|
|
11993
12301
|
}
|
|
11994
12302
|
}
|
|
11995
12303
|
function formatContextWindow(summary) {
|
|
@@ -12031,7 +12339,7 @@ function evidenceChipClass(value) {
|
|
|
12031
12339
|
return "border-amber-300/35 bg-amber-400/10 text-amber-100";
|
|
12032
12340
|
}
|
|
12033
12341
|
if (normalized.includes("pass") || normalized.includes("complete") || normalized.includes("accept")) {
|
|
12034
|
-
return "border-
|
|
12342
|
+
return "border-cyan-300/25 bg-cyan-400/10 text-cyan-100";
|
|
12035
12343
|
}
|
|
12036
12344
|
return "border-border/70 bg-background/70 text-muted-foreground";
|
|
12037
12345
|
}
|
|
@@ -12064,13 +12372,13 @@ function SessionMembershipPanel({
|
|
|
12064
12372
|
].filter(
|
|
12065
12373
|
(value) => value !== null && value.label.length > 0 && value.value.length > 0
|
|
12066
12374
|
);
|
|
12067
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
12375
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mb-3 rounded-[8px] text-xs", children: [
|
|
12068
12376
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12069
12377
|
"button",
|
|
12070
12378
|
{
|
|
12071
12379
|
type: "button",
|
|
12072
12380
|
onClick: () => setOpen((value) => !value),
|
|
12073
|
-
className: "flex w-full items-center gap-3 px-3 py-2 text-left transition-colors hover:bg-
|
|
12381
|
+
className: "flex w-full items-center gap-3 px-3 py-2 text-left transition-colors hover:bg-white/[0.04]",
|
|
12074
12382
|
"aria-expanded": open,
|
|
12075
12383
|
children: [
|
|
12076
12384
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
@@ -12099,7 +12407,7 @@ function SessionMembershipPanel({
|
|
|
12099
12407
|
]
|
|
12100
12408
|
}
|
|
12101
12409
|
),
|
|
12102
|
-
open && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 border-t border-
|
|
12410
|
+
open && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 border-t border-white/10 px-3 py-2", children: memberships.map((membership) => {
|
|
12103
12411
|
const member = membership.member;
|
|
12104
12412
|
const metadataRows = getMemberMetadataRows(member);
|
|
12105
12413
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
|
|
@@ -12131,7 +12439,7 @@ function SessionMembershipPanel({
|
|
|
12131
12439
|
metadataRows.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1 sm:grid-cols-2 xl:grid-cols-3", children: metadataRows.map((row) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12132
12440
|
"div",
|
|
12133
12441
|
{
|
|
12134
|
-
className: "min-w-0 rounded
|
|
12442
|
+
className: "border border-border bg-muted/40 min-w-0 rounded-md px-2 py-1",
|
|
12135
12443
|
children: [
|
|
12136
12444
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-[10px] text-muted-foreground", children: row.key }),
|
|
12137
12445
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -12175,7 +12483,7 @@ function LogPaginationButton({
|
|
|
12175
12483
|
type: "button",
|
|
12176
12484
|
onClick,
|
|
12177
12485
|
disabled,
|
|
12178
|
-
className: "inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:
|
|
12486
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45",
|
|
12179
12487
|
title,
|
|
12180
12488
|
children: [
|
|
12181
12489
|
icon,
|
|
@@ -12196,7 +12504,7 @@ function LogPaginationBar({
|
|
|
12196
12504
|
{
|
|
12197
12505
|
className: cn(
|
|
12198
12506
|
"flex min-h-9 flex-col gap-2 px-1 py-1 sm:flex-row sm:items-center",
|
|
12199
|
-
embedded ? "border-t border-
|
|
12507
|
+
embedded ? "border-t border-white/10 pt-2" : "border border-border bg-card shadow-sm mb-3 rounded-[8px] px-2"
|
|
12200
12508
|
),
|
|
12201
12509
|
children: [
|
|
12202
12510
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full min-w-0 px-1 font-mono text-[11px] text-muted-foreground sm:flex-1", children: [
|
|
@@ -12264,7 +12572,7 @@ function sessionRiskClass(risk) {
|
|
|
12264
12572
|
case "unknown":
|
|
12265
12573
|
return "text-muted-foreground";
|
|
12266
12574
|
case "ok":
|
|
12267
|
-
return "text-
|
|
12575
|
+
return "text-cyan-200";
|
|
12268
12576
|
}
|
|
12269
12577
|
}
|
|
12270
12578
|
function sessionHealthClass(level) {
|
|
@@ -12274,7 +12582,7 @@ function sessionHealthClass(level) {
|
|
|
12274
12582
|
case "optimizable":
|
|
12275
12583
|
return "border-amber-400/25 bg-amber-400/8 text-amber-100";
|
|
12276
12584
|
case "ok":
|
|
12277
|
-
return "border-
|
|
12585
|
+
return "border-cyan-300/25 bg-cyan-400/8 text-cyan-100";
|
|
12278
12586
|
}
|
|
12279
12587
|
}
|
|
12280
12588
|
function sessionHealthLabel(level) {
|
|
@@ -12325,14 +12633,14 @@ function CopyableCommand({ command }) {
|
|
|
12325
12633
|
setTimeout(() => setCopied(false), 2e3);
|
|
12326
12634
|
});
|
|
12327
12635
|
}, [command]);
|
|
12328
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex items-center gap-2
|
|
12329
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "
|
|
12636
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 inline-flex max-w-full items-center gap-2 rounded-md px-3 py-2", children: [
|
|
12637
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "m-0 overflow-x-auto font-mono text-sm text-cyan-200", children: command }),
|
|
12330
12638
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12331
12639
|
"button",
|
|
12332
12640
|
{
|
|
12333
12641
|
type: "button",
|
|
12334
12642
|
onClick: handleCopy,
|
|
12335
|
-
className: "
|
|
12643
|
+
className: "shrink-0 cursor-pointer text-muted-foreground transition-colors hover:text-foreground",
|
|
12336
12644
|
"aria-label": "Copy command",
|
|
12337
12645
|
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" })
|
|
12338
12646
|
}
|
|
@@ -12341,14 +12649,30 @@ function CopyableCommand({ command }) {
|
|
|
12341
12649
|
}
|
|
12342
12650
|
function McpReadyBadge() {
|
|
12343
12651
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
12344
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex h-7 items-center gap-2 rounded-md
|
|
12345
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-1.5 rounded-full bg-
|
|
12652
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "border border-border bg-muted/40 inline-flex h-7 items-center gap-2 rounded-md px-2.5 font-mono text-[11px] font-medium text-cyan-200", children: [
|
|
12653
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-1.5 rounded-full bg-cyan-200 shadow-[0_0_8px_rgba(125,211,252,0.75)]" }),
|
|
12346
12654
|
"MCP Ready",
|
|
12347
12655
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "hidden text-cyan-200/70 sm:inline", children: "/api/mcp" })
|
|
12348
12656
|
] }) }),
|
|
12349
12657
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { sideOffset: 8, className: "max-w-[320px] text-left leading-relaxed", children: "Coding agents can inspect logs, replay requests, test providers, and debug sessions through MCP at /api/mcp." })
|
|
12350
12658
|
] }) });
|
|
12351
12659
|
}
|
|
12660
|
+
function SidebarPanel({
|
|
12661
|
+
label,
|
|
12662
|
+
children,
|
|
12663
|
+
className
|
|
12664
|
+
}) {
|
|
12665
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: cn("border border-border bg-card shadow-sm rounded-[8px]", className), children: [
|
|
12666
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-b border-white/10 px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-[10px] font-semibold uppercase tracking-[0.14em] text-white/40", children: label }) }),
|
|
12667
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3", children })
|
|
12668
|
+
] });
|
|
12669
|
+
}
|
|
12670
|
+
function SidebarMetric({ label, value }) {
|
|
12671
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 min-w-0 rounded-md px-2 py-2", children: [
|
|
12672
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate font-mono text-lg font-semibold leading-6 text-slate-100", children: value }),
|
|
12673
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-0.5 truncate font-mono text-[10px] uppercase tracking-[0.12em] text-white/35", children: label })
|
|
12674
|
+
] });
|
|
12675
|
+
}
|
|
12352
12676
|
const CRAB_VARIANT_COLORS = [
|
|
12353
12677
|
"text-amber-500",
|
|
12354
12678
|
"text-rose-500",
|
|
@@ -12394,7 +12718,7 @@ function BrandHeader({
|
|
|
12394
12718
|
crabEntrancePhase
|
|
12395
12719
|
}) {
|
|
12396
12720
|
if (compact) {
|
|
12397
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
12721
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm rounded-[8px] p-3", children: [
|
|
12398
12722
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
12399
12723
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [
|
|
12400
12724
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CrabFamily, { compact: true, entrancePhase: crabEntrancePhase }),
|
|
@@ -12449,7 +12773,7 @@ function SessionContextLogButton({ label, logId }) {
|
|
|
12449
12773
|
{
|
|
12450
12774
|
type: "button",
|
|
12451
12775
|
onClick: () => openLogContext(logId),
|
|
12452
|
-
className: "inline-flex h-5 items-center rounded px-1 font-mono text-[10px] text-muted-foreground transition-colors hover:bg-
|
|
12776
|
+
className: "inline-flex h-5 items-center rounded px-1 font-mono text-[10px] text-muted-foreground transition-colors hover:bg-white/[0.06] hover:text-foreground",
|
|
12453
12777
|
title: `Open Context for ${formatLogReference(logId)}`,
|
|
12454
12778
|
children: [
|
|
12455
12779
|
label,
|
|
@@ -12481,7 +12805,7 @@ function SessionContextProgressBar({
|
|
|
12481
12805
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12482
12806
|
"span",
|
|
12483
12807
|
{
|
|
12484
|
-
className: "relative block h-2.5 overflow-hidden rounded-full border border-
|
|
12808
|
+
className: "relative block h-2.5 overflow-hidden rounded-full border border-white/10 bg-black/25 transition-colors group-hover:border-cyan-200/35",
|
|
12485
12809
|
role: "meter",
|
|
12486
12810
|
"aria-label": ariaLabel,
|
|
12487
12811
|
"aria-valuemin": 0,
|
|
@@ -12518,7 +12842,7 @@ function SessionModelContextRow({ summary }) {
|
|
|
12518
12842
|
const openLatestContext = () => {
|
|
12519
12843
|
openLogContext(summary.latest.logId);
|
|
12520
12844
|
};
|
|
12521
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-x-4 gap-y-2 border-t border-
|
|
12845
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-x-4 gap-y-2 border-t border-white/10 py-2 first:border-t-0 lg:grid-cols-[minmax(180px,1fr)_minmax(260px,1fr)_minmax(260px,1.4fr)]", children: [
|
|
12522
12846
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
|
|
12523
12847
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
12524
12848
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -12576,7 +12900,7 @@ function SessionModelContextRow({ summary }) {
|
|
|
12576
12900
|
{
|
|
12577
12901
|
className: cn(
|
|
12578
12902
|
"size-3",
|
|
12579
|
-
trend !== null && trend > 0 ? "text-amber-300" : "text-
|
|
12903
|
+
trend !== null && trend > 0 ? "text-amber-300" : "text-cyan-300"
|
|
12580
12904
|
)
|
|
12581
12905
|
}
|
|
12582
12906
|
),
|
|
@@ -12615,7 +12939,7 @@ function SessionContextSummaryPanel({
|
|
|
12615
12939
|
summary
|
|
12616
12940
|
}) {
|
|
12617
12941
|
if (summary.models.length === 0) return null;
|
|
12618
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 border-t border-
|
|
12942
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 border-t border-white/10 pt-2", children: [
|
|
12619
12943
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [
|
|
12620
12944
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[11px] font-semibold uppercase tracking-normal text-muted-foreground", children: "Session Context" }),
|
|
12621
12945
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono text-[10px] text-muted-foreground", children: [
|
|
@@ -12663,13 +12987,13 @@ function SessionContextBar({
|
|
|
12663
12987
|
setTimeout(() => setCopied(false), 2e3);
|
|
12664
12988
|
});
|
|
12665
12989
|
}, []);
|
|
12666
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
12990
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mb-3 rounded-[8px] px-3 py-2 text-xs", children: [
|
|
12667
12991
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
12668
12992
|
showBackLink && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12669
12993
|
"a",
|
|
12670
12994
|
{
|
|
12671
12995
|
href: "/",
|
|
12672
|
-
className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:
|
|
12996
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
|
|
12673
12997
|
"aria-label": "Back to all sessions",
|
|
12674
12998
|
title: "Back to all sessions",
|
|
12675
12999
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "size-3.5" })
|
|
@@ -12707,7 +13031,7 @@ function SessionContextBar({
|
|
|
12707
13031
|
{
|
|
12708
13032
|
type: "button",
|
|
12709
13033
|
onClick: () => setDetailsOpen((value) => !value),
|
|
12710
|
-
className: "inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md
|
|
13034
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md px-2.5 font-mono text-[11px] text-muted-foreground transition-colors hover:text-foreground",
|
|
12711
13035
|
"aria-expanded": detailsOpen,
|
|
12712
13036
|
title: detailsOpen ? "Hide context details" : "Show context details",
|
|
12713
13037
|
children: [
|
|
@@ -12721,7 +13045,7 @@ function SessionContextBar({
|
|
|
12721
13045
|
{
|
|
12722
13046
|
type: "button",
|
|
12723
13047
|
onClick: handleCopyLink,
|
|
12724
|
-
className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:
|
|
13048
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
|
|
12725
13049
|
"aria-label": copied ? "Copied session link" : "Copy session link",
|
|
12726
13050
|
title: copied ? "Copied session link" : "Copy session link",
|
|
12727
13051
|
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
|
|
@@ -12741,6 +13065,7 @@ function ProxyViewer({
|
|
|
12741
13065
|
onModelChange,
|
|
12742
13066
|
onClearAll,
|
|
12743
13067
|
onClearGroup,
|
|
13068
|
+
onNotify,
|
|
12744
13069
|
onImportLogs,
|
|
12745
13070
|
viewMode,
|
|
12746
13071
|
captureMode,
|
|
@@ -12794,13 +13119,17 @@ function ProxyViewer({
|
|
|
12794
13119
|
try {
|
|
12795
13120
|
const result = await exportLogsAsZip(logs, mode);
|
|
12796
13121
|
if (!result.ok) {
|
|
12797
|
-
|
|
13122
|
+
if (onNotify !== void 0) {
|
|
13123
|
+
onNotify({ message: result.message, tone: "error" });
|
|
13124
|
+
} else {
|
|
13125
|
+
setExportError(result.message);
|
|
13126
|
+
}
|
|
12798
13127
|
}
|
|
12799
13128
|
} finally {
|
|
12800
13129
|
setExporting(null);
|
|
12801
13130
|
}
|
|
12802
13131
|
},
|
|
12803
|
-
[logs]
|
|
13132
|
+
[logs, onNotify]
|
|
12804
13133
|
);
|
|
12805
13134
|
const handleImportClick = reactExports.useCallback(() => {
|
|
12806
13135
|
importInputRef.current?.click();
|
|
@@ -12815,16 +13144,24 @@ function ProxyViewer({
|
|
|
12815
13144
|
setImportStatus(null);
|
|
12816
13145
|
void onImportLogs(file).then((result) => {
|
|
12817
13146
|
const skipped = result.skipped > 0 ? `, skipped ${String(result.skipped)}` : "";
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
13147
|
+
const message = `Imported ${String(result.imported)} logs as ${result.sessionId}${skipped}.`;
|
|
13148
|
+
if (onNotify !== void 0) {
|
|
13149
|
+
onNotify({ message, tone: "success" });
|
|
13150
|
+
} else {
|
|
13151
|
+
setImportStatus(message);
|
|
13152
|
+
}
|
|
12821
13153
|
}).catch((err) => {
|
|
12822
|
-
|
|
13154
|
+
const message = err instanceof Error ? err.message : "Failed to import logs";
|
|
13155
|
+
if (onNotify !== void 0) {
|
|
13156
|
+
onNotify({ message, tone: "error" });
|
|
13157
|
+
} else {
|
|
13158
|
+
setImportError(message);
|
|
13159
|
+
}
|
|
12823
13160
|
}).finally(() => {
|
|
12824
13161
|
setImporting(false);
|
|
12825
13162
|
});
|
|
12826
13163
|
},
|
|
12827
|
-
[onImportLogs]
|
|
13164
|
+
[onImportLogs, onNotify]
|
|
12828
13165
|
);
|
|
12829
13166
|
reactExports.useEffect(() => {
|
|
12830
13167
|
setComparePair(null);
|
|
@@ -12869,38 +13206,38 @@ function ProxyViewer({
|
|
|
12869
13206
|
},
|
|
12870
13207
|
[comparisonPredecessors]
|
|
12871
13208
|
);
|
|
12872
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-h-screen w-full
|
|
13209
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-background min-h-screen w-full text-foreground", children: [
|
|
12873
13210
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid min-h-screen w-full grid-cols-1 lg:grid-cols-[340px_minmax(0,1fr)] xl:grid-cols-[360px_minmax(0,1fr)]", children: [
|
|
12874
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "
|
|
13211
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "bg-background border-b lg:sticky lg:top-0 lg:h-screen lg:overflow-y-auto lg:border-b-0 lg:border-r", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 p-4", children: [
|
|
12875
13212
|
/* @__PURE__ */ jsxRuntimeExports.jsx(BrandHeader, { compact: true, crabEntrancePhase }),
|
|
12876
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-2
|
|
12877
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
|
|
12901
|
-
|
|
12902
|
-
] })
|
|
12903
|
-
] }),
|
|
13213
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Session", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
13214
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarMetric, { label: "Requests", value: logs.length }),
|
|
13215
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13216
|
+
SidebarMetric,
|
|
13217
|
+
{
|
|
13218
|
+
label: "Input",
|
|
13219
|
+
value: formatTokens(hasSessionContext ? sessionContextTotalIn : totalIn)
|
|
13220
|
+
}
|
|
13221
|
+
),
|
|
13222
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13223
|
+
SidebarMetric,
|
|
13224
|
+
{
|
|
13225
|
+
label: "Output",
|
|
13226
|
+
value: formatTokens(hasSessionContext ? sessionContextTotalOut : totalOut)
|
|
13227
|
+
}
|
|
13228
|
+
)
|
|
13229
|
+
] }) }),
|
|
13230
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Workspace", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
|
|
13231
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13232
|
+
"div",
|
|
13233
|
+
{
|
|
13234
|
+
className: "truncate font-mono text-xs font-semibold text-cyan-100",
|
|
13235
|
+
title: activeScopeLabel,
|
|
13236
|
+
children: activeScopeLabel
|
|
13237
|
+
}
|
|
13238
|
+
),
|
|
13239
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-[11px] text-muted-foreground", children: isPinnedSessionPage ? "Session workspace" : "Live workspace" })
|
|
13240
|
+
] }) }),
|
|
12904
13241
|
hasSessionContext && sessionContextScope !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12905
13242
|
SessionContextBar,
|
|
12906
13243
|
{
|
|
@@ -12914,26 +13251,25 @@ function ProxyViewer({
|
|
|
12914
13251
|
}
|
|
12915
13252
|
),
|
|
12916
13253
|
hasSessionContext && pinnedSessionId !== void 0 && sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }),
|
|
12917
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
12918
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-semibold uppercase tracking-normal text-muted-foreground", children: "Filters" }),
|
|
13254
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Filters", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
12919
13255
|
!hideSessionFilter && /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedSession, onValueChange: onSessionChange, children: [
|
|
12920
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
|
|
13256
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
|
|
12921
13257
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
12922
13258
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All sessions" }),
|
|
12923
13259
|
sessions.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: s, children: truncateSessionId(s) }, s))
|
|
12924
13260
|
] })
|
|
12925
13261
|
] }),
|
|
12926
13262
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedModel, onValueChange: onModelChange, children: [
|
|
12927
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All models" }) }),
|
|
13263
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All models" }) }),
|
|
12928
13264
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
12929
13265
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All models" }),
|
|
12930
13266
|
models.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: m, children: m }, m))
|
|
12931
13267
|
] })
|
|
12932
13268
|
] })
|
|
12933
|
-
] })
|
|
13269
|
+
] }) })
|
|
12934
13270
|
] }) }),
|
|
12935
13271
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("main", { className: "min-w-0", children: [
|
|
12936
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sticky top-0 z-30 border-b
|
|
13272
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-background/95 shadow-sm sticky top-0 z-30 border-b px-4 py-3 lg:px-5", children: [
|
|
12937
13273
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
12938
13274
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-[180px] flex-1", children: [
|
|
12939
13275
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold text-foreground", children: "Logs" }),
|
|
@@ -12956,7 +13292,7 @@ function ProxyViewer({
|
|
|
12956
13292
|
type: "button",
|
|
12957
13293
|
onClick: handleImportClick,
|
|
12958
13294
|
disabled: importing,
|
|
12959
|
-
className: "inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:
|
|
13295
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
12960
13296
|
title: "Import Agent Inspector export",
|
|
12961
13297
|
children: importing ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Importing..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
12962
13298
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-3.5" }),
|
|
@@ -12973,7 +13309,7 @@ function ProxyViewer({
|
|
|
12973
13309
|
void handleExport("redacted");
|
|
12974
13310
|
},
|
|
12975
13311
|
disabled: exporting !== null,
|
|
12976
|
-
className: "inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:
|
|
13312
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
12977
13313
|
title: "Export redacted logs as JSON ZIP",
|
|
12978
13314
|
children: exporting === "redacted" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
12979
13315
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3.5" }),
|
|
@@ -12989,7 +13325,7 @@ function ProxyViewer({
|
|
|
12989
13325
|
void handleExport("raw");
|
|
12990
13326
|
},
|
|
12991
13327
|
disabled: exporting !== null,
|
|
12992
|
-
className: "inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:
|
|
13328
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
12993
13329
|
title: "Export raw logs without redaction",
|
|
12994
13330
|
children: exporting === "raw" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
12995
13331
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FileBraces, { className: "size-3.5" }),
|
|
@@ -13002,7 +13338,7 @@ function ProxyViewer({
|
|
|
13002
13338
|
{
|
|
13003
13339
|
type: "button",
|
|
13004
13340
|
onClick: onClearAll,
|
|
13005
|
-
className: "inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:
|
|
13341
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:text-foreground",
|
|
13006
13342
|
title: "Clear all logs",
|
|
13007
13343
|
children: [
|
|
13008
13344
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" }),
|
|
@@ -13012,13 +13348,13 @@ function ProxyViewer({
|
|
|
13012
13348
|
)
|
|
13013
13349
|
] }),
|
|
13014
13350
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LogPaginationBar, { logs, pagination, embedded: true }),
|
|
13015
|
-
exportError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: exportError }),
|
|
13016
|
-
importError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: importError }),
|
|
13017
|
-
importStatus !== null && importError === null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-
|
|
13351
|
+
onNotify === void 0 && exportError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: exportError }),
|
|
13352
|
+
onNotify === void 0 && importError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: importError }),
|
|
13353
|
+
onNotify === void 0 && importStatus !== null && importError === null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-cyan-400/25 bg-cyan-500/10 px-3 py-2 text-xs text-cyan-100", children: importStatus })
|
|
13018
13354
|
] }),
|
|
13019
13355
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-4 lg:px-5", children: [
|
|
13020
13356
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SessionOpeningSlate, { stats: slateStats }),
|
|
13021
|
-
logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-xl space-y-4 rounded-
|
|
13357
|
+
logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mx-auto max-w-xl space-y-4 rounded-[8px] px-4 py-8", children: [
|
|
13022
13358
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: isLoading ? "Loading session data..." : "Session not found" }),
|
|
13023
13359
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "inline-block max-w-full rounded bg-muted px-3 py-1 font-mono text-xs break-all", children: truncateSessionId(selectedSession) }),
|
|
13024
13360
|
sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-left", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }) }),
|
|
@@ -13035,7 +13371,7 @@ function ProxyViewer({
|
|
|
13035
13371
|
}
|
|
13036
13372
|
)
|
|
13037
13373
|
] })
|
|
13038
|
-
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-2xl space-y-4 rounded-
|
|
13374
|
+
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mx-auto max-w-2xl space-y-4 rounded-[8px] px-4 py-8", children: [
|
|
13039
13375
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No requests captured yet." }),
|
|
13040
13376
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
13041
13377
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "ANTHROPIC_BASE_URL=http://localhost:25947/proxy <your-tool>" }),
|
|
@@ -13060,8 +13396,7 @@ function ProxyViewer({
|
|
|
13060
13396
|
onCompareWithPrevious: handleCompareWithPrevious,
|
|
13061
13397
|
comparisonPredecessors,
|
|
13062
13398
|
onClearGroup,
|
|
13063
|
-
|
|
13064
|
-
hasPinnedSessionContext: hasSessionContext,
|
|
13399
|
+
defaultExpanded: groups.length === 1,
|
|
13065
13400
|
timeDisplayFormat
|
|
13066
13401
|
}
|
|
13067
13402
|
) }),
|
|
@@ -13084,6 +13419,79 @@ function ProxyViewer({
|
|
|
13084
13419
|
) })
|
|
13085
13420
|
] });
|
|
13086
13421
|
}
|
|
13422
|
+
const TRANSIENT_TOAST_AUTO_DISMISS_MS = 3e3;
|
|
13423
|
+
function createNextTransientToast(previous, input) {
|
|
13424
|
+
return {
|
|
13425
|
+
id: (previous?.id ?? 0) + 1,
|
|
13426
|
+
message: input.message,
|
|
13427
|
+
tone: input.tone ?? "error"
|
|
13428
|
+
};
|
|
13429
|
+
}
|
|
13430
|
+
function useTransientToast() {
|
|
13431
|
+
const [notice, setNotice] = reactExports.useState(null);
|
|
13432
|
+
const showToast = reactExports.useCallback((input) => {
|
|
13433
|
+
setNotice((previous) => createNextTransientToast(previous, input));
|
|
13434
|
+
}, []);
|
|
13435
|
+
const dismissToast = reactExports.useCallback(() => {
|
|
13436
|
+
setNotice(null);
|
|
13437
|
+
}, []);
|
|
13438
|
+
reactExports.useEffect(() => {
|
|
13439
|
+
if (notice === null) return void 0;
|
|
13440
|
+
const timeout = window.setTimeout(() => {
|
|
13441
|
+
setNotice(null);
|
|
13442
|
+
}, TRANSIENT_TOAST_AUTO_DISMISS_MS);
|
|
13443
|
+
return () => {
|
|
13444
|
+
window.clearTimeout(timeout);
|
|
13445
|
+
};
|
|
13446
|
+
}, [notice]);
|
|
13447
|
+
return { notice, showToast, dismissToast };
|
|
13448
|
+
}
|
|
13449
|
+
function TransientToast({
|
|
13450
|
+
notice,
|
|
13451
|
+
onDismiss
|
|
13452
|
+
}) {
|
|
13453
|
+
if (notice === null) return null;
|
|
13454
|
+
const isError = notice.tone === "error";
|
|
13455
|
+
const Icon2 = isError ? TriangleAlert : CircleCheck;
|
|
13456
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13457
|
+
"div",
|
|
13458
|
+
{
|
|
13459
|
+
"aria-atomic": "true",
|
|
13460
|
+
"aria-live": "polite",
|
|
13461
|
+
className: "pointer-events-none fixed top-4 right-4 z-[100] w-[min(calc(100vw-2rem),26rem)]",
|
|
13462
|
+
role: "status",
|
|
13463
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13464
|
+
"div",
|
|
13465
|
+
{
|
|
13466
|
+
className: cn(
|
|
13467
|
+
"pointer-events-auto flex items-start gap-2 rounded-md border px-3 py-2 text-sm shadow-[0_18px_50px_rgba(0,0,0,0.45)] backdrop-blur",
|
|
13468
|
+
isError ? "border-red-400/30 bg-[#16090b]/95 text-red-100" : "border-cyan-300/25 bg-[#071318]/95 text-cyan-100"
|
|
13469
|
+
),
|
|
13470
|
+
children: [
|
|
13471
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13472
|
+
Icon2,
|
|
13473
|
+
{
|
|
13474
|
+
className: cn("mt-0.5 size-4 shrink-0", isError ? "text-red-300" : "text-cyan-200")
|
|
13475
|
+
}
|
|
13476
|
+
),
|
|
13477
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 flex-1 break-words leading-5", children: notice.message }),
|
|
13478
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13479
|
+
"button",
|
|
13480
|
+
{
|
|
13481
|
+
type: "button",
|
|
13482
|
+
className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-current/70 transition-colors hover:bg-white/10 hover:text-current",
|
|
13483
|
+
"aria-label": "Dismiss notification",
|
|
13484
|
+
onClick: onDismiss,
|
|
13485
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" })
|
|
13486
|
+
}
|
|
13487
|
+
)
|
|
13488
|
+
]
|
|
13489
|
+
},
|
|
13490
|
+
notice.id
|
|
13491
|
+
)
|
|
13492
|
+
}
|
|
13493
|
+
);
|
|
13494
|
+
}
|
|
13087
13495
|
const SSEUpdateSchema = union([
|
|
13088
13496
|
object({
|
|
13089
13497
|
type: literal("init"),
|
|
@@ -13196,7 +13604,7 @@ function ProxyViewerContainer({
|
|
|
13196
13604
|
const [allLogs, setAllLogs] = reactExports.useState([]);
|
|
13197
13605
|
const [selectedSession, setSelectedSession] = reactExports.useState(initialSessionId ?? "__all__");
|
|
13198
13606
|
const [selectedModel, setSelectedModel] = reactExports.useState("__all__");
|
|
13199
|
-
const
|
|
13607
|
+
const { notice, showToast, dismissToast } = useTransientToast();
|
|
13200
13608
|
const [streamInitialized, setStreamInitialized] = reactExports.useState(initialSessionId === void 0);
|
|
13201
13609
|
const [logPage, setLogPage] = reactExports.useState(null);
|
|
13202
13610
|
const [sessionPageLoading, setSessionPageLoading] = reactExports.useState(initialSessionId !== void 0);
|
|
@@ -13209,6 +13617,12 @@ function ProxyViewerContainer({
|
|
|
13209
13617
|
const logIndexRef = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
13210
13618
|
const pendingUpdatesRef = reactExports.useRef([]);
|
|
13211
13619
|
const flushTimerRef = reactExports.useRef(null);
|
|
13620
|
+
const showErrorToast = reactExports.useCallback(
|
|
13621
|
+
(message) => {
|
|
13622
|
+
showToast({ message, tone: "error" });
|
|
13623
|
+
},
|
|
13624
|
+
[showToast]
|
|
13625
|
+
);
|
|
13212
13626
|
const logs = reactExports.useMemo(
|
|
13213
13627
|
() => filterLogs(allLogs, selectedSession, selectedModel),
|
|
13214
13628
|
[allLogs, selectedSession, selectedModel]
|
|
@@ -13264,7 +13678,7 @@ function ProxyViewerContainer({
|
|
|
13264
13678
|
const parsed = JSON.parse(rawData);
|
|
13265
13679
|
const updateResult = SSEUpdateSchema.safeParse(parsed);
|
|
13266
13680
|
if (!updateResult.success) {
|
|
13267
|
-
|
|
13681
|
+
showErrorToast("Failed to parse SSE data");
|
|
13268
13682
|
return;
|
|
13269
13683
|
}
|
|
13270
13684
|
const update = updateResult.data;
|
|
@@ -13278,16 +13692,16 @@ function ProxyViewerContainer({
|
|
|
13278
13692
|
logIndexRef.current = buildLogIndex(nextLogs);
|
|
13279
13693
|
setAllLogs(nextLogs);
|
|
13280
13694
|
setStreamInitialized(true);
|
|
13281
|
-
|
|
13695
|
+
dismissToast();
|
|
13282
13696
|
} else if (update.type === "update") {
|
|
13283
13697
|
scheduleUpdate(update.log);
|
|
13284
13698
|
}
|
|
13285
13699
|
} catch {
|
|
13286
|
-
|
|
13700
|
+
showErrorToast("Failed to parse SSE data");
|
|
13287
13701
|
}
|
|
13288
13702
|
};
|
|
13289
13703
|
es.onerror = () => {
|
|
13290
|
-
|
|
13704
|
+
showErrorToast("SSE connection lost, reconnecting...");
|
|
13291
13705
|
setStreamInitialized(true);
|
|
13292
13706
|
es.close();
|
|
13293
13707
|
if (reconnectTimeoutRef.current !== null) {
|
|
@@ -13295,14 +13709,14 @@ function ProxyViewerContainer({
|
|
|
13295
13709
|
}
|
|
13296
13710
|
reconnectTimeoutRef.current = setTimeout(connectSSE, 3e3);
|
|
13297
13711
|
};
|
|
13298
|
-
}, [initialSessionId, scheduleUpdate]);
|
|
13712
|
+
}, [dismissToast, initialSessionId, scheduleUpdate, showErrorToast]);
|
|
13299
13713
|
const loadSessionPage = reactExports.useCallback(
|
|
13300
13714
|
(request) => {
|
|
13301
13715
|
if (initialSessionId === void 0) return;
|
|
13302
13716
|
const requestId = sessionPageRequestIdRef.current + 1;
|
|
13303
13717
|
sessionPageRequestIdRef.current = requestId;
|
|
13304
13718
|
setSessionPageLoading(true);
|
|
13305
|
-
|
|
13719
|
+
dismissToast();
|
|
13306
13720
|
void fetchJson(buildSessionLogsPageUrl(initialSessionId, request), LogCursorPageSchema).then((page) => {
|
|
13307
13721
|
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
13308
13722
|
const nextLogs = page.logs;
|
|
@@ -13311,16 +13725,16 @@ function ProxyViewerContainer({
|
|
|
13311
13725
|
setLogPage(page);
|
|
13312
13726
|
setSelectedSession(initialSessionId);
|
|
13313
13727
|
setSessionPageLoading(false);
|
|
13314
|
-
|
|
13728
|
+
dismissToast();
|
|
13315
13729
|
}).catch((err) => {
|
|
13316
13730
|
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
13317
13731
|
setAllLogs([]);
|
|
13318
13732
|
setLogPage(null);
|
|
13319
13733
|
setSessionPageLoading(false);
|
|
13320
|
-
|
|
13734
|
+
showErrorToast(err instanceof Error ? err.message : "Failed to load session logs");
|
|
13321
13735
|
});
|
|
13322
13736
|
},
|
|
13323
|
-
[initialSessionId]
|
|
13737
|
+
[dismissToast, initialSessionId, showErrorToast]
|
|
13324
13738
|
);
|
|
13325
13739
|
reactExports.useEffect(() => {
|
|
13326
13740
|
if (initialSessionId === void 0) {
|
|
@@ -13426,64 +13840,70 @@ function ProxyViewerContainer({
|
|
|
13426
13840
|
}
|
|
13427
13841
|
});
|
|
13428
13842
|
if (!res.ok) {
|
|
13429
|
-
|
|
13843
|
+
showErrorToast("Failed to clear logs");
|
|
13430
13844
|
return;
|
|
13431
13845
|
}
|
|
13432
13846
|
logIndexRef.current.clear();
|
|
13433
13847
|
setAllLogs([]);
|
|
13434
|
-
|
|
13848
|
+
dismissToast();
|
|
13435
13849
|
} catch (err) {
|
|
13436
|
-
|
|
13850
|
+
showErrorToast(err instanceof Error ? err.message : "Unknown error clearing logs");
|
|
13437
13851
|
}
|
|
13438
13852
|
})();
|
|
13439
|
-
}, [allLogs, initialSessionId]);
|
|
13440
|
-
const handleClearGroup = reactExports.useCallback(
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13446
|
-
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13853
|
+
}, [allLogs, dismissToast, initialSessionId, showErrorToast]);
|
|
13854
|
+
const handleClearGroup = reactExports.useCallback(
|
|
13855
|
+
(ids) => {
|
|
13856
|
+
if (ids.length === 0) return;
|
|
13857
|
+
void (async () => {
|
|
13858
|
+
try {
|
|
13859
|
+
const res = await fetch("/api/logs", {
|
|
13860
|
+
method: "DELETE",
|
|
13861
|
+
headers: { "Content-Type": "application/json" },
|
|
13862
|
+
body: JSON.stringify({ ids })
|
|
13863
|
+
});
|
|
13864
|
+
if (!res.ok) {
|
|
13865
|
+
showErrorToast("Failed to clear group");
|
|
13866
|
+
return;
|
|
13867
|
+
}
|
|
13868
|
+
const idSet = new Set(ids);
|
|
13869
|
+
setAllLogs((prev) => {
|
|
13870
|
+
const remaining = prev.filter((l) => !idSet.has(l.id));
|
|
13871
|
+
logIndexRef.current = buildLogIndex(remaining);
|
|
13872
|
+
return remaining;
|
|
13873
|
+
});
|
|
13874
|
+
dismissToast();
|
|
13875
|
+
} catch (err) {
|
|
13876
|
+
showErrorToast(err instanceof Error ? err.message : "Unknown error clearing group");
|
|
13452
13877
|
}
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
);
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
setSelectedModel("__all__");
|
|
13483
|
-
setLogPage(null);
|
|
13484
|
-
setError(null);
|
|
13485
|
-
return result;
|
|
13486
|
-
}, []);
|
|
13878
|
+
})();
|
|
13879
|
+
},
|
|
13880
|
+
[dismissToast, showErrorToast]
|
|
13881
|
+
);
|
|
13882
|
+
const handleImportLogs = reactExports.useCallback(
|
|
13883
|
+
async (file) => {
|
|
13884
|
+
const formData = new FormData();
|
|
13885
|
+
formData.set("file", file);
|
|
13886
|
+
const result = await fetchJson("/api/logs/import", ImportLogsResponseSchema, {
|
|
13887
|
+
method: "POST",
|
|
13888
|
+
body: formData
|
|
13889
|
+
});
|
|
13890
|
+
setAllLogs((prev) => {
|
|
13891
|
+
const importedIds = new Set(result.logs.map((log) => log.id));
|
|
13892
|
+
const next = [...prev.filter((log) => !importedIds.has(log.id)), ...result.logs].sort(
|
|
13893
|
+
(left, right) => left.id - right.id
|
|
13894
|
+
);
|
|
13895
|
+
const trimmed = trimClientLogs(next);
|
|
13896
|
+
logIndexRef.current = buildLogIndex(trimmed);
|
|
13897
|
+
return trimmed;
|
|
13898
|
+
});
|
|
13899
|
+
setSelectedSession(result.sessionId);
|
|
13900
|
+
setSelectedModel("__all__");
|
|
13901
|
+
setLogPage(null);
|
|
13902
|
+
dismissToast();
|
|
13903
|
+
return result;
|
|
13904
|
+
},
|
|
13905
|
+
[dismissToast]
|
|
13906
|
+
);
|
|
13487
13907
|
const { strip, captureMode, slowResponseThresholdSeconds, timeDisplayFormat } = useStripConfig();
|
|
13488
13908
|
const viewMode = captureMode;
|
|
13489
13909
|
const loadOldestPage = reactExports.useCallback(() => {
|
|
@@ -13529,7 +13949,7 @@ function ProxyViewerContainer({
|
|
|
13529
13949
|
sessionPageLoading
|
|
13530
13950
|
]);
|
|
13531
13951
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
13532
|
-
|
|
13952
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TransientToast, { notice, onDismiss: dismissToast }),
|
|
13533
13953
|
/* @__PURE__ */ jsxRuntimeExports.jsx(OnboardingBanner, {}),
|
|
13534
13954
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13535
13955
|
ProxyViewer,
|
|
@@ -13543,6 +13963,7 @@ function ProxyViewerContainer({
|
|
|
13543
13963
|
onModelChange: setSelectedModel,
|
|
13544
13964
|
onClearAll: handleClearAll,
|
|
13545
13965
|
onClearGroup: handleClearGroup,
|
|
13966
|
+
onNotify: showToast,
|
|
13546
13967
|
onImportLogs: initialSessionId === void 0 ? handleImportLogs : void 0,
|
|
13547
13968
|
isLoading: initialSessionId === void 0 ? !streamInitialized : sessionPageLoading,
|
|
13548
13969
|
pagination,
|