@tonyclaw/agent-inspector 2.0.3 → 2.0.5
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-3nRwtk8J.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-CbW5VRER.js +101 -0
- package/.output/public/assets/ReplayDialog-Cl62N9PI.js +1 -0
- package/.output/public/assets/RequestAnatomy-DgQWGvjs.js +1 -0
- package/.output/public/assets/ResponseView-Cvc-ct4E.js +1 -0
- package/.output/public/assets/StreamingChunkSequence-BCQaCAIe.js +1 -0
- package/.output/public/assets/_sessionId-CcD_aLGq.js +1 -0
- package/.output/public/assets/index-B_dffD3u.js +1 -0
- package/.output/public/assets/index-CX796gvi.css +1 -0
- package/.output/public/assets/{json-viewer-BbU0n8eM.js → json-viewer-IXejqXB0.js} +1 -1
- package/.output/public/assets/{main-CZT_F-gu.js → main-2NlGzgOe.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +181 -114
- package/.output/server/{_sessionId-B-s9P7fJ.mjs → _sessionId-DWCTasJU.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-C08L3UOO.mjs → CompareDrawer-DhrN1uC2.mjs} +6 -6
- package/.output/server/_ssr/{ProxyViewerContainer-CMWl3Ijy.mjs → ProxyViewerContainer-DRl51s_n.mjs} +910 -186
- package/.output/server/_ssr/{ReplayDialog-CPDo9_G5.mjs → ReplayDialog-BQT_ygxC.mjs} +240 -14
- package/.output/server/_ssr/{RequestAnatomy-D9wt_K1E.mjs → RequestAnatomy-DS2tZOgq.mjs} +5 -5
- package/.output/server/_ssr/{ResponseView-DXaL7nY3.mjs → ResponseView-e0kL2C3x.mjs} +25 -21
- package/.output/server/_ssr/{StreamingChunkSequence-B_hudZyb.mjs → StreamingChunkSequence-BJG-m7xs.mjs} +3 -3
- package/.output/server/_ssr/{index-CuE_BN86.mjs → index-Dea3OeRw.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-Ci6kkjde.mjs → json-viewer-DDU55MLK.mjs} +3 -3
- package/.output/server/_ssr/{router-BemxgIg7.mjs → router-Dl7oh0zx.mjs} +164 -82
- package/.output/server/_tanstack-start-manifest_v-m-FJNBVf.mjs +4 -0
- package/.output/server/index.mjs +70 -70
- package/package.json +1 -1
- package/src/components/OnboardingBanner.tsx +11 -19
- package/src/components/ProxyViewer.tsx +26 -16
- package/src/components/ProxyViewerContainer.tsx +2 -1
- package/src/components/providers/ProviderCard.tsx +6 -20
- package/src/components/providers/SettingsDialog.tsx +140 -3
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +731 -72
- package/src/components/proxy-viewer/AnswerMarkdown.tsx +16 -0
- package/src/components/proxy-viewer/CompareDrawer.tsx +4 -2
- 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 +21 -36
- package/src/components/proxy-viewer/ReplayDialog.tsx +190 -8
- package/src/components/proxy-viewer/ResponseView.tsx +4 -8
- package/src/components/proxy-viewer/ToolTraceEvents.tsx +37 -17
- package/src/components/proxy-viewer/TurnGroup.tsx +18 -2
- 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/anthropic/ResponseView.tsx +2 -2
- package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +10 -14
- package/src/components/proxy-viewer/replayComparison.ts +131 -0
- package/src/components/proxy-viewer/useKeyboardNavigation.ts +64 -22
- package/src/components/proxy-viewer/viewerState.ts +14 -2
- package/src/knowledge/candidateStore.ts +32 -1
- 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/src/routes/api/knowledge.candidates.$candidateId.ts +50 -0
- package/src/routes/api/knowledge.sessions.$sessionId.candidates.ts +12 -2
- package/.output/public/assets/ProxyViewerContainer-Da0jpBkp.js +0 -101
- package/.output/public/assets/ReplayDialog-CxUk_TF0.js +0 -1
- package/.output/public/assets/RequestAnatomy-DIlzjgjJ.js +0 -1
- package/.output/public/assets/ResponseView-DQCuKJ1G.js +0 -1
- package/.output/public/assets/StreamingChunkSequence-DHk4SGGL.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
- package/.output/server/_tanstack-start-manifest_v--L1_b4sd.mjs +0 -4
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, {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getCandidate, updateCandidateDraft } from "../../knowledge/candidateStore";
|
|
4
|
+
import { KnowledgeCandidateSchema, KnowledgeCandidateTypeSchema } from "../../knowledge/types";
|
|
5
|
+
|
|
6
|
+
const CandidateUpdateSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
type: KnowledgeCandidateTypeSchema.optional(),
|
|
9
|
+
title: z.string().trim().min(1).max(160).optional(),
|
|
10
|
+
content: z.string().trim().min(1).max(12000).optional(),
|
|
11
|
+
tags: z.array(z.string().trim().min(1).max(64)).max(24).optional(),
|
|
12
|
+
})
|
|
13
|
+
.strict();
|
|
14
|
+
|
|
15
|
+
const CandidateUpdateResponseSchema = z.object({
|
|
16
|
+
candidate: KnowledgeCandidateSchema,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export type CandidateUpdateResponse = z.infer<typeof CandidateUpdateResponseSchema>;
|
|
20
|
+
|
|
21
|
+
export const Route = createFileRoute("/api/knowledge/candidates/$candidateId")({
|
|
22
|
+
server: {
|
|
23
|
+
handlers: {
|
|
24
|
+
PATCH: async ({ params, request }: { params: { candidateId: string }; request: Request }) => {
|
|
25
|
+
const existing = getCandidate(params.candidateId);
|
|
26
|
+
if (existing === null) {
|
|
27
|
+
return Response.json({ error: "Knowledge candidate not found" }, { status: 404 });
|
|
28
|
+
}
|
|
29
|
+
if (existing.status === "promoted") {
|
|
30
|
+
return Response.json(
|
|
31
|
+
{ error: "Promoted knowledge candidates cannot be edited" },
|
|
32
|
+
{ status: 409 },
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const raw: unknown = await request.json().catch(() => null);
|
|
37
|
+
const parsed = CandidateUpdateSchema.safeParse(raw);
|
|
38
|
+
if (!parsed.success) {
|
|
39
|
+
return Response.json({ error: parsed.error.message }, { status: 400 });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const updated = updateCandidateDraft(existing.id, parsed.data);
|
|
43
|
+
if (updated === null) {
|
|
44
|
+
return Response.json({ error: "Knowledge candidate update failed" }, { status: 409 });
|
|
45
|
+
}
|
|
46
|
+
return Response.json({ candidate: updated } satisfies CandidateUpdateResponse);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { createFileRoute } from "@tanstack/react-router";
|
|
2
|
-
import { getFilteredLogs } from "../../proxy/store";
|
|
2
|
+
import { getFilteredLogs, getLogSessionId } from "../../proxy/store";
|
|
3
3
|
import { distillSessionCandidates } from "../../knowledge/distiller";
|
|
4
4
|
import { saveCandidates } from "../../knowledge/candidateStore";
|
|
5
5
|
|
|
6
|
+
function getCandidateScopeId(log: ReturnType<typeof getFilteredLogs>[number]): string {
|
|
7
|
+
return getLogSessionId(log) ?? "default";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function getLogsForCandidateScope(scopeId: string): ReturnType<typeof getFilteredLogs> {
|
|
11
|
+
const direct = getFilteredLogs(scopeId);
|
|
12
|
+
if (direct.length > 0) return direct;
|
|
13
|
+
return getFilteredLogs().filter((log) => getCandidateScopeId(log) === scopeId);
|
|
14
|
+
}
|
|
15
|
+
|
|
6
16
|
export const Route = createFileRoute("/api/knowledge/sessions/$sessionId/candidates")({
|
|
7
17
|
server: {
|
|
8
18
|
handlers: {
|
|
9
19
|
POST: ({ params }: { params: { sessionId: string } }) => {
|
|
10
|
-
const logs =
|
|
20
|
+
const logs = getLogsForCandidateScope(params.sessionId);
|
|
11
21
|
const candidates = saveCandidates(distillSessionCandidates(params.sessionId, logs));
|
|
12
22
|
return Response.json({ candidates });
|
|
13
23
|
},
|