@tonyclaw/llm-inspector 1.14.8 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/assets/index-CMuJQyt1.js +105 -0
- package/.output/public/assets/index-DciyfYBk.css +1 -0
- package/.output/public/assets/{main-CJ4MreBr.js → main-BLYgekFx.js} +1 -1
- package/.output/server/_libs/lucide-react.mjs +85 -111
- package/.output/server/_libs/radix-ui__react-id.mjs +1 -1
- package/.output/server/_ssr/{index-9uTJ4xYR.mjs → index-P66uoVEU.mjs} +677 -304
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-BKnjB_zi.mjs → router-DpLCKk51.mjs} +45 -14
- package/.output/server/{_tanstack-start-manifest_v-IsglLVKy.mjs → _tanstack-start-manifest_v-C9Wq6YdJ.mjs} +1 -1
- package/.output/server/index.mjs +22 -22
- package/package.json +1 -1
- package/src/components/ProxyViewer.tsx +99 -180
- package/src/components/proxy-viewer/ConversationGroup.tsx +70 -66
- package/src/components/proxy-viewer/ConversationHeader.tsx +15 -39
- package/src/components/proxy-viewer/LogEntry.tsx +68 -9
- package/src/components/proxy-viewer/LogEntryHeader.tsx +62 -75
- package/src/components/proxy-viewer/ThreadConnector.tsx +78 -65
- package/src/components/proxy-viewer/TurnGroup.tsx +83 -0
- package/src/components/ui/crab-variants.tsx +456 -0
- package/src/lib/stopReason.ts +7 -6
- package/src/proxy/formats/anthropic/handler.ts +2 -5
- package/src/proxy/formats/openai/handler.ts +33 -7
- package/src/proxy/formats/openai/schemas.ts +1 -0
- package/src/proxy/formats/openai/stream.ts +24 -0
- package/src/proxy/handler.ts +8 -2
- package/src/proxy/schemas.ts +6 -3
- package/styles/globals.css +38 -0
- package/.output/public/assets/index-CdnotuLh.js +0 -105
- package/.output/public/assets/index-vP91146S.css +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
|
|
2
|
-
import { C as CapturedLogSchema, a as parseRequest,
|
|
2
|
+
import { C as CapturedLogSchema, a as parseRequest, R as RuntimeConfigSchema, c as createPendingProviderTestResults, P as ProviderTestResultsSchema, b as createFailedProviderTestResults, d as ProviderConfigSchema, O as OpenAIRequestSchema, p as parseOpenAIResponse, I as InspectorResponseSchema, s as stripClaudeCodeBillingHeader } from "./router-DpLCKk51.mjs";
|
|
3
3
|
import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
|
|
4
4
|
import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
5
5
|
import { c as clsx } from "../_libs/clsx.mjs";
|
|
@@ -8,13 +8,13 @@ import { J as JSZip } from "../_libs/jszip.mjs";
|
|
|
8
8
|
import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
9
9
|
import { d as diffLines, a as diffJson } from "../_libs/diff.mjs";
|
|
10
10
|
import { R as Root, T as Trigger$2, C as Content, a as Close, b as Title, P as Portal$2, O as Overlay } from "../_libs/radix-ui__react-dialog.mjs";
|
|
11
|
-
import { R as Root2, T as Trigger
|
|
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
12
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
13
|
-
import { D as Download,
|
|
13
|
+
import { D as Download, S as Settings, C as ChevronDown, a as Check, X, U as Upload, b as Scan, P as Plus, c as Copy, d as CircleAlert, e as ChevronUp, L as LoaderCircle, f as ChevronRight, g as User, h as Clock, M as MessageSquare, Z as Zap, R as Rows3, i as Columns2, j as Minus, k as Pencil, E as Equal, l as EyeOff, m as Eye, n as ExternalLink, o as RotateCw, T as Trash2, G as GitCompareArrows, p as RotateCcw, q as CircleCheckBig, W as Wrench, r as Globe, F as FileTerminal, s as Radio, t as CircleQuestionMark, u as Server, v as Gauge, w as Lock, x as Wifi, y as WifiOff, A as ArrowUp, z as ArrowDown, B as TriangleAlert, H as CircleStop, I as ChevronsUp, J as ChevronsDown, K as Brain, N as Terminal } from "../_libs/lucide-react.mjs";
|
|
14
14
|
import { M as Markdown } from "../_libs/react-markdown.mjs";
|
|
15
15
|
import { a as array, b as string, u as union, d as object, l as literal, n as number, c as boolean, _ as _enum } from "../_libs/zod.mjs";
|
|
16
|
-
import { P as Provider, R as Root3, T as Trigger, a as Portal, C as Content2, A as Arrow2 } from "../_libs/radix-ui__react-tooltip.mjs";
|
|
17
|
-
import { R as Root2$1, L as List
|
|
16
|
+
import { P as Provider, R as Root3, T as Trigger$1, a as Portal$1, C as Content2$1, A as Arrow2 } from "../_libs/radix-ui__react-tooltip.mjs";
|
|
17
|
+
import { R as Root2$1, L as List, T as Trigger$3, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
|
|
18
18
|
import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
|
|
19
19
|
import { R as Root$1 } from "../_libs/radix-ui__react-separator.mjs";
|
|
20
20
|
import { R as Root$2, C as CollapsibleTrigger$1, a as CollapsibleContent$1 } from "../_libs/radix-ui__react-collapsible.mjs";
|
|
@@ -269,7 +269,7 @@ function Tooltip({ ...props }) {
|
|
|
269
269
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root3, { "data-slot": "tooltip", ...props });
|
|
270
270
|
}
|
|
271
271
|
function TooltipTrigger({ ...props }) {
|
|
272
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
272
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger$1, { "data-slot": "tooltip-trigger", ...props });
|
|
273
273
|
}
|
|
274
274
|
function TooltipContent({
|
|
275
275
|
className,
|
|
@@ -277,8 +277,8 @@ function TooltipContent({
|
|
|
277
277
|
children,
|
|
278
278
|
...props
|
|
279
279
|
}) {
|
|
280
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
281
|
-
Content2,
|
|
280
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
281
|
+
Content2$1,
|
|
282
282
|
{
|
|
283
283
|
"data-slot": "tooltip-content",
|
|
284
284
|
sideOffset,
|
|
@@ -333,7 +333,7 @@ async function exportLogsAsZip(logs) {
|
|
|
333
333
|
document.body.removeChild(anchor);
|
|
334
334
|
URL.revokeObjectURL(url);
|
|
335
335
|
}
|
|
336
|
-
const version = "1.
|
|
336
|
+
const version = "1.15.0";
|
|
337
337
|
const packageJson = {
|
|
338
338
|
version
|
|
339
339
|
};
|
|
@@ -348,13 +348,13 @@ function extractStopReason(log) {
|
|
|
348
348
|
json = JSON.parse(json);
|
|
349
349
|
}
|
|
350
350
|
if (!isRecord(json)) return null;
|
|
351
|
-
if (
|
|
351
|
+
if (typeof json.stop_reason === "string") {
|
|
352
352
|
if (json.stop_reason === "end_turn" || json.stop_reason === "tool_use") {
|
|
353
353
|
return json.stop_reason;
|
|
354
354
|
}
|
|
355
355
|
return null;
|
|
356
356
|
}
|
|
357
|
-
if (
|
|
357
|
+
if (Array.isArray(json.choices) && json.choices.length > 0 && isRecord(json.choices[0]) && typeof json.choices[0].finish_reason === "string" && json.choices[0].finish_reason === "stop") {
|
|
358
358
|
return "stop";
|
|
359
359
|
}
|
|
360
360
|
return null;
|
|
@@ -362,6 +362,9 @@ function extractStopReason(log) {
|
|
|
362
362
|
return null;
|
|
363
363
|
}
|
|
364
364
|
}
|
|
365
|
+
function isTurnBoundary(stopReason) {
|
|
366
|
+
return stopReason === "end_turn" || stopReason === "stop";
|
|
367
|
+
}
|
|
365
368
|
const badgeVariants = cva(
|
|
366
369
|
"inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
|
367
370
|
{
|
|
@@ -418,8 +421,7 @@ function ConversationHeader({
|
|
|
418
421
|
onToggle,
|
|
419
422
|
hideApiFormat = false,
|
|
420
423
|
isLoading = false,
|
|
421
|
-
|
|
422
|
-
onToggleViewMode
|
|
424
|
+
userAgent
|
|
423
425
|
}) {
|
|
424
426
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
425
427
|
"div",
|
|
@@ -441,22 +443,6 @@ function ConversationHeader({
|
|
|
441
443
|
},
|
|
442
444
|
children: [
|
|
443
445
|
expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 text-muted-foreground shrink-0" }) : isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin text-muted-foreground shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" }),
|
|
444
|
-
expanded && onToggleViewMode !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
445
|
-
"button",
|
|
446
|
-
{
|
|
447
|
-
type: "button",
|
|
448
|
-
onClick: (e) => {
|
|
449
|
-
e.stopPropagation();
|
|
450
|
-
onToggleViewMode();
|
|
451
|
-
},
|
|
452
|
-
className: cn(
|
|
453
|
-
"px-1.5 py-0.5 rounded text-[10px] font-mono transition-colors shrink-0 cursor-pointer",
|
|
454
|
-
viewMode === "thread" ? "bg-amber-500/15 text-amber-400 border border-amber-500/30" : "bg-muted text-muted-foreground border border-border hover:text-foreground"
|
|
455
|
-
),
|
|
456
|
-
title: viewMode === "thread" ? "Thread view — click for flat view" : "Flat view — click for thread view",
|
|
457
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(GitBranch, { className: "size-3" })
|
|
458
|
-
}
|
|
459
|
-
),
|
|
460
446
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
461
447
|
"span",
|
|
462
448
|
{
|
|
@@ -465,6 +451,17 @@ function ConversationHeader({
|
|
|
465
451
|
children: conversationId.length > 24 ? conversationId.slice(0, 12) + "…" + conversationId.slice(-12) : conversationId
|
|
466
452
|
}
|
|
467
453
|
),
|
|
454
|
+
userAgent !== null && userAgent !== void 0 && userAgent !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
455
|
+
"span",
|
|
456
|
+
{
|
|
457
|
+
className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0",
|
|
458
|
+
title: userAgent,
|
|
459
|
+
children: [
|
|
460
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(User, { className: "size-3" }),
|
|
461
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[120px]", children: userAgent })
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
),
|
|
468
465
|
!hideApiFormat && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
469
466
|
Badge,
|
|
470
467
|
{
|
|
@@ -983,7 +980,7 @@ function TabsList({
|
|
|
983
980
|
...props
|
|
984
981
|
}) {
|
|
985
982
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
986
|
-
List
|
|
983
|
+
List,
|
|
987
984
|
{
|
|
988
985
|
"data-slot": "tabs-list",
|
|
989
986
|
"data-variant": variant,
|
|
@@ -1455,16 +1452,15 @@ function CacheTrendIndicator({ trend }) {
|
|
|
1455
1452
|
}
|
|
1456
1453
|
const LogEntryHeader = reactExports.memo(function({
|
|
1457
1454
|
log,
|
|
1458
|
-
|
|
1455
|
+
messageCount = null,
|
|
1456
|
+
toolCount = null,
|
|
1459
1457
|
expanded,
|
|
1460
1458
|
onToggle,
|
|
1461
|
-
|
|
1459
|
+
responseToolNames = null,
|
|
1462
1460
|
cacheTrend = null
|
|
1463
1461
|
}) {
|
|
1464
1462
|
const statusCategory = getStatusCategory(log.responseStatus);
|
|
1465
1463
|
const hasTokens = log.inputTokens !== null || log.outputTokens !== null;
|
|
1466
|
-
const messageCount = parsedRequest !== null ? parsedRequest.messages.length : null;
|
|
1467
|
-
const toolCount = parsedRequest !== null && parsedRequest.tools !== void 0 && parsedRequest.tools.length > 0 ? parsedRequest.tools.length : null;
|
|
1468
1464
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1469
1465
|
"div",
|
|
1470
1466
|
{
|
|
@@ -1491,20 +1487,14 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
1491
1487
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: detectProvider(log.model), className: "size-4" }) }) }),
|
|
1492
1488
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: log.model })
|
|
1493
1489
|
] }) }),
|
|
1494
|
-
|
|
1490
|
+
statusCategory !== "success" && /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: statusCategory === "server_error" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1495
1491
|
Badge,
|
|
1496
1492
|
{
|
|
1497
|
-
variant: "
|
|
1498
|
-
className:
|
|
1499
|
-
|
|
1500
|
-
log.apiFormat === "openai" && "border-blue-500/40 text-blue-400",
|
|
1501
|
-
log.apiFormat === "anthropic" && "border-orange-500/40 text-orange-400",
|
|
1502
|
-
log.apiFormat === "unknown" && "border-muted text-muted-foreground"
|
|
1503
|
-
),
|
|
1504
|
-
children: log.apiFormat === "anthropic" ? "Anthropic" : log.apiFormat === "openai" ? "OpenAI" : "Unknown"
|
|
1493
|
+
variant: "destructive",
|
|
1494
|
+
className: "text-[10px] px-1.5 py-0 h-5 font-mono tabular-nums",
|
|
1495
|
+
children: log.responseStatus
|
|
1505
1496
|
}
|
|
1506
|
-
)
|
|
1507
|
-
statusCategory === "server_error" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "destructive", className: "text-[10px] px-1.5 py-0 h-5 font-mono tabular-nums", children: log.responseStatus }) : statusCategory === "pending" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1497
|
+
) : statusCategory === "pending" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1508
1498
|
Badge,
|
|
1509
1499
|
{
|
|
1510
1500
|
variant: "outline",
|
|
@@ -1524,8 +1514,8 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
1524
1514
|
),
|
|
1525
1515
|
children: log.responseStatus
|
|
1526
1516
|
}
|
|
1527
|
-
),
|
|
1528
|
-
log.elapsedMs !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0", children: [
|
|
1517
|
+
) }),
|
|
1518
|
+
log.elapsedMs !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden xl:flex items-center gap-1 text-muted-foreground text-xs shrink-0", children: [
|
|
1529
1519
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
1530
1520
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed(log.elapsedMs) })
|
|
1531
1521
|
] }),
|
|
@@ -1583,10 +1573,20 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
1583
1573
|
] }) }),
|
|
1584
1574
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Number of tools defined in the request" })
|
|
1585
1575
|
] }) }),
|
|
1576
|
+
responseToolNames !== null && responseToolNames.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
1577
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-amber-400/80 text-xs shrink-0", children: [
|
|
1578
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3" }),
|
|
1579
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[160px]", children: responseToolNames.join(", ") })
|
|
1580
|
+
] }) }),
|
|
1581
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { children: [
|
|
1582
|
+
"Tools called by model: ",
|
|
1583
|
+
responseToolNames.join(", ")
|
|
1584
|
+
] })
|
|
1585
|
+
] }) }),
|
|
1586
1586
|
log.origin !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1587
1587
|
"span",
|
|
1588
1588
|
{
|
|
1589
|
-
className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0",
|
|
1589
|
+
className: "hidden xl:flex items-center gap-1 text-muted-foreground text-xs shrink-0",
|
|
1590
1590
|
title: `Origin: ${log.origin}`,
|
|
1591
1591
|
children: [
|
|
1592
1592
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Globe, { className: "size-3" }),
|
|
@@ -1594,19 +1594,8 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
1594
1594
|
]
|
|
1595
1595
|
}
|
|
1596
1596
|
),
|
|
1597
|
-
log.userAgent !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1598
|
-
"span",
|
|
1599
|
-
{
|
|
1600
|
-
className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0",
|
|
1601
|
-
title: `User-Agent: ${log.userAgent}`,
|
|
1602
|
-
children: [
|
|
1603
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(User, { className: "size-3" }),
|
|
1604
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[150px]", title: log.userAgent, children: log.userAgent })
|
|
1605
|
-
]
|
|
1606
|
-
}
|
|
1607
|
-
),
|
|
1608
1597
|
(log.clientPid !== null || log.clientProjectFolder !== null) && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
1609
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-purple-400/80 text-xs shrink-0", children: [
|
|
1598
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden xl:flex items-center gap-1 text-purple-400/80 text-xs shrink-0", children: [
|
|
1610
1599
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FileTerminal, { className: "size-3" }),
|
|
1611
1600
|
log.clientProjectFolder !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: log.clientProjectFolder }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
1612
1601
|
"PID ",
|
|
@@ -2479,7 +2468,6 @@ function DiffToggleButton({
|
|
|
2479
2468
|
const LogEntry = reactExports.memo(function({
|
|
2480
2469
|
log,
|
|
2481
2470
|
viewMode = "simple",
|
|
2482
|
-
suppressApiFormatBadge = false,
|
|
2483
2471
|
strip,
|
|
2484
2472
|
cacheTrend = null,
|
|
2485
2473
|
onCompareWithPrevious
|
|
@@ -2491,7 +2479,60 @@ const LogEntry = reactExports.memo(function({
|
|
|
2491
2479
|
const [replayOpen, setReplayOpen] = reactExports.useState(false);
|
|
2492
2480
|
const [headersDiff, setHeadersDiff] = reactExports.useState(false);
|
|
2493
2481
|
const [requestDiff, setRequestDiff] = reactExports.useState(false);
|
|
2494
|
-
const
|
|
2482
|
+
const messageCount = reactExports.useMemo(() => {
|
|
2483
|
+
if (log.rawRequestBody === null) return null;
|
|
2484
|
+
if (log.apiFormat === "anthropic") {
|
|
2485
|
+
const parsed = parseRequest(log.rawRequestBody);
|
|
2486
|
+
if (parsed !== null) return parsed.messages.length;
|
|
2487
|
+
} else if (log.apiFormat === "openai") {
|
|
2488
|
+
try {
|
|
2489
|
+
const result = OpenAIRequestSchema.safeParse(JSON.parse(log.rawRequestBody));
|
|
2490
|
+
if (result.success) return result.data.messages.length;
|
|
2491
|
+
} catch {
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
return null;
|
|
2495
|
+
}, [log.rawRequestBody, log.apiFormat]);
|
|
2496
|
+
const toolCount = reactExports.useMemo(() => {
|
|
2497
|
+
if (log.rawRequestBody === null) return null;
|
|
2498
|
+
if (log.apiFormat === "anthropic") {
|
|
2499
|
+
const parsed = parseRequest(log.rawRequestBody);
|
|
2500
|
+
if (parsed !== null && parsed.tools !== void 0 && parsed.tools.length > 0) {
|
|
2501
|
+
return parsed.tools.length;
|
|
2502
|
+
}
|
|
2503
|
+
} else if (log.apiFormat === "openai") {
|
|
2504
|
+
try {
|
|
2505
|
+
const result = OpenAIRequestSchema.safeParse(JSON.parse(log.rawRequestBody));
|
|
2506
|
+
if (result.success && result.data.tools !== void 0 && result.data.tools.length > 0) {
|
|
2507
|
+
return result.data.tools.length;
|
|
2508
|
+
}
|
|
2509
|
+
} catch {
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
return null;
|
|
2513
|
+
}, [log.rawRequestBody, log.apiFormat]);
|
|
2514
|
+
const responseToolNames = reactExports.useMemo(() => {
|
|
2515
|
+
if (log.responseText === null) return null;
|
|
2516
|
+
if (log.apiFormat === "openai") {
|
|
2517
|
+
const parsed = parseOpenAIResponse(log.responseText);
|
|
2518
|
+
if (parsed !== null) {
|
|
2519
|
+
const toolCalls = parsed.choices[0]?.message?.tool_calls;
|
|
2520
|
+
if (toolCalls !== void 0 && toolCalls !== null && toolCalls.length > 0) {
|
|
2521
|
+
return toolCalls.map((tc) => tc.function?.name ?? "?").filter((n) => n !== "");
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
} else if (log.apiFormat === "anthropic") {
|
|
2525
|
+
try {
|
|
2526
|
+
const result = InspectorResponseSchema.safeParse(JSON.parse(log.responseText));
|
|
2527
|
+
if (result.success) {
|
|
2528
|
+
const names = result.data.content.filter((c) => c.type === "tool_use").map((c) => c.name);
|
|
2529
|
+
if (names.length > 0) return names;
|
|
2530
|
+
}
|
|
2531
|
+
} catch {
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
return null;
|
|
2535
|
+
}, [log.responseText, log.apiFormat]);
|
|
2495
2536
|
const strippedRequestBody = reactExports.useMemo(() => {
|
|
2496
2537
|
if (!strip || log.apiFormat !== "anthropic" || log.rawRequestBody === null) {
|
|
2497
2538
|
return null;
|
|
@@ -2537,10 +2578,11 @@ const LogEntry = reactExports.memo(function({
|
|
|
2537
2578
|
LogEntryHeader,
|
|
2538
2579
|
{
|
|
2539
2580
|
log,
|
|
2540
|
-
|
|
2581
|
+
messageCount,
|
|
2582
|
+
toolCount,
|
|
2541
2583
|
expanded,
|
|
2542
2584
|
onToggle: () => setExpanded(!expanded),
|
|
2543
|
-
|
|
2585
|
+
responseToolNames,
|
|
2544
2586
|
cacheTrend
|
|
2545
2587
|
}
|
|
2546
2588
|
),
|
|
@@ -2727,72 +2769,470 @@ const LogEntry = reactExports.memo(function({
|
|
|
2727
2769
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ReplayDialog, { log, open: replayOpen, onOpenChange: setReplayOpen })
|
|
2728
2770
|
] });
|
|
2729
2771
|
});
|
|
2772
|
+
function SvgShell({
|
|
2773
|
+
className,
|
|
2774
|
+
style,
|
|
2775
|
+
d,
|
|
2776
|
+
eyeStalks,
|
|
2777
|
+
eyes,
|
|
2778
|
+
legs,
|
|
2779
|
+
extras
|
|
2780
|
+
}) {
|
|
2781
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2782
|
+
"svg",
|
|
2783
|
+
{
|
|
2784
|
+
viewBox: "0 0 24 24",
|
|
2785
|
+
fill: "none",
|
|
2786
|
+
stroke: "currentColor",
|
|
2787
|
+
strokeWidth: "1.5",
|
|
2788
|
+
strokeLinecap: "round",
|
|
2789
|
+
strokeLinejoin: "round",
|
|
2790
|
+
"aria-hidden": "true",
|
|
2791
|
+
style,
|
|
2792
|
+
className: cn("inline-block size-5", className),
|
|
2793
|
+
children: [
|
|
2794
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d }),
|
|
2795
|
+
eyeStalks,
|
|
2796
|
+
eyes,
|
|
2797
|
+
legs,
|
|
2798
|
+
extras
|
|
2799
|
+
]
|
|
2800
|
+
}
|
|
2801
|
+
);
|
|
2802
|
+
}
|
|
2803
|
+
const StdLegs = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2804
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "6.5", y1: "16", x2: "4.5", y2: "19.5" }),
|
|
2805
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "17.5", x2: "8", y2: "20.5" }),
|
|
2806
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15", y1: "17.5", x2: "16", y2: "20.5" }),
|
|
2807
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17.5", y1: "16", x2: "19.5", y2: "19.5" })
|
|
2808
|
+
] });
|
|
2809
|
+
const ShortLegs = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2810
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7", y1: "16", x2: "5.5", y2: "18.5" }),
|
|
2811
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "17", x2: "8.5", y2: "19.5" }),
|
|
2812
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "17", x2: "15.5", y2: "19.5" }),
|
|
2813
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "16", x2: "18.5", y2: "18.5" })
|
|
2814
|
+
] });
|
|
2815
|
+
function Crab1({ className }) {
|
|
2816
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2817
|
+
SvgShell,
|
|
2818
|
+
{
|
|
2819
|
+
className,
|
|
2820
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
2821
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2822
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
2823
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
2824
|
+
] }),
|
|
2825
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2826
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
2827
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" })
|
|
2828
|
+
] }),
|
|
2829
|
+
legs: StdLegs,
|
|
2830
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2831
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
2832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" })
|
|
2833
|
+
] })
|
|
2834
|
+
}
|
|
2835
|
+
);
|
|
2836
|
+
}
|
|
2837
|
+
function Crab2({ className }) {
|
|
2838
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2839
|
+
SvgShell,
|
|
2840
|
+
{
|
|
2841
|
+
className,
|
|
2842
|
+
d: "M4 13 C4 7 7.5 5.5 12 5.5 C16.5 5.5 20 7 20 13 C20 17.5 16.5 19 12 19 C7.5 19 4 17.5 4 13 Z",
|
|
2843
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2844
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "6.5", x2: "9.5", y2: "4.5" }),
|
|
2845
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "6.5", x2: "14.5", y2: "4.5" })
|
|
2846
|
+
] }),
|
|
2847
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2848
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4", r: "1.1", fill: "currentColor", stroke: "none" }),
|
|
2849
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4", r: "1.1", fill: "currentColor", stroke: "none" })
|
|
2850
|
+
] }),
|
|
2851
|
+
legs: ShortLegs,
|
|
2852
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2853
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C4 9.5 2.5 10 3 12 C3.5 13.5 4.5 13 5 12" }),
|
|
2854
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20 9.5 21.5 10 21 12 C20.5 13.5 19.5 13 19 12" })
|
|
2855
|
+
] })
|
|
2856
|
+
}
|
|
2857
|
+
);
|
|
2858
|
+
}
|
|
2859
|
+
function Crab3({ className }) {
|
|
2860
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2861
|
+
SvgShell,
|
|
2862
|
+
{
|
|
2863
|
+
className,
|
|
2864
|
+
d: "M3 13.5 C3 8 7 6 12 6 C17 6 21 8 21 13.5 C21 17 17 19 12 19 C7 19 3 17 3 13.5 Z",
|
|
2865
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2866
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7", y1: "7", x2: "6.5", y2: "4.5" }),
|
|
2867
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "7", x2: "17.5", y2: "4.5" })
|
|
2868
|
+
] }),
|
|
2869
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2870
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "6.5", cy: "4", r: "0.8", fill: "currentColor", stroke: "none" }),
|
|
2871
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17.5", cy: "4", r: "0.8", fill: "currentColor", stroke: "none" })
|
|
2872
|
+
] }),
|
|
2873
|
+
legs: StdLegs,
|
|
2874
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2875
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M4 12 C2.5 10.5 1 11 1.5 13 C2 14.5 3.5 14 4.5 13" }),
|
|
2876
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M20 12 C21.5 10.5 23 11 22.5 13 C22 14.5 20.5 14 19.5 13" })
|
|
2877
|
+
] })
|
|
2878
|
+
}
|
|
2879
|
+
);
|
|
2880
|
+
}
|
|
2881
|
+
function Crab4({ className }) {
|
|
2882
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2883
|
+
SvgShell,
|
|
2884
|
+
{
|
|
2885
|
+
className,
|
|
2886
|
+
d: "M6 14 C6 8 9 5.5 12 5.5 C15 5.5 18 8 18 14 C18 18 15 20 12 20 C9 20 6 18 6 14 Z",
|
|
2887
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2888
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "6.5", x2: "10", y2: "3.5" }),
|
|
2889
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "6.5", x2: "14", y2: "3.5" })
|
|
2890
|
+
] }),
|
|
2891
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2892
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "10", cy: "3", r: "0.7", fill: "currentColor", stroke: "none" }),
|
|
2893
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14", cy: "3", r: "0.7", fill: "currentColor", stroke: "none" })
|
|
2894
|
+
] }),
|
|
2895
|
+
legs: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2896
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7", y1: "17", x2: "5", y2: "20.5" }),
|
|
2897
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "18.5", x2: "8.5", y2: "21.5" }),
|
|
2898
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "18.5", x2: "15.5", y2: "21.5" }),
|
|
2899
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "17", x2: "19", y2: "20.5" })
|
|
2900
|
+
] }),
|
|
2901
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2902
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6.5 11 C5 8.5 3 9 3.5 11.5 C4 13.5 5 13 6 12" }),
|
|
2903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M17.5 11 C19 8.5 21 9 20.5 11.5 C20 13.5 19 13 18 12" })
|
|
2904
|
+
] })
|
|
2905
|
+
}
|
|
2906
|
+
);
|
|
2907
|
+
}
|
|
2908
|
+
function Crab5({ className }) {
|
|
2909
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2910
|
+
SvgShell,
|
|
2911
|
+
{
|
|
2912
|
+
className,
|
|
2913
|
+
d: "M5 13 C5 9 8 7 12 7 L13 4 L14 7 C16 7 19 9 19 13 C19 16 16 18 13 18 L12 21 L11 18 C8 18 5 16 5 13 Z",
|
|
2914
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2915
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
2916
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
2917
|
+
] }),
|
|
2918
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2919
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.8", fill: "currentColor", stroke: "none" }),
|
|
2920
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.8", fill: "currentColor", stroke: "none" })
|
|
2921
|
+
] }),
|
|
2922
|
+
legs: StdLegs,
|
|
2923
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2924
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
2925
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" })
|
|
2926
|
+
] })
|
|
2927
|
+
}
|
|
2928
|
+
);
|
|
2929
|
+
}
|
|
2930
|
+
function Crab6({ className }) {
|
|
2931
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2932
|
+
SvgShell,
|
|
2933
|
+
{
|
|
2934
|
+
className,
|
|
2935
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
2936
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2937
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
2938
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
2939
|
+
] }),
|
|
2940
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2941
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
2942
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13.5", y1: "4", x2: "15.5", y2: "5" })
|
|
2943
|
+
] }),
|
|
2944
|
+
legs: StdLegs,
|
|
2945
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2946
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
2947
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" })
|
|
2948
|
+
] })
|
|
2949
|
+
}
|
|
2950
|
+
);
|
|
2951
|
+
}
|
|
2952
|
+
function Crab7({ className }) {
|
|
2953
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2954
|
+
SvgShell,
|
|
2955
|
+
{
|
|
2956
|
+
className,
|
|
2957
|
+
d: "M5.5 13.5 C5.5 10 8.5 8 12 8 C15.5 8 18.5 10 18.5 13.5 C18.5 16 15.5 17.5 12 17.5 C8.5 17.5 5.5 16 5.5 13.5 Z",
|
|
2958
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2959
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "8", x2: "10", y2: "6" }),
|
|
2960
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "8", x2: "14", y2: "6" })
|
|
2961
|
+
] }),
|
|
2962
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2963
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "6", x2: "11", y2: "6.5" }),
|
|
2964
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13", y1: "6", x2: "15", y2: "6.5" })
|
|
2965
|
+
] }),
|
|
2966
|
+
legs: ShortLegs,
|
|
2967
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 11.5 C4.5 10.5 3 11 3.5 12.5 C4 13.5 5 13 5.5 12.5" }),
|
|
2969
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M18 11.5 C19.5 10.5 21 11 20.5 12.5 C20 13.5 19 13 18.5 12.5" })
|
|
2970
|
+
] })
|
|
2971
|
+
}
|
|
2972
|
+
);
|
|
2973
|
+
}
|
|
2974
|
+
function Crab8({ className }) {
|
|
2975
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2976
|
+
SvgShell,
|
|
2977
|
+
{
|
|
2978
|
+
className,
|
|
2979
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
2980
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
2982
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
2983
|
+
] }),
|
|
2984
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2985
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.7", fill: "currentColor", stroke: "none" }),
|
|
2986
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.7", fill: "currentColor", stroke: "none" })
|
|
2987
|
+
] }),
|
|
2988
|
+
legs: StdLegs,
|
|
2989
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2990
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
2991
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
2992
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "8.5", y1: "4", x2: "10.5", y2: "4.5" }),
|
|
2993
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15.5", y1: "4", x2: "13.5", y2: "4.5" }),
|
|
2994
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 15.5 C10 14.5 14 14.5 15 15.5" })
|
|
2995
|
+
] })
|
|
2996
|
+
}
|
|
2997
|
+
);
|
|
2998
|
+
}
|
|
2999
|
+
function Crab9({ className }) {
|
|
3000
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3001
|
+
SvgShell,
|
|
3002
|
+
{
|
|
3003
|
+
className,
|
|
3004
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
3005
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3006
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
3007
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
3008
|
+
] }),
|
|
3009
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3010
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "1.2", fill: "none", stroke: "currentColor" }),
|
|
3011
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "1.2", fill: "none", stroke: "currentColor" })
|
|
3012
|
+
] }),
|
|
3013
|
+
legs: StdLegs,
|
|
3014
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3015
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
3016
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
3017
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("ellipse", { cx: "12", cy: "15", rx: "2", ry: "1.5", fill: "currentColor", stroke: "none" })
|
|
3018
|
+
] })
|
|
3019
|
+
}
|
|
3020
|
+
);
|
|
3021
|
+
}
|
|
3022
|
+
function Crab10({ className }) {
|
|
3023
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3024
|
+
SvgShell,
|
|
3025
|
+
{
|
|
3026
|
+
className,
|
|
3027
|
+
d: "M4.5 13 C4.5 8 7.5 6 12 6 C16.5 6 19.5 8 19.5 13 C19.5 17 16.5 18.5 12 18.5 C7.5 18.5 4.5 17 4.5 13 Z",
|
|
3028
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3029
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "7", x2: "9", y2: "5" }),
|
|
3030
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "7", x2: "15", y2: "5" })
|
|
3031
|
+
] }),
|
|
3032
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3033
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9", cy: "4.5", r: "1", fill: "currentColor", stroke: "none" }),
|
|
3034
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "15", cy: "4.5", r: "1", fill: "currentColor", stroke: "none" })
|
|
3035
|
+
] }),
|
|
3036
|
+
legs: StdLegs,
|
|
3037
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3038
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9 2 9.5 2.5 12 C3 14 4 13 5 12" }),
|
|
3039
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9 22 9.5 21.5 12 C21 14 20 13 19 12" }),
|
|
3040
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 14.5 C10 16 14 16 15 14.5" }),
|
|
3041
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "7", cy: "13", r: "1", fill: "currentColor", stroke: "none", opacity: "0.3" }),
|
|
3042
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17", cy: "13", r: "1", fill: "currentColor", stroke: "none", opacity: "0.3" })
|
|
3043
|
+
] })
|
|
3044
|
+
}
|
|
3045
|
+
);
|
|
3046
|
+
}
|
|
3047
|
+
function Crab11({ className }) {
|
|
3048
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3049
|
+
SvgShell,
|
|
3050
|
+
{
|
|
3051
|
+
className,
|
|
3052
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
3053
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3054
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5.5" }),
|
|
3055
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5.5" })
|
|
3056
|
+
] }),
|
|
3057
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3058
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7.5", y1: "5.5", x2: "16.5", y2: "5.5" }),
|
|
3059
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "7", y: "5", width: "4", height: "2", rx: "0.5", fill: "currentColor", stroke: "none" }),
|
|
3060
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "13", y: "5", width: "4", height: "2", rx: "0.5", fill: "currentColor", stroke: "none" })
|
|
3061
|
+
] }),
|
|
3062
|
+
legs: StdLegs,
|
|
3063
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3064
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
3065
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
3066
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9.5 15 C10.5 16 13.5 16 14.5 15" })
|
|
3067
|
+
] })
|
|
3068
|
+
}
|
|
3069
|
+
);
|
|
3070
|
+
}
|
|
3071
|
+
function Crab12({ className }) {
|
|
3072
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3073
|
+
SvgShell,
|
|
3074
|
+
{
|
|
3075
|
+
className,
|
|
3076
|
+
d: "M7 13.5 C7 10.5 9.5 9 12 9 C14.5 9 17 10.5 17 13.5 C17 16 14.5 17.5 12 17.5 C9.5 17.5 7 16 7 13.5 Z",
|
|
3077
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3078
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10.5", y1: "9.5", x2: "10.5", y2: "8" }),
|
|
3079
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13.5", y1: "9.5", x2: "13.5", y2: "8" })
|
|
3080
|
+
] }),
|
|
3081
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3082
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "10.5", cy: "7.5", r: "0.8", fill: "currentColor", stroke: "none" }),
|
|
3083
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "13.5", cy: "7.5", r: "0.8", fill: "currentColor", stroke: "none" })
|
|
3084
|
+
] }),
|
|
3085
|
+
legs: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3086
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "8", y1: "16", x2: "6.5", y2: "18" }),
|
|
3087
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "17", x2: "9.5", y2: "19" }),
|
|
3088
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "17", x2: "14.5", y2: "19" }),
|
|
3089
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "16", y1: "16", x2: "17.5", y2: "18" })
|
|
3090
|
+
] }),
|
|
3091
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3092
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7.5 12 C6.5 11 5.5 11.5 6 13 C6.5 14 7 13.5 7.5 13" }),
|
|
3093
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16.5 12 C17.5 11 18.5 11.5 18 13 C17.5 14 17 13.5 16.5 13" })
|
|
3094
|
+
] })
|
|
3095
|
+
}
|
|
3096
|
+
);
|
|
3097
|
+
}
|
|
3098
|
+
const crabVariants = [
|
|
3099
|
+
Crab1,
|
|
3100
|
+
Crab2,
|
|
3101
|
+
Crab3,
|
|
3102
|
+
Crab4,
|
|
3103
|
+
Crab5,
|
|
3104
|
+
Crab6,
|
|
3105
|
+
Crab7,
|
|
3106
|
+
Crab8,
|
|
3107
|
+
Crab9,
|
|
3108
|
+
Crab10,
|
|
3109
|
+
Crab11,
|
|
3110
|
+
Crab12
|
|
3111
|
+
];
|
|
3112
|
+
function getCrabVariant(index) {
|
|
3113
|
+
return crabVariants[Math.abs(index) % crabVariants.length] ?? Crab1;
|
|
3114
|
+
}
|
|
2730
3115
|
function ThreadConnector({
|
|
2731
3116
|
stopReason,
|
|
2732
3117
|
isPending,
|
|
2733
3118
|
isFirst,
|
|
2734
|
-
|
|
3119
|
+
isTurnStart,
|
|
3120
|
+
crabIndex = 0,
|
|
3121
|
+
collapsible = false,
|
|
3122
|
+
collapsed = false,
|
|
3123
|
+
onToggle
|
|
2735
3124
|
}) {
|
|
2736
3125
|
const isBoundary = stopReason === "end_turn" || stopReason === "stop";
|
|
2737
|
-
const
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute left-1/2 -translate-x-1/2 w-0.5 top-0 flex flex-col items-center", children: [
|
|
2744
|
-
!isFirst && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2745
|
-
"div",
|
|
2746
|
-
{
|
|
2747
|
-
className: cn("w-0.5 grow", "bg-muted-foreground/30", "h-4"),
|
|
2748
|
-
style: { minHeight: "0.5rem" }
|
|
2749
|
-
}
|
|
2750
|
-
),
|
|
2751
|
-
isFirst && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4" })
|
|
2752
|
-
] }),
|
|
2753
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-1/2 -translate-x-1/2 top-4 flex items-center justify-center z-10", children: isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2754
|
-
"div",
|
|
3126
|
+
const isRunning = isPending && !isBoundary;
|
|
3127
|
+
const Crab = reactExports.useMemo(() => getCrabVariant(crabIndex), [crabIndex]);
|
|
3128
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center w-6 shrink-0", children: [
|
|
3129
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center h-2.5", children: !isFirst && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-0.5 bg-muted-foreground/30" }) }),
|
|
3130
|
+
collapsible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3131
|
+
"button",
|
|
2755
3132
|
{
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
),
|
|
2761
|
-
title: stopReason === "end_turn" ? "End of Turn (Anthropic)" : "End of Turn (OpenAI)"
|
|
3133
|
+
type: "button",
|
|
3134
|
+
onClick: onToggle,
|
|
3135
|
+
title: collapsed ? "Expand turn" : "Collapse turn",
|
|
3136
|
+
className: "cursor-pointer flex justify-center py-0.5",
|
|
3137
|
+
children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground hover:text-foreground transition-colors" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground hover:text-foreground transition-colors" })
|
|
2762
3138
|
}
|
|
2763
|
-
)
|
|
2764
|
-
|
|
3139
|
+
),
|
|
3140
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-0.5", children: isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3141
|
+
"span",
|
|
2765
3142
|
{
|
|
2766
|
-
|
|
2767
|
-
|
|
3143
|
+
title: stopReason === "end_turn" ? "End of Turn (Anthropic)" : "End of Turn (OpenAI)",
|
|
3144
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3145
|
+
Crab,
|
|
3146
|
+
{
|
|
3147
|
+
className: cn(
|
|
3148
|
+
"size-3.5 text-amber-400",
|
|
3149
|
+
"animate-crab-settle",
|
|
3150
|
+
"drop-shadow-[0_0_4px_rgba(251,191,36,0.5)]"
|
|
3151
|
+
)
|
|
3152
|
+
}
|
|
3153
|
+
)
|
|
2768
3154
|
}
|
|
2769
|
-
) :
|
|
2770
|
-
|
|
3155
|
+
) : isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Start of turn", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3156
|
+
Crab,
|
|
2771
3157
|
{
|
|
2772
|
-
className:
|
|
2773
|
-
|
|
3158
|
+
className: cn(
|
|
3159
|
+
"size-3.5 text-emerald-400",
|
|
3160
|
+
"animate-crab-appear",
|
|
3161
|
+
"drop-shadow-[0_0_4px_rgba(52,211,153,0.5)]"
|
|
3162
|
+
)
|
|
2774
3163
|
}
|
|
2775
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx("
|
|
2776
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
3164
|
+
) }) : 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(Crab, { className: "size-3.5 text-muted-foreground/40" }) }),
|
|
3165
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-1", children: isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-0.5 bg-muted-foreground/10 h-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2777
3166
|
"div",
|
|
2778
3167
|
{
|
|
2779
|
-
className:
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
3168
|
+
className: cn(
|
|
3169
|
+
"w-0.5 h-full",
|
|
3170
|
+
isPending ? "border-dashed bg-transparent border-l-2 border-muted-foreground/20" : "bg-muted-foreground/30"
|
|
3171
|
+
)
|
|
3172
|
+
}
|
|
3173
|
+
) })
|
|
3174
|
+
] });
|
|
3175
|
+
}
|
|
3176
|
+
function TurnGroup({
|
|
3177
|
+
logs,
|
|
3178
|
+
viewMode,
|
|
3179
|
+
strip,
|
|
3180
|
+
cacheTrends,
|
|
3181
|
+
onCompareWithPrevious,
|
|
3182
|
+
turnIndex = 0
|
|
3183
|
+
}) {
|
|
3184
|
+
const stopReasons = reactExports.useMemo(() => logs.map((l) => extractStopReason(l)), [logs]);
|
|
3185
|
+
const lastIdx = logs.length - 1;
|
|
3186
|
+
const lastStop = stopReasons[lastIdx] ?? null;
|
|
3187
|
+
const isComplete = lastStop !== null ? isTurnBoundary(lastStop) : false;
|
|
3188
|
+
const isPending = logs[lastIdx]?.responseStatus === null;
|
|
3189
|
+
const collapsible = isComplete && !isPending;
|
|
3190
|
+
const [collapsed, setCollapsed] = reactExports.useState(false);
|
|
3191
|
+
const toggleCollapse = reactExports.useCallback(() => {
|
|
3192
|
+
if (collapsible) setCollapsed((prev) => !prev);
|
|
3193
|
+
}, [collapsible]);
|
|
3194
|
+
const visibleLogs = reactExports.useMemo(() => {
|
|
3195
|
+
if (!collapsed) return logs;
|
|
3196
|
+
const last = logs[lastIdx];
|
|
3197
|
+
return last !== void 0 ? [last] : [];
|
|
3198
|
+
}, [logs, collapsed, lastIdx]);
|
|
3199
|
+
const bgClass = turnIndex % 2 === 0 ? "bg-muted/10" : "bg-muted/25";
|
|
3200
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3201
|
+
"div",
|
|
3202
|
+
{
|
|
3203
|
+
className: cn("border rounded-lg", isPending ? "border-amber-500/10" : "border-transparent"),
|
|
3204
|
+
children: visibleLogs.map((log, visibleIdx) => {
|
|
3205
|
+
const originalIdx = collapsed ? lastIdx : visibleIdx;
|
|
3206
|
+
const reason = stopReasons[originalIdx] ?? null;
|
|
3207
|
+
const isBoundary = reason === "end_turn" || reason === "stop";
|
|
3208
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-stretch", children: [
|
|
3209
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3210
|
+
ThreadConnector,
|
|
2784
3211
|
{
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
3212
|
+
stopReason: reason,
|
|
3213
|
+
isPending: log.responseStatus === null,
|
|
3214
|
+
isFirst: originalIdx === 0,
|
|
3215
|
+
isTurnStart: originalIdx === 0,
|
|
3216
|
+
crabIndex: log.id % 12,
|
|
3217
|
+
collapsible: collapsible && isBoundary && logs.length > 1,
|
|
3218
|
+
collapsed,
|
|
3219
|
+
onToggle: toggleCollapse
|
|
2789
3220
|
}
|
|
2790
3221
|
),
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
3222
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("flex-1 min-w-0 mb-2 rounded-lg", bgClass), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3223
|
+
LogEntry,
|
|
3224
|
+
{
|
|
3225
|
+
log,
|
|
3226
|
+
viewMode,
|
|
3227
|
+
strip,
|
|
3228
|
+
cacheTrend: cacheTrends?.get(log.id) ?? null,
|
|
3229
|
+
onCompareWithPrevious: () => onCompareWithPrevious(log)
|
|
3230
|
+
}
|
|
3231
|
+
) })
|
|
3232
|
+
] }, log.id);
|
|
3233
|
+
})
|
|
3234
|
+
}
|
|
3235
|
+
);
|
|
2796
3236
|
}
|
|
2797
3237
|
function computeStats(logs) {
|
|
2798
3238
|
let totalInput = 0;
|
|
@@ -2809,22 +3249,52 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
2809
3249
|
strip,
|
|
2810
3250
|
cacheTrends,
|
|
2811
3251
|
onCompareWithPrevious,
|
|
2812
|
-
|
|
3252
|
+
standalone = false
|
|
2813
3253
|
}) {
|
|
2814
|
-
const [expanded, setExpanded] = reactExports.useState(
|
|
2815
|
-
const [groupViewMode, setGroupViewMode] = reactExports.useState(defaultGroupViewMode);
|
|
2816
|
-
reactExports.useEffect(() => {
|
|
2817
|
-
setGroupViewMode(defaultGroupViewMode);
|
|
2818
|
-
}, [defaultGroupViewMode]);
|
|
3254
|
+
const [expanded, setExpanded] = reactExports.useState(standalone);
|
|
2819
3255
|
const stats = computeStats(group.logs);
|
|
2820
3256
|
const startTime = group.logs[0]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2821
3257
|
const endTime = group.logs[group.logs.length - 1]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2822
3258
|
const mixed = hasMixedApiFormat(group.logs);
|
|
2823
3259
|
const isLoading = group.logs.some((log) => log.responseStatus === null);
|
|
2824
3260
|
const stopReasons = reactExports.useMemo(() => group.logs.map((log) => extractStopReason(log)), [group.logs]);
|
|
3261
|
+
const turnIndices = reactExports.useMemo(() => {
|
|
3262
|
+
const indices = [];
|
|
3263
|
+
let turn = 0;
|
|
3264
|
+
for (let i = 0; i < stopReasons.length; i++) {
|
|
3265
|
+
if (i > 0 && (stopReasons[i - 1] === "end_turn" || stopReasons[i - 1] === "stop")) {
|
|
3266
|
+
turn++;
|
|
3267
|
+
}
|
|
3268
|
+
indices.push(turn);
|
|
3269
|
+
}
|
|
3270
|
+
return indices;
|
|
3271
|
+
}, [stopReasons]);
|
|
3272
|
+
const turnGroups = reactExports.useMemo(() => {
|
|
3273
|
+
const groups = [];
|
|
3274
|
+
let currentGroup = [];
|
|
3275
|
+
let currentTurn = 0;
|
|
3276
|
+
for (let i = 0; i < group.logs.length; i++) {
|
|
3277
|
+
const turnIdx = turnIndices[i] ?? 0;
|
|
3278
|
+
const log = group.logs[i];
|
|
3279
|
+
if (!log) continue;
|
|
3280
|
+
if (turnIdx !== currentTurn) {
|
|
3281
|
+
if (currentGroup.length > 0) {
|
|
3282
|
+
groups.push({ logs: currentGroup, turnIndex: currentTurn });
|
|
3283
|
+
}
|
|
3284
|
+
currentGroup = [log];
|
|
3285
|
+
currentTurn = turnIdx;
|
|
3286
|
+
} else {
|
|
3287
|
+
currentGroup.push(log);
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
if (currentGroup.length > 0) {
|
|
3291
|
+
groups.push({ logs: currentGroup, turnIndex: currentTurn });
|
|
3292
|
+
}
|
|
3293
|
+
return groups;
|
|
3294
|
+
}, [group.logs, turnIndices]);
|
|
2825
3295
|
const displayId = group.conversationId.startsWith("PID:") || group.conversationId.includes("|") ? group.conversationId : group.conversationId.length > 24 ? group.conversationId.slice(0, 12) + "…" + group.conversationId.slice(-12) : group.conversationId;
|
|
2826
3296
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
|
|
2827
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3297
|
+
!standalone && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2828
3298
|
ConversationHeader,
|
|
2829
3299
|
{
|
|
2830
3300
|
conversationId: displayId,
|
|
@@ -2838,44 +3308,21 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
2838
3308
|
onToggle: () => setExpanded(!expanded),
|
|
2839
3309
|
hideApiFormat: mixed,
|
|
2840
3310
|
isLoading,
|
|
2841
|
-
|
|
2842
|
-
onToggleViewMode: () => setGroupViewMode((prev) => prev === "thread" ? "flat" : "thread")
|
|
3311
|
+
userAgent: group.logs[0]?.userAgent ?? null
|
|
2843
3312
|
}
|
|
2844
3313
|
),
|
|
2845
|
-
expanded &&
|
|
2846
|
-
|
|
3314
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: turnGroups.map((tg) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3315
|
+
TurnGroup,
|
|
2847
3316
|
{
|
|
2848
|
-
|
|
3317
|
+
logs: tg.logs,
|
|
2849
3318
|
viewMode,
|
|
2850
|
-
suppressApiFormatBadge: !mixed,
|
|
2851
3319
|
strip,
|
|
2852
|
-
|
|
2853
|
-
onCompareWithPrevious
|
|
3320
|
+
cacheTrends,
|
|
3321
|
+
onCompareWithPrevious,
|
|
3322
|
+
turnIndex: tg.turnIndex
|
|
2854
3323
|
},
|
|
2855
|
-
|
|
2856
|
-
)) })
|
|
2857
|
-
expanded && groupViewMode === "thread" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-3", children: group.logs.map((log, idx) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-stretch", children: [
|
|
2858
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2859
|
-
ThreadConnector,
|
|
2860
|
-
{
|
|
2861
|
-
stopReason: stopReasons[idx] ?? null,
|
|
2862
|
-
isPending: log.responseStatus === null,
|
|
2863
|
-
isFirst: idx === 0,
|
|
2864
|
-
isLast: idx === group.logs.length - 1
|
|
2865
|
-
}
|
|
2866
|
-
),
|
|
2867
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 mb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2868
|
-
LogEntry,
|
|
2869
|
-
{
|
|
2870
|
-
log,
|
|
2871
|
-
viewMode,
|
|
2872
|
-
suppressApiFormatBadge: !mixed,
|
|
2873
|
-
strip,
|
|
2874
|
-
cacheTrend: cacheTrends?.get(log.id) ?? null,
|
|
2875
|
-
onCompareWithPrevious: () => onCompareWithPrevious(log)
|
|
2876
|
-
}
|
|
2877
|
-
) })
|
|
2878
|
-
] }, log.id)) })
|
|
3324
|
+
tg.turnIndex
|
|
3325
|
+
)) })
|
|
2879
3326
|
] });
|
|
2880
3327
|
});
|
|
2881
3328
|
function CrabLogo({ className }) {
|
|
@@ -2923,7 +3370,7 @@ function SelectTrigger({
|
|
|
2923
3370
|
...props
|
|
2924
3371
|
}) {
|
|
2925
3372
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2926
|
-
Trigger
|
|
3373
|
+
Trigger,
|
|
2927
3374
|
{
|
|
2928
3375
|
"data-slot": "select-trigger",
|
|
2929
3376
|
"data-size": size,
|
|
@@ -2946,8 +3393,8 @@ function SelectContent({
|
|
|
2946
3393
|
align = "center",
|
|
2947
3394
|
...props
|
|
2948
3395
|
}) {
|
|
2949
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal
|
|
2950
|
-
Content2
|
|
3396
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3397
|
+
Content2,
|
|
2951
3398
|
{
|
|
2952
3399
|
"data-slot": "select-content",
|
|
2953
3400
|
className: cn(
|
|
@@ -5674,8 +6121,6 @@ function ProxyViewer({
|
|
|
5674
6121
|
strip
|
|
5675
6122
|
}) {
|
|
5676
6123
|
const { totalIn, totalOut } = computeTokenSummary(logs);
|
|
5677
|
-
const [groupedView, setGroupedView] = reactExports.useState(true);
|
|
5678
|
-
const [groupViewMode, setGroupViewMode] = reactExports.useState("thread");
|
|
5679
6124
|
const [exporting, setExporting] = reactExports.useState(false);
|
|
5680
6125
|
const [comparePair, setComparePair] = reactExports.useState(null);
|
|
5681
6126
|
const handleExport = reactExports.useCallback(async () => {
|
|
@@ -5705,19 +6150,40 @@ function ProxyViewer({
|
|
|
5705
6150
|
);
|
|
5706
6151
|
const groups = reactExports.useMemo(() => groupLogsByConversation(logs), [logs]);
|
|
5707
6152
|
const cacheTrends = reactExports.useMemo(() => computeCacheTrends(groups), [groups]);
|
|
5708
|
-
const stopReasons = reactExports.useMemo(() => logs.map((log) => extractStopReason(log)), [logs]);
|
|
5709
|
-
const renderGroups = logs.length > 0 && groupedView && groups.length > 1;
|
|
5710
6153
|
const rowVirtualizer = useVirtualizer({
|
|
5711
|
-
count:
|
|
6154
|
+
count: groups.length,
|
|
5712
6155
|
getScrollElement: () => parentRef.current,
|
|
5713
6156
|
estimateSize: () => 150,
|
|
5714
6157
|
measureElement: typeof window !== "undefined" ? (element) => element.getBoundingClientRect().height : void 0,
|
|
5715
6158
|
overscan: 5
|
|
5716
6159
|
});
|
|
5717
6160
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-[1200px] mx-auto flex flex-col h-screen", style: { maxHeight: "100vh" }, children: [
|
|
5718
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-
|
|
5719
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "text-lg font-bold flex
|
|
5720
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
6161
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-end px-6 pt-6 pb-3 relative", children: [
|
|
6162
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "text-lg font-bold flex items-end gap-2 absolute left-1/2 -translate-x-1/2 whitespace-nowrap", children: [
|
|
6163
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-end gap-1 group cursor-default", "aria-hidden": "true", children: [
|
|
6164
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: "size-10 text-amber-500 transition-all duration-300 group-hover:scale-125 group-hover:-translate-y-1.5" }),
|
|
6165
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex items-end gap-0.5", children: crabVariants.map((Crab, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6166
|
+
Crab,
|
|
6167
|
+
{
|
|
6168
|
+
className: `size-5 ${[
|
|
6169
|
+
"text-amber-500",
|
|
6170
|
+
"text-rose-500",
|
|
6171
|
+
"text-sky-500",
|
|
6172
|
+
"text-emerald-500",
|
|
6173
|
+
"text-violet-500",
|
|
6174
|
+
"text-orange-500",
|
|
6175
|
+
"text-cyan-500",
|
|
6176
|
+
"text-pink-500",
|
|
6177
|
+
"text-lime-500",
|
|
6178
|
+
"text-blue-500",
|
|
6179
|
+
"text-yellow-500",
|
|
6180
|
+
"text-fuchsia-500"
|
|
6181
|
+
][i]} transition-all duration-300 ease-out group-hover:scale-125 group-hover:-translate-y-1`,
|
|
6182
|
+
style: { transitionDelay: `${i * 50}ms` }
|
|
6183
|
+
},
|
|
6184
|
+
i
|
|
6185
|
+
)) })
|
|
6186
|
+
] }),
|
|
5721
6187
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-baseline gap-2", children: [
|
|
5722
6188
|
"LLM Inspector",
|
|
5723
6189
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-muted-foreground font-mono", children: [
|
|
@@ -5726,6 +6192,23 @@ function ProxyViewer({
|
|
|
5726
6192
|
] })
|
|
5727
6193
|
] })
|
|
5728
6194
|
] }),
|
|
6195
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsDialog, {}) })
|
|
6196
|
+
] }),
|
|
6197
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 px-6 mb-4", children: [
|
|
6198
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedSession, onValueChange: onSessionChange, children: [
|
|
6199
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "flex-1 max-w-[350px] text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
|
|
6200
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
6201
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All sessions" }),
|
|
6202
|
+
sessions.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: s, children: truncateSessionId(s) }, s))
|
|
6203
|
+
] })
|
|
6204
|
+
] }),
|
|
6205
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedModel, onValueChange: onModelChange, children: [
|
|
6206
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "flex-1 max-w-[250px] text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All models" }) }),
|
|
6207
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
6208
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All models" }),
|
|
6209
|
+
models.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: m, children: m }, m))
|
|
6210
|
+
] })
|
|
6211
|
+
] }),
|
|
5729
6212
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
5730
6213
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center border border-border rounded-md overflow-hidden", children: [
|
|
5731
6214
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -5749,7 +6232,7 @@ function ProxyViewer({
|
|
|
5749
6232
|
] }) }),
|
|
5750
6233
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Simple shows parsed output; Full adds raw headers and tokens" })
|
|
5751
6234
|
] }) }),
|
|
5752
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6235
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1" }),
|
|
5753
6236
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground text-xs font-mono", children: [
|
|
5754
6237
|
logs.length,
|
|
5755
6238
|
" request",
|
|
@@ -5768,7 +6251,7 @@ function ProxyViewer({
|
|
|
5768
6251
|
title: "Export all logs as JSON ZIP",
|
|
5769
6252
|
children: exporting ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5770
6253
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3" }),
|
|
5771
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Export
|
|
6254
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Export" })
|
|
5772
6255
|
] })
|
|
5773
6256
|
}
|
|
5774
6257
|
),
|
|
@@ -5779,71 +6262,12 @@ function ProxyViewer({
|
|
|
5779
6262
|
onClick: onClearAll,
|
|
5780
6263
|
className: "text-xs text-muted-foreground hover:text-foreground transition-colors cursor-pointer",
|
|
5781
6264
|
title: "Clear all logs",
|
|
5782
|
-
children: "Clear
|
|
6265
|
+
children: "Clear"
|
|
5783
6266
|
}
|
|
5784
6267
|
)
|
|
5785
6268
|
] }),
|
|
5786
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 px-6 mb-4", children: [
|
|
5787
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedSession, onValueChange: onSessionChange, children: [
|
|
5788
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "flex-1 max-w-[400px] text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
|
|
5789
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
5790
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All sessions" }),
|
|
5791
|
-
sessions.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: s, children: truncateSessionId(s) }, s))
|
|
5792
|
-
] })
|
|
5793
|
-
] }),
|
|
5794
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedModel, onValueChange: onModelChange, children: [
|
|
5795
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All models" }) }),
|
|
5796
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
5797
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All models" }),
|
|
5798
|
-
models.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: m, children: m }, m))
|
|
5799
|
-
] })
|
|
5800
|
-
] }),
|
|
5801
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center border border-border rounded-md overflow-hidden", children: [
|
|
5802
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5803
|
-
"button",
|
|
5804
|
-
{
|
|
5805
|
-
type: "button",
|
|
5806
|
-
onClick: () => setGroupedView(true),
|
|
5807
|
-
className: `px-2 py-1.5 cursor-pointer transition-colors ${groupedView ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5808
|
-
title: "Grouped view",
|
|
5809
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(LayoutGrid, { className: "size-4" })
|
|
5810
|
-
}
|
|
5811
|
-
),
|
|
5812
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5813
|
-
"button",
|
|
5814
|
-
{
|
|
5815
|
-
type: "button",
|
|
5816
|
-
onClick: () => setGroupedView(false),
|
|
5817
|
-
className: `px-2 py-1.5 cursor-pointer transition-colors ${!groupedView ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5818
|
-
title: "Flat view",
|
|
5819
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(List, { className: "size-4" })
|
|
5820
|
-
}
|
|
5821
|
-
)
|
|
5822
|
-
] }),
|
|
5823
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center border border-border rounded-md overflow-hidden", children: [
|
|
5824
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5825
|
-
"button",
|
|
5826
|
-
{
|
|
5827
|
-
type: "button",
|
|
5828
|
-
onClick: () => setGroupViewMode("thread"),
|
|
5829
|
-
className: `px-2 py-1.5 cursor-pointer transition-colors ${groupViewMode === "thread" ? "bg-amber-500/15 text-amber-400 border-r border-amber-500/30" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5830
|
-
title: "Thread view (connected timeline)",
|
|
5831
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(GitBranch, { className: "size-4" })
|
|
5832
|
-
}
|
|
5833
|
-
),
|
|
5834
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5835
|
-
"button",
|
|
5836
|
-
{
|
|
5837
|
-
type: "button",
|
|
5838
|
-
onClick: () => setGroupViewMode("flat"),
|
|
5839
|
-
className: `px-2 py-1.5 cursor-pointer transition-colors ${groupViewMode === "flat" ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5840
|
-
title: "Flat view (card list)",
|
|
5841
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(List, { className: "size-4" })
|
|
5842
|
-
}
|
|
5843
|
-
)
|
|
5844
|
-
] })
|
|
5845
|
-
] }),
|
|
5846
6269
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 px-6 pb-6", children: logs.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-muted-foreground py-16 space-y-4", children: [
|
|
6270
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: "size-12 text-muted-foreground/20 mx-auto" }),
|
|
5847
6271
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No requests captured yet." }),
|
|
5848
6272
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs", children: "Route AI coding tools through the proxy:" }),
|
|
5849
6273
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "LLM_BASE_URL=http://localhost:25947/proxy <your-tool>" })
|
|
@@ -5856,85 +6280,34 @@ function ProxyViewer({
|
|
|
5856
6280
|
position: "relative"
|
|
5857
6281
|
},
|
|
5858
6282
|
children: rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
transform: `translateY(${virtualRow.start}px)`
|
|
5873
|
-
},
|
|
5874
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5875
|
-
ConversationGroup,
|
|
5876
|
-
{
|
|
5877
|
-
group,
|
|
5878
|
-
viewMode,
|
|
5879
|
-
strip,
|
|
5880
|
-
cacheTrends,
|
|
5881
|
-
onCompareWithPrevious: handleCompareWithPrevious,
|
|
5882
|
-
defaultGroupViewMode: groupViewMode
|
|
5883
|
-
}
|
|
5884
|
-
)
|
|
5885
|
-
},
|
|
5886
|
-
group.id
|
|
5887
|
-
);
|
|
5888
|
-
} else {
|
|
5889
|
-
const log = logs[virtualRow.index];
|
|
5890
|
-
if (log === void 0) return null;
|
|
5891
|
-
const idx = virtualRow.index;
|
|
5892
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5893
|
-
"div",
|
|
5894
|
-
{
|
|
5895
|
-
"data-index": virtualRow.index,
|
|
5896
|
-
ref: rowVirtualizer.measureElement,
|
|
5897
|
-
style: {
|
|
5898
|
-
position: "absolute",
|
|
5899
|
-
top: 0,
|
|
5900
|
-
left: 0,
|
|
5901
|
-
width: "100%",
|
|
5902
|
-
transform: `translateY(${virtualRow.start}px)`
|
|
5903
|
-
},
|
|
5904
|
-
children: groupViewMode === "thread" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-stretch ml-3", children: [
|
|
5905
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5906
|
-
ThreadConnector,
|
|
5907
|
-
{
|
|
5908
|
-
stopReason: stopReasons[idx] ?? null,
|
|
5909
|
-
isPending: log.responseStatus === null,
|
|
5910
|
-
isFirst: idx === 0,
|
|
5911
|
-
isLast: idx === logs.length - 1
|
|
5912
|
-
}
|
|
5913
|
-
),
|
|
5914
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 mb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5915
|
-
LogEntry,
|
|
5916
|
-
{
|
|
5917
|
-
log,
|
|
5918
|
-
viewMode,
|
|
5919
|
-
strip,
|
|
5920
|
-
cacheTrend: cacheTrends.get(log.id) ?? null,
|
|
5921
|
-
onCompareWithPrevious: () => handleCompareWithPrevious(log)
|
|
5922
|
-
}
|
|
5923
|
-
) })
|
|
5924
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5925
|
-
LogEntry,
|
|
5926
|
-
{
|
|
5927
|
-
log,
|
|
5928
|
-
viewMode,
|
|
5929
|
-
strip,
|
|
5930
|
-
cacheTrend: cacheTrends.get(log.id) ?? null,
|
|
5931
|
-
onCompareWithPrevious: () => handleCompareWithPrevious(log)
|
|
5932
|
-
}
|
|
5933
|
-
)
|
|
6283
|
+
const group = groups[virtualRow.index];
|
|
6284
|
+
if (group === void 0) return null;
|
|
6285
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6286
|
+
"div",
|
|
6287
|
+
{
|
|
6288
|
+
"data-index": virtualRow.index,
|
|
6289
|
+
ref: rowVirtualizer.measureElement,
|
|
6290
|
+
style: {
|
|
6291
|
+
position: "absolute",
|
|
6292
|
+
top: 0,
|
|
6293
|
+
left: 0,
|
|
6294
|
+
width: "100%",
|
|
6295
|
+
transform: `translateY(${virtualRow.start}px)`
|
|
5934
6296
|
},
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
6297
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6298
|
+
ConversationGroup,
|
|
6299
|
+
{
|
|
6300
|
+
group,
|
|
6301
|
+
viewMode,
|
|
6302
|
+
strip,
|
|
6303
|
+
cacheTrends,
|
|
6304
|
+
onCompareWithPrevious: handleCompareWithPrevious,
|
|
6305
|
+
standalone: groups.length === 1
|
|
6306
|
+
}
|
|
6307
|
+
)
|
|
6308
|
+
},
|
|
6309
|
+
group.id
|
|
6310
|
+
);
|
|
5938
6311
|
})
|
|
5939
6312
|
}
|
|
5940
6313
|
) }) }),
|