@tonyclaw/agent-inspector 3.0.26 → 3.0.28
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/cli.js +80 -11
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-SZRUDQc9.js → CompareDrawer-TghZr5t1.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-BJvwOrSi.js → ProxyViewerContainer-fShBAZjj.js} +201 -201
- package/.output/public/assets/{ReplayDialog-DgfmqiM3.js → ReplayDialog-CZMApaF4.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-CS6c7Qfn.js → RequestAnatomy-DNWccR7O.js} +1 -1
- package/.output/public/assets/{ResponseView-C0Ri_5gm.js → ResponseView-d25MdFhY.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-7dYcHWyZ.js → StreamingChunkSequence-DIFZEnWe.js} +1 -1
- package/.output/public/assets/{_sessionId-D-V84cgw.js → _sessionId-DRfvuE2k.js} +1 -1
- package/.output/public/assets/{index-DgFWCxOs.js → index-B3aAuqWq.js} +1 -1
- package/.output/public/assets/index-BsxAGqMA.css +1 -0
- package/.output/public/assets/{index-DrVJsks2.js → index-D4HkS7Ct.js} +1 -1
- package/.output/public/assets/{index-CSIL7-MK.js → index-DzARL2Fi.js} +3 -3
- package/.output/public/assets/{json-viewer-C9Ji3gYN.js → json-viewer-wuJSKaed.js} +1 -1
- package/.output/server/_libs/lucide-react.mjs +39 -39
- package/.output/server/{_sessionId-BQ6YQOO1.mjs → _sessionId-BJTNiP_O.mjs} +4 -2
- package/.output/server/_ssr/{CompareDrawer-CqNzIeMR.mjs → CompareDrawer-BMRH3N97.mjs} +5 -3
- package/.output/server/_ssr/{ProxyViewerContainer-CMC7Vsbw.mjs → ProxyViewerContainer-AFwcHAIR.mjs} +330 -223
- package/.output/server/_ssr/{ReplayDialog-D9p_LaTr.mjs → ReplayDialog-CbWvRHiN.mjs} +6 -4
- package/.output/server/_ssr/{RequestAnatomy-B4ge3qNZ.mjs → RequestAnatomy-C4kcPyqN.mjs} +4 -2
- package/.output/server/_ssr/{ResponseView-BCqMKApI.mjs → ResponseView-D8VYt-gZ.mjs} +5 -3
- package/.output/server/_ssr/{StreamingChunkSequence-BA4zTLE4.mjs → StreamingChunkSequence-BUUo6vU0.mjs} +4 -2
- package/.output/server/_ssr/{index-CzxhDjlq.mjs → index-DTwMEEXO.mjs} +4 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-B3qV6iEJ.mjs → json-viewer-BqF1pSQD.mjs} +5 -3
- package/.output/server/_ssr/{router-CZe_R31M.mjs → router-C8BOns7y.mjs} +839 -368
- package/.output/server/{_tanstack-start-manifest_v-B50VTLrH.mjs → _tanstack-start-manifest_v-BBf2nRhb.mjs} +1 -1
- package/.output/server/index.mjs +70 -70
- package/README.md +8 -0
- package/package.json +4 -5
- package/src/cli.ts +43 -9
- package/src/components/ProxyViewer.tsx +57 -1
- package/src/components/clients/ClientLogo.tsx +43 -4
- package/src/components/inspector-pet/InspectorPet.tsx +0 -7
- package/src/components/providers/ProviderCard.tsx +3 -36
- package/src/components/providers/ProviderForm.tsx +13 -12
- package/src/components/providers/ProvidersPanel.tsx +2 -2
- package/src/components/providers/SettingsDialog.tsx +3 -3
- package/src/components/proxy-viewer/ConversationGroup.tsx +1 -1
- package/src/components/proxy-viewer/ConversationGroupList.tsx +233 -152
- package/src/components/proxy-viewer/ConversationHeader.tsx +29 -13
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +0 -3
- package/src/contracts/anthropic.ts +0 -5
- package/src/contracts/index.ts +0 -4
- package/src/contracts/log.ts +0 -1
- package/src/contracts/openai.ts +0 -3
- package/src/knowledge/openclawClient.ts +22 -9
- package/src/knowledge/openclawGatewayClient.ts +20 -13
- package/src/lib/alertContract.ts +0 -3
- package/src/lib/ecosystemContract.ts +0 -3
- package/src/lib/export-logs.ts +1 -4
- package/src/lib/jsonFile.ts +46 -0
- package/src/lib/safeFetch.ts +100 -0
- package/src/lib/ssrfGuard.ts +133 -0
- package/src/lib/stopReason.ts +1 -4
- package/src/lib/unknown.ts +27 -0
- package/src/lib/useProviders.ts +1 -1
- package/src/mcp/mode.ts +3 -9
- package/src/mcp/server.ts +5 -14
- package/src/mcp/toolHandlers.ts +45 -54
- package/src/proxy/constants.ts +17 -0
- package/src/proxy/evidenceAnalysis.ts +116 -117
- package/src/proxy/formats/anthropic/handler.ts +5 -1
- package/src/proxy/formats/anthropic/schemas.ts +1 -7
- package/src/proxy/formats/index.ts +1 -1
- package/src/proxy/formats/openai/schemas.ts +0 -3
- package/src/proxy/formats/registry.ts +0 -3
- package/src/proxy/groupEvidenceExporter.ts +4 -8
- package/src/proxy/groupStore.ts +3 -10
- package/src/proxy/handler.ts +91 -12
- package/src/proxy/identityProxy.ts +74 -1
- package/src/proxy/logImporter.ts +82 -12
- package/src/proxy/logIndex.ts +1 -4
- package/src/proxy/providerSecretStore.ts +177 -0
- package/src/proxy/providers.ts +84 -11
- package/src/proxy/runFailures.ts +4 -10
- package/src/proxy/runStore.ts +4 -11
- package/src/proxy/schemas.ts +1 -8
- package/src/proxy/sqliteLogIndex.ts +0 -16
- package/src/proxy/store.ts +1 -5
- package/src/proxy/toolSchemaWarnings.ts +1 -9
- package/src/routes/api/logs.$id.replay.ts +17 -5
- package/src/routes/api/providers.$providerId.model-metadata.ts +11 -1
- package/src/routes/api/providers.$providerId.ts +18 -5
- package/src/routes/api/providers.ts +18 -7
- package/.output/public/assets/index-CmeF5XXS.css +0 -1
package/.output/server/_ssr/{ProxyViewerContainer-CMC7Vsbw.mjs → ProxyViewerContainer-AFwcHAIR.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, R as React } from "../_libs/react.mjs";
|
|
2
|
-
import { C as CapturedLogSchema,
|
|
2
|
+
import { C as CapturedLogSchema, B as DeleteInspectorGroupsResponseSchema, 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, g as readStoredUiScalePreference, h as persistUiScalePreference, j as applyUiScalePreference, x as extractStopReason, p as packageJson, P as ProviderConfigSchema, U as UI_SCALE_STORAGE_KEY, k as normalizeUiScalePreference, t as apiFormatForPath, E as GroupEvidenceExportResultSchema, F as DeleteInspectorGroupResponseSchema, $ as PiAgentResponseSchema, w as isTurnBoundary, r as readStoredThemeMode, e as applyThemeMode, f as persistThemeMode, a2 as formatUiScale, y as AlertSummarySchema, z as AlertListResponseSchema, I as InspectorGroupsListResponseSchema, G as GroupEvidenceReadResponseSchema, V as createPendingProviderTestResults, W as ProviderTestResultsSchema, X as createFailedProviderTestResults, Y as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, Z as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, _ as TimeDisplayFormatSchema, i as isRecord, T as THEME_MODE_STORAGE_KEY, n as normalizeThemeMode, M as PATH_V1_MESSAGES, N as PATH_V1_CHAT_COMPLETIONS, Q as PATH_V1_RESPONSES, H as providerHasContextMetadata, m as parseOpenAIResponse, o as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, q as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, l as AnthropicRequestSchema, s as safeGetOwnProperty, a0 as resolveProviderContextWindow, u as getSessionPath, J as findProviderModelMetadata, S as previewUpstreamUrl, K as KnowledgeCandidateSchema, a1 as isPlainRecord, v as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-C8BOns7y.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 { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstac
|
|
|
9
9
|
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
10
10
|
import { r as reactDomExports } from "../_libs/react-dom.mjs";
|
|
11
11
|
import { W as WebGLRenderer, S as SRGBColorSpace, A as ACESFilmicToneMapping, a as Scene, O as OrthographicCamera, M as MeshPhysicalMaterial, C as Color, G as Group, b as Mesh, c as CircleGeometry, d as MeshBasicMaterial, e as SphereGeometry, f as AmbientLight, H as HemisphereLight, D as DirectionalLight, P as PointLight, V as Vector3, g as CylinderGeometry } from "../_libs/three.mjs";
|
|
12
|
-
import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, P as PanelRightOpen, c as PanelRightClose, S as Search, U as Upload, D as Download, F as FileBraces, R as RefreshCw, d as Trash2, H as Heart, e as Pause, f as Play, g as Plus, B as BrainCircuit, L as LoaderCircle, h as Send, A as ArrowLeft, i as ChevronUp, j as Copy, k as ChevronsLeft, l as ChevronLeft, m as ChevronRight, n as ChevronsRight, o as Clapperboard, p as Flag, q as Siren, r as Timer, G as Gauge, s as Sun, E as Eye, M as Moon, t as ALargeSmall, u as Layers, v as FlaskConical, w as Sparkles, x as Activity, y as Beaker, N as Network, z as Terminal, J as Settings, K as Monitor, O as Rocket, Q as PackageCheck, V as History, W as Scan, Y as CircleAlert, Z as ArrowUpRight, _ as ArrowDownRight, $ as
|
|
12
|
+
import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, P as PanelRightOpen, c as PanelRightClose, S as Search, U as Upload, D as Download, F as FileBraces, R as RefreshCw, d as Trash2, H as Heart, e as Pause, f as Play, g as Plus, B as BrainCircuit, L as LoaderCircle, h as Send, A as ArrowLeft, i as ChevronUp, j as Copy, k as ChevronsLeft, l as ChevronLeft, m as ChevronRight, n as ChevronsRight, o as Clapperboard, p as Flag, q as Siren, r as Timer, G as Gauge, s as Sun, E as Eye, M as Moon, t as ALargeSmall, u as Layers, v as FlaskConical, w as Sparkles, x as Activity, y as Beaker, N as Network, z as Terminal, J as Settings, K as Monitor, O as Rocket, Q as PackageCheck, V as History, W as Scan, Y as CircleAlert, Z as ArrowUpRight, _ as ArrowDownRight, $ as CodeXml, a0 as Cpu, a1 as FolderOpen, a2 as Bell, a3 as Clock3, a4 as ShieldAlert, a5 as EyeOff, a6 as ExternalLink, a7 as Clock, a8 as RotateCw, a9 as CircleCheckBig, aa as Pencil, ab as MessageSquare, ac as Zap, ad as Wrench, ae as Brain, af as Minus, ag as CircleX, ah as ShieldCheck, ai as Save, aj as FileSearch, ak as CloudUpload, al as CircleQuestionMark, am as Server, an as Lock, ao as Wifi, ap as WifiOff, aq as OctagonAlert, ar as Radio, as as Globe, at as FileTerminal, au as ChevronsUp, av as ChevronsDown, aw as FileDiff, ax as RotateCcw, ay as GitCompareArrows, az as ArrowUp, aA as ArrowDown, aB as Ellipsis, aC as Blocks, aD as MousePointerClick, aE as FileText, aF as Rows3, aG as Columns2 } from "../_libs/lucide-react.mjs";
|
|
13
13
|
import { u as union, o as object, e as array, l as literal, n as number, d as boolean, b as string, _ as _enum } from "../_libs/zod.mjs";
|
|
14
14
|
import { S as Select$1, a as SelectTrigger$1, b as SelectIcon, c as SelectValue$1, d as SelectPortal, e as SelectContent$1, f as SelectViewport, g as SelectItem$1, h as SelectItemIndicator, i as SelectItemText, j as SelectScrollUpButton$1, k as SelectScrollDownButton$1 } from "../_libs/radix-ui__react-select.mjs";
|
|
15
15
|
import { D as Dialog$1, a as DialogContent$1, b as DialogClose, c as DialogTitle$1, d as DialogDescription$1, e as DialogPortal$1, f as DialogOverlay$1, g as DialogTrigger$1 } from "../_libs/radix-ui__react-dialog.mjs";
|
|
@@ -391,9 +391,6 @@ async function fetchStreamingChunks(logId, signal) {
|
|
|
391
391
|
return null;
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
|
-
function isRecord(value) {
|
|
395
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
396
|
-
}
|
|
397
394
|
function redactValue(value) {
|
|
398
395
|
if (Array.isArray(value)) return value.map((item) => redactValue(item));
|
|
399
396
|
if (!isRecord(value)) return value;
|
|
@@ -690,7 +687,7 @@ async function fetcher(url) {
|
|
|
690
687
|
}
|
|
691
688
|
function useProviders() {
|
|
692
689
|
const response = useSWR(
|
|
693
|
-
"/api/providers
|
|
690
|
+
"/api/providers",
|
|
694
691
|
fetcher,
|
|
695
692
|
{
|
|
696
693
|
revalidateOnFocus: false,
|
|
@@ -877,7 +874,8 @@ const CLIENT_LABELS = {
|
|
|
877
874
|
codex: "Codex",
|
|
878
875
|
opencode: "OpenCode",
|
|
879
876
|
"mimo-code": "MiMo Code",
|
|
880
|
-
"claude-code": "Claude Code"
|
|
877
|
+
"claude-code": "Claude Code",
|
|
878
|
+
"ai-sdk": "AI SDK"
|
|
881
879
|
};
|
|
882
880
|
function normalize(value) {
|
|
883
881
|
return value?.toLowerCase() ?? "";
|
|
@@ -905,6 +903,7 @@ function detectClientApp(input) {
|
|
|
905
903
|
if (matchesAny(haystack, ["codex desktop", "codex-cli", "openai-codex", "codex"])) {
|
|
906
904
|
return "codex";
|
|
907
905
|
}
|
|
906
|
+
if (matchesAny(normalize(input.userAgent), ["ai-sdk", "ai/"])) return "ai-sdk";
|
|
908
907
|
return "unknown";
|
|
909
908
|
}
|
|
910
909
|
function clientAppLabel(client) {
|
|
@@ -914,11 +913,25 @@ function clientAppLabel(client) {
|
|
|
914
913
|
case "opencode":
|
|
915
914
|
case "mimo-code":
|
|
916
915
|
case "claude-code":
|
|
916
|
+
case "ai-sdk":
|
|
917
917
|
return CLIENT_LABELS[client];
|
|
918
918
|
case "unknown":
|
|
919
919
|
return null;
|
|
920
920
|
}
|
|
921
921
|
}
|
|
922
|
+
function clientAppTypeLabel(client) {
|
|
923
|
+
switch (client) {
|
|
924
|
+
case "codex":
|
|
925
|
+
case "opencode":
|
|
926
|
+
case "mimo-code":
|
|
927
|
+
case "claude-code":
|
|
928
|
+
return "IDE";
|
|
929
|
+
case "agent-inspector":
|
|
930
|
+
case "ai-sdk":
|
|
931
|
+
case "unknown":
|
|
932
|
+
return "CLIENT";
|
|
933
|
+
}
|
|
934
|
+
}
|
|
922
935
|
const CLIENT_LOGOS = {
|
|
923
936
|
"agent-inspector": AgentInspectorLogo,
|
|
924
937
|
codex: CodexLogoSvg,
|
|
@@ -942,11 +955,27 @@ const CLIENT_LOGO_IMAGES = {
|
|
|
942
955
|
};
|
|
943
956
|
function ClientLogo({
|
|
944
957
|
client,
|
|
945
|
-
className
|
|
958
|
+
className,
|
|
959
|
+
decorative = false
|
|
946
960
|
}) {
|
|
947
961
|
if (client === "unknown") return null;
|
|
948
962
|
const label = clientAppLabel(client);
|
|
949
963
|
if (label === null) return null;
|
|
964
|
+
if (client === "ai-sdk") {
|
|
965
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
966
|
+
"span",
|
|
967
|
+
{
|
|
968
|
+
className: cn(
|
|
969
|
+
"inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-cyan-200/20 bg-cyan-300/[0.08] text-cyan-100 shadow-sm",
|
|
970
|
+
className
|
|
971
|
+
),
|
|
972
|
+
"aria-label": decorative ? void 0 : label,
|
|
973
|
+
"aria-hidden": decorative ? true : void 0,
|
|
974
|
+
title: label,
|
|
975
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { className: "size-1/2", "aria-hidden": "true" })
|
|
976
|
+
}
|
|
977
|
+
);
|
|
978
|
+
}
|
|
950
979
|
const logoSrc = CLIENT_LOGOS[client];
|
|
951
980
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
952
981
|
"span",
|
|
@@ -956,7 +985,8 @@ function ClientLogo({
|
|
|
956
985
|
CLIENT_LOGO_FRAMES[client],
|
|
957
986
|
className
|
|
958
987
|
),
|
|
959
|
-
"aria-label": label,
|
|
988
|
+
"aria-label": decorative ? void 0 : label,
|
|
989
|
+
"aria-hidden": decorative ? true : void 0,
|
|
960
990
|
title: label,
|
|
961
991
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
962
992
|
"img",
|
|
@@ -1673,6 +1703,13 @@ function resolveLogFormat(log) {
|
|
|
1673
1703
|
return pathFormat === "unknown" ? log.apiFormat : pathFormat;
|
|
1674
1704
|
}
|
|
1675
1705
|
const HEADER_ACTION_BUTTON_CLASS$1 = "bg-white/[0.045] hover:bg-white/[0.075] inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground";
|
|
1706
|
+
function isSyntheticSessionId(conversationId) {
|
|
1707
|
+
return conversationId.startsWith("PID:") || conversationId.startsWith("process:") || conversationId.startsWith("connection:") || conversationId.includes("|");
|
|
1708
|
+
}
|
|
1709
|
+
function compactSessionLabel(conversationId) {
|
|
1710
|
+
if (isSyntheticSessionId(conversationId)) return "Sessionless";
|
|
1711
|
+
return conversationId.length > 24 ? `${conversationId.slice(0, 12)}...${conversationId.slice(-12)}` : conversationId;
|
|
1712
|
+
}
|
|
1676
1713
|
function HeaderMetric({
|
|
1677
1714
|
icon,
|
|
1678
1715
|
children,
|
|
@@ -1694,11 +1731,11 @@ function HeaderMetric({
|
|
|
1694
1731
|
}
|
|
1695
1732
|
);
|
|
1696
1733
|
}
|
|
1697
|
-
function PendingTurnBadge
|
|
1734
|
+
function PendingTurnBadge() {
|
|
1698
1735
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1699
1736
|
"span",
|
|
1700
1737
|
{
|
|
1701
|
-
className: "inline-flex h-6 shrink-0 items-center gap-1.5 rounded-md bg-amber-300/[0.10] px-1.5 font-mono text-[10px] uppercase
|
|
1738
|
+
className: "inline-flex h-6 shrink-0 items-center gap-1.5 rounded-md bg-amber-300/[0.10] px-1.5 font-mono text-[10px] uppercase text-amber-100/90 ring-1 ring-amber-200/10",
|
|
1702
1739
|
title: "This session has a turn that has not finished yet",
|
|
1703
1740
|
children: [
|
|
1704
1741
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3 animate-spin" }),
|
|
@@ -1748,8 +1785,8 @@ function ConversationHeader({
|
|
|
1748
1785
|
const hasUserAgent = userAgent !== null && userAgent !== void 0 && userAgent !== "";
|
|
1749
1786
|
const clientDisplayLabel = detectedClientLabel ?? userAgent ?? null;
|
|
1750
1787
|
const clientTooltip = detectedClientLabel !== null && hasUserAgent ? `${detectedClientLabel} - ${userAgent}` : null;
|
|
1751
|
-
const isFallbackConversation =
|
|
1752
|
-
const
|
|
1788
|
+
const isFallbackConversation = isSyntheticSessionId(conversationId);
|
|
1789
|
+
const sessionLabel = compactSessionLabel(conversationId);
|
|
1753
1790
|
const timeLabel = formatTimestampRange(startTime, endTime, timeDisplayFormat);
|
|
1754
1791
|
const callsLabel = `${totalCalls} call${totalCalls !== 1 ? "s" : ""}`;
|
|
1755
1792
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -1760,8 +1797,8 @@ function ConversationHeader({
|
|
|
1760
1797
|
"data-nav-id": `conv-${conversationId}`,
|
|
1761
1798
|
"data-nav-action": expanded ? "collapse" : "expand",
|
|
1762
1799
|
className: cn(
|
|
1763
|
-
"bg-
|
|
1764
|
-
"hover:bg-
|
|
1800
|
+
"bg-black/[0.10] relative flex cursor-pointer items-start gap-2.5 overflow-hidden rounded-[8px] px-3 py-2.5 transition-colors",
|
|
1801
|
+
"hover:bg-black/[0.16]",
|
|
1765
1802
|
"select-none",
|
|
1766
1803
|
"sticky top-0 z-10 mb-2",
|
|
1767
1804
|
"focus-visible:ring-1 focus-visible:ring-cyan-300/35 focus-visible:outline-none"
|
|
@@ -1785,10 +1822,11 @@ function ConversationHeader({
|
|
|
1785
1822
|
),
|
|
1786
1823
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
1787
1824
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
1825
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 rounded bg-white/[0.04] px-1.5 py-0.5 font-mono text-[9px] uppercase text-muted-foreground/70", children: "Session" }),
|
|
1788
1826
|
isFallbackConversation && showProcessMetadata ? clientPid !== null && clientPid !== void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1789
1827
|
"span",
|
|
1790
1828
|
{
|
|
1791
|
-
className: "min-w-0 max-w-full truncate font-mono text-xs font-semibold text-
|
|
1829
|
+
className: "min-w-0 max-w-full truncate font-mono text-xs font-semibold text-slate-100",
|
|
1792
1830
|
title: `PID ${clientPid}`,
|
|
1793
1831
|
children: [
|
|
1794
1832
|
"PID ",
|
|
@@ -1798,16 +1836,16 @@ function ConversationHeader({
|
|
|
1798
1836
|
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1799
1837
|
"span",
|
|
1800
1838
|
{
|
|
1801
|
-
className: "min-w-0 max-w-full truncate font-mono text-xs font-semibold text-
|
|
1839
|
+
className: "min-w-0 max-w-full truncate font-mono text-xs font-semibold text-slate-100",
|
|
1802
1840
|
title: conversationId,
|
|
1803
1841
|
children: conversationId
|
|
1804
1842
|
}
|
|
1805
1843
|
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1806
1844
|
"span",
|
|
1807
1845
|
{
|
|
1808
|
-
className: "min-w-0 max-w-full truncate font-mono text-xs font-semibold text-
|
|
1846
|
+
className: "min-w-0 max-w-full truncate font-mono text-xs font-semibold text-slate-100",
|
|
1809
1847
|
title: conversationId,
|
|
1810
|
-
children:
|
|
1848
|
+
children: sessionLabel
|
|
1811
1849
|
}
|
|
1812
1850
|
),
|
|
1813
1851
|
!isFallbackConversation && showProcessMetadata && clientPid !== null && clientPid !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -1835,12 +1873,12 @@ function ConversationHeader({
|
|
|
1835
1873
|
className: "bg-white/[0.045] inline-flex min-h-6 shrink-0 flex-wrap items-center gap-1 rounded-md px-1.5 py-0.5 text-xs text-muted-foreground",
|
|
1836
1874
|
title: clientTooltip ?? clientDisplayLabel,
|
|
1837
1875
|
children: [
|
|
1838
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: clientApp, className: "size-4 shrink-0" }),
|
|
1876
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: clientApp, className: "size-4 shrink-0", decorative: true }),
|
|
1839
1877
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono leading-snug tabular-nums", children: clientDisplayLabel })
|
|
1840
1878
|
]
|
|
1841
1879
|
}
|
|
1842
1880
|
),
|
|
1843
|
-
isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx(PendingTurnBadge
|
|
1881
|
+
isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx(PendingTurnBadge, {})
|
|
1844
1882
|
] }),
|
|
1845
1883
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1.5 flex min-w-0 flex-wrap items-center gap-1.5", children: [
|
|
1846
1884
|
/* @__PURE__ */ jsxRuntimeExports.jsx(HeaderMetric, { icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3 shrink-0" }), title: timeLabel, children: timeLabel }),
|
|
@@ -2527,27 +2565,27 @@ function useCopyFeedback(text) {
|
|
|
2527
2565
|
return { copied, copy };
|
|
2528
2566
|
}
|
|
2529
2567
|
const LazyCompareDrawer = reactExports.lazy(
|
|
2530
|
-
() => import("./CompareDrawer-
|
|
2568
|
+
() => import("./CompareDrawer-BMRH3N97.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
2531
2569
|
);
|
|
2532
2570
|
const LazyReplayDialog = reactExports.lazy(
|
|
2533
|
-
() => import("./ReplayDialog-
|
|
2571
|
+
() => import("./ReplayDialog-CbWvRHiN.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
2534
2572
|
);
|
|
2535
2573
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
2536
|
-
() => import("./RequestAnatomy-
|
|
2574
|
+
() => import("./RequestAnatomy-C4kcPyqN.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
2537
2575
|
);
|
|
2538
2576
|
const LazyResponseView = reactExports.lazy(
|
|
2539
|
-
() => import("./ResponseView-
|
|
2577
|
+
() => import("./ResponseView-D8VYt-gZ.mjs").then((m) => ({ default: m.ResponseView }))
|
|
2540
2578
|
);
|
|
2541
2579
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
2542
|
-
() => import("./StreamingChunkSequence-
|
|
2580
|
+
() => import("./StreamingChunkSequence-BUUo6vU0.mjs").then((m) => ({
|
|
2543
2581
|
default: m.StreamingChunkSequence
|
|
2544
2582
|
}))
|
|
2545
2583
|
);
|
|
2546
2584
|
const LazyJsonViewer = reactExports.lazy(
|
|
2547
|
-
() => import("./json-viewer-
|
|
2585
|
+
() => import("./json-viewer-BqF1pSQD.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
2548
2586
|
);
|
|
2549
2587
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
2550
|
-
() => import("./json-viewer-
|
|
2588
|
+
() => import("./json-viewer-BqF1pSQD.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
2551
2589
|
);
|
|
2552
2590
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
2553
2591
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -6173,7 +6211,7 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
6173
6211
|
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
6174
6212
|
};
|
|
6175
6213
|
}, [group.logs, setExpanded]);
|
|
6176
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-
|
|
6214
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-1.5", children: [
|
|
6177
6215
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6178
6216
|
ConversationHeader,
|
|
6179
6217
|
{
|
|
@@ -9067,16 +9105,7 @@ function ProviderCard({
|
|
|
9067
9105
|
onRefreshMetadata,
|
|
9068
9106
|
isRefreshingMetadata = false
|
|
9069
9107
|
}) {
|
|
9070
|
-
const [showApiKey, setShowApiKey] = reactExports.useState(false);
|
|
9071
|
-
const [copied, setCopied] = reactExports.useState(false);
|
|
9072
9108
|
const [showDetails, setShowDetails] = reactExports.useState(false);
|
|
9073
|
-
function handleCopy() {
|
|
9074
|
-
void copyTextToClipboard(provider.apiKey).then((success) => {
|
|
9075
|
-
if (!success) return;
|
|
9076
|
-
setCopied(true);
|
|
9077
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
9078
|
-
});
|
|
9079
|
-
}
|
|
9080
9109
|
const docsUrl = provider.apiDocsUrl ?? Object.entries(KNOWN_PROVIDER_DOCS).find(
|
|
9081
9110
|
([keyword]) => provider.name.toLowerCase().includes(keyword)
|
|
9082
9111
|
)?.[1];
|
|
@@ -9163,28 +9192,9 @@ function ProviderCard({
|
|
|
9163
9192
|
] })
|
|
9164
9193
|
] }),
|
|
9165
9194
|
showDetails && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 border-t border-border/60 pt-3", children: [
|
|
9166
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9167
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9168
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9169
|
-
"button",
|
|
9170
|
-
{
|
|
9171
|
-
type: "button",
|
|
9172
|
-
onClick: () => setShowApiKey((s) => !s),
|
|
9173
|
-
className: "p-1 text-muted-foreground transition-colors hover:text-foreground",
|
|
9174
|
-
"aria-label": showApiKey ? "Hide API key" : "Show API key",
|
|
9175
|
-
children: showApiKey ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "size-4" })
|
|
9176
|
-
}
|
|
9177
|
-
),
|
|
9178
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9179
|
-
"button",
|
|
9180
|
-
{
|
|
9181
|
-
type: "button",
|
|
9182
|
-
onClick: handleCopy,
|
|
9183
|
-
className: "p-1 text-muted-foreground transition-colors hover:text-foreground",
|
|
9184
|
-
"aria-label": "Copy API key",
|
|
9185
|
-
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4 text-cyan-300" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" })
|
|
9186
|
-
}
|
|
9187
|
-
)
|
|
9195
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
9196
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "size-3.5 text-emerald-500" }),
|
|
9197
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "API key configured" })
|
|
9188
9198
|
] }),
|
|
9189
9199
|
provider.models !== void 0 && provider.models.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: provider.models.map((model) => /* @__PURE__ */ jsxRuntimeExports.jsx(ModelChip, { provider, model }, model)) }),
|
|
9190
9200
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "space-y-2", children: [
|
|
@@ -9500,7 +9510,7 @@ function EndpointUrlPreview({
|
|
|
9500
9510
|
function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
9501
9511
|
const initialCapabilities = deriveProviderCapabilities(provider);
|
|
9502
9512
|
const [name, setName] = reactExports.useState(provider?.name ?? "");
|
|
9503
|
-
const [apiKey, setApiKey] = reactExports.useState(
|
|
9513
|
+
const [apiKey, setApiKey] = reactExports.useState("");
|
|
9504
9514
|
const [showApiKey, setShowApiKey] = reactExports.useState(false);
|
|
9505
9515
|
const [copied, setCopied] = reactExports.useState(false);
|
|
9506
9516
|
const initialModels = provider?.models;
|
|
@@ -9568,7 +9578,8 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9568
9578
|
reactExports.useEffect(() => {
|
|
9569
9579
|
if (provider) {
|
|
9570
9580
|
setName(provider.name);
|
|
9571
|
-
setApiKey(
|
|
9581
|
+
setApiKey("");
|
|
9582
|
+
setShowApiKey(false);
|
|
9572
9583
|
const nextModels = (provider.models?.length ?? 0) > 0 ? provider.models : [""];
|
|
9573
9584
|
setModels(nextModels);
|
|
9574
9585
|
setModelMetadataDrafts(createMetadataDrafts(provider, nextModels));
|
|
@@ -9628,7 +9639,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9628
9639
|
if (!name.trim()) {
|
|
9629
9640
|
newErrors.name = "Name is required";
|
|
9630
9641
|
}
|
|
9631
|
-
if (!apiKey.trim()) {
|
|
9642
|
+
if (provider === void 0 && !apiKey.trim()) {
|
|
9632
9643
|
newErrors.apiKey = "API key is required";
|
|
9633
9644
|
}
|
|
9634
9645
|
if (models.length === 0 || models.every((m) => !m.trim())) {
|
|
@@ -10072,21 +10083,17 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
10072
10083
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
10073
10084
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { htmlFor: "provider-apikey", className: "text-sm font-medium", children: [
|
|
10074
10085
|
"API Key ",
|
|
10075
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
10086
|
+
provider === void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
10076
10087
|
] }),
|
|
10077
10088
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10078
10089
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10079
10090
|
"input",
|
|
10080
10091
|
{
|
|
10081
10092
|
id: "provider-apikey",
|
|
10082
|
-
type: "text",
|
|
10083
|
-
value:
|
|
10093
|
+
type: showApiKey ? "text" : "password",
|
|
10094
|
+
value: apiKey,
|
|
10084
10095
|
onChange: (e) => setApiKey(e.target.value),
|
|
10085
|
-
|
|
10086
|
-
if (!showApiKey && apiKey.length > 0) setShowApiKey(true);
|
|
10087
|
-
},
|
|
10088
|
-
placeholder: "sk-ant-...",
|
|
10089
|
-
readOnly: !showApiKey && apiKey.length > 0,
|
|
10096
|
+
placeholder: provider === void 0 ? "sk-ant-..." : "Leave blank to keep current key",
|
|
10090
10097
|
className: "flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50"
|
|
10091
10098
|
}
|
|
10092
10099
|
),
|
|
@@ -10111,6 +10118,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
10111
10118
|
}
|
|
10112
10119
|
)
|
|
10113
10120
|
] }),
|
|
10121
|
+
provider !== void 0 && apiKey.trim() === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "A key is configured. Enter a new value only to rotate it." }),
|
|
10114
10122
|
errors.apiKey !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.apiKey })
|
|
10115
10123
|
] }),
|
|
10116
10124
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
@@ -10336,7 +10344,7 @@ function endpointPayloadValue(value, preserveEmptyEndpoints) {
|
|
|
10336
10344
|
function createProviderPayload(data, preserveEmptyEndpoints = false) {
|
|
10337
10345
|
return {
|
|
10338
10346
|
name: data.name,
|
|
10339
|
-
apiKey: data.apiKey,
|
|
10347
|
+
...data.apiKey.trim() === "" ? {} : { apiKey: data.apiKey },
|
|
10340
10348
|
models: data.models,
|
|
10341
10349
|
anthropicBaseUrl: endpointPayloadValue(data.anthropicBaseUrl, preserveEmptyEndpoints),
|
|
10342
10350
|
openaiBaseUrl: endpointPayloadValue(data.openaiBaseUrl, preserveEmptyEndpoints),
|
|
@@ -10636,7 +10644,7 @@ function ProvidersPanel({
|
|
|
10636
10644
|
await refreshProviderMetadata(updated.id, data.modelMetadataUrl, false);
|
|
10637
10645
|
}
|
|
10638
10646
|
refreshProviders();
|
|
10639
|
-
const criticalFieldsChanged =
|
|
10647
|
+
const criticalFieldsChanged = data.apiKey.trim() !== "" || JSON.stringify(data.models) !== JSON.stringify(editingProvider.models) || (data.anthropicBaseUrl ?? "") !== (editingProvider.anthropicBaseUrl ?? "") || (data.openaiBaseUrl ?? "") !== (editingProvider.openaiBaseUrl ?? "") || (data.openaiResponsesBaseUrl ?? "") !== (editingProvider.openaiResponsesBaseUrl ?? "");
|
|
10640
10648
|
if (criticalFieldsChanged) {
|
|
10641
10649
|
await runTest(updated.id);
|
|
10642
10650
|
}
|
|
@@ -11283,9 +11291,9 @@ function McpSettingsTab() {
|
|
|
11283
11291
|
value: `agent-inspector-mcp doctor --url ${endpoint}`
|
|
11284
11292
|
},
|
|
11285
11293
|
{
|
|
11286
|
-
id: "
|
|
11287
|
-
label: "
|
|
11288
|
-
value: "
|
|
11294
|
+
id: "writes",
|
|
11295
|
+
label: "Enable write tools",
|
|
11296
|
+
value: "AGENT_INSPECTOR_MCP_WRITES=1 agent-inspector"
|
|
11289
11297
|
},
|
|
11290
11298
|
{
|
|
11291
11299
|
id: "capabilities",
|
|
@@ -12449,8 +12457,8 @@ function resolveInspectorPetStatus(logs, nowMs) {
|
|
|
12449
12457
|
capturedCount
|
|
12450
12458
|
};
|
|
12451
12459
|
}
|
|
12452
|
-
const
|
|
12453
|
-
if (Number.isFinite(
|
|
12460
|
+
const latestTimestamp2 = Date.parse(latest.timestamp);
|
|
12461
|
+
if (Number.isFinite(latestTimestamp2) && nowMs - latestTimestamp2 >= INSPECTOR_PET_SLEEP_AFTER_MS) {
|
|
12454
12462
|
return {
|
|
12455
12463
|
mood: "sleeping",
|
|
12456
12464
|
label: "All quiet",
|
|
@@ -13076,16 +13084,6 @@ function InspectorPet({ logs }) {
|
|
|
13076
13084
|
) })
|
|
13077
13085
|
}
|
|
13078
13086
|
),
|
|
13079
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13080
|
-
"span",
|
|
13081
|
-
{
|
|
13082
|
-
className: cn(
|
|
13083
|
-
"absolute right-0 top-2 size-3 rounded-full border border-background/90",
|
|
13084
|
-
moodDotClass(status.mood),
|
|
13085
|
-
status.mood === "active" && !reduceMotion && "animate-pulse"
|
|
13086
|
-
)
|
|
13087
|
-
}
|
|
13088
|
-
),
|
|
13089
13087
|
reactionVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13090
13088
|
Heart,
|
|
13091
13089
|
{
|
|
@@ -13301,6 +13299,11 @@ function compareField(previous, current) {
|
|
|
13301
13299
|
if (current < previous) return { direction: "down", delta: previous - current };
|
|
13302
13300
|
return null;
|
|
13303
13301
|
}
|
|
13302
|
+
const COLLAPSED_CLIENTS_STORAGE_KEY = "agent-inspector.hierarchy.collapsedClients";
|
|
13303
|
+
const COLLAPSED_PROCESSES_STORAGE_KEY = "agent-inspector.hierarchy.collapsedProcesses";
|
|
13304
|
+
function hasPendingLogs(logs) {
|
|
13305
|
+
return logs.some((log) => log.responseStatus === null);
|
|
13306
|
+
}
|
|
13304
13307
|
function countPendingTurns(logs) {
|
|
13305
13308
|
return logs.filter((log) => log.responseStatus === null).length;
|
|
13306
13309
|
}
|
|
@@ -13335,9 +13338,9 @@ function groupClient(group) {
|
|
|
13335
13338
|
});
|
|
13336
13339
|
}
|
|
13337
13340
|
function fallbackClientLabel(userAgent) {
|
|
13338
|
-
if (userAgent === null || userAgent === "") return "Unknown
|
|
13341
|
+
if (userAgent === null || userAgent === "") return "Unknown client";
|
|
13339
13342
|
const firstToken = userAgent.split(/[ /;]/)[0] ?? "";
|
|
13340
|
-
if (firstToken === "") return "Unknown
|
|
13343
|
+
if (firstToken === "") return "Unknown client";
|
|
13341
13344
|
return firstToken;
|
|
13342
13345
|
}
|
|
13343
13346
|
function clientLabel(client, userAgent) {
|
|
@@ -13359,22 +13362,41 @@ function processKey(clientPid, projectFolder) {
|
|
|
13359
13362
|
function sortLogsByTimestamp(logs) {
|
|
13360
13363
|
return [...logs].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
13361
13364
|
}
|
|
13362
|
-
function
|
|
13363
|
-
|
|
13365
|
+
function latestTimestamp(logs) {
|
|
13366
|
+
let latest = "";
|
|
13367
|
+
for (const log of logs) {
|
|
13368
|
+
if (log.timestamp > latest) latest = log.timestamp;
|
|
13369
|
+
}
|
|
13370
|
+
return latest;
|
|
13364
13371
|
}
|
|
13365
|
-
function
|
|
13366
|
-
|
|
13372
|
+
function operationalPriority(logs) {
|
|
13373
|
+
if (hasPendingLogs(logs)) return 0;
|
|
13374
|
+
if (logs.some(
|
|
13375
|
+
(log) => log.error !== null && log.error !== void 0 || log.responseStatus !== null && log.responseStatus !== void 0 && log.responseStatus >= 400
|
|
13376
|
+
)) {
|
|
13377
|
+
return 1;
|
|
13378
|
+
}
|
|
13379
|
+
return 2;
|
|
13380
|
+
}
|
|
13381
|
+
function sortByOperationalPriority(items) {
|
|
13382
|
+
return [...items].sort((left, right) => {
|
|
13383
|
+
const priorityDifference = operationalPriority(left.logs) - operationalPriority(right.logs);
|
|
13384
|
+
if (priorityDifference !== 0) return priorityDifference;
|
|
13385
|
+
const recencyDifference = latestTimestamp(right.logs).localeCompare(latestTimestamp(left.logs));
|
|
13386
|
+
if (recencyDifference !== 0) return recencyDifference;
|
|
13387
|
+
return left.id.localeCompare(right.id);
|
|
13388
|
+
});
|
|
13367
13389
|
}
|
|
13368
13390
|
function buildConversationHierarchy(groups) {
|
|
13369
|
-
const
|
|
13391
|
+
const clientGroups = /* @__PURE__ */ new Map();
|
|
13370
13392
|
for (const group of groups) {
|
|
13371
13393
|
const userAgent = firstUserAgent(group.logs);
|
|
13372
13394
|
const projectFolder = firstClientProjectFolder(group.logs);
|
|
13373
13395
|
const client = groupClient(group);
|
|
13374
13396
|
const currentIdeKey = ideKey(client, userAgent, projectFolder);
|
|
13375
|
-
let
|
|
13376
|
-
if (
|
|
13377
|
-
|
|
13397
|
+
let clientGroup = clientGroups.get(currentIdeKey);
|
|
13398
|
+
if (clientGroup === void 0) {
|
|
13399
|
+
clientGroup = {
|
|
13378
13400
|
id: currentIdeKey,
|
|
13379
13401
|
client,
|
|
13380
13402
|
label: clientLabel(client, userAgent),
|
|
@@ -13382,12 +13404,12 @@ function buildConversationHierarchy(groups) {
|
|
|
13382
13404
|
processes: /* @__PURE__ */ new Map(),
|
|
13383
13405
|
logs: []
|
|
13384
13406
|
};
|
|
13385
|
-
|
|
13407
|
+
clientGroups.set(currentIdeKey, clientGroup);
|
|
13386
13408
|
}
|
|
13387
|
-
|
|
13409
|
+
clientGroup.logs.push(...group.logs);
|
|
13388
13410
|
const clientPid = firstClientPid(group.logs);
|
|
13389
13411
|
const currentProcessKey = `${currentIdeKey}:${processKey(clientPid, projectFolder)}`;
|
|
13390
|
-
let processGroup =
|
|
13412
|
+
let processGroup = clientGroup.processes.get(currentProcessKey);
|
|
13391
13413
|
if (processGroup === void 0) {
|
|
13392
13414
|
processGroup = {
|
|
13393
13415
|
id: currentProcessKey,
|
|
@@ -13396,32 +13418,32 @@ function buildConversationHierarchy(groups) {
|
|
|
13396
13418
|
sessions: [],
|
|
13397
13419
|
logs: []
|
|
13398
13420
|
};
|
|
13399
|
-
|
|
13421
|
+
clientGroup.processes.set(currentProcessKey, processGroup);
|
|
13400
13422
|
}
|
|
13401
13423
|
processGroup.sessions.push(group);
|
|
13402
13424
|
processGroup.logs.push(...group.logs);
|
|
13403
13425
|
}
|
|
13404
13426
|
const hierarchy = [];
|
|
13405
|
-
for (const
|
|
13406
|
-
const processes =
|
|
13407
|
-
[...
|
|
13427
|
+
for (const clientGroup of clientGroups.values()) {
|
|
13428
|
+
const processes = sortByOperationalPriority(
|
|
13429
|
+
[...clientGroup.processes.values()].map((processGroup) => ({
|
|
13408
13430
|
id: processGroup.id,
|
|
13409
13431
|
clientPid: processGroup.clientPid,
|
|
13410
13432
|
clientProjectFolder: processGroup.clientProjectFolder,
|
|
13411
|
-
sessions:
|
|
13433
|
+
sessions: sortByOperationalPriority(processGroup.sessions),
|
|
13412
13434
|
logs: sortLogsByTimestamp(processGroup.logs)
|
|
13413
13435
|
}))
|
|
13414
13436
|
);
|
|
13415
13437
|
hierarchy.push({
|
|
13416
|
-
id:
|
|
13417
|
-
client:
|
|
13418
|
-
label:
|
|
13419
|
-
userAgent:
|
|
13438
|
+
id: clientGroup.id,
|
|
13439
|
+
client: clientGroup.client,
|
|
13440
|
+
label: clientGroup.label,
|
|
13441
|
+
userAgent: clientGroup.userAgent,
|
|
13420
13442
|
processes,
|
|
13421
|
-
logs: sortLogsByTimestamp(
|
|
13443
|
+
logs: sortLogsByTimestamp(clientGroup.logs)
|
|
13422
13444
|
});
|
|
13423
13445
|
}
|
|
13424
|
-
return
|
|
13446
|
+
return sortByOperationalPriority(hierarchy);
|
|
13425
13447
|
}
|
|
13426
13448
|
function formatTokenCount(count) {
|
|
13427
13449
|
if (count <= 0) return "0";
|
|
@@ -13445,6 +13467,30 @@ function countSessions(processes) {
|
|
|
13445
13467
|
}
|
|
13446
13468
|
return sessions;
|
|
13447
13469
|
}
|
|
13470
|
+
function readStoredIdSet(storageKey) {
|
|
13471
|
+
if (typeof window === "undefined") return /* @__PURE__ */ new Set();
|
|
13472
|
+
try {
|
|
13473
|
+
const parsed = JSON.parse(window.localStorage.getItem(storageKey) ?? "[]");
|
|
13474
|
+
if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
|
|
13475
|
+
return new Set(parsed.filter((value) => typeof value === "string"));
|
|
13476
|
+
} catch {
|
|
13477
|
+
return /* @__PURE__ */ new Set();
|
|
13478
|
+
}
|
|
13479
|
+
}
|
|
13480
|
+
function persistIdSet(storageKey, values) {
|
|
13481
|
+
try {
|
|
13482
|
+
window.localStorage.setItem(storageKey, JSON.stringify([...values]));
|
|
13483
|
+
} catch {
|
|
13484
|
+
}
|
|
13485
|
+
}
|
|
13486
|
+
function removeIds(values, ids) {
|
|
13487
|
+
let changed = false;
|
|
13488
|
+
const next = new Set(values);
|
|
13489
|
+
for (const id of ids) {
|
|
13490
|
+
if (next.delete(id)) changed = true;
|
|
13491
|
+
}
|
|
13492
|
+
return changed ? next : values;
|
|
13493
|
+
}
|
|
13448
13494
|
function shortProjectPath(projectFolder) {
|
|
13449
13495
|
if (projectFolder === null || projectFolder === "") return null;
|
|
13450
13496
|
const parts = projectFolder.replaceAll("\\", "/").split("/").filter((part) => part !== "");
|
|
@@ -13463,57 +13509,67 @@ function SummaryChip({
|
|
|
13463
13509
|
"span",
|
|
13464
13510
|
{
|
|
13465
13511
|
className: cn(
|
|
13466
|
-
"bg-white/[0.
|
|
13512
|
+
"bg-white/[0.04] inline-flex h-7 items-center gap-1 rounded-md px-2 text-xs text-muted-foreground",
|
|
13467
13513
|
className
|
|
13468
13514
|
),
|
|
13469
13515
|
children: [
|
|
13470
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] uppercase
|
|
13516
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] uppercase text-white/35", children: label }),
|
|
13471
13517
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums text-slate-100", children: value })
|
|
13472
13518
|
]
|
|
13473
13519
|
}
|
|
13474
13520
|
);
|
|
13475
13521
|
}
|
|
13476
|
-
function
|
|
13477
|
-
count
|
|
13478
|
-
label = "Turn open"
|
|
13479
|
-
}) {
|
|
13522
|
+
function AncestorActivityIndicator({ count }) {
|
|
13523
|
+
const label = `${count} open turn${count === 1 ? "" : "s"}`;
|
|
13480
13524
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13481
13525
|
"span",
|
|
13482
13526
|
{
|
|
13483
|
-
className: "inline-flex
|
|
13484
|
-
|
|
13527
|
+
className: "relative inline-flex size-6 shrink-0 items-center justify-center rounded-md bg-amber-300/[0.08] text-amber-100/90 ring-1 ring-amber-200/10",
|
|
13528
|
+
"aria-label": label,
|
|
13529
|
+
title: label,
|
|
13485
13530
|
children: [
|
|
13486
13531
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3 animate-spin" }),
|
|
13487
|
-
|
|
13488
|
-
count > 1 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "tabular-nums", children: [
|
|
13489
|
-
"x",
|
|
13490
|
-
count
|
|
13491
|
-
] })
|
|
13532
|
+
count > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute translate-x-2 -translate-y-2 rounded bg-background px-0.5 font-mono text-[8px] tabular-nums text-amber-100", children: count })
|
|
13492
13533
|
]
|
|
13493
13534
|
}
|
|
13494
13535
|
);
|
|
13495
13536
|
}
|
|
13496
|
-
function LoadingSweep() {
|
|
13497
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13498
|
-
"span",
|
|
13499
|
-
{
|
|
13500
|
-
className: "pointer-events-none absolute inset-x-3 bottom-0 h-px overflow-hidden rounded-full bg-white/[0.06]",
|
|
13501
|
-
"aria-hidden": "true",
|
|
13502
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute inset-y-0 left-0 w-1/3 animate-pulse rounded-full bg-amber-200/65 shadow-[0_0_14px_rgba(252,211,77,0.32)]" })
|
|
13503
|
-
}
|
|
13504
|
-
);
|
|
13505
|
-
}
|
|
13506
13537
|
function ConversationGroupList({
|
|
13507
13538
|
groups,
|
|
13508
13539
|
...groupProps
|
|
13509
13540
|
}) {
|
|
13510
13541
|
const hierarchy = reactExports.useMemo(() => buildConversationHierarchy(groups), [groups]);
|
|
13511
|
-
const [
|
|
13542
|
+
const [collapsedClientIds, setCollapsedClientIds] = reactExports.useState(
|
|
13543
|
+
() => /* @__PURE__ */ new Set()
|
|
13544
|
+
);
|
|
13512
13545
|
const [collapsedProcessIds, setCollapsedProcessIds] = reactExports.useState(
|
|
13513
13546
|
() => /* @__PURE__ */ new Set()
|
|
13514
13547
|
);
|
|
13515
|
-
const
|
|
13516
|
-
|
|
13548
|
+
const [storedCollapseStateLoaded, setStoredCollapseStateLoaded] = reactExports.useState(false);
|
|
13549
|
+
reactExports.useEffect(() => {
|
|
13550
|
+
setCollapsedClientIds(readStoredIdSet(COLLAPSED_CLIENTS_STORAGE_KEY));
|
|
13551
|
+
setCollapsedProcessIds(readStoredIdSet(COLLAPSED_PROCESSES_STORAGE_KEY));
|
|
13552
|
+
setStoredCollapseStateLoaded(true);
|
|
13553
|
+
}, []);
|
|
13554
|
+
reactExports.useEffect(() => {
|
|
13555
|
+
if (!storedCollapseStateLoaded) return;
|
|
13556
|
+
persistIdSet(COLLAPSED_CLIENTS_STORAGE_KEY, collapsedClientIds);
|
|
13557
|
+
persistIdSet(COLLAPSED_PROCESSES_STORAGE_KEY, collapsedProcessIds);
|
|
13558
|
+
}, [collapsedClientIds, collapsedProcessIds, storedCollapseStateLoaded]);
|
|
13559
|
+
reactExports.useEffect(() => {
|
|
13560
|
+
const activeClientIds = new Set(
|
|
13561
|
+
hierarchy.filter((group) => hasPendingLogs(group.logs)).map((group) => group.id)
|
|
13562
|
+
);
|
|
13563
|
+
const activeProcessIds = new Set(
|
|
13564
|
+
hierarchy.flatMap(
|
|
13565
|
+
(group) => group.processes.filter((process) => hasPendingLogs(process.logs)).map((process) => process.id)
|
|
13566
|
+
)
|
|
13567
|
+
);
|
|
13568
|
+
setCollapsedClientIds((previous) => removeIds(previous, activeClientIds));
|
|
13569
|
+
setCollapsedProcessIds((previous) => removeIds(previous, activeProcessIds));
|
|
13570
|
+
}, [hierarchy]);
|
|
13571
|
+
const toggleClient = reactExports.useCallback((id) => {
|
|
13572
|
+
setCollapsedClientIds((previous) => {
|
|
13517
13573
|
const next = new Set(previous);
|
|
13518
13574
|
if (next.has(id)) {
|
|
13519
13575
|
next.delete(id);
|
|
@@ -13534,24 +13590,24 @@ function ConversationGroupList({
|
|
|
13534
13590
|
return next;
|
|
13535
13591
|
});
|
|
13536
13592
|
}, []);
|
|
13537
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-
|
|
13538
|
-
|
|
13593
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: hierarchy.map((clientGroup) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13594
|
+
ClientGroupSection,
|
|
13539
13595
|
{
|
|
13540
|
-
group:
|
|
13541
|
-
collapsed:
|
|
13596
|
+
group: clientGroup,
|
|
13597
|
+
collapsed: collapsedClientIds.has(clientGroup.id),
|
|
13542
13598
|
collapsedProcessIds,
|
|
13543
|
-
|
|
13599
|
+
onToggleClient: () => toggleClient(clientGroup.id),
|
|
13544
13600
|
onToggleProcess: toggleProcess,
|
|
13545
13601
|
conversationProps: groupProps
|
|
13546
13602
|
},
|
|
13547
|
-
|
|
13603
|
+
clientGroup.id
|
|
13548
13604
|
)) });
|
|
13549
13605
|
}
|
|
13550
|
-
function
|
|
13606
|
+
function ClientGroupSection({
|
|
13551
13607
|
group,
|
|
13552
13608
|
collapsed,
|
|
13553
13609
|
collapsedProcessIds,
|
|
13554
|
-
|
|
13610
|
+
onToggleClient,
|
|
13555
13611
|
onToggleProcess,
|
|
13556
13612
|
conversationProps
|
|
13557
13613
|
}) {
|
|
@@ -13564,8 +13620,8 @@ function IdeGroupSection({
|
|
|
13564
13620
|
"section",
|
|
13565
13621
|
{
|
|
13566
13622
|
className: cn(
|
|
13567
|
-
"bg-card/
|
|
13568
|
-
isWorking && "bg-card/
|
|
13623
|
+
"bg-card/60 relative isolate overflow-hidden rounded-[8px] shadow-sm",
|
|
13624
|
+
isWorking && "bg-card/70"
|
|
13569
13625
|
),
|
|
13570
13626
|
"data-ide-group": group.id,
|
|
13571
13627
|
children: [
|
|
@@ -13573,12 +13629,19 @@ function IdeGroupSection({
|
|
|
13573
13629
|
"button",
|
|
13574
13630
|
{
|
|
13575
13631
|
type: "button",
|
|
13576
|
-
className: "
|
|
13577
|
-
onClick:
|
|
13632
|
+
className: "grid w-full min-w-0 grid-cols-[2.25rem_minmax(0,1fr)_auto] items-center gap-2.5 px-3 py-2.5 text-left transition-colors hover:bg-white/[0.025] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-300/40",
|
|
13633
|
+
onClick: onToggleClient,
|
|
13578
13634
|
"aria-expanded": !collapsed,
|
|
13579
13635
|
children: [
|
|
13580
|
-
group.client === "unknown" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "bg-white/[0.
|
|
13581
|
-
|
|
13636
|
+
group.client === "unknown" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "bg-white/[0.04] inline-flex size-9 shrink-0 items-center justify-center rounded-md text-slate-300", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Monitor, { className: "size-4" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13637
|
+
ClientLogo,
|
|
13638
|
+
{
|
|
13639
|
+
client: group.client,
|
|
13640
|
+
className: "size-9 rounded-md text-cyan-100",
|
|
13641
|
+
decorative: true
|
|
13642
|
+
}
|
|
13643
|
+
),
|
|
13644
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0", children: [
|
|
13582
13645
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
13583
13646
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13584
13647
|
"span",
|
|
@@ -13588,10 +13651,10 @@ function IdeGroupSection({
|
|
|
13588
13651
|
children: group.label
|
|
13589
13652
|
}
|
|
13590
13653
|
),
|
|
13591
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded bg-cyan-300/[0.
|
|
13592
|
-
isWorking && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13654
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded bg-cyan-300/[0.05] px-1.5 py-0.5 font-mono text-[9px] uppercase text-cyan-100/70", children: clientAppTypeLabel(group.client) }),
|
|
13655
|
+
isWorking && /* @__PURE__ */ jsxRuntimeExports.jsx(AncestorActivityIndicator, { count: pendingTurnCount })
|
|
13593
13656
|
] }),
|
|
13594
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-
|
|
13657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-muted-foreground", children: [
|
|
13595
13658
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
13596
13659
|
group.processes.length,
|
|
13597
13660
|
" process",
|
|
@@ -13604,21 +13667,21 @@ function IdeGroupSection({
|
|
|
13604
13667
|
] }),
|
|
13605
13668
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
13606
13669
|
logCount,
|
|
13607
|
-
"
|
|
13608
|
-
logCount !== 1 ? "s" : ""
|
|
13670
|
+
" req"
|
|
13609
13671
|
] })
|
|
13610
13672
|
] })
|
|
13611
13673
|
] }),
|
|
13612
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
13613
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13674
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
|
|
13675
|
+
collapsed && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 items-center gap-2 md:flex", children: [
|
|
13676
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "IN", value: formatTokenCount(totals.inputTokens) }),
|
|
13677
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "OUT", value: formatTokenCount(totals.outputTokens) })
|
|
13678
|
+
] }),
|
|
13679
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "bg-white/[0.04] hover:bg-white/[0.07] inline-flex size-8 shrink-0 items-center justify-center rounded-md text-slate-300", children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }) })
|
|
13680
|
+
] })
|
|
13617
13681
|
]
|
|
13618
13682
|
}
|
|
13619
13683
|
),
|
|
13620
|
-
|
|
13621
|
-
!collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3 px-3 pb-3 pt-2 sm:px-4", children: group.processes.map((processGroup) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13684
|
+
!collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 px-2 pb-2 pt-1", children: group.processes.map((processGroup) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13622
13685
|
ProcessGroupSection,
|
|
13623
13686
|
{
|
|
13624
13687
|
group: processGroup,
|
|
@@ -13644,69 +13707,66 @@ function ProcessGroupSection({
|
|
|
13644
13707
|
const logCount = group.logs.length;
|
|
13645
13708
|
const pendingTurnCount = countPendingTurns(group.logs);
|
|
13646
13709
|
const isWorking = pendingTurnCount > 0;
|
|
13647
|
-
const processLabel = group.clientPid !== null && group.clientPid !== void 0 ? `PID ${group.clientPid}` : "
|
|
13648
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "relative pl-
|
|
13649
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
"button",
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
"
|
|
13658
|
-
children: [
|
|
13659
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
13660
|
-
|
|
13661
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
13662
|
-
|
|
13663
|
-
|
|
13664
|
-
|
|
13665
|
-
"
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
|
|
13669
|
-
children:
|
|
13670
|
-
|
|
13671
|
-
|
|
13672
|
-
|
|
13673
|
-
|
|
13674
|
-
|
|
13710
|
+
const processLabel = group.clientPid !== null && group.clientPid !== void 0 ? `PID ${group.clientPid}` : "PID unavailable";
|
|
13711
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "relative pl-4", children: [
|
|
13712
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13713
|
+
"button",
|
|
13714
|
+
{
|
|
13715
|
+
type: "button",
|
|
13716
|
+
className: "bg-black/[0.07] grid w-full min-w-0 grid-cols-[2rem_minmax(0,1fr)_auto] items-center gap-2.5 rounded-md px-2.5 py-2 text-left transition-colors hover:bg-white/[0.03] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-300/35",
|
|
13717
|
+
onClick: onToggle,
|
|
13718
|
+
"aria-expanded": !collapsed,
|
|
13719
|
+
children: [
|
|
13720
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "bg-white/[0.04] inline-flex size-8 shrink-0 items-center justify-center rounded-md text-amber-100/85", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Cpu, { className: "size-4" }) }),
|
|
13721
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0", children: [
|
|
13722
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
13723
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs font-semibold tabular-nums text-slate-100", children: processLabel }),
|
|
13724
|
+
isWorking && /* @__PURE__ */ jsxRuntimeExports.jsx(AncestorActivityIndicator, { count: pendingTurnCount }),
|
|
13725
|
+
projectLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13726
|
+
"span",
|
|
13727
|
+
{
|
|
13728
|
+
className: "inline-flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground",
|
|
13729
|
+
title: group.clientProjectFolder ?? projectLabel,
|
|
13730
|
+
children: [
|
|
13731
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-3 shrink-0" }),
|
|
13732
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-mono", children: projectLabel })
|
|
13733
|
+
]
|
|
13734
|
+
}
|
|
13735
|
+
)
|
|
13736
|
+
] }),
|
|
13737
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-muted-foreground", children: [
|
|
13738
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
13739
|
+
sessionCount,
|
|
13740
|
+
" session",
|
|
13741
|
+
sessionCount !== 1 ? "s" : ""
|
|
13675
13742
|
] }),
|
|
13676
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", {
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
" session",
|
|
13680
|
-
sessionCount !== 1 ? "s" : ""
|
|
13681
|
-
] }),
|
|
13682
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
13683
|
-
logCount,
|
|
13684
|
-
" log",
|
|
13685
|
-
logCount !== 1 ? "s" : ""
|
|
13686
|
-
] })
|
|
13743
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
13744
|
+
logCount,
|
|
13745
|
+
" req"
|
|
13687
13746
|
] })
|
|
13688
|
-
] })
|
|
13689
|
-
|
|
13747
|
+
] })
|
|
13748
|
+
] }),
|
|
13749
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
|
|
13750
|
+
collapsed && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 items-center gap-2 md:flex", children: [
|
|
13690
13751
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "IN", value: formatTokenCount(totals.inputTokens) }),
|
|
13691
13752
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "OUT", value: formatTokenCount(totals.outputTokens) })
|
|
13692
13753
|
] }),
|
|
13693
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "bg-white/[0.
|
|
13694
|
-
]
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
|
|
13701
|
-
|
|
13702
|
-
|
|
13703
|
-
|
|
13704
|
-
|
|
13705
|
-
|
|
13706
|
-
|
|
13707
|
-
|
|
13708
|
-
|
|
13709
|
-
] })
|
|
13754
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "bg-white/[0.04] hover:bg-white/[0.07] inline-flex size-7 shrink-0 items-center justify-center rounded-md text-slate-300", children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }) })
|
|
13755
|
+
] })
|
|
13756
|
+
]
|
|
13757
|
+
}
|
|
13758
|
+
),
|
|
13759
|
+
!collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1.5 pb-1 pl-4 pr-1 pt-1.5", children: group.sessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13760
|
+
ConversationGroup,
|
|
13761
|
+
{
|
|
13762
|
+
group: session,
|
|
13763
|
+
...conversationProps,
|
|
13764
|
+
showClientIdentity: false,
|
|
13765
|
+
showLogClientMetadata: false,
|
|
13766
|
+
showProcessMetadata: false
|
|
13767
|
+
},
|
|
13768
|
+
session.id
|
|
13769
|
+
)) })
|
|
13710
13770
|
] });
|
|
13711
13771
|
}
|
|
13712
13772
|
const NAV_ATTR = "data-nav-id";
|
|
@@ -15454,6 +15514,27 @@ function ThemeModeToggle() {
|
|
|
15454
15514
|
}
|
|
15455
15515
|
);
|
|
15456
15516
|
}
|
|
15517
|
+
function PetVisibilityToggle({
|
|
15518
|
+
visible,
|
|
15519
|
+
onToggle
|
|
15520
|
+
}) {
|
|
15521
|
+
const label = visible ? "Hide Inspector pet" : "Summon Inspector pet";
|
|
15522
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15523
|
+
"button",
|
|
15524
|
+
{
|
|
15525
|
+
type: "button",
|
|
15526
|
+
onClick: onToggle,
|
|
15527
|
+
className: cn(
|
|
15528
|
+
"border-border/70 bg-muted/70 inline-flex size-8 shrink-0 items-center justify-center rounded-md border text-muted-foreground shadow-sm transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
15529
|
+
visible && "bg-background text-amber-500 shadow-sm"
|
|
15530
|
+
),
|
|
15531
|
+
"aria-label": label,
|
|
15532
|
+
"aria-pressed": visible,
|
|
15533
|
+
title: label,
|
|
15534
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: cn("size-4 transition-opacity", !visible && "opacity-45") })
|
|
15535
|
+
}
|
|
15536
|
+
);
|
|
15537
|
+
}
|
|
15457
15538
|
function UiScaleControl({
|
|
15458
15539
|
preference,
|
|
15459
15540
|
resolvedScale,
|
|
@@ -15565,11 +15646,20 @@ function BrandHeader({
|
|
|
15565
15646
|
] });
|
|
15566
15647
|
}
|
|
15567
15648
|
const DETAILS_PANEL_COLLAPSED_STORAGE_KEY = "agent-inspector.detailsPanelCollapsed";
|
|
15649
|
+
const INSPECTOR_PET_VISIBLE_STORAGE_KEY = "agent-inspector.pet.visible";
|
|
15568
15650
|
function readStoredDetailsPanelCollapsed() {
|
|
15569
15651
|
if (typeof window === "undefined") return true;
|
|
15570
15652
|
const stored = window.localStorage.getItem(DETAILS_PANEL_COLLAPSED_STORAGE_KEY);
|
|
15571
15653
|
return stored === null || stored === "1";
|
|
15572
15654
|
}
|
|
15655
|
+
function readStoredInspectorPetVisible() {
|
|
15656
|
+
if (typeof window === "undefined") return true;
|
|
15657
|
+
try {
|
|
15658
|
+
return window.localStorage.getItem(INSPECTOR_PET_VISIBLE_STORAGE_KEY) !== "0";
|
|
15659
|
+
} catch {
|
|
15660
|
+
return true;
|
|
15661
|
+
}
|
|
15662
|
+
}
|
|
15573
15663
|
function SessionContextLogButton({ label, logId }) {
|
|
15574
15664
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
15575
15665
|
"button",
|
|
@@ -15896,6 +15986,8 @@ function ProxyViewer({
|
|
|
15896
15986
|
const [deletingCurrentView, setDeletingCurrentView] = reactExports.useState(false);
|
|
15897
15987
|
const [detailsPanelCollapsed, setDetailsPanelCollapsed] = reactExports.useState(true);
|
|
15898
15988
|
const [detailsPanelStorageLoaded, setDetailsPanelStorageLoaded] = reactExports.useState(false);
|
|
15989
|
+
const [petVisible, setPetVisible] = reactExports.useState(true);
|
|
15990
|
+
const [petVisibilityStorageLoaded, setPetVisibilityStorageLoaded] = reactExports.useState(false);
|
|
15899
15991
|
const [comparePair, setComparePair] = reactExports.useState(null);
|
|
15900
15992
|
const [crabEntrancePhase, setCrabEntrancePhase] = reactExports.useState(
|
|
15901
15993
|
"hidden"
|
|
@@ -15943,6 +16035,17 @@ function ProxyViewer({
|
|
|
15943
16035
|
detailsPanelCollapsed ? "1" : "0"
|
|
15944
16036
|
);
|
|
15945
16037
|
}, [detailsPanelCollapsed, detailsPanelStorageLoaded]);
|
|
16038
|
+
reactExports.useEffect(() => {
|
|
16039
|
+
setPetVisible(readStoredInspectorPetVisible());
|
|
16040
|
+
setPetVisibilityStorageLoaded(true);
|
|
16041
|
+
}, []);
|
|
16042
|
+
reactExports.useEffect(() => {
|
|
16043
|
+
if (!petVisibilityStorageLoaded) return;
|
|
16044
|
+
try {
|
|
16045
|
+
window.localStorage.setItem(INSPECTOR_PET_VISIBLE_STORAGE_KEY, petVisible ? "1" : "0");
|
|
16046
|
+
} catch {
|
|
16047
|
+
}
|
|
16048
|
+
}, [petVisibilityStorageLoaded, petVisible]);
|
|
15946
16049
|
reactExports.useEffect(() => {
|
|
15947
16050
|
if (pinnedSessionId === void 0) {
|
|
15948
16051
|
document.title = "Agent Inspector";
|
|
@@ -16060,6 +16163,9 @@ function ProxyViewer({
|
|
|
16060
16163
|
const toggleDetailsPanelCollapsed = reactExports.useCallback(() => {
|
|
16061
16164
|
setDetailsPanelCollapsed((value) => !value);
|
|
16062
16165
|
}, []);
|
|
16166
|
+
const togglePetVisibility = reactExports.useCallback(() => {
|
|
16167
|
+
setPetVisible((value) => !value);
|
|
16168
|
+
}, []);
|
|
16063
16169
|
const groups = reactExports.useMemo(() => groupLogsByConversation(logs), [logs]);
|
|
16064
16170
|
const displayNumberByLogId = reactExports.useMemo(() => buildDisplayNumberByLogId(groups), [groups]);
|
|
16065
16171
|
const sessionContextScope = reactExports.useMemo(
|
|
@@ -16138,7 +16244,7 @@ function ProxyViewer({
|
|
|
16138
16244
|
]
|
|
16139
16245
|
}
|
|
16140
16246
|
),
|
|
16141
|
-
|
|
16247
|
+
petVisibilityStorageLoaded && petVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(InspectorPet, { logs }),
|
|
16142
16248
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16143
16249
|
"div",
|
|
16144
16250
|
{
|
|
@@ -16262,6 +16368,7 @@ function ProxyViewer({
|
|
|
16262
16368
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold text-foreground", children: "Logs" }),
|
|
16263
16369
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-0.5 font-mono text-[11px] text-muted-foreground", children: activeScopeLabel })
|
|
16264
16370
|
] }),
|
|
16371
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(PetVisibilityToggle, { visible: petVisible, onToggle: togglePetVisibility }),
|
|
16265
16372
|
onImportLogs !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
16266
16373
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16267
16374
|
"input",
|