@tonyclaw/agent-inspector 2.0.39 → 2.0.40

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.
Files changed (31) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-Jfe6M6DQ.js → CompareDrawer-p0uYxW7_.js} +1 -1
  3. package/.output/public/assets/{ProxyViewerContainer-CQKV0Bqq.js → ProxyViewerContainer-BGqeiYKD.js} +26 -26
  4. package/.output/public/assets/{ReplayDialog-B58TbTtY.js → ReplayDialog-TTTVCMe9.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-d4P6JNiP.js → RequestAnatomy-c8ru0pS-.js} +1 -1
  6. package/.output/public/assets/{ResponseView-Bum1a3tG.js → ResponseView-D59jTMy4.js} +1 -1
  7. package/.output/public/assets/{StreamingChunkSequence-CjBDp5E9.js → StreamingChunkSequence-UlAMVF9j.js} +1 -1
  8. package/.output/public/assets/_sessionId-EHPexdPl.js +1 -0
  9. package/.output/public/assets/index-CZP-XfpB.js +1 -0
  10. package/.output/public/assets/{main-DK9PoBjx.js → main-CKYe6UUv.js} +2 -2
  11. package/.output/server/{_sessionId-DjarbXpT.mjs → _sessionId-CkwhOzdS.mjs} +2 -2
  12. package/.output/server/_ssr/{CompareDrawer-C5Z6AlUk.mjs → CompareDrawer-BHDiuYMw.mjs} +2 -2
  13. package/.output/server/_ssr/{ProxyViewerContainer-4pXsBywn.mjs → ProxyViewerContainer-0c2_DBMX.mjs} +29 -6
  14. package/.output/server/_ssr/{ReplayDialog-w1vc1p5e.mjs → ReplayDialog-CTjwzDDH.mjs} +3 -3
  15. package/.output/server/_ssr/{RequestAnatomy-2HaBhsNV.mjs → RequestAnatomy-D36oujv2.mjs} +2 -2
  16. package/.output/server/_ssr/{ResponseView-SO_Y_W85.mjs → ResponseView-ClZ3oODE.mjs} +2 -2
  17. package/.output/server/_ssr/{StreamingChunkSequence-CXEa2DkO.mjs → StreamingChunkSequence-Ck5l4p1m.mjs} +2 -2
  18. package/.output/server/_ssr/{index-DuCGt4a2.mjs → index-DKBYH0TC.mjs} +2 -2
  19. package/.output/server/_ssr/index.mjs +2 -2
  20. package/.output/server/_ssr/{router-D0BaSzkZ.mjs → router-D4I3ZyVS.mjs} +434 -6
  21. package/.output/server/{_tanstack-start-manifest_v-6N4SODyd.mjs → _tanstack-start-manifest_v-D4vSn_wD.mjs} +1 -1
  22. package/.output/server/index.mjs +59 -59
  23. package/package.json +1 -1
  24. package/src/components/proxy-viewer/LogEntry.tsx +15 -1
  25. package/src/components/proxy-viewer/LogEntryHeader.tsx +20 -0
  26. package/src/contracts/log.ts +1 -0
  27. package/src/proxy/logFinalizer.ts +58 -0
  28. package/src/proxy/logSearch.ts +1 -0
  29. package/src/proxy/toolSchemaWarnings.ts +515 -0
  30. package/.output/public/assets/_sessionId-BupV2gtf.js +0 -1
  31. package/.output/public/assets/index-DHSww5em.js +0 -1
@@ -38,100 +38,100 @@ const assets = {
38
38
  "/assets/alibaba-TTwafVwX.svg": {
39
39
  "type": "image/svg+xml",
40
40
  "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
41
- "mtime": "2026-07-01T08:15:03.700Z",
41
+ "mtime": "2026-07-02T01:15:23.247Z",
42
42
  "size": 5915,
43
43
  "path": "../public/assets/alibaba-TTwafVwX.svg"
44
44
  },
45
- "/assets/index-BfGJEb-2.css": {
46
- "type": "text/css; charset=utf-8",
47
- "etag": '"1acc9-JrjZs7fIRGuBr66cqP9miLHcLKk"',
48
- "mtime": "2026-07-01T08:15:03.700Z",
49
- "size": 109769,
50
- "path": "../public/assets/index-BfGJEb-2.css"
51
- },
52
- "/assets/CompareDrawer-Jfe6M6DQ.js": {
45
+ "/assets/CompareDrawer-p0uYxW7_.js": {
53
46
  "type": "text/javascript; charset=utf-8",
54
- "etag": '"49fe-cZOHUuR1k4rWdDq/tpP3ItQh8XQ"',
55
- "mtime": "2026-07-01T08:15:03.700Z",
47
+ "etag": '"49fe-PDyw+vlyo9dEC/B0BR4p7sgHWGc"',
48
+ "mtime": "2026-07-02T01:15:23.247Z",
56
49
  "size": 18942,
57
- "path": "../public/assets/CompareDrawer-Jfe6M6DQ.js"
50
+ "path": "../public/assets/CompareDrawer-p0uYxW7_.js"
58
51
  },
59
- "/assets/ReplayDialog-B58TbTtY.js": {
52
+ "/assets/index-CZP-XfpB.js": {
60
53
  "type": "text/javascript; charset=utf-8",
61
- "etag": '"318c-bhy3YBiteXvsEiEFJJ5jKXid1do"',
62
- "mtime": "2026-07-01T08:15:03.700Z",
63
- "size": 12684,
64
- "path": "../public/assets/ReplayDialog-B58TbTtY.js"
54
+ "etag": '"74-T8zsQO7lllBR44srKw3fW8/4eS4"',
55
+ "mtime": "2026-07-02T01:15:23.247Z",
56
+ "size": 116,
57
+ "path": "../public/assets/index-CZP-XfpB.js"
65
58
  },
66
- "/assets/index-DHSww5em.js": {
59
+ "/assets/RequestAnatomy-c8ru0pS-.js": {
67
60
  "type": "text/javascript; charset=utf-8",
68
- "etag": '"74-XnA+tuBqoE04/VDIU5skdKnqMeo"',
69
- "mtime": "2026-07-01T08:15:03.700Z",
70
- "size": 116,
71
- "path": "../public/assets/index-DHSww5em.js"
61
+ "etag": '"4485-7HJ86QTNO6hp1l7c8bsI7vDnIao"',
62
+ "mtime": "2026-07-02T01:15:23.247Z",
63
+ "size": 17541,
64
+ "path": "../public/assets/RequestAnatomy-c8ru0pS-.js"
72
65
  },
73
- "/assets/minimax-BPMzvuL-.jpeg": {
74
- "type": "image/jpeg",
75
- "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
76
- "mtime": "2026-07-01T08:15:03.700Z",
77
- "size": 6918,
78
- "path": "../public/assets/minimax-BPMzvuL-.jpeg"
66
+ "/assets/index-BfGJEb-2.css": {
67
+ "type": "text/css; charset=utf-8",
68
+ "etag": '"1acc9-JrjZs7fIRGuBr66cqP9miLHcLKk"',
69
+ "mtime": "2026-07-02T01:15:23.247Z",
70
+ "size": 109769,
71
+ "path": "../public/assets/index-BfGJEb-2.css"
79
72
  },
80
- "/assets/main-DK9PoBjx.js": {
73
+ "/assets/ReplayDialog-TTTVCMe9.js": {
81
74
  "type": "text/javascript; charset=utf-8",
82
- "etag": '"517d9-Rb3G8Owiwv/6jNymVmF2TN5klug"',
83
- "mtime": "2026-07-01T08:15:03.700Z",
84
- "size": 333785,
85
- "path": "../public/assets/main-DK9PoBjx.js"
75
+ "etag": '"318c-7uKjiGCOGPnw5aJSXfioga1NTsM"',
76
+ "mtime": "2026-07-02T01:15:23.247Z",
77
+ "size": 12684,
78
+ "path": "../public/assets/ReplayDialog-TTTVCMe9.js"
86
79
  },
87
- "/assets/ResponseView-Bum1a3tG.js": {
80
+ "/assets/main-CKYe6UUv.js": {
88
81
  "type": "text/javascript; charset=utf-8",
89
- "etag": '"30d0-nm7943Zf3wkOX8Qkx5tFeTPBdhs"',
90
- "mtime": "2026-07-01T08:15:03.702Z",
91
- "size": 12496,
92
- "path": "../public/assets/ResponseView-Bum1a3tG.js"
82
+ "etag": '"517d9-2aRLKvQ58GrmKFTsuV0pk+1qC6Y"',
83
+ "mtime": "2026-07-02T01:15:23.247Z",
84
+ "size": 333785,
85
+ "path": "../public/assets/main-CKYe6UUv.js"
93
86
  },
94
- "/assets/RequestAnatomy-d4P6JNiP.js": {
87
+ "/assets/StreamingChunkSequence-UlAMVF9j.js": {
95
88
  "type": "text/javascript; charset=utf-8",
96
- "etag": '"4485-R6aSqQKKsXZ9KJifvk5uB/aAP/w"',
97
- "mtime": "2026-07-01T08:15:03.700Z",
98
- "size": 17541,
99
- "path": "../public/assets/RequestAnatomy-d4P6JNiP.js"
89
+ "etag": '"d57-66GSO+9YzBli1luuyHBvRTVMfcc"',
90
+ "mtime": "2026-07-02T01:15:23.247Z",
91
+ "size": 3415,
92
+ "path": "../public/assets/StreamingChunkSequence-UlAMVF9j.js"
100
93
  },
101
94
  "/assets/zhipuai-BPNAnxo-.svg": {
102
95
  "type": "image/svg+xml",
103
96
  "etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
104
- "mtime": "2026-07-01T08:15:03.700Z",
97
+ "mtime": "2026-07-02T01:15:23.247Z",
105
98
  "size": 11256,
106
99
  "path": "../public/assets/zhipuai-BPNAnxo-.svg"
107
100
  },
108
- "/assets/StreamingChunkSequence-CjBDp5E9.js": {
101
+ "/assets/minimax-BPMzvuL-.jpeg": {
102
+ "type": "image/jpeg",
103
+ "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
104
+ "mtime": "2026-07-02T01:15:23.247Z",
105
+ "size": 6918,
106
+ "path": "../public/assets/minimax-BPMzvuL-.jpeg"
107
+ },
108
+ "/assets/ResponseView-D59jTMy4.js": {
109
109
  "type": "text/javascript; charset=utf-8",
110
- "etag": '"d57-japFPQBd84wFo2PfIzD3rpUCwE0"',
111
- "mtime": "2026-07-01T08:15:03.700Z",
112
- "size": 3415,
113
- "path": "../public/assets/StreamingChunkSequence-CjBDp5E9.js"
110
+ "etag": '"30d0-PRaxUUFPWC7Oei05DaQSd/wZ9Bw"',
111
+ "mtime": "2026-07-02T01:15:23.247Z",
112
+ "size": 12496,
113
+ "path": "../public/assets/ResponseView-D59jTMy4.js"
114
114
  },
115
115
  "/assets/qwen-CONDcHqt.png": {
116
116
  "type": "image/png",
117
117
  "etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
118
- "mtime": "2026-07-01T08:15:03.700Z",
118
+ "mtime": "2026-07-02T01:15:23.247Z",
119
119
  "size": 357059,
120
120
  "path": "../public/assets/qwen-CONDcHqt.png"
121
121
  },
122
- "/assets/_sessionId-BupV2gtf.js": {
122
+ "/assets/_sessionId-EHPexdPl.js": {
123
123
  "type": "text/javascript; charset=utf-8",
124
- "etag": '"d2-yDl+GeqeLZbuzelLqReyuecyYVA"',
125
- "mtime": "2026-07-01T08:15:03.700Z",
124
+ "etag": '"d2-ePZpCpCw8kcmKbtHPj19t6iJuaA"',
125
+ "mtime": "2026-07-02T01:15:23.247Z",
126
126
  "size": 210,
127
- "path": "../public/assets/_sessionId-BupV2gtf.js"
127
+ "path": "../public/assets/_sessionId-EHPexdPl.js"
128
128
  },
129
- "/assets/ProxyViewerContainer-CQKV0Bqq.js": {
129
+ "/assets/ProxyViewerContainer-BGqeiYKD.js": {
130
130
  "type": "text/javascript; charset=utf-8",
131
- "etag": '"b5e33-yXZRXjn1n1qIfzezs39GrqNlfhg"',
132
- "mtime": "2026-07-01T08:15:03.702Z",
133
- "size": 745011,
134
- "path": "../public/assets/ProxyViewerContainer-CQKV0Bqq.js"
131
+ "etag": '"b6168-t944j+wio4ZprelsCA8iT/6ifVU"',
132
+ "mtime": "2026-07-02T01:15:23.247Z",
133
+ "size": 745832,
134
+ "path": "../public/assets/ProxyViewerContainer-BGqeiYKD.js"
135
135
  }
136
136
  };
137
137
  function readAsset(id) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonyclaw/agent-inspector",
3
- "version": "2.0.39",
3
+ "version": "2.0.40",
4
4
  "type": "module",
5
5
  "description": "Agent observability and knowledge capture layer for AI coding tools.",
6
6
  "license": "MIT",
@@ -1,4 +1,4 @@
1
- import { GitCompareArrows } from "lucide-react";
1
+ import { AlertTriangle, GitCompareArrows } from "lucide-react";
2
2
  import { Suspense, type JSX } from "react";
3
3
  import { useEffect, useMemo, useRef, useState, memo } from "react";
4
4
  import type { CapturedLog } from "../../contracts";
@@ -295,6 +295,7 @@ export const LogEntry = memo(function ({
295
295
  () => parseRequestTools(requestExpansion.parsedData),
296
296
  [requestExpansion.parsedData],
297
297
  );
298
+ const warnings = log.warnings ?? [];
298
299
  const anatomyPaths = useMemo(() => {
299
300
  if (anatomySegments === null) return undefined;
300
301
  return new Set(anatomySegments.map((s) => s.path));
@@ -392,6 +393,19 @@ export const LogEntry = memo(function ({
392
393
  <TabsContent value="request">
393
394
  {activeTab === "request" && (
394
395
  <div className="px-4 pt-1 pb-3">
396
+ {warnings.length > 0 && (
397
+ <div className="mb-3 rounded border border-amber-500/30 bg-amber-500/10 p-3 text-xs">
398
+ <div className="flex items-center gap-2 font-semibold text-amber-300">
399
+ <AlertTriangle className="size-3.5" />
400
+ Tool schema warnings
401
+ </div>
402
+ <ul className="mt-2 space-y-1 text-muted-foreground">
403
+ {warnings.map((warning) => (
404
+ <li key={warning}>{warning}</li>
405
+ ))}
406
+ </ul>
407
+ </div>
408
+ )}
395
409
  <RequestTools
396
410
  summary={requestTools}
397
411
  calledToolNames={responseAnalysis.toolNames ?? []}
@@ -159,6 +159,7 @@ export const LogEntryHeader = memo(function ({
159
159
  const firstChunkLabel = firstChunkMs === null ? null : formatElapsed(firstChunkMs);
160
160
  const tokenRateLabel =
161
161
  tokensPerSecond === null || tokensPerSecond <= 0 ? null : formatTokenRate(tokensPerSecond);
162
+ const warningCount = log.warnings?.length ?? 0;
162
163
 
163
164
  return (
164
165
  <TooltipProvider>
@@ -229,6 +230,25 @@ export const LogEntryHeader = memo(function ({
229
230
  </Badge>
230
231
  )}
231
232
 
233
+ {warningCount > 0 && (
234
+ <Tooltip>
235
+ <TooltipTrigger asChild>
236
+ <Badge
237
+ variant="outline"
238
+ className="text-[10px] px-1.5 py-0 h-5 font-mono tabular-nums gap-1 bg-amber-500/15 text-amber-400 border-amber-500/25"
239
+ >
240
+ <AlertTriangle className="size-3" aria-label="Tool schema warnings" />
241
+ {warningCount}
242
+ </Badge>
243
+ </TooltipTrigger>
244
+ <TooltipContent>
245
+ {warningCount === 1
246
+ ? "1 tool schema warning"
247
+ : `${warningCount} tool schema warnings`}
248
+ </TooltipContent>
249
+ </Tooltip>
250
+ )}
251
+
232
252
  {/* Elapsed time */}
233
253
  {log.elapsedMs !== null && (
234
254
  <Tooltip>
@@ -58,6 +58,7 @@ export const CapturedLogSchema = z.object({
58
58
  rawRequestBodyBytes: z.number().int().nonnegative().nullable().optional(),
59
59
  responseTextBytes: z.number().int().nonnegative().nullable().optional(),
60
60
  bodyContentMode: z.enum(["full", "compact", "truncated"]).optional(),
61
+ warnings: z.array(z.string()).optional(),
61
62
  /** Error message from streaming response (e.g., SSE error event) */
62
63
  error: z.string().nullable().optional(),
63
64
  });
@@ -9,6 +9,7 @@ import type { CapturedLog } from "./schemas";
9
9
  import { getSessionProcess, isSessionProcessAvailable } from "./sessionProcess";
10
10
  import { finalizeLogUpdate } from "./store";
11
11
  import { computeTokensPerSecond } from "./streamTiming";
12
+ import { analyzeToolSchemaWarnings } from "./toolSchemaWarnings";
12
13
 
13
14
  type BaseFinalizeLogJob = {
14
15
  log: CapturedLog;
@@ -91,6 +92,7 @@ export function buildFileLogEntry(log: CapturedLog, upstreamUrl: string): Record
91
92
  clientProjectFolder: log.clientProjectFolder,
92
93
  streamingChunks: log.streamingChunks,
93
94
  streamingChunksPath: log.streamingChunksPath,
95
+ warnings: log.warnings,
94
96
  error: log.error,
95
97
  };
96
98
  }
@@ -152,6 +154,57 @@ function applyOptionalStreamingTiming(log: CapturedLog, job: FinalizeLogJob): vo
152
154
  }
153
155
  }
154
156
 
157
+ type ToolSchemaWarningAnalysisJob = {
158
+ log: CapturedLog;
159
+ upstreamUrl: string;
160
+ error: string | null;
161
+ };
162
+
163
+ let toolSchemaWarningQueue: Promise<void> = Promise.resolve();
164
+
165
+ function deferToolSchemaWarningAnalysis(): Promise<void> {
166
+ return new Promise((resolve) => {
167
+ setTimeout(resolve, 0);
168
+ });
169
+ }
170
+
171
+ function withToolSchemaWarnings(log: CapturedLog): CapturedLog | null {
172
+ const warnings = analyzeToolSchemaWarnings({
173
+ rawRequestBody: log.rawRequestBody,
174
+ responseText: log.responseText,
175
+ apiFormat: log.apiFormat,
176
+ });
177
+ if (warnings.length === 0) return null;
178
+ const mergedWarnings = Array.from(new Set([...(log.warnings ?? []), ...warnings]));
179
+ if (mergedWarnings.length === (log.warnings?.length ?? 0)) return null;
180
+ return { ...log, warnings: mergedWarnings };
181
+ }
182
+
183
+ async function runToolSchemaWarningAnalysis(job: ToolSchemaWarningAnalysisJob): Promise<void> {
184
+ await deferToolSchemaWarningAnalysis();
185
+ const updatedLog = withToolSchemaWarnings(job.log);
186
+ if (updatedLog === null) return;
187
+
188
+ appendLogEntry({ ...buildFileLogEntry(updatedLog, job.upstreamUrl), error: job.error });
189
+ finalizeLogUpdate(updatedLog);
190
+ }
191
+
192
+ function scheduleToolSchemaWarningAnalysis(job: ToolSchemaWarningAnalysisJob): void {
193
+ toolSchemaWarningQueue = toolSchemaWarningQueue
194
+ .catch(() => undefined)
195
+ .then(() => runToolSchemaWarningAnalysis(job))
196
+ .catch((err: unknown) => {
197
+ logger.warn(
198
+ `[logFinalizer] Tool schema warning analysis failed for log #${job.log.id}:`,
199
+ errorMessage(err),
200
+ );
201
+ });
202
+ }
203
+
204
+ export async function flushToolSchemaWarningAnalysis(): Promise<void> {
205
+ await toolSchemaWarningQueue;
206
+ }
207
+
155
208
  function finalizeNonStreaming(
156
209
  job: FinalizeNonStreamingLogJob,
157
210
  log: CapturedLog,
@@ -384,6 +437,11 @@ export function buildFinalizeLogResult(job: FinalizeLogJob): FinalizeLogResult {
384
437
  export function commitFinalizeLogResult(result: FinalizeLogResult): void {
385
438
  appendLogEntry({ ...buildFileLogEntry(result.log, result.upstreamUrl), error: result.error });
386
439
  finalizeLogUpdate(result.log);
440
+ scheduleToolSchemaWarningAnalysis({
441
+ log: cloneLog(result.log),
442
+ upstreamUrl: result.upstreamUrl,
443
+ error: result.error,
444
+ });
387
445
  if (result.cleanupRawStreamPath !== undefined && result.cleanupRawStreamPath !== null) {
388
446
  try {
389
447
  rmSync(result.cleanupRawStreamPath, { force: true });
@@ -70,6 +70,7 @@ function searchableFields(log: CapturedLog): string[] {
70
70
  optionalText(log.clientCwd),
71
71
  optionalText(log.clientProjectFolder),
72
72
  optionalText(log.error),
73
+ ...(log.warnings ?? []),
73
74
  ].filter((value): value is string => value !== null && value.length > 0);
74
75
  }
75
76