@tonyclaw/agent-inspector 2.0.13 → 2.0.15

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 (37) hide show
  1. package/.output/cli.js +84 -0
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-CrMyE23D.js → CompareDrawer-B6WCFRJq.js} +1 -1
  4. package/.output/public/assets/{ProxyViewerContainer-BZuo0px3.js → ProxyViewerContainer-CofGRJoO.js} +31 -31
  5. package/.output/public/assets/{ReplayDialog-TQGhDdTa.js → ReplayDialog-O_53zkX8.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-D6kQYtfa.js → RequestAnatomy-CqBSMZv5.js} +1 -1
  7. package/.output/public/assets/{ResponseView-C6ybWuB8.js → ResponseView-BvbA6zot.js} +1 -1
  8. package/.output/public/assets/{StreamingChunkSequence-Bvs59_-I.js → StreamingChunkSequence-Bnf6djjc.js} +1 -1
  9. package/.output/public/assets/_sessionId-9ICCw6YA.js +1 -0
  10. package/.output/public/assets/index-DVkMYH8H.js +1 -0
  11. package/.output/public/assets/{main-DvFSJlOd.js → main-Biir9ZGe.js} +2 -2
  12. package/.output/server/{_sessionId-DHYJxPb7.mjs → _sessionId-B77Gh4IL.mjs} +2 -2
  13. package/.output/server/_ssr/{CompareDrawer-meimDBeA.mjs → CompareDrawer-D4-RHFqW.mjs} +2 -2
  14. package/.output/server/_ssr/{ProxyViewerContainer-Co-WKq6u.mjs → ProxyViewerContainer-YP28-_2H.mjs} +31 -10
  15. package/.output/server/_ssr/{ReplayDialog-cclcGyR9.mjs → ReplayDialog-D9rQlrcY.mjs} +3 -3
  16. package/.output/server/_ssr/{RequestAnatomy-to_rezzu.mjs → RequestAnatomy-BXCRWD9H.mjs} +2 -2
  17. package/.output/server/_ssr/{ResponseView-CZZI4IZd.mjs → ResponseView-DEwWMqSS.mjs} +2 -2
  18. package/.output/server/_ssr/{StreamingChunkSequence-BTF4xSYX.mjs → StreamingChunkSequence-CdrTPf5v.mjs} +2 -2
  19. package/.output/server/_ssr/{index-D2fpJFP5.mjs → index-Chf1DYqT.mjs} +2 -2
  20. package/.output/server/_ssr/index.mjs +2 -2
  21. package/.output/server/_ssr/{router-RDBAF-Iu.mjs → router-BHXU5jWm.mjs} +89 -46
  22. package/.output/server/{_tanstack-start-manifest_v-DB9sseoH.mjs → _tanstack-start-manifest_v-D1dtacWy.mjs} +1 -1
  23. package/.output/server/index.mjs +59 -59
  24. package/README.md +141 -1
  25. package/package.json +1 -1
  26. package/src/cli.ts +91 -0
  27. package/src/components/ProxyViewer.tsx +32 -24
  28. package/src/components/ProxyViewerContainer.tsx +2 -1
  29. package/src/components/providers/SettingsDialog.tsx +10 -0
  30. package/src/lib/runtimeConfig.ts +4 -0
  31. package/src/lib/useStripConfig.ts +10 -2
  32. package/src/proxy/config.ts +33 -3
  33. package/src/proxy/handler.ts +30 -13
  34. package/src/proxy/logFinalizer.ts +4 -2
  35. package/src/routes/api/providers.$providerId.test.log.ts +17 -7
  36. package/.output/public/assets/_sessionId-BNG_mnaH.js +0 -1
  37. package/.output/public/assets/index-BUxIwHhC.js +0 -1
@@ -36,16 +36,21 @@ import {
36
36
  * Strips all custom/non-standard headers from the request and replaces with
37
37
  * unified proxy identity. Only preserves standard HTTP headers needed for API calls.
38
38
  */
39
- function buildProxyHeaders(originalHeaders: Headers): {
39
+ function buildProxyHeaders(
40
+ originalHeaders: Headers,
41
+ captureRawHeaders: boolean,
42
+ ): {
40
43
  headers: Headers;
41
- rawHeaders: Record<string, string>;
44
+ rawHeaders: Record<string, string> | undefined;
42
45
  } {
43
- const rawHeaders: Record<string, string> = {};
46
+ const rawHeaders: Record<string, string> | undefined = captureRawHeaders ? {} : undefined;
44
47
  const headers = new Headers();
45
48
 
46
- originalHeaders.forEach((value, key) => {
47
- rawHeaders[key.toLowerCase()] = value;
48
- });
49
+ if (rawHeaders !== undefined) {
50
+ originalHeaders.forEach((value, key) => {
51
+ rawHeaders[key.toLowerCase()] = value;
52
+ });
53
+ }
49
54
 
50
55
  headers.set(HEADER_USER_AGENT, PROXY_IDENTITY);
51
56
  headers.set(HEADER_X_PROXY_IDENTITY, PROXY_IDENTITY);
@@ -128,6 +133,7 @@ function handleStreamingResponse(
128
133
  startTime: number,
129
134
  upstreamUrl: string,
130
135
  log: CapturedLog,
136
+ collectStreamingChunks: boolean,
131
137
  ): Response {
132
138
  log.streaming = true;
133
139
  log.responseStatus = upstreamRes.status;
@@ -151,6 +157,7 @@ function handleStreamingResponse(
151
157
  elapsedMs,
152
158
  responseStatus: upstreamRes.status,
153
159
  rawStream: full,
160
+ collectStreamingChunks,
154
161
  });
155
162
  },
156
163
  });
@@ -175,6 +182,7 @@ function handleStreamingResponse(
175
182
  elapsedMs,
176
183
  rawStream: full,
177
184
  hasChunks,
185
+ collectStreamingChunks,
178
186
  });
179
187
  }
180
188
  });
@@ -208,8 +216,9 @@ export async function handleProxy(req: Request): Promise<Response> {
208
216
  // Important: the original `requestBody` must be preserved so the log stores
209
217
  // the unmodified request (the "Raw Request" tab needs the true bytes the
210
218
  // client sent). The rewritten body is only used for the upstream fetch.
219
+ const config = getConfig();
211
220
  let bodyToForward = requestBody;
212
- if (getConfig().stripClaudeCodeBillingHeader && requestBody !== null && parsed.isMessages) {
221
+ if (config.stripClaudeCodeBillingHeader && requestBody !== null && parsed.isMessages) {
213
222
  const stripped = stripClaudeCodeBillingHeader(requestBody);
214
223
  if (stripped.removed > 0) {
215
224
  logger.info(
@@ -248,7 +257,11 @@ export async function handleProxy(req: Request): Promise<Response> {
248
257
  const upstreamUrl = buildUpstreamUrl(upstreamBase, parsed.normalizedPath);
249
258
  const startTime = Date.now();
250
259
 
251
- const { headers: upstreamHeaders, rawHeaders } = buildProxyHeaders(req.headers);
260
+ const captureFullDetails = config.captureMode === "full";
261
+ const { headers: upstreamHeaders, rawHeaders } = buildProxyHeaders(
262
+ req.headers,
263
+ captureFullDetails,
264
+ );
252
265
  setUpstreamHost(upstreamHeaders, upstreamBase);
253
266
  injectProviderAuth(upstreamHeaders, matchedProviderConfig);
254
267
 
@@ -277,10 +290,14 @@ export async function handleProxy(req: Request): Promise<Response> {
277
290
  // full PowerShell round-trip on top of everything else before
278
291
  // `fetch` is even issued.
279
292
  const [clientInfo, preAcquiredId] = await Promise.all([getClientInfo(req), getNextLogId()]);
280
- const upstreamHeadersObj: Record<string, string> = {};
281
- upstreamHeaders.forEach((value, key) => {
282
- upstreamHeadersObj[key.toLowerCase()] = value;
283
- });
293
+ const upstreamHeadersObj: Record<string, string> | undefined = captureFullDetails
294
+ ? {}
295
+ : undefined;
296
+ if (upstreamHeadersObj !== undefined) {
297
+ upstreamHeaders.forEach((value, key) => {
298
+ upstreamHeadersObj[key.toLowerCase()] = value;
299
+ });
300
+ }
284
301
  const log = await createLog(
285
302
  req.method,
286
303
  parsed.apiPath,
@@ -330,5 +347,5 @@ export async function handleProxy(req: Request): Promise<Response> {
330
347
  return handleNonStreamingResponse(upstreamRes, responseBody, startTime, upstreamUrl, log);
331
348
  }
332
349
 
333
- return handleStreamingResponse(upstreamRes, req, startTime, upstreamUrl, log);
350
+ return handleStreamingResponse(upstreamRes, req, startTime, upstreamUrl, log, captureFullDetails);
334
351
  }
@@ -22,12 +22,14 @@ export type FinalizeStreamingLogJob = BaseFinalizeLogJob & {
22
22
  type: "streaming";
23
23
  responseStatus: number;
24
24
  rawStream: string;
25
+ collectStreamingChunks: boolean;
25
26
  };
26
27
 
27
28
  export type FinalizeStreamAbortLogJob = BaseFinalizeLogJob & {
28
29
  type: "stream-abort";
29
30
  rawStream: string;
30
31
  hasChunks: boolean;
32
+ collectStreamingChunks: boolean;
31
33
  };
32
34
 
33
35
  export type FinalizeLogJob =
@@ -145,7 +147,7 @@ function finalizeStreaming(job: FinalizeStreamingLogJob, log: CapturedLog): Fina
145
147
  job.rawStream,
146
148
  log,
147
149
  log.model ?? undefined,
148
- true,
150
+ job.collectStreamingChunks,
149
151
  );
150
152
  persistStreamingChunks(log);
151
153
 
@@ -168,7 +170,7 @@ function finalizeStreamAbort(job: FinalizeStreamAbortLogJob, log: CapturedLog):
168
170
  job.rawStream,
169
171
  log,
170
172
  log.model ?? undefined,
171
- true,
173
+ job.collectStreamingChunks,
172
174
  );
173
175
  persistStreamingChunks(log);
174
176
  } else {
@@ -1,6 +1,7 @@
1
1
  import { createFileRoute } from "@tanstack/react-router";
2
2
  import { getProvider, getModelUsageName } from "../../proxy/providers";
3
3
  import { addTestLogEntry } from "../../proxy/store";
4
+ import { getConfig } from "../../proxy/config";
4
5
  import { buildProviderTestRequestBody } from "../../lib/providerTestPrompt";
5
6
  import {
6
7
  ProviderTestResultsSchema,
@@ -21,6 +22,7 @@ async function logModelResults(
21
22
  anthropic: { nonStreaming: ProviderTestState; streaming: ProviderTestState };
22
23
  openai: { nonStreaming: ProviderTestState; streaming: ProviderTestState };
23
24
  },
25
+ captureFullDetails: boolean,
24
26
  ): Promise<void> {
25
27
  const usageModel = getModelUsageName(displayName, providerName);
26
28
 
@@ -53,7 +55,7 @@ async function logModelResults(
53
55
  apiFormat: "anthropic",
54
56
  isTest: true,
55
57
  providerName,
56
- headers: nonStreamingResult.requestHeaders ?? {},
58
+ headers: captureFullDetails ? (nonStreamingResult.requestHeaders ?? {}) : undefined,
57
59
  });
58
60
 
59
61
  const streamingRequestBody = JSON.stringify(
@@ -75,13 +77,13 @@ async function logModelResults(
75
77
  cacheReadInputTokens: streamingResult.cacheReadInputTokens ?? null,
76
78
  elapsedMs: streamingResult.latencyMs ?? 0,
77
79
  streaming: true,
78
- streamingChunks: streamingResult.streamingChunks,
80
+ streamingChunks: captureFullDetails ? streamingResult.streamingChunks : undefined,
79
81
  userAgent: "provider-test",
80
82
  origin: null,
81
83
  apiFormat: "anthropic",
82
84
  isTest: true,
83
85
  providerName,
84
- headers: streamingResult.requestHeaders ?? {},
86
+ headers: captureFullDetails ? (streamingResult.requestHeaders ?? {}) : undefined,
85
87
  });
86
88
  }
87
89
  }
@@ -115,7 +117,7 @@ async function logModelResults(
115
117
  apiFormat: "openai",
116
118
  isTest: true,
117
119
  providerName,
118
- headers: nonStreamingResult.requestHeaders ?? {},
120
+ headers: captureFullDetails ? (nonStreamingResult.requestHeaders ?? {}) : undefined,
119
121
  });
120
122
 
121
123
  const streamingRequestBody = JSON.stringify(
@@ -137,13 +139,13 @@ async function logModelResults(
137
139
  cacheReadInputTokens: null,
138
140
  elapsedMs: streamingResult.latencyMs ?? 0,
139
141
  streaming: true,
140
- streamingChunks: streamingResult.streamingChunks,
142
+ streamingChunks: captureFullDetails ? streamingResult.streamingChunks : undefined,
141
143
  userAgent: "provider-test",
142
144
  origin: null,
143
145
  apiFormat: "openai",
144
146
  isTest: true,
145
147
  providerName,
146
- headers: streamingResult.requestHeaders ?? {},
148
+ headers: captureFullDetails ? (streamingResult.requestHeaders ?? {}) : undefined,
147
149
  });
148
150
  }
149
151
  }
@@ -174,6 +176,7 @@ export const Route = createFileRoute("/api/providers/$providerId/test/log")({
174
176
  }
175
177
 
176
178
  const results = parsed.data;
179
+ const captureFullDetails = getConfig().captureMode === "full";
177
180
  const anthropicUrl =
178
181
  provider.anthropicBaseUrl !== undefined && provider.anthropicBaseUrl.length > 0
179
182
  ? provider.anthropicBaseUrl
@@ -187,7 +190,14 @@ export const Route = createFileRoute("/api/providers/$providerId/test/log")({
187
190
  if (results.models !== undefined) {
188
191
  for (const [modelName, modelResult] of Object.entries(results.models)) {
189
192
  entries.push(
190
- logModelResults(modelName, provider.name, anthropicUrl, openaiUrl, modelResult),
193
+ logModelResults(
194
+ modelName,
195
+ provider.name,
196
+ anthropicUrl,
197
+ openaiUrl,
198
+ modelResult,
199
+ captureFullDetails,
200
+ ),
191
201
  );
192
202
  }
193
203
  }
@@ -1 +0,0 @@
1
- import{R as s,j as e}from"./main-DvFSJlOd.js";import{P as i}from"./ProxyViewerContainer-BZuo0px3.js";function t(){const{sessionId:o}=s.useParams();return e.jsx(i,{initialSessionId:o},o)}export{t as component};
@@ -1 +0,0 @@
1
- import{P as o}from"./ProxyViewerContainer-BZuo0px3.js";import"./main-DvFSJlOd.js";const r=o;export{r as component};