@tonyclaw/agent-inspector 3.0.29 → 3.0.30
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 +791 -191
- package/.output/nitro.json +1 -1
- package/.output/public/assets/CompareDrawer-B6cXJohL.js +1 -0
- package/.output/public/assets/InspectorPet-mAzeGmEE.js +4108 -0
- package/.output/public/assets/ProxyViewerContainer-CkFWv_Nm.js +126 -0
- package/.output/public/assets/{ReplayDialog-CctnITbt.js → ReplayDialog-DodiTL6E.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-BrN0RBbL.js → RequestAnatomy-B3IauToI.js} +1 -1
- package/.output/public/assets/ResponseView-Hn-5ordK.js +3 -0
- package/.output/public/assets/StreamingChunkSequence-vLDOVQM_.js +1 -0
- package/.output/public/assets/_sessionId-BFH4TOaI.js +1 -0
- package/.output/public/assets/{_sessionId-DKM91udC.js → _sessionId-Cj_HIFZx.js} +1 -1
- package/.output/public/assets/{index-Bq-nqolG.js → index-Bmj2lcWE.js} +1 -1
- package/.output/public/assets/index-CgJj-HBC.css +1 -0
- package/.output/public/assets/index-Ch7uqnCT.js +1 -0
- package/.output/public/assets/index-DkDdKvLl.js +76 -0
- package/.output/public/assets/{index-DPiESBo2.js → index-ZlhqCrSg.js} +6 -6
- package/.output/public/assets/{json-viewer-CfaDJwx8.js → json-viewer-BdrnVQu-.js} +1 -1
- package/.output/public/assets/jszip.min-CS_nt_o1.js +2 -0
- package/.output/public/assets/qwen-mMn3f5ul.webp +0 -0
- package/.output/server/_libs/jszip.mjs +35 -9
- package/.output/server/_libs/lucide-react.mjs +86 -86
- package/.output/server/_libs/radix-ui__react-dialog.mjs +3 -3
- package/.output/server/_libs/tanstack__react-router.mjs +1 -1
- package/.output/server/{_sessionId-CwGXPD4C.mjs → _sessionId-C5S3pGZd.mjs} +15 -15
- package/.output/server/_sessionId-g6D69lKq.mjs +81 -0
- package/.output/server/_ssr/{CompareDrawer-R_P1-VNr.mjs → CompareDrawer-CqUmGHal.mjs} +138 -103
- package/.output/server/_ssr/InspectorPet-DI0UJd01.mjs +925 -0
- package/.output/server/_ssr/{ProxyViewerContainer-DUgxRNbj.mjs → ProxyViewerContainer-CvsUmbJ3.mjs} +1157 -1613
- package/.output/server/_ssr/{ReplayDialog-De9wKKzS.mjs → ReplayDialog-DS48dpFG.mjs} +18 -18
- package/.output/server/_ssr/{RequestAnatomy-Db4MxUYo.mjs → RequestAnatomy-DxYVQU1C.mjs} +58 -58
- package/.output/server/_ssr/{ResponseView-8rDXOiNB.mjs → ResponseView-BLXW73eq.mjs} +60 -60
- package/.output/server/_ssr/{StreamingChunkSequence-N9teZHkA.mjs → StreamingChunkSequence-DD0iFuy0.mjs} +16 -16
- package/.output/server/_ssr/{index-D4DvByuW.mjs → index-B10LIaK0.mjs} +15 -15
- package/.output/server/_ssr/index-RHVJnU2p.mjs +81 -0
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-BjoHRbjS.mjs → json-viewer-LDu2XBaK.mjs} +58 -58
- package/.output/server/_ssr/{router-BYlePDj8.mjs → router-GKvrwifJ.mjs} +9005 -6488
- package/.output/server/_tanstack-start-manifest_v-Df2n4mbT.mjs +4 -0
- package/.output/server/index.mjs +103 -75
- package/.output/workers/logFinalizer.worker.js +16908 -0
- package/.output/workers/sessionWorkerEntry.js +16904 -0
- package/README.md +21 -5
- package/package.json +6 -2
- package/src/assets/logos/qwen.webp +0 -0
- package/src/cli.ts +85 -10
- package/src/components/OnboardingBanner.tsx +41 -21
- package/src/components/ProxyViewer.tsx +198 -269
- package/src/components/ProxyViewerContainer.tsx +128 -17
- package/src/components/ecosystem/AgentLabDialog.tsx +166 -19
- package/src/components/errors/SafeErrorBoundary.tsx +201 -0
- package/src/components/pi-agent/PiAgentPanel.tsx +4 -1
- package/src/components/providers/ImportWizardDialog.tsx +18 -42
- package/src/components/providers/ProviderLogo.tsx +1 -1
- package/src/components/providers/ProvidersPanel.tsx +8 -5
- package/src/components/providers/SettingsDialog.tsx +34 -11
- package/src/components/proxy-viewer/ApplicationBar.tsx +63 -0
- package/src/components/proxy-viewer/CompareDrawer.tsx +92 -49
- package/src/components/proxy-viewer/LiveConnectionStatus.tsx +186 -0
- package/src/components/proxy-viewer/LogEntry.tsx +283 -275
- package/src/components/proxy-viewer/RawExportWarning.tsx +77 -0
- package/src/components/proxy-viewer/SessionLoadProgressBar.tsx +61 -0
- package/src/components/proxy-viewer/ThreadConnector.tsx +16 -1
- package/src/components/proxy-viewer/TurnGroup.tsx +13 -2
- package/src/components/proxy-viewer/accessibility.ts +8 -0
- package/src/components/proxy-viewer/lazy.ts +4 -0
- package/src/components/proxy-viewer/liveConnectionState.ts +158 -0
- package/src/components/proxy-viewer/proxyViewerLogic.ts +10 -0
- package/src/components/proxy-viewer/viewerState.ts +2 -6
- package/src/components/ui/select.tsx +1 -1
- package/src/components/ui/tabs.tsx +3 -3
- package/src/components/ui/transient-toast.tsx +1 -1
- package/src/lib/apiClient.ts +17 -2
- package/src/lib/ecosystemContract.ts +34 -0
- package/src/lib/export-logs.ts +1 -1
- package/src/lib/providerContract.ts +70 -4
- package/src/lib/providerImportContract.ts +27 -0
- package/src/lib/providerModelMetadata.ts +16 -7
- package/src/lib/resourceLimits.ts +152 -0
- package/src/lib/safeDiagnostic.ts +38 -0
- package/src/lib/useProviders.ts +4 -4
- package/src/mcp/server.ts +39 -6
- package/src/mcp/toolHandlers.ts +131 -4
- package/src/proxy/chunkStorage.ts +20 -6
- package/src/proxy/config.ts +20 -6
- package/src/proxy/dataDir.ts +3 -0
- package/src/proxy/ecosystemExecutionConfirmation.ts +114 -0
- package/src/proxy/ecosystemExecutionRoute.ts +116 -0
- package/src/proxy/ecosystemTasks.ts +48 -0
- package/src/proxy/evidenceExporter.ts +23 -9
- package/src/proxy/groupEvidenceExporter.ts +26 -5
- package/src/proxy/groupStore.ts +13 -3
- package/src/proxy/handler.ts +103 -20
- package/src/proxy/identityProxy.ts +333 -14
- package/src/proxy/logFinalizer.ts +73 -6
- package/src/proxy/logImportUpload.ts +128 -0
- package/src/proxy/logImporter.ts +321 -70
- package/src/proxy/logIndex.ts +16 -6
- package/src/proxy/logger.ts +294 -41
- package/src/proxy/privateDataPath.ts +183 -0
- package/src/proxy/providerScanStore.ts +87 -0
- package/src/proxy/providerSecretStore.ts +58 -19
- package/src/proxy/providers.ts +175 -58
- package/src/proxy/rawStreamCapture.ts +66 -5
- package/src/proxy/runStore.ts +13 -3
- package/src/proxy/runtimeAdmission.ts +52 -0
- package/src/proxy/runtimeHealth.ts +206 -0
- package/src/proxy/runtimeShutdown.ts +75 -0
- package/src/proxy/sessionArchive.ts +15 -2
- package/src/proxy/sessionProcess.ts +19 -0
- package/src/proxy/sessionRuntime.ts +7 -0
- package/src/proxy/shutdownCoordinator.ts +90 -0
- package/src/proxy/sqliteLogIndex.ts +18 -2
- package/src/proxy/store.ts +18 -2
- package/src/routes/__root.tsx +18 -1
- package/src/routes/api/alerts.summary.ts +12 -8
- package/src/routes/api/alerts.ts +27 -9
- package/src/routes/api/ecosystem.packages.$packageId.help.ts +3 -8
- package/src/routes/api/ecosystem.packages.$packageId.install.ts +3 -8
- package/src/routes/api/ecosystem.packages.$packageId.runner-presets.ts +3 -11
- package/src/routes/api/ecosystem.packages.$packageId.upgrade.ts +3 -8
- package/src/routes/api/ecosystem.recipes.$recipeId.run.ts +3 -8
- package/src/routes/api/health.ts +9 -2
- package/src/routes/api/knowledge.project-context.ts +11 -0
- package/src/routes/api/knowledge.search.ts +33 -2
- package/src/routes/api/logs.$id.body.ts +16 -2
- package/src/routes/api/logs.import.ts +7 -18
- package/src/routes/api/logs.stream.ts +147 -69
- package/src/routes/api/logs.ts +55 -14
- package/src/routes/api/providers.$providerId.model-metadata.ts +22 -4
- package/src/routes/api/providers.$providerId.ts +37 -6
- package/src/routes/api/providers.export.ts +34 -16
- package/src/routes/api/providers.import.ts +42 -8
- package/src/routes/api/providers.scan.ts +13 -8
- package/src/routes/api/providers.ts +36 -5
- package/src/routes/api/runs.ts +12 -12
- package/src/routes/api/sessions.ts +15 -8
- package/src/routes/index.tsx +6 -0
- package/src/routes/livez.ts +13 -0
- package/src/routes/readyz.ts +18 -0
- package/src/routes/session/$sessionId.tsx +6 -0
- package/styles/globals.css +19 -3
- package/.output/public/assets/CompareDrawer-Cb5ccPeX.js +0 -1
- package/.output/public/assets/ProxyViewerContainer-COBe5GTT.js +0 -4234
- package/.output/public/assets/ResponseView-Cqq87lX_.js +0 -3
- package/.output/public/assets/StreamingChunkSequence-CnTa9mCr.js +0 -1
- package/.output/public/assets/index-DTLNVcgc.js +0 -76
- package/.output/public/assets/index-DliqmwUw.css +0 -1
- package/.output/public/assets/qwen-CONDcHqt.png +0 -0
- package/.output/server/_tanstack-start-manifest_v-DMCA8KK3.mjs +0 -4
- package/src/assets/logos/mcp.png +0 -0
- package/src/assets/logos/qwen.png +0 -0
- package/src/components/ui/mcp-logo.tsx +0 -20
package/.output/server/_ssr/{ProxyViewerContainer-DUgxRNbj.mjs → ProxyViewerContainer-CvsUmbJ3.mjs}
RENAMED
|
@@ -1,26 +1,31 @@
|
|
|
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, P 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, m as cn, F as LazyFeatureBoundary, x as formatTokens, B as Button, d as RuntimeConfigSchema, g as readStoredUiScalePreference, h as persistUiScalePreference, j as applyUiScalePreference, H as extractStopReason, af as CrabLogo, p as packageJson, k as normalizeUiScalePreference, Q as GroupEvidenceExportResultSchema, V as DeleteInspectorGroupResponseSchema, y as copyTextToClipboard, l as RedactedProviderDtoSchema, U as UI_SCALE_STORAGE_KEY, v as apiFormatForPath, a4 as createPendingProviderTestResults, a5 as ProviderTestResultsSchema, a6 as createFailedProviderTestResults, a7 as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, a8 as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, a9 as TimeDisplayFormatSchema, I as AlertSummarySchema, J as AlertListResponseSchema, r as readStoredThemeMode, e as applyThemeMode, f as persistThemeMode, ai as formatUiScale, N as InspectorGroupsListResponseSchema, M as GroupEvidenceReadResponseSchema, aa as EcosystemPackagesResponseSchema, ab as EcosystemTaskResponseSchema, ac as EcosystemTasksResponseSchema, ae as PiAgentResponseSchema, G as isTurnBoundary, _ as PATH_V1_MESSAGES, $ as PATH_V1_CHAT_COMPLETIONS, a0 as PATH_V1_RESPONSES, X as providerHasContextMetadata, W as ProviderScanResponseSchema, T as THEME_MODE_STORAGE_KEY, n as normalizeThemeMode, ad as EcosystemExecutionConfirmationResponseSchema, i as isRecord, a1 as formatContextWindowInput, Y as findProviderModelMetadata, Z as formatContextWindowTokens, w as getSessionPath, q as parseOpenAIResponse, t as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, u as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, o as AnthropicRequestSchema, s as safeGetOwnProperty, ag as resolveProviderContextWindow, a2 as parseContextWindowTokensInput, a3 as previewUpstreamUrl, K as KnowledgeCandidateSchema, ah as isPlainRecord, E as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema, z as getStatusCategory } from "./router-GKvrwifJ.mjs";
|
|
3
3
|
import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
|
|
4
|
-
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
5
|
-
import { c as clsx } from "../_libs/clsx.mjs";
|
|
6
|
-
import { t as twMerge } from "../_libs/tailwind-merge.mjs";
|
|
7
|
-
import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
8
4
|
import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
5
|
+
import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
9
6
|
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
10
|
-
import { r as
|
|
11
|
-
import {
|
|
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
|
-
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";
|
|
7
|
+
import { T as TriangleAlert, C as CircleCheck, X, P as PanelRightOpen, a as PanelRightClose, S as Search, U as Upload, D as Download, F as FileBraces, R as RefreshCw, b as Trash2, I as Info, c as ChevronDown, d as Check, e as Settings, f as Siren, L as LoaderCircle, g as Sun, E as Eye, M as Moon, A as ALargeSmall, h as Layers, i as FlaskConical, j as Sparkles, k as Activity, B as Beaker, N as Network, l as Copy, m as Terminal, n as BrainCircuit, o as Send, p as ArrowLeft, q as ChevronUp, r as ChevronsLeft, s as ChevronLeft, t as ChevronRight, u as ChevronsRight, v as CircleStop, w as Clapperboard, x as Flag, y as Timer, G as Gauge, z as Scan, H as Plus, J as CircleAlert, K as Rocket, O as PackageCheck, Q as History, V as Monitor, W as EyeOff, Y as ExternalLink, Z as Clock, _ as RotateCw, $ as CircleCheckBig, a0 as Pencil, a1 as Bell, a2 as Clock3, a3 as ShieldAlert, a4 as ArrowUpRight, a5 as ArrowDownRight, a6 as CodeXml, a7 as Cpu, a8 as FolderOpen, a9 as MessageSquare, aa as Zap, ab as Wrench, ac as Brain, ad as Minus, ae as CircleQuestionMark, af as Server, ag as Lock, ah as Wifi, ai as WifiOff, aj as CircleX, ak as ShieldCheck, al as Save, am as FileSearch, an as CloudUpload, ao as OctagonAlert, ap as Radio, aq as Globe, ar as FileTerminal, as as ChevronsUp, at as ChevronsDown, au as FileDiff, av as RotateCcw, aw as GitCompareArrows, ax as ArrowUp, ay as ArrowDown, az as Ellipsis, aA as Blocks, aB as MousePointerClick, aC as FileText, aD as Rows3, aE as Columns2 } from "../_libs/lucide-react.mjs";
|
|
8
|
+
import { u as union, o as object, e as array, l as literal, n as number, d as boolean, b as string } from "../_libs/zod.mjs";
|
|
14
9
|
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
|
-
import { D as Dialog$1, a as DialogContent$1, b as DialogClose, c as DialogTitle$1, d as DialogDescription$1, e as
|
|
10
|
+
import { D as Dialog$1, a as DialogContent$1, b as DialogClose, c as DialogTitle$1, d as DialogDescription$1, e as DialogTrigger$1, f as DialogPortal$1, g as DialogOverlay$1 } from "../_libs/radix-ui__react-dialog.mjs";
|
|
11
|
+
import { R as Root2, C as Content, L as List, T as Trigger } from "../_libs/radix-ui__react-tabs.mjs";
|
|
16
12
|
import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
|
|
17
|
-
import { R as Root2, L as List, T as Trigger, C as Content } from "../_libs/radix-ui__react-tabs.mjs";
|
|
18
13
|
import { P as Provider, R as Root3, T as Trigger$1, a as Portal, C as Content2, A as Arrow2 } from "../_libs/radix-ui__react-tooltip.mjs";
|
|
19
14
|
import { R as Root, C as CollapsibleContent$1, a as CollapsibleTrigger$1 } from "../_libs/radix-ui__react-collapsible.mjs";
|
|
20
15
|
import { R as Root$1, V as Viewport, C as Corner, S as ScrollAreaScrollbar, a as ScrollAreaThumb } from "../_libs/radix-ui__react-scroll-area.mjs";
|
|
21
16
|
const ApiErrorSchema = object({
|
|
22
17
|
error: string()
|
|
23
18
|
});
|
|
19
|
+
const MUTATION_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
20
|
+
function withBrowserMutationProof(init) {
|
|
21
|
+
const method = init?.method?.toUpperCase();
|
|
22
|
+
if (method === void 0 || !MUTATION_METHODS.has(method)) return init;
|
|
23
|
+
const headers = new Headers(init?.headers);
|
|
24
|
+
if (!headers.has("x-agent-inspector-csrf")) {
|
|
25
|
+
headers.set("x-agent-inspector-csrf", "1");
|
|
26
|
+
}
|
|
27
|
+
return { ...init, headers };
|
|
28
|
+
}
|
|
24
29
|
async function parseJsonResponse$1(response, schema) {
|
|
25
30
|
const data = await response.json();
|
|
26
31
|
return schema.parse(data);
|
|
@@ -35,7 +40,7 @@ async function readApiError(response, fallback) {
|
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
42
|
async function fetchJson(input, schema, init, errorFallback) {
|
|
38
|
-
const response = await fetch(input, init);
|
|
43
|
+
const response = await fetch(input, withBrowserMutationProof(init));
|
|
39
44
|
if (!response.ok) {
|
|
40
45
|
const fallback = errorFallback?.(response) ?? `Request failed with status ${response.status}`;
|
|
41
46
|
throw new Error(await readApiError(response, fallback));
|
|
@@ -69,7 +74,10 @@ async function fetchWithTimeout(input, timeoutMs, init) {
|
|
|
69
74
|
}
|
|
70
75
|
}
|
|
71
76
|
try {
|
|
72
|
-
return await fetch(input, {
|
|
77
|
+
return await fetch(input, {
|
|
78
|
+
...withBrowserMutationProof(init),
|
|
79
|
+
signal: controller.signal
|
|
80
|
+
});
|
|
73
81
|
} catch (error) {
|
|
74
82
|
if (timedOut && error instanceof DOMException && error.name === "AbortError") {
|
|
75
83
|
throw new ApiTimeoutError(timeoutMs);
|
|
@@ -248,22 +256,23 @@ function useOnboarding() {
|
|
|
248
256
|
markSeen
|
|
249
257
|
};
|
|
250
258
|
}
|
|
251
|
-
function
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
259
|
+
function OnboardingTip({
|
|
260
|
+
expanded,
|
|
261
|
+
onToggle,
|
|
262
|
+
onDismiss
|
|
263
|
+
}) {
|
|
255
264
|
const detailClass = expanded ? "grid" : "hidden sm:grid";
|
|
256
265
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
257
266
|
"div",
|
|
258
267
|
{
|
|
259
268
|
role: "note",
|
|
260
269
|
"aria-label": "Onboarding tip",
|
|
261
|
-
className: "mx-
|
|
270
|
+
className: "mx-3 mt-2 mb-1 rounded-md border border-warning/30 bg-warning/10 px-3 py-2 text-sm shadow-sm sm:mx-4",
|
|
262
271
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
263
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Info, { className: "mt-0.5 size-4 shrink-0 text-
|
|
272
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Info, { className: "mt-0.5 size-4 shrink-0 text-warning", "aria-hidden": "true" }),
|
|
264
273
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
265
274
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
266
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-
|
|
275
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground", children: "Inspector ready" }),
|
|
267
276
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "hidden truncate text-xs text-muted-foreground sm:inline", children: "Request, response, tool, timing, token, replay, and memory signals are active." })
|
|
268
277
|
] }),
|
|
269
278
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-xs leading-relaxed text-muted-foreground sm:hidden", children: "Core capture is active." }),
|
|
@@ -290,8 +299,8 @@ function OnboardingBanner() {
|
|
|
290
299
|
"button",
|
|
291
300
|
{
|
|
292
301
|
type: "button",
|
|
293
|
-
onClick:
|
|
294
|
-
className: "inline-flex h-8 shrink-0 items-center gap-1 rounded-md border border-
|
|
302
|
+
onClick: onToggle,
|
|
303
|
+
className: "inline-flex h-8 shrink-0 items-center gap-1 rounded-md border border-warning/35 px-2 text-xs font-medium text-foreground transition-colors hover:bg-warning/15 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none sm:hidden",
|
|
295
304
|
"aria-expanded": expanded,
|
|
296
305
|
"aria-label": expanded ? "Hide onboarding details" : "Show onboarding details",
|
|
297
306
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -306,10 +315,8 @@ function OnboardingBanner() {
|
|
|
306
315
|
"button",
|
|
307
316
|
{
|
|
308
317
|
type: "button",
|
|
309
|
-
onClick:
|
|
310
|
-
|
|
311
|
-
},
|
|
312
|
-
className: "hidden h-8 shrink-0 items-center gap-1.5 rounded-md border border-amber-500/40 px-3 text-xs text-amber-200 transition-colors hover:bg-amber-500/10 sm:inline-flex",
|
|
318
|
+
onClick: onDismiss,
|
|
319
|
+
className: "hidden h-8 shrink-0 items-center gap-1.5 rounded-md border border-warning/40 px-3 text-xs font-medium text-foreground transition-colors hover:bg-warning/15 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none sm:inline-flex",
|
|
313
320
|
"aria-label": "Dismiss onboarding tip",
|
|
314
321
|
children: [
|
|
315
322
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5" }),
|
|
@@ -321,10 +328,8 @@ function OnboardingBanner() {
|
|
|
321
328
|
"button",
|
|
322
329
|
{
|
|
323
330
|
type: "button",
|
|
324
|
-
onClick:
|
|
325
|
-
|
|
326
|
-
},
|
|
327
|
-
className: "-m-1 shrink-0 p-1 text-muted-foreground transition-colors hover:text-foreground",
|
|
331
|
+
onClick: onDismiss,
|
|
332
|
+
className: "-m-1 shrink-0 rounded-sm p-1 text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none",
|
|
328
333
|
"aria-label": "Dismiss",
|
|
329
334
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" })
|
|
330
335
|
}
|
|
@@ -333,6 +338,21 @@ function OnboardingBanner() {
|
|
|
333
338
|
}
|
|
334
339
|
);
|
|
335
340
|
}
|
|
341
|
+
function OnboardingBanner() {
|
|
342
|
+
const { hasSeenOnboarding, isLoading, markSeen } = useOnboarding();
|
|
343
|
+
const [expanded, setExpanded] = reactExports.useState(false);
|
|
344
|
+
if (isLoading || hasSeenOnboarding) return null;
|
|
345
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
346
|
+
OnboardingTip,
|
|
347
|
+
{
|
|
348
|
+
expanded,
|
|
349
|
+
onToggle: () => setExpanded((value) => !value),
|
|
350
|
+
onDismiss: () => {
|
|
351
|
+
void markSeen();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
);
|
|
355
|
+
}
|
|
336
356
|
const REDACTED = "[REDACTED]";
|
|
337
357
|
const SECRET_KEY_PATTERN = /(^|[-_])(api[-_]?key|authorization|cookie|token|secret|password|access[-_]?token|refresh[-_]?token)([-_]|$)/i;
|
|
338
358
|
const SECRET_TEXT_PATTERNS = [
|
|
@@ -446,6 +466,9 @@ async function exportLogsAsZip(logs, mode = "redacted", options = {}) {
|
|
|
446
466
|
if (initialCancel !== null) return initialCancel;
|
|
447
467
|
const limitMessage = exportLimitMessage(logs);
|
|
448
468
|
if (limitMessage !== null) return { ok: false, message: limitMessage };
|
|
469
|
+
const { default: JSZip } = await import("../_libs/jszip.mjs").then(function(n) {
|
|
470
|
+
return n.i;
|
|
471
|
+
});
|
|
449
472
|
const zip = new JSZip();
|
|
450
473
|
const suffix = mode === "redacted" ? "redacted" : "raw";
|
|
451
474
|
const streamingLogs = logs.filter((log) => log.streaming).slice(0, MAX_STREAMING_CHUNK_EXPORTS);
|
|
@@ -492,61 +515,6 @@ async function exportLogsAsZip(logs, mode = "redacted", options = {}) {
|
|
|
492
515
|
URL.revokeObjectURL(url);
|
|
493
516
|
return { ok: true };
|
|
494
517
|
}
|
|
495
|
-
function restoreSelection(selection, ranges) {
|
|
496
|
-
if (selection === null) return;
|
|
497
|
-
selection.removeAllRanges();
|
|
498
|
-
for (const range of ranges) {
|
|
499
|
-
selection.addRange(range);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
function readSelectionRanges(selection) {
|
|
503
|
-
if (selection === null) return [];
|
|
504
|
-
const ranges = [];
|
|
505
|
-
for (let index = 0; index < selection.rangeCount; index++) {
|
|
506
|
-
ranges.push(selection.getRangeAt(index));
|
|
507
|
-
}
|
|
508
|
-
return ranges;
|
|
509
|
-
}
|
|
510
|
-
function copyWithTextareaFallback(text) {
|
|
511
|
-
if (typeof document === "undefined") return false;
|
|
512
|
-
const activeElement = document.activeElement;
|
|
513
|
-
const selection = document.getSelection();
|
|
514
|
-
const ranges = readSelectionRanges(selection);
|
|
515
|
-
const textarea = document.createElement("textarea");
|
|
516
|
-
textarea.value = text;
|
|
517
|
-
textarea.setAttribute("readonly", "");
|
|
518
|
-
textarea.style.position = "fixed";
|
|
519
|
-
textarea.style.top = "0";
|
|
520
|
-
textarea.style.left = "-9999px";
|
|
521
|
-
textarea.style.opacity = "0";
|
|
522
|
-
document.body.appendChild(textarea);
|
|
523
|
-
textarea.focus();
|
|
524
|
-
textarea.select();
|
|
525
|
-
textarea.setSelectionRange(0, text.length);
|
|
526
|
-
let copied = false;
|
|
527
|
-
try {
|
|
528
|
-
copied = document.execCommand("copy");
|
|
529
|
-
} catch {
|
|
530
|
-
} finally {
|
|
531
|
-
document.body.removeChild(textarea);
|
|
532
|
-
restoreSelection(selection, ranges);
|
|
533
|
-
if (typeof HTMLElement !== "undefined" && activeElement instanceof HTMLElement) {
|
|
534
|
-
activeElement.focus({ preventScroll: true });
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
return copied;
|
|
538
|
-
}
|
|
539
|
-
async function copyTextToClipboard(text) {
|
|
540
|
-
const clipboard = globalThis.navigator?.clipboard;
|
|
541
|
-
if (clipboard !== void 0) {
|
|
542
|
-
try {
|
|
543
|
-
await clipboard.writeText(text);
|
|
544
|
-
return true;
|
|
545
|
-
} catch {
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
return copyWithTextareaFallback(text);
|
|
549
|
-
}
|
|
550
518
|
function formatTimestamp$2(iso, format) {
|
|
551
519
|
switch (format) {
|
|
552
520
|
case "full":
|
|
@@ -562,72 +530,6 @@ function formatTimestamp$2(iso, format) {
|
|
|
562
530
|
function formatTimestampRange(startedAt, endedAt, format) {
|
|
563
531
|
return `${formatTimestamp$2(startedAt, format)} - ${formatTimestamp$2(endedAt, format)}`;
|
|
564
532
|
}
|
|
565
|
-
function cn(...inputs) {
|
|
566
|
-
return twMerge(clsx(inputs));
|
|
567
|
-
}
|
|
568
|
-
function formatTokens(count) {
|
|
569
|
-
const absoluteCount = Math.abs(count);
|
|
570
|
-
if (absoluteCount < 1e3) return String(count);
|
|
571
|
-
if (absoluteCount >= 1e6) {
|
|
572
|
-
return (count / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
|
|
573
|
-
}
|
|
574
|
-
return (count / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
|
|
575
|
-
}
|
|
576
|
-
function formatContextWindowTokens(count) {
|
|
577
|
-
if (count >= 1024 * 1024) {
|
|
578
|
-
return (count / (1024 * 1024)).toFixed(1).replace(/\.0$/, "") + "M";
|
|
579
|
-
}
|
|
580
|
-
return (count / 1024).toFixed(1).replace(/\.0$/, "") + "K";
|
|
581
|
-
}
|
|
582
|
-
function formatExactContextUnit(count, multiplier, unit) {
|
|
583
|
-
const tenths = count * 10;
|
|
584
|
-
if (!Number.isSafeInteger(tenths) || tenths % multiplier !== 0) return null;
|
|
585
|
-
return (tenths / multiplier / 10).toFixed(1).replace(/\.0$/, "") + unit;
|
|
586
|
-
}
|
|
587
|
-
function formatContextWindowInput(count) {
|
|
588
|
-
if (!Number.isSafeInteger(count) || count <= 0) return count.toString();
|
|
589
|
-
if (count >= 1024 * 1024) {
|
|
590
|
-
const megaValue = formatExactContextUnit(count, 1024 * 1024, "M");
|
|
591
|
-
if (megaValue !== null) return megaValue;
|
|
592
|
-
}
|
|
593
|
-
const kiloValue = formatExactContextUnit(count, 1024, "K");
|
|
594
|
-
if (kiloValue !== null) return kiloValue;
|
|
595
|
-
return count.toString();
|
|
596
|
-
}
|
|
597
|
-
function contextWindowUnitMultiplier(unit) {
|
|
598
|
-
if (unit === void 0 || unit === "") return 1;
|
|
599
|
-
switch (unit.toLowerCase()) {
|
|
600
|
-
case "k":
|
|
601
|
-
return 1024;
|
|
602
|
-
case "m":
|
|
603
|
-
return 1024 * 1024;
|
|
604
|
-
default:
|
|
605
|
-
return null;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
function parseContextWindowTokensInput(value) {
|
|
609
|
-
const trimmed = value.trim().replaceAll(",", "");
|
|
610
|
-
if (trimmed === "") return null;
|
|
611
|
-
const match = /^(\d+(?:\.\d+)?)\s*([kKmM])?$/.exec(trimmed);
|
|
612
|
-
if (match === null) return null;
|
|
613
|
-
const amountText = match[1];
|
|
614
|
-
if (amountText === void 0) return null;
|
|
615
|
-
const amount = Number(amountText);
|
|
616
|
-
const unit = match[2];
|
|
617
|
-
const multiplier = contextWindowUnitMultiplier(unit);
|
|
618
|
-
if (!Number.isFinite(amount) || amount <= 0 || multiplier === null) return null;
|
|
619
|
-
if ((unit === void 0 || unit === "") && !Number.isInteger(amount)) return null;
|
|
620
|
-
const tokens = Math.round(amount * multiplier);
|
|
621
|
-
if (!Number.isSafeInteger(tokens) || tokens <= 0) return null;
|
|
622
|
-
return tokens;
|
|
623
|
-
}
|
|
624
|
-
function getStatusCategory(status) {
|
|
625
|
-
if (status === null) return "pending";
|
|
626
|
-
if (status >= 200 && status < 300) return "success";
|
|
627
|
-
if (status >= 400 && status < 500) return "client_error";
|
|
628
|
-
if (status >= 500) return "server_error";
|
|
629
|
-
return "pending";
|
|
630
|
-
}
|
|
631
533
|
function useThemeMode() {
|
|
632
534
|
const [themeMode, setThemeModeState] = reactExports.useState(readStoredThemeMode);
|
|
633
535
|
const setThemeMode = reactExports.useCallback((nextThemeMode) => {
|
|
@@ -684,7 +586,7 @@ function useUiScale() {
|
|
|
684
586
|
async function fetcher(url) {
|
|
685
587
|
return fetchJson(
|
|
686
588
|
url,
|
|
687
|
-
|
|
589
|
+
RedactedProviderDtoSchema.array(),
|
|
688
590
|
void 0,
|
|
689
591
|
(response) => `Failed to fetch ${url}: ${response.status}`
|
|
690
592
|
);
|
|
@@ -799,46 +701,6 @@ function DialogDescription({
|
|
|
799
701
|
}
|
|
800
702
|
);
|
|
801
703
|
}
|
|
802
|
-
const buttonVariants = cva(
|
|
803
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
804
|
-
{
|
|
805
|
-
variants: {
|
|
806
|
-
variant: {
|
|
807
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
808
|
-
destructive: "bg-destructive text-white hover:bg-destructive/90",
|
|
809
|
-
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
810
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
811
|
-
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
812
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
813
|
-
},
|
|
814
|
-
size: {
|
|
815
|
-
default: "h-9 px-4 py-2",
|
|
816
|
-
sm: "h-8 rounded-md px-3 text-xs",
|
|
817
|
-
lg: "h-10 rounded-md px-8",
|
|
818
|
-
icon: "size-9"
|
|
819
|
-
}
|
|
820
|
-
},
|
|
821
|
-
defaultVariants: {
|
|
822
|
-
variant: "default",
|
|
823
|
-
size: "default"
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
);
|
|
827
|
-
function Button({
|
|
828
|
-
className,
|
|
829
|
-
variant,
|
|
830
|
-
size,
|
|
831
|
-
...props
|
|
832
|
-
}) {
|
|
833
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
834
|
-
"button",
|
|
835
|
-
{
|
|
836
|
-
"data-slot": "button",
|
|
837
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
838
|
-
...props
|
|
839
|
-
}
|
|
840
|
-
);
|
|
841
|
-
}
|
|
842
704
|
function ConfirmDialog({
|
|
843
705
|
open,
|
|
844
706
|
onOpenChange,
|
|
@@ -1009,7 +871,7 @@ const OpenAILogoSvg = "data:image/svg+xml,%3csvg%20height='2500'%20viewBox='-1%2
|
|
|
1009
871
|
const DeepSeekLogoSvg = "data:image/svg+xml,%3csvg%20fill='none'%20height='1320'%20viewBox='3.771%206.973%2023.993%2017.652'%20width='2500'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='m27.501%208.469c-.252-.123-.36.111-.508.23-.05.04-.093.09-.135.135-.368.395-.797.652-1.358.621-.821-.045-1.521.213-2.14.842-.132-.776-.57-1.238-1.235-1.535-.349-.155-.701-.309-.944-.645-.171-.238-.217-.504-.303-.765-.054-.159-.108-.32-.29-.348-.197-.031-.274.135-.352.273-.31.567-.43%201.192-.419%201.825.028%201.421.628%202.554%201.82%203.36.136.093.17.186.128.321-.081.278-.178.547-.264.824-.054.178-.135.217-.324.14a5.448%205.448%200%200%201%20-1.719-1.169c-.848-.82-1.614-1.726-2.57-2.435-.225-.166-.449-.32-.681-.467-.976-.95.128-1.729.383-1.82.267-.096.093-.428-.77-.424s-1.653.293-2.659.677a2.782%202.782%200%200%201%20-.46.135%209.554%209.554%200%200%200%20-2.853-.1c-1.866.21-3.356%201.092-4.452%202.6-1.315%201.81-1.625%203.87-1.246%206.018.399%202.261%201.552%204.136%203.326%205.601%201.837%201.518%203.955%202.262%206.37%202.12%201.466-.085%203.1-.282%204.942-1.842.465.23.952.322%201.762.392.623.059%201.223-.031%201.687-.127.728-.154.677-.828.414-.953-2.132-.994-1.665-.59-2.09-.916%201.084-1.285%202.717-2.619%203.356-6.94.05-.343.007-.558%200-.837-.004-.168.034-.235.228-.254a4.084%204.084%200%200%200%201.529-.47c1.382-.757%201.938-1.997%202.07-3.485.02-.227-.004-.463-.243-.582zm-12.041%2013.391c-2.067-1.627-3.07-2.162-3.483-2.138-.387.021-.318.465-.233.754.089.285.205.482.368.732.113.166.19.414-.112.598-.666.414-1.823-.139-1.878-.166-1.347-.793-2.473-1.842-3.267-3.276-.765-1.38-1.21-2.861-1.284-4.441-.02-.383.093-.518.472-.586a4.692%204.692%200%200%201%201.514-.04c2.109.31%203.905%201.255%205.41%202.749.86.853%201.51%201.871%202.18%202.865.711%201.057%201.478%202.063%202.454%202.887.343.289.619.51.881.672-.792.088-2.117.107-3.022-.61zm.99-6.38a.304.304%200%201%201%20.609%200c0%20.17-.136.304-.306.304a.3.3%200%200%201%20-.303-.305zm3.077%201.581c-.197.08-.394.15-.584.159a1.246%201.246%200%200%201%20-.79-.252c-.27-.227-.463-.354-.546-.752a1.752%201.752%200%200%201%20.016-.582c.07-.324-.008-.531-.235-.72-.187-.155-.422-.196-.682-.196a.551.551%200%200%201%20-.252-.078c-.108-.055-.197-.19-.112-.356.027-.053.159-.183.19-.207.352-.201.758-.135%201.134.016.349.142.611.404.99.773.388.448.457.573.678.906.174.264.333.534.441.842.066.192-.02.35-.248.448z'%20fill='%234d6bfe'/%3e%3c/svg%3e";
|
|
1010
872
|
const MiniMaxLogoSvg = "/assets/minimax-BPMzvuL-.jpeg";
|
|
1011
873
|
const AlibabaLogoSvg = "/assets/alibaba-TTwafVwX.svg";
|
|
1012
|
-
const QwenLogoSvg = "/assets/qwen-
|
|
874
|
+
const QwenLogoSvg = "/assets/qwen-mMn3f5ul.webp";
|
|
1013
875
|
const ZhipuAILogoSvg = "/assets/zhipuai-BPNAnxo-.svg";
|
|
1014
876
|
const PROVIDER_MAP = {
|
|
1015
877
|
"claude-": "anthropic",
|
|
@@ -2521,9 +2383,9 @@ function TabsTrigger({
|
|
|
2521
2383
|
{
|
|
2522
2384
|
"data-slot": "tabs-trigger",
|
|
2523
2385
|
className: cn(
|
|
2524
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-
|
|
2525
|
-
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:
|
|
2526
|
-
"data-[state=active]:
|
|
2386
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-muted-foreground hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
2387
|
+
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
|
|
2388
|
+
"data-[state=active]:border-border data-[state=active]:bg-background data-[state=active]:text-foreground",
|
|
2527
2389
|
"after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
|
|
2528
2390
|
className
|
|
2529
2391
|
),
|
|
@@ -2569,27 +2431,30 @@ function useCopyFeedback(text) {
|
|
|
2569
2431
|
return { copied, copy };
|
|
2570
2432
|
}
|
|
2571
2433
|
const LazyCompareDrawer = reactExports.lazy(
|
|
2572
|
-
() => import("./CompareDrawer-
|
|
2434
|
+
() => import("./CompareDrawer-CqUmGHal.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
2435
|
+
);
|
|
2436
|
+
const LazyInspectorPet = reactExports.lazy(
|
|
2437
|
+
() => import("./InspectorPet-DI0UJd01.mjs").then((m) => ({ default: m.InspectorPet }))
|
|
2573
2438
|
);
|
|
2574
2439
|
const LazyReplayDialog = reactExports.lazy(
|
|
2575
|
-
() => import("./ReplayDialog-
|
|
2440
|
+
() => import("./ReplayDialog-DS48dpFG.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
2576
2441
|
);
|
|
2577
2442
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
2578
|
-
() => import("./RequestAnatomy-
|
|
2443
|
+
() => import("./RequestAnatomy-DxYVQU1C.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
2579
2444
|
);
|
|
2580
2445
|
const LazyResponseView = reactExports.lazy(
|
|
2581
|
-
() => import("./ResponseView-
|
|
2446
|
+
() => import("./ResponseView-BLXW73eq.mjs").then((m) => ({ default: m.ResponseView }))
|
|
2582
2447
|
);
|
|
2583
2448
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
2584
|
-
() => import("./StreamingChunkSequence-
|
|
2449
|
+
() => import("./StreamingChunkSequence-DD0iFuy0.mjs").then((m) => ({
|
|
2585
2450
|
default: m.StreamingChunkSequence
|
|
2586
2451
|
}))
|
|
2587
2452
|
);
|
|
2588
2453
|
const LazyJsonViewer = reactExports.lazy(
|
|
2589
|
-
() => import("./json-viewer-
|
|
2454
|
+
() => import("./json-viewer-LDu2XBaK.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
2590
2455
|
);
|
|
2591
2456
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
2592
|
-
() => import("./json-viewer-
|
|
2457
|
+
() => import("./json-viewer-LDu2XBaK.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
2593
2458
|
);
|
|
2594
2459
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
2595
2460
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -4397,7 +4262,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
4397
4262
|
"aria-hidden": "true"
|
|
4398
4263
|
}
|
|
4399
4264
|
),
|
|
4400
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "gap-2", children: [
|
|
4265
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LazyFeatureBoundary, { feature: "Log details", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "gap-2", children: [
|
|
4401
4266
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4402
4267
|
TabsList,
|
|
4403
4268
|
{
|
|
@@ -4533,7 +4398,13 @@ const LogEntry = reactExports.memo(function({
|
|
|
4533
4398
|
headers: displayLog.headers,
|
|
4534
4399
|
emptyLabel: "No transformation applied; raw and processed headers are identical."
|
|
4535
4400
|
}
|
|
4536
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4401
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4402
|
+
HeaderRows,
|
|
4403
|
+
{
|
|
4404
|
+
headers: displayLog.headers,
|
|
4405
|
+
emptyLabel: "No headers captured"
|
|
4406
|
+
}
|
|
4407
|
+
)
|
|
4537
4408
|
] }) }),
|
|
4538
4409
|
shouldShowRawHeadersTab(
|
|
4539
4410
|
viewMode,
|
|
@@ -4618,14 +4489,14 @@ const LogEntry = reactExports.memo(function({
|
|
|
4618
4489
|
}
|
|
4619
4490
|
) })
|
|
4620
4491
|
] }) })
|
|
4621
|
-
] })
|
|
4492
|
+
] }) })
|
|
4622
4493
|
]
|
|
4623
4494
|
}
|
|
4624
4495
|
)
|
|
4625
4496
|
]
|
|
4626
4497
|
}
|
|
4627
4498
|
),
|
|
4628
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4499
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LazyFeatureBoundary, { feature: "Replay", children: /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4629
4500
|
LazyReplayDialog,
|
|
4630
4501
|
{
|
|
4631
4502
|
log: displayLog,
|
|
@@ -4633,7 +4504,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
4633
4504
|
open: replayOpen,
|
|
4634
4505
|
onOpenChange: setReplayOpen
|
|
4635
4506
|
}
|
|
4636
|
-
) })
|
|
4507
|
+
) }) })
|
|
4637
4508
|
] });
|
|
4638
4509
|
});
|
|
4639
4510
|
function boundaryTitle(stopReason) {
|
|
@@ -4658,6 +4529,7 @@ function ThreadConnector({
|
|
|
4658
4529
|
isFirst,
|
|
4659
4530
|
isTurnStart,
|
|
4660
4531
|
isOnlyEntry = false,
|
|
4532
|
+
isOpenTurnTail = false,
|
|
4661
4533
|
crabIndex = 0,
|
|
4662
4534
|
collapsible = false,
|
|
4663
4535
|
onToggle
|
|
@@ -4741,8 +4613,23 @@ function ThreadConnector({
|
|
|
4741
4613
|
}
|
|
4742
4614
|
)
|
|
4743
4615
|
}
|
|
4616
|
+
) : isOpenTurnTail ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4617
|
+
"span",
|
|
4618
|
+
{
|
|
4619
|
+
title: isPending ? "Current end of open turn (processing)" : "Current end of open turn",
|
|
4620
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4621
|
+
Crab,
|
|
4622
|
+
{
|
|
4623
|
+
className: cn(
|
|
4624
|
+
"size-3.5 text-cyan-300/85",
|
|
4625
|
+
isRunning ? "animate-crab-crawl" : "animate-crab-appear",
|
|
4626
|
+
"drop-shadow-[0_0_4px_rgba(103,232,249,0.4)]"
|
|
4627
|
+
)
|
|
4628
|
+
}
|
|
4629
|
+
)
|
|
4630
|
+
}
|
|
4744
4631
|
) : isRunning ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Processing", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: cn("size-3.5 text-amber-300/80", "animate-crab-crawl") }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Request in turn", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: "size-3.5 text-muted-foreground/40" }) }),
|
|
4745
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-0", children: !isBoundary && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4632
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-0", children: !isBoundary && !isOpenTurnTail && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4746
4633
|
"div",
|
|
4747
4634
|
{
|
|
4748
4635
|
className: cn(
|
|
@@ -4767,8 +4654,8 @@ function responseMayContainToolTrace(log, format) {
|
|
|
4767
4654
|
return false;
|
|
4768
4655
|
}
|
|
4769
4656
|
}
|
|
4770
|
-
function isTurnCollapsible(entryCount
|
|
4771
|
-
return entryCount > 1
|
|
4657
|
+
function isTurnCollapsible(entryCount) {
|
|
4658
|
+
return entryCount > 1;
|
|
4772
4659
|
}
|
|
4773
4660
|
function buildTurnGroups(logs) {
|
|
4774
4661
|
const groups = [];
|
|
@@ -5019,7 +4906,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
5019
4906
|
const isComplete = lastStop !== null ? isTurnBoundary(lastStop) : false;
|
|
5020
4907
|
const isPending = entries[lastIdx]?.log.responseStatus === null;
|
|
5021
4908
|
const isSingleLog = entries.length === 1;
|
|
5022
|
-
const collapsible = isTurnCollapsible(entries.length
|
|
4909
|
+
const collapsible = isTurnCollapsible(entries.length);
|
|
5023
4910
|
const [collapsed, setCollapsed] = reactExports.useState(false);
|
|
5024
4911
|
const prevCompleteRef = reactExports.useRef(false);
|
|
5025
4912
|
reactExports.useEffect(() => {
|
|
@@ -5162,7 +5049,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
5162
5049
|
}
|
|
5163
5050
|
),
|
|
5164
5051
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px bg-muted-foreground/14 h-full" }) }),
|
|
5165
|
-
isComplete
|
|
5052
|
+
isComplete ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5166
5053
|
CollapsedCrab,
|
|
5167
5054
|
{
|
|
5168
5055
|
className: cn(
|
|
@@ -5170,7 +5057,16 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
5170
5057
|
"drop-shadow-[0_0_4px_rgba(251,191,36,0.45)]"
|
|
5171
5058
|
)
|
|
5172
5059
|
}
|
|
5173
|
-
)
|
|
5060
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Current end of open turn", "aria-label": "Current end of open turn", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5061
|
+
CollapsedCrab,
|
|
5062
|
+
{
|
|
5063
|
+
className: cn(
|
|
5064
|
+
"size-3.5 text-cyan-300/85",
|
|
5065
|
+
isPending ? "animate-crab-crawl" : "animate-crab-appear",
|
|
5066
|
+
"drop-shadow-[0_0_4px_rgba(103,232,249,0.4)]"
|
|
5067
|
+
)
|
|
5068
|
+
}
|
|
5069
|
+
) })
|
|
5174
5070
|
] }),
|
|
5175
5071
|
entries.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5176
5072
|
"div",
|
|
@@ -5263,6 +5159,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
5263
5159
|
isFirst: visibleIdx === 0,
|
|
5264
5160
|
isTurnStart,
|
|
5265
5161
|
isOnlyEntry: isSingleLog,
|
|
5162
|
+
isOpenTurnTail: visibleIdx === lastIdx && !isComplete,
|
|
5266
5163
|
crabIndex: log.id % 12,
|
|
5267
5164
|
collapsible: collapsible && isTurnStart,
|
|
5268
5165
|
onToggle: toggleCollapse
|
|
@@ -6266,9 +6163,14 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
6266
6163
|
] })
|
|
6267
6164
|
] });
|
|
6268
6165
|
});
|
|
6166
|
+
const COPYABLE_COMMAND_CONTAINER_CLASS_NAME = "flex w-full min-w-0 items-center gap-2 rounded-md border border-border/70 bg-muted/35 px-3 py-2 sm:w-auto sm:max-w-full";
|
|
6167
|
+
const COPYABLE_COMMAND_TEXT_CLASS_NAME = "m-0 min-w-0 flex-1 overflow-x-auto font-mono text-xs text-foreground sm:text-sm";
|
|
6269
6168
|
function shouldShowRawExport(captureMode) {
|
|
6270
6169
|
return captureMode === "full";
|
|
6271
6170
|
}
|
|
6171
|
+
function exportRequiresConfirmation(mode) {
|
|
6172
|
+
return mode === "raw";
|
|
6173
|
+
}
|
|
6272
6174
|
function getExportActionVisibility(captureMode, logCount) {
|
|
6273
6175
|
const hasLogs = logCount > 0;
|
|
6274
6176
|
return {
|
|
@@ -6565,46 +6467,6 @@ function formatPaginationStatus({
|
|
|
6565
6467
|
}
|
|
6566
6468
|
return `Showing ${logs.length} of ${pagination.total} logs (${range})`;
|
|
6567
6469
|
}
|
|
6568
|
-
function CrabLogo({ className }) {
|
|
6569
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
6570
|
-
"svg",
|
|
6571
|
-
{
|
|
6572
|
-
viewBox: "0 0 24 24",
|
|
6573
|
-
fill: "none",
|
|
6574
|
-
stroke: "currentColor",
|
|
6575
|
-
strokeWidth: "1.5",
|
|
6576
|
-
strokeLinecap: "round",
|
|
6577
|
-
strokeLinejoin: "round",
|
|
6578
|
-
"aria-hidden": "true",
|
|
6579
|
-
className: cn("inline-block size-5", className),
|
|
6580
|
-
children: [
|
|
6581
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { 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" }),
|
|
6582
|
-
/* @__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" }),
|
|
6583
|
-
/* @__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" }),
|
|
6584
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
6585
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" }),
|
|
6586
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
6587
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
6588
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "6.5", y1: "16", x2: "4.5", y2: "19.5" }),
|
|
6589
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "17.5", x2: "8", y2: "20.5" }),
|
|
6590
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15", y1: "17.5", x2: "16", y2: "20.5" }),
|
|
6591
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17.5", y1: "16", x2: "19.5", y2: "19.5" })
|
|
6592
|
-
]
|
|
6593
|
-
}
|
|
6594
|
-
);
|
|
6595
|
-
}
|
|
6596
|
-
const McpLogoPng = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAQAAAAi5ZK2AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfpCxsJDCnsge2KAAAM2ElEQVR42u2de3AW1RnGnyQQDARDwiUFpHIVMHIpYgFRB2nLxQrC0FIDiCKDWNqBUqBlai8wvciIpaRTWh3QDqCDIIjKDL0IaBC5SKlysWJArgqh3BMICYFs/wgpGUi+8579dr89e/Z5zp/59j2755fn3d2z5wJQFEVRFEVRoVQSm+AG1UFrtEdT1EcjNEA5SlCMIhxDAQoJ3S4lIwf9cD+6ozXq1vKbYuzHNmxEPo6xwcKtungIS3EajkYpwLPoyqYLp3KwACe1cFcvezATmWzEMOk+rMBV18CrSjHy0IqNGQb1wMa4cV8vZfgzGrNRTVYm8nDFQ+SV5QymIIWNa6ZGaz6y6ZR/I4cNbJrSkOcb8MpyCVPYzCapKz71GXllWY5b2dhm6EGcTwhyBw52oyUbPHgNx6WEIXfg4CDuYKMHq0kevI/rlhP4Ghs+OE1ERcKRO3BwEh3Z+NFC7sDBATQngMRrcoDIHTj4iE/yUXJ5VVlhYsMkWezy+a6urgRbsAP7cRincQGpqI+maI+O6IMuSHYRbwIW0X/mJvZTeAH9ah1CATTCaKxBmWbUi7iTOMxEXoCncIsodgvM1ezo2cFPMebdy89qfyHL0vxSN5FQzHL5ajRxVU8v7NO4cWQRjCnIy/DDOOq6FcvENS0gGjMS+wUMjvvdZ5awrsv4KvEE7/Iz+Lontc4Q1vc8AQXt8rO4x7Oa54hqLOLI2aBdfrenHVyviWqdQUx2uLxS6fhMUO8ugrLD5VXqLfpmfxdh2eHyKi0S1P5b4rLF5ZVqiiJl/Z8SmD0ur9TzgnNoQWi2uLxSt+Gy8ixGEpvZLs9AN3RGqsYRa5Xn8SeCM9XlDfFT7Ll2bDnWYYRwOMZjyjP5kOjMdPkDOHpTjPX4iuDILOWL2znCMxH5IyitMc4+ZAuO3q08nyYEaFpiHxbjYWyDIMm/qDyje4kwPMgdOBihjDBNeU7fJcQwIXewTnBzUJ3Vk8Rozr18mOAtuxT1FFH6KmNMJkhTkH+7lse3G0s7RZyuygjPEGVYEntV6aSIlKOM8CvCDEtirywVyFDE6q2M8WPiDJPLJcMgBiljPEWg4XG5AwfTlfEmKWPkEml4XO7gCBooI85TRvlm8I1ax3CX68w8PYeB2KGFfEWM6Yo3qgy5uKj8VU/lLz5HG2QjHRlIA1CCIhTjBI6ggg43LbGXYYggZj3lgkYVtbwaluITvIlf4gHhNEomdheJXfpeXoX8EVHUAR4sY1CKfEyN5gibMCIHXvJsBYur2IDxSCNy05HXx1mPFy/5L2ZFZb6rGR2uusiByb6sWlOMZ5FOl5vocqAuDvm2XNExjLV5t52wuhyY7vM6Ve+jA11uksuB5glYcLgIY+hyc1yeJBj87E35q6BXkC5PAHJgdgKXI9xlzzt8eF0OjE/wypQH7Li7h9nl4wJYjPQ4utPlwSF/LKD1Z8+gC10eLeQOHHyJ1nR54pGPCniVadmcGyK3xOVVZYvWnNpqb5hBIv+L1hCJAdiuhXyVcpT6dV3GSLylhXyxy7YrxHYU4CBO4yKABmiCNuiIe9DMVbT5mMp7eWJc/rgLl1dgC6bE2NelM6Zim4uoDzOxm5nYS/GicNOuznhJc0X5k2HprIkS8gos1cTSSrgYodFbhkQ5sR/F/a7aqD8Oa9TSny43x+UblDNialcmVovr2WP2qOYoIV8V57tREuaK6/o+E7sJid2bO+00Ya0HTPV6lFy+3LNWmymsMZfIg+1w9fZ5ep6ozp3mjaKjy90rGetF9d5H5Ha4vFLZOB62zYGIPH6NEk2NqEvk4U/s1V/f8gX1DyJye5ADQC/BGfyRyO1I7Nf1rvIcPiZye1xeqaGCua6ZNiMf7sOSAolD3h+v4otrH2RewYPCo1JxWnkmQ4jcROTZNcyGWSMcN7PQ5KUJw4zc33t5G+xHzfu3S7655wqmPRG5ccgPxxjkqN7DvbnyfDYRuVmJvY1iYMQEQYxCxRkVEnlYXF5ZdguibFLEKI/6S9pQg1x+Ow4IYrZSxlmqjJFGl4fF5dLVJBcoYzQl8jDcy3XestV7tbcl8vC43IGD3spo6gEVtxF5mJCXCu7H6u6ZRlFE/nAoE7sDB8sEEd9URqkTfuT2P7FXlSuiZQb2KKKU0OXhcbmDGYKYdZWrTO8l8nDcyx04mCeKqh5IsYaJPRyJ3cEfhHFnePTPQ+ShQQ68r4z1NJEHkdj9Q95KcN7didwmlwOzBC2dTOT2uByoj5PBPcbR5UEgly0tPo3I7XE5kI1zgoVOWhO5PS4HXhHE/IDI7XE5MFIU9QdEbo/LO6NIEPWS98Mn/F04pD+R16oWOCiK+4LXyMf4irwnin1ErrtWzGtGIW+MXcJvdB4v/H87LvqIvL1yWG90XZ6J7UHNpVvoI/KGKPDxS5q/Lm/ry5e06i7/SBi5HHd5izxVI/nqIpcM6aXL1WW+1z7v6SPyJ0I7RMJvl+sgP+H9uLihviFvp5FDmNhrL096/34+2Jf3cgBYw8TuAfI3/OiHu8MXl+tsMM97ee3lKBr7AT1JuVuwG+Sp2EvkcSMvR1+/PqbO9Bw5MIn38rgTu69rP6fFeJd2hzwFn/OJPU6XO5gNX5VTy6iNk66QA4+KLqoCY5nYay0L4bs6YedN1e5EJ5fRdogu60dM7DE+/SZk+lIqxmMzrl5br2wzxrvbCA5Ad9FlraTLay2vJ3YV2DS0Rds4VzuYI7isQ1q9TNG6l79uzsK/8ldAyffhYRoRwz0qJgLIgT6CC/uHMcjpck/0c8Gl9aHLbUIO/FN5aflEbhfyOoJBfrlEbhNyydf5C0jnvdwm5MAY5eWtInK7kAOzlRc4mYndLuTAq8pL7KGMMTzUXTGGdrj6qc2KS7yq7O27E1fYxx4ufaK4yCOK41M0ofg7dYHIRVIh2xr3gyBdbpxUW8+8ozh+PV0ePqkmSK1RJPdLhrj890Qu1ynFxa6PeXRTQ76X871cS6rPqh/GPDrLiJc0ulxTqgVtj8U8OglneS8Pn9RrHjaMefwbvJeHT4vj/JY+iMjDJ/UQip8oIqyNcewyJnYT9T3lpf9NEaEJPqvlyEV0uZnqKpjVkqWIkV3DTuKlmusfE3kClYwzygaYIIiSi03XxuA7OIF5aE7kJuttZRPsQpIoUga64W601l75mF0xCZdkYdvBPtZP5AGom6Ahtvu2brnfiZ3IXfbKye7rdHmo9AtBc5zyYftIujxAtRONcduIFLrcJm3wpdmDdfm/iDy2BgqbZnpoXE7kSiUJOy8qMNWD2nJwlC43QY+Km+i5OF/fHhD0ARJ5grpjt4qbaT1auM4oU1DGxG6Oev2/71xdCpEr7Jqtro5YpwWELk+AXtZqsHz01ojdDHM1PU7kCVEznNDEko8RuEXQ0bsAJZqRiTxhGqQ5FdGBg3NYgsfRpoZoDTEIv8N/tCNGDnlSwPU/hxkujyzCPhzBOZQiBY3QFB3i6Lidp7lhZSbe0VorcyVGoZwer1JdbHHlTC8LE3vC1US8CLg/xf+XtDqEfLPa4BiRR0/dBXsGhzOxE3kMdcGXCUc+h8iDT/IFCQR+BROJ3ARlaw5DcF8uYAiRm6J6yHPRXaNb9mhvUknkPmuocuGC+MoS1Cdy89QSK3wCvg8PaZ8NkSdM/YT7hsvLRcwSfKwh8kBVB08LN/JSlxIscNUzT+QBKBlDsC1O4OeR53LkDZEHqN7Ic9VRW4a3kav92EbkxigF38BcbEO5CMBhLME45Tz3yCJPChn8dPRBF7RHB3RARrVtvC6hGIewHwUowBYcirMW/e/lubhCZybunyALmR7/6zKxR05ETuRETuRETuRsNCKniJwicorIKSKniJwicorIKSKniJyqGfnHmvsyE3nIlRJzHxi63ErlEXnUNI6JPWrKUO7rTJdbp98QedSUjWIm9qjpGSKPnrYysUdNzYRLEBO5RRrLxF6p5AhB7yz4zUqMtn+CUpSgZyt/sZpz0mzTWuXU5sbRaIgoOT1T8fdCnCZ026RC2lJzQ25CD4EKFX9PwWLUI/RoQQe+hbdcrEBFGazRovf0tdFwe1SUJVyx5u90u03aKOx7J3aLNEP8lY1J3ho10hg3Q7dbo59pjJwhdkvUAMeJPXr6jtY2Ary3W6Jfaw2CptutUJLmJgLEboXSsUkLO5O8JQ9079LtxE7sxE7sxE7sFqkhH+mIXV1WhG43DMoD7OPZZNHD/gWnPUUR+4BwX2wyeQMAijEYH4h/fS+hRw97c0K3B/tAvCf6ZRmh26OLGCpy+wE2VfQe6XLYTFHD/h6bKGrYy9CDDWQr9vwakV/FE2wce5WGl29CfgrD2TC2qy+W4/w14Hsxy5aVKvjFSN1CLVAPp1DEpqAoiqIoyiz9D9lYMumhgrvLAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDI1LTExLTI3VDA5OjEyOjQxKzAwOjAwvIZCxQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyNS0xMS0yN1QwOToxMjo0MSswMDowMM3b+nkAAAAASUVORK5CYII=";
|
|
6597
|
-
function McpLogo({ className }) {
|
|
6598
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6599
|
-
"img",
|
|
6600
|
-
{
|
|
6601
|
-
src: McpLogoPng,
|
|
6602
|
-
alt: "Model Context Protocol",
|
|
6603
|
-
"aria-hidden": "true",
|
|
6604
|
-
className: cn("inline-block size-8 object-contain invert", className)
|
|
6605
|
-
}
|
|
6606
|
-
);
|
|
6607
|
-
}
|
|
6608
6470
|
function Select({
|
|
6609
6471
|
...props
|
|
6610
6472
|
}) {
|
|
@@ -6650,7 +6512,7 @@ function SelectContent({
|
|
|
6650
6512
|
{
|
|
6651
6513
|
"data-slot": "select-content",
|
|
6652
6514
|
className: cn(
|
|
6653
|
-
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
|
6515
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 motion-reduce:data-[state=open]:animate-none motion-reduce:data-[state=closed]:animate-none relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
|
6654
6516
|
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
6655
6517
|
className
|
|
6656
6518
|
),
|
|
@@ -7360,7 +7222,7 @@ function TransientToast({
|
|
|
7360
7222
|
"button",
|
|
7361
7223
|
{
|
|
7362
7224
|
type: "button",
|
|
7363
|
-
className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-current/70 transition-colors hover:bg-white/10 hover:text-current",
|
|
7225
|
+
className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-current/70 transition-colors hover:bg-white/10 hover:text-current focus-visible:ring-1 focus-visible:ring-current focus-visible:outline-none",
|
|
7364
7226
|
"aria-label": "Dismiss notification",
|
|
7365
7227
|
onClick: onDismiss,
|
|
7366
7228
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" })
|
|
@@ -8357,21 +8219,6 @@ function MemberMetadata({ entries }) {
|
|
|
8357
8219
|
}) })
|
|
8358
8220
|
] });
|
|
8359
8221
|
}
|
|
8360
|
-
const ExternalProviderSchema = object({
|
|
8361
|
-
name: string(),
|
|
8362
|
-
apiKey: string(),
|
|
8363
|
-
format: _enum(["anthropic", "openai"]),
|
|
8364
|
-
anthropicBaseUrl: string(),
|
|
8365
|
-
openaiBaseUrl: string(),
|
|
8366
|
-
openaiResponsesBaseUrl: string().optional().default(""),
|
|
8367
|
-
models: array(string()),
|
|
8368
|
-
sourceTool: _enum(["claude-code", "opencode", "mimo-code"]),
|
|
8369
|
-
alreadyExists: boolean()
|
|
8370
|
-
});
|
|
8371
|
-
const ScanResponseSchema = object({
|
|
8372
|
-
providers: array(ExternalProviderSchema),
|
|
8373
|
-
warnings: array(string()).optional()
|
|
8374
|
-
});
|
|
8375
8222
|
const ImportResponseSchema$1 = object({
|
|
8376
8223
|
success: boolean().optional(),
|
|
8377
8224
|
imported: number().optional(),
|
|
@@ -8386,6 +8233,7 @@ function ImportWizardDialog({
|
|
|
8386
8233
|
}) {
|
|
8387
8234
|
const [scanning, setScanning] = reactExports.useState(false);
|
|
8388
8235
|
const [scanError, setScanError] = reactExports.useState(null);
|
|
8236
|
+
const [scanId, setScanId] = reactExports.useState(null);
|
|
8389
8237
|
const [providers, setProviders] = reactExports.useState([]);
|
|
8390
8238
|
const [warnings, setWarnings] = reactExports.useState([]);
|
|
8391
8239
|
const [selected, setSelected] = reactExports.useState(/* @__PURE__ */ new Set());
|
|
@@ -8400,18 +8248,20 @@ function ImportWizardDialog({
|
|
|
8400
8248
|
setScanning(true);
|
|
8401
8249
|
setScanError(null);
|
|
8402
8250
|
setWarnings([]);
|
|
8251
|
+
setScanId(null);
|
|
8403
8252
|
setProviders([]);
|
|
8404
8253
|
setSelected(/* @__PURE__ */ new Set());
|
|
8405
8254
|
setImportResult(null);
|
|
8406
8255
|
setImportError(null);
|
|
8407
8256
|
void fetchJsonWithTimeout(
|
|
8408
8257
|
"/api/providers/scan",
|
|
8409
|
-
|
|
8258
|
+
ProviderScanResponseSchema,
|
|
8410
8259
|
PROVIDER_IMPORT_TIMEOUT_MS$1,
|
|
8411
|
-
|
|
8260
|
+
{ method: "POST" },
|
|
8412
8261
|
(response) => `Scan failed (${String(response.status)})`
|
|
8413
8262
|
).then((data) => {
|
|
8414
8263
|
if (scanRequestIdRef.current !== requestId) return;
|
|
8264
|
+
setScanId(data.scanId);
|
|
8415
8265
|
setProviders(data.providers);
|
|
8416
8266
|
setWarnings(data.warnings ?? []);
|
|
8417
8267
|
const indices = /* @__PURE__ */ new Set();
|
|
@@ -8452,25 +8302,12 @@ function ImportWizardDialog({
|
|
|
8452
8302
|
}, []);
|
|
8453
8303
|
const importSelected = reactExports.useCallback(() => {
|
|
8454
8304
|
const toImport = providers.filter((_, i) => selected.has(i));
|
|
8455
|
-
if (toImport.length === 0) return;
|
|
8305
|
+
if (toImport.length === 0 || scanId === null) return;
|
|
8456
8306
|
const requestId = importRequestIdRef.current + 1;
|
|
8457
8307
|
importRequestIdRef.current = requestId;
|
|
8458
8308
|
setImporting(true);
|
|
8459
8309
|
setImportError(null);
|
|
8460
8310
|
setImportResult(null);
|
|
8461
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
8462
|
-
const providersPayload = toImport.map((p) => ({
|
|
8463
|
-
id: window.crypto.randomUUID(),
|
|
8464
|
-
name: p.name,
|
|
8465
|
-
apiKey: p.apiKey,
|
|
8466
|
-
format: p.format,
|
|
8467
|
-
anthropicBaseUrl: p.anthropicBaseUrl,
|
|
8468
|
-
openaiBaseUrl: p.openaiBaseUrl,
|
|
8469
|
-
openaiResponsesBaseUrl: p.openaiResponsesBaseUrl,
|
|
8470
|
-
models: p.models,
|
|
8471
|
-
createdAt: now,
|
|
8472
|
-
updatedAt: now
|
|
8473
|
-
}));
|
|
8474
8311
|
void fetchJsonWithTimeout(
|
|
8475
8312
|
"/api/providers/import",
|
|
8476
8313
|
ImportResponseSchema$1,
|
|
@@ -8478,7 +8315,10 @@ function ImportWizardDialog({
|
|
|
8478
8315
|
{
|
|
8479
8316
|
method: "POST",
|
|
8480
8317
|
headers: { "Content-Type": "application/json" },
|
|
8481
|
-
body: JSON.stringify({
|
|
8318
|
+
body: JSON.stringify({
|
|
8319
|
+
scanId,
|
|
8320
|
+
selectionIds: toImport.map((provider) => provider.selectionId)
|
|
8321
|
+
})
|
|
8482
8322
|
},
|
|
8483
8323
|
(response) => `Import failed (${String(response.status)})`
|
|
8484
8324
|
).then((result) => {
|
|
@@ -8500,7 +8340,7 @@ function ImportWizardDialog({
|
|
|
8500
8340
|
if (importRequestIdRef.current !== requestId) return;
|
|
8501
8341
|
setImporting(false);
|
|
8502
8342
|
});
|
|
8503
|
-
}, [providers, selected, onImportComplete]);
|
|
8343
|
+
}, [providers, scanId, selected, onImportComplete]);
|
|
8504
8344
|
const hasSelectable = providers.some((p) => !p.alreadyExists);
|
|
8505
8345
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-xl max-h-[80vh] overflow-hidden flex flex-col", children: [
|
|
8506
8346
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
|
|
@@ -8546,11 +8386,11 @@ function ImportWizardDialog({
|
|
|
8546
8386
|
p.models.length > 4 ? ` +${p.models.length - 4} more` : ""
|
|
8547
8387
|
] }),
|
|
8548
8388
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: p.format === "anthropic" ? p.anthropicBaseUrl : p.openaiResponsesBaseUrl !== "" ? p.openaiResponsesBaseUrl : p.openaiBaseUrl }),
|
|
8549
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: p.
|
|
8389
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: p.apiKeyHint })
|
|
8550
8390
|
] })
|
|
8551
8391
|
]
|
|
8552
8392
|
},
|
|
8553
|
-
|
|
8393
|
+
p.selectionId
|
|
8554
8394
|
)),
|
|
8555
8395
|
warnings.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground space-y-1 border-t pt-2", children: warnings.map((w, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8556
8396
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-3" }),
|
|
@@ -10327,7 +10167,7 @@ const ImportResponseSchema = object({
|
|
|
10327
10167
|
errors: array(string()).optional()
|
|
10328
10168
|
});
|
|
10329
10169
|
const ModelMetadataRefreshResponseSchema = object({
|
|
10330
|
-
provider:
|
|
10170
|
+
provider: RedactedProviderDtoSchema,
|
|
10331
10171
|
imported: number(),
|
|
10332
10172
|
matchedModels: array(string()),
|
|
10333
10173
|
missingModels: array(string()),
|
|
@@ -10606,7 +10446,7 @@ function ProvidersPanel({
|
|
|
10606
10446
|
try {
|
|
10607
10447
|
const newProvider = await fetchJsonWithTimeout(
|
|
10608
10448
|
"/api/providers",
|
|
10609
|
-
|
|
10449
|
+
RedactedProviderDtoSchema,
|
|
10610
10450
|
PROVIDER_WRITE_TIMEOUT_MS,
|
|
10611
10451
|
{
|
|
10612
10452
|
method: "POST",
|
|
@@ -10633,7 +10473,7 @@ function ProvidersPanel({
|
|
|
10633
10473
|
try {
|
|
10634
10474
|
const updated = await fetchJsonWithTimeout(
|
|
10635
10475
|
`/api/providers/${editingProvider.id}`,
|
|
10636
|
-
|
|
10476
|
+
RedactedProviderDtoSchema,
|
|
10637
10477
|
PROVIDER_WRITE_TIMEOUT_MS,
|
|
10638
10478
|
{
|
|
10639
10479
|
method: "PUT",
|
|
@@ -10754,61 +10594,68 @@ function ProvidersPanel({
|
|
|
10754
10594
|
] });
|
|
10755
10595
|
}
|
|
10756
10596
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
10757
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
|
|
10794
|
-
|
|
10795
|
-
|
|
10796
|
-
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
10802
|
-
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10597
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10598
|
+
"div",
|
|
10599
|
+
{
|
|
10600
|
+
"data-provider-toolbar": "true",
|
|
10601
|
+
className: "sticky top-0 z-10 flex min-w-0 flex-wrap items-center justify-start gap-2 rounded-[8px] bg-background/95 px-1 py-1 backdrop-blur sm:justify-end",
|
|
10602
|
+
children: [
|
|
10603
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10604
|
+
Button,
|
|
10605
|
+
{
|
|
10606
|
+
variant: "outline",
|
|
10607
|
+
size: "sm",
|
|
10608
|
+
onClick: () => handleExport(),
|
|
10609
|
+
className: "gap-1 hover:bg-muted",
|
|
10610
|
+
children: [
|
|
10611
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3" }),
|
|
10612
|
+
"Export"
|
|
10613
|
+
]
|
|
10614
|
+
}
|
|
10615
|
+
),
|
|
10616
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10617
|
+
Button,
|
|
10618
|
+
{
|
|
10619
|
+
variant: "outline",
|
|
10620
|
+
size: "sm",
|
|
10621
|
+
onClick: handleImportClick,
|
|
10622
|
+
className: "gap-1 hover:bg-muted",
|
|
10623
|
+
children: [
|
|
10624
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-3" }),
|
|
10625
|
+
"Import"
|
|
10626
|
+
]
|
|
10627
|
+
}
|
|
10628
|
+
),
|
|
10629
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10630
|
+
"input",
|
|
10631
|
+
{
|
|
10632
|
+
type: "file",
|
|
10633
|
+
ref: fileInputRef,
|
|
10634
|
+
accept: ".json",
|
|
10635
|
+
onChange: handleFileChange,
|
|
10636
|
+
style: { display: "none" }
|
|
10637
|
+
}
|
|
10638
|
+
),
|
|
10639
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10640
|
+
Button,
|
|
10641
|
+
{
|
|
10642
|
+
variant: "outline",
|
|
10643
|
+
size: "sm",
|
|
10644
|
+
onClick: () => setShowImportWizard(true),
|
|
10645
|
+
className: "gap-1",
|
|
10646
|
+
children: [
|
|
10647
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Scan, { className: "size-3" }),
|
|
10648
|
+
"Scan"
|
|
10649
|
+
]
|
|
10650
|
+
}
|
|
10651
|
+
),
|
|
10652
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: () => setShowForm(true), size: "sm", className: "gap-1", children: [
|
|
10653
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
|
|
10654
|
+
"Add Provider"
|
|
10655
|
+
] })
|
|
10656
|
+
]
|
|
10657
|
+
}
|
|
10658
|
+
),
|
|
10812
10659
|
configPath !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 rounded-[8px] bg-muted/15 px-3 py-2 text-xs text-muted-foreground", children: [
|
|
10813
10660
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono truncate", title: configPath, children: configPath }),
|
|
10814
10661
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -10896,6 +10743,23 @@ function ProvidersPanel({
|
|
|
10896
10743
|
)
|
|
10897
10744
|
] });
|
|
10898
10745
|
}
|
|
10746
|
+
const SETTINGS_SECTIONS = [
|
|
10747
|
+
{ value: "providers", label: "Providers" },
|
|
10748
|
+
{ value: "proxy", label: "Proxy" },
|
|
10749
|
+
{ value: "storage", label: "Storage" },
|
|
10750
|
+
{ value: "mcp", label: "MCP" },
|
|
10751
|
+
{ value: "onboarding", label: "Onboarding" }
|
|
10752
|
+
];
|
|
10753
|
+
function ResponsiveSettingsTabs() {
|
|
10754
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10755
|
+
TabsList,
|
|
10756
|
+
{
|
|
10757
|
+
"aria-label": "Settings sections",
|
|
10758
|
+
className: "grid w-full grid-cols-3 justify-stretch gap-1 bg-muted/35 p-1 group-data-[orientation=horizontal]/tabs:h-auto sm:grid-cols-5",
|
|
10759
|
+
children: SETTINGS_SECTIONS.map((section) => /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: section.value, className: "min-w-0 w-full", children: section.label }, section.value))
|
|
10760
|
+
}
|
|
10761
|
+
);
|
|
10762
|
+
}
|
|
10899
10763
|
function SettingsDialog() {
|
|
10900
10764
|
const [open, setOpen] = reactExports.useState(false);
|
|
10901
10765
|
const [activeTab, setActiveTab] = reactExports.useState("providers");
|
|
@@ -10948,39 +10812,41 @@ function SettingsDialog() {
|
|
|
10948
10812
|
]
|
|
10949
10813
|
}
|
|
10950
10814
|
) }),
|
|
10951
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "flex max-h-[
|
|
10815
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "flex max-h-[calc(100vh-1rem)] w-[calc(100%-1rem)] max-w-2xl flex-col overflow-hidden p-4 sm:max-h-[80vh] sm:p-6", children: [
|
|
10952
10816
|
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Settings" }) }),
|
|
10953
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10817
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10818
|
+
Tabs,
|
|
10819
|
+
{
|
|
10820
|
+
value: activeTab,
|
|
10821
|
+
onValueChange: setActiveTab,
|
|
10822
|
+
className: "min-h-0 min-w-0 flex-1 overflow-hidden",
|
|
10823
|
+
children: [
|
|
10824
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveSettingsTabs, {}),
|
|
10825
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 min-w-0 flex-1 overflow-x-hidden overflow-y-auto pr-1 sm:pr-2", children: [
|
|
10826
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "providers", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10827
|
+
ProvidersPanel,
|
|
10828
|
+
{
|
|
10829
|
+
externalProviders: providers,
|
|
10830
|
+
isLoading,
|
|
10831
|
+
externalTestResults: testResults,
|
|
10832
|
+
externalTestingProviders: testingProviders,
|
|
10833
|
+
externalTestingTimeLeft: testingTimeLeft,
|
|
10834
|
+
onProvidersMutate: () => {
|
|
10835
|
+
return mutate();
|
|
10836
|
+
},
|
|
10837
|
+
onTestResultsChange: handleTestResultsChange,
|
|
10838
|
+
onTestingProvidersChange: handleTestingProvidersChange,
|
|
10839
|
+
onTestingTimeLeftChange: handleTestingTimeLeftChange
|
|
10840
|
+
}
|
|
10841
|
+
) }),
|
|
10842
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "proxy", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProxySettingsTab, {}) }),
|
|
10843
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "storage", children: /* @__PURE__ */ jsxRuntimeExports.jsx(StorageSettingsTab, {}) }),
|
|
10844
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "mcp", children: /* @__PURE__ */ jsxRuntimeExports.jsx(McpSettingsTab, {}) }),
|
|
10845
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "onboarding", children: /* @__PURE__ */ jsxRuntimeExports.jsx(OnboardingSettingsTab, {}) })
|
|
10846
|
+
] })
|
|
10847
|
+
]
|
|
10848
|
+
}
|
|
10849
|
+
)
|
|
10984
10850
|
] })
|
|
10985
10851
|
] });
|
|
10986
10852
|
}
|
|
@@ -11122,7 +10988,7 @@ function CopyableSetupValue({
|
|
|
11122
10988
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 rounded-md border border-border/45 bg-muted/15 px-3 py-2 transition-colors hover:bg-muted/25", children: [
|
|
11123
10989
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: label }),
|
|
11124
10990
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
11125
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "min-w-0 flex-1 truncate font-mono text-xs text-foreground", children: value }),
|
|
10991
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "min-w-0 flex-1 truncate font-mono text-xs text-foreground", title: value, children: value }),
|
|
11126
10992
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11127
10993
|
Button,
|
|
11128
10994
|
{
|
|
@@ -11593,83 +11459,6 @@ function ProxySettingsTab() {
|
|
|
11593
11459
|
] })
|
|
11594
11460
|
] });
|
|
11595
11461
|
}
|
|
11596
|
-
const EcosystemPackageStateSchema = _enum([
|
|
11597
|
-
"installed",
|
|
11598
|
-
"update-available",
|
|
11599
|
-
"available",
|
|
11600
|
-
"planned",
|
|
11601
|
-
"unknown"
|
|
11602
|
-
]);
|
|
11603
|
-
const EcosystemPackageSchema = object({
|
|
11604
|
-
id: string(),
|
|
11605
|
-
name: string(),
|
|
11606
|
-
npmName: string(),
|
|
11607
|
-
capability: string(),
|
|
11608
|
-
description: string(),
|
|
11609
|
-
workflow: string(),
|
|
11610
|
-
installCommand: string(),
|
|
11611
|
-
state: EcosystemPackageStateSchema,
|
|
11612
|
-
installedVersion: string().nullable(),
|
|
11613
|
-
latestVersion: string().nullable(),
|
|
11614
|
-
primary: boolean()
|
|
11615
|
-
});
|
|
11616
|
-
const EcosystemRunnerPresetSchema = object({
|
|
11617
|
-
id: string(),
|
|
11618
|
-
name: string(),
|
|
11619
|
-
validatedVersion: string(),
|
|
11620
|
-
binary: string(),
|
|
11621
|
-
modelFlag: string(),
|
|
11622
|
-
variantFlag: string().nullable(),
|
|
11623
|
-
tools: array(string()),
|
|
11624
|
-
logDir: string(),
|
|
11625
|
-
skillsDir: string(),
|
|
11626
|
-
agentsDir: string()
|
|
11627
|
-
});
|
|
11628
|
-
const EcosystemRecipeSchema = object({
|
|
11629
|
-
id: string(),
|
|
11630
|
-
title: string(),
|
|
11631
|
-
stage: string(),
|
|
11632
|
-
packageId: string(),
|
|
11633
|
-
description: string(),
|
|
11634
|
-
command: string(),
|
|
11635
|
-
requiresSession: boolean(),
|
|
11636
|
-
runnable: boolean()
|
|
11637
|
-
});
|
|
11638
|
-
const EcosystemPackagesResponseSchema = object({
|
|
11639
|
-
checkedAt: string(),
|
|
11640
|
-
packages: array(EcosystemPackageSchema),
|
|
11641
|
-
runnerPresets: array(EcosystemRunnerPresetSchema),
|
|
11642
|
-
recipes: array(EcosystemRecipeSchema)
|
|
11643
|
-
});
|
|
11644
|
-
const EcosystemTaskActionSchema = _enum([
|
|
11645
|
-
"install",
|
|
11646
|
-
"upgrade",
|
|
11647
|
-
"help",
|
|
11648
|
-
"runner-presets",
|
|
11649
|
-
"recipe"
|
|
11650
|
-
]);
|
|
11651
|
-
const EcosystemTaskStatusSchema = _enum(["queued", "running", "succeeded", "failed"]);
|
|
11652
|
-
const EcosystemTaskSchema = object({
|
|
11653
|
-
id: string(),
|
|
11654
|
-
packageId: string(),
|
|
11655
|
-
npmName: string(),
|
|
11656
|
-
recipeId: string().nullable().default(null),
|
|
11657
|
-
action: EcosystemTaskActionSchema,
|
|
11658
|
-
status: EcosystemTaskStatusSchema,
|
|
11659
|
-
command: string(),
|
|
11660
|
-
output: string(),
|
|
11661
|
-
createdAt: string(),
|
|
11662
|
-
startedAt: string().nullable(),
|
|
11663
|
-
finishedAt: string().nullable(),
|
|
11664
|
-
exitCode: number().nullable(),
|
|
11665
|
-
error: string().nullable()
|
|
11666
|
-
});
|
|
11667
|
-
const EcosystemTaskResponseSchema = object({
|
|
11668
|
-
task: EcosystemTaskSchema
|
|
11669
|
-
});
|
|
11670
|
-
const EcosystemTasksResponseSchema = object({
|
|
11671
|
-
tasks: array(EcosystemTaskSchema)
|
|
11672
|
-
});
|
|
11673
11462
|
const WORKFLOWS = [
|
|
11674
11463
|
{
|
|
11675
11464
|
id: "observe",
|
|
@@ -11728,24 +11517,51 @@ async function fetchEcosystemTasks(url) {
|
|
|
11728
11517
|
(response) => `Failed to load ecosystem tasks: ${String(response.status)}`
|
|
11729
11518
|
);
|
|
11730
11519
|
}
|
|
11731
|
-
async function
|
|
11520
|
+
async function prepareEcosystemTask(packageId, action) {
|
|
11521
|
+
const endpoint = `/api/ecosystem/packages/${encodeURIComponent(packageId)}/${action}`;
|
|
11732
11522
|
const response = await fetchJson(
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
{
|
|
11736
|
-
|
|
11523
|
+
endpoint,
|
|
11524
|
+
EcosystemExecutionConfirmationResponseSchema,
|
|
11525
|
+
{
|
|
11526
|
+
method: "POST",
|
|
11527
|
+
headers: { "content-type": "application/json" },
|
|
11528
|
+
body: JSON.stringify({ intent: "prepare" })
|
|
11529
|
+
},
|
|
11530
|
+
(result) => `Failed to prepare ecosystem task: ${String(result.status)}`
|
|
11737
11531
|
);
|
|
11738
|
-
return response.
|
|
11532
|
+
return { endpoint, confirmation: response.confirmation };
|
|
11739
11533
|
}
|
|
11740
|
-
async function
|
|
11534
|
+
async function prepareEcosystemRecipe(recipeId) {
|
|
11535
|
+
const endpoint = `/api/ecosystem/recipes/${encodeURIComponent(recipeId)}/run`;
|
|
11741
11536
|
const response = await fetchJson(
|
|
11742
|
-
|
|
11743
|
-
|
|
11744
|
-
{
|
|
11745
|
-
|
|
11746
|
-
|
|
11747
|
-
|
|
11748
|
-
}
|
|
11537
|
+
endpoint,
|
|
11538
|
+
EcosystemExecutionConfirmationResponseSchema,
|
|
11539
|
+
{
|
|
11540
|
+
method: "POST",
|
|
11541
|
+
headers: { "content-type": "application/json" },
|
|
11542
|
+
body: JSON.stringify({ intent: "prepare" })
|
|
11543
|
+
},
|
|
11544
|
+
(result) => `Failed to prepare ecosystem recipe: ${String(result.status)}`
|
|
11545
|
+
);
|
|
11546
|
+
return { endpoint, confirmation: response.confirmation };
|
|
11547
|
+
}
|
|
11548
|
+
async function confirmEcosystemExecution(pending) {
|
|
11549
|
+
const response = await fetchJson(
|
|
11550
|
+
pending.endpoint,
|
|
11551
|
+
EcosystemTaskResponseSchema,
|
|
11552
|
+
{
|
|
11553
|
+
method: "POST",
|
|
11554
|
+
headers: { "content-type": "application/json" },
|
|
11555
|
+
body: JSON.stringify({
|
|
11556
|
+
intent: "confirm",
|
|
11557
|
+
nonce: pending.confirmation.nonce,
|
|
11558
|
+
confirmation: pending.confirmation.phrase
|
|
11559
|
+
})
|
|
11560
|
+
},
|
|
11561
|
+
(result) => `Failed to start ecosystem task: ${String(result.status)}`
|
|
11562
|
+
);
|
|
11563
|
+
return response.task;
|
|
11564
|
+
}
|
|
11749
11565
|
function stateLabel(state) {
|
|
11750
11566
|
switch (state) {
|
|
11751
11567
|
case "installed":
|
|
@@ -12049,6 +11865,76 @@ function RecentTaskRow({
|
|
|
12049
11865
|
)
|
|
12050
11866
|
] });
|
|
12051
11867
|
}
|
|
11868
|
+
function ExecutionConfirmationDialog({
|
|
11869
|
+
pending,
|
|
11870
|
+
busy,
|
|
11871
|
+
onOpenChange,
|
|
11872
|
+
onConfirm
|
|
11873
|
+
}) {
|
|
11874
|
+
const plan = pending?.confirmation.plan ?? null;
|
|
11875
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: pending !== null, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-xl", children: [
|
|
11876
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
|
|
11877
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Confirm local command" }),
|
|
11878
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "Review the exact allowlisted action Agent Inspector will run on this machine." })
|
|
11879
|
+
] }),
|
|
11880
|
+
plan !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
|
|
11881
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2 text-xs sm:grid-cols-2", children: [
|
|
11882
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border bg-muted/30 p-3", children: [
|
|
11883
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground", children: "Source" }),
|
|
11884
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 break-words font-medium", children: plan.source })
|
|
11885
|
+
] }),
|
|
11886
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border bg-muted/30 p-3", children: [
|
|
11887
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground", children: "Timeout" }),
|
|
11888
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-medium", children: [
|
|
11889
|
+
String(plan.timeoutMs / 1e3),
|
|
11890
|
+
" seconds"
|
|
11891
|
+
] })
|
|
11892
|
+
] }),
|
|
11893
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border bg-muted/30 p-3 sm:col-span-2", children: [
|
|
11894
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground", children: "Affected scope" }),
|
|
11895
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 font-medium", children: plan.scope })
|
|
11896
|
+
] })
|
|
11897
|
+
] }),
|
|
11898
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
11899
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-1 text-xs font-medium", children: "Resolved command" }),
|
|
11900
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "max-h-32 overflow-auto whitespace-pre-wrap break-all rounded-md bg-black/80 p-3 font-mono text-xs leading-5 text-white/80", children: plan.command })
|
|
11901
|
+
] }),
|
|
11902
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
11903
|
+
"Confirmation phrase: ",
|
|
11904
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: pending?.confirmation.phrase }),
|
|
11905
|
+
". The one-time confirmation expires at",
|
|
11906
|
+
" ",
|
|
11907
|
+
new Date(pending?.confirmation.expiresAt ?? "").toLocaleTimeString(),
|
|
11908
|
+
"."
|
|
11909
|
+
] })
|
|
11910
|
+
] }),
|
|
11911
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [
|
|
11912
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11913
|
+
Button,
|
|
11914
|
+
{
|
|
11915
|
+
type: "button",
|
|
11916
|
+
variant: "outline",
|
|
11917
|
+
disabled: busy,
|
|
11918
|
+
onClick: () => onOpenChange(false),
|
|
11919
|
+
children: "Cancel"
|
|
11920
|
+
}
|
|
11921
|
+
),
|
|
11922
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11923
|
+
Button,
|
|
11924
|
+
{
|
|
11925
|
+
type: "button",
|
|
11926
|
+
variant: "secondary",
|
|
11927
|
+
disabled: busy || plan === null,
|
|
11928
|
+
onClick: onConfirm,
|
|
11929
|
+
children: [
|
|
11930
|
+
busy ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5" }),
|
|
11931
|
+
busy ? "Starting" : "Confirm & Run"
|
|
11932
|
+
]
|
|
11933
|
+
}
|
|
11934
|
+
)
|
|
11935
|
+
] })
|
|
11936
|
+
] }) });
|
|
11937
|
+
}
|
|
12052
11938
|
function AgentLabDialog({ currentSessionId, logCount }) {
|
|
12053
11939
|
const [open, setOpen] = reactExports.useState(false);
|
|
12054
11940
|
const [copied, setCopied] = reactExports.useState(false);
|
|
@@ -12056,6 +11942,8 @@ function AgentLabDialog({ currentSessionId, logCount }) {
|
|
|
12056
11942
|
const [copiedRecipeId, setCopiedRecipeId] = reactExports.useState(null);
|
|
12057
11943
|
const [activeTaskId, setActiveTaskId] = reactExports.useState(null);
|
|
12058
11944
|
const [taskError, setTaskError] = reactExports.useState(null);
|
|
11945
|
+
const [pendingExecution, setPendingExecution] = reactExports.useState(null);
|
|
11946
|
+
const [confirmationBusy, setConfirmationBusy] = reactExports.useState(false);
|
|
12059
11947
|
const response = useSWR("/api/ecosystem/packages", fetchEcosystemPackages, {
|
|
12060
11948
|
revalidateOnFocus: false,
|
|
12061
11949
|
revalidateIfStale: false
|
|
@@ -12105,12 +11993,10 @@ function AgentLabDialog({ currentSessionId, logCount }) {
|
|
|
12105
11993
|
};
|
|
12106
11994
|
const runRecipe = (recipe) => {
|
|
12107
11995
|
setTaskError(null);
|
|
12108
|
-
void
|
|
12109
|
-
|
|
12110
|
-
void activeTaskResponse.mutate({ task }, { revalidate: true });
|
|
12111
|
-
void tasksResponse.mutate();
|
|
11996
|
+
void prepareEcosystemRecipe(recipe.id).then((pending) => {
|
|
11997
|
+
setPendingExecution(pending);
|
|
12112
11998
|
}).catch((error) => {
|
|
12113
|
-
setTaskError(error instanceof Error ? error.message : "Failed to
|
|
11999
|
+
setTaskError(error instanceof Error ? error.message : "Failed to prepare ecosystem recipe");
|
|
12114
12000
|
});
|
|
12115
12001
|
};
|
|
12116
12002
|
const activeTask = activeTaskResponse.data?.task ?? null;
|
|
@@ -12122,12 +12008,25 @@ function AgentLabDialog({ currentSessionId, logCount }) {
|
|
|
12122
12008
|
}, [activeTask, response, tasksResponse]);
|
|
12123
12009
|
const handleStartTask = (packageId, action) => {
|
|
12124
12010
|
setTaskError(null);
|
|
12125
|
-
void
|
|
12011
|
+
void prepareEcosystemTask(packageId, action).then((pending) => {
|
|
12012
|
+
setPendingExecution(pending);
|
|
12013
|
+
}).catch((error) => {
|
|
12014
|
+
setTaskError(error instanceof Error ? error.message : "Failed to prepare ecosystem task");
|
|
12015
|
+
});
|
|
12016
|
+
};
|
|
12017
|
+
const confirmPendingExecution = () => {
|
|
12018
|
+
if (pendingExecution === null) return;
|
|
12019
|
+
setTaskError(null);
|
|
12020
|
+
setConfirmationBusy(true);
|
|
12021
|
+
void confirmEcosystemExecution(pendingExecution).then((task) => {
|
|
12126
12022
|
setActiveTaskId(task.id);
|
|
12023
|
+
setPendingExecution(null);
|
|
12127
12024
|
void activeTaskResponse.mutate({ task }, { revalidate: true });
|
|
12128
12025
|
void tasksResponse.mutate();
|
|
12129
12026
|
}).catch((error) => {
|
|
12130
12027
|
setTaskError(error instanceof Error ? error.message : "Failed to start ecosystem task");
|
|
12028
|
+
}).finally(() => {
|
|
12029
|
+
setConfirmationBusy(false);
|
|
12131
12030
|
});
|
|
12132
12031
|
};
|
|
12133
12032
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open, onOpenChange: setOpen, children: [
|
|
@@ -12288,857 +12187,20 @@ function AgentLabDialog({ currentSessionId, logCount }) {
|
|
|
12288
12187
|
] }),
|
|
12289
12188
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TaskConsole, { task: activeTask })
|
|
12290
12189
|
] })
|
|
12291
|
-
] })
|
|
12292
|
-
] });
|
|
12293
|
-
}
|
|
12294
|
-
const INSPECTOR_PET_SIZE = 112;
|
|
12295
|
-
const INSPECTOR_PET_MARGIN = 14;
|
|
12296
|
-
const INSPECTOR_PET_EDGE_GAP = 20;
|
|
12297
|
-
const INSPECTOR_PET_MIN_STEP = 36;
|
|
12298
|
-
const INSPECTOR_PET_MAX_STEP = 92;
|
|
12299
|
-
const INSPECTOR_PET_SLEEP_AFTER_MS = 45e3;
|
|
12300
|
-
const INSPECTOR_PET_PANEL_WIDTH = 192;
|
|
12301
|
-
const INSPECTOR_PET_PANEL_HEIGHT = 68;
|
|
12302
|
-
const INSPECTOR_PET_PANEL_GAP = 10;
|
|
12303
|
-
const INSPECTOR_PET_VERTICAL_SAFE_MARGIN = 78;
|
|
12304
|
-
function viewportScale(viewport) {
|
|
12305
|
-
const scale = viewport.scale ?? 1;
|
|
12306
|
-
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
12307
|
-
}
|
|
12308
|
-
function scaledMetric(value, viewport) {
|
|
12309
|
-
return value * viewportScale(viewport);
|
|
12310
|
-
}
|
|
12311
|
-
function clampUnit(value) {
|
|
12312
|
-
return Math.min(Math.max(value, 0), 1);
|
|
12313
|
-
}
|
|
12314
|
-
function maximumPetX(viewport) {
|
|
12315
|
-
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12316
|
-
return Math.max(edgeGap, viewport.width - scaledMetric(INSPECTOR_PET_SIZE, viewport) - edgeGap);
|
|
12317
|
-
}
|
|
12318
|
-
function maximumPetY(viewport) {
|
|
12319
|
-
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12320
|
-
return Math.max(edgeGap, viewport.height - scaledMetric(INSPECTOR_PET_SIZE, viewport) - edgeGap);
|
|
12321
|
-
}
|
|
12322
|
-
function clampInspectorPetPosition(position, viewport) {
|
|
12323
|
-
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12324
|
-
return {
|
|
12325
|
-
x: Math.min(Math.max(position.x, edgeGap), maximumPetX(viewport)),
|
|
12326
|
-
y: Math.min(Math.max(position.y, edgeGap), maximumPetY(viewport))
|
|
12327
|
-
};
|
|
12328
|
-
}
|
|
12329
|
-
function nearestInspectorPetEdge(position, viewport) {
|
|
12330
|
-
const clamped = clampInspectorPetPosition(position, viewport);
|
|
12331
|
-
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12332
|
-
const distances = [
|
|
12333
|
-
{ edge: "left", distance: clamped.x - edgeGap },
|
|
12334
|
-
{ edge: "right", distance: maximumPetX(viewport) - clamped.x },
|
|
12335
|
-
{ edge: "top", distance: clamped.y - edgeGap },
|
|
12336
|
-
{ edge: "bottom", distance: maximumPetY(viewport) - clamped.y }
|
|
12337
|
-
];
|
|
12338
|
-
return distances.reduce((best, current) => current.distance < best.distance ? current : best).edge;
|
|
12339
|
-
}
|
|
12340
|
-
function snapInspectorPetToEdge(position, viewport) {
|
|
12341
|
-
const clamped = clampInspectorPetPosition(position, viewport);
|
|
12342
|
-
const edge = nearestInspectorPetEdge(clamped, viewport);
|
|
12343
|
-
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12344
|
-
switch (edge) {
|
|
12345
|
-
case "left":
|
|
12346
|
-
return { x: edgeGap, y: clamped.y };
|
|
12347
|
-
case "right":
|
|
12348
|
-
return { x: maximumPetX(viewport), y: clamped.y };
|
|
12349
|
-
case "top":
|
|
12350
|
-
return { x: clamped.x, y: edgeGap };
|
|
12351
|
-
case "bottom":
|
|
12352
|
-
return { x: clamped.x, y: maximumPetY(viewport) };
|
|
12353
|
-
}
|
|
12354
|
-
}
|
|
12355
|
-
function randomInspectorPetEdgePosition(viewport, positionSample) {
|
|
12356
|
-
const maxX = maximumPetX(viewport);
|
|
12357
|
-
const maxY = maximumPetY(viewport);
|
|
12358
|
-
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12359
|
-
return {
|
|
12360
|
-
x: edgeGap + clampUnit(positionSample) * (maxX - edgeGap),
|
|
12361
|
-
y: maxY
|
|
12362
|
-
};
|
|
12363
|
-
}
|
|
12364
|
-
function nextInspectorPetWalkingPosition(position, viewport, stepSample, directionSample) {
|
|
12365
|
-
const clamped = snapInspectorPetToEdge(position, viewport);
|
|
12366
|
-
const step = scaledMetric(INSPECTOR_PET_MIN_STEP, viewport) + clampUnit(stepSample) * scaledMetric(INSPECTOR_PET_MAX_STEP - INSPECTOR_PET_MIN_STEP, viewport);
|
|
12367
|
-
const direction = directionSample >= 0.5 ? 1 : -1;
|
|
12368
|
-
const edge = nearestInspectorPetEdge(clamped, viewport);
|
|
12369
|
-
const maxX = maximumPetX(viewport);
|
|
12370
|
-
const maxY = maximumPetY(viewport);
|
|
12371
|
-
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12372
|
-
const minimumSafeY = Math.min(scaledMetric(INSPECTOR_PET_VERTICAL_SAFE_MARGIN, viewport), maxY);
|
|
12373
|
-
switch (edge) {
|
|
12374
|
-
case "left":
|
|
12375
|
-
return {
|
|
12376
|
-
x: edgeGap,
|
|
12377
|
-
y: Math.min(Math.max(clamped.y + step * direction, minimumSafeY), maxY)
|
|
12378
|
-
};
|
|
12379
|
-
case "right":
|
|
12380
|
-
return {
|
|
12381
|
-
x: maxX,
|
|
12382
|
-
y: Math.min(Math.max(clamped.y + step * direction, minimumSafeY), maxY)
|
|
12383
|
-
};
|
|
12384
|
-
case "top":
|
|
12385
|
-
return {
|
|
12386
|
-
x: Math.min(Math.max(clamped.x + step * direction, edgeGap), maxX),
|
|
12387
|
-
y: edgeGap
|
|
12388
|
-
};
|
|
12389
|
-
case "bottom":
|
|
12390
|
-
return {
|
|
12391
|
-
x: Math.min(Math.max(clamped.x + step * direction, edgeGap), maxX),
|
|
12392
|
-
y: maxY
|
|
12393
|
-
};
|
|
12394
|
-
}
|
|
12395
|
-
}
|
|
12396
|
-
function inspectorPetPanelPosition(position, viewport) {
|
|
12397
|
-
const edge = nearestInspectorPetEdge(position, viewport);
|
|
12398
|
-
const petSize = scaledMetric(INSPECTOR_PET_SIZE, viewport);
|
|
12399
|
-
const panelWidth = scaledMetric(INSPECTOR_PET_PANEL_WIDTH, viewport);
|
|
12400
|
-
const panelHeight = scaledMetric(INSPECTOR_PET_PANEL_HEIGHT, viewport);
|
|
12401
|
-
const panelGap = scaledMetric(INSPECTOR_PET_PANEL_GAP, viewport);
|
|
12402
|
-
const margin = scaledMetric(INSPECTOR_PET_MARGIN, viewport);
|
|
12403
|
-
let x = position.x + petSize / 2 - panelWidth / 2;
|
|
12404
|
-
let y = position.y + petSize / 2 - panelHeight / 2;
|
|
12405
|
-
switch (edge) {
|
|
12406
|
-
case "left":
|
|
12407
|
-
x = position.x + petSize + panelGap;
|
|
12408
|
-
break;
|
|
12409
|
-
case "right":
|
|
12410
|
-
x = position.x - panelWidth - panelGap;
|
|
12411
|
-
break;
|
|
12412
|
-
case "top":
|
|
12413
|
-
y = position.y + petSize + panelGap;
|
|
12414
|
-
break;
|
|
12415
|
-
case "bottom":
|
|
12416
|
-
y = position.y - panelHeight - panelGap;
|
|
12417
|
-
break;
|
|
12418
|
-
}
|
|
12419
|
-
return {
|
|
12420
|
-
x: Math.min(Math.max(x, margin), Math.max(margin, viewport.width - panelWidth - margin)),
|
|
12421
|
-
y: Math.min(Math.max(y, margin), Math.max(margin, viewport.height - panelHeight - margin))
|
|
12422
|
-
};
|
|
12423
|
-
}
|
|
12424
|
-
function latestCapturedLog(logs) {
|
|
12425
|
-
let latest = null;
|
|
12426
|
-
for (const log of logs) {
|
|
12427
|
-
if (latest === null || log.id > latest.id) latest = log;
|
|
12428
|
-
}
|
|
12429
|
-
return latest;
|
|
12430
|
-
}
|
|
12431
|
-
function logNeedsAttention(log) {
|
|
12432
|
-
const hasHttpError = log.responseStatus !== null && log.responseStatus >= 400;
|
|
12433
|
-
const hasStreamError = log.error !== null && log.error !== void 0 && log.error !== "";
|
|
12434
|
-
return hasHttpError || hasStreamError;
|
|
12435
|
-
}
|
|
12436
|
-
function resolveInspectorPetStatus(logs, nowMs) {
|
|
12437
|
-
const pendingCount = logs.filter((log) => log.responseStatus === null).length;
|
|
12438
|
-
const capturedCount = logs.length;
|
|
12439
|
-
if (pendingCount > 0) {
|
|
12440
|
-
return {
|
|
12441
|
-
mood: "active",
|
|
12442
|
-
label: `${String(pendingCount)} request${pendingCount === 1 ? "" : "s"} in flight`,
|
|
12443
|
-
pendingCount,
|
|
12444
|
-
capturedCount
|
|
12445
|
-
};
|
|
12446
|
-
}
|
|
12447
|
-
const latest = latestCapturedLog(logs);
|
|
12448
|
-
if (latest !== null && logNeedsAttention(latest)) {
|
|
12449
|
-
return {
|
|
12450
|
-
mood: "attention",
|
|
12451
|
-
label: "Latest request needs attention",
|
|
12452
|
-
pendingCount,
|
|
12453
|
-
capturedCount
|
|
12454
|
-
};
|
|
12455
|
-
}
|
|
12456
|
-
if (latest === null) {
|
|
12457
|
-
return {
|
|
12458
|
-
mood: "idle",
|
|
12459
|
-
label: "Waiting for traffic",
|
|
12460
|
-
pendingCount,
|
|
12461
|
-
capturedCount
|
|
12462
|
-
};
|
|
12463
|
-
}
|
|
12464
|
-
const latestTimestamp2 = Date.parse(latest.timestamp);
|
|
12465
|
-
if (Number.isFinite(latestTimestamp2) && nowMs - latestTimestamp2 >= INSPECTOR_PET_SLEEP_AFTER_MS) {
|
|
12466
|
-
return {
|
|
12467
|
-
mood: "sleeping",
|
|
12468
|
-
label: "All quiet",
|
|
12469
|
-
pendingCount,
|
|
12470
|
-
capturedCount
|
|
12471
|
-
};
|
|
12472
|
-
}
|
|
12473
|
-
return {
|
|
12474
|
-
mood: "idle",
|
|
12475
|
-
label: "Watching the session",
|
|
12476
|
-
pendingCount,
|
|
12477
|
-
capturedCount
|
|
12478
|
-
};
|
|
12479
|
-
}
|
|
12480
|
-
function createRod(start, end, radius, material) {
|
|
12481
|
-
const direction = end.clone().sub(start);
|
|
12482
|
-
const length = direction.length();
|
|
12483
|
-
const rod = new Mesh(new CylinderGeometry(radius, radius * 0.9, length, 12), material);
|
|
12484
|
-
rod.position.copy(start.clone().add(end).multiplyScalar(0.5));
|
|
12485
|
-
rod.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), direction.normalize());
|
|
12486
|
-
return rod;
|
|
12487
|
-
}
|
|
12488
|
-
function addClaw(root, side, shellMaterial, accentMaterial) {
|
|
12489
|
-
const clawScale = side < 0 ? 1.5 : 0.68;
|
|
12490
|
-
const clawGroup = new Group();
|
|
12491
|
-
const pincers = [];
|
|
12492
|
-
root.add(clawGroup);
|
|
12493
|
-
const shoulder = new Vector3(side * 1.2, 0.25, -0.05);
|
|
12494
|
-
const wrist = new Vector3(side * (1.65 + clawScale * 0.18), 0.5, 0);
|
|
12495
|
-
const arm = createRod(shoulder, wrist, 0.16 * clawScale, accentMaterial);
|
|
12496
|
-
clawGroup.add(arm);
|
|
12497
|
-
const palm = new Mesh(new SphereGeometry(0.55, 24, 16), shellMaterial);
|
|
12498
|
-
palm.position.set(side * (1.95 + clawScale * 0.16), 0.62, 0.05);
|
|
12499
|
-
palm.scale.set(1.05 * clawScale, 0.72 * clawScale, 0.55 * clawScale);
|
|
12500
|
-
clawGroup.add(palm);
|
|
12501
|
-
for (const pincerDirection of [-1, 1]) {
|
|
12502
|
-
const pincer = new Mesh(new SphereGeometry(0.36, 20, 14), accentMaterial);
|
|
12503
|
-
pincer.position.set(
|
|
12504
|
-
side * (2.22 + clawScale * 0.26),
|
|
12505
|
-
0.62 + pincerDirection * 0.24 * clawScale,
|
|
12506
|
-
0.08
|
|
12507
|
-
);
|
|
12508
|
-
pincer.scale.set(1.05 * clawScale, 0.34 * clawScale, 0.42 * clawScale);
|
|
12509
|
-
pincer.rotation.z = pincerDirection * side * 0.42;
|
|
12510
|
-
clawGroup.add(pincer);
|
|
12511
|
-
pincers.push({
|
|
12512
|
-
direction: pincerDirection,
|
|
12513
|
-
mesh: pincer,
|
|
12514
|
-
restRotationZ: pincer.rotation.z,
|
|
12515
|
-
restY: pincer.position.y
|
|
12516
|
-
});
|
|
12517
|
-
}
|
|
12518
|
-
return { group: clawGroup, pincers, scale: clawScale };
|
|
12519
|
-
}
|
|
12520
|
-
function pinchPulse(cycleTime, start, duration) {
|
|
12521
|
-
const progress = (cycleTime - start) / duration;
|
|
12522
|
-
if (progress <= 0 || progress >= 1) return 0;
|
|
12523
|
-
return Math.sin(progress * Math.PI);
|
|
12524
|
-
}
|
|
12525
|
-
function dominantClawGrip(elapsed) {
|
|
12526
|
-
const cycleTime = elapsed % 6.8;
|
|
12527
|
-
return Math.max(pinchPulse(cycleTime, 0.72, 0.82), pinchPulse(cycleTime, 1.72, 0.68));
|
|
12528
|
-
}
|
|
12529
|
-
function addEyes(root, shellMaterial, eyeMaterial) {
|
|
12530
|
-
const eyes = [];
|
|
12531
|
-
for (const side of [-1, 1]) {
|
|
12532
|
-
const stalkStart = new Vector3(side * 0.48, 0.68, 0.05);
|
|
12533
|
-
const stalkEnd = new Vector3(side * 0.1, 0.82, 0.07);
|
|
12534
|
-
const eyeGroup = new Group();
|
|
12535
|
-
eyeGroup.position.copy(stalkStart);
|
|
12536
|
-
eyeGroup.add(createRod(new Vector3(0, 0, 0), stalkEnd, 0.1, shellMaterial));
|
|
12537
|
-
const eye = new Mesh(new SphereGeometry(0.24, 20, 16), eyeMaterial);
|
|
12538
|
-
eye.position.copy(stalkEnd);
|
|
12539
|
-
eye.scale.set(1, 1, 0.85);
|
|
12540
|
-
eyeGroup.add(eye);
|
|
12541
|
-
const pupil = new Mesh(
|
|
12542
|
-
new SphereGeometry(0.105, 16, 12),
|
|
12543
|
-
new MeshPhysicalMaterial({ color: 1120295, roughness: 0.25 })
|
|
12544
|
-
);
|
|
12545
|
-
const pupilRest = new Vector3(stalkEnd.x, stalkEnd.y, stalkEnd.z + 0.2);
|
|
12546
|
-
pupil.position.copy(pupilRest);
|
|
12547
|
-
eyeGroup.add(pupil);
|
|
12548
|
-
root.add(eyeGroup);
|
|
12549
|
-
eyes.push({
|
|
12550
|
-
group: eyeGroup,
|
|
12551
|
-
phase: side < 0 ? 0 : Math.PI / 3,
|
|
12552
|
-
pupil,
|
|
12553
|
-
pupilRest
|
|
12554
|
-
});
|
|
12555
|
-
}
|
|
12556
|
-
return eyes;
|
|
12557
|
-
}
|
|
12558
|
-
function addLegs(root, legMaterial) {
|
|
12559
|
-
const legs = [];
|
|
12560
|
-
for (const side of [-1, 1]) {
|
|
12561
|
-
for (let index = 0; index < 4; index += 1) {
|
|
12562
|
-
const leg = new Group();
|
|
12563
|
-
const baseY = -0.3 - index * 0.22;
|
|
12564
|
-
leg.position.set(side * (0.8 + index * 0.12), baseY, -0.18);
|
|
12565
|
-
leg.add(
|
|
12566
|
-
createRod(
|
|
12567
|
-
new Vector3(0, 0, 0),
|
|
12568
|
-
new Vector3(side * (0.62 + index * 0.06), -0.34, 0),
|
|
12569
|
-
0.095,
|
|
12570
|
-
legMaterial
|
|
12571
|
-
)
|
|
12572
|
-
);
|
|
12573
|
-
leg.add(
|
|
12574
|
-
createRod(
|
|
12575
|
-
new Vector3(side * (0.58 + index * 0.06), -0.31, 0),
|
|
12576
|
-
new Vector3(side * (1.02 + index * 0.08), -0.88 + index * 0.07, 0.04),
|
|
12577
|
-
0.075,
|
|
12578
|
-
legMaterial
|
|
12579
|
-
)
|
|
12580
|
-
);
|
|
12581
|
-
root.add(leg);
|
|
12582
|
-
legs.push({ group: leg, phase: index * Math.PI + (side > 0 ? Math.PI / 2 : 0), side });
|
|
12583
|
-
}
|
|
12584
|
-
}
|
|
12585
|
-
return legs;
|
|
12586
|
-
}
|
|
12587
|
-
function createCrabScene(scene) {
|
|
12588
|
-
const shellMaterial = new MeshPhysicalMaterial({
|
|
12589
|
-
color: 16096779,
|
|
12590
|
-
roughness: 0.34,
|
|
12591
|
-
metalness: 0.04,
|
|
12592
|
-
clearcoat: 0.78,
|
|
12593
|
-
clearcoatRoughness: 0.18,
|
|
12594
|
-
emissive: new Color(0),
|
|
12595
|
-
emissiveIntensity: 0
|
|
12596
|
-
});
|
|
12597
|
-
const accentMaterial = new MeshPhysicalMaterial({
|
|
12598
|
-
color: 16486972,
|
|
12599
|
-
roughness: 0.42,
|
|
12600
|
-
metalness: 0.02,
|
|
12601
|
-
clearcoat: 0.52,
|
|
12602
|
-
clearcoatRoughness: 0.28
|
|
12603
|
-
});
|
|
12604
|
-
const legMaterial = new MeshPhysicalMaterial({
|
|
12605
|
-
color: 14251782,
|
|
12606
|
-
roughness: 0.48,
|
|
12607
|
-
clearcoat: 0.35,
|
|
12608
|
-
clearcoatRoughness: 0.35
|
|
12609
|
-
});
|
|
12610
|
-
const eyeMaterial = new MeshPhysicalMaterial({
|
|
12611
|
-
color: 16776171,
|
|
12612
|
-
roughness: 0.22,
|
|
12613
|
-
clearcoat: 0.8,
|
|
12614
|
-
clearcoatRoughness: 0.12
|
|
12615
|
-
});
|
|
12616
|
-
const root = new Group();
|
|
12617
|
-
root.rotation.x = -0.12;
|
|
12618
|
-
root.rotation.y = -0.08;
|
|
12619
|
-
root.scale.setScalar(1.08);
|
|
12620
|
-
scene.add(root);
|
|
12621
|
-
const shadow = new Mesh(
|
|
12622
|
-
new CircleGeometry(1.65, 40),
|
|
12623
|
-
new MeshBasicMaterial({ color: 1120295, transparent: true, opacity: 0.16, depthWrite: false })
|
|
12624
|
-
);
|
|
12625
|
-
shadow.position.set(0, -1.33, -0.65);
|
|
12626
|
-
shadow.scale.set(1.4, 0.34, 1);
|
|
12627
|
-
root.add(shadow);
|
|
12628
|
-
const body = new Mesh(new SphereGeometry(1, 36, 24), shellMaterial);
|
|
12629
|
-
body.position.set(0, 0.02, 0);
|
|
12630
|
-
body.scale.set(1.58, 0.92, 0.68);
|
|
12631
|
-
root.add(body);
|
|
12632
|
-
const lowerShell = new Mesh(new SphereGeometry(0.92, 28, 20), accentMaterial);
|
|
12633
|
-
lowerShell.position.set(0, -0.48, 0.22);
|
|
12634
|
-
lowerShell.scale.set(1.28, 0.42, 0.56);
|
|
12635
|
-
root.add(lowerShell);
|
|
12636
|
-
const dominantClaw = addClaw(root, -1, shellMaterial, accentMaterial);
|
|
12637
|
-
addClaw(root, 1, shellMaterial, accentMaterial);
|
|
12638
|
-
const eyes = addEyes(root, shellMaterial, eyeMaterial);
|
|
12639
|
-
const legs = addLegs(root, legMaterial);
|
|
12640
|
-
scene.add(new AmbientLight(16775149, 1.65));
|
|
12641
|
-
scene.add(new HemisphereLight(16775149, 1515571, 2.15));
|
|
12642
|
-
const keyLight = new DirectionalLight(16777215, 3.6);
|
|
12643
|
-
keyLight.position.set(3.5, 4.5, 6);
|
|
12644
|
-
scene.add(keyLight);
|
|
12645
|
-
const fillLight = new DirectionalLight(16498468, 1.35);
|
|
12646
|
-
fillLight.position.set(-4, 1.5, 4);
|
|
12647
|
-
scene.add(fillLight);
|
|
12648
|
-
const rimLight = new PointLight(16096779, 1.8, 12, 2);
|
|
12649
|
-
rimLight.position.set(0, 1.8, 4.5);
|
|
12650
|
-
scene.add(rimLight);
|
|
12651
|
-
return { bodyMaterial: shellMaterial, dominantClaw, eyes, legs, rimLight, root };
|
|
12652
|
-
}
|
|
12653
|
-
function moodColor(mood) {
|
|
12654
|
-
switch (mood) {
|
|
12655
|
-
case "active":
|
|
12656
|
-
return 2282478;
|
|
12657
|
-
case "attention":
|
|
12658
|
-
return 15680580;
|
|
12659
|
-
case "idle":
|
|
12660
|
-
return 16096779;
|
|
12661
|
-
case "sleeping":
|
|
12662
|
-
return 9741240;
|
|
12663
|
-
}
|
|
12664
|
-
}
|
|
12665
|
-
function isDisposableMesh(object2) {
|
|
12666
|
-
return object2 instanceof Mesh;
|
|
12667
|
-
}
|
|
12668
|
-
function disposeScene(scene) {
|
|
12669
|
-
const materials = /* @__PURE__ */ new Set();
|
|
12670
|
-
scene.traverse((object2) => {
|
|
12671
|
-
if (!isDisposableMesh(object2)) return;
|
|
12672
|
-
object2.geometry.dispose();
|
|
12673
|
-
const material = object2.material;
|
|
12674
|
-
if (Array.isArray(material)) {
|
|
12675
|
-
for (const item of material) materials.add(item);
|
|
12676
|
-
return;
|
|
12677
|
-
}
|
|
12678
|
-
materials.add(material);
|
|
12679
|
-
});
|
|
12680
|
-
for (const material of materials) material.dispose();
|
|
12681
|
-
}
|
|
12682
|
-
function InspectorPetCrab3D({
|
|
12683
|
-
mood,
|
|
12684
|
-
moving,
|
|
12685
|
-
reduceMotion
|
|
12686
|
-
}) {
|
|
12687
|
-
const canvasRef = reactExports.useRef(null);
|
|
12688
|
-
const moodRef = reactExports.useRef(mood);
|
|
12689
|
-
const movingRef = reactExports.useRef(moving);
|
|
12690
|
-
const reduceMotionRef = reactExports.useRef(reduceMotion);
|
|
12691
|
-
const [renderFailed, setRenderFailed] = reactExports.useState(false);
|
|
12692
|
-
reactExports.useEffect(() => {
|
|
12693
|
-
moodRef.current = mood;
|
|
12694
|
-
}, [mood]);
|
|
12695
|
-
reactExports.useEffect(() => {
|
|
12696
|
-
movingRef.current = moving;
|
|
12697
|
-
}, [moving]);
|
|
12698
|
-
reactExports.useEffect(() => {
|
|
12699
|
-
reduceMotionRef.current = reduceMotion;
|
|
12700
|
-
}, [reduceMotion]);
|
|
12701
|
-
reactExports.useEffect(() => {
|
|
12702
|
-
const canvas = canvasRef.current;
|
|
12703
|
-
if (canvas === null) return void 0;
|
|
12704
|
-
let renderer;
|
|
12705
|
-
try {
|
|
12706
|
-
renderer = new WebGLRenderer({
|
|
12707
|
-
alpha: true,
|
|
12708
|
-
antialias: true,
|
|
12709
|
-
canvas,
|
|
12710
|
-
powerPreference: "low-power",
|
|
12711
|
-
preserveDrawingBuffer: true
|
|
12712
|
-
});
|
|
12713
|
-
} catch {
|
|
12714
|
-
setRenderFailed(true);
|
|
12715
|
-
return void 0;
|
|
12716
|
-
}
|
|
12717
|
-
renderer.setClearColor(0, 0);
|
|
12718
|
-
renderer.outputColorSpace = SRGBColorSpace;
|
|
12719
|
-
renderer.toneMapping = ACESFilmicToneMapping;
|
|
12720
|
-
renderer.toneMappingExposure = 1.18;
|
|
12721
|
-
const scene = new Scene();
|
|
12722
|
-
const camera = new OrthographicCamera(-3.65, 3.65, 3.65, -3.65, 0.1, 20);
|
|
12723
|
-
camera.position.set(0, 0.05, 8);
|
|
12724
|
-
camera.lookAt(0, 0, 0);
|
|
12725
|
-
const parts = createCrabScene(scene);
|
|
12726
|
-
const startedAt = window.performance.now();
|
|
12727
|
-
let lastFrameAt = 0;
|
|
12728
|
-
const renderFrame = (timestamp) => {
|
|
12729
|
-
if (timestamp - lastFrameAt < 32) return;
|
|
12730
|
-
lastFrameAt = timestamp;
|
|
12731
|
-
const elapsed = (timestamp - startedAt) / 1e3;
|
|
12732
|
-
const motionAllowed = !reduceMotionRef.current;
|
|
12733
|
-
const gait = movingRef.current ? 1 : moodRef.current === "active" ? 0.42 : 0;
|
|
12734
|
-
const idleMotion = motionAllowed ? Math.sin(elapsed * 0.85) : 0;
|
|
12735
|
-
const stepMotion = motionAllowed ? Math.sin(elapsed * 3.4) : 0;
|
|
12736
|
-
const clawGrip = motionAllowed ? dominantClawGrip(elapsed) : 0;
|
|
12737
|
-
parts.root.position.y = idleMotion * 0.035 + Math.abs(stepMotion) * 0.055 * gait;
|
|
12738
|
-
parts.root.rotation.y = -0.08 + idleMotion * 0.055;
|
|
12739
|
-
parts.root.rotation.z = stepMotion * 0.028 * gait;
|
|
12740
|
-
parts.dominantClaw.group.rotation.z = -clawGrip * 0.035;
|
|
12741
|
-
for (const pincer of parts.dominantClaw.pincers) {
|
|
12742
|
-
pincer.mesh.position.y = pincer.restY - pincer.direction * parts.dominantClaw.scale * 0.16 * clawGrip;
|
|
12743
|
-
pincer.mesh.rotation.z = pincer.restRotationZ * (1 - clawGrip * 0.72);
|
|
12744
|
-
}
|
|
12745
|
-
for (const leg of parts.legs) {
|
|
12746
|
-
leg.group.rotation.z = motionAllowed && gait > 0 ? Math.sin(elapsed * 4.25 + leg.phase) * 0.2 * leg.side * gait : 0;
|
|
12747
|
-
leg.group.rotation.x = motionAllowed && gait > 0 ? stepMotion * 0.045 * gait : 0;
|
|
12748
|
-
}
|
|
12749
|
-
for (const eye of parts.eyes) {
|
|
12750
|
-
const gaze = motionAllowed ? Math.sin(elapsed * 0.72 + eye.phase) : 0;
|
|
12751
|
-
const lift = motionAllowed ? Math.cos(elapsed * 0.9 + eye.phase) : 0;
|
|
12752
|
-
eye.group.rotation.z = gaze * 0.075;
|
|
12753
|
-
eye.group.rotation.x = lift * 0.025;
|
|
12754
|
-
eye.pupil.position.set(
|
|
12755
|
-
eye.pupilRest.x + gaze * 0.055,
|
|
12756
|
-
eye.pupilRest.y + lift * 0.025,
|
|
12757
|
-
eye.pupilRest.z
|
|
12758
|
-
);
|
|
12759
|
-
}
|
|
12760
|
-
const color = moodColor(moodRef.current);
|
|
12761
|
-
parts.rimLight.color.setHex(color);
|
|
12762
|
-
parts.rimLight.intensity = moodRef.current === "attention" ? 3.2 : 1.8;
|
|
12763
|
-
parts.bodyMaterial.emissive.setHex(color);
|
|
12764
|
-
parts.bodyMaterial.emissiveIntensity = moodRef.current === "active" ? 0.12 : 0.035;
|
|
12765
|
-
renderer.render(scene, camera);
|
|
12766
|
-
};
|
|
12767
|
-
const resize = () => {
|
|
12768
|
-
const width = Math.max(canvas.clientWidth, 1);
|
|
12769
|
-
const height = Math.max(canvas.clientHeight, 1);
|
|
12770
|
-
renderer.setDrawingBufferSize(width, height, Math.min(window.devicePixelRatio, 2));
|
|
12771
|
-
renderer.render(scene, camera);
|
|
12772
|
-
};
|
|
12773
|
-
const resizeObserver = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(resize);
|
|
12774
|
-
if (resizeObserver === null) {
|
|
12775
|
-
window.addEventListener("resize", resize);
|
|
12776
|
-
} else {
|
|
12777
|
-
resizeObserver.observe(canvas);
|
|
12778
|
-
}
|
|
12779
|
-
resize();
|
|
12780
|
-
const handleContextLost = (event) => {
|
|
12781
|
-
event.preventDefault();
|
|
12782
|
-
setRenderFailed(true);
|
|
12783
|
-
};
|
|
12784
|
-
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
12785
|
-
renderer.setAnimationLoop(renderFrame);
|
|
12786
|
-
return () => {
|
|
12787
|
-
renderer.setAnimationLoop(null);
|
|
12788
|
-
if (resizeObserver === null) {
|
|
12789
|
-
window.removeEventListener("resize", resize);
|
|
12790
|
-
} else {
|
|
12791
|
-
resizeObserver.disconnect();
|
|
12792
|
-
}
|
|
12793
|
-
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
12794
|
-
disposeScene(scene);
|
|
12795
|
-
renderer.dispose();
|
|
12796
|
-
};
|
|
12797
|
-
}, []);
|
|
12798
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "relative flex size-24 items-center justify-center", "aria-hidden": "true", children: [
|
|
12190
|
+
] }),
|
|
12799
12191
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12800
|
-
|
|
12192
|
+
ExecutionConfirmationDialog,
|
|
12801
12193
|
{
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12194
|
+
pending: pendingExecution,
|
|
12195
|
+
busy: confirmationBusy,
|
|
12196
|
+
onOpenChange: (confirmationOpen) => {
|
|
12197
|
+
if (!confirmationOpen && !confirmationBusy) setPendingExecution(null);
|
|
12198
|
+
},
|
|
12199
|
+
onConfirm: confirmPendingExecution
|
|
12805
12200
|
}
|
|
12806
|
-
)
|
|
12807
|
-
renderFailed && /* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: "size-22 text-amber-500 drop-shadow-[0_0_18px_rgba(245,158,11,0.28)]" })
|
|
12201
|
+
)
|
|
12808
12202
|
] });
|
|
12809
12203
|
}
|
|
12810
|
-
const INSPECTOR_PET_ROAMING_STORAGE_KEY = "agent-inspector.pet.roaming";
|
|
12811
|
-
const INSPECTOR_PET_MIN_PAUSE_MS = 11e3;
|
|
12812
|
-
const INSPECTOR_PET_PAUSE_WINDOW_MS = 9e3;
|
|
12813
|
-
const INSPECTOR_PET_SCUTTLE_MS = 7200;
|
|
12814
|
-
const INSPECTOR_PET_PANEL_DISMISS_MS = 6e3;
|
|
12815
|
-
const INSPECTOR_PET_REACTION_MS = 760;
|
|
12816
|
-
const INSPECTOR_PET_DRAG_THRESHOLD = 4;
|
|
12817
|
-
const INSPECTOR_PET_TOP_LAYER_Z_INDEX = 2147483647;
|
|
12818
|
-
function readViewport() {
|
|
12819
|
-
if (typeof window === "undefined") return { width: 1280, height: 720, scale: 1 };
|
|
12820
|
-
const rawScale = window.getComputedStyle(document.documentElement).getPropertyValue("--inspector-ui-scale");
|
|
12821
|
-
const parsedScale = Number.parseFloat(rawScale);
|
|
12822
|
-
const scale = Number.isFinite(parsedScale) && parsedScale > 0 ? parsedScale : 1;
|
|
12823
|
-
return {
|
|
12824
|
-
width: Math.max(window.innerWidth, INSPECTOR_PET_MARGIN * 2),
|
|
12825
|
-
height: Math.max(window.innerHeight, INSPECTOR_PET_MARGIN * 2),
|
|
12826
|
-
scale
|
|
12827
|
-
};
|
|
12828
|
-
}
|
|
12829
|
-
function readStoredRoaming() {
|
|
12830
|
-
if (typeof window === "undefined") return true;
|
|
12831
|
-
try {
|
|
12832
|
-
return window.localStorage.getItem(INSPECTOR_PET_ROAMING_STORAGE_KEY) !== "0";
|
|
12833
|
-
} catch {
|
|
12834
|
-
return true;
|
|
12835
|
-
}
|
|
12836
|
-
}
|
|
12837
|
-
function moodDotClass(mood) {
|
|
12838
|
-
switch (mood) {
|
|
12839
|
-
case "active":
|
|
12840
|
-
return "bg-cyan-400 shadow-[0_0_9px_rgba(34,211,238,0.65)]";
|
|
12841
|
-
case "attention":
|
|
12842
|
-
return "bg-red-500 shadow-[0_0_9px_rgba(239,68,68,0.55)]";
|
|
12843
|
-
case "idle":
|
|
12844
|
-
return "bg-amber-400 shadow-[0_0_8px_rgba(251,191,36,0.45)]";
|
|
12845
|
-
case "sleeping":
|
|
12846
|
-
return "bg-muted-foreground/45";
|
|
12847
|
-
}
|
|
12848
|
-
}
|
|
12849
|
-
function moodMotionClass(mood) {
|
|
12850
|
-
switch (mood) {
|
|
12851
|
-
case "active":
|
|
12852
|
-
return "inspector-pet-active";
|
|
12853
|
-
case "attention":
|
|
12854
|
-
return "inspector-pet-attention";
|
|
12855
|
-
case "idle":
|
|
12856
|
-
return "";
|
|
12857
|
-
case "sleeping":
|
|
12858
|
-
return "inspector-pet-sleeping";
|
|
12859
|
-
}
|
|
12860
|
-
}
|
|
12861
|
-
function InspectorPet({ logs }) {
|
|
12862
|
-
const [portalHost, setPortalHost] = reactExports.useState(null);
|
|
12863
|
-
const [viewport, setViewport] = reactExports.useState(readViewport);
|
|
12864
|
-
const [position, setPosition] = reactExports.useState({
|
|
12865
|
-
x: INSPECTOR_PET_MARGIN,
|
|
12866
|
-
y: INSPECTOR_PET_MARGIN
|
|
12867
|
-
});
|
|
12868
|
-
const [clockMs, setClockMs] = reactExports.useState(() => Date.now());
|
|
12869
|
-
const [scuttling, setScuttling] = reactExports.useState(false);
|
|
12870
|
-
const [panelTick, setPanelTick] = reactExports.useState(0);
|
|
12871
|
-
const [panelVisible, setPanelVisible] = reactExports.useState(false);
|
|
12872
|
-
const [reactionTick, setReactionTick] = reactExports.useState(0);
|
|
12873
|
-
const [reactionVisible, setReactionVisible] = reactExports.useState(false);
|
|
12874
|
-
const [dragging, setDragging] = reactExports.useState(false);
|
|
12875
|
-
const [roaming, setRoaming] = reactExports.useState(readStoredRoaming);
|
|
12876
|
-
const [reduceMotion, setReduceMotion] = reactExports.useState(false);
|
|
12877
|
-
const dragStateRef = reactExports.useRef(null);
|
|
12878
|
-
const dragOccurredRef = reactExports.useRef(false);
|
|
12879
|
-
const status = reactExports.useMemo(() => resolveInspectorPetStatus(logs, clockMs), [clockMs, logs]);
|
|
12880
|
-
const panelPosition = reactExports.useMemo(
|
|
12881
|
-
() => inspectorPetPanelPosition(position, viewport),
|
|
12882
|
-
[position, viewport]
|
|
12883
|
-
);
|
|
12884
|
-
reactExports.useEffect(() => setPortalHost(document.body), []);
|
|
12885
|
-
reactExports.useEffect(() => {
|
|
12886
|
-
const nextViewport = readViewport();
|
|
12887
|
-
setViewport(nextViewport);
|
|
12888
|
-
setPosition(randomInspectorPetEdgePosition(nextViewport, Math.random()));
|
|
12889
|
-
}, []);
|
|
12890
|
-
reactExports.useEffect(() => {
|
|
12891
|
-
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
12892
|
-
const handleChange = (event) => setReduceMotion(event.matches);
|
|
12893
|
-
setReduceMotion(mediaQuery.matches);
|
|
12894
|
-
mediaQuery.addEventListener("change", handleChange);
|
|
12895
|
-
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
12896
|
-
}, []);
|
|
12897
|
-
reactExports.useEffect(() => {
|
|
12898
|
-
const intervalId = window.setInterval(() => setClockMs(Date.now()), 15e3);
|
|
12899
|
-
return () => window.clearInterval(intervalId);
|
|
12900
|
-
}, []);
|
|
12901
|
-
reactExports.useEffect(() => {
|
|
12902
|
-
try {
|
|
12903
|
-
window.localStorage.setItem(INSPECTOR_PET_ROAMING_STORAGE_KEY, roaming ? "1" : "0");
|
|
12904
|
-
} catch {
|
|
12905
|
-
}
|
|
12906
|
-
}, [roaming]);
|
|
12907
|
-
reactExports.useEffect(() => {
|
|
12908
|
-
if (!roaming || dragging || reduceMotion) return void 0;
|
|
12909
|
-
let pauseTimeoutId = null;
|
|
12910
|
-
let scuttleTimeoutId = null;
|
|
12911
|
-
const scheduleScuttle = () => {
|
|
12912
|
-
const delay = INSPECTOR_PET_MIN_PAUSE_MS + Math.random() * INSPECTOR_PET_PAUSE_WINDOW_MS;
|
|
12913
|
-
pauseTimeoutId = window.setTimeout(() => {
|
|
12914
|
-
setScuttling(true);
|
|
12915
|
-
setPosition(
|
|
12916
|
-
(current) => nextInspectorPetWalkingPosition(current, viewport, Math.random(), Math.random())
|
|
12917
|
-
);
|
|
12918
|
-
scuttleTimeoutId = window.setTimeout(() => {
|
|
12919
|
-
setScuttling(false);
|
|
12920
|
-
scheduleScuttle();
|
|
12921
|
-
}, INSPECTOR_PET_SCUTTLE_MS);
|
|
12922
|
-
}, delay);
|
|
12923
|
-
};
|
|
12924
|
-
scheduleScuttle();
|
|
12925
|
-
return () => {
|
|
12926
|
-
if (pauseTimeoutId !== null) window.clearTimeout(pauseTimeoutId);
|
|
12927
|
-
if (scuttleTimeoutId !== null) window.clearTimeout(scuttleTimeoutId);
|
|
12928
|
-
};
|
|
12929
|
-
}, [dragging, reduceMotion, roaming, viewport]);
|
|
12930
|
-
reactExports.useEffect(() => {
|
|
12931
|
-
const handleResize = () => {
|
|
12932
|
-
const nextViewport = readViewport();
|
|
12933
|
-
setScuttling(false);
|
|
12934
|
-
setViewport(nextViewport);
|
|
12935
|
-
setPosition((current) => snapInspectorPetToEdge(current, nextViewport));
|
|
12936
|
-
};
|
|
12937
|
-
window.addEventListener("resize", handleResize);
|
|
12938
|
-
return () => window.removeEventListener("resize", handleResize);
|
|
12939
|
-
}, []);
|
|
12940
|
-
reactExports.useEffect(() => {
|
|
12941
|
-
if (!panelVisible) return void 0;
|
|
12942
|
-
const timeoutId = window.setTimeout(
|
|
12943
|
-
() => setPanelVisible(false),
|
|
12944
|
-
INSPECTOR_PET_PANEL_DISMISS_MS
|
|
12945
|
-
);
|
|
12946
|
-
return () => window.clearTimeout(timeoutId);
|
|
12947
|
-
}, [panelTick, panelVisible]);
|
|
12948
|
-
reactExports.useEffect(() => {
|
|
12949
|
-
if (!reactionVisible) return void 0;
|
|
12950
|
-
const timeoutId = window.setTimeout(() => setReactionVisible(false), INSPECTOR_PET_REACTION_MS);
|
|
12951
|
-
return () => window.clearTimeout(timeoutId);
|
|
12952
|
-
}, [reactionTick, reactionVisible]);
|
|
12953
|
-
const handlePet = reactExports.useCallback(() => {
|
|
12954
|
-
if (dragOccurredRef.current) {
|
|
12955
|
-
dragOccurredRef.current = false;
|
|
12956
|
-
return;
|
|
12957
|
-
}
|
|
12958
|
-
setClockMs(Date.now());
|
|
12959
|
-
setPanelTick((current) => current + 1);
|
|
12960
|
-
setPanelVisible(true);
|
|
12961
|
-
setReactionTick((current) => current + 1);
|
|
12962
|
-
setReactionVisible(true);
|
|
12963
|
-
}, []);
|
|
12964
|
-
const handlePointerDown = reactExports.useCallback((event) => {
|
|
12965
|
-
const rect = event.currentTarget.getBoundingClientRect();
|
|
12966
|
-
dragOccurredRef.current = false;
|
|
12967
|
-
dragStateRef.current = {
|
|
12968
|
-
pointerId: event.pointerId,
|
|
12969
|
-
offsetX: event.clientX - rect.left,
|
|
12970
|
-
offsetY: event.clientY - rect.top,
|
|
12971
|
-
startX: event.clientX,
|
|
12972
|
-
startY: event.clientY,
|
|
12973
|
-
moved: false
|
|
12974
|
-
};
|
|
12975
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
12976
|
-
setScuttling(false);
|
|
12977
|
-
setPanelVisible(false);
|
|
12978
|
-
setDragging(true);
|
|
12979
|
-
}, []);
|
|
12980
|
-
const handlePointerMove = reactExports.useCallback(
|
|
12981
|
-
(event) => {
|
|
12982
|
-
const dragState = dragStateRef.current;
|
|
12983
|
-
if (dragState === null || dragState.pointerId !== event.pointerId) return;
|
|
12984
|
-
const moved = dragState.moved || Math.abs(event.clientX - dragState.startX) >= INSPECTOR_PET_DRAG_THRESHOLD || Math.abs(event.clientY - dragState.startY) >= INSPECTOR_PET_DRAG_THRESHOLD;
|
|
12985
|
-
dragState.moved = moved;
|
|
12986
|
-
dragOccurredRef.current = moved;
|
|
12987
|
-
setPosition(
|
|
12988
|
-
clampInspectorPetPosition(
|
|
12989
|
-
{
|
|
12990
|
-
x: event.clientX - dragState.offsetX,
|
|
12991
|
-
y: event.clientY - dragState.offsetY
|
|
12992
|
-
},
|
|
12993
|
-
viewport
|
|
12994
|
-
)
|
|
12995
|
-
);
|
|
12996
|
-
},
|
|
12997
|
-
[viewport]
|
|
12998
|
-
);
|
|
12999
|
-
const handlePointerUp = reactExports.useCallback(
|
|
13000
|
-
(event) => {
|
|
13001
|
-
const dragState = dragStateRef.current;
|
|
13002
|
-
if (dragState === null || dragState.pointerId !== event.pointerId) return;
|
|
13003
|
-
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
13004
|
-
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
13005
|
-
}
|
|
13006
|
-
dragOccurredRef.current = dragState.moved;
|
|
13007
|
-
dragStateRef.current = null;
|
|
13008
|
-
setDragging(false);
|
|
13009
|
-
setPosition((current) => snapInspectorPetToEdge(current, viewport));
|
|
13010
|
-
},
|
|
13011
|
-
[viewport]
|
|
13012
|
-
);
|
|
13013
|
-
const handlePointerCancel = reactExports.useCallback((event) => {
|
|
13014
|
-
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
13015
|
-
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
13016
|
-
}
|
|
13017
|
-
dragStateRef.current = null;
|
|
13018
|
-
dragOccurredRef.current = false;
|
|
13019
|
-
setDragging(false);
|
|
13020
|
-
}, []);
|
|
13021
|
-
const handleToggleRoaming = reactExports.useCallback(() => {
|
|
13022
|
-
setScuttling(false);
|
|
13023
|
-
setRoaming((current) => !current);
|
|
13024
|
-
}, []);
|
|
13025
|
-
const petStyle = reactExports.useMemo(
|
|
13026
|
-
() => ({
|
|
13027
|
-
transform: `translate3d(${String(position.x)}px, ${String(position.y)}px, 0) scale(${dragging ? "1.04" : "1"})`,
|
|
13028
|
-
transition: dragging ? "none" : scuttling ? `transform ${String(INSPECTOR_PET_SCUTTLE_MS)}ms cubic-bezier(0.22, 0.72, 0.32, 1)` : "transform 900ms cubic-bezier(0.22, 0.72, 0.32, 1)",
|
|
13029
|
-
touchAction: "none"
|
|
13030
|
-
}),
|
|
13031
|
-
[dragging, position.x, position.y, scuttling]
|
|
13032
|
-
);
|
|
13033
|
-
const panelStyle = reactExports.useMemo(
|
|
13034
|
-
() => ({ left: panelPosition.x, top: panelPosition.y }),
|
|
13035
|
-
[panelPosition.x, panelPosition.y]
|
|
13036
|
-
);
|
|
13037
|
-
const roamingLabel = roaming ? "Pause pet roaming" : "Resume pet roaming";
|
|
13038
|
-
if (portalHost === null) return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {});
|
|
13039
|
-
return reactDomExports.createPortal(
|
|
13040
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13041
|
-
"div",
|
|
13042
|
-
{
|
|
13043
|
-
className: "pointer-events-none fixed inset-0 isolate",
|
|
13044
|
-
style: { zIndex: INSPECTOR_PET_TOP_LAYER_Z_INDEX },
|
|
13045
|
-
"data-inspector-pet-layer": "true",
|
|
13046
|
-
children: [
|
|
13047
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13048
|
-
"button",
|
|
13049
|
-
{
|
|
13050
|
-
type: "button",
|
|
13051
|
-
className: cn(
|
|
13052
|
-
"pointer-events-auto fixed left-0 top-0 z-10 flex size-28 items-center justify-center bg-transparent text-foreground outline-none transition-[filter,opacity] duration-200 hover:opacity-95 hover:drop-shadow-[0_0_28px_rgba(245,158,11,0.32)] focus-visible:drop-shadow-[0_0_14px_rgba(251,191,36,0.72)]",
|
|
13053
|
-
dragging ? "cursor-grabbing" : "cursor-grab"
|
|
13054
|
-
),
|
|
13055
|
-
style: petStyle,
|
|
13056
|
-
"data-pet-mood": status.mood,
|
|
13057
|
-
"data-pet-moving": scuttling ? "true" : "false",
|
|
13058
|
-
onClick: handlePet,
|
|
13059
|
-
onPointerDown: handlePointerDown,
|
|
13060
|
-
onPointerMove: handlePointerMove,
|
|
13061
|
-
onPointerUp: handlePointerUp,
|
|
13062
|
-
onPointerCancel: handlePointerCancel,
|
|
13063
|
-
"aria-label": `Inspector pet: ${status.label}`,
|
|
13064
|
-
title: status.label,
|
|
13065
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13066
|
-
"span",
|
|
13067
|
-
{
|
|
13068
|
-
className: cn(
|
|
13069
|
-
"relative z-10 flex size-24 items-center justify-center",
|
|
13070
|
-
reactionVisible && "inspector-pet-patted"
|
|
13071
|
-
),
|
|
13072
|
-
"aria-hidden": "true",
|
|
13073
|
-
children: [
|
|
13074
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13075
|
-
"span",
|
|
13076
|
-
{
|
|
13077
|
-
className: cn(
|
|
13078
|
-
"relative flex size-24 items-center justify-center",
|
|
13079
|
-
moodMotionClass(status.mood)
|
|
13080
|
-
),
|
|
13081
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "relative flex size-24 items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13082
|
-
InspectorPetCrab3D,
|
|
13083
|
-
{
|
|
13084
|
-
mood: status.mood,
|
|
13085
|
-
moving: scuttling && !dragging,
|
|
13086
|
-
reduceMotion
|
|
13087
|
-
}
|
|
13088
|
-
) })
|
|
13089
|
-
}
|
|
13090
|
-
),
|
|
13091
|
-
reactionVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13092
|
-
Heart,
|
|
13093
|
-
{
|
|
13094
|
-
className: "inspector-pet-heart absolute -right-2 -top-3 size-5 fill-amber-400 text-amber-400"
|
|
13095
|
-
},
|
|
13096
|
-
reactionTick
|
|
13097
|
-
)
|
|
13098
|
-
]
|
|
13099
|
-
}
|
|
13100
|
-
)
|
|
13101
|
-
}
|
|
13102
|
-
),
|
|
13103
|
-
panelVisible && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13104
|
-
"div",
|
|
13105
|
-
{
|
|
13106
|
-
className: "pointer-events-auto fixed z-20 w-48 rounded-md border border-border/80 bg-popover/95 px-3 py-2 text-popover-foreground shadow-[0_14px_34px_rgba(0,0,0,0.28)] backdrop-blur",
|
|
13107
|
-
style: panelStyle,
|
|
13108
|
-
role: "status",
|
|
13109
|
-
"aria-live": "polite",
|
|
13110
|
-
children: [
|
|
13111
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
13112
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("size-2 shrink-0 rounded-full", moodDotClass(status.mood)) }),
|
|
13113
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate text-xs font-medium", children: status.label }),
|
|
13114
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13115
|
-
"button",
|
|
13116
|
-
{
|
|
13117
|
-
type: "button",
|
|
13118
|
-
className: "inline-flex size-6 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
13119
|
-
onClick: handleToggleRoaming,
|
|
13120
|
-
"aria-label": roamingLabel,
|
|
13121
|
-
title: roamingLabel,
|
|
13122
|
-
children: roaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(Pause, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Play, { className: "size-3.5" })
|
|
13123
|
-
}
|
|
13124
|
-
)
|
|
13125
|
-
] }),
|
|
13126
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex items-center justify-between gap-3 font-mono text-[10px] text-muted-foreground", children: [
|
|
13127
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
13128
|
-
String(status.capturedCount),
|
|
13129
|
-
" captured"
|
|
13130
|
-
] }),
|
|
13131
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: status.pendingCount > 0 ? `${String(status.pendingCount)} active` : scuttling ? "Scuttling" : roaming ? "Resting" : "Paused" })
|
|
13132
|
-
] })
|
|
13133
|
-
]
|
|
13134
|
-
}
|
|
13135
|
-
)
|
|
13136
|
-
]
|
|
13137
|
-
}
|
|
13138
|
-
),
|
|
13139
|
-
portalHost
|
|
13140
|
-
);
|
|
13141
|
-
}
|
|
13142
12204
|
const DEFAULT_QUESTION = "Analyze the current Inspector session. What looks abnormal, slow, or likely to hang?";
|
|
13143
12205
|
function providerSupportsPiAgent(provider) {
|
|
13144
12206
|
return provider.openaiResponsesBaseUrl !== void 0 || provider.openaiBaseUrl !== void 0 || provider.anthropicBaseUrl !== void 0;
|
|
@@ -13196,7 +12258,10 @@ function PiAgentPanel({ currentSessionId, logCount }) {
|
|
|
13196
12258
|
};
|
|
13197
12259
|
void fetch("/api/pi-agent", {
|
|
13198
12260
|
method: "POST",
|
|
13199
|
-
headers: {
|
|
12261
|
+
headers: {
|
|
12262
|
+
"content-type": "application/json",
|
|
12263
|
+
"x-agent-inspector-csrf": "1"
|
|
12264
|
+
},
|
|
13200
12265
|
body: JSON.stringify(body)
|
|
13201
12266
|
}).then(async (response) => {
|
|
13202
12267
|
const raw = await response.text();
|
|
@@ -13264,44 +12329,421 @@ function PiAgentPanel({ currentSessionId, logCount }) {
|
|
|
13264
12329
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13265
12330
|
"button",
|
|
13266
12331
|
{
|
|
13267
|
-
type: "button",
|
|
13268
|
-
onClick: askPiAgent,
|
|
13269
|
-
disabled: !canAsk,
|
|
13270
|
-
className: "mt-2 inline-flex h-8 w-full items-center justify-center gap-2 rounded-md bg-cyan-400/12 px-3 text-xs font-medium text-cyan-100 shadow-[inset_0_0_0_1px_rgba(103,232,249,0.18)] transition-colors hover:bg-cyan-400/18 disabled:cursor-not-allowed disabled:opacity-50",
|
|
13271
|
-
children: [
|
|
13272
|
-
loading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "size-3.5" }),
|
|
13273
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: loading ? "Thinking..." : "Ask Pi" })
|
|
13274
|
-
]
|
|
12332
|
+
type: "button",
|
|
12333
|
+
onClick: askPiAgent,
|
|
12334
|
+
disabled: !canAsk,
|
|
12335
|
+
className: "mt-2 inline-flex h-8 w-full items-center justify-center gap-2 rounded-md bg-cyan-400/12 px-3 text-xs font-medium text-cyan-100 shadow-[inset_0_0_0_1px_rgba(103,232,249,0.18)] transition-colors hover:bg-cyan-400/18 disabled:cursor-not-allowed disabled:opacity-50",
|
|
12336
|
+
children: [
|
|
12337
|
+
loading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "size-3.5" }),
|
|
12338
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: loading ? "Thinking..." : "Ask Pi" })
|
|
12339
|
+
]
|
|
12340
|
+
}
|
|
12341
|
+
),
|
|
12342
|
+
piProviders.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-[11px] leading-5 text-muted-foreground", children: "Configure a Provider with Responses, Chat, or Anthropic URL to enable Pi Agent." }),
|
|
12343
|
+
status !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 break-words font-mono text-[10px] text-cyan-100/70", children: status }),
|
|
12344
|
+
answer !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 max-h-64 overflow-y-auto whitespace-pre-wrap rounded-md bg-black/25 p-3 text-xs leading-5 text-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.05)]", children: answer }),
|
|
12345
|
+
logCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-[11px] leading-5 text-muted-foreground", children: "No logs are visible in this scope yet; Pi Agent can still answer Provider setup questions." })
|
|
12346
|
+
] });
|
|
12347
|
+
}
|
|
12348
|
+
function computeCacheTrends(groups) {
|
|
12349
|
+
const result = /* @__PURE__ */ new Map();
|
|
12350
|
+
for (const group of groups) {
|
|
12351
|
+
const logs = group.logs;
|
|
12352
|
+
for (let i = 1; i < logs.length; i++) {
|
|
12353
|
+
const prev = logs[i - 1];
|
|
12354
|
+
const curr = logs[i];
|
|
12355
|
+
if (prev === void 0 || curr === void 0) continue;
|
|
12356
|
+
result.set(curr.id, {
|
|
12357
|
+
creation: compareField(prev.cacheCreationInputTokens, curr.cacheCreationInputTokens),
|
|
12358
|
+
read: compareField(prev.cacheReadInputTokens, curr.cacheReadInputTokens)
|
|
12359
|
+
});
|
|
12360
|
+
}
|
|
12361
|
+
}
|
|
12362
|
+
return result;
|
|
12363
|
+
}
|
|
12364
|
+
function compareField(previous, current) {
|
|
12365
|
+
if (current === null) return null;
|
|
12366
|
+
if (previous === null) return null;
|
|
12367
|
+
if (current > previous) return { direction: "up", delta: current - previous };
|
|
12368
|
+
if (current < previous) return { direction: "down", delta: previous - current };
|
|
12369
|
+
return null;
|
|
12370
|
+
}
|
|
12371
|
+
function formatLastSuccess(lastSuccessAt) {
|
|
12372
|
+
if (lastSuccessAt === null) return null;
|
|
12373
|
+
return new Date(lastSuccessAt).toLocaleTimeString([], {
|
|
12374
|
+
hour: "2-digit",
|
|
12375
|
+
minute: "2-digit",
|
|
12376
|
+
second: "2-digit"
|
|
12377
|
+
});
|
|
12378
|
+
}
|
|
12379
|
+
function buildDescription(state, message, hasLogs) {
|
|
12380
|
+
const lastSuccess = formatLastSuccess(state.lastSuccessAt);
|
|
12381
|
+
const retry = state.retryCount > 0 ? ` Retry ${state.retryCount.toString()}.` : "";
|
|
12382
|
+
const retained = hasLogs ? " Captured logs remain visible." : "";
|
|
12383
|
+
const lastUpdate = lastSuccess === null ? "" : ` Last update ${lastSuccess}.`;
|
|
12384
|
+
return `${message}${lastUpdate}${retry}${retained}`;
|
|
12385
|
+
}
|
|
12386
|
+
function presentationForStatus(status, state, hasLogs) {
|
|
12387
|
+
switch (status) {
|
|
12388
|
+
case "connecting":
|
|
12389
|
+
return {
|
|
12390
|
+
label: "Connecting",
|
|
12391
|
+
description: buildDescription(state, "Waiting for the first live update.", hasLogs),
|
|
12392
|
+
toneClass: "border-cyan-400/20 bg-cyan-500/8 text-cyan-100",
|
|
12393
|
+
dotClass: "bg-cyan-300 animate-pulse motion-reduce:animate-none",
|
|
12394
|
+
canRetry: false,
|
|
12395
|
+
canStop: false
|
|
12396
|
+
};
|
|
12397
|
+
case "live":
|
|
12398
|
+
return {
|
|
12399
|
+
label: "Live",
|
|
12400
|
+
description: buildDescription(state, "Live updates are current.", hasLogs),
|
|
12401
|
+
toneClass: "border-emerald-400/20 bg-emerald-500/8 text-emerald-100",
|
|
12402
|
+
dotClass: "bg-emerald-300",
|
|
12403
|
+
canRetry: false,
|
|
12404
|
+
canStop: false
|
|
12405
|
+
};
|
|
12406
|
+
case "reconnecting":
|
|
12407
|
+
return {
|
|
12408
|
+
label: "Reconnecting",
|
|
12409
|
+
description: buildDescription(state, "Live updates were interrupted.", hasLogs),
|
|
12410
|
+
toneClass: "border-amber-400/20 bg-amber-500/8 text-amber-100",
|
|
12411
|
+
dotClass: "bg-amber-300 animate-pulse motion-reduce:animate-none",
|
|
12412
|
+
canRetry: true,
|
|
12413
|
+
canStop: true
|
|
12414
|
+
};
|
|
12415
|
+
case "stale":
|
|
12416
|
+
return {
|
|
12417
|
+
label: "Stale data",
|
|
12418
|
+
description: buildDescription(state, "Live updates have not resumed.", hasLogs),
|
|
12419
|
+
toneClass: "border-orange-400/25 bg-orange-500/10 text-orange-100",
|
|
12420
|
+
dotClass: "bg-orange-300",
|
|
12421
|
+
canRetry: true,
|
|
12422
|
+
canStop: true
|
|
12423
|
+
};
|
|
12424
|
+
case "offline":
|
|
12425
|
+
return {
|
|
12426
|
+
label: "Offline",
|
|
12427
|
+
description: buildDescription(
|
|
12428
|
+
state,
|
|
12429
|
+
state.errorMessage ?? "Live updates are paused.",
|
|
12430
|
+
hasLogs
|
|
12431
|
+
),
|
|
12432
|
+
toneClass: "border-slate-400/20 bg-slate-500/10 text-slate-200",
|
|
12433
|
+
dotClass: "bg-slate-400",
|
|
12434
|
+
canRetry: true,
|
|
12435
|
+
canStop: false
|
|
12436
|
+
};
|
|
12437
|
+
case "error":
|
|
12438
|
+
return {
|
|
12439
|
+
label: "Connection error",
|
|
12440
|
+
description: buildDescription(
|
|
12441
|
+
state,
|
|
12442
|
+
state.errorMessage ?? "The live stream reported a recoverable error.",
|
|
12443
|
+
hasLogs
|
|
12444
|
+
),
|
|
12445
|
+
toneClass: "border-red-400/25 bg-red-500/10 text-red-100",
|
|
12446
|
+
dotClass: "bg-red-300",
|
|
12447
|
+
canRetry: true,
|
|
12448
|
+
canStop: true
|
|
12449
|
+
};
|
|
12450
|
+
}
|
|
12451
|
+
}
|
|
12452
|
+
function LiveConnectionBadge({ state }) {
|
|
12453
|
+
const presentation = presentationForStatus(state.status, state, false);
|
|
12454
|
+
const lastSuccess = formatLastSuccess(state.lastSuccessAt);
|
|
12455
|
+
const retryLabel = state.retryCount > 0 ? `Retry ${state.retryCount.toString()}` : null;
|
|
12456
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12457
|
+
"span",
|
|
12458
|
+
{
|
|
12459
|
+
role: "status",
|
|
12460
|
+
"aria-label": presentation.description,
|
|
12461
|
+
"data-connection-state": state.status,
|
|
12462
|
+
className: cn(
|
|
12463
|
+
"inline-flex h-7 max-w-full items-center gap-1.5 rounded-full border px-2.5 text-xs font-medium",
|
|
12464
|
+
presentation.toneClass
|
|
12465
|
+
),
|
|
12466
|
+
children: [
|
|
12467
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("size-1.5 shrink-0 rounded-full", presentation.dotClass) }),
|
|
12468
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0", children: presentation.label }),
|
|
12469
|
+
retryLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "hidden truncate text-current/70 sm:inline", children: retryLabel }),
|
|
12470
|
+
lastSuccess !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden truncate font-mono text-[10px] text-current/65 md:inline", children: [
|
|
12471
|
+
"Last ",
|
|
12472
|
+
lastSuccess
|
|
12473
|
+
] })
|
|
12474
|
+
]
|
|
12475
|
+
}
|
|
12476
|
+
);
|
|
12477
|
+
}
|
|
12478
|
+
function LiveConnectionStatus({
|
|
12479
|
+
state,
|
|
12480
|
+
hasLogs,
|
|
12481
|
+
onRetry,
|
|
12482
|
+
onStop
|
|
12483
|
+
}) {
|
|
12484
|
+
const presentation = presentationForStatus(state.status, state, hasLogs);
|
|
12485
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12486
|
+
"div",
|
|
12487
|
+
{
|
|
12488
|
+
role: "status",
|
|
12489
|
+
"aria-live": "polite",
|
|
12490
|
+
"data-connection-state": state.status,
|
|
12491
|
+
className: cn(
|
|
12492
|
+
"mt-2 flex flex-wrap items-center gap-x-3 gap-y-2 rounded-md border px-3 py-2 text-xs",
|
|
12493
|
+
presentation.toneClass
|
|
12494
|
+
),
|
|
12495
|
+
children: [
|
|
12496
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
12497
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("size-2 shrink-0 rounded-full", presentation.dotClass) }),
|
|
12498
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 font-semibold", children: presentation.label }),
|
|
12499
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 text-current/75", children: presentation.description })
|
|
12500
|
+
] }),
|
|
12501
|
+
(presentation.canRetry || presentation.canStop) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
12502
|
+
presentation.canRetry && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12503
|
+
"button",
|
|
12504
|
+
{
|
|
12505
|
+
type: "button",
|
|
12506
|
+
onClick: onRetry,
|
|
12507
|
+
className: "inline-flex h-7 items-center gap-1 rounded-md bg-black/15 px-2 font-medium transition-colors hover:bg-black/25 focus-visible:ring-1 focus-visible:ring-current focus-visible:outline-none",
|
|
12508
|
+
children: [
|
|
12509
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3" }),
|
|
12510
|
+
"Retry now"
|
|
12511
|
+
]
|
|
12512
|
+
}
|
|
12513
|
+
),
|
|
12514
|
+
presentation.canStop && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12515
|
+
"button",
|
|
12516
|
+
{
|
|
12517
|
+
type: "button",
|
|
12518
|
+
onClick: onStop,
|
|
12519
|
+
className: "inline-flex h-7 items-center gap-1 rounded-md px-2 text-current/70 transition-colors hover:bg-black/15 hover:text-current focus-visible:ring-1 focus-visible:ring-current focus-visible:outline-none",
|
|
12520
|
+
children: [
|
|
12521
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleStop, { className: "size-3" }),
|
|
12522
|
+
"Stop retrying"
|
|
12523
|
+
]
|
|
12524
|
+
}
|
|
12525
|
+
)
|
|
12526
|
+
] })
|
|
12527
|
+
]
|
|
12528
|
+
}
|
|
12529
|
+
);
|
|
12530
|
+
}
|
|
12531
|
+
function ApplicationBar({
|
|
12532
|
+
liveConnection,
|
|
12533
|
+
alertsAction,
|
|
12534
|
+
settingsAction
|
|
12535
|
+
}) {
|
|
12536
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12537
|
+
"header",
|
|
12538
|
+
{
|
|
12539
|
+
"data-application-bar": "true",
|
|
12540
|
+
className: "border-border/70 bg-background/95 sticky top-0 z-50 shrink-0 border-b px-3 py-2 shadow-[0_10px_30px_rgba(0,0,0,0.14)] backdrop-blur lg:px-4",
|
|
12541
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 gap-y-2 sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]", children: [
|
|
12542
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12543
|
+
"a",
|
|
12544
|
+
{
|
|
12545
|
+
href: "/",
|
|
12546
|
+
"aria-label": "Agent Inspector home",
|
|
12547
|
+
className: "flex min-w-0 items-center gap-2 rounded-md focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
12548
|
+
children: [
|
|
12549
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: "size-7 shrink-0 text-amber-500" }),
|
|
12550
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0", children: [
|
|
12551
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block truncate text-sm font-bold leading-4", children: "Agent Inspector" }),
|
|
12552
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "hidden truncate text-[10px] font-medium text-muted-foreground md:block", children: "Local First. Evidence First." })
|
|
12553
|
+
] }),
|
|
12554
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 font-mono text-[10px] text-muted-foreground lg:inline", children: [
|
|
12555
|
+
"v",
|
|
12556
|
+
packageJson.version
|
|
12557
|
+
] })
|
|
12558
|
+
]
|
|
12559
|
+
}
|
|
12560
|
+
),
|
|
12561
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "order-3 col-span-2 flex min-w-0 justify-start sm:order-2 sm:col-span-1 sm:justify-center", children: liveConnection === void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12562
|
+
"span",
|
|
12563
|
+
{
|
|
12564
|
+
"data-connection-state": "stored",
|
|
12565
|
+
className: "border-border/70 bg-muted/50 inline-flex h-7 max-w-full items-center gap-1.5 rounded-full border px-2.5 text-xs font-medium text-muted-foreground",
|
|
12566
|
+
children: [
|
|
12567
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-1.5 shrink-0 rounded-full bg-slate-400" }),
|
|
12568
|
+
"Stored session"
|
|
12569
|
+
]
|
|
12570
|
+
}
|
|
12571
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(LiveConnectionBadge, { state: liveConnection }) }),
|
|
12572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12573
|
+
"nav",
|
|
12574
|
+
{
|
|
12575
|
+
"aria-label": "Application actions",
|
|
12576
|
+
className: "order-2 flex shrink-0 items-center justify-end gap-1 sm:order-3",
|
|
12577
|
+
children: [
|
|
12578
|
+
alertsAction,
|
|
12579
|
+
settingsAction
|
|
12580
|
+
]
|
|
12581
|
+
}
|
|
12582
|
+
)
|
|
12583
|
+
] })
|
|
12584
|
+
}
|
|
12585
|
+
);
|
|
12586
|
+
}
|
|
12587
|
+
function formatDurationSeconds(ms) {
|
|
12588
|
+
return `${Math.max(0, Math.ceil(ms / 1e3)).toString()}s`;
|
|
12589
|
+
}
|
|
12590
|
+
function SessionLoadProgressBar({
|
|
12591
|
+
progress
|
|
12592
|
+
}) {
|
|
12593
|
+
const elapsedRatio = Math.min(1, progress.elapsedMs / progress.timeoutMs);
|
|
12594
|
+
const percent = Math.max(4, Math.round(elapsedRatio * 100));
|
|
12595
|
+
const remainingMs = Math.max(0, progress.timeoutMs - progress.elapsedMs);
|
|
12596
|
+
const nearTimeout = elapsedRatio >= 0.75;
|
|
12597
|
+
const details = [
|
|
12598
|
+
progress.loadedLogs > 0 ? `${progress.loadedLogs.toString()} logs` : null,
|
|
12599
|
+
progress.loadedPages > 0 ? `${progress.loadedPages.toString()} page${progress.loadedPages === 1 ? "" : "s"}` : null,
|
|
12600
|
+
`${formatDurationSeconds(remainingMs)} before timeout`
|
|
12601
|
+
].filter((item) => item !== null);
|
|
12602
|
+
const valueText = `${progress.label}: ${details.join(", ")}`;
|
|
12603
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 space-y-1 px-1 pb-1", children: [
|
|
12604
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center justify-between gap-3 font-mono text-[10px] text-muted-foreground", children: [
|
|
12605
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 truncate", children: progress.label }),
|
|
12606
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("shrink-0 tabular-nums", nearTimeout && "text-amber-300"), children: details.join(" / ") })
|
|
12607
|
+
] }),
|
|
12608
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12609
|
+
"div",
|
|
12610
|
+
{
|
|
12611
|
+
role: "progressbar",
|
|
12612
|
+
"aria-label": progress.label,
|
|
12613
|
+
"aria-valuemin": 0,
|
|
12614
|
+
"aria-valuemax": progress.timeoutMs,
|
|
12615
|
+
"aria-valuenow": Math.min(progress.elapsedMs, progress.timeoutMs),
|
|
12616
|
+
"aria-valuetext": valueText,
|
|
12617
|
+
className: "h-1.5 overflow-hidden rounded-full bg-white/[0.06]",
|
|
12618
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12619
|
+
"div",
|
|
12620
|
+
{
|
|
12621
|
+
className: cn(
|
|
12622
|
+
"h-full rounded-full transition-all duration-300 motion-reduce:transition-none",
|
|
12623
|
+
nearTimeout ? "bg-amber-300/80" : "bg-cyan-300/70"
|
|
12624
|
+
),
|
|
12625
|
+
style: { width: `${percent.toString()}%` }
|
|
12626
|
+
}
|
|
12627
|
+
)
|
|
13275
12628
|
}
|
|
13276
|
-
)
|
|
13277
|
-
piProviders.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-[11px] leading-5 text-muted-foreground", children: "Configure a Provider with Responses, Chat, or Anthropic URL to enable Pi Agent." }),
|
|
13278
|
-
status !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 break-words font-mono text-[10px] text-cyan-100/70", children: status }),
|
|
13279
|
-
answer !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 max-h-64 overflow-y-auto whitespace-pre-wrap rounded-md bg-black/25 p-3 text-xs leading-5 text-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.05)]", children: answer }),
|
|
13280
|
-
logCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-[11px] leading-5 text-muted-foreground", children: "No logs are visible in this scope yet; Pi Agent can still answer Provider setup questions." })
|
|
12629
|
+
)
|
|
13281
12630
|
] });
|
|
13282
12631
|
}
|
|
13283
|
-
function
|
|
13284
|
-
|
|
13285
|
-
|
|
13286
|
-
|
|
13287
|
-
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
12632
|
+
function preferredScrollBehavior(reducedMotion) {
|
|
12633
|
+
return reducedMotion ? "auto" : "smooth";
|
|
12634
|
+
}
|
|
12635
|
+
function browserPrefersReducedMotion() {
|
|
12636
|
+
if (typeof window === "undefined") return false;
|
|
12637
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
12638
|
+
}
|
|
12639
|
+
function createInitialLiveConnectionState() {
|
|
12640
|
+
return {
|
|
12641
|
+
status: "connecting",
|
|
12642
|
+
lastSuccessAt: null,
|
|
12643
|
+
retryCount: 0,
|
|
12644
|
+
errorMessage: null
|
|
12645
|
+
};
|
|
12646
|
+
}
|
|
12647
|
+
function reduceLiveConnectionState(state, event) {
|
|
12648
|
+
switch (event.type) {
|
|
12649
|
+
case "connect-requested":
|
|
12650
|
+
return {
|
|
12651
|
+
...state,
|
|
12652
|
+
status: state.lastSuccessAt === null ? "connecting" : state.status === "stale" ? "stale" : "reconnecting",
|
|
12653
|
+
errorMessage: null
|
|
12654
|
+
};
|
|
12655
|
+
case "message-received":
|
|
12656
|
+
return {
|
|
12657
|
+
status: "live",
|
|
12658
|
+
lastSuccessAt: event.at,
|
|
12659
|
+
retryCount: 0,
|
|
12660
|
+
errorMessage: null
|
|
12661
|
+
};
|
|
12662
|
+
case "connection-lost": {
|
|
12663
|
+
const retryCount = state.retryCount + 1;
|
|
12664
|
+
if (!event.online) {
|
|
12665
|
+
return {
|
|
12666
|
+
...state,
|
|
12667
|
+
status: "offline",
|
|
12668
|
+
retryCount,
|
|
12669
|
+
errorMessage: "Browser is offline."
|
|
12670
|
+
};
|
|
12671
|
+
}
|
|
12672
|
+
return {
|
|
12673
|
+
...state,
|
|
12674
|
+
status: state.lastSuccessAt === null ? "error" : "reconnecting",
|
|
12675
|
+
retryCount,
|
|
12676
|
+
errorMessage: event.message
|
|
12677
|
+
};
|
|
13295
12678
|
}
|
|
12679
|
+
case "stale-timeout":
|
|
12680
|
+
if (state.lastSuccessAt === null || state.status === "live" || state.status === "offline") {
|
|
12681
|
+
return state;
|
|
12682
|
+
}
|
|
12683
|
+
return { ...state, status: "stale" };
|
|
12684
|
+
case "browser-offline":
|
|
12685
|
+
return {
|
|
12686
|
+
...state,
|
|
12687
|
+
status: "offline",
|
|
12688
|
+
errorMessage: "Browser is offline."
|
|
12689
|
+
};
|
|
12690
|
+
case "stop-retrying":
|
|
12691
|
+
return {
|
|
12692
|
+
...state,
|
|
12693
|
+
status: "offline",
|
|
12694
|
+
errorMessage: "Automatic live updates are paused."
|
|
12695
|
+
};
|
|
12696
|
+
case "recoverable-error":
|
|
12697
|
+
return {
|
|
12698
|
+
...state,
|
|
12699
|
+
status: "error",
|
|
12700
|
+
errorMessage: event.message
|
|
12701
|
+
};
|
|
13296
12702
|
}
|
|
13297
|
-
return result;
|
|
13298
12703
|
}
|
|
13299
|
-
function
|
|
13300
|
-
if (
|
|
13301
|
-
|
|
13302
|
-
|
|
13303
|
-
|
|
13304
|
-
|
|
12704
|
+
function resolveLiveEmptyState(state) {
|
|
12705
|
+
if (state === void 0 || state.status === "live") return "empty";
|
|
12706
|
+
return state.status;
|
|
12707
|
+
}
|
|
12708
|
+
function getLiveEmptyStateCopy(state) {
|
|
12709
|
+
switch (state) {
|
|
12710
|
+
case "connecting":
|
|
12711
|
+
return {
|
|
12712
|
+
title: "Connecting to the live stream...",
|
|
12713
|
+
description: "Waiting for the first successful initialization before checking for logs.",
|
|
12714
|
+
showConnectionCommands: false
|
|
12715
|
+
};
|
|
12716
|
+
case "empty":
|
|
12717
|
+
return {
|
|
12718
|
+
title: "No logs captured yet.",
|
|
12719
|
+
description: "Connect an AI coding tool to capture its first request.",
|
|
12720
|
+
showConnectionCommands: true
|
|
12721
|
+
};
|
|
12722
|
+
case "reconnecting":
|
|
12723
|
+
return {
|
|
12724
|
+
title: "Reconnecting to live updates...",
|
|
12725
|
+
description: "The stream was interrupted. Agent Inspector is retrying automatically.",
|
|
12726
|
+
showConnectionCommands: false
|
|
12727
|
+
};
|
|
12728
|
+
case "stale":
|
|
12729
|
+
return {
|
|
12730
|
+
title: "Live data is stale.",
|
|
12731
|
+
description: "No logs are hidden; retry the connection to resume live updates.",
|
|
12732
|
+
showConnectionCommands: false
|
|
12733
|
+
};
|
|
12734
|
+
case "offline":
|
|
12735
|
+
return {
|
|
12736
|
+
title: "Live updates are offline.",
|
|
12737
|
+
description: "Check the browser and Inspector connection, then retry.",
|
|
12738
|
+
showConnectionCommands: false
|
|
12739
|
+
};
|
|
12740
|
+
case "error":
|
|
12741
|
+
return {
|
|
12742
|
+
title: "Live updates could not initialize.",
|
|
12743
|
+
description: "The error is recoverable. Retry without reloading the page.",
|
|
12744
|
+
showConnectionCommands: false
|
|
12745
|
+
};
|
|
12746
|
+
}
|
|
13305
12747
|
}
|
|
13306
12748
|
const COLLAPSED_CLIENTS_STORAGE_KEY = "agent-inspector.hierarchy.collapsedClients";
|
|
13307
12749
|
const COLLAPSED_PROCESSES_STORAGE_KEY = "agent-inspector.hierarchy.collapsedProcesses";
|
|
@@ -13782,6 +13224,61 @@ function ProcessGroupSection({
|
|
|
13782
13224
|
)) })
|
|
13783
13225
|
] });
|
|
13784
13226
|
}
|
|
13227
|
+
const RAW_EXPORT_DIALOG_CLASS_NAME = "w-[calc(100%-1rem)] border-warning/30 bg-popover text-popover-foreground sm:max-w-lg";
|
|
13228
|
+
const RAW_EXPORT_RISK_ITEMS = [
|
|
13229
|
+
{
|
|
13230
|
+
label: "Headers",
|
|
13231
|
+
detail: "request and response headers, including authorization or cookie values"
|
|
13232
|
+
},
|
|
13233
|
+
{
|
|
13234
|
+
label: "Prompts",
|
|
13235
|
+
detail: "system instructions, user prompts, model responses, and conversation history"
|
|
13236
|
+
},
|
|
13237
|
+
{
|
|
13238
|
+
label: "Source content",
|
|
13239
|
+
detail: "source code, file contents, tool inputs, and tool output"
|
|
13240
|
+
},
|
|
13241
|
+
{
|
|
13242
|
+
label: "Secrets",
|
|
13243
|
+
detail: "API keys, access tokens, credentials, and other sensitive values"
|
|
13244
|
+
}
|
|
13245
|
+
];
|
|
13246
|
+
function RawExportWarning({
|
|
13247
|
+
onCancel,
|
|
13248
|
+
onExportRedacted,
|
|
13249
|
+
onConfirmRaw
|
|
13250
|
+
}) {
|
|
13251
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
13252
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
|
|
13253
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Export unredacted logs?" }),
|
|
13254
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "Raw exports bypass Agent Inspector redaction and may expose sensitive captured data." })
|
|
13255
|
+
] }),
|
|
13256
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13257
|
+
"div",
|
|
13258
|
+
{
|
|
13259
|
+
role: "alert",
|
|
13260
|
+
className: "rounded-md border border-warning/35 bg-warning/10 px-3 py-3 text-sm text-foreground",
|
|
13261
|
+
children: [
|
|
13262
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium", children: "The raw archive may include:" }),
|
|
13263
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "mt-2 list-disc space-y-1 pl-5 text-xs leading-relaxed text-muted-foreground", children: RAW_EXPORT_RISK_ITEMS.map((item) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
13264
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-semibold text-foreground", children: [
|
|
13265
|
+
item.label,
|
|
13266
|
+
":"
|
|
13267
|
+
] }),
|
|
13268
|
+
" ",
|
|
13269
|
+
item.detail
|
|
13270
|
+
] }, item.label)) }),
|
|
13271
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 text-xs leading-relaxed text-muted-foreground", children: "Only continue if you trust where this file will be stored and everyone it may be shared with." })
|
|
13272
|
+
]
|
|
13273
|
+
}
|
|
13274
|
+
),
|
|
13275
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [
|
|
13276
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: onCancel, children: "Cancel" }),
|
|
13277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: onExportRedacted, children: "Export redacted instead" }),
|
|
13278
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "destructive", size: "sm", onClick: onConfirmRaw, children: "Export raw data" })
|
|
13279
|
+
] })
|
|
13280
|
+
] });
|
|
13281
|
+
}
|
|
13785
13282
|
const NAV_ATTR = "data-nav-id";
|
|
13786
13283
|
const NAV_ACTION_ATTR = "data-nav-action";
|
|
13787
13284
|
function findNavItems(container) {
|
|
@@ -15209,7 +14706,7 @@ function LogPaginationButton({
|
|
|
15209
14706
|
type: "button",
|
|
15210
14707
|
onClick,
|
|
15211
14708
|
disabled,
|
|
15212
|
-
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45",
|
|
14709
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-45",
|
|
15213
14710
|
title,
|
|
15214
14711
|
children: [
|
|
15215
14712
|
icon,
|
|
@@ -15218,36 +14715,6 @@ function LogPaginationButton({
|
|
|
15218
14715
|
}
|
|
15219
14716
|
);
|
|
15220
14717
|
}
|
|
15221
|
-
function formatDurationSeconds(ms) {
|
|
15222
|
-
return `${Math.max(0, Math.ceil(ms / 1e3)).toString()}s`;
|
|
15223
|
-
}
|
|
15224
|
-
function SessionLoadProgressBar({ progress }) {
|
|
15225
|
-
const elapsedRatio = Math.min(1, progress.elapsedMs / progress.timeoutMs);
|
|
15226
|
-
const percent = Math.max(4, Math.round(elapsedRatio * 100));
|
|
15227
|
-
const remainingMs = Math.max(0, progress.timeoutMs - progress.elapsedMs);
|
|
15228
|
-
const nearTimeout = elapsedRatio >= 0.75;
|
|
15229
|
-
const details = [
|
|
15230
|
-
progress.loadedLogs > 0 ? `${progress.loadedLogs.toString()} logs` : null,
|
|
15231
|
-
progress.loadedPages > 0 ? `${progress.loadedPages.toString()} page${progress.loadedPages === 1 ? "" : "s"}` : null,
|
|
15232
|
-
`${formatDurationSeconds(remainingMs)} before timeout`
|
|
15233
|
-
].filter((item) => item !== null);
|
|
15234
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 space-y-1 px-1 pb-1", children: [
|
|
15235
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center justify-between gap-3 font-mono text-[10px] text-muted-foreground", children: [
|
|
15236
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 truncate", children: progress.label }),
|
|
15237
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("shrink-0 tabular-nums", nearTimeout && "text-amber-300"), children: details.join(" / ") })
|
|
15238
|
-
] }),
|
|
15239
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1.5 overflow-hidden rounded-full bg-white/[0.06]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15240
|
-
"div",
|
|
15241
|
-
{
|
|
15242
|
-
className: cn(
|
|
15243
|
-
"h-full rounded-full transition-all duration-300",
|
|
15244
|
-
nearTimeout ? "bg-amber-300/80" : "bg-cyan-300/70"
|
|
15245
|
-
),
|
|
15246
|
-
style: { width: `${percent.toString()}%` }
|
|
15247
|
-
}
|
|
15248
|
-
) })
|
|
15249
|
-
] });
|
|
15250
|
-
}
|
|
15251
14718
|
function LogPaginationBar({
|
|
15252
14719
|
logs,
|
|
15253
14720
|
pagination,
|
|
@@ -15256,16 +14723,19 @@ function LogPaginationBar({
|
|
|
15256
14723
|
if (pagination === void 0) return null;
|
|
15257
14724
|
const disabled = pagination.isLoading;
|
|
15258
14725
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
15259
|
-
"
|
|
14726
|
+
"nav",
|
|
15260
14727
|
{
|
|
14728
|
+
"aria-label": "Session log pagination",
|
|
15261
14729
|
className: cn(
|
|
15262
14730
|
"flex min-h-9 flex-col gap-2 px-1 py-1 sm:flex-row sm:items-center",
|
|
15263
14731
|
embedded ? "border-t border-white/10 pt-2" : "border border-border bg-card shadow-sm mb-3 rounded-[8px] px-2"
|
|
15264
14732
|
),
|
|
15265
14733
|
children: [
|
|
15266
14734
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full min-w-0 px-1 font-mono text-[11px] text-muted-foreground sm:flex-1", children: [
|
|
15267
|
-
|
|
15268
|
-
|
|
14735
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", children: [
|
|
14736
|
+
formatPaginationStatus({ logs, pagination }),
|
|
14737
|
+
pagination.isLoading && logs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2", children: "Loading..." })
|
|
14738
|
+
] }),
|
|
15269
14739
|
pagination.loadProgress !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(SessionLoadProgressBar, { progress: pagination.loadProgress })
|
|
15270
14740
|
] }),
|
|
15271
14741
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center gap-1 overflow-x-auto sm:w-auto", children: [
|
|
@@ -15363,7 +14833,10 @@ function highlightLogTarget(target) {
|
|
|
15363
14833
|
function focusLogTarget(logId) {
|
|
15364
14834
|
const target = document.getElementById(`log-${String(logId)}`);
|
|
15365
14835
|
if (!(target instanceof HTMLElement)) return false;
|
|
15366
|
-
target.scrollIntoView({
|
|
14836
|
+
target.scrollIntoView({
|
|
14837
|
+
block: "center",
|
|
14838
|
+
behavior: preferredScrollBehavior(browserPrefersReducedMotion())
|
|
14839
|
+
});
|
|
15367
14840
|
target.focus({ preventScroll: true });
|
|
15368
14841
|
highlightLogTarget(target);
|
|
15369
14842
|
return true;
|
|
@@ -15390,14 +14863,14 @@ function CopyableCommand({ command }) {
|
|
|
15390
14863
|
setTimeout(() => setCopied(false), 2e3);
|
|
15391
14864
|
});
|
|
15392
14865
|
}, [command]);
|
|
15393
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
15394
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className:
|
|
14866
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { "data-command-example": "true", className: COPYABLE_COMMAND_CONTAINER_CLASS_NAME, children: [
|
|
14867
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: COPYABLE_COMMAND_TEXT_CLASS_NAME, children: command }),
|
|
15395
14868
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15396
14869
|
"button",
|
|
15397
14870
|
{
|
|
15398
14871
|
type: "button",
|
|
15399
14872
|
onClick: handleCopy,
|
|
15400
|
-
className: "shrink-0 cursor-pointer text-muted-foreground transition-colors hover:text-foreground",
|
|
14873
|
+
className: "shrink-0 cursor-pointer rounded-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
15401
14874
|
"aria-label": "Copy command",
|
|
15402
14875
|
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" })
|
|
15403
14876
|
}
|
|
@@ -15429,46 +14902,6 @@ function SidebarMetric({ label, value }) {
|
|
|
15429
14902
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-0.5 truncate font-mono text-[10px] uppercase tracking-[0.12em] text-white/35", children: label })
|
|
15430
14903
|
] });
|
|
15431
14904
|
}
|
|
15432
|
-
const CRAB_VARIANT_COLORS = [
|
|
15433
|
-
"text-amber-500",
|
|
15434
|
-
"text-rose-500",
|
|
15435
|
-
"text-sky-500",
|
|
15436
|
-
"text-emerald-500",
|
|
15437
|
-
"text-violet-500",
|
|
15438
|
-
"text-orange-500",
|
|
15439
|
-
"text-cyan-500",
|
|
15440
|
-
"text-pink-500",
|
|
15441
|
-
"text-lime-500",
|
|
15442
|
-
"text-blue-500",
|
|
15443
|
-
"text-yellow-500",
|
|
15444
|
-
"text-fuchsia-500"
|
|
15445
|
-
];
|
|
15446
|
-
function CrabFamily({
|
|
15447
|
-
compact,
|
|
15448
|
-
entrancePhase
|
|
15449
|
-
}) {
|
|
15450
|
-
if (compact) {
|
|
15451
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: "size-14 text-amber-500" });
|
|
15452
|
-
}
|
|
15453
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex shrink-0 items-end gap-1 group cursor-default", "aria-hidden": "true", children: [
|
|
15454
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: "size-10 text-amber-500 transition-all duration-300 group-hover:scale-125 group-hover:-translate-y-1.5" }),
|
|
15455
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "hidden items-end gap-0.5 sm:flex", children: crabVariants.map((Crab, i) => {
|
|
15456
|
-
const color = CRAB_VARIANT_COLORS[i] ?? "text-amber-500";
|
|
15457
|
-
const entranceClass = entrancePhase === "hidden" ? "opacity-0 scale-0" : entrancePhase === "playing" ? "animate-crab-piano-pop" : "";
|
|
15458
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15459
|
-
Crab,
|
|
15460
|
-
{
|
|
15461
|
-
className: `size-5 ${color} transition-all duration-300 ease-out group-hover:scale-125 group-hover:-translate-y-1 ${entranceClass}`,
|
|
15462
|
-
style: {
|
|
15463
|
-
transitionDelay: `${i * 50}ms`,
|
|
15464
|
-
...entrancePhase === "playing" ? { animationDelay: `${i * 400}ms` } : {}
|
|
15465
|
-
}
|
|
15466
|
-
},
|
|
15467
|
-
i
|
|
15468
|
-
);
|
|
15469
|
-
}) })
|
|
15470
|
-
] });
|
|
15471
|
-
}
|
|
15472
14905
|
function ThemeModeToggle() {
|
|
15473
14906
|
const { themeMode, setThemeMode } = useThemeMode();
|
|
15474
14907
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -15484,7 +14917,7 @@ function ThemeModeToggle() {
|
|
|
15484
14917
|
type: "button",
|
|
15485
14918
|
onClick: () => setThemeMode("light"),
|
|
15486
14919
|
className: cn(
|
|
15487
|
-
"inline-flex size-7 items-center justify-center rounded-[6px] text-muted-foreground transition-colors hover:text-foreground",
|
|
14920
|
+
"inline-flex size-7 items-center justify-center rounded-[6px] text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
15488
14921
|
themeMode === "light" && "bg-background text-foreground shadow-sm"
|
|
15489
14922
|
),
|
|
15490
14923
|
"aria-label": "Use light mode",
|
|
@@ -15499,7 +14932,7 @@ function ThemeModeToggle() {
|
|
|
15499
14932
|
type: "button",
|
|
15500
14933
|
onClick: () => setThemeMode("eye-care"),
|
|
15501
14934
|
className: cn(
|
|
15502
|
-
"inline-flex size-7 items-center justify-center rounded-[6px] text-muted-foreground transition-colors hover:text-foreground",
|
|
14935
|
+
"inline-flex size-7 items-center justify-center rounded-[6px] text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
15503
14936
|
themeMode === "eye-care" && "bg-background text-foreground shadow-sm"
|
|
15504
14937
|
),
|
|
15505
14938
|
"aria-label": "Use eye care mode",
|
|
@@ -15514,7 +14947,7 @@ function ThemeModeToggle() {
|
|
|
15514
14947
|
type: "button",
|
|
15515
14948
|
onClick: () => setThemeMode("dark"),
|
|
15516
14949
|
className: cn(
|
|
15517
|
-
"inline-flex size-7 items-center justify-center rounded-[6px] text-muted-foreground transition-colors hover:text-foreground",
|
|
14950
|
+
"inline-flex size-7 items-center justify-center rounded-[6px] text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
15518
14951
|
themeMode === "dark" && "bg-background text-foreground shadow-sm"
|
|
15519
14952
|
),
|
|
15520
14953
|
"aria-label": "Use dark mode",
|
|
@@ -15583,81 +15016,6 @@ function UiScaleControl({
|
|
|
15583
15016
|
}
|
|
15584
15017
|
);
|
|
15585
15018
|
}
|
|
15586
|
-
function BrandHeader({
|
|
15587
|
-
compact,
|
|
15588
|
-
crabEntrancePhase,
|
|
15589
|
-
currentSessionId,
|
|
15590
|
-
logCount,
|
|
15591
|
-
uiScalePreference,
|
|
15592
|
-
resolvedUiScale,
|
|
15593
|
-
onUiScaleChange
|
|
15594
|
-
}) {
|
|
15595
|
-
if (compact) {
|
|
15596
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.045),0_16px_44px_rgba(0,0,0,0.18)] rounded-[8px] p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
|
|
15597
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-fit items-start gap-3", children: [
|
|
15598
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CrabFamily, { compact: true, entrancePhase: crabEntrancePhase }),
|
|
15599
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-fit", children: [
|
|
15600
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-fit flex-wrap items-baseline gap-x-2 gap-y-0.5", children: [
|
|
15601
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "whitespace-nowrap text-base font-bold", children: "Agent Inspector" }),
|
|
15602
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 font-mono text-[11px] font-semibold text-muted-foreground sm:inline", children: [
|
|
15603
|
-
"v",
|
|
15604
|
-
packageJson.version
|
|
15605
|
-
] })
|
|
15606
|
-
] }),
|
|
15607
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "hidden text-[11px] font-semibold text-muted-foreground sm:block", children: "Local First. Evidence First." })
|
|
15608
|
-
] })
|
|
15609
|
-
] }),
|
|
15610
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
15611
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ThemeModeToggle, {}),
|
|
15612
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15613
|
-
UiScaleControl,
|
|
15614
|
-
{
|
|
15615
|
-
preference: uiScalePreference,
|
|
15616
|
-
resolvedScale: resolvedUiScale,
|
|
15617
|
-
onChange: onUiScaleChange
|
|
15618
|
-
}
|
|
15619
|
-
),
|
|
15620
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertsDialog, {}),
|
|
15621
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(GroupsDialog, {}),
|
|
15622
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AgentLabDialog, { currentSessionId, logCount }),
|
|
15623
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SettingsDialog, {})
|
|
15624
|
-
] })
|
|
15625
|
-
] }) });
|
|
15626
|
-
}
|
|
15627
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-x-4 gap-y-3 pb-6", children: [
|
|
15628
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-10 flex-1", "aria-hidden": "true" }),
|
|
15629
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "flex min-w-fit flex-col items-center gap-2 text-center", children: [
|
|
15630
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex max-w-full flex-wrap items-end justify-center gap-x-2 gap-y-1", children: [
|
|
15631
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CrabFamily, { compact: false, entrancePhase: crabEntrancePhase }),
|
|
15632
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-fit flex-wrap items-baseline justify-center gap-x-2 gap-y-0.5 pl-1", children: [
|
|
15633
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "whitespace-nowrap text-lg font-bold", children: "Agent Inspector" }),
|
|
15634
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "shrink-0 font-mono text-xs font-semibold text-muted-foreground", children: [
|
|
15635
|
-
"v",
|
|
15636
|
-
packageJson.version
|
|
15637
|
-
] })
|
|
15638
|
-
] }),
|
|
15639
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4 shrink-0 text-muted-foreground/70", "aria-hidden": "true" }),
|
|
15640
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(McpLogo, { className: "size-10 shrink-0" })
|
|
15641
|
-
] }),
|
|
15642
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "max-w-full text-sm font-semibold text-muted-foreground", children: "Local First. Evidence First." })
|
|
15643
|
-
] }),
|
|
15644
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 justify-end gap-1", children: [
|
|
15645
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ThemeModeToggle, {}),
|
|
15646
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15647
|
-
UiScaleControl,
|
|
15648
|
-
{
|
|
15649
|
-
preference: uiScalePreference,
|
|
15650
|
-
resolvedScale: resolvedUiScale,
|
|
15651
|
-
onChange: onUiScaleChange
|
|
15652
|
-
}
|
|
15653
|
-
),
|
|
15654
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertsDialog, {}),
|
|
15655
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(GroupsDialog, {}),
|
|
15656
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AgentLabDialog, { currentSessionId, logCount }),
|
|
15657
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SettingsDialog, {})
|
|
15658
|
-
] })
|
|
15659
|
-
] });
|
|
15660
|
-
}
|
|
15661
15019
|
const DETAILS_PANEL_COLLAPSED_STORAGE_KEY = "agent-inspector.detailsPanelCollapsed";
|
|
15662
15020
|
const INSPECTOR_PET_VISIBLE_STORAGE_KEY = "agent-inspector.pet.visible";
|
|
15663
15021
|
function readStoredDetailsPanelCollapsed() {
|
|
@@ -15981,8 +15339,12 @@ function ProxyViewer({
|
|
|
15981
15339
|
slowResponseThresholdSeconds,
|
|
15982
15340
|
timeDisplayFormat,
|
|
15983
15341
|
isLoading = false,
|
|
15342
|
+
liveConnection,
|
|
15343
|
+
onRetryLiveConnection,
|
|
15344
|
+
onStopLiveConnection,
|
|
15984
15345
|
pagination,
|
|
15985
15346
|
sessionLoadProgress,
|
|
15347
|
+
sessionLoadError,
|
|
15986
15348
|
sessionMemberships = [],
|
|
15987
15349
|
hideSessionFilter = false,
|
|
15988
15350
|
pinnedSessionId
|
|
@@ -15992,6 +15354,7 @@ function ProxyViewer({
|
|
|
15992
15354
|
const { uiScalePreference, resolvedUiScale, setUiScalePreference } = useUiScale();
|
|
15993
15355
|
const [exporting, setExporting] = reactExports.useState(null);
|
|
15994
15356
|
const [exportError, setExportError] = reactExports.useState(null);
|
|
15357
|
+
const [rawExportDialogOpen, setRawExportDialogOpen] = reactExports.useState(false);
|
|
15995
15358
|
const [importing, setImporting] = reactExports.useState(false);
|
|
15996
15359
|
const [importStatus, setImportStatus] = reactExports.useState(null);
|
|
15997
15360
|
const [importError, setImportError] = reactExports.useState(null);
|
|
@@ -16002,9 +15365,6 @@ function ProxyViewer({
|
|
|
16002
15365
|
const [petVisible, setPetVisible] = reactExports.useState(true);
|
|
16003
15366
|
const [petVisibilityStorageLoaded, setPetVisibilityStorageLoaded] = reactExports.useState(false);
|
|
16004
15367
|
const [comparePair, setComparePair] = reactExports.useState(null);
|
|
16005
|
-
const [crabEntrancePhase, setCrabEntrancePhase] = reactExports.useState(
|
|
16006
|
-
"hidden"
|
|
16007
|
-
);
|
|
16008
15368
|
const logListRef = reactExports.useRef(null);
|
|
16009
15369
|
const logListWrapperRef = reactExports.useRef(null);
|
|
16010
15370
|
const importInputRef = reactExports.useRef(null);
|
|
@@ -16026,17 +15386,6 @@ function ProxyViewer({
|
|
|
16026
15386
|
},
|
|
16027
15387
|
[]
|
|
16028
15388
|
);
|
|
16029
|
-
reactExports.useEffect(() => {
|
|
16030
|
-
const perCrabDuration = 400;
|
|
16031
|
-
const startDelay = 50;
|
|
16032
|
-
const playingDone = startDelay + crabVariants.length * perCrabDuration;
|
|
16033
|
-
const t1 = setTimeout(() => setCrabEntrancePhase("playing"), startDelay);
|
|
16034
|
-
const t2 = setTimeout(() => setCrabEntrancePhase("done"), playingDone);
|
|
16035
|
-
return () => {
|
|
16036
|
-
clearTimeout(t1);
|
|
16037
|
-
clearTimeout(t2);
|
|
16038
|
-
};
|
|
16039
|
-
}, []);
|
|
16040
15389
|
reactExports.useEffect(() => {
|
|
16041
15390
|
setDetailsPanelCollapsed(readStoredDetailsPanelCollapsed());
|
|
16042
15391
|
setDetailsPanelStorageLoaded(true);
|
|
@@ -16096,6 +15445,24 @@ function ProxyViewer({
|
|
|
16096
15445
|
},
|
|
16097
15446
|
[logs, onNotify]
|
|
16098
15447
|
);
|
|
15448
|
+
const handleExportRequest = reactExports.useCallback(
|
|
15449
|
+
(mode) => {
|
|
15450
|
+
if (exportRequiresConfirmation(mode)) {
|
|
15451
|
+
setRawExportDialogOpen(true);
|
|
15452
|
+
return;
|
|
15453
|
+
}
|
|
15454
|
+
void handleExport(mode);
|
|
15455
|
+
},
|
|
15456
|
+
[handleExport]
|
|
15457
|
+
);
|
|
15458
|
+
const handleExportRedactedInstead = reactExports.useCallback(() => {
|
|
15459
|
+
setRawExportDialogOpen(false);
|
|
15460
|
+
void handleExport("redacted");
|
|
15461
|
+
}, [handleExport]);
|
|
15462
|
+
const handleConfirmRawExport = reactExports.useCallback(() => {
|
|
15463
|
+
setRawExportDialogOpen(false);
|
|
15464
|
+
void handleExport("raw");
|
|
15465
|
+
}, [handleExport]);
|
|
16099
15466
|
const handleImportClick = reactExports.useCallback(() => {
|
|
16100
15467
|
importInputRef.current?.click();
|
|
16101
15468
|
}, []);
|
|
@@ -16207,6 +15574,8 @@ function ProxyViewer({
|
|
|
16207
15574
|
const sessionInputValue = selectedSession === "__all__" ? "" : selectedSession;
|
|
16208
15575
|
const sessionSelectValue = selectedSession === "__all__" || sessions.includes(selectedSession) ? selectedSession : "__typed__";
|
|
16209
15576
|
const activeScopeLabel = hasSessionContext && sessionContextScope !== null ? truncateSessionId(sessionContextScope.label) : selectedSession === "__all__" ? "All sessions" : truncateSessionId(selectedSession);
|
|
15577
|
+
const liveEmptyState = resolveLiveEmptyState(liveConnection);
|
|
15578
|
+
const liveEmptyStateCopy = getLiveEmptyStateCopy(liveEmptyState);
|
|
16210
15579
|
const slateStats = reactExports.useMemo(
|
|
16211
15580
|
() => buildSessionSlateStats({
|
|
16212
15581
|
logs,
|
|
@@ -16239,14 +15608,22 @@ function ProxyViewer({
|
|
|
16239
15608
|
[onSessionChange]
|
|
16240
15609
|
);
|
|
16241
15610
|
const labSessionId = pinnedSessionId !== void 0 ? pinnedSessionId : selectedSession === "__all__" ? null : selectedSession;
|
|
16242
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-background min-h-screen w-full text-foreground lg:h-screen lg:flex lg:flex-col lg:overflow-hidden", children: [
|
|
15611
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-background min-h-screen w-full overflow-x-clip text-foreground lg:h-screen lg:flex lg:flex-col lg:overflow-hidden", children: [
|
|
15612
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15613
|
+
ApplicationBar,
|
|
15614
|
+
{
|
|
15615
|
+
liveConnection,
|
|
15616
|
+
alertsAction: /* @__PURE__ */ jsxRuntimeExports.jsx(AlertsDialog, {}),
|
|
15617
|
+
settingsAction: /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsDialog, {})
|
|
15618
|
+
}
|
|
15619
|
+
),
|
|
16243
15620
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16244
15621
|
"button",
|
|
16245
15622
|
{
|
|
16246
15623
|
type: "button",
|
|
16247
15624
|
onClick: toggleDetailsPanelCollapsed,
|
|
16248
15625
|
className: cn(
|
|
16249
|
-
"group fixed top-1/2 right-3 z-40 inline-flex h-14 w-7 -translate-y-1/2 items-center justify-center rounded-l-md border border-white/[0.08] bg-background/90 text-muted-foreground shadow-[0_12px_34px_rgba(0,0,0,0.26),inset_0_1px_0_rgba(255,255,255,0.06)] backdrop-blur transition-[right,background-color,color,border-color] duration-200 hover:border-white/[0.16] hover:bg-white/[0.07] hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
15626
|
+
"group fixed top-1/2 right-3 z-40 inline-flex h-14 w-7 -translate-y-1/2 items-center justify-center rounded-l-md border border-white/[0.08] bg-background/90 text-muted-foreground shadow-[0_12px_34px_rgba(0,0,0,0.26),inset_0_1px_0_rgba(255,255,255,0.06)] backdrop-blur transition-[right,background-color,color,border-color] duration-200 motion-reduce:transition-none hover:border-white/[0.16] hover:bg-white/[0.07] hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
16250
15627
|
detailsPanelCollapsed ? "right-3" : "lg:right-[calc(21.25rem-0.875rem)] xl:right-[calc(22.5rem-0.875rem)]"
|
|
16251
15628
|
),
|
|
16252
15629
|
"aria-label": detailsPanelCollapsed ? "Show details panel" : "Hide details panel",
|
|
@@ -16257,7 +15634,7 @@ function ProxyViewer({
|
|
|
16257
15634
|
]
|
|
16258
15635
|
}
|
|
16259
15636
|
),
|
|
16260
|
-
petVisibilityStorageLoaded && petVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15637
|
+
petVisibilityStorageLoaded && petVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(LazyFeatureBoundary, { feature: "Inspector Pet", children: /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyInspectorPet, { logs }) }) }),
|
|
16261
15638
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16262
15639
|
"div",
|
|
16263
15640
|
{
|
|
@@ -16267,18 +15644,19 @@ function ProxyViewer({
|
|
|
16267
15644
|
),
|
|
16268
15645
|
children: [
|
|
16269
15646
|
!detailsPanelCollapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "bg-background/95 order-1 border-b border-white/[0.045] lg:order-2 lg:h-full lg:overflow-y-auto lg:border-b-0 lg:border-l lg:border-white/[0.055] inspector-scrollbar", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 p-4", children: [
|
|
16270
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
|
|
16274
|
-
|
|
16275
|
-
|
|
16276
|
-
|
|
16277
|
-
|
|
16278
|
-
|
|
16279
|
-
|
|
16280
|
-
}
|
|
16281
|
-
|
|
15647
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Tools", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
15648
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ThemeModeToggle, {}),
|
|
15649
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15650
|
+
UiScaleControl,
|
|
15651
|
+
{
|
|
15652
|
+
preference: uiScalePreference,
|
|
15653
|
+
resolvedScale: resolvedUiScale,
|
|
15654
|
+
onChange: setUiScalePreference
|
|
15655
|
+
}
|
|
15656
|
+
),
|
|
15657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(GroupsDialog, {}),
|
|
15658
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AgentLabDialog, { currentSessionId: labSessionId, logCount: logs.length })
|
|
15659
|
+
] }) }),
|
|
16282
15660
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(SidebarPanel, { label: "Session", children: [
|
|
16283
15661
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
16284
15662
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarMetric, { label: "Requests", value: logs.length }),
|
|
@@ -16346,7 +15724,7 @@ function ProxyViewer({
|
|
|
16346
15724
|
{
|
|
16347
15725
|
type: "button",
|
|
16348
15726
|
onClick: () => onSessionChange("__all__"),
|
|
16349
|
-
className: "absolute right-1.5 top-1/2 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-white/[0.06] hover:text-foreground",
|
|
15727
|
+
className: "absolute right-1.5 top-1/2 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-white/[0.06] hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
16350
15728
|
"aria-label": "Clear session filter",
|
|
16351
15729
|
title: "Clear session filter",
|
|
16352
15730
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" })
|
|
@@ -16354,7 +15732,14 @@ function ProxyViewer({
|
|
|
16354
15732
|
)
|
|
16355
15733
|
] }),
|
|
16356
15734
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: sessionSelectValue, onValueChange: handleSessionSelectChange, children: [
|
|
16357
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15735
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15736
|
+
SelectTrigger,
|
|
15737
|
+
{
|
|
15738
|
+
"aria-label": "Select a session",
|
|
15739
|
+
className: "bg-black/25 hover:bg-white/[0.045] h-9 w-full border-0 text-xs text-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)]",
|
|
15740
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" })
|
|
15741
|
+
}
|
|
15742
|
+
),
|
|
16358
15743
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
16359
15744
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All sessions" }),
|
|
16360
15745
|
sessionSelectValue === "__typed__" && /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectItem, { value: "__typed__", children: [
|
|
@@ -16366,7 +15751,14 @@ function ProxyViewer({
|
|
|
16366
15751
|
] })
|
|
16367
15752
|
] }),
|
|
16368
15753
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedModel, onValueChange: onModelChange, children: [
|
|
16369
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15754
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15755
|
+
SelectTrigger,
|
|
15756
|
+
{
|
|
15757
|
+
"aria-label": "Select a model",
|
|
15758
|
+
className: "bg-black/25 hover:bg-white/[0.045] h-9 w-full border-0 text-xs text-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)]",
|
|
15759
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All models" })
|
|
15760
|
+
}
|
|
15761
|
+
),
|
|
16370
15762
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
16371
15763
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All models" }),
|
|
16372
15764
|
models.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: m, children: m }, m))
|
|
@@ -16399,7 +15791,7 @@ function ProxyViewer({
|
|
|
16399
15791
|
type: "button",
|
|
16400
15792
|
onClick: handleImportClick,
|
|
16401
15793
|
disabled: importing,
|
|
16402
|
-
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
15794
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
16403
15795
|
title: "Import Agent Inspector export",
|
|
16404
15796
|
children: importing ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Importing..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
16405
15797
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-3.5" }),
|
|
@@ -16413,10 +15805,10 @@ function ProxyViewer({
|
|
|
16413
15805
|
{
|
|
16414
15806
|
type: "button",
|
|
16415
15807
|
onClick: () => {
|
|
16416
|
-
|
|
15808
|
+
handleExportRequest("redacted");
|
|
16417
15809
|
},
|
|
16418
15810
|
disabled: exporting !== null,
|
|
16419
|
-
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
15811
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
16420
15812
|
title: "Export redacted logs as JSON ZIP",
|
|
16421
15813
|
children: exporting === "redacted" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
16422
15814
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3.5" }),
|
|
@@ -16429,10 +15821,10 @@ function ProxyViewer({
|
|
|
16429
15821
|
{
|
|
16430
15822
|
type: "button",
|
|
16431
15823
|
onClick: () => {
|
|
16432
|
-
|
|
15824
|
+
handleExportRequest("raw");
|
|
16433
15825
|
},
|
|
16434
15826
|
disabled: exporting !== null,
|
|
16435
|
-
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
15827
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
16436
15828
|
title: "Export raw logs without redaction",
|
|
16437
15829
|
children: exporting === "raw" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
16438
15830
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FileBraces, { className: "size-3.5" }),
|
|
@@ -16446,10 +15838,18 @@ function ProxyViewer({
|
|
|
16446
15838
|
type: "button",
|
|
16447
15839
|
onClick: handleReloadCurrentSession,
|
|
16448
15840
|
disabled: isLoading,
|
|
16449
|
-
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
15841
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
16450
15842
|
title: "Reload this session from stored logs",
|
|
16451
15843
|
children: [
|
|
16452
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15844
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15845
|
+
RefreshCw,
|
|
15846
|
+
{
|
|
15847
|
+
className: cn(
|
|
15848
|
+
"size-3.5",
|
|
15849
|
+
isLoading && "animate-spin motion-reduce:animate-none"
|
|
15850
|
+
)
|
|
15851
|
+
}
|
|
15852
|
+
),
|
|
16453
15853
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: reloadSessionLabel })
|
|
16454
15854
|
]
|
|
16455
15855
|
}
|
|
@@ -16460,7 +15860,7 @@ function ProxyViewer({
|
|
|
16460
15860
|
type: "button",
|
|
16461
15861
|
onClick: handleClearCurrentView,
|
|
16462
15862
|
disabled: !canClearCurrentView,
|
|
16463
|
-
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
15863
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
16464
15864
|
title: "Clear the current view. Stored logs remain reloadable.",
|
|
16465
15865
|
children: [
|
|
16466
15866
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" }),
|
|
@@ -16474,7 +15874,7 @@ function ProxyViewer({
|
|
|
16474
15874
|
type: "button",
|
|
16475
15875
|
onClick: handleRequestDeleteCurrentView,
|
|
16476
15876
|
disabled: !canDeleteCurrentView || deletingCurrentView,
|
|
16477
|
-
className: "bg-red-500/[0.07] hover:bg-red-500/[0.12] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-red-200 shadow-[inset_0_0_0_1px_rgba(248,113,113,0.14)] transition-colors hover:text-red-100 disabled:cursor-not-allowed disabled:opacity-50",
|
|
15877
|
+
className: "bg-red-500/[0.07] hover:bg-red-500/[0.12] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-red-200 shadow-[inset_0_0_0_1px_rgba(248,113,113,0.14)] transition-colors hover:text-red-100 focus-visible:ring-1 focus-visible:ring-red-300 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
16478
15878
|
title: "Delete persisted history for the selected session.",
|
|
16479
15879
|
children: [
|
|
16480
15880
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" }),
|
|
@@ -16484,15 +15884,50 @@ function ProxyViewer({
|
|
|
16484
15884
|
)
|
|
16485
15885
|
] }),
|
|
16486
15886
|
pagination === void 0 && sessionLoadProgress !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md bg-black/20 px-2 py-2 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.045)]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SessionLoadProgressBar, { progress: sessionLoadProgress }) }),
|
|
15887
|
+
sessionLoadError !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
15888
|
+
"div",
|
|
15889
|
+
{
|
|
15890
|
+
role: "alert",
|
|
15891
|
+
className: "mt-2 flex flex-wrap items-center gap-2 rounded-md border border-red-400/25 bg-red-500/10 px-3 py-2 text-xs text-red-100",
|
|
15892
|
+
children: [
|
|
15893
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
15894
|
+
"Session logs could not be loaded. ",
|
|
15895
|
+
sessionLoadError,
|
|
15896
|
+
" Existing logs remain visible."
|
|
15897
|
+
] }),
|
|
15898
|
+
onReloadSession !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
15899
|
+
"button",
|
|
15900
|
+
{
|
|
15901
|
+
type: "button",
|
|
15902
|
+
onClick: handleReloadCurrentSession,
|
|
15903
|
+
className: "inline-flex h-7 items-center gap-1 rounded-md bg-black/15 px-2 font-medium transition-colors hover:bg-black/25 focus-visible:ring-1 focus-visible:ring-current focus-visible:outline-none",
|
|
15904
|
+
children: [
|
|
15905
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3" }),
|
|
15906
|
+
"Retry"
|
|
15907
|
+
]
|
|
15908
|
+
}
|
|
15909
|
+
)
|
|
15910
|
+
]
|
|
15911
|
+
}
|
|
15912
|
+
),
|
|
16487
15913
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LogPaginationBar, { logs, pagination, embedded: true }),
|
|
16488
15914
|
onNotify === void 0 && exportError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: exportError }),
|
|
16489
15915
|
onNotify === void 0 && importError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: importError }),
|
|
16490
|
-
onNotify === void 0 && importStatus !== null && importError === null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-cyan-400/25 bg-cyan-500/10 px-3 py-2 text-xs text-cyan-100", children: importStatus })
|
|
15916
|
+
onNotify === void 0 && importStatus !== null && importError === null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-cyan-400/25 bg-cyan-500/10 px-3 py-2 text-xs text-cyan-100", children: importStatus }),
|
|
15917
|
+
liveConnection !== void 0 && liveConnection.status !== "live" && onRetryLiveConnection !== void 0 && onStopLiveConnection !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15918
|
+
LiveConnectionStatus,
|
|
15919
|
+
{
|
|
15920
|
+
state: liveConnection,
|
|
15921
|
+
hasLogs: logs.length > 0,
|
|
15922
|
+
onRetry: onRetryLiveConnection,
|
|
15923
|
+
onStop: onStopLiveConnection
|
|
15924
|
+
}
|
|
15925
|
+
)
|
|
16491
15926
|
] }),
|
|
16492
15927
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-4 lg:px-5", children: [
|
|
16493
15928
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SessionOpeningSlate, { stats: slateStats }),
|
|
16494
15929
|
logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.045),0_18px_52px_rgba(0,0,0,0.18)] mx-auto max-w-xl space-y-4 rounded-[8px] px-4 py-8", children: [
|
|
16495
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: isLoading ? "Loading session data..." : "No logs loaded for this session" }),
|
|
15930
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: isLoading ? "Loading session data..." : sessionLoadError === void 0 ? "No logs loaded for this session" : "Session logs could not be loaded" }),
|
|
16496
15931
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "inline-block max-w-full rounded bg-muted px-3 py-1 font-mono text-xs break-all", children: truncateSessionId(selectedSession) }),
|
|
16497
15932
|
sessionLoadProgress !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto max-w-md rounded-md bg-black/20 px-2 py-2 text-left shadow-[inset_0_0_0_1px_rgba(255,255,255,0.045)]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SessionLoadProgressBar, { progress: sessionLoadProgress }) }),
|
|
16498
15933
|
sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-left", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }) }),
|
|
@@ -16504,7 +15939,7 @@ function ProxyViewer({
|
|
|
16504
15939
|
{
|
|
16505
15940
|
type: "button",
|
|
16506
15941
|
onClick: handleReloadCurrentSession,
|
|
16507
|
-
className: "bg-white/[0.045] hover:bg-white/[0.075] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground",
|
|
15942
|
+
className: "bg-white/[0.045] hover:bg-white/[0.075] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
16508
15943
|
children: [
|
|
16509
15944
|
/* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3.5" }),
|
|
16510
15945
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Load session" })
|
|
@@ -16515,7 +15950,7 @@ function ProxyViewer({
|
|
|
16515
15950
|
"a",
|
|
16516
15951
|
{
|
|
16517
15952
|
href: "/",
|
|
16518
|
-
className: "inline-flex h-8 items-center rounded-md px-3 text-xs text-muted-foreground underline transition-colors hover:text-foreground",
|
|
15953
|
+
className: "inline-flex h-8 items-center rounded-md px-3 text-xs text-muted-foreground underline transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
16519
15954
|
children: "Back to all sessions"
|
|
16520
15955
|
}
|
|
16521
15956
|
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -16523,26 +15958,30 @@ function ProxyViewer({
|
|
|
16523
15958
|
{
|
|
16524
15959
|
type: "button",
|
|
16525
15960
|
onClick: () => onSessionChange("__all__"),
|
|
16526
|
-
className: "inline-flex h-8 items-center rounded-md px-3 text-xs text-muted-foreground underline transition-colors hover:text-foreground",
|
|
15961
|
+
className: "inline-flex h-8 items-center rounded-md px-3 text-xs text-muted-foreground underline transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
16527
15962
|
children: "Show all sessions"
|
|
16528
15963
|
}
|
|
16529
15964
|
)
|
|
16530
15965
|
] })
|
|
16531
15966
|
] })
|
|
16532
15967
|
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.045),0_18px_52px_rgba(0,0,0,0.18)] mx-auto max-w-2xl space-y-4 rounded-[8px] px-4 py-8", children: [
|
|
16533
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children:
|
|
16534
|
-
|
|
16535
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
16536
|
-
|
|
16537
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
16538
|
-
|
|
16539
|
-
|
|
15968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: liveEmptyStateCopy.title }),
|
|
15969
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mx-auto max-w-xl text-xs leading-relaxed text-muted-foreground", children: liveEmptyStateCopy.description }),
|
|
15970
|
+
liveEmptyState === "empty" && sessions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mx-auto max-w-xl text-xs leading-relaxed text-muted-foreground", children: "Pick a session from the filter panel to load stored logs on demand." }),
|
|
15971
|
+
liveEmptyStateCopy.showConnectionCommands && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
15972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
15973
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "ANTHROPIC_BASE_URL=http://localhost:9527/proxy <your-tool>" }),
|
|
15974
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "OPENAI_BASE_URL=http://localhost:9527/proxy <your-tool>" })
|
|
15975
|
+
] }),
|
|
15976
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mx-auto max-w-xl text-xs leading-relaxed text-muted-foreground", children: "Container note: if your AI tool runs in a different container or host than Agent Inspector, replace localhost with an address reachable from that tool and verify the network/firewall path." })
|
|
15977
|
+
] })
|
|
16540
15978
|
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
16541
15979
|
"div",
|
|
16542
15980
|
{
|
|
16543
15981
|
ref: logListWrapperRef,
|
|
16544
15982
|
tabIndex: 0,
|
|
16545
|
-
|
|
15983
|
+
"aria-label": "Captured logs",
|
|
15984
|
+
className: "flex flex-col gap-2 rounded-md focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none",
|
|
16546
15985
|
children: [
|
|
16547
15986
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: logListRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16548
15987
|
ConversationGroupList,
|
|
@@ -16568,6 +16007,14 @@ function ProxyViewer({
|
|
|
16568
16007
|
]
|
|
16569
16008
|
}
|
|
16570
16009
|
),
|
|
16010
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: rawExportDialogOpen, onOpenChange: setRawExportDialogOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogContent, { className: RAW_EXPORT_DIALOG_CLASS_NAME, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16011
|
+
RawExportWarning,
|
|
16012
|
+
{
|
|
16013
|
+
onCancel: () => setRawExportDialogOpen(false),
|
|
16014
|
+
onExportRedacted: handleExportRedactedInstead,
|
|
16015
|
+
onConfirmRaw: handleConfirmRawExport
|
|
16016
|
+
}
|
|
16017
|
+
) }) }),
|
|
16571
16018
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "border-red-500/20 bg-zinc-950 text-zinc-100 sm:max-w-md", children: [
|
|
16572
16019
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
|
|
16573
16020
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { children: [
|
|
@@ -16606,7 +16053,7 @@ function ProxyViewer({
|
|
|
16606
16053
|
)
|
|
16607
16054
|
] })
|
|
16608
16055
|
] }) }),
|
|
16609
|
-
comparePair !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16056
|
+
comparePair !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(LazyFeatureBoundary, { feature: "Compare", children: /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16610
16057
|
LazyCompareDrawer,
|
|
16611
16058
|
{
|
|
16612
16059
|
left: comparePair[0],
|
|
@@ -16615,7 +16062,7 @@ function ProxyViewer({
|
|
|
16615
16062
|
rightDisplayNumber: displayNumberForLog(comparePair[1], displayNumberByLogId),
|
|
16616
16063
|
onClose: closeCompare
|
|
16617
16064
|
}
|
|
16618
|
-
) })
|
|
16065
|
+
) }) })
|
|
16619
16066
|
] });
|
|
16620
16067
|
}
|
|
16621
16068
|
function filterLogs(logs, selectedSession, selectedModel) {
|
|
@@ -16712,11 +16159,12 @@ const SESSION_RELOAD_PAGE_LIMIT = 500;
|
|
|
16712
16159
|
const MAX_SESSION_RELOAD_PAGES = 200;
|
|
16713
16160
|
const SESSION_LOGS_FETCH_TIMEOUT_MS = 2e4;
|
|
16714
16161
|
const SESSION_MEMBERSHIP_FETCH_TIMEOUT_MS = 1e4;
|
|
16162
|
+
const SSE_RECONNECT_DELAY_MS = 3e3;
|
|
16163
|
+
const SSE_STALE_AFTER_MS = 1e4;
|
|
16715
16164
|
function buildLogsStreamUrl(sessionId) {
|
|
16716
|
-
const params = new URLSearchParams();
|
|
16165
|
+
const params = new URLSearchParams({ compact: "1" });
|
|
16717
16166
|
if (sessionId !== void 0) {
|
|
16718
16167
|
params.set("sessionId", sessionId);
|
|
16719
|
-
params.set("compact", "1");
|
|
16720
16168
|
}
|
|
16721
16169
|
const query = params.toString();
|
|
16722
16170
|
return query.length > 0 ? `/api/logs/stream?${query}` : "/api/logs/stream";
|
|
@@ -16796,9 +16244,10 @@ function ProxyViewerContainer({
|
|
|
16796
16244
|
const [selectedModel, setSelectedModel] = reactExports.useState("__all__");
|
|
16797
16245
|
const [knownSessions, setKnownSessions] = reactExports.useState([]);
|
|
16798
16246
|
const { notice, showToast, dismissToast } = useTransientToast();
|
|
16799
|
-
const [
|
|
16247
|
+
const [liveConnection, setLiveConnection] = reactExports.useState(createInitialLiveConnectionState);
|
|
16800
16248
|
const [logPage, setLogPage] = reactExports.useState(null);
|
|
16801
16249
|
const [sessionPageLoading, setSessionPageLoading] = reactExports.useState(initialSessionId !== void 0);
|
|
16250
|
+
const [sessionLoadError, setSessionLoadError] = reactExports.useState(null);
|
|
16802
16251
|
const [sessionLoadProgress, setSessionLoadProgress] = reactExports.useState(
|
|
16803
16252
|
void 0
|
|
16804
16253
|
);
|
|
@@ -16806,6 +16255,8 @@ function ProxyViewerContainer({
|
|
|
16806
16255
|
const [, startLogTransition] = reactExports.useTransition();
|
|
16807
16256
|
const eventSourceRef = reactExports.useRef(null);
|
|
16808
16257
|
const reconnectTimeoutRef = reactExports.useRef(null);
|
|
16258
|
+
const staleTimeoutRef = reactExports.useRef(null);
|
|
16259
|
+
const automaticRetryEnabledRef = reactExports.useRef(true);
|
|
16809
16260
|
const handledHashRef = reactExports.useRef(null);
|
|
16810
16261
|
const sessionPageRequestIdRef = reactExports.useRef(0);
|
|
16811
16262
|
const sessionLoadStartedAtRef = reactExports.useRef(null);
|
|
@@ -16904,7 +16355,11 @@ function ProxyViewerContainer({
|
|
|
16904
16355
|
if (eventSourceRef.current) {
|
|
16905
16356
|
eventSourceRef.current.close();
|
|
16906
16357
|
}
|
|
16907
|
-
|
|
16358
|
+
if (reconnectTimeoutRef.current !== null) {
|
|
16359
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
16360
|
+
reconnectTimeoutRef.current = null;
|
|
16361
|
+
}
|
|
16362
|
+
setLiveConnection((state) => reduceLiveConnectionState(state, { type: "connect-requested" }));
|
|
16908
16363
|
const es = new EventSource(buildLogsStreamUrl(initialSessionId));
|
|
16909
16364
|
eventSourceRef.current = es;
|
|
16910
16365
|
es.onmessage = (event) => {
|
|
@@ -16913,6 +16368,12 @@ function ProxyViewerContainer({
|
|
|
16913
16368
|
const parsed = JSON.parse(rawData);
|
|
16914
16369
|
const updateResult = SSEUpdateSchema.safeParse(parsed);
|
|
16915
16370
|
if (!updateResult.success) {
|
|
16371
|
+
setLiveConnection(
|
|
16372
|
+
(state) => reduceLiveConnectionState(state, {
|
|
16373
|
+
type: "recoverable-error",
|
|
16374
|
+
message: "The live stream returned invalid data."
|
|
16375
|
+
})
|
|
16376
|
+
);
|
|
16916
16377
|
showErrorToast("Failed to parse SSE data");
|
|
16917
16378
|
return;
|
|
16918
16379
|
}
|
|
@@ -16929,7 +16390,13 @@ function ProxyViewerContainer({
|
|
|
16929
16390
|
return nextLogs;
|
|
16930
16391
|
});
|
|
16931
16392
|
setKnownSessions((prev) => mergeSessionIds(prev, extractSessions(update.logs)));
|
|
16932
|
-
|
|
16393
|
+
if (staleTimeoutRef.current !== null) {
|
|
16394
|
+
clearTimeout(staleTimeoutRef.current);
|
|
16395
|
+
staleTimeoutRef.current = null;
|
|
16396
|
+
}
|
|
16397
|
+
setLiveConnection(
|
|
16398
|
+
(state) => reduceLiveConnectionState(state, { type: "message-received", at: Date.now() })
|
|
16399
|
+
);
|
|
16933
16400
|
dismissToast();
|
|
16934
16401
|
} else if (update.type === "update") {
|
|
16935
16402
|
setKnownSessions((prev) => {
|
|
@@ -16937,27 +16404,73 @@ function ProxyViewerContainer({
|
|
|
16937
16404
|
return mergeSessionIds(prev, [update.log.sessionId]);
|
|
16938
16405
|
});
|
|
16939
16406
|
scheduleUpdate(update.log);
|
|
16407
|
+
if (staleTimeoutRef.current !== null) {
|
|
16408
|
+
clearTimeout(staleTimeoutRef.current);
|
|
16409
|
+
staleTimeoutRef.current = null;
|
|
16410
|
+
}
|
|
16411
|
+
setLiveConnection(
|
|
16412
|
+
(state) => reduceLiveConnectionState(state, { type: "message-received", at: Date.now() })
|
|
16413
|
+
);
|
|
16940
16414
|
}
|
|
16941
16415
|
} catch {
|
|
16416
|
+
setLiveConnection(
|
|
16417
|
+
(state) => reduceLiveConnectionState(state, {
|
|
16418
|
+
type: "recoverable-error",
|
|
16419
|
+
message: "The live stream returned malformed JSON."
|
|
16420
|
+
})
|
|
16421
|
+
);
|
|
16942
16422
|
showErrorToast("Failed to parse SSE data");
|
|
16943
16423
|
}
|
|
16944
16424
|
};
|
|
16945
16425
|
es.onerror = () => {
|
|
16946
|
-
|
|
16947
|
-
|
|
16426
|
+
const online = navigator.onLine;
|
|
16427
|
+
setLiveConnection(
|
|
16428
|
+
(state) => reduceLiveConnectionState(state, {
|
|
16429
|
+
type: "connection-lost",
|
|
16430
|
+
online,
|
|
16431
|
+
message: "The live stream disconnected."
|
|
16432
|
+
})
|
|
16433
|
+
);
|
|
16948
16434
|
es.close();
|
|
16949
|
-
if (
|
|
16950
|
-
|
|
16435
|
+
if (!online || !automaticRetryEnabledRef.current) return;
|
|
16436
|
+
if (staleTimeoutRef.current === null) {
|
|
16437
|
+
staleTimeoutRef.current = setTimeout(() => {
|
|
16438
|
+
staleTimeoutRef.current = null;
|
|
16439
|
+
setLiveConnection((state) => reduceLiveConnectionState(state, { type: "stale-timeout" }));
|
|
16440
|
+
}, SSE_STALE_AFTER_MS);
|
|
16951
16441
|
}
|
|
16952
|
-
reconnectTimeoutRef.current = setTimeout(connectSSE,
|
|
16442
|
+
reconnectTimeoutRef.current = setTimeout(connectSSE, SSE_RECONNECT_DELAY_MS);
|
|
16953
16443
|
};
|
|
16954
16444
|
}, [dismissToast, initialSessionId, scheduleUpdate, showErrorToast]);
|
|
16445
|
+
const retryLiveConnection = reactExports.useCallback(() => {
|
|
16446
|
+
automaticRetryEnabledRef.current = true;
|
|
16447
|
+
if (reconnectTimeoutRef.current !== null) {
|
|
16448
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
16449
|
+
reconnectTimeoutRef.current = null;
|
|
16450
|
+
}
|
|
16451
|
+
connectSSE();
|
|
16452
|
+
}, [connectSSE]);
|
|
16453
|
+
const stopLiveConnection = reactExports.useCallback(() => {
|
|
16454
|
+
automaticRetryEnabledRef.current = false;
|
|
16455
|
+
eventSourceRef.current?.close();
|
|
16456
|
+
eventSourceRef.current = null;
|
|
16457
|
+
if (reconnectTimeoutRef.current !== null) {
|
|
16458
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
16459
|
+
reconnectTimeoutRef.current = null;
|
|
16460
|
+
}
|
|
16461
|
+
if (staleTimeoutRef.current !== null) {
|
|
16462
|
+
clearTimeout(staleTimeoutRef.current);
|
|
16463
|
+
staleTimeoutRef.current = null;
|
|
16464
|
+
}
|
|
16465
|
+
setLiveConnection((state) => reduceLiveConnectionState(state, { type: "stop-retrying" }));
|
|
16466
|
+
}, []);
|
|
16955
16467
|
const loadSessionPage = reactExports.useCallback(
|
|
16956
16468
|
(request) => {
|
|
16957
16469
|
if (initialSessionId === void 0) return;
|
|
16958
16470
|
const requestId = sessionPageRequestIdRef.current + 1;
|
|
16959
16471
|
sessionPageRequestIdRef.current = requestId;
|
|
16960
16472
|
setSessionPageLoading(true);
|
|
16473
|
+
setSessionLoadError(null);
|
|
16961
16474
|
startSessionLoadProgress("Loading session logs", requestId);
|
|
16962
16475
|
dismissToast();
|
|
16963
16476
|
void fetchSessionLogsPage(initialSessionId, request).then((page) => {
|
|
@@ -16968,15 +16481,16 @@ function ProxyViewerContainer({
|
|
|
16968
16481
|
setLogPage(page);
|
|
16969
16482
|
setSelectedSession(initialSessionId);
|
|
16970
16483
|
setSessionPageLoading(false);
|
|
16484
|
+
setSessionLoadError(null);
|
|
16971
16485
|
stopSessionLoadProgress();
|
|
16972
16486
|
dismissToast();
|
|
16973
16487
|
}).catch((err) => {
|
|
16974
16488
|
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
16975
|
-
setAllLogs([]);
|
|
16976
|
-
setLogPage(null);
|
|
16977
16489
|
setSessionPageLoading(false);
|
|
16978
16490
|
stopSessionLoadProgress();
|
|
16979
|
-
|
|
16491
|
+
const message = err instanceof Error ? err.message : "Failed to load session logs";
|
|
16492
|
+
setSessionLoadError(message);
|
|
16493
|
+
showErrorToast(message);
|
|
16980
16494
|
});
|
|
16981
16495
|
},
|
|
16982
16496
|
[
|
|
@@ -16992,6 +16506,7 @@ function ProxyViewerContainer({
|
|
|
16992
16506
|
const requestId = sessionPageRequestIdRef.current + 1;
|
|
16993
16507
|
sessionPageRequestIdRef.current = requestId;
|
|
16994
16508
|
setSessionPageLoading(true);
|
|
16509
|
+
setSessionLoadError(null);
|
|
16995
16510
|
startSessionLoadProgress("Reloading full session", requestId);
|
|
16996
16511
|
dismissToast();
|
|
16997
16512
|
void (async () => {
|
|
@@ -17027,6 +16542,7 @@ function ProxyViewerContainer({
|
|
|
17027
16542
|
});
|
|
17028
16543
|
setKnownSessions((prev) => mergeSessionIds(prev, [sessionId]));
|
|
17029
16544
|
setSessionPageLoading(false);
|
|
16545
|
+
setSessionLoadError(null);
|
|
17030
16546
|
stopSessionLoadProgress();
|
|
17031
16547
|
if (page.hasNewer) {
|
|
17032
16548
|
showToast({
|
|
@@ -17040,7 +16556,9 @@ function ProxyViewerContainer({
|
|
|
17040
16556
|
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
17041
16557
|
setSessionPageLoading(false);
|
|
17042
16558
|
stopSessionLoadProgress();
|
|
17043
|
-
|
|
16559
|
+
const message = err instanceof Error ? err.message : "Failed to reload session logs";
|
|
16560
|
+
setSessionLoadError(message);
|
|
16561
|
+
showErrorToast(message);
|
|
17044
16562
|
});
|
|
17045
16563
|
},
|
|
17046
16564
|
[
|
|
@@ -17092,7 +16610,28 @@ function ProxyViewerContainer({
|
|
|
17092
16610
|
reactExports.useEffect(() => {
|
|
17093
16611
|
if (initialSessionId !== void 0) return void 0;
|
|
17094
16612
|
connectSSE();
|
|
16613
|
+
const handleOffline = () => {
|
|
16614
|
+
eventSourceRef.current?.close();
|
|
16615
|
+
eventSourceRef.current = null;
|
|
16616
|
+
if (reconnectTimeoutRef.current !== null) {
|
|
16617
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
16618
|
+
reconnectTimeoutRef.current = null;
|
|
16619
|
+
}
|
|
16620
|
+
if (staleTimeoutRef.current !== null) {
|
|
16621
|
+
clearTimeout(staleTimeoutRef.current);
|
|
16622
|
+
staleTimeoutRef.current = null;
|
|
16623
|
+
}
|
|
16624
|
+
setLiveConnection((state) => reduceLiveConnectionState(state, { type: "browser-offline" }));
|
|
16625
|
+
};
|
|
16626
|
+
const handleOnline = () => {
|
|
16627
|
+
if (!automaticRetryEnabledRef.current) return;
|
|
16628
|
+
connectSSE();
|
|
16629
|
+
};
|
|
16630
|
+
window.addEventListener("offline", handleOffline);
|
|
16631
|
+
window.addEventListener("online", handleOnline);
|
|
17095
16632
|
return () => {
|
|
16633
|
+
window.removeEventListener("offline", handleOffline);
|
|
16634
|
+
window.removeEventListener("online", handleOnline);
|
|
17096
16635
|
if (eventSourceRef.current) {
|
|
17097
16636
|
eventSourceRef.current.close();
|
|
17098
16637
|
eventSourceRef.current = null;
|
|
@@ -17101,6 +16640,10 @@ function ProxyViewerContainer({
|
|
|
17101
16640
|
clearTimeout(reconnectTimeoutRef.current);
|
|
17102
16641
|
reconnectTimeoutRef.current = null;
|
|
17103
16642
|
}
|
|
16643
|
+
if (staleTimeoutRef.current !== null) {
|
|
16644
|
+
clearTimeout(staleTimeoutRef.current);
|
|
16645
|
+
staleTimeoutRef.current = null;
|
|
16646
|
+
}
|
|
17104
16647
|
if (flushTimerRef.current !== null) {
|
|
17105
16648
|
clearTimeout(flushTimerRef.current);
|
|
17106
16649
|
flushTimerRef.current = null;
|
|
@@ -17125,7 +16668,10 @@ function ProxyViewerContainer({
|
|
|
17125
16668
|
const target = document.getElementById(targetId);
|
|
17126
16669
|
if (target !== null) {
|
|
17127
16670
|
handledHashRef.current = hash;
|
|
17128
|
-
target.scrollIntoView({
|
|
16671
|
+
target.scrollIntoView({
|
|
16672
|
+
block: "center",
|
|
16673
|
+
behavior: preferredScrollBehavior(browserPrefersReducedMotion())
|
|
16674
|
+
});
|
|
17129
16675
|
if (target instanceof HTMLElement) {
|
|
17130
16676
|
highlightedTarget = target;
|
|
17131
16677
|
target.setAttribute("data-deep-link-highlight", "true");
|
|
@@ -17385,9 +16931,13 @@ function ProxyViewerContainer({
|
|
|
17385
16931
|
onClearGroup: handleClearGroup,
|
|
17386
16932
|
onNotify: showToast,
|
|
17387
16933
|
onImportLogs: initialSessionId === void 0 ? handleImportLogs : void 0,
|
|
17388
|
-
isLoading: initialSessionId === void 0 ?
|
|
16934
|
+
isLoading: initialSessionId === void 0 ? liveConnection.status === "connecting" && liveConnection.lastSuccessAt === null || sessionPageLoading : sessionPageLoading,
|
|
16935
|
+
liveConnection: initialSessionId === void 0 ? liveConnection : void 0,
|
|
16936
|
+
onRetryLiveConnection: retryLiveConnection,
|
|
16937
|
+
onStopLiveConnection: stopLiveConnection,
|
|
17389
16938
|
pagination,
|
|
17390
16939
|
sessionLoadProgress,
|
|
16940
|
+
sessionLoadError: sessionLoadError ?? void 0,
|
|
17391
16941
|
sessionMemberships,
|
|
17392
16942
|
viewMode,
|
|
17393
16943
|
captureMode,
|
|
@@ -17405,40 +16955,34 @@ export {
|
|
|
17405
16955
|
Badge as B,
|
|
17406
16956
|
CONTEXT_USAGE_THRESHOLDS as C,
|
|
17407
16957
|
Dialog as D,
|
|
17408
|
-
CollapsibleContent as E,
|
|
17409
|
-
ScrollArea as F,
|
|
17410
|
-
LazyJsonViewer as G,
|
|
17411
|
-
safeJsonValue as H,
|
|
17412
|
-
parseJsonText as I,
|
|
17413
16958
|
LazyJsonViewerFromString as L,
|
|
17414
16959
|
ProxyViewerContainer as P,
|
|
17415
16960
|
ROLE_COLOR_CLASSES as R,
|
|
17416
16961
|
SegmentBar as S,
|
|
17417
16962
|
Tabs as T,
|
|
17418
16963
|
getConversationId as a,
|
|
17419
|
-
|
|
17420
|
-
|
|
17421
|
-
|
|
17422
|
-
|
|
17423
|
-
|
|
16964
|
+
DialogContent as b,
|
|
16965
|
+
DialogHeader as c,
|
|
16966
|
+
DialogTitle as d,
|
|
16967
|
+
TabsList as e,
|
|
16968
|
+
fetchJsonWithTimeout as f,
|
|
17424
16969
|
getLogFormatAdapter as g,
|
|
17425
|
-
|
|
17426
|
-
|
|
17427
|
-
|
|
17428
|
-
|
|
17429
|
-
|
|
17430
|
-
|
|
17431
|
-
|
|
17432
|
-
|
|
17433
|
-
|
|
17434
|
-
|
|
16970
|
+
TabsTrigger as h,
|
|
16971
|
+
TabsContent as i,
|
|
16972
|
+
TooltipProvider as j,
|
|
16973
|
+
Tooltip as k,
|
|
16974
|
+
TooltipTrigger as l,
|
|
16975
|
+
TooltipContent as m,
|
|
16976
|
+
dispatchLogFocusRequest as n,
|
|
16977
|
+
analyzeContextIntelligence as o,
|
|
16978
|
+
ANATOMY_ROLE_LABELS as p,
|
|
16979
|
+
Collapsible as q,
|
|
17435
16980
|
resolveLogFormat as r,
|
|
17436
|
-
|
|
17437
|
-
|
|
16981
|
+
CollapsibleTrigger as s,
|
|
16982
|
+
CollapsibleContent as t,
|
|
17438
16983
|
useProviders as u,
|
|
17439
|
-
|
|
17440
|
-
|
|
17441
|
-
|
|
17442
|
-
|
|
17443
|
-
CollapsibleTrigger as z
|
|
16984
|
+
ScrollArea as v,
|
|
16985
|
+
LazyJsonViewer as w,
|
|
16986
|
+
safeJsonValue as x,
|
|
16987
|
+
parseJsonText as y
|
|
17444
16988
|
};
|