@tonyclaw/agent-inspector 2.0.8 → 2.0.10
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-Djb4XFZS.js → CompareDrawer-BWMipEjS.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-DIAgurux.js +114 -0
- package/.output/public/assets/{ReplayDialog-DBPMIs2I.js → ReplayDialog-DaSzZsvM.js} +1 -1
- package/.output/public/assets/RequestAnatomy-BfQmPHCd.js +1 -0
- package/.output/public/assets/ResponseView-CblEWDMx.js +1 -0
- package/.output/public/assets/StreamingChunkSequence-B4atnL99.js +1 -0
- package/.output/public/assets/_sessionId-DUzYnZXV.js +1 -0
- package/.output/public/assets/index-CxhRsekH.css +1 -0
- package/.output/public/assets/index-jagRsQaV.js +1 -0
- package/.output/public/assets/{main-CwhqfJqM.js → main-DE6Y4-wV.js} +2 -2
- package/.output/server/{_sessionId-DzBy9gLa.mjs → _sessionId-61HO9rUI.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-C5NBvE2e.mjs → CompareDrawer-CSPqneYm.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-DiZjOTQT.mjs → ProxyViewerContainer-DrSMa5O7.mjs} +159 -14
- package/.output/server/_ssr/{ReplayDialog-EpvTwFvp.mjs → ReplayDialog-Dn3naENv.mjs} +3 -3
- package/.output/server/_ssr/{RequestAnatomy-DaQjhixp.mjs → RequestAnatomy-D1X3f3AX.mjs} +336 -42
- package/.output/server/_ssr/{ResponseView-D8tGHCGY.mjs → ResponseView-CwXAWOoE.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-DGQnb1QE.mjs → StreamingChunkSequence-DRSR2FfN.mjs} +2 -2
- package/.output/server/_ssr/{index-N25hqa7t.mjs → index-D4zn5CAg.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-Bf0m6F0G.mjs → router-CSRaa_tu.mjs} +531 -111
- package/.output/server/{_tanstack-start-manifest_v-DlAyJ5DB.mjs → _tanstack-start-manifest_v-CfvVUYYj.mjs} +1 -1
- package/.output/server/index.mjs +60 -60
- package/bin/agent-inspector.js +2 -0
- package/package.json +3 -2
- 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 +134 -3
- package/src/components/proxy-viewer/anatomy/contextIntelligence.ts +298 -40
- 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-CWdkPZsJ.js +0 -114
- package/.output/public/assets/RequestAnatomy-FBfRNQN7.js +0 -1
- package/.output/public/assets/ResponseView-Db4pJL7U.js +0 -1
- package/.output/public/assets/StreamingChunkSequence-BH175O6R.js +0 -1
- package/.output/public/assets/_sessionId-3ipVoQtW.js +0 -1
- package/.output/public/assets/index-Bo1dGS4R.css +0 -1
- package/.output/public/assets/index-CJgaCJo8.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-DrSMa5O7.mjs";
|
|
3
|
+
import { s as safeGetOwnProperty, k as resolveProviderContextWindow, l as isPlainRecord } from "./router-CSRaa_tu.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",
|
|
@@ -415,13 +599,14 @@ function analyzeContextIntelligence({
|
|
|
415
599
|
segments,
|
|
416
600
|
inputTokens,
|
|
417
601
|
parsed,
|
|
418
|
-
model
|
|
602
|
+
model,
|
|
603
|
+
providers = []
|
|
419
604
|
}) {
|
|
420
605
|
const totalEstimatedTokens = segments.reduce((sum, segment) => sum + segment.size, 0);
|
|
421
606
|
const requestModel = model ?? readRequestModel(parsed);
|
|
422
607
|
const estimatedInputTokens = inputTokens ?? totalEstimatedTokens;
|
|
423
608
|
const outputReserveTokens = readPositiveIntegerField(parsed, OUTPUT_RESERVE_FIELDS);
|
|
424
|
-
const contextWindow = resolveContextWindow(requestModel, parsed);
|
|
609
|
+
const contextWindow = resolveContextWindow(requestModel, parsed, providers);
|
|
425
610
|
const reservedTokens = outputReserveTokens ?? 0;
|
|
426
611
|
const windowUsedTokens = contextWindow.tokens === null ? null : estimatedInputTokens + reservedTokens;
|
|
427
612
|
const remainingInputTokens = contextWindow.tokens === null ? null : contextWindow.tokens - estimatedInputTokens;
|
|
@@ -430,7 +615,8 @@ function analyzeContextIntelligence({
|
|
|
430
615
|
const roleUsages = buildRoleUsages(segments, totalEstimatedTokens);
|
|
431
616
|
const largestRole = roleUsages[0] ?? null;
|
|
432
617
|
const messageSegmentCount = segments.filter((segment) => segment.role !== "tools").length;
|
|
433
|
-
const
|
|
618
|
+
const duplicateGroups = duplicateContextGroups(segments);
|
|
619
|
+
const duplicate = duplicateDiagnostic(duplicateGroups);
|
|
434
620
|
const diagnostics = diagnosticsForRolePressure(
|
|
435
621
|
roleUsages,
|
|
436
622
|
totalEstimatedTokens,
|
|
@@ -449,7 +635,8 @@ function analyzeContextIntelligence({
|
|
|
449
635
|
riskLevel: riskLevel(usagePercent),
|
|
450
636
|
roleUsages,
|
|
451
637
|
largestRole,
|
|
452
|
-
diagnostics
|
|
638
|
+
diagnostics,
|
|
639
|
+
duplicateGroups
|
|
453
640
|
};
|
|
454
641
|
}
|
|
455
642
|
const CONTEXT_USAGE_THRESHOLDS = {
|
|
@@ -662,6 +849,8 @@ const SegmentBar = reactExports.memo(function SegmentBar2({
|
|
|
662
849
|
});
|
|
663
850
|
const DIVERGENCE_AMBER_THRESHOLD = 0.25;
|
|
664
851
|
const TOP_CONTRIBUTOR_COUNT = 5;
|
|
852
|
+
const DUPLICATE_GROUP_DISPLAY_COUNT = 4;
|
|
853
|
+
const DUPLICATE_SEGMENT_DISPLAY_COUNT = 6;
|
|
665
854
|
const ROLE_ORDER = ["system", "user", "assistant", "tool", "tools"];
|
|
666
855
|
const ROLE_DESCRIPTIONS = {
|
|
667
856
|
system: "instructions",
|
|
@@ -709,6 +898,8 @@ function formatContextSource(intelligence) {
|
|
|
709
898
|
switch (intelligence.contextWindow.source) {
|
|
710
899
|
case "request":
|
|
711
900
|
return intelligence.contextWindow.label;
|
|
901
|
+
case "provider":
|
|
902
|
+
return intelligence.contextWindow.label;
|
|
712
903
|
case "model-rule":
|
|
713
904
|
return intelligence.contextWindow.label;
|
|
714
905
|
case "unknown":
|
|
@@ -729,6 +920,7 @@ function ContextIntelligenceStrip({
|
|
|
729
920
|
const usageWidth = intelligence.usagePercent === null ? 0 : Math.max(1, intelligence.usagePercent * 100);
|
|
730
921
|
const outputReserveLabel = intelligence.outputReserveTokens === null ? "No output reserve" : `Output reserve ${formatTokens(intelligence.outputReserveTokens)}`;
|
|
731
922
|
const largestRole = intelligence.largestRole;
|
|
923
|
+
const visibleDiagnostics = intelligence.duplicateGroups.length === 0 ? intelligence.diagnostics : intelligence.diagnostics.filter((diagnostic) => diagnostic.kind !== "duplicate");
|
|
732
924
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
733
925
|
/* @__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
926
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
|
|
@@ -810,7 +1002,7 @@ function ContextIntelligenceStrip({
|
|
|
810
1002
|
] })
|
|
811
1003
|
] })
|
|
812
1004
|
] }),
|
|
813
|
-
|
|
1005
|
+
visibleDiagnostics.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid gap-1.5 sm:grid-cols-2", children: visibleDiagnostics.map((diagnostic) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
814
1006
|
"div",
|
|
815
1007
|
{
|
|
816
1008
|
className: cn("rounded border px-2 py-1.5 text-xs", diagnosticTone(diagnostic)),
|
|
@@ -823,6 +1015,98 @@ function ContextIntelligenceStrip({
|
|
|
823
1015
|
)) })
|
|
824
1016
|
] });
|
|
825
1017
|
}
|
|
1018
|
+
function resolveDuplicateSegment(duplicateSegment, segments) {
|
|
1019
|
+
return segments.find((segment) => segment.path === duplicateSegment.path) ?? null;
|
|
1020
|
+
}
|
|
1021
|
+
function DuplicateContentPanel({
|
|
1022
|
+
groups,
|
|
1023
|
+
segments,
|
|
1024
|
+
onSegmentActivate
|
|
1025
|
+
}) {
|
|
1026
|
+
if (groups.length === 0) return null;
|
|
1027
|
+
const visibleGroups = groups.slice(0, DUPLICATE_GROUP_DISPLAY_COUNT);
|
|
1028
|
+
const hiddenGroupCount = groups.length - visibleGroups.length;
|
|
1029
|
+
const totalRepeatedTokens = groups.reduce((sum, group) => sum + group.repeatedTokens, 0);
|
|
1030
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "space-y-2 rounded border border-border/70 bg-muted/15 p-2", children: [
|
|
1031
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
1032
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-foreground", children: "Duplicate Content" }),
|
|
1033
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono text-[11px] text-muted-foreground", children: [
|
|
1034
|
+
String(groups.length),
|
|
1035
|
+
" group",
|
|
1036
|
+
groups.length === 1 ? "" : "s",
|
|
1037
|
+
" | ~",
|
|
1038
|
+
formatTokens(totalRepeatedTokens),
|
|
1039
|
+
" repeated"
|
|
1040
|
+
] })
|
|
1041
|
+
] }),
|
|
1042
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: visibleGroups.map((group, groupIndex) => {
|
|
1043
|
+
const visibleSegments = group.segments.slice(0, DUPLICATE_SEGMENT_DISPLAY_COUNT);
|
|
1044
|
+
const hiddenSegmentCount = group.segments.length - visibleSegments.length;
|
|
1045
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1046
|
+
"div",
|
|
1047
|
+
{
|
|
1048
|
+
className: "space-y-1.5 border-t border-border/50 pt-2 first:border-t-0 first:pt-0",
|
|
1049
|
+
children: [
|
|
1050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2 text-xs", children: [
|
|
1051
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-5 shrink-0 text-right font-mono text-muted-foreground/70", children: String(groupIndex + 1) }),
|
|
1052
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate text-foreground", children: group.firstLabel }),
|
|
1053
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "shrink-0 font-mono text-muted-foreground", children: [
|
|
1054
|
+
"x",
|
|
1055
|
+
String(group.count),
|
|
1056
|
+
" | ~",
|
|
1057
|
+
formatTokens(group.repeatedTokens),
|
|
1058
|
+
" saved"
|
|
1059
|
+
] })
|
|
1060
|
+
] }),
|
|
1061
|
+
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 }),
|
|
1062
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-7 flex flex-wrap gap-1", children: [
|
|
1063
|
+
visibleSegments.map((duplicateSegment, segmentIndex) => {
|
|
1064
|
+
const target = resolveDuplicateSegment(duplicateSegment, segments);
|
|
1065
|
+
const activate = target === null || onSegmentActivate === void 0 ? void 0 : onSegmentActivate;
|
|
1066
|
+
const label = `${duplicateSegment.label} ~${formatTokens(
|
|
1067
|
+
duplicateSegment.tokens
|
|
1068
|
+
)}`;
|
|
1069
|
+
if (activate === void 0 || target === null) {
|
|
1070
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1071
|
+
"span",
|
|
1072
|
+
{
|
|
1073
|
+
className: "inline-flex h-6 max-w-40 items-center rounded border border-border/60 px-1.5 text-[11px] text-muted-foreground",
|
|
1074
|
+
title: label,
|
|
1075
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: label })
|
|
1076
|
+
},
|
|
1077
|
+
`${duplicateSegment.path}-${segmentIndex}`
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1081
|
+
"button",
|
|
1082
|
+
{
|
|
1083
|
+
type: "button",
|
|
1084
|
+
onClick: () => activate(target),
|
|
1085
|
+
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",
|
|
1086
|
+
title: "Jump to this duplicate block",
|
|
1087
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: label })
|
|
1088
|
+
},
|
|
1089
|
+
`${duplicateSegment.path}-${segmentIndex}`
|
|
1090
|
+
);
|
|
1091
|
+
}),
|
|
1092
|
+
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: [
|
|
1093
|
+
"+",
|
|
1094
|
+
String(hiddenSegmentCount)
|
|
1095
|
+
] })
|
|
1096
|
+
] })
|
|
1097
|
+
]
|
|
1098
|
+
},
|
|
1099
|
+
group.key
|
|
1100
|
+
);
|
|
1101
|
+
}) }),
|
|
1102
|
+
hiddenGroupCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border/50 pt-2 font-mono text-[11px] text-muted-foreground", children: [
|
|
1103
|
+
"+",
|
|
1104
|
+
String(hiddenGroupCount),
|
|
1105
|
+
" more duplicate group",
|
|
1106
|
+
hiddenGroupCount === 1 ? "" : "s"
|
|
1107
|
+
] })
|
|
1108
|
+
] });
|
|
1109
|
+
}
|
|
826
1110
|
function aggregateByRole(segments) {
|
|
827
1111
|
const result = [];
|
|
828
1112
|
for (const role of ROLE_ORDER) {
|
|
@@ -853,6 +1137,7 @@ function RequestAnatomy({
|
|
|
853
1137
|
onSegmentActivate,
|
|
854
1138
|
segments: providedSegments
|
|
855
1139
|
}) {
|
|
1140
|
+
const { providers } = useProviders();
|
|
856
1141
|
const [viewMode, setViewMode] = reactExports.useState("role");
|
|
857
1142
|
const segments = reactExports.useMemo(() => providedSegments ?? null, [providedSegments]);
|
|
858
1143
|
const total = reactExports.useMemo(
|
|
@@ -872,9 +1157,10 @@ function RequestAnatomy({
|
|
|
872
1157
|
segments,
|
|
873
1158
|
inputTokens,
|
|
874
1159
|
parsed,
|
|
875
|
-
model
|
|
1160
|
+
model,
|
|
1161
|
+
providers
|
|
876
1162
|
}),
|
|
877
|
-
[inputTokens, model, parsed, segments]
|
|
1163
|
+
[inputTokens, model, parsed, providers, segments]
|
|
878
1164
|
);
|
|
879
1165
|
const showDivergenceWarning = reactExports.useMemo(() => {
|
|
880
1166
|
if (segments === null) return false;
|
|
@@ -951,6 +1237,14 @@ function RequestAnatomy({
|
|
|
951
1237
|
"Estimate differs from provider-reported input."
|
|
952
1238
|
] }),
|
|
953
1239
|
intelligence !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextIntelligenceStrip, { intelligence }),
|
|
1240
|
+
intelligence !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1241
|
+
DuplicateContentPanel,
|
|
1242
|
+
{
|
|
1243
|
+
groups: intelligence.duplicateGroups,
|
|
1244
|
+
segments,
|
|
1245
|
+
onSegmentActivate
|
|
1246
|
+
}
|
|
1247
|
+
),
|
|
954
1248
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
955
1249
|
SegmentBar,
|
|
956
1250
|
{
|
|
@@ -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-DrSMa5O7.mjs";
|
|
3
|
+
import "./router-CSRaa_tu.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-DrSMa5O7.mjs";
|
|
3
|
+
import "./router-CSRaa_tu.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-DrSMa5O7.mjs";
|
|
2
2
|
import "../_libs/react.mjs";
|
|
3
|
-
import "./router-
|
|
3
|
+
import "./router-CSRaa_tu.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-CfvVUYYj.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-CSRaa_tu.mjs").then((n) => n.m);
|
|
771
771
|
const startEntry = await import("./start-HYkvq4Ni.mjs");
|
|
772
772
|
return { startEntry, routerEntry };
|
|
773
773
|
}
|