@tonyclaw/agent-inspector 3.0.23 → 3.0.25

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 (49) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-CFedvZHU.js → CompareDrawer-BnvOPwpe.js} +1 -1
  3. package/.output/public/assets/ProxyViewerContainer-DcqFqo1m.js +127 -0
  4. package/.output/public/assets/{ReplayDialog-X-fRSKAu.js → ReplayDialog-BJgoQWdW.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-S8qB5nVg.js → RequestAnatomy-CpBZEHnM.js} +1 -1
  6. package/.output/public/assets/{ResponseView-_rcOWSwJ.js → ResponseView-CWmyRb2M.js} +2 -2
  7. package/.output/public/assets/{StreamingChunkSequence-Bc15AVpN.js → StreamingChunkSequence-BWhC8bwx.js} +1 -1
  8. package/.output/public/assets/{_sessionId-Cz-HW2Wf.js → _sessionId-Cq-2OqUU.js} +1 -1
  9. package/.output/public/assets/{index-CEgwWY3E.js → index-BKi9IRtV.js} +71 -7
  10. package/.output/public/assets/index-BMYuDL5X.css +1 -0
  11. package/.output/public/assets/{index-CXYBU0j8.js → index-Cf8O0Oos.js} +1 -1
  12. package/.output/public/assets/{index-ClKXooQd.js → index-DdgTJ4QJ.js} +1 -1
  13. package/.output/public/assets/{json-viewer-QfU4qGdd.js → json-viewer-Bqu_4hmm.js} +1 -1
  14. package/.output/server/_libs/lucide-react.mjs +306 -246
  15. package/.output/server/{_sessionId-9FAmYZVf.mjs → _sessionId-Ba7H3Gjw.mjs} +2 -2
  16. package/.output/server/_ssr/{CompareDrawer-BLKjOzwD.mjs → CompareDrawer-aH59Ab6x.mjs} +3 -3
  17. package/.output/server/_ssr/{ProxyViewerContainer-Dcs2Mq8l.mjs → ProxyViewerContainer-By-I0tJv.mjs} +1791 -1259
  18. package/.output/server/_ssr/{ReplayDialog-oyiF4LIo.mjs → ReplayDialog-BO4Vy0et.mjs} +4 -4
  19. package/.output/server/_ssr/{RequestAnatomy-DkyQXSuj.mjs → RequestAnatomy-FtOr7vSS.mjs} +3 -3
  20. package/.output/server/_ssr/{ResponseView-3NTDEiDh.mjs → ResponseView-cvw6ajue.mjs} +3 -3
  21. package/.output/server/_ssr/{StreamingChunkSequence-DRq-5Bgn.mjs → StreamingChunkSequence-Oc8S2kD6.mjs} +3 -3
  22. package/.output/server/_ssr/{index-dtMiNUa1.mjs → index-BDRlQheR.mjs} +2 -2
  23. package/.output/server/_ssr/index.mjs +2 -2
  24. package/.output/server/_ssr/{json-viewer-BhUwicvp.mjs → json-viewer-Cd6trhQr.mjs} +3 -3
  25. package/.output/server/_ssr/{router-DO0OntUK.mjs → router-bofP-Ekl.mjs} +296 -91
  26. package/.output/server/{_tanstack-start-manifest_v-DO5v3BHY.mjs → _tanstack-start-manifest_v-BPuf86qB.mjs} +1 -1
  27. package/.output/server/index.mjs +76 -76
  28. package/package.json +3 -2
  29. package/src/components/ProxyViewer.tsx +138 -740
  30. package/src/components/ProxyViewerContainer.tsx +5 -47
  31. package/src/components/alerts/AlertsDialog.tsx +6 -2
  32. package/src/components/inspector-pet/InspectorPet.tsx +390 -0
  33. package/src/components/inspector-pet/inspectorPetLogic.ts +273 -0
  34. package/src/components/providers/ProviderCard.tsx +20 -579
  35. package/src/components/providers/ProviderTestResultsView.tsx +732 -0
  36. package/src/components/proxy-viewer/LogEntry.tsx +5 -0
  37. package/src/components/proxy-viewer/LogEntryHeader.tsx +7 -0
  38. package/src/components/proxy-viewer/ToolTraceEvents.tsx +33 -36
  39. package/src/components/proxy-viewer/TurnGroup.tsx +1 -5
  40. package/src/components/proxy-viewer/proxyViewerContainerLogic.ts +46 -0
  41. package/src/components/proxy-viewer/proxyViewerLogic.ts +469 -0
  42. package/src/lib/themeMode.ts +45 -0
  43. package/src/lib/uiScale.ts +112 -0
  44. package/src/lib/useThemeMode.ts +40 -0
  45. package/src/lib/useUiScale.ts +52 -0
  46. package/src/routes/__root.tsx +78 -1
  47. package/styles/globals.css +403 -24
  48. package/.output/public/assets/ProxyViewerContainer-BlCrBvdm.js +0 -127
  49. package/.output/public/assets/index-B_SIQ47i.css +0 -1
@@ -0,0 +1,273 @@
1
+ import type { CapturedLog } from "../../contracts";
2
+
3
+ export type InspectorPetPosition = {
4
+ x: number;
5
+ y: number;
6
+ };
7
+
8
+ export type InspectorPetViewport = {
9
+ width: number;
10
+ height: number;
11
+ scale?: number;
12
+ };
13
+
14
+ export type InspectorPetEdge = "left" | "right" | "top" | "bottom";
15
+ export type InspectorPetMood = "active" | "attention" | "idle" | "sleeping";
16
+
17
+ export type InspectorPetStatus = {
18
+ mood: InspectorPetMood;
19
+ label: string;
20
+ pendingCount: number;
21
+ capturedCount: number;
22
+ };
23
+
24
+ export const INSPECTOR_PET_SIZE = 56;
25
+ export const INSPECTOR_PET_MARGIN = 14;
26
+ export const INSPECTOR_PET_EDGE_PEEK = 18;
27
+ export const INSPECTOR_PET_MIN_STEP = 72;
28
+ export const INSPECTOR_PET_MAX_STEP = 156;
29
+ export const INSPECTOR_PET_SLEEP_AFTER_MS = 45_000;
30
+
31
+ const INSPECTOR_PET_PANEL_WIDTH = 192;
32
+ const INSPECTOR_PET_PANEL_HEIGHT = 68;
33
+ const INSPECTOR_PET_PANEL_GAP = 10;
34
+ const INSPECTOR_PET_VERTICAL_SAFE_MARGIN = 78;
35
+
36
+ function viewportScale(viewport: InspectorPetViewport): number {
37
+ const scale = viewport.scale ?? 1;
38
+ return Number.isFinite(scale) && scale > 0 ? scale : 1;
39
+ }
40
+
41
+ function scaledMetric(value: number, viewport: InspectorPetViewport): number {
42
+ return value * viewportScale(viewport);
43
+ }
44
+
45
+ function clampUnit(value: number): number {
46
+ return Math.min(Math.max(value, 0), 1);
47
+ }
48
+
49
+ function maximumPetX(viewport: InspectorPetViewport): number {
50
+ const edgePeek = scaledMetric(INSPECTOR_PET_EDGE_PEEK, viewport);
51
+ return Math.max(
52
+ -edgePeek,
53
+ viewport.width - scaledMetric(INSPECTOR_PET_SIZE, viewport) + edgePeek,
54
+ );
55
+ }
56
+
57
+ function maximumPetY(viewport: InspectorPetViewport): number {
58
+ const edgePeek = scaledMetric(INSPECTOR_PET_EDGE_PEEK, viewport);
59
+ return Math.max(
60
+ -edgePeek,
61
+ viewport.height - scaledMetric(INSPECTOR_PET_SIZE, viewport) + edgePeek,
62
+ );
63
+ }
64
+
65
+ export function clampInspectorPetPosition(
66
+ position: InspectorPetPosition,
67
+ viewport: InspectorPetViewport,
68
+ ): InspectorPetPosition {
69
+ const edgePeek = scaledMetric(INSPECTOR_PET_EDGE_PEEK, viewport);
70
+ return {
71
+ x: Math.min(Math.max(position.x, -edgePeek), maximumPetX(viewport)),
72
+ y: Math.min(Math.max(position.y, -edgePeek), maximumPetY(viewport)),
73
+ };
74
+ }
75
+
76
+ export function nearestInspectorPetEdge(
77
+ position: InspectorPetPosition,
78
+ viewport: InspectorPetViewport,
79
+ ): InspectorPetEdge {
80
+ const clamped = clampInspectorPetPosition(position, viewport);
81
+ const edgePeek = scaledMetric(INSPECTOR_PET_EDGE_PEEK, viewport);
82
+ const distances: { edge: InspectorPetEdge; distance: number }[] = [
83
+ { edge: "left", distance: clamped.x + edgePeek },
84
+ { edge: "right", distance: maximumPetX(viewport) - clamped.x },
85
+ { edge: "top", distance: clamped.y + INSPECTOR_PET_EDGE_PEEK },
86
+ { edge: "bottom", distance: maximumPetY(viewport) - clamped.y },
87
+ ];
88
+ return distances.reduce((best, current) => (current.distance < best.distance ? current : best))
89
+ .edge;
90
+ }
91
+
92
+ export function snapInspectorPetToEdge(
93
+ position: InspectorPetPosition,
94
+ viewport: InspectorPetViewport,
95
+ ): InspectorPetPosition {
96
+ const clamped = clampInspectorPetPosition(position, viewport);
97
+ const edge = nearestInspectorPetEdge(clamped, viewport);
98
+ const edgePeek = scaledMetric(INSPECTOR_PET_EDGE_PEEK, viewport);
99
+
100
+ switch (edge) {
101
+ case "left":
102
+ return { x: -edgePeek, y: clamped.y };
103
+ case "right":
104
+ return { x: maximumPetX(viewport), y: clamped.y };
105
+ case "top":
106
+ return { x: clamped.x, y: -edgePeek };
107
+ case "bottom":
108
+ return { x: clamped.x, y: maximumPetY(viewport) };
109
+ }
110
+ }
111
+
112
+ export function randomInspectorPetEdgePosition(
113
+ viewport: InspectorPetViewport,
114
+ edgeSample: number,
115
+ ySample: number,
116
+ ): InspectorPetPosition {
117
+ const maxX = maximumPetX(viewport);
118
+ const maxY = maximumPetY(viewport);
119
+ const edgePeek = scaledMetric(INSPECTOR_PET_EDGE_PEEK, viewport);
120
+ const minimumSafeY = Math.min(scaledMetric(INSPECTOR_PET_VERTICAL_SAFE_MARGIN, viewport), maxY);
121
+ const randomY = minimumSafeY + clampUnit(ySample) * (maxY - minimumSafeY);
122
+ const edgeIndex = Math.min(1, Math.floor(clampUnit(edgeSample) * 2));
123
+
124
+ switch (edgeIndex) {
125
+ case 0:
126
+ return { x: -edgePeek, y: randomY };
127
+ case 1:
128
+ return { x: maxX, y: randomY };
129
+ default:
130
+ return { x: maxX, y: maxY };
131
+ }
132
+ }
133
+
134
+ export function nextInspectorPetWalkingPosition(
135
+ position: InspectorPetPosition,
136
+ viewport: InspectorPetViewport,
137
+ stepSample: number,
138
+ directionSample: number,
139
+ ): InspectorPetPosition {
140
+ const clamped = snapInspectorPetToEdge(position, viewport);
141
+ const step =
142
+ scaledMetric(INSPECTOR_PET_MIN_STEP, viewport) +
143
+ clampUnit(stepSample) * scaledMetric(INSPECTOR_PET_MAX_STEP - INSPECTOR_PET_MIN_STEP, viewport);
144
+ const direction = directionSample >= 0.5 ? 1 : -1;
145
+ const edge = nearestInspectorPetEdge(clamped, viewport);
146
+ const maxX = maximumPetX(viewport);
147
+ const maxY = maximumPetY(viewport);
148
+ const edgePeek = scaledMetric(INSPECTOR_PET_EDGE_PEEK, viewport);
149
+ const minimumSafeY = Math.min(scaledMetric(INSPECTOR_PET_VERTICAL_SAFE_MARGIN, viewport), maxY);
150
+
151
+ switch (edge) {
152
+ case "left":
153
+ return {
154
+ x: -edgePeek,
155
+ y: Math.min(Math.max(clamped.y + step * direction, minimumSafeY), maxY),
156
+ };
157
+ case "right":
158
+ return {
159
+ x: maxX,
160
+ y: Math.min(Math.max(clamped.y + step * direction, minimumSafeY), maxY),
161
+ };
162
+ case "top":
163
+ return {
164
+ x: Math.min(Math.max(clamped.x + step * direction, -edgePeek), maxX),
165
+ y: -edgePeek,
166
+ };
167
+ case "bottom":
168
+ return {
169
+ x: Math.min(Math.max(clamped.x + step * direction, -edgePeek), maxX),
170
+ y: maxY,
171
+ };
172
+ }
173
+ }
174
+
175
+ export function inspectorPetPanelPosition(
176
+ position: InspectorPetPosition,
177
+ viewport: InspectorPetViewport,
178
+ ): InspectorPetPosition {
179
+ const edge = nearestInspectorPetEdge(position, viewport);
180
+ const petSize = scaledMetric(INSPECTOR_PET_SIZE, viewport);
181
+ const panelWidth = scaledMetric(INSPECTOR_PET_PANEL_WIDTH, viewport);
182
+ const panelHeight = scaledMetric(INSPECTOR_PET_PANEL_HEIGHT, viewport);
183
+ const panelGap = scaledMetric(INSPECTOR_PET_PANEL_GAP, viewport);
184
+ const margin = scaledMetric(INSPECTOR_PET_MARGIN, viewport);
185
+ let x = position.x + petSize / 2 - panelWidth / 2;
186
+ let y = position.y + petSize / 2 - panelHeight / 2;
187
+
188
+ switch (edge) {
189
+ case "left":
190
+ x = position.x + petSize + panelGap;
191
+ break;
192
+ case "right":
193
+ x = position.x - panelWidth - panelGap;
194
+ break;
195
+ case "top":
196
+ y = position.y + petSize + panelGap;
197
+ break;
198
+ case "bottom":
199
+ y = position.y - panelHeight - panelGap;
200
+ break;
201
+ }
202
+
203
+ return {
204
+ x: Math.min(Math.max(x, margin), Math.max(margin, viewport.width - panelWidth - margin)),
205
+ y: Math.min(Math.max(y, margin), Math.max(margin, viewport.height - panelHeight - margin)),
206
+ };
207
+ }
208
+
209
+ function latestCapturedLog(logs: readonly CapturedLog[]): CapturedLog | null {
210
+ let latest: CapturedLog | null = null;
211
+ for (const log of logs) {
212
+ if (latest === null || log.id > latest.id) latest = log;
213
+ }
214
+ return latest;
215
+ }
216
+
217
+ function logNeedsAttention(log: CapturedLog): boolean {
218
+ const hasHttpError = log.responseStatus !== null && log.responseStatus >= 400;
219
+ const hasStreamError = log.error !== null && log.error !== undefined && log.error !== "";
220
+ return hasHttpError || hasStreamError;
221
+ }
222
+
223
+ export function resolveInspectorPetStatus(
224
+ logs: readonly CapturedLog[],
225
+ nowMs: number,
226
+ ): InspectorPetStatus {
227
+ const pendingCount = logs.filter((log) => log.responseStatus === null).length;
228
+ const capturedCount = logs.length;
229
+ if (pendingCount > 0) {
230
+ return {
231
+ mood: "active",
232
+ label: `${String(pendingCount)} request${pendingCount === 1 ? "" : "s"} in flight`,
233
+ pendingCount,
234
+ capturedCount,
235
+ };
236
+ }
237
+
238
+ const latest = latestCapturedLog(logs);
239
+ if (latest !== null && logNeedsAttention(latest)) {
240
+ return {
241
+ mood: "attention",
242
+ label: "Latest request needs attention",
243
+ pendingCount,
244
+ capturedCount,
245
+ };
246
+ }
247
+
248
+ if (latest === null) {
249
+ return {
250
+ mood: "idle",
251
+ label: "Waiting for traffic",
252
+ pendingCount,
253
+ capturedCount,
254
+ };
255
+ }
256
+
257
+ const latestTimestamp = Date.parse(latest.timestamp);
258
+ if (Number.isFinite(latestTimestamp) && nowMs - latestTimestamp >= INSPECTOR_PET_SLEEP_AFTER_MS) {
259
+ return {
260
+ mood: "sleeping",
261
+ label: "All quiet",
262
+ pendingCount,
263
+ capturedCount,
264
+ };
265
+ }
266
+
267
+ return {
268
+ mood: "idle",
269
+ label: "Watching the session",
270
+ pendingCount,
271
+ capturedCount,
272
+ };
273
+ }