@tonyclaw/agent-inspector 2.0.9 → 2.0.11
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-Cb4RH049.js → CompareDrawer-C9OWdxHM.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-CNzay4u8.js +114 -0
- package/.output/public/assets/{ReplayDialog-B3y8E7IE.js → ReplayDialog-CwE6I1Pe.js} +1 -1
- package/.output/public/assets/RequestAnatomy-DEehC3yz.js +1 -0
- package/.output/public/assets/ResponseView-CE5UsuUq.js +1 -0
- package/.output/public/assets/StreamingChunkSequence-CLcLZ7-W.js +1 -0
- package/.output/public/assets/_sessionId-DE__tPTo.js +1 -0
- package/.output/public/assets/index-BFO4Jmw5.js +1 -0
- package/.output/public/assets/index-CDzZ7l_S.css +1 -0
- package/.output/public/assets/{main-Bww0Bc88.js → main-D1Xanzu7.js} +2 -2
- package/.output/server/{_sessionId-BnCF8Ito.mjs → _sessionId-D3IyPpws.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-jPU14EI3.mjs → CompareDrawer-BIMThqxy.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-xesEFppM.mjs → ProxyViewerContainer-BiBdKWtj.mjs} +159 -14
- package/.output/server/_ssr/{ReplayDialog-DQvW2zoW.mjs → ReplayDialog-D_wiDyM2.mjs} +3 -3
- package/.output/server/_ssr/{RequestAnatomy-BilEphjP.mjs → RequestAnatomy-5UiMTESr.mjs} +399 -44
- package/.output/server/_ssr/{ResponseView-DB5PPcWf.mjs → ResponseView-Drk5ghmL.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-Dnrgn2AP.mjs → StreamingChunkSequence-F889rmG0.mjs} +2 -2
- package/.output/server/_ssr/{index-YPp821bH.mjs → index-CaPniq9z.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-BvuK0vQv.mjs → router-C7S8FRth.mjs} +531 -111
- package/.output/server/{_tanstack-start-manifest_v-DGw3vVOm.mjs → _tanstack-start-manifest_v-CVTkFOdT.mjs} +1 -1
- package/.output/server/index.mjs +59 -59
- package/package.json +1 -1
- package/src/components/providers/ProviderCard.tsx +59 -5
- package/src/components/providers/ProviderForm.tsx +42 -0
- package/src/components/providers/ProvidersPanel.tsx +68 -0
- package/src/components/proxy-viewer/LogEntry.tsx +6 -1
- package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +179 -4
- package/src/components/proxy-viewer/anatomy/contextIntelligence.ts +346 -41
- package/src/lib/providerContract.ts +12 -0
- package/src/lib/providerModelMetadata.ts +327 -0
- package/src/proxy/providers.ts +112 -52
- package/src/routes/api/providers.$providerId.model-metadata.ts +134 -0
- package/src/routes/api/providers.$providerId.ts +3 -0
- package/src/routes/api/providers.ts +2 -0
- package/.output/public/assets/ProxyViewerContainer-Cmr2TANl.js +0 -114
- package/.output/public/assets/RequestAnatomy-C7BQYj95.js +0 -1
- package/.output/public/assets/ResponseView-Bylsp4WJ.js +0 -1
- package/.output/public/assets/StreamingChunkSequence-CJH13VD3.js +0 -1
- package/.output/public/assets/_sessionId-3e8W68GL.js +0 -1
- package/.output/public/assets/index-Bo1dGS4R.css +0 -1
- package/.output/public/assets/index-Cz5aqmzE.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { f as formatTokens, k as TooltipProvider, c as cn, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer-
|
|
3
|
-
import { s as safeGetOwnProperty } from "./router-
|
|
2
|
+
import { u as useProviders, f as formatTokens, k as TooltipProvider, c as cn, l as Tooltip, m as TooltipTrigger, n as TooltipContent, p as countCharacters, q as estimateTokens } from "./ProxyViewerContainer-BiBdKWtj.mjs";
|
|
3
|
+
import { s as safeGetOwnProperty, k as resolveProviderContextWindow, l as isPlainRecord } from "./router-C7S8FRth.mjs";
|
|
4
4
|
import "../_libs/jszip.mjs";
|
|
5
5
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
6
6
|
import { aa as Info } from "../_libs/lucide-react.mjs";
|
|
@@ -171,11 +171,30 @@ const LONG_TOOL_SCHEMA_TOKENS = 8e3;
|
|
|
171
171
|
const LARGE_ROLE_PERCENT = 0.35;
|
|
172
172
|
const DUPLICATE_MIN_TOKENS = 40;
|
|
173
173
|
const DUPLICATE_MIN_CHARS = 160;
|
|
174
|
+
const DUPLICATE_NESTED_MAX_DEPTH = 5;
|
|
175
|
+
const DUPLICATE_NESTED_MAX_CANDIDATES_PER_SEGMENT = 8;
|
|
174
176
|
const HISTORY_BLOAT_SEGMENTS = 18;
|
|
175
177
|
const HISTORY_BLOAT_TOKENS = 6e4;
|
|
176
178
|
const HISTORY_BLOAT_PERCENT = 0.7;
|
|
177
179
|
const SYSTEM_HEAVY_TOKENS = 3e3;
|
|
178
180
|
const SYSTEM_HEAVY_PERCENT = 0.3;
|
|
181
|
+
const DUPLICATE_PREVIEW_CHARS = 160;
|
|
182
|
+
const DUPLICATE_NESTED_FIELD_NAMES = /* @__PURE__ */ new Set([
|
|
183
|
+
"answer",
|
|
184
|
+
"body",
|
|
185
|
+
"content",
|
|
186
|
+
"data",
|
|
187
|
+
"error",
|
|
188
|
+
"message",
|
|
189
|
+
"markdown",
|
|
190
|
+
"output",
|
|
191
|
+
"response",
|
|
192
|
+
"result",
|
|
193
|
+
"stderr",
|
|
194
|
+
"stdout",
|
|
195
|
+
"text",
|
|
196
|
+
"transcript"
|
|
197
|
+
]);
|
|
179
198
|
const EXPLICIT_CONTEXT_WINDOW_FIELDS = [
|
|
180
199
|
"context_window",
|
|
181
200
|
"contextWindow",
|
|
@@ -219,6 +238,12 @@ const MODEL_CONTEXT_RULES = [
|
|
|
219
238
|
mode: "prefix",
|
|
220
239
|
patterns: ["claude-"]
|
|
221
240
|
},
|
|
241
|
+
{
|
|
242
|
+
family: "DeepSeek V4",
|
|
243
|
+
tokens: 1e6,
|
|
244
|
+
mode: "prefix",
|
|
245
|
+
patterns: ["deepseek-v4-pro", "deepseek-v4-flash"]
|
|
246
|
+
},
|
|
222
247
|
{
|
|
223
248
|
family: "DeepSeek",
|
|
224
249
|
tokens: 64e3,
|
|
@@ -226,10 +251,16 @@ const MODEL_CONTEXT_RULES = [
|
|
|
226
251
|
patterns: ["deepseek-"]
|
|
227
252
|
},
|
|
228
253
|
{
|
|
229
|
-
family: "MiniMax",
|
|
254
|
+
family: "MiniMax M3",
|
|
230
255
|
tokens: 1e6,
|
|
231
256
|
mode: "includes",
|
|
232
|
-
patterns: ["minimax"]
|
|
257
|
+
patterns: ["minimax-m3"]
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
family: "MiniMax M2",
|
|
261
|
+
tokens: 204800,
|
|
262
|
+
mode: "includes",
|
|
263
|
+
patterns: ["minimax-m2.7", "minimax-m2.5", "minimax-m2.1"]
|
|
233
264
|
}
|
|
234
265
|
];
|
|
235
266
|
const ROLE_LABELS = {
|
|
@@ -271,7 +302,7 @@ function matchesRule(model, rule) {
|
|
|
271
302
|
return rule.patterns.some((pattern) => model.includes(pattern));
|
|
272
303
|
}
|
|
273
304
|
}
|
|
274
|
-
function resolveContextWindow(model, parsed) {
|
|
305
|
+
function resolveContextWindow(model, parsed, providers = []) {
|
|
275
306
|
const explicitWindow = readPositiveIntegerField(parsed, EXPLICIT_CONTEXT_WINDOW_FIELDS);
|
|
276
307
|
if (explicitWindow !== null) {
|
|
277
308
|
return {
|
|
@@ -280,6 +311,14 @@ function resolveContextWindow(model, parsed) {
|
|
|
280
311
|
source: "request"
|
|
281
312
|
};
|
|
282
313
|
}
|
|
314
|
+
const providerWindow = resolveProviderContextWindow(model, providers);
|
|
315
|
+
if (providerWindow !== null) {
|
|
316
|
+
return {
|
|
317
|
+
tokens: providerWindow.tokens,
|
|
318
|
+
label: `${providerWindow.providerName} config`,
|
|
319
|
+
source: "provider"
|
|
320
|
+
};
|
|
321
|
+
}
|
|
283
322
|
if (model === null) {
|
|
284
323
|
return {
|
|
285
324
|
tokens: null,
|
|
@@ -287,12 +326,12 @@ function resolveContextWindow(model, parsed) {
|
|
|
287
326
|
source: "unknown"
|
|
288
327
|
};
|
|
289
328
|
}
|
|
290
|
-
const normalized = model.trim().toLowerCase();
|
|
329
|
+
const normalized = model.trim().toLowerCase().replace(/\s+/g, "-");
|
|
291
330
|
for (const rule of MODEL_CONTEXT_RULES) {
|
|
292
331
|
if (matchesRule(normalized, rule)) {
|
|
293
332
|
return {
|
|
294
333
|
tokens: rule.tokens,
|
|
295
|
-
label: rule.family
|
|
334
|
+
label: `${rule.family} local rule`,
|
|
296
335
|
source: "model-rule"
|
|
297
336
|
};
|
|
298
337
|
}
|
|
@@ -332,42 +371,187 @@ function buildRoleUsages(segments, total) {
|
|
|
332
371
|
function normalizeDuplicateText(text) {
|
|
333
372
|
return text.replace(/\s+/g, " ").trim().toLowerCase();
|
|
334
373
|
}
|
|
335
|
-
function
|
|
374
|
+
function duplicatePreview(text) {
|
|
375
|
+
const singleLine = text.replace(/\s+/g, " ").trim();
|
|
376
|
+
if (singleLine.length <= DUPLICATE_PREVIEW_CHARS) return singleLine;
|
|
377
|
+
return `${singleLine.slice(0, DUPLICATE_PREVIEW_CHARS - 3)}...`;
|
|
378
|
+
}
|
|
379
|
+
function duplicateSegmentRef(candidate) {
|
|
380
|
+
return {
|
|
381
|
+
role: candidate.role,
|
|
382
|
+
label: candidate.label,
|
|
383
|
+
path: candidate.path,
|
|
384
|
+
tokens: candidate.tokens,
|
|
385
|
+
characters: candidate.characters
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function duplicateCandidateFromSegment(segment) {
|
|
389
|
+
return {
|
|
390
|
+
role: segment.role,
|
|
391
|
+
label: segment.label,
|
|
392
|
+
path: segment.path,
|
|
393
|
+
tokens: segment.size,
|
|
394
|
+
characters: segment.characters,
|
|
395
|
+
text: segment.text
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function jsonLikeText(text) {
|
|
399
|
+
const trimmed = text.trim();
|
|
400
|
+
return trimmed.startsWith("{") || trimmed.startsWith("[");
|
|
401
|
+
}
|
|
402
|
+
function parseJsonLikeText(text) {
|
|
403
|
+
if (!jsonLikeText(text)) return null;
|
|
404
|
+
try {
|
|
405
|
+
const parsed = JSON.parse(text);
|
|
406
|
+
return parsed;
|
|
407
|
+
} catch {
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function normalizePathFieldName(field) {
|
|
412
|
+
return field.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
413
|
+
}
|
|
414
|
+
function lastNamedPathField(path) {
|
|
415
|
+
for (let index = path.length - 1; index >= 0; index -= 1) {
|
|
416
|
+
const field = path[index] ?? "";
|
|
417
|
+
if (field.startsWith("[") && field.endsWith("]")) continue;
|
|
418
|
+
return field;
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
function nestedDuplicateFieldPath(path) {
|
|
423
|
+
const field = lastNamedPathField(path);
|
|
424
|
+
if (field === null) return false;
|
|
425
|
+
return DUPLICATE_NESTED_FIELD_NAMES.has(normalizePathFieldName(field));
|
|
426
|
+
}
|
|
427
|
+
function formatNestedDuplicatePath(path) {
|
|
428
|
+
return path.map((part) => part.startsWith("[") ? part : `.${part}`).join("").replace(/^\./, "");
|
|
429
|
+
}
|
|
430
|
+
function duplicateCandidateFromNestedText(segment, text, path) {
|
|
431
|
+
const characters = countCharacters(text);
|
|
432
|
+
if (characters < DUPLICATE_MIN_CHARS) return null;
|
|
433
|
+
const tokens = estimateTokens(text);
|
|
434
|
+
if (tokens < DUPLICATE_MIN_TOKENS) return null;
|
|
435
|
+
return {
|
|
436
|
+
role: segment.role,
|
|
437
|
+
label: `${segment.label} ${formatNestedDuplicatePath(path)}`,
|
|
438
|
+
path: segment.path,
|
|
439
|
+
tokens,
|
|
440
|
+
characters,
|
|
441
|
+
text
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
function collectNestedDuplicateCandidates({
|
|
445
|
+
value,
|
|
446
|
+
segment,
|
|
447
|
+
path,
|
|
448
|
+
depth,
|
|
449
|
+
candidates
|
|
450
|
+
}) {
|
|
451
|
+
if (candidates.length >= DUPLICATE_NESTED_MAX_CANDIDATES_PER_SEGMENT) return;
|
|
452
|
+
if (depth > DUPLICATE_NESTED_MAX_DEPTH) return;
|
|
453
|
+
if (typeof value === "string") {
|
|
454
|
+
if (!nestedDuplicateFieldPath(path)) return;
|
|
455
|
+
const candidate = duplicateCandidateFromNestedText(segment, value, path);
|
|
456
|
+
if (candidate !== null) candidates.push(candidate);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (Array.isArray(value)) {
|
|
460
|
+
value.forEach(
|
|
461
|
+
(item, index) => collectNestedDuplicateCandidates({
|
|
462
|
+
value: item,
|
|
463
|
+
segment,
|
|
464
|
+
path: [...path, `[${String(index)}]`],
|
|
465
|
+
depth: depth + 1,
|
|
466
|
+
candidates
|
|
467
|
+
})
|
|
468
|
+
);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
if (!isPlainRecord(value)) return;
|
|
472
|
+
Object.entries(value).forEach(
|
|
473
|
+
([key, child]) => collectNestedDuplicateCandidates({
|
|
474
|
+
value: child,
|
|
475
|
+
segment,
|
|
476
|
+
path: [...path, key],
|
|
477
|
+
depth: depth + 1,
|
|
478
|
+
candidates
|
|
479
|
+
})
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
function duplicateCandidatesForSegment(segment) {
|
|
483
|
+
const segmentCandidate = duplicateCandidateFromSegment(segment);
|
|
484
|
+
const parsed = parseJsonLikeText(segment.text);
|
|
485
|
+
if (parsed === null) return [segmentCandidate];
|
|
486
|
+
const candidates = [];
|
|
487
|
+
collectNestedDuplicateCandidates({
|
|
488
|
+
value: parsed,
|
|
489
|
+
segment,
|
|
490
|
+
path: [],
|
|
491
|
+
depth: 0,
|
|
492
|
+
candidates
|
|
493
|
+
});
|
|
494
|
+
const normalizedSegment = normalizeDuplicateText(segment.text);
|
|
495
|
+
const seen = /* @__PURE__ */ new Set([normalizedSegment]);
|
|
496
|
+
const uniqueNested = candidates.filter((candidate) => {
|
|
497
|
+
const normalized = normalizeDuplicateText(candidate.text);
|
|
498
|
+
if (normalized === "") return false;
|
|
499
|
+
if (seen.has(normalized)) return false;
|
|
500
|
+
seen.add(normalized);
|
|
501
|
+
return true;
|
|
502
|
+
});
|
|
503
|
+
return [segmentCandidate, ...uniqueNested];
|
|
504
|
+
}
|
|
505
|
+
function duplicateContextGroups(segments) {
|
|
336
506
|
const buckets = /* @__PURE__ */ new Map();
|
|
337
507
|
for (const segment of segments) {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
508
|
+
const candidates = duplicateCandidatesForSegment(segment);
|
|
509
|
+
for (const candidate of candidates) {
|
|
510
|
+
if (candidate.tokens < DUPLICATE_MIN_TOKENS) continue;
|
|
511
|
+
if (candidate.characters < DUPLICATE_MIN_CHARS) continue;
|
|
512
|
+
const normalized = normalizeDuplicateText(candidate.text);
|
|
513
|
+
if (normalized === "") continue;
|
|
514
|
+
const existing = buckets.get(normalized);
|
|
515
|
+
if (existing === void 0) {
|
|
516
|
+
buckets.set(normalized, {
|
|
517
|
+
tokens: candidate.tokens,
|
|
518
|
+
candidates: [candidate]
|
|
519
|
+
});
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
344
522
|
buckets.set(normalized, {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
firstTokens: segment.size,
|
|
348
|
-
label: segment.label
|
|
523
|
+
tokens: existing.tokens + candidate.tokens,
|
|
524
|
+
candidates: [...existing.candidates, candidate]
|
|
349
525
|
});
|
|
350
|
-
continue;
|
|
351
526
|
}
|
|
352
|
-
buckets.set(normalized, {
|
|
353
|
-
count: existing.count + 1,
|
|
354
|
-
tokens: existing.tokens + segment.size,
|
|
355
|
-
firstTokens: existing.firstTokens,
|
|
356
|
-
label: existing.label
|
|
357
|
-
});
|
|
358
527
|
}
|
|
359
|
-
|
|
360
|
-
let repeatedSegments = 0;
|
|
361
|
-
let repeatedTokens = 0;
|
|
362
|
-
let largest = null;
|
|
528
|
+
const groups = [];
|
|
363
529
|
for (const bucket of buckets.values()) {
|
|
364
|
-
if (bucket.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
repeatedTokens
|
|
368
|
-
|
|
530
|
+
if (bucket.candidates.length < 2) continue;
|
|
531
|
+
const firstCandidate = bucket.candidates[0] ?? null;
|
|
532
|
+
if (firstCandidate === null) continue;
|
|
533
|
+
const repeatedTokens = bucket.tokens - firstCandidate.tokens;
|
|
534
|
+
groups.push({
|
|
535
|
+
key: `${firstCandidate.path}:${firstCandidate.label}:${String(
|
|
536
|
+
bucket.candidates.length
|
|
537
|
+
)}:${String(bucket.tokens)}`,
|
|
538
|
+
count: bucket.candidates.length,
|
|
539
|
+
totalTokens: bucket.tokens,
|
|
540
|
+
repeatedTokens,
|
|
541
|
+
preview: duplicatePreview(firstCandidate.text),
|
|
542
|
+
firstLabel: firstCandidate.label,
|
|
543
|
+
segments: bucket.candidates.map(duplicateSegmentRef)
|
|
544
|
+
});
|
|
369
545
|
}
|
|
370
|
-
|
|
546
|
+
return groups.sort(
|
|
547
|
+
(left, right) => right.repeatedTokens - left.repeatedTokens || right.totalTokens - left.totalTokens
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
function duplicateDiagnostic(duplicateGroups) {
|
|
551
|
+
if (duplicateGroups.length === 0) return null;
|
|
552
|
+
const repeatedGroups = duplicateGroups.length;
|
|
553
|
+
const repeatedSegments = duplicateGroups.reduce((sum, group) => sum + group.count, 0);
|
|
554
|
+
const repeatedTokens = duplicateGroups.reduce((sum, group) => sum + group.repeatedTokens, 0);
|
|
371
555
|
return {
|
|
372
556
|
kind: "duplicate",
|
|
373
557
|
severity: repeatedTokens >= LONG_TOOL_SCHEMA_TOKENS ? "danger" : "watch",
|
|
@@ -377,6 +561,9 @@ function duplicateDiagnostic(segments) {
|
|
|
377
561
|
)} group${repeatedGroups === 1 ? "" : "s"}, ~${String(repeatedTokens)} repeated tokens.`
|
|
378
562
|
};
|
|
379
563
|
}
|
|
564
|
+
function duplicateReclaimableTokens(duplicateGroups) {
|
|
565
|
+
return duplicateGroups.reduce((sum, group) => sum + group.repeatedTokens, 0);
|
|
566
|
+
}
|
|
380
567
|
function diagnosticsForRolePressure(roleUsages, total, messageSegmentCount) {
|
|
381
568
|
const diagnostics = [];
|
|
382
569
|
const toolUsage = roleUsages.find((usage) => usage.role === "tools") ?? null;
|
|
@@ -411,17 +598,36 @@ function diagnosticsForRolePressure(roleUsages, total, messageSegmentCount) {
|
|
|
411
598
|
}
|
|
412
599
|
return diagnostics;
|
|
413
600
|
}
|
|
601
|
+
function contextHealth({
|
|
602
|
+
risk,
|
|
603
|
+
contextWindow,
|
|
604
|
+
diagnostics,
|
|
605
|
+
duplicateGroups
|
|
606
|
+
}) {
|
|
607
|
+
const diagnosticKinds = new Set(diagnostics.map((diagnostic) => diagnostic.kind));
|
|
608
|
+
let opportunityCount = diagnosticKinds.size;
|
|
609
|
+
if (risk === "watch" || risk === "danger") opportunityCount += 1;
|
|
610
|
+
if (contextWindow.source === "unknown") opportunityCount += 1;
|
|
611
|
+
const hasDangerDiagnostic = diagnostics.some((diagnostic) => diagnostic.severity === "danger");
|
|
612
|
+
const level = risk === "danger" || hasDangerDiagnostic ? "risk" : opportunityCount > 0 ? "optimizable" : "ok";
|
|
613
|
+
return {
|
|
614
|
+
level,
|
|
615
|
+
opportunityCount,
|
|
616
|
+
reclaimableTokens: duplicateReclaimableTokens(duplicateGroups)
|
|
617
|
+
};
|
|
618
|
+
}
|
|
414
619
|
function analyzeContextIntelligence({
|
|
415
620
|
segments,
|
|
416
621
|
inputTokens,
|
|
417
622
|
parsed,
|
|
418
|
-
model
|
|
623
|
+
model,
|
|
624
|
+
providers = []
|
|
419
625
|
}) {
|
|
420
626
|
const totalEstimatedTokens = segments.reduce((sum, segment) => sum + segment.size, 0);
|
|
421
627
|
const requestModel = model ?? readRequestModel(parsed);
|
|
422
628
|
const estimatedInputTokens = inputTokens ?? totalEstimatedTokens;
|
|
423
629
|
const outputReserveTokens = readPositiveIntegerField(parsed, OUTPUT_RESERVE_FIELDS);
|
|
424
|
-
const contextWindow = resolveContextWindow(requestModel, parsed);
|
|
630
|
+
const contextWindow = resolveContextWindow(requestModel, parsed, providers);
|
|
425
631
|
const reservedTokens = outputReserveTokens ?? 0;
|
|
426
632
|
const windowUsedTokens = contextWindow.tokens === null ? null : estimatedInputTokens + reservedTokens;
|
|
427
633
|
const remainingInputTokens = contextWindow.tokens === null ? null : contextWindow.tokens - estimatedInputTokens;
|
|
@@ -430,13 +636,15 @@ function analyzeContextIntelligence({
|
|
|
430
636
|
const roleUsages = buildRoleUsages(segments, totalEstimatedTokens);
|
|
431
637
|
const largestRole = roleUsages[0] ?? null;
|
|
432
638
|
const messageSegmentCount = segments.filter((segment) => segment.role !== "tools").length;
|
|
433
|
-
const
|
|
639
|
+
const duplicateGroups = duplicateContextGroups(segments);
|
|
640
|
+
const duplicate = duplicateDiagnostic(duplicateGroups);
|
|
434
641
|
const diagnostics = diagnosticsForRolePressure(
|
|
435
642
|
roleUsages,
|
|
436
643
|
totalEstimatedTokens,
|
|
437
644
|
messageSegmentCount
|
|
438
645
|
);
|
|
439
646
|
if (duplicate !== null) diagnostics.unshift(duplicate);
|
|
647
|
+
const risk = riskLevel(usagePercent);
|
|
440
648
|
return {
|
|
441
649
|
model: requestModel,
|
|
442
650
|
contextWindow,
|
|
@@ -446,10 +654,17 @@ function analyzeContextIntelligence({
|
|
|
446
654
|
remainingInputTokens,
|
|
447
655
|
remainingAfterReserveTokens,
|
|
448
656
|
usagePercent,
|
|
449
|
-
riskLevel:
|
|
657
|
+
riskLevel: risk,
|
|
450
658
|
roleUsages,
|
|
451
659
|
largestRole,
|
|
452
|
-
diagnostics
|
|
660
|
+
diagnostics,
|
|
661
|
+
duplicateGroups,
|
|
662
|
+
health: contextHealth({
|
|
663
|
+
risk,
|
|
664
|
+
contextWindow,
|
|
665
|
+
diagnostics,
|
|
666
|
+
duplicateGroups
|
|
667
|
+
})
|
|
453
668
|
};
|
|
454
669
|
}
|
|
455
670
|
const CONTEXT_USAGE_THRESHOLDS = {
|
|
@@ -662,6 +877,8 @@ const SegmentBar = reactExports.memo(function SegmentBar2({
|
|
|
662
877
|
});
|
|
663
878
|
const DIVERGENCE_AMBER_THRESHOLD = 0.25;
|
|
664
879
|
const TOP_CONTRIBUTOR_COUNT = 5;
|
|
880
|
+
const DUPLICATE_GROUP_DISPLAY_COUNT = 4;
|
|
881
|
+
const DUPLICATE_SEGMENT_DISPLAY_COUNT = 6;
|
|
665
882
|
const ROLE_ORDER = ["system", "user", "assistant", "tool", "tools"];
|
|
666
883
|
const ROLE_DESCRIPTIONS = {
|
|
667
884
|
system: "instructions",
|
|
@@ -686,6 +903,16 @@ const RISK_TEXT_CLASS = {
|
|
|
686
903
|
watch: "text-amber-300",
|
|
687
904
|
danger: "text-red-300"
|
|
688
905
|
};
|
|
906
|
+
const HEALTH_BADGE_CLASS = {
|
|
907
|
+
ok: "border-emerald-400/30 bg-emerald-400/8 text-emerald-200",
|
|
908
|
+
optimizable: "border-amber-400/30 bg-amber-400/8 text-amber-100",
|
|
909
|
+
risk: "border-red-400/35 bg-red-500/10 text-red-100"
|
|
910
|
+
};
|
|
911
|
+
const HEALTH_LABEL = {
|
|
912
|
+
ok: "OK",
|
|
913
|
+
optimizable: "Optimizable",
|
|
914
|
+
risk: "Risk"
|
|
915
|
+
};
|
|
689
916
|
function formatPercent(value) {
|
|
690
917
|
if (value >= 10) return `${value.toFixed(0)}%`;
|
|
691
918
|
if (value >= 1) return `${value.toFixed(1)}%`;
|
|
@@ -709,6 +936,8 @@ function formatContextSource(intelligence) {
|
|
|
709
936
|
switch (intelligence.contextWindow.source) {
|
|
710
937
|
case "request":
|
|
711
938
|
return intelligence.contextWindow.label;
|
|
939
|
+
case "provider":
|
|
940
|
+
return intelligence.contextWindow.label;
|
|
712
941
|
case "model-rule":
|
|
713
942
|
return intelligence.contextWindow.label;
|
|
714
943
|
case "unknown":
|
|
@@ -723,12 +952,33 @@ function diagnosticTone(diagnostic) {
|
|
|
723
952
|
return "border-red-400/35 bg-red-500/10 text-red-100";
|
|
724
953
|
}
|
|
725
954
|
}
|
|
955
|
+
function formatContextHealth(health) {
|
|
956
|
+
const label = HEALTH_LABEL[health.level];
|
|
957
|
+
if (health.level === "ok") return label;
|
|
958
|
+
const countLabel = health.level === "risk" ? `${String(health.opportunityCount)} signal${health.opportunityCount === 1 ? "" : "s"}` : `${String(health.opportunityCount)} opportunit${health.opportunityCount === 1 ? "y" : "ies"}`;
|
|
959
|
+
if (health.reclaimableTokens <= 0) return `${label} | ${countLabel}`;
|
|
960
|
+
return `${label} | ${countLabel} | ~${formatTokens(health.reclaimableTokens)} tokens`;
|
|
961
|
+
}
|
|
962
|
+
function ContextHealthBadge({ health }) {
|
|
963
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
964
|
+
"span",
|
|
965
|
+
{
|
|
966
|
+
className: cn(
|
|
967
|
+
"inline-flex h-5 max-w-full items-center rounded border px-1.5 font-mono text-[10px]",
|
|
968
|
+
HEALTH_BADGE_CLASS[health.level]
|
|
969
|
+
),
|
|
970
|
+
"aria-label": `Context health ${formatContextHealth(health)}`,
|
|
971
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: formatContextHealth(health) })
|
|
972
|
+
}
|
|
973
|
+
);
|
|
974
|
+
}
|
|
726
975
|
function ContextIntelligenceStrip({
|
|
727
976
|
intelligence
|
|
728
977
|
}) {
|
|
729
978
|
const usageWidth = intelligence.usagePercent === null ? 0 : Math.max(1, intelligence.usagePercent * 100);
|
|
730
979
|
const outputReserveLabel = intelligence.outputReserveTokens === null ? "No output reserve" : `Output reserve ${formatTokens(intelligence.outputReserveTokens)}`;
|
|
731
980
|
const largestRole = intelligence.largestRole;
|
|
981
|
+
const visibleDiagnostics = intelligence.duplicateGroups.length === 0 ? intelligence.diagnostics : intelligence.diagnostics.filter((diagnostic) => diagnostic.kind !== "duplicate");
|
|
732
982
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
733
983
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-x-4 gap-y-2 border-y border-border/60 py-2 text-xs sm:grid-cols-4", children: [
|
|
734
984
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
|
|
@@ -810,7 +1060,7 @@ function ContextIntelligenceStrip({
|
|
|
810
1060
|
] })
|
|
811
1061
|
] })
|
|
812
1062
|
] }),
|
|
813
|
-
|
|
1063
|
+
visibleDiagnostics.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid gap-1.5 sm:grid-cols-2", children: visibleDiagnostics.map((diagnostic) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
814
1064
|
"div",
|
|
815
1065
|
{
|
|
816
1066
|
className: cn("rounded border px-2 py-1.5 text-xs", diagnosticTone(diagnostic)),
|
|
@@ -823,6 +1073,98 @@ function ContextIntelligenceStrip({
|
|
|
823
1073
|
)) })
|
|
824
1074
|
] });
|
|
825
1075
|
}
|
|
1076
|
+
function resolveDuplicateSegment(duplicateSegment, segments) {
|
|
1077
|
+
return segments.find((segment) => segment.path === duplicateSegment.path) ?? null;
|
|
1078
|
+
}
|
|
1079
|
+
function DuplicateContentPanel({
|
|
1080
|
+
groups,
|
|
1081
|
+
segments,
|
|
1082
|
+
onSegmentActivate
|
|
1083
|
+
}) {
|
|
1084
|
+
if (groups.length === 0) return null;
|
|
1085
|
+
const visibleGroups = groups.slice(0, DUPLICATE_GROUP_DISPLAY_COUNT);
|
|
1086
|
+
const hiddenGroupCount = groups.length - visibleGroups.length;
|
|
1087
|
+
const totalRepeatedTokens = groups.reduce((sum, group) => sum + group.repeatedTokens, 0);
|
|
1088
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "space-y-2 rounded border border-border/70 bg-muted/15 p-2", children: [
|
|
1089
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
1090
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-foreground", children: "Duplicate Content" }),
|
|
1091
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono text-[11px] text-muted-foreground", children: [
|
|
1092
|
+
String(groups.length),
|
|
1093
|
+
" group",
|
|
1094
|
+
groups.length === 1 ? "" : "s",
|
|
1095
|
+
" | ~",
|
|
1096
|
+
formatTokens(totalRepeatedTokens),
|
|
1097
|
+
" repeated"
|
|
1098
|
+
] })
|
|
1099
|
+
] }),
|
|
1100
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: visibleGroups.map((group, groupIndex) => {
|
|
1101
|
+
const visibleSegments = group.segments.slice(0, DUPLICATE_SEGMENT_DISPLAY_COUNT);
|
|
1102
|
+
const hiddenSegmentCount = group.segments.length - visibleSegments.length;
|
|
1103
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1104
|
+
"div",
|
|
1105
|
+
{
|
|
1106
|
+
className: "space-y-1.5 border-t border-border/50 pt-2 first:border-t-0 first:pt-0",
|
|
1107
|
+
children: [
|
|
1108
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2 text-xs", children: [
|
|
1109
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-5 shrink-0 text-right font-mono text-muted-foreground/70", children: String(groupIndex + 1) }),
|
|
1110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate text-foreground", children: group.firstLabel }),
|
|
1111
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "shrink-0 font-mono text-muted-foreground", children: [
|
|
1112
|
+
"x",
|
|
1113
|
+
String(group.count),
|
|
1114
|
+
" | ~",
|
|
1115
|
+
formatTokens(group.repeatedTokens),
|
|
1116
|
+
" saved"
|
|
1117
|
+
] })
|
|
1118
|
+
] }),
|
|
1119
|
+
group.preview.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-7 line-clamp-2 break-words rounded bg-background/40 px-2 py-1 font-mono text-[11px] leading-4 text-muted-foreground", children: group.preview }),
|
|
1120
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-7 flex flex-wrap gap-1", children: [
|
|
1121
|
+
visibleSegments.map((duplicateSegment, segmentIndex) => {
|
|
1122
|
+
const target = resolveDuplicateSegment(duplicateSegment, segments);
|
|
1123
|
+
const activate = target === null || onSegmentActivate === void 0 ? void 0 : onSegmentActivate;
|
|
1124
|
+
const label = `${duplicateSegment.label} ~${formatTokens(
|
|
1125
|
+
duplicateSegment.tokens
|
|
1126
|
+
)}`;
|
|
1127
|
+
if (activate === void 0 || target === null) {
|
|
1128
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1129
|
+
"span",
|
|
1130
|
+
{
|
|
1131
|
+
className: "inline-flex h-6 max-w-40 items-center rounded border border-border/60 px-1.5 text-[11px] text-muted-foreground",
|
|
1132
|
+
title: label,
|
|
1133
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: label })
|
|
1134
|
+
},
|
|
1135
|
+
`${duplicateSegment.path}-${segmentIndex}`
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1139
|
+
"button",
|
|
1140
|
+
{
|
|
1141
|
+
type: "button",
|
|
1142
|
+
onClick: () => activate(target),
|
|
1143
|
+
className: "inline-flex h-6 max-w-40 items-center rounded border border-border/60 px-1.5 text-[11px] text-muted-foreground hover:border-border hover:bg-muted/40 hover:text-foreground",
|
|
1144
|
+
title: "Jump to this duplicate block",
|
|
1145
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: label })
|
|
1146
|
+
},
|
|
1147
|
+
`${duplicateSegment.path}-${segmentIndex}`
|
|
1148
|
+
);
|
|
1149
|
+
}),
|
|
1150
|
+
hiddenSegmentCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex h-6 items-center rounded border border-border/40 px-1.5 font-mono text-[11px] text-muted-foreground/70", children: [
|
|
1151
|
+
"+",
|
|
1152
|
+
String(hiddenSegmentCount)
|
|
1153
|
+
] })
|
|
1154
|
+
] })
|
|
1155
|
+
]
|
|
1156
|
+
},
|
|
1157
|
+
group.key
|
|
1158
|
+
);
|
|
1159
|
+
}) }),
|
|
1160
|
+
hiddenGroupCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border/50 pt-2 font-mono text-[11px] text-muted-foreground", children: [
|
|
1161
|
+
"+",
|
|
1162
|
+
String(hiddenGroupCount),
|
|
1163
|
+
" more duplicate group",
|
|
1164
|
+
hiddenGroupCount === 1 ? "" : "s"
|
|
1165
|
+
] })
|
|
1166
|
+
] });
|
|
1167
|
+
}
|
|
826
1168
|
function aggregateByRole(segments) {
|
|
827
1169
|
const result = [];
|
|
828
1170
|
for (const role of ROLE_ORDER) {
|
|
@@ -853,6 +1195,7 @@ function RequestAnatomy({
|
|
|
853
1195
|
onSegmentActivate,
|
|
854
1196
|
segments: providedSegments
|
|
855
1197
|
}) {
|
|
1198
|
+
const { providers } = useProviders();
|
|
856
1199
|
const [viewMode, setViewMode] = reactExports.useState("role");
|
|
857
1200
|
const segments = reactExports.useMemo(() => providedSegments ?? null, [providedSegments]);
|
|
858
1201
|
const total = reactExports.useMemo(
|
|
@@ -872,9 +1215,10 @@ function RequestAnatomy({
|
|
|
872
1215
|
segments,
|
|
873
1216
|
inputTokens,
|
|
874
1217
|
parsed,
|
|
875
|
-
model
|
|
1218
|
+
model,
|
|
1219
|
+
providers
|
|
876
1220
|
}),
|
|
877
|
-
[inputTokens, model, parsed, segments]
|
|
1221
|
+
[inputTokens, model, parsed, providers, segments]
|
|
878
1222
|
);
|
|
879
1223
|
const showDivergenceWarning = reactExports.useMemo(() => {
|
|
880
1224
|
if (segments === null) return false;
|
|
@@ -897,7 +1241,10 @@ function RequestAnatomy({
|
|
|
897
1241
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 150, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-3 space-y-3", "data-testid": "anatomy-root", children: [
|
|
898
1242
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
|
|
899
1243
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
|
|
900
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
1244
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
|
|
1245
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold text-foreground", children: "Request Context" }),
|
|
1246
|
+
intelligence !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextHealthBadge, { health: intelligence.health })
|
|
1247
|
+
] }),
|
|
901
1248
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("mt-0.5 text-xs font-mono tabular-nums", summaryColorClass), children: [
|
|
902
1249
|
"Estimated ~",
|
|
903
1250
|
formatTokens(total),
|
|
@@ -951,6 +1298,14 @@ function RequestAnatomy({
|
|
|
951
1298
|
"Estimate differs from provider-reported input."
|
|
952
1299
|
] }),
|
|
953
1300
|
intelligence !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextIntelligenceStrip, { intelligence }),
|
|
1301
|
+
intelligence !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1302
|
+
DuplicateContentPanel,
|
|
1303
|
+
{
|
|
1304
|
+
groups: intelligence.duplicateGroups,
|
|
1305
|
+
segments,
|
|
1306
|
+
onSegmentActivate
|
|
1307
|
+
}
|
|
1308
|
+
),
|
|
954
1309
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
955
1310
|
SegmentBar,
|
|
956
1311
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { g as getLogFormatAdapter, f as formatTokens, c as cn,
|
|
3
|
-
import "./router-
|
|
2
|
+
import { g as getLogFormatAdapter, f as formatTokens, c as cn, s as getStatusCategory, B as Badge, C as Collapsible, t as CollapsibleTrigger, v as CollapsibleContent, S as ScrollArea, w as JsonViewer, x as safeJsonValue } from "./ProxyViewerContainer-BiBdKWtj.mjs";
|
|
3
|
+
import "./router-C7S8FRth.mjs";
|
|
4
4
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
5
5
|
import "../_libs/jszip.mjs";
|
|
6
6
|
import { Z as Zap, j as TriangleAlert, ab as CircleStop, B as Brain, b as ChevronDown, f as ChevronRight, T as Terminal } from "../_libs/lucide-react.mjs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { k as TooltipProvider, l as Tooltip, m as TooltipTrigger, B as Badge, n as TooltipContent,
|
|
3
|
-
import "./router-
|
|
2
|
+
import { k as TooltipProvider, l as Tooltip, m as TooltipTrigger, B as Badge, n as TooltipContent, w as JsonViewer } from "./ProxyViewerContainer-BiBdKWtj.mjs";
|
|
3
|
+
import "./router-C7S8FRth.mjs";
|
|
4
4
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
5
5
|
import "../_libs/jszip.mjs";
|
|
6
6
|
import { b as ChevronDown, f as ChevronRight, L as LoaderCircle } from "../_libs/lucide-react.mjs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as ProxyViewerContainer } from "./ProxyViewerContainer-
|
|
1
|
+
import { P as ProxyViewerContainer } from "./ProxyViewerContainer-BiBdKWtj.mjs";
|
|
2
2
|
import "../_libs/react.mjs";
|
|
3
|
-
import "./router-
|
|
3
|
+
import "./router-C7S8FRth.mjs";
|
|
4
4
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
5
5
|
import "../_libs/jszip.mjs";
|
|
6
6
|
import "../_libs/swr.mjs";
|
|
@@ -198,7 +198,7 @@ function getResponse() {
|
|
|
198
198
|
return event.res;
|
|
199
199
|
}
|
|
200
200
|
async function getStartManifest(matchedRoutes) {
|
|
201
|
-
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-
|
|
201
|
+
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-CVTkFOdT.mjs");
|
|
202
202
|
const startManifest = tsrStartManifest();
|
|
203
203
|
const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
|
|
204
204
|
rootRoute.assets = rootRoute.assets || [];
|
|
@@ -767,7 +767,7 @@ let entriesPromise;
|
|
|
767
767
|
let baseManifestPromise;
|
|
768
768
|
let cachedFinalManifestPromise;
|
|
769
769
|
async function loadEntries() {
|
|
770
|
-
const routerEntry = await import("./router-
|
|
770
|
+
const routerEntry = await import("./router-C7S8FRth.mjs").then((n) => n.m);
|
|
771
771
|
const startEntry = await import("./start-HYkvq4Ni.mjs");
|
|
772
772
|
return { startEntry, routerEntry };
|
|
773
773
|
}
|