@tonyclaw/agent-inspector 3.0.23 → 3.0.25
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-CFedvZHU.js → CompareDrawer-BnvOPwpe.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-DcqFqo1m.js +127 -0
- package/.output/public/assets/{ReplayDialog-X-fRSKAu.js → ReplayDialog-BJgoQWdW.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-S8qB5nVg.js → RequestAnatomy-CpBZEHnM.js} +1 -1
- package/.output/public/assets/{ResponseView-_rcOWSwJ.js → ResponseView-CWmyRb2M.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-Bc15AVpN.js → StreamingChunkSequence-BWhC8bwx.js} +1 -1
- package/.output/public/assets/{_sessionId-Cz-HW2Wf.js → _sessionId-Cq-2OqUU.js} +1 -1
- package/.output/public/assets/{index-CEgwWY3E.js → index-BKi9IRtV.js} +71 -7
- package/.output/public/assets/index-BMYuDL5X.css +1 -0
- package/.output/public/assets/{index-CXYBU0j8.js → index-Cf8O0Oos.js} +1 -1
- package/.output/public/assets/{index-ClKXooQd.js → index-DdgTJ4QJ.js} +1 -1
- package/.output/public/assets/{json-viewer-QfU4qGdd.js → json-viewer-Bqu_4hmm.js} +1 -1
- package/.output/server/_libs/lucide-react.mjs +306 -246
- package/.output/server/{_sessionId-9FAmYZVf.mjs → _sessionId-Ba7H3Gjw.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-BLKjOzwD.mjs → CompareDrawer-aH59Ab6x.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-Dcs2Mq8l.mjs → ProxyViewerContainer-By-I0tJv.mjs} +1791 -1259
- package/.output/server/_ssr/{ReplayDialog-oyiF4LIo.mjs → ReplayDialog-BO4Vy0et.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-DkyQXSuj.mjs → RequestAnatomy-FtOr7vSS.mjs} +3 -3
- package/.output/server/_ssr/{ResponseView-3NTDEiDh.mjs → ResponseView-cvw6ajue.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-DRq-5Bgn.mjs → StreamingChunkSequence-Oc8S2kD6.mjs} +3 -3
- package/.output/server/_ssr/{index-dtMiNUa1.mjs → index-BDRlQheR.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-BhUwicvp.mjs → json-viewer-Cd6trhQr.mjs} +3 -3
- package/.output/server/_ssr/{router-DO0OntUK.mjs → router-bofP-Ekl.mjs} +296 -91
- package/.output/server/{_tanstack-start-manifest_v-DO5v3BHY.mjs → _tanstack-start-manifest_v-BPuf86qB.mjs} +1 -1
- package/.output/server/index.mjs +76 -76
- package/package.json +3 -2
- package/src/components/ProxyViewer.tsx +138 -740
- package/src/components/ProxyViewerContainer.tsx +5 -47
- package/src/components/alerts/AlertsDialog.tsx +6 -2
- package/src/components/inspector-pet/InspectorPet.tsx +390 -0
- package/src/components/inspector-pet/inspectorPetLogic.ts +273 -0
- package/src/components/providers/ProviderCard.tsx +20 -579
- package/src/components/providers/ProviderTestResultsView.tsx +732 -0
- package/src/components/proxy-viewer/LogEntry.tsx +5 -0
- package/src/components/proxy-viewer/LogEntryHeader.tsx +7 -0
- package/src/components/proxy-viewer/ToolTraceEvents.tsx +33 -36
- package/src/components/proxy-viewer/TurnGroup.tsx +1 -5
- package/src/components/proxy-viewer/proxyViewerContainerLogic.ts +46 -0
- package/src/components/proxy-viewer/proxyViewerLogic.ts +469 -0
- package/src/lib/themeMode.ts +45 -0
- package/src/lib/uiScale.ts +112 -0
- package/src/lib/useThemeMode.ts +40 -0
- package/src/lib/useUiScale.ts +52 -0
- package/src/routes/__root.tsx +78 -1
- package/styles/globals.css +403 -24
- package/.output/public/assets/ProxyViewerContainer-BlCrBvdm.js +0 -127
- package/.output/public/assets/index-B_SIQ47i.css +0 -1
|
@@ -39,6 +39,7 @@ import { RequestTools } from "./RequestToolsPanel";
|
|
|
39
39
|
import type { CacheTrendEntry } from "./cacheTrend";
|
|
40
40
|
import { getLogFormatAdapter, resolveLogFormat } from "./log-formats";
|
|
41
41
|
import { LOG_FOCUS_REQUEST_EVENT, readLogFocusRequest, type LogFocusTab } from "./logFocus";
|
|
42
|
+
import type { ToolTraceEvent } from "./viewerState";
|
|
42
43
|
import {
|
|
43
44
|
shouldShowHeadersDiffButton,
|
|
44
45
|
shouldShowHeadersTab,
|
|
@@ -353,6 +354,8 @@ export type LogEntryProps = {
|
|
|
353
354
|
onCompareWithPrevious?: (log: CapturedLog) => void;
|
|
354
355
|
/** Show client PID/project metadata on the log header row. */
|
|
355
356
|
showClientMetadata?: boolean;
|
|
357
|
+
/** Tools called by the response, rendered in the compact log header. */
|
|
358
|
+
toolEvents?: ToolTraceEvent[];
|
|
356
359
|
};
|
|
357
360
|
|
|
358
361
|
function DiffToggleButton({
|
|
@@ -427,6 +430,7 @@ export const LogEntry = memo(function ({
|
|
|
427
430
|
cacheTrend = null,
|
|
428
431
|
onCompareWithPrevious,
|
|
429
432
|
showClientMetadata = true,
|
|
433
|
+
toolEvents = [],
|
|
430
434
|
}: LogEntryProps): JSX.Element {
|
|
431
435
|
const [expanded, setExpanded] = useState<boolean>(false);
|
|
432
436
|
const [replayOpen, setReplayOpen] = useState<boolean>(false);
|
|
@@ -831,6 +835,7 @@ export const LogEntry = memo(function ({
|
|
|
831
835
|
displayNumber={displayNumber}
|
|
832
836
|
messageCount={requestAnalysis.messageCount}
|
|
833
837
|
toolCount={requestAnalysis.toolCount}
|
|
838
|
+
toolEvents={toolEvents}
|
|
834
839
|
expanded={expanded}
|
|
835
840
|
onToggle={handleToggleExpanded}
|
|
836
841
|
cacheTrend={cacheTrend}
|
|
@@ -32,6 +32,8 @@ import { Badge } from "../ui/badge";
|
|
|
32
32
|
import { Button } from "../ui/button";
|
|
33
33
|
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "../ui/tooltip";
|
|
34
34
|
import type { CacheTrend } from "./cacheTrend";
|
|
35
|
+
import { ToolTraceEvents } from "./ToolTraceEvents";
|
|
36
|
+
import type { ToolTraceEvent } from "./viewerState";
|
|
35
37
|
|
|
36
38
|
const STATUS_BADGE_CLASSES: Record<StatusCategory, string> = {
|
|
37
39
|
success: "bg-slate-300/[0.08] text-slate-100 border-transparent",
|
|
@@ -150,6 +152,8 @@ export type LogEntryHeaderProps = {
|
|
|
150
152
|
messageCount?: number | null;
|
|
151
153
|
/** Number of tools defined in the request (supports both Anthropic and OpenAI formats). */
|
|
152
154
|
toolCount?: number | null;
|
|
155
|
+
/** Tools actually called by this response, shown inline with the log telemetry. */
|
|
156
|
+
toolEvents?: ToolTraceEvent[];
|
|
153
157
|
expanded: boolean;
|
|
154
158
|
onToggle: () => void;
|
|
155
159
|
/** Per-log cache token trend (creation + read) relative to the previous log
|
|
@@ -180,6 +184,7 @@ export const LogEntryHeader = memo(function ({
|
|
|
180
184
|
displayNumber,
|
|
181
185
|
messageCount = null,
|
|
182
186
|
toolCount = null,
|
|
187
|
+
toolEvents = [],
|
|
183
188
|
expanded,
|
|
184
189
|
onToggle,
|
|
185
190
|
cacheTrend = null,
|
|
@@ -406,6 +411,8 @@ export const LogEntryHeader = memo(function ({
|
|
|
406
411
|
</span>
|
|
407
412
|
)}
|
|
408
413
|
|
|
414
|
+
<ToolTraceEvents events={toolEvents} />
|
|
415
|
+
|
|
409
416
|
{/* Origin */}
|
|
410
417
|
{log.origin !== null && (
|
|
411
418
|
<span
|
|
@@ -1,67 +1,64 @@
|
|
|
1
|
-
import { type JSX } from "react";
|
|
2
|
-
import {
|
|
1
|
+
import { type JSX, type MouseEvent } from "react";
|
|
2
|
+
import { Wrench } from "lucide-react";
|
|
3
3
|
import type { ToolTraceEvent } from "./viewerState";
|
|
4
4
|
import { dispatchLogFocusRequest } from "./logFocus";
|
|
5
5
|
|
|
6
6
|
type ToolTraceEventsProps = {
|
|
7
7
|
events: ToolTraceEvent[];
|
|
8
|
-
warnings?: readonly string[];
|
|
9
8
|
};
|
|
10
9
|
|
|
11
|
-
const VISIBLE_TOOL_LIMIT =
|
|
10
|
+
const VISIBLE_TOOL_LIMIT = 3;
|
|
12
11
|
|
|
13
12
|
function ToolTraceEventChip({ event }: { event: ToolTraceEvent }): JSX.Element {
|
|
13
|
+
const handleClick = (clickEvent: MouseEvent<HTMLButtonElement>): void => {
|
|
14
|
+
clickEvent.stopPropagation();
|
|
15
|
+
dispatchLogFocusRequest({
|
|
16
|
+
logId: event.logId,
|
|
17
|
+
tab: "response",
|
|
18
|
+
toolCallIndex: event.index,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
14
22
|
return (
|
|
15
23
|
<button
|
|
16
24
|
type="button"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
dispatchLogFocusRequest({
|
|
21
|
-
logId: event.logId,
|
|
22
|
-
tab: "response",
|
|
23
|
-
toolCallIndex: event.index,
|
|
24
|
-
})
|
|
25
|
-
}
|
|
25
|
+
className="inline-flex h-5 min-w-0 max-w-[8.5rem] items-center rounded px-1.5 text-[10px] text-muted-foreground transition-colors hover:bg-background/65 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
26
|
+
onClick={handleClick}
|
|
27
|
+
onKeyDown={(keyEvent) => keyEvent.stopPropagation()}
|
|
26
28
|
aria-label={`Open response tool call ${event.name}`}
|
|
29
|
+
title={event.name}
|
|
27
30
|
>
|
|
28
|
-
<Wrench className="size-3 shrink-0 text-sky-400/65" />
|
|
29
31
|
<span className="min-w-0 truncate font-mono font-semibold">{event.name}</span>
|
|
30
32
|
</button>
|
|
31
33
|
);
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
export function ToolTraceEvents({
|
|
35
|
-
events
|
|
36
|
-
warnings = [],
|
|
37
|
-
}: ToolTraceEventsProps): JSX.Element | null {
|
|
38
|
-
if (events.length === 0 && warnings.length === 0) return null;
|
|
36
|
+
export function ToolTraceEvents({ events }: ToolTraceEventsProps): JSX.Element | null {
|
|
37
|
+
if (events.length === 0) return null;
|
|
39
38
|
const visibleEvents = events.slice(0, VISIBLE_TOOL_LIMIT);
|
|
40
39
|
const hiddenCount = Math.max(0, events.length - visibleEvents.length);
|
|
41
40
|
return (
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)}
|
|
55
|
-
<div className="flex min-w-0 flex-1 items-center gap-1 overflow-hidden">
|
|
41
|
+
<span
|
|
42
|
+
className="inline-flex h-7 min-w-0 max-w-full items-center gap-1 overflow-hidden rounded-md border border-cyan-300/10 bg-cyan-300/[0.055] px-1 sm:max-w-[26rem]"
|
|
43
|
+
role="group"
|
|
44
|
+
aria-label={`${events.length} response tool ${events.length === 1 ? "call" : "calls"}`}
|
|
45
|
+
onClick={(clickEvent) => clickEvent.stopPropagation()}
|
|
46
|
+
onKeyDown={(keyEvent) => keyEvent.stopPropagation()}
|
|
47
|
+
>
|
|
48
|
+
<span className="inline-flex h-5 shrink-0 items-center gap-1 px-1 font-mono text-[9px] font-semibold uppercase text-cyan-300">
|
|
49
|
+
<Wrench className="size-3" />
|
|
50
|
+
Call {events.length}
|
|
51
|
+
</span>
|
|
52
|
+
<span className="flex min-w-0 flex-1 items-center gap-0.5 overflow-hidden">
|
|
56
53
|
{visibleEvents.map((event) => (
|
|
57
54
|
<ToolTraceEventChip key={event.id} event={event} />
|
|
58
55
|
))}
|
|
59
56
|
{hiddenCount > 0 && (
|
|
60
|
-
<span className="inline-flex h-
|
|
57
|
+
<span className="inline-flex h-5 shrink-0 items-center rounded px-1 font-mono text-[10px] font-semibold text-muted-foreground">
|
|
61
58
|
+{hiddenCount}
|
|
62
59
|
</span>
|
|
63
60
|
)}
|
|
64
|
-
</
|
|
65
|
-
</
|
|
61
|
+
</span>
|
|
62
|
+
</span>
|
|
66
63
|
);
|
|
67
64
|
}
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
type LogFocusRequest,
|
|
25
25
|
} from "./logFocus";
|
|
26
26
|
import { ThreadConnector } from "./ThreadConnector";
|
|
27
|
-
import { ToolTraceEvents } from "./ToolTraceEvents";
|
|
28
27
|
import { extractToolTraceEvents, isTurnCollapsible, type TurnEntry } from "./viewerState";
|
|
29
28
|
|
|
30
29
|
function formatElapsed(ms: number): string {
|
|
@@ -358,14 +357,11 @@ export const TurnGroup = memo(function TurnGroup({
|
|
|
358
357
|
timeDisplayFormat={timeDisplayFormat}
|
|
359
358
|
cacheTrend={cacheTrends?.get(log.id) ?? null}
|
|
360
359
|
showClientMetadata={showLogClientMetadata}
|
|
360
|
+
toolEvents={toolEventsByLogId.get(log.id)}
|
|
361
361
|
onCompareWithPrevious={
|
|
362
362
|
comparisonPredecessors.has(log.id) ? onCompareWithPrevious : undefined
|
|
363
363
|
}
|
|
364
364
|
/>
|
|
365
|
-
<ToolTraceEvents
|
|
366
|
-
events={toolEventsByLogId.get(log.id) ?? []}
|
|
367
|
-
warnings={log.warnings ?? []}
|
|
368
|
-
/>
|
|
369
365
|
</div>
|
|
370
366
|
</div>
|
|
371
367
|
);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CapturedLog } from "../../contracts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Filter logs by selected session/model. Both `__all__` and missing values
|
|
5
|
+
* pass through. Returns the input array reference when no log matches the
|
|
6
|
+
* filter, so referential equality is preserved for empty results.
|
|
7
|
+
*/
|
|
8
|
+
export function filterLogs(
|
|
9
|
+
logs: CapturedLog[],
|
|
10
|
+
selectedSession: string,
|
|
11
|
+
selectedModel: string,
|
|
12
|
+
): CapturedLog[] {
|
|
13
|
+
if (selectedSession === "__all__" && selectedModel === "__all__") return logs;
|
|
14
|
+
return logs.filter((l) => {
|
|
15
|
+
if (selectedSession !== "__all__" && l.sessionId !== selectedSession) return false;
|
|
16
|
+
if (selectedModel !== "__all__" && l.model !== selectedModel) return false;
|
|
17
|
+
return true;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function mergeLogsById(
|
|
22
|
+
previousLogs: readonly CapturedLog[],
|
|
23
|
+
incomingLogs: readonly CapturedLog[],
|
|
24
|
+
): CapturedLog[] {
|
|
25
|
+
if (previousLogs.length === 0) return [...incomingLogs];
|
|
26
|
+
if (incomingLogs.length === 0) return [...previousLogs];
|
|
27
|
+
|
|
28
|
+
const byId = new Map<number, CapturedLog>();
|
|
29
|
+
for (const log of previousLogs) byId.set(log.id, log);
|
|
30
|
+
for (const log of incomingLogs) byId.set(log.id, log);
|
|
31
|
+
return [...byId.values()].toSorted((left, right) => left.id - right.id);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function mergeSessionIds(
|
|
35
|
+
previousSessions: readonly string[],
|
|
36
|
+
incomingSessions: readonly string[],
|
|
37
|
+
): string[] {
|
|
38
|
+
const merged = new Set<string>();
|
|
39
|
+
for (const session of previousSessions) {
|
|
40
|
+
if (session !== "") merged.add(session);
|
|
41
|
+
}
|
|
42
|
+
for (const session of incomingSessions) {
|
|
43
|
+
if (session !== "") merged.add(session);
|
|
44
|
+
}
|
|
45
|
+
return [...merged].sort();
|
|
46
|
+
}
|