@copilotz/admin 0.3.7 → 0.3.9

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/dist/index.cjs CHANGED
@@ -31,19 +31,28 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  CopilotzAdmin: () => CopilotzAdmin,
34
+ createCollectionItem: () => createCollectionItem,
34
35
  defaultAdminConfig: () => defaultAdminConfig,
36
+ deleteCollectionItem: () => deleteCollectionItem,
35
37
  fetchAdminActivity: () => fetchAdminActivity,
36
38
  fetchAdminAgents: () => fetchAdminAgents,
37
39
  fetchAdminOverview: () => fetchAdminOverview,
38
40
  fetchAdminParticipants: () => fetchAdminParticipants,
39
41
  fetchAdminThreads: () => fetchAdminThreads,
42
+ fetchCollectionItem: () => fetchCollectionItem,
43
+ fetchCollectionItems: () => fetchCollectionItems,
44
+ fetchCollectionNames: () => fetchCollectionNames,
45
+ fetchParticipantDetail: () => fetchParticipantDetail,
46
+ fetchThreadEvents: () => fetchThreadEvents,
40
47
  mergeAdminConfig: () => mergeAdminConfig,
48
+ updateCollectionItem: () => updateCollectionItem,
49
+ updateParticipant: () => updateParticipant,
41
50
  useCopilotzAdmin: () => useCopilotzAdmin
42
51
  });
43
52
  module.exports = __toCommonJS(index_exports);
44
53
 
45
54
  // src/CopilotzAdmin.tsx
46
- var import_react3 = require("react");
55
+ var import_react8 = require("react");
47
56
 
48
57
  // src/config.ts
49
58
  var defaultAdminConfig = {
@@ -76,7 +85,21 @@ var defaultAdminConfig = {
76
85
  activeThreadsCard: "Active threads",
77
86
  participantsCard: "Participants",
78
87
  tokensCard: "LLM tokens",
88
+ costCard: "LLM cost",
79
89
  queueCard: "Queued events",
90
+ llmUsageTitle: "LLM Usage",
91
+ usageMetricLabel: "Metric",
92
+ usageDimensionLabel: "Usage type",
93
+ usageMetricTokens: "Tokens",
94
+ usageMetricCost: "Cost",
95
+ usageTotal: "Total",
96
+ usageInput: "Input",
97
+ usageOutput: "Output",
98
+ usageReasoning: "Reasoning",
99
+ usageCacheRead: "Cache read",
100
+ usageCacheWrite: "Cache write",
101
+ usageCallsDetail: "LLM calls",
102
+ usageUnavailableDetail: "Available when provider-native usage exists",
80
103
  statusActive: "Active",
81
104
  statusArchived: "Archived",
82
105
  scopeGlobal: "Global",
@@ -85,7 +108,9 @@ var defaultAdminConfig = {
85
108
  unconfigured: "Observed only",
86
109
  noResults: "No results",
87
110
  eventsTitle: "Events",
88
- dashboardTitle: "Dashboard"
111
+ dashboardTitle: "Dashboard",
112
+ collectionsTitle: "Collections",
113
+ collectionsEndpoint: "/v1/collections"
89
114
  },
90
115
  features: {
91
116
  showOverview: true,
@@ -93,7 +118,8 @@ var defaultAdminConfig = {
93
118
  showThreads: true,
94
119
  showParticipants: true,
95
120
  showAgents: true,
96
- showEvents: false
121
+ showEvents: true,
122
+ showCollections: true
97
123
  },
98
124
  ui: {
99
125
  compact: false,
@@ -280,6 +306,122 @@ async function fetchThreadMessages(threadId, messageOptions, options) {
280
306
  options
281
307
  );
282
308
  }
309
+ async function fetchParticipantDetail(participantId, options) {
310
+ return await fetchAdminJson(
311
+ `/v1/participants/${encodeURIComponent(participantId)}`,
312
+ {},
313
+ options
314
+ );
315
+ }
316
+ async function updateParticipant(participantId, data, options) {
317
+ const url = new URL(
318
+ `${resolveBaseUrl(options?.baseUrl)}/v1/participants/${encodeURIComponent(participantId)}`,
319
+ window.location.origin
320
+ );
321
+ const response = await fetch(url.toString(), {
322
+ method: "PUT",
323
+ headers: await withAuthHeaders(
324
+ { "Content-Type": "application/json" },
325
+ options?.getRequestHeaders
326
+ ),
327
+ body: JSON.stringify(data)
328
+ });
329
+ if (!response.ok) {
330
+ throw new Error(`Update participant failed (${response.status})`);
331
+ }
332
+ const payload = await response.json();
333
+ return payload.data;
334
+ }
335
+ async function fetchCollectionNames(options) {
336
+ return await fetchAdminJson("/v1/collections", {}, options);
337
+ }
338
+ async function fetchCollectionItems(collection, queryOptions, options) {
339
+ const params = {
340
+ namespace: queryOptions?.namespace,
341
+ limit: queryOptions?.limit?.toString()
342
+ };
343
+ if (queryOptions?.search) {
344
+ params.q = queryOptions.search;
345
+ } else {
346
+ params.offset = queryOptions?.offset?.toString();
347
+ }
348
+ return await fetchAdminJson(
349
+ `/v1/collections/${encodeURIComponent(collection)}`,
350
+ params,
351
+ options
352
+ );
353
+ }
354
+ async function fetchCollectionItem(collection, itemId, namespace, options) {
355
+ return await fetchAdminJson(
356
+ `/v1/collections/${encodeURIComponent(collection)}/${encodeURIComponent(itemId)}`,
357
+ { namespace },
358
+ options
359
+ );
360
+ }
361
+ async function createCollectionItem(collection, data, namespace, options) {
362
+ const url = new URL(
363
+ `${resolveBaseUrl(options?.baseUrl)}/v1/collections/${encodeURIComponent(collection)}`,
364
+ window.location.origin
365
+ );
366
+ if (namespace) url.searchParams.set("namespace", namespace);
367
+ const response = await fetch(url.toString(), {
368
+ method: "POST",
369
+ headers: await withAuthHeaders(
370
+ { "Content-Type": "application/json" },
371
+ options?.getRequestHeaders
372
+ ),
373
+ body: JSON.stringify(data)
374
+ });
375
+ if (!response.ok) {
376
+ throw new Error(`Create collection item failed (${response.status})`);
377
+ }
378
+ const payload = await response.json();
379
+ if ("body" in payload && payload.body && typeof payload.body === "object") {
380
+ return payload.body;
381
+ }
382
+ return payload;
383
+ }
384
+ async function updateCollectionItem(collection, itemId, data, namespace, options) {
385
+ const url = new URL(
386
+ `${resolveBaseUrl(options?.baseUrl)}/v1/collections/${encodeURIComponent(collection)}/${encodeURIComponent(itemId)}`,
387
+ window.location.origin
388
+ );
389
+ if (namespace) url.searchParams.set("namespace", namespace);
390
+ const response = await fetch(url.toString(), {
391
+ method: "PUT",
392
+ headers: await withAuthHeaders(
393
+ { "Content-Type": "application/json" },
394
+ options?.getRequestHeaders
395
+ ),
396
+ body: JSON.stringify(data)
397
+ });
398
+ if (!response.ok) {
399
+ throw new Error(`Update collection item failed (${response.status})`);
400
+ }
401
+ const payload = await response.json();
402
+ return payload.data;
403
+ }
404
+ async function deleteCollectionItem(collection, itemId, namespace, options) {
405
+ const url = new URL(
406
+ `${resolveBaseUrl(options?.baseUrl)}/v1/collections/${encodeURIComponent(collection)}/${encodeURIComponent(itemId)}`,
407
+ window.location.origin
408
+ );
409
+ if (namespace) url.searchParams.set("namespace", namespace);
410
+ const response = await fetch(url.toString(), {
411
+ method: "DELETE",
412
+ headers: await withAuthHeaders({}, options?.getRequestHeaders)
413
+ });
414
+ if (!response.ok) {
415
+ throw new Error(`Delete collection item failed (${response.status})`);
416
+ }
417
+ }
418
+ async function fetchThreadEvents(threadId, options) {
419
+ return await fetchAdminJson(
420
+ `/v1/threads/${encodeURIComponent(threadId)}/events`,
421
+ {},
422
+ options
423
+ );
424
+ }
283
425
 
284
426
  // src/useCopilotzAdmin.ts
285
427
  function useCopilotzAdmin(options = {}) {
@@ -568,11 +710,35 @@ function Input({ className, type, ...props }) {
568
710
  );
569
711
  }
570
712
 
713
+ // src/components/ui/separator.tsx
714
+ var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"), 1);
715
+ var import_jsx_runtime5 = require("react/jsx-runtime");
716
+ function Separator({
717
+ className,
718
+ orientation = "horizontal",
719
+ decorative = true,
720
+ ...props
721
+ }) {
722
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
723
+ SeparatorPrimitive.Root,
724
+ {
725
+ "data-slot": "separator",
726
+ decorative,
727
+ orientation,
728
+ className: cn(
729
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
730
+ className
731
+ ),
732
+ ...props
733
+ }
734
+ );
735
+ }
736
+
571
737
  // src/components/ui/sheet.tsx
572
738
  var React2 = __toESM(require("react"), 1);
573
739
  var SheetPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
574
740
  var import_lucide_react = require("lucide-react");
575
- var import_jsx_runtime5 = require("react/jsx-runtime");
741
+ var import_jsx_runtime6 = require("react/jsx-runtime");
576
742
  function cleanupBodyStyles() {
577
743
  if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
578
744
  document.body.style.pointerEvents = "";
@@ -592,18 +758,18 @@ function Sheet({ open, onOpenChange, ...props }) {
592
758
  cleanupBodyStyles();
593
759
  };
594
760
  }, []);
595
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SheetPrimitive.Root, { "data-slot": "sheet", open, onOpenChange, ...props });
761
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SheetPrimitive.Root, { "data-slot": "sheet", open, onOpenChange, ...props });
596
762
  }
597
763
  function SheetPortal({
598
764
  ...props
599
765
  }) {
600
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
766
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
601
767
  }
602
768
  function SheetOverlay({
603
769
  className,
604
770
  ...props
605
771
  }) {
606
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
772
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
607
773
  SheetPrimitive.Overlay,
608
774
  {
609
775
  "data-slot": "sheet-overlay",
@@ -624,9 +790,9 @@ function SheetContent({
624
790
  side = "right",
625
791
  ...props
626
792
  }) {
627
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(SheetPortal, { children: [
628
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SheetOverlay, {}),
629
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
793
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(SheetPortal, { children: [
794
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SheetOverlay, {}),
795
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
630
796
  SheetPrimitive.Content,
631
797
  {
632
798
  "data-slot": "sheet-content",
@@ -642,9 +808,9 @@ function SheetContent({
642
808
  ...props,
643
809
  children: [
644
810
  children,
645
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(SheetPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
646
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.XIcon, { className: "size-4" }),
647
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "sr-only", children: "Close" })
811
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(SheetPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
812
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.XIcon, { className: "size-4" }),
813
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Close" })
648
814
  ] })
649
815
  ]
650
816
  }
@@ -652,7 +818,7 @@ function SheetContent({
652
818
  ] });
653
819
  }
654
820
  function SheetHeader({ className, ...props }) {
655
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
821
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
656
822
  "div",
657
823
  {
658
824
  "data-slot": "sheet-header",
@@ -665,7 +831,7 @@ function SheetTitle({
665
831
  className,
666
832
  ...props
667
833
  }) {
668
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
834
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
669
835
  SheetPrimitive.Title,
670
836
  {
671
837
  "data-slot": "sheet-title",
@@ -678,7 +844,7 @@ function SheetDescription({
678
844
  className,
679
845
  ...props
680
846
  }) {
681
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
847
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
682
848
  SheetPrimitive.Description,
683
849
  {
684
850
  "data-slot": "sheet-description",
@@ -689,7 +855,7 @@ function SheetDescription({
689
855
  }
690
856
 
691
857
  // src/components/ui/sidebar.tsx
692
- var import_jsx_runtime6 = require("react/jsx-runtime");
858
+ var import_jsx_runtime7 = require("react/jsx-runtime");
693
859
  var SIDEBAR_COOKIE_NAME = "sidebar_state";
694
860
  var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
695
861
  var SIDEBAR_WIDTH = "16rem";
@@ -755,7 +921,7 @@ function SidebarProvider({
755
921
  }),
756
922
  [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
757
923
  );
758
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
924
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
759
925
  "div",
760
926
  {
761
927
  "data-slot": "sidebar-wrapper",
@@ -783,7 +949,7 @@ function Sidebar({
783
949
  }) {
784
950
  const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
785
951
  if (collapsible === "none") {
786
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
952
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
787
953
  "div",
788
954
  {
789
955
  "data-slot": "sidebar",
@@ -797,7 +963,7 @@ function Sidebar({
797
963
  );
798
964
  }
799
965
  if (isMobile) {
800
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
966
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
801
967
  SheetContent,
802
968
  {
803
969
  "data-sidebar": "sidebar",
@@ -809,16 +975,16 @@ function Sidebar({
809
975
  },
810
976
  side,
811
977
  children: [
812
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(SheetHeader, { className: "sr-only", children: [
813
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SheetTitle, { children: "Sidebar" }),
814
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SheetDescription, { children: "Displays the mobile sidebar." })
978
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(SheetHeader, { className: "sr-only", children: [
979
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SheetTitle, { children: "Sidebar" }),
980
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SheetDescription, { children: "Displays the mobile sidebar." })
815
981
  ] }),
816
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex h-full w-full flex-col", children })
982
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex h-full w-full flex-col", children })
817
983
  ]
818
984
  }
819
985
  ) });
820
986
  }
821
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
987
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
822
988
  "div",
823
989
  {
824
990
  className: "group peer text-sidebar-foreground hidden md:block",
@@ -828,7 +994,7 @@ function Sidebar({
828
994
  "data-side": side,
829
995
  "data-slot": "sidebar",
830
996
  children: [
831
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
997
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
832
998
  "div",
833
999
  {
834
1000
  "data-slot": "sidebar-gap",
@@ -840,7 +1006,7 @@ function Sidebar({
840
1006
  )
841
1007
  }
842
1008
  ),
843
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1009
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
844
1010
  "div",
845
1011
  {
846
1012
  "data-slot": "sidebar-container",
@@ -851,7 +1017,7 @@ function Sidebar({
851
1017
  className
852
1018
  ),
853
1019
  ...props,
854
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1020
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
855
1021
  "div",
856
1022
  {
857
1023
  "data-sidebar": "sidebar",
@@ -872,7 +1038,7 @@ function SidebarTrigger({
872
1038
  ...props
873
1039
  }) {
874
1040
  const { toggleSidebar } = useSidebar();
875
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1041
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
876
1042
  Button,
877
1043
  {
878
1044
  "data-sidebar": "trigger",
@@ -886,15 +1052,15 @@ function SidebarTrigger({
886
1052
  },
887
1053
  ...props,
888
1054
  children: [
889
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.PanelLeftIcon, {}),
890
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Toggle Sidebar" })
1055
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react2.PanelLeftIcon, {}),
1056
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sr-only", children: "Toggle Sidebar" })
891
1057
  ]
892
1058
  }
893
1059
  );
894
1060
  }
895
1061
  function SidebarRail({ className, ...props }) {
896
1062
  const { toggleSidebar } = useSidebar();
897
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1063
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
898
1064
  "button",
899
1065
  {
900
1066
  "data-sidebar": "rail",
@@ -917,7 +1083,7 @@ function SidebarRail({ className, ...props }) {
917
1083
  );
918
1084
  }
919
1085
  function SidebarInset({ className, ...props }) {
920
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1086
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
921
1087
  "main",
922
1088
  {
923
1089
  "data-slot": "sidebar-inset",
@@ -931,7 +1097,7 @@ function SidebarInset({ className, ...props }) {
931
1097
  );
932
1098
  }
933
1099
  function SidebarHeader({ className, ...props }) {
934
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1100
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
935
1101
  "div",
936
1102
  {
937
1103
  "data-slot": "sidebar-header",
@@ -942,7 +1108,7 @@ function SidebarHeader({ className, ...props }) {
942
1108
  );
943
1109
  }
944
1110
  function SidebarFooter({ className, ...props }) {
945
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1111
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
946
1112
  "div",
947
1113
  {
948
1114
  "data-slot": "sidebar-footer",
@@ -952,8 +1118,22 @@ function SidebarFooter({ className, ...props }) {
952
1118
  }
953
1119
  );
954
1120
  }
1121
+ function SidebarSeparator({
1122
+ className,
1123
+ ...props
1124
+ }) {
1125
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1126
+ Separator,
1127
+ {
1128
+ "data-slot": "sidebar-separator",
1129
+ "data-sidebar": "separator",
1130
+ className: cn("bg-sidebar-border mx-2 w-auto", className),
1131
+ ...props
1132
+ }
1133
+ );
1134
+ }
955
1135
  function SidebarContent({ className, ...props }) {
956
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1136
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
957
1137
  "div",
958
1138
  {
959
1139
  "data-slot": "sidebar-content",
@@ -967,7 +1147,7 @@ function SidebarContent({ className, ...props }) {
967
1147
  );
968
1148
  }
969
1149
  function SidebarGroup({ className, ...props }) {
970
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1150
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
971
1151
  "div",
972
1152
  {
973
1153
  "data-slot": "sidebar-group",
@@ -983,7 +1163,7 @@ function SidebarGroupLabel({
983
1163
  ...props
984
1164
  }) {
985
1165
  const Comp = asChild ? import_react_slot2.Slot : "div";
986
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1166
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
987
1167
  Comp,
988
1168
  {
989
1169
  "data-slot": "sidebar-group-label",
@@ -1001,7 +1181,7 @@ function SidebarGroupContent({
1001
1181
  className,
1002
1182
  ...props
1003
1183
  }) {
1004
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1184
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1005
1185
  "div",
1006
1186
  {
1007
1187
  "data-slot": "sidebar-group-content",
@@ -1012,7 +1192,7 @@ function SidebarGroupContent({
1012
1192
  );
1013
1193
  }
1014
1194
  function SidebarMenu({ className, ...props }) {
1015
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1195
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1016
1196
  "ul",
1017
1197
  {
1018
1198
  "data-slot": "sidebar-menu",
@@ -1023,7 +1203,7 @@ function SidebarMenu({ className, ...props }) {
1023
1203
  );
1024
1204
  }
1025
1205
  function SidebarMenuItem({ className, ...props }) {
1026
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1206
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1027
1207
  "li",
1028
1208
  {
1029
1209
  "data-slot": "sidebar-menu-item",
@@ -1064,7 +1244,7 @@ function SidebarMenuButton({
1064
1244
  }) {
1065
1245
  const Comp = asChild ? import_react_slot2.Slot : "button";
1066
1246
  const { isMobile, state } = useSidebar();
1067
- const button = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1247
+ const button = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1068
1248
  Comp,
1069
1249
  {
1070
1250
  "data-slot": "sidebar-menu-button",
@@ -1083,9 +1263,9 @@ function SidebarMenuButton({
1083
1263
  children: tooltip
1084
1264
  };
1085
1265
  }
1086
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Tooltip, { children: [
1087
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TooltipTrigger, { asChild: true, children: button }),
1088
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1266
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Tooltip, { children: [
1267
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipTrigger, { asChild: true, children: button }),
1268
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1089
1269
  TooltipContent,
1090
1270
  {
1091
1271
  side: "right",
@@ -1098,86 +1278,12 @@ function SidebarMenuButton({
1098
1278
  }
1099
1279
 
1100
1280
  // src/components/layout/AdminSidebar.tsx
1101
- var import_lucide_react3 = require("lucide-react");
1102
- var import_jsx_runtime7 = require("react/jsx-runtime");
1103
- var NAV_ITEMS = [
1104
- {
1105
- page: "dashboard",
1106
- label: "Dashboard",
1107
- icon: import_lucide_react3.LayoutDashboard
1108
- },
1109
- {
1110
- page: "threads",
1111
- label: "Threads",
1112
- icon: import_lucide_react3.MessageSquare,
1113
- featureKey: "showThreads"
1114
- },
1115
- {
1116
- page: "participants",
1117
- label: "Participants",
1118
- icon: import_lucide_react3.Users,
1119
- featureKey: "showParticipants"
1120
- },
1121
- {
1122
- page: "agents",
1123
- label: "Agents",
1124
- icon: import_lucide_react3.Bot,
1125
- featureKey: "showAgents"
1126
- },
1127
- {
1128
- page: "events",
1129
- label: "Events",
1130
- icon: import_lucide_react3.Activity,
1131
- featureKey: "showEvents"
1132
- }
1133
- ];
1134
- var AdminSidebar = ({
1135
- config,
1136
- currentPage,
1137
- onNavigate
1138
- }) => {
1139
- const visibleItems = NAV_ITEMS.filter(
1140
- (item) => !item.featureKey || config.features[item.featureKey]
1141
- );
1142
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Sidebar, { collapsible: config.sidebar.collapsible, children: [
1143
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-3 px-2 py-3", children: [
1144
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex items-center justify-center shrink-0", children: config.branding.logo || /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react3.LayoutDashboard, { className: "h-4 w-4" }) }) }),
1145
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col min-w-0 group-data-[collapsible=icon]:hidden", children: [
1146
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm font-semibold truncate", children: config.branding.title }),
1147
- config.branding.subtitle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-xs text-muted-foreground truncate", children: config.branding.subtitle })
1148
- ] })
1149
- ] }) }),
1150
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarContent, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(SidebarGroup, { children: [
1151
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: "Navigation" }),
1152
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarMenu, { children: visibleItems.map((item) => {
1153
- const Icon2 = item.icon;
1154
- const label = config.labels[`${item.page}Title`] || item.label;
1155
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1156
- SidebarMenuButton,
1157
- {
1158
- isActive: currentPage === item.page,
1159
- onClick: () => onNavigate(item.page),
1160
- tooltip: label,
1161
- children: [
1162
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon2, {}),
1163
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: label })
1164
- ]
1165
- }
1166
- ) }, item.page);
1167
- }) }) })
1168
- ] }) }),
1169
- config.namespace && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarFooter, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "px-2 py-2 text-xs text-muted-foreground group-data-[collapsible=icon]:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "font-medium uppercase tracking-[0.18em]", children: config.namespace }) }) }),
1170
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarRail, {})
1171
- ] });
1172
- };
1173
-
1174
- // src/components/layout/AdminHeader.tsx
1175
- var import_lucide_react5 = require("lucide-react");
1281
+ var import_lucide_react4 = require("lucide-react");
1176
1282
 
1177
1283
  // src/components/ui/select.tsx
1178
1284
  var React4 = __toESM(require("react"), 1);
1179
1285
  var SelectPrimitive = __toESM(require("@radix-ui/react-select"), 1);
1180
- var import_lucide_react4 = require("lucide-react");
1286
+ var import_lucide_react3 = require("lucide-react");
1181
1287
  var import_jsx_runtime8 = require("react/jsx-runtime");
1182
1288
  var Select = SelectPrimitive.Root;
1183
1289
  var SelectValue = SelectPrimitive.Value;
@@ -1192,7 +1298,7 @@ var SelectTrigger = React4.forwardRef(({ className, children, ...props }, ref) =
1192
1298
  ...props,
1193
1299
  children: [
1194
1300
  children,
1195
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
1301
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
1196
1302
  ]
1197
1303
  }
1198
1304
  ));
@@ -1209,7 +1315,7 @@ var SelectContent = React4.forwardRef(({ className, children, position = "popper
1209
1315
  position,
1210
1316
  ...props,
1211
1317
  children: [
1212
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ScrollUpButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.ChevronUp, { className: "h-4 w-4" }) }),
1318
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ScrollUpButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.ChevronUp, { className: "h-4 w-4" }) }),
1213
1319
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1214
1320
  SelectPrimitive.Viewport,
1215
1321
  {
@@ -1220,7 +1326,7 @@ var SelectContent = React4.forwardRef(({ className, children, position = "popper
1220
1326
  children
1221
1327
  }
1222
1328
  ),
1223
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ScrollDownButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.ChevronDown, { className: "h-4 w-4" }) })
1329
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ScrollDownButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.ChevronDown, { className: "h-4 w-4" }) })
1224
1330
  ]
1225
1331
  }
1226
1332
  ) }));
@@ -1236,25 +1342,117 @@ var SelectItem = React4.forwardRef(({ className, children, ...props }, ref) => /
1236
1342
  ...props,
1237
1343
  children: [
1238
1344
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ItemText, { children }),
1239
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ItemIndicator, { className: "absolute right-2 inline-flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.Check, { className: "h-4 w-4" }) })
1345
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ItemIndicator, { className: "absolute right-2 inline-flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.Check, { className: "h-4 w-4" }) })
1240
1346
  ]
1241
1347
  }
1242
1348
  ));
1243
1349
  SelectItem.displayName = SelectPrimitive.Item.displayName;
1244
1350
 
1245
- // src/components/layout/AdminHeader.tsx
1351
+ // src/components/layout/AdminSidebar.tsx
1246
1352
  var import_jsx_runtime9 = require("react/jsx-runtime");
1353
+ var NAV_ITEMS = [
1354
+ { page: "dashboard", label: "Dashboard", icon: import_lucide_react4.LayoutDashboard },
1355
+ { page: "threads", label: "Threads", icon: import_lucide_react4.MessageSquare, featureKey: "showThreads" },
1356
+ { page: "participants", label: "Participants", icon: import_lucide_react4.Users, featureKey: "showParticipants" },
1357
+ { page: "agents", label: "Agents", icon: import_lucide_react4.Bot, featureKey: "showAgents" },
1358
+ { page: "events", label: "Events", icon: import_lucide_react4.Activity, featureKey: "showEvents" }
1359
+ ];
1360
+ var AdminSidebar = ({
1361
+ config,
1362
+ currentPage,
1363
+ currentRoute,
1364
+ onNavigate,
1365
+ onNavigateRoute,
1366
+ collections,
1367
+ namespace,
1368
+ onNamespaceChange
1369
+ }) => {
1370
+ const visibleItems = NAV_ITEMS.filter(
1371
+ (item) => !item.featureKey || config.features[item.featureKey]
1372
+ );
1373
+ const showCollections = config.features.showCollections && collections.length > 0;
1374
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Sidebar, { collapsible: config.sidebar.collapsible, children: [
1375
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-3 px-2 py-3", children: [
1376
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center justify-center shrink-0", children: config.branding.logo || /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.LayoutDashboard, { className: "h-4 w-4" }) }) }),
1377
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col min-w-0 group-data-[collapsible=icon]:hidden", children: [
1378
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm font-semibold truncate", children: config.branding.title }),
1379
+ config.branding.subtitle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-xs text-muted-foreground truncate", children: config.branding.subtitle })
1380
+ ] })
1381
+ ] }) }),
1382
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(SidebarContent, { children: [
1383
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(SidebarGroup, { children: [
1384
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: "Navigation" }),
1385
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarMenu, { children: visibleItems.map((item) => {
1386
+ const Icon2 = item.icon;
1387
+ const label = config.labels[`${item.page}Title`] || item.label;
1388
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1389
+ SidebarMenuButton,
1390
+ {
1391
+ isActive: currentPage === item.page,
1392
+ onClick: () => onNavigate(item.page),
1393
+ tooltip: label,
1394
+ children: [
1395
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon2, {}),
1396
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: label })
1397
+ ]
1398
+ }
1399
+ ) }, item.page);
1400
+ }) }) })
1401
+ ] }),
1402
+ showCollections && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1403
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarSeparator, {}),
1404
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(SidebarGroup, { children: [
1405
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: config.labels.collectionsTitle }),
1406
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarMenu, { children: collections.map((col) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1407
+ SidebarMenuButton,
1408
+ {
1409
+ isActive: currentRoute.page === "collection-items" && currentRoute.collection === col,
1410
+ onClick: () => onNavigateRoute({ page: "collection-items", collection: col }),
1411
+ tooltip: col,
1412
+ children: [
1413
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Database, {}),
1414
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "capitalize", children: col })
1415
+ ]
1416
+ }
1417
+ ) }, col)) }) })
1418
+ ] })
1419
+ ] })
1420
+ ] }),
1421
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(SidebarFooter, { children: [
1422
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "group-data-[collapsible=icon]:hidden", children: [
1423
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "text-xs font-medium text-muted-foreground mb-1 block px-2", children: "Namespace" }),
1424
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Select, { value: namespace || "__all__", onValueChange: (v) => onNamespaceChange(v === "__all__" ? "" : v), children: [
1425
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectValue, { placeholder: "All namespaces" }) }),
1426
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(SelectContent, { children: [
1427
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectItem, { value: "__all__", children: "All namespaces" }),
1428
+ config.namespace && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectItem, { value: config.namespace, children: config.namespace })
1429
+ ] })
1430
+ ] })
1431
+ ] }),
1432
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "hidden group-data-[collapsible=icon]:flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.ChevronsUpDown, { className: "h-4 w-4 text-muted-foreground" }) })
1433
+ ] }),
1434
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarRail, {})
1435
+ ] });
1436
+ };
1437
+
1438
+ // src/components/layout/AdminHeader.tsx
1439
+ var import_lucide_react5 = require("lucide-react");
1440
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1247
1441
  var PAGE_TITLES = {
1248
1442
  dashboard: "Dashboard",
1249
1443
  threads: "Threads",
1250
1444
  "thread-detail": "Thread Detail",
1251
1445
  participants: "Participants",
1446
+ "participant-detail": "Participant Detail",
1252
1447
  agents: "Agents",
1448
+ "agent-detail": "Agent Detail",
1449
+ "collection-items": "Collection",
1450
+ "collection-item-detail": "Item Detail",
1253
1451
  events: "Events"
1254
1452
  };
1255
1453
  var AdminHeader = ({
1256
1454
  config,
1257
- currentPage,
1455
+ currentRoute,
1258
1456
  range,
1259
1457
  interval,
1260
1458
  onRangeChange,
@@ -1262,19 +1460,22 @@ var AdminHeader = ({
1262
1460
  onRefresh,
1263
1461
  isLoading
1264
1462
  }) => {
1265
- const pageTitle = config.labels[`${currentPage}Title`] || PAGE_TITLES[currentPage];
1266
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Card, { className: "py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CardHeader, { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
1267
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-1", children: [
1268
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1269
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
1270
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { children: "Toggle Sidebar" })
1463
+ let pageTitle = config.labels[`${currentRoute.page}Title`] || PAGE_TITLES[currentRoute.page] || currentRoute.page;
1464
+ if (currentRoute.page === "collection-items" && currentRoute.collection) {
1465
+ pageTitle = currentRoute.collection.charAt(0).toUpperCase() + currentRoute.collection.slice(1);
1466
+ }
1467
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Card, { className: "py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardHeader, { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
1468
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1", children: [
1469
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Tooltip, { children: [
1470
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
1471
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipContent, { children: "Toggle Sidebar" })
1271
1472
  ] }),
1272
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h1", { className: "text-sm font-medium ml-2", children: pageTitle })
1473
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "text-sm font-medium ml-2", children: pageTitle })
1273
1474
  ] }),
1274
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex-1" }),
1275
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-1", children: [
1276
- currentPage === "dashboard" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1277
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1475
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-1" }),
1476
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1", children: [
1477
+ currentRoute.page === "dashboard" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1478
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1278
1479
  Button,
1279
1480
  {
1280
1481
  variant: range === "24h" ? "default" : "ghost",
@@ -1284,7 +1485,7 @@ var AdminHeader = ({
1284
1485
  children: config.labels.range24h
1285
1486
  }
1286
1487
  ),
1287
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1488
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1288
1489
  Button,
1289
1490
  {
1290
1491
  variant: range === "7d" ? "default" : "ghost",
@@ -1294,7 +1495,7 @@ var AdminHeader = ({
1294
1495
  children: config.labels.range7d
1295
1496
  }
1296
1497
  ),
1297
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1498
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1298
1499
  Button,
1299
1500
  {
1300
1501
  variant: range === "30d" ? "default" : "ghost",
@@ -1304,23 +1505,23 @@ var AdminHeader = ({
1304
1505
  children: config.labels.range30d
1305
1506
  }
1306
1507
  ),
1307
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1508
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1308
1509
  Select,
1309
1510
  {
1310
1511
  value: interval,
1311
1512
  onValueChange: (v) => onIntervalChange(v),
1312
1513
  children: [
1313
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectTrigger, { className: "h-7 w-[90px] text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectValue, {}) }),
1314
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(SelectContent, { children: [
1315
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectItem, { value: "hour", children: config.labels.intervalHour }),
1316
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectItem, { value: "day", children: config.labels.intervalDay })
1514
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectTrigger, { className: "h-7 w-[90px] text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectValue, {}) }),
1515
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SelectContent, { children: [
1516
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectItem, { value: "hour", children: config.labels.intervalHour }),
1517
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectItem, { value: "day", children: config.labels.intervalDay })
1317
1518
  ] })
1318
1519
  ]
1319
1520
  }
1320
1521
  )
1321
1522
  ] }),
1322
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1323
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1523
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Tooltip, { children: [
1524
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1324
1525
  Button,
1325
1526
  {
1326
1527
  variant: "ghost",
@@ -1328,7 +1529,7 @@ var AdminHeader = ({
1328
1529
  className: "h-7 w-7",
1329
1530
  onClick: onRefresh,
1330
1531
  disabled: isLoading,
1331
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1532
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1332
1533
  import_lucide_react5.RefreshCw,
1333
1534
  {
1334
1535
  className: `h-4 w-4 ${isLoading ? "animate-spin" : ""}`
@@ -1336,17 +1537,20 @@ var AdminHeader = ({
1336
1537
  )
1337
1538
  }
1338
1539
  ) }),
1339
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { children: config.labels.refresh })
1540
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipContent, { children: config.labels.refresh })
1340
1541
  ] }),
1341
1542
  config.branding.actions
1342
1543
  ] })
1343
1544
  ] }) }) });
1344
1545
  };
1345
1546
 
1547
+ // src/components/views/DashboardView.tsx
1548
+ var import_react2 = __toESM(require("react"), 1);
1549
+
1346
1550
  // src/components/ui/badge.tsx
1347
1551
  var import_react_slot3 = require("@radix-ui/react-slot");
1348
1552
  var import_class_variance_authority3 = require("class-variance-authority");
1349
- var import_jsx_runtime10 = require("react/jsx-runtime");
1553
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1350
1554
  var badgeVariants = (0, import_class_variance_authority3.cva)(
1351
1555
  "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
1352
1556
  {
@@ -1370,7 +1574,7 @@ function Badge({
1370
1574
  ...props
1371
1575
  }) {
1372
1576
  const Comp = asChild ? import_react_slot3.Slot : "span";
1373
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1577
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1374
1578
  Comp,
1375
1579
  {
1376
1580
  "data-slot": "badge",
@@ -1381,7 +1585,7 @@ function Badge({
1381
1585
  }
1382
1586
 
1383
1587
  // src/components/views/DashboardView.tsx
1384
- var import_jsx_runtime11 = require("react/jsx-runtime");
1588
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1385
1589
  var DashboardView = ({
1386
1590
  config,
1387
1591
  overview,
@@ -1398,6 +1602,23 @@ var DashboardView = ({
1398
1602
  onAgentSearchChange,
1399
1603
  onThreadClick
1400
1604
  }) => {
1605
+ const [usageMetricKind, setUsageMetricKind] = import_react2.default.useState(
1606
+ "tokens"
1607
+ );
1608
+ const [usageDimension, setUsageDimension] = import_react2.default.useState(
1609
+ "total"
1610
+ );
1611
+ const llmSummaryValue = overview ? getOverviewUsageValue(overview, usageMetricKind, usageDimension) : 0;
1612
+ const llmSummaryLabel = getUsageSummaryLabel(
1613
+ config.labels,
1614
+ usageMetricKind,
1615
+ usageDimension
1616
+ );
1617
+ const usageBreakdownCards = USAGE_DIMENSIONS.map((dimension) => ({
1618
+ dimension,
1619
+ label: getUsageDimensionLabel(config.labels, dimension),
1620
+ value: overview ? getOverviewUsageValue(overview, usageMetricKind, dimension) : 0
1621
+ }));
1401
1622
  const cards = [
1402
1623
  {
1403
1624
  label: config.labels.messagesCard,
@@ -1415,9 +1636,10 @@ var DashboardView = ({
1415
1636
  detail: `${overview?.participantTotals.agents ?? 0} agents`
1416
1637
  },
1417
1638
  {
1418
- label: config.labels.tokensCard,
1419
- value: overview?.llmTotals.totalTokens ?? 0,
1420
- detail: `${overview?.llmTotals.totalCalls ?? 0} calls`
1639
+ label: llmSummaryLabel,
1640
+ value: llmSummaryValue,
1641
+ detail: `${overview?.llmTotals.totalCalls ?? 0} ${config.labels.usageCallsDetail}`,
1642
+ metricKind: usageMetricKind
1421
1643
  },
1422
1644
  {
1423
1645
  label: config.labels.queueCard,
@@ -1426,40 +1648,110 @@ var DashboardView = ({
1426
1648
  }
1427
1649
  ];
1428
1650
  const isEmpty = cards.every((card) => card.value === 0) && activity.length === 0 && threads.length === 0 && participants.length === 0 && agents.length === 0;
1429
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-6", children: [
1430
- isEmpty && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
1431
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "text-lg font-semibold", children: config.labels.emptyTitle }),
1432
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-2 text-sm text-muted-foreground", children: config.labels.emptyDescription })
1651
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-6", children: [
1652
+ isEmpty && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
1653
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-semibold", children: config.labels.emptyTitle }),
1654
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-2 text-sm text-muted-foreground", children: config.labels.emptyDescription })
1433
1655
  ] }),
1434
- config.features.showOverview && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "space-y-4", children: [
1435
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionHeading, { title: config.labels.overviewTitle }),
1436
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-5", children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1656
+ config.features.showOverview && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "space-y-4", children: [
1657
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SectionHeading, { title: config.labels.overviewTitle }),
1658
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-5", children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1437
1659
  "div",
1438
1660
  {
1439
1661
  className: "rounded-xl border bg-card p-5 shadow-sm",
1440
1662
  children: [
1441
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
1442
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-3 text-3xl font-semibold tracking-tight", children: formatNumber(card.value) }),
1443
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-2 text-xs text-muted-foreground", children: card.detail })
1663
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
1664
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-3 text-3xl font-semibold tracking-tight", children: formatMetricValue(
1665
+ card.value,
1666
+ card.metricKind ?? "tokens"
1667
+ ) }),
1668
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-2 text-xs text-muted-foreground", children: card.detail })
1444
1669
  ]
1445
1670
  },
1446
1671
  card.label
1447
1672
  )) })
1448
1673
  ] }),
1449
- config.features.showActivity && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "space-y-4", children: [
1450
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionHeading, { title: config.labels.activityTitle }),
1451
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1674
+ config.features.showOverview && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "space-y-4", children: [
1675
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between", children: [
1676
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SectionHeading, { title: config.labels.llmUsageTitle }),
1677
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid gap-3 sm:grid-cols-2", children: [
1678
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-1", children: [
1679
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageMetricLabel }),
1680
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1681
+ Select,
1682
+ {
1683
+ value: usageMetricKind,
1684
+ onValueChange: (value) => setUsageMetricKind(value),
1685
+ children: [
1686
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectValue, {}) }),
1687
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(SelectContent, { children: [
1688
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectItem, { value: "tokens", children: config.labels.usageMetricTokens }),
1689
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectItem, { value: "cost", children: config.labels.usageMetricCost })
1690
+ ] })
1691
+ ]
1692
+ }
1693
+ )
1694
+ ] }),
1695
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-1", children: [
1696
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageDimensionLabel }),
1697
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1698
+ Select,
1699
+ {
1700
+ value: usageDimension,
1701
+ onValueChange: (value) => setUsageDimension(value),
1702
+ children: [
1703
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectValue, {}) }),
1704
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectContent, { children: USAGE_DIMENSIONS.map((dimension) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectItem, { value: dimension, children: getUsageDimensionLabel(config.labels, dimension) }, dimension)) })
1705
+ ]
1706
+ }
1707
+ )
1708
+ ] })
1709
+ ] })
1710
+ ] }),
1711
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: usageBreakdownCards.map((card) => {
1712
+ const isSelected = card.dimension === usageDimension;
1713
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1714
+ "div",
1715
+ {
1716
+ className: cn(
1717
+ "rounded-xl border bg-card p-5 shadow-sm transition-colors",
1718
+ isSelected && "border-primary/60 ring-1 ring-primary/15"
1719
+ ),
1720
+ children: [
1721
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
1722
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
1723
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
1724
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-3 text-2xl font-semibold tracking-tight", children: formatMetricValue(card.value, usageMetricKind) })
1725
+ ] }),
1726
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Badge, { variant: "outline", children: config.labels.usageDimensionLabel })
1727
+ ] }),
1728
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "mt-2 text-xs text-muted-foreground", children: [
1729
+ overview?.llmTotals.totalCalls ?? 0,
1730
+ " ",
1731
+ config.labels.usageCallsDetail
1732
+ ] })
1733
+ ]
1734
+ },
1735
+ card.dimension
1736
+ );
1737
+ }) })
1738
+ ] }),
1739
+ config.features.showActivity && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "space-y-4", children: [
1740
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SectionHeading, { title: config.labels.activityTitle }),
1741
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1452
1742
  ActivityChart,
1453
1743
  {
1454
1744
  interval,
1455
1745
  labels: config.labels,
1456
1746
  maxBars: config.ui.maxActivityBars,
1457
- points: activity
1747
+ points: activity,
1748
+ usageDimension,
1749
+ usageMetricKind
1458
1750
  }
1459
1751
  )
1460
1752
  ] }),
1461
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid gap-6 lg:grid-cols-3", children: [
1462
- config.features.showThreads && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1753
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid gap-6 lg:grid-cols-3", children: [
1754
+ config.features.showThreads && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1463
1755
  DataTable,
1464
1756
  {
1465
1757
  rows: threads,
@@ -1467,7 +1759,7 @@ var DashboardView = ({
1467
1759
  searchValue: threadSearch,
1468
1760
  setSearchValue: onThreadSearchChange,
1469
1761
  title: config.labels.threadsTitle,
1470
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1762
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1471
1763
  ThreadsTable,
1472
1764
  {
1473
1765
  rows: threads,
@@ -1477,7 +1769,7 @@ var DashboardView = ({
1477
1769
  )
1478
1770
  }
1479
1771
  ),
1480
- config.features.showParticipants && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1772
+ config.features.showParticipants && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1481
1773
  DataTable,
1482
1774
  {
1483
1775
  rows: participants,
@@ -1485,10 +1777,10 @@ var DashboardView = ({
1485
1777
  searchValue: participantSearch,
1486
1778
  setSearchValue: onParticipantSearchChange,
1487
1779
  title: config.labels.participantsTitle,
1488
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ParticipantsTable, { rows: participants, labels: config.labels })
1780
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ParticipantsTable, { rows: participants, labels: config.labels })
1489
1781
  }
1490
1782
  ),
1491
- config.features.showAgents && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1783
+ config.features.showAgents && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1492
1784
  DataTable,
1493
1785
  {
1494
1786
  rows: agents,
@@ -1496,52 +1788,75 @@ var DashboardView = ({
1496
1788
  searchValue: agentSearch,
1497
1789
  setSearchValue: onAgentSearchChange,
1498
1790
  title: config.labels.agentsTitle,
1499
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AgentsTable, { rows: agents, labels: config.labels })
1791
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1792
+ AgentsTable,
1793
+ {
1794
+ rows: agents,
1795
+ labels: config.labels,
1796
+ usageMetricKind,
1797
+ usageDimension
1798
+ }
1799
+ )
1500
1800
  }
1501
1801
  )
1502
1802
  ] })
1503
1803
  ] });
1504
1804
  };
1505
1805
  function SectionHeading({ title }) {
1506
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: title });
1806
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: title });
1507
1807
  }
1508
1808
  function ActivityChart(props) {
1509
1809
  const trimmedPoints = props.points.slice(-props.maxBars);
1510
- const maxMessages = Math.max(
1511
- ...trimmedPoints.map((point) => point.messageCount),
1810
+ const maxUsageValue = Math.max(
1811
+ ...trimmedPoints.map(
1812
+ (point) => getActivityUsageValue(
1813
+ point,
1814
+ props.usageMetricKind,
1815
+ props.usageDimension
1816
+ )
1817
+ ),
1512
1818
  1
1513
1819
  );
1514
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: trimmedPoints.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-muted-foreground", children: props.labels.noResults }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex min-h-48 items-end gap-2", children: trimmedPoints.map((point) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1515
- "div",
1516
- {
1517
- className: "flex min-w-0 flex-1 flex-col items-center gap-2",
1518
- children: [
1519
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1520
- "div",
1521
- {
1522
- className: "w-full rounded-md bg-primary transition-all",
1523
- style: {
1524
- height: `${Math.max(point.messageCount / maxMessages * 100, 8)}%`
1820
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: trimmedPoints.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm text-muted-foreground", children: props.labels.noResults }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex min-h-48 items-end gap-2", children: trimmedPoints.map((point) => {
1821
+ const usageValue = getActivityUsageValue(
1822
+ point,
1823
+ props.usageMetricKind,
1824
+ props.usageDimension
1825
+ );
1826
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1827
+ "div",
1828
+ {
1829
+ className: "flex min-w-0 flex-1 flex-col items-center gap-2",
1830
+ children: [
1831
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1832
+ "div",
1833
+ {
1834
+ className: "w-full rounded-md bg-primary transition-all",
1835
+ style: {
1836
+ height: `${Math.max(usageValue / maxUsageValue * 100, 8)}%`
1837
+ }
1525
1838
  }
1526
- }
1527
- ) }),
1528
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-center", children: [
1529
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-xs font-medium", children: formatBucket(point.bucket, props.interval) }),
1530
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
1531
- formatNumber(point.messageCount),
1532
- " msg"
1839
+ ) }),
1840
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-center", children: [
1841
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs font-medium", children: formatBucket(point.bucket, props.interval) }),
1842
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-[11px] text-muted-foreground", children: formatMetricValue(usageValue, props.usageMetricKind) }),
1843
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
1844
+ formatNumber(point.totalCalls),
1845
+ " ",
1846
+ props.labels.usageCallsDetail
1847
+ ] })
1533
1848
  ] })
1534
- ] })
1535
- ]
1536
- },
1537
- point.bucket
1538
- )) }) });
1849
+ ]
1850
+ },
1851
+ point.bucket
1852
+ );
1853
+ }) }) });
1539
1854
  }
1540
1855
  function DataTable(props) {
1541
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
1542
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-4 flex items-center justify-between gap-3", children: [
1543
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionHeading, { title: props.title }),
1544
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1856
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
1857
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mb-4 flex items-center justify-between gap-3", children: [
1858
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SectionHeading, { title: props.title }),
1859
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1545
1860
  Input,
1546
1861
  {
1547
1862
  className: "h-8 w-full max-w-44",
@@ -1551,7 +1866,7 @@ function DataTable(props) {
1551
1866
  }
1552
1867
  )
1553
1868
  ] }),
1554
- props.rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-muted-foreground", children: "No results" }) : props.children
1869
+ props.rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm text-muted-foreground", children: "No results" }) : props.children
1555
1870
  ] });
1556
1871
  }
1557
1872
  function ThreadsTable({
@@ -1559,7 +1874,7 @@ function ThreadsTable({
1559
1874
  labels,
1560
1875
  onThreadClick
1561
1876
  }) {
1562
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-3", children: rows.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1877
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-3", children: rows.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1563
1878
  "div",
1564
1879
  {
1565
1880
  className: cn(
@@ -1568,12 +1883,12 @@ function ThreadsTable({
1568
1883
  ),
1569
1884
  onClick: () => onThreadClick?.(thread.threadId),
1570
1885
  children: [
1571
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
1572
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "min-w-0", children: [
1573
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "font-medium", children: thread.name }),
1574
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
1886
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
1887
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "min-w-0", children: [
1888
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "font-medium", children: thread.name }),
1889
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
1575
1890
  ] }),
1576
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1891
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1577
1892
  Badge,
1578
1893
  {
1579
1894
  variant: thread.status === "archived" ? "secondary" : "default",
@@ -1581,16 +1896,16 @@ function ThreadsTable({
1581
1896
  }
1582
1897
  )
1583
1898
  ] }),
1584
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground", children: [
1585
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1899
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground", children: [
1900
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1586
1901
  formatNumber(thread.messageCount),
1587
1902
  " messages"
1588
1903
  ] }),
1589
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1904
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1590
1905
  thread.participantIds.length,
1591
1906
  " participants"
1592
1907
  ] }),
1593
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: formatDate(thread.lastActivityAt) })
1908
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: formatDate(thread.lastActivityAt) })
1594
1909
  ] })
1595
1910
  ]
1596
1911
  },
@@ -1601,28 +1916,28 @@ function ParticipantsTable({
1601
1916
  rows,
1602
1917
  labels
1603
1918
  }) {
1604
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-3", children: rows.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1919
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-3", children: rows.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1605
1920
  "div",
1606
1921
  {
1607
1922
  className: "rounded-lg border bg-muted/50 p-4",
1608
1923
  children: [
1609
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
1610
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "min-w-0", children: [
1611
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "font-medium", children: participant.displayName }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-muted-foreground", children: participant.participantType })
1924
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
1925
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "min-w-0", children: [
1926
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "font-medium", children: participant.displayName }),
1927
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-muted-foreground", children: participant.participantType })
1613
1928
  ] }),
1614
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Badge, { variant: "outline", children: participant.isGlobal ? labels.scopeGlobal : labels.scopeScoped })
1929
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Badge, { variant: "outline", children: participant.isGlobal ? labels.scopeGlobal : labels.scopeScoped })
1615
1930
  ] }),
1616
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground", children: [
1617
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1931
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground", children: [
1932
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1618
1933
  formatNumber(participant.messageCount),
1619
1934
  " messages"
1620
1935
  ] }),
1621
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1936
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1622
1937
  formatNumber(participant.threadCount),
1623
1938
  " threads"
1624
1939
  ] }),
1625
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: formatDate(participant.lastActivityAt) })
1940
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: formatDate(participant.lastActivityAt) })
1626
1941
  ] })
1627
1942
  ]
1628
1943
  },
@@ -1631,38 +1946,46 @@ function ParticipantsTable({
1631
1946
  }
1632
1947
  function AgentsTable({
1633
1948
  rows,
1634
- labels
1949
+ labels,
1950
+ usageMetricKind,
1951
+ usageDimension
1635
1952
  }) {
1636
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-3", children: rows.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1953
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-3", children: rows.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1637
1954
  "div",
1638
1955
  {
1639
1956
  className: "rounded-lg border bg-muted/50 p-4",
1640
1957
  children: [
1641
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
1642
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "min-w-0", children: [
1643
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "font-medium", children: agent.displayName }),
1644
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
1958
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
1959
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "min-w-0", children: [
1960
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "font-medium", children: agent.displayName }),
1961
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
1645
1962
  ] }),
1646
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Badge, { variant: "outline", children: agent.isConfigured ? labels.configured : labels.unconfigured })
1963
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Badge, { variant: "outline", children: agent.isConfigured ? labels.configured : labels.unconfigured })
1647
1964
  ] }),
1648
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-3 grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
1649
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1650
- formatNumber(agent.messageCount),
1651
- " messages"
1652
- ] }),
1653
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1654
- formatNumber(agent.llmCallCount),
1655
- " LLM calls"
1656
- ] }),
1657
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1658
- formatNumber(agent.toolCallMessageCount),
1659
- " tool calls"
1660
- ] }),
1661
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1662
- formatNumber(agent.totalTokens),
1663
- " tokens"
1664
- ] })
1665
- ] })
1965
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-3 grid grid-cols-2 gap-2 text-xs", children: [
1966
+ {
1967
+ label: "Messages",
1968
+ value: formatNumber(agent.messageCount)
1969
+ },
1970
+ {
1971
+ label: "LLM calls",
1972
+ value: formatNumber(agent.llmCallCount)
1973
+ },
1974
+ {
1975
+ label: "Tool calls",
1976
+ value: formatNumber(agent.toolCallMessageCount)
1977
+ },
1978
+ {
1979
+ label: getUsageSummaryLabel(labels, usageMetricKind, usageDimension),
1980
+ value: formatMetricValue(
1981
+ getAgentUsageValue(agent, usageMetricKind, usageDimension),
1982
+ usageMetricKind
1983
+ )
1984
+ }
1985
+ ].map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
1986
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "font-medium text-foreground", children: item.value }),
1987
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-muted-foreground", children: item.label })
1988
+ ] }, item.label)) })
1666
1989
  ]
1667
1990
  },
1668
1991
  `${agent.namespace}:${agent.agentId}`
@@ -1694,22 +2017,167 @@ function formatDate(value) {
1694
2017
  function formatNumber(value) {
1695
2018
  return new Intl.NumberFormat().format(value);
1696
2019
  }
1697
-
1698
- // src/components/views/ThreadsView.tsx
1699
- var import_lucide_react6 = require("lucide-react");
1700
- var import_jsx_runtime12 = require("react/jsx-runtime");
1701
- var ThreadsView = ({
1702
- config,
1703
- threads,
1704
- searchValue,
1705
- onSearchChange,
1706
- onThreadClick
1707
- }) => {
1708
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-4", children: [
1709
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative max-w-sm", children: [
1710
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
1711
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1712
- Input,
2020
+ var USAGE_DIMENSIONS = [
2021
+ "total",
2022
+ "input",
2023
+ "output",
2024
+ "reasoning",
2025
+ "cacheRead",
2026
+ "cacheWrite"
2027
+ ];
2028
+ function getUsageDimensionLabel(labels, dimension) {
2029
+ switch (dimension) {
2030
+ case "input":
2031
+ return labels.usageInput;
2032
+ case "output":
2033
+ return labels.usageOutput;
2034
+ case "reasoning":
2035
+ return labels.usageReasoning;
2036
+ case "cacheRead":
2037
+ return labels.usageCacheRead;
2038
+ case "cacheWrite":
2039
+ return labels.usageCacheWrite;
2040
+ case "total":
2041
+ default:
2042
+ return labels.usageTotal;
2043
+ }
2044
+ }
2045
+ function getUsageSummaryLabel(labels, metricKind, dimension) {
2046
+ const metricLabel = metricKind === "cost" ? labels.usageMetricCost : labels.usageMetricTokens;
2047
+ return `${getUsageDimensionLabel(labels, dimension)} ${metricLabel}`;
2048
+ }
2049
+ function getOverviewUsageValue(overview, metricKind, dimension) {
2050
+ const llmTotals = overview.llmTotals;
2051
+ if (metricKind === "cost") {
2052
+ switch (dimension) {
2053
+ case "input":
2054
+ return llmTotals.inputCostUsd;
2055
+ case "output":
2056
+ return llmTotals.outputCostUsd;
2057
+ case "reasoning":
2058
+ return llmTotals.reasoningCostUsd;
2059
+ case "cacheRead":
2060
+ return llmTotals.cacheReadInputCostUsd;
2061
+ case "cacheWrite":
2062
+ return llmTotals.cacheCreationInputCostUsd;
2063
+ case "total":
2064
+ default:
2065
+ return llmTotals.totalCostUsd;
2066
+ }
2067
+ }
2068
+ switch (dimension) {
2069
+ case "input":
2070
+ return llmTotals.inputTokens;
2071
+ case "output":
2072
+ return llmTotals.outputTokens;
2073
+ case "reasoning":
2074
+ return llmTotals.reasoningTokens;
2075
+ case "cacheRead":
2076
+ return llmTotals.cacheReadInputTokens;
2077
+ case "cacheWrite":
2078
+ return llmTotals.cacheCreationInputTokens;
2079
+ case "total":
2080
+ default:
2081
+ return llmTotals.totalTokens;
2082
+ }
2083
+ }
2084
+ function getAgentUsageValue(agent, metricKind, dimension) {
2085
+ if (metricKind === "cost") {
2086
+ switch (dimension) {
2087
+ case "input":
2088
+ return agent.inputCostUsd;
2089
+ case "output":
2090
+ return agent.outputCostUsd;
2091
+ case "reasoning":
2092
+ return agent.reasoningCostUsd;
2093
+ case "cacheRead":
2094
+ return agent.cacheReadInputCostUsd;
2095
+ case "cacheWrite":
2096
+ return agent.cacheCreationInputCostUsd;
2097
+ case "total":
2098
+ default:
2099
+ return agent.totalCostUsd;
2100
+ }
2101
+ }
2102
+ switch (dimension) {
2103
+ case "input":
2104
+ return agent.inputTokens;
2105
+ case "output":
2106
+ return agent.outputTokens;
2107
+ case "reasoning":
2108
+ return agent.reasoningTokens;
2109
+ case "cacheRead":
2110
+ return agent.cacheReadInputTokens;
2111
+ case "cacheWrite":
2112
+ return agent.cacheCreationInputTokens;
2113
+ case "total":
2114
+ default:
2115
+ return agent.totalTokens;
2116
+ }
2117
+ }
2118
+ function getActivityUsageValue(point, metricKind, dimension) {
2119
+ if (metricKind === "cost") {
2120
+ switch (dimension) {
2121
+ case "input":
2122
+ return point.inputCostUsd;
2123
+ case "output":
2124
+ return point.outputCostUsd;
2125
+ case "reasoning":
2126
+ return point.reasoningCostUsd;
2127
+ case "cacheRead":
2128
+ return point.cacheReadInputCostUsd;
2129
+ case "cacheWrite":
2130
+ return point.cacheCreationInputCostUsd;
2131
+ case "total":
2132
+ default:
2133
+ return point.totalCostUsd;
2134
+ }
2135
+ }
2136
+ switch (dimension) {
2137
+ case "input":
2138
+ return point.inputTokens;
2139
+ case "output":
2140
+ return point.outputTokens;
2141
+ case "reasoning":
2142
+ return point.reasoningTokens;
2143
+ case "cacheRead":
2144
+ return point.cacheReadInputTokens;
2145
+ case "cacheWrite":
2146
+ return point.cacheCreationInputTokens;
2147
+ case "total":
2148
+ default:
2149
+ return point.totalTokens;
2150
+ }
2151
+ }
2152
+ function formatMetricValue(value, metricKind) {
2153
+ if (metricKind === "cost") {
2154
+ const absoluteValue = Math.abs(value);
2155
+ const maximumFractionDigits = absoluteValue >= 1 ? 2 : absoluteValue >= 0.01 ? 4 : 6;
2156
+ return new Intl.NumberFormat(void 0, {
2157
+ style: "currency",
2158
+ currency: "USD",
2159
+ minimumFractionDigits: 2,
2160
+ maximumFractionDigits
2161
+ }).format(value);
2162
+ }
2163
+ return formatNumber(value);
2164
+ }
2165
+
2166
+ // src/components/views/ThreadsView.tsx
2167
+ var import_lucide_react6 = require("lucide-react");
2168
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2169
+ var ThreadsView = ({
2170
+ config,
2171
+ threads,
2172
+ searchValue,
2173
+ onSearchChange,
2174
+ onThreadClick
2175
+ }) => {
2176
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-4", children: [
2177
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative max-w-sm", children: [
2178
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2179
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2180
+ Input,
1713
2181
  {
1714
2182
  className: "pl-9",
1715
2183
  placeholder: config.labels.threadSearchPlaceholder,
@@ -1718,19 +2186,19 @@ var ThreadsView = ({
1718
2186
  }
1719
2187
  )
1720
2188
  ] }),
1721
- threads.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
1722
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.MessageSquare, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
1723
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
1724
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-2", children: threads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2189
+ threads.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2190
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.MessageSquare, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
2191
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
2192
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "space-y-2", children: threads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1725
2193
  "div",
1726
2194
  {
1727
2195
  className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
1728
2196
  onClick: () => onThreadClick?.(thread.threadId),
1729
2197
  children: [
1730
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex-1 min-w-0", children: [
1731
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2", children: [
1732
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "font-medium truncate", children: thread.name }),
1733
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2198
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex-1 min-w-0", children: [
2199
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
2200
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "font-medium truncate", children: thread.name }),
2201
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1734
2202
  Badge,
1735
2203
  {
1736
2204
  variant: thread.status === "archived" ? "secondary" : "default",
@@ -1739,18 +2207,18 @@ var ThreadsView = ({
1739
2207
  }
1740
2208
  )
1741
2209
  ] }),
1742
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-1 text-sm text-muted-foreground truncate", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
2210
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-1 text-sm text-muted-foreground truncate", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
1743
2211
  ] }),
1744
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
1745
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { children: [
2212
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
2213
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { children: [
1746
2214
  formatNumber2(thread.messageCount),
1747
2215
  " messages"
1748
2216
  ] }),
1749
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { children: [
2217
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { children: [
1750
2218
  thread.participantIds.length,
1751
2219
  " participants"
1752
2220
  ] }),
1753
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: formatDate2(thread.lastActivityAt) })
2221
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: formatDate2(thread.lastActivityAt) })
1754
2222
  ] })
1755
2223
  ]
1756
2224
  },
@@ -1774,26 +2242,26 @@ function formatNumber2(value) {
1774
2242
  }
1775
2243
 
1776
2244
  // src/components/views/ThreadDetailView.tsx
1777
- var import_react2 = require("react");
2245
+ var import_react3 = require("react");
1778
2246
  var import_lucide_react7 = require("lucide-react");
1779
- var import_jsx_runtime13 = require("react/jsx-runtime");
2247
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1780
2248
  var MESSAGES_PAGE_SIZE = 50;
1781
2249
  var ThreadDetailView = ({
1782
2250
  threadId,
1783
2251
  config,
1784
2252
  onBack
1785
2253
  }) => {
1786
- const [thread, setThread] = (0, import_react2.useState)(null);
1787
- const [messages, setMessages] = (0, import_react2.useState)([]);
1788
- const [pageInfo, setPageInfo] = (0, import_react2.useState)(null);
1789
- const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
1790
- const [isLoadingMore, setIsLoadingMore] = (0, import_react2.useState)(false);
1791
- const [error, setError] = (0, import_react2.useState)(null);
2254
+ const [thread, setThread] = (0, import_react3.useState)(null);
2255
+ const [messages, setMessages] = (0, import_react3.useState)([]);
2256
+ const [pageInfo, setPageInfo] = (0, import_react3.useState)(null);
2257
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
2258
+ const [isLoadingMore, setIsLoadingMore] = (0, import_react3.useState)(false);
2259
+ const [error, setError] = (0, import_react3.useState)(null);
1792
2260
  const fetchOptions = {
1793
2261
  baseUrl: config.baseUrl,
1794
2262
  getRequestHeaders: config.getRequestHeaders
1795
2263
  };
1796
- const loadInitial = (0, import_react2.useCallback)(async () => {
2264
+ const loadInitial = (0, import_react3.useCallback)(async () => {
1797
2265
  setIsLoading(true);
1798
2266
  setError(null);
1799
2267
  try {
@@ -1812,10 +2280,10 @@ var ThreadDetailView = ({
1812
2280
  setIsLoading(false);
1813
2281
  }
1814
2282
  }, [threadId, config.baseUrl, config.getRequestHeaders]);
1815
- (0, import_react2.useEffect)(() => {
2283
+ (0, import_react3.useEffect)(() => {
1816
2284
  void loadInitial();
1817
2285
  }, [loadInitial]);
1818
- const loadMore = (0, import_react2.useCallback)(async () => {
2286
+ const loadMore = (0, import_react3.useCallback)(async () => {
1819
2287
  if (!pageInfo?.hasMoreBefore || !pageInfo.oldestMessageId || isLoadingMore) {
1820
2288
  return;
1821
2289
  }
@@ -1834,36 +2302,36 @@ var ThreadDetailView = ({
1834
2302
  }
1835
2303
  }, [threadId, pageInfo, isLoadingMore, config.baseUrl, config.getRequestHeaders]);
1836
2304
  if (isLoading) {
1837
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
2305
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
1838
2306
  }
1839
2307
  if (error) {
1840
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-4 py-10 text-center", children: [
1841
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-destructive font-medium", children: error.message }),
1842
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-center gap-2", children: [
1843
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Button, { variant: "outline", onClick: onBack, children: [
1844
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ArrowLeft, { className: "mr-2 h-4 w-4" }),
2308
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "space-y-4 py-10 text-center", children: [
2309
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-destructive font-medium", children: error.message }),
2310
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-center gap-2", children: [
2311
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Button, { variant: "outline", onClick: onBack, children: [
2312
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ArrowLeft, { className: "mr-2 h-4 w-4" }),
1845
2313
  "Back"
1846
2314
  ] }),
1847
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { variant: "destructive", onClick: () => void loadInitial(), children: config.labels.retry })
2315
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "destructive", onClick: () => void loadInitial(), children: config.labels.retry })
1848
2316
  ] })
1849
2317
  ] });
1850
2318
  }
1851
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-6", children: [
1852
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-start gap-4", children: [
1853
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2319
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "space-y-6", children: [
2320
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-start gap-4", children: [
2321
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1854
2322
  Button,
1855
2323
  {
1856
2324
  variant: "ghost",
1857
2325
  size: "icon",
1858
2326
  className: "mt-1 shrink-0",
1859
2327
  onClick: onBack,
1860
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ArrowLeft, { className: "h-4 w-4" })
2328
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ArrowLeft, { className: "h-4 w-4" })
1861
2329
  }
1862
2330
  ),
1863
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex-1 min-w-0", children: [
1864
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
1865
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "text-xl font-semibold truncate", children: thread?.name ?? threadId }),
1866
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2331
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex-1 min-w-0", children: [
2332
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2", children: [
2333
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h2", { className: "text-xl font-semibold truncate", children: thread?.name ?? threadId }),
2334
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1867
2335
  Badge,
1868
2336
  {
1869
2337
  variant: thread?.status === "archived" ? "secondary" : "default",
@@ -1871,31 +2339,31 @@ var ThreadDetailView = ({
1871
2339
  }
1872
2340
  )
1873
2341
  ] }),
1874
- thread?.summary && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: thread.summary }),
1875
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
1876
- thread?.createdAt && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
2342
+ thread?.summary && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: thread.summary }),
2343
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
2344
+ thread?.createdAt && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
1877
2345
  "Created ",
1878
2346
  formatDate3(thread.createdAt)
1879
2347
  ] }),
1880
- thread?.updatedAt && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
2348
+ thread?.updatedAt && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
1881
2349
  "Updated ",
1882
2350
  formatDate3(thread.updatedAt)
1883
2351
  ] }),
1884
- thread?.participants && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
2352
+ thread?.participants && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
1885
2353
  thread.participants.length,
1886
2354
  " participants"
1887
2355
  ] })
1888
2356
  ] })
1889
2357
  ] })
1890
2358
  ] }),
1891
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-1", children: [
1892
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("h3", { className: "text-sm font-medium text-muted-foreground", children: [
2359
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "space-y-1", children: [
2360
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("h3", { className: "text-sm font-medium text-muted-foreground", children: [
1893
2361
  "Messages (",
1894
2362
  messages.length,
1895
2363
  pageInfo?.hasMoreBefore ? "+" : "",
1896
2364
  ")"
1897
2365
  ] }) }),
1898
- pageInfo?.hasMoreBefore && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2366
+ pageInfo?.hasMoreBefore && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1899
2367
  Button,
1900
2368
  {
1901
2369
  variant: "ghost",
@@ -1903,56 +2371,56 @@ var ThreadDetailView = ({
1903
2371
  onClick: () => void loadMore(),
1904
2372
  disabled: isLoadingMore,
1905
2373
  children: [
1906
- isLoadingMore ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronUp, { className: "mr-2 h-3 w-3" }),
2374
+ isLoadingMore ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ChevronUp, { className: "mr-2 h-3 w-3" }),
1907
2375
  "Load older messages"
1908
2376
  ]
1909
2377
  }
1910
2378
  ) }),
1911
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "rounded-lg border bg-card", children: messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No messages in this thread yet." }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MessageRow, { message }, message.id)) }) })
2379
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "rounded-lg border bg-card", children: messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No messages in this thread yet." }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MessageRow, { message }, message.id)) }) })
1912
2380
  ] })
1913
2381
  ] });
1914
2382
  };
1915
2383
  function MessageRow({ message }) {
1916
- const [expanded, setExpanded] = (0, import_react2.useState)(false);
2384
+ const [expanded, setExpanded] = (0, import_react3.useState)(false);
1917
2385
  const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
1918
2386
  const hasReasoning = !!message.reasoning;
1919
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-start gap-3", children: [
1920
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SenderIcon, { senderType: message.senderType }),
1921
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex-1 min-w-0", children: [
1922
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
1923
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
1924
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "outline", className: "text-[10px] px-1.5 py-0", children: message.senderType }),
1925
- message.createdAt && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-muted-foreground", children: formatTimestamp(message.createdAt) })
2387
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-start gap-3", children: [
2388
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SenderIcon, { senderType: message.senderType }),
2389
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex-1 min-w-0", children: [
2390
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
2391
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
2392
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Badge, { variant: "outline", className: "text-[10px] px-1.5 py-0", children: message.senderType }),
2393
+ message.createdAt && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-muted-foreground", children: formatTimestamp(message.createdAt) })
1926
2394
  ] }),
1927
- message.content && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-1 text-sm whitespace-pre-wrap break-words", children: message.content }),
1928
- (hasToolCalls || hasReasoning) && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mt-2 space-y-2", children: [
1929
- hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2395
+ message.content && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-1 text-sm whitespace-pre-wrap break-words", children: message.content }),
2396
+ (hasToolCalls || hasReasoning) && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "mt-2 space-y-2", children: [
2397
+ hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1930
2398
  "button",
1931
2399
  {
1932
2400
  type: "button",
1933
2401
  onClick: () => setExpanded(!expanded),
1934
2402
  className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
1935
2403
  children: [
1936
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Wrench, { className: "h-3 w-3" }),
2404
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Wrench, { className: "h-3 w-3" }),
1937
2405
  message.toolCalls.length,
1938
2406
  " tool call",
1939
2407
  message.toolCalls.length > 1 ? "s" : ""
1940
2408
  ]
1941
2409
  }
1942
2410
  ),
1943
- hasReasoning && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2411
+ hasReasoning && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1944
2412
  "button",
1945
2413
  {
1946
2414
  type: "button",
1947
2415
  onClick: () => setExpanded(!expanded),
1948
2416
  className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
1949
2417
  children: [
1950
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Cpu, { className: "h-3 w-3" }),
2418
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Cpu, { className: "h-3 w-3" }),
1951
2419
  "Reasoning"
1952
2420
  ]
1953
2421
  }
1954
2422
  ),
1955
- expanded && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("pre", { className: "mt-2 rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(
2423
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("pre", { className: "mt-2 rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(
1956
2424
  {
1957
2425
  ...hasToolCalls ? { toolCalls: message.toolCalls } : {},
1958
2426
  ...hasReasoning ? { reasoning: message.reasoning } : {}
@@ -1968,13 +2436,13 @@ function SenderIcon({ senderType }) {
1968
2436
  const base = "flex h-7 w-7 shrink-0 items-center justify-center rounded-full";
1969
2437
  switch (senderType) {
1970
2438
  case "agent":
1971
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Bot, { className: "h-3.5 w-3.5" }) });
2439
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Bot, { className: "h-3.5 w-3.5" }) });
1972
2440
  case "user":
1973
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.User, { className: "h-3.5 w-3.5" }) });
2441
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.User, { className: "h-3.5 w-3.5" }) });
1974
2442
  case "tool":
1975
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Wrench, { className: "h-3.5 w-3.5" }) });
2443
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Wrench, { className: "h-3.5 w-3.5" }) });
1976
2444
  default:
1977
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Cpu, { className: "h-3.5 w-3.5" }) });
2445
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Cpu, { className: "h-3.5 w-3.5" }) });
1978
2446
  }
1979
2447
  }
1980
2448
  function formatDate3(value) {
@@ -1998,79 +2466,737 @@ function formatTimestamp(value) {
1998
2466
  });
1999
2467
  }
2000
2468
 
2469
+ // src/components/views/ParticipantsView.tsx
2470
+ var import_lucide_react8 = require("lucide-react");
2471
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2472
+ var ParticipantsView = ({
2473
+ config,
2474
+ participants,
2475
+ searchValue,
2476
+ onSearchChange,
2477
+ onParticipantClick
2478
+ }) => {
2479
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "space-y-4", children: [
2480
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "relative max-w-sm", children: [
2481
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react8.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2482
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2483
+ Input,
2484
+ {
2485
+ className: "pl-9",
2486
+ placeholder: config.labels.participantSearchPlaceholder,
2487
+ value: searchValue,
2488
+ onChange: (e) => onSearchChange(e.target.value)
2489
+ }
2490
+ )
2491
+ ] }),
2492
+ participants.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2493
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react8.Users, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
2494
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
2495
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "space-y-2", children: participants.map((p) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2496
+ "div",
2497
+ {
2498
+ className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
2499
+ onClick: () => onParticipantClick?.(p.externalId),
2500
+ children: [
2501
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex-1 min-w-0", children: [
2502
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", children: [
2503
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "font-medium truncate", children: p.displayName }),
2504
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Badge, { variant: "outline", className: "shrink-0 text-xs", children: p.participantType }),
2505
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Badge, { variant: p.isGlobal ? "default" : "secondary", className: "shrink-0 text-xs", children: p.isGlobal ? config.labels.scopeGlobal : config.labels.scopeScoped })
2506
+ ] }),
2507
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "mt-1 text-xs text-muted-foreground", children: p.externalId })
2508
+ ] }),
2509
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
2510
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { children: [
2511
+ formatNumber3(p.messageCount),
2512
+ " messages"
2513
+ ] }),
2514
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { children: [
2515
+ formatNumber3(p.threadCount),
2516
+ " threads"
2517
+ ] }),
2518
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: formatDate4(p.lastActivityAt) })
2519
+ ] })
2520
+ ]
2521
+ },
2522
+ `${p.namespace}:${p.externalId}`
2523
+ )) })
2524
+ ] });
2525
+ };
2526
+ function formatDate4(value) {
2527
+ if (!value) return "No activity";
2528
+ const date = new Date(value);
2529
+ if (Number.isNaN(date.getTime())) return value;
2530
+ return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
2531
+ }
2532
+ function formatNumber3(value) {
2533
+ return new Intl.NumberFormat().format(value);
2534
+ }
2535
+
2536
+ // src/components/views/ParticipantDetailView.tsx
2537
+ var import_react4 = require("react");
2538
+ var import_lucide_react9 = require("lucide-react");
2539
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2540
+ var ParticipantDetailView = ({
2541
+ participantId,
2542
+ config,
2543
+ onBack
2544
+ }) => {
2545
+ const [data, setData] = (0, import_react4.useState)(null);
2546
+ const [editJson, setEditJson] = (0, import_react4.useState)("");
2547
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
2548
+ const [isSaving, setIsSaving] = (0, import_react4.useState)(false);
2549
+ const [error, setError] = (0, import_react4.useState)(null);
2550
+ const [saveMessage, setSaveMessage] = (0, import_react4.useState)(null);
2551
+ const fetchOptions = {
2552
+ baseUrl: config.baseUrl,
2553
+ getRequestHeaders: config.getRequestHeaders
2554
+ };
2555
+ const load = (0, import_react4.useCallback)(async () => {
2556
+ setIsLoading(true);
2557
+ setError(null);
2558
+ try {
2559
+ const result = await fetchParticipantDetail(participantId, fetchOptions);
2560
+ setData(result);
2561
+ setEditJson(JSON.stringify(result, null, 2));
2562
+ } catch (err) {
2563
+ setError(err instanceof Error ? err.message : "Failed to load participant");
2564
+ } finally {
2565
+ setIsLoading(false);
2566
+ }
2567
+ }, [participantId, config.baseUrl, config.getRequestHeaders]);
2568
+ (0, import_react4.useEffect)(() => {
2569
+ void load();
2570
+ }, [load]);
2571
+ const handleSave = async () => {
2572
+ setIsSaving(true);
2573
+ setError(null);
2574
+ setSaveMessage(null);
2575
+ try {
2576
+ const parsed = JSON.parse(editJson);
2577
+ const updated = await updateParticipant(participantId, parsed, fetchOptions);
2578
+ setData(updated);
2579
+ setEditJson(JSON.stringify(updated, null, 2));
2580
+ setSaveMessage("Saved successfully");
2581
+ setTimeout(() => setSaveMessage(null), 3e3);
2582
+ } catch (err) {
2583
+ setError(err instanceof Error ? err.message : "Failed to save");
2584
+ } finally {
2585
+ setIsSaving(false);
2586
+ }
2587
+ };
2588
+ if (isLoading) {
2589
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react9.Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
2590
+ }
2591
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-6", children: [
2592
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-4", children: [
2593
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react9.ArrowLeft, { className: "h-4 w-4" }) }),
2594
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex-1 min-w-0", children: [
2595
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h2", { className: "text-xl font-semibold truncate", children: participantId }),
2596
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm text-muted-foreground", children: "Participant Detail" })
2597
+ ] }),
2598
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
2599
+ saveMessage && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-xs text-emerald-600", children: saveMessage }),
2600
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
2601
+ isSaving ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react9.Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react9.Save, { className: "mr-2 h-3 w-3" }),
2602
+ "Save"
2603
+ ] })
2604
+ ] })
2605
+ ] }),
2606
+ error && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
2607
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2608
+ "textarea",
2609
+ {
2610
+ className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
2611
+ value: editJson,
2612
+ onChange: (e) => setEditJson(e.target.value),
2613
+ spellCheck: false
2614
+ }
2615
+ ) })
2616
+ ] });
2617
+ };
2618
+
2619
+ // src/components/views/AgentsView.tsx
2620
+ var import_lucide_react10 = require("lucide-react");
2621
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2622
+ var AgentsView = ({
2623
+ config,
2624
+ agents,
2625
+ searchValue,
2626
+ onSearchChange,
2627
+ onAgentClick
2628
+ }) => {
2629
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-4", children: [
2630
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative max-w-sm", children: [
2631
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react10.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2632
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2633
+ Input,
2634
+ {
2635
+ className: "pl-9",
2636
+ placeholder: config.labels.agentSearchPlaceholder,
2637
+ value: searchValue,
2638
+ onChange: (e) => onSearchChange(e.target.value)
2639
+ }
2640
+ )
2641
+ ] }),
2642
+ agents.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2643
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react10.Bot, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
2644
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
2645
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: agents.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2646
+ "div",
2647
+ {
2648
+ className: "rounded-lg border bg-card p-5 transition-colors hover:bg-muted/50 cursor-pointer",
2649
+ onClick: () => onAgentClick?.(agent.agentId),
2650
+ children: [
2651
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
2652
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "min-w-0", children: [
2653
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "font-medium truncate", children: agent.displayName }),
2654
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
2655
+ ] }),
2656
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Badge, { variant: "outline", className: "shrink-0", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
2657
+ ] }),
2658
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "mt-4 grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
2659
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { children: [
2660
+ formatNumber4(agent.messageCount),
2661
+ " messages"
2662
+ ] }),
2663
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { children: [
2664
+ formatNumber4(agent.llmCallCount),
2665
+ " LLM calls"
2666
+ ] }),
2667
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { children: [
2668
+ formatNumber4(agent.toolCallMessageCount),
2669
+ " tool calls"
2670
+ ] }),
2671
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { children: [
2672
+ formatNumber4(agent.totalTokens),
2673
+ " tokens"
2674
+ ] })
2675
+ ] }),
2676
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "mt-3 text-xs text-muted-foreground", children: formatDate5(agent.lastActivityAt) })
2677
+ ]
2678
+ },
2679
+ `${agent.namespace}:${agent.agentId}`
2680
+ )) })
2681
+ ] });
2682
+ };
2683
+ function formatDate5(value) {
2684
+ if (!value) return "No activity";
2685
+ const date = new Date(value);
2686
+ if (Number.isNaN(date.getTime())) return value;
2687
+ return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
2688
+ }
2689
+ function formatNumber4(value) {
2690
+ return new Intl.NumberFormat().format(value);
2691
+ }
2692
+
2693
+ // src/components/views/AgentDetailView.tsx
2694
+ var import_lucide_react11 = require("lucide-react");
2695
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2696
+ var AgentDetailView = ({
2697
+ agentId,
2698
+ config,
2699
+ agents,
2700
+ onBack
2701
+ }) => {
2702
+ const agent = agents.find((a) => a.agentId === agentId);
2703
+ if (!agent) {
2704
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-4 py-10 text-center", children: [
2705
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("p", { className: "text-muted-foreground", children: [
2706
+ "Agent not found: ",
2707
+ agentId
2708
+ ] }),
2709
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Button, { variant: "outline", onClick: onBack, children: [
2710
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react11.ArrowLeft, { className: "mr-2 h-4 w-4" }),
2711
+ " Back"
2712
+ ] })
2713
+ ] });
2714
+ }
2715
+ const stats = [
2716
+ { label: "Messages", value: agent.messageCount },
2717
+ { label: "LLM Calls", value: agent.llmCallCount },
2718
+ { label: "Tool Calls", value: agent.toolCallMessageCount },
2719
+ { label: "Input Tokens", value: agent.inputTokens },
2720
+ { label: "Output Tokens", value: agent.outputTokens },
2721
+ { label: "Reasoning Tokens", value: agent.reasoningTokens },
2722
+ { label: "Cache Read", value: agent.cacheReadInputTokens },
2723
+ { label: "Cache Created", value: agent.cacheCreationInputTokens },
2724
+ { label: "Total Tokens", value: agent.totalTokens }
2725
+ ];
2726
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-6", children: [
2727
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-start gap-4", children: [
2728
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { variant: "ghost", size: "icon", className: "mt-1 shrink-0", onClick: onBack, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react11.ArrowLeft, { className: "h-4 w-4" }) }),
2729
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1 min-w-0", children: [
2730
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-3", children: [
2731
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react11.Bot, { className: "h-5 w-5" }) }),
2732
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
2733
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-2", children: [
2734
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { className: "text-xl font-semibold", children: agent.displayName }),
2735
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Badge, { variant: "outline", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
2736
+ ] }),
2737
+ agent.description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm text-muted-foreground", children: agent.description })
2738
+ ] })
2739
+ ] }),
2740
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
2741
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { children: [
2742
+ "ID: ",
2743
+ agent.agentId
2744
+ ] }),
2745
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { children: [
2746
+ "Namespace: ",
2747
+ agent.namespace
2748
+ ] }),
2749
+ agent.lastActivityAt && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { children: [
2750
+ "Last active: ",
2751
+ formatDate6(agent.lastActivityAt)
2752
+ ] })
2753
+ ] })
2754
+ ] })
2755
+ ] }),
2756
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "grid gap-4 sm:grid-cols-3 lg:grid-cols-3", children: stats.map((stat) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
2757
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: stat.label }),
2758
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "mt-2 text-2xl font-semibold tracking-tight", children: new Intl.NumberFormat().format(stat.value) })
2759
+ ] }, stat.label)) })
2760
+ ] });
2761
+ };
2762
+ function formatDate6(value) {
2763
+ const date = new Date(value);
2764
+ if (Number.isNaN(date.getTime())) return value;
2765
+ return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
2766
+ }
2767
+
2768
+ // src/components/views/CollectionItemsView.tsx
2769
+ var import_react5 = require("react");
2770
+ var import_lucide_react12 = require("lucide-react");
2771
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2772
+ var CollectionItemsView = ({
2773
+ collection,
2774
+ config,
2775
+ namespace,
2776
+ onItemClick,
2777
+ onCreateNew
2778
+ }) => {
2779
+ const [items, setItems] = (0, import_react5.useState)([]);
2780
+ const [isLoading, setIsLoading] = (0, import_react5.useState)(true);
2781
+ const [search, setSearch] = (0, import_react5.useState)("");
2782
+ const [error, setError] = (0, import_react5.useState)(null);
2783
+ const fetchOptions = {
2784
+ baseUrl: config.baseUrl,
2785
+ getRequestHeaders: config.getRequestHeaders
2786
+ };
2787
+ const load = (0, import_react5.useCallback)(async () => {
2788
+ setIsLoading(true);
2789
+ setError(null);
2790
+ try {
2791
+ const result = await fetchCollectionItems(
2792
+ collection,
2793
+ { search: search || void 0, namespace, limit: 50 },
2794
+ fetchOptions
2795
+ );
2796
+ setItems(result);
2797
+ } catch (err) {
2798
+ setError(err instanceof Error ? err.message : "Failed to load items");
2799
+ } finally {
2800
+ setIsLoading(false);
2801
+ }
2802
+ }, [collection, search, namespace, config.baseUrl, config.getRequestHeaders]);
2803
+ (0, import_react5.useEffect)(() => {
2804
+ void load();
2805
+ }, [load]);
2806
+ const getItemId = (item) => {
2807
+ return String(item.id ?? item._id ?? JSON.stringify(item).slice(0, 40));
2808
+ };
2809
+ const getItemPreview = (item) => {
2810
+ const { id, _id, ...rest } = item;
2811
+ const name = item.name ?? item.title ?? item.displayName ?? item.label;
2812
+ if (typeof name === "string") return name;
2813
+ const keys = Object.keys(rest);
2814
+ if (keys.length === 0) return "(empty)";
2815
+ return keys.slice(0, 3).map((k) => `${k}: ${JSON.stringify(rest[k])?.slice(0, 30)}`).join(", ");
2816
+ };
2817
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-4", children: [
2818
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
2819
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { className: "text-lg font-semibold capitalize", children: collection }),
2820
+ onCreateNew && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Button, { size: "sm", onClick: onCreateNew, children: [
2821
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react12.Plus, { className: "mr-2 h-3 w-3" }),
2822
+ " New"
2823
+ ] })
2824
+ ] }),
2825
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "relative max-w-sm", children: [
2826
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react12.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2827
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2828
+ Input,
2829
+ {
2830
+ className: "pl-9",
2831
+ placeholder: `Search ${collection}...`,
2832
+ value: search,
2833
+ onChange: (e) => setSearch(e.target.value)
2834
+ }
2835
+ )
2836
+ ] }),
2837
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
2838
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react12.Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2839
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react12.Database, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
2840
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "mt-3 text-sm text-muted-foreground", children: search ? config.labels.noResults : `No items in ${collection}` })
2841
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "space-y-2", children: items.map((item, idx) => {
2842
+ const itemId = getItemId(item);
2843
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2844
+ "div",
2845
+ {
2846
+ className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
2847
+ onClick: () => onItemClick?.(itemId),
2848
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex-1 min-w-0", children: [
2849
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "font-medium font-mono text-sm truncate", children: itemId }),
2850
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "mt-1 text-xs text-muted-foreground truncate", children: getItemPreview(item) })
2851
+ ] })
2852
+ },
2853
+ itemId + idx
2854
+ );
2855
+ }) })
2856
+ ] });
2857
+ };
2858
+
2859
+ // src/components/views/CollectionItemDetailView.tsx
2860
+ var import_react6 = require("react");
2861
+ var import_lucide_react13 = require("lucide-react");
2862
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2863
+ var CollectionItemDetailView = ({
2864
+ collection,
2865
+ itemId,
2866
+ config,
2867
+ namespace,
2868
+ onBack,
2869
+ onDeleted
2870
+ }) => {
2871
+ const isNew = !itemId;
2872
+ const [editJson, setEditJson] = (0, import_react6.useState)(isNew ? "{\n \n}" : "");
2873
+ const [isLoading, setIsLoading] = (0, import_react6.useState)(!isNew);
2874
+ const [isSaving, setIsSaving] = (0, import_react6.useState)(false);
2875
+ const [isDeleting, setIsDeleting] = (0, import_react6.useState)(false);
2876
+ const [error, setError] = (0, import_react6.useState)(null);
2877
+ const [saveMessage, setSaveMessage] = (0, import_react6.useState)(null);
2878
+ const fetchOptions = {
2879
+ baseUrl: config.baseUrl,
2880
+ getRequestHeaders: config.getRequestHeaders
2881
+ };
2882
+ const load = (0, import_react6.useCallback)(async () => {
2883
+ if (!itemId) return;
2884
+ setIsLoading(true);
2885
+ setError(null);
2886
+ try {
2887
+ const result = await fetchCollectionItem(collection, itemId, namespace, fetchOptions);
2888
+ setEditJson(JSON.stringify(result, null, 2));
2889
+ } catch (err) {
2890
+ setError(err instanceof Error ? err.message : "Failed to load item");
2891
+ } finally {
2892
+ setIsLoading(false);
2893
+ }
2894
+ }, [collection, itemId, namespace, config.baseUrl, config.getRequestHeaders]);
2895
+ (0, import_react6.useEffect)(() => {
2896
+ void load();
2897
+ }, [load]);
2898
+ const handleSave = async () => {
2899
+ setIsSaving(true);
2900
+ setError(null);
2901
+ setSaveMessage(null);
2902
+ try {
2903
+ const parsed = JSON.parse(editJson);
2904
+ if (isNew) {
2905
+ const created = await createCollectionItem(collection, parsed, namespace, fetchOptions);
2906
+ setEditJson(JSON.stringify(created, null, 2));
2907
+ setSaveMessage("Created successfully");
2908
+ } else {
2909
+ const updated = await updateCollectionItem(collection, itemId, parsed, namespace, fetchOptions);
2910
+ setEditJson(JSON.stringify(updated, null, 2));
2911
+ setSaveMessage("Saved successfully");
2912
+ }
2913
+ setTimeout(() => setSaveMessage(null), 3e3);
2914
+ } catch (err) {
2915
+ setError(err instanceof Error ? err.message : "Failed to save");
2916
+ } finally {
2917
+ setIsSaving(false);
2918
+ }
2919
+ };
2920
+ const handleDelete = async () => {
2921
+ if (!itemId) return;
2922
+ if (!window.confirm(`Delete this item from ${collection}?`)) return;
2923
+ setIsDeleting(true);
2924
+ setError(null);
2925
+ try {
2926
+ await deleteCollectionItem(collection, itemId, namespace, fetchOptions);
2927
+ onDeleted?.();
2928
+ onBack();
2929
+ } catch (err) {
2930
+ setError(err instanceof Error ? err.message : "Failed to delete");
2931
+ } finally {
2932
+ setIsDeleting(false);
2933
+ }
2934
+ };
2935
+ if (isLoading) {
2936
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react13.Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
2937
+ }
2938
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "space-y-6", children: [
2939
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-4", children: [
2940
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react13.ArrowLeft, { className: "h-4 w-4" }) }),
2941
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h2", { className: "text-xl font-semibold truncate capitalize", children: isNew ? `New ${collection} item` : `${collection} / ${itemId}` }) }),
2942
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
2943
+ saveMessage && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-emerald-600", children: saveMessage }),
2944
+ !isNew && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
2945
+ Button,
2946
+ {
2947
+ variant: "destructive",
2948
+ size: "sm",
2949
+ onClick: () => void handleDelete(),
2950
+ disabled: isDeleting,
2951
+ children: [
2952
+ isDeleting ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react13.Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react13.Trash2, { className: "mr-2 h-3 w-3" }),
2953
+ "Delete"
2954
+ ]
2955
+ }
2956
+ ),
2957
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
2958
+ isSaving ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react13.Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react13.Save, { className: "mr-2 h-3 w-3" }),
2959
+ isNew ? "Create" : "Save"
2960
+ ] })
2961
+ ] })
2962
+ ] }),
2963
+ error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
2964
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2965
+ "textarea",
2966
+ {
2967
+ className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
2968
+ value: editJson,
2969
+ onChange: (e) => setEditJson(e.target.value),
2970
+ spellCheck: false
2971
+ }
2972
+ ) })
2973
+ ] });
2974
+ };
2975
+
2976
+ // src/components/views/EventsView.tsx
2977
+ var import_react7 = require("react");
2978
+ var import_lucide_react14 = require("lucide-react");
2979
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2980
+ var STATUS_VARIANTS = {
2981
+ pending: "outline",
2982
+ processing: "default",
2983
+ completed: "secondary",
2984
+ failed: "destructive",
2985
+ expired: "secondary",
2986
+ overwritten: "secondary"
2987
+ };
2988
+ var EventsView = ({ config }) => {
2989
+ const [threadId, setThreadId] = (0, import_react7.useState)("");
2990
+ const [event, setEvent] = (0, import_react7.useState)(null);
2991
+ const [hasSearched, setHasSearched] = (0, import_react7.useState)(false);
2992
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
2993
+ const [error, setError] = (0, import_react7.useState)(null);
2994
+ const fetchOptions = {
2995
+ baseUrl: config.baseUrl,
2996
+ getRequestHeaders: config.getRequestHeaders
2997
+ };
2998
+ const handleSearch = (0, import_react7.useCallback)(async () => {
2999
+ if (!threadId.trim()) return;
3000
+ setIsLoading(true);
3001
+ setError(null);
3002
+ setHasSearched(true);
3003
+ try {
3004
+ const result = await fetchThreadEvents(threadId.trim(), fetchOptions);
3005
+ setEvent(result ?? null);
3006
+ } catch (err) {
3007
+ setError(err instanceof Error ? err.message : "Failed to load events");
3008
+ } finally {
3009
+ setIsLoading(false);
3010
+ }
3011
+ }, [threadId, config.baseUrl, config.getRequestHeaders]);
3012
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-6", children: [
3013
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-end gap-3 max-w-lg", children: [
3014
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1", children: [
3015
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "text-sm font-medium mb-1 block", children: "Thread ID" }),
3016
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "relative", children: [
3017
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3018
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3019
+ Input,
3020
+ {
3021
+ className: "pl-9",
3022
+ placeholder: "Enter thread ID to inspect events...",
3023
+ value: threadId,
3024
+ onChange: (e) => setThreadId(e.target.value),
3025
+ onKeyDown: (e) => e.key === "Enter" && void handleSearch()
3026
+ }
3027
+ )
3028
+ ] })
3029
+ ] }),
3030
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { onClick: () => void handleSearch(), disabled: isLoading || !threadId.trim(), children: [
3031
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
3032
+ "Inspect"
3033
+ ] })
3034
+ ] }),
3035
+ error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
3036
+ !hasSearched ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
3037
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.Activity, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
3038
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-3 text-sm text-muted-foreground", children: "Enter a thread ID to inspect its next pending queue event." })
3039
+ ] }) : isLoading ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : !event ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
3040
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.Activity, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
3041
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-3 text-sm text-muted-foreground", children: "No pending events found for this thread." })
3042
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-lg border bg-card p-5 space-y-4", children: [
3043
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
3044
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3045
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "font-medium", children: event.eventType }),
3046
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-xs text-muted-foreground font-mono mt-1", children: event.id })
3047
+ ] }),
3048
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: STATUS_VARIANTS[event.status] ?? "outline", children: event.status })
3049
+ ] }),
3050
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "grid gap-3 sm:grid-cols-2 text-sm", children: [
3051
+ event.traceId && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3052
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "Trace:" }),
3053
+ " ",
3054
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "font-mono text-xs", children: event.traceId })
3055
+ ] }),
3056
+ event.parentEventId && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3057
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "Parent:" }),
3058
+ " ",
3059
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "font-mono text-xs", children: event.parentEventId })
3060
+ ] }),
3061
+ event.priority != null && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3062
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "Priority:" }),
3063
+ " ",
3064
+ event.priority
3065
+ ] }),
3066
+ event.createdAt && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3067
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "Created:" }),
3068
+ " ",
3069
+ formatTimestamp2(event.createdAt)
3070
+ ] })
3071
+ ] }),
3072
+ event.payload != null && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3073
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Payload" }),
3074
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(event.payload, null, 2) })
3075
+ ] }),
3076
+ event.metadata != null && Object.keys(event.metadata).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3077
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Metadata" }),
3078
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-40", children: JSON.stringify(event.metadata, null, 2) })
3079
+ ] })
3080
+ ] })
3081
+ ] });
3082
+ };
3083
+ function formatTimestamp2(value) {
3084
+ const date = new Date(value);
3085
+ if (Number.isNaN(date.getTime())) return value;
3086
+ return date.toLocaleString(void 0, {
3087
+ month: "short",
3088
+ day: "numeric",
3089
+ hour: "numeric",
3090
+ minute: "2-digit",
3091
+ second: "2-digit"
3092
+ });
3093
+ }
3094
+
2001
3095
  // src/CopilotzAdmin.tsx
2002
- var import_jsx_runtime14 = require("react/jsx-runtime");
3096
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2003
3097
  var CopilotzAdmin = ({
2004
3098
  config: userConfig,
2005
3099
  className
2006
3100
  }) => {
2007
- const config = (0, import_react3.useMemo)(
3101
+ const config = (0, import_react8.useMemo)(
2008
3102
  () => mergeAdminConfig(defaultAdminConfig, userConfig),
2009
3103
  [userConfig]
2010
3104
  );
2011
- const [route, setRoute] = (0, import_react3.useState)({ page: config.defaultPage });
2012
- const [threadSearch, setThreadSearch] = (0, import_react3.useState)("");
2013
- const [participantSearch, setParticipantSearch] = (0, import_react3.useState)("");
2014
- const [agentSearch, setAgentSearch] = (0, import_react3.useState)("");
2015
- const deferredThreadSearch = (0, import_react3.useDeferredValue)(threadSearch);
2016
- const deferredParticipantSearch = (0, import_react3.useDeferredValue)(participantSearch);
2017
- const deferredAgentSearch = (0, import_react3.useDeferredValue)(agentSearch);
3105
+ const [route, setRoute] = (0, import_react8.useState)({ page: config.defaultPage });
3106
+ const [namespace, setNamespace] = (0, import_react8.useState)(config.namespace);
3107
+ const [collections, setCollections] = (0, import_react8.useState)([]);
3108
+ const [threadSearch, setThreadSearch] = (0, import_react8.useState)("");
3109
+ const [participantSearch, setParticipantSearch] = (0, import_react8.useState)("");
3110
+ const [agentSearch, setAgentSearch] = (0, import_react8.useState)("");
3111
+ const deferredThreadSearch = (0, import_react8.useDeferredValue)(threadSearch);
3112
+ const deferredParticipantSearch = (0, import_react8.useDeferredValue)(participantSearch);
3113
+ const deferredAgentSearch = (0, import_react8.useDeferredValue)(agentSearch);
2018
3114
  const admin = useCopilotzAdmin({
2019
3115
  baseUrl: config.baseUrl,
2020
3116
  getRequestHeaders: config.getRequestHeaders,
2021
- namespace: config.namespace,
3117
+ namespace,
2022
3118
  range: config.initialRange,
2023
3119
  interval: config.initialInterval,
2024
3120
  threadSearch: deferredThreadSearch,
2025
3121
  participantSearch: deferredParticipantSearch,
2026
3122
  agentSearch: deferredAgentSearch
2027
3123
  });
2028
- const navigate = (0, import_react3.useCallback)(
3124
+ (0, import_react8.useEffect)(() => {
3125
+ if (!config.features.showCollections) return;
3126
+ fetchCollectionNames({
3127
+ baseUrl: config.baseUrl,
3128
+ getRequestHeaders: config.getRequestHeaders
3129
+ }).then(setCollections).catch(() => setCollections([]));
3130
+ }, [config.baseUrl, config.getRequestHeaders, config.features.showCollections]);
3131
+ const navigate = (0, import_react8.useCallback)(
2029
3132
  (next) => {
2030
3133
  setRoute(next);
2031
3134
  config.onNavigate?.(next);
2032
3135
  },
2033
3136
  [config]
2034
3137
  );
2035
- const handleSidebarNavigate = (0, import_react3.useCallback)(
3138
+ const handleSidebarNavigate = (0, import_react8.useCallback)(
2036
3139
  (page) => navigate({ page }),
2037
3140
  [navigate]
2038
3141
  );
2039
- const handleThreadClick = (0, import_react3.useCallback)(
3142
+ const handleSidebarRouteNavigate = (0, import_react8.useCallback)(
3143
+ (r) => navigate(r),
3144
+ [navigate]
3145
+ );
3146
+ const handleThreadClick = (0, import_react8.useCallback)(
2040
3147
  (threadId) => navigate({ page: "thread-detail", resourceId: threadId }),
2041
3148
  [navigate]
2042
3149
  );
2043
- const handleBackToThreads = (0, import_react3.useCallback)(
2044
- () => navigate({ page: "threads" }),
3150
+ const handleBackToThreads = (0, import_react8.useCallback)(() => navigate({ page: "threads" }), [navigate]);
3151
+ const handleParticipantClick = (0, import_react8.useCallback)(
3152
+ (id) => navigate({ page: "participant-detail", resourceId: id }),
2045
3153
  [navigate]
2046
3154
  );
2047
- const sidebarPage = route.page === "thread-detail" ? "threads" : route.page;
3155
+ const handleBackToParticipants = (0, import_react8.useCallback)(() => navigate({ page: "participants" }), [navigate]);
3156
+ const handleAgentClick = (0, import_react8.useCallback)(
3157
+ (id) => navigate({ page: "agent-detail", resourceId: id }),
3158
+ [navigate]
3159
+ );
3160
+ const handleBackToAgents = (0, import_react8.useCallback)(() => navigate({ page: "agents" }), [navigate]);
3161
+ const handleCollectionItemClick = (0, import_react8.useCallback)(
3162
+ (itemId) => navigate({ page: "collection-item-detail", resourceId: itemId, collection: route.collection }),
3163
+ [navigate, route.collection]
3164
+ );
3165
+ const handleCollectionCreateNew = (0, import_react8.useCallback)(
3166
+ () => navigate({ page: "collection-item-detail", resourceId: void 0, collection: route.collection }),
3167
+ [navigate, route.collection]
3168
+ );
3169
+ const handleBackToCollectionItems = (0, import_react8.useCallback)(
3170
+ () => navigate({ page: "collection-items", collection: route.collection }),
3171
+ [navigate, route.collection]
3172
+ );
3173
+ const sidebarPage = (() => {
3174
+ switch (route.page) {
3175
+ case "thread-detail":
3176
+ return "threads";
3177
+ case "participant-detail":
3178
+ return "participants";
3179
+ case "agent-detail":
3180
+ return "agents";
3181
+ case "collection-item-detail":
3182
+ return "collection-items";
3183
+ default:
3184
+ return route.page;
3185
+ }
3186
+ })();
2048
3187
  if (admin.isLoading && !admin.overview) {
2049
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Card, { className: cn("border-border", className), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CardContent, { className: "text-muted-foreground flex items-center justify-center min-h-[200px]", children: config.labels.loading }) });
3188
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Card, { className: cn("border-border", className), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "text-muted-foreground flex items-center justify-center min-h-[200px]", children: config.labels.loading }) });
2050
3189
  }
2051
3190
  if (admin.error && !admin.overview) {
2052
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2053
- Card,
2054
- {
2055
- className: cn("border-destructive/50 bg-destructive/10", className),
2056
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(CardContent, { className: "space-y-4", children: [
2057
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-base font-semibold text-destructive", children: admin.error.message }),
2058
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2059
- Button,
2060
- {
2061
- variant: "destructive",
2062
- onClick: () => void admin.refresh(),
2063
- children: config.labels.retry
2064
- }
2065
- )
2066
- ] })
2067
- }
2068
- );
3191
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Card, { className: cn("border-destructive/50 bg-destructive/10", className), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardContent, { className: "space-y-4", children: [
3192
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-base font-semibold text-destructive", children: admin.error.message }),
3193
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "destructive", onClick: () => void admin.refresh(), children: config.labels.retry })
3194
+ ] }) });
2069
3195
  }
2070
3196
  const renderCurrentView = () => {
2071
3197
  switch (route.page) {
2072
3198
  case "dashboard":
2073
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3199
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2074
3200
  DashboardView,
2075
3201
  {
2076
3202
  config,
@@ -2090,7 +3216,7 @@ var CopilotzAdmin = ({
2090
3216
  }
2091
3217
  );
2092
3218
  case "threads":
2093
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3219
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2094
3220
  ThreadsView,
2095
3221
  {
2096
3222
  config,
@@ -2101,34 +3227,62 @@ var CopilotzAdmin = ({
2101
3227
  }
2102
3228
  );
2103
3229
  case "thread-detail":
2104
- return route.resourceId ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2105
- ThreadDetailView,
3230
+ return route.resourceId ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThreadDetailView, { threadId: route.resourceId, config, onBack: handleBackToThreads }) : null;
3231
+ case "participants":
3232
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3233
+ ParticipantsView,
2106
3234
  {
2107
- threadId: route.resourceId,
2108
3235
  config,
2109
- onBack: handleBackToThreads
3236
+ participants: admin.participants,
3237
+ searchValue: participantSearch,
3238
+ onSearchChange: setParticipantSearch,
3239
+ onParticipantClick: handleParticipantClick
2110
3240
  }
2111
- ) : null;
2112
- case "participants":
2113
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2114
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-lg font-semibold", children: config.labels.participantsTitle }),
2115
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-2 text-sm text-muted-foreground", children: "Detailed participant management coming soon." })
2116
- ] });
3241
+ );
3242
+ case "participant-detail":
3243
+ return route.resourceId ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ParticipantDetailView, { participantId: route.resourceId, config, onBack: handleBackToParticipants }) : null;
2117
3244
  case "agents":
2118
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2119
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-lg font-semibold", children: config.labels.agentsTitle }),
2120
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-2 text-sm text-muted-foreground", children: "Agent configuration management coming soon." })
2121
- ] });
3245
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3246
+ AgentsView,
3247
+ {
3248
+ config,
3249
+ agents: admin.agents,
3250
+ searchValue: agentSearch,
3251
+ onSearchChange: setAgentSearch,
3252
+ onAgentClick: handleAgentClick
3253
+ }
3254
+ );
3255
+ case "agent-detail":
3256
+ return route.resourceId ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AgentDetailView, { agentId: route.resourceId, config, agents: admin.agents, onBack: handleBackToAgents }) : null;
3257
+ case "collection-items":
3258
+ return route.collection ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3259
+ CollectionItemsView,
3260
+ {
3261
+ collection: route.collection,
3262
+ config,
3263
+ namespace,
3264
+ onItemClick: handleCollectionItemClick,
3265
+ onCreateNew: handleCollectionCreateNew
3266
+ }
3267
+ ) : null;
3268
+ case "collection-item-detail":
3269
+ return route.collection ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3270
+ CollectionItemDetailView,
3271
+ {
3272
+ collection: route.collection,
3273
+ itemId: route.resourceId ?? null,
3274
+ config,
3275
+ namespace,
3276
+ onBack: handleBackToCollectionItems
3277
+ }
3278
+ ) : null;
2122
3279
  case "events":
2123
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2124
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-lg font-semibold", children: config.labels.eventsTitle }),
2125
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-2 text-sm text-muted-foreground", children: "Event inspector coming soon." })
2126
- ] });
3280
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EventsView, { config });
2127
3281
  default:
2128
3282
  return null;
2129
3283
  }
2130
3284
  };
2131
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SidebarProvider, { defaultOpen: config.sidebar.defaultOpen, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3285
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarProvider, { defaultOpen: config.sidebar.defaultOpen, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2132
3286
  "div",
2133
3287
  {
2134
3288
  className: cn(
@@ -2136,20 +3290,25 @@ var CopilotzAdmin = ({
2136
3290
  className
2137
3291
  ),
2138
3292
  children: [
2139
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3293
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2140
3294
  AdminSidebar,
2141
3295
  {
2142
3296
  config,
2143
3297
  currentPage: sidebarPage,
2144
- onNavigate: handleSidebarNavigate
3298
+ currentRoute: route,
3299
+ onNavigate: handleSidebarNavigate,
3300
+ onNavigateRoute: handleSidebarRouteNavigate,
3301
+ collections,
3302
+ namespace,
3303
+ onNamespaceChange: setNamespace
2145
3304
  }
2146
3305
  ),
2147
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
2148
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3306
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
3307
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2149
3308
  AdminHeader,
2150
3309
  {
2151
3310
  config,
2152
- currentPage: route.page,
3311
+ currentRoute: route,
2153
3312
  range: admin.filters.range,
2154
3313
  interval: admin.filters.interval,
2155
3314
  onRangeChange: admin.setRange,
@@ -2158,7 +3317,7 @@ var CopilotzAdmin = ({
2158
3317
  isLoading: admin.isLoading
2159
3318
  }
2160
3319
  ),
2161
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex-1 overflow-auto p-6", children: renderCurrentView() })
3320
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 overflow-auto p-6", children: renderCurrentView() })
2162
3321
  ] }) })
2163
3322
  ]
2164
3323
  }
@@ -2167,13 +3326,22 @@ var CopilotzAdmin = ({
2167
3326
  // Annotate the CommonJS export names for ESM import in node:
2168
3327
  0 && (module.exports = {
2169
3328
  CopilotzAdmin,
3329
+ createCollectionItem,
2170
3330
  defaultAdminConfig,
3331
+ deleteCollectionItem,
2171
3332
  fetchAdminActivity,
2172
3333
  fetchAdminAgents,
2173
3334
  fetchAdminOverview,
2174
3335
  fetchAdminParticipants,
2175
3336
  fetchAdminThreads,
3337
+ fetchCollectionItem,
3338
+ fetchCollectionItems,
3339
+ fetchCollectionNames,
3340
+ fetchParticipantDetail,
3341
+ fetchThreadEvents,
2176
3342
  mergeAdminConfig,
3343
+ updateCollectionItem,
3344
+ updateParticipant,
2177
3345
  useCopilotzAdmin
2178
3346
  });
2179
3347
  //# sourceMappingURL=index.cjs.map