@tonyclaw/agent-inspector 2.1.12 → 2.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/cli.js +0 -8
- package/.output/nitro.json +1 -1
- package/.output/public/assets/CompareDrawer-DjgjIFx7.js +1 -0
- package/.output/public/assets/ProxyViewerContainer-CWUQZLYy.js +106 -0
- package/.output/public/assets/{ReplayDialog-Cd1VsfRe.js → ReplayDialog-CU0Tbb2c.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-QxSpbmsj.js → RequestAnatomy-BNahe83D.js} +1 -1
- package/.output/public/assets/ResponseView-DSOnGqi6.js +3 -0
- package/.output/public/assets/{StreamingChunkSequence-CwNGqJ5n.js → StreamingChunkSequence-BEKTDklB.js} +1 -1
- package/.output/public/assets/_sessionId-Cif8JZdn.js +1 -0
- package/.output/public/assets/index-DWOkqdCa.js +14 -0
- package/.output/public/assets/index-D_WfwzUi.js +1 -0
- package/.output/public/assets/index-DtLuQrs0.css +1 -0
- package/.output/public/assets/json-viewer-C2JpgcW0.js +1 -0
- package/.output/public/assets/{main-B_EcGyf-.js → main-CSONBwwn.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +20 -20
- package/.output/server/_libs/react-markdown.mjs +90 -2
- package/.output/server/{_sessionId-CmO9read.mjs → _sessionId-CPAa37n5.mjs} +6 -57
- package/.output/server/_ssr/{CompareDrawer-D9wf870o.mjs → CompareDrawer-ceW5VxMo.mjs} +17 -62
- package/.output/server/_ssr/{ProxyViewerContainer-BDLJSawP.mjs → ProxyViewerContainer-CDfEE_w-.mjs} +872 -688
- package/.output/server/_ssr/{ReplayDialog-B2dS4kmP.mjs → ReplayDialog-V0s_eEbR.mjs} +8 -59
- package/.output/server/_ssr/{RequestAnatomy-k49Peshi.mjs → RequestAnatomy-f1ccwR9d.mjs} +6 -57
- package/.output/server/_ssr/{ResponseView-Bk3B1suu.mjs → ResponseView-BIRrqG4H.mjs} +138 -60
- package/.output/server/_ssr/{StreamingChunkSequence-D6MDGCgh.mjs → StreamingChunkSequence-V3JFjCgX.mjs} +13 -58
- package/.output/server/_ssr/{index-CC8KdlTb.mjs → index-DsykulzS.mjs} +6 -57
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/json-viewer-Dcnm0Ivf.mjs +478 -0
- package/.output/server/_ssr/{router-BEmMnVa7.mjs → router-4bdm6Mt2.mjs} +674 -173
- package/.output/server/{_tanstack-start-manifest_v-Bf_4hG4w.mjs → _tanstack-start-manifest_v-Xp4CO64V.mjs} +1 -1
- package/.output/server/index.mjs +70 -56
- package/package.json +1 -1
- package/src/components/ProxyViewerContainer.tsx +25 -17
- 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/AnswerMarkdown.tsx +8 -3
- package/src/components/proxy-viewer/CompareDrawer.tsx +20 -6
- package/src/components/proxy-viewer/ConversationGroup.tsx +11 -15
- package/src/components/proxy-viewer/LogEntry.tsx +31 -11
- package/src/components/proxy-viewer/LogEntryHeader.tsx +111 -40
- package/src/components/proxy-viewer/RequestToolsPanel.tsx +19 -13
- package/src/components/proxy-viewer/StreamingChunkSequence.tsx +9 -3
- package/src/components/proxy-viewer/TurnGroup.tsx +53 -7
- 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 +72 -3
- 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/stopReason.ts +12 -0
- 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/identityProxy.ts +0 -7
- package/src/proxy/providerImporters.ts +45 -5
- package/src/proxy/providers.ts +31 -11
- package/src/proxy/schemas.ts +6 -0
- 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-XTdSOto9.js +0 -1
- package/.output/public/assets/ProxyViewerContainer-Cc944N8i.js +0 -117
- package/.output/public/assets/ResponseView-8GivXCzp.js +0 -1
- package/.output/public/assets/_sessionId-D89uDTQs.js +0 -1
- package/.output/public/assets/index-BsFdgXac.js +0 -1
- package/.output/public/assets/index-CmtfjQPv.css +0 -1
package/.output/server/_ssr/{ProxyViewerContainer-BDLJSawP.mjs → ProxyViewerContainer-CDfEE_w-.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-4bdm6Mt2.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 User, q as Clock, M as MessageSquare, Z as Zap, E as ExternalLink, W as Wrench, r as TriangleAlert, B as Brain, s as Bell, t as Clock3, u as ShieldAlert, v as EyeOff, w as Eye, x as RotateCw, y as Pencil, z as CircleX, H as ShieldCheck, J as Save, K as FileSearch, N as CircleCheck, O as CloudUpload, Q 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 User, q as Clock, M as MessageSquare, Z as Zap, E as ExternalLink, W as Wrench, r as TriangleAlert, B as Brain, s as Bell, t as Clock3, u as ShieldAlert, v as EyeOff, w as Eye, x as RotateCw, y as Pencil, z as CircleX, H as ShieldCheck, J as Save, K as FileSearch, N as CircleCheck, O as CloudUpload, Q as Minus, V as CircleCheckBig, Y as CircleQuestionMark, _ as Server, $ as Lock, a0 as Wifi, a1 as WifiOff, a2 as OctagonAlert, a3 as Radio, a4 as Globe, a5 as FileTerminal, a6 as ChevronsUp, a7 as ChevronsDown, a8 as FileDiff, a9 as History, aa as RotateCcw, ab as Search, ac as GitCompareArrows, ad as ArrowUp, ae as ArrowDown, af as Ellipsis, ag as CodeXml, ah as Blocks, ai as MousePointerClick, aj as FileText, ak as Rows3, al 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";
|
|
@@ -1078,9 +1077,9 @@ function contentToText(content) {
|
|
|
1078
1077
|
if (block === null || typeof block !== "object") continue;
|
|
1079
1078
|
const b = block;
|
|
1080
1079
|
const type = b.type;
|
|
1081
|
-
if (type === "text" && typeof b.text === "string") {
|
|
1080
|
+
if ((type === "text" || type === "input_text" || type === "output_text") && typeof b.text === "string") {
|
|
1082
1081
|
parts.push(b.text);
|
|
1083
|
-
} else if (type === "image_url") {
|
|
1082
|
+
} else if (type === "image_url" || type === "input_image") {
|
|
1084
1083
|
parts.push("[image]");
|
|
1085
1084
|
}
|
|
1086
1085
|
}
|
|
@@ -1110,15 +1109,54 @@ function toolsToText(tools) {
|
|
|
1110
1109
|
const parts = [];
|
|
1111
1110
|
for (const tool of tools) {
|
|
1112
1111
|
if (tool === null || typeof tool !== "object") continue;
|
|
1113
|
-
const
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
if (typeof
|
|
1118
|
-
if (
|
|
1112
|
+
const fn = safeGetOwnProperty(tool, "function");
|
|
1113
|
+
const name = safeGetOwnProperty(fn, "name") ?? safeGetOwnProperty(tool, "name");
|
|
1114
|
+
const description = safeGetOwnProperty(fn, "description") ?? safeGetOwnProperty(tool, "description");
|
|
1115
|
+
const parameters = safeGetOwnProperty(fn, "parameters") ?? safeGetOwnProperty(tool, "parameters");
|
|
1116
|
+
if (typeof name === "string") parts.push(name);
|
|
1117
|
+
if (typeof description === "string") parts.push(description);
|
|
1118
|
+
if (parameters !== void 0) parts.push(JSON.stringify(parameters));
|
|
1119
1119
|
}
|
|
1120
1120
|
return parts.join("\n");
|
|
1121
1121
|
}
|
|
1122
|
+
function countResponsesInput(input) {
|
|
1123
|
+
if (typeof input === "string") return input.length > 0 ? 1 : 0;
|
|
1124
|
+
if (Array.isArray(input)) return input.length;
|
|
1125
|
+
if (input === void 0 || input === null) return null;
|
|
1126
|
+
return 1;
|
|
1127
|
+
}
|
|
1128
|
+
function responsesInputItemToText(input) {
|
|
1129
|
+
if (typeof input === "string") return input;
|
|
1130
|
+
const directText = safeGetOwnProperty(input, "text");
|
|
1131
|
+
if (typeof directText === "string") return directText;
|
|
1132
|
+
const contentText = contentToText(safeGetOwnProperty(input, "content"));
|
|
1133
|
+
if (contentText.length > 0) return contentText;
|
|
1134
|
+
const outputText = contentToText(safeGetOwnProperty(input, "output"));
|
|
1135
|
+
if (outputText.length > 0) return outputText;
|
|
1136
|
+
const argumentsText = safeGetOwnProperty(input, "arguments");
|
|
1137
|
+
return typeof argumentsText === "string" ? argumentsText : "";
|
|
1138
|
+
}
|
|
1139
|
+
function responsesInputRole(input) {
|
|
1140
|
+
const role = safeGetOwnProperty(input, "role");
|
|
1141
|
+
if (role === "system" || role === "user" || role === "assistant" || role === "tool") {
|
|
1142
|
+
return role;
|
|
1143
|
+
}
|
|
1144
|
+
const type = safeGetOwnProperty(input, "type");
|
|
1145
|
+
if (type === "function_call_output") return "tool";
|
|
1146
|
+
if (type === "message") return "user";
|
|
1147
|
+
return "user";
|
|
1148
|
+
}
|
|
1149
|
+
function responsesToolNames(response) {
|
|
1150
|
+
const output = safeGetOwnProperty(response, "output");
|
|
1151
|
+
if (!Array.isArray(output)) return [];
|
|
1152
|
+
const names = [];
|
|
1153
|
+
for (const item of output) {
|
|
1154
|
+
if (safeGetOwnProperty(item, "type") !== "function_call") continue;
|
|
1155
|
+
const name = safeGetOwnProperty(item, "name");
|
|
1156
|
+
if (typeof name === "string" && name.length > 0) names.push(name);
|
|
1157
|
+
}
|
|
1158
|
+
return names;
|
|
1159
|
+
}
|
|
1122
1160
|
function segment(role, label, text, path) {
|
|
1123
1161
|
return {
|
|
1124
1162
|
role,
|
|
@@ -1135,7 +1173,16 @@ const openAILogFormatAdapter = {
|
|
|
1135
1173
|
if (rawBody === null) return emptyRequestAnalysis(rawBody);
|
|
1136
1174
|
try {
|
|
1137
1175
|
const result = OpenAIRequestSchema.safeParse(JSON.parse(rawBody));
|
|
1138
|
-
if (!result.success)
|
|
1176
|
+
if (!result.success) {
|
|
1177
|
+
const responsesResult = OpenAIResponsesRequestSchema.safeParse(JSON.parse(rawBody));
|
|
1178
|
+
if (!responsesResult.success) return emptyRequestAnalysis(rawBody);
|
|
1179
|
+
return {
|
|
1180
|
+
parsed: responsesResult.data,
|
|
1181
|
+
comparisonValue: responsesResult.data,
|
|
1182
|
+
messageCount: countResponsesInput(responsesResult.data.input),
|
|
1183
|
+
toolCount: responsesResult.data.tools !== void 0 && responsesResult.data.tools.length > 0 ? responsesResult.data.tools.length : null
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1139
1186
|
return {
|
|
1140
1187
|
parsed: result.data,
|
|
1141
1188
|
comparisonValue: result.data,
|
|
@@ -1149,7 +1196,15 @@ const openAILogFormatAdapter = {
|
|
|
1149
1196
|
analyzeResponse(responseText) {
|
|
1150
1197
|
if (responseText === null) return EMPTY_RESPONSE_ANALYSIS;
|
|
1151
1198
|
const parsed = parseOpenAIResponse(responseText);
|
|
1152
|
-
if (parsed === null)
|
|
1199
|
+
if (parsed === null) {
|
|
1200
|
+
const responsesParsed = parseOpenAIResponsesResponse(responseText);
|
|
1201
|
+
if (responsesParsed === null) return EMPTY_RESPONSE_ANALYSIS;
|
|
1202
|
+
const toolNames2 = responsesToolNames(responsesParsed);
|
|
1203
|
+
return {
|
|
1204
|
+
parsed: responsesParsed,
|
|
1205
|
+
toolNames: toolNames2.length > 0 ? toolNames2 : null
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1153
1208
|
const toolNames = parsed.choices[0]?.message?.tool_calls?.map((toolCall) => toolCall.function?.name ?? "").filter((name) => name !== "") ?? [];
|
|
1154
1209
|
return {
|
|
1155
1210
|
parsed,
|
|
@@ -1160,6 +1215,9 @@ const openAILogFormatAdapter = {
|
|
|
1160
1215
|
if (parsed === null || typeof parsed !== "object") return null;
|
|
1161
1216
|
const body = parsed;
|
|
1162
1217
|
const segments = [];
|
|
1218
|
+
if (typeof body.instructions === "string" && body.instructions.length > 0) {
|
|
1219
|
+
segments.push(segment("system", "instructions", body.instructions, "/instructions"));
|
|
1220
|
+
}
|
|
1163
1221
|
if (Array.isArray(body.messages)) {
|
|
1164
1222
|
body.messages.forEach((message, index) => {
|
|
1165
1223
|
if (message === null || typeof message !== "object") return;
|
|
@@ -1169,6 +1227,17 @@ const openAILogFormatAdapter = {
|
|
|
1169
1227
|
segments.push(segment(role, `[${index}] ${role}`, text, `/messages/${index}`));
|
|
1170
1228
|
});
|
|
1171
1229
|
}
|
|
1230
|
+
if (!Array.isArray(body.messages)) {
|
|
1231
|
+
if (typeof body.input === "string" && body.input.length > 0) {
|
|
1232
|
+
segments.push(segment("user", "input", body.input, "/input"));
|
|
1233
|
+
} else if (Array.isArray(body.input)) {
|
|
1234
|
+
body.input.forEach((item, index) => {
|
|
1235
|
+
const role = responsesInputRole(item);
|
|
1236
|
+
const text = responsesInputItemToText(item);
|
|
1237
|
+
segments.push(segment(role, `[${index}] ${role}`, text, `/input/${index}`));
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1172
1241
|
if (Array.isArray(body.tools) && body.tools.length > 0) {
|
|
1173
1242
|
const text = toolsToText(body.tools);
|
|
1174
1243
|
segments.push(segment("tools", "tools", text, "/tools"));
|
|
@@ -1418,6 +1487,35 @@ function groupLogsByConversation(logs) {
|
|
|
1418
1487
|
result.sort((a, b) => (a.logs[0]?.timestamp ?? "").localeCompare(b.logs[0]?.timestamp ?? ""));
|
|
1419
1488
|
return result;
|
|
1420
1489
|
}
|
|
1490
|
+
const LOG_FOCUS_REQUEST_EVENT = "agent-inspector:focus-log";
|
|
1491
|
+
function dispatchLogFocusRequest(request) {
|
|
1492
|
+
window.dispatchEvent(new CustomEvent(LOG_FOCUS_REQUEST_EVENT, { detail: request }));
|
|
1493
|
+
}
|
|
1494
|
+
function readLogFocusRequest(event) {
|
|
1495
|
+
if (typeof CustomEvent === "undefined" || !(event instanceof CustomEvent)) return null;
|
|
1496
|
+
const detail = event.detail;
|
|
1497
|
+
const logId = safeGetOwnProperty(detail, "logId");
|
|
1498
|
+
if (typeof logId !== "number" || !Number.isInteger(logId) || logId < 0) return null;
|
|
1499
|
+
const tab = safeGetOwnProperty(detail, "tab");
|
|
1500
|
+
switch (tab) {
|
|
1501
|
+
case "anatomy":
|
|
1502
|
+
case "request":
|
|
1503
|
+
break;
|
|
1504
|
+
case void 0:
|
|
1505
|
+
break;
|
|
1506
|
+
default:
|
|
1507
|
+
return null;
|
|
1508
|
+
}
|
|
1509
|
+
const source = safeGetOwnProperty(detail, "source");
|
|
1510
|
+
switch (source) {
|
|
1511
|
+
case "virtualizer":
|
|
1512
|
+
return { logId, tab: tab ?? "request", source };
|
|
1513
|
+
case void 0:
|
|
1514
|
+
return { logId, tab: tab ?? "request" };
|
|
1515
|
+
default:
|
|
1516
|
+
return null;
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1421
1519
|
function isRecord(value) {
|
|
1422
1520
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1423
1521
|
}
|
|
@@ -1438,6 +1536,16 @@ function extractStopReason(log) {
|
|
|
1438
1536
|
if (Array.isArray(json.choices) && json.choices.length > 0 && isRecord(json.choices[0]) && typeof json.choices[0].finish_reason === "string" && json.choices[0].finish_reason === "stop") {
|
|
1439
1537
|
return "stop";
|
|
1440
1538
|
}
|
|
1539
|
+
if (Array.isArray(json.output)) {
|
|
1540
|
+
for (const item of json.output) {
|
|
1541
|
+
if (isRecord(item) && item.type === "function_call") {
|
|
1542
|
+
return "tool_use";
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
if (json.status === "completed") {
|
|
1546
|
+
return "stop";
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1441
1549
|
return null;
|
|
1442
1550
|
} catch {
|
|
1443
1551
|
return null;
|
|
@@ -1798,8 +1906,38 @@ function getInteriorCrabVariantIndex(seed) {
|
|
|
1798
1906
|
function getInteriorCrabVariant(seed) {
|
|
1799
1907
|
return getCrabVariant(getInteriorCrabVariantIndex(seed));
|
|
1800
1908
|
}
|
|
1801
|
-
|
|
1802
|
-
|
|
1909
|
+
const FULL_EXPAND_NODE_LIMIT = 400;
|
|
1910
|
+
const STRUCTURE_EXPAND_NODE_LIMIT = 2e3;
|
|
1911
|
+
function isJsonArray(value) {
|
|
1912
|
+
return Array.isArray(value);
|
|
1913
|
+
}
|
|
1914
|
+
function countJsonNodesUpTo(value, limit) {
|
|
1915
|
+
const stack = [value];
|
|
1916
|
+
let count = 0;
|
|
1917
|
+
while (stack.length > 0) {
|
|
1918
|
+
const current = stack.pop();
|
|
1919
|
+
if (current === void 0) continue;
|
|
1920
|
+
count += 1;
|
|
1921
|
+
if (count > limit) return count;
|
|
1922
|
+
if (current === null || typeof current !== "object") continue;
|
|
1923
|
+
if (isJsonArray(current)) {
|
|
1924
|
+
for (const child of current) {
|
|
1925
|
+
stack.push(child);
|
|
1926
|
+
}
|
|
1927
|
+
continue;
|
|
1928
|
+
}
|
|
1929
|
+
for (const key of Object.keys(current)) {
|
|
1930
|
+
const child = current[key];
|
|
1931
|
+
if (child !== void 0) stack.push(child);
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
return count;
|
|
1935
|
+
}
|
|
1936
|
+
function getJsonExpansionPolicy(value) {
|
|
1937
|
+
const nodeCount = countJsonNodesUpTo(value, STRUCTURE_EXPAND_NODE_LIMIT + 1);
|
|
1938
|
+
if (nodeCount <= FULL_EXPAND_NODE_LIMIT) return { depth: Number.POSITIVE_INFINITY };
|
|
1939
|
+
if (nodeCount <= STRUCTURE_EXPAND_NODE_LIMIT) return { depth: 3 };
|
|
1940
|
+
return { depth: 2 };
|
|
1803
1941
|
}
|
|
1804
1942
|
function parseJsonText(text) {
|
|
1805
1943
|
try {
|
|
@@ -1813,7 +1951,7 @@ function useJsonBulkExpansion(text) {
|
|
|
1813
1951
|
const parsed = reactExports.useMemo(() => text === null ? null : parseJsonText(text), [text]);
|
|
1814
1952
|
const parsedData = parsed?.kind === "json" ? parsed.data : null;
|
|
1815
1953
|
const policy = reactExports.useMemo(
|
|
1816
|
-
() => parsedData === null ? null : getJsonExpansionPolicy(),
|
|
1954
|
+
() => parsedData === null ? null : getJsonExpansionPolicy(parsedData),
|
|
1817
1955
|
[parsedData]
|
|
1818
1956
|
);
|
|
1819
1957
|
const [isExpanded, setIsExpanded] = reactExports.useState(false);
|
|
@@ -1961,27 +2099,27 @@ function useCopyFeedback(text) {
|
|
|
1961
2099
|
return { copied, copy };
|
|
1962
2100
|
}
|
|
1963
2101
|
const LazyCompareDrawer = reactExports.lazy(
|
|
1964
|
-
() => import("./CompareDrawer-
|
|
2102
|
+
() => import("./CompareDrawer-ceW5VxMo.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
1965
2103
|
);
|
|
1966
2104
|
const LazyReplayDialog = reactExports.lazy(
|
|
1967
|
-
() => import("./ReplayDialog-
|
|
2105
|
+
() => import("./ReplayDialog-V0s_eEbR.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
1968
2106
|
);
|
|
1969
2107
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
1970
|
-
() => import("./RequestAnatomy-
|
|
2108
|
+
() => import("./RequestAnatomy-f1ccwR9d.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
1971
2109
|
);
|
|
1972
2110
|
const LazyResponseView = reactExports.lazy(
|
|
1973
|
-
() => import("./ResponseView-
|
|
2111
|
+
() => import("./ResponseView-BIRrqG4H.mjs").then((m) => ({ default: m.ResponseView }))
|
|
1974
2112
|
);
|
|
1975
2113
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
1976
|
-
() => import("./StreamingChunkSequence-
|
|
2114
|
+
() => import("./StreamingChunkSequence-V3JFjCgX.mjs").then((m) => ({
|
|
1977
2115
|
default: m.StreamingChunkSequence
|
|
1978
2116
|
}))
|
|
1979
2117
|
);
|
|
1980
2118
|
const LazyJsonViewer = reactExports.lazy(
|
|
1981
|
-
() =>
|
|
2119
|
+
() => import("./json-viewer-Dcnm0Ivf.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
1982
2120
|
);
|
|
1983
2121
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
1984
|
-
() =>
|
|
2122
|
+
() => import("./json-viewer-Dcnm0Ivf.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
1985
2123
|
);
|
|
1986
2124
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
1987
2125
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -2405,12 +2543,35 @@ function Badge({
|
|
|
2405
2543
|
);
|
|
2406
2544
|
}
|
|
2407
2545
|
const STATUS_BADGE_CLASSES = {
|
|
2408
|
-
success: "bg-emerald-
|
|
2409
|
-
client_error: "bg-amber-
|
|
2410
|
-
server_error: "bg-rose-
|
|
2411
|
-
pending: "bg-
|
|
2546
|
+
success: "bg-emerald-400/[0.08] text-emerald-200 border-emerald-300/25",
|
|
2547
|
+
client_error: "bg-amber-300/[0.10] text-amber-100 border-amber-300/30",
|
|
2548
|
+
server_error: "bg-rose-400/[0.10] text-rose-100 border-rose-300/30",
|
|
2549
|
+
pending: "bg-cyan-300/[0.08] text-cyan-100 border-cyan-300/25"
|
|
2550
|
+
};
|
|
2551
|
+
const STATUS_CUE_CLASSES = {
|
|
2552
|
+
success: {
|
|
2553
|
+
frame: "border-emerald-300/20 bg-emerald-300/[0.06] text-emerald-100",
|
|
2554
|
+
dot: "bg-emerald-300 shadow-[0_0_14px_rgba(110,231,183,0.8)]",
|
|
2555
|
+
rail: "bg-emerald-300/45 shadow-[0_0_22px_rgba(110,231,183,0.28)]"
|
|
2556
|
+
},
|
|
2557
|
+
client_error: {
|
|
2558
|
+
frame: "border-amber-300/25 bg-amber-300/[0.08] text-amber-100",
|
|
2559
|
+
dot: "bg-amber-200 shadow-[0_0_14px_rgba(252,211,77,0.8)]",
|
|
2560
|
+
rail: "bg-amber-300/50 shadow-[0_0_22px_rgba(252,211,77,0.28)]"
|
|
2561
|
+
},
|
|
2562
|
+
server_error: {
|
|
2563
|
+
frame: "border-rose-300/25 bg-rose-300/[0.08] text-rose-100",
|
|
2564
|
+
dot: "bg-rose-300 shadow-[0_0_14px_rgba(253,164,175,0.8)]",
|
|
2565
|
+
rail: "bg-rose-300/50 shadow-[0_0_22px_rgba(253,164,175,0.28)]"
|
|
2566
|
+
},
|
|
2567
|
+
pending: {
|
|
2568
|
+
frame: "border-cyan-300/25 bg-cyan-300/[0.08] text-cyan-100",
|
|
2569
|
+
dot: "bg-cyan-200 shadow-[0_0_14px_rgba(103,232,249,0.8)]",
|
|
2570
|
+
rail: "bg-cyan-300/50 shadow-[0_0_22px_rgba(103,232,249,0.28)]"
|
|
2571
|
+
}
|
|
2412
2572
|
};
|
|
2413
2573
|
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";
|
|
2574
|
+
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
2575
|
function formatElapsed$3(ms) {
|
|
2415
2576
|
if (ms < 1e3) return `${ms}ms`;
|
|
2416
2577
|
return `${(ms / 1e3).toFixed(1)}s`;
|
|
@@ -2419,6 +2580,18 @@ function formatTokenRate$1(tokensPerSecond) {
|
|
|
2419
2580
|
if (tokensPerSecond >= 10) return `${tokensPerSecond.toFixed(0)}/s`;
|
|
2420
2581
|
return `${tokensPerSecond.toFixed(1)}/s`;
|
|
2421
2582
|
}
|
|
2583
|
+
function statusCueLabel(category, status) {
|
|
2584
|
+
switch (category) {
|
|
2585
|
+
case "success":
|
|
2586
|
+
return status === null ? "OK" : String(status);
|
|
2587
|
+
case "client_error":
|
|
2588
|
+
return status === null ? "WARN" : String(status);
|
|
2589
|
+
case "server_error":
|
|
2590
|
+
return status === null ? "FAIL" : String(status);
|
|
2591
|
+
case "pending":
|
|
2592
|
+
return "ROLL";
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2422
2595
|
function CacheTrendIndicator({ trend }) {
|
|
2423
2596
|
if (trend === null) return null;
|
|
2424
2597
|
const isUp = trend.direction === "up";
|
|
@@ -2456,6 +2629,8 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2456
2629
|
const hasClientPid = log.clientPid !== null && log.clientPid !== void 0;
|
|
2457
2630
|
const hasClientProjectFolder = log.clientProjectFolder !== null && log.clientProjectFolder !== void 0 && log.clientProjectFolder !== "";
|
|
2458
2631
|
const hasClientCwd = log.clientCwd !== null && log.clientCwd !== void 0 && log.clientCwd !== "";
|
|
2632
|
+
const statusCue = STATUS_CUE_CLASSES[statusCategory];
|
|
2633
|
+
const statusLabel2 = statusCueLabel(statusCategory, log.responseStatus);
|
|
2459
2634
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2460
2635
|
"div",
|
|
2461
2636
|
{
|
|
@@ -2465,9 +2640,9 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2465
2640
|
"data-nav-id": `log-${log.id}`,
|
|
2466
2641
|
"data-nav-action": expanded ? "collapse" : "expand",
|
|
2467
2642
|
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",
|
|
2643
|
+
"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]",
|
|
2644
|
+
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]",
|
|
2645
|
+
"select-none before:pointer-events-none before:absolute before:inset-x-0 before:top-0 before:h-px before:bg-white/10",
|
|
2471
2646
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
2472
2647
|
),
|
|
2473
2648
|
onClick: onToggle,
|
|
@@ -2478,25 +2653,48 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2478
2653
|
}
|
|
2479
2654
|
},
|
|
2480
2655
|
children: [
|
|
2481
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
2482
|
-
"
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2656
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2657
|
+
"span",
|
|
2658
|
+
{
|
|
2659
|
+
className: cn(
|
|
2660
|
+
"absolute left-0 top-2 bottom-2 w-0.5 rounded-r-full transition-colors",
|
|
2661
|
+
statusCue.rail
|
|
2662
|
+
),
|
|
2663
|
+
"aria-hidden": "true"
|
|
2664
|
+
}
|
|
2665
|
+
),
|
|
2666
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2667
|
+
"span",
|
|
2668
|
+
{
|
|
2669
|
+
className: cn(
|
|
2670
|
+
"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)]",
|
|
2671
|
+
statusCue.frame
|
|
2672
|
+
),
|
|
2673
|
+
children: [
|
|
2674
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("size-1.5 rounded-full", statusCue.dot), "aria-hidden": "true" }),
|
|
2675
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-semibold uppercase tracking-normal text-current/65", children: "Shot" }),
|
|
2676
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-semibold tabular-nums", children: [
|
|
2677
|
+
"#",
|
|
2678
|
+
log.id
|
|
2679
|
+
] })
|
|
2680
|
+
]
|
|
2681
|
+
}
|
|
2682
|
+
),
|
|
2683
|
+
/* @__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
2684
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
2487
2685
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", title: log.timestamp, children: formatTimestamp$2(log.timestamp, timeDisplayFormat) })
|
|
2488
2686
|
] }),
|
|
2489
|
-
|
|
2687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2490
2688
|
Badge,
|
|
2491
2689
|
{
|
|
2492
2690
|
variant: "outline",
|
|
2493
2691
|
className: cn(
|
|
2494
|
-
"
|
|
2692
|
+
"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
2693
|
STATUS_BADGE_CLASSES[statusCategory]
|
|
2496
2694
|
),
|
|
2497
2695
|
children: [
|
|
2498
|
-
statusCategory === "
|
|
2499
|
-
|
|
2696
|
+
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" }),
|
|
2697
|
+
statusLabel2
|
|
2500
2698
|
]
|
|
2501
2699
|
}
|
|
2502
2700
|
),
|
|
@@ -2505,7 +2703,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2505
2703
|
Badge,
|
|
2506
2704
|
{
|
|
2507
2705
|
variant: "outline",
|
|
2508
|
-
className: "
|
|
2706
|
+
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
2707
|
children: [
|
|
2510
2708
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Tool schema warnings" }),
|
|
2511
2709
|
warningCount
|
|
@@ -2515,11 +2713,20 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2515
2713
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: warningCount === 1 ? "1 tool schema warning" : `${warningCount} tool schema warnings` })
|
|
2516
2714
|
] }),
|
|
2517
2715
|
log.elapsedMs !== null && (isSlowResponse ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2518
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2716
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2717
|
+
"span",
|
|
2718
|
+
{
|
|
2719
|
+
className: cn(
|
|
2720
|
+
TELEMETRY_CHIP_CLASS,
|
|
2721
|
+
"shrink-0 border-amber-300/25 text-amber-200"
|
|
2722
|
+
),
|
|
2723
|
+
children: [
|
|
2724
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
2725
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed$3(log.elapsedMs) }),
|
|
2726
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Slow response" })
|
|
2727
|
+
]
|
|
2728
|
+
}
|
|
2729
|
+
) }),
|
|
2523
2730
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { children: [
|
|
2524
2731
|
"Slow response: ",
|
|
2525
2732
|
formatElapsed$3(log.elapsedMs),
|
|
@@ -2527,12 +2734,12 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2527
2734
|
" ",
|
|
2528
2735
|
formatElapsed$3(slowResponseThresholdSeconds * 1e3)
|
|
2529
2736
|
] })
|
|
2530
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2737
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-muted-foreground"), children: [
|
|
2531
2738
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
2532
2739
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed$3(log.elapsedMs) })
|
|
2533
2740
|
] })),
|
|
2534
2741
|
log.streaming && firstChunkLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2535
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2742
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-cyan-300"), children: [
|
|
2536
2743
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Radio, { className: "size-3" }),
|
|
2537
2744
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
2538
2745
|
"first ",
|
|
@@ -2542,13 +2749,13 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2542
2749
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Time to first streaming chunk" })
|
|
2543
2750
|
] }),
|
|
2544
2751
|
log.streaming && tokenRateLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2545
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2752
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-emerald-300"), children: [
|
|
2546
2753
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Gauge, { className: "size-3" }),
|
|
2547
2754
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: tokenRateLabel })
|
|
2548
2755
|
] }) }),
|
|
2549
2756
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Output token throughput after first chunk" })
|
|
2550
2757
|
] }),
|
|
2551
|
-
hasTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2758
|
+
hasTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "min-w-0 sm:shrink-0"), children: [
|
|
2552
2759
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3 text-muted-foreground" }),
|
|
2553
2760
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-1 font-mono tabular-nums", children: [
|
|
2554
2761
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -2580,32 +2787,32 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2580
2787
|
)
|
|
2581
2788
|
] })
|
|
2582
2789
|
] }),
|
|
2583
|
-
log.cacheCreationInputTokens !== null && log.cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2790
|
+
log.cacheCreationInputTokens !== null && log.cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0"), children: [
|
|
2584
2791
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CacheTrendIndicator, { trend: cacheTrend?.creation ?? null }),
|
|
2585
2792
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-emerald-400", children: [
|
|
2586
2793
|
"KV Cache +",
|
|
2587
2794
|
formatTokens(log.cacheCreationInputTokens)
|
|
2588
2795
|
] })
|
|
2589
2796
|
] }),
|
|
2590
|
-
log.cacheReadInputTokens !== null && log.cacheReadInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2797
|
+
log.cacheReadInputTokens !== null && log.cacheReadInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0"), children: [
|
|
2591
2798
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CacheTrendIndicator, { trend: cacheTrend?.read ?? null }),
|
|
2592
2799
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-purple-400", children: [
|
|
2593
2800
|
"KV Cache ~",
|
|
2594
2801
|
formatTokens(log.cacheReadInputTokens)
|
|
2595
2802
|
] })
|
|
2596
2803
|
] }),
|
|
2597
|
-
messageCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2804
|
+
messageCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-muted-foreground"), children: [
|
|
2598
2805
|
/* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3" }),
|
|
2599
2806
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: messageCount })
|
|
2600
2807
|
] }),
|
|
2601
|
-
toolCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "
|
|
2808
|
+
toolCount !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-muted-foreground"), children: [
|
|
2602
2809
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3" }),
|
|
2603
2810
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: toolCount })
|
|
2604
2811
|
] }),
|
|
2605
2812
|
log.origin !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2606
2813
|
"span",
|
|
2607
2814
|
{
|
|
2608
|
-
className: "hidden
|
|
2815
|
+
className: cn(TELEMETRY_CHIP_CLASS, "hidden shrink-0 text-muted-foreground xl:flex"),
|
|
2609
2816
|
title: `Origin: ${log.origin}`,
|
|
2610
2817
|
children: [
|
|
2611
2818
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Globe, { className: "size-3" }),
|
|
@@ -2614,7 +2821,7 @@ const LogEntryHeader = reactExports.memo(function({
|
|
|
2614
2821
|
}
|
|
2615
2822
|
),
|
|
2616
2823
|
(hasClientPid || hasClientProjectFolder) && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2617
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden
|
|
2824
|
+
/* @__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
2825
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FileTerminal, { className: "size-3" }),
|
|
2619
2826
|
hasClientProjectFolder ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: log.clientProjectFolder }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
2620
2827
|
"PID ",
|
|
@@ -2740,365 +2947,6 @@ function CollapsibleContent({
|
|
|
2740
2947
|
}) {
|
|
2741
2948
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent$1, { "data-slot": "collapsible-content", ...props });
|
|
2742
2949
|
}
|
|
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
2950
|
function ScrollArea({
|
|
3103
2951
|
className,
|
|
3104
2952
|
children,
|
|
@@ -3253,10 +3101,16 @@ function ToolRow({ tool, called }) {
|
|
|
3253
3101
|
}
|
|
3254
3102
|
)
|
|
3255
3103
|
] }),
|
|
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: [
|
|
3104
|
+
/* @__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
3105
|
tool.description !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs leading-relaxed text-muted-foreground", children: tool.description }),
|
|
3258
3106
|
/* @__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(
|
|
3107
|
+
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(
|
|
3108
|
+
reactExports.Suspense,
|
|
3109
|
+
{
|
|
3110
|
+
fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "Loading JSON..." }),
|
|
3111
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyJsonViewer, { data: safeJsonValue(tool.schema), defaultExpandDepth: 0 })
|
|
3112
|
+
}
|
|
3113
|
+
) })
|
|
3260
3114
|
] }) })
|
|
3261
3115
|
] }) });
|
|
3262
3116
|
}
|
|
@@ -3369,26 +3223,6 @@ const RequestTools = reactExports.memo(function RequestTools2({
|
|
|
3369
3223
|
] })
|
|
3370
3224
|
] });
|
|
3371
3225
|
});
|
|
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
3226
|
function shouldShowRawRequestTab(apiFormat, viewMode, strip) {
|
|
3393
3227
|
return apiFormat === "anthropic" && viewMode === "full" && strip;
|
|
3394
3228
|
}
|
|
@@ -3500,10 +3334,12 @@ function parseAnthropicTool(tool) {
|
|
|
3500
3334
|
}
|
|
3501
3335
|
function parseOpenAITool(tool) {
|
|
3502
3336
|
const fn = safeGetOwnProperty(tool, "function");
|
|
3503
|
-
const
|
|
3337
|
+
const toolType = safeGetOwnProperty(tool, "type");
|
|
3338
|
+
if (fn === void 0 && toolType !== "function") return null;
|
|
3339
|
+
const name = safeGetOwnProperty(fn, "name") ?? safeGetOwnProperty(tool, "name");
|
|
3504
3340
|
if (typeof name !== "string" || name.length === 0) return null;
|
|
3505
|
-
const description = safeGetOwnProperty(fn, "description");
|
|
3506
|
-
const schema = safeGetOwnProperty(fn, "parameters") ?? null;
|
|
3341
|
+
const description = safeGetOwnProperty(fn, "description") ?? safeGetOwnProperty(tool, "description");
|
|
3342
|
+
const schema = safeGetOwnProperty(fn, "parameters") ?? safeGetOwnProperty(tool, "parameters") ?? null;
|
|
3507
3343
|
const normalizedDescription = typeof description === "string" ? description : null;
|
|
3508
3344
|
return {
|
|
3509
3345
|
name,
|
|
@@ -3576,7 +3412,7 @@ const FULL_LOG_HYDRATION_TIMEOUT_MS = 15e3;
|
|
|
3576
3412
|
const BODY_CHUNK_TIMEOUT_MS = 15e3;
|
|
3577
3413
|
const BODY_CHUNK_BYTES = 256 * 1024;
|
|
3578
3414
|
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.
|
|
3415
|
+
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
3416
|
function createEmptyBodyPreviewState(totalBytes = null) {
|
|
3581
3417
|
return {
|
|
3582
3418
|
status: "idle",
|
|
@@ -3627,7 +3463,7 @@ function ExpandedPanel({
|
|
|
3627
3463
|
"div",
|
|
3628
3464
|
{
|
|
3629
3465
|
className: cn(
|
|
3630
|
-
"inspector-scrollbar mx-3 mb-3 max-h-[72vh] overflow-auto rounded-md border border-
|
|
3466
|
+
"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
3467
|
className
|
|
3632
3468
|
),
|
|
3633
3469
|
children
|
|
@@ -3786,6 +3622,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
3786
3622
|
);
|
|
3787
3623
|
const requestJsonRef = reactExports.useRef(null);
|
|
3788
3624
|
const logIdRef = reactExports.useRef(log.id);
|
|
3625
|
+
const bodyHydrationInFlightRef = reactExports.useRef(false);
|
|
3789
3626
|
const displayLog = hydratedLog ?? log;
|
|
3790
3627
|
const useChunkedBody = hydratedLog === null && shouldUseChunkedBodyLoading(log);
|
|
3791
3628
|
const requestPreviewBody = bodyPreviewTextForView(useChunkedBody, requestPreview);
|
|
@@ -3817,10 +3654,10 @@ const LogEntry = reactExports.memo(function({
|
|
|
3817
3654
|
requestPreviewShouldParse ? displayedRequestBody : null
|
|
3818
3655
|
);
|
|
3819
3656
|
const rawRequestExpansion = useJsonBulkExpansion(
|
|
3820
|
-
requestPreviewShouldParse ? rawRequestBodyForView : null
|
|
3657
|
+
activeTab === "raw-request" && requestPreviewShouldParse ? rawRequestBodyForView : null
|
|
3821
3658
|
);
|
|
3822
3659
|
const responseExpansion = useJsonBulkExpansion(
|
|
3823
|
-
responsePreviewShouldParse ? responseTextForView : null
|
|
3660
|
+
activeTab === "raw" && responsePreviewShouldParse ? responseTextForView : null
|
|
3824
3661
|
);
|
|
3825
3662
|
const headersText = reactExports.useMemo(
|
|
3826
3663
|
() => displayLog.headers && Object.keys(displayLog.headers).length > 0 ? JSON.stringify(displayLog.headers, null, 2) : null,
|
|
@@ -3993,6 +3830,7 @@ const LogEntry = reactExports.memo(function({
|
|
|
3993
3830
|
}, [anatomySegments, expanded]);
|
|
3994
3831
|
reactExports.useEffect(() => {
|
|
3995
3832
|
logIdRef.current = log.id;
|
|
3833
|
+
bodyHydrationInFlightRef.current = false;
|
|
3996
3834
|
setHydratedLog(null);
|
|
3997
3835
|
setBodyHydrationState("idle");
|
|
3998
3836
|
setRequestPreview(createEmptyBodyPreviewState(log.rawRequestBodyBytes ?? null));
|
|
@@ -4001,8 +3839,9 @@ const LogEntry = reactExports.memo(function({
|
|
|
4001
3839
|
reactExports.useEffect(() => {
|
|
4002
3840
|
if (!expanded) return;
|
|
4003
3841
|
if (!shouldHydrateLogBody(log)) return;
|
|
4004
|
-
if (hydratedLog !== null ||
|
|
3842
|
+
if (hydratedLog !== null || bodyHydrationInFlightRef.current) return;
|
|
4005
3843
|
let cancelled = false;
|
|
3844
|
+
bodyHydrationInFlightRef.current = true;
|
|
4006
3845
|
setBodyHydrationState("loading");
|
|
4007
3846
|
void fetchJsonWithTimeout(
|
|
4008
3847
|
`/api/logs/${String(log.id)}`,
|
|
@@ -4010,17 +3849,19 @@ const LogEntry = reactExports.memo(function({
|
|
|
4010
3849
|
FULL_LOG_HYDRATION_TIMEOUT_MS
|
|
4011
3850
|
).then((fullLog) => {
|
|
4012
3851
|
if (cancelled) return;
|
|
3852
|
+
bodyHydrationInFlightRef.current = false;
|
|
4013
3853
|
setHydratedLog(fullLog);
|
|
4014
3854
|
setBodyHydrationState("idle");
|
|
4015
3855
|
}).catch(() => {
|
|
4016
3856
|
if (cancelled) return;
|
|
3857
|
+
bodyHydrationInFlightRef.current = false;
|
|
4017
3858
|
setBodyHydrationState("failed");
|
|
4018
3859
|
});
|
|
4019
3860
|
return () => {
|
|
4020
3861
|
cancelled = true;
|
|
3862
|
+
bodyHydrationInFlightRef.current = false;
|
|
4021
3863
|
};
|
|
4022
3864
|
}, [
|
|
4023
|
-
bodyHydrationState,
|
|
4024
3865
|
expanded,
|
|
4025
3866
|
hydratedLog,
|
|
4026
3867
|
log.bodyContentMode,
|
|
@@ -4060,10 +3901,27 @@ const LogEntry = reactExports.memo(function({
|
|
|
4060
3901
|
"div",
|
|
4061
3902
|
{
|
|
4062
3903
|
className: cn(
|
|
4063
|
-
"mb-2 overflow-hidden rounded-
|
|
4064
|
-
expanded ? "border-cyan-300/
|
|
3904
|
+
"relative mb-2 overflow-hidden rounded-lg border bg-[#07090d] transition-[background-color,border-color,box-shadow]",
|
|
3905
|
+
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
3906
|
),
|
|
4066
3907
|
children: [
|
|
3908
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3909
|
+
"div",
|
|
3910
|
+
{
|
|
3911
|
+
className: cn(
|
|
3912
|
+
"pointer-events-none absolute inset-y-3 left-1 w-px rounded-full",
|
|
3913
|
+
expanded ? "bg-cyan-300/45 shadow-[0_0_20px_rgba(103,232,249,0.28)]" : "bg-white/10"
|
|
3914
|
+
),
|
|
3915
|
+
"aria-hidden": "true"
|
|
3916
|
+
}
|
|
3917
|
+
),
|
|
3918
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3919
|
+
"div",
|
|
3920
|
+
{
|
|
3921
|
+
className: "pointer-events-none absolute inset-x-3 top-0 h-px bg-gradient-to-r from-transparent via-white/15 to-transparent",
|
|
3922
|
+
"aria-hidden": "true"
|
|
3923
|
+
}
|
|
3924
|
+
),
|
|
4067
3925
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4068
3926
|
LogEntryHeader,
|
|
4069
3927
|
{
|
|
@@ -4082,186 +3940,195 @@ const LogEntry = reactExports.memo(function({
|
|
|
4082
3940
|
}
|
|
4083
3941
|
}
|
|
4084
3942
|
),
|
|
4085
|
-
expanded && /* @__PURE__ */ jsxRuntimeExports.
|
|
3943
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4086
3944
|
"div",
|
|
4087
3945
|
{
|
|
4088
|
-
className: "border-t border-
|
|
3946
|
+
className: "relative border-t border-cyan-300/10 bg-[linear-gradient(180deg,#06090d_0%,#040506_100%)] pt-2",
|
|
4089
3947
|
onClick: (e) => e.stopPropagation(),
|
|
4090
3948
|
onKeyDown: (e) => e.stopPropagation(),
|
|
4091
|
-
children:
|
|
4092
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
4093
|
-
|
|
3949
|
+
children: [
|
|
3950
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3951
|
+
"div",
|
|
4094
3952
|
{
|
|
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
|
-
]
|
|
3953
|
+
className: "pointer-events-none absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-cyan-300/[0.035] to-transparent",
|
|
3954
|
+
"aria-hidden": "true"
|
|
4106
3955
|
}
|
|
4107
3956
|
),
|
|
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,
|
|
3957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "gap-2", children: [
|
|
3958
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3959
|
+
TabsList,
|
|
4132
3960
|
{
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
3961
|
+
variant: "line",
|
|
3962
|
+
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",
|
|
3963
|
+
children: [
|
|
3964
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-headers", children: "Raw Headers" }),
|
|
3965
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "headers", children: "Headers" }),
|
|
3966
|
+
anatomySegments !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "anatomy", children: "Context" }),
|
|
3967
|
+
shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-request", children: "Raw Request" }),
|
|
3968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "request", children: "Request" }),
|
|
3969
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw", children: "Raw Response" }),
|
|
3970
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "parsed", children: "Response" })
|
|
3971
|
+
]
|
|
4137
3972
|
}
|
|
4138
3973
|
),
|
|
4139
|
-
|
|
4140
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
4141
|
-
|
|
4142
|
-
|
|
3974
|
+
shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-request", children: activeTab === "raw-request" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
3975
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3976
|
+
BodyPreviewNotice,
|
|
3977
|
+
{
|
|
3978
|
+
label: "Request",
|
|
3979
|
+
state: requestPreview,
|
|
3980
|
+
expectedBytes: log.rawRequestBodyBytes ?? null,
|
|
3981
|
+
onLoadMore: () => loadBodyChunk("request", requestPreview.offset)
|
|
3982
|
+
}
|
|
3983
|
+
),
|
|
3984
|
+
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(
|
|
3985
|
+
LazyJsonViewer,
|
|
3986
|
+
{
|
|
3987
|
+
data: rawRequestExpansion.parsedData,
|
|
3988
|
+
bulkDepth: rawRequestExpansion.bulkDepth,
|
|
3989
|
+
bulkRevision: rawRequestExpansion.bulkRevision
|
|
3990
|
+
}
|
|
3991
|
+
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: rawRequestBodyForView })
|
|
3992
|
+
] }) }),
|
|
3993
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "request", children: activeTab === "request" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
3994
|
+
bodyHydrationState === "loading" && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "loading", children: "Loading full request and response bodies..." }),
|
|
3995
|
+
bodyHydrationState === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsx(NoticeBlock, { tone: "warning", children: "Full request and response bodies could not be loaded. Compact metadata is still available." }),
|
|
3996
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3997
|
+
BodyPreviewNotice,
|
|
3998
|
+
{
|
|
3999
|
+
label: "Request",
|
|
4000
|
+
state: requestPreview,
|
|
4001
|
+
expectedBytes: log.rawRequestBodyBytes ?? null,
|
|
4002
|
+
onLoadMore: () => loadBodyChunk("request", requestPreview.offset)
|
|
4003
|
+
}
|
|
4004
|
+
),
|
|
4005
|
+
warnings.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(NoticeBlock, { tone: "warning", children: [
|
|
4006
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 font-semibold text-amber-300", children: [
|
|
4007
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3.5" }),
|
|
4008
|
+
"Tool schema warnings"
|
|
4009
|
+
] }),
|
|
4010
|
+
/* @__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
4011
|
] }),
|
|
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);
|
|
4012
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4013
|
+
RequestTools,
|
|
4014
|
+
{
|
|
4015
|
+
summary: requestTools,
|
|
4016
|
+
calledToolNames: responseAnalysis.toolNames ?? []
|
|
4192
4017
|
}
|
|
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,
|
|
4018
|
+
),
|
|
4019
|
+
requestDiff ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4020
|
+
RequestDiffContent,
|
|
4021
|
+
{
|
|
4022
|
+
rawBody: displayLog.rawRequestBody,
|
|
4023
|
+
displayedBody: displayedRequestBody,
|
|
4024
|
+
emptyLabel: "No transformation applied; raw and sent request bodies are identical."
|
|
4025
|
+
}
|
|
4026
|
+
) : /* @__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(
|
|
4027
|
+
LazyJsonViewer,
|
|
4028
|
+
{
|
|
4029
|
+
data: requestExpansion.parsedData,
|
|
4030
|
+
bulkDepth: requestExpansion.bulkDepth,
|
|
4031
|
+
bulkRevision: requestExpansion.bulkRevision,
|
|
4032
|
+
anatomyPaths,
|
|
4033
|
+
expandToPath
|
|
4034
|
+
}
|
|
4035
|
+
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: displayedRequestBody }) })
|
|
4036
|
+
] }) }),
|
|
4037
|
+
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(
|
|
4038
|
+
LazyRequestAnatomy,
|
|
4242
4039
|
{
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4040
|
+
parsed: requestExpansion.parsedData,
|
|
4041
|
+
inputTokens: displayLog.inputTokens ?? null,
|
|
4042
|
+
model: displayLog.model,
|
|
4043
|
+
segments: anatomySegments,
|
|
4044
|
+
onSegmentActivate: jumpToAnatomySegment
|
|
4247
4045
|
}
|
|
4248
|
-
),
|
|
4249
|
-
|
|
4250
|
-
|
|
4046
|
+
) }) }) }),
|
|
4047
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "headers", children: activeTab === "headers" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4048
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end gap-2 mb-2", children: shouldShowHeadersDiffButton(
|
|
4049
|
+
viewMode,
|
|
4050
|
+
displayLog.rawHeaders !== void 0 && Object.keys(displayLog.rawHeaders).length > 0
|
|
4051
|
+
) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4052
|
+
DiffToggleButton,
|
|
4053
|
+
{
|
|
4054
|
+
active: headersDiff,
|
|
4055
|
+
onClick: (e) => {
|
|
4056
|
+
e.stopPropagation();
|
|
4057
|
+
setHeadersDiff(!headersDiff);
|
|
4058
|
+
}
|
|
4059
|
+
}
|
|
4060
|
+
) }),
|
|
4061
|
+
headersDiff ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4062
|
+
HeadersDiffContent,
|
|
4063
|
+
{
|
|
4064
|
+
rawHeaders: displayLog.rawHeaders,
|
|
4065
|
+
headers: displayLog.headers,
|
|
4066
|
+
emptyLabel: "No transformation applied; raw and processed headers are identical."
|
|
4067
|
+
}
|
|
4068
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(HeaderRows, { headers: displayLog.headers, emptyLabel: "No headers captured" })
|
|
4069
|
+
] }) }),
|
|
4070
|
+
viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-headers", children: activeTab === "raw-headers" && /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandedPanel, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4071
|
+
HeaderRows,
|
|
4251
4072
|
{
|
|
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
|
|
4073
|
+
headers: displayLog.rawHeaders,
|
|
4074
|
+
emptyLabel: "No raw headers captured"
|
|
4261
4075
|
}
|
|
4262
|
-
) })
|
|
4263
|
-
|
|
4264
|
-
|
|
4076
|
+
) }) }),
|
|
4077
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw", children: activeTab === "raw" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { className: "space-y-3", children: [
|
|
4078
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4079
|
+
BodyPreviewNotice,
|
|
4080
|
+
{
|
|
4081
|
+
label: "Response",
|
|
4082
|
+
state: responsePreview,
|
|
4083
|
+
expectedBytes: log.responseTextBytes ?? null,
|
|
4084
|
+
onLoadMore: () => loadBodyChunk("response", responsePreview.offset)
|
|
4085
|
+
}
|
|
4086
|
+
),
|
|
4087
|
+
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 }) }),
|
|
4088
|
+
responseTextForView !== null && responsePreviewShouldParse ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4089
|
+
LazyJsonViewerFromString,
|
|
4090
|
+
{
|
|
4091
|
+
text: responseTextForView,
|
|
4092
|
+
defaultExpandDepth: 0,
|
|
4093
|
+
bulkDepth: responseExpansion.bulkDepth,
|
|
4094
|
+
bulkRevision: responseExpansion.bulkRevision
|
|
4095
|
+
}
|
|
4096
|
+
) }) : responseTextForView !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: responseTextForView }) : /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: useChunkedBody ? "Response preview is loading" : "No response" }),
|
|
4097
|
+
displayLog.streaming === true && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4098
|
+
LazyStreamingChunkSequence,
|
|
4099
|
+
{
|
|
4100
|
+
logId: displayLog.id,
|
|
4101
|
+
truncated: displayLog.streamingChunksPath !== null
|
|
4102
|
+
}
|
|
4103
|
+
) })
|
|
4104
|
+
] }) }),
|
|
4105
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "parsed", children: activeTab === "parsed" && /* @__PURE__ */ jsxRuntimeExports.jsxs(ExpandedPanel, { children: [
|
|
4106
|
+
useChunkedBody && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4107
|
+
BodyPreviewNotice,
|
|
4108
|
+
{
|
|
4109
|
+
label: "Response",
|
|
4110
|
+
state: responsePreview,
|
|
4111
|
+
expectedBytes: log.responseTextBytes ?? null,
|
|
4112
|
+
onLoadMore: () => loadBodyChunk("response", responsePreview.offset)
|
|
4113
|
+
}
|
|
4114
|
+
),
|
|
4115
|
+
responsePreviewIsActive && !responsePreviewShouldParse ? /* @__PURE__ */ jsxRuntimeExports.jsx(RawTextBlock, { children: responseTextForView }) : /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4116
|
+
LazyResponseView,
|
|
4117
|
+
{
|
|
4118
|
+
responseText: responseTextForView,
|
|
4119
|
+
responseStatus: displayLog.responseStatus,
|
|
4120
|
+
streaming: displayLog.streaming,
|
|
4121
|
+
inputTokens: displayLog.inputTokens,
|
|
4122
|
+
outputTokens: displayLog.outputTokens,
|
|
4123
|
+
cacheCreationInputTokens: displayLog.cacheCreationInputTokens,
|
|
4124
|
+
cacheReadInputTokens: displayLog.cacheReadInputTokens,
|
|
4125
|
+
apiFormat: resolvedFormat,
|
|
4126
|
+
error: displayLog.error
|
|
4127
|
+
}
|
|
4128
|
+
) })
|
|
4129
|
+
] }) })
|
|
4130
|
+
] })
|
|
4131
|
+
]
|
|
4265
4132
|
}
|
|
4266
4133
|
)
|
|
4267
4134
|
]
|
|
@@ -4383,6 +4250,19 @@ function ToolTraceEvents({ events }) {
|
|
|
4383
4250
|
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
4251
|
}
|
|
4385
4252
|
const PREVIEW_LIMIT = 180;
|
|
4253
|
+
const toolTraceCache = /* @__PURE__ */ new WeakMap();
|
|
4254
|
+
function responseMayContainToolTrace(log, format) {
|
|
4255
|
+
const responseText = log.responseText;
|
|
4256
|
+
if (responseText === null) return false;
|
|
4257
|
+
switch (format) {
|
|
4258
|
+
case "anthropic":
|
|
4259
|
+
return responseText.includes("tool_use");
|
|
4260
|
+
case "openai":
|
|
4261
|
+
return responseText.includes("tool_calls") || responseText.includes("function_call");
|
|
4262
|
+
case "unknown":
|
|
4263
|
+
return false;
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4386
4266
|
function shouldRenderConversationContent(standalone, expanded) {
|
|
4387
4267
|
return standalone || expanded;
|
|
4388
4268
|
}
|
|
@@ -4494,18 +4374,59 @@ function extractOpenAIToolTraceEvents(log) {
|
|
|
4494
4374
|
});
|
|
4495
4375
|
}
|
|
4496
4376
|
}
|
|
4377
|
+
const output = safeGetOwnProperty(parsed, "output");
|
|
4378
|
+
if (Array.isArray(output)) {
|
|
4379
|
+
for (const item of output) {
|
|
4380
|
+
if (safeGetOwnProperty(item, "type") !== "function_call") continue;
|
|
4381
|
+
const name = safeGetOwnProperty(item, "name");
|
|
4382
|
+
if (typeof name !== "string" || name.length === 0) continue;
|
|
4383
|
+
const args = safeGetOwnProperty(item, "arguments");
|
|
4384
|
+
events.push({
|
|
4385
|
+
id: `${String(log.id)}-openai-tool-${String(events.length)}`,
|
|
4386
|
+
logId: log.id,
|
|
4387
|
+
index: events.length,
|
|
4388
|
+
provider: "openai",
|
|
4389
|
+
name,
|
|
4390
|
+
argumentsText: copyValue(args),
|
|
4391
|
+
argumentsPreview: previewValue(args)
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
4497
4395
|
return events;
|
|
4498
4396
|
}
|
|
4499
4397
|
function extractToolTraceEvents(log) {
|
|
4398
|
+
const cached = toolTraceCache.get(log);
|
|
4399
|
+
if (cached !== void 0 && cached.apiFormat === log.apiFormat && cached.responseText === log.responseText) {
|
|
4400
|
+
return cached.events;
|
|
4401
|
+
}
|
|
4500
4402
|
const format = resolveLogFormat(log);
|
|
4403
|
+
if (!responseMayContainToolTrace(log, format)) {
|
|
4404
|
+
const events2 = [];
|
|
4405
|
+
toolTraceCache.set(log, {
|
|
4406
|
+
apiFormat: log.apiFormat,
|
|
4407
|
+
responseText: log.responseText,
|
|
4408
|
+
events: events2
|
|
4409
|
+
});
|
|
4410
|
+
return events2;
|
|
4411
|
+
}
|
|
4412
|
+
let events;
|
|
4501
4413
|
switch (format) {
|
|
4502
4414
|
case "anthropic":
|
|
4503
|
-
|
|
4415
|
+
events = extractAnthropicToolTraceEvents(log);
|
|
4416
|
+
break;
|
|
4504
4417
|
case "openai":
|
|
4505
|
-
|
|
4418
|
+
events = extractOpenAIToolTraceEvents(log);
|
|
4419
|
+
break;
|
|
4506
4420
|
case "unknown":
|
|
4507
|
-
|
|
4421
|
+
events = [];
|
|
4422
|
+
break;
|
|
4508
4423
|
}
|
|
4424
|
+
toolTraceCache.set(log, {
|
|
4425
|
+
apiFormat: log.apiFormat,
|
|
4426
|
+
responseText: log.responseText,
|
|
4427
|
+
events
|
|
4428
|
+
});
|
|
4429
|
+
return events;
|
|
4509
4430
|
}
|
|
4510
4431
|
function buildTraceSummary(logs, slowResponseThresholdSeconds, knowledgeCandidateCount = 0) {
|
|
4511
4432
|
let failedCallCount = 0;
|
|
@@ -4571,7 +4492,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4571
4492
|
onCompareWithPrevious,
|
|
4572
4493
|
comparisonPredecessors,
|
|
4573
4494
|
turnIndex = 0,
|
|
4574
|
-
timeDisplayFormat
|
|
4495
|
+
timeDisplayFormat,
|
|
4496
|
+
pendingFocusRequest
|
|
4575
4497
|
}) {
|
|
4576
4498
|
const lastIdx = entries.length - 1;
|
|
4577
4499
|
const lastStop = entries[lastIdx]?.stopReason ?? null;
|
|
@@ -4601,6 +4523,19 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4601
4523
|
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4602
4524
|
};
|
|
4603
4525
|
}, [collapsible, entries]);
|
|
4526
|
+
reactExports.useEffect(() => {
|
|
4527
|
+
if (pendingFocusRequest === void 0) return void 0;
|
|
4528
|
+
if (!entries.some((entry) => entry.log.id === pendingFocusRequest.logId)) return void 0;
|
|
4529
|
+
if (collapsible) setCollapsed(false);
|
|
4530
|
+
const timer = window.setTimeout(() => {
|
|
4531
|
+
dispatchLogFocusRequest({
|
|
4532
|
+
logId: pendingFocusRequest.logId,
|
|
4533
|
+
tab: pendingFocusRequest.tab,
|
|
4534
|
+
source: "virtualizer"
|
|
4535
|
+
});
|
|
4536
|
+
}, 0);
|
|
4537
|
+
return () => window.clearTimeout(timer);
|
|
4538
|
+
}, [collapsible, entries, pendingFocusRequest]);
|
|
4604
4539
|
const toggleCollapse = reactExports.useCallback(() => {
|
|
4605
4540
|
if (collapsible) setCollapsed((prev) => !prev);
|
|
4606
4541
|
}, [collapsible]);
|
|
@@ -4639,7 +4574,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4639
4574
|
}, [entries]);
|
|
4640
4575
|
const StartCrab = reactExports.useMemo(() => getCrabVariant(entries[0]?.log.id ?? 0), [entries]);
|
|
4641
4576
|
const EndCrab = reactExports.useMemo(() => getCrabVariant(entries[lastIdx]?.log.id ?? 0), [entries, lastIdx]);
|
|
4642
|
-
const bgClass = turnIndex % 2 === 0 ? "bg-
|
|
4577
|
+
const bgClass = turnIndex % 2 === 0 ? "bg-[#070a0f]" : "bg-[#090d12]";
|
|
4643
4578
|
const aggregateIsSlow = aggregate.maxElapsed !== null && slowResponseThresholdSeconds > 0 && aggregate.maxElapsed > slowResponseThresholdSeconds * 1e3;
|
|
4644
4579
|
const toolEventsByLogId = reactExports.useMemo(() => {
|
|
4645
4580
|
const events = /* @__PURE__ */ new Map();
|
|
@@ -4667,17 +4602,25 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4667
4602
|
}, []);
|
|
4668
4603
|
const firstLogId = entries[0]?.log.id ?? turnIndex;
|
|
4669
4604
|
const turnLabel = `Turn ${String(turnIndex + 1)}`;
|
|
4605
|
+
const containmentStyle = reactExports.useMemo(
|
|
4606
|
+
() => ({
|
|
4607
|
+
contentVisibility: "auto",
|
|
4608
|
+
containIntrinsicSize: collapsed ? "48px" : "160px"
|
|
4609
|
+
}),
|
|
4610
|
+
[collapsed]
|
|
4611
|
+
);
|
|
4670
4612
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4671
4613
|
"div",
|
|
4672
4614
|
{
|
|
4673
4615
|
ref: containerRef,
|
|
4616
|
+
style: containmentStyle,
|
|
4674
4617
|
tabIndex: collapsed ? void 0 : 0,
|
|
4675
4618
|
role: collapsed ? void 0 : "group",
|
|
4676
4619
|
"aria-label": collapsed ? void 0 : turnLabel,
|
|
4677
4620
|
"data-nav-id": collapsed ? void 0 : `turn-${String(firstLogId)}`,
|
|
4678
4621
|
className: cn(
|
|
4679
|
-
"border rounded-lg",
|
|
4680
|
-
isPending ? "border-amber-
|
|
4622
|
+
"border rounded-lg transition-[border-color,box-shadow]",
|
|
4623
|
+
isPending ? "border-amber-300/15 shadow-[0_0_0_1px_rgba(252,211,77,0.04)]" : "border-transparent",
|
|
4681
4624
|
!collapsed && "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
4682
4625
|
),
|
|
4683
4626
|
children: collapsed ? (
|
|
@@ -4763,7 +4706,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4763
4706
|
"div",
|
|
4764
4707
|
{
|
|
4765
4708
|
className: cn(
|
|
4766
|
-
"flex-1 min-w-0 mb-0.5 rounded-lg border border-
|
|
4709
|
+
"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
4710
|
bgClass
|
|
4768
4711
|
),
|
|
4769
4712
|
children: [
|
|
@@ -4861,6 +4804,103 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
|
4861
4804
|
}
|
|
4862
4805
|
);
|
|
4863
4806
|
});
|
|
4807
|
+
const VIRTUALIZE_TURN_THRESHOLD = 24;
|
|
4808
|
+
const ESTIMATED_TURN_HEIGHT = 132;
|
|
4809
|
+
const VIRTUAL_OVERSCAN$1 = 8;
|
|
4810
|
+
function shouldVirtualizeTurnGroups(turnCount) {
|
|
4811
|
+
return turnCount > VIRTUALIZE_TURN_THRESHOLD;
|
|
4812
|
+
}
|
|
4813
|
+
function buildLogTurnIndex(turnGroups) {
|
|
4814
|
+
const result = /* @__PURE__ */ new Map();
|
|
4815
|
+
for (let index = 0; index < turnGroups.length; index++) {
|
|
4816
|
+
const group = turnGroups[index];
|
|
4817
|
+
if (group === void 0) continue;
|
|
4818
|
+
for (const entry of group.entries) {
|
|
4819
|
+
result.set(entry.log.id, index);
|
|
4820
|
+
}
|
|
4821
|
+
}
|
|
4822
|
+
return result;
|
|
4823
|
+
}
|
|
4824
|
+
function renderTurnGroup(turnGroup, props, pendingFocusRequest) {
|
|
4825
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4826
|
+
TurnGroup,
|
|
4827
|
+
{
|
|
4828
|
+
entries: turnGroup.entries,
|
|
4829
|
+
viewMode: props.viewMode,
|
|
4830
|
+
strip: props.strip,
|
|
4831
|
+
slowResponseThresholdSeconds: props.slowResponseThresholdSeconds,
|
|
4832
|
+
timeDisplayFormat: props.timeDisplayFormat,
|
|
4833
|
+
cacheTrends: props.cacheTrends,
|
|
4834
|
+
onCompareWithPrevious: props.onCompareWithPrevious,
|
|
4835
|
+
comparisonPredecessors: props.comparisonPredecessors,
|
|
4836
|
+
turnIndex: turnGroup.turnIndex,
|
|
4837
|
+
pendingFocusRequest
|
|
4838
|
+
},
|
|
4839
|
+
turnGroup.turnIndex
|
|
4840
|
+
);
|
|
4841
|
+
}
|
|
4842
|
+
function TurnGroupList(props) {
|
|
4843
|
+
if (!shouldVirtualizeTurnGroups(props.turnGroups.length)) {
|
|
4844
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: props.turnGroups.map((turnGroup) => renderTurnGroup(turnGroup, props)) });
|
|
4845
|
+
}
|
|
4846
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(VirtualizedTurnGroupList, { ...props });
|
|
4847
|
+
}
|
|
4848
|
+
function VirtualizedTurnGroupList(props) {
|
|
4849
|
+
const { turnGroups } = props;
|
|
4850
|
+
const [pendingFocusRequest, setPendingFocusRequest] = reactExports.useState(
|
|
4851
|
+
null
|
|
4852
|
+
);
|
|
4853
|
+
const virtualizer = useWindowVirtualizer({
|
|
4854
|
+
count: turnGroups.length,
|
|
4855
|
+
estimateSize: () => ESTIMATED_TURN_HEIGHT,
|
|
4856
|
+
overscan: VIRTUAL_OVERSCAN$1,
|
|
4857
|
+
getItemKey: (index) => turnGroups[index]?.turnIndex ?? index
|
|
4858
|
+
});
|
|
4859
|
+
const turnIndexByLogId = reactExports.useMemo(() => buildLogTurnIndex(turnGroups), [turnGroups]);
|
|
4860
|
+
reactExports.useEffect(() => {
|
|
4861
|
+
const handleLogFocusRequest = (event) => {
|
|
4862
|
+
const request = readLogFocusRequest(event);
|
|
4863
|
+
if (request === null) return;
|
|
4864
|
+
if (request.source === "virtualizer") return;
|
|
4865
|
+
const turnIndex = turnIndexByLogId.get(request.logId);
|
|
4866
|
+
if (turnIndex === void 0) return;
|
|
4867
|
+
virtualizer.scrollToIndex(turnIndex, { align: "center" });
|
|
4868
|
+
setPendingFocusRequest((previous) => ({
|
|
4869
|
+
...request,
|
|
4870
|
+
turnIndex,
|
|
4871
|
+
nonce: previous === null ? 1 : previous.nonce + 1
|
|
4872
|
+
}));
|
|
4873
|
+
};
|
|
4874
|
+
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4875
|
+
return () => {
|
|
4876
|
+
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4877
|
+
};
|
|
4878
|
+
}, [turnIndexByLogId, virtualizer]);
|
|
4879
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4880
|
+
"div",
|
|
4881
|
+
{
|
|
4882
|
+
className: "relative w-full",
|
|
4883
|
+
style: { height: `${virtualizer.getTotalSize()}px` },
|
|
4884
|
+
"data-virtualized-turn-list": "true",
|
|
4885
|
+
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
4886
|
+
const turnGroup = turnGroups[virtualItem.index];
|
|
4887
|
+
if (turnGroup === void 0) return null;
|
|
4888
|
+
const itemFocusRequest = pendingFocusRequest !== null && pendingFocusRequest.turnIndex === virtualItem.index ? pendingFocusRequest : void 0;
|
|
4889
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4890
|
+
"div",
|
|
4891
|
+
{
|
|
4892
|
+
"data-index": virtualItem.index,
|
|
4893
|
+
ref: virtualizer.measureElement,
|
|
4894
|
+
className: "absolute left-0 top-0 w-full",
|
|
4895
|
+
style: { transform: `translateY(${virtualItem.start}px)` },
|
|
4896
|
+
children: renderTurnGroup(turnGroup, props, itemFocusRequest)
|
|
4897
|
+
},
|
|
4898
|
+
virtualItem.key
|
|
4899
|
+
);
|
|
4900
|
+
})
|
|
4901
|
+
}
|
|
4902
|
+
);
|
|
4903
|
+
}
|
|
4864
4904
|
const CandidateResponseSchema = object({
|
|
4865
4905
|
candidates: array(KnowledgeCandidateSchema)
|
|
4866
4906
|
});
|
|
@@ -5703,21 +5743,19 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
5703
5743
|
timeDisplayFormat
|
|
5704
5744
|
}
|
|
5705
5745
|
),
|
|
5706
|
-
|
|
5707
|
-
|
|
5746
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5747
|
+
TurnGroupList,
|
|
5708
5748
|
{
|
|
5709
|
-
|
|
5749
|
+
turnGroups,
|
|
5710
5750
|
viewMode,
|
|
5711
5751
|
strip,
|
|
5712
5752
|
slowResponseThresholdSeconds,
|
|
5713
5753
|
timeDisplayFormat,
|
|
5714
5754
|
cacheTrends,
|
|
5715
5755
|
onCompareWithPrevious,
|
|
5716
|
-
comparisonPredecessors
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
tg.turnIndex
|
|
5720
|
-
))
|
|
5756
|
+
comparisonPredecessors
|
|
5757
|
+
}
|
|
5758
|
+
)
|
|
5721
5759
|
] })
|
|
5722
5760
|
] });
|
|
5723
5761
|
});
|
|
@@ -7449,6 +7487,7 @@ const ExternalProviderSchema = object({
|
|
|
7449
7487
|
format: _enum(["anthropic", "openai"]),
|
|
7450
7488
|
anthropicBaseUrl: string(),
|
|
7451
7489
|
openaiBaseUrl: string(),
|
|
7490
|
+
openaiResponsesBaseUrl: string().optional().default(""),
|
|
7452
7491
|
models: array(string()),
|
|
7453
7492
|
sourceTool: _enum(["claude-code", "opencode", "mimo-code"]),
|
|
7454
7493
|
alreadyExists: boolean()
|
|
@@ -7545,6 +7584,7 @@ function ImportWizardDialog({
|
|
|
7545
7584
|
format: p.format,
|
|
7546
7585
|
anthropicBaseUrl: p.anthropicBaseUrl,
|
|
7547
7586
|
openaiBaseUrl: p.openaiBaseUrl,
|
|
7587
|
+
openaiResponsesBaseUrl: p.openaiResponsesBaseUrl,
|
|
7548
7588
|
models: p.models,
|
|
7549
7589
|
createdAt: now,
|
|
7550
7590
|
updatedAt: now
|
|
@@ -7624,7 +7664,7 @@ function ImportWizardDialog({
|
|
|
7624
7664
|
p.models.slice(0, 4).join(", "),
|
|
7625
7665
|
p.models.length > 4 ? ` +${p.models.length - 4} more` : ""
|
|
7626
7666
|
] }),
|
|
7627
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: p.format === "anthropic" ? p.anthropicBaseUrl : p.openaiBaseUrl }),
|
|
7667
|
+
/* @__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
7668
|
/* @__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
7669
|
] })
|
|
7630
7670
|
]
|
|
@@ -8069,12 +8109,17 @@ function ProviderCard({
|
|
|
8069
8109
|
] }),
|
|
8070
8110
|
provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-col gap-2", children: [
|
|
8071
8111
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 text-xs text-muted-foreground", children: [
|
|
8072
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "OpenAI:" }),
|
|
8112
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "OpenAI Chat:" }),
|
|
8073
8113
|
" ",
|
|
8074
8114
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: provider.openaiBaseUrl })
|
|
8075
8115
|
] }),
|
|
8076
8116
|
testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.openai })
|
|
8077
8117
|
] }),
|
|
8118
|
+
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: [
|
|
8119
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "OpenAI Responses:" }),
|
|
8120
|
+
" ",
|
|
8121
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: provider.openaiResponsesBaseUrl })
|
|
8122
|
+
] }) }),
|
|
8078
8123
|
testResults?.testedAt !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-1", children: [
|
|
8079
8124
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
8080
8125
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
@@ -8166,12 +8211,17 @@ const ZHIPU_CODING_PROVIDER_KEYWORDS = [
|
|
|
8166
8211
|
"z.ai coding",
|
|
8167
8212
|
"zai coding"
|
|
8168
8213
|
];
|
|
8214
|
+
const ANTHROPIC_MESSAGES_ENDPOINT = "/v1/messages";
|
|
8215
|
+
const OPENAI_CHAT_COMPLETIONS_ENDPOINT = "/v1/chat/completions";
|
|
8216
|
+
const OPENAI_RESPONSES_ENDPOINT = "/v1/responses";
|
|
8169
8217
|
const KNOWN_PROVIDER_PRESETS = {
|
|
8170
8218
|
deepseek: {
|
|
8171
8219
|
openaiBaseUrl: "https://api.deepseek.com"
|
|
8172
8220
|
},
|
|
8173
8221
|
minimax: {
|
|
8174
8222
|
anthropicBaseUrl: "https://api.minimaxi.com/anthropic",
|
|
8223
|
+
openaiBaseUrl: "https://api.minimaxi.com",
|
|
8224
|
+
openaiResponsesBaseUrl: "https://api.minimaxi.com",
|
|
8175
8225
|
apiDocsUrl: "https://platform.minimaxi.com/docs/api-reference/api-overview"
|
|
8176
8226
|
},
|
|
8177
8227
|
"zhipu coding": {
|
|
@@ -8345,6 +8395,27 @@ function readPositiveIntegerInput(value) {
|
|
|
8345
8395
|
if (!Number.isInteger(parsed) || parsed <= 0) return null;
|
|
8346
8396
|
return parsed;
|
|
8347
8397
|
}
|
|
8398
|
+
function stripEndpointSuffix(value, endpoint) {
|
|
8399
|
+
if (value === void 0) return "";
|
|
8400
|
+
const trimmed = value.trim();
|
|
8401
|
+
const normalized = trimmed.replace(/\/+$/, "");
|
|
8402
|
+
return normalized.endsWith(endpoint) ? normalized.slice(0, -endpoint.length).replace(/\/+$/, "") : trimmed;
|
|
8403
|
+
}
|
|
8404
|
+
function previewEndpointUrl(baseUrl, endpoint) {
|
|
8405
|
+
const trimmed = baseUrl.trim();
|
|
8406
|
+
return trimmed === "" ? null : buildUpstreamUrl(trimmed, endpoint);
|
|
8407
|
+
}
|
|
8408
|
+
function EndpointUrlPreview({
|
|
8409
|
+
baseUrl,
|
|
8410
|
+
endpoint
|
|
8411
|
+
}) {
|
|
8412
|
+
const finalUrl = previewEndpointUrl(baseUrl, endpoint);
|
|
8413
|
+
if (finalUrl === null) return null;
|
|
8414
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border/70 bg-muted/35 px-3 py-2 text-xs", children: [
|
|
8415
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground", children: "Final URL" }),
|
|
8416
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "break-all font-mono text-foreground", children: finalUrl })
|
|
8417
|
+
] });
|
|
8418
|
+
}
|
|
8348
8419
|
function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
8349
8420
|
const [name, setName] = reactExports.useState(provider?.name ?? "");
|
|
8350
8421
|
const [apiKey, setApiKey] = reactExports.useState(provider?.apiKey ?? "");
|
|
@@ -8361,8 +8432,15 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8361
8432
|
)
|
|
8362
8433
|
);
|
|
8363
8434
|
const [activeTab, setActiveTab] = reactExports.useState("anthropic");
|
|
8364
|
-
const [anthropicBaseUrl, setAnthropicBaseUrl] = reactExports.useState(
|
|
8365
|
-
|
|
8435
|
+
const [anthropicBaseUrl, setAnthropicBaseUrl] = reactExports.useState(
|
|
8436
|
+
stripEndpointSuffix(provider?.anthropicBaseUrl, ANTHROPIC_MESSAGES_ENDPOINT)
|
|
8437
|
+
);
|
|
8438
|
+
const [openaiBaseUrl, setOpenaiBaseUrl] = reactExports.useState(
|
|
8439
|
+
stripEndpointSuffix(provider?.openaiBaseUrl, OPENAI_CHAT_COMPLETIONS_ENDPOINT)
|
|
8440
|
+
);
|
|
8441
|
+
const [openaiResponsesBaseUrl, setOpenaiResponsesBaseUrl] = reactExports.useState(
|
|
8442
|
+
stripEndpointSuffix(provider?.openaiResponsesBaseUrl, OPENAI_RESPONSES_ENDPOINT)
|
|
8443
|
+
);
|
|
8366
8444
|
const [apiDocsUrl, setApiDocsUrl] = reactExports.useState(provider?.apiDocsUrl ?? "");
|
|
8367
8445
|
const [modelMetadataUrl, setModelMetadataUrl] = reactExports.useState(provider?.modelMetadataUrl ?? "");
|
|
8368
8446
|
const [source, setSource] = reactExports.useState(provider?.source);
|
|
@@ -8385,6 +8463,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8385
8463
|
}, [openModelDropdown]);
|
|
8386
8464
|
const [manualAnthropicUrlOverride, setManualAnthropicUrlOverride] = reactExports.useState(false);
|
|
8387
8465
|
const [manualOpenaiUrlOverride, setManualOpenaiUrlOverride] = reactExports.useState(false);
|
|
8466
|
+
const [manualOpenaiResponsesUrlOverride, setManualOpenaiResponsesUrlOverride] = reactExports.useState(false);
|
|
8388
8467
|
const isMiniMax = name.toLowerCase().includes("minimax");
|
|
8389
8468
|
const isAlibaba = name.toLowerCase().includes("alibaba");
|
|
8390
8469
|
const isZhipu = [...ZHIPU_PROVIDER_KEYWORDS, ...ZHIPU_CODING_PROVIDER_KEYWORDS].some(
|
|
@@ -8406,13 +8485,21 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8406
8485
|
const nextModels = (provider.models?.length ?? 0) > 0 ? provider.models : [""];
|
|
8407
8486
|
setModels(nextModels);
|
|
8408
8487
|
setModelMetadataDrafts(createMetadataDrafts(provider, nextModels));
|
|
8409
|
-
setAnthropicBaseUrl(
|
|
8410
|
-
|
|
8488
|
+
setAnthropicBaseUrl(
|
|
8489
|
+
stripEndpointSuffix(provider.anthropicBaseUrl, ANTHROPIC_MESSAGES_ENDPOINT)
|
|
8490
|
+
);
|
|
8491
|
+
setOpenaiBaseUrl(
|
|
8492
|
+
stripEndpointSuffix(provider.openaiBaseUrl, OPENAI_CHAT_COMPLETIONS_ENDPOINT)
|
|
8493
|
+
);
|
|
8494
|
+
setOpenaiResponsesBaseUrl(
|
|
8495
|
+
stripEndpointSuffix(provider.openaiResponsesBaseUrl, OPENAI_RESPONSES_ENDPOINT)
|
|
8496
|
+
);
|
|
8411
8497
|
setApiDocsUrl(provider.apiDocsUrl ?? "");
|
|
8412
8498
|
setModelMetadataUrl(provider.modelMetadataUrl ?? "");
|
|
8413
8499
|
setSource(provider.source);
|
|
8414
8500
|
setManualAnthropicUrlOverride(false);
|
|
8415
8501
|
setManualOpenaiUrlOverride(false);
|
|
8502
|
+
setManualOpenaiResponsesUrlOverride(false);
|
|
8416
8503
|
}
|
|
8417
8504
|
}, [provider]);
|
|
8418
8505
|
reactExports.useEffect(() => {
|
|
@@ -8425,6 +8512,9 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8425
8512
|
if (preset.openaiBaseUrl !== void 0 && !manualOpenaiUrlOverride) {
|
|
8426
8513
|
setOpenaiBaseUrl(preset.openaiBaseUrl);
|
|
8427
8514
|
}
|
|
8515
|
+
if (preset.openaiResponsesBaseUrl !== void 0 && !manualOpenaiResponsesUrlOverride) {
|
|
8516
|
+
setOpenaiResponsesBaseUrl(preset.openaiResponsesBaseUrl);
|
|
8517
|
+
}
|
|
8428
8518
|
if (preset.apiDocsUrl !== void 0 && !apiDocsUrl) {
|
|
8429
8519
|
setApiDocsUrl(preset.apiDocsUrl);
|
|
8430
8520
|
}
|
|
@@ -8458,6 +8548,9 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8458
8548
|
if (openaiBaseUrl.trim() && !isValidUrl(openaiBaseUrl.trim())) {
|
|
8459
8549
|
newErrors.openaiBaseUrl = "Invalid URL format";
|
|
8460
8550
|
}
|
|
8551
|
+
if (openaiResponsesBaseUrl.trim() && !isValidUrl(openaiResponsesBaseUrl.trim())) {
|
|
8552
|
+
newErrors.openaiResponsesBaseUrl = "Invalid URL format";
|
|
8553
|
+
}
|
|
8461
8554
|
if (modelMetadataUrl.trim() && !isValidUrl(modelMetadataUrl.trim())) {
|
|
8462
8555
|
newErrors.modelMetadataUrl = "Invalid URL format";
|
|
8463
8556
|
}
|
|
@@ -8474,7 +8567,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8474
8567
|
newErrors[`modelMetadata.${index}.outputLimit`] = "Output limit should not exceed context window";
|
|
8475
8568
|
}
|
|
8476
8569
|
});
|
|
8477
|
-
if (!anthropicBaseUrl.trim() && !openaiBaseUrl.trim()) {
|
|
8570
|
+
if (!anthropicBaseUrl.trim() && !openaiBaseUrl.trim() && !openaiResponsesBaseUrl.trim()) {
|
|
8478
8571
|
newErrors.format = "At least one format URL (Anthropic or OpenAI) is required";
|
|
8479
8572
|
}
|
|
8480
8573
|
setErrors(newErrors);
|
|
@@ -8590,6 +8683,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8590
8683
|
models: models.map((m) => m.trim()).filter((m) => m !== ""),
|
|
8591
8684
|
anthropicBaseUrl: anthropicBaseUrl.trim() || void 0,
|
|
8592
8685
|
openaiBaseUrl: openaiBaseUrl.trim() || void 0,
|
|
8686
|
+
openaiResponsesBaseUrl: openaiResponsesBaseUrl.trim() || void 0,
|
|
8593
8687
|
apiDocsUrl: apiDocsUrl.trim() || void 0,
|
|
8594
8688
|
modelMetadataUrl: modelMetadataUrl.trim() || void 0,
|
|
8595
8689
|
modelMetadata: buildModelMetadata(),
|
|
@@ -8902,41 +8996,86 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
8902
8996
|
] }),
|
|
8903
8997
|
activeTab === "anthropic" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
8904
8998
|
/* @__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
|
-
|
|
8999
|
+
/* @__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: [
|
|
9000
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9001
|
+
"input",
|
|
9002
|
+
{
|
|
9003
|
+
id: "provider-anthropic-base-url",
|
|
9004
|
+
type: "text",
|
|
9005
|
+
value: anthropicBaseUrl,
|
|
9006
|
+
onChange: (e) => {
|
|
9007
|
+
setManualAnthropicUrlOverride(true);
|
|
9008
|
+
setAnthropicBaseUrl(e.target.value);
|
|
9009
|
+
},
|
|
9010
|
+
placeholder: "https://api.anthropic.com",
|
|
9011
|
+
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"
|
|
9012
|
+
}
|
|
9013
|
+
),
|
|
9014
|
+
/* @__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 })
|
|
9015
|
+
] }),
|
|
8919
9016
|
errors.anthropicBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.anthropicBaseUrl }),
|
|
8920
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9017
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(EndpointUrlPreview, { baseUrl: anthropicBaseUrl, endpoint: ANTHROPIC_MESSAGES_ENDPOINT }),
|
|
9018
|
+
/* @__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
9019
|
] }),
|
|
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
|
-
|
|
9020
|
+
activeTab === "openai" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
9021
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9022
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-base-url", className: "text-sm font-medium", children: "OpenAI Chat Base URL" }),
|
|
9023
|
+
/* @__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: [
|
|
9024
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9025
|
+
"input",
|
|
9026
|
+
{
|
|
9027
|
+
id: "provider-openai-base-url",
|
|
9028
|
+
type: "text",
|
|
9029
|
+
value: openaiBaseUrl,
|
|
9030
|
+
onChange: (e) => {
|
|
9031
|
+
setManualOpenaiUrlOverride(true);
|
|
9032
|
+
setOpenaiBaseUrl(e.target.value);
|
|
9033
|
+
},
|
|
9034
|
+
placeholder: "https://api.openai.com",
|
|
9035
|
+
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"
|
|
9036
|
+
}
|
|
9037
|
+
),
|
|
9038
|
+
/* @__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 })
|
|
9039
|
+
] }),
|
|
9040
|
+
errors.openaiBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiBaseUrl }),
|
|
9041
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9042
|
+
EndpointUrlPreview,
|
|
9043
|
+
{
|
|
9044
|
+
baseUrl: openaiBaseUrl,
|
|
9045
|
+
endpoint: OPENAI_CHAT_COMPLETIONS_ENDPOINT
|
|
9046
|
+
}
|
|
9047
|
+
),
|
|
9048
|
+
/* @__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." })
|
|
9049
|
+
] }),
|
|
9050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9051
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-responses-base-url", className: "text-sm font-medium", children: "OpenAI Responses Base URL" }),
|
|
9052
|
+
/* @__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: [
|
|
9053
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9054
|
+
"input",
|
|
9055
|
+
{
|
|
9056
|
+
id: "provider-openai-responses-base-url",
|
|
9057
|
+
type: "text",
|
|
9058
|
+
value: openaiResponsesBaseUrl,
|
|
9059
|
+
onChange: (e) => {
|
|
9060
|
+
setManualOpenaiResponsesUrlOverride(true);
|
|
9061
|
+
setOpenaiResponsesBaseUrl(e.target.value);
|
|
9062
|
+
},
|
|
9063
|
+
placeholder: "https://api.openai.com",
|
|
9064
|
+
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"
|
|
9065
|
+
}
|
|
9066
|
+
),
|
|
9067
|
+
/* @__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 })
|
|
9068
|
+
] }),
|
|
9069
|
+
errors.openaiResponsesBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiResponsesBaseUrl }),
|
|
9070
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9071
|
+
EndpointUrlPreview,
|
|
9072
|
+
{
|
|
9073
|
+
baseUrl: openaiResponsesBaseUrl,
|
|
9074
|
+
endpoint: OPENAI_RESPONSES_ENDPOINT
|
|
9075
|
+
}
|
|
9076
|
+
),
|
|
9077
|
+
/* @__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." })
|
|
9078
|
+
] })
|
|
8940
9079
|
] }),
|
|
8941
9080
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
8942
9081
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-api-docs-url", className: "text-sm font-medium", children: "API Docs URL" }),
|
|
@@ -8983,6 +9122,7 @@ function createProviderPayload(data) {
|
|
|
8983
9122
|
models: data.models,
|
|
8984
9123
|
anthropicBaseUrl: (data.anthropicBaseUrl?.length ?? 0) > 0 ? data.anthropicBaseUrl : void 0,
|
|
8985
9124
|
openaiBaseUrl: (data.openaiBaseUrl?.length ?? 0) > 0 ? data.openaiBaseUrl : void 0,
|
|
9125
|
+
openaiResponsesBaseUrl: (data.openaiResponsesBaseUrl?.length ?? 0) > 0 ? data.openaiResponsesBaseUrl : void 0,
|
|
8986
9126
|
apiDocsUrl: (data.apiDocsUrl?.length ?? 0) > 0 ? data.apiDocsUrl : void 0,
|
|
8987
9127
|
modelMetadataUrl: (data.modelMetadataUrl?.length ?? 0) > 0 ? data.modelMetadataUrl : void 0,
|
|
8988
9128
|
modelMetadata: data.modelMetadata,
|
|
@@ -9272,7 +9412,7 @@ function ProvidersPanel({
|
|
|
9272
9412
|
await refreshProviderMetadata(updated.id, data.modelMetadataUrl, false);
|
|
9273
9413
|
}
|
|
9274
9414
|
refreshProviders();
|
|
9275
|
-
const criticalFieldsChanged = (data.apiKey ?? "") !== (editingProvider.apiKey ?? "") || JSON.stringify(data.models) !== JSON.stringify(editingProvider.models) || (data.anthropicBaseUrl ?? "") !== (editingProvider.anthropicBaseUrl ?? "") || (data.openaiBaseUrl ?? "") !== (editingProvider.openaiBaseUrl ?? "");
|
|
9415
|
+
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
9416
|
if (criticalFieldsChanged) {
|
|
9277
9417
|
await runTest(updated.id);
|
|
9278
9418
|
}
|
|
@@ -11259,6 +11399,13 @@ const CONTEXT_USAGE_THRESHOLDS = {
|
|
|
11259
11399
|
watch: WATCH_USAGE_PERCENT,
|
|
11260
11400
|
danger: DANGER_USAGE_PERCENT
|
|
11261
11401
|
};
|
|
11402
|
+
const snapshotCache = /* @__PURE__ */ new WeakMap();
|
|
11403
|
+
function providerSignature(providers) {
|
|
11404
|
+
return providers.map((provider) => {
|
|
11405
|
+
const metadata = provider.modelMetadata?.map((entry) => `${entry.model}:${String(entry.contextWindow ?? "")}`).join(",") ?? "";
|
|
11406
|
+
return `${provider.id}:${provider.updatedAt}:${provider.models.join(",")}:${metadata}`;
|
|
11407
|
+
}).join("|");
|
|
11408
|
+
}
|
|
11262
11409
|
function parseRequestBody(rawBody) {
|
|
11263
11410
|
if (rawBody === null) return null;
|
|
11264
11411
|
try {
|
|
@@ -11308,6 +11455,25 @@ function snapshotFromLog(log, providers) {
|
|
|
11308
11455
|
roleTotalTokens: roleSegments.reduce((sum, segment2) => sum + segment2.size, 0)
|
|
11309
11456
|
};
|
|
11310
11457
|
}
|
|
11458
|
+
function cachedSnapshotFromLog(log, providers, providersSignature) {
|
|
11459
|
+
const cached = snapshotCache.get(log);
|
|
11460
|
+
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) {
|
|
11461
|
+
return cached.snapshot;
|
|
11462
|
+
}
|
|
11463
|
+
const snapshot = snapshotFromLog(log, providers);
|
|
11464
|
+
snapshotCache.set(log, {
|
|
11465
|
+
id: log.id,
|
|
11466
|
+
rawRequestBody: log.rawRequestBody,
|
|
11467
|
+
inputTokens: log.inputTokens,
|
|
11468
|
+
model: log.model,
|
|
11469
|
+
path: log.path,
|
|
11470
|
+
apiFormat: log.apiFormat,
|
|
11471
|
+
timestamp: log.timestamp,
|
|
11472
|
+
providersSignature,
|
|
11473
|
+
snapshot
|
|
11474
|
+
});
|
|
11475
|
+
return snapshot;
|
|
11476
|
+
}
|
|
11311
11477
|
function isHigherPeak(candidate, current) {
|
|
11312
11478
|
if (candidate.usagePercent !== null && current.usagePercent !== null) {
|
|
11313
11479
|
return candidate.usagePercent > current.usagePercent;
|
|
@@ -11341,11 +11507,21 @@ function trendPercent(first, latest) {
|
|
|
11341
11507
|
if (first.usagePercent === null || latest.usagePercent === null) return null;
|
|
11342
11508
|
return (latest.usagePercent - first.usagePercent) * 100;
|
|
11343
11509
|
}
|
|
11510
|
+
function logsInAscendingIdOrder(logs) {
|
|
11511
|
+
for (let index = 1; index < logs.length; index++) {
|
|
11512
|
+
const previous = logs[index - 1];
|
|
11513
|
+
const current = logs[index];
|
|
11514
|
+
if (previous === void 0 || current === void 0) continue;
|
|
11515
|
+
if (previous.id > current.id) return [...logs].sort((left, right) => left.id - right.id);
|
|
11516
|
+
}
|
|
11517
|
+
return logs;
|
|
11518
|
+
}
|
|
11344
11519
|
function buildSessionContextSummary(logs, providers = []) {
|
|
11345
|
-
const sortedLogs =
|
|
11520
|
+
const sortedLogs = logsInAscendingIdOrder(logs);
|
|
11521
|
+
const providersSignature = providerSignature(providers);
|
|
11346
11522
|
const byModel = /* @__PURE__ */ new Map();
|
|
11347
11523
|
for (const log of sortedLogs) {
|
|
11348
|
-
const snapshot =
|
|
11524
|
+
const snapshot = cachedSnapshotFromLog(log, providers, providersSignature);
|
|
11349
11525
|
if (snapshot === null) continue;
|
|
11350
11526
|
const existing = byModel.get(snapshot.model);
|
|
11351
11527
|
if (existing === void 0) {
|
|
@@ -12730,7 +12906,7 @@ function filterLogs(logs, selectedSession, selectedModel) {
|
|
|
12730
12906
|
return true;
|
|
12731
12907
|
});
|
|
12732
12908
|
}
|
|
12733
|
-
const DEBOUNCE_MS =
|
|
12909
|
+
const DEBOUNCE_MS = 100;
|
|
12734
12910
|
const HASH_SCROLL_ATTEMPTS = 12;
|
|
12735
12911
|
const HASH_HIGHLIGHT_MS = 1800;
|
|
12736
12912
|
const MAX_CLIENT_LOGS = 500;
|
|
@@ -12787,6 +12963,7 @@ function ProxyViewerContainer({
|
|
|
12787
12963
|
const [logPage, setLogPage] = reactExports.useState(null);
|
|
12788
12964
|
const [sessionPageLoading, setSessionPageLoading] = reactExports.useState(initialSessionId !== void 0);
|
|
12789
12965
|
const [sessionMemberships, setSessionMemberships] = reactExports.useState([]);
|
|
12966
|
+
const [, startLogTransition] = reactExports.useTransition();
|
|
12790
12967
|
const eventSourceRef = reactExports.useRef(null);
|
|
12791
12968
|
const reconnectTimeoutRef = reactExports.useRef(null);
|
|
12792
12969
|
const handledHashRef = reactExports.useRef(null);
|
|
@@ -12805,22 +12982,28 @@ function ProxyViewerContainer({
|
|
|
12805
12982
|
const updates = pendingUpdatesRef.current;
|
|
12806
12983
|
pendingUpdatesRef.current = [];
|
|
12807
12984
|
if (updates.length === 0) return;
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12811
|
-
const
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
|
|
12985
|
+
startLogTransition(() => {
|
|
12986
|
+
setAllLogs((prev) => {
|
|
12987
|
+
const next = [...prev];
|
|
12988
|
+
for (const log of updates) {
|
|
12989
|
+
const indexedPosition = logIndexRef.current.get(log.id);
|
|
12990
|
+
if (indexedPosition !== void 0 && next[indexedPosition]?.id === log.id) {
|
|
12991
|
+
next[indexedPosition] = log;
|
|
12992
|
+
continue;
|
|
12993
|
+
}
|
|
12994
|
+
const existingPosition = next.findIndex((entry) => entry.id === log.id);
|
|
12995
|
+
if (existingPosition >= 0) {
|
|
12996
|
+
next[existingPosition] = log;
|
|
12997
|
+
continue;
|
|
12998
|
+
}
|
|
12999
|
+
next.push(log);
|
|
12817
13000
|
}
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
13001
|
+
const trimmed = trimClientLogs(next);
|
|
13002
|
+
logIndexRef.current = buildLogIndex(trimmed);
|
|
13003
|
+
return trimmed;
|
|
13004
|
+
});
|
|
12822
13005
|
});
|
|
12823
|
-
}, []);
|
|
13006
|
+
}, [startLogTransition]);
|
|
12824
13007
|
const scheduleUpdate = reactExports.useCallback(
|
|
12825
13008
|
(log) => {
|
|
12826
13009
|
pendingUpdatesRef.current.push(log);
|
|
@@ -13142,9 +13325,10 @@ export {
|
|
|
13142
13325
|
Badge as B,
|
|
13143
13326
|
CONTEXT_USAGE_THRESHOLDS as C,
|
|
13144
13327
|
Dialog as D,
|
|
13145
|
-
|
|
13328
|
+
LazyJsonViewer as E,
|
|
13146
13329
|
safeJsonValue as F,
|
|
13147
|
-
|
|
13330
|
+
parseJsonText as G,
|
|
13331
|
+
LazyJsonViewerFromString as L,
|
|
13148
13332
|
ProxyViewerContainer as P,
|
|
13149
13333
|
ROLE_COLOR_CLASSES as R,
|
|
13150
13334
|
SegmentBar as S,
|