@tonyclaw/agent-inspector 3.0.3 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-CufpM7_P.js → CompareDrawer-Bs2kzUSp.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-BUnlrfiS.js +106 -0
- package/.output/public/assets/{ReplayDialog-ClDmxv57.js → ReplayDialog-B6xy7pl5.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-DcuIghmp.js → RequestAnatomy-BSvSmpCO.js} +1 -1
- package/.output/public/assets/{ResponseView-C7Tl47j3.js → ResponseView-BFnUva7Z.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-DBK_R540.js → StreamingChunkSequence-u7ZaJOqn.js} +1 -1
- package/.output/public/assets/{_sessionId-D8Ke-EcI.js → _sessionId-CH4nsMOA.js} +1 -1
- package/.output/public/assets/{index-CpWH7b2O.js → index-B5HS6AxR.js} +1 -1
- package/.output/public/assets/index-BqVL284D.js +1 -0
- package/.output/public/assets/index-DJW6qbnH.css +1 -0
- package/.output/public/assets/{json-viewer-BEifdKM_.js → json-viewer-5Tj5vkqe.js} +1 -1
- package/.output/public/assets/{main-DDfExS3_.js → main-ChxZWG8K.js} +2 -2
- package/.output/server/{_sessionId-Di7z893V.mjs → _sessionId-B3r-VBdM.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-ABv-8FMB.mjs → CompareDrawer-DAYrKHKe.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-CGX-1aUr.mjs → ProxyViewerContainer-CYmNmQK9.mjs} +332 -148
- package/.output/server/_ssr/{ReplayDialog-DD31ftzG.mjs → ReplayDialog-CdKvdXxk.mjs} +3 -3
- package/.output/server/_ssr/{RequestAnatomy-54kNHAjH.mjs → RequestAnatomy-BtmTUq7O.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-CRnibtlX.mjs → ResponseView-DuD_z5hd.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-Cb5WGfMm.mjs → StreamingChunkSequence-DpIV2wt_.mjs} +2 -2
- package/.output/server/_ssr/{index-BJ-8DomR.mjs → index-B4_8vH8k.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-DB5188I7.mjs → json-viewer-gcNJEB7y.mjs} +2 -2
- package/.output/server/_ssr/{router-BKf70uDr.mjs → router-CYjIsElo.mjs} +4 -4
- package/.output/server/{_tanstack-start-manifest_v-DUuf3Rgf.mjs → _tanstack-start-manifest_v-BRdOxY6q.mjs} +1 -1
- package/.output/server/index.mjs +67 -67
- package/package.json +1 -1
- package/src/components/ProxyViewer.tsx +92 -25
- package/src/components/ProxyViewerContainer.tsx +154 -55
- package/src/components/providers/ProviderCard.tsx +83 -36
- package/src/components/proxy-viewer/ConversationGroup.tsx +1 -1
- package/src/components/proxy-viewer/ConversationHeader.tsx +4 -5
- package/.output/public/assets/ProxyViewerContainer-Dppr2zGE.js +0 -106
- package/.output/public/assets/index-BskTYcAH.css +0 -1
- package/.output/public/assets/index-DRHfTEM5.js +0 -1
package/.output/server/_ssr/{ProxyViewerContainer-CGX-1aUr.mjs → ProxyViewerContainer-CYmNmQK9.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
|
|
2
|
-
import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as DeleteInspectorGroupsResponseSchema, o as GroupEvidenceExportResultSchema, q as DeleteInspectorGroupResponseSchema, z as createPendingProviderTestResults, B as ProviderTestResultsSchema, E as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, F as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, u as maskApiKey, v as PATH_V1_MESSAGES, w as PATH_V1_CHAT_COMPLETIONS, x as PATH_V1_RESPONSES, r as providerHasContextMetadata, t as findProviderModelMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, H as resolveProviderContextWindow, j as getSessionPath, y as previewUpstreamUrl, K as KnowledgeCandidateSchema, J as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-
|
|
2
|
+
import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as DeleteInspectorGroupsResponseSchema, o as GroupEvidenceExportResultSchema, q as DeleteInspectorGroupResponseSchema, z as createPendingProviderTestResults, B as ProviderTestResultsSchema, E as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, F as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, u as maskApiKey, v as PATH_V1_MESSAGES, w as PATH_V1_CHAT_COMPLETIONS, x as PATH_V1_RESPONSES, r as providerHasContextMetadata, t as findProviderModelMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, H as resolveProviderContextWindow, j as getSessionPath, y as previewUpstreamUrl, K as KnowledgeCandidateSchema, J as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-CYjIsElo.mjs";
|
|
3
3
|
import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
|
|
4
4
|
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
5
5
|
import { c as clsx } from "../_libs/clsx.mjs";
|
|
@@ -9,7 +9,7 @@ import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
|
9
9
|
import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
10
10
|
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
11
11
|
import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
|
|
12
|
-
import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, S as Search, U as Upload, D as Download, F as FileBraces,
|
|
12
|
+
import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, R as RefreshCw, c as Trash2, S as Search, U as Upload, D as Download, F as FileBraces, P as Plus, A as ArrowLeft, d as ChevronUp, e as Copy, f as ChevronsLeft, g as ChevronLeft, h as ChevronRight, i as ChevronsRight, j as Clapperboard, k as Flag, l as Siren, m as Timer, G as Gauge, L as LoaderCircle, n as Layers, o as Settings, M as Monitor, p as Scan, q as CircleAlert, r as Terminal, s as ArrowUpRight, t as ArrowDownRight, u as Cpu, v as FolderOpen, B as Bell, w as Clock3, x as ShieldAlert, E as EyeOff, y as Eye, z as ExternalLink, H as RotateCw, J as Clock, K as Pencil, N as MessageSquare, Z as Zap, W as Wrench, O as Brain, Q as Minus, V as CircleCheckBig, Y as CircleQuestionMark, _ as Server, $ as Lock, a0 as Wifi, a1 as WifiOff, a2 as CircleX, a3 as ShieldCheck, a4 as Save, a5 as FileSearch, a6 as CloudUpload, a7 as OctagonAlert, a8 as Radio, a9 as Globe, aa as FileTerminal, ab as ChevronsUp, ac as ChevronsDown, ad as FileDiff, ae as History, af as RotateCcw, ag as GitCompareArrows, ah as ArrowUp, ai as ArrowDown, aj as Ellipsis, ak as CodeXml, al as Blocks, am as MousePointerClick, an as FileText, ao as Rows3, ap as Columns2 } from "../_libs/lucide-react.mjs";
|
|
13
13
|
import { u as union, d as object, a as array, l as literal, b as string, n as number, c as boolean, _ as _enum } from "../_libs/zod.mjs";
|
|
14
14
|
import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
|
|
15
15
|
import { R as Root2$1, L as List, T as Trigger$2, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
|
|
@@ -1650,7 +1650,7 @@ function ConversationHeader({
|
|
|
1650
1650
|
type: "button",
|
|
1651
1651
|
onClick: handleClearClick,
|
|
1652
1652
|
"aria-label": `Clear group (${totalCalls} request${totalCalls !== 1 ? "s" : ""})`,
|
|
1653
|
-
title: "Clear this group",
|
|
1653
|
+
title: "Clear this group from the current view",
|
|
1654
1654
|
className: HEADER_ACTION_BUTTON_CLASS$1,
|
|
1655
1655
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" })
|
|
1656
1656
|
}
|
|
@@ -1677,8 +1677,8 @@ function ConversationHeader({
|
|
|
1677
1677
|
{
|
|
1678
1678
|
open: confirmOpen,
|
|
1679
1679
|
onOpenChange: setConfirmOpen,
|
|
1680
|
-
title: "Clear this group?",
|
|
1681
|
-
description: `This will
|
|
1680
|
+
title: "Clear this group from the current view?",
|
|
1681
|
+
description: `This will hide ${totalCalls} request${totalCalls !== 1 ? "s" : ""} from the current view. Stored logs remain reloadable.`,
|
|
1682
1682
|
confirmLabel: "Clear",
|
|
1683
1683
|
variant: "destructive",
|
|
1684
1684
|
onConfirm: () => {
|
|
@@ -2302,27 +2302,27 @@ function useCopyFeedback(text) {
|
|
|
2302
2302
|
return { copied, copy };
|
|
2303
2303
|
}
|
|
2304
2304
|
const LazyCompareDrawer = reactExports.lazy(
|
|
2305
|
-
() => import("./CompareDrawer-
|
|
2305
|
+
() => import("./CompareDrawer-DAYrKHKe.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
2306
2306
|
);
|
|
2307
2307
|
const LazyReplayDialog = reactExports.lazy(
|
|
2308
|
-
() => import("./ReplayDialog-
|
|
2308
|
+
() => import("./ReplayDialog-CdKvdXxk.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
2309
2309
|
);
|
|
2310
2310
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
2311
|
-
() => import("./RequestAnatomy-
|
|
2311
|
+
() => import("./RequestAnatomy-BtmTUq7O.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
2312
2312
|
);
|
|
2313
2313
|
const LazyResponseView = reactExports.lazy(
|
|
2314
|
-
() => import("./ResponseView-
|
|
2314
|
+
() => import("./ResponseView-DuD_z5hd.mjs").then((m) => ({ default: m.ResponseView }))
|
|
2315
2315
|
);
|
|
2316
2316
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
2317
|
-
() => import("./StreamingChunkSequence-
|
|
2317
|
+
() => import("./StreamingChunkSequence-DpIV2wt_.mjs").then((m) => ({
|
|
2318
2318
|
default: m.StreamingChunkSequence
|
|
2319
2319
|
}))
|
|
2320
2320
|
);
|
|
2321
2321
|
const LazyJsonViewer = reactExports.lazy(
|
|
2322
|
-
() => import("./json-viewer-
|
|
2322
|
+
() => import("./json-viewer-gcNJEB7y.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
2323
2323
|
);
|
|
2324
2324
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
2325
|
-
() => import("./json-viewer-
|
|
2325
|
+
() => import("./json-viewer-gcNJEB7y.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
2326
2326
|
);
|
|
2327
2327
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
2328
2328
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -8327,6 +8327,40 @@ function ProviderEndpointSummary({
|
|
|
8327
8327
|
children
|
|
8328
8328
|
] });
|
|
8329
8329
|
}
|
|
8330
|
+
function providerHasEndpoint(value) {
|
|
8331
|
+
return value !== void 0 && value !== "";
|
|
8332
|
+
}
|
|
8333
|
+
function providerTestTargets(provider) {
|
|
8334
|
+
const targets = [];
|
|
8335
|
+
if (providerHasEndpoint(provider.anthropicBaseUrl)) {
|
|
8336
|
+
targets.push("Anthropic");
|
|
8337
|
+
}
|
|
8338
|
+
if (providerHasEndpoint(provider.openaiBaseUrl)) {
|
|
8339
|
+
targets.push("Chat");
|
|
8340
|
+
}
|
|
8341
|
+
if (providerHasEndpoint(provider.openaiResponsesBaseUrl)) {
|
|
8342
|
+
targets.push("Responses");
|
|
8343
|
+
}
|
|
8344
|
+
return targets;
|
|
8345
|
+
}
|
|
8346
|
+
function ProviderTestCoverage({ provider }) {
|
|
8347
|
+
const targets = providerTestTargets(provider);
|
|
8348
|
+
if (targets.length === 0) {
|
|
8349
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "Test requires at least one configured endpoint." });
|
|
8350
|
+
}
|
|
8351
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
8352
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Test covers" }),
|
|
8353
|
+
targets.map((target) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8354
|
+
"span",
|
|
8355
|
+
{
|
|
8356
|
+
className: "rounded border border-border/70 bg-muted/25 px-1.5 py-0.5 text-foreground/80",
|
|
8357
|
+
children: target
|
|
8358
|
+
},
|
|
8359
|
+
target
|
|
8360
|
+
)),
|
|
8361
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "non-stream + stream" })
|
|
8362
|
+
] });
|
|
8363
|
+
}
|
|
8330
8364
|
function getErrorIcon(type) {
|
|
8331
8365
|
const iconProps = { className: "size-3", strokeWidth: 2 };
|
|
8332
8366
|
switch (type) {
|
|
@@ -8650,30 +8684,30 @@ function ProviderCard({
|
|
|
8650
8684
|
}
|
|
8651
8685
|
)
|
|
8652
8686
|
] }),
|
|
8653
|
-
provider.anthropicBaseUrl
|
|
8687
|
+
providerHasEndpoint(provider.anthropicBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8654
8688
|
ProviderEndpointSummary,
|
|
8655
8689
|
{
|
|
8656
|
-
label: "Anthropic",
|
|
8690
|
+
label: "Test: Anthropic",
|
|
8657
8691
|
baseUrl: provider.anthropicBaseUrl,
|
|
8658
8692
|
endpoint: PATH_V1_MESSAGES,
|
|
8659
8693
|
providerName: provider.name,
|
|
8660
8694
|
children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.anthropic })
|
|
8661
8695
|
}
|
|
8662
8696
|
),
|
|
8663
|
-
provider.openaiBaseUrl
|
|
8697
|
+
providerHasEndpoint(provider.openaiBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8664
8698
|
ProviderEndpointSummary,
|
|
8665
8699
|
{
|
|
8666
|
-
label: "
|
|
8700
|
+
label: "Test: Chat",
|
|
8667
8701
|
baseUrl: provider.openaiBaseUrl,
|
|
8668
8702
|
endpoint: PATH_V1_CHAT_COMPLETIONS,
|
|
8669
8703
|
providerName: provider.name,
|
|
8670
8704
|
children: testResults !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderFormatTestStatus, { results: testResults.openaiChat })
|
|
8671
8705
|
}
|
|
8672
8706
|
),
|
|
8673
|
-
provider.openaiResponsesBaseUrl
|
|
8707
|
+
providerHasEndpoint(provider.openaiResponsesBaseUrl) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8674
8708
|
ProviderEndpointSummary,
|
|
8675
8709
|
{
|
|
8676
|
-
label: "
|
|
8710
|
+
label: "Test: Responses",
|
|
8677
8711
|
baseUrl: provider.openaiResponsesBaseUrl,
|
|
8678
8712
|
endpoint: PATH_V1_RESPONSES,
|
|
8679
8713
|
providerName: provider.name,
|
|
@@ -8717,49 +8751,52 @@ function ProviderCard({
|
|
|
8717
8751
|
] }, modelName)) })
|
|
8718
8752
|
] }) })
|
|
8719
8753
|
] }),
|
|
8720
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-1 border-t", children: [
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8754
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 pt-1 border-t sm:flex-row sm:items-center sm:justify-between", children: [
|
|
8755
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ProviderTestCoverage, { provider }),
|
|
8756
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
8757
|
+
onTest !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
8758
|
+
Button,
|
|
8759
|
+
{
|
|
8760
|
+
variant: "outline",
|
|
8761
|
+
size: "sm",
|
|
8762
|
+
onClick: () => onTest(provider.id),
|
|
8763
|
+
className: "text-xs h-7 gap-1",
|
|
8764
|
+
disabled: isTesting ?? false,
|
|
8765
|
+
children: [
|
|
8766
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: `size-3 ${isTesting ?? false ? "animate-spin" : ""}` }),
|
|
8767
|
+
isTesting ?? false ? testingTimeLeft !== void 0 ? `Testing (${testingTimeLeft}s)` : "Testing..." : "Test"
|
|
8768
|
+
]
|
|
8769
|
+
}
|
|
8770
|
+
),
|
|
8771
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
8772
|
+
Button,
|
|
8773
|
+
{
|
|
8774
|
+
variant: "outline",
|
|
8775
|
+
size: "sm",
|
|
8776
|
+
onClick: () => onEdit(provider),
|
|
8777
|
+
className: "text-xs h-7 gap-1",
|
|
8778
|
+
disabled: isTesting ?? false,
|
|
8779
|
+
children: [
|
|
8780
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3" }),
|
|
8781
|
+
"Edit"
|
|
8782
|
+
]
|
|
8783
|
+
}
|
|
8784
|
+
),
|
|
8785
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
8786
|
+
Button,
|
|
8787
|
+
{
|
|
8788
|
+
variant: "outline",
|
|
8789
|
+
size: "sm",
|
|
8790
|
+
onClick: () => onDelete(provider.id),
|
|
8791
|
+
className: "text-xs h-7 gap-1 text-destructive hover:text-destructive",
|
|
8792
|
+
disabled: isTesting ?? false,
|
|
8793
|
+
children: [
|
|
8794
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3" }),
|
|
8795
|
+
"Delete"
|
|
8796
|
+
]
|
|
8797
|
+
}
|
|
8798
|
+
)
|
|
8799
|
+
] })
|
|
8763
8800
|
] })
|
|
8764
8801
|
]
|
|
8765
8802
|
}
|
|
@@ -13704,6 +13741,7 @@ function ProxyViewer({
|
|
|
13704
13741
|
onSessionChange,
|
|
13705
13742
|
onModelChange,
|
|
13706
13743
|
onClearAll,
|
|
13744
|
+
onReloadSession,
|
|
13707
13745
|
onClearGroup,
|
|
13708
13746
|
onNotify,
|
|
13709
13747
|
onImportLogs,
|
|
@@ -13829,6 +13867,8 @@ function ProxyViewer({
|
|
|
13829
13867
|
const comparisonPredecessors = reactExports.useMemo(() => buildValidPredecessors(groups), [groups]);
|
|
13830
13868
|
const exportActionVisibility = getExportActionVisibility(captureMode, logs.length);
|
|
13831
13869
|
const isPinnedSessionPage = pinnedSessionId !== void 0;
|
|
13870
|
+
const canClearCurrentView = logs.length > 0;
|
|
13871
|
+
const reloadSessionLabel = logs.length === 0 ? "Load" : "Reload";
|
|
13832
13872
|
const sessionInputValue = selectedSession === "__all__" ? "" : selectedSession;
|
|
13833
13873
|
const sessionSelectValue = selectedSession === "__all__" || sessions.includes(selectedSession) ? selectedSession : "__typed__";
|
|
13834
13874
|
const activeScopeLabel = hasSessionContext && sessionContextScope !== null ? truncateSessionId(sessionContextScope.label) : selectedSession === "__all__" ? "All sessions" : truncateSessionId(selectedSession);
|
|
@@ -13864,26 +13904,62 @@ function ProxyViewer({
|
|
|
13864
13904
|
[onSessionChange]
|
|
13865
13905
|
);
|
|
13866
13906
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-background min-h-screen w-full text-foreground", children: [
|
|
13867
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid min-h-screen w-full grid-cols-1 lg:grid-cols-[
|
|
13868
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "bg-background/95 border-b border-white/[0.045] lg:sticky lg:top-0 lg:h-screen lg:overflow-y-auto lg:border-b-0 lg:border-
|
|
13907
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid min-h-screen w-full grid-cols-1 lg:grid-cols-[minmax(0,1fr)_340px] xl:grid-cols-[minmax(0,1fr)_360px]", children: [
|
|
13908
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "bg-background/95 order-1 border-b border-white/[0.045] lg:sticky lg:top-0 lg:order-2 lg:h-screen lg:overflow-y-auto lg:border-b-0 lg:border-l lg:border-white/[0.055]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 p-4", children: [
|
|
13869
13909
|
/* @__PURE__ */ jsxRuntimeExports.jsx(BrandHeader, { compact: true, crabEntrancePhase }),
|
|
13870
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
13871
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
13872
|
-
|
|
13873
|
-
SidebarMetric,
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
|
|
13877
|
-
|
|
13878
|
-
|
|
13879
|
-
|
|
13880
|
-
|
|
13881
|
-
|
|
13882
|
-
|
|
13883
|
-
|
|
13884
|
-
|
|
13885
|
-
|
|
13886
|
-
|
|
13910
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(SidebarPanel, { label: "Session", children: [
|
|
13911
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
13912
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarMetric, { label: "Requests", value: logs.length }),
|
|
13913
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarMetric, { label: "Sessions", value: sessions.length }),
|
|
13914
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13915
|
+
SidebarMetric,
|
|
13916
|
+
{
|
|
13917
|
+
label: "Input",
|
|
13918
|
+
value: formatTokens(hasSessionContext ? sessionContextTotalIn : totalIn)
|
|
13919
|
+
}
|
|
13920
|
+
),
|
|
13921
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13922
|
+
SidebarMetric,
|
|
13923
|
+
{
|
|
13924
|
+
label: "Output",
|
|
13925
|
+
value: formatTokens(hasSessionContext ? sessionContextTotalOut : totalOut)
|
|
13926
|
+
}
|
|
13927
|
+
)
|
|
13928
|
+
] }),
|
|
13929
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 grid grid-cols-2 gap-2", children: [
|
|
13930
|
+
onReloadSession !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13931
|
+
"button",
|
|
13932
|
+
{
|
|
13933
|
+
type: "button",
|
|
13934
|
+
onClick: onReloadSession,
|
|
13935
|
+
disabled: isLoading,
|
|
13936
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 min-w-0 items-center justify-center gap-1.5 rounded-md px-2 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
13937
|
+
title: "Load stored logs for this session",
|
|
13938
|
+
children: [
|
|
13939
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: cn("size-3.5", isLoading && "animate-spin") }),
|
|
13940
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: reloadSessionLabel })
|
|
13941
|
+
]
|
|
13942
|
+
}
|
|
13943
|
+
),
|
|
13944
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13945
|
+
"button",
|
|
13946
|
+
{
|
|
13947
|
+
type: "button",
|
|
13948
|
+
onClick: onClearAll,
|
|
13949
|
+
disabled: !canClearCurrentView,
|
|
13950
|
+
className: cn(
|
|
13951
|
+
"bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 min-w-0 items-center justify-center gap-1.5 rounded-md px-2 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
13952
|
+
onReloadSession === void 0 && "col-span-2"
|
|
13953
|
+
),
|
|
13954
|
+
title: "Clear the current view. Stored logs remain reloadable.",
|
|
13955
|
+
children: [
|
|
13956
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" }),
|
|
13957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Clear view" })
|
|
13958
|
+
]
|
|
13959
|
+
}
|
|
13960
|
+
)
|
|
13961
|
+
] })
|
|
13962
|
+
] }),
|
|
13887
13963
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Workspace", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-black/20 rounded-md px-3 py-2 shadow-[inset_0_1px_0_rgba(255,255,255,0.035)]", children: [
|
|
13888
13964
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13889
13965
|
"div",
|
|
@@ -13957,7 +14033,7 @@ function ProxyViewer({
|
|
|
13957
14033
|
] })
|
|
13958
14034
|
] }) })
|
|
13959
14035
|
] }) }),
|
|
13960
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("main", { className: "min-w-0", children: [
|
|
14036
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("main", { className: "order-2 min-w-0 lg:order-1", children: [
|
|
13961
14037
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-background/95 shadow-[0_12px_36px_rgba(0,0,0,0.18),inset_0_-1px_0_rgba(255,255,255,0.045)] sticky top-0 z-30 px-4 py-3 lg:px-5", children: [
|
|
13962
14038
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
13963
14039
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-[180px] flex-1", children: [
|
|
@@ -14022,16 +14098,31 @@ function ProxyViewer({
|
|
|
14022
14098
|
] })
|
|
14023
14099
|
}
|
|
14024
14100
|
),
|
|
14101
|
+
onReloadSession !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
14102
|
+
"button",
|
|
14103
|
+
{
|
|
14104
|
+
type: "button",
|
|
14105
|
+
onClick: onReloadSession,
|
|
14106
|
+
disabled: isLoading,
|
|
14107
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
14108
|
+
title: "Reload this session from stored logs",
|
|
14109
|
+
children: [
|
|
14110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: cn("size-3.5", isLoading && "animate-spin") }),
|
|
14111
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: reloadSessionLabel })
|
|
14112
|
+
]
|
|
14113
|
+
}
|
|
14114
|
+
),
|
|
14025
14115
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
14026
14116
|
"button",
|
|
14027
14117
|
{
|
|
14028
14118
|
type: "button",
|
|
14029
14119
|
onClick: onClearAll,
|
|
14030
|
-
|
|
14031
|
-
|
|
14120
|
+
disabled: !canClearCurrentView,
|
|
14121
|
+
className: "bg-white/[0.035] hover:bg-white/[0.065] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
14122
|
+
title: "Clear the current view. Stored logs remain reloadable.",
|
|
14032
14123
|
children: [
|
|
14033
14124
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" }),
|
|
14034
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Clear" })
|
|
14125
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Clear view" })
|
|
14035
14126
|
]
|
|
14036
14127
|
}
|
|
14037
14128
|
)
|
|
@@ -14044,24 +14135,45 @@ function ProxyViewer({
|
|
|
14044
14135
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-4 lg:px-5", children: [
|
|
14045
14136
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SessionOpeningSlate, { stats: slateStats }),
|
|
14046
14137
|
logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.045),0_18px_52px_rgba(0,0,0,0.18)] mx-auto max-w-xl space-y-4 rounded-[8px] px-4 py-8", children: [
|
|
14047
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: isLoading ? "Loading session data..." : "
|
|
14138
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: isLoading ? "Loading session data..." : "No logs loaded for this session" }),
|
|
14048
14139
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "inline-block max-w-full rounded bg-muted px-3 py-1 font-mono text-xs break-all", children: truncateSessionId(selectedSession) }),
|
|
14049
14140
|
sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-left", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }) }),
|
|
14050
|
-
!isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
14051
|
-
"
|
|
14052
|
-
" ",
|
|
14053
|
-
|
|
14054
|
-
|
|
14055
|
-
|
|
14056
|
-
|
|
14057
|
-
|
|
14058
|
-
|
|
14059
|
-
|
|
14060
|
-
|
|
14061
|
-
|
|
14141
|
+
!isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3 text-xs", children: [
|
|
14142
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Stored logs may still be available." }),
|
|
14143
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2", children: [
|
|
14144
|
+
onReloadSession !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
14145
|
+
"button",
|
|
14146
|
+
{
|
|
14147
|
+
type: "button",
|
|
14148
|
+
onClick: onReloadSession,
|
|
14149
|
+
className: "bg-white/[0.045] hover:bg-white/[0.075] inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors hover:text-foreground",
|
|
14150
|
+
children: [
|
|
14151
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3.5" }),
|
|
14152
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Load session" })
|
|
14153
|
+
]
|
|
14154
|
+
}
|
|
14155
|
+
),
|
|
14156
|
+
hideSessionFilter ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
14157
|
+
"a",
|
|
14158
|
+
{
|
|
14159
|
+
href: "/",
|
|
14160
|
+
className: "inline-flex h-8 items-center rounded-md px-3 text-xs text-muted-foreground underline transition-colors hover:text-foreground",
|
|
14161
|
+
children: "Back to all sessions"
|
|
14162
|
+
}
|
|
14163
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
14164
|
+
"button",
|
|
14165
|
+
{
|
|
14166
|
+
type: "button",
|
|
14167
|
+
onClick: () => onSessionChange("__all__"),
|
|
14168
|
+
className: "inline-flex h-8 items-center rounded-md px-3 text-xs text-muted-foreground underline transition-colors hover:text-foreground",
|
|
14169
|
+
children: "Show all sessions"
|
|
14170
|
+
}
|
|
14171
|
+
)
|
|
14172
|
+
] })
|
|
14062
14173
|
] })
|
|
14063
14174
|
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.045),0_18px_52px_rgba(0,0,0,0.18)] mx-auto max-w-2xl space-y-4 rounded-[8px] px-4 py-8", children: [
|
|
14064
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No
|
|
14175
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No logs loaded in the current view." }),
|
|
14176
|
+
sessions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mx-auto max-w-xl text-xs leading-relaxed text-muted-foreground", children: "Pick a session from the filter panel to load stored logs on demand." }),
|
|
14065
14177
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
14066
14178
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "ANTHROPIC_BASE_URL=http://localhost:9527/proxy <your-tool>" }),
|
|
14067
14179
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "OPENAI_BASE_URL=http://localhost:9527/proxy <your-tool>" })
|
|
@@ -14127,6 +14239,7 @@ const LogCursorPageSchema = object({
|
|
|
14127
14239
|
oldestLogId: number().int().positive().nullable(),
|
|
14128
14240
|
newestLogId: number().int().positive().nullable()
|
|
14129
14241
|
});
|
|
14242
|
+
const SessionsResponseSchema = array(string());
|
|
14130
14243
|
function buildSessionMembershipEvidence(groups, sessionId) {
|
|
14131
14244
|
const memberships = [];
|
|
14132
14245
|
for (const group of groups) {
|
|
@@ -14172,6 +14285,8 @@ const DEBOUNCE_MS = 100;
|
|
|
14172
14285
|
const HASH_SCROLL_ATTEMPTS = 12;
|
|
14173
14286
|
const HASH_HIGHLIGHT_MS = 1800;
|
|
14174
14287
|
const SESSION_PAGE_LIMIT = 100;
|
|
14288
|
+
const SESSION_RELOAD_PAGE_LIMIT = 500;
|
|
14289
|
+
const MAX_SESSION_RELOAD_PAGES = 200;
|
|
14175
14290
|
function buildLogsStreamUrl(sessionId) {
|
|
14176
14291
|
const params = new URLSearchParams();
|
|
14177
14292
|
if (sessionId !== void 0) {
|
|
@@ -14181,11 +14296,11 @@ function buildLogsStreamUrl(sessionId) {
|
|
|
14181
14296
|
const query = params.toString();
|
|
14182
14297
|
return query.length > 0 ? `/api/logs/stream?${query}` : "/api/logs/stream";
|
|
14183
14298
|
}
|
|
14184
|
-
function buildSessionLogsPageUrl(sessionId, request) {
|
|
14299
|
+
function buildSessionLogsPageUrl(sessionId, request, limit = SESSION_PAGE_LIMIT) {
|
|
14185
14300
|
const params = new URLSearchParams({
|
|
14186
14301
|
cursor: "1",
|
|
14187
14302
|
compact: "1",
|
|
14188
|
-
limit: String(
|
|
14303
|
+
limit: String(limit),
|
|
14189
14304
|
sessionId
|
|
14190
14305
|
});
|
|
14191
14306
|
switch (request.kind) {
|
|
@@ -14220,12 +14335,23 @@ function mergeLogsById(previousLogs, incomingLogs) {
|
|
|
14220
14335
|
}
|
|
14221
14336
|
return [...byId.values()].sort((left, right) => left.id - right.id);
|
|
14222
14337
|
}
|
|
14338
|
+
function mergeSessionIds(previousSessions, incomingSessions) {
|
|
14339
|
+
const sessions = /* @__PURE__ */ new Set();
|
|
14340
|
+
for (const session of previousSessions) {
|
|
14341
|
+
if (session !== "") sessions.add(session);
|
|
14342
|
+
}
|
|
14343
|
+
for (const session of incomingSessions) {
|
|
14344
|
+
if (session !== "") sessions.add(session);
|
|
14345
|
+
}
|
|
14346
|
+
return [...sessions].sort();
|
|
14347
|
+
}
|
|
14223
14348
|
function ProxyViewerContainer({
|
|
14224
14349
|
initialSessionId
|
|
14225
14350
|
} = {}) {
|
|
14226
14351
|
const [allLogs, setAllLogs] = reactExports.useState([]);
|
|
14227
14352
|
const [selectedSession, setSelectedSession] = reactExports.useState(initialSessionId ?? "__all__");
|
|
14228
14353
|
const [selectedModel, setSelectedModel] = reactExports.useState("__all__");
|
|
14354
|
+
const [knownSessions, setKnownSessions] = reactExports.useState([]);
|
|
14229
14355
|
const { notice, showToast, dismissToast } = useTransientToast();
|
|
14230
14356
|
const [streamInitialized, setStreamInitialized] = reactExports.useState(initialSessionId === void 0);
|
|
14231
14357
|
const [logPage, setLogPage] = reactExports.useState(null);
|
|
@@ -14249,8 +14375,17 @@ function ProxyViewerContainer({
|
|
|
14249
14375
|
() => filterLogs(allLogs, selectedSession, selectedModel),
|
|
14250
14376
|
[allLogs, selectedSession, selectedModel]
|
|
14251
14377
|
);
|
|
14252
|
-
const sessions = reactExports.useMemo(
|
|
14378
|
+
const sessions = reactExports.useMemo(
|
|
14379
|
+
() => mergeSessionIds(knownSessions, extractSessions(allLogs)),
|
|
14380
|
+
[allLogs, knownSessions]
|
|
14381
|
+
);
|
|
14253
14382
|
const models = reactExports.useMemo(() => extractModels(allLogs), [allLogs]);
|
|
14383
|
+
const refreshSessions = reactExports.useCallback(() => {
|
|
14384
|
+
void fetchJson("/api/sessions", SessionsResponseSchema).then((sessionIds) => {
|
|
14385
|
+
setKnownSessions((prev) => mergeSessionIds(prev, sessionIds));
|
|
14386
|
+
}).catch(() => {
|
|
14387
|
+
});
|
|
14388
|
+
}, []);
|
|
14254
14389
|
const flushUpdates = reactExports.useCallback(() => {
|
|
14255
14390
|
flushTimerRef.current = null;
|
|
14256
14391
|
const updates = pendingUpdatesRef.current;
|
|
@@ -14301,9 +14436,14 @@ function ProxyViewerContainer({
|
|
|
14301
14436
|
logIndexRef.current = buildLogIndex(nextLogs);
|
|
14302
14437
|
return nextLogs;
|
|
14303
14438
|
});
|
|
14439
|
+
setKnownSessions((prev) => mergeSessionIds(prev, extractSessions(update.logs)));
|
|
14304
14440
|
setStreamInitialized(true);
|
|
14305
14441
|
dismissToast();
|
|
14306
14442
|
} else if (update.type === "update") {
|
|
14443
|
+
setKnownSessions((prev) => {
|
|
14444
|
+
if (update.log.sessionId === null || update.log.sessionId === "") return prev;
|
|
14445
|
+
return mergeSessionIds(prev, [update.log.sessionId]);
|
|
14446
|
+
});
|
|
14307
14447
|
scheduleUpdate(update.log);
|
|
14308
14448
|
}
|
|
14309
14449
|
} catch {
|
|
@@ -14346,6 +14486,56 @@ function ProxyViewerContainer({
|
|
|
14346
14486
|
},
|
|
14347
14487
|
[dismissToast, initialSessionId, showErrorToast]
|
|
14348
14488
|
);
|
|
14489
|
+
const reloadSessionLogs = reactExports.useCallback(
|
|
14490
|
+
(sessionId) => {
|
|
14491
|
+
const requestId = sessionPageRequestIdRef.current + 1;
|
|
14492
|
+
sessionPageRequestIdRef.current = requestId;
|
|
14493
|
+
setSessionPageLoading(true);
|
|
14494
|
+
dismissToast();
|
|
14495
|
+
void (async () => {
|
|
14496
|
+
const collected = [];
|
|
14497
|
+
let page = await fetchJson(
|
|
14498
|
+
buildSessionLogsPageUrl(sessionId, { kind: "oldest" }, SESSION_RELOAD_PAGE_LIMIT),
|
|
14499
|
+
LogCursorPageSchema
|
|
14500
|
+
);
|
|
14501
|
+
collected.push(...page.logs);
|
|
14502
|
+
let loadedPages = 1;
|
|
14503
|
+
while (page.hasNewer && page.newestLogId !== null && loadedPages < MAX_SESSION_RELOAD_PAGES) {
|
|
14504
|
+
page = await fetchJson(
|
|
14505
|
+
buildSessionLogsPageUrl(
|
|
14506
|
+
sessionId,
|
|
14507
|
+
{ kind: "newer", afterLogId: page.newestLogId },
|
|
14508
|
+
SESSION_RELOAD_PAGE_LIMIT
|
|
14509
|
+
),
|
|
14510
|
+
LogCursorPageSchema
|
|
14511
|
+
);
|
|
14512
|
+
collected.push(...page.logs);
|
|
14513
|
+
loadedPages += 1;
|
|
14514
|
+
}
|
|
14515
|
+
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
14516
|
+
setAllLogs((prev) => {
|
|
14517
|
+
const next = mergeLogsById(prev, collected);
|
|
14518
|
+
logIndexRef.current = buildLogIndex(next);
|
|
14519
|
+
return next;
|
|
14520
|
+
});
|
|
14521
|
+
setKnownSessions((prev) => mergeSessionIds(prev, [sessionId]));
|
|
14522
|
+
setSessionPageLoading(false);
|
|
14523
|
+
if (page.hasNewer) {
|
|
14524
|
+
showToast({
|
|
14525
|
+
message: `Loaded ${String(collected.length)} logs for this session. More history is available.`,
|
|
14526
|
+
tone: "success"
|
|
14527
|
+
});
|
|
14528
|
+
} else {
|
|
14529
|
+
dismissToast();
|
|
14530
|
+
}
|
|
14531
|
+
})().catch((err) => {
|
|
14532
|
+
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
14533
|
+
setSessionPageLoading(false);
|
|
14534
|
+
showErrorToast(err instanceof Error ? err.message : "Failed to reload session logs");
|
|
14535
|
+
});
|
|
14536
|
+
},
|
|
14537
|
+
[dismissToast, showErrorToast, showToast]
|
|
14538
|
+
);
|
|
14349
14539
|
reactExports.useEffect(() => {
|
|
14350
14540
|
if (initialSessionId === void 0) {
|
|
14351
14541
|
setSessionMemberships([]);
|
|
@@ -14367,10 +14557,18 @@ function ProxyViewerContainer({
|
|
|
14367
14557
|
cancelled = true;
|
|
14368
14558
|
};
|
|
14369
14559
|
}, [initialSessionId]);
|
|
14560
|
+
reactExports.useEffect(() => {
|
|
14561
|
+
refreshSessions();
|
|
14562
|
+
}, [refreshSessions]);
|
|
14370
14563
|
reactExports.useEffect(() => {
|
|
14371
14564
|
if (initialSessionId === void 0) return;
|
|
14372
14565
|
loadSessionPage({ kind: "newest" });
|
|
14373
14566
|
}, [initialSessionId, loadSessionPage]);
|
|
14567
|
+
reactExports.useEffect(() => {
|
|
14568
|
+
if (initialSessionId !== void 0) return;
|
|
14569
|
+
if (selectedSession === "__all__") return;
|
|
14570
|
+
reloadSessionLogs(selectedSession);
|
|
14571
|
+
}, [initialSessionId, reloadSessionLogs, selectedSession]);
|
|
14374
14572
|
reactExports.useEffect(() => {
|
|
14375
14573
|
if (initialSessionId !== void 0) return void 0;
|
|
14376
14574
|
connectSSE();
|
|
@@ -14438,57 +14636,42 @@ function ProxyViewerContainer({
|
|
|
14438
14636
|
};
|
|
14439
14637
|
}, [logs.length]);
|
|
14440
14638
|
const handleClearAll = reactExports.useCallback(() => {
|
|
14441
|
-
|
|
14442
|
-
|
|
14443
|
-
|
|
14444
|
-
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
});
|
|
14452
|
-
if (!res.ok) {
|
|
14453
|
-
showErrorToast("Failed to clear logs");
|
|
14454
|
-
return;
|
|
14455
|
-
}
|
|
14456
|
-
logIndexRef.current.clear();
|
|
14457
|
-
setAllLogs([]);
|
|
14458
|
-
dismissToast();
|
|
14459
|
-
} catch (err) {
|
|
14460
|
-
showErrorToast(err instanceof Error ? err.message : "Unknown error clearing logs");
|
|
14461
|
-
}
|
|
14462
|
-
})();
|
|
14463
|
-
}, [allLogs, dismissToast, initialSessionId, showErrorToast]);
|
|
14639
|
+
const clearedSessions = extractSessions(allLogs);
|
|
14640
|
+
logIndexRef.current.clear();
|
|
14641
|
+
setAllLogs([]);
|
|
14642
|
+
setLogPage(null);
|
|
14643
|
+
setKnownSessions((prev) => mergeSessionIds(prev, clearedSessions));
|
|
14644
|
+
showToast({
|
|
14645
|
+
message: "Cleared the current view. Stored logs are still reloadable.",
|
|
14646
|
+
tone: "success"
|
|
14647
|
+
});
|
|
14648
|
+
}, [allLogs, showToast]);
|
|
14464
14649
|
const handleClearGroup = reactExports.useCallback(
|
|
14465
14650
|
(ids) => {
|
|
14466
14651
|
if (ids.length === 0) return;
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
return;
|
|
14477
|
-
}
|
|
14478
|
-
const idSet = new Set(ids);
|
|
14479
|
-
setAllLogs((prev) => {
|
|
14480
|
-
const remaining = prev.filter((l) => !idSet.has(l.id));
|
|
14481
|
-
logIndexRef.current = buildLogIndex(remaining);
|
|
14482
|
-
return remaining;
|
|
14483
|
-
});
|
|
14484
|
-
dismissToast();
|
|
14485
|
-
} catch (err) {
|
|
14486
|
-
showErrorToast(err instanceof Error ? err.message : "Unknown error clearing group");
|
|
14487
|
-
}
|
|
14488
|
-
})();
|
|
14652
|
+
const idSet = new Set(ids);
|
|
14653
|
+
setAllLogs((prev) => {
|
|
14654
|
+
const removed = prev.filter((log) => idSet.has(log.id));
|
|
14655
|
+
const remaining = prev.filter((log) => !idSet.has(log.id));
|
|
14656
|
+
setKnownSessions((known) => mergeSessionIds(known, extractSessions(removed)));
|
|
14657
|
+
logIndexRef.current = buildLogIndex(remaining);
|
|
14658
|
+
return remaining;
|
|
14659
|
+
});
|
|
14660
|
+
showToast({ message: "Cleared this group from the current view.", tone: "success" });
|
|
14489
14661
|
},
|
|
14490
|
-
[
|
|
14662
|
+
[showToast]
|
|
14491
14663
|
);
|
|
14664
|
+
const handleReloadSession = reactExports.useCallback(() => {
|
|
14665
|
+
if (initialSessionId !== void 0) {
|
|
14666
|
+
loadSessionPage({ kind: "newest" });
|
|
14667
|
+
return;
|
|
14668
|
+
}
|
|
14669
|
+
if (selectedSession === "__all__") {
|
|
14670
|
+
refreshSessions();
|
|
14671
|
+
return;
|
|
14672
|
+
}
|
|
14673
|
+
reloadSessionLogs(selectedSession);
|
|
14674
|
+
}, [initialSessionId, loadSessionPage, refreshSessions, reloadSessionLogs, selectedSession]);
|
|
14492
14675
|
const handleImportLogs = reactExports.useCallback(
|
|
14493
14676
|
async (file) => {
|
|
14494
14677
|
const formData = new FormData();
|
|
@@ -14572,10 +14755,11 @@ function ProxyViewerContainer({
|
|
|
14572
14755
|
onSessionChange: setSelectedSession,
|
|
14573
14756
|
onModelChange: setSelectedModel,
|
|
14574
14757
|
onClearAll: handleClearAll,
|
|
14758
|
+
onReloadSession: initialSessionId !== void 0 || selectedSession !== "__all__" ? handleReloadSession : void 0,
|
|
14575
14759
|
onClearGroup: handleClearGroup,
|
|
14576
14760
|
onNotify: showToast,
|
|
14577
14761
|
onImportLogs: initialSessionId === void 0 ? handleImportLogs : void 0,
|
|
14578
|
-
isLoading: initialSessionId === void 0 ? !streamInitialized : sessionPageLoading,
|
|
14762
|
+
isLoading: initialSessionId === void 0 ? !streamInitialized || sessionPageLoading : sessionPageLoading,
|
|
14579
14763
|
pagination,
|
|
14580
14764
|
sessionMemberships,
|
|
14581
14765
|
viewMode,
|