@tonyclaw/agent-inspector 2.0.32 → 2.0.34

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 (52) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-Dgi0hhg5.js → CompareDrawer-s5T7W5_w.js} +1 -1
  3. package/.output/public/assets/{ProxyViewerContainer-4dG0nLRp.js → ProxyViewerContainer-DfGfP9VH.js} +22 -22
  4. package/.output/public/assets/{ReplayDialog-BL6BwDuI.js → ReplayDialog-DIxp-ccL.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-DZMmiIiD.js → RequestAnatomy-tfdpiRgw.js} +1 -1
  6. package/.output/public/assets/{ResponseView-DJLOiTYq.js → ResponseView-DMZp3aLW.js} +1 -1
  7. package/.output/public/assets/{StreamingChunkSequence--SxZ5cxc.js → StreamingChunkSequence-xXzLVw7m.js} +1 -1
  8. package/.output/public/assets/_sessionId-Dfxcty_X.js +1 -0
  9. package/.output/public/assets/index-C_8PFAm2.css +1 -0
  10. package/.output/public/assets/index-DztLtWHr.js +1 -0
  11. package/.output/public/assets/{main-CbRIHhJ5.js → main-DHq8ZD95.js} +2 -2
  12. package/.output/server/_libs/ajv.mjs +827 -6191
  13. package/.output/server/_libs/cookie-es.mjs +7 -21
  14. package/.output/server/_libs/h3-v2.mjs +18 -7
  15. package/.output/server/_libs/json-schema-traverse.mjs +1 -90
  16. package/.output/server/_libs/seroval-plugins.mjs +5 -5
  17. package/.output/server/_libs/seroval.mjs +606 -596
  18. package/.output/server/_libs/srvx.mjs +10 -5
  19. package/.output/server/_libs/tanstack__history.mjs +55 -38
  20. package/.output/server/_libs/tanstack__router-core.mjs +4366 -4075
  21. package/.output/server/{_sessionId-DNfumR8F.mjs → _sessionId-Bow47H8m.mjs} +4 -4
  22. package/.output/server/_ssr/{CompareDrawer-CzgjhnUa.mjs → CompareDrawer-Ctn56NJX.mjs} +4 -4
  23. package/.output/server/_ssr/{ProxyViewerContainer-BqOcZ7en.mjs → ProxyViewerContainer-DgPsLI2Q.mjs} +131 -122
  24. package/.output/server/_ssr/{ReplayDialog-DmEknIL8.mjs → ReplayDialog-BD9_rksD.mjs} +5 -5
  25. package/.output/server/_ssr/{RequestAnatomy-DNoiMudY.mjs → RequestAnatomy-BJyzD8pO.mjs} +4 -4
  26. package/.output/server/_ssr/{ResponseView-C_cRrleT.mjs → ResponseView-lebGC0QX.mjs} +4 -4
  27. package/.output/server/_ssr/{StreamingChunkSequence-DHZ9Q_dL.mjs → StreamingChunkSequence-BcOLywzn.mjs} +4 -4
  28. package/.output/server/_ssr/{index-coYS9XyS.mjs → index-CgJOsItz.mjs} +4 -4
  29. package/.output/server/_ssr/index.mjs +20 -11
  30. package/.output/server/_ssr/{router-DUb5lKw1.mjs → router-BMv4lGQi.mjs} +5193 -5269
  31. package/.output/server/{_tanstack-start-manifest_v-xcG1o8Vt.mjs → _tanstack-start-manifest_v-D2LyT1-l.mjs} +1 -1
  32. package/.output/server/index.mjs +68 -68
  33. package/README.md +23 -0
  34. package/package.json +6 -2
  35. package/src/components/groups/GroupsDialog.tsx +132 -121
  36. package/src/lib/groupContract.ts +0 -2
  37. package/src/lib/runContract.ts +0 -3
  38. package/src/mcp/server.ts +101 -164
  39. package/src/mcp/toolHandlers.ts +80 -177
  40. package/src/routes/api/groups.$groupId.evidence.ts +14 -33
  41. package/src/routes/api/groups.$groupId.sessions.ts +9 -9
  42. package/src/routes/api/groups.$groupId.ts +19 -13
  43. package/src/routes/api/groups.ts +3 -3
  44. package/src/routes/api/runs.$runId.evidence.ts +14 -21
  45. package/src/routes/api/runs.$runId.ts +9 -9
  46. package/src/routes/api/runs.ts +9 -5
  47. package/src/services/groups.ts +110 -0
  48. package/src/services/result.ts +17 -0
  49. package/src/services/runs.ts +76 -0
  50. package/.output/public/assets/_sessionId-C4z6gu9i.js +0 -1
  51. package/.output/public/assets/index-Drpb2qR5.js +0 -1
  52. package/.output/public/assets/index-fUUi8iQF.css +0 -1
@@ -305,15 +305,19 @@ export function GroupsDialog(): JSX.Element {
305
305
  setDeleteError(null);
306
306
  }, []);
307
307
 
308
- const handleDeleteDialogOpenChange = useCallback(
309
- (nextOpen: boolean) => {
310
- if (nextOpen || deletingGroupId !== null) return;
311
- setDeleteTarget(null);
312
- setDeleteEvidence(false);
313
- setDeleteError(null);
314
- },
315
- [deletingGroupId],
316
- );
308
+ const handleCancelDelete = useCallback(() => {
309
+ if (deletingGroupId !== null) return;
310
+ setDeleteTarget(null);
311
+ setDeleteEvidence(false);
312
+ setDeleteError(null);
313
+ }, [deletingGroupId]);
314
+
315
+ const handleSelectGroup = useCallback((groupId: string) => {
316
+ setSelectedGroupId(groupId);
317
+ setDeleteTarget(null);
318
+ setDeleteEvidence(false);
319
+ setDeleteError(null);
320
+ }, []);
317
321
 
318
322
  const handleDelete = useCallback(async () => {
319
323
  const group = deleteTarget;
@@ -351,88 +355,81 @@ export function GroupsDialog(): JSX.Element {
351
355
  }, [deleteEvidence, deleteTarget, mutate, mutateEvidence]);
352
356
 
353
357
  return (
354
- <>
355
- <Dialog open={open} onOpenChange={setOpen}>
356
- <DialogTrigger asChild>
358
+ <Dialog open={open} onOpenChange={setOpen}>
359
+ <DialogTrigger asChild>
360
+ <Button
361
+ type="button"
362
+ variant="ghost"
363
+ size="icon"
364
+ className="relative size-8"
365
+ aria-label="Evaluation groups"
366
+ title="Evaluation groups"
367
+ >
368
+ <Layers className="size-4" />
369
+ {isLoading ? (
370
+ <Loader2 className="absolute -right-0.5 -top-0.5 size-3 animate-spin text-muted-foreground" />
371
+ ) : groups.length > 0 ? (
372
+ <span className="absolute -right-1 -top-1 min-w-4 rounded-full bg-primary px-1 text-[10px] leading-4 text-primary-foreground">
373
+ {groups.length}
374
+ </span>
375
+ ) : null}
376
+ <span className="sr-only">Evaluation groups</span>
377
+ </Button>
378
+ </DialogTrigger>
379
+ <DialogContent className="flex max-h-[85vh] max-w-5xl flex-col overflow-hidden">
380
+ <DialogHeader>
381
+ <DialogTitle className="flex items-center gap-2 pr-8">
382
+ <Layers className="size-5 text-muted-foreground" />
383
+ <span>Groups</span>
384
+ <Badge variant="outline">{formatNumber(groups.length)}</Badge>
385
+ </DialogTitle>
386
+ </DialogHeader>
387
+
388
+ <div className="flex min-h-0 items-center justify-between gap-3 border-b border-border pb-3">
389
+ <p className="text-xs text-muted-foreground">
390
+ Evaluation batches, model runs, and exported evidence packs.
391
+ </p>
357
392
  <Button
358
393
  type="button"
359
- variant="ghost"
360
- size="icon"
361
- className="relative size-8"
362
- aria-label="Evaluation groups"
363
- title="Evaluation groups"
394
+ variant="outline"
395
+ size="sm"
396
+ className="shrink-0"
397
+ onClick={handleRefresh}
364
398
  >
365
- <Layers className="size-4" />
366
- {isLoading ? (
367
- <Loader2 className="absolute -right-0.5 -top-0.5 size-3 animate-spin text-muted-foreground" />
368
- ) : groups.length > 0 ? (
369
- <span className="absolute -right-1 -top-1 min-w-4 rounded-full bg-primary px-1 text-[10px] leading-4 text-primary-foreground">
370
- {groups.length}
371
- </span>
372
- ) : null}
373
- <span className="sr-only">Evaluation groups</span>
399
+ <RefreshCw className="size-3.5" />
400
+ Refresh
374
401
  </Button>
375
- </DialogTrigger>
376
- <DialogContent className="flex max-h-[85vh] max-w-5xl flex-col overflow-hidden">
377
- <DialogHeader>
378
- <DialogTitle className="flex items-center gap-2 pr-8">
379
- <Layers className="size-5 text-muted-foreground" />
380
- <span>Groups</span>
381
- <Badge variant="outline">{formatNumber(groups.length)}</Badge>
382
- </DialogTitle>
383
- </DialogHeader>
384
-
385
- <div className="flex min-h-0 items-center justify-between gap-3 border-b border-border pb-3">
386
- <p className="text-xs text-muted-foreground">
387
- Evaluation batches, model runs, and exported evidence packs.
388
- </p>
389
- <Button
390
- type="button"
391
- variant="outline"
392
- size="sm"
393
- className="shrink-0"
394
- onClick={handleRefresh}
395
- >
396
- <RefreshCw className="size-3.5" />
397
- Refresh
398
- </Button>
399
- </div>
402
+ </div>
400
403
 
401
- <div className="grid min-h-0 flex-1 gap-4 md:grid-cols-[260px_minmax(0,1fr)]">
402
- <GroupList
403
- groups={groups}
404
- selectedGroupId={selectedGroup?.id ?? null}
405
- isLoading={isLoading}
406
- error={error}
407
- onSelect={setSelectedGroupId}
408
- />
409
- <GroupDetails
410
- group={selectedGroup}
411
- exportResult={selectedExportResult}
412
- evidenceResponse={evidenceResponse}
413
- evidenceLoading={evidenceLoading}
414
- evidenceError={evidenceError}
415
- exportError={exportError}
416
- deleteError={deleteError}
417
- exportingGroupId={exportingGroupId}
418
- deletingGroupId={deletingGroupId}
419
- onExport={handleExport}
420
- onRequestDelete={handleRequestDelete}
421
- />
422
- </div>
423
- </DialogContent>
424
- </Dialog>
425
- <DeleteGroupDialog
426
- group={deleteTarget}
427
- open={deleteTarget !== null}
428
- deleteEvidence={deleteEvidence}
429
- isDeleting={deleteTarget !== null && deletingGroupId === deleteTarget.id}
430
- error={deleteError}
431
- onDeleteEvidenceChange={setDeleteEvidence}
432
- onOpenChange={handleDeleteDialogOpenChange}
433
- onConfirm={() => void handleDelete()}
434
- />
435
- </>
404
+ <div className="grid min-h-0 flex-1 gap-4 md:grid-cols-[260px_minmax(0,1fr)]">
405
+ <GroupList
406
+ groups={groups}
407
+ selectedGroupId={selectedGroup?.id ?? null}
408
+ isLoading={isLoading}
409
+ error={error}
410
+ onSelect={handleSelectGroup}
411
+ />
412
+ <GroupDetails
413
+ group={selectedGroup}
414
+ deleteTarget={deleteTarget}
415
+ deleteEvidence={deleteEvidence}
416
+ exportResult={selectedExportResult}
417
+ evidenceResponse={evidenceResponse}
418
+ evidenceLoading={evidenceLoading}
419
+ evidenceError={evidenceError}
420
+ exportError={exportError}
421
+ deleteError={deleteError}
422
+ exportingGroupId={exportingGroupId}
423
+ deletingGroupId={deletingGroupId}
424
+ onDeleteEvidenceChange={setDeleteEvidence}
425
+ onExport={handleExport}
426
+ onRequestDelete={handleRequestDelete}
427
+ onCancelDelete={handleCancelDelete}
428
+ onConfirmDelete={() => void handleDelete()}
429
+ />
430
+ </div>
431
+ </DialogContent>
432
+ </Dialog>
436
433
  );
437
434
  }
438
435
 
@@ -511,6 +508,8 @@ function GroupList({
511
508
 
512
509
  function GroupDetails({
513
510
  group,
511
+ deleteTarget,
512
+ deleteEvidence,
514
513
  exportResult,
515
514
  evidenceResponse,
516
515
  evidenceLoading,
@@ -519,10 +518,15 @@ function GroupDetails({
519
518
  deleteError,
520
519
  exportingGroupId,
521
520
  deletingGroupId,
521
+ onDeleteEvidenceChange,
522
522
  onExport,
523
523
  onRequestDelete,
524
+ onCancelDelete,
525
+ onConfirmDelete,
524
526
  }: {
525
527
  group: InspectorGroup | null;
528
+ deleteTarget: InspectorGroup | null;
529
+ deleteEvidence: boolean;
526
530
  exportResult: GroupEvidenceExportResult | null;
527
531
  evidenceResponse: GroupEvidenceReadResponse | null;
528
532
  evidenceLoading: boolean;
@@ -531,8 +535,11 @@ function GroupDetails({
531
535
  deleteError: string | null;
532
536
  exportingGroupId: string | null;
533
537
  deletingGroupId: string | null;
538
+ onDeleteEvidenceChange: (deleteEvidence: boolean) => void;
534
539
  onExport: (group: InspectorGroup) => Promise<void>;
535
540
  onRequestDelete: (group: InspectorGroup) => void;
541
+ onCancelDelete: () => void;
542
+ onConfirmDelete: () => void;
536
543
  }): JSX.Element {
537
544
  if (group === null) {
538
545
  return (
@@ -549,6 +556,7 @@ function GroupDetails({
549
556
  const rows = buildGroupMemberRows(group, exportResult);
550
557
  const isExporting = exportingGroupId === group.id;
551
558
  const isDeleting = deletingGroupId === group.id;
559
+ const isConfirmingDelete = deleteTarget?.id === group.id;
552
560
 
553
561
  return (
554
562
  <div className="min-h-0 overflow-y-auto pr-1">
@@ -608,6 +616,18 @@ function GroupDetails({
608
616
  </p>
609
617
  )}
610
618
 
619
+ {isConfirmingDelete && (
620
+ <DeleteGroupPanel
621
+ group={group}
622
+ deleteEvidence={deleteEvidence}
623
+ isDeleting={isDeleting}
624
+ error={deleteError}
625
+ onDeleteEvidenceChange={onDeleteEvidenceChange}
626
+ onCancel={onCancelDelete}
627
+ onConfirm={onConfirmDelete}
628
+ />
629
+ )}
630
+
611
631
  <div className="grid gap-2 sm:grid-cols-4">
612
632
  <SummaryStat label="Members" value={summary.memberCount} />
613
633
  <SummaryStat label="Done" value={summary.completedMembers} />
@@ -639,7 +659,7 @@ function GroupDetails({
639
659
  </div>
640
660
  )}
641
661
 
642
- {deleteError !== null && (
662
+ {deleteError !== null && !isConfirmingDelete && (
643
663
  <div className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700">
644
664
  {deleteError}
645
665
  </div>
@@ -651,80 +671,71 @@ function GroupDetails({
651
671
  );
652
672
  }
653
673
 
654
- function DeleteGroupDialog({
674
+ function DeleteGroupPanel({
655
675
  group,
656
- open,
657
676
  deleteEvidence,
658
677
  isDeleting,
659
678
  error,
660
679
  onDeleteEvidenceChange,
661
- onOpenChange,
680
+ onCancel,
662
681
  onConfirm,
663
682
  }: {
664
- group: InspectorGroup | null;
665
- open: boolean;
683
+ group: InspectorGroup;
666
684
  deleteEvidence: boolean;
667
685
  isDeleting: boolean;
668
686
  error: string | null;
669
687
  onDeleteEvidenceChange: (deleteEvidence: boolean) => void;
670
- onOpenChange: (open: boolean) => void;
688
+ onCancel: () => void;
671
689
  onConfirm: () => void;
672
690
  }): JSX.Element {
673
- const title = group?.title ?? "this group";
674
- const hasEvidence = group?.evidence !== null && group?.evidence !== undefined;
675
- const evidencePath = group?.evidence?.markdownPath ?? "No evidence pack exported.";
691
+ const hasEvidence = group.evidence !== null;
692
+ const evidencePath = group.evidence?.markdownPath ?? "No evidence pack exported.";
676
693
 
677
694
  return (
678
- <Dialog open={open} onOpenChange={onOpenChange}>
679
- <DialogContent className="max-w-md">
680
- <DialogHeader>
681
- <DialogTitle className="flex items-center gap-2 pr-8">
682
- <Trash2 className="size-5 text-red-600" />
683
- <span>Delete group</span>
684
- </DialogTitle>
685
- </DialogHeader>
686
-
687
- <div className="space-y-3">
688
- <p className="text-sm text-muted-foreground">
689
- Delete <span className="font-medium text-foreground">{title}</span>? Session logs and
690
- run records stay intact.
695
+ <div className="rounded-md border border-red-200 bg-red-50 px-3 py-3 text-red-900">
696
+ <div className="flex min-w-0 flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
697
+ <div className="min-w-0 space-y-2">
698
+ <div className="flex items-center gap-2 text-sm font-semibold">
699
+ <Trash2 className="size-4 text-red-600" />
700
+ <span>Delete group?</span>
701
+ </div>
702
+ <p className="text-xs text-red-800">
703
+ Delete <span className="font-medium">{group.title}</span>. Session logs and run records
704
+ stay intact.
691
705
  </p>
692
-
693
706
  <label
694
707
  className={cn(
695
- "flex items-start gap-3 rounded-md border border-border bg-muted/20 px-3 py-2 text-sm",
708
+ "flex min-w-0 items-start gap-2 text-xs",
696
709
  hasEvidence ? "cursor-pointer" : "opacity-60",
697
710
  )}
698
711
  >
699
712
  <input
700
713
  type="checkbox"
701
- className="mt-0.5 size-4"
714
+ className="mt-0.5 size-4 shrink-0"
702
715
  checked={deleteEvidence}
703
716
  disabled={!hasEvidence || isDeleting}
704
717
  onChange={(event) => onDeleteEvidenceChange(event.currentTarget.checked)}
705
718
  />
706
719
  <span className="min-w-0">
707
720
  <span className="block font-medium">Also delete exported evidence files</span>
708
- <code className="mt-1 block truncate font-mono text-[11px] text-muted-foreground">
721
+ <code className="mt-1 block truncate font-mono text-[11px] text-red-700">
709
722
  {evidencePath}
710
723
  </code>
711
724
  </span>
712
725
  </label>
713
-
714
726
  {error !== null && (
715
- <div className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700">
727
+ <div className="rounded-md border border-red-200 bg-white px-2 py-1.5 text-xs text-red-700">
716
728
  {error}
717
729
  </div>
718
730
  )}
719
731
  </div>
720
-
721
- <div className="flex justify-end gap-2 pt-1">
732
+ <div className="flex shrink-0 justify-end gap-2">
722
733
  <Button
723
734
  type="button"
724
735
  variant="outline"
725
736
  size="sm"
726
737
  disabled={isDeleting}
727
- onClick={() => onOpenChange(false)}
738
+ onClick={onCancel}
728
739
  >
729
740
  Cancel
730
741
  </Button>
@@ -732,7 +743,7 @@ function DeleteGroupDialog({
732
743
  type="button"
733
744
  variant="destructive"
734
745
  size="sm"
735
- disabled={isDeleting || group === null}
746
+ disabled={isDeleting}
736
747
  onClick={onConfirm}
737
748
  >
738
749
  {isDeleting ? (
@@ -743,8 +754,8 @@ function DeleteGroupDialog({
743
754
  Delete
744
755
  </Button>
745
756
  </div>
746
- </DialogContent>
747
- </Dialog>
757
+ </div>
758
+ </div>
748
759
  );
749
760
  }
750
761
 
@@ -143,8 +143,6 @@ export const InspectorGroupsListResponseSchema = z.object({
143
143
  groups: z.array(InspectorGroupSchema),
144
144
  });
145
145
 
146
- export type InspectorGroupStatus = z.infer<typeof InspectorGroupStatusSchema>;
147
- export type InspectorGroupKind = z.infer<typeof InspectorGroupKindSchema>;
148
146
  export type InspectorGroupEvidence = z.infer<typeof InspectorGroupEvidenceSchema>;
149
147
  export type InspectorGroupMember = z.infer<typeof InspectorGroupMemberSchema>;
150
148
  export type InspectorGroup = z.infer<typeof InspectorGroupSchema>;
@@ -146,10 +146,7 @@ export const RecentFailuresResponseSchema = z.object({
146
146
  limit: z.number().int().positive(),
147
147
  });
148
148
 
149
- export type InspectorRunStatus = z.infer<typeof InspectorRunStatusSchema>;
150
149
  export type InspectorRunEvidence = z.infer<typeof InspectorRunEvidenceSchema>;
151
- export type RunTimelineEventKind = z.infer<typeof RunTimelineEventKindSchema>;
152
- export type RunTimelineEventSeverity = z.infer<typeof RunTimelineEventSeveritySchema>;
153
150
  export type RunTimelineEvent = z.infer<typeof RunTimelineEventSchema>;
154
151
  export type FailureCategory = z.infer<typeof FailureCategorySchema>;
155
152
  export type FailureClassification = z.infer<typeof FailureClassificationSchema>;