@tonyclaw/agent-inspector 2.0.3 → 2.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-D5A4bTfV.js → CompareDrawer-BCH_fsLm.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-D85_UANk.js +101 -0
- package/.output/public/assets/{ReplayDialog-CxUk_TF0.js → ReplayDialog-DTeaHHit.js} +1 -1
- package/.output/public/assets/RequestAnatomy-DZ8grAih.js +1 -0
- package/.output/public/assets/ResponseView-Cldm6RCi.js +1 -0
- package/.output/public/assets/{StreamingChunkSequence-DHk4SGGL.js → StreamingChunkSequence-3x4p-yT7.js} +1 -1
- package/.output/public/assets/_sessionId-YqWFBu6d.js +1 -0
- package/.output/public/assets/index-BIw2H6jO.js +1 -0
- package/.output/public/assets/index-CobXD0yH.css +1 -0
- package/.output/public/assets/{json-viewer-BbU0n8eM.js → json-viewer-BrzjD7qI.js} +1 -1
- package/.output/public/assets/{main-CZT_F-gu.js → main-mgxeUdZQ.js} +2 -2
- package/.output/server/{_sessionId-B-s9P7fJ.mjs → _sessionId-C4xsxIWm.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-C08L3UOO.mjs → CompareDrawer-DuWEpqQ7.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-CMWl3Ijy.mjs → ProxyViewerContainer-Cckz5qKu.mjs} +167 -87
- package/.output/server/_ssr/{ReplayDialog-CPDo9_G5.mjs → ReplayDialog-BDRcr8E5.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-D9wt_K1E.mjs → RequestAnatomy-BoO2_Ij0.mjs} +4 -4
- package/.output/server/_ssr/{ResponseView-DXaL7nY3.mjs → ResponseView-DZiPBxvO.mjs} +20 -16
- package/.output/server/_ssr/{StreamingChunkSequence-B_hudZyb.mjs → StreamingChunkSequence-D-be7KEL.mjs} +3 -3
- package/.output/server/_ssr/{index-CuE_BN86.mjs → index-5RImHKfu.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-Ci6kkjde.mjs → json-viewer-aJhb93ZK.mjs} +2 -2
- package/.output/server/_ssr/{router-BemxgIg7.mjs → router-Dgkv5nKP.mjs} +22 -14
- package/.output/server/{_tanstack-start-manifest_v--L1_b4sd.mjs → _tanstack-start-manifest_v-B8rrWXjr.mjs} +1 -1
- package/.output/server/index.mjs +61 -61
- package/package.json +1 -1
- package/src/components/ProxyViewer.tsx +25 -15
- package/src/components/ProxyViewerContainer.tsx +2 -1
- package/src/components/providers/SettingsDialog.tsx +45 -1
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +103 -45
- package/src/components/proxy-viewer/AnswerMarkdown.tsx +16 -0
- package/src/components/proxy-viewer/ConversationGroup.tsx +12 -0
- package/src/components/proxy-viewer/ConversationHeader.tsx +6 -6
- package/src/components/proxy-viewer/LogEntry.tsx +5 -5
- package/src/components/proxy-viewer/LogEntryHeader.tsx +9 -14
- package/src/components/proxy-viewer/ResponseView.tsx +2 -6
- package/src/components/proxy-viewer/ToolTraceEvents.tsx +3 -4
- package/src/components/proxy-viewer/TurnGroup.tsx +4 -0
- package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +2 -2
- package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +6 -12
- package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +10 -14
- package/src/lib/runtimeConfig.ts +6 -0
- package/src/lib/timeDisplay.ts +22 -0
- package/src/lib/useOnboarding.ts +2 -0
- package/src/lib/useStripConfig.ts +16 -0
- package/src/proxy/config.ts +3 -0
- package/src/routes/api/config.ts +5 -1
- package/.output/public/assets/ProxyViewerContainer-Da0jpBkp.js +0 -101
- package/.output/public/assets/RequestAnatomy-DIlzjgjJ.js +0 -1
- package/.output/public/assets/ResponseView-DQCuKJ1G.js +0 -1
- package/.output/public/assets/_sessionId-dY1TTl7N.js +0 -1
- package/.output/public/assets/index-D7wwbwly.css +0 -1
- package/.output/public/assets/index-FqQZbfl2.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Brain, ChevronDown, ChevronRight, Terminal } from "lucide-react";
|
|
2
2
|
import { type JSX, memo, useState } from "react";
|
|
3
|
-
import ReactMarkdown from "react-markdown";
|
|
4
3
|
import type { ResponseContentBlockType } from "../../../../proxy/schemas";
|
|
4
|
+
import { AnswerMarkdown } from "../../AnswerMarkdown";
|
|
5
5
|
import { Badge } from "../../../ui/badge";
|
|
6
6
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../../ui/collapsible";
|
|
7
7
|
import { JsonViewer } from "../../../ui/json-viewer";
|
|
@@ -30,9 +30,7 @@ function SystemReminderBlock({ text }: { text: string }): JSX.Element {
|
|
|
30
30
|
</CollapsibleTrigger>
|
|
31
31
|
<CollapsibleContent>
|
|
32
32
|
<div className="pl-4 pt-1">
|
|
33
|
-
<
|
|
34
|
-
<ReactMarkdown>{text}</ReactMarkdown>
|
|
35
|
-
</div>
|
|
33
|
+
<AnswerMarkdown text={text} />
|
|
36
34
|
</div>
|
|
37
35
|
</CollapsibleContent>
|
|
38
36
|
</Collapsible>
|
|
@@ -50,11 +48,7 @@ export const TextBlock = memo(function TextBlock({ text }: { text: string }): JS
|
|
|
50
48
|
return (
|
|
51
49
|
<div className="space-y-2">
|
|
52
50
|
{thinking !== null && <ThinkingBlock thinking={thinking} />}
|
|
53
|
-
{remainingText.length > 0 &&
|
|
54
|
-
<div className="prose prose-sm dark:prose-invert max-w-none [&_pre]:bg-muted [&_pre]:text-foreground [&_code]:text-[0.8em] [&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1">
|
|
55
|
-
<ReactMarkdown>{remainingText}</ReactMarkdown>
|
|
56
|
-
</div>
|
|
57
|
-
)}
|
|
51
|
+
{remainingText.length > 0 && <AnswerMarkdown text={remainingText} />}
|
|
58
52
|
{thinking === null && remainingText.length === 0 && (
|
|
59
53
|
<p className="text-xs text-muted-foreground italic">Empty text block</p>
|
|
60
54
|
)}
|
|
@@ -113,9 +107,9 @@ export const ToolUseBlock = memo(function ToolUseBlock({
|
|
|
113
107
|
|
|
114
108
|
return (
|
|
115
109
|
<Collapsible open={open} onOpenChange={setOpen}>
|
|
116
|
-
<div className="border-l-2 border-
|
|
117
|
-
<CollapsibleTrigger className="flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-
|
|
118
|
-
<Terminal className="size-3.5 text-
|
|
110
|
+
<div className="border-l-2 border-sky-400/25 my-1">
|
|
111
|
+
<CollapsibleTrigger className="flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-sky-400/[0.04] transition-colors rounded-r-sm group">
|
|
112
|
+
<Terminal className="size-3.5 text-sky-400/70 shrink-0" />
|
|
119
113
|
<Badge variant="outline" className="text-[10px] font-mono px-1.5 py-0 h-4">
|
|
120
114
|
{name}
|
|
121
115
|
</Badge>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { StopCircle, Terminal, Zap } from "lucide-react";
|
|
2
2
|
import { memo, useState, type JSX } from "react";
|
|
3
|
-
import ReactMarkdown from "react-markdown";
|
|
4
3
|
import type { OpenAIResponse, OpenAIToolCall } from "../../../../proxy/schemas";
|
|
5
4
|
import { formatTokens } from "../../../../lib/utils";
|
|
5
|
+
import { AnswerMarkdown } from "../../AnswerMarkdown";
|
|
6
6
|
import { Badge } from "../../../ui/badge";
|
|
7
7
|
import { JsonViewer } from "../../../ui/json-viewer";
|
|
8
8
|
import { safeJsonValue } from "../../../ui/json-viewer-bulk";
|
|
@@ -29,8 +29,8 @@ function parseToolArguments(raw: string | undefined): unknown {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/** One collapsible tool_use row, mirroring the Anthropic ToolUseBlock visual
|
|
32
|
-
* treatment (Terminal icon,
|
|
33
|
-
* scrollable JsonViewer). */
|
|
32
|
+
* treatment (Terminal icon, soft tool accent, name as a Badge, JSON input in
|
|
33
|
+
* a scrollable JsonViewer). */
|
|
34
34
|
function OpenAIToolCallBlock({ call }: { call: OpenAIToolCall }): JSX.Element {
|
|
35
35
|
const [open, setOpen] = useState(false);
|
|
36
36
|
const name = call.function.name ?? "(unnamed tool)";
|
|
@@ -38,9 +38,9 @@ function OpenAIToolCallBlock({ call }: { call: OpenAIToolCall }): JSX.Element {
|
|
|
38
38
|
|
|
39
39
|
return (
|
|
40
40
|
<Collapsible open={open} onOpenChange={setOpen}>
|
|
41
|
-
<div className="border-l-2 border-
|
|
42
|
-
<CollapsibleTrigger className="flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-
|
|
43
|
-
<Terminal className="size-3.5 text-
|
|
41
|
+
<div className="border-l-2 border-sky-400/25 my-1">
|
|
42
|
+
<CollapsibleTrigger className="flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-sky-400/[0.04] transition-colors rounded-r-sm group">
|
|
43
|
+
<Terminal className="size-3.5 text-sky-400/70 shrink-0" />
|
|
44
44
|
<Badge variant="outline" className="text-[10px] font-mono px-1.5 py-0 h-4">
|
|
45
45
|
{name}
|
|
46
46
|
</Badge>
|
|
@@ -133,11 +133,7 @@ export const OpenAIResponseView = memo(function OpenAIResponseView({
|
|
|
133
133
|
<div className="space-y-2">
|
|
134
134
|
{/* Show thinking from tags only if no reasoning_content field */}
|
|
135
135
|
{thinking !== null && !hasReasoningField && <ThinkingBlock thinking={thinking} />}
|
|
136
|
-
{remainingText.length > 0 &&
|
|
137
|
-
<div className="prose prose-sm dark:prose-invert max-w-none [&_pre]:bg-muted [&_pre]:text-foreground [&_code]:text-[0.8em] [&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1">
|
|
138
|
-
<ReactMarkdown>{remainingText}</ReactMarkdown>
|
|
139
|
-
</div>
|
|
140
|
-
)}
|
|
136
|
+
{remainingText.length > 0 && <AnswerMarkdown text={remainingText} />}
|
|
141
137
|
</div>
|
|
142
138
|
);
|
|
143
139
|
})()}
|
|
@@ -146,10 +142,10 @@ export const OpenAIResponseView = memo(function OpenAIResponseView({
|
|
|
146
142
|
<OpenAIToolCallBlock key={call.id ?? `tc-${i}`} call={call} />
|
|
147
143
|
))}
|
|
148
144
|
{message?.function_call !== null && message?.function_call !== undefined && (
|
|
149
|
-
<div className="border border-
|
|
150
|
-
<div className="text-xs text-
|
|
145
|
+
<div className="border border-sky-400/20 rounded-md p-3 bg-muted/20">
|
|
146
|
+
<div className="text-xs text-sky-400/80 font-mono mb-1">function_call</div>
|
|
151
147
|
<div className="font-mono text-xs">
|
|
152
|
-
<span className="text-
|
|
148
|
+
<span className="text-foreground/80">{message.function_call.name}</span>
|
|
153
149
|
<span className="text-muted-foreground">({message.function_call.arguments})</span>
|
|
154
150
|
</div>
|
|
155
151
|
</div>
|
package/src/lib/runtimeConfig.ts
CHANGED
|
@@ -2,6 +2,11 @@ import { z } from "zod";
|
|
|
2
2
|
|
|
3
3
|
export const DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS = 10;
|
|
4
4
|
export const MAX_SLOW_RESPONSE_THRESHOLD_SECONDS = 600;
|
|
5
|
+
export const DEFAULT_TIME_DISPLAY_FORMAT = "time";
|
|
6
|
+
|
|
7
|
+
export const TimeDisplayFormatSchema = z.enum(["time", "full"]);
|
|
8
|
+
|
|
9
|
+
export type TimeDisplayFormat = z.infer<typeof TimeDisplayFormatSchema>;
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
12
|
* Schema for the runtime proxy config. Shared between server
|
|
@@ -20,6 +25,7 @@ export const RuntimeConfigSchema = z.object({
|
|
|
20
25
|
.min(0)
|
|
21
26
|
.max(MAX_SLOW_RESPONSE_THRESHOLD_SECONDS)
|
|
22
27
|
.default(DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS),
|
|
28
|
+
timeDisplayFormat: TimeDisplayFormatSchema.default(DEFAULT_TIME_DISPLAY_FORMAT),
|
|
23
29
|
});
|
|
24
30
|
|
|
25
31
|
export type RuntimeConfig = z.infer<typeof RuntimeConfigSchema>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TimeDisplayFormat } from "./runtimeConfig";
|
|
2
|
+
|
|
3
|
+
export function formatTimestamp(iso: string, format: TimeDisplayFormat): string {
|
|
4
|
+
switch (format) {
|
|
5
|
+
case "full":
|
|
6
|
+
return iso;
|
|
7
|
+
case "time":
|
|
8
|
+
return new Date(iso).toLocaleTimeString([], {
|
|
9
|
+
hour: "2-digit",
|
|
10
|
+
minute: "2-digit",
|
|
11
|
+
second: "2-digit",
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function formatTimestampRange(
|
|
17
|
+
startedAt: string,
|
|
18
|
+
endedAt: string,
|
|
19
|
+
format: TimeDisplayFormat,
|
|
20
|
+
): string {
|
|
21
|
+
return `${formatTimestamp(startedAt, format)} - ${formatTimestamp(endedAt, format)}`;
|
|
22
|
+
}
|
package/src/lib/useOnboarding.ts
CHANGED
|
@@ -2,6 +2,7 @@ import useSWR, { type SWRResponse, useSWRConfig } from "swr";
|
|
|
2
2
|
import { fetchJson } from "./apiClient";
|
|
3
3
|
import {
|
|
4
4
|
DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
5
|
+
DEFAULT_TIME_DISPLAY_FORMAT,
|
|
5
6
|
RuntimeConfigSchema,
|
|
6
7
|
type RuntimeConfig,
|
|
7
8
|
} from "./runtimeConfig";
|
|
@@ -66,6 +67,7 @@ export function useOnboarding(): UseOnboarding {
|
|
|
66
67
|
hasSeenOnboarding: true,
|
|
67
68
|
slowResponseThresholdSeconds:
|
|
68
69
|
response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
70
|
+
timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
|
|
69
71
|
},
|
|
70
72
|
rollbackOnError: true,
|
|
71
73
|
revalidate: false,
|
|
@@ -2,7 +2,9 @@ import useSWR, { type SWRResponse, useSWRConfig } from "swr";
|
|
|
2
2
|
import { fetchJson } from "./apiClient";
|
|
3
3
|
import {
|
|
4
4
|
DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
5
|
+
DEFAULT_TIME_DISPLAY_FORMAT,
|
|
5
6
|
RuntimeConfigSchema,
|
|
7
|
+
type TimeDisplayFormat,
|
|
6
8
|
type RuntimeConfig,
|
|
7
9
|
} from "./runtimeConfig";
|
|
8
10
|
|
|
@@ -36,10 +38,12 @@ export async function setRuntimeConfig(patch: Partial<RuntimeConfig>): Promise<R
|
|
|
36
38
|
export type UseStripConfig = {
|
|
37
39
|
strip: boolean;
|
|
38
40
|
slowResponseThresholdSeconds: number;
|
|
41
|
+
timeDisplayFormat: TimeDisplayFormat;
|
|
39
42
|
isLoading: boolean;
|
|
40
43
|
isError: boolean;
|
|
41
44
|
setStrip: (next: boolean) => Promise<void>;
|
|
42
45
|
setSlowResponseThresholdSeconds: (next: number) => Promise<void>;
|
|
46
|
+
setTimeDisplayFormat: (next: TimeDisplayFormat) => Promise<void>;
|
|
43
47
|
};
|
|
44
48
|
|
|
45
49
|
/**
|
|
@@ -64,12 +68,14 @@ export function useStripConfig(): UseStripConfig {
|
|
|
64
68
|
const strip = response.data?.stripClaudeCodeBillingHeader ?? false;
|
|
65
69
|
const slowResponseThresholdSeconds =
|
|
66
70
|
response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS;
|
|
71
|
+
const timeDisplayFormat = response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT;
|
|
67
72
|
|
|
68
73
|
const optimisticConfig = (patch: Partial<RuntimeConfig>): RuntimeConfig => ({
|
|
69
74
|
stripClaudeCodeBillingHeader: response.data?.stripClaudeCodeBillingHeader ?? false,
|
|
70
75
|
hasSeenOnboarding: response.data?.hasSeenOnboarding ?? false,
|
|
71
76
|
slowResponseThresholdSeconds:
|
|
72
77
|
response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
78
|
+
timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
|
|
73
79
|
...patch,
|
|
74
80
|
});
|
|
75
81
|
|
|
@@ -97,12 +103,22 @@ export function useStripConfig(): UseStripConfig {
|
|
|
97
103
|
);
|
|
98
104
|
};
|
|
99
105
|
|
|
106
|
+
const setTimeDisplayFormat = async (next: TimeDisplayFormat): Promise<void> => {
|
|
107
|
+
await globalMutate(STRIP_CONFIG_SWR_KEY, setRuntimeConfig({ timeDisplayFormat: next }), {
|
|
108
|
+
optimisticData: optimisticConfig({ timeDisplayFormat: next }),
|
|
109
|
+
rollbackOnError: true,
|
|
110
|
+
revalidate: false,
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
|
|
100
114
|
return {
|
|
101
115
|
strip,
|
|
102
116
|
slowResponseThresholdSeconds,
|
|
117
|
+
timeDisplayFormat,
|
|
103
118
|
isLoading: response.isLoading,
|
|
104
119
|
isError: response.error !== undefined,
|
|
105
120
|
setStrip,
|
|
106
121
|
setSlowResponseThresholdSeconds,
|
|
122
|
+
setTimeDisplayFormat,
|
|
107
123
|
};
|
|
108
124
|
}
|
package/src/proxy/config.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { logger } from "./logger";
|
|
|
12
12
|
import { getDataDir } from "./dataDir";
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
15
|
+
DEFAULT_TIME_DISPLAY_FORMAT,
|
|
15
16
|
RuntimeConfigSchema,
|
|
16
17
|
type RuntimeConfig,
|
|
17
18
|
} from "../lib/runtimeConfig";
|
|
@@ -79,6 +80,7 @@ function resolveInitialConfig(): RuntimeConfig {
|
|
|
79
80
|
stripClaudeCodeBillingHeader: true,
|
|
80
81
|
hasSeenOnboarding: false,
|
|
81
82
|
slowResponseThresholdSeconds: DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
83
|
+
timeDisplayFormat: DEFAULT_TIME_DISPLAY_FORMAT,
|
|
82
84
|
};
|
|
83
85
|
}
|
|
84
86
|
|
|
@@ -87,6 +89,7 @@ function resolveInitialConfig(): RuntimeConfig {
|
|
|
87
89
|
stripClaudeCodeBillingHeader: false,
|
|
88
90
|
hasSeenOnboarding: false,
|
|
89
91
|
slowResponseThresholdSeconds: DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
92
|
+
timeDisplayFormat: DEFAULT_TIME_DISPLAY_FORMAT,
|
|
90
93
|
};
|
|
91
94
|
}
|
|
92
95
|
|
package/src/routes/api/config.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { createFileRoute } from "@tanstack/react-router";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
MAX_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
5
|
+
TimeDisplayFormatSchema,
|
|
6
|
+
} from "../../lib/runtimeConfig";
|
|
4
7
|
import { getConfig, setConfig, RuntimeConfigSchema } from "../../proxy/config";
|
|
5
8
|
|
|
6
9
|
// Partial schema for PATCH: at least one known field must be present.
|
|
@@ -14,6 +17,7 @@ const RuntimeConfigPatchSchema = z
|
|
|
14
17
|
.min(0)
|
|
15
18
|
.max(MAX_SLOW_RESPONSE_THRESHOLD_SECONDS)
|
|
16
19
|
.optional(),
|
|
20
|
+
timeDisplayFormat: TimeDisplayFormatSchema.optional(),
|
|
17
21
|
})
|
|
18
22
|
.strict()
|
|
19
23
|
.refine((v) => Object.keys(v).length > 0, {
|