@tonyclaw/agent-inspector 2.1.13 → 2.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/assets/CompareDrawer-BcEd6V-V.js +1 -0
- package/.output/public/assets/ProxyViewerContainer-h851qWNp.js +106 -0
- package/.output/public/assets/ReplayDialog-BNpC0548.js +1 -0
- package/.output/public/assets/{RequestAnatomy-BjlBT-Cy.js → RequestAnatomy-Ds1uRLVB.js} +1 -1
- package/.output/public/assets/ResponseView-7KPVqKl5.js +3 -0
- package/.output/public/assets/{StreamingChunkSequence-D2_SMhlE.js → StreamingChunkSequence-BHQT261s.js} +1 -1
- package/.output/public/assets/_sessionId-DWePGjnS.js +1 -0
- package/.output/public/assets/index-CI1-G8ua.js +1 -0
- package/.output/public/assets/index-DdhFqPsI.css +1 -0
- package/.output/public/assets/index-DjKt8XKe.js +14 -0
- package/.output/public/assets/json-viewer-CkCu-rka.js +1 -0
- package/.output/public/assets/{main-Dtspb4Ui.js → main-DpD1N0S8.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +194 -200
- package/.output/server/_libs/react-markdown.mjs +90 -2
- package/.output/server/{_sessionId-CXDcLuvi.mjs → _sessionId-DF9Sy8cP.mjs} +6 -57
- package/.output/server/_ssr/{CompareDrawer-CMoCAoeq.mjs → CompareDrawer-BoxztaO7.mjs} +50 -74
- package/.output/server/_ssr/{ProxyViewerContainer-BW2vVCBN.mjs → ProxyViewerContainer-CRBkqFlJ.mjs} +1221 -799
- package/.output/server/_ssr/{ReplayDialog-ChXL1t8H.mjs → ReplayDialog-Cc1dyDuK.mjs} +18 -62
- package/.output/server/_ssr/{RequestAnatomy-DtKzIlfU.mjs → RequestAnatomy-CMGSsz5Z.mjs} +6 -57
- package/.output/server/_ssr/{ResponseView-B5I8drzc.mjs → ResponseView-Cp10DM1D.mjs} +139 -61
- package/.output/server/_ssr/{StreamingChunkSequence-DvwjQNcO.mjs → StreamingChunkSequence-B1VGxy3A.mjs} +13 -58
- package/.output/server/_ssr/{index-D_ZHtRfl.mjs → index-47XVPghS.mjs} +6 -57
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/json-viewer-zDE2rrmJ.mjs +478 -0
- package/.output/server/_ssr/{router-DhL9Wp3N.mjs → router-DVeuZFqI.mjs} +680 -174
- package/.output/server/{_tanstack-start-manifest_v-BHgoAmxZ.mjs → _tanstack-start-manifest_v-Bp8JxtPW.mjs} +1 -1
- package/.output/server/index.mjs +72 -58
- package/package.json +1 -1
- package/src/components/ProxyViewer.tsx +28 -2
- package/src/components/ProxyViewerContainer.tsx +25 -17
- package/src/components/clients/ClientLogo.tsx +132 -0
- package/src/components/groups/GroupsDialog.tsx +18 -13
- package/src/components/providers/ImportWizardDialog.tsx +7 -1
- package/src/components/providers/ProviderCard.tsx +10 -1
- package/src/components/providers/ProviderForm.tsx +157 -41
- package/src/components/providers/ProvidersPanel.tsx +5 -1
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +56 -23
- package/src/components/proxy-viewer/AnswerMarkdown.tsx +8 -3
- package/src/components/proxy-viewer/CompareDrawer.tsx +58 -14
- package/src/components/proxy-viewer/ConversationGroup.tsx +11 -15
- package/src/components/proxy-viewer/ConversationHeader.tsx +33 -41
- package/src/components/proxy-viewer/LogEntry.tsx +41 -12
- package/src/components/proxy-viewer/LogEntryHeader.tsx +122 -51
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +60 -0
- package/src/components/proxy-viewer/ReplayDialog.tsx +8 -2
- package/src/components/proxy-viewer/RequestToolsPanel.tsx +19 -13
- package/src/components/proxy-viewer/StreamingChunkSequence.tsx +9 -3
- package/src/components/proxy-viewer/ThreadConnector.tsx +18 -7
- package/src/components/proxy-viewer/TurnGroup.tsx +67 -32
- package/src/components/proxy-viewer/TurnGroupList.tsx +153 -0
- package/src/components/proxy-viewer/anatomy/sessionContextSummary.ts +74 -2
- package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +13 -7
- package/src/components/proxy-viewer/formats/index.tsx +10 -3
- package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +185 -17
- package/src/components/proxy-viewer/log-formats/openai.ts +107 -15
- package/src/components/proxy-viewer/logFocus.ts +15 -2
- package/src/components/proxy-viewer/requestTools.ts +7 -3
- package/src/components/proxy-viewer/viewerState.ts +77 -5
- package/src/components/ui/json-viewer-bulk.ts +41 -6
- package/src/components/ui/json-viewer.tsx +9 -8
- package/src/contracts/index.ts +15 -1
- package/src/contracts/openai.ts +94 -0
- package/src/lib/providerContract.ts +1 -0
- package/src/lib/providerModelMetadata.ts +7 -1
- package/src/lib/sessionInfoContract.ts +1 -0
- package/src/lib/stopReason.ts +59 -15
- package/src/lib/upstreamUrl.ts +46 -0
- package/src/mcp/previewExtractor.ts +73 -3
- package/src/mcp/server.ts +2 -0
- package/src/mcp/toolHandlers.ts +2 -0
- package/src/proxy/constants.ts +2 -0
- package/src/proxy/formats/openai/handler.ts +40 -9
- package/src/proxy/formats/openai/index.ts +7 -0
- package/src/proxy/formats/openai/schemas.ts +15 -1
- package/src/proxy/formats/openai/stream.ts +529 -135
- package/src/proxy/formats/registry.ts +9 -1
- package/src/proxy/providerImporters.ts +45 -5
- package/src/proxy/providers.ts +31 -11
- package/src/proxy/schemas.ts +6 -0
- package/src/proxy/sessionInfo.ts +5 -1
- package/src/proxy/toolSchemaWarnings.ts +25 -3
- package/src/proxy/upstream.ts +18 -37
- package/src/routes/api/providers.$providerId.ts +1 -0
- package/src/routes/api/providers.ts +2 -0
- package/.output/public/assets/CompareDrawer-Cz_1vIpR.js +0 -1
- package/.output/public/assets/ProxyViewerContainer-7QSiluMf.js +0 -117
- package/.output/public/assets/ReplayDialog-sBA1KAYD.js +0 -1
- package/.output/public/assets/ResponseView-PtEKzml9.js +0 -1
- package/.output/public/assets/_sessionId-DZfB4ruK.js +0 -1
- package/.output/public/assets/index-B-QQLbpz.js +0 -1
- package/.output/public/assets/index-CmtfjQPv.css +0 -1
package/.output/server/_ssr/{ProxyViewerContainer-BW2vVCBN.mjs → ProxyViewerContainer-CRBkqFlJ.mjs}
RENAMED
|
@@ -1,16 +1,15 @@
|
|
|
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,
|
|
2
|
+
import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as GroupEvidenceExportResultSchema, o as DeleteInspectorGroupResponseSchema, v as createPendingProviderTestResults, w as ProviderTestResultsSchema, x as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, y as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, j as getSessionPath, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, t as maskApiKey, q as providerHasContextMetadata, r as findProviderModelMetadata, s as safeGetOwnProperty, K as KnowledgeCandidateSchema, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, z as resolveProviderContextWindow, u as buildUpstreamUrl, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema, B as isPlainRecord } from "./router-DVeuZFqI.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";
|
|
6
6
|
import { t as twMerge } from "../_libs/tailwind-merge.mjs";
|
|
7
7
|
import { R as Root, T as Trigger$1, C as Content, a as Close, b as Title, D as Description, P as Portal$2, O as Overlay } from "../_libs/radix-ui__react-dialog.mjs";
|
|
8
8
|
import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
9
|
-
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
10
9
|
import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
10
|
+
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
11
11
|
import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
|
|
12
|
-
import { I as Info, C as ChevronDown, a as Check, X, U as Upload, D as Download, F as FileBraces, T as Trash2, P as Plus, A as ArrowLeft, b as ChevronUp, c as Copy, d as ChevronsLeft, e as ChevronLeft, f as ChevronRight, g as ChevronsRight, h as Clapperboard, S as Siren, G as Gauge, L as LoaderCircle, R as RefreshCw, i as Layers, j as Settings, k as Scan, l as CircleAlert, m as Terminal, n as ArrowUpRight, o as ArrowDownRight, p as
|
|
13
|
-
import { M as Markdown } from "../_libs/react-markdown.mjs";
|
|
12
|
+
import { I as Info, C as ChevronDown, a as Check, X, U as Upload, D as Download, F as FileBraces, T as Trash2, P as Plus, A as ArrowLeft, b as ChevronUp, c as Copy, d as ChevronsLeft, e as ChevronLeft, f as ChevronRight, g as ChevronsRight, h as Clapperboard, S as Siren, G as Gauge, L as LoaderCircle, R as RefreshCw, i as Layers, j as Settings, k as Scan, l as CircleAlert, m as Terminal, n as ArrowUpRight, o as ArrowDownRight, p as Clock, M as MessageSquare, Z as Zap, E as ExternalLink, W as Wrench, q as TriangleAlert, B as Brain, r as Bell, s as Clock3, t as ShieldAlert, u as EyeOff, v as Eye, w as RotateCw, x as Pencil, y as CircleX, z as ShieldCheck, H as Save, J as FileSearch, K as CircleCheck, N as CloudUpload, O as Minus, Q as CircleCheckBig, V as CircleQuestionMark, Y as Server, _ as Lock, $ as Wifi, a0 as WifiOff, a1 as OctagonAlert, a2 as Radio, a3 as Globe, a4 as FileTerminal, a5 as ChevronsUp, a6 as ChevronsDown, a7 as FileDiff, a8 as History, a9 as RotateCcw, aa as Search, ab as GitCompareArrows, ac as ArrowUp, ad as ArrowDown, ae as Ellipsis, af as CodeXml, ag as Blocks, ah as MousePointerClick, ai as FileText, aj as Rows3, ak as Columns2 } from "../_libs/lucide-react.mjs";
|
|
14
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";
|
|
15
14
|
import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
|
|
16
15
|
import { R as Root2$1, L as List, T as Trigger$2, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
|
|
@@ -772,6 +771,111 @@ function ConfirmDialog({
|
|
|
772
771
|
] })
|
|
773
772
|
] }) });
|
|
774
773
|
}
|
|
774
|
+
const CLIENT_LABELS = {
|
|
775
|
+
codex: "Codex",
|
|
776
|
+
opencode: "OpenCode",
|
|
777
|
+
"mimo-code": "MiMo Code",
|
|
778
|
+
"claude-code": "Claude Code"
|
|
779
|
+
};
|
|
780
|
+
function normalize(value) {
|
|
781
|
+
return value?.toLowerCase() ?? "";
|
|
782
|
+
}
|
|
783
|
+
function matchesAny(value, candidates) {
|
|
784
|
+
for (const candidate of candidates) {
|
|
785
|
+
if (value.includes(candidate)) return true;
|
|
786
|
+
}
|
|
787
|
+
return false;
|
|
788
|
+
}
|
|
789
|
+
function detectClientApp(input) {
|
|
790
|
+
const haystack = [
|
|
791
|
+
normalize(input.userAgent),
|
|
792
|
+
normalize(input.conversationId),
|
|
793
|
+
normalize(input.clientProjectFolder)
|
|
794
|
+
].join(" ");
|
|
795
|
+
if (matchesAny(haystack, ["mimocode", "mimo-code", "mimo code"])) return "mimo-code";
|
|
796
|
+
if (matchesAny(haystack, ["opencode", "open-code", "open code"])) return "opencode";
|
|
797
|
+
if (matchesAny(haystack, ["claude-code", "claude code", "claudecode"])) return "claude-code";
|
|
798
|
+
if (matchesAny(haystack, ["codex desktop", "codex-cli", "openai-codex", "codex"])) {
|
|
799
|
+
return "codex";
|
|
800
|
+
}
|
|
801
|
+
return "unknown";
|
|
802
|
+
}
|
|
803
|
+
function clientAppLabel(client) {
|
|
804
|
+
switch (client) {
|
|
805
|
+
case "codex":
|
|
806
|
+
case "opencode":
|
|
807
|
+
case "mimo-code":
|
|
808
|
+
case "claude-code":
|
|
809
|
+
return CLIENT_LABELS[client];
|
|
810
|
+
case "unknown":
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
function CodexMark() {
|
|
815
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: [
|
|
816
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2.2" }),
|
|
817
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
818
|
+
"path",
|
|
819
|
+
{
|
|
820
|
+
d: "M14.8 8.6a4.8 4.8 0 1 0 0 6.8",
|
|
821
|
+
fill: "none",
|
|
822
|
+
stroke: "currentColor",
|
|
823
|
+
strokeLinecap: "round",
|
|
824
|
+
strokeWidth: "2.2"
|
|
825
|
+
}
|
|
826
|
+
)
|
|
827
|
+
] });
|
|
828
|
+
}
|
|
829
|
+
function OpenCodeMark() {
|
|
830
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: [
|
|
831
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7 4h10v16H7z", fill: "none", stroke: "currentColor", strokeWidth: "2.2" }),
|
|
832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M10 8h4M10 12h4M10 16h2", stroke: "currentColor", strokeLinecap: "round" })
|
|
833
|
+
] });
|
|
834
|
+
}
|
|
835
|
+
function MiMoCodeMark() {
|
|
836
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
837
|
+
"path",
|
|
838
|
+
{
|
|
839
|
+
d: "M5 18V6h3.2l3.8 6.1L15.8 6H19v12h-3V11.3l-3.1 5h-1.8L8 11.3V18z",
|
|
840
|
+
fill: "currentColor"
|
|
841
|
+
}
|
|
842
|
+
) });
|
|
843
|
+
}
|
|
844
|
+
function ClaudeCodeMark() {
|
|
845
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
846
|
+
"path",
|
|
847
|
+
{
|
|
848
|
+
fill: "currentColor",
|
|
849
|
+
fillRule: "evenodd",
|
|
850
|
+
clipRule: "evenodd",
|
|
851
|
+
d: "M21 10.95h3v3.1h-3v3.03h-1.49V20H18v-2.92h-1.49V20H15v-2.92H9V20H7.49v-2.92H6V20H4.49v-2.92H3v-3.03H0v-3.1h3V5h18v5.95zM6 10.95h1.49V8.1H6v2.85zm10.51 0H18V8.1h-1.49v2.85z"
|
|
852
|
+
}
|
|
853
|
+
) });
|
|
854
|
+
}
|
|
855
|
+
function ClientLogo({
|
|
856
|
+
client,
|
|
857
|
+
className
|
|
858
|
+
}) {
|
|
859
|
+
const label = clientAppLabel(client);
|
|
860
|
+
if (label === null) return null;
|
|
861
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
862
|
+
"span",
|
|
863
|
+
{
|
|
864
|
+
className: cn(
|
|
865
|
+
"inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-white/10 bg-black/20 p-1 text-cyan-100 shadow-[inset_0_1px_0_rgba(255,255,255,0.05)]",
|
|
866
|
+
className
|
|
867
|
+
),
|
|
868
|
+
"aria-label": label,
|
|
869
|
+
title: label,
|
|
870
|
+
children: [
|
|
871
|
+
client === "codex" && /* @__PURE__ */ jsxRuntimeExports.jsx(CodexMark, {}),
|
|
872
|
+
client === "opencode" && /* @__PURE__ */ jsxRuntimeExports.jsx(OpenCodeMark, {}),
|
|
873
|
+
client === "mimo-code" && /* @__PURE__ */ jsxRuntimeExports.jsx(MiMoCodeMark, {}),
|
|
874
|
+
client === "claude-code" && /* @__PURE__ */ jsxRuntimeExports.jsx(ClaudeCodeMark, {})
|
|
875
|
+
]
|
|
876
|
+
}
|
|
877
|
+
);
|
|
878
|
+
}
|
|
775
879
|
const AnthropicLogoSvg = "data:image/svg+xml,%3csvg%20height='2500'%20viewBox='0%206.603%201192.672%201193.397'%20width='2500'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='m233.96%20800.215%20234.684-131.678%203.947-11.436-3.947-6.363h-11.436l-39.221-2.416-134.094-3.624-116.296-4.832-112.67-6.04-28.35-6.04-26.577-35.035%202.738-17.477%2023.84-16.027%2034.147%202.98%2075.463%205.155%20113.235%207.812%2082.147%204.832%20121.692%2012.644h19.329l2.738-7.812-6.604-4.832-5.154-4.832-117.182-79.41-126.845-83.92-66.443-48.321-35.92-24.484-18.12-22.953-7.813-50.093%2032.618-35.92%2043.812%202.98%2011.195%202.98%2044.375%2034.147%2094.792%2073.37%20123.786%2091.167%2018.12%2015.06%207.249-5.154.886-3.624-8.135-13.61-67.329-121.692-71.838-123.785-31.974-51.302-8.456-30.765c-2.98-12.645-5.154-23.275-5.154-36.242l37.127-50.416%2020.537-6.604%2049.53%206.604%2020.86%2018.121%2030.765%2070.39%2049.852%20110.818%2077.315%20150.684%2022.631%2044.698%2012.08%2041.396%204.51%2012.645h7.813v-7.248l6.362-84.886%2011.759-104.215%2011.436-134.094%203.946-37.772%2018.685-45.262%2037.127-24.482%2028.994%2013.852%2023.839%2034.148-3.303%2022.067-14.174%2092.134-27.785%20144.323-18.121%2096.644h10.55l12.08-12.08%2048.887-64.913%2082.147-102.685%2036.242-40.752%2042.282-45.02%2027.14-21.423h51.303l37.772%2056.135-16.913%2057.986-52.832%2067.007-43.812%2056.779-62.82%2084.563-39.22%2067.651%203.623%205.396%209.343-.886%20141.906-30.201%2076.671-13.852%2091.49-15.705%2041.396%2019.329%204.51%2019.65-16.269%2040.189-97.852%2024.16-114.764%2022.954-170.9%2040.43-2.093%201.53%202.416%202.98%2076.993%207.248%2032.94%201.771h80.617l150.12%2011.195%2039.222%2025.933%2023.517%2031.732-3.946%2024.16-60.403%2030.766-81.503-19.33-190.228-45.26-65.235-16.27h-9.02v5.397l54.362%2053.154%2099.624%2089.96%20124.752%20115.973%206.362%2028.671-16.027%2022.63-16.912-2.415-109.611-82.47-42.282-37.127-95.758-80.618h-6.363v8.456l22.067%2032.296%20116.537%20175.167%206.04%2053.719-8.456%2017.476-30.201%2010.55-33.181-6.04-68.215-95.758-70.39-107.84-56.778-96.644-6.926%203.947-33.503%20360.886-15.705%2018.443-36.243%2013.852-30.201-22.953-16.027-37.127%2016.027-73.37%2019.329-95.758%2015.704-76.107%2014.175-94.55%208.456-31.41-.563-2.094-6.927.886-71.275%2097.852-108.402%20146.497-85.772%2091.812-20.537%208.134-35.597-18.443%203.301-32.94%2019.893-29.315%20118.712-151.007%2071.597-93.583%2046.228-54.04-.322-7.813h-2.738l-315.302%20204.725-56.135%207.248-24.16-22.63%202.98-37.128%2011.435-12.08%2094.792-65.236-.322.323z'%20fill='%23d97757'/%3e%3c/svg%3e";
|
|
776
880
|
const OpenAILogoSvg = "data:image/svg+xml,%3csvg%20height='2500'%20viewBox='-1%20-.1%20949.1%20959.8'%20width='2474'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='m925.8%20456.3c10.4%2023.2%2017%2048%2019.7%2073.3%202.6%2025.3%201.3%2050.9-4.1%2075.8-5.3%2024.9-14.5%2048.8-27.3%2070.8-8.4%2014.7-18.3%2028.5-29.7%2041.2-11.3%2012.6-23.9%2024-37.6%2034-13.8%2010-28.5%2018.4-44.1%2025.3-15.5%206.8-31.7%2012-48.3%2015.4-7.8%2024.2-19.4%2047.1-34.4%2067.7-14.9%2020.6-33%2038.7-53.6%2053.6-20.6%2015-43.4%2026.6-67.6%2034.4-24.2%207.9-49.5%2011.8-75%2011.8-16.9.1-33.9-1.7-50.5-5.1-16.5-3.5-32.7-8.8-48.2-15.7s-30.2-15.5-43.9-25.5c-13.6-10-26.2-21.5-37.4-34.2-25%205.4-50.6%206.7-75.9%204.1-25.3-2.7-50.1-9.3-73.4-19.7-23.2-10.3-44.7-24.3-63.6-41.4s-35-37.1-47.7-59.1c-8.5-14.7-15.5-30.2-20.8-46.3s-8.8-32.7-10.6-49.6c-1.8-16.8-1.7-33.8.1-50.7%201.8-16.8%205.5-33.4%2010.8-49.5-17-18.9-31-40.4-41.4-63.6-10.3-23.3-17-48-19.6-73.3-2.7-25.3-1.3-50.9%204-75.8s14.5-48.8%2027.3-70.8c8.4-14.7%2018.3-28.6%2029.6-41.2s24-24%2037.7-34%2028.5-18.5%2044-25.3c15.6-6.9%2031.8-12%2048.4-15.4%207.8-24.3%2019.4-47.1%2034.3-67.7%2015-20.6%2033.1-38.7%2053.7-53.7%2020.6-14.9%2043.4-26.5%2067.6-34.4%2024.2-7.8%2049.5-11.8%2075-11.7%2016.9-.1%2033.9%201.6%2050.5%205.1s32.8%208.7%2048.3%2015.6c15.5%207%2030.2%2015.5%2043.9%2025.5%2013.7%2010.1%2026.3%2021.5%2037.5%2034.2%2024.9-5.3%2050.5-6.6%2075.8-4s50%209.3%2073.3%2019.6c23.2%2010.4%2044.7%2024.3%2063.6%2041.4%2018.9%2017%2035%2036.9%2047.7%2059%208.5%2014.6%2015.5%2030.1%2020.8%2046.3%205.3%2016.1%208.9%2032.7%2010.6%2049.6%201.8%2016.9%201.8%2033.9-.1%2050.8-1.8%2016.9-5.5%2033.5-10.8%2049.6%2017.1%2018.9%2031%2040.3%2041.4%2063.6zm-333.2%20426.9c21.8-9%2041.6-22.3%2058.3-39s30-36.5%2039-58.4c9-21.8%2013.7-45.2%2013.7-68.8v-223q-.1-.3-.2-.7-.1-.3-.3-.6-.2-.3-.5-.5-.3-.3-.6-.4l-80.7-46.6v269.4c0%202.7-.4%205.5-1.1%208.1-.7%202.7-1.7%205.2-3.1%207.6s-3%204.6-5%206.5a32.1%2032.1%200%200%201%20-6.5%205l-191.1%20110.3c-1.6%201-4.3%202.4-5.7%203.2%207.9%206.7%2016.5%2012.6%2025.5%2017.8%209.1%205.2%2018.5%209.6%2028.3%2013.2%209.8%203.5%2019.9%206.2%2030.1%208%2010.3%201.8%2020.7%202.7%2031.1%202.7%2023.6%200%2047-4.7%2068.8-13.8zm-455.1-151.4c11.9%2020.5%2027.6%2038.3%2046.3%2052.7%2018.8%2014.4%2040.1%2024.9%2062.9%2031s46.6%207.7%2070%204.6%2045.9-10.7%2066.4-22.5l193.2-111.5.5-.5q.2-.2.3-.6.2-.3.3-.6v-94l-233.2%20134.9c-2.4%201.4-4.9%202.4-7.5%203.2-2.7.7-5.4%201-8.2%201-2.7%200-5.4-.3-8.1-1-2.6-.8-5.2-1.8-7.6-3.2l-191.1-110.4c-1.7-1-4.2-2.5-5.6-3.4-1.8%2010.3-2.7%2020.7-2.7%2031.1s1%2020.8%202.8%2031.1c1.8%2010.2%204.6%2020.3%208.1%2030.1%203.6%209.8%208%2019.2%2013.2%2028.2zm-50.2-417c-11.8%2020.5-19.4%2043.1-22.5%2066.5s-1.5%2047.1%204.6%2070c6.1%2022.8%2016.6%2044.1%2031%2062.9%2014.4%2018.7%2032.3%2034.4%2052.7%2046.2l193.1%20111.6q.3.1.7.2h.7q.4%200%20.7-.2.3-.1.6-.3l81-46.8-233.2-134.6c-2.3-1.4-4.5-3.1-6.5-5a32.1%2032.1%200%200%201%20-5-6.5c-1.3-2.4-2.4-4.9-3.1-7.6-.7-2.6-1.1-5.3-1-8.1v-227.1c-9.8%203.6-19.3%208-28.3%2013.2-9%205.3-17.5%2011.3-25.5%2018-7.9%206.7-15.3%2014.1-22%2022.1-6.7%207.9-12.6%2016.5-17.8%2025.5zm663.3%20154.4c2.4%201.4%204.6%203%206.6%205%201.9%201.9%203.6%204.1%205%206.5%201.3%202.4%202.4%205%203.1%207.6.6%202.7%201%205.4.9%208.2v227.1c32.1-11.8%2060.1-32.5%2080.8-59.7%2020.8-27.2%2033.3-59.7%2036.2-93.7s-3.9-68.2-19.7-98.5-39.9-55.5-69.5-72.5l-193.1-111.6q-.3-.1-.7-.2h-.7q-.3.1-.7.2-.3.1-.6.3l-80.6%2046.6%20233.2%20134.7zm80.5-121h-.1v.1zm-.1-.1c5.8-33.6%201.9-68.2-11.3-99.7-13.1-31.5-35-58.6-63-78.2-28-19.5-61-30.7-95.1-32.2-34.2-1.4-68%206.9-97.6%2023.9l-193.1%20111.5q-.3.2-.5.5l-.4.6q-.1.3-.2.7-.1.3-.1.7v93.2l233.2-134.7c2.4-1.4%205-2.4%207.6-3.2%202.7-.7%205.4-1%208.1-1%202.8%200%205.5.3%208.2%201%202.6.8%205.1%201.8%207.5%203.2l191.1%20110.4c1.7%201%204.2%202.4%205.6%203.3zm-505.3-103.2c0-2.7.4-5.4%201.1-8.1.7-2.6%201.7-5.2%203.1-7.6%201.4-2.3%203-4.5%205-6.5%201.9-1.9%204.1-3.6%206.5-4.9l191.1-110.3c1.8-1.1%204.3-2.5%205.7-3.2-26.2-21.9-58.2-35.9-92.1-40.2-33.9-4.4-68.3%201-99.2%2015.5-31%2014.5-57.2%2037.6-75.5%2066.4-18.3%2028.9-28%2062.3-28%2096.5v223q.1.4.2.7.1.3.3.6.2.3.5.6.2.2.6.4l80.7%2046.6zm43.8%20294.7%20103.9%2060%20103.9-60v-119.9l-103.8-60-103.9%2060z'/%3e%3c/svg%3e";
|
|
777
881
|
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";
|
|
@@ -894,6 +998,38 @@ function TooltipContent({
|
|
|
894
998
|
}
|
|
895
999
|
) });
|
|
896
1000
|
}
|
|
1001
|
+
const MAX_VISIBLE_LOGOS = 3;
|
|
1002
|
+
const ROW_CHEVRON_SLOT_CLASS = "flex h-8 w-5 shrink-0 items-center justify-center text-muted-foreground";
|
|
1003
|
+
function ProviderLogoStack({
|
|
1004
|
+
items,
|
|
1005
|
+
ariaLabel,
|
|
1006
|
+
className
|
|
1007
|
+
}) {
|
|
1008
|
+
if (items.length === 0) {
|
|
1009
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("flex h-8 w-12 shrink-0 items-center", className), "aria-hidden": "true" });
|
|
1010
|
+
}
|
|
1011
|
+
const visibleItems = items.slice(0, MAX_VISIBLE_LOGOS);
|
|
1012
|
+
const overflowCount = items.length - visibleItems.length;
|
|
1013
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 150, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn("flex h-8 w-12 shrink-0 items-center", className), "aria-label": ariaLabel, children: [
|
|
1014
|
+
visibleItems.map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
1015
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1016
|
+
"span",
|
|
1017
|
+
{
|
|
1018
|
+
className: cn(
|
|
1019
|
+
"inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-white/10 bg-black/20 shadow-[inset_0_1px_0_rgba(255,255,255,0.05)]",
|
|
1020
|
+
index > 0 && "-ml-2"
|
|
1021
|
+
),
|
|
1022
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: item.provider, className: "size-4" })
|
|
1023
|
+
}
|
|
1024
|
+
) }),
|
|
1025
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: item.tooltip })
|
|
1026
|
+
] }, `${item.provider}-${String(index)}`)),
|
|
1027
|
+
overflowCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "-ml-2 inline-flex h-6 min-w-6 shrink-0 items-center justify-center rounded-md border border-white/10 bg-black/40 px-1 font-mono text-[10px] text-muted-foreground", children: [
|
|
1028
|
+
"+",
|
|
1029
|
+
overflowCount
|
|
1030
|
+
] })
|
|
1031
|
+
] }) });
|
|
1032
|
+
}
|
|
897
1033
|
function forEachCodePoint(text, visit) {
|
|
898
1034
|
for (const ch of Array.from(text)) {
|
|
899
1035
|
visit(ch);
|
|
@@ -1078,9 +1214,9 @@ function contentToText(content) {
|
|
|
1078
1214
|
if (block === null || typeof block !== "object") continue;
|
|
1079
1215
|
const b = block;
|
|
1080
1216
|
const type = b.type;
|
|
1081
|
-
if (type === "text" && typeof b.text === "string") {
|
|
1217
|
+
if ((type === "text" || type === "input_text" || type === "output_text") && typeof b.text === "string") {
|
|
1082
1218
|
parts.push(b.text);
|
|
1083
|
-
} else if (type === "image_url") {
|
|
1219
|
+
} else if (type === "image_url" || type === "input_image") {
|
|
1084
1220
|
parts.push("[image]");
|
|
1085
1221
|
}
|
|
1086
1222
|
}
|
|
@@ -1110,15 +1246,54 @@ function toolsToText(tools) {
|
|
|
1110
1246
|
const parts = [];
|
|
1111
1247
|
for (const tool of tools) {
|
|
1112
1248
|
if (tool === null || typeof tool !== "object") continue;
|
|
1113
|
-
const
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
if (typeof
|
|
1118
|
-
if (
|
|
1249
|
+
const fn = safeGetOwnProperty(tool, "function");
|
|
1250
|
+
const name = safeGetOwnProperty(fn, "name") ?? safeGetOwnProperty(tool, "name");
|
|
1251
|
+
const description = safeGetOwnProperty(fn, "description") ?? safeGetOwnProperty(tool, "description");
|
|
1252
|
+
const parameters = safeGetOwnProperty(fn, "parameters") ?? safeGetOwnProperty(tool, "parameters");
|
|
1253
|
+
if (typeof name === "string") parts.push(name);
|
|
1254
|
+
if (typeof description === "string") parts.push(description);
|
|
1255
|
+
if (parameters !== void 0) parts.push(JSON.stringify(parameters));
|
|
1119
1256
|
}
|
|
1120
1257
|
return parts.join("\n");
|
|
1121
1258
|
}
|
|
1259
|
+
function countResponsesInput(input) {
|
|
1260
|
+
if (typeof input === "string") return input.length > 0 ? 1 : 0;
|
|
1261
|
+
if (Array.isArray(input)) return input.length;
|
|
1262
|
+
if (input === void 0 || input === null) return null;
|
|
1263
|
+
return 1;
|
|
1264
|
+
}
|
|
1265
|
+
function responsesInputItemToText(input) {
|
|
1266
|
+
if (typeof input === "string") return input;
|
|
1267
|
+
const directText = safeGetOwnProperty(input, "text");
|
|
1268
|
+
if (typeof directText === "string") return directText;
|
|
1269
|
+
const contentText = contentToText(safeGetOwnProperty(input, "content"));
|
|
1270
|
+
if (contentText.length > 0) return contentText;
|
|
1271
|
+
const outputText = contentToText(safeGetOwnProperty(input, "output"));
|
|
1272
|
+
if (outputText.length > 0) return outputText;
|
|
1273
|
+
const argumentsText = safeGetOwnProperty(input, "arguments");
|
|
1274
|
+
return typeof argumentsText === "string" ? argumentsText : "";
|
|
1275
|
+
}
|
|
1276
|
+
function responsesInputRole(input) {
|
|
1277
|
+
const role = safeGetOwnProperty(input, "role");
|
|
1278
|
+
if (role === "system" || role === "user" || role === "assistant" || role === "tool") {
|
|
1279
|
+
return role;
|
|
1280
|
+
}
|
|
1281
|
+
const type = safeGetOwnProperty(input, "type");
|
|
1282
|
+
if (type === "function_call_output") return "tool";
|
|
1283
|
+
if (type === "message") return "user";
|
|
1284
|
+
return "user";
|
|
1285
|
+
}
|
|
1286
|
+
function responsesToolNames(response) {
|
|
1287
|
+
const output = safeGetOwnProperty(response, "output");
|
|
1288
|
+
if (!Array.isArray(output)) return [];
|
|
1289
|
+
const names = [];
|
|
1290
|
+
for (const item of output) {
|
|
1291
|
+
if (safeGetOwnProperty(item, "type") !== "function_call") continue;
|
|
1292
|
+
const name = safeGetOwnProperty(item, "name");
|
|
1293
|
+
if (typeof name === "string" && name.length > 0) names.push(name);
|
|
1294
|
+
}
|
|
1295
|
+
return names;
|
|
1296
|
+
}
|
|
1122
1297
|
function segment(role, label, text, path) {
|
|
1123
1298
|
return {
|
|
1124
1299
|
role,
|
|
@@ -1135,7 +1310,16 @@ const openAILogFormatAdapter = {
|
|
|
1135
1310
|
if (rawBody === null) return emptyRequestAnalysis(rawBody);
|
|
1136
1311
|
try {
|
|
1137
1312
|
const result = OpenAIRequestSchema.safeParse(JSON.parse(rawBody));
|
|
1138
|
-
if (!result.success)
|
|
1313
|
+
if (!result.success) {
|
|
1314
|
+
const responsesResult = OpenAIResponsesRequestSchema.safeParse(JSON.parse(rawBody));
|
|
1315
|
+
if (!responsesResult.success) return emptyRequestAnalysis(rawBody);
|
|
1316
|
+
return {
|
|
1317
|
+
parsed: responsesResult.data,
|
|
1318
|
+
comparisonValue: responsesResult.data,
|
|
1319
|
+
messageCount: countResponsesInput(responsesResult.data.input),
|
|
1320
|
+
toolCount: responsesResult.data.tools !== void 0 && responsesResult.data.tools.length > 0 ? responsesResult.data.tools.length : null
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1139
1323
|
return {
|
|
1140
1324
|
parsed: result.data,
|
|
1141
1325
|
comparisonValue: result.data,
|
|
@@ -1149,7 +1333,15 @@ const openAILogFormatAdapter = {
|
|
|
1149
1333
|
analyzeResponse(responseText) {
|
|
1150
1334
|
if (responseText === null) return EMPTY_RESPONSE_ANALYSIS;
|
|
1151
1335
|
const parsed = parseOpenAIResponse(responseText);
|
|
1152
|
-
if (parsed === null)
|
|
1336
|
+
if (parsed === null) {
|
|
1337
|
+
const responsesParsed = parseOpenAIResponsesResponse(responseText);
|
|
1338
|
+
if (responsesParsed === null) return EMPTY_RESPONSE_ANALYSIS;
|
|
1339
|
+
const toolNames2 = responsesToolNames(responsesParsed);
|
|
1340
|
+
return {
|
|
1341
|
+
parsed: responsesParsed,
|
|
1342
|
+
toolNames: toolNames2.length > 0 ? toolNames2 : null
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1153
1345
|
const toolNames = parsed.choices[0]?.message?.tool_calls?.map((toolCall) => toolCall.function?.name ?? "").filter((name) => name !== "") ?? [];
|
|
1154
1346
|
return {
|
|
1155
1347
|
parsed,
|
|
@@ -1160,6 +1352,9 @@ const openAILogFormatAdapter = {
|
|
|
1160
1352
|
if (parsed === null || typeof parsed !== "object") return null;
|
|
1161
1353
|
const body = parsed;
|
|
1162
1354
|
const segments = [];
|
|
1355
|
+
if (typeof body.instructions === "string" && body.instructions.length > 0) {
|
|
1356
|
+
segments.push(segment("system", "instructions", body.instructions, "/instructions"));
|
|
1357
|
+
}
|
|
1163
1358
|
if (Array.isArray(body.messages)) {
|
|
1164
1359
|
body.messages.forEach((message, index) => {
|
|
1165
1360
|
if (message === null || typeof message !== "object") return;
|
|
@@ -1169,6 +1364,17 @@ const openAILogFormatAdapter = {
|
|
|
1169
1364
|
segments.push(segment(role, `[${index}] ${role}`, text, `/messages/${index}`));
|
|
1170
1365
|
});
|
|
1171
1366
|
}
|
|
1367
|
+
if (!Array.isArray(body.messages)) {
|
|
1368
|
+
if (typeof body.input === "string" && body.input.length > 0) {
|
|
1369
|
+
segments.push(segment("user", "input", body.input, "/input"));
|
|
1370
|
+
} else if (Array.isArray(body.input)) {
|
|
1371
|
+
body.input.forEach((item, index) => {
|
|
1372
|
+
const role = responsesInputRole(item);
|
|
1373
|
+
const text = responsesInputItemToText(item);
|
|
1374
|
+
segments.push(segment(role, `[${index}] ${role}`, text, `/input/${index}`));
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1172
1378
|
if (Array.isArray(body.tools) && body.tools.length > 0) {
|
|
1173
1379
|
const text = toolsToText(body.tools);
|
|
1174
1380
|
segments.push(segment("tools", "tools", text, "/tools"));
|
|
@@ -1230,6 +1436,15 @@ function ConversationHeader({
|
|
|
1230
1436
|
},
|
|
1231
1437
|
[conversationId]
|
|
1232
1438
|
);
|
|
1439
|
+
const providerLogoItems = providers?.map(({ provider, models }) => ({
|
|
1440
|
+
provider,
|
|
1441
|
+
tooltip: models.length === 1 ? models[0] ?? provider : models.join(", ")
|
|
1442
|
+
})) ?? [];
|
|
1443
|
+
const clientApp = detectClientApp({ userAgent, conversationId, clientProjectFolder });
|
|
1444
|
+
const detectedClientLabel = clientAppLabel(clientApp);
|
|
1445
|
+
const hasUserAgent = userAgent !== null && userAgent !== void 0 && userAgent !== "";
|
|
1446
|
+
const clientDisplayLabel = detectedClientLabel ?? userAgent ?? null;
|
|
1447
|
+
const clientTooltip = detectedClientLabel !== null && hasUserAgent ? `${detectedClientLabel} - ${userAgent}` : null;
|
|
1233
1448
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1234
1449
|
"div",
|
|
1235
1450
|
{
|
|
@@ -1253,7 +1468,8 @@ function ConversationHeader({
|
|
|
1253
1468
|
}
|
|
1254
1469
|
},
|
|
1255
1470
|
children: [
|
|
1256
|
-
|
|
1471
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogoStack, { items: providerLogoItems, ariaLabel: "Models used in this session" }),
|
|
1472
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: ROW_CHEVRON_SLOT_CLASS, children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 shrink-0" }) : isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" }) }),
|
|
1257
1473
|
conversationId.startsWith("PID:") || conversationId.includes("|") ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
1258
1474
|
clientPid !== null && clientPid !== void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1259
1475
|
"span",
|
|
@@ -1295,28 +1511,17 @@ function ConversationHeader({
|
|
|
1295
1511
|
}
|
|
1296
1512
|
)
|
|
1297
1513
|
] }),
|
|
1298
|
-
|
|
1514
|
+
clientDisplayLabel !== null && clientDisplayLabel !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1299
1515
|
"span",
|
|
1300
1516
|
{
|
|
1301
1517
|
className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0",
|
|
1302
|
-
title:
|
|
1518
|
+
title: clientTooltip ?? clientDisplayLabel,
|
|
1303
1519
|
children: [
|
|
1304
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1305
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[120px]", children:
|
|
1520
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: clientApp, className: "size-5" }),
|
|
1521
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[120px]", children: clientDisplayLabel })
|
|
1306
1522
|
]
|
|
1307
1523
|
}
|
|
1308
1524
|
),
|
|
1309
|
-
providers !== void 0 && providers.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 150, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1310
|
-
"span",
|
|
1311
|
-
{
|
|
1312
|
-
className: "flex items-center gap-0.5 shrink-0",
|
|
1313
|
-
"aria-label": "Models used in this session",
|
|
1314
|
-
children: providers.map(({ provider, models }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
1315
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider, className: "size-4" }) }) }),
|
|
1316
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: models.length === 1 ? models[0] : models.join(", ") })
|
|
1317
|
-
] }, provider))
|
|
1318
|
-
}
|
|
1319
|
-
) }),
|
|
1320
1525
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0", children: [
|
|
1321
1526
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
1322
1527
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatTimestampRange(startTime, endTime, timeDisplayFormat) })
|
|
@@ -1418,9 +1623,65 @@ function groupLogsByConversation(logs) {
|
|
|
1418
1623
|
result.sort((a, b) => (a.logs[0]?.timestamp ?? "").localeCompare(b.logs[0]?.timestamp ?? ""));
|
|
1419
1624
|
return result;
|
|
1420
1625
|
}
|
|
1626
|
+
const LOG_FOCUS_REQUEST_EVENT = "agent-inspector:focus-log";
|
|
1627
|
+
function dispatchLogFocusRequest(request) {
|
|
1628
|
+
window.dispatchEvent(new CustomEvent(LOG_FOCUS_REQUEST_EVENT, { detail: request }));
|
|
1629
|
+
}
|
|
1630
|
+
function readLogFocusRequest(event) {
|
|
1631
|
+
if (typeof CustomEvent === "undefined" || !(event instanceof CustomEvent)) return null;
|
|
1632
|
+
const detail = event.detail;
|
|
1633
|
+
const logId = safeGetOwnProperty(detail, "logId");
|
|
1634
|
+
if (typeof logId !== "number" || !Number.isInteger(logId) || logId < 0) return null;
|
|
1635
|
+
const tab = safeGetOwnProperty(detail, "tab");
|
|
1636
|
+
switch (tab) {
|
|
1637
|
+
case "anatomy":
|
|
1638
|
+
case "request":
|
|
1639
|
+
break;
|
|
1640
|
+
case void 0:
|
|
1641
|
+
break;
|
|
1642
|
+
default:
|
|
1643
|
+
return null;
|
|
1644
|
+
}
|
|
1645
|
+
const source = safeGetOwnProperty(detail, "source");
|
|
1646
|
+
switch (source) {
|
|
1647
|
+
case "virtualizer":
|
|
1648
|
+
return { logId, tab: tab ?? "request", source };
|
|
1649
|
+
case void 0:
|
|
1650
|
+
return { logId, tab: tab ?? "request" };
|
|
1651
|
+
default:
|
|
1652
|
+
return null;
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1421
1655
|
function isRecord(value) {
|
|
1422
1656
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1423
1657
|
}
|
|
1658
|
+
function normalizeAnthropicStopReason(value) {
|
|
1659
|
+
switch (value) {
|
|
1660
|
+
case "end_turn":
|
|
1661
|
+
case "tool_use":
|
|
1662
|
+
return value;
|
|
1663
|
+
default:
|
|
1664
|
+
return null;
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
function normalizeOpenAIFinishReason(value) {
|
|
1668
|
+
switch (value) {
|
|
1669
|
+
case "stop":
|
|
1670
|
+
case "length":
|
|
1671
|
+
return value;
|
|
1672
|
+
default:
|
|
1673
|
+
return null;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
function isResponsesLengthLimitReason(value) {
|
|
1677
|
+
switch (value) {
|
|
1678
|
+
case "max_output_tokens":
|
|
1679
|
+
case "max_tokens":
|
|
1680
|
+
return true;
|
|
1681
|
+
default:
|
|
1682
|
+
return false;
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1424
1685
|
function extractStopReason(log) {
|
|
1425
1686
|
if (log.responseText === null) return null;
|
|
1426
1687
|
try {
|
|
@@ -1430,13 +1691,30 @@ function extractStopReason(log) {
|
|
|
1430
1691
|
}
|
|
1431
1692
|
if (!isRecord(json)) return null;
|
|
1432
1693
|
if (typeof json.stop_reason === "string") {
|
|
1433
|
-
|
|
1434
|
-
|
|
1694
|
+
return normalizeAnthropicStopReason(json.stop_reason);
|
|
1695
|
+
}
|
|
1696
|
+
if (Array.isArray(json.choices)) {
|
|
1697
|
+
for (const choice of json.choices) {
|
|
1698
|
+
if (!isRecord(choice) || typeof choice.finish_reason !== "string") continue;
|
|
1699
|
+
const reason = normalizeOpenAIFinishReason(choice.finish_reason);
|
|
1700
|
+
if (reason !== null) return reason;
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
if (Array.isArray(json.output)) {
|
|
1704
|
+
for (const item of json.output) {
|
|
1705
|
+
if (isRecord(item) && item.type === "function_call") {
|
|
1706
|
+
return "tool_use";
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
if (json.status === "completed") {
|
|
1710
|
+
return "stop";
|
|
1435
1711
|
}
|
|
1436
|
-
return null;
|
|
1437
1712
|
}
|
|
1438
|
-
if (
|
|
1439
|
-
|
|
1713
|
+
if (json.status === "incomplete" && isRecord(json.incomplete_details)) {
|
|
1714
|
+
const reason = json.incomplete_details.reason;
|
|
1715
|
+
if (typeof reason === "string" && isResponsesLengthLimitReason(reason)) {
|
|
1716
|
+
return "length";
|
|
1717
|
+
}
|
|
1440
1718
|
}
|
|
1441
1719
|
return null;
|
|
1442
1720
|
} catch {
|
|
@@ -1444,7 +1722,7 @@ function extractStopReason(log) {
|
|
|
1444
1722
|
}
|
|
1445
1723
|
}
|
|
1446
1724
|
function isTurnBoundary(stopReason) {
|
|
1447
|
-
return stopReason === "end_turn" || stopReason === "stop";
|
|
1725
|
+
return stopReason === "end_turn" || stopReason === "stop" || stopReason === "length";
|
|
1448
1726
|
}
|
|
1449
1727
|
function SvgShell({
|
|
1450
1728
|
className,
|
|
@@ -1798,8 +2076,38 @@ function getInteriorCrabVariantIndex(seed) {
|
|
|
1798
2076
|
function getInteriorCrabVariant(seed) {
|
|
1799
2077
|
return getCrabVariant(getInteriorCrabVariantIndex(seed));
|
|
1800
2078
|
}
|
|
1801
|
-
|
|
1802
|
-
|
|
2079
|
+
const FULL_EXPAND_NODE_LIMIT = 400;
|
|
2080
|
+
const STRUCTURE_EXPAND_NODE_LIMIT = 2e3;
|
|
2081
|
+
function isJsonArray(value) {
|
|
2082
|
+
return Array.isArray(value);
|
|
2083
|
+
}
|
|
2084
|
+
function countJsonNodesUpTo(value, limit) {
|
|
2085
|
+
const stack = [value];
|
|
2086
|
+
let count = 0;
|
|
2087
|
+
while (stack.length > 0) {
|
|
2088
|
+
const current = stack.pop();
|
|
2089
|
+
if (current === void 0) continue;
|
|
2090
|
+
count += 1;
|
|
2091
|
+
if (count > limit) return count;
|
|
2092
|
+
if (current === null || typeof current !== "object") continue;
|
|
2093
|
+
if (isJsonArray(current)) {
|
|
2094
|
+
for (const child of current) {
|
|
2095
|
+
stack.push(child);
|
|
2096
|
+
}
|
|
2097
|
+
continue;
|
|
2098
|
+
}
|
|
2099
|
+
for (const key of Object.keys(current)) {
|
|
2100
|
+
const child = current[key];
|
|
2101
|
+
if (child !== void 0) stack.push(child);
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
return count;
|
|
2105
|
+
}
|
|
2106
|
+
function getJsonExpansionPolicy(value) {
|
|
2107
|
+
const nodeCount = countJsonNodesUpTo(value, STRUCTURE_EXPAND_NODE_LIMIT + 1);
|
|
2108
|
+
if (nodeCount <= FULL_EXPAND_NODE_LIMIT) return { depth: Number.POSITIVE_INFINITY };
|
|
2109
|
+
if (nodeCount <= STRUCTURE_EXPAND_NODE_LIMIT) return { depth: 3 };
|
|
2110
|
+
return { depth: 2 };
|
|
1803
2111
|
}
|
|
1804
2112
|
function parseJsonText(text) {
|
|
1805
2113
|
try {
|
|
@@ -1813,7 +2121,7 @@ function useJsonBulkExpansion(text) {
|
|
|
1813
2121
|
const parsed = reactExports.useMemo(() => text === null ? null : parseJsonText(text), [text]);
|
|
1814
2122
|
const parsedData = parsed?.kind === "json" ? parsed.data : null;
|
|
1815
2123
|
const policy = reactExports.useMemo(
|
|
1816
|
-
() => parsedData === null ? null : getJsonExpansionPolicy(),
|
|
2124
|
+
() => parsedData === null ? null : getJsonExpansionPolicy(parsedData),
|
|
1817
2125
|
[parsedData]
|
|
1818
2126
|
);
|
|
1819
2127
|
const [isExpanded, setIsExpanded] = reactExports.useState(false);
|
|
@@ -1961,27 +2269,27 @@ function useCopyFeedback(text) {
|
|
|
1961
2269
|
return { copied, copy };
|
|
1962
2270
|
}
|
|
1963
2271
|
const LazyCompareDrawer = reactExports.lazy(
|
|
1964
|
-
() => import("./CompareDrawer-
|
|
2272
|
+
() => import("./CompareDrawer-BoxztaO7.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
1965
2273
|
);
|
|
1966
2274
|
const LazyReplayDialog = reactExports.lazy(
|
|
1967
|
-
() => import("./ReplayDialog-
|
|
2275
|
+
() => import("./ReplayDialog-Cc1dyDuK.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
1968
2276
|
);
|
|
1969
2277
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
1970
|
-
() => import("./RequestAnatomy-
|
|
2278
|
+
() => import("./RequestAnatomy-CMGSsz5Z.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
1971
2279
|
);
|
|
1972
2280
|
const LazyResponseView = reactExports.lazy(
|
|
1973
|
-
() => import("./ResponseView-
|
|
2281
|
+
() => import("./ResponseView-Cp10DM1D.mjs").then((m) => ({ default: m.ResponseView }))
|
|
1974
2282
|
);
|
|
1975
2283
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
1976
|
-
() => import("./StreamingChunkSequence-
|
|
2284
|
+
() => import("./StreamingChunkSequence-B1VGxy3A.mjs").then((m) => ({
|
|
1977
2285
|
default: m.StreamingChunkSequence
|
|
1978
2286
|
}))
|
|
1979
2287
|
);
|
|
1980
2288
|
const LazyJsonViewer = reactExports.lazy(
|
|
1981
|
-
() =>
|
|
2289
|
+
() => import("./json-viewer-zDE2rrmJ.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
1982
2290
|
);
|
|
1983
2291
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
1984
|
-
() =>
|
|
2292
|
+
() => import("./json-viewer-zDE2rrmJ.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
1985
2293
|
);
|
|
1986
2294
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
1987
2295
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -2405,12 +2713,35 @@ function Badge({
|
|
|
2405
2713
|
);
|
|
2406
2714
|
}
|
|
2407
2715
|
const STATUS_BADGE_CLASSES = {
|
|
2408
|
-
success: "bg-emerald-
|
|
2409
|
-
client_error: "bg-amber-
|
|
2410
|
-
server_error: "bg-rose-
|
|
2411
|
-
pending: "bg-
|
|
2716
|
+
success: "bg-emerald-400/[0.08] text-emerald-200 border-emerald-300/25",
|
|
2717
|
+
client_error: "bg-amber-300/[0.10] text-amber-100 border-amber-300/30",
|
|
2718
|
+
server_error: "bg-rose-400/[0.10] text-rose-100 border-rose-300/30",
|
|
2719
|
+
pending: "bg-cyan-300/[0.08] text-cyan-100 border-cyan-300/25"
|
|
2720
|
+
};
|
|
2721
|
+
const STATUS_CUE_CLASSES = {
|
|
2722
|
+
success: {
|
|
2723
|
+
frame: "border-emerald-300/20 bg-emerald-300/[0.06] text-emerald-100",
|
|
2724
|
+
dot: "bg-emerald-300 shadow-[0_0_14px_rgba(110,231,183,0.8)]",
|
|
2725
|
+
rail: "bg-emerald-300/45 shadow-[0_0_22px_rgba(110,231,183,0.28)]"
|
|
2726
|
+
},
|
|
2727
|
+
client_error: {
|
|
2728
|
+
frame: "border-amber-300/25 bg-amber-300/[0.08] text-amber-100",
|
|
2729
|
+
dot: "bg-amber-200 shadow-[0_0_14px_rgba(252,211,77,0.8)]",
|
|
2730
|
+
rail: "bg-amber-300/50 shadow-[0_0_22px_rgba(252,211,77,0.28)]"
|
|
2731
|
+
},
|
|
2732
|
+
server_error: {
|
|
2733
|
+
frame: "border-rose-300/25 bg-rose-300/[0.08] text-rose-100",
|
|
2734
|
+
dot: "bg-rose-300 shadow-[0_0_14px_rgba(253,164,175,0.8)]",
|
|
2735
|
+
rail: "bg-rose-300/50 shadow-[0_0_22px_rgba(253,164,175,0.28)]"
|
|
2736
|
+
},
|
|
2737
|
+
pending: {
|
|
2738
|
+
frame: "border-cyan-300/25 bg-cyan-300/[0.08] text-cyan-100",
|
|
2739
|
+
dot: "bg-cyan-200 shadow-[0_0_14px_rgba(103,232,249,0.8)]",
|
|
2740
|
+
rail: "bg-cyan-300/50 shadow-[0_0_22px_rgba(103,232,249,0.28)]"
|
|
2741
|
+
}
|
|
2412
2742
|
};
|
|
2413
2743
|
const HEADER_ACTION_BUTTON_CLASS = "size-8 border-white/10 bg-[#0a0d11] text-muted-foreground shadow-none hover:border-cyan-300/30 hover:bg-cyan-400/10 hover:text-cyan-100";
|
|
2744
|
+
const TELEMETRY_CHIP_CLASS = "flex h-7 items-center gap-1 rounded-md border border-white/10 bg-black/20 px-2 text-xs shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]";
|
|
2414
2745
|
function formatElapsed$3(ms) {
|
|
2415
2746
|
if (ms < 1e3) return `${ms}ms`;
|
|
2416
2747
|
return `${(ms / 1e3).toFixed(1)}s`;
|
|
@@ -2419,6 +2750,18 @@ function formatTokenRate$1(tokensPerSecond) {
|
|
|
2419
2750
|
if (tokensPerSecond >= 10) return `${tokensPerSecond.toFixed(0)}/s`;
|
|
2420
2751
|
return `${tokensPerSecond.toFixed(1)}/s`;
|
|
2421
2752
|
}
|
|
2753
|
+
function statusCueLabel(category, status) {
|
|
2754
|
+
switch (category) {
|
|
2755
|
+
case "success":
|
|
2756
|
+
return status === null ? "OK" : String(status);
|
|
2757
|
+
case "client_error":
|
|
2758
|
+
return status === null ? "WARN" : String(status);
|
|
2759
|
+
case "server_error":
|
|
2760
|
+
return status === null ? "FAIL" : String(status);
|
|
2761
|
+
case "pending":
|
|
2762
|
+
return "ROLL";
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2422
2765
|
function CacheTrendIndicator({ trend }) {
|
|
2423
2766
|
if (trend === null) return null;
|
|
2424
2767
|
const isUp = trend.direction === "up";
|
|
@@ -2434,6 +2777,7 @@ function CacheTrendIndicator({ trend }) {
|
|
|
2434
2777
|
}
|
|
2435
2778
|
const LogEntryHeader = reactExports.memo(function({
|
|
2436
2779
|
log,
|
|
2780
|
+
displayNumber,
|
|
2437
2781
|
messageCount = null,
|
|
2438
2782
|
toolCount = null,
|
|
2439
2783
|
expanded,
|
|
@@ -2456,6 +2800,8 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2456
2800
|
const hasClientPid = log.clientPid !== null && log.clientPid !== void 0;
|
|
2457
2801
|
const hasClientProjectFolder = log.clientProjectFolder !== null && log.clientProjectFolder !== void 0 && log.clientProjectFolder !== "";
|
|
2458
2802
|
const hasClientCwd = log.clientCwd !== null && log.clientCwd !== void 0 && log.clientCwd !== "";
|
|
2803
|
+
const statusCue = STATUS_CUE_CLASSES[statusCategory];
|
|
2804
|
+
const statusLabel2 = statusCueLabel(statusCategory, log.responseStatus);
|
|
2459
2805
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2460
2806
|
"div",
|
|
2461
2807
|
{
|
|
@@ -2465,9 +2811,9 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2465
2811
|
"data-nav-id": `log-${log.id}`,
|
|
2466
2812
|
"data-nav-action": expanded ? "collapse" : "expand",
|
|
2467
2813
|
className: cn(
|
|
2468
|
-
"flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 px-3 py-
|
|
2469
|
-
expanded ? "bg-[
|
|
2470
|
-
"select-none",
|
|
2814
|
+
"group/header relative isolate flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 overflow-hidden px-3 py-2 cursor-pointer transition-[background-color,border-color,box-shadow]",
|
|
2815
|
+
expanded ? "bg-[linear-gradient(90deg,#0f1720_0%,#090d12_50%,#07090d_100%)] shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]" : "bg-[#080b10] hover:bg-[#0b1016]",
|
|
2816
|
+
"select-none before:pointer-events-none before:absolute before:inset-x-0 before:top-0 before:h-px before:bg-white/10",
|
|
2471
2817
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
2472
2818
|
),
|
|
2473
2819
|
onClick: onToggle,
|
|
@@ -2478,25 +2824,48 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2478
2824
|
}
|
|
2479
2825
|
},
|
|
2480
2826
|
children: [
|
|
2481
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
2482
|
-
"
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2827
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2828
|
+
"span",
|
|
2829
|
+
{
|
|
2830
|
+
className: cn(
|
|
2831
|
+
"absolute left-0 top-2 bottom-2 w-0.5 rounded-r-full transition-colors",
|
|
2832
|
+
statusCue.rail
|
|
2833
|
+
),
|
|
2834
|
+
"aria-hidden": "true"
|
|
2835
|
+
}
|
|
2836
|
+
),
|
|
2837
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: ROW_CHEVRON_SLOT_CLASS, children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" }) }),
|
|
2838
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2839
|
+
"span",
|
|
2840
|
+
{
|
|
2841
|
+
className: cn(
|
|
2842
|
+
"inline-flex h-8 shrink-0 items-center gap-2 rounded-md border px-2 font-mono shadow-[inset_0_1px_0_rgba(255,255,255,0.05)]",
|
|
2843
|
+
statusCue.frame
|
|
2844
|
+
),
|
|
2845
|
+
children: [
|
|
2846
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("size-1.5 rounded-full", statusCue.dot), "aria-hidden": "true" }),
|
|
2847
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-semibold tabular-nums", title: `Log ID ${String(log.id)}`, children: [
|
|
2848
|
+
"#",
|
|
2849
|
+
displayNumber
|
|
2850
|
+
] })
|
|
2851
|
+
]
|
|
2852
|
+
}
|
|
2853
|
+
),
|
|
2854
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex h-7 items-center gap-1 rounded-md border border-white/10 bg-black/20 px-2 text-muted-foreground text-xs shrink-0", children: [
|
|
2486
2855
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
2487
2856
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", title: log.timestamp, children: formatTimestamp$2(log.timestamp, timeDisplayFormat) })
|
|
2488
2857
|
] }),
|
|
2489
|
-
|
|
2858
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2490
2859
|
Badge,
|
|
2491
2860
|
{
|
|
2492
2861
|
variant: "outline",
|
|
2493
2862
|
className: cn(
|
|
2494
|
-
"
|
|
2863
|
+
"h-6 gap-1 rounded-md px-2 py-0 font-mono text-[10px] font-semibold uppercase tabular-nums shadow-[inset_0_1px_0_rgba(255,255,255,0.05)]",
|
|
2495
2864
|
STATUS_BADGE_CLASSES[statusCategory]
|
|
2496
2865
|
),
|
|
2497
2866
|
children: [
|
|
2498
|
-
statusCategory === "
|
|
2499
|
-
|
|
2867
|
+
statusCategory === "success" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3", "aria-label": "Success" }) : statusCategory === "server_error" ? /* @__PURE__ */ jsxRuntimeExports.jsx(OctagonAlert, { className: "size-3", "aria-label": "Server error" }) : statusCategory === "client_error" ? /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Client error" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3 animate-spin", "aria-label": "Pending" }),
|
|
2868
|
+
statusLabel2
|
|
2500
2869
|
]
|
|
2501
2870
|
}
|
|
2502
2871
|
),
|
|
@@ -2505,7 +2874,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2505
2874
|
Badge,
|
|
2506
2875
|
{
|
|
2507
2876
|
variant: "outline",
|
|
2508
|
-
className: "
|
|
2877
|
+
className: "h-6 gap-1 rounded-md border-amber-300/30 bg-amber-300/[0.10] px-2 py-0 font-mono text-[10px] tabular-nums text-amber-100",
|
|
2509
2878
|
children: [
|
|
2510
2879
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Tool schema warnings" }),
|
|
2511
2880
|
warningCount
|
|
@@ -2515,11 +2884,20 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2515
2884
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: warningCount === 1 ? "1 tool schema warning" : `${warningCount} tool schema warnings` })
|
|
2516
2885
|
] }),
|
|
2517
2886
|
log.elapsedMs !== null && (isSlowResponse ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2518
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2887
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2888
|
+
"span",
|
|
2889
|
+
{
|
|
2890
|
+
className: cn(
|
|
2891
|
+
TELEMETRY_CHIP_CLASS,
|
|
2892
|
+
"shrink-0 border-amber-300/25 text-amber-200"
|
|
2893
|
+
),
|
|
2894
|
+
children: [
|
|
2895
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
2896
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed$3(log.elapsedMs) }),
|
|
2897
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Slow response" })
|
|
2898
|
+
]
|
|
2899
|
+
}
|
|
2900
|
+
) }),
|
|
2523
2901
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { children: [
|
|
2524
2902
|
"Slow response: ",
|
|
2525
2903
|
formatElapsed$3(log.elapsedMs),
|
|
@@ -2527,12 +2905,12 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2527
2905
|
" ",
|
|
2528
2906
|
formatElapsed$3(slowResponseThresholdSeconds * 1e3)
|
|
2529
2907
|
] })
|
|
2530
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2908
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-muted-foreground"), children: [
|
|
2531
2909
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
2532
2910
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed$3(log.elapsedMs) })
|
|
2533
2911
|
] })),
|
|
2534
2912
|
log.streaming && firstChunkLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2535
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2913
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-cyan-300"), children: [
|
|
2536
2914
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Radio, { className: "size-3" }),
|
|
2537
2915
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
2538
2916
|
"first ",
|
|
@@ -2542,13 +2920,13 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2542
2920
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Time to first streaming chunk" })
|
|
2543
2921
|
] }),
|
|
2544
2922
|
log.streaming && tokenRateLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2545
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2923
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-emerald-300"), children: [
|
|
2546
2924
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Gauge, { className: "size-3" }),
|
|
2547
2925
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: tokenRateLabel })
|
|
2548
2926
|
] }) }),
|
|
2549
2927
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Output token throughput after first chunk" })
|
|
2550
2928
|
] }),
|
|
2551
|
-
hasTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2929
|
+
hasTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "min-w-0 sm:shrink-0"), children: [
|
|
2552
2930
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3 text-muted-foreground" }),
|
|
2553
2931
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-1 font-mono tabular-nums", children: [
|
|
2554
2932
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -2580,32 +2958,32 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2580
2958
|
)
|
|
2581
2959
|
] })
|
|
2582
2960
|
] }),
|
|
2583
|
-
log.cacheCreationInputTokens !== null && log.cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2961
|
+
log.cacheCreationInputTokens !== null && log.cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0"), children: [
|
|
2584
2962
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CacheTrendIndicator, { trend: cacheTrend?.creation ?? null }),
|
|
2585
2963
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-emerald-400", children: [
|
|
2586
2964
|
"KV Cache +",
|
|
2587
2965
|
formatTokens(log.cacheCreationInputTokens)
|
|
2588
2966
|
] })
|
|
2589
2967
|
] }),
|
|
2590
|
-
log.cacheReadInputTokens !== null && log.cacheReadInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2968
|
+
log.cacheReadInputTokens !== null && log.cacheReadInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0"), children: [
|
|
2591
2969
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CacheTrendIndicator, { trend: cacheTrend?.read ?? null }),
|
|
2592
2970
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-purple-400", children: [
|
|
2593
2971
|
"KV Cache ~",
|
|
2594
2972
|
formatTokens(log.cacheReadInputTokens)
|
|
2595
2973
|
] })
|
|
2596
2974
|
] }),
|
|
2597
|
-
messageCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2975
|
+
messageCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-muted-foreground"), children: [
|
|
2598
2976
|
/* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3" }),
|
|
2599
2977
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: messageCount })
|
|
2600
2978
|
] }),
|
|
2601
|
-
toolCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2979
|
+
toolCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-muted-foreground"), children: [
|
|
2602
2980
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3" }),
|
|
2603
2981
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: toolCount })
|
|
2604
2982
|
] }),
|
|
2605
2983
|
log.origin !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2606
2984
|
"span",
|
|
2607
2985
|
{
|
|
2608
|
-
className: "hidden
|
|
2986
|
+
className: cn(TELEMETRY_CHIP_CLASS, "hidden shrink-0 text-muted-foreground xl:flex"),
|
|
2609
2987
|
title: `Origin: ${log.origin}`,
|
|
2610
2988
|
children: [
|
|
2611
2989
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Globe, { className: "size-3" }),
|
|
@@ -2614,7 +2992,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2614
2992
|
}
|
|
2615
2993
|
),
|
|
2616
2994
|
(hasClientPid || hasClientProjectFolder) && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2617
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden
|
|
2995
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "hidden shrink-0 text-purple-300 xl:flex"), children: [
|
|
2618
2996
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FileTerminal, { className: "size-3" }),
|
|
2619
2997
|
hasClientProjectFolder ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: log.clientProjectFolder }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
2620
2998
|
"PID ",
|
|
@@ -2719,8 +3097,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2719
3097
|
] })
|
|
2720
3098
|
]
|
|
2721
3099
|
}
|
|
2722
|
-
)
|
|
2723
|
-
expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 text-muted-foreground shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" })
|
|
3100
|
+
)
|
|
2724
3101
|
]
|
|
2725
3102
|
}
|
|
2726
3103
|
) });
|
|
@@ -2740,365 +3117,6 @@ function CollapsibleContent({
|
|
|
2740
3117
|
}) {
|
|
2741
3118
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent$1, { "data-slot": "collapsible-content", ...props });
|
|
2742
3119
|
}
|
|
2743
|
-
function classifyValue(value) {
|
|
2744
|
-
if (value === null) return "null";
|
|
2745
|
-
if (Array.isArray(value)) return "array";
|
|
2746
|
-
switch (typeof value) {
|
|
2747
|
-
case "string":
|
|
2748
|
-
return "string";
|
|
2749
|
-
case "number":
|
|
2750
|
-
return "number";
|
|
2751
|
-
case "boolean":
|
|
2752
|
-
return "boolean";
|
|
2753
|
-
case "object":
|
|
2754
|
-
return "object";
|
|
2755
|
-
case "bigint":
|
|
2756
|
-
case "symbol":
|
|
2757
|
-
case "undefined":
|
|
2758
|
-
case "function":
|
|
2759
|
-
return "object";
|
|
2760
|
-
}
|
|
2761
|
-
}
|
|
2762
|
-
function isExpandable(value) {
|
|
2763
|
-
return value !== null && (Array.isArray(value) || typeof value === "object");
|
|
2764
|
-
}
|
|
2765
|
-
function getEntries(value) {
|
|
2766
|
-
if (Array.isArray(value)) {
|
|
2767
|
-
return value.map((item, index) => [String(index), item]);
|
|
2768
|
-
}
|
|
2769
|
-
if (typeof value === "object" && value !== null) {
|
|
2770
|
-
return Object.entries(value);
|
|
2771
|
-
}
|
|
2772
|
-
return [];
|
|
2773
|
-
}
|
|
2774
|
-
const STRING_TRUNCATE_LIMIT = 120;
|
|
2775
|
-
function StringValue({ text }) {
|
|
2776
|
-
const [expanded, setExpanded] = reactExports.useState(false);
|
|
2777
|
-
const isLong = text.length > STRING_TRUNCATE_LIMIT;
|
|
2778
|
-
if (!isLong) {
|
|
2779
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-emerald-400 break-all", children: [
|
|
2780
|
-
'"',
|
|
2781
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "prose prose-sm dark:prose-invert inline max-w-none [&_p]:inline [&_p]:my-0 [&_code]:text-emerald-300 [&_a]:text-emerald-300", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: text }) }),
|
|
2782
|
-
'"'
|
|
2783
|
-
] });
|
|
2784
|
-
}
|
|
2785
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-emerald-400 break-all", children: [
|
|
2786
|
-
'"',
|
|
2787
|
-
expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2788
|
-
"span",
|
|
2789
|
-
{
|
|
2790
|
-
className: "cursor-pointer prose prose-sm dark:prose-invert inline max-w-none [&_p]:inline [&_p]:my-0 [&_code]:text-emerald-300 [&_a]:text-emerald-300",
|
|
2791
|
-
onClick: (e) => {
|
|
2792
|
-
e.stopPropagation();
|
|
2793
|
-
setExpanded(false);
|
|
2794
|
-
},
|
|
2795
|
-
onKeyDown: (e) => {
|
|
2796
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
2797
|
-
e.stopPropagation();
|
|
2798
|
-
setExpanded(false);
|
|
2799
|
-
}
|
|
2800
|
-
},
|
|
2801
|
-
role: "button",
|
|
2802
|
-
tabIndex: 0,
|
|
2803
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: text })
|
|
2804
|
-
}
|
|
2805
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { delayDuration: 300, children: [
|
|
2806
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2807
|
-
TooltipTrigger,
|
|
2808
|
-
{
|
|
2809
|
-
onClick: (e) => {
|
|
2810
|
-
e.stopPropagation();
|
|
2811
|
-
setExpanded(true);
|
|
2812
|
-
},
|
|
2813
|
-
className: "text-left cursor-pointer",
|
|
2814
|
-
children: [
|
|
2815
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: text.slice(0, STRING_TRUNCATE_LIMIT) }),
|
|
2816
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-emerald-400/50", children: "…" })
|
|
2817
|
-
]
|
|
2818
|
-
}
|
|
2819
|
-
),
|
|
2820
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2821
|
-
TooltipContent,
|
|
2822
|
-
{
|
|
2823
|
-
side: "bottom",
|
|
2824
|
-
className: "max-w-md text-xs p-2 break-words whitespace-pre-wrap",
|
|
2825
|
-
children: [
|
|
2826
|
-
text.slice(0, 500),
|
|
2827
|
-
text.length > 500 ? "…" : ""
|
|
2828
|
-
]
|
|
2829
|
-
}
|
|
2830
|
-
)
|
|
2831
|
-
] }),
|
|
2832
|
-
'"'
|
|
2833
|
-
] });
|
|
2834
|
-
}
|
|
2835
|
-
function PrimitiveValue({ value }) {
|
|
2836
|
-
if (value === null) {
|
|
2837
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-rose-400 italic", children: "null" });
|
|
2838
|
-
}
|
|
2839
|
-
switch (typeof value) {
|
|
2840
|
-
case "string":
|
|
2841
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(StringValue, { text: value });
|
|
2842
|
-
case "number":
|
|
2843
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-400", children: value });
|
|
2844
|
-
case "boolean":
|
|
2845
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400", children: value ? "true" : "false" });
|
|
2846
|
-
case "object":
|
|
2847
|
-
case "bigint":
|
|
2848
|
-
case "symbol":
|
|
2849
|
-
case "undefined":
|
|
2850
|
-
case "function":
|
|
2851
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: JSON.stringify(value) });
|
|
2852
|
-
}
|
|
2853
|
-
}
|
|
2854
|
-
function CopyValueButton({ value }) {
|
|
2855
|
-
const [copied, setCopied] = reactExports.useState(false);
|
|
2856
|
-
function handleCopy(e) {
|
|
2857
|
-
e.stopPropagation();
|
|
2858
|
-
void copyTextToClipboard(JSON.stringify(value, null, 2)).then((success) => {
|
|
2859
|
-
if (!success) return;
|
|
2860
|
-
setCopied(true);
|
|
2861
|
-
setTimeout(() => {
|
|
2862
|
-
setCopied(false);
|
|
2863
|
-
}, 2e3);
|
|
2864
|
-
});
|
|
2865
|
-
}
|
|
2866
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2867
|
-
"button",
|
|
2868
|
-
{
|
|
2869
|
-
type: "button",
|
|
2870
|
-
onClick: handleCopy,
|
|
2871
|
-
className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors",
|
|
2872
|
-
"aria-label": copied ? "Copied JSON" : "Copy JSON",
|
|
2873
|
-
title: "Copy JSON",
|
|
2874
|
-
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3 text-green-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3" })
|
|
2875
|
-
}
|
|
2876
|
-
);
|
|
2877
|
-
}
|
|
2878
|
-
function CopyButton({ value }) {
|
|
2879
|
-
const [copied, setCopied] = reactExports.useState(false);
|
|
2880
|
-
function handleCopy(e) {
|
|
2881
|
-
e.stopPropagation();
|
|
2882
|
-
void copyTextToClipboard(JSON.stringify(value, null, 2)).then((success) => {
|
|
2883
|
-
if (!success) return;
|
|
2884
|
-
setCopied(true);
|
|
2885
|
-
setTimeout(() => {
|
|
2886
|
-
setCopied(false);
|
|
2887
|
-
}, 2e3);
|
|
2888
|
-
});
|
|
2889
|
-
}
|
|
2890
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2891
|
-
"button",
|
|
2892
|
-
{
|
|
2893
|
-
type: "button",
|
|
2894
|
-
onClick: handleCopy,
|
|
2895
|
-
className: "opacity-0 group-hover/row:opacity-100 hover:bg-muted p-0.5 rounded transition-opacity shrink-0",
|
|
2896
|
-
"aria-label": copied ? "Copied JSON value" : "Copy JSON value",
|
|
2897
|
-
title: "Copy to clipboard",
|
|
2898
|
-
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3 text-green-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3 text-muted-foreground" })
|
|
2899
|
-
}
|
|
2900
|
-
);
|
|
2901
|
-
}
|
|
2902
|
-
function ExpandCollapseButton({
|
|
2903
|
-
onClick
|
|
2904
|
-
}) {
|
|
2905
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2906
|
-
"button",
|
|
2907
|
-
{
|
|
2908
|
-
type: "button",
|
|
2909
|
-
onClick,
|
|
2910
|
-
className: "opacity-0 group-hover/row:opacity-100 hover:bg-muted p-0.5 rounded transition-opacity shrink-0",
|
|
2911
|
-
title: "Expand all descendants",
|
|
2912
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsDown, { className: "size-3.5 text-muted-foreground" })
|
|
2913
|
-
}
|
|
2914
|
-
);
|
|
2915
|
-
}
|
|
2916
|
-
const JsonNode = reactExports.memo(function JsonNode2({
|
|
2917
|
-
name,
|
|
2918
|
-
value,
|
|
2919
|
-
level,
|
|
2920
|
-
defaultExpandDepth,
|
|
2921
|
-
isArrayItem,
|
|
2922
|
-
path,
|
|
2923
|
-
expandTargetPath,
|
|
2924
|
-
anatomyPaths
|
|
2925
|
-
}) {
|
|
2926
|
-
const isAncestorOfTarget = reactExports.useMemo(() => {
|
|
2927
|
-
if (expandTargetPath === null) return false;
|
|
2928
|
-
if (path === "") return expandTargetPath.length > 0;
|
|
2929
|
-
return expandTargetPath === path || expandTargetPath.startsWith(`${path}/`);
|
|
2930
|
-
}, [expandTargetPath, path]);
|
|
2931
|
-
const initialExpanded = level < defaultExpandDepth || isAncestorOfTarget && isExpandable(value);
|
|
2932
|
-
const [expanded, setExpanded] = reactExports.useState(initialExpanded);
|
|
2933
|
-
reactExports.useEffect(() => {
|
|
2934
|
-
if (isAncestorOfTarget && isExpandable(value) && !expanded) {
|
|
2935
|
-
setExpanded(true);
|
|
2936
|
-
}
|
|
2937
|
-
}, [expandTargetPath]);
|
|
2938
|
-
const [childResetKey, setChildResetKey] = reactExports.useState(0);
|
|
2939
|
-
const [childDepthOverride, setChildDepthOverride] = reactExports.useState(null);
|
|
2940
|
-
const expandable = isExpandable(value);
|
|
2941
|
-
const fullyExpanded = childDepthOverride === Number.POSITIVE_INFINITY;
|
|
2942
|
-
const entries = reactExports.useMemo(() => getEntries(value), [value]);
|
|
2943
|
-
const hasExpandableChild = reactExports.useMemo(
|
|
2944
|
-
() => entries.some(([, child]) => isExpandable(child)),
|
|
2945
|
-
[entries]
|
|
2946
|
-
);
|
|
2947
|
-
const dataType = classifyValue(value);
|
|
2948
|
-
const openBracket = dataType === "array" ? "[" : "{";
|
|
2949
|
-
const closeBracket = dataType === "array" ? "]" : "}";
|
|
2950
|
-
const hasAnatomyPath = anatomyPaths !== null && anatomyPaths.has(path);
|
|
2951
|
-
function expandAllDeep() {
|
|
2952
|
-
setExpanded(true);
|
|
2953
|
-
setChildDepthOverride(Number.POSITIVE_INFINITY);
|
|
2954
|
-
setChildResetKey((k) => k + 1);
|
|
2955
|
-
}
|
|
2956
|
-
function collapseToDefault() {
|
|
2957
|
-
setExpanded(false);
|
|
2958
|
-
setChildDepthOverride(0);
|
|
2959
|
-
setChildResetKey((k) => k + 1);
|
|
2960
|
-
}
|
|
2961
|
-
function handleRowToggle() {
|
|
2962
|
-
if (fullyExpanded) {
|
|
2963
|
-
collapseToDefault();
|
|
2964
|
-
} else {
|
|
2965
|
-
setExpanded(!expanded);
|
|
2966
|
-
}
|
|
2967
|
-
}
|
|
2968
|
-
function handleExpandAll(e) {
|
|
2969
|
-
e.stopPropagation();
|
|
2970
|
-
expandAllDeep();
|
|
2971
|
-
}
|
|
2972
|
-
const effectiveChildDepth = childDepthOverride ?? defaultExpandDepth;
|
|
2973
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn(level > 0 && "border-l border-border/50 ml-2"), children: [
|
|
2974
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2975
|
-
"div",
|
|
2976
|
-
{
|
|
2977
|
-
className: cn(
|
|
2978
|
-
"flex items-start gap-1 py-0.5 px-1 -ml-1 rounded-sm group/row",
|
|
2979
|
-
expandable && "cursor-pointer hover:bg-muted/50"
|
|
2980
|
-
),
|
|
2981
|
-
"data-anatomy-path": hasAnatomyPath ? path : void 0,
|
|
2982
|
-
onClick: expandable ? handleRowToggle : void 0,
|
|
2983
|
-
onKeyDown: expandable ? (e) => {
|
|
2984
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
2985
|
-
e.preventDefault();
|
|
2986
|
-
handleRowToggle();
|
|
2987
|
-
}
|
|
2988
|
-
} : void 0,
|
|
2989
|
-
onDoubleClick: expandable && hasExpandableChild ? () => expandAllDeep() : void 0,
|
|
2990
|
-
role: expandable ? "button" : void 0,
|
|
2991
|
-
tabIndex: expandable ? 0 : void 0,
|
|
2992
|
-
children: [
|
|
2993
|
-
expandable ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-4 h-5 flex items-center justify-center shrink-0", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-4 shrink-0" }),
|
|
2994
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("shrink-0", isArrayItem ? "text-muted-foreground" : "text-cyan-400"), children: isArrayItem ? name : `"${name}"` }),
|
|
2995
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground shrink-0", children: expandable ? "" : ":" }),
|
|
2996
|
-
expandable ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [
|
|
2997
|
-
openBracket,
|
|
2998
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground/60 text-xs", children: [
|
|
2999
|
-
" ",
|
|
3000
|
-
entries.length,
|
|
3001
|
-
" ",
|
|
3002
|
-
entries.length === 1 ? "item" : "items",
|
|
3003
|
-
" ",
|
|
3004
|
-
closeBracket
|
|
3005
|
-
] })
|
|
3006
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(PrimitiveValue, { value }) }),
|
|
3007
|
-
expandable && hasExpandableChild && !fullyExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandCollapseButton, { onClick: handleExpandAll }),
|
|
3008
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyButton, { value })
|
|
3009
|
-
]
|
|
3010
|
-
}
|
|
3011
|
-
),
|
|
3012
|
-
expandable && expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pl-4", children: [
|
|
3013
|
-
entries.map(([key, childValue]) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3014
|
-
JsonNode2,
|
|
3015
|
-
{
|
|
3016
|
-
name: key,
|
|
3017
|
-
value: childValue,
|
|
3018
|
-
level: level + 1,
|
|
3019
|
-
defaultExpandDepth: effectiveChildDepth,
|
|
3020
|
-
isArrayItem: dataType === "array",
|
|
3021
|
-
path: path === "" ? `/${key}` : `${path}/${key}`,
|
|
3022
|
-
expandTargetPath,
|
|
3023
|
-
anatomyPaths
|
|
3024
|
-
},
|
|
3025
|
-
key
|
|
3026
|
-
)),
|
|
3027
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground py-0.5 px-1", children: closeBracket })
|
|
3028
|
-
] }, childResetKey)
|
|
3029
|
-
] });
|
|
3030
|
-
});
|
|
3031
|
-
function JsonViewer({
|
|
3032
|
-
data,
|
|
3033
|
-
defaultExpandDepth = 0,
|
|
3034
|
-
className,
|
|
3035
|
-
showCopy = false,
|
|
3036
|
-
bulkDepth: controlledBulkDepth,
|
|
3037
|
-
bulkRevision: controlledBulkRevision,
|
|
3038
|
-
anatomyPaths = null,
|
|
3039
|
-
expandToPath = null
|
|
3040
|
-
}) {
|
|
3041
|
-
const expandable = isExpandable(data);
|
|
3042
|
-
const entries = reactExports.useMemo(() => getEntries(data), [data]);
|
|
3043
|
-
const bulkDepth = controlledBulkDepth ?? defaultExpandDepth;
|
|
3044
|
-
const bulkRevision = controlledBulkRevision ?? 0;
|
|
3045
|
-
if (!expandable) {
|
|
3046
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("font-mono text-xs leading-relaxed", className), children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
3047
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(PrimitiveValue, { value: data }),
|
|
3048
|
-
showCopy && /* @__PURE__ */ jsxRuntimeExports.jsx(CopyValueButton, { value: data })
|
|
3049
|
-
] }) }) });
|
|
3050
|
-
}
|
|
3051
|
-
const dataType = classifyValue(data);
|
|
3052
|
-
const isArray = dataType === "array";
|
|
3053
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("font-mono text-xs leading-relaxed", className), children: [
|
|
3054
|
-
showCopy && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-2 flex items-center justify-end gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyValueButton, { value: data }) }),
|
|
3055
|
-
entries.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-white/10 bg-black/20 px-3 py-2 text-muted-foreground", children: [
|
|
3056
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-cyan-300", children: isArray ? "[]" : "{}" }),
|
|
3057
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2 text-[10px] uppercase", children: "0 items" })
|
|
3058
|
-
] }),
|
|
3059
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: entries.map(([key, childValue]) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3060
|
-
JsonNode,
|
|
3061
|
-
{
|
|
3062
|
-
name: key,
|
|
3063
|
-
value: childValue,
|
|
3064
|
-
level: 0,
|
|
3065
|
-
defaultExpandDepth: bulkDepth,
|
|
3066
|
-
isArrayItem: isArray,
|
|
3067
|
-
path: `/${key}`,
|
|
3068
|
-
expandTargetPath: expandToPath,
|
|
3069
|
-
anatomyPaths
|
|
3070
|
-
},
|
|
3071
|
-
key
|
|
3072
|
-
)) }, bulkRevision)
|
|
3073
|
-
] }) });
|
|
3074
|
-
}
|
|
3075
|
-
const JsonViewerFromString = reactExports.memo(function JsonViewerFromString2({
|
|
3076
|
-
text,
|
|
3077
|
-
defaultExpandDepth = 0,
|
|
3078
|
-
className,
|
|
3079
|
-
bulkDepth,
|
|
3080
|
-
bulkRevision
|
|
3081
|
-
}) {
|
|
3082
|
-
const parsed = reactExports.useMemo(() => parseJsonText(text), [text]);
|
|
3083
|
-
if (parsed.kind === "json") {
|
|
3084
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3085
|
-
JsonViewer,
|
|
3086
|
-
{
|
|
3087
|
-
data: parsed.data,
|
|
3088
|
-
defaultExpandDepth,
|
|
3089
|
-
className,
|
|
3090
|
-
bulkDepth,
|
|
3091
|
-
bulkRevision
|
|
3092
|
-
}
|
|
3093
|
-
);
|
|
3094
|
-
}
|
|
3095
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: cn("font-mono text-xs whitespace-pre-wrap break-words", className), children: text });
|
|
3096
|
-
});
|
|
3097
|
-
const jsonViewer = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
3098
|
-
__proto__: null,
|
|
3099
|
-
JsonViewer,
|
|
3100
|
-
JsonViewerFromString
|
|
3101
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
3102
3120
|
function ScrollArea({
|
|
3103
3121
|
className,
|
|
3104
3122
|
children,
|
|
@@ -3253,10 +3271,16 @@ function ToolRow({ tool, called }) {
|
|
|
3253
3271
|
}
|
|
3254
3272
|
)
|
|
3255
3273
|
] }),
|
|
3256
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-white/[0.02] px-2.5 py-2", children: [
|
|
3274
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: open && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-white/[0.02] px-2.5 py-2", children: [
|
|
3257
3275
|
tool.description !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs leading-relaxed text-muted-foreground", children: tool.description }),
|
|
3258
3276
|
/* @__PURE__ */ jsxRuntimeExports.jsx(RequiredParameters, { names: tool.requiredParameters }),
|
|
3259
|
-
tool.schema !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "max-h-64 rounded-md border border-white/10 bg-[#06080b] p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3277
|
+
tool.schema !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "max-h-64 rounded-md border border-white/10 bg-[#06080b] p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3278
|
+
reactExports.Suspense,
|
|
3279
|
+
{
|
|
3280
|
+
fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "Loading JSON..." }),
|
|
3281
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyJsonViewer, { data: safeJsonValue(tool.schema), defaultExpandDepth: 0 })
|
|
3282
|
+
}
|
|
3283
|
+
) })
|
|
3260
3284
|
] }) })
|
|
3261
3285
|
] }) });
|
|
3262
3286
|
}
|
|
@@ -3369,26 +3393,6 @@ const RequestTools = reactExports.memo(function RequestTools2({
|
|
|
3369
3393
|
] })
|
|
3370
3394
|
] });
|
|
3371
3395
|
});
|
|
3372
|
-
const LOG_FOCUS_REQUEST_EVENT = "agent-inspector:focus-log";
|
|
3373
|
-
function dispatchLogFocusRequest(request) {
|
|
3374
|
-
window.dispatchEvent(new CustomEvent(LOG_FOCUS_REQUEST_EVENT, { detail: request }));
|
|
3375
|
-
}
|
|
3376
|
-
function readLogFocusRequest(event) {
|
|
3377
|
-
if (typeof CustomEvent === "undefined" || !(event instanceof CustomEvent)) return null;
|
|
3378
|
-
const detail = event.detail;
|
|
3379
|
-
const logId = safeGetOwnProperty(detail, "logId");
|
|
3380
|
-
if (typeof logId !== "number" || !Number.isInteger(logId) || logId < 0) return null;
|
|
3381
|
-
const tab = safeGetOwnProperty(detail, "tab");
|
|
3382
|
-
switch (tab) {
|
|
3383
|
-
case "anatomy":
|
|
3384
|
-
case "request":
|
|
3385
|
-
return { logId, tab };
|
|
3386
|
-
case void 0:
|
|
3387
|
-
return { logId, tab: "request" };
|
|
3388
|
-
default:
|
|
3389
|
-
return null;
|
|
3390
|
-
}
|
|
3391
|
-
}
|
|
3392
3396
|
function shouldShowRawRequestTab(apiFormat, viewMode, strip) {
|
|
3393
3397
|
return apiFormat === "anthropic" && viewMode === "full" && strip;
|
|
3394
3398
|
}
|
|
@@ -3500,10 +3504,12 @@ function parseAnthropicTool(tool) {
|
|
|
3500
3504
|
}
|
|
3501
3505
|
function parseOpenAITool(tool) {
|
|
3502
3506
|
const fn = safeGetOwnProperty(tool, "function");
|
|
3503
|
-
const
|
|
3507
|
+
const toolType = safeGetOwnProperty(tool, "type");
|
|
3508
|
+
if (fn === void 0 && toolType !== "function") return null;
|
|
3509
|
+
const name = safeGetOwnProperty(fn, "name") ?? safeGetOwnProperty(tool, "name");
|
|
3504
3510
|
if (typeof name !== "string" || name.length === 0) return null;
|
|
3505
|
-
const description = safeGetOwnProperty(fn, "description");
|
|
3506
|
-
const schema = safeGetOwnProperty(fn, "parameters") ?? null;
|
|
3511
|
+
const description = safeGetOwnProperty(fn, "description") ?? safeGetOwnProperty(tool, "description");
|
|
3512
|
+
const schema = safeGetOwnProperty(fn, "parameters") ?? safeGetOwnProperty(tool, "parameters") ?? null;
|
|
3507
3513
|
const normalizedDescription = typeof description === "string" ? description : null;
|
|
3508
3514
|
return {
|
|
3509
3515
|
name,
|
|
@@ -3576,7 +3582,7 @@ const FULL_LOG_HYDRATION_TIMEOUT_MS = 15e3;
|
|
|
3576
3582
|
const BODY_CHUNK_TIMEOUT_MS = 15e3;
|
|
3577
3583
|
const BODY_CHUNK_BYTES = 256 * 1024;
|
|
3578
3584
|
const CHUNKED_BODY_THRESHOLD_BYTES = 1024 * 1024;
|
|
3579
|
-
const TAB_TRIGGER_CLASS = "h-9 flex-none rounded-none border-0 border-b-2 border-transparent bg-transparent px-3 text-xs font-semibold text-muted-foreground shadow-none hover:bg-cyan-400/[0.
|
|
3585
|
+
const TAB_TRIGGER_CLASS = "h-9 flex-none rounded-none border-0 border-b-2 border-transparent bg-transparent px-3 text-xs font-semibold text-muted-foreground shadow-none transition-colors hover:bg-cyan-400/[0.05] hover:text-foreground data-[state=active]:border-cyan-300 data-[state=active]:bg-cyan-300/[0.04] data-[state=active]:text-cyan-100 data-[state=active]:shadow-none";
|
|
3580
3586
|
function createEmptyBodyPreviewState(totalBytes = null) {
|
|
3581
3587
|
return {
|
|
3582
3588
|
status: "idle",
|
|
@@ -3627,7 +3633,7 @@ function ExpandedPanel({
|
|
|
3627
3633
|
"div",
|
|
3628
3634
|
{
|
|
3629
3635
|
className: cn(
|
|
3630
|
-
"inspector-scrollbar mx-3 mb-3 max-h-[72vh] overflow-auto rounded-md border border-
|
|
3636
|
+
"inspector-scrollbar mx-3 mb-3 max-h-[72vh] overflow-auto rounded-md border border-cyan-300/10 bg-[#05070a] p-3 shadow-[0_16px_45px_rgba(0,0,0,0.24),inset_0_1px_0_rgba(255,255,255,0.05)]",
|
|
3631
3637
|
className
|
|
3632
3638
|
),
|
|
3633
3639
|
children
|
|
@@ -3763,6 +3769,7 @@ const HeadersDiffContent = reactExports.memo(function({
|
|
|
3763
3769
|
});
|
|
3764
3770
|
const LogEntry = reactExports.memo(function({
|
|
3765
3771
|
log,
|
|
3772
|
+
displayNumber,
|
|
3766
3773
|
viewMode = "simple",
|
|
3767
3774
|
strip,
|
|
3768
3775
|
slowResponseThresholdSeconds,
|
|
@@ -3786,6 +3793,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
3786
3793
|
);
|
|
3787
3794
|
const requestJsonRef = reactExports.useRef(null);
|
|
3788
3795
|
const logIdRef = reactExports.useRef(log.id);
|
|
3796
|
+
const bodyHydrationInFlightRef = reactExports.useRef(false);
|
|
3789
3797
|
const displayLog = hydratedLog ?? log;
|
|
3790
3798
|
const useChunkedBody = hydratedLog === null && shouldUseChunkedBodyLoading(log);
|
|
3791
3799
|
const requestPreviewBody = bodyPreviewTextForView(useChunkedBody, requestPreview);
|
|
@@ -3817,10 +3825,10 @@ const LogEntry = reactExports.memo(function({
|
|
|
3817
3825
|
requestPreviewShouldParse ? displayedRequestBody : null
|
|
3818
3826
|
);
|
|
3819
3827
|
const rawRequestExpansion = useJsonBulkExpansion(
|
|
3820
|
-
requestPreviewShouldParse ? rawRequestBodyForView : null
|
|
3828
|
+
activeTab === "raw-request" && requestPreviewShouldParse ? rawRequestBodyForView : null
|
|
3821
3829
|
);
|
|
3822
3830
|
const responseExpansion = useJsonBulkExpansion(
|
|
3823
|
-
responsePreviewShouldParse ? responseTextForView : null
|
|
3831
|
+
activeTab === "raw" && responsePreviewShouldParse ? responseTextForView : null
|
|
3824
3832
|
);
|
|
3825
3833
|
const headersText = reactExports.useMemo(
|
|
3826
3834
|
() => displayLog.headers && Object.keys(displayLog.headers).length > 0 ? JSON.stringify(displayLog.headers, null, 2) : null,
|
|
@@ -3993,6 +4001,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
3993
4001
|
}, [anatomySegments, expanded]);
|
|
3994
4002
|
reactExports.useEffect(() => {
|
|
3995
4003
|
logIdRef.current = log.id;
|
|
4004
|
+
bodyHydrationInFlightRef.current = false;
|
|
3996
4005
|
setHydratedLog(null);
|
|
3997
4006
|
setBodyHydrationState("idle");
|
|
3998
4007
|
setRequestPreview(createEmptyBodyPreviewState(log.rawRequestBodyBytes ?? null));
|
|
@@ -4001,8 +4010,9 @@ const LogEntry = reactExports.memo(function({
|
|
|
4001
4010
|
reactExports.useEffect(() => {
|
|
4002
4011
|
if (!expanded) return;
|
|
4003
4012
|
if (!shouldHydrateLogBody(log)) return;
|
|
4004
|
-
if (hydratedLog !== null ||
|
|
4013
|
+
if (hydratedLog !== null || bodyHydrationInFlightRef.current) return;
|
|
4005
4014
|
let cancelled = false;
|
|
4015
|
+
bodyHydrationInFlightRef.current = true;
|
|
4006
4016
|
setBodyHydrationState("loading");
|
|
4007
4017
|
void fetchJsonWithTimeout(
|
|
4008
4018
|
`/api/logs/${String(log.id)}`,
|
|
@@ -4010,17 +4020,19 @@ const LogEntry = reactExports.memo(function({
|
|
|
4010
4020
|
FULL_LOG_HYDRATION_TIMEOUT_MS
|
|
4011
4021
|
).then((fullLog) => {
|
|
4012
4022
|
if (cancelled) return;
|
|
4023
|
+
bodyHydrationInFlightRef.current = false;
|
|
4013
4024
|
setHydratedLog(fullLog);
|
|
4014
4025
|
setBodyHydrationState("idle");
|
|
4015
4026
|
}).catch(() => {
|
|
4016
4027
|
if (cancelled) return;
|
|
4028
|
+
bodyHydrationInFlightRef.current = false;
|
|
4017
4029
|
setBodyHydrationState("failed");
|
|
4018
4030
|
});
|
|
4019
4031
|
return () => {
|
|
4020
4032
|
cancelled = true;
|
|
4033
|
+
bodyHydrationInFlightRef.current = false;
|
|
4021
4034
|
};
|
|
4022
4035
|
}, [
|
|
4023
|
-
bodyHydrationState,
|
|
4024
4036
|
expanded,
|
|
4025
4037
|
hydratedLog,
|
|
4026
4038
|
log.bodyContentMode,
|
|
@@ -4060,14 +4072,32 @@ const LogEntry = reactExports.memo(function({
|
|
|
4060
4072
|
"div",
|
|
4061
4073
|
{
|
|
4062
4074
|
className: cn(
|
|
4063
|
-
"mb-2 overflow-hidden rounded-
|
|
4064
|
-
expanded ? "border-cyan-300/
|
|
4075
|
+
"relative mb-2 overflow-hidden rounded-lg border bg-[#07090d] transition-[background-color,border-color,box-shadow]",
|
|
4076
|
+
expanded ? "border-cyan-300/25 shadow-[0_24px_80px_rgba(0,0,0,0.34),0_0_0_1px_rgba(103,232,249,0.04),inset_0_1px_0_rgba(255,255,255,0.06)]" : "border-white/10 shadow-[0_6px_24px_rgba(0,0,0,0.16)] hover:border-cyan-300/15"
|
|
4065
4077
|
),
|
|
4066
4078
|
children: [
|
|
4079
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4080
|
+
"div",
|
|
4081
|
+
{
|
|
4082
|
+
className: cn(
|
|
4083
|
+
"pointer-events-none absolute inset-y-3 left-1 w-px rounded-full",
|
|
4084
|
+
expanded ? "bg-cyan-300/45 shadow-[0_0_20px_rgba(103,232,249,0.28)]" : "bg-white/10"
|
|
4085
|
+
),
|
|
4086
|
+
"aria-hidden": "true"
|
|
4087
|
+
}
|
|
4088
|
+
),
|
|
4089
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4090
|
+
"div",
|
|
4091
|
+
{
|
|
4092
|
+
className: "pointer-events-none absolute inset-x-3 top-0 h-px bg-gradient-to-r from-transparent via-white/15 to-transparent",
|
|
4093
|
+
"aria-hidden": "true"
|
|
4094
|
+
}
|
|
4095
|
+
),
|
|
4067
4096
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4068
4097
|
LogEntryHeader,
|
|
4069
4098
|
{
|
|
4070
4099
|
log: displayLog,
|
|
4100
|
+
displayNumber,
|
|
4071
4101
|
messageCount: requestAnalysis.messageCount,
|
|
4072
4102
|
toolCount: requestAnalysis.toolCount,
|
|
4073
4103
|
expanded,
|
|
@@ -4082,194 +4112,224 @@ const LogEntry = reactExports.memo(function({
|
|
|
4082
4112
|
}
|
|
4083
4113
|
}
|
|
4084
4114
|
),
|
|
4085
|
-
expanded && /* @__PURE__ */ jsxRuntimeExports.
|
|
4115
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4086
4116
|
"div",
|
|
4087
4117
|
{
|
|
4088
|
-
className: "border-t border-
|
|
4118
|
+
className: "relative border-t border-cyan-300/10 bg-[linear-gradient(180deg,#06090d_0%,#040506_100%)] pt-2",
|
|
4089
4119
|
onClick: (e) => e.stopPropagation(),
|
|
4090
4120
|
onKeyDown: (e) => e.stopPropagation(),
|
|
4091
|
-
children:
|
|
4092
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
4093
|
-
|
|
4121
|
+
children: [
|
|
4122
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4123
|
+
"div",
|
|
4094
4124
|
{
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
children: [
|
|
4098
|
-
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-headers", children: "Raw Headers" }),
|
|
4099
|
-
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "headers", children: "Headers" }),
|
|
4100
|
-
anatomySegments !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "anatomy", children: "Context" }),
|
|
4101
|
-
shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-request", children: "Raw Request" }),
|
|
4102
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "request", children: "Request" }),
|
|
4103
|
-
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw", children: "Raw Response" }),
|
|
4104
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "parsed", children: "Response" })
|
|
4105
|
-
]
|
|
4125
|
+
className: "pointer-events-none absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-cyan-300/[0.035] to-transparent",
|
|
4126
|
+
"aria-hidden": "true"
|
|
4106
4127
|
}
|
|
4107
4128
|
),
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
{
|
|
4112
|
-
label: "Request",
|
|
4113
|
-
state: requestPreview,
|
|
4114
|
-
expectedBytes: log.rawRequestBodyBytes ?? null,
|
|
4115
|
-
onLoadMore: () => loadBodyChunk("request", requestPreview.offset)
|
|
4116
|
-
}
|
|
4117
|
-
),
|
|
4118
|
-
rawRequestBodyForView === null ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: useChunkedBody ? "Request preview is loading" : "No request body" }) : rawRequestExpansion.parsedData !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4119
|
-
LazyJsonViewer,
|
|
4120
|
-
{
|
|
4121
|
-
data: rawRequestExpansion.parsedData,
|
|
4122
|
-
bulkDepth: rawRequestExpansion.bulkDepth,
|
|
4123
|
-
bulkRevision: rawRequestExpansion.bulkRevision
|
|
4124
|
-
}
|
|
4125
|
-
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: rawRequestBodyForView })
|
|
4126
|
-
] }) }),
|
|
4127
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "request", children: activeTab === "request" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4128
|
-
bodyHydrationState === "loading" && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "loading", children: "Loading full request and response bodies..." }),
|
|
4129
|
-
bodyHydrationState === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "warning", children: "Full request and response bodies could not be loaded. Compact metadata is still available." }),
|
|
4130
|
-
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4131
|
-
BodyPreviewNotice,
|
|
4129
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "gap-2", children: [
|
|
4130
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4131
|
+
TabsList,
|
|
4132
4132
|
{
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4133
|
+
variant: "line",
|
|
4134
|
+
className: "inspector-scrollbar relative mx-3 h-auto w-[calc(100%-1.5rem)] justify-start overflow-x-auto rounded-none border-b border-cyan-300/10 bg-black/10 p-0",
|
|
4135
|
+
children: [
|
|
4136
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-headers", children: "Raw Headers" }),
|
|
4137
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "headers", children: "Headers" }),
|
|
4138
|
+
anatomySegments !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "anatomy", children: "Context" }),
|
|
4139
|
+
shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-request", children: "Raw Request" }),
|
|
4140
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "request", children: "Request" }),
|
|
4141
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw", children: "Raw Response" }),
|
|
4142
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "parsed", children: "Response" })
|
|
4143
|
+
]
|
|
4137
4144
|
}
|
|
4138
4145
|
),
|
|
4139
|
-
|
|
4140
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
4141
|
-
|
|
4142
|
-
|
|
4146
|
+
shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-request", children: activeTab === "raw-request" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4147
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4148
|
+
BodyPreviewNotice,
|
|
4149
|
+
{
|
|
4150
|
+
label: "Request",
|
|
4151
|
+
state: requestPreview,
|
|
4152
|
+
expectedBytes: log.rawRequestBodyBytes ?? null,
|
|
4153
|
+
onLoadMore: () => loadBodyChunk("request", requestPreview.offset)
|
|
4154
|
+
}
|
|
4155
|
+
),
|
|
4156
|
+
rawRequestBodyForView === null ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: useChunkedBody ? "Request preview is loading" : "No request body" }) : rawRequestExpansion.parsedData !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4157
|
+
LazyJsonViewer,
|
|
4158
|
+
{
|
|
4159
|
+
data: rawRequestExpansion.parsedData,
|
|
4160
|
+
bulkDepth: rawRequestExpansion.bulkDepth,
|
|
4161
|
+
bulkRevision: rawRequestExpansion.bulkRevision
|
|
4162
|
+
}
|
|
4163
|
+
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: rawRequestBodyForView })
|
|
4164
|
+
] }) }),
|
|
4165
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "request", children: activeTab === "request" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4166
|
+
bodyHydrationState === "loading" && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "loading", children: "Loading full request and response bodies..." }),
|
|
4167
|
+
bodyHydrationState === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "warning", children: "Full request and response bodies could not be loaded. Compact metadata is still available." }),
|
|
4168
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4169
|
+
BodyPreviewNotice,
|
|
4170
|
+
{
|
|
4171
|
+
label: "Request",
|
|
4172
|
+
state: requestPreview,
|
|
4173
|
+
expectedBytes: log.rawRequestBodyBytes ?? null,
|
|
4174
|
+
onLoadMore: () => loadBodyChunk("request", requestPreview.offset)
|
|
4175
|
+
}
|
|
4176
|
+
),
|
|
4177
|
+
warnings.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(NoticeBlock, { tone: "warning", children: [
|
|
4178
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 font-semibold text-amber-300", children: [
|
|
4179
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3.5" }),
|
|
4180
|
+
"Tool schema warnings"
|
|
4181
|
+
] }),
|
|
4182
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "mt-2 space-y-1 text-muted-foreground", children: warnings.map((warning) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: warning }, warning)) })
|
|
4143
4183
|
] }),
|
|
4144
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
summary: requestTools,
|
|
4150
|
-
calledToolNames: responseAnalysis.toolNames ?? []
|
|
4151
|
-
}
|
|
4152
|
-
),
|
|
4153
|
-
requestDiff ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4154
|
-
RequestDiffContent,
|
|
4155
|
-
{
|
|
4156
|
-
rawBody: displayLog.rawRequestBody,
|
|
4157
|
-
displayedBody: displayedRequestBody,
|
|
4158
|
-
emptyLabel: "No transformation applied; raw and sent request bodies are identical."
|
|
4159
|
-
}
|
|
4160
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: requestJsonRef, children: displayedRequestBody === null ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: useChunkedBody ? "Request preview is loading" : "No request body" }) : requestExpansion.parsedData !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4161
|
-
LazyJsonViewer,
|
|
4162
|
-
{
|
|
4163
|
-
data: requestExpansion.parsedData,
|
|
4164
|
-
bulkDepth: requestExpansion.bulkDepth,
|
|
4165
|
-
bulkRevision: requestExpansion.bulkRevision,
|
|
4166
|
-
anatomyPaths,
|
|
4167
|
-
expandToPath
|
|
4168
|
-
}
|
|
4169
|
-
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: displayedRequestBody }) })
|
|
4170
|
-
] }) }),
|
|
4171
|
-
anatomySegments !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "anatomy", children: activeTab === "anatomy" && /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandedPanel, { className: "p-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4172
|
-
LazyRequestAnatomy,
|
|
4173
|
-
{
|
|
4174
|
-
parsed: requestExpansion.parsedData,
|
|
4175
|
-
inputTokens: displayLog.inputTokens ?? null,
|
|
4176
|
-
model: displayLog.model,
|
|
4177
|
-
segments: anatomySegments,
|
|
4178
|
-
onSegmentActivate: jumpToAnatomySegment
|
|
4179
|
-
}
|
|
4180
|
-
) }) }) }),
|
|
4181
|
-
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "headers", children: activeTab === "headers" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4182
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end gap-2 mb-2", children: shouldShowHeadersDiffButton(
|
|
4183
|
-
viewMode,
|
|
4184
|
-
displayLog.rawHeaders !== void 0 && Object.keys(displayLog.rawHeaders).length > 0
|
|
4185
|
-
) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4186
|
-
DiffToggleButton,
|
|
4187
|
-
{
|
|
4188
|
-
active: headersDiff,
|
|
4189
|
-
onClick: (e) => {
|
|
4190
|
-
e.stopPropagation();
|
|
4191
|
-
setHeadersDiff(!headersDiff);
|
|
4184
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4185
|
+
RequestTools,
|
|
4186
|
+
{
|
|
4187
|
+
summary: requestTools,
|
|
4188
|
+
calledToolNames: responseAnalysis.toolNames ?? []
|
|
4192
4189
|
}
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
}
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
{
|
|
4215
|
-
label: "Response",
|
|
4216
|
-
state: responsePreview,
|
|
4217
|
-
expectedBytes: log.responseTextBytes ?? null,
|
|
4218
|
-
onLoadMore: () => loadBodyChunk("response", responsePreview.offset)
|
|
4219
|
-
}
|
|
4220
|
-
),
|
|
4221
|
-
displayLog.error !== void 0 && displayLog.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "danger", title: "SSE Error", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: displayLog.error }) }),
|
|
4222
|
-
responseTextForView !== null && responsePreviewShouldParse ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4223
|
-
LazyJsonViewerFromString,
|
|
4224
|
-
{
|
|
4225
|
-
text: responseTextForView,
|
|
4226
|
-
defaultExpandDepth: 0,
|
|
4227
|
-
bulkDepth: responseExpansion.bulkDepth,
|
|
4228
|
-
bulkRevision: responseExpansion.bulkRevision
|
|
4229
|
-
}
|
|
4230
|
-
) }) : responseTextForView !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: responseTextForView }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: useChunkedBody ? "Response preview is loading" : "No response" }),
|
|
4231
|
-
displayLog.streaming === true && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4232
|
-
LazyStreamingChunkSequence,
|
|
4233
|
-
{
|
|
4234
|
-
logId: displayLog.id,
|
|
4235
|
-
truncated: displayLog.streamingChunksPath !== null
|
|
4236
|
-
}
|
|
4237
|
-
) })
|
|
4238
|
-
] }) }),
|
|
4239
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "parsed", children: activeTab === "parsed" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4240
|
-
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4241
|
-
BodyPreviewNotice,
|
|
4190
|
+
),
|
|
4191
|
+
requestDiff ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4192
|
+
RequestDiffContent,
|
|
4193
|
+
{
|
|
4194
|
+
rawBody: displayLog.rawRequestBody,
|
|
4195
|
+
displayedBody: displayedRequestBody,
|
|
4196
|
+
emptyLabel: "No transformation applied; raw and sent request bodies are identical."
|
|
4197
|
+
}
|
|
4198
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: requestJsonRef, children: displayedRequestBody === null ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: useChunkedBody ? "Request preview is loading" : "No request body" }) : requestExpansion.parsedData !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4199
|
+
LazyJsonViewer,
|
|
4200
|
+
{
|
|
4201
|
+
data: requestExpansion.parsedData,
|
|
4202
|
+
bulkDepth: requestExpansion.bulkDepth,
|
|
4203
|
+
bulkRevision: requestExpansion.bulkRevision,
|
|
4204
|
+
anatomyPaths,
|
|
4205
|
+
expandToPath
|
|
4206
|
+
}
|
|
4207
|
+
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: displayedRequestBody }) })
|
|
4208
|
+
] }) }),
|
|
4209
|
+
anatomySegments !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "anatomy", children: activeTab === "anatomy" && /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandedPanel, { className: "p-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4210
|
+
LazyRequestAnatomy,
|
|
4242
4211
|
{
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4212
|
+
parsed: requestExpansion.parsedData,
|
|
4213
|
+
inputTokens: displayLog.inputTokens ?? null,
|
|
4214
|
+
model: displayLog.model,
|
|
4215
|
+
segments: anatomySegments,
|
|
4216
|
+
onSegmentActivate: jumpToAnatomySegment
|
|
4247
4217
|
}
|
|
4248
|
-
),
|
|
4249
|
-
|
|
4250
|
-
|
|
4218
|
+
) }) }) }),
|
|
4219
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "headers", children: activeTab === "headers" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4220
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end gap-2 mb-2", children: shouldShowHeadersDiffButton(
|
|
4221
|
+
viewMode,
|
|
4222
|
+
displayLog.rawHeaders !== void 0 && Object.keys(displayLog.rawHeaders).length > 0
|
|
4223
|
+
) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4224
|
+
DiffToggleButton,
|
|
4225
|
+
{
|
|
4226
|
+
active: headersDiff,
|
|
4227
|
+
onClick: (e) => {
|
|
4228
|
+
e.stopPropagation();
|
|
4229
|
+
setHeadersDiff(!headersDiff);
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
) }),
|
|
4233
|
+
headersDiff ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4234
|
+
HeadersDiffContent,
|
|
4235
|
+
{
|
|
4236
|
+
rawHeaders: displayLog.rawHeaders,
|
|
4237
|
+
headers: displayLog.headers,
|
|
4238
|
+
emptyLabel: "No transformation applied; raw and processed headers are identical."
|
|
4239
|
+
}
|
|
4240
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(HeaderRows, { headers: displayLog.headers, emptyLabel: "No headers captured" })
|
|
4241
|
+
] }) }),
|
|
4242
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-headers", children: activeTab === "raw-headers" && /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandedPanel, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4243
|
+
HeaderRows,
|
|
4251
4244
|
{
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
streaming: displayLog.streaming,
|
|
4255
|
-
inputTokens: displayLog.inputTokens,
|
|
4256
|
-
outputTokens: displayLog.outputTokens,
|
|
4257
|
-
cacheCreationInputTokens: displayLog.cacheCreationInputTokens,
|
|
4258
|
-
cacheReadInputTokens: displayLog.cacheReadInputTokens,
|
|
4259
|
-
apiFormat: resolvedFormat,
|
|
4260
|
-
error: displayLog.error
|
|
4245
|
+
headers: displayLog.rawHeaders,
|
|
4246
|
+
emptyLabel: "No raw headers captured"
|
|
4261
4247
|
}
|
|
4262
|
-
) })
|
|
4263
|
-
|
|
4264
|
-
|
|
4248
|
+
) }) }),
|
|
4249
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw", children: activeTab === "raw" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { className: "space-y-3", children: [
|
|
4250
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4251
|
+
BodyPreviewNotice,
|
|
4252
|
+
{
|
|
4253
|
+
label: "Response",
|
|
4254
|
+
state: responsePreview,
|
|
4255
|
+
expectedBytes: log.responseTextBytes ?? null,
|
|
4256
|
+
onLoadMore: () => loadBodyChunk("response", responsePreview.offset)
|
|
4257
|
+
}
|
|
4258
|
+
),
|
|
4259
|
+
displayLog.error !== void 0 && displayLog.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "danger", title: "SSE Error", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: displayLog.error }) }),
|
|
4260
|
+
responseTextForView !== null && responsePreviewShouldParse ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4261
|
+
LazyJsonViewerFromString,
|
|
4262
|
+
{
|
|
4263
|
+
text: responseTextForView,
|
|
4264
|
+
defaultExpandDepth: 0,
|
|
4265
|
+
bulkDepth: responseExpansion.bulkDepth,
|
|
4266
|
+
bulkRevision: responseExpansion.bulkRevision
|
|
4267
|
+
}
|
|
4268
|
+
) }) : responseTextForView !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: responseTextForView }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: useChunkedBody ? "Response preview is loading" : "No response" }),
|
|
4269
|
+
displayLog.streaming === true && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4270
|
+
LazyStreamingChunkSequence,
|
|
4271
|
+
{
|
|
4272
|
+
logId: displayLog.id,
|
|
4273
|
+
truncated: displayLog.streamingChunksPath !== null
|
|
4274
|
+
}
|
|
4275
|
+
) })
|
|
4276
|
+
] }) }),
|
|
4277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "parsed", children: activeTab === "parsed" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4278
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4279
|
+
BodyPreviewNotice,
|
|
4280
|
+
{
|
|
4281
|
+
label: "Response",
|
|
4282
|
+
state: responsePreview,
|
|
4283
|
+
expectedBytes: log.responseTextBytes ?? null,
|
|
4284
|
+
onLoadMore: () => loadBodyChunk("response", responsePreview.offset)
|
|
4285
|
+
}
|
|
4286
|
+
),
|
|
4287
|
+
responsePreviewIsActive && !responsePreviewShouldParse ? /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: responseTextForView }) : /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4288
|
+
LazyResponseView,
|
|
4289
|
+
{
|
|
4290
|
+
responseText: responseTextForView,
|
|
4291
|
+
responseStatus: displayLog.responseStatus,
|
|
4292
|
+
streaming: displayLog.streaming,
|
|
4293
|
+
inputTokens: displayLog.inputTokens,
|
|
4294
|
+
outputTokens: displayLog.outputTokens,
|
|
4295
|
+
cacheCreationInputTokens: displayLog.cacheCreationInputTokens,
|
|
4296
|
+
cacheReadInputTokens: displayLog.cacheReadInputTokens,
|
|
4297
|
+
apiFormat: resolvedFormat,
|
|
4298
|
+
error: displayLog.error
|
|
4299
|
+
}
|
|
4300
|
+
) })
|
|
4301
|
+
] }) })
|
|
4302
|
+
] })
|
|
4303
|
+
]
|
|
4265
4304
|
}
|
|
4266
4305
|
)
|
|
4267
4306
|
]
|
|
4268
4307
|
}
|
|
4269
4308
|
),
|
|
4270
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4309
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4310
|
+
LazyReplayDialog,
|
|
4311
|
+
{
|
|
4312
|
+
log: displayLog,
|
|
4313
|
+
displayNumber,
|
|
4314
|
+
open: replayOpen,
|
|
4315
|
+
onOpenChange: setReplayOpen
|
|
4316
|
+
}
|
|
4317
|
+
) })
|
|
4271
4318
|
] });
|
|
4272
4319
|
});
|
|
4320
|
+
function boundaryTitle(stopReason) {
|
|
4321
|
+
switch (stopReason) {
|
|
4322
|
+
case "end_turn":
|
|
4323
|
+
return "End of Turn (Anthropic)";
|
|
4324
|
+
case "stop":
|
|
4325
|
+
return "End of Turn (OpenAI)";
|
|
4326
|
+
case "length":
|
|
4327
|
+
return "End of Turn (length limit)";
|
|
4328
|
+
case "tool_use":
|
|
4329
|
+
case null:
|
|
4330
|
+
return "End of Turn";
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4273
4333
|
function ThreadConnector({
|
|
4274
4334
|
stopReason,
|
|
4275
4335
|
isPending,
|
|
@@ -4280,7 +4340,7 @@ function ThreadConnector({
|
|
|
4280
4340
|
collapsible = false,
|
|
4281
4341
|
onToggle
|
|
4282
4342
|
}) {
|
|
4283
|
-
const isBoundary = stopReason
|
|
4343
|
+
const isBoundary = isTurnBoundary(stopReason);
|
|
4284
4344
|
const isFusedBoundary = isOnlyEntry && isTurnStart && isBoundary;
|
|
4285
4345
|
const isRunning = isPending && !isBoundary;
|
|
4286
4346
|
const Crab = reactExports.useMemo(() => getCrabVariant(crabIndex), [crabIndex]);
|
|
@@ -4311,23 +4371,16 @@ function ThreadConnector({
|
|
|
4311
4371
|
"drop-shadow-[0_0_4px_rgba(128,255,0,0.5)]"
|
|
4312
4372
|
)
|
|
4313
4373
|
}
|
|
4314
|
-
) }) : isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4315
|
-
|
|
4374
|
+
) }) : isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: boundaryTitle(stopReason), ...interactiveProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4375
|
+
Crab,
|
|
4316
4376
|
{
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
{
|
|
4322
|
-
className: cn(
|
|
4323
|
-
"size-3.5 text-amber-400",
|
|
4324
|
-
"animate-crab-settle",
|
|
4325
|
-
"drop-shadow-[0_0_4px_rgba(251,191,36,0.5)]"
|
|
4326
|
-
)
|
|
4327
|
-
}
|
|
4377
|
+
className: cn(
|
|
4378
|
+
"size-3.5 text-amber-400",
|
|
4379
|
+
"animate-crab-settle",
|
|
4380
|
+
"drop-shadow-[0_0_4px_rgba(251,191,36,0.5)]"
|
|
4328
4381
|
)
|
|
4329
4382
|
}
|
|
4330
|
-
) : isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Start of turn", ...interactiveProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4383
|
+
) }) : isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Start of turn", ...interactiveProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4331
4384
|
Crab,
|
|
4332
4385
|
{
|
|
4333
4386
|
className: cn(
|
|
@@ -4383,6 +4436,19 @@ function ToolTraceEvents({ events }) {
|
|
|
4383
4436
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-3 mb-2 grid gap-1.5", children: events.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(ToolTraceEventRow, { event }, event.id)) });
|
|
4384
4437
|
}
|
|
4385
4438
|
const PREVIEW_LIMIT = 180;
|
|
4439
|
+
const toolTraceCache = /* @__PURE__ */ new WeakMap();
|
|
4440
|
+
function responseMayContainToolTrace(log, format) {
|
|
4441
|
+
const responseText = log.responseText;
|
|
4442
|
+
if (responseText === null) return false;
|
|
4443
|
+
switch (format) {
|
|
4444
|
+
case "anthropic":
|
|
4445
|
+
return responseText.includes("tool_use");
|
|
4446
|
+
case "openai":
|
|
4447
|
+
return responseText.includes("tool_calls") || responseText.includes("function_call");
|
|
4448
|
+
case "unknown":
|
|
4449
|
+
return false;
|
|
4450
|
+
}
|
|
4451
|
+
}
|
|
4386
4452
|
function shouldRenderConversationContent(standalone, expanded) {
|
|
4387
4453
|
return standalone || expanded;
|
|
4388
4454
|
}
|
|
@@ -4393,8 +4459,10 @@ function buildTurnGroups(logs) {
|
|
|
4393
4459
|
const groups = [];
|
|
4394
4460
|
let entries = [];
|
|
4395
4461
|
let turnIndex = 0;
|
|
4396
|
-
for (
|
|
4397
|
-
|
|
4462
|
+
for (let index = 0; index < logs.length; index += 1) {
|
|
4463
|
+
const log = logs[index];
|
|
4464
|
+
if (log === void 0) continue;
|
|
4465
|
+
entries.push({ log, stopReason: extractStopReason(log), sessionLogNumber: index + 1 });
|
|
4398
4466
|
const current = entries[entries.length - 1];
|
|
4399
4467
|
if (current !== void 0 && isTurnBoundary(current.stopReason)) {
|
|
4400
4468
|
groups.push({ entries, turnIndex });
|
|
@@ -4494,18 +4562,59 @@ function extractOpenAIToolTraceEvents(log) {
|
|
|
4494
4562
|
});
|
|
4495
4563
|
}
|
|
4496
4564
|
}
|
|
4565
|
+
const output = safeGetOwnProperty(parsed, "output");
|
|
4566
|
+
if (Array.isArray(output)) {
|
|
4567
|
+
for (const item of output) {
|
|
4568
|
+
if (safeGetOwnProperty(item, "type") !== "function_call") continue;
|
|
4569
|
+
const name = safeGetOwnProperty(item, "name");
|
|
4570
|
+
if (typeof name !== "string" || name.length === 0) continue;
|
|
4571
|
+
const args = safeGetOwnProperty(item, "arguments");
|
|
4572
|
+
events.push({
|
|
4573
|
+
id: `${String(log.id)}-openai-tool-${String(events.length)}`,
|
|
4574
|
+
logId: log.id,
|
|
4575
|
+
index: events.length,
|
|
4576
|
+
provider: "openai",
|
|
4577
|
+
name,
|
|
4578
|
+
argumentsText: copyValue(args),
|
|
4579
|
+
argumentsPreview: previewValue(args)
|
|
4580
|
+
});
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4497
4583
|
return events;
|
|
4498
4584
|
}
|
|
4499
4585
|
function extractToolTraceEvents(log) {
|
|
4586
|
+
const cached = toolTraceCache.get(log);
|
|
4587
|
+
if (cached !== void 0 && cached.apiFormat === log.apiFormat && cached.responseText === log.responseText) {
|
|
4588
|
+
return cached.events;
|
|
4589
|
+
}
|
|
4500
4590
|
const format = resolveLogFormat(log);
|
|
4591
|
+
if (!responseMayContainToolTrace(log, format)) {
|
|
4592
|
+
const events2 = [];
|
|
4593
|
+
toolTraceCache.set(log, {
|
|
4594
|
+
apiFormat: log.apiFormat,
|
|
4595
|
+
responseText: log.responseText,
|
|
4596
|
+
events: events2
|
|
4597
|
+
});
|
|
4598
|
+
return events2;
|
|
4599
|
+
}
|
|
4600
|
+
let events;
|
|
4501
4601
|
switch (format) {
|
|
4502
4602
|
case "anthropic":
|
|
4503
|
-
|
|
4603
|
+
events = extractAnthropicToolTraceEvents(log);
|
|
4604
|
+
break;
|
|
4504
4605
|
case "openai":
|
|
4505
|
-
|
|
4606
|
+
events = extractOpenAIToolTraceEvents(log);
|
|
4607
|
+
break;
|
|
4506
4608
|
case "unknown":
|
|
4507
|
-
|
|
4609
|
+
events = [];
|
|
4610
|
+
break;
|
|
4508
4611
|
}
|
|
4612
|
+
toolTraceCache.set(log, {
|
|
4613
|
+
apiFormat: log.apiFormat,
|
|
4614
|
+
responseText: log.responseText,
|
|
4615
|
+
events
|
|
4616
|
+
});
|
|
4617
|
+
return events;
|
|
4509
4618
|
}
|
|
4510
4619
|
function buildTraceSummary(logs, slowResponseThresholdSeconds, knowledgeCandidateCount = 0) {
|
|
4511
4620
|
let failedCallCount = 0;
|
|
@@ -4571,7 +4680,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4571
4680
|
onCompareWithPrevious,
|
|
4572
4681
|
comparisonPredecessors,
|
|
4573
4682
|
turnIndex = 0,
|
|
4574
|
-
timeDisplayFormat
|
|
4683
|
+
timeDisplayFormat,
|
|
4684
|
+
pendingFocusRequest
|
|
4575
4685
|
}) {
|
|
4576
4686
|
const lastIdx = entries.length - 1;
|
|
4577
4687
|
const lastStop = entries[lastIdx]?.stopReason ?? null;
|
|
@@ -4601,6 +4711,19 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4601
4711
|
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4602
4712
|
};
|
|
4603
4713
|
}, [collapsible, entries]);
|
|
4714
|
+
reactExports.useEffect(() => {
|
|
4715
|
+
if (pendingFocusRequest === void 0) return void 0;
|
|
4716
|
+
if (!entries.some((entry) => entry.log.id === pendingFocusRequest.logId)) return void 0;
|
|
4717
|
+
if (collapsible) setCollapsed(false);
|
|
4718
|
+
const timer = window.setTimeout(() => {
|
|
4719
|
+
dispatchLogFocusRequest({
|
|
4720
|
+
logId: pendingFocusRequest.logId,
|
|
4721
|
+
tab: pendingFocusRequest.tab,
|
|
4722
|
+
source: "virtualizer"
|
|
4723
|
+
});
|
|
4724
|
+
}, 0);
|
|
4725
|
+
return () => window.clearTimeout(timer);
|
|
4726
|
+
}, [collapsible, entries, pendingFocusRequest]);
|
|
4604
4727
|
const toggleCollapse = reactExports.useCallback(() => {
|
|
4605
4728
|
if (collapsible) setCollapsed((prev) => !prev);
|
|
4606
4729
|
}, [collapsible]);
|
|
@@ -4629,17 +4752,9 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4629
4752
|
maxElapsed
|
|
4630
4753
|
};
|
|
4631
4754
|
}, [entries, lastIdx]);
|
|
4632
|
-
const uniqueProviders = reactExports.useMemo(() => {
|
|
4633
|
-
const seen = /* @__PURE__ */ new Set();
|
|
4634
|
-
for (const e of entries) {
|
|
4635
|
-
const p = detectProvider(e.log.model);
|
|
4636
|
-
if (p !== "unknown") seen.add(p);
|
|
4637
|
-
}
|
|
4638
|
-
return [...seen];
|
|
4639
|
-
}, [entries]);
|
|
4640
4755
|
const StartCrab = reactExports.useMemo(() => getCrabVariant(entries[0]?.log.id ?? 0), [entries]);
|
|
4641
4756
|
const EndCrab = reactExports.useMemo(() => getCrabVariant(entries[lastIdx]?.log.id ?? 0), [entries, lastIdx]);
|
|
4642
|
-
const bgClass = turnIndex % 2 === 0 ? "bg-
|
|
4757
|
+
const bgClass = turnIndex % 2 === 0 ? "bg-[#070a0f]" : "bg-[#090d12]";
|
|
4643
4758
|
const aggregateIsSlow = aggregate.maxElapsed !== null && slowResponseThresholdSeconds > 0 && aggregate.maxElapsed > slowResponseThresholdSeconds * 1e3;
|
|
4644
4759
|
const toolEventsByLogId = reactExports.useMemo(() => {
|
|
4645
4760
|
const events = /* @__PURE__ */ new Map();
|
|
@@ -4667,17 +4782,25 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4667
4782
|
}, []);
|
|
4668
4783
|
const firstLogId = entries[0]?.log.id ?? turnIndex;
|
|
4669
4784
|
const turnLabel = `Turn ${String(turnIndex + 1)}`;
|
|
4785
|
+
const containmentStyle = reactExports.useMemo(
|
|
4786
|
+
() => ({
|
|
4787
|
+
contentVisibility: "auto",
|
|
4788
|
+
containIntrinsicSize: collapsed ? "48px" : "160px"
|
|
4789
|
+
}),
|
|
4790
|
+
[collapsed]
|
|
4791
|
+
);
|
|
4670
4792
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4671
4793
|
"div",
|
|
4672
4794
|
{
|
|
4673
4795
|
ref: containerRef,
|
|
4796
|
+
style: containmentStyle,
|
|
4674
4797
|
tabIndex: collapsed ? void 0 : 0,
|
|
4675
4798
|
role: collapsed ? void 0 : "group",
|
|
4676
4799
|
"aria-label": collapsed ? void 0 : turnLabel,
|
|
4677
4800
|
"data-nav-id": collapsed ? void 0 : `turn-${String(firstLogId)}`,
|
|
4678
4801
|
className: cn(
|
|
4679
|
-
"border rounded-lg",
|
|
4680
|
-
isPending ? "border-amber-
|
|
4802
|
+
"border rounded-lg transition-[border-color,box-shadow]",
|
|
4803
|
+
isPending ? "border-amber-300/15 shadow-[0_0_0_1px_rgba(252,211,77,0.04)]" : "border-transparent",
|
|
4681
4804
|
!collapsed && "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
4682
4805
|
),
|
|
4683
4806
|
children: collapsed ? (
|
|
@@ -4763,22 +4886,31 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4763
4886
|
"div",
|
|
4764
4887
|
{
|
|
4765
4888
|
className: cn(
|
|
4766
|
-
"flex-1 min-w-0 mb-0.5 rounded-lg border border-
|
|
4889
|
+
"flex-1 min-w-0 mb-0.5 rounded-lg border border-cyan-300/10 py-1.5 px-3 flex items-center gap-3 text-xs shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]",
|
|
4767
4890
|
bgClass
|
|
4768
4891
|
),
|
|
4769
4892
|
children: [
|
|
4770
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4893
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: ROW_CHEVRON_SLOT_CLASS, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" }) }),
|
|
4894
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4895
|
+
"span",
|
|
4896
|
+
{
|
|
4897
|
+
className: "text-blue-400/80 font-mono font-semibold tabular-nums shrink-0",
|
|
4898
|
+
title: `Log IDs ${String(entries[0]?.log.id ?? "?")} ~ ${String(
|
|
4899
|
+
entries[lastIdx]?.log.id ?? "?"
|
|
4900
|
+
)}`,
|
|
4901
|
+
children: [
|
|
4902
|
+
"#",
|
|
4903
|
+
entries[0]?.sessionLogNumber ?? "?",
|
|
4904
|
+
" ~ #",
|
|
4905
|
+
entries[lastIdx]?.sessionLogNumber ?? "?"
|
|
4906
|
+
]
|
|
4907
|
+
}
|
|
4908
|
+
),
|
|
4776
4909
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground shrink-0", children: [
|
|
4777
4910
|
entries.length,
|
|
4778
4911
|
" request",
|
|
4779
4912
|
entries.length > 1 ? "s" : ""
|
|
4780
4913
|
] }),
|
|
4781
|
-
uniqueProviders.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex items-center gap-0.5 shrink-0", children: uniqueProviders.map((p) => /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: p, className: "size-4" }, p)) }),
|
|
4782
4914
|
aggregate.maxElapsed !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
4783
4915
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4784
4916
|
"span",
|
|
@@ -4812,8 +4944,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4812
4944
|
] })
|
|
4813
4945
|
] })
|
|
4814
4946
|
] }),
|
|
4815
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0" })
|
|
4816
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" })
|
|
4947
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0" })
|
|
4817
4948
|
]
|
|
4818
4949
|
}
|
|
4819
4950
|
)
|
|
@@ -4845,6 +4976,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4845
4976
|
LogEntry,
|
|
4846
4977
|
{
|
|
4847
4978
|
log,
|
|
4979
|
+
displayNumber: entry.sessionLogNumber,
|
|
4848
4980
|
viewMode,
|
|
4849
4981
|
strip,
|
|
4850
4982
|
slowResponseThresholdSeconds,
|
|
@@ -4861,6 +4993,103 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4861
4993
|
}
|
|
4862
4994
|
);
|
|
4863
4995
|
});
|
|
4996
|
+
const VIRTUALIZE_TURN_THRESHOLD = 24;
|
|
4997
|
+
const ESTIMATED_TURN_HEIGHT = 132;
|
|
4998
|
+
const VIRTUAL_OVERSCAN$1 = 8;
|
|
4999
|
+
function shouldVirtualizeTurnGroups(turnCount) {
|
|
5000
|
+
return turnCount > VIRTUALIZE_TURN_THRESHOLD;
|
|
5001
|
+
}
|
|
5002
|
+
function buildLogTurnIndex(turnGroups) {
|
|
5003
|
+
const result = /* @__PURE__ */ new Map();
|
|
5004
|
+
for (let index = 0; index < turnGroups.length; index++) {
|
|
5005
|
+
const group = turnGroups[index];
|
|
5006
|
+
if (group === void 0) continue;
|
|
5007
|
+
for (const entry of group.entries) {
|
|
5008
|
+
result.set(entry.log.id, index);
|
|
5009
|
+
}
|
|
5010
|
+
}
|
|
5011
|
+
return result;
|
|
5012
|
+
}
|
|
5013
|
+
function renderTurnGroup(turnGroup, props, pendingFocusRequest) {
|
|
5014
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5015
|
+
TurnGroup,
|
|
5016
|
+
{
|
|
5017
|
+
entries: turnGroup.entries,
|
|
5018
|
+
viewMode: props.viewMode,
|
|
5019
|
+
strip: props.strip,
|
|
5020
|
+
slowResponseThresholdSeconds: props.slowResponseThresholdSeconds,
|
|
5021
|
+
timeDisplayFormat: props.timeDisplayFormat,
|
|
5022
|
+
cacheTrends: props.cacheTrends,
|
|
5023
|
+
onCompareWithPrevious: props.onCompareWithPrevious,
|
|
5024
|
+
comparisonPredecessors: props.comparisonPredecessors,
|
|
5025
|
+
turnIndex: turnGroup.turnIndex,
|
|
5026
|
+
pendingFocusRequest
|
|
5027
|
+
},
|
|
5028
|
+
turnGroup.turnIndex
|
|
5029
|
+
);
|
|
5030
|
+
}
|
|
5031
|
+
function TurnGroupList(props) {
|
|
5032
|
+
if (!shouldVirtualizeTurnGroups(props.turnGroups.length)) {
|
|
5033
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: props.turnGroups.map((turnGroup) => renderTurnGroup(turnGroup, props)) });
|
|
5034
|
+
}
|
|
5035
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(VirtualizedTurnGroupList, { ...props });
|
|
5036
|
+
}
|
|
5037
|
+
function VirtualizedTurnGroupList(props) {
|
|
5038
|
+
const { turnGroups } = props;
|
|
5039
|
+
const [pendingFocusRequest, setPendingFocusRequest] = reactExports.useState(
|
|
5040
|
+
null
|
|
5041
|
+
);
|
|
5042
|
+
const virtualizer = useWindowVirtualizer({
|
|
5043
|
+
count: turnGroups.length,
|
|
5044
|
+
estimateSize: () => ESTIMATED_TURN_HEIGHT,
|
|
5045
|
+
overscan: VIRTUAL_OVERSCAN$1,
|
|
5046
|
+
getItemKey: (index) => turnGroups[index]?.turnIndex ?? index
|
|
5047
|
+
});
|
|
5048
|
+
const turnIndexByLogId = reactExports.useMemo(() => buildLogTurnIndex(turnGroups), [turnGroups]);
|
|
5049
|
+
reactExports.useEffect(() => {
|
|
5050
|
+
const handleLogFocusRequest = (event) => {
|
|
5051
|
+
const request = readLogFocusRequest(event);
|
|
5052
|
+
if (request === null) return;
|
|
5053
|
+
if (request.source === "virtualizer") return;
|
|
5054
|
+
const turnIndex = turnIndexByLogId.get(request.logId);
|
|
5055
|
+
if (turnIndex === void 0) return;
|
|
5056
|
+
virtualizer.scrollToIndex(turnIndex, { align: "center" });
|
|
5057
|
+
setPendingFocusRequest((previous) => ({
|
|
5058
|
+
...request,
|
|
5059
|
+
turnIndex,
|
|
5060
|
+
nonce: previous === null ? 1 : previous.nonce + 1
|
|
5061
|
+
}));
|
|
5062
|
+
};
|
|
5063
|
+
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
5064
|
+
return () => {
|
|
5065
|
+
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
5066
|
+
};
|
|
5067
|
+
}, [turnIndexByLogId, virtualizer]);
|
|
5068
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5069
|
+
"div",
|
|
5070
|
+
{
|
|
5071
|
+
className: "relative w-full",
|
|
5072
|
+
style: { height: `${virtualizer.getTotalSize()}px` },
|
|
5073
|
+
"data-virtualized-turn-list": "true",
|
|
5074
|
+
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
5075
|
+
const turnGroup = turnGroups[virtualItem.index];
|
|
5076
|
+
if (turnGroup === void 0) return null;
|
|
5077
|
+
const itemFocusRequest = pendingFocusRequest !== null && pendingFocusRequest.turnIndex === virtualItem.index ? pendingFocusRequest : void 0;
|
|
5078
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5079
|
+
"div",
|
|
5080
|
+
{
|
|
5081
|
+
"data-index": virtualItem.index,
|
|
5082
|
+
ref: virtualizer.measureElement,
|
|
5083
|
+
className: "absolute left-0 top-0 w-full",
|
|
5084
|
+
style: { transform: `translateY(${virtualItem.start}px)` },
|
|
5085
|
+
children: renderTurnGroup(turnGroup, props, itemFocusRequest)
|
|
5086
|
+
},
|
|
5087
|
+
virtualItem.key
|
|
5088
|
+
);
|
|
5089
|
+
})
|
|
5090
|
+
}
|
|
5091
|
+
);
|
|
5092
|
+
}
|
|
4864
5093
|
const CandidateResponseSchema = object({
|
|
4865
5094
|
candidates: array(KnowledgeCandidateSchema)
|
|
4866
5095
|
});
|
|
@@ -4926,6 +5155,18 @@ function firstToolLog(logs) {
|
|
|
4926
5155
|
}
|
|
4927
5156
|
return null;
|
|
4928
5157
|
}
|
|
5158
|
+
function buildDisplayNumberByLogId$1(logs) {
|
|
5159
|
+
const result = /* @__PURE__ */ new Map();
|
|
5160
|
+
for (let index = 0; index < logs.length; index += 1) {
|
|
5161
|
+
const log = logs[index];
|
|
5162
|
+
if (log === void 0) continue;
|
|
5163
|
+
result.set(log.id, index + 1);
|
|
5164
|
+
}
|
|
5165
|
+
return result;
|
|
5166
|
+
}
|
|
5167
|
+
function displayLogNumber(logId, displayNumberByLogId) {
|
|
5168
|
+
return String(displayNumberByLogId.get(logId) ?? logId);
|
|
5169
|
+
}
|
|
4929
5170
|
function buildTraceInsights(input) {
|
|
4930
5171
|
const insights = [
|
|
4931
5172
|
{
|
|
@@ -4940,7 +5181,7 @@ function buildTraceInsights(input) {
|
|
|
4940
5181
|
insights.push({
|
|
4941
5182
|
kind: "tool",
|
|
4942
5183
|
title: `${String(input.summary.toolCallCount)} tool call${input.summary.toolCallCount === 1 ? "" : "s"}`,
|
|
4943
|
-
detail: `First tool evidence at #${
|
|
5184
|
+
detail: `First tool evidence at #${displayLogNumber(toolLog.id, input.displayNumberByLogId)}`,
|
|
4944
5185
|
logId: toolLog.id
|
|
4945
5186
|
});
|
|
4946
5187
|
}
|
|
@@ -4949,7 +5190,7 @@ function buildTraceInsights(input) {
|
|
|
4949
5190
|
insights.push({
|
|
4950
5191
|
kind: "failure",
|
|
4951
5192
|
title: `Failure #${String(failure.responseStatus)}`,
|
|
4952
|
-
detail: `First failed request is #${
|
|
5193
|
+
detail: `First failed request is #${displayLogNumber(failure.id, input.displayNumberByLogId)}`,
|
|
4953
5194
|
logId: failure.id
|
|
4954
5195
|
});
|
|
4955
5196
|
}
|
|
@@ -4958,7 +5199,7 @@ function buildTraceInsights(input) {
|
|
|
4958
5199
|
insights.push({
|
|
4959
5200
|
kind: "slow",
|
|
4960
5201
|
title: `Slowest ${formatElapsed$1(input.summary.maxElapsedMs)}`,
|
|
4961
|
-
detail: `Max latency observed at #${
|
|
5202
|
+
detail: `Max latency observed at #${displayLogNumber(slowest.id, input.displayNumberByLogId)}`,
|
|
4962
5203
|
logId: slowest.id
|
|
4963
5204
|
});
|
|
4964
5205
|
}
|
|
@@ -5046,12 +5287,13 @@ function previewText(value, maxLength) {
|
|
|
5046
5287
|
if (normalized.length <= maxLength) return normalized;
|
|
5047
5288
|
return `${normalized.slice(0, maxLength - 3)}...`;
|
|
5048
5289
|
}
|
|
5049
|
-
function logRangeLabel(logIds) {
|
|
5290
|
+
function logRangeLabel(logIds, displayNumberByLogId) {
|
|
5050
5291
|
const first = logIds[0];
|
|
5051
5292
|
const last = logIds[logIds.length - 1];
|
|
5052
5293
|
if (first === void 0) return "No evidence logs";
|
|
5053
|
-
|
|
5054
|
-
|
|
5294
|
+
const firstLabel = displayLogNumber(first, displayNumberByLogId);
|
|
5295
|
+
if (last === void 0 || first === last) return `#${firstLabel}`;
|
|
5296
|
+
return `#${firstLabel}-#${displayLogNumber(last, displayNumberByLogId)}`;
|
|
5055
5297
|
}
|
|
5056
5298
|
function tagsToText(tags) {
|
|
5057
5299
|
return tags.join(", ");
|
|
@@ -5064,7 +5306,8 @@ function CandidateItem({
|
|
|
5064
5306
|
isPromoting,
|
|
5065
5307
|
isUpdating,
|
|
5066
5308
|
onPromoteCandidate,
|
|
5067
|
-
onUpdateCandidate
|
|
5309
|
+
onUpdateCandidate,
|
|
5310
|
+
displayNumberByLogId
|
|
5068
5311
|
}) {
|
|
5069
5312
|
const [editing, setEditing] = reactExports.useState(false);
|
|
5070
5313
|
const [draftType, setDraftType] = reactExports.useState(candidate.type);
|
|
@@ -5233,7 +5476,7 @@ function CandidateItem({
|
|
|
5233
5476
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-[10px] text-muted-foreground", children: [
|
|
5234
5477
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
5235
5478
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FileSearch, { className: "size-3" }),
|
|
5236
|
-
logRangeLabel(candidate.logIds)
|
|
5479
|
+
logRangeLabel(candidate.logIds, displayNumberByLogId)
|
|
5237
5480
|
] }),
|
|
5238
5481
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
5239
5482
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ShieldCheck, { className: "size-3" }),
|
|
@@ -5249,23 +5492,27 @@ function CandidateItem({
|
|
|
5249
5492
|
] })
|
|
5250
5493
|
] }),
|
|
5251
5494
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1.5", children: [
|
|
5252
|
-
candidate.logIds.map((logId) =>
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5495
|
+
candidate.logIds.map((logId) => {
|
|
5496
|
+
const displayNumber = displayLogNumber(logId, displayNumberByLogId);
|
|
5497
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5498
|
+
"a",
|
|
5499
|
+
{
|
|
5500
|
+
href: `#${getLogAnchor(logId)}`,
|
|
5501
|
+
onClick: (event) => {
|
|
5502
|
+
event.preventDefault();
|
|
5503
|
+
jumpToLog(logId);
|
|
5504
|
+
},
|
|
5505
|
+
className: "rounded border border-blue-400/25 px-1.5 py-0.5 font-mono text-[10px] text-blue-400 underline-offset-2 transition-colors hover:bg-blue-400/10 hover:text-blue-300 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5506
|
+
"aria-label": `Jump to evidence log ${displayNumber}`,
|
|
5507
|
+
title: `Log ID ${String(logId)}`,
|
|
5508
|
+
children: [
|
|
5509
|
+
"#",
|
|
5510
|
+
displayNumber
|
|
5511
|
+
]
|
|
5259
5512
|
},
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
"#",
|
|
5264
|
-
logId
|
|
5265
|
-
]
|
|
5266
|
-
},
|
|
5267
|
-
logId
|
|
5268
|
-
)),
|
|
5513
|
+
logId
|
|
5514
|
+
);
|
|
5515
|
+
}),
|
|
5269
5516
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
|
|
5270
5517
|
canEdit && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5271
5518
|
Button,
|
|
@@ -5305,7 +5552,8 @@ function CandidateList({
|
|
|
5305
5552
|
promotingCandidateIds,
|
|
5306
5553
|
updatingCandidateIds,
|
|
5307
5554
|
onPromoteCandidate,
|
|
5308
|
-
onUpdateCandidate
|
|
5555
|
+
onUpdateCandidate,
|
|
5556
|
+
displayNumberByLogId
|
|
5309
5557
|
}) {
|
|
5310
5558
|
if (candidates.length === 0) return null;
|
|
5311
5559
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1.5", children: candidates.map((candidate) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -5315,7 +5563,8 @@ function CandidateList({
|
|
|
5315
5563
|
isPromoting: promotingCandidateIds.has(candidate.id),
|
|
5316
5564
|
isUpdating: updatingCandidateIds.has(candidate.id),
|
|
5317
5565
|
onPromoteCandidate,
|
|
5318
|
-
onUpdateCandidate
|
|
5566
|
+
onUpdateCandidate,
|
|
5567
|
+
displayNumberByLogId
|
|
5319
5568
|
},
|
|
5320
5569
|
candidate.id
|
|
5321
5570
|
)) });
|
|
@@ -5344,9 +5593,10 @@ function AgentTraceSummary({
|
|
|
5344
5593
|
() => buildTraceSummary(logs, slowResponseThresholdSeconds, candidates.length),
|
|
5345
5594
|
[candidates.length, logs, slowResponseThresholdSeconds]
|
|
5346
5595
|
);
|
|
5596
|
+
const displayNumberByLogId = reactExports.useMemo(() => buildDisplayNumberByLogId$1(logs), [logs]);
|
|
5347
5597
|
const traceInsights = reactExports.useMemo(
|
|
5348
|
-
() => buildTraceInsights({ logs, scopeId, summary, candidates }),
|
|
5349
|
-
[candidates, logs, scopeId, summary]
|
|
5598
|
+
() => buildTraceInsights({ logs, scopeId, summary, candidates, displayNumberByLogId }),
|
|
5599
|
+
[candidates, displayNumberByLogId, logs, scopeId, summary]
|
|
5350
5600
|
);
|
|
5351
5601
|
const showElapsedSummary = showRollupMetrics || summary.maxElapsedMs !== null;
|
|
5352
5602
|
const timeRange = reactExports.useMemo(
|
|
@@ -5574,7 +5824,8 @@ function AgentTraceSummary({
|
|
|
5574
5824
|
promotingCandidateIds,
|
|
5575
5825
|
updatingCandidateIds,
|
|
5576
5826
|
onPromoteCandidate: promoteCandidate,
|
|
5577
|
-
onUpdateCandidate: updateCandidate
|
|
5827
|
+
onUpdateCandidate: updateCandidate,
|
|
5828
|
+
displayNumberByLogId
|
|
5578
5829
|
}
|
|
5579
5830
|
)
|
|
5580
5831
|
] });
|
|
@@ -5703,21 +5954,19 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
5703
5954
|
timeDisplayFormat
|
|
5704
5955
|
}
|
|
5705
5956
|
),
|
|
5706
|
-
|
|
5707
|
-
|
|
5957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5958
|
+
TurnGroupList,
|
|
5708
5959
|
{
|
|
5709
|
-
|
|
5960
|
+
turnGroups,
|
|
5710
5961
|
viewMode,
|
|
5711
5962
|
strip,
|
|
5712
5963
|
slowResponseThresholdSeconds,
|
|
5713
5964
|
timeDisplayFormat,
|
|
5714
5965
|
cacheTrends,
|
|
5715
5966
|
onCompareWithPrevious,
|
|
5716
|
-
comparisonPredecessors
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
tg.turnIndex
|
|
5720
|
-
))
|
|
5967
|
+
comparisonPredecessors
|
|
5968
|
+
}
|
|
5969
|
+
)
|
|
5721
5970
|
] })
|
|
5722
5971
|
] });
|
|
5723
5972
|
});
|
|
@@ -7342,28 +7591,31 @@ function LatestLogsPreview({ logs }) {
|
|
|
7342
7591
|
}
|
|
7343
7592
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden rounded-md border border-border", children: [
|
|
7344
7593
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-b border-border bg-muted/30 px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Latest logs" }),
|
|
7345
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "divide-y divide-border", children: visibleLogs.map((log) =>
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
log.id
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
"
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7594
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "divide-y divide-border", children: visibleLogs.map((log) => {
|
|
7595
|
+
const displayNumber = log.sessionLogNumber ?? log.id;
|
|
7596
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
7597
|
+
"div",
|
|
7598
|
+
{
|
|
7599
|
+
className: "grid gap-2 px-3 py-2 text-xs sm:grid-cols-[72px_1fr_88px_88px]",
|
|
7600
|
+
children: [
|
|
7601
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-muted-foreground", title: `Log ID ${String(log.id)}`, children: [
|
|
7602
|
+
"#",
|
|
7603
|
+
displayNumber
|
|
7604
|
+
] }),
|
|
7605
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 truncate", children: [
|
|
7606
|
+
displayText(log.model),
|
|
7607
|
+
" · ",
|
|
7608
|
+
log.apiFormat,
|
|
7609
|
+
" · ",
|
|
7610
|
+
log.path
|
|
7611
|
+
] }),
|
|
7612
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground", children: formatMs(log.firstChunkMs) }),
|
|
7613
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground", children: formatMs(log.latencyMs) })
|
|
7614
|
+
]
|
|
7615
|
+
},
|
|
7616
|
+
log.id
|
|
7617
|
+
);
|
|
7618
|
+
}) })
|
|
7367
7619
|
] });
|
|
7368
7620
|
}
|
|
7369
7621
|
function MemberMetadata({ entries }) {
|
|
@@ -7449,6 +7701,7 @@ const ExternalProviderSchema = object({
|
|
|
7449
7701
|
format: _enum(["anthropic", "openai"]),
|
|
7450
7702
|
anthropicBaseUrl: string(),
|
|
7451
7703
|
openaiBaseUrl: string(),
|
|
7704
|
+
openaiResponsesBaseUrl: string().optional().default(""),
|
|
7452
7705
|
models: array(string()),
|
|
7453
7706
|
sourceTool: _enum(["claude-code", "opencode", "mimo-code"]),
|
|
7454
7707
|
alreadyExists: boolean()
|
|
@@ -7545,6 +7798,7 @@ function ImportWizardDialog({
|
|
|
7545
7798
|
format: p.format,
|
|
7546
7799
|
anthropicBaseUrl: p.anthropicBaseUrl,
|
|
7547
7800
|
openaiBaseUrl: p.openaiBaseUrl,
|
|
7801
|
+
openaiResponsesBaseUrl: p.openaiResponsesBaseUrl,
|
|
7548
7802
|
models: p.models,
|
|
7549
7803
|
createdAt: now,
|
|
7550
7804
|
updatedAt: now
|
|
@@ -7624,7 +7878,7 @@ function ImportWizardDialog({
|
|
|
7624
7878
|
p.models.slice(0, 4).join(", "),
|
|
7625
7879
|
p.models.length > 4 ? ` +${p.models.length - 4} more` : ""
|
|
7626
7880
|
] }),
|
|
7627
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: p.format === "anthropic" ? p.anthropicBaseUrl : p.openaiBaseUrl }),
|
|
7881
|
+
/* @__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 }),
|
|
7628
7882
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: p.apiKey.length > 8 ? `${p.apiKey.slice(0, 4)}••••${p.apiKey.slice(-4)}` : "••••" })
|
|
7629
7883
|
] })
|
|
7630
7884
|
]
|
|
@@ -8069,12 +8323,17 @@ function ProviderCard({
|
|
|
8069
8323
|
] }),
|
|
8070
8324
|
provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-col gap-2", children: [
|
|
8071
8325
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 text-xs text-muted-foreground", children: [
|
|
8072
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "OpenAI:" }),
|
|
8326
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "OpenAI Chat:" }),
|
|
8073
8327
|
" ",
|
|
8074
8328
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: provider.openaiBaseUrl })
|
|
8075
8329
|
] }),
|
|
8076
8330
|
testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.openai })
|
|
8077
8331
|
] }),
|
|
8332
|
+
provider.openaiResponsesBaseUrl !== void 0 && provider.openaiResponsesBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-w-0 flex-col gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 text-xs text-muted-foreground", children: [
|
|
8333
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "OpenAI Responses:" }),
|
|
8334
|
+
" ",
|
|
8335
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: provider.openaiResponsesBaseUrl })
|
|
8336
|
+
] }) }),
|
|
8078
8337
|
testResults?.testedAt !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-1", children: [
|
|
8079
8338
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
8080
8339
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
@@ -8166,12 +8425,17 @@ const ZHIPU_CODING_PROVIDER_KEYWORDS = [
|
|
|
8166
8425
|
"z.ai coding",
|
|
8167
8426
|
"zai coding"
|
|
8168
8427
|
];
|
|
8428
|
+
const ANTHROPIC_MESSAGES_ENDPOINT = "/v1/messages";
|
|
8429
|
+
const OPENAI_CHAT_COMPLETIONS_ENDPOINT = "/v1/chat/completions";
|
|
8430
|
+
const OPENAI_RESPONSES_ENDPOINT = "/v1/responses";
|
|
8169
8431
|
const KNOWN_PROVIDER_PRESETS = {
|
|
8170
8432
|
deepseek: {
|
|
8171
8433
|
openaiBaseUrl: "https://api.deepseek.com"
|
|
8172
8434
|
},
|
|
8173
8435
|
minimax: {
|
|
8174
8436
|
anthropicBaseUrl: "https://api.minimaxi.com/anthropic",
|
|
8437
|
+
openaiBaseUrl: "https://api.minimaxi.com",
|
|
8438
|
+
openaiResponsesBaseUrl: "https://api.minimaxi.com",
|
|
8175
8439
|
apiDocsUrl: "https://platform.minimaxi.com/docs/api-reference/api-overview"
|
|
8176
8440
|
},
|
|
8177
8441
|
"zhipu coding": {
|
|
@@ -8345,6 +8609,27 @@ function readPositiveIntegerInput(value) {
|
|
|
8345
8609
|
if (!Number.isInteger(parsed) || parsed <= 0) return null;
|
|
8346
8610
|
return parsed;
|
|
8347
8611
|
}
|
|
8612
|
+
function stripEndpointSuffix(value, endpoint) {
|
|
8613
|
+
if (value === void 0) return "";
|
|
8614
|
+
const trimmed = value.trim();
|
|
8615
|
+
const normalized = trimmed.replace(/\/+$/, "");
|
|
8616
|
+
return normalized.endsWith(endpoint) ? normalized.slice(0, -endpoint.length).replace(/\/+$/, "") : trimmed;
|
|
8617
|
+
}
|
|
8618
|
+
function previewEndpointUrl(baseUrl, endpoint) {
|
|
8619
|
+
const trimmed = baseUrl.trim();
|
|
8620
|
+
return trimmed === "" ? null : buildUpstreamUrl(trimmed, endpoint);
|
|
8621
|
+
}
|
|
8622
|
+
function EndpointUrlPreview({
|
|
8623
|
+
baseUrl,
|
|
8624
|
+
endpoint
|
|
8625
|
+
}) {
|
|
8626
|
+
const finalUrl = previewEndpointUrl(baseUrl, endpoint);
|
|
8627
|
+
if (finalUrl === null) return null;
|
|
8628
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border/70 bg-muted/35 px-3 py-2 text-xs", children: [
|
|
8629
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground", children: "Final URL" }),
|
|
8630
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "break-all font-mono text-foreground", children: finalUrl })
|
|
8631
|
+
] });
|
|
8632
|
+
}
|
|
8348
8633
|
function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
8349
8634
|
const [name, setName] = reactExports.useState(provider?.name ?? "");
|
|
8350
8635
|
const [apiKey, setApiKey] = reactExports.useState(provider?.apiKey ?? "");
|
|
@@ -8361,8 +8646,15 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8361
8646
|
)
|
|
8362
8647
|
);
|
|
8363
8648
|
const [activeTab, setActiveTab] = reactExports.useState("anthropic");
|
|
8364
|
-
const [anthropicBaseUrl, setAnthropicBaseUrl] = reactExports.useState(
|
|
8365
|
-
|
|
8649
|
+
const [anthropicBaseUrl, setAnthropicBaseUrl] = reactExports.useState(
|
|
8650
|
+
stripEndpointSuffix(provider?.anthropicBaseUrl, ANTHROPIC_MESSAGES_ENDPOINT)
|
|
8651
|
+
);
|
|
8652
|
+
const [openaiBaseUrl, setOpenaiBaseUrl] = reactExports.useState(
|
|
8653
|
+
stripEndpointSuffix(provider?.openaiBaseUrl, OPENAI_CHAT_COMPLETIONS_ENDPOINT)
|
|
8654
|
+
);
|
|
8655
|
+
const [openaiResponsesBaseUrl, setOpenaiResponsesBaseUrl] = reactExports.useState(
|
|
8656
|
+
stripEndpointSuffix(provider?.openaiResponsesBaseUrl, OPENAI_RESPONSES_ENDPOINT)
|
|
8657
|
+
);
|
|
8366
8658
|
const [apiDocsUrl, setApiDocsUrl] = reactExports.useState(provider?.apiDocsUrl ?? "");
|
|
8367
8659
|
const [modelMetadataUrl, setModelMetadataUrl] = reactExports.useState(provider?.modelMetadataUrl ?? "");
|
|
8368
8660
|
const [source, setSource] = reactExports.useState(provider?.source);
|
|
@@ -8385,6 +8677,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8385
8677
|
}, [openModelDropdown]);
|
|
8386
8678
|
const [manualAnthropicUrlOverride, setManualAnthropicUrlOverride] = reactExports.useState(false);
|
|
8387
8679
|
const [manualOpenaiUrlOverride, setManualOpenaiUrlOverride] = reactExports.useState(false);
|
|
8680
|
+
const [manualOpenaiResponsesUrlOverride, setManualOpenaiResponsesUrlOverride] = reactExports.useState(false);
|
|
8388
8681
|
const isMiniMax = name.toLowerCase().includes("minimax");
|
|
8389
8682
|
const isAlibaba = name.toLowerCase().includes("alibaba");
|
|
8390
8683
|
const isZhipu = [...ZHIPU_PROVIDER_KEYWORDS, ...ZHIPU_CODING_PROVIDER_KEYWORDS].some(
|
|
@@ -8406,13 +8699,21 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8406
8699
|
const nextModels = (provider.models?.length ?? 0) > 0 ? provider.models : [""];
|
|
8407
8700
|
setModels(nextModels);
|
|
8408
8701
|
setModelMetadataDrafts(createMetadataDrafts(provider, nextModels));
|
|
8409
|
-
setAnthropicBaseUrl(
|
|
8410
|
-
|
|
8702
|
+
setAnthropicBaseUrl(
|
|
8703
|
+
stripEndpointSuffix(provider.anthropicBaseUrl, ANTHROPIC_MESSAGES_ENDPOINT)
|
|
8704
|
+
);
|
|
8705
|
+
setOpenaiBaseUrl(
|
|
8706
|
+
stripEndpointSuffix(provider.openaiBaseUrl, OPENAI_CHAT_COMPLETIONS_ENDPOINT)
|
|
8707
|
+
);
|
|
8708
|
+
setOpenaiResponsesBaseUrl(
|
|
8709
|
+
stripEndpointSuffix(provider.openaiResponsesBaseUrl, OPENAI_RESPONSES_ENDPOINT)
|
|
8710
|
+
);
|
|
8411
8711
|
setApiDocsUrl(provider.apiDocsUrl ?? "");
|
|
8412
8712
|
setModelMetadataUrl(provider.modelMetadataUrl ?? "");
|
|
8413
8713
|
setSource(provider.source);
|
|
8414
8714
|
setManualAnthropicUrlOverride(false);
|
|
8415
8715
|
setManualOpenaiUrlOverride(false);
|
|
8716
|
+
setManualOpenaiResponsesUrlOverride(false);
|
|
8416
8717
|
}
|
|
8417
8718
|
}, [provider]);
|
|
8418
8719
|
reactExports.useEffect(() => {
|
|
@@ -8425,6 +8726,9 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8425
8726
|
if (preset.openaiBaseUrl !== void 0 && !manualOpenaiUrlOverride) {
|
|
8426
8727
|
setOpenaiBaseUrl(preset.openaiBaseUrl);
|
|
8427
8728
|
}
|
|
8729
|
+
if (preset.openaiResponsesBaseUrl !== void 0 && !manualOpenaiResponsesUrlOverride) {
|
|
8730
|
+
setOpenaiResponsesBaseUrl(preset.openaiResponsesBaseUrl);
|
|
8731
|
+
}
|
|
8428
8732
|
if (preset.apiDocsUrl !== void 0 && !apiDocsUrl) {
|
|
8429
8733
|
setApiDocsUrl(preset.apiDocsUrl);
|
|
8430
8734
|
}
|
|
@@ -8458,6 +8762,9 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8458
8762
|
if (openaiBaseUrl.trim() && !isValidUrl(openaiBaseUrl.trim())) {
|
|
8459
8763
|
newErrors.openaiBaseUrl = "Invalid URL format";
|
|
8460
8764
|
}
|
|
8765
|
+
if (openaiResponsesBaseUrl.trim() && !isValidUrl(openaiResponsesBaseUrl.trim())) {
|
|
8766
|
+
newErrors.openaiResponsesBaseUrl = "Invalid URL format";
|
|
8767
|
+
}
|
|
8461
8768
|
if (modelMetadataUrl.trim() && !isValidUrl(modelMetadataUrl.trim())) {
|
|
8462
8769
|
newErrors.modelMetadataUrl = "Invalid URL format";
|
|
8463
8770
|
}
|
|
@@ -8474,7 +8781,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8474
8781
|
newErrors[`modelMetadata.${index}.outputLimit`] = "Output limit should not exceed context window";
|
|
8475
8782
|
}
|
|
8476
8783
|
});
|
|
8477
|
-
if (!anthropicBaseUrl.trim() && !openaiBaseUrl.trim()) {
|
|
8784
|
+
if (!anthropicBaseUrl.trim() && !openaiBaseUrl.trim() && !openaiResponsesBaseUrl.trim()) {
|
|
8478
8785
|
newErrors.format = "At least one format URL (Anthropic or OpenAI) is required";
|
|
8479
8786
|
}
|
|
8480
8787
|
setErrors(newErrors);
|
|
@@ -8590,6 +8897,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8590
8897
|
models: models.map((m) => m.trim()).filter((m) => m !== ""),
|
|
8591
8898
|
anthropicBaseUrl: anthropicBaseUrl.trim() || void 0,
|
|
8592
8899
|
openaiBaseUrl: openaiBaseUrl.trim() || void 0,
|
|
8900
|
+
openaiResponsesBaseUrl: openaiResponsesBaseUrl.trim() || void 0,
|
|
8593
8901
|
apiDocsUrl: apiDocsUrl.trim() || void 0,
|
|
8594
8902
|
modelMetadataUrl: modelMetadataUrl.trim() || void 0,
|
|
8595
8903
|
modelMetadata: buildModelMetadata(),
|
|
@@ -8902,41 +9210,86 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8902
9210
|
] }),
|
|
8903
9211
|
activeTab === "anthropic" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
8904
9212
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-anthropic-base-url", className: "text-sm font-medium", children: "Anthropic Base URL" }),
|
|
8905
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
8906
|
-
|
|
8907
|
-
|
|
8908
|
-
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
9213
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md border border-input bg-background ring-offset-background focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9214
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9215
|
+
"input",
|
|
9216
|
+
{
|
|
9217
|
+
id: "provider-anthropic-base-url",
|
|
9218
|
+
type: "text",
|
|
9219
|
+
value: anthropicBaseUrl,
|
|
9220
|
+
onChange: (e) => {
|
|
9221
|
+
setManualAnthropicUrlOverride(true);
|
|
9222
|
+
setAnthropicBaseUrl(e.target.value);
|
|
9223
|
+
},
|
|
9224
|
+
placeholder: "https://api.anthropic.com",
|
|
9225
|
+
className: "min-w-0 flex-1 bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9226
|
+
}
|
|
9227
|
+
),
|
|
9228
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-muted px-3 py-2 font-mono text-xs text-muted-foreground", children: ANTHROPIC_MESSAGES_ENDPOINT })
|
|
9229
|
+
] }),
|
|
8919
9230
|
errors.anthropicBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.anthropicBaseUrl }),
|
|
8920
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9231
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(EndpointUrlPreview, { baseUrl: anthropicBaseUrl, endpoint: ANTHROPIC_MESSAGES_ENDPOINT }),
|
|
9232
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Anthropic-compatible base URL. Leave empty if this provider does not support Anthropic format." })
|
|
8921
9233
|
] }),
|
|
8922
|
-
activeTab === "openai" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-
|
|
8923
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
8924
|
-
|
|
8925
|
-
"input",
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
9234
|
+
activeTab === "openai" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
9235
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9236
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-base-url", className: "text-sm font-medium", children: "OpenAI Chat Base URL" }),
|
|
9237
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md border border-input bg-background ring-offset-background focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9238
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9239
|
+
"input",
|
|
9240
|
+
{
|
|
9241
|
+
id: "provider-openai-base-url",
|
|
9242
|
+
type: "text",
|
|
9243
|
+
value: openaiBaseUrl,
|
|
9244
|
+
onChange: (e) => {
|
|
9245
|
+
setManualOpenaiUrlOverride(true);
|
|
9246
|
+
setOpenaiBaseUrl(e.target.value);
|
|
9247
|
+
},
|
|
9248
|
+
placeholder: "https://api.openai.com",
|
|
9249
|
+
className: "min-w-0 flex-1 bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9250
|
+
}
|
|
9251
|
+
),
|
|
9252
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-muted px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_CHAT_COMPLETIONS_ENDPOINT })
|
|
9253
|
+
] }),
|
|
9254
|
+
errors.openaiBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiBaseUrl }),
|
|
9255
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9256
|
+
EndpointUrlPreview,
|
|
9257
|
+
{
|
|
9258
|
+
baseUrl: openaiBaseUrl,
|
|
9259
|
+
endpoint: OPENAI_CHAT_COMPLETIONS_ENDPOINT
|
|
9260
|
+
}
|
|
9261
|
+
),
|
|
9262
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "OpenAI Chat Completions-compatible base URL. Leave empty if this provider only supports the Responses API." })
|
|
9263
|
+
] }),
|
|
9264
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9265
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-responses-base-url", className: "text-sm font-medium", children: "OpenAI Responses Base URL" }),
|
|
9266
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md border border-input bg-background ring-offset-background focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9267
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9268
|
+
"input",
|
|
9269
|
+
{
|
|
9270
|
+
id: "provider-openai-responses-base-url",
|
|
9271
|
+
type: "text",
|
|
9272
|
+
value: openaiResponsesBaseUrl,
|
|
9273
|
+
onChange: (e) => {
|
|
9274
|
+
setManualOpenaiResponsesUrlOverride(true);
|
|
9275
|
+
setOpenaiResponsesBaseUrl(e.target.value);
|
|
9276
|
+
},
|
|
9277
|
+
placeholder: "https://api.openai.com",
|
|
9278
|
+
className: "min-w-0 flex-1 bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9279
|
+
}
|
|
9280
|
+
),
|
|
9281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-muted px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_RESPONSES_ENDPOINT })
|
|
9282
|
+
] }),
|
|
9283
|
+
errors.openaiResponsesBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiResponsesBaseUrl }),
|
|
9284
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9285
|
+
EndpointUrlPreview,
|
|
9286
|
+
{
|
|
9287
|
+
baseUrl: openaiResponsesBaseUrl,
|
|
9288
|
+
endpoint: OPENAI_RESPONSES_ENDPOINT
|
|
9289
|
+
}
|
|
9290
|
+
),
|
|
9291
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Optional Responses-compatible base URL. Set only when the provider supports the Responses API." })
|
|
9292
|
+
] })
|
|
8940
9293
|
] }),
|
|
8941
9294
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
8942
9295
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-api-docs-url", className: "text-sm font-medium", children: "API Docs URL" }),
|
|
@@ -8983,6 +9336,7 @@ function createProviderPayload(data) {
|
|
|
8983
9336
|
models: data.models,
|
|
8984
9337
|
anthropicBaseUrl: (data.anthropicBaseUrl?.length ?? 0) > 0 ? data.anthropicBaseUrl : void 0,
|
|
8985
9338
|
openaiBaseUrl: (data.openaiBaseUrl?.length ?? 0) > 0 ? data.openaiBaseUrl : void 0,
|
|
9339
|
+
openaiResponsesBaseUrl: (data.openaiResponsesBaseUrl?.length ?? 0) > 0 ? data.openaiResponsesBaseUrl : void 0,
|
|
8986
9340
|
apiDocsUrl: (data.apiDocsUrl?.length ?? 0) > 0 ? data.apiDocsUrl : void 0,
|
|
8987
9341
|
modelMetadataUrl: (data.modelMetadataUrl?.length ?? 0) > 0 ? data.modelMetadataUrl : void 0,
|
|
8988
9342
|
modelMetadata: data.modelMetadata,
|
|
@@ -9272,7 +9626,7 @@ function ProvidersPanel({
|
|
|
9272
9626
|
await refreshProviderMetadata(updated.id, data.modelMetadataUrl, false);
|
|
9273
9627
|
}
|
|
9274
9628
|
refreshProviders();
|
|
9275
|
-
const criticalFieldsChanged = (data.apiKey ?? "") !== (editingProvider.apiKey ?? "") || JSON.stringify(data.models) !== JSON.stringify(editingProvider.models) || (data.anthropicBaseUrl ?? "") !== (editingProvider.anthropicBaseUrl ?? "") || (data.openaiBaseUrl ?? "") !== (editingProvider.openaiBaseUrl ?? "");
|
|
9629
|
+
const criticalFieldsChanged = (data.apiKey ?? "") !== (editingProvider.apiKey ?? "") || JSON.stringify(data.models) !== JSON.stringify(editingProvider.models) || (data.anthropicBaseUrl ?? "") !== (editingProvider.anthropicBaseUrl ?? "") || (data.openaiBaseUrl ?? "") !== (editingProvider.openaiBaseUrl ?? "") || (data.openaiResponsesBaseUrl ?? "") !== (editingProvider.openaiResponsesBaseUrl ?? "");
|
|
9276
9630
|
if (criticalFieldsChanged) {
|
|
9277
9631
|
await runTest(updated.id);
|
|
9278
9632
|
}
|
|
@@ -11259,6 +11613,13 @@ const CONTEXT_USAGE_THRESHOLDS = {
|
|
|
11259
11613
|
watch: WATCH_USAGE_PERCENT,
|
|
11260
11614
|
danger: DANGER_USAGE_PERCENT
|
|
11261
11615
|
};
|
|
11616
|
+
const snapshotCache = /* @__PURE__ */ new WeakMap();
|
|
11617
|
+
function providerSignature(providers) {
|
|
11618
|
+
return providers.map((provider) => {
|
|
11619
|
+
const metadata = provider.modelMetadata?.map((entry) => `${entry.model}:${String(entry.contextWindow ?? "")}`).join(",") ?? "";
|
|
11620
|
+
return `${provider.id}:${provider.updatedAt}:${provider.models.join(",")}:${metadata}`;
|
|
11621
|
+
}).join("|");
|
|
11622
|
+
}
|
|
11262
11623
|
function parseRequestBody(rawBody) {
|
|
11263
11624
|
if (rawBody === null) return null;
|
|
11264
11625
|
try {
|
|
@@ -11308,6 +11669,25 @@ function snapshotFromLog(log, providers) {
|
|
|
11308
11669
|
roleTotalTokens: roleSegments.reduce((sum, segment2) => sum + segment2.size, 0)
|
|
11309
11670
|
};
|
|
11310
11671
|
}
|
|
11672
|
+
function cachedSnapshotFromLog(log, providers, providersSignature) {
|
|
11673
|
+
const cached = snapshotCache.get(log);
|
|
11674
|
+
if (cached !== void 0 && cached.id === log.id && cached.rawRequestBody === log.rawRequestBody && cached.inputTokens === log.inputTokens && cached.model === log.model && cached.path === log.path && cached.apiFormat === log.apiFormat && cached.timestamp === log.timestamp && cached.providersSignature === providersSignature) {
|
|
11675
|
+
return cached.snapshot;
|
|
11676
|
+
}
|
|
11677
|
+
const snapshot = snapshotFromLog(log, providers);
|
|
11678
|
+
snapshotCache.set(log, {
|
|
11679
|
+
id: log.id,
|
|
11680
|
+
rawRequestBody: log.rawRequestBody,
|
|
11681
|
+
inputTokens: log.inputTokens,
|
|
11682
|
+
model: log.model,
|
|
11683
|
+
path: log.path,
|
|
11684
|
+
apiFormat: log.apiFormat,
|
|
11685
|
+
timestamp: log.timestamp,
|
|
11686
|
+
providersSignature,
|
|
11687
|
+
snapshot
|
|
11688
|
+
});
|
|
11689
|
+
return snapshot;
|
|
11690
|
+
}
|
|
11311
11691
|
function isHigherPeak(candidate, current) {
|
|
11312
11692
|
if (candidate.usagePercent !== null && current.usagePercent !== null) {
|
|
11313
11693
|
return candidate.usagePercent > current.usagePercent;
|
|
@@ -11341,11 +11721,21 @@ function trendPercent(first, latest) {
|
|
|
11341
11721
|
if (first.usagePercent === null || latest.usagePercent === null) return null;
|
|
11342
11722
|
return (latest.usagePercent - first.usagePercent) * 100;
|
|
11343
11723
|
}
|
|
11724
|
+
function logsInAscendingIdOrder(logs) {
|
|
11725
|
+
for (let index = 1; index < logs.length; index++) {
|
|
11726
|
+
const previous = logs[index - 1];
|
|
11727
|
+
const current = logs[index];
|
|
11728
|
+
if (previous === void 0 || current === void 0) continue;
|
|
11729
|
+
if (previous.id > current.id) return [...logs].sort((left, right) => left.id - right.id);
|
|
11730
|
+
}
|
|
11731
|
+
return logs;
|
|
11732
|
+
}
|
|
11344
11733
|
function buildSessionContextSummary(logs, providers = []) {
|
|
11345
|
-
const sortedLogs =
|
|
11734
|
+
const sortedLogs = logsInAscendingIdOrder(logs);
|
|
11735
|
+
const providersSignature = providerSignature(providers);
|
|
11346
11736
|
const byModel = /* @__PURE__ */ new Map();
|
|
11347
11737
|
for (const log of sortedLogs) {
|
|
11348
|
-
const snapshot =
|
|
11738
|
+
const snapshot = cachedSnapshotFromLog(log, providers, providersSignature);
|
|
11349
11739
|
if (snapshot === null) continue;
|
|
11350
11740
|
const existing = byModel.get(snapshot.model);
|
|
11351
11741
|
if (existing === void 0) {
|
|
@@ -11380,6 +11770,20 @@ function truncateSessionId(id) {
|
|
|
11380
11770
|
if (id.length <= 30) return id;
|
|
11381
11771
|
return `${id.slice(0, 12)}...${id.slice(-12)}`;
|
|
11382
11772
|
}
|
|
11773
|
+
function buildDisplayNumberByLogId(groups) {
|
|
11774
|
+
const result = /* @__PURE__ */ new Map();
|
|
11775
|
+
for (const group of groups) {
|
|
11776
|
+
for (let index = 0; index < group.logs.length; index += 1) {
|
|
11777
|
+
const log = group.logs[index];
|
|
11778
|
+
if (log === void 0) continue;
|
|
11779
|
+
result.set(log.id, index + 1);
|
|
11780
|
+
}
|
|
11781
|
+
}
|
|
11782
|
+
return result;
|
|
11783
|
+
}
|
|
11784
|
+
function displayNumberForLog(log, displayNumberByLogId) {
|
|
11785
|
+
return displayNumberByLogId.get(log.id) ?? log.id;
|
|
11786
|
+
}
|
|
11383
11787
|
function shouldShowRawExport(captureMode) {
|
|
11384
11788
|
return captureMode === "full";
|
|
11385
11789
|
}
|
|
@@ -12429,6 +12833,7 @@ function ProxyViewer({
|
|
|
12429
12833
|
setComparePair(null);
|
|
12430
12834
|
}, []);
|
|
12431
12835
|
const groups = reactExports.useMemo(() => groupLogsByConversation(logs), [logs]);
|
|
12836
|
+
const displayNumberByLogId = reactExports.useMemo(() => buildDisplayNumberByLogId(groups), [groups]);
|
|
12432
12837
|
const sessionContextScope = reactExports.useMemo(
|
|
12433
12838
|
() => resolveSessionContextScope({ pinnedSessionId, selectedSession, sessions, logs }),
|
|
12434
12839
|
[logs, pinnedSessionId, selectedSession, sessions]
|
|
@@ -12667,7 +13072,16 @@ function ProxyViewer({
|
|
|
12667
13072
|
] })
|
|
12668
13073
|
] })
|
|
12669
13074
|
] }),
|
|
12670
|
-
comparePair !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13075
|
+
comparePair !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13076
|
+
LazyCompareDrawer,
|
|
13077
|
+
{
|
|
13078
|
+
left: comparePair[0],
|
|
13079
|
+
right: comparePair[1],
|
|
13080
|
+
leftDisplayNumber: displayNumberForLog(comparePair[0], displayNumberByLogId),
|
|
13081
|
+
rightDisplayNumber: displayNumberForLog(comparePair[1], displayNumberByLogId),
|
|
13082
|
+
onClose: closeCompare
|
|
13083
|
+
}
|
|
13084
|
+
) })
|
|
12671
13085
|
] });
|
|
12672
13086
|
}
|
|
12673
13087
|
const SSEUpdateSchema = union([
|
|
@@ -12730,7 +13144,7 @@ function filterLogs(logs, selectedSession, selectedModel) {
|
|
|
12730
13144
|
return true;
|
|
12731
13145
|
});
|
|
12732
13146
|
}
|
|
12733
|
-
const DEBOUNCE_MS =
|
|
13147
|
+
const DEBOUNCE_MS = 100;
|
|
12734
13148
|
const HASH_SCROLL_ATTEMPTS = 12;
|
|
12735
13149
|
const HASH_HIGHLIGHT_MS = 1800;
|
|
12736
13150
|
const MAX_CLIENT_LOGS = 500;
|
|
@@ -12787,6 +13201,7 @@ function ProxyViewerContainer({
|
|
|
12787
13201
|
const [logPage, setLogPage] = reactExports.useState(null);
|
|
12788
13202
|
const [sessionPageLoading, setSessionPageLoading] = reactExports.useState(initialSessionId !== void 0);
|
|
12789
13203
|
const [sessionMemberships, setSessionMemberships] = reactExports.useState([]);
|
|
13204
|
+
const [, startLogTransition] = reactExports.useTransition();
|
|
12790
13205
|
const eventSourceRef = reactExports.useRef(null);
|
|
12791
13206
|
const reconnectTimeoutRef = reactExports.useRef(null);
|
|
12792
13207
|
const handledHashRef = reactExports.useRef(null);
|
|
@@ -12805,22 +13220,28 @@ function ProxyViewerContainer({
|
|
|
12805
13220
|
const updates = pendingUpdatesRef.current;
|
|
12806
13221
|
pendingUpdatesRef.current = [];
|
|
12807
13222
|
if (updates.length === 0) return;
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12811
|
-
const
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
|
|
13223
|
+
startLogTransition(() => {
|
|
13224
|
+
setAllLogs((prev) => {
|
|
13225
|
+
const next = [...prev];
|
|
13226
|
+
for (const log of updates) {
|
|
13227
|
+
const indexedPosition = logIndexRef.current.get(log.id);
|
|
13228
|
+
if (indexedPosition !== void 0 && next[indexedPosition]?.id === log.id) {
|
|
13229
|
+
next[indexedPosition] = log;
|
|
13230
|
+
continue;
|
|
13231
|
+
}
|
|
13232
|
+
const existingPosition = next.findIndex((entry) => entry.id === log.id);
|
|
13233
|
+
if (existingPosition >= 0) {
|
|
13234
|
+
next[existingPosition] = log;
|
|
13235
|
+
continue;
|
|
13236
|
+
}
|
|
13237
|
+
next.push(log);
|
|
12817
13238
|
}
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
13239
|
+
const trimmed = trimClientLogs(next);
|
|
13240
|
+
logIndexRef.current = buildLogIndex(trimmed);
|
|
13241
|
+
return trimmed;
|
|
13242
|
+
});
|
|
12822
13243
|
});
|
|
12823
|
-
}, []);
|
|
13244
|
+
}, [startLogTransition]);
|
|
12824
13245
|
const scheduleUpdate = reactExports.useCallback(
|
|
12825
13246
|
(log) => {
|
|
12826
13247
|
pendingUpdatesRef.current.push(log);
|
|
@@ -13142,9 +13563,10 @@ export {
|
|
|
13142
13563
|
Badge as B,
|
|
13143
13564
|
CONTEXT_USAGE_THRESHOLDS as C,
|
|
13144
13565
|
Dialog as D,
|
|
13145
|
-
|
|
13566
|
+
LazyJsonViewer as E,
|
|
13146
13567
|
safeJsonValue as F,
|
|
13147
|
-
|
|
13568
|
+
parseJsonText as G,
|
|
13569
|
+
LazyJsonViewerFromString as L,
|
|
13148
13570
|
ProxyViewerContainer as P,
|
|
13149
13571
|
ROLE_COLOR_CLASSES as R,
|
|
13150
13572
|
SegmentBar as S,
|