@tonyclaw/agent-inspector 2.0.18 → 2.0.19
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 +137 -8
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-CepU-dLW.js → CompareDrawer-D-90PIPw.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-CxRDWacg.js +114 -0
- package/.output/public/assets/ReplayDialog-DzlLYoTO.js +1 -0
- package/.output/public/assets/{RequestAnatomy-C_C6ZU3T.js → RequestAnatomy-0hbyf6oa.js} +1 -1
- package/.output/public/assets/ResponseView-CKe0tNqr.js +1 -0
- package/.output/public/assets/StreamingChunkSequence-enhfdeNh.js +1 -0
- package/.output/public/assets/_sessionId-CJ-SusES.js +1 -0
- package/.output/public/assets/index-BbFsmQRC.js +1 -0
- package/.output/public/assets/index-BfBgrkgU.css +1 -0
- package/.output/public/assets/{main-BRXsrxtv.js → main-o9-hg8g1.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +141 -118
- package/.output/server/_libs/tanstack__react-virtual.mjs +13 -2
- package/.output/server/_libs/tanstack__virtual-core.mjs +24 -1
- package/.output/server/{_sessionId-B8Bbfs-v.mjs → _sessionId-F8lm6PIb.mjs} +3 -2
- package/.output/server/_ssr/{CompareDrawer-TgGZLf1J.mjs → CompareDrawer-Cf1yfwfd.mjs} +4 -3
- package/.output/server/_ssr/{ProxyViewerContainer-B_ppaNmQ.mjs → ProxyViewerContainer-Bmu9867L.mjs} +349 -74
- package/.output/server/_ssr/{ReplayDialog-BXlajnMC.mjs → ReplayDialog-DxZfLBOe.mjs} +199 -17
- package/.output/server/_ssr/{RequestAnatomy-CCrx09-i.mjs → RequestAnatomy-CbdERGZd.mjs} +4 -3
- package/.output/server/_ssr/{ResponseView-BxtMJrov.mjs → ResponseView-CvLd6qxI.mjs} +4 -3
- package/.output/server/_ssr/{StreamingChunkSequence-BlpdSPb8.mjs → StreamingChunkSequence-B_lkRB6o.mjs} +4 -3
- package/.output/server/_ssr/{index-BeTMNSJy.mjs → index-ejrSItfz.mjs} +3 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-Ddl1tuU7.mjs → router-SbCnbDc2.mjs} +872 -232
- package/.output/server/{_tanstack-start-manifest_v-Bvdz_U0f.mjs → _tanstack-start-manifest_v-yx8ftqWz.mjs} +1 -1
- package/.output/server/index.mjs +54 -54
- package/README.md +11 -109
- package/package.json +2 -1
- package/src/cli/doctor.ts +150 -5
- package/src/components/OnboardingBanner.tsx +13 -13
- package/src/components/ProxyViewer.tsx +55 -38
- package/src/components/ProxyViewerContainer.tsx +5 -0
- package/src/components/providers/SettingsDialog.tsx +113 -2
- package/src/components/proxy-viewer/ConversationGroup.tsx +20 -3
- package/src/components/proxy-viewer/ConversationGroupList.tsx +144 -0
- package/src/components/proxy-viewer/ConversationHeader.tsx +0 -2
- package/src/components/proxy-viewer/ReplayDialog.tsx +200 -13
- package/src/components/proxy-viewer/index.ts +1 -1
- package/src/knowledge/openclawClient.ts +0 -8
- package/src/knowledge/types.ts +0 -2
- package/src/lib/export-logs.ts +72 -5
- package/src/lib/providerTestContract.ts +0 -1
- package/src/lib/useProviders.ts +1 -1
- package/src/mcp/server.ts +14 -6
- package/src/mcp/toolHandlers.ts +21 -4
- package/src/proxy/chunkStorage.ts +2 -4
- package/src/proxy/dataDir.ts +3 -3
- package/src/proxy/formats/anthropic/index.ts +0 -1
- package/src/proxy/formats/anthropic/schemas.ts +0 -2
- package/src/proxy/handler.ts +41 -29
- package/src/proxy/logFinalizer.ts +93 -11
- package/src/proxy/logger.ts +35 -10
- package/src/proxy/providers.ts +12 -5
- package/src/proxy/rawStreamCapture.ts +85 -0
- package/src/proxy/schemas.ts +1 -51
- package/src/proxy/sessionRuntime.ts +0 -9
- package/src/proxy/socketTracker.ts +15 -8
- package/src/proxy/store.ts +414 -13
- package/src/routes/api/logs.$id.replay.ts +66 -1
- package/src/routes/api/logs.stream.ts +11 -3
- package/src/routes/api/logs.ts +51 -17
- package/src/routes/api/providers.$providerId.ts +10 -3
- package/src/routes/api/providers.ts +6 -3
- package/.output/public/assets/ProxyViewerContainer-BG7rc33d.js +0 -114
- package/.output/public/assets/ReplayDialog-DK6SPv8X.js +0 -1
- package/.output/public/assets/ResponseView-Bqpra4Zw.js +0 -1
- package/.output/public/assets/StreamingChunkSequence-CdPbpprq.js +0 -1
- package/.output/public/assets/_sessionId-CsNARHj5.js +0 -1
- package/.output/public/assets/index-37NfO0zx.js +0 -1
- package/.output/public/assets/index-D_nZj9Vt.css +0 -1
- package/src/components/ui/json-expansion-button.tsx +0 -56
package/.output/server/_ssr/{ProxyViewerContainer-B_ppaNmQ.mjs → ProxyViewerContainer-Bmu9867L.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
|
|
2
|
-
import { C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_TIME_DISPLAY_FORMAT, c as RuntimeConfigSchema, P as ProviderConfigSchema, r as requestFormatForPath, i as createPendingProviderTestResults, j as ProviderTestResultsSchema, k as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, T as TimeDisplayFormatSchema,
|
|
2
|
+
import { C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_TIME_DISPLAY_FORMAT, c as RuntimeConfigSchema, P as ProviderConfigSchema, r as requestFormatForPath, i as createPendingProviderTestResults, j as ProviderTestResultsSchema, k as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, T as TimeDisplayFormatSchema, m as maskApiKey, f as providerHasContextMetadata, h as findProviderModelMetadata, g as getSessionPath, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, d as AnthropicRequestSchema, s as safeGetOwnProperty, l as resolveProviderContextWindow, K as KnowledgeCandidateSchema, e as stripClaudeCodeBillingHeader, n as isPlainRecord } from "./router-SbCnbDc2.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";
|
|
@@ -7,9 +7,9 @@ import { t as twMerge } from "../_libs/tailwind-merge.mjs";
|
|
|
7
7
|
import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
8
8
|
import { R as Root, T as Trigger$2, C as Content, a as Close, b as Title, P as Portal$2, O as Overlay } from "../_libs/radix-ui__react-dialog.mjs";
|
|
9
9
|
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
10
|
-
import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
10
|
+
import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.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 { C as Check, X, P as Plus, D as Download, S as Settings, A as ArrowLeft, a as Copy, b as ChevronDown, U as Upload, c as Scan, d as CircleAlert, T as Terminal, e as ChevronUp,
|
|
12
|
+
import { C as Check, X, P as Plus, D as Download, S as Settings, A as ArrowLeft, a as Copy, b as ChevronDown, U as Upload, c as Scan, d as CircleAlert, T as Terminal, e as ChevronUp, E as EyeOff, f as Eye, g as ExternalLink, R as RotateCw, h as Clock, i as Pencil, j as Trash2, L as LoaderCircle, k as ArrowUpRight, l as ArrowDownRight, m as ChevronRight, n as User, M as MessageSquare, Z as Zap, W as Wrench, o as TriangleAlert, B as Brain, p as Minus, q as CircleCheckBig, r as CircleQuestionMark, s as Server, G as Gauge, t as Lock, u as Wifi, v as WifiOff, w as CircleX, x as ShieldCheck, y as RefreshCw, z as Save, F as FileSearch, H as CircleCheck, I as CloudUpload, O as OctagonAlert, J as Globe, K as FileTerminal, N as Radio, Q as ChevronsUp, V as ChevronsDown, Y as FileDiff, _ as History, $ as RotateCcw, a0 as Search, a1 as GitCompareArrows, a2 as ArrowUp, a3 as ArrowDown, a4 as Ellipsis, a5 as CodeXml, a6 as Blocks, a7 as MousePointerClick, a8 as FileText, a9 as Rows3, aa as Columns2 } from "../_libs/lucide-react.mjs";
|
|
13
13
|
import { M as Markdown } from "../_libs/react-markdown.mjs";
|
|
14
14
|
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
15
|
import { P as Provider, R as Root3, T as Trigger$1, a as Portal$1, C as Content2$1, A as Arrow2 } from "../_libs/radix-ui__react-tooltip.mjs";
|
|
@@ -191,36 +191,39 @@ function OnboardingBanner() {
|
|
|
191
191
|
children: [
|
|
192
192
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
193
193
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-1 font-medium text-amber-600 dark:text-amber-400", children: isFullMode ? "Agent Inspector is ready in Full mode" : "Agent Inspector is ready in Simple mode" }),
|
|
194
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
194
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("ol", { className: "space-y-0.5 text-xs leading-relaxed text-muted-foreground", children: [
|
|
195
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
196
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "1. Start in the right mode" }),
|
|
197
|
+
": this process is currently running in",
|
|
198
|
+
" ",
|
|
199
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: captureMode }),
|
|
200
|
+
". Mode is fixed at startup."
|
|
201
|
+
] }),
|
|
195
202
|
isFullMode ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
196
203
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
197
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Full
|
|
198
|
-
": raw headers, raw response, and SSE chunks are captured for
|
|
204
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "2. Full diagnostics" }),
|
|
205
|
+
": raw headers, raw response, and SSE chunks are captured for deep investigations."
|
|
199
206
|
] }),
|
|
200
207
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
201
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Daily work" }),
|
|
202
|
-
": restart with
|
|
203
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "agent-inspector --mode simple" }),
|
|
208
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "3. Daily work" }),
|
|
209
|
+
": restart with",
|
|
204
210
|
" ",
|
|
205
|
-
|
|
211
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "agent-inspector --mode simple" }),
|
|
212
|
+
" to reduce capture overhead."
|
|
206
213
|
] })
|
|
207
214
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
208
215
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
209
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Simple
|
|
210
|
-
":
|
|
216
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "2. Simple capture" }),
|
|
217
|
+
": requests, responses, tools, timing, tokens, replay, and memory candidates are available with lower overhead."
|
|
211
218
|
] }),
|
|
212
219
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
213
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Need diagnostics?" }),
|
|
220
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "3. Need raw diagnostics?" }),
|
|
214
221
|
" Restart with",
|
|
215
222
|
" ",
|
|
216
223
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "agent-inspector --mode full" }),
|
|
217
224
|
" for raw headers, raw response, and SSE chunks."
|
|
218
225
|
] })
|
|
219
226
|
] }),
|
|
220
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
221
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Replay and Memory" }),
|
|
222
|
-
": available in both modes for provider checks and reviewable knowledge candidates."
|
|
223
|
-
] }),
|
|
224
227
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
225
228
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Agent setup" }),
|
|
226
229
|
": run ",
|
|
@@ -265,6 +268,15 @@ function OnboardingBanner() {
|
|
|
265
268
|
}
|
|
266
269
|
);
|
|
267
270
|
}
|
|
271
|
+
const REDACTED = "[REDACTED]";
|
|
272
|
+
const SECRET_KEY_PATTERN = /(^|[-_])(api[-_]?key|authorization|cookie|token|secret|password|access[-_]?token|refresh[-_]?token)([-_]|$)/i;
|
|
273
|
+
const SECRET_TEXT_PATTERNS = [
|
|
274
|
+
/Bearer\s+[A-Za-z0-9._~+/=-]{12,}/gi,
|
|
275
|
+
/\bsk-[A-Za-z0-9_-]{12,}\b/g,
|
|
276
|
+
/\bsk-ant-[A-Za-z0-9_-]{12,}\b/g,
|
|
277
|
+
/\bghp_[A-Za-z0-9_]{12,}\b/g,
|
|
278
|
+
/\bglpat-[A-Za-z0-9_-]{12,}\b/g
|
|
279
|
+
];
|
|
268
280
|
async function fetchStreamingChunks(logId) {
|
|
269
281
|
try {
|
|
270
282
|
const response = await fetch(`/api/logs/${logId}/chunks`);
|
|
@@ -275,14 +287,59 @@ async function fetchStreamingChunks(logId) {
|
|
|
275
287
|
return null;
|
|
276
288
|
}
|
|
277
289
|
}
|
|
278
|
-
|
|
290
|
+
function isRecord$1(value) {
|
|
291
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
292
|
+
}
|
|
293
|
+
function redactValue(value) {
|
|
294
|
+
if (Array.isArray(value)) return value.map((item) => redactValue(item));
|
|
295
|
+
if (!isRecord$1(value)) return value;
|
|
296
|
+
const result = {};
|
|
297
|
+
for (const [key, item] of Object.entries(value)) {
|
|
298
|
+
result[key] = SECRET_KEY_PATTERN.test(key) ? REDACTED : redactValue(item);
|
|
299
|
+
}
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
function redactJsonText(text) {
|
|
303
|
+
const redactText = (value) => {
|
|
304
|
+
let result = value;
|
|
305
|
+
for (const pattern of SECRET_TEXT_PATTERNS) {
|
|
306
|
+
result = result.replace(pattern, REDACTED);
|
|
307
|
+
}
|
|
308
|
+
return result;
|
|
309
|
+
};
|
|
310
|
+
try {
|
|
311
|
+
const parsed = JSON.parse(text);
|
|
312
|
+
return redactText(JSON.stringify(redactValue(parsed), null, 2));
|
|
313
|
+
} catch {
|
|
314
|
+
return redactText(text);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function exportText(text, mode) {
|
|
318
|
+
return mode === "redacted" ? redactJsonText(text) : text;
|
|
319
|
+
}
|
|
320
|
+
async function exportLogsAsZip(logs, mode = "redacted") {
|
|
279
321
|
const zip = new JSZip();
|
|
322
|
+
const suffix = mode === "redacted" ? "redacted" : "raw";
|
|
323
|
+
zip.file(
|
|
324
|
+
"manifest.json",
|
|
325
|
+
JSON.stringify(
|
|
326
|
+
{
|
|
327
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
328
|
+
mode,
|
|
329
|
+
redacted: mode === "redacted",
|
|
330
|
+
logCount: logs.length,
|
|
331
|
+
logIds: logs.map((log) => log.id)
|
|
332
|
+
},
|
|
333
|
+
null,
|
|
334
|
+
2
|
|
335
|
+
)
|
|
336
|
+
);
|
|
280
337
|
for (const log of logs) {
|
|
281
338
|
if (log.rawRequestBody !== null) {
|
|
282
|
-
zip.file(`#${log.id}.Request.json`, log.rawRequestBody);
|
|
339
|
+
zip.file(`#${log.id}.Request.json`, exportText(log.rawRequestBody, mode));
|
|
283
340
|
}
|
|
284
341
|
if (log.responseText !== null) {
|
|
285
|
-
zip.file(`#${log.id}.Response.json`, log.responseText);
|
|
342
|
+
zip.file(`#${log.id}.Response.json`, exportText(log.responseText, mode));
|
|
286
343
|
}
|
|
287
344
|
}
|
|
288
345
|
const streamingLogs = logs.filter((log) => log.streaming);
|
|
@@ -290,7 +347,7 @@ async function exportLogsAsZip(logs) {
|
|
|
290
347
|
streamingLogs.map(async (log) => {
|
|
291
348
|
const chunks = await fetchStreamingChunks(log.id);
|
|
292
349
|
if (chunks !== null) {
|
|
293
|
-
zip.file(`#${log.id}.SSE.Response.json`, chunks);
|
|
350
|
+
zip.file(`#${log.id}.SSE.Response.json`, exportText(chunks, mode));
|
|
294
351
|
}
|
|
295
352
|
})
|
|
296
353
|
);
|
|
@@ -298,7 +355,7 @@ async function exportLogsAsZip(logs) {
|
|
|
298
355
|
const url = URL.createObjectURL(blob);
|
|
299
356
|
const anchor = document.createElement("a");
|
|
300
357
|
anchor.href = url;
|
|
301
|
-
anchor.download = `agent-inspector-export-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.zip`;
|
|
358
|
+
anchor.download = `agent-inspector-export-${suffix}-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.zip`;
|
|
302
359
|
document.body.appendChild(anchor);
|
|
303
360
|
anchor.click();
|
|
304
361
|
document.body.removeChild(anchor);
|
|
@@ -349,7 +406,7 @@ async function fetcher(url) {
|
|
|
349
406
|
}
|
|
350
407
|
function useProviders() {
|
|
351
408
|
const response = useSWR(
|
|
352
|
-
"/api/providers",
|
|
409
|
+
"/api/providers?includeSecrets=1",
|
|
353
410
|
fetcher,
|
|
354
411
|
{
|
|
355
412
|
revalidateOnFocus: false,
|
|
@@ -363,7 +420,7 @@ function useProviders() {
|
|
|
363
420
|
mutate: response.mutate
|
|
364
421
|
};
|
|
365
422
|
}
|
|
366
|
-
const version = "2.0.
|
|
423
|
+
const version = "2.0.19";
|
|
367
424
|
const packageJson = {
|
|
368
425
|
version
|
|
369
426
|
};
|
|
@@ -1424,19 +1481,19 @@ function useCopyFeedback(text) {
|
|
|
1424
1481
|
return { copied, copy };
|
|
1425
1482
|
}
|
|
1426
1483
|
const LazyCompareDrawer = reactExports.lazy(
|
|
1427
|
-
() => import("./CompareDrawer-
|
|
1484
|
+
() => import("./CompareDrawer-Cf1yfwfd.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
1428
1485
|
);
|
|
1429
1486
|
const LazyReplayDialog = reactExports.lazy(
|
|
1430
|
-
() => import("./ReplayDialog-
|
|
1487
|
+
() => import("./ReplayDialog-DxZfLBOe.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
1431
1488
|
);
|
|
1432
1489
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
1433
|
-
() => import("./RequestAnatomy-
|
|
1490
|
+
() => import("./RequestAnatomy-CbdERGZd.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
1434
1491
|
);
|
|
1435
1492
|
const LazyResponseView = reactExports.lazy(
|
|
1436
|
-
() => import("./ResponseView-
|
|
1493
|
+
() => import("./ResponseView-CvLd6qxI.mjs").then((m) => ({ default: m.ResponseView }))
|
|
1437
1494
|
);
|
|
1438
1495
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
1439
|
-
() => import("./StreamingChunkSequence-
|
|
1496
|
+
() => import("./StreamingChunkSequence-B_lkRB6o.mjs").then((m) => ({
|
|
1440
1497
|
default: m.StreamingChunkSequence
|
|
1441
1498
|
}))
|
|
1442
1499
|
);
|
|
@@ -4944,9 +5001,22 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
4944
5001
|
onClearGroup,
|
|
4945
5002
|
standalone = false,
|
|
4946
5003
|
hasPinnedSessionContext = false,
|
|
4947
|
-
timeDisplayFormat
|
|
5004
|
+
timeDisplayFormat,
|
|
5005
|
+
expanded: controlledExpanded,
|
|
5006
|
+
onExpandedChange
|
|
4948
5007
|
}) {
|
|
4949
|
-
const [
|
|
5008
|
+
const [internalExpanded, setInternalExpanded] = reactExports.useState(false);
|
|
5009
|
+
const expanded = controlledExpanded ?? internalExpanded;
|
|
5010
|
+
const setExpanded = reactExports.useCallback(
|
|
5011
|
+
(nextExpanded) => {
|
|
5012
|
+
if (onExpandedChange !== void 0) {
|
|
5013
|
+
onExpandedChange(nextExpanded);
|
|
5014
|
+
return;
|
|
5015
|
+
}
|
|
5016
|
+
setInternalExpanded(nextExpanded);
|
|
5017
|
+
},
|
|
5018
|
+
[onExpandedChange]
|
|
5019
|
+
);
|
|
4950
5020
|
const stats = reactExports.useMemo(() => computeStats(group.logs), [group.logs]);
|
|
4951
5021
|
const startTime = group.logs[0]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
4952
5022
|
const endTime = group.logs[group.logs.length - 1]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -4966,7 +5036,7 @@ const ConversationGroup = reactExports.memo(function({
|
|
|
4966
5036
|
return () => {
|
|
4967
5037
|
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4968
5038
|
};
|
|
4969
|
-
}, [group.logs, standalone]);
|
|
5039
|
+
}, [group.logs, setExpanded, standalone]);
|
|
4970
5040
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
|
|
4971
5041
|
!standalone && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4972
5042
|
ConversationHeader,
|
|
@@ -5520,10 +5590,6 @@ function ImportWizardDialog({
|
|
|
5520
5590
|
] })
|
|
5521
5591
|
] }) });
|
|
5522
5592
|
}
|
|
5523
|
-
function maskApiKey(apiKey) {
|
|
5524
|
-
if (apiKey.length <= 8) return "••••••••";
|
|
5525
|
-
return apiKey.slice(0, 4) + "••••••••" + apiKey.slice(-4);
|
|
5526
|
-
}
|
|
5527
5593
|
const KNOWN_PROVIDER_DOCS = {
|
|
5528
5594
|
deepseek: "https://api-docs.deepseek.com/zh-cn/"
|
|
5529
5595
|
};
|
|
@@ -7112,6 +7178,7 @@ function SettingsDialog() {
|
|
|
7112
7178
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { children: [
|
|
7113
7179
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "providers", children: "Providers" }),
|
|
7114
7180
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "proxy", children: "Proxy" }),
|
|
7181
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "storage", children: "Storage" }),
|
|
7115
7182
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "onboarding", children: "Onboarding" })
|
|
7116
7183
|
] }),
|
|
7117
7184
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 flex-1 overflow-x-hidden overflow-y-auto pr-3", children: [
|
|
@@ -7132,12 +7199,95 @@ function SettingsDialog() {
|
|
|
7132
7199
|
}
|
|
7133
7200
|
) }),
|
|
7134
7201
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "proxy", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProxySettingsTab, {}) }),
|
|
7202
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "storage", children: /* @__PURE__ */ jsxRuntimeExports.jsx(StorageSettingsTab, {}) }),
|
|
7135
7203
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "onboarding", children: /* @__PURE__ */ jsxRuntimeExports.jsx(OnboardingSettingsTab, {}) })
|
|
7136
7204
|
] })
|
|
7137
7205
|
] })
|
|
7138
7206
|
] })
|
|
7139
7207
|
] });
|
|
7140
7208
|
}
|
|
7209
|
+
const LogStorageStatsSchema = object({
|
|
7210
|
+
memoryCount: number(),
|
|
7211
|
+
logDir: string(),
|
|
7212
|
+
logFileCount: number(),
|
|
7213
|
+
logBytes: number(),
|
|
7214
|
+
chunkDir: string(),
|
|
7215
|
+
chunkFileCount: number(),
|
|
7216
|
+
chunkBytes: number()
|
|
7217
|
+
});
|
|
7218
|
+
function formatBytes(bytes) {
|
|
7219
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
7220
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;
|
|
7221
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MiB`;
|
|
7222
|
+
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GiB`;
|
|
7223
|
+
}
|
|
7224
|
+
function StorageSettingsTab() {
|
|
7225
|
+
const [stats, setStats] = reactExports.useState(null);
|
|
7226
|
+
const [error, setError] = reactExports.useState(null);
|
|
7227
|
+
const [loading, setLoading] = reactExports.useState(false);
|
|
7228
|
+
const refresh = reactExports.useCallback(async () => {
|
|
7229
|
+
setLoading(true);
|
|
7230
|
+
setError(null);
|
|
7231
|
+
try {
|
|
7232
|
+
const response = await fetch("/api/logs?stats=1");
|
|
7233
|
+
if (!response.ok) {
|
|
7234
|
+
setError(`Failed to load storage stats: HTTP ${String(response.status)}`);
|
|
7235
|
+
return;
|
|
7236
|
+
}
|
|
7237
|
+
const data = await response.json();
|
|
7238
|
+
const parsed = LogStorageStatsSchema.safeParse(data);
|
|
7239
|
+
if (!parsed.success) {
|
|
7240
|
+
setError("Storage stats response was not valid.");
|
|
7241
|
+
return;
|
|
7242
|
+
}
|
|
7243
|
+
setStats(parsed.data);
|
|
7244
|
+
} catch (err) {
|
|
7245
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
7246
|
+
} finally {
|
|
7247
|
+
setLoading(false);
|
|
7248
|
+
}
|
|
7249
|
+
}, []);
|
|
7250
|
+
reactExports.useEffect(() => {
|
|
7251
|
+
void refresh();
|
|
7252
|
+
}, [refresh]);
|
|
7253
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
7254
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
7255
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
7256
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold", children: "Log storage" }),
|
|
7257
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Inspect local log and streaming chunk footprint before exporting or clearing sessions." })
|
|
7258
|
+
] }),
|
|
7259
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => void refresh(), children: loading ? "Refreshing..." : "Refresh" })
|
|
7260
|
+
] }),
|
|
7261
|
+
stats !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2 text-xs", children: [
|
|
7262
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
|
|
7263
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "In-memory logs" }),
|
|
7264
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
|
|
7265
|
+
stats.memoryCount.toLocaleString(),
|
|
7266
|
+
" loaded"
|
|
7267
|
+
] })
|
|
7268
|
+
] }),
|
|
7269
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
|
|
7270
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Log files" }),
|
|
7271
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 break-all font-mono text-muted-foreground", children: stats.logDir }),
|
|
7272
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
|
|
7273
|
+
stats.logFileCount.toLocaleString(),
|
|
7274
|
+
" files / ",
|
|
7275
|
+
formatBytes(stats.logBytes)
|
|
7276
|
+
] })
|
|
7277
|
+
] }),
|
|
7278
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
|
|
7279
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Streaming chunks" }),
|
|
7280
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 break-all font-mono text-muted-foreground", children: stats.chunkDir }),
|
|
7281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
|
|
7282
|
+
stats.chunkFileCount.toLocaleString(),
|
|
7283
|
+
" files / ",
|
|
7284
|
+
formatBytes(stats.chunkBytes)
|
|
7285
|
+
] })
|
|
7286
|
+
] })
|
|
7287
|
+
] }),
|
|
7288
|
+
error !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: error })
|
|
7289
|
+
] });
|
|
7290
|
+
}
|
|
7141
7291
|
function CopyableSetupValue({
|
|
7142
7292
|
id,
|
|
7143
7293
|
label,
|
|
@@ -7300,7 +7450,8 @@ function ProxySettingsTab() {
|
|
|
7300
7450
|
"agent-inspector --mode ",
|
|
7301
7451
|
alternateCaptureMode
|
|
7302
7452
|
] }),
|
|
7303
|
-
" to change it."
|
|
7453
|
+
" to change it.",
|
|
7454
|
+
captureMode === "simple" ? " Simple mode keeps replay, parsed requests, responses, timing, tools, and token usage while skipping raw headers, raw response retention, and detailed SSE chunk retention." : " Full mode retains raw headers, raw responses, and SSE chunks for diagnostics; use simple mode for everyday lower-overhead capture."
|
|
7304
7455
|
] })
|
|
7305
7456
|
] }),
|
|
7306
7457
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
|
|
@@ -7330,7 +7481,7 @@ function ProxySettingsTab() {
|
|
|
7330
7481
|
className: "size-4 cursor-pointer disabled:cursor-not-allowed disabled:opacity-50"
|
|
7331
7482
|
}
|
|
7332
7483
|
),
|
|
7333
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: isLoading ? "Loading
|
|
7484
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: isLoading ? "Loading..." : strip ? "Stripping enabled" : "Stripping disabled" })
|
|
7334
7485
|
] }),
|
|
7335
7486
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
|
|
7336
7487
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "slow-response-threshold", className: "text-sm font-semibold", children: "Slow response threshold" }),
|
|
@@ -7413,6 +7564,107 @@ function compareField(previous, current) {
|
|
|
7413
7564
|
if (current < previous) return { direction: "down", delta: previous - current };
|
|
7414
7565
|
return null;
|
|
7415
7566
|
}
|
|
7567
|
+
const VIRTUALIZE_GROUP_THRESHOLD = 30;
|
|
7568
|
+
const ESTIMATED_GROUP_HEIGHT = 112;
|
|
7569
|
+
const VIRTUAL_OVERSCAN = 6;
|
|
7570
|
+
function shouldVirtualizeConversationGroups(groupCount) {
|
|
7571
|
+
return groupCount > VIRTUALIZE_GROUP_THRESHOLD;
|
|
7572
|
+
}
|
|
7573
|
+
function ConversationGroupList({
|
|
7574
|
+
groups,
|
|
7575
|
+
standalone,
|
|
7576
|
+
...groupProps
|
|
7577
|
+
}) {
|
|
7578
|
+
if (!shouldVirtualizeConversationGroups(groups.length)) {
|
|
7579
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: groups.map((group) => /* @__PURE__ */ jsxRuntimeExports.jsx(ConversationGroup, { group, standalone, ...groupProps }, group.id)) });
|
|
7580
|
+
}
|
|
7581
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(VirtualizedConversationGroupList, { groups, standalone, ...groupProps });
|
|
7582
|
+
}
|
|
7583
|
+
function VirtualizedConversationGroupList({
|
|
7584
|
+
groups,
|
|
7585
|
+
standalone,
|
|
7586
|
+
...groupProps
|
|
7587
|
+
}) {
|
|
7588
|
+
const [expandedByGroupId, setExpandedByGroupId] = reactExports.useState(
|
|
7589
|
+
() => /* @__PURE__ */ new Map()
|
|
7590
|
+
);
|
|
7591
|
+
const virtualizer = useWindowVirtualizer({
|
|
7592
|
+
count: groups.length,
|
|
7593
|
+
estimateSize: () => ESTIMATED_GROUP_HEIGHT,
|
|
7594
|
+
overscan: VIRTUAL_OVERSCAN,
|
|
7595
|
+
getItemKey: (index) => groups[index]?.id ?? index
|
|
7596
|
+
});
|
|
7597
|
+
const setGroupExpanded = reactExports.useCallback((groupId, expanded) => {
|
|
7598
|
+
setExpandedByGroupId((previous) => {
|
|
7599
|
+
const next = new Map(previous);
|
|
7600
|
+
if (expanded) {
|
|
7601
|
+
next.set(groupId, true);
|
|
7602
|
+
} else {
|
|
7603
|
+
next.delete(groupId);
|
|
7604
|
+
}
|
|
7605
|
+
return next;
|
|
7606
|
+
});
|
|
7607
|
+
}, []);
|
|
7608
|
+
const indexByLogId = reactExports.useMemo(() => {
|
|
7609
|
+
const result = /* @__PURE__ */ new Map();
|
|
7610
|
+
for (let index = 0; index < groups.length; index++) {
|
|
7611
|
+
const group = groups[index];
|
|
7612
|
+
if (group === void 0) continue;
|
|
7613
|
+
for (const log of group.logs) {
|
|
7614
|
+
result.set(log.id, index);
|
|
7615
|
+
}
|
|
7616
|
+
}
|
|
7617
|
+
return result;
|
|
7618
|
+
}, [groups]);
|
|
7619
|
+
reactExports.useEffect(() => {
|
|
7620
|
+
const handleLogFocusRequest = (event) => {
|
|
7621
|
+
const request = readLogFocusRequest(event);
|
|
7622
|
+
if (request === null) return;
|
|
7623
|
+
const index = indexByLogId.get(request.logId);
|
|
7624
|
+
if (index === void 0) return;
|
|
7625
|
+
const group = groups[index];
|
|
7626
|
+
if (group === void 0) return;
|
|
7627
|
+
setGroupExpanded(group.id, true);
|
|
7628
|
+
virtualizer.scrollToIndex(index, { align: "center" });
|
|
7629
|
+
};
|
|
7630
|
+
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
7631
|
+
return () => {
|
|
7632
|
+
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
7633
|
+
};
|
|
7634
|
+
}, [groups, indexByLogId, setGroupExpanded, virtualizer]);
|
|
7635
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7636
|
+
"div",
|
|
7637
|
+
{
|
|
7638
|
+
className: "relative w-full",
|
|
7639
|
+
style: { height: `${virtualizer.getTotalSize()}px` },
|
|
7640
|
+
"data-virtualized-conversation-list": "true",
|
|
7641
|
+
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
7642
|
+
const group = groups[virtualItem.index];
|
|
7643
|
+
if (group === void 0) return null;
|
|
7644
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7645
|
+
"div",
|
|
7646
|
+
{
|
|
7647
|
+
"data-index": virtualItem.index,
|
|
7648
|
+
ref: virtualizer.measureElement,
|
|
7649
|
+
className: "absolute left-0 top-0 w-full",
|
|
7650
|
+
style: { transform: `translateY(${virtualItem.start}px)` },
|
|
7651
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7652
|
+
ConversationGroup,
|
|
7653
|
+
{
|
|
7654
|
+
group,
|
|
7655
|
+
standalone,
|
|
7656
|
+
expanded: expandedByGroupId.get(group.id) ?? false,
|
|
7657
|
+
onExpandedChange: (expanded) => setGroupExpanded(group.id, expanded),
|
|
7658
|
+
...groupProps
|
|
7659
|
+
}
|
|
7660
|
+
)
|
|
7661
|
+
},
|
|
7662
|
+
virtualItem.key
|
|
7663
|
+
);
|
|
7664
|
+
})
|
|
7665
|
+
}
|
|
7666
|
+
);
|
|
7667
|
+
}
|
|
7416
7668
|
const NAV_ATTR = "data-nav-id";
|
|
7417
7669
|
const NAV_ACTION_ATTR = "data-nav-action";
|
|
7418
7670
|
function findNavItems(container) {
|
|
@@ -8434,7 +8686,7 @@ function buildSessionContextSummary(logs, providers = []) {
|
|
|
8434
8686
|
}
|
|
8435
8687
|
function truncateSessionId(id) {
|
|
8436
8688
|
if (id.length <= 30) return id;
|
|
8437
|
-
return id.slice(0, 12)
|
|
8689
|
+
return `${id.slice(0, 12)}...${id.slice(-12)}`;
|
|
8438
8690
|
}
|
|
8439
8691
|
function computeTokenSummary(logs) {
|
|
8440
8692
|
let totalIn = 0;
|
|
@@ -8939,7 +9191,7 @@ function ProxyViewer({
|
|
|
8939
9191
|
}) {
|
|
8940
9192
|
const { totalIn, totalOut } = reactExports.useMemo(() => computeTokenSummary(logs), [logs]);
|
|
8941
9193
|
const { providers } = useProviders();
|
|
8942
|
-
const [exporting, setExporting] = reactExports.useState(
|
|
9194
|
+
const [exporting, setExporting] = reactExports.useState(null);
|
|
8943
9195
|
const [comparePair, setComparePair] = reactExports.useState(null);
|
|
8944
9196
|
const [crabEntrancePhase, setCrabEntrancePhase] = reactExports.useState(
|
|
8945
9197
|
"hidden"
|
|
@@ -8966,14 +9218,17 @@ function ProxyViewer({
|
|
|
8966
9218
|
const requestLabel = logs.length === 1 ? "1 req" : `${logs.length} req`;
|
|
8967
9219
|
document.title = `${truncateSessionId(pinnedSessionId)} - ${requestLabel} - Agent Inspector`;
|
|
8968
9220
|
}, [logs.length, pinnedSessionId]);
|
|
8969
|
-
const handleExport = reactExports.useCallback(
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
9221
|
+
const handleExport = reactExports.useCallback(
|
|
9222
|
+
async (mode) => {
|
|
9223
|
+
setExporting(mode);
|
|
9224
|
+
try {
|
|
9225
|
+
await exportLogsAsZip(logs, mode);
|
|
9226
|
+
} finally {
|
|
9227
|
+
setExporting(null);
|
|
9228
|
+
}
|
|
9229
|
+
},
|
|
9230
|
+
[logs]
|
|
9231
|
+
);
|
|
8977
9232
|
reactExports.useEffect(() => {
|
|
8978
9233
|
setComparePair(null);
|
|
8979
9234
|
}, [selectedSession, selectedModel]);
|
|
@@ -9114,24 +9369,37 @@ function ProxyViewer({
|
|
|
9114
9369
|
logs.length,
|
|
9115
9370
|
" request",
|
|
9116
9371
|
logs.length !== 1 ? "s" : "",
|
|
9117
|
-
totalIn > 0 || totalOut > 0 ? `
|
|
9372
|
+
totalIn > 0 || totalOut > 0 ? ` - ${formatTokens(totalIn)} in / ${formatTokens(totalOut)} out` : ""
|
|
9118
9373
|
] }),
|
|
9119
9374
|
logs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9120
9375
|
"button",
|
|
9121
9376
|
{
|
|
9122
9377
|
type: "button",
|
|
9123
9378
|
onClick: () => {
|
|
9124
|
-
void handleExport();
|
|
9379
|
+
void handleExport("redacted");
|
|
9125
9380
|
},
|
|
9126
|
-
disabled: exporting,
|
|
9381
|
+
disabled: exporting !== null,
|
|
9127
9382
|
className: "h-8 px-3 text-xs text-muted-foreground hover:text-foreground transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed inline-flex items-center gap-1.5 rounded-md hover:bg-muted",
|
|
9128
|
-
title: "Export
|
|
9129
|
-
children: exporting ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
9383
|
+
title: "Export redacted logs as JSON ZIP",
|
|
9384
|
+
children: exporting === "redacted" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
9130
9385
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3.5" }),
|
|
9131
9386
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Export" })
|
|
9132
9387
|
] })
|
|
9133
9388
|
}
|
|
9134
9389
|
),
|
|
9390
|
+
logs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9391
|
+
"button",
|
|
9392
|
+
{
|
|
9393
|
+
type: "button",
|
|
9394
|
+
onClick: () => {
|
|
9395
|
+
void handleExport("raw");
|
|
9396
|
+
},
|
|
9397
|
+
disabled: exporting !== null,
|
|
9398
|
+
className: "h-8 px-2 text-xs text-muted-foreground hover:text-foreground transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed rounded-md hover:bg-muted",
|
|
9399
|
+
title: "Export raw logs without redaction",
|
|
9400
|
+
children: exporting === "raw" ? "Exporting..." : "Raw"
|
|
9401
|
+
}
|
|
9402
|
+
),
|
|
9135
9403
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9136
9404
|
"button",
|
|
9137
9405
|
{
|
|
@@ -9163,17 +9431,20 @@ function ProxyViewer({
|
|
|
9163
9431
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-muted-foreground py-16 space-y-4", children: [
|
|
9164
9432
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No requests captured yet." }),
|
|
9165
9433
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs", children: "Route AI coding tools through the proxy:" }),
|
|
9166
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
9434
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
9435
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "ANTHROPIC_BASE_URL=http://localhost:25947/proxy <your-tool>" }),
|
|
9436
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "OPENAI_BASE_URL=http://localhost:25947/proxy <your-tool>" })
|
|
9437
|
+
] })
|
|
9167
9438
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9168
9439
|
"div",
|
|
9169
9440
|
{
|
|
9170
9441
|
ref: logListWrapperRef,
|
|
9171
9442
|
tabIndex: 0,
|
|
9172
9443
|
className: "flex flex-col gap-2 focus:outline-none",
|
|
9173
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: logListRef, children:
|
|
9174
|
-
|
|
9444
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: logListRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9445
|
+
ConversationGroupList,
|
|
9175
9446
|
{
|
|
9176
|
-
|
|
9447
|
+
groups,
|
|
9177
9448
|
viewMode,
|
|
9178
9449
|
strip,
|
|
9179
9450
|
slowResponseThresholdSeconds,
|
|
@@ -9184,9 +9455,8 @@ function ProxyViewer({
|
|
|
9184
9455
|
standalone: groups.length === 1,
|
|
9185
9456
|
hasPinnedSessionContext: hasSessionContext,
|
|
9186
9457
|
timeDisplayFormat
|
|
9187
|
-
}
|
|
9188
|
-
|
|
9189
|
-
)) })
|
|
9458
|
+
}
|
|
9459
|
+
) })
|
|
9190
9460
|
}
|
|
9191
9461
|
) }),
|
|
9192
9462
|
comparePair !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyCompareDrawer, { left: comparePair[0], right: comparePair[1], onClose: closeCompare }) })
|
|
@@ -9348,6 +9618,10 @@ function ProxyViewerContainer({
|
|
|
9348
9618
|
if (!hash.startsWith("#log-")) return;
|
|
9349
9619
|
if (handledHashRef.current === hash) return;
|
|
9350
9620
|
const targetId = hash.slice(1);
|
|
9621
|
+
const logId = Number(targetId.replace(/^log-/, ""));
|
|
9622
|
+
if (Number.isInteger(logId) && logId > 0) {
|
|
9623
|
+
dispatchLogFocusRequest({ logId, tab: "request" });
|
|
9624
|
+
}
|
|
9351
9625
|
let cancelled = false;
|
|
9352
9626
|
let attempts = 0;
|
|
9353
9627
|
let highlightedTarget = null;
|
|
@@ -9474,6 +9748,7 @@ export {
|
|
|
9474
9748
|
Badge as B,
|
|
9475
9749
|
CONTEXT_USAGE_THRESHOLDS as C,
|
|
9476
9750
|
Dialog as D,
|
|
9751
|
+
safeJsonValue as E,
|
|
9477
9752
|
JsonViewerFromString as J,
|
|
9478
9753
|
ProxyViewerContainer as P,
|
|
9479
9754
|
ROLE_COLOR_CLASSES as R,
|
|
@@ -9489,20 +9764,20 @@ export {
|
|
|
9489
9764
|
TabsList as h,
|
|
9490
9765
|
TabsTrigger as i,
|
|
9491
9766
|
TabsContent as j,
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9767
|
+
Button as k,
|
|
9768
|
+
TooltipProvider as l,
|
|
9769
|
+
Tooltip as m,
|
|
9770
|
+
TooltipTrigger as n,
|
|
9771
|
+
TooltipContent as o,
|
|
9772
|
+
dispatchLogFocusRequest as p,
|
|
9773
|
+
analyzeContextIntelligence as q,
|
|
9499
9774
|
resolveLogFormat as r,
|
|
9500
|
-
|
|
9501
|
-
|
|
9775
|
+
formatContextWindowTokens as s,
|
|
9776
|
+
getStatusCategory as t,
|
|
9502
9777
|
useProviders as u,
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9778
|
+
Collapsible as v,
|
|
9779
|
+
CollapsibleTrigger as w,
|
|
9780
|
+
CollapsibleContent as x,
|
|
9781
|
+
ScrollArea as y,
|
|
9782
|
+
JsonViewer as z
|
|
9508
9783
|
};
|