@tonyclaw/agent-inspector 3.0.4 → 3.0.6

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.
Files changed (38) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-Bs2kzUSp.js → CompareDrawer-DsvO6QyJ.js} +1 -1
  3. package/.output/public/assets/ProxyViewerContainer-CfP-komD.js +106 -0
  4. package/.output/public/assets/{ReplayDialog-B6xy7pl5.js → ReplayDialog-CQlLX1Uo.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-BSvSmpCO.js → RequestAnatomy-m1q-uVTl.js} +1 -1
  6. package/.output/public/assets/{ResponseView-BFnUva7Z.js → ResponseView-DuLLeYSh.js} +2 -2
  7. package/.output/public/assets/{StreamingChunkSequence-u7ZaJOqn.js → StreamingChunkSequence-CN4aRFBx.js} +1 -1
  8. package/.output/public/assets/{_sessionId-CH4nsMOA.js → _sessionId-CWP4pxOU.js} +1 -1
  9. package/.output/public/assets/index-0pt1umWP.css +1 -0
  10. package/.output/public/assets/index-DSUEOPbC.js +1 -0
  11. package/.output/public/assets/{index-B5HS6AxR.js → index-zfZUz67K.js} +1 -1
  12. package/.output/public/assets/{json-viewer-5Tj5vkqe.js → json-viewer-_4r1LBBE.js} +1 -1
  13. package/.output/public/assets/{main-ChxZWG8K.js → main-C_nEHNUM.js} +2 -2
  14. package/.output/server/_libs/lucide-react.mjs +292 -203
  15. package/.output/server/{_sessionId-B3r-VBdM.mjs → _sessionId-CTqCAmUF.mjs} +3 -3
  16. package/.output/server/_ssr/{CompareDrawer-DAYrKHKe.mjs → CompareDrawer-D6b6TZ-O.mjs} +3 -3
  17. package/.output/server/_ssr/{ProxyViewerContainer-CYmNmQK9.mjs → ProxyViewerContainer-Dp7Va9_T.mjs} +593 -148
  18. package/.output/server/_ssr/{ReplayDialog-CdKvdXxk.mjs → ReplayDialog-D_KWQ1GY.mjs} +4 -4
  19. package/.output/server/_ssr/{RequestAnatomy-BtmTUq7O.mjs → RequestAnatomy-CPubXjMX.mjs} +2 -2
  20. package/.output/server/_ssr/{ResponseView-DuD_z5hd.mjs → ResponseView-CsTiNoOE.mjs} +3 -3
  21. package/.output/server/_ssr/{StreamingChunkSequence-DpIV2wt_.mjs → StreamingChunkSequence-Bgbzt23U.mjs} +2 -2
  22. package/.output/server/_ssr/{index-B4_8vH8k.mjs → index-P1gSpuM5.mjs} +2 -2
  23. package/.output/server/_ssr/index.mjs +2 -2
  24. package/.output/server/_ssr/{json-viewer-gcNJEB7y.mjs → json-viewer-10ciVGnc.mjs} +3 -3
  25. package/.output/server/_ssr/{router-CYjIsElo.mjs → router-BJJ0VhsB.mjs} +362 -151
  26. package/.output/server/_tanstack-start-manifest_v-CltlYL3I.mjs +4 -0
  27. package/.output/server/index.mjs +75 -75
  28. package/package.json +1 -1
  29. package/src/components/ProxyViewer.tsx +19 -1
  30. package/src/components/ecosystem/AgentLabDialog.tsx +379 -0
  31. package/src/components/providers/ProviderCard.tsx +342 -206
  32. package/src/lib/ecosystemContract.ts +47 -0
  33. package/src/lib/stopReason.ts +4 -0
  34. package/src/routes/api/ecosystem.packages.ts +263 -0
  35. package/.output/public/assets/ProxyViewerContainer-BUnlrfiS.js +0 -106
  36. package/.output/public/assets/index-BqVL284D.js +0 -1
  37. package/.output/public/assets/index-DJW6qbnH.css +0 -1
  38. package/.output/server/_tanstack-start-manifest_v-BRdOxY6q.mjs +0 -4
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
2
- import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as DeleteInspectorGroupsResponseSchema, o as GroupEvidenceExportResultSchema, q as DeleteInspectorGroupResponseSchema, z as createPendingProviderTestResults, B as ProviderTestResultsSchema, E as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, F as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, u as maskApiKey, v as PATH_V1_MESSAGES, w as PATH_V1_CHAT_COMPLETIONS, x as PATH_V1_RESPONSES, r as providerHasContextMetadata, t as findProviderModelMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, H as resolveProviderContextWindow, j as getSessionPath, y as previewUpstreamUrl, K as KnowledgeCandidateSchema, J as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-CYjIsElo.mjs";
2
+ import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as DeleteInspectorGroupsResponseSchema, o as GroupEvidenceExportResultSchema, q as DeleteInspectorGroupResponseSchema, z as createPendingProviderTestResults, B as ProviderTestResultsSchema, E as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, F as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, t as maskApiKey, u as PATH_V1_MESSAGES, v as PATH_V1_CHAT_COMPLETIONS, w as PATH_V1_RESPONSES, r as providerHasContextMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, H as resolveProviderContextWindow, j as getSessionPath, x as findProviderModelMetadata, y as previewUpstreamUrl, K as KnowledgeCandidateSchema, J as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-BJJ0VhsB.mjs";
3
3
  import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
4
4
  import { J as JSZip } from "../_libs/jszip.mjs";
5
5
  import { c as clsx } from "../_libs/clsx.mjs";
@@ -9,7 +9,7 @@ import { c as cva } from "../_libs/class-variance-authority.mjs";
9
9
  import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
10
10
  import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
11
11
  import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
12
- import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, R as RefreshCw, c as Trash2, S as Search, U as Upload, D as Download, F as FileBraces, P as Plus, A as ArrowLeft, d as ChevronUp, e as Copy, f as ChevronsLeft, g as ChevronLeft, h as ChevronRight, i as ChevronsRight, j as Clapperboard, k as Flag, l as Siren, m as Timer, G as Gauge, L as LoaderCircle, n as Layers, o as Settings, M as Monitor, p as Scan, q as CircleAlert, r as Terminal, s as ArrowUpRight, t as ArrowDownRight, u as Cpu, v as FolderOpen, B as Bell, w as Clock3, x as ShieldAlert, E as EyeOff, y as Eye, z as ExternalLink, H as RotateCw, J as Clock, K as Pencil, N as MessageSquare, Z as Zap, W as Wrench, O as Brain, Q as Minus, V as CircleCheckBig, Y as CircleQuestionMark, _ as Server, $ as Lock, a0 as Wifi, a1 as WifiOff, a2 as CircleX, a3 as ShieldCheck, a4 as Save, a5 as FileSearch, a6 as CloudUpload, a7 as OctagonAlert, a8 as Radio, a9 as Globe, aa as FileTerminal, ab as ChevronsUp, ac as ChevronsDown, ad as FileDiff, ae as History, af as RotateCcw, ag as GitCompareArrows, ah as ArrowUp, ai as ArrowDown, aj as Ellipsis, ak as CodeXml, al as Blocks, am as MousePointerClick, an as FileText, ao as Rows3, ap as Columns2 } from "../_libs/lucide-react.mjs";
12
+ import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, R as RefreshCw, c as Trash2, S as Search, U as Upload, D as Download, F as FileBraces, P as Plus, A as ArrowLeft, d as ChevronUp, e as Copy, f as ChevronsLeft, g as ChevronLeft, h as ChevronRight, i as ChevronsRight, j as Clapperboard, k as Flag, l as Siren, m as Timer, G as Gauge, L as LoaderCircle, n as Layers, o as FlaskConical, p as Sparkles, q as Activity, B as Beaker, N as Network, r as Terminal, s as Settings, M as Monitor, t as Rocket, u as PackageCheck, v as Scan, w as CircleAlert, x as ArrowUpRight, y as ArrowDownRight, z as Cpu, E as FolderOpen, H as Bell, J as Clock3, K as ShieldAlert, O as EyeOff, Q as Eye, V as ExternalLink, W as Clock, Y as RotateCw, Z as Pencil, _ as MessageSquare, $ as Zap, a0 as Wrench, a1 as Brain, a2 as Minus, a3 as CircleCheckBig, a4 as CircleQuestionMark, a5 as Server, a6 as Lock, a7 as Wifi, a8 as WifiOff, a9 as CircleX, aa as ShieldCheck, ab as Save, ac as FileSearch, ad as CloudUpload, ae as OctagonAlert, af as Radio, ag as Globe, ah as FileTerminal, ai as ChevronsUp, aj as ChevronsDown, ak as FileDiff, al as History, am as RotateCcw, an as GitCompareArrows, ao as ArrowUp, ap as ArrowDown, aq as Ellipsis, ar as CodeXml, as as Blocks, at as MousePointerClick, au as FileText, av as Rows3, aw as Columns2 } from "../_libs/lucide-react.mjs";
13
13
  import { u as union, d as object, a as array, l as literal, b as string, n as number, c as boolean, _ as _enum } from "../_libs/zod.mjs";
14
14
  import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
15
15
  import { R as Root2$1, L as List, T as Trigger$2, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
@@ -530,6 +530,8 @@ function normalizeAnthropicStopReason(value) {
530
530
  case "end_turn":
531
531
  case "tool_use":
532
532
  return value;
533
+ case "max_tokens":
534
+ return "length";
533
535
  default:
534
536
  return null;
535
537
  }
@@ -539,6 +541,8 @@ function normalizeOpenAIFinishReason(value) {
539
541
  case "stop":
540
542
  case "length":
541
543
  return value;
544
+ case "max_tokens":
545
+ return "length";
542
546
  default:
543
547
  return null;
544
548
  }
@@ -2302,27 +2306,27 @@ function useCopyFeedback(text) {
2302
2306
  return { copied, copy };
2303
2307
  }
2304
2308
  const LazyCompareDrawer = reactExports.lazy(
2305
- () => import("./CompareDrawer-DAYrKHKe.mjs").then((m) => ({ default: m.CompareDrawer }))
2309
+ () => import("./CompareDrawer-D6b6TZ-O.mjs").then((m) => ({ default: m.CompareDrawer }))
2306
2310
  );
2307
2311
  const LazyReplayDialog = reactExports.lazy(
2308
- () => import("./ReplayDialog-CdKvdXxk.mjs").then((m) => ({ default: m.ReplayDialog }))
2312
+ () => import("./ReplayDialog-D_KWQ1GY.mjs").then((m) => ({ default: m.ReplayDialog }))
2309
2313
  );
2310
2314
  const LazyRequestAnatomy = reactExports.lazy(
2311
- () => import("./RequestAnatomy-BtmTUq7O.mjs").then((m) => ({ default: m.RequestAnatomy }))
2315
+ () => import("./RequestAnatomy-CPubXjMX.mjs").then((m) => ({ default: m.RequestAnatomy }))
2312
2316
  );
2313
2317
  const LazyResponseView = reactExports.lazy(
2314
- () => import("./ResponseView-DuD_z5hd.mjs").then((m) => ({ default: m.ResponseView }))
2318
+ () => import("./ResponseView-CsTiNoOE.mjs").then((m) => ({ default: m.ResponseView }))
2315
2319
  );
2316
2320
  const LazyStreamingChunkSequence = reactExports.lazy(
2317
- () => import("./StreamingChunkSequence-DpIV2wt_.mjs").then((m) => ({
2321
+ () => import("./StreamingChunkSequence-Bgbzt23U.mjs").then((m) => ({
2318
2322
  default: m.StreamingChunkSequence
2319
2323
  }))
2320
2324
  );
2321
2325
  const LazyJsonViewer = reactExports.lazy(
2322
- () => import("./json-viewer-gcNJEB7y.mjs").then((m) => ({ default: m.JsonViewer }))
2326
+ () => import("./json-viewer-10ciVGnc.mjs").then((m) => ({ default: m.JsonViewer }))
2323
2327
  );
2324
2328
  const LazyJsonViewerFromString = reactExports.lazy(
2325
- () => import("./json-viewer-gcNJEB7y.mjs").then((m) => ({ default: m.JsonViewerFromString }))
2329
+ () => import("./json-viewer-10ciVGnc.mjs").then((m) => ({ default: m.JsonViewerFromString }))
2326
2330
  );
2327
2331
  const HIGHLIGHT_DURATION_MS = 1200;
2328
2332
  const MAX_HIGHLIGHT_ATTEMPTS = 12;
@@ -8361,6 +8365,119 @@ function ProviderTestCoverage({ provider }) {
8361
8365
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "non-stream + stream" })
8362
8366
  ] });
8363
8367
  }
8368
+ function configuredFormatResults(provider, testResults) {
8369
+ if (testResults === void 0) return [];
8370
+ const results = [];
8371
+ if (providerHasEndpoint(provider.anthropicBaseUrl)) {
8372
+ results.push(testResults.anthropic);
8373
+ }
8374
+ if (providerHasEndpoint(provider.openaiBaseUrl)) {
8375
+ results.push(testResults.openaiChat);
8376
+ }
8377
+ if (providerHasEndpoint(provider.openaiResponsesBaseUrl)) {
8378
+ results.push(testResults.openaiResponses);
8379
+ }
8380
+ return results;
8381
+ }
8382
+ function summarizeTestResults(provider, testResults) {
8383
+ const summary = { total: 0, passed: 0, failed: 0, testing: 0 };
8384
+ for (const results of configuredFormatResults(provider, testResults)) {
8385
+ for (const state of [results.nonStreaming, results.streaming]) {
8386
+ if (isNotConfiguredState(state)) continue;
8387
+ summary.total += 1;
8388
+ if (hasSuccessField(state)) {
8389
+ if (state.success) {
8390
+ summary.passed += 1;
8391
+ } else {
8392
+ summary.failed += 1;
8393
+ }
8394
+ } else {
8395
+ summary.testing += 1;
8396
+ }
8397
+ }
8398
+ }
8399
+ return summary;
8400
+ }
8401
+ function ProviderTestPill({
8402
+ provider,
8403
+ testResults,
8404
+ isTesting
8405
+ }) {
8406
+ const targets = providerTestTargets(provider);
8407
+ const summary = summarizeTestResults(provider, testResults);
8408
+ if (isTesting) {
8409
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-cyan-300/25 bg-cyan-300/[0.08] px-2 py-1 text-xs text-cyan-100", children: [
8410
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: "size-3 animate-spin" }),
8411
+ "Testing"
8412
+ ] });
8413
+ }
8414
+ if (targets.length === 0) {
8415
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded border border-border/70 bg-muted/20 px-2 py-1 text-xs text-muted-foreground", children: "No endpoint" });
8416
+ }
8417
+ if (testResults === void 0 || summary.total === 0) {
8418
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded border border-border/70 bg-muted/20 px-2 py-1 text-xs text-muted-foreground", children: "Not tested" });
8419
+ }
8420
+ if (summary.failed > 0) {
8421
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-red-400/25 bg-red-500/[0.08] px-2 py-1 text-xs text-red-200", children: [
8422
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-3" }),
8423
+ summary.passed,
8424
+ "/",
8425
+ summary.total,
8426
+ " passed"
8427
+ ] });
8428
+ }
8429
+ if (summary.testing > 0 || summary.passed < summary.total) {
8430
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "rounded border border-amber-300/25 bg-amber-400/[0.08] px-2 py-1 text-xs text-amber-100", children: [
8431
+ "Partial ",
8432
+ summary.passed,
8433
+ "/",
8434
+ summary.total
8435
+ ] });
8436
+ }
8437
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-cyan-300/25 bg-cyan-300/[0.08] px-2 py-1 text-xs text-cyan-100", children: [
8438
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "size-3" }),
8439
+ "OK ",
8440
+ summary.passed,
8441
+ "/",
8442
+ summary.total
8443
+ ] });
8444
+ }
8445
+ function compactModelLabel(provider) {
8446
+ const models = provider.models ?? [];
8447
+ if (models.length === 0) return "No models configured";
8448
+ const visible = models.slice(0, 2).join(", ");
8449
+ const hiddenCount = models.length - 2;
8450
+ return hiddenCount > 0 ? `${visible} +${hiddenCount} more` : visible;
8451
+ }
8452
+ function ModelChip({ provider, model }) {
8453
+ const metadata = findProviderModelMetadata(provider, model);
8454
+ const sourceLink = getModelSourceLink(metadata?.sourceUrl);
8455
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground", children: [
8456
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: model }),
8457
+ metadata !== null && metadata.contextWindow !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-foreground/80", children: formatContextWindowTokens(metadata.contextWindow) }),
8458
+ sourceLink !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
8459
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8460
+ "a",
8461
+ {
8462
+ href: sourceLink.url,
8463
+ target: "_blank",
8464
+ rel: "noopener noreferrer",
8465
+ className: "inline-flex items-center gap-0.5 rounded border border-border/70 bg-background/70 px-1 font-mono text-[10px] leading-4 text-muted-foreground transition-colors hover:text-foreground",
8466
+ "aria-label": sourceLink.title,
8467
+ children: sourceLink.label
8468
+ }
8469
+ ) }),
8470
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: sourceLink.title })
8471
+ ] }) })
8472
+ ] });
8473
+ }
8474
+ function modelResultsLabel(testResults) {
8475
+ const models = testResults?.models;
8476
+ if (models === void 0) return null;
8477
+ const count = Object.keys(models).length;
8478
+ if (count === 0) return null;
8479
+ return `${count} model${count === 1 ? "" : "s"} tested`;
8480
+ }
8364
8481
  function getErrorIcon(type) {
8365
8482
  const iconProps = { className: "size-3", strokeWidth: 2 };
8366
8483
  switch (type) {
@@ -8547,6 +8664,7 @@ function ProviderCard({
8547
8664
  }) {
8548
8665
  const [showApiKey, setShowApiKey] = reactExports.useState(false);
8549
8666
  const [copied, setCopied] = reactExports.useState(false);
8667
+ const [showDetails, setShowDetails] = reactExports.useState(false);
8550
8668
  const [showModelResults, setShowModelResults] = reactExports.useState(false);
8551
8669
  function handleCopy() {
8552
8670
  void copyTextToClipboard(provider.apiKey).then((success) => {
@@ -8561,6 +8679,8 @@ function ProviderCard({
8561
8679
  const hasContextMetadata = providerHasContextMetadata(provider);
8562
8680
  const canRefreshMetadata = provider.modelMetadataUrl !== void 0 && provider.modelMetadataUrl.trim() !== "";
8563
8681
  const metadataImportLabel = canRefreshMetadata ? "Refresh" : "Import defaults";
8682
+ const isTestingValue = isTesting ?? false;
8683
+ const testedModelsLabel = modelResultsLabel(testResults);
8564
8684
  const providerSourceBadge = provider.source === "company" ? /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
8565
8685
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 rounded border border-cyan-300/20 bg-cyan-300/[0.08] px-1.5 py-0.5 text-xs text-cyan-100", children: "Company" }) }),
8566
8686
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Company-provided API key" })
@@ -8571,65 +8691,53 @@ function ProviderCard({
8571
8691
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
8572
8692
  "div",
8573
8693
  {
8574
- className: `border border-border bg-card shadow-sm flex flex-col gap-3 rounded-[8px] p-4 transition-all duration-500 ${isHighlighted === true ? "ring-2 ring-primary shadow-md" : ""}`,
8694
+ className: `flex flex-col gap-3 rounded-[8px] border border-border bg-card p-4 shadow-sm transition-all duration-500 ${isHighlighted === true ? "ring-2 ring-primary shadow-md" : ""}`,
8575
8695
  children: [
8576
8696
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
8577
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
8578
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate", children: provider.name }),
8579
- providerSourceBadge,
8580
- providerSourceBadge === null && provider.source === "company" && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
8581
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs px-1.5 py-0.5 rounded bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400 shrink-0", children: "公司" }) }),
8582
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Company-provided API key" })
8583
- ] }) }),
8584
- providerSourceBadge === null && provider.source === "personal" && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
8585
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs px-1.5 py-0.5 rounded bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400 shrink-0", children: "个人" }) }),
8586
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Your personal API key" })
8587
- ] }) })
8697
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 space-y-1", children: [
8698
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
8699
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-medium", children: provider.name }),
8700
+ providerSourceBadge
8701
+ ] }),
8702
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-xs text-muted-foreground", children: compactModelLabel(provider) })
8588
8703
  ] }),
8589
- docsUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
8590
- "a",
8591
- {
8592
- href: docsUrl,
8593
- target: "_blank",
8594
- rel: "noopener noreferrer",
8595
- className: "text-muted-foreground hover:text-foreground transition-colors flex items-center gap-1 text-xs",
8596
- title: "View API documentation",
8597
- children: [
8598
- /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3" }),
8599
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Docs" })
8600
- ]
8601
- }
8602
- )
8704
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
8705
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
8706
+ ProviderTestPill,
8707
+ {
8708
+ provider,
8709
+ testResults,
8710
+ isTesting: isTestingValue
8711
+ }
8712
+ ),
8713
+ docsUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
8714
+ "a",
8715
+ {
8716
+ href: docsUrl,
8717
+ target: "_blank",
8718
+ rel: "noopener noreferrer",
8719
+ className: "flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground",
8720
+ title: "View API documentation",
8721
+ children: [
8722
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3" }),
8723
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Docs" })
8724
+ ]
8725
+ }
8726
+ )
8727
+ ] })
8728
+ ] }),
8729
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center sm:justify-between", children: [
8730
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderTestCoverage, { provider }),
8731
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
8732
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Key configured" }),
8733
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: provider.authHeader === "x-api-key" ? "x-api-key" : "Bearer" }),
8734
+ testedModelsLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: testedModelsLabel }),
8735
+ testResults?.testedAt !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
8736
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
8737
+ formatTimeAgo(testResults.testedAt)
8738
+ ] })
8739
+ ] })
8603
8740
  ] }),
8604
- provider.models !== void 0 && provider.models.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: provider.models.map((m) => {
8605
- const metadata = findProviderModelMetadata(provider, m);
8606
- const sourceLink = getModelSourceLink(metadata?.sourceUrl);
8607
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
8608
- "span",
8609
- {
8610
- className: "inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-muted text-muted-foreground",
8611
- children: [
8612
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: m }),
8613
- metadata !== null && metadata.contextWindow !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-foreground/80", children: formatContextWindowTokens(metadata.contextWindow) }),
8614
- sourceLink !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
8615
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8616
- "a",
8617
- {
8618
- href: sourceLink.url,
8619
- target: "_blank",
8620
- rel: "noopener noreferrer",
8621
- className: "inline-flex items-center gap-0.5 rounded border border-border/70 bg-background/70 px-1 font-mono text-[10px] leading-4 text-muted-foreground transition-colors hover:text-foreground",
8622
- "aria-label": sourceLink.title,
8623
- children: sourceLink.label
8624
- }
8625
- ) }),
8626
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: sourceLink.title })
8627
- ] }) })
8628
- ]
8629
- },
8630
- m
8631
- );
8632
- }) }),
8633
8741
  !hasContextMetadata && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 rounded-md border border-amber-500/25 bg-amber-500/6 px-2 py-1.5 text-xs text-muted-foreground", children: [
8634
8742
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Context window metadata missing" }),
8635
8743
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
@@ -8661,98 +8769,106 @@ function ProviderCard({
8661
8769
  )
8662
8770
  ] })
8663
8771
  ] }),
8664
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
8665
- /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "text-xs text-muted-foreground bg-muted px-2 py-1 rounded flex-1 truncate", children: showApiKey ? provider.apiKey : maskApiKey(provider.apiKey) }),
8666
- /* @__PURE__ */ jsxRuntimeExports.jsx(
8667
- "button",
8772
+ showDetails && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 border-t border-border/60 pt-3", children: [
8773
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
8774
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "flex-1 truncate rounded bg-muted px-2 py-1 text-xs text-muted-foreground", children: showApiKey ? provider.apiKey : maskApiKey(provider.apiKey) }),
8775
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
8776
+ "button",
8777
+ {
8778
+ type: "button",
8779
+ onClick: () => setShowApiKey((s) => !s),
8780
+ className: "p-1 text-muted-foreground transition-colors hover:text-foreground",
8781
+ "aria-label": showApiKey ? "Hide API key" : "Show API key",
8782
+ children: showApiKey ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "size-4" })
8783
+ }
8784
+ ),
8785
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
8786
+ "button",
8787
+ {
8788
+ type: "button",
8789
+ onClick: handleCopy,
8790
+ className: "p-1 text-muted-foreground transition-colors hover:text-foreground",
8791
+ "aria-label": "Copy API key",
8792
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4 text-cyan-300" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" })
8793
+ }
8794
+ )
8795
+ ] }),
8796
+ provider.models !== void 0 && provider.models.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: provider.models.map((model) => /* @__PURE__ */ jsxRuntimeExports.jsx(ModelChip, { provider, model }, model)) }),
8797
+ providerHasEndpoint(provider.anthropicBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
8798
+ ProviderEndpointSummary,
8668
8799
  {
8669
- type: "button",
8670
- onClick: () => setShowApiKey((s) => !s),
8671
- className: "text-muted-foreground hover:text-foreground transition-colors p-1",
8672
- "aria-label": showApiKey ? "Hide API key" : "Show API key",
8673
- children: showApiKey ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "size-4" })
8800
+ label: "Anthropic",
8801
+ baseUrl: provider.anthropicBaseUrl,
8802
+ endpoint: PATH_V1_MESSAGES,
8803
+ providerName: provider.name,
8804
+ children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.anthropic })
8674
8805
  }
8675
8806
  ),
8676
- /* @__PURE__ */ jsxRuntimeExports.jsx(
8677
- "button",
8807
+ providerHasEndpoint(provider.openaiBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
8808
+ ProviderEndpointSummary,
8678
8809
  {
8679
- type: "button",
8680
- onClick: handleCopy,
8681
- className: "text-muted-foreground hover:text-foreground transition-colors p-1",
8682
- "aria-label": "Copy API key",
8683
- children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4 text-cyan-300" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" })
8810
+ label: "Chat",
8811
+ baseUrl: provider.openaiBaseUrl,
8812
+ endpoint: PATH_V1_CHAT_COMPLETIONS,
8813
+ providerName: provider.name,
8814
+ children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.openaiChat })
8684
8815
  }
8685
- )
8686
- ] }),
8687
- providerHasEndpoint(provider.anthropicBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
8688
- ProviderEndpointSummary,
8689
- {
8690
- label: "Test: Anthropic",
8691
- baseUrl: provider.anthropicBaseUrl,
8692
- endpoint: PATH_V1_MESSAGES,
8693
- providerName: provider.name,
8694
- children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.anthropic })
8695
- }
8696
- ),
8697
- providerHasEndpoint(provider.openaiBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
8698
- ProviderEndpointSummary,
8699
- {
8700
- label: "Test: Chat",
8701
- baseUrl: provider.openaiBaseUrl,
8702
- endpoint: PATH_V1_CHAT_COMPLETIONS,
8703
- providerName: provider.name,
8704
- children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.openaiChat })
8705
- }
8706
- ),
8707
- providerHasEndpoint(provider.openaiResponsesBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
8708
- ProviderEndpointSummary,
8709
- {
8710
- label: "Test: Responses",
8711
- baseUrl: provider.openaiResponsesBaseUrl,
8712
- endpoint: PATH_V1_RESPONSES,
8713
- providerName: provider.name,
8714
- children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.openaiResponses })
8715
- }
8716
- ),
8717
- testResults?.testedAt !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-1", children: [
8718
- /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
8719
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
8720
- "Tested ",
8721
- formatTimeAgo(testResults.testedAt)
8816
+ ),
8817
+ providerHasEndpoint(provider.openaiResponsesBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
8818
+ ProviderEndpointSummary,
8819
+ {
8820
+ label: "Responses",
8821
+ baseUrl: provider.openaiResponsesBaseUrl,
8822
+ endpoint: PATH_V1_RESPONSES,
8823
+ providerName: provider.name,
8824
+ children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.openaiResponses })
8825
+ }
8826
+ ),
8827
+ testResults?.models !== void 0 && Object.keys(testResults.models).length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8828
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
8829
+ "button",
8830
+ {
8831
+ type: "button",
8832
+ onClick: () => setShowModelResults((value) => !value),
8833
+ className: "flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground",
8834
+ children: [
8835
+ showModelResults ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3" }),
8836
+ "Model Test Results (",
8837
+ Object.keys(testResults.models).length,
8838
+ ")"
8839
+ ]
8840
+ }
8841
+ ),
8842
+ showModelResults && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full border-collapse text-xs", children: [
8843
+ /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border", children: [
8844
+ /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-1 text-left font-medium text-muted-foreground", children: "Model" }),
8845
+ providerHasEndpoint(provider.anthropicBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-1 text-left font-medium text-muted-foreground", children: "Anthropic" }),
8846
+ providerHasEndpoint(provider.openaiBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-1 text-left font-medium text-muted-foreground", children: "Chat" }),
8847
+ providerHasEndpoint(provider.openaiResponsesBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-1 text-left font-medium text-muted-foreground", children: "Responses" })
8848
+ ] }) }),
8849
+ /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: Object.entries(testResults.models).map(([modelName, modelResult]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border/50 last:border-0", children: [
8850
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1 font-medium", children: modelName }),
8851
+ providerHasEndpoint(provider.anthropicBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1 align-top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: modelResult.anthropic }) }),
8852
+ providerHasEndpoint(provider.openaiBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1 align-top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: modelResult.openaiChat }) }),
8853
+ providerHasEndpoint(provider.openaiResponsesBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1 align-top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: modelResult.openaiResponses }) })
8854
+ ] }, modelName)) })
8855
+ ] }) })
8722
8856
  ] })
8723
8857
  ] }),
8724
- testResults?.models !== void 0 && Object.keys(testResults.models).length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t pt-2", children: [
8858
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 border-t pt-1 sm:flex-row sm:items-center sm:justify-between", children: [
8725
8859
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
8726
8860
  "button",
8727
8861
  {
8728
8862
  type: "button",
8729
- onClick: () => setShowModelResults((value) => !value),
8730
- className: "text-xs text-muted-foreground hover:text-foreground transition-colors flex items-center gap-1",
8863
+ onClick: () => setShowDetails((value) => !value),
8864
+ className: "inline-flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground",
8865
+ "aria-expanded": showDetails,
8731
8866
  children: [
8732
- showModelResults ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3" }),
8733
- "Model Test Results (",
8734
- Object.keys(testResults.models).length,
8735
- ")"
8867
+ showDetails ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3" }),
8868
+ "Details"
8736
8869
  ]
8737
8870
  }
8738
8871
  ),
8739
- showModelResults && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs border-collapse", children: [
8740
- /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border", children: [
8741
- /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-1 px-2 font-medium text-muted-foreground", children: "Model" }),
8742
- provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-1 px-2 font-medium text-muted-foreground", children: "Anthropic" }),
8743
- provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-1 px-2 font-medium text-muted-foreground", children: "Chat" }),
8744
- provider.openaiResponsesBaseUrl !== void 0 && provider.openaiResponsesBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-1 px-2 font-medium text-muted-foreground", children: "Responses" })
8745
- ] }) }),
8746
- /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: Object.entries(testResults.models).map(([modelName, modelResult]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border/50 last:border-0", children: [
8747
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-1 px-2 font-medium", children: modelName }),
8748
- provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-1 px-2 align-top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: modelResult.anthropic }) }),
8749
- provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-1 px-2 align-top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: modelResult.openaiChat }) }),
8750
- provider.openaiResponsesBaseUrl !== void 0 && provider.openaiResponsesBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-1 px-2 align-top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: modelResult.openaiResponses }) })
8751
- ] }, modelName)) })
8752
- ] }) })
8753
- ] }),
8754
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 pt-1 border-t sm:flex-row sm:items-center sm:justify-between", children: [
8755
- /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderTestCoverage, { provider }),
8756
8872
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
8757
8873
  onTest !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
8758
8874
  Button,
@@ -8761,10 +8877,10 @@ function ProviderCard({
8761
8877
  size: "sm",
8762
8878
  onClick: () => onTest(provider.id),
8763
8879
  className: "text-xs h-7 gap-1",
8764
- disabled: isTesting ?? false,
8880
+ disabled: isTestingValue,
8765
8881
  children: [
8766
- /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: `size-3 ${isTesting ?? false ? "animate-spin" : ""}` }),
8767
- isTesting ?? false ? testingTimeLeft !== void 0 ? `Testing (${testingTimeLeft}s)` : "Testing..." : "Test"
8882
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: `size-3 ${isTestingValue ? "animate-spin" : ""}` }),
8883
+ isTestingValue ? testingTimeLeft !== void 0 ? `Testing (${testingTimeLeft}s)` : "Testing..." : "Test"
8768
8884
  ]
8769
8885
  }
8770
8886
  ),
@@ -8775,7 +8891,7 @@ function ProviderCard({
8775
8891
  size: "sm",
8776
8892
  onClick: () => onEdit(provider),
8777
8893
  className: "text-xs h-7 gap-1",
8778
- disabled: isTesting ?? false,
8894
+ disabled: isTestingValue,
8779
8895
  children: [
8780
8896
  /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3" }),
8781
8897
  "Edit"
@@ -8789,7 +8905,7 @@ function ProviderCard({
8789
8905
  size: "sm",
8790
8906
  onClick: () => onDelete(provider.id),
8791
8907
  className: "text-xs h-7 gap-1 text-destructive hover:text-destructive",
8792
- disabled: isTesting ?? false,
8908
+ disabled: isTestingValue,
8793
8909
  children: [
8794
8910
  /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3" }),
8795
8911
  "Delete"
@@ -11000,6 +11116,322 @@ function ProxySettingsTab() {
11000
11116
  ] })
11001
11117
  ] });
11002
11118
  }
11119
+ const EcosystemPackageStateSchema = _enum([
11120
+ "installed",
11121
+ "update-available",
11122
+ "available",
11123
+ "planned",
11124
+ "unknown"
11125
+ ]);
11126
+ const EcosystemPackageSchema = object({
11127
+ id: string(),
11128
+ name: string(),
11129
+ npmName: string(),
11130
+ capability: string(),
11131
+ description: string(),
11132
+ workflow: string(),
11133
+ installCommand: string(),
11134
+ state: EcosystemPackageStateSchema,
11135
+ installedVersion: string().nullable(),
11136
+ latestVersion: string().nullable(),
11137
+ primary: boolean()
11138
+ });
11139
+ const EcosystemRunnerPresetSchema = object({
11140
+ id: string(),
11141
+ name: string(),
11142
+ validatedVersion: string(),
11143
+ binary: string(),
11144
+ modelFlag: string(),
11145
+ variantFlag: string().nullable(),
11146
+ tools: array(string()),
11147
+ logDir: string(),
11148
+ skillsDir: string(),
11149
+ agentsDir: string()
11150
+ });
11151
+ const EcosystemPackagesResponseSchema = object({
11152
+ checkedAt: string(),
11153
+ packages: array(EcosystemPackageSchema),
11154
+ runnerPresets: array(EcosystemRunnerPresetSchema)
11155
+ });
11156
+ const WORKFLOWS = [
11157
+ {
11158
+ id: "observe",
11159
+ title: "Observe",
11160
+ label: "Live",
11161
+ description: "Capture IDE, process, session, turn, request, response, tools, and providers.",
11162
+ metric: "Inspector core",
11163
+ icon: Activity
11164
+ },
11165
+ {
11166
+ id: "replay",
11167
+ title: "Replay",
11168
+ label: "Ready",
11169
+ description: "Promote real logs into repeatable replay evidence without losing the raw context.",
11170
+ metric: "Session asset",
11171
+ icon: RefreshCw
11172
+ },
11173
+ {
11174
+ id: "evaluate",
11175
+ title: "Evaluate",
11176
+ label: "Next",
11177
+ description: "Use eval-harness to turn sessions into regression cases and provider bakeoffs.",
11178
+ metric: "Eval loop",
11179
+ icon: Beaker
11180
+ },
11181
+ {
11182
+ id: "connect",
11183
+ title: "Connect",
11184
+ label: "MCP",
11185
+ description: "Expose Inspector state to coding agents as queryable context and durable evidence.",
11186
+ metric: "/api/mcp",
11187
+ icon: Network
11188
+ }
11189
+ ];
11190
+ async function fetchEcosystemPackages(url) {
11191
+ return fetchJson(
11192
+ url,
11193
+ EcosystemPackagesResponseSchema,
11194
+ void 0,
11195
+ (response) => `Failed to load ecosystem packages: ${String(response.status)}`
11196
+ );
11197
+ }
11198
+ function stateLabel(state) {
11199
+ switch (state) {
11200
+ case "installed":
11201
+ return "Installed";
11202
+ case "update-available":
11203
+ return "Update";
11204
+ case "available":
11205
+ return "Available";
11206
+ case "planned":
11207
+ return "Planned";
11208
+ case "unknown":
11209
+ return "Unknown";
11210
+ }
11211
+ }
11212
+ function stateClassName(state) {
11213
+ switch (state) {
11214
+ case "installed":
11215
+ return "border-emerald-400/20 bg-emerald-400/8 text-emerald-200";
11216
+ case "update-available":
11217
+ return "border-amber-400/20 bg-amber-400/8 text-amber-200";
11218
+ case "available":
11219
+ return "border-sky-400/20 bg-sky-400/8 text-sky-200";
11220
+ case "planned":
11221
+ return "border-white/10 bg-white/[0.04] text-white/55";
11222
+ case "unknown":
11223
+ return "border-white/10 bg-white/[0.04] text-white/45";
11224
+ }
11225
+ }
11226
+ function versionLabel(pkg) {
11227
+ if (pkg.installedVersion !== null && pkg.latestVersion !== null) {
11228
+ if (pkg.installedVersion === pkg.latestVersion) return `v${pkg.installedVersion}`;
11229
+ return `v${pkg.installedVersion} -> v${pkg.latestVersion}`;
11230
+ }
11231
+ if (pkg.installedVersion !== null) return `v${pkg.installedVersion}`;
11232
+ if (pkg.latestVersion !== null) return `latest v${pkg.latestVersion}`;
11233
+ return "not published";
11234
+ }
11235
+ function PackageStatusCard({ pkg }) {
11236
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg bg-white/[0.025] p-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.055)]", children: [
11237
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
11238
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
11239
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
11240
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PackageCheck, { className: "size-4 shrink-0 text-white/55" }),
11241
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-sm font-semibold", children: pkg.name })
11242
+ ] }),
11243
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-white/35", children: pkg.npmName })
11244
+ ] }),
11245
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: cn("shrink-0", stateClassName(pkg.state)), variant: "outline", children: stateLabel(pkg.state) })
11246
+ ] }),
11247
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 text-xs leading-5 text-muted-foreground", children: pkg.description }),
11248
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2 text-[11px]", children: [
11249
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded bg-white/[0.035] px-2 py-1 font-mono text-white/50", children: versionLabel(pkg) }),
11250
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded bg-white/[0.035] px-2 py-1 text-white/45", children: pkg.capability }),
11251
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded bg-white/[0.035] px-2 py-1 font-mono text-white/35", children: pkg.installCommand })
11252
+ ] })
11253
+ ] });
11254
+ }
11255
+ function WorkflowTile({ workflow }) {
11256
+ const Icon2 = workflow.icon;
11257
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg bg-white/[0.025] p-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.055)]", children: [
11258
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
11259
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
11260
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: "size-4 shrink-0 text-cyan-200/75" }),
11261
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-sm font-semibold", children: workflow.title })
11262
+ ] }),
11263
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded bg-white/[0.04] px-2 py-0.5 font-mono text-[10px] text-white/45", children: workflow.label })
11264
+ ] }),
11265
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 min-h-10 text-xs leading-5 text-muted-foreground", children: workflow.description }),
11266
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 font-mono text-[11px] text-white/35", children: workflow.metric })
11267
+ ] });
11268
+ }
11269
+ function buildSessionCommand(sessionId) {
11270
+ if (sessionId === null) {
11271
+ return 'npx @tonyclaw/eval-harness inspector-smoke --title "TonyClaw Lab smoke" --latest-log-limit 5';
11272
+ }
11273
+ return `npx @tonyclaw/eval-harness inspector-smoke --title "TonyClaw Lab smoke ${sessionId}" --latest-log-limit 5`;
11274
+ }
11275
+ function RunnerPresetCard({ preset }) {
11276
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg bg-white/[0.025] p-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.055)]", children: [
11277
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
11278
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
11279
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
11280
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Rocket, { className: "size-4 shrink-0 text-cyan-200/75" }),
11281
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-sm font-semibold", children: preset.name })
11282
+ ] }),
11283
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-[11px] text-white/35", children: [
11284
+ preset.binary,
11285
+ " ",
11286
+ preset.modelFlag,
11287
+ preset.variantFlag !== null ? ` ${preset.variantFlag}` : ""
11288
+ ] })
11289
+ ] }),
11290
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "border-white/10 bg-white/[0.04] text-white/55", children: [
11291
+ "v",
11292
+ preset.validatedVersion
11293
+ ] })
11294
+ ] }),
11295
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 grid grid-cols-2 gap-2 text-[11px]", children: [
11296
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded bg-black/15 px-2 py-1 text-white/45", children: [
11297
+ "logs/",
11298
+ preset.logDir
11299
+ ] }),
11300
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded bg-black/15 px-2 py-1 text-white/45", children: preset.tools.join(", ") }),
11301
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded bg-black/15 px-2 py-1 font-mono text-white/35", children: preset.skillsDir }),
11302
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded bg-black/15 px-2 py-1 font-mono text-white/35", children: preset.agentsDir })
11303
+ ] })
11304
+ ] });
11305
+ }
11306
+ function AgentLabDialog({ currentSessionId, logCount }) {
11307
+ const [open, setOpen] = reactExports.useState(false);
11308
+ const [copied, setCopied] = reactExports.useState(false);
11309
+ const [copiedPresets, setCopiedPresets] = reactExports.useState(false);
11310
+ const response = useSWR("/api/ecosystem/packages", fetchEcosystemPackages, {
11311
+ revalidateOnFocus: false,
11312
+ revalidateIfStale: false
11313
+ });
11314
+ const packages = response.data?.packages ?? [];
11315
+ const runnerPresets = response.data?.runnerPresets ?? [];
11316
+ const installedCount = reactExports.useMemo(
11317
+ () => packages.filter((pkg) => pkg.state === "installed" || pkg.state === "update-available").length,
11318
+ [packages]
11319
+ );
11320
+ const sessionCommand = buildSessionCommand(currentSessionId);
11321
+ const presetsCommand = "npx @tonyclaw/eval-harness runner-presets";
11322
+ const copySessionCommand = () => {
11323
+ void copyTextToClipboard(sessionCommand).then(() => {
11324
+ setCopied(true);
11325
+ window.setTimeout(() => setCopied(false), 1200);
11326
+ });
11327
+ };
11328
+ const copyPresetsCommand = () => {
11329
+ void copyTextToClipboard(presetsCommand).then(() => {
11330
+ setCopiedPresets(true);
11331
+ window.setTimeout(() => setCopiedPresets(false), 1200);
11332
+ });
11333
+ };
11334
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open, onOpenChange: setOpen, children: [
11335
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
11336
+ Button,
11337
+ {
11338
+ variant: "ghost",
11339
+ size: "icon",
11340
+ className: INSPECTOR_ICON_TRIGGER_CLASS,
11341
+ "aria-label": "TonyClaw Lab",
11342
+ title: "TonyClaw Lab",
11343
+ children: [
11344
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FlaskConical, { className: "size-4" }),
11345
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "TonyClaw Lab" })
11346
+ ]
11347
+ }
11348
+ ) }),
11349
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "flex max-h-[84vh] max-w-5xl flex-col overflow-hidden", children: [
11350
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
11351
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "size-4 text-cyan-200/80" }),
11352
+ "TonyClaw Lab"
11353
+ ] }) }),
11354
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-y-auto pr-2", children: [
11355
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-3 lg:grid-cols-[1.1fr_0.9fr]", children: [
11356
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "rounded-lg bg-white/[0.025] p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.055)]", children: [
11357
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
11358
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
11359
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold", children: "Session asset pipeline" }),
11360
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 max-w-2xl text-xs leading-5 text-muted-foreground", children: "Treat captured traffic as durable assets: observe it, replay it, evaluate it, and expose it back to agents through MCP." })
11361
+ ] }),
11362
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "border-cyan-300/20 bg-cyan-300/8 text-cyan-100", children: [
11363
+ String(installedCount),
11364
+ "/",
11365
+ String(packages.length),
11366
+ " packages"
11367
+ ] })
11368
+ ] }),
11369
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4 grid gap-3 sm:grid-cols-2", children: WORKFLOWS.map((workflow) => /* @__PURE__ */ jsxRuntimeExports.jsx(WorkflowTile, { workflow }, workflow.id)) })
11370
+ ] }),
11371
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "rounded-lg bg-white/[0.025] p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.055)]", children: [
11372
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
11373
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
11374
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold", children: "Current session" }),
11375
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: currentSessionId === null ? "MCP smoke command" : currentSessionId })
11376
+ ] }),
11377
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "border-white/10 bg-white/[0.04] text-white/55", children: [
11378
+ String(logCount),
11379
+ " logs"
11380
+ ] })
11381
+ ] }),
11382
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4 rounded-md bg-black/20 p-3 font-mono text-[11px] leading-5 text-white/55 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.045)]", children: sessionCommand }),
11383
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
11384
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", variant: "secondary", onClick: copySessionCommand, children: [
11385
+ copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" }),
11386
+ copied ? "Copied" : "Copy"
11387
+ ] }),
11388
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", variant: "outline", onClick: copyPresetsCommand, children: [
11389
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Beaker, { className: "size-3.5" }),
11390
+ copiedPresets ? "Presets copied" : "Runner Presets"
11391
+ ] })
11392
+ ] })
11393
+ ] })
11394
+ ] }),
11395
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mt-3", children: [
11396
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
11397
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold", children: "Runner presets" }),
11398
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "hidden items-center gap-1 font-mono text-[11px] text-muted-foreground sm:flex", children: [
11399
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5" }),
11400
+ presetsCommand
11401
+ ] })
11402
+ ] }),
11403
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-4", children: [
11404
+ runnerPresets.map((preset) => /* @__PURE__ */ jsxRuntimeExports.jsx(RunnerPresetCard, { preset }, preset.id)),
11405
+ response.isLoading && runnerPresets.length === 0 && [0, 1, 2, 3].map((index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
11406
+ "div",
11407
+ {
11408
+ className: "h-32 animate-pulse rounded-lg bg-white/[0.025] shadow-[inset_0_0_0_1px_rgba(255,255,255,0.055)]"
11409
+ },
11410
+ index
11411
+ ))
11412
+ ] })
11413
+ ] }),
11414
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mt-3", children: [
11415
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
11416
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold", children: "TonyClaw packages" }),
11417
+ response.isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-[11px] text-muted-foreground", children: "checking npm..." })
11418
+ ] }),
11419
+ response.error !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-lg bg-red-500/8 p-3 text-xs text-red-100 shadow-[inset_0_0_0_1px_rgba(248,113,113,0.16)]", children: "Package status is temporarily unavailable." }),
11420
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-3 md:grid-cols-3", children: [
11421
+ packages.map((pkg) => /* @__PURE__ */ jsxRuntimeExports.jsx(PackageStatusCard, { pkg }, pkg.id)),
11422
+ response.isLoading && packages.length === 0 && [0, 1, 2].map((index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
11423
+ "div",
11424
+ {
11425
+ className: "h-36 animate-pulse rounded-lg bg-white/[0.025] shadow-[inset_0_0_0_1px_rgba(255,255,255,0.055)]"
11426
+ },
11427
+ index
11428
+ ))
11429
+ ] })
11430
+ ] })
11431
+ ] })
11432
+ ] })
11433
+ ] });
11434
+ }
11003
11435
  function computeCacheTrends(groups) {
11004
11436
  const result = /* @__PURE__ */ new Map();
11005
11437
  for (const group of groups) {
@@ -13392,7 +13824,9 @@ function CrabFamily({
13392
13824
  }
13393
13825
  function BrandHeader({
13394
13826
  compact,
13395
- crabEntrancePhase
13827
+ crabEntrancePhase,
13828
+ currentSessionId,
13829
+ logCount
13396
13830
  }) {
13397
13831
  if (compact) {
13398
13832
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("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: [
@@ -13413,6 +13847,7 @@ function BrandHeader({
13413
13847
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
13414
13848
  /* @__PURE__ */ jsxRuntimeExports.jsx(AlertsDialog, {}),
13415
13849
  /* @__PURE__ */ jsxRuntimeExports.jsx(GroupsDialog, {}),
13850
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AgentLabDialog, { currentSessionId, logCount }),
13416
13851
  /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsDialog, {})
13417
13852
  ] })
13418
13853
  ] }),
@@ -13440,6 +13875,7 @@ function BrandHeader({
13440
13875
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "justify-self-end flex items-center gap-1", children: [
13441
13876
  /* @__PURE__ */ jsxRuntimeExports.jsx(AlertsDialog, {}),
13442
13877
  /* @__PURE__ */ jsxRuntimeExports.jsx(GroupsDialog, {}),
13878
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AgentLabDialog, { currentSessionId, logCount }),
13443
13879
  /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsDialog, {})
13444
13880
  ] })
13445
13881
  ] });
@@ -13903,10 +14339,19 @@ function ProxyViewer({
13903
14339
  },
13904
14340
  [onSessionChange]
13905
14341
  );
14342
+ const labSessionId = pinnedSessionId !== void 0 ? pinnedSessionId : selectedSession === "__all__" ? null : selectedSession;
13906
14343
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-background min-h-screen w-full text-foreground", children: [
13907
14344
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid min-h-screen w-full grid-cols-1 lg:grid-cols-[minmax(0,1fr)_340px] xl:grid-cols-[minmax(0,1fr)_360px]", children: [
13908
14345
  /* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "bg-background/95 order-1 border-b border-white/[0.045] lg:sticky lg:top-0 lg:order-2 lg:h-screen lg:overflow-y-auto lg:border-b-0 lg:border-l lg:border-white/[0.055]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 p-4", children: [
13909
- /* @__PURE__ */ jsxRuntimeExports.jsx(BrandHeader, { compact: true, crabEntrancePhase }),
14346
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
14347
+ BrandHeader,
14348
+ {
14349
+ compact: true,
14350
+ crabEntrancePhase,
14351
+ currentSessionId: labSessionId,
14352
+ logCount: logs.length
14353
+ }
14354
+ ),
13910
14355
  /* @__PURE__ */ jsxRuntimeExports.jsxs(SidebarPanel, { label: "Session", children: [
13911
14356
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
13912
14357
  /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarMetric, { label: "Requests", value: logs.length }),