@tonyclaw/agent-inspector 2.0.21 → 2.0.23

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 (46) hide show
  1. package/.output/cli.js +10 -0
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-ztKMd-FE.js → CompareDrawer-DnYQtd8R.js} +1 -1
  4. package/.output/public/assets/ProxyViewerContainer-BTYGkg36.js +115 -0
  5. package/.output/public/assets/{ReplayDialog-RNhfLSsW.js → ReplayDialog-B-3V95xT.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-fsUI5HhH.js → RequestAnatomy-CT8hLGLa.js} +1 -1
  7. package/.output/public/assets/{ResponseView-B3YTDBBX.js → ResponseView-DK3CYom0.js} +1 -1
  8. package/.output/public/assets/{StreamingChunkSequence-CbGqQ0mO.js → StreamingChunkSequence-D3jJutjp.js} +1 -1
  9. package/.output/public/assets/_sessionId-DpdfAzbo.js +1 -0
  10. package/.output/public/assets/index-780zTVwp.css +1 -0
  11. package/.output/public/assets/index-BpJNbm9G.js +1 -0
  12. package/.output/public/assets/{main-lTQKpxiU.js → main-hF_572U6.js} +2 -2
  13. package/.output/server/_libs/lucide-react.mjs +27 -27
  14. package/.output/server/{_sessionId-DsF6LFJG.mjs → _sessionId-BqhNE2M8.mjs} +2 -2
  15. package/.output/server/_ssr/{CompareDrawer-DgdZcMpg.mjs → CompareDrawer-C4LQW4S1.mjs} +3 -3
  16. package/.output/server/_ssr/{ProxyViewerContainer-DaFW1IVu.mjs → ProxyViewerContainer-BKInvawk.mjs} +214 -41
  17. package/.output/server/_ssr/{ReplayDialog-BOaTX1ir.mjs → ReplayDialog-C3ZiRihL.mjs} +4 -4
  18. package/.output/server/_ssr/{RequestAnatomy-C-2_dejd.mjs → RequestAnatomy-DlVAPIQZ.mjs} +3 -3
  19. package/.output/server/_ssr/{ResponseView-BtRVhgzy.mjs → ResponseView-nMS0rkxu.mjs} +3 -3
  20. package/.output/server/_ssr/{StreamingChunkSequence-DZaerowX.mjs → StreamingChunkSequence-PDWqrNiO.mjs} +3 -3
  21. package/.output/server/_ssr/{index-B3_fgwFy.mjs → index-Cd1zD-lo.mjs} +2 -2
  22. package/.output/server/_ssr/index.mjs +2 -2
  23. package/.output/server/_ssr/{router-CDOnHAWy.mjs → router-R9gm7_sh.mjs} +394 -151
  24. package/.output/server/{_tanstack-start-manifest_v-Brrx1NEa.mjs → _tanstack-start-manifest_v-BnLVH_EX.mjs} +1 -1
  25. package/.output/server/index.mjs +60 -60
  26. package/package.json +1 -1
  27. package/src/cli/templates/codex-skill-onboard.ts +5 -0
  28. package/src/cli/templates/skill-onboard.ts +5 -0
  29. package/src/components/OnboardingBanner.tsx +4 -0
  30. package/src/components/ProxyViewer.tsx +5 -0
  31. package/src/components/providers/ProviderCard.tsx +178 -38
  32. package/src/components/providers/ProvidersPanel.tsx +21 -3
  33. package/src/components/providers/SettingsDialog.tsx +76 -2
  34. package/src/lib/providerTestContract.ts +13 -0
  35. package/src/lib/runtimeConfig.ts +8 -0
  36. package/src/lib/useOnboarding.ts +3 -0
  37. package/src/lib/useStripConfig.ts +22 -0
  38. package/src/proxy/config.ts +4 -0
  39. package/src/proxy/store.ts +198 -135
  40. package/src/routes/api/config.ts +7 -0
  41. package/src/routes/api/logs.stream.ts +1 -1
  42. package/src/routes/api/providers.$providerId.test.log.ts +28 -12
  43. package/.output/public/assets/ProxyViewerContainer-BT8Ilsbs.js +0 -114
  44. package/.output/public/assets/_sessionId-C9cpyfLX.js +0 -1
  45. package/.output/public/assets/index-0mTTpvA2.js +0 -1
  46. package/.output/public/assets/index-DynnYt7S.css +0 -1
@@ -8,6 +8,7 @@ import { ProvidersPanel } from "./ProvidersPanel";
8
8
  import { useProviders } from "../../lib/useProviders";
9
9
  import { useStripConfig } from "../../lib/useStripConfig";
10
10
  import {
11
+ MAX_PROVIDER_TEST_TIMEOUT_SECONDS,
11
12
  MAX_SLOW_RESPONSE_THRESHOLD_SECONDS,
12
13
  TimeDisplayFormatSchema,
13
14
  type TimeDisplayFormat,
@@ -140,6 +141,7 @@ function StorageSettingsTab(): JSX.Element {
140
141
  const [stats, setStats] = useState<LogStorageStats | null>(null);
141
142
  const [error, setError] = useState<string | null>(null);
142
143
  const [loading, setLoading] = useState(false);
144
+ const [copiedId, setCopiedId] = useState<string | null>(null);
143
145
 
144
146
  const refresh = useCallback(async () => {
145
147
  setLoading(true);
@@ -168,6 +170,13 @@ function StorageSettingsTab(): JSX.Element {
168
170
  void refresh();
169
171
  }, [refresh]);
170
172
 
173
+ const handleCopy = useCallback((id: string, value: string) => {
174
+ void window.navigator.clipboard.writeText(value).then(() => {
175
+ setCopiedId(id);
176
+ setTimeout(() => setCopiedId(null), 1600);
177
+ });
178
+ }, []);
179
+
171
180
  return (
172
181
  <div className="space-y-4">
173
182
  <div className="flex items-center justify-between gap-3">
@@ -184,6 +193,20 @@ function StorageSettingsTab(): JSX.Element {
184
193
 
185
194
  {stats !== null && (
186
195
  <div className="grid gap-2 text-xs">
196
+ <CopyableSetupValue
197
+ id="log-dir"
198
+ label="Log storage path"
199
+ value={stats.logDir}
200
+ copiedId={copiedId}
201
+ onCopy={handleCopy}
202
+ />
203
+ <CopyableSetupValue
204
+ id="chunk-dir"
205
+ label="Streaming chunks storage path"
206
+ value={stats.chunkDir}
207
+ copiedId={copiedId}
208
+ onCopy={handleCopy}
209
+ />
187
210
  <div className="rounded-md border border-border bg-muted/20 px-3 py-2">
188
211
  <div className="font-medium">In-memory logs</div>
189
212
  <div className="mt-1 font-mono text-muted-foreground">
@@ -192,14 +215,12 @@ function StorageSettingsTab(): JSX.Element {
192
215
  </div>
193
216
  <div className="rounded-md border border-border bg-muted/20 px-3 py-2">
194
217
  <div className="font-medium">Log files</div>
195
- <div className="mt-1 break-all font-mono text-muted-foreground">{stats.logDir}</div>
196
218
  <div className="mt-1 font-mono text-muted-foreground">
197
219
  {stats.logFileCount.toLocaleString()} files / {formatBytes(stats.logBytes)}
198
220
  </div>
199
221
  </div>
200
222
  <div className="rounded-md border border-border bg-muted/20 px-3 py-2">
201
223
  <div className="font-medium">Streaming chunks</div>
202
- <div className="mt-1 break-all font-mono text-muted-foreground">{stats.chunkDir}</div>
203
224
  <div className="mt-1 font-mono text-muted-foreground">
204
225
  {stats.chunkFileCount.toLocaleString()} files / {formatBytes(stats.chunkBytes)}
205
226
  </div>
@@ -314,6 +335,13 @@ function OnboardingSettingsTab(): JSX.Element {
314
335
  <Check className="size-3.5 text-emerald-500" />
315
336
  <span>Captured sessions can produce reviewable memory candidates.</span>
316
337
  </div>
338
+ <div className="flex items-start gap-2">
339
+ <Check className="mt-0.5 size-3.5 text-emerald-500" />
340
+ <span>
341
+ If your AI tool runs in another container or host, replace localhost with an address
342
+ reachable from that tool and verify the network/firewall path.
343
+ </span>
344
+ </div>
317
345
  </div>
318
346
  </div>
319
347
  );
@@ -324,10 +352,12 @@ function ProxySettingsTab(): JSX.Element {
324
352
  strip,
325
353
  captureMode,
326
354
  slowResponseThresholdSeconds,
355
+ providerTestTimeoutSeconds,
327
356
  timeDisplayFormat,
328
357
  isLoading,
329
358
  setStrip,
330
359
  setSlowResponseThresholdSeconds,
360
+ setProviderTestTimeoutSeconds,
331
361
  setTimeDisplayFormat,
332
362
  } = useStripConfig();
333
363
  const [error, setError] = useState<string | null>(null);
@@ -364,6 +394,21 @@ function ProxySettingsTab(): JSX.Element {
364
394
  [setSlowResponseThresholdSeconds],
365
395
  );
366
396
 
397
+ const handleProviderTestTimeoutChange = useCallback(
398
+ async (next: number) => {
399
+ setError(null);
400
+ setPending(true);
401
+ try {
402
+ await setProviderTestTimeoutSeconds(next);
403
+ } catch (err) {
404
+ setError(err instanceof Error ? err.message : String(err));
405
+ } finally {
406
+ setPending(false);
407
+ }
408
+ },
409
+ [setProviderTestTimeoutSeconds],
410
+ );
411
+
367
412
  const handleTimeDisplayFormatChange = useCallback(
368
413
  async (next: TimeDisplayFormat) => {
369
414
  setError(null);
@@ -449,6 +494,35 @@ function ProxySettingsTab(): JSX.Element {
449
494
  </div>
450
495
  </div>
451
496
 
497
+ <div className="space-y-1">
498
+ <label htmlFor="provider-test-timeout" className="text-sm font-semibold">
499
+ Provider test timeout
500
+ </label>
501
+ <p className="text-xs text-muted-foreground">
502
+ Provider Test waits this many seconds per configured model before aborting slow probes.
503
+ The full test window scales with model count.
504
+ </p>
505
+ <div className="flex items-center gap-2">
506
+ <input
507
+ id="provider-test-timeout"
508
+ type="number"
509
+ min={1}
510
+ max={MAX_PROVIDER_TEST_TIMEOUT_SECONDS}
511
+ step={1}
512
+ value={providerTestTimeoutSeconds}
513
+ disabled={isLoading || pending}
514
+ onChange={(e) => {
515
+ const next = Number(e.currentTarget.value);
516
+ if (!Number.isInteger(next)) return;
517
+ if (next < 1 || next > MAX_PROVIDER_TEST_TIMEOUT_SECONDS) return;
518
+ void handleProviderTestTimeoutChange(next);
519
+ }}
520
+ className="h-8 w-24 rounded-md border border-input bg-transparent px-2 text-sm font-mono disabled:cursor-not-allowed disabled:opacity-50"
521
+ />
522
+ <span className="text-xs text-muted-foreground">seconds / model</span>
523
+ </div>
524
+ </div>
525
+
452
526
  <div className="space-y-1">
453
527
  <label htmlFor="time-display-format" className="text-sm font-semibold">
454
528
  Time display
@@ -25,6 +25,17 @@ const ProviderTestContentSchema = z.object({
25
25
  thinking: z.string().optional(),
26
26
  });
27
27
 
28
+ const ProviderTestDebugSchema = z.object({
29
+ requestUrl: z.string().optional(),
30
+ requestMethod: z.string().optional(),
31
+ requestHeaders: z.record(z.string(), z.string()).optional(),
32
+ requestBody: z.string().optional(),
33
+ responseStatus: z.number().optional(),
34
+ responseStatusText: z.string().optional(),
35
+ responseHeaders: z.record(z.string(), z.string()).optional(),
36
+ responseBody: z.string().optional(),
37
+ });
38
+
28
39
  export const ProviderTestResultSchema = z.object({
29
40
  success: z.boolean(),
30
41
  error: ProviderTestErrorSchema.optional(),
@@ -44,6 +55,7 @@ export const ProviderTestResultSchema = z.object({
44
55
  })
45
56
  .optional(),
46
57
  requestHeaders: z.record(z.string(), z.string()).optional(),
58
+ debug: ProviderTestDebugSchema.optional(),
47
59
  });
48
60
 
49
61
  export const ProviderTestStateSchema = z.union([
@@ -70,6 +82,7 @@ export const ProviderTestResultsSchema = z.object({
70
82
  });
71
83
 
72
84
  export type ProviderTestErrorType = z.infer<typeof ProviderTestErrorTypeSchema>;
85
+ export type ProviderTestDebug = z.infer<typeof ProviderTestDebugSchema>;
73
86
  export type ProviderTestResult = z.infer<typeof ProviderTestResultSchema>;
74
87
  export type ProviderTestState = z.infer<typeof ProviderTestStateSchema>;
75
88
  export type ProviderTestResults = z.infer<typeof ProviderTestResultsSchema>;
@@ -2,6 +2,8 @@ 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_PROVIDER_TEST_TIMEOUT_SECONDS = 60;
6
+ export const MAX_PROVIDER_TEST_TIMEOUT_SECONDS = 600;
5
7
  export const DEFAULT_TIME_DISPLAY_FORMAT = "time";
6
8
  export const DEFAULT_CAPTURE_MODE = "simple";
7
9
 
@@ -28,6 +30,12 @@ export const RuntimeConfigSchema = z.object({
28
30
  .min(0)
29
31
  .max(MAX_SLOW_RESPONSE_THRESHOLD_SECONDS)
30
32
  .default(DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS),
33
+ providerTestTimeoutSeconds: z
34
+ .number()
35
+ .int()
36
+ .min(1)
37
+ .max(MAX_PROVIDER_TEST_TIMEOUT_SECONDS)
38
+ .default(DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS),
31
39
  timeDisplayFormat: TimeDisplayFormatSchema.default(DEFAULT_TIME_DISPLAY_FORMAT),
32
40
  captureMode: CaptureModeSchema.default(DEFAULT_CAPTURE_MODE),
33
41
  });
@@ -2,6 +2,7 @@ import useSWR, { type SWRResponse, useSWRConfig } from "swr";
2
2
  import { fetchJson } from "./apiClient";
3
3
  import {
4
4
  DEFAULT_CAPTURE_MODE,
5
+ DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
5
6
  DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
6
7
  DEFAULT_TIME_DISPLAY_FORMAT,
7
8
  RuntimeConfigSchema,
@@ -73,6 +74,8 @@ export function useOnboarding(): UseOnboarding {
73
74
  hasSeenOnboarding: true,
74
75
  slowResponseThresholdSeconds:
75
76
  response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
77
+ providerTestTimeoutSeconds:
78
+ response.data?.providerTestTimeoutSeconds ?? DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
76
79
  timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
77
80
  captureMode,
78
81
  },
@@ -2,6 +2,7 @@ import useSWR, { type SWRResponse, useSWRConfig } from "swr";
2
2
  import { fetchJson } from "./apiClient";
3
3
  import {
4
4
  DEFAULT_CAPTURE_MODE,
5
+ DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
5
6
  DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
6
7
  DEFAULT_TIME_DISPLAY_FORMAT,
7
8
  type CaptureMode,
@@ -43,11 +44,13 @@ export type UseStripConfig = {
43
44
  strip: boolean;
44
45
  captureMode: CaptureMode;
45
46
  slowResponseThresholdSeconds: number;
47
+ providerTestTimeoutSeconds: number;
46
48
  timeDisplayFormat: TimeDisplayFormat;
47
49
  isLoading: boolean;
48
50
  isError: boolean;
49
51
  setStrip: (next: boolean) => Promise<void>;
50
52
  setSlowResponseThresholdSeconds: (next: number) => Promise<void>;
53
+ setProviderTestTimeoutSeconds: (next: number) => Promise<void>;
51
54
  setTimeDisplayFormat: (next: TimeDisplayFormat) => Promise<void>;
52
55
  };
53
56
 
@@ -56,6 +59,7 @@ export type UseStripConfig = {
56
59
  *
57
60
  * - `strip` is the live value from the server (or the optimistic value mid-PATCH).
58
61
  * - `slowResponseThresholdSeconds` controls the UI's slow-response indicator.
62
+ * - `providerTestTimeoutSeconds` controls each per-model Provider Test probe.
59
63
  * - `setStrip(next)` PATCHes the server with optimistic update; on failure
60
64
  * it throws and SWR rolls back the optimistic value.
61
65
  */
@@ -74,6 +78,8 @@ export function useStripConfig(): UseStripConfig {
74
78
  const captureMode = response.data?.captureMode ?? DEFAULT_CAPTURE_MODE;
75
79
  const slowResponseThresholdSeconds =
76
80
  response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS;
81
+ const providerTestTimeoutSeconds =
82
+ response.data?.providerTestTimeoutSeconds ?? DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS;
77
83
  const timeDisplayFormat = response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT;
78
84
 
79
85
  const optimisticConfig = (patch: RuntimeConfigPatch): RuntimeConfig => ({
@@ -81,6 +87,8 @@ export function useStripConfig(): UseStripConfig {
81
87
  hasSeenOnboarding: response.data?.hasSeenOnboarding ?? false,
82
88
  slowResponseThresholdSeconds:
83
89
  response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
90
+ providerTestTimeoutSeconds:
91
+ response.data?.providerTestTimeoutSeconds ?? DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
84
92
  timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
85
93
  captureMode,
86
94
  ...patch,
@@ -118,15 +126,29 @@ export function useStripConfig(): UseStripConfig {
118
126
  });
119
127
  };
120
128
 
129
+ const setProviderTestTimeoutSeconds = async (next: number): Promise<void> => {
130
+ await globalMutate(
131
+ STRIP_CONFIG_SWR_KEY,
132
+ setRuntimeConfig({ providerTestTimeoutSeconds: next }),
133
+ {
134
+ optimisticData: optimisticConfig({ providerTestTimeoutSeconds: next }),
135
+ rollbackOnError: true,
136
+ revalidate: false,
137
+ },
138
+ );
139
+ };
140
+
121
141
  return {
122
142
  strip,
123
143
  captureMode,
124
144
  slowResponseThresholdSeconds,
145
+ providerTestTimeoutSeconds,
125
146
  timeDisplayFormat,
126
147
  isLoading: response.isLoading,
127
148
  isError: response.error !== undefined,
128
149
  setStrip,
129
150
  setSlowResponseThresholdSeconds,
151
+ setProviderTestTimeoutSeconds,
130
152
  setTimeDisplayFormat,
131
153
  };
132
154
  }
@@ -13,6 +13,7 @@ import { getDataDir } from "./dataDir";
13
13
  import {
14
14
  CaptureModeSchema,
15
15
  DEFAULT_CAPTURE_MODE,
16
+ DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
16
17
  DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
17
18
  DEFAULT_TIME_DISPLAY_FORMAT,
18
19
  RuntimeConfigSchema,
@@ -98,6 +99,7 @@ function resolveInitialConfig(): RuntimeConfig {
98
99
  stripClaudeCodeBillingHeader: true,
99
100
  hasSeenOnboarding: false,
100
101
  slowResponseThresholdSeconds: DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
102
+ providerTestTimeoutSeconds: DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
101
103
  timeDisplayFormat: DEFAULT_TIME_DISPLAY_FORMAT,
102
104
  captureMode,
103
105
  };
@@ -108,6 +110,7 @@ function resolveInitialConfig(): RuntimeConfig {
108
110
  stripClaudeCodeBillingHeader: false,
109
111
  hasSeenOnboarding: false,
110
112
  slowResponseThresholdSeconds: DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
113
+ providerTestTimeoutSeconds: DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
111
114
  timeDisplayFormat: DEFAULT_TIME_DISPLAY_FORMAT,
112
115
  captureMode,
113
116
  };
@@ -200,6 +203,7 @@ function toPersistedConfig(value: RuntimeConfig): Record<string, unknown> {
200
203
  stripClaudeCodeBillingHeader: value.stripClaudeCodeBillingHeader,
201
204
  hasSeenOnboarding: value.hasSeenOnboarding,
202
205
  slowResponseThresholdSeconds: value.slowResponseThresholdSeconds,
206
+ providerTestTimeoutSeconds: value.providerTestTimeoutSeconds,
203
207
  timeDisplayFormat: value.timeDisplayFormat,
204
208
  };
205
209
  }