@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 +1565 -397
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -20
- package/dist/index.d.ts +84 -20
- package/dist/index.js +1476 -314
- package/dist/index.js.map +1 -1
- package/dist/styles.css +106 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// src/CopilotzAdmin.tsx
|
|
2
2
|
import {
|
|
3
|
-
useCallback as
|
|
3
|
+
useCallback as useCallback8,
|
|
4
4
|
useDeferredValue,
|
|
5
|
+
useEffect as useEffect9,
|
|
5
6
|
useMemo as useMemo3,
|
|
6
|
-
useState as
|
|
7
|
+
useState as useState9
|
|
7
8
|
} from "react";
|
|
8
9
|
|
|
9
10
|
// src/config.ts
|
|
@@ -37,7 +38,21 @@ var defaultAdminConfig = {
|
|
|
37
38
|
activeThreadsCard: "Active threads",
|
|
38
39
|
participantsCard: "Participants",
|
|
39
40
|
tokensCard: "LLM tokens",
|
|
41
|
+
costCard: "LLM cost",
|
|
40
42
|
queueCard: "Queued events",
|
|
43
|
+
llmUsageTitle: "LLM Usage",
|
|
44
|
+
usageMetricLabel: "Metric",
|
|
45
|
+
usageDimensionLabel: "Usage type",
|
|
46
|
+
usageMetricTokens: "Tokens",
|
|
47
|
+
usageMetricCost: "Cost",
|
|
48
|
+
usageTotal: "Total",
|
|
49
|
+
usageInput: "Input",
|
|
50
|
+
usageOutput: "Output",
|
|
51
|
+
usageReasoning: "Reasoning",
|
|
52
|
+
usageCacheRead: "Cache read",
|
|
53
|
+
usageCacheWrite: "Cache write",
|
|
54
|
+
usageCallsDetail: "LLM calls",
|
|
55
|
+
usageUnavailableDetail: "Available when provider-native usage exists",
|
|
41
56
|
statusActive: "Active",
|
|
42
57
|
statusArchived: "Archived",
|
|
43
58
|
scopeGlobal: "Global",
|
|
@@ -46,7 +61,9 @@ var defaultAdminConfig = {
|
|
|
46
61
|
unconfigured: "Observed only",
|
|
47
62
|
noResults: "No results",
|
|
48
63
|
eventsTitle: "Events",
|
|
49
|
-
dashboardTitle: "Dashboard"
|
|
64
|
+
dashboardTitle: "Dashboard",
|
|
65
|
+
collectionsTitle: "Collections",
|
|
66
|
+
collectionsEndpoint: "/v1/collections"
|
|
50
67
|
},
|
|
51
68
|
features: {
|
|
52
69
|
showOverview: true,
|
|
@@ -54,7 +71,8 @@ var defaultAdminConfig = {
|
|
|
54
71
|
showThreads: true,
|
|
55
72
|
showParticipants: true,
|
|
56
73
|
showAgents: true,
|
|
57
|
-
showEvents:
|
|
74
|
+
showEvents: true,
|
|
75
|
+
showCollections: true
|
|
58
76
|
},
|
|
59
77
|
ui: {
|
|
60
78
|
compact: false,
|
|
@@ -245,6 +263,122 @@ async function fetchThreadMessages(threadId, messageOptions, options) {
|
|
|
245
263
|
options
|
|
246
264
|
);
|
|
247
265
|
}
|
|
266
|
+
async function fetchParticipantDetail(participantId, options) {
|
|
267
|
+
return await fetchAdminJson(
|
|
268
|
+
`/v1/participants/${encodeURIComponent(participantId)}`,
|
|
269
|
+
{},
|
|
270
|
+
options
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
async function updateParticipant(participantId, data, options) {
|
|
274
|
+
const url = new URL(
|
|
275
|
+
`${resolveBaseUrl(options?.baseUrl)}/v1/participants/${encodeURIComponent(participantId)}`,
|
|
276
|
+
window.location.origin
|
|
277
|
+
);
|
|
278
|
+
const response = await fetch(url.toString(), {
|
|
279
|
+
method: "PUT",
|
|
280
|
+
headers: await withAuthHeaders(
|
|
281
|
+
{ "Content-Type": "application/json" },
|
|
282
|
+
options?.getRequestHeaders
|
|
283
|
+
),
|
|
284
|
+
body: JSON.stringify(data)
|
|
285
|
+
});
|
|
286
|
+
if (!response.ok) {
|
|
287
|
+
throw new Error(`Update participant failed (${response.status})`);
|
|
288
|
+
}
|
|
289
|
+
const payload = await response.json();
|
|
290
|
+
return payload.data;
|
|
291
|
+
}
|
|
292
|
+
async function fetchCollectionNames(options) {
|
|
293
|
+
return await fetchAdminJson("/v1/collections", {}, options);
|
|
294
|
+
}
|
|
295
|
+
async function fetchCollectionItems(collection, queryOptions, options) {
|
|
296
|
+
const params = {
|
|
297
|
+
namespace: queryOptions?.namespace,
|
|
298
|
+
limit: queryOptions?.limit?.toString()
|
|
299
|
+
};
|
|
300
|
+
if (queryOptions?.search) {
|
|
301
|
+
params.q = queryOptions.search;
|
|
302
|
+
} else {
|
|
303
|
+
params.offset = queryOptions?.offset?.toString();
|
|
304
|
+
}
|
|
305
|
+
return await fetchAdminJson(
|
|
306
|
+
`/v1/collections/${encodeURIComponent(collection)}`,
|
|
307
|
+
params,
|
|
308
|
+
options
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
async function fetchCollectionItem(collection, itemId, namespace, options) {
|
|
312
|
+
return await fetchAdminJson(
|
|
313
|
+
`/v1/collections/${encodeURIComponent(collection)}/${encodeURIComponent(itemId)}`,
|
|
314
|
+
{ namespace },
|
|
315
|
+
options
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
async function createCollectionItem(collection, data, namespace, options) {
|
|
319
|
+
const url = new URL(
|
|
320
|
+
`${resolveBaseUrl(options?.baseUrl)}/v1/collections/${encodeURIComponent(collection)}`,
|
|
321
|
+
window.location.origin
|
|
322
|
+
);
|
|
323
|
+
if (namespace) url.searchParams.set("namespace", namespace);
|
|
324
|
+
const response = await fetch(url.toString(), {
|
|
325
|
+
method: "POST",
|
|
326
|
+
headers: await withAuthHeaders(
|
|
327
|
+
{ "Content-Type": "application/json" },
|
|
328
|
+
options?.getRequestHeaders
|
|
329
|
+
),
|
|
330
|
+
body: JSON.stringify(data)
|
|
331
|
+
});
|
|
332
|
+
if (!response.ok) {
|
|
333
|
+
throw new Error(`Create collection item failed (${response.status})`);
|
|
334
|
+
}
|
|
335
|
+
const payload = await response.json();
|
|
336
|
+
if ("body" in payload && payload.body && typeof payload.body === "object") {
|
|
337
|
+
return payload.body;
|
|
338
|
+
}
|
|
339
|
+
return payload;
|
|
340
|
+
}
|
|
341
|
+
async function updateCollectionItem(collection, itemId, data, namespace, options) {
|
|
342
|
+
const url = new URL(
|
|
343
|
+
`${resolveBaseUrl(options?.baseUrl)}/v1/collections/${encodeURIComponent(collection)}/${encodeURIComponent(itemId)}`,
|
|
344
|
+
window.location.origin
|
|
345
|
+
);
|
|
346
|
+
if (namespace) url.searchParams.set("namespace", namespace);
|
|
347
|
+
const response = await fetch(url.toString(), {
|
|
348
|
+
method: "PUT",
|
|
349
|
+
headers: await withAuthHeaders(
|
|
350
|
+
{ "Content-Type": "application/json" },
|
|
351
|
+
options?.getRequestHeaders
|
|
352
|
+
),
|
|
353
|
+
body: JSON.stringify(data)
|
|
354
|
+
});
|
|
355
|
+
if (!response.ok) {
|
|
356
|
+
throw new Error(`Update collection item failed (${response.status})`);
|
|
357
|
+
}
|
|
358
|
+
const payload = await response.json();
|
|
359
|
+
return payload.data;
|
|
360
|
+
}
|
|
361
|
+
async function deleteCollectionItem(collection, itemId, namespace, options) {
|
|
362
|
+
const url = new URL(
|
|
363
|
+
`${resolveBaseUrl(options?.baseUrl)}/v1/collections/${encodeURIComponent(collection)}/${encodeURIComponent(itemId)}`,
|
|
364
|
+
window.location.origin
|
|
365
|
+
);
|
|
366
|
+
if (namespace) url.searchParams.set("namespace", namespace);
|
|
367
|
+
const response = await fetch(url.toString(), {
|
|
368
|
+
method: "DELETE",
|
|
369
|
+
headers: await withAuthHeaders({}, options?.getRequestHeaders)
|
|
370
|
+
});
|
|
371
|
+
if (!response.ok) {
|
|
372
|
+
throw new Error(`Delete collection item failed (${response.status})`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
async function fetchThreadEvents(threadId, options) {
|
|
376
|
+
return await fetchAdminJson(
|
|
377
|
+
`/v1/threads/${encodeURIComponent(threadId)}/events`,
|
|
378
|
+
{},
|
|
379
|
+
options
|
|
380
|
+
);
|
|
381
|
+
}
|
|
248
382
|
|
|
249
383
|
// src/useCopilotzAdmin.ts
|
|
250
384
|
function useCopilotzAdmin(options = {}) {
|
|
@@ -533,11 +667,35 @@ function Input({ className, type, ...props }) {
|
|
|
533
667
|
);
|
|
534
668
|
}
|
|
535
669
|
|
|
670
|
+
// src/components/ui/separator.tsx
|
|
671
|
+
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
672
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
673
|
+
function Separator({
|
|
674
|
+
className,
|
|
675
|
+
orientation = "horizontal",
|
|
676
|
+
decorative = true,
|
|
677
|
+
...props
|
|
678
|
+
}) {
|
|
679
|
+
return /* @__PURE__ */ jsx5(
|
|
680
|
+
SeparatorPrimitive.Root,
|
|
681
|
+
{
|
|
682
|
+
"data-slot": "separator",
|
|
683
|
+
decorative,
|
|
684
|
+
orientation,
|
|
685
|
+
className: cn(
|
|
686
|
+
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
|
|
687
|
+
className
|
|
688
|
+
),
|
|
689
|
+
...props
|
|
690
|
+
}
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
|
|
536
694
|
// src/components/ui/sheet.tsx
|
|
537
695
|
import * as React2 from "react";
|
|
538
696
|
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
|
539
697
|
import { XIcon } from "lucide-react";
|
|
540
|
-
import { jsx as
|
|
698
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
541
699
|
function cleanupBodyStyles() {
|
|
542
700
|
if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
|
|
543
701
|
document.body.style.pointerEvents = "";
|
|
@@ -557,18 +715,18 @@ function Sheet({ open, onOpenChange, ...props }) {
|
|
|
557
715
|
cleanupBodyStyles();
|
|
558
716
|
};
|
|
559
717
|
}, []);
|
|
560
|
-
return /* @__PURE__ */
|
|
718
|
+
return /* @__PURE__ */ jsx6(SheetPrimitive.Root, { "data-slot": "sheet", open, onOpenChange, ...props });
|
|
561
719
|
}
|
|
562
720
|
function SheetPortal({
|
|
563
721
|
...props
|
|
564
722
|
}) {
|
|
565
|
-
return /* @__PURE__ */
|
|
723
|
+
return /* @__PURE__ */ jsx6(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
|
|
566
724
|
}
|
|
567
725
|
function SheetOverlay({
|
|
568
726
|
className,
|
|
569
727
|
...props
|
|
570
728
|
}) {
|
|
571
|
-
return /* @__PURE__ */
|
|
729
|
+
return /* @__PURE__ */ jsx6(
|
|
572
730
|
SheetPrimitive.Overlay,
|
|
573
731
|
{
|
|
574
732
|
"data-slot": "sheet-overlay",
|
|
@@ -590,7 +748,7 @@ function SheetContent({
|
|
|
590
748
|
...props
|
|
591
749
|
}) {
|
|
592
750
|
return /* @__PURE__ */ jsxs2(SheetPortal, { children: [
|
|
593
|
-
/* @__PURE__ */
|
|
751
|
+
/* @__PURE__ */ jsx6(SheetOverlay, {}),
|
|
594
752
|
/* @__PURE__ */ jsxs2(
|
|
595
753
|
SheetPrimitive.Content,
|
|
596
754
|
{
|
|
@@ -608,8 +766,8 @@ function SheetContent({
|
|
|
608
766
|
children: [
|
|
609
767
|
children,
|
|
610
768
|
/* @__PURE__ */ jsxs2(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: [
|
|
611
|
-
/* @__PURE__ */
|
|
612
|
-
/* @__PURE__ */
|
|
769
|
+
/* @__PURE__ */ jsx6(XIcon, { className: "size-4" }),
|
|
770
|
+
/* @__PURE__ */ jsx6("span", { className: "sr-only", children: "Close" })
|
|
613
771
|
] })
|
|
614
772
|
]
|
|
615
773
|
}
|
|
@@ -617,7 +775,7 @@ function SheetContent({
|
|
|
617
775
|
] });
|
|
618
776
|
}
|
|
619
777
|
function SheetHeader({ className, ...props }) {
|
|
620
|
-
return /* @__PURE__ */
|
|
778
|
+
return /* @__PURE__ */ jsx6(
|
|
621
779
|
"div",
|
|
622
780
|
{
|
|
623
781
|
"data-slot": "sheet-header",
|
|
@@ -630,7 +788,7 @@ function SheetTitle({
|
|
|
630
788
|
className,
|
|
631
789
|
...props
|
|
632
790
|
}) {
|
|
633
|
-
return /* @__PURE__ */
|
|
791
|
+
return /* @__PURE__ */ jsx6(
|
|
634
792
|
SheetPrimitive.Title,
|
|
635
793
|
{
|
|
636
794
|
"data-slot": "sheet-title",
|
|
@@ -643,7 +801,7 @@ function SheetDescription({
|
|
|
643
801
|
className,
|
|
644
802
|
...props
|
|
645
803
|
}) {
|
|
646
|
-
return /* @__PURE__ */
|
|
804
|
+
return /* @__PURE__ */ jsx6(
|
|
647
805
|
SheetPrimitive.Description,
|
|
648
806
|
{
|
|
649
807
|
"data-slot": "sheet-description",
|
|
@@ -654,7 +812,7 @@ function SheetDescription({
|
|
|
654
812
|
}
|
|
655
813
|
|
|
656
814
|
// src/components/ui/sidebar.tsx
|
|
657
|
-
import { jsx as
|
|
815
|
+
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
658
816
|
var SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
659
817
|
var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
660
818
|
var SIDEBAR_WIDTH = "16rem";
|
|
@@ -720,7 +878,7 @@ function SidebarProvider({
|
|
|
720
878
|
}),
|
|
721
879
|
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
|
|
722
880
|
);
|
|
723
|
-
return /* @__PURE__ */
|
|
881
|
+
return /* @__PURE__ */ jsx7(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx7(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx7(
|
|
724
882
|
"div",
|
|
725
883
|
{
|
|
726
884
|
"data-slot": "sidebar-wrapper",
|
|
@@ -748,7 +906,7 @@ function Sidebar({
|
|
|
748
906
|
}) {
|
|
749
907
|
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
750
908
|
if (collapsible === "none") {
|
|
751
|
-
return /* @__PURE__ */
|
|
909
|
+
return /* @__PURE__ */ jsx7(
|
|
752
910
|
"div",
|
|
753
911
|
{
|
|
754
912
|
"data-slot": "sidebar",
|
|
@@ -762,7 +920,7 @@ function Sidebar({
|
|
|
762
920
|
);
|
|
763
921
|
}
|
|
764
922
|
if (isMobile) {
|
|
765
|
-
return /* @__PURE__ */
|
|
923
|
+
return /* @__PURE__ */ jsx7(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs3(
|
|
766
924
|
SheetContent,
|
|
767
925
|
{
|
|
768
926
|
"data-sidebar": "sidebar",
|
|
@@ -775,10 +933,10 @@ function Sidebar({
|
|
|
775
933
|
side,
|
|
776
934
|
children: [
|
|
777
935
|
/* @__PURE__ */ jsxs3(SheetHeader, { className: "sr-only", children: [
|
|
778
|
-
/* @__PURE__ */
|
|
779
|
-
/* @__PURE__ */
|
|
936
|
+
/* @__PURE__ */ jsx7(SheetTitle, { children: "Sidebar" }),
|
|
937
|
+
/* @__PURE__ */ jsx7(SheetDescription, { children: "Displays the mobile sidebar." })
|
|
780
938
|
] }),
|
|
781
|
-
/* @__PURE__ */
|
|
939
|
+
/* @__PURE__ */ jsx7("div", { className: "flex h-full w-full flex-col", children })
|
|
782
940
|
]
|
|
783
941
|
}
|
|
784
942
|
) });
|
|
@@ -793,7 +951,7 @@ function Sidebar({
|
|
|
793
951
|
"data-side": side,
|
|
794
952
|
"data-slot": "sidebar",
|
|
795
953
|
children: [
|
|
796
|
-
/* @__PURE__ */
|
|
954
|
+
/* @__PURE__ */ jsx7(
|
|
797
955
|
"div",
|
|
798
956
|
{
|
|
799
957
|
"data-slot": "sidebar-gap",
|
|
@@ -805,7 +963,7 @@ function Sidebar({
|
|
|
805
963
|
)
|
|
806
964
|
}
|
|
807
965
|
),
|
|
808
|
-
/* @__PURE__ */
|
|
966
|
+
/* @__PURE__ */ jsx7(
|
|
809
967
|
"div",
|
|
810
968
|
{
|
|
811
969
|
"data-slot": "sidebar-container",
|
|
@@ -816,7 +974,7 @@ function Sidebar({
|
|
|
816
974
|
className
|
|
817
975
|
),
|
|
818
976
|
...props,
|
|
819
|
-
children: /* @__PURE__ */
|
|
977
|
+
children: /* @__PURE__ */ jsx7(
|
|
820
978
|
"div",
|
|
821
979
|
{
|
|
822
980
|
"data-sidebar": "sidebar",
|
|
@@ -851,15 +1009,15 @@ function SidebarTrigger({
|
|
|
851
1009
|
},
|
|
852
1010
|
...props,
|
|
853
1011
|
children: [
|
|
854
|
-
/* @__PURE__ */
|
|
855
|
-
/* @__PURE__ */
|
|
1012
|
+
/* @__PURE__ */ jsx7(PanelLeftIcon, {}),
|
|
1013
|
+
/* @__PURE__ */ jsx7("span", { className: "sr-only", children: "Toggle Sidebar" })
|
|
856
1014
|
]
|
|
857
1015
|
}
|
|
858
1016
|
);
|
|
859
1017
|
}
|
|
860
1018
|
function SidebarRail({ className, ...props }) {
|
|
861
1019
|
const { toggleSidebar } = useSidebar();
|
|
862
|
-
return /* @__PURE__ */
|
|
1020
|
+
return /* @__PURE__ */ jsx7(
|
|
863
1021
|
"button",
|
|
864
1022
|
{
|
|
865
1023
|
"data-sidebar": "rail",
|
|
@@ -882,7 +1040,7 @@ function SidebarRail({ className, ...props }) {
|
|
|
882
1040
|
);
|
|
883
1041
|
}
|
|
884
1042
|
function SidebarInset({ className, ...props }) {
|
|
885
|
-
return /* @__PURE__ */
|
|
1043
|
+
return /* @__PURE__ */ jsx7(
|
|
886
1044
|
"main",
|
|
887
1045
|
{
|
|
888
1046
|
"data-slot": "sidebar-inset",
|
|
@@ -896,7 +1054,7 @@ function SidebarInset({ className, ...props }) {
|
|
|
896
1054
|
);
|
|
897
1055
|
}
|
|
898
1056
|
function SidebarHeader({ className, ...props }) {
|
|
899
|
-
return /* @__PURE__ */
|
|
1057
|
+
return /* @__PURE__ */ jsx7(
|
|
900
1058
|
"div",
|
|
901
1059
|
{
|
|
902
1060
|
"data-slot": "sidebar-header",
|
|
@@ -907,7 +1065,7 @@ function SidebarHeader({ className, ...props }) {
|
|
|
907
1065
|
);
|
|
908
1066
|
}
|
|
909
1067
|
function SidebarFooter({ className, ...props }) {
|
|
910
|
-
return /* @__PURE__ */
|
|
1068
|
+
return /* @__PURE__ */ jsx7(
|
|
911
1069
|
"div",
|
|
912
1070
|
{
|
|
913
1071
|
"data-slot": "sidebar-footer",
|
|
@@ -917,8 +1075,22 @@ function SidebarFooter({ className, ...props }) {
|
|
|
917
1075
|
}
|
|
918
1076
|
);
|
|
919
1077
|
}
|
|
1078
|
+
function SidebarSeparator({
|
|
1079
|
+
className,
|
|
1080
|
+
...props
|
|
1081
|
+
}) {
|
|
1082
|
+
return /* @__PURE__ */ jsx7(
|
|
1083
|
+
Separator,
|
|
1084
|
+
{
|
|
1085
|
+
"data-slot": "sidebar-separator",
|
|
1086
|
+
"data-sidebar": "separator",
|
|
1087
|
+
className: cn("bg-sidebar-border mx-2 w-auto", className),
|
|
1088
|
+
...props
|
|
1089
|
+
}
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
920
1092
|
function SidebarContent({ className, ...props }) {
|
|
921
|
-
return /* @__PURE__ */
|
|
1093
|
+
return /* @__PURE__ */ jsx7(
|
|
922
1094
|
"div",
|
|
923
1095
|
{
|
|
924
1096
|
"data-slot": "sidebar-content",
|
|
@@ -932,7 +1104,7 @@ function SidebarContent({ className, ...props }) {
|
|
|
932
1104
|
);
|
|
933
1105
|
}
|
|
934
1106
|
function SidebarGroup({ className, ...props }) {
|
|
935
|
-
return /* @__PURE__ */
|
|
1107
|
+
return /* @__PURE__ */ jsx7(
|
|
936
1108
|
"div",
|
|
937
1109
|
{
|
|
938
1110
|
"data-slot": "sidebar-group",
|
|
@@ -948,7 +1120,7 @@ function SidebarGroupLabel({
|
|
|
948
1120
|
...props
|
|
949
1121
|
}) {
|
|
950
1122
|
const Comp = asChild ? Slot2 : "div";
|
|
951
|
-
return /* @__PURE__ */
|
|
1123
|
+
return /* @__PURE__ */ jsx7(
|
|
952
1124
|
Comp,
|
|
953
1125
|
{
|
|
954
1126
|
"data-slot": "sidebar-group-label",
|
|
@@ -966,7 +1138,7 @@ function SidebarGroupContent({
|
|
|
966
1138
|
className,
|
|
967
1139
|
...props
|
|
968
1140
|
}) {
|
|
969
|
-
return /* @__PURE__ */
|
|
1141
|
+
return /* @__PURE__ */ jsx7(
|
|
970
1142
|
"div",
|
|
971
1143
|
{
|
|
972
1144
|
"data-slot": "sidebar-group-content",
|
|
@@ -977,7 +1149,7 @@ function SidebarGroupContent({
|
|
|
977
1149
|
);
|
|
978
1150
|
}
|
|
979
1151
|
function SidebarMenu({ className, ...props }) {
|
|
980
|
-
return /* @__PURE__ */
|
|
1152
|
+
return /* @__PURE__ */ jsx7(
|
|
981
1153
|
"ul",
|
|
982
1154
|
{
|
|
983
1155
|
"data-slot": "sidebar-menu",
|
|
@@ -988,7 +1160,7 @@ function SidebarMenu({ className, ...props }) {
|
|
|
988
1160
|
);
|
|
989
1161
|
}
|
|
990
1162
|
function SidebarMenuItem({ className, ...props }) {
|
|
991
|
-
return /* @__PURE__ */
|
|
1163
|
+
return /* @__PURE__ */ jsx7(
|
|
992
1164
|
"li",
|
|
993
1165
|
{
|
|
994
1166
|
"data-slot": "sidebar-menu-item",
|
|
@@ -1029,7 +1201,7 @@ function SidebarMenuButton({
|
|
|
1029
1201
|
}) {
|
|
1030
1202
|
const Comp = asChild ? Slot2 : "button";
|
|
1031
1203
|
const { isMobile, state } = useSidebar();
|
|
1032
|
-
const button = /* @__PURE__ */
|
|
1204
|
+
const button = /* @__PURE__ */ jsx7(
|
|
1033
1205
|
Comp,
|
|
1034
1206
|
{
|
|
1035
1207
|
"data-slot": "sidebar-menu-button",
|
|
@@ -1049,8 +1221,8 @@ function SidebarMenuButton({
|
|
|
1049
1221
|
};
|
|
1050
1222
|
}
|
|
1051
1223
|
return /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
1052
|
-
/* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1224
|
+
/* @__PURE__ */ jsx7(TooltipTrigger, { asChild: true, children: button }),
|
|
1225
|
+
/* @__PURE__ */ jsx7(
|
|
1054
1226
|
TooltipContent,
|
|
1055
1227
|
{
|
|
1056
1228
|
side: "right",
|
|
@@ -1068,91 +1240,19 @@ import {
|
|
|
1068
1240
|
MessageSquare,
|
|
1069
1241
|
Users,
|
|
1070
1242
|
Bot,
|
|
1071
|
-
Activity
|
|
1243
|
+
Activity,
|
|
1244
|
+
Database,
|
|
1245
|
+
ChevronsUpDown
|
|
1072
1246
|
} from "lucide-react";
|
|
1073
|
-
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1074
|
-
var NAV_ITEMS = [
|
|
1075
|
-
{
|
|
1076
|
-
page: "dashboard",
|
|
1077
|
-
label: "Dashboard",
|
|
1078
|
-
icon: LayoutDashboard
|
|
1079
|
-
},
|
|
1080
|
-
{
|
|
1081
|
-
page: "threads",
|
|
1082
|
-
label: "Threads",
|
|
1083
|
-
icon: MessageSquare,
|
|
1084
|
-
featureKey: "showThreads"
|
|
1085
|
-
},
|
|
1086
|
-
{
|
|
1087
|
-
page: "participants",
|
|
1088
|
-
label: "Participants",
|
|
1089
|
-
icon: Users,
|
|
1090
|
-
featureKey: "showParticipants"
|
|
1091
|
-
},
|
|
1092
|
-
{
|
|
1093
|
-
page: "agents",
|
|
1094
|
-
label: "Agents",
|
|
1095
|
-
icon: Bot,
|
|
1096
|
-
featureKey: "showAgents"
|
|
1097
|
-
},
|
|
1098
|
-
{
|
|
1099
|
-
page: "events",
|
|
1100
|
-
label: "Events",
|
|
1101
|
-
icon: Activity,
|
|
1102
|
-
featureKey: "showEvents"
|
|
1103
|
-
}
|
|
1104
|
-
];
|
|
1105
|
-
var AdminSidebar = ({
|
|
1106
|
-
config,
|
|
1107
|
-
currentPage,
|
|
1108
|
-
onNavigate
|
|
1109
|
-
}) => {
|
|
1110
|
-
const visibleItems = NAV_ITEMS.filter(
|
|
1111
|
-
(item) => !item.featureKey || config.features[item.featureKey]
|
|
1112
|
-
);
|
|
1113
|
-
return /* @__PURE__ */ jsxs4(Sidebar, { collapsible: config.sidebar.collapsible, children: [
|
|
1114
|
-
/* @__PURE__ */ jsx7(SidebarHeader, { children: /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-3 px-2 py-3", children: [
|
|
1115
|
-
/* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center shrink-0", children: config.branding.logo || /* @__PURE__ */ jsx7("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx7(LayoutDashboard, { className: "h-4 w-4" }) }) }),
|
|
1116
|
-
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col min-w-0 group-data-[collapsible=icon]:hidden", children: [
|
|
1117
|
-
/* @__PURE__ */ jsx7("span", { className: "text-sm font-semibold truncate", children: config.branding.title }),
|
|
1118
|
-
config.branding.subtitle && /* @__PURE__ */ jsx7("span", { className: "text-xs text-muted-foreground truncate", children: config.branding.subtitle })
|
|
1119
|
-
] })
|
|
1120
|
-
] }) }),
|
|
1121
|
-
/* @__PURE__ */ jsx7(SidebarContent, { children: /* @__PURE__ */ jsxs4(SidebarGroup, { children: [
|
|
1122
|
-
/* @__PURE__ */ jsx7(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: "Navigation" }),
|
|
1123
|
-
/* @__PURE__ */ jsx7(SidebarGroupContent, { children: /* @__PURE__ */ jsx7(SidebarMenu, { children: visibleItems.map((item) => {
|
|
1124
|
-
const Icon2 = item.icon;
|
|
1125
|
-
const label = config.labels[`${item.page}Title`] || item.label;
|
|
1126
|
-
return /* @__PURE__ */ jsx7(SidebarMenuItem, { children: /* @__PURE__ */ jsxs4(
|
|
1127
|
-
SidebarMenuButton,
|
|
1128
|
-
{
|
|
1129
|
-
isActive: currentPage === item.page,
|
|
1130
|
-
onClick: () => onNavigate(item.page),
|
|
1131
|
-
tooltip: label,
|
|
1132
|
-
children: [
|
|
1133
|
-
/* @__PURE__ */ jsx7(Icon2, {}),
|
|
1134
|
-
/* @__PURE__ */ jsx7("span", { children: label })
|
|
1135
|
-
]
|
|
1136
|
-
}
|
|
1137
|
-
) }, item.page);
|
|
1138
|
-
}) }) })
|
|
1139
|
-
] }) }),
|
|
1140
|
-
config.namespace && /* @__PURE__ */ jsx7(SidebarFooter, { children: /* @__PURE__ */ jsx7("div", { className: "px-2 py-2 text-xs text-muted-foreground group-data-[collapsible=icon]:hidden", children: /* @__PURE__ */ jsx7("span", { className: "font-medium uppercase tracking-[0.18em]", children: config.namespace }) }) }),
|
|
1141
|
-
/* @__PURE__ */ jsx7(SidebarRail, {})
|
|
1142
|
-
] });
|
|
1143
|
-
};
|
|
1144
|
-
|
|
1145
|
-
// src/components/layout/AdminHeader.tsx
|
|
1146
|
-
import { RefreshCw } from "lucide-react";
|
|
1147
1247
|
|
|
1148
1248
|
// src/components/ui/select.tsx
|
|
1149
1249
|
import * as React4 from "react";
|
|
1150
1250
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
1151
1251
|
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
|
1152
|
-
import { jsx as jsx8, jsxs as
|
|
1252
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1153
1253
|
var Select = SelectPrimitive.Root;
|
|
1154
1254
|
var SelectValue = SelectPrimitive.Value;
|
|
1155
|
-
var SelectTrigger = React4.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
1255
|
+
var SelectTrigger = React4.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
1156
1256
|
SelectPrimitive.Trigger,
|
|
1157
1257
|
{
|
|
1158
1258
|
ref,
|
|
@@ -1168,7 +1268,7 @@ var SelectTrigger = React4.forwardRef(({ className, children, ...props }, ref) =
|
|
|
1168
1268
|
}
|
|
1169
1269
|
));
|
|
1170
1270
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
1171
|
-
var SelectContent = React4.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx8(SelectPrimitive.Portal, { children: /* @__PURE__ */
|
|
1271
|
+
var SelectContent = React4.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx8(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs4(
|
|
1172
1272
|
SelectPrimitive.Content,
|
|
1173
1273
|
{
|
|
1174
1274
|
ref,
|
|
@@ -1196,7 +1296,7 @@ var SelectContent = React4.forwardRef(({ className, children, position = "popper
|
|
|
1196
1296
|
}
|
|
1197
1297
|
) }));
|
|
1198
1298
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
1199
|
-
var SelectItem = React4.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
1299
|
+
var SelectItem = React4.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
1200
1300
|
SelectPrimitive.Item,
|
|
1201
1301
|
{
|
|
1202
1302
|
ref,
|
|
@@ -1213,19 +1313,111 @@ var SelectItem = React4.forwardRef(({ className, children, ...props }, ref) => /
|
|
|
1213
1313
|
));
|
|
1214
1314
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
1215
1315
|
|
|
1316
|
+
// src/components/layout/AdminSidebar.tsx
|
|
1317
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1318
|
+
var NAV_ITEMS = [
|
|
1319
|
+
{ page: "dashboard", label: "Dashboard", icon: LayoutDashboard },
|
|
1320
|
+
{ page: "threads", label: "Threads", icon: MessageSquare, featureKey: "showThreads" },
|
|
1321
|
+
{ page: "participants", label: "Participants", icon: Users, featureKey: "showParticipants" },
|
|
1322
|
+
{ page: "agents", label: "Agents", icon: Bot, featureKey: "showAgents" },
|
|
1323
|
+
{ page: "events", label: "Events", icon: Activity, featureKey: "showEvents" }
|
|
1324
|
+
];
|
|
1325
|
+
var AdminSidebar = ({
|
|
1326
|
+
config,
|
|
1327
|
+
currentPage,
|
|
1328
|
+
currentRoute,
|
|
1329
|
+
onNavigate,
|
|
1330
|
+
onNavigateRoute,
|
|
1331
|
+
collections,
|
|
1332
|
+
namespace,
|
|
1333
|
+
onNamespaceChange
|
|
1334
|
+
}) => {
|
|
1335
|
+
const visibleItems = NAV_ITEMS.filter(
|
|
1336
|
+
(item) => !item.featureKey || config.features[item.featureKey]
|
|
1337
|
+
);
|
|
1338
|
+
const showCollections = config.features.showCollections && collections.length > 0;
|
|
1339
|
+
return /* @__PURE__ */ jsxs5(Sidebar, { collapsible: config.sidebar.collapsible, children: [
|
|
1340
|
+
/* @__PURE__ */ jsx9(SidebarHeader, { children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 px-2 py-3", children: [
|
|
1341
|
+
/* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center shrink-0", children: config.branding.logo || /* @__PURE__ */ jsx9("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx9(LayoutDashboard, { className: "h-4 w-4" }) }) }),
|
|
1342
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col min-w-0 group-data-[collapsible=icon]:hidden", children: [
|
|
1343
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm font-semibold truncate", children: config.branding.title }),
|
|
1344
|
+
config.branding.subtitle && /* @__PURE__ */ jsx9("span", { className: "text-xs text-muted-foreground truncate", children: config.branding.subtitle })
|
|
1345
|
+
] })
|
|
1346
|
+
] }) }),
|
|
1347
|
+
/* @__PURE__ */ jsxs5(SidebarContent, { children: [
|
|
1348
|
+
/* @__PURE__ */ jsxs5(SidebarGroup, { children: [
|
|
1349
|
+
/* @__PURE__ */ jsx9(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: "Navigation" }),
|
|
1350
|
+
/* @__PURE__ */ jsx9(SidebarGroupContent, { children: /* @__PURE__ */ jsx9(SidebarMenu, { children: visibleItems.map((item) => {
|
|
1351
|
+
const Icon2 = item.icon;
|
|
1352
|
+
const label = config.labels[`${item.page}Title`] || item.label;
|
|
1353
|
+
return /* @__PURE__ */ jsx9(SidebarMenuItem, { children: /* @__PURE__ */ jsxs5(
|
|
1354
|
+
SidebarMenuButton,
|
|
1355
|
+
{
|
|
1356
|
+
isActive: currentPage === item.page,
|
|
1357
|
+
onClick: () => onNavigate(item.page),
|
|
1358
|
+
tooltip: label,
|
|
1359
|
+
children: [
|
|
1360
|
+
/* @__PURE__ */ jsx9(Icon2, {}),
|
|
1361
|
+
/* @__PURE__ */ jsx9("span", { children: label })
|
|
1362
|
+
]
|
|
1363
|
+
}
|
|
1364
|
+
) }, item.page);
|
|
1365
|
+
}) }) })
|
|
1366
|
+
] }),
|
|
1367
|
+
showCollections && /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1368
|
+
/* @__PURE__ */ jsx9(SidebarSeparator, {}),
|
|
1369
|
+
/* @__PURE__ */ jsxs5(SidebarGroup, { children: [
|
|
1370
|
+
/* @__PURE__ */ jsx9(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: config.labels.collectionsTitle }),
|
|
1371
|
+
/* @__PURE__ */ jsx9(SidebarGroupContent, { children: /* @__PURE__ */ jsx9(SidebarMenu, { children: collections.map((col) => /* @__PURE__ */ jsx9(SidebarMenuItem, { children: /* @__PURE__ */ jsxs5(
|
|
1372
|
+
SidebarMenuButton,
|
|
1373
|
+
{
|
|
1374
|
+
isActive: currentRoute.page === "collection-items" && currentRoute.collection === col,
|
|
1375
|
+
onClick: () => onNavigateRoute({ page: "collection-items", collection: col }),
|
|
1376
|
+
tooltip: col,
|
|
1377
|
+
children: [
|
|
1378
|
+
/* @__PURE__ */ jsx9(Database, {}),
|
|
1379
|
+
/* @__PURE__ */ jsx9("span", { className: "capitalize", children: col })
|
|
1380
|
+
]
|
|
1381
|
+
}
|
|
1382
|
+
) }, col)) }) })
|
|
1383
|
+
] })
|
|
1384
|
+
] })
|
|
1385
|
+
] }),
|
|
1386
|
+
/* @__PURE__ */ jsxs5(SidebarFooter, { children: [
|
|
1387
|
+
/* @__PURE__ */ jsxs5("div", { className: "group-data-[collapsible=icon]:hidden", children: [
|
|
1388
|
+
/* @__PURE__ */ jsx9("label", { className: "text-xs font-medium text-muted-foreground mb-1 block px-2", children: "Namespace" }),
|
|
1389
|
+
/* @__PURE__ */ jsxs5(Select, { value: namespace || "__all__", onValueChange: (v) => onNamespaceChange(v === "__all__" ? "" : v), children: [
|
|
1390
|
+
/* @__PURE__ */ jsx9(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx9(SelectValue, { placeholder: "All namespaces" }) }),
|
|
1391
|
+
/* @__PURE__ */ jsxs5(SelectContent, { children: [
|
|
1392
|
+
/* @__PURE__ */ jsx9(SelectItem, { value: "__all__", children: "All namespaces" }),
|
|
1393
|
+
config.namespace && /* @__PURE__ */ jsx9(SelectItem, { value: config.namespace, children: config.namespace })
|
|
1394
|
+
] })
|
|
1395
|
+
] })
|
|
1396
|
+
] }),
|
|
1397
|
+
/* @__PURE__ */ jsx9("div", { className: "hidden group-data-[collapsible=icon]:flex justify-center", children: /* @__PURE__ */ jsx9(ChevronsUpDown, { className: "h-4 w-4 text-muted-foreground" }) })
|
|
1398
|
+
] }),
|
|
1399
|
+
/* @__PURE__ */ jsx9(SidebarRail, {})
|
|
1400
|
+
] });
|
|
1401
|
+
};
|
|
1402
|
+
|
|
1216
1403
|
// src/components/layout/AdminHeader.tsx
|
|
1217
|
-
import {
|
|
1404
|
+
import { RefreshCw } from "lucide-react";
|
|
1405
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1218
1406
|
var PAGE_TITLES = {
|
|
1219
1407
|
dashboard: "Dashboard",
|
|
1220
1408
|
threads: "Threads",
|
|
1221
1409
|
"thread-detail": "Thread Detail",
|
|
1222
1410
|
participants: "Participants",
|
|
1411
|
+
"participant-detail": "Participant Detail",
|
|
1223
1412
|
agents: "Agents",
|
|
1413
|
+
"agent-detail": "Agent Detail",
|
|
1414
|
+
"collection-items": "Collection",
|
|
1415
|
+
"collection-item-detail": "Item Detail",
|
|
1224
1416
|
events: "Events"
|
|
1225
1417
|
};
|
|
1226
1418
|
var AdminHeader = ({
|
|
1227
1419
|
config,
|
|
1228
|
-
|
|
1420
|
+
currentRoute,
|
|
1229
1421
|
range,
|
|
1230
1422
|
interval,
|
|
1231
1423
|
onRangeChange,
|
|
@@ -1233,19 +1425,22 @@ var AdminHeader = ({
|
|
|
1233
1425
|
onRefresh,
|
|
1234
1426
|
isLoading
|
|
1235
1427
|
}) => {
|
|
1236
|
-
|
|
1237
|
-
|
|
1428
|
+
let pageTitle = config.labels[`${currentRoute.page}Title`] || PAGE_TITLES[currentRoute.page] || currentRoute.page;
|
|
1429
|
+
if (currentRoute.page === "collection-items" && currentRoute.collection) {
|
|
1430
|
+
pageTitle = currentRoute.collection.charAt(0).toUpperCase() + currentRoute.collection.slice(1);
|
|
1431
|
+
}
|
|
1432
|
+
return /* @__PURE__ */ jsx10(Card, { className: "py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: /* @__PURE__ */ jsx10(CardHeader, { className: "p-2", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1238
1433
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
|
|
1239
1434
|
/* @__PURE__ */ jsxs6(Tooltip, { children: [
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
/* @__PURE__ */
|
|
1435
|
+
/* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(SidebarTrigger, { className: "-ml-1" }) }),
|
|
1436
|
+
/* @__PURE__ */ jsx10(TooltipContent, { children: "Toggle Sidebar" })
|
|
1242
1437
|
] }),
|
|
1243
|
-
/* @__PURE__ */
|
|
1438
|
+
/* @__PURE__ */ jsx10("h1", { className: "text-sm font-medium ml-2", children: pageTitle })
|
|
1244
1439
|
] }),
|
|
1245
|
-
/* @__PURE__ */
|
|
1440
|
+
/* @__PURE__ */ jsx10("div", { className: "flex-1" }),
|
|
1246
1441
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
|
|
1247
|
-
|
|
1248
|
-
/* @__PURE__ */
|
|
1442
|
+
currentRoute.page === "dashboard" && /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1443
|
+
/* @__PURE__ */ jsx10(
|
|
1249
1444
|
Button,
|
|
1250
1445
|
{
|
|
1251
1446
|
variant: range === "24h" ? "default" : "ghost",
|
|
@@ -1255,7 +1450,7 @@ var AdminHeader = ({
|
|
|
1255
1450
|
children: config.labels.range24h
|
|
1256
1451
|
}
|
|
1257
1452
|
),
|
|
1258
|
-
/* @__PURE__ */
|
|
1453
|
+
/* @__PURE__ */ jsx10(
|
|
1259
1454
|
Button,
|
|
1260
1455
|
{
|
|
1261
1456
|
variant: range === "7d" ? "default" : "ghost",
|
|
@@ -1265,7 +1460,7 @@ var AdminHeader = ({
|
|
|
1265
1460
|
children: config.labels.range7d
|
|
1266
1461
|
}
|
|
1267
1462
|
),
|
|
1268
|
-
/* @__PURE__ */
|
|
1463
|
+
/* @__PURE__ */ jsx10(
|
|
1269
1464
|
Button,
|
|
1270
1465
|
{
|
|
1271
1466
|
variant: range === "30d" ? "default" : "ghost",
|
|
@@ -1281,17 +1476,17 @@ var AdminHeader = ({
|
|
|
1281
1476
|
value: interval,
|
|
1282
1477
|
onValueChange: (v) => onIntervalChange(v),
|
|
1283
1478
|
children: [
|
|
1284
|
-
/* @__PURE__ */
|
|
1479
|
+
/* @__PURE__ */ jsx10(SelectTrigger, { className: "h-7 w-[90px] text-xs", children: /* @__PURE__ */ jsx10(SelectValue, {}) }),
|
|
1285
1480
|
/* @__PURE__ */ jsxs6(SelectContent, { children: [
|
|
1286
|
-
/* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1481
|
+
/* @__PURE__ */ jsx10(SelectItem, { value: "hour", children: config.labels.intervalHour }),
|
|
1482
|
+
/* @__PURE__ */ jsx10(SelectItem, { value: "day", children: config.labels.intervalDay })
|
|
1288
1483
|
] })
|
|
1289
1484
|
]
|
|
1290
1485
|
}
|
|
1291
1486
|
)
|
|
1292
1487
|
] }),
|
|
1293
1488
|
/* @__PURE__ */ jsxs6(Tooltip, { children: [
|
|
1294
|
-
/* @__PURE__ */
|
|
1489
|
+
/* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(
|
|
1295
1490
|
Button,
|
|
1296
1491
|
{
|
|
1297
1492
|
variant: "ghost",
|
|
@@ -1299,7 +1494,7 @@ var AdminHeader = ({
|
|
|
1299
1494
|
className: "h-7 w-7",
|
|
1300
1495
|
onClick: onRefresh,
|
|
1301
1496
|
disabled: isLoading,
|
|
1302
|
-
children: /* @__PURE__ */
|
|
1497
|
+
children: /* @__PURE__ */ jsx10(
|
|
1303
1498
|
RefreshCw,
|
|
1304
1499
|
{
|
|
1305
1500
|
className: `h-4 w-4 ${isLoading ? "animate-spin" : ""}`
|
|
@@ -1307,17 +1502,20 @@ var AdminHeader = ({
|
|
|
1307
1502
|
)
|
|
1308
1503
|
}
|
|
1309
1504
|
) }),
|
|
1310
|
-
/* @__PURE__ */
|
|
1505
|
+
/* @__PURE__ */ jsx10(TooltipContent, { children: config.labels.refresh })
|
|
1311
1506
|
] }),
|
|
1312
1507
|
config.branding.actions
|
|
1313
1508
|
] })
|
|
1314
1509
|
] }) }) });
|
|
1315
1510
|
};
|
|
1316
1511
|
|
|
1512
|
+
// src/components/views/DashboardView.tsx
|
|
1513
|
+
import React5 from "react";
|
|
1514
|
+
|
|
1317
1515
|
// src/components/ui/badge.tsx
|
|
1318
1516
|
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
1319
1517
|
import { cva as cva3 } from "class-variance-authority";
|
|
1320
|
-
import { jsx as
|
|
1518
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1321
1519
|
var badgeVariants = cva3(
|
|
1322
1520
|
"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",
|
|
1323
1521
|
{
|
|
@@ -1341,7 +1539,7 @@ function Badge({
|
|
|
1341
1539
|
...props
|
|
1342
1540
|
}) {
|
|
1343
1541
|
const Comp = asChild ? Slot3 : "span";
|
|
1344
|
-
return /* @__PURE__ */
|
|
1542
|
+
return /* @__PURE__ */ jsx11(
|
|
1345
1543
|
Comp,
|
|
1346
1544
|
{
|
|
1347
1545
|
"data-slot": "badge",
|
|
@@ -1352,7 +1550,7 @@ function Badge({
|
|
|
1352
1550
|
}
|
|
1353
1551
|
|
|
1354
1552
|
// src/components/views/DashboardView.tsx
|
|
1355
|
-
import { jsx as
|
|
1553
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1356
1554
|
var DashboardView = ({
|
|
1357
1555
|
config,
|
|
1358
1556
|
overview,
|
|
@@ -1369,6 +1567,23 @@ var DashboardView = ({
|
|
|
1369
1567
|
onAgentSearchChange,
|
|
1370
1568
|
onThreadClick
|
|
1371
1569
|
}) => {
|
|
1570
|
+
const [usageMetricKind, setUsageMetricKind] = React5.useState(
|
|
1571
|
+
"tokens"
|
|
1572
|
+
);
|
|
1573
|
+
const [usageDimension, setUsageDimension] = React5.useState(
|
|
1574
|
+
"total"
|
|
1575
|
+
);
|
|
1576
|
+
const llmSummaryValue = overview ? getOverviewUsageValue(overview, usageMetricKind, usageDimension) : 0;
|
|
1577
|
+
const llmSummaryLabel = getUsageSummaryLabel(
|
|
1578
|
+
config.labels,
|
|
1579
|
+
usageMetricKind,
|
|
1580
|
+
usageDimension
|
|
1581
|
+
);
|
|
1582
|
+
const usageBreakdownCards = USAGE_DIMENSIONS.map((dimension) => ({
|
|
1583
|
+
dimension,
|
|
1584
|
+
label: getUsageDimensionLabel(config.labels, dimension),
|
|
1585
|
+
value: overview ? getOverviewUsageValue(overview, usageMetricKind, dimension) : 0
|
|
1586
|
+
}));
|
|
1372
1587
|
const cards = [
|
|
1373
1588
|
{
|
|
1374
1589
|
label: config.labels.messagesCard,
|
|
@@ -1386,9 +1601,10 @@ var DashboardView = ({
|
|
|
1386
1601
|
detail: `${overview?.participantTotals.agents ?? 0} agents`
|
|
1387
1602
|
},
|
|
1388
1603
|
{
|
|
1389
|
-
label:
|
|
1390
|
-
value:
|
|
1391
|
-
detail: `${overview?.llmTotals.totalCalls ?? 0}
|
|
1604
|
+
label: llmSummaryLabel,
|
|
1605
|
+
value: llmSummaryValue,
|
|
1606
|
+
detail: `${overview?.llmTotals.totalCalls ?? 0} ${config.labels.usageCallsDetail}`,
|
|
1607
|
+
metricKind: usageMetricKind
|
|
1392
1608
|
},
|
|
1393
1609
|
{
|
|
1394
1610
|
label: config.labels.queueCard,
|
|
@@ -1399,38 +1615,108 @@ var DashboardView = ({
|
|
|
1399
1615
|
const isEmpty = cards.every((card) => card.value === 0) && activity.length === 0 && threads.length === 0 && participants.length === 0 && agents.length === 0;
|
|
1400
1616
|
return /* @__PURE__ */ jsxs7("div", { className: "space-y-6", children: [
|
|
1401
1617
|
isEmpty && /* @__PURE__ */ jsxs7("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */
|
|
1618
|
+
/* @__PURE__ */ jsx12("h3", { className: "text-lg font-semibold", children: config.labels.emptyTitle }),
|
|
1619
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-2 text-sm text-muted-foreground", children: config.labels.emptyDescription })
|
|
1404
1620
|
] }),
|
|
1405
1621
|
config.features.showOverview && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
|
|
1406
|
-
/* @__PURE__ */
|
|
1407
|
-
/* @__PURE__ */
|
|
1622
|
+
/* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.overviewTitle }),
|
|
1623
|
+
/* @__PURE__ */ jsx12("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-5", children: cards.map((card) => /* @__PURE__ */ jsxs7(
|
|
1408
1624
|
"div",
|
|
1409
1625
|
{
|
|
1410
1626
|
className: "rounded-xl border bg-card p-5 shadow-sm",
|
|
1411
1627
|
children: [
|
|
1412
|
-
/* @__PURE__ */
|
|
1413
|
-
/* @__PURE__ */
|
|
1414
|
-
|
|
1628
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
|
|
1629
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-3 text-3xl font-semibold tracking-tight", children: formatMetricValue(
|
|
1630
|
+
card.value,
|
|
1631
|
+
card.metricKind ?? "tokens"
|
|
1632
|
+
) }),
|
|
1633
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-2 text-xs text-muted-foreground", children: card.detail })
|
|
1415
1634
|
]
|
|
1416
1635
|
},
|
|
1417
1636
|
card.label
|
|
1418
1637
|
)) })
|
|
1419
1638
|
] }),
|
|
1639
|
+
config.features.showOverview && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
|
|
1640
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between", children: [
|
|
1641
|
+
/* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.llmUsageTitle }),
|
|
1642
|
+
/* @__PURE__ */ jsxs7("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
1643
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1644
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageMetricLabel }),
|
|
1645
|
+
/* @__PURE__ */ jsxs7(
|
|
1646
|
+
Select,
|
|
1647
|
+
{
|
|
1648
|
+
value: usageMetricKind,
|
|
1649
|
+
onValueChange: (value) => setUsageMetricKind(value),
|
|
1650
|
+
children: [
|
|
1651
|
+
/* @__PURE__ */ jsx12(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
|
|
1652
|
+
/* @__PURE__ */ jsxs7(SelectContent, { children: [
|
|
1653
|
+
/* @__PURE__ */ jsx12(SelectItem, { value: "tokens", children: config.labels.usageMetricTokens }),
|
|
1654
|
+
/* @__PURE__ */ jsx12(SelectItem, { value: "cost", children: config.labels.usageMetricCost })
|
|
1655
|
+
] })
|
|
1656
|
+
]
|
|
1657
|
+
}
|
|
1658
|
+
)
|
|
1659
|
+
] }),
|
|
1660
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1661
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageDimensionLabel }),
|
|
1662
|
+
/* @__PURE__ */ jsxs7(
|
|
1663
|
+
Select,
|
|
1664
|
+
{
|
|
1665
|
+
value: usageDimension,
|
|
1666
|
+
onValueChange: (value) => setUsageDimension(value),
|
|
1667
|
+
children: [
|
|
1668
|
+
/* @__PURE__ */ jsx12(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
|
|
1669
|
+
/* @__PURE__ */ jsx12(SelectContent, { children: USAGE_DIMENSIONS.map((dimension) => /* @__PURE__ */ jsx12(SelectItem, { value: dimension, children: getUsageDimensionLabel(config.labels, dimension) }, dimension)) })
|
|
1670
|
+
]
|
|
1671
|
+
}
|
|
1672
|
+
)
|
|
1673
|
+
] })
|
|
1674
|
+
] })
|
|
1675
|
+
] }),
|
|
1676
|
+
/* @__PURE__ */ jsx12("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: usageBreakdownCards.map((card) => {
|
|
1677
|
+
const isSelected = card.dimension === usageDimension;
|
|
1678
|
+
return /* @__PURE__ */ jsxs7(
|
|
1679
|
+
"div",
|
|
1680
|
+
{
|
|
1681
|
+
className: cn(
|
|
1682
|
+
"rounded-xl border bg-card p-5 shadow-sm transition-colors",
|
|
1683
|
+
isSelected && "border-primary/60 ring-1 ring-primary/15"
|
|
1684
|
+
),
|
|
1685
|
+
children: [
|
|
1686
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1687
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1688
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
|
|
1689
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-3 text-2xl font-semibold tracking-tight", children: formatMetricValue(card.value, usageMetricKind) })
|
|
1690
|
+
] }),
|
|
1691
|
+
isSelected && /* @__PURE__ */ jsx12(Badge, { variant: "outline", children: config.labels.usageDimensionLabel })
|
|
1692
|
+
] }),
|
|
1693
|
+
/* @__PURE__ */ jsxs7("p", { className: "mt-2 text-xs text-muted-foreground", children: [
|
|
1694
|
+
overview?.llmTotals.totalCalls ?? 0,
|
|
1695
|
+
" ",
|
|
1696
|
+
config.labels.usageCallsDetail
|
|
1697
|
+
] })
|
|
1698
|
+
]
|
|
1699
|
+
},
|
|
1700
|
+
card.dimension
|
|
1701
|
+
);
|
|
1702
|
+
}) })
|
|
1703
|
+
] }),
|
|
1420
1704
|
config.features.showActivity && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
|
|
1421
|
-
/* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */
|
|
1705
|
+
/* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.activityTitle }),
|
|
1706
|
+
/* @__PURE__ */ jsx12(
|
|
1423
1707
|
ActivityChart,
|
|
1424
1708
|
{
|
|
1425
1709
|
interval,
|
|
1426
1710
|
labels: config.labels,
|
|
1427
1711
|
maxBars: config.ui.maxActivityBars,
|
|
1428
|
-
points: activity
|
|
1712
|
+
points: activity,
|
|
1713
|
+
usageDimension,
|
|
1714
|
+
usageMetricKind
|
|
1429
1715
|
}
|
|
1430
1716
|
)
|
|
1431
1717
|
] }),
|
|
1432
1718
|
/* @__PURE__ */ jsxs7("div", { className: "grid gap-6 lg:grid-cols-3", children: [
|
|
1433
|
-
config.features.showThreads && /* @__PURE__ */
|
|
1719
|
+
config.features.showThreads && /* @__PURE__ */ jsx12(
|
|
1434
1720
|
DataTable,
|
|
1435
1721
|
{
|
|
1436
1722
|
rows: threads,
|
|
@@ -1438,7 +1724,7 @@ var DashboardView = ({
|
|
|
1438
1724
|
searchValue: threadSearch,
|
|
1439
1725
|
setSearchValue: onThreadSearchChange,
|
|
1440
1726
|
title: config.labels.threadsTitle,
|
|
1441
|
-
children: /* @__PURE__ */
|
|
1727
|
+
children: /* @__PURE__ */ jsx12(
|
|
1442
1728
|
ThreadsTable,
|
|
1443
1729
|
{
|
|
1444
1730
|
rows: threads,
|
|
@@ -1448,7 +1734,7 @@ var DashboardView = ({
|
|
|
1448
1734
|
)
|
|
1449
1735
|
}
|
|
1450
1736
|
),
|
|
1451
|
-
config.features.showParticipants && /* @__PURE__ */
|
|
1737
|
+
config.features.showParticipants && /* @__PURE__ */ jsx12(
|
|
1452
1738
|
DataTable,
|
|
1453
1739
|
{
|
|
1454
1740
|
rows: participants,
|
|
@@ -1456,10 +1742,10 @@ var DashboardView = ({
|
|
|
1456
1742
|
searchValue: participantSearch,
|
|
1457
1743
|
setSearchValue: onParticipantSearchChange,
|
|
1458
1744
|
title: config.labels.participantsTitle,
|
|
1459
|
-
children: /* @__PURE__ */
|
|
1745
|
+
children: /* @__PURE__ */ jsx12(ParticipantsTable, { rows: participants, labels: config.labels })
|
|
1460
1746
|
}
|
|
1461
1747
|
),
|
|
1462
|
-
config.features.showAgents && /* @__PURE__ */
|
|
1748
|
+
config.features.showAgents && /* @__PURE__ */ jsx12(
|
|
1463
1749
|
DataTable,
|
|
1464
1750
|
{
|
|
1465
1751
|
rows: agents,
|
|
@@ -1467,52 +1753,75 @@ var DashboardView = ({
|
|
|
1467
1753
|
searchValue: agentSearch,
|
|
1468
1754
|
setSearchValue: onAgentSearchChange,
|
|
1469
1755
|
title: config.labels.agentsTitle,
|
|
1470
|
-
children: /* @__PURE__ */
|
|
1756
|
+
children: /* @__PURE__ */ jsx12(
|
|
1757
|
+
AgentsTable,
|
|
1758
|
+
{
|
|
1759
|
+
rows: agents,
|
|
1760
|
+
labels: config.labels,
|
|
1761
|
+
usageMetricKind,
|
|
1762
|
+
usageDimension
|
|
1763
|
+
}
|
|
1764
|
+
)
|
|
1471
1765
|
}
|
|
1472
1766
|
)
|
|
1473
1767
|
] })
|
|
1474
1768
|
] });
|
|
1475
1769
|
};
|
|
1476
1770
|
function SectionHeading({ title }) {
|
|
1477
|
-
return /* @__PURE__ */
|
|
1771
|
+
return /* @__PURE__ */ jsx12("h3", { className: "text-lg font-semibold tracking-tight", children: title });
|
|
1478
1772
|
}
|
|
1479
1773
|
function ActivityChart(props) {
|
|
1480
1774
|
const trimmedPoints = props.points.slice(-props.maxBars);
|
|
1481
|
-
const
|
|
1482
|
-
...trimmedPoints.map(
|
|
1775
|
+
const maxUsageValue = Math.max(
|
|
1776
|
+
...trimmedPoints.map(
|
|
1777
|
+
(point) => getActivityUsageValue(
|
|
1778
|
+
point,
|
|
1779
|
+
props.usageMetricKind,
|
|
1780
|
+
props.usageDimension
|
|
1781
|
+
)
|
|
1782
|
+
),
|
|
1483
1783
|
1
|
|
1484
1784
|
);
|
|
1485
|
-
return /* @__PURE__ */
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1785
|
+
return /* @__PURE__ */ jsx12("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: trimmedPoints.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: props.labels.noResults }) : /* @__PURE__ */ jsx12("div", { className: "flex min-h-48 items-end gap-2", children: trimmedPoints.map((point) => {
|
|
1786
|
+
const usageValue = getActivityUsageValue(
|
|
1787
|
+
point,
|
|
1788
|
+
props.usageMetricKind,
|
|
1789
|
+
props.usageDimension
|
|
1790
|
+
);
|
|
1791
|
+
return /* @__PURE__ */ jsxs7(
|
|
1792
|
+
"div",
|
|
1793
|
+
{
|
|
1794
|
+
className: "flex min-w-0 flex-1 flex-col items-center gap-2",
|
|
1795
|
+
children: [
|
|
1796
|
+
/* @__PURE__ */ jsx12("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ jsx12(
|
|
1797
|
+
"div",
|
|
1798
|
+
{
|
|
1799
|
+
className: "w-full rounded-md bg-primary transition-all",
|
|
1800
|
+
style: {
|
|
1801
|
+
height: `${Math.max(usageValue / maxUsageValue * 100, 8)}%`
|
|
1802
|
+
}
|
|
1496
1803
|
}
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1804
|
+
) }),
|
|
1805
|
+
/* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
|
|
1806
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium", children: formatBucket(point.bucket, props.interval) }),
|
|
1807
|
+
/* @__PURE__ */ jsx12("p", { className: "text-[11px] text-muted-foreground", children: formatMetricValue(usageValue, props.usageMetricKind) }),
|
|
1808
|
+
/* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
1809
|
+
formatNumber(point.totalCalls),
|
|
1810
|
+
" ",
|
|
1811
|
+
props.labels.usageCallsDetail
|
|
1812
|
+
] })
|
|
1504
1813
|
] })
|
|
1505
|
-
]
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
)
|
|
1814
|
+
]
|
|
1815
|
+
},
|
|
1816
|
+
point.bucket
|
|
1817
|
+
);
|
|
1818
|
+
}) }) });
|
|
1510
1819
|
}
|
|
1511
1820
|
function DataTable(props) {
|
|
1512
1821
|
return /* @__PURE__ */ jsxs7("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
|
|
1513
1822
|
/* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center justify-between gap-3", children: [
|
|
1514
|
-
/* @__PURE__ */
|
|
1515
|
-
/* @__PURE__ */
|
|
1823
|
+
/* @__PURE__ */ jsx12(SectionHeading, { title: props.title }),
|
|
1824
|
+
/* @__PURE__ */ jsx12(
|
|
1516
1825
|
Input,
|
|
1517
1826
|
{
|
|
1518
1827
|
className: "h-8 w-full max-w-44",
|
|
@@ -1522,7 +1831,7 @@ function DataTable(props) {
|
|
|
1522
1831
|
}
|
|
1523
1832
|
)
|
|
1524
1833
|
] }),
|
|
1525
|
-
props.rows.length === 0 ? /* @__PURE__ */
|
|
1834
|
+
props.rows.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: "No results" }) : props.children
|
|
1526
1835
|
] });
|
|
1527
1836
|
}
|
|
1528
1837
|
function ThreadsTable({
|
|
@@ -1530,7 +1839,7 @@ function ThreadsTable({
|
|
|
1530
1839
|
labels,
|
|
1531
1840
|
onThreadClick
|
|
1532
1841
|
}) {
|
|
1533
|
-
return /* @__PURE__ */
|
|
1842
|
+
return /* @__PURE__ */ jsx12("div", { className: "space-y-3", children: rows.map((thread) => /* @__PURE__ */ jsxs7(
|
|
1534
1843
|
"div",
|
|
1535
1844
|
{
|
|
1536
1845
|
className: cn(
|
|
@@ -1541,10 +1850,10 @@ function ThreadsTable({
|
|
|
1541
1850
|
children: [
|
|
1542
1851
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1543
1852
|
/* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
1544
|
-
/* @__PURE__ */
|
|
1545
|
-
/* @__PURE__ */
|
|
1853
|
+
/* @__PURE__ */ jsx12("p", { className: "font-medium", children: thread.name }),
|
|
1854
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
|
|
1546
1855
|
] }),
|
|
1547
|
-
/* @__PURE__ */
|
|
1856
|
+
/* @__PURE__ */ jsx12(
|
|
1548
1857
|
Badge,
|
|
1549
1858
|
{
|
|
1550
1859
|
variant: thread.status === "archived" ? "secondary" : "default",
|
|
@@ -1561,7 +1870,7 @@ function ThreadsTable({
|
|
|
1561
1870
|
thread.participantIds.length,
|
|
1562
1871
|
" participants"
|
|
1563
1872
|
] }),
|
|
1564
|
-
/* @__PURE__ */
|
|
1873
|
+
/* @__PURE__ */ jsx12("span", { children: formatDate(thread.lastActivityAt) })
|
|
1565
1874
|
] })
|
|
1566
1875
|
]
|
|
1567
1876
|
},
|
|
@@ -1572,17 +1881,17 @@ function ParticipantsTable({
|
|
|
1572
1881
|
rows,
|
|
1573
1882
|
labels
|
|
1574
1883
|
}) {
|
|
1575
|
-
return /* @__PURE__ */
|
|
1884
|
+
return /* @__PURE__ */ jsx12("div", { className: "space-y-3", children: rows.map((participant) => /* @__PURE__ */ jsxs7(
|
|
1576
1885
|
"div",
|
|
1577
1886
|
{
|
|
1578
1887
|
className: "rounded-lg border bg-muted/50 p-4",
|
|
1579
1888
|
children: [
|
|
1580
1889
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1581
1890
|
/* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
1582
|
-
/* @__PURE__ */
|
|
1583
|
-
/* @__PURE__ */
|
|
1891
|
+
/* @__PURE__ */ jsx12("p", { className: "font-medium", children: participant.displayName }),
|
|
1892
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-1 text-xs uppercase tracking-[0.18em] text-muted-foreground", children: participant.participantType })
|
|
1584
1893
|
] }),
|
|
1585
|
-
/* @__PURE__ */
|
|
1894
|
+
/* @__PURE__ */ jsx12(Badge, { variant: "outline", children: participant.isGlobal ? labels.scopeGlobal : labels.scopeScoped })
|
|
1586
1895
|
] }),
|
|
1587
1896
|
/* @__PURE__ */ jsxs7("div", { className: "mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground", children: [
|
|
1588
1897
|
/* @__PURE__ */ jsxs7("span", { children: [
|
|
@@ -1593,7 +1902,7 @@ function ParticipantsTable({
|
|
|
1593
1902
|
formatNumber(participant.threadCount),
|
|
1594
1903
|
" threads"
|
|
1595
1904
|
] }),
|
|
1596
|
-
/* @__PURE__ */
|
|
1905
|
+
/* @__PURE__ */ jsx12("span", { children: formatDate(participant.lastActivityAt) })
|
|
1597
1906
|
] })
|
|
1598
1907
|
]
|
|
1599
1908
|
},
|
|
@@ -1602,38 +1911,46 @@ function ParticipantsTable({
|
|
|
1602
1911
|
}
|
|
1603
1912
|
function AgentsTable({
|
|
1604
1913
|
rows,
|
|
1605
|
-
labels
|
|
1914
|
+
labels,
|
|
1915
|
+
usageMetricKind,
|
|
1916
|
+
usageDimension
|
|
1606
1917
|
}) {
|
|
1607
|
-
return /* @__PURE__ */
|
|
1918
|
+
return /* @__PURE__ */ jsx12("div", { className: "space-y-3", children: rows.map((agent) => /* @__PURE__ */ jsxs7(
|
|
1608
1919
|
"div",
|
|
1609
1920
|
{
|
|
1610
1921
|
className: "rounded-lg border bg-muted/50 p-4",
|
|
1611
1922
|
children: [
|
|
1612
1923
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1613
1924
|
/* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
1614
|
-
/* @__PURE__ */
|
|
1615
|
-
/* @__PURE__ */
|
|
1925
|
+
/* @__PURE__ */ jsx12("p", { className: "font-medium", children: agent.displayName }),
|
|
1926
|
+
/* @__PURE__ */ jsx12("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
|
|
1616
1927
|
] }),
|
|
1617
|
-
/* @__PURE__ */
|
|
1928
|
+
/* @__PURE__ */ jsx12(Badge, { variant: "outline", children: agent.isConfigured ? labels.configured : labels.unconfigured })
|
|
1618
1929
|
] }),
|
|
1619
|
-
/* @__PURE__ */
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1930
|
+
/* @__PURE__ */ jsx12("div", { className: "mt-3 grid grid-cols-2 gap-2 text-xs", children: [
|
|
1931
|
+
{
|
|
1932
|
+
label: "Messages",
|
|
1933
|
+
value: formatNumber(agent.messageCount)
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
label: "LLM calls",
|
|
1937
|
+
value: formatNumber(agent.llmCallCount)
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
label: "Tool calls",
|
|
1941
|
+
value: formatNumber(agent.toolCallMessageCount)
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
label: getUsageSummaryLabel(labels, usageMetricKind, usageDimension),
|
|
1945
|
+
value: formatMetricValue(
|
|
1946
|
+
getAgentUsageValue(agent, usageMetricKind, usageDimension),
|
|
1947
|
+
usageMetricKind
|
|
1948
|
+
)
|
|
1949
|
+
}
|
|
1950
|
+
].map((item) => /* @__PURE__ */ jsxs7("div", { children: [
|
|
1951
|
+
/* @__PURE__ */ jsx12("p", { className: "font-medium text-foreground", children: item.value }),
|
|
1952
|
+
/* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: item.label })
|
|
1953
|
+
] }, item.label)) })
|
|
1637
1954
|
]
|
|
1638
1955
|
},
|
|
1639
1956
|
`${agent.namespace}:${agent.agentId}`
|
|
@@ -1665,10 +1982,155 @@ function formatDate(value) {
|
|
|
1665
1982
|
function formatNumber(value) {
|
|
1666
1983
|
return new Intl.NumberFormat().format(value);
|
|
1667
1984
|
}
|
|
1985
|
+
var USAGE_DIMENSIONS = [
|
|
1986
|
+
"total",
|
|
1987
|
+
"input",
|
|
1988
|
+
"output",
|
|
1989
|
+
"reasoning",
|
|
1990
|
+
"cacheRead",
|
|
1991
|
+
"cacheWrite"
|
|
1992
|
+
];
|
|
1993
|
+
function getUsageDimensionLabel(labels, dimension) {
|
|
1994
|
+
switch (dimension) {
|
|
1995
|
+
case "input":
|
|
1996
|
+
return labels.usageInput;
|
|
1997
|
+
case "output":
|
|
1998
|
+
return labels.usageOutput;
|
|
1999
|
+
case "reasoning":
|
|
2000
|
+
return labels.usageReasoning;
|
|
2001
|
+
case "cacheRead":
|
|
2002
|
+
return labels.usageCacheRead;
|
|
2003
|
+
case "cacheWrite":
|
|
2004
|
+
return labels.usageCacheWrite;
|
|
2005
|
+
case "total":
|
|
2006
|
+
default:
|
|
2007
|
+
return labels.usageTotal;
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
function getUsageSummaryLabel(labels, metricKind, dimension) {
|
|
2011
|
+
const metricLabel = metricKind === "cost" ? labels.usageMetricCost : labels.usageMetricTokens;
|
|
2012
|
+
return `${getUsageDimensionLabel(labels, dimension)} ${metricLabel}`;
|
|
2013
|
+
}
|
|
2014
|
+
function getOverviewUsageValue(overview, metricKind, dimension) {
|
|
2015
|
+
const llmTotals = overview.llmTotals;
|
|
2016
|
+
if (metricKind === "cost") {
|
|
2017
|
+
switch (dimension) {
|
|
2018
|
+
case "input":
|
|
2019
|
+
return llmTotals.inputCostUsd;
|
|
2020
|
+
case "output":
|
|
2021
|
+
return llmTotals.outputCostUsd;
|
|
2022
|
+
case "reasoning":
|
|
2023
|
+
return llmTotals.reasoningCostUsd;
|
|
2024
|
+
case "cacheRead":
|
|
2025
|
+
return llmTotals.cacheReadInputCostUsd;
|
|
2026
|
+
case "cacheWrite":
|
|
2027
|
+
return llmTotals.cacheCreationInputCostUsd;
|
|
2028
|
+
case "total":
|
|
2029
|
+
default:
|
|
2030
|
+
return llmTotals.totalCostUsd;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
switch (dimension) {
|
|
2034
|
+
case "input":
|
|
2035
|
+
return llmTotals.inputTokens;
|
|
2036
|
+
case "output":
|
|
2037
|
+
return llmTotals.outputTokens;
|
|
2038
|
+
case "reasoning":
|
|
2039
|
+
return llmTotals.reasoningTokens;
|
|
2040
|
+
case "cacheRead":
|
|
2041
|
+
return llmTotals.cacheReadInputTokens;
|
|
2042
|
+
case "cacheWrite":
|
|
2043
|
+
return llmTotals.cacheCreationInputTokens;
|
|
2044
|
+
case "total":
|
|
2045
|
+
default:
|
|
2046
|
+
return llmTotals.totalTokens;
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
function getAgentUsageValue(agent, metricKind, dimension) {
|
|
2050
|
+
if (metricKind === "cost") {
|
|
2051
|
+
switch (dimension) {
|
|
2052
|
+
case "input":
|
|
2053
|
+
return agent.inputCostUsd;
|
|
2054
|
+
case "output":
|
|
2055
|
+
return agent.outputCostUsd;
|
|
2056
|
+
case "reasoning":
|
|
2057
|
+
return agent.reasoningCostUsd;
|
|
2058
|
+
case "cacheRead":
|
|
2059
|
+
return agent.cacheReadInputCostUsd;
|
|
2060
|
+
case "cacheWrite":
|
|
2061
|
+
return agent.cacheCreationInputCostUsd;
|
|
2062
|
+
case "total":
|
|
2063
|
+
default:
|
|
2064
|
+
return agent.totalCostUsd;
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
switch (dimension) {
|
|
2068
|
+
case "input":
|
|
2069
|
+
return agent.inputTokens;
|
|
2070
|
+
case "output":
|
|
2071
|
+
return agent.outputTokens;
|
|
2072
|
+
case "reasoning":
|
|
2073
|
+
return agent.reasoningTokens;
|
|
2074
|
+
case "cacheRead":
|
|
2075
|
+
return agent.cacheReadInputTokens;
|
|
2076
|
+
case "cacheWrite":
|
|
2077
|
+
return agent.cacheCreationInputTokens;
|
|
2078
|
+
case "total":
|
|
2079
|
+
default:
|
|
2080
|
+
return agent.totalTokens;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
function getActivityUsageValue(point, metricKind, dimension) {
|
|
2084
|
+
if (metricKind === "cost") {
|
|
2085
|
+
switch (dimension) {
|
|
2086
|
+
case "input":
|
|
2087
|
+
return point.inputCostUsd;
|
|
2088
|
+
case "output":
|
|
2089
|
+
return point.outputCostUsd;
|
|
2090
|
+
case "reasoning":
|
|
2091
|
+
return point.reasoningCostUsd;
|
|
2092
|
+
case "cacheRead":
|
|
2093
|
+
return point.cacheReadInputCostUsd;
|
|
2094
|
+
case "cacheWrite":
|
|
2095
|
+
return point.cacheCreationInputCostUsd;
|
|
2096
|
+
case "total":
|
|
2097
|
+
default:
|
|
2098
|
+
return point.totalCostUsd;
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
switch (dimension) {
|
|
2102
|
+
case "input":
|
|
2103
|
+
return point.inputTokens;
|
|
2104
|
+
case "output":
|
|
2105
|
+
return point.outputTokens;
|
|
2106
|
+
case "reasoning":
|
|
2107
|
+
return point.reasoningTokens;
|
|
2108
|
+
case "cacheRead":
|
|
2109
|
+
return point.cacheReadInputTokens;
|
|
2110
|
+
case "cacheWrite":
|
|
2111
|
+
return point.cacheCreationInputTokens;
|
|
2112
|
+
case "total":
|
|
2113
|
+
default:
|
|
2114
|
+
return point.totalTokens;
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
function formatMetricValue(value, metricKind) {
|
|
2118
|
+
if (metricKind === "cost") {
|
|
2119
|
+
const absoluteValue = Math.abs(value);
|
|
2120
|
+
const maximumFractionDigits = absoluteValue >= 1 ? 2 : absoluteValue >= 0.01 ? 4 : 6;
|
|
2121
|
+
return new Intl.NumberFormat(void 0, {
|
|
2122
|
+
style: "currency",
|
|
2123
|
+
currency: "USD",
|
|
2124
|
+
minimumFractionDigits: 2,
|
|
2125
|
+
maximumFractionDigits
|
|
2126
|
+
}).format(value);
|
|
2127
|
+
}
|
|
2128
|
+
return formatNumber(value);
|
|
2129
|
+
}
|
|
1668
2130
|
|
|
1669
2131
|
// src/components/views/ThreadsView.tsx
|
|
1670
2132
|
import { Search, MessageSquare as MessageSquare2 } from "lucide-react";
|
|
1671
|
-
import { jsx as
|
|
2133
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1672
2134
|
var ThreadsView = ({
|
|
1673
2135
|
config,
|
|
1674
2136
|
threads,
|
|
@@ -1678,8 +2140,8 @@ var ThreadsView = ({
|
|
|
1678
2140
|
}) => {
|
|
1679
2141
|
return /* @__PURE__ */ jsxs8("div", { className: "space-y-4", children: [
|
|
1680
2142
|
/* @__PURE__ */ jsxs8("div", { className: "relative max-w-sm", children: [
|
|
1681
|
-
/* @__PURE__ */
|
|
1682
|
-
/* @__PURE__ */
|
|
2143
|
+
/* @__PURE__ */ jsx13(Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2144
|
+
/* @__PURE__ */ jsx13(
|
|
1683
2145
|
Input,
|
|
1684
2146
|
{
|
|
1685
2147
|
className: "pl-9",
|
|
@@ -1690,9 +2152,9 @@ var ThreadsView = ({
|
|
|
1690
2152
|
)
|
|
1691
2153
|
] }),
|
|
1692
2154
|
threads.length === 0 ? /* @__PURE__ */ jsxs8("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
1693
|
-
/* @__PURE__ */
|
|
1694
|
-
/* @__PURE__ */
|
|
1695
|
-
] }) : /* @__PURE__ */
|
|
2155
|
+
/* @__PURE__ */ jsx13(MessageSquare2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
2156
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
2157
|
+
] }) : /* @__PURE__ */ jsx13("div", { className: "space-y-2", children: threads.map((thread) => /* @__PURE__ */ jsxs8(
|
|
1696
2158
|
"div",
|
|
1697
2159
|
{
|
|
1698
2160
|
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
@@ -1700,8 +2162,8 @@ var ThreadsView = ({
|
|
|
1700
2162
|
children: [
|
|
1701
2163
|
/* @__PURE__ */ jsxs8("div", { className: "flex-1 min-w-0", children: [
|
|
1702
2164
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
1703
|
-
/* @__PURE__ */
|
|
1704
|
-
/* @__PURE__ */
|
|
2165
|
+
/* @__PURE__ */ jsx13("p", { className: "font-medium truncate", children: thread.name }),
|
|
2166
|
+
/* @__PURE__ */ jsx13(
|
|
1705
2167
|
Badge,
|
|
1706
2168
|
{
|
|
1707
2169
|
variant: thread.status === "archived" ? "secondary" : "default",
|
|
@@ -1710,7 +2172,7 @@ var ThreadsView = ({
|
|
|
1710
2172
|
}
|
|
1711
2173
|
)
|
|
1712
2174
|
] }),
|
|
1713
|
-
/* @__PURE__ */
|
|
2175
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-1 text-sm text-muted-foreground truncate", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
|
|
1714
2176
|
] }),
|
|
1715
2177
|
/* @__PURE__ */ jsxs8("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
|
|
1716
2178
|
/* @__PURE__ */ jsxs8("p", { children: [
|
|
@@ -1721,7 +2183,7 @@ var ThreadsView = ({
|
|
|
1721
2183
|
thread.participantIds.length,
|
|
1722
2184
|
" participants"
|
|
1723
2185
|
] }),
|
|
1724
|
-
/* @__PURE__ */
|
|
2186
|
+
/* @__PURE__ */ jsx13("p", { children: formatDate2(thread.lastActivityAt) })
|
|
1725
2187
|
] })
|
|
1726
2188
|
]
|
|
1727
2189
|
},
|
|
@@ -1755,7 +2217,7 @@ import {
|
|
|
1755
2217
|
Wrench,
|
|
1756
2218
|
Cpu
|
|
1757
2219
|
} from "lucide-react";
|
|
1758
|
-
import { jsx as
|
|
2220
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1759
2221
|
var MESSAGES_PAGE_SIZE = 50;
|
|
1760
2222
|
var ThreadDetailView = ({
|
|
1761
2223
|
threadId,
|
|
@@ -1813,36 +2275,36 @@ var ThreadDetailView = ({
|
|
|
1813
2275
|
}
|
|
1814
2276
|
}, [threadId, pageInfo, isLoadingMore, config.baseUrl, config.getRequestHeaders]);
|
|
1815
2277
|
if (isLoading) {
|
|
1816
|
-
return /* @__PURE__ */
|
|
2278
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx14(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
1817
2279
|
}
|
|
1818
2280
|
if (error) {
|
|
1819
2281
|
return /* @__PURE__ */ jsxs9("div", { className: "space-y-4 py-10 text-center", children: [
|
|
1820
|
-
/* @__PURE__ */
|
|
2282
|
+
/* @__PURE__ */ jsx14("p", { className: "text-destructive font-medium", children: error.message }),
|
|
1821
2283
|
/* @__PURE__ */ jsxs9("div", { className: "flex justify-center gap-2", children: [
|
|
1822
2284
|
/* @__PURE__ */ jsxs9(Button, { variant: "outline", onClick: onBack, children: [
|
|
1823
|
-
/* @__PURE__ */
|
|
2285
|
+
/* @__PURE__ */ jsx14(ArrowLeft, { className: "mr-2 h-4 w-4" }),
|
|
1824
2286
|
"Back"
|
|
1825
2287
|
] }),
|
|
1826
|
-
/* @__PURE__ */
|
|
2288
|
+
/* @__PURE__ */ jsx14(Button, { variant: "destructive", onClick: () => void loadInitial(), children: config.labels.retry })
|
|
1827
2289
|
] })
|
|
1828
2290
|
] });
|
|
1829
2291
|
}
|
|
1830
2292
|
return /* @__PURE__ */ jsxs9("div", { className: "space-y-6", children: [
|
|
1831
2293
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-4", children: [
|
|
1832
|
-
/* @__PURE__ */
|
|
2294
|
+
/* @__PURE__ */ jsx14(
|
|
1833
2295
|
Button,
|
|
1834
2296
|
{
|
|
1835
2297
|
variant: "ghost",
|
|
1836
2298
|
size: "icon",
|
|
1837
2299
|
className: "mt-1 shrink-0",
|
|
1838
2300
|
onClick: onBack,
|
|
1839
|
-
children: /* @__PURE__ */
|
|
2301
|
+
children: /* @__PURE__ */ jsx14(ArrowLeft, { className: "h-4 w-4" })
|
|
1840
2302
|
}
|
|
1841
2303
|
),
|
|
1842
2304
|
/* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
|
|
1843
2305
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
1844
|
-
/* @__PURE__ */
|
|
1845
|
-
/* @__PURE__ */
|
|
2306
|
+
/* @__PURE__ */ jsx14("h2", { className: "text-xl font-semibold truncate", children: thread?.name ?? threadId }),
|
|
2307
|
+
/* @__PURE__ */ jsx14(
|
|
1846
2308
|
Badge,
|
|
1847
2309
|
{
|
|
1848
2310
|
variant: thread?.status === "archived" ? "secondary" : "default",
|
|
@@ -1850,7 +2312,7 @@ var ThreadDetailView = ({
|
|
|
1850
2312
|
}
|
|
1851
2313
|
)
|
|
1852
2314
|
] }),
|
|
1853
|
-
thread?.summary && /* @__PURE__ */
|
|
2315
|
+
thread?.summary && /* @__PURE__ */ jsx14("p", { className: "mt-1 text-sm text-muted-foreground", children: thread.summary }),
|
|
1854
2316
|
/* @__PURE__ */ jsxs9("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
|
|
1855
2317
|
thread?.createdAt && /* @__PURE__ */ jsxs9("span", { children: [
|
|
1856
2318
|
"Created ",
|
|
@@ -1868,13 +2330,13 @@ var ThreadDetailView = ({
|
|
|
1868
2330
|
] })
|
|
1869
2331
|
] }),
|
|
1870
2332
|
/* @__PURE__ */ jsxs9("div", { className: "space-y-1", children: [
|
|
1871
|
-
/* @__PURE__ */
|
|
2333
|
+
/* @__PURE__ */ jsx14("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs9("h3", { className: "text-sm font-medium text-muted-foreground", children: [
|
|
1872
2334
|
"Messages (",
|
|
1873
2335
|
messages.length,
|
|
1874
2336
|
pageInfo?.hasMoreBefore ? "+" : "",
|
|
1875
2337
|
")"
|
|
1876
2338
|
] }) }),
|
|
1877
|
-
pageInfo?.hasMoreBefore && /* @__PURE__ */
|
|
2339
|
+
pageInfo?.hasMoreBefore && /* @__PURE__ */ jsx14("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsxs9(
|
|
1878
2340
|
Button,
|
|
1879
2341
|
{
|
|
1880
2342
|
variant: "ghost",
|
|
@@ -1882,12 +2344,12 @@ var ThreadDetailView = ({
|
|
|
1882
2344
|
onClick: () => void loadMore(),
|
|
1883
2345
|
disabled: isLoadingMore,
|
|
1884
2346
|
children: [
|
|
1885
|
-
isLoadingMore ? /* @__PURE__ */
|
|
2347
|
+
isLoadingMore ? /* @__PURE__ */ jsx14(Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx14(ChevronUp2, { className: "mr-2 h-3 w-3" }),
|
|
1886
2348
|
"Load older messages"
|
|
1887
2349
|
]
|
|
1888
2350
|
}
|
|
1889
2351
|
) }),
|
|
1890
|
-
/* @__PURE__ */
|
|
2352
|
+
/* @__PURE__ */ jsx14("div", { className: "rounded-lg border bg-card", children: messages.length === 0 ? /* @__PURE__ */ jsx14("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No messages in this thread yet." }) : /* @__PURE__ */ jsx14("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ jsx14(MessageRow, { message }, message.id)) }) })
|
|
1891
2353
|
] })
|
|
1892
2354
|
] });
|
|
1893
2355
|
};
|
|
@@ -1895,15 +2357,15 @@ function MessageRow({ message }) {
|
|
|
1895
2357
|
const [expanded, setExpanded] = useState4(false);
|
|
1896
2358
|
const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
|
|
1897
2359
|
const hasReasoning = !!message.reasoning;
|
|
1898
|
-
return /* @__PURE__ */
|
|
1899
|
-
/* @__PURE__ */
|
|
2360
|
+
return /* @__PURE__ */ jsx14("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-3", children: [
|
|
2361
|
+
/* @__PURE__ */ jsx14(SenderIcon, { senderType: message.senderType }),
|
|
1900
2362
|
/* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
|
|
1901
2363
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
1902
|
-
/* @__PURE__ */
|
|
1903
|
-
/* @__PURE__ */
|
|
1904
|
-
message.createdAt && /* @__PURE__ */
|
|
2364
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
|
|
2365
|
+
/* @__PURE__ */ jsx14(Badge, { variant: "outline", className: "text-[10px] px-1.5 py-0", children: message.senderType }),
|
|
2366
|
+
message.createdAt && /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: formatTimestamp(message.createdAt) })
|
|
1905
2367
|
] }),
|
|
1906
|
-
message.content && /* @__PURE__ */
|
|
2368
|
+
message.content && /* @__PURE__ */ jsx14("p", { className: "mt-1 text-sm whitespace-pre-wrap break-words", children: message.content }),
|
|
1907
2369
|
(hasToolCalls || hasReasoning) && /* @__PURE__ */ jsxs9("div", { className: "mt-2 space-y-2", children: [
|
|
1908
2370
|
hasToolCalls && /* @__PURE__ */ jsxs9(
|
|
1909
2371
|
"button",
|
|
@@ -1912,7 +2374,7 @@ function MessageRow({ message }) {
|
|
|
1912
2374
|
onClick: () => setExpanded(!expanded),
|
|
1913
2375
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
1914
2376
|
children: [
|
|
1915
|
-
/* @__PURE__ */
|
|
2377
|
+
/* @__PURE__ */ jsx14(Wrench, { className: "h-3 w-3" }),
|
|
1916
2378
|
message.toolCalls.length,
|
|
1917
2379
|
" tool call",
|
|
1918
2380
|
message.toolCalls.length > 1 ? "s" : ""
|
|
@@ -1926,12 +2388,12 @@ function MessageRow({ message }) {
|
|
|
1926
2388
|
onClick: () => setExpanded(!expanded),
|
|
1927
2389
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
1928
2390
|
children: [
|
|
1929
|
-
/* @__PURE__ */
|
|
2391
|
+
/* @__PURE__ */ jsx14(Cpu, { className: "h-3 w-3" }),
|
|
1930
2392
|
"Reasoning"
|
|
1931
2393
|
]
|
|
1932
2394
|
}
|
|
1933
2395
|
),
|
|
1934
|
-
expanded && /* @__PURE__ */
|
|
2396
|
+
expanded && /* @__PURE__ */ jsx14("pre", { className: "mt-2 rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(
|
|
1935
2397
|
{
|
|
1936
2398
|
...hasToolCalls ? { toolCalls: message.toolCalls } : {},
|
|
1937
2399
|
...hasReasoning ? { reasoning: message.reasoning } : {}
|
|
@@ -1947,13 +2409,13 @@ function SenderIcon({ senderType }) {
|
|
|
1947
2409
|
const base = "flex h-7 w-7 shrink-0 items-center justify-center rounded-full";
|
|
1948
2410
|
switch (senderType) {
|
|
1949
2411
|
case "agent":
|
|
1950
|
-
return /* @__PURE__ */
|
|
2412
|
+
return /* @__PURE__ */ jsx14("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ jsx14(Bot2, { className: "h-3.5 w-3.5" }) });
|
|
1951
2413
|
case "user":
|
|
1952
|
-
return /* @__PURE__ */
|
|
2414
|
+
return /* @__PURE__ */ jsx14("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ jsx14(User, { className: "h-3.5 w-3.5" }) });
|
|
1953
2415
|
case "tool":
|
|
1954
|
-
return /* @__PURE__ */
|
|
2416
|
+
return /* @__PURE__ */ jsx14("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx14(Wrench, { className: "h-3.5 w-3.5" }) });
|
|
1955
2417
|
default:
|
|
1956
|
-
return /* @__PURE__ */
|
|
2418
|
+
return /* @__PURE__ */ jsx14("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx14(Cpu, { className: "h-3.5 w-3.5" }) });
|
|
1957
2419
|
}
|
|
1958
2420
|
}
|
|
1959
2421
|
function formatDate3(value) {
|
|
@@ -1977,8 +2439,634 @@ function formatTimestamp(value) {
|
|
|
1977
2439
|
});
|
|
1978
2440
|
}
|
|
1979
2441
|
|
|
2442
|
+
// src/components/views/ParticipantsView.tsx
|
|
2443
|
+
import { Search as Search2, Users as Users2 } from "lucide-react";
|
|
2444
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2445
|
+
var ParticipantsView = ({
|
|
2446
|
+
config,
|
|
2447
|
+
participants,
|
|
2448
|
+
searchValue,
|
|
2449
|
+
onSearchChange,
|
|
2450
|
+
onParticipantClick
|
|
2451
|
+
}) => {
|
|
2452
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-4", children: [
|
|
2453
|
+
/* @__PURE__ */ jsxs10("div", { className: "relative max-w-sm", children: [
|
|
2454
|
+
/* @__PURE__ */ jsx15(Search2, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2455
|
+
/* @__PURE__ */ jsx15(
|
|
2456
|
+
Input,
|
|
2457
|
+
{
|
|
2458
|
+
className: "pl-9",
|
|
2459
|
+
placeholder: config.labels.participantSearchPlaceholder,
|
|
2460
|
+
value: searchValue,
|
|
2461
|
+
onChange: (e) => onSearchChange(e.target.value)
|
|
2462
|
+
}
|
|
2463
|
+
)
|
|
2464
|
+
] }),
|
|
2465
|
+
participants.length === 0 ? /* @__PURE__ */ jsxs10("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
2466
|
+
/* @__PURE__ */ jsx15(Users2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
2467
|
+
/* @__PURE__ */ jsx15("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
2468
|
+
] }) : /* @__PURE__ */ jsx15("div", { className: "space-y-2", children: participants.map((p) => /* @__PURE__ */ jsxs10(
|
|
2469
|
+
"div",
|
|
2470
|
+
{
|
|
2471
|
+
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2472
|
+
onClick: () => onParticipantClick?.(p.externalId),
|
|
2473
|
+
children: [
|
|
2474
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
|
|
2475
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
2476
|
+
/* @__PURE__ */ jsx15("p", { className: "font-medium truncate", children: p.displayName }),
|
|
2477
|
+
/* @__PURE__ */ jsx15(Badge, { variant: "outline", className: "shrink-0 text-xs", children: p.participantType }),
|
|
2478
|
+
/* @__PURE__ */ jsx15(Badge, { variant: p.isGlobal ? "default" : "secondary", className: "shrink-0 text-xs", children: p.isGlobal ? config.labels.scopeGlobal : config.labels.scopeScoped })
|
|
2479
|
+
] }),
|
|
2480
|
+
/* @__PURE__ */ jsx15("p", { className: "mt-1 text-xs text-muted-foreground", children: p.externalId })
|
|
2481
|
+
] }),
|
|
2482
|
+
/* @__PURE__ */ jsxs10("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
|
|
2483
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
2484
|
+
formatNumber3(p.messageCount),
|
|
2485
|
+
" messages"
|
|
2486
|
+
] }),
|
|
2487
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
2488
|
+
formatNumber3(p.threadCount),
|
|
2489
|
+
" threads"
|
|
2490
|
+
] }),
|
|
2491
|
+
/* @__PURE__ */ jsx15("p", { children: formatDate4(p.lastActivityAt) })
|
|
2492
|
+
] })
|
|
2493
|
+
]
|
|
2494
|
+
},
|
|
2495
|
+
`${p.namespace}:${p.externalId}`
|
|
2496
|
+
)) })
|
|
2497
|
+
] });
|
|
2498
|
+
};
|
|
2499
|
+
function formatDate4(value) {
|
|
2500
|
+
if (!value) return "No activity";
|
|
2501
|
+
const date = new Date(value);
|
|
2502
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
2503
|
+
return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
2504
|
+
}
|
|
2505
|
+
function formatNumber3(value) {
|
|
2506
|
+
return new Intl.NumberFormat().format(value);
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
// src/components/views/ParticipantDetailView.tsx
|
|
2510
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useState as useState5 } from "react";
|
|
2511
|
+
import { ArrowLeft as ArrowLeft2, Loader2 as Loader22, Save } from "lucide-react";
|
|
2512
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2513
|
+
var ParticipantDetailView = ({
|
|
2514
|
+
participantId,
|
|
2515
|
+
config,
|
|
2516
|
+
onBack
|
|
2517
|
+
}) => {
|
|
2518
|
+
const [data, setData] = useState5(null);
|
|
2519
|
+
const [editJson, setEditJson] = useState5("");
|
|
2520
|
+
const [isLoading, setIsLoading] = useState5(true);
|
|
2521
|
+
const [isSaving, setIsSaving] = useState5(false);
|
|
2522
|
+
const [error, setError] = useState5(null);
|
|
2523
|
+
const [saveMessage, setSaveMessage] = useState5(null);
|
|
2524
|
+
const fetchOptions = {
|
|
2525
|
+
baseUrl: config.baseUrl,
|
|
2526
|
+
getRequestHeaders: config.getRequestHeaders
|
|
2527
|
+
};
|
|
2528
|
+
const load = useCallback4(async () => {
|
|
2529
|
+
setIsLoading(true);
|
|
2530
|
+
setError(null);
|
|
2531
|
+
try {
|
|
2532
|
+
const result = await fetchParticipantDetail(participantId, fetchOptions);
|
|
2533
|
+
setData(result);
|
|
2534
|
+
setEditJson(JSON.stringify(result, null, 2));
|
|
2535
|
+
} catch (err) {
|
|
2536
|
+
setError(err instanceof Error ? err.message : "Failed to load participant");
|
|
2537
|
+
} finally {
|
|
2538
|
+
setIsLoading(false);
|
|
2539
|
+
}
|
|
2540
|
+
}, [participantId, config.baseUrl, config.getRequestHeaders]);
|
|
2541
|
+
useEffect6(() => {
|
|
2542
|
+
void load();
|
|
2543
|
+
}, [load]);
|
|
2544
|
+
const handleSave = async () => {
|
|
2545
|
+
setIsSaving(true);
|
|
2546
|
+
setError(null);
|
|
2547
|
+
setSaveMessage(null);
|
|
2548
|
+
try {
|
|
2549
|
+
const parsed = JSON.parse(editJson);
|
|
2550
|
+
const updated = await updateParticipant(participantId, parsed, fetchOptions);
|
|
2551
|
+
setData(updated);
|
|
2552
|
+
setEditJson(JSON.stringify(updated, null, 2));
|
|
2553
|
+
setSaveMessage("Saved successfully");
|
|
2554
|
+
setTimeout(() => setSaveMessage(null), 3e3);
|
|
2555
|
+
} catch (err) {
|
|
2556
|
+
setError(err instanceof Error ? err.message : "Failed to save");
|
|
2557
|
+
} finally {
|
|
2558
|
+
setIsSaving(false);
|
|
2559
|
+
}
|
|
2560
|
+
};
|
|
2561
|
+
if (isLoading) {
|
|
2562
|
+
return /* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx16(Loader22, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
2563
|
+
}
|
|
2564
|
+
return /* @__PURE__ */ jsxs11("div", { className: "space-y-6", children: [
|
|
2565
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4", children: [
|
|
2566
|
+
/* @__PURE__ */ jsx16(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx16(ArrowLeft2, { className: "h-4 w-4" }) }),
|
|
2567
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex-1 min-w-0", children: [
|
|
2568
|
+
/* @__PURE__ */ jsx16("h2", { className: "text-xl font-semibold truncate", children: participantId }),
|
|
2569
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: "Participant Detail" })
|
|
2570
|
+
] }),
|
|
2571
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
2572
|
+
saveMessage && /* @__PURE__ */ jsx16("span", { className: "text-xs text-emerald-600", children: saveMessage }),
|
|
2573
|
+
/* @__PURE__ */ jsxs11(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
|
|
2574
|
+
isSaving ? /* @__PURE__ */ jsx16(Loader22, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx16(Save, { className: "mr-2 h-3 w-3" }),
|
|
2575
|
+
"Save"
|
|
2576
|
+
] })
|
|
2577
|
+
] })
|
|
2578
|
+
] }),
|
|
2579
|
+
error && /* @__PURE__ */ jsx16("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
2580
|
+
/* @__PURE__ */ jsx16("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx16(
|
|
2581
|
+
"textarea",
|
|
2582
|
+
{
|
|
2583
|
+
className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
|
|
2584
|
+
value: editJson,
|
|
2585
|
+
onChange: (e) => setEditJson(e.target.value),
|
|
2586
|
+
spellCheck: false
|
|
2587
|
+
}
|
|
2588
|
+
) })
|
|
2589
|
+
] });
|
|
2590
|
+
};
|
|
2591
|
+
|
|
2592
|
+
// src/components/views/AgentsView.tsx
|
|
2593
|
+
import { Search as Search3, Bot as Bot3 } from "lucide-react";
|
|
2594
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2595
|
+
var AgentsView = ({
|
|
2596
|
+
config,
|
|
2597
|
+
agents,
|
|
2598
|
+
searchValue,
|
|
2599
|
+
onSearchChange,
|
|
2600
|
+
onAgentClick
|
|
2601
|
+
}) => {
|
|
2602
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
|
|
2603
|
+
/* @__PURE__ */ jsxs12("div", { className: "relative max-w-sm", children: [
|
|
2604
|
+
/* @__PURE__ */ jsx17(Search3, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2605
|
+
/* @__PURE__ */ jsx17(
|
|
2606
|
+
Input,
|
|
2607
|
+
{
|
|
2608
|
+
className: "pl-9",
|
|
2609
|
+
placeholder: config.labels.agentSearchPlaceholder,
|
|
2610
|
+
value: searchValue,
|
|
2611
|
+
onChange: (e) => onSearchChange(e.target.value)
|
|
2612
|
+
}
|
|
2613
|
+
)
|
|
2614
|
+
] }),
|
|
2615
|
+
agents.length === 0 ? /* @__PURE__ */ jsxs12("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
2616
|
+
/* @__PURE__ */ jsx17(Bot3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
2617
|
+
/* @__PURE__ */ jsx17("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
2618
|
+
] }) : /* @__PURE__ */ jsx17("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: agents.map((agent) => /* @__PURE__ */ jsxs12(
|
|
2619
|
+
"div",
|
|
2620
|
+
{
|
|
2621
|
+
className: "rounded-lg border bg-card p-5 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2622
|
+
onClick: () => onAgentClick?.(agent.agentId),
|
|
2623
|
+
children: [
|
|
2624
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
|
|
2625
|
+
/* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
|
|
2626
|
+
/* @__PURE__ */ jsx17("p", { className: "font-medium truncate", children: agent.displayName }),
|
|
2627
|
+
/* @__PURE__ */ jsx17("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
|
|
2628
|
+
] }),
|
|
2629
|
+
/* @__PURE__ */ jsx17(Badge, { variant: "outline", className: "shrink-0", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
|
|
2630
|
+
] }),
|
|
2631
|
+
/* @__PURE__ */ jsxs12("div", { className: "mt-4 grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
|
|
2632
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
2633
|
+
formatNumber4(agent.messageCount),
|
|
2634
|
+
" messages"
|
|
2635
|
+
] }),
|
|
2636
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
2637
|
+
formatNumber4(agent.llmCallCount),
|
|
2638
|
+
" LLM calls"
|
|
2639
|
+
] }),
|
|
2640
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
2641
|
+
formatNumber4(agent.toolCallMessageCount),
|
|
2642
|
+
" tool calls"
|
|
2643
|
+
] }),
|
|
2644
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
2645
|
+
formatNumber4(agent.totalTokens),
|
|
2646
|
+
" tokens"
|
|
2647
|
+
] })
|
|
2648
|
+
] }),
|
|
2649
|
+
/* @__PURE__ */ jsx17("p", { className: "mt-3 text-xs text-muted-foreground", children: formatDate5(agent.lastActivityAt) })
|
|
2650
|
+
]
|
|
2651
|
+
},
|
|
2652
|
+
`${agent.namespace}:${agent.agentId}`
|
|
2653
|
+
)) })
|
|
2654
|
+
] });
|
|
2655
|
+
};
|
|
2656
|
+
function formatDate5(value) {
|
|
2657
|
+
if (!value) return "No activity";
|
|
2658
|
+
const date = new Date(value);
|
|
2659
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
2660
|
+
return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
2661
|
+
}
|
|
2662
|
+
function formatNumber4(value) {
|
|
2663
|
+
return new Intl.NumberFormat().format(value);
|
|
2664
|
+
}
|
|
2665
|
+
|
|
2666
|
+
// src/components/views/AgentDetailView.tsx
|
|
2667
|
+
import { ArrowLeft as ArrowLeft3, Bot as Bot4 } from "lucide-react";
|
|
2668
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2669
|
+
var AgentDetailView = ({
|
|
2670
|
+
agentId,
|
|
2671
|
+
config,
|
|
2672
|
+
agents,
|
|
2673
|
+
onBack
|
|
2674
|
+
}) => {
|
|
2675
|
+
const agent = agents.find((a) => a.agentId === agentId);
|
|
2676
|
+
if (!agent) {
|
|
2677
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-4 py-10 text-center", children: [
|
|
2678
|
+
/* @__PURE__ */ jsxs13("p", { className: "text-muted-foreground", children: [
|
|
2679
|
+
"Agent not found: ",
|
|
2680
|
+
agentId
|
|
2681
|
+
] }),
|
|
2682
|
+
/* @__PURE__ */ jsxs13(Button, { variant: "outline", onClick: onBack, children: [
|
|
2683
|
+
/* @__PURE__ */ jsx18(ArrowLeft3, { className: "mr-2 h-4 w-4" }),
|
|
2684
|
+
" Back"
|
|
2685
|
+
] })
|
|
2686
|
+
] });
|
|
2687
|
+
}
|
|
2688
|
+
const stats = [
|
|
2689
|
+
{ label: "Messages", value: agent.messageCount },
|
|
2690
|
+
{ label: "LLM Calls", value: agent.llmCallCount },
|
|
2691
|
+
{ label: "Tool Calls", value: agent.toolCallMessageCount },
|
|
2692
|
+
{ label: "Input Tokens", value: agent.inputTokens },
|
|
2693
|
+
{ label: "Output Tokens", value: agent.outputTokens },
|
|
2694
|
+
{ label: "Reasoning Tokens", value: agent.reasoningTokens },
|
|
2695
|
+
{ label: "Cache Read", value: agent.cacheReadInputTokens },
|
|
2696
|
+
{ label: "Cache Created", value: agent.cacheCreationInputTokens },
|
|
2697
|
+
{ label: "Total Tokens", value: agent.totalTokens }
|
|
2698
|
+
];
|
|
2699
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-6", children: [
|
|
2700
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-4", children: [
|
|
2701
|
+
/* @__PURE__ */ jsx18(Button, { variant: "ghost", size: "icon", className: "mt-1 shrink-0", onClick: onBack, children: /* @__PURE__ */ jsx18(ArrowLeft3, { className: "h-4 w-4" }) }),
|
|
2702
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
|
|
2703
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3", children: [
|
|
2704
|
+
/* @__PURE__ */ jsx18("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx18(Bot4, { className: "h-5 w-5" }) }),
|
|
2705
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
2706
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
2707
|
+
/* @__PURE__ */ jsx18("h2", { className: "text-xl font-semibold", children: agent.displayName }),
|
|
2708
|
+
/* @__PURE__ */ jsx18(Badge, { variant: "outline", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
|
|
2709
|
+
] }),
|
|
2710
|
+
agent.description && /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: agent.description })
|
|
2711
|
+
] })
|
|
2712
|
+
] }),
|
|
2713
|
+
/* @__PURE__ */ jsxs13("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
|
|
2714
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2715
|
+
"ID: ",
|
|
2716
|
+
agent.agentId
|
|
2717
|
+
] }),
|
|
2718
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2719
|
+
"Namespace: ",
|
|
2720
|
+
agent.namespace
|
|
2721
|
+
] }),
|
|
2722
|
+
agent.lastActivityAt && /* @__PURE__ */ jsxs13("span", { children: [
|
|
2723
|
+
"Last active: ",
|
|
2724
|
+
formatDate6(agent.lastActivityAt)
|
|
2725
|
+
] })
|
|
2726
|
+
] })
|
|
2727
|
+
] })
|
|
2728
|
+
] }),
|
|
2729
|
+
/* @__PURE__ */ jsx18("div", { className: "grid gap-4 sm:grid-cols-3 lg:grid-cols-3", children: stats.map((stat) => /* @__PURE__ */ jsxs13("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
|
|
2730
|
+
/* @__PURE__ */ jsx18("p", { className: "text-sm font-medium text-muted-foreground", children: stat.label }),
|
|
2731
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-2 text-2xl font-semibold tracking-tight", children: new Intl.NumberFormat().format(stat.value) })
|
|
2732
|
+
] }, stat.label)) })
|
|
2733
|
+
] });
|
|
2734
|
+
};
|
|
2735
|
+
function formatDate6(value) {
|
|
2736
|
+
const date = new Date(value);
|
|
2737
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
2738
|
+
return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
// src/components/views/CollectionItemsView.tsx
|
|
2742
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useState as useState6 } from "react";
|
|
2743
|
+
import { Loader2 as Loader23, Plus, Search as Search4, Database as Database2 } from "lucide-react";
|
|
2744
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2745
|
+
var CollectionItemsView = ({
|
|
2746
|
+
collection,
|
|
2747
|
+
config,
|
|
2748
|
+
namespace,
|
|
2749
|
+
onItemClick,
|
|
2750
|
+
onCreateNew
|
|
2751
|
+
}) => {
|
|
2752
|
+
const [items, setItems] = useState6([]);
|
|
2753
|
+
const [isLoading, setIsLoading] = useState6(true);
|
|
2754
|
+
const [search, setSearch] = useState6("");
|
|
2755
|
+
const [error, setError] = useState6(null);
|
|
2756
|
+
const fetchOptions = {
|
|
2757
|
+
baseUrl: config.baseUrl,
|
|
2758
|
+
getRequestHeaders: config.getRequestHeaders
|
|
2759
|
+
};
|
|
2760
|
+
const load = useCallback5(async () => {
|
|
2761
|
+
setIsLoading(true);
|
|
2762
|
+
setError(null);
|
|
2763
|
+
try {
|
|
2764
|
+
const result = await fetchCollectionItems(
|
|
2765
|
+
collection,
|
|
2766
|
+
{ search: search || void 0, namespace, limit: 50 },
|
|
2767
|
+
fetchOptions
|
|
2768
|
+
);
|
|
2769
|
+
setItems(result);
|
|
2770
|
+
} catch (err) {
|
|
2771
|
+
setError(err instanceof Error ? err.message : "Failed to load items");
|
|
2772
|
+
} finally {
|
|
2773
|
+
setIsLoading(false);
|
|
2774
|
+
}
|
|
2775
|
+
}, [collection, search, namespace, config.baseUrl, config.getRequestHeaders]);
|
|
2776
|
+
useEffect7(() => {
|
|
2777
|
+
void load();
|
|
2778
|
+
}, [load]);
|
|
2779
|
+
const getItemId = (item) => {
|
|
2780
|
+
return String(item.id ?? item._id ?? JSON.stringify(item).slice(0, 40));
|
|
2781
|
+
};
|
|
2782
|
+
const getItemPreview = (item) => {
|
|
2783
|
+
const { id, _id, ...rest } = item;
|
|
2784
|
+
const name = item.name ?? item.title ?? item.displayName ?? item.label;
|
|
2785
|
+
if (typeof name === "string") return name;
|
|
2786
|
+
const keys = Object.keys(rest);
|
|
2787
|
+
if (keys.length === 0) return "(empty)";
|
|
2788
|
+
return keys.slice(0, 3).map((k) => `${k}: ${JSON.stringify(rest[k])?.slice(0, 30)}`).join(", ");
|
|
2789
|
+
};
|
|
2790
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
|
|
2791
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between gap-4", children: [
|
|
2792
|
+
/* @__PURE__ */ jsx19("h2", { className: "text-lg font-semibold capitalize", children: collection }),
|
|
2793
|
+
onCreateNew && /* @__PURE__ */ jsxs14(Button, { size: "sm", onClick: onCreateNew, children: [
|
|
2794
|
+
/* @__PURE__ */ jsx19(Plus, { className: "mr-2 h-3 w-3" }),
|
|
2795
|
+
" New"
|
|
2796
|
+
] })
|
|
2797
|
+
] }),
|
|
2798
|
+
/* @__PURE__ */ jsxs14("div", { className: "relative max-w-sm", children: [
|
|
2799
|
+
/* @__PURE__ */ jsx19(Search4, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2800
|
+
/* @__PURE__ */ jsx19(
|
|
2801
|
+
Input,
|
|
2802
|
+
{
|
|
2803
|
+
className: "pl-9",
|
|
2804
|
+
placeholder: `Search ${collection}...`,
|
|
2805
|
+
value: search,
|
|
2806
|
+
onChange: (e) => setSearch(e.target.value)
|
|
2807
|
+
}
|
|
2808
|
+
)
|
|
2809
|
+
] }),
|
|
2810
|
+
error && /* @__PURE__ */ jsx19("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
2811
|
+
isLoading ? /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx19(Loader23, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
2812
|
+
/* @__PURE__ */ jsx19(Database2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
2813
|
+
/* @__PURE__ */ jsx19("p", { className: "mt-3 text-sm text-muted-foreground", children: search ? config.labels.noResults : `No items in ${collection}` })
|
|
2814
|
+
] }) : /* @__PURE__ */ jsx19("div", { className: "space-y-2", children: items.map((item, idx) => {
|
|
2815
|
+
const itemId = getItemId(item);
|
|
2816
|
+
return /* @__PURE__ */ jsx19(
|
|
2817
|
+
"div",
|
|
2818
|
+
{
|
|
2819
|
+
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2820
|
+
onClick: () => onItemClick?.(itemId),
|
|
2821
|
+
children: /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
|
|
2822
|
+
/* @__PURE__ */ jsx19("p", { className: "font-medium font-mono text-sm truncate", children: itemId }),
|
|
2823
|
+
/* @__PURE__ */ jsx19("p", { className: "mt-1 text-xs text-muted-foreground truncate", children: getItemPreview(item) })
|
|
2824
|
+
] })
|
|
2825
|
+
},
|
|
2826
|
+
itemId + idx
|
|
2827
|
+
);
|
|
2828
|
+
}) })
|
|
2829
|
+
] });
|
|
2830
|
+
};
|
|
2831
|
+
|
|
2832
|
+
// src/components/views/CollectionItemDetailView.tsx
|
|
2833
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useState as useState7 } from "react";
|
|
2834
|
+
import { ArrowLeft as ArrowLeft5, Loader2 as Loader24, Save as Save2, Trash2 } from "lucide-react";
|
|
2835
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2836
|
+
var CollectionItemDetailView = ({
|
|
2837
|
+
collection,
|
|
2838
|
+
itemId,
|
|
2839
|
+
config,
|
|
2840
|
+
namespace,
|
|
2841
|
+
onBack,
|
|
2842
|
+
onDeleted
|
|
2843
|
+
}) => {
|
|
2844
|
+
const isNew = !itemId;
|
|
2845
|
+
const [editJson, setEditJson] = useState7(isNew ? "{\n \n}" : "");
|
|
2846
|
+
const [isLoading, setIsLoading] = useState7(!isNew);
|
|
2847
|
+
const [isSaving, setIsSaving] = useState7(false);
|
|
2848
|
+
const [isDeleting, setIsDeleting] = useState7(false);
|
|
2849
|
+
const [error, setError] = useState7(null);
|
|
2850
|
+
const [saveMessage, setSaveMessage] = useState7(null);
|
|
2851
|
+
const fetchOptions = {
|
|
2852
|
+
baseUrl: config.baseUrl,
|
|
2853
|
+
getRequestHeaders: config.getRequestHeaders
|
|
2854
|
+
};
|
|
2855
|
+
const load = useCallback6(async () => {
|
|
2856
|
+
if (!itemId) return;
|
|
2857
|
+
setIsLoading(true);
|
|
2858
|
+
setError(null);
|
|
2859
|
+
try {
|
|
2860
|
+
const result = await fetchCollectionItem(collection, itemId, namespace, fetchOptions);
|
|
2861
|
+
setEditJson(JSON.stringify(result, null, 2));
|
|
2862
|
+
} catch (err) {
|
|
2863
|
+
setError(err instanceof Error ? err.message : "Failed to load item");
|
|
2864
|
+
} finally {
|
|
2865
|
+
setIsLoading(false);
|
|
2866
|
+
}
|
|
2867
|
+
}, [collection, itemId, namespace, config.baseUrl, config.getRequestHeaders]);
|
|
2868
|
+
useEffect8(() => {
|
|
2869
|
+
void load();
|
|
2870
|
+
}, [load]);
|
|
2871
|
+
const handleSave = async () => {
|
|
2872
|
+
setIsSaving(true);
|
|
2873
|
+
setError(null);
|
|
2874
|
+
setSaveMessage(null);
|
|
2875
|
+
try {
|
|
2876
|
+
const parsed = JSON.parse(editJson);
|
|
2877
|
+
if (isNew) {
|
|
2878
|
+
const created = await createCollectionItem(collection, parsed, namespace, fetchOptions);
|
|
2879
|
+
setEditJson(JSON.stringify(created, null, 2));
|
|
2880
|
+
setSaveMessage("Created successfully");
|
|
2881
|
+
} else {
|
|
2882
|
+
const updated = await updateCollectionItem(collection, itemId, parsed, namespace, fetchOptions);
|
|
2883
|
+
setEditJson(JSON.stringify(updated, null, 2));
|
|
2884
|
+
setSaveMessage("Saved successfully");
|
|
2885
|
+
}
|
|
2886
|
+
setTimeout(() => setSaveMessage(null), 3e3);
|
|
2887
|
+
} catch (err) {
|
|
2888
|
+
setError(err instanceof Error ? err.message : "Failed to save");
|
|
2889
|
+
} finally {
|
|
2890
|
+
setIsSaving(false);
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
const handleDelete = async () => {
|
|
2894
|
+
if (!itemId) return;
|
|
2895
|
+
if (!window.confirm(`Delete this item from ${collection}?`)) return;
|
|
2896
|
+
setIsDeleting(true);
|
|
2897
|
+
setError(null);
|
|
2898
|
+
try {
|
|
2899
|
+
await deleteCollectionItem(collection, itemId, namespace, fetchOptions);
|
|
2900
|
+
onDeleted?.();
|
|
2901
|
+
onBack();
|
|
2902
|
+
} catch (err) {
|
|
2903
|
+
setError(err instanceof Error ? err.message : "Failed to delete");
|
|
2904
|
+
} finally {
|
|
2905
|
+
setIsDeleting(false);
|
|
2906
|
+
}
|
|
2907
|
+
};
|
|
2908
|
+
if (isLoading) {
|
|
2909
|
+
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx20(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
2910
|
+
}
|
|
2911
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-6", children: [
|
|
2912
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-4", children: [
|
|
2913
|
+
/* @__PURE__ */ jsx20(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx20(ArrowLeft5, { className: "h-4 w-4" }) }),
|
|
2914
|
+
/* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold truncate capitalize", children: isNew ? `New ${collection} item` : `${collection} / ${itemId}` }) }),
|
|
2915
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
2916
|
+
saveMessage && /* @__PURE__ */ jsx20("span", { className: "text-xs text-emerald-600", children: saveMessage }),
|
|
2917
|
+
!isNew && /* @__PURE__ */ jsxs15(
|
|
2918
|
+
Button,
|
|
2919
|
+
{
|
|
2920
|
+
variant: "destructive",
|
|
2921
|
+
size: "sm",
|
|
2922
|
+
onClick: () => void handleDelete(),
|
|
2923
|
+
disabled: isDeleting,
|
|
2924
|
+
children: [
|
|
2925
|
+
isDeleting ? /* @__PURE__ */ jsx20(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx20(Trash2, { className: "mr-2 h-3 w-3" }),
|
|
2926
|
+
"Delete"
|
|
2927
|
+
]
|
|
2928
|
+
}
|
|
2929
|
+
),
|
|
2930
|
+
/* @__PURE__ */ jsxs15(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
|
|
2931
|
+
isSaving ? /* @__PURE__ */ jsx20(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx20(Save2, { className: "mr-2 h-3 w-3" }),
|
|
2932
|
+
isNew ? "Create" : "Save"
|
|
2933
|
+
] })
|
|
2934
|
+
] })
|
|
2935
|
+
] }),
|
|
2936
|
+
error && /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
2937
|
+
/* @__PURE__ */ jsx20("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx20(
|
|
2938
|
+
"textarea",
|
|
2939
|
+
{
|
|
2940
|
+
className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
|
|
2941
|
+
value: editJson,
|
|
2942
|
+
onChange: (e) => setEditJson(e.target.value),
|
|
2943
|
+
spellCheck: false
|
|
2944
|
+
}
|
|
2945
|
+
) })
|
|
2946
|
+
] });
|
|
2947
|
+
};
|
|
2948
|
+
|
|
2949
|
+
// src/components/views/EventsView.tsx
|
|
2950
|
+
import { useCallback as useCallback7, useState as useState8 } from "react";
|
|
2951
|
+
import { Activity as Activity2, Loader2 as Loader25, Search as Search5 } from "lucide-react";
|
|
2952
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2953
|
+
var STATUS_VARIANTS = {
|
|
2954
|
+
pending: "outline",
|
|
2955
|
+
processing: "default",
|
|
2956
|
+
completed: "secondary",
|
|
2957
|
+
failed: "destructive",
|
|
2958
|
+
expired: "secondary",
|
|
2959
|
+
overwritten: "secondary"
|
|
2960
|
+
};
|
|
2961
|
+
var EventsView = ({ config }) => {
|
|
2962
|
+
const [threadId, setThreadId] = useState8("");
|
|
2963
|
+
const [event, setEvent] = useState8(null);
|
|
2964
|
+
const [hasSearched, setHasSearched] = useState8(false);
|
|
2965
|
+
const [isLoading, setIsLoading] = useState8(false);
|
|
2966
|
+
const [error, setError] = useState8(null);
|
|
2967
|
+
const fetchOptions = {
|
|
2968
|
+
baseUrl: config.baseUrl,
|
|
2969
|
+
getRequestHeaders: config.getRequestHeaders
|
|
2970
|
+
};
|
|
2971
|
+
const handleSearch = useCallback7(async () => {
|
|
2972
|
+
if (!threadId.trim()) return;
|
|
2973
|
+
setIsLoading(true);
|
|
2974
|
+
setError(null);
|
|
2975
|
+
setHasSearched(true);
|
|
2976
|
+
try {
|
|
2977
|
+
const result = await fetchThreadEvents(threadId.trim(), fetchOptions);
|
|
2978
|
+
setEvent(result ?? null);
|
|
2979
|
+
} catch (err) {
|
|
2980
|
+
setError(err instanceof Error ? err.message : "Failed to load events");
|
|
2981
|
+
} finally {
|
|
2982
|
+
setIsLoading(false);
|
|
2983
|
+
}
|
|
2984
|
+
}, [threadId, config.baseUrl, config.getRequestHeaders]);
|
|
2985
|
+
return /* @__PURE__ */ jsxs16("div", { className: "space-y-6", children: [
|
|
2986
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-end gap-3 max-w-lg", children: [
|
|
2987
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex-1", children: [
|
|
2988
|
+
/* @__PURE__ */ jsx21("label", { className: "text-sm font-medium mb-1 block", children: "Thread ID" }),
|
|
2989
|
+
/* @__PURE__ */ jsxs16("div", { className: "relative", children: [
|
|
2990
|
+
/* @__PURE__ */ jsx21(Search5, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2991
|
+
/* @__PURE__ */ jsx21(
|
|
2992
|
+
Input,
|
|
2993
|
+
{
|
|
2994
|
+
className: "pl-9",
|
|
2995
|
+
placeholder: "Enter thread ID to inspect events...",
|
|
2996
|
+
value: threadId,
|
|
2997
|
+
onChange: (e) => setThreadId(e.target.value),
|
|
2998
|
+
onKeyDown: (e) => e.key === "Enter" && void handleSearch()
|
|
2999
|
+
}
|
|
3000
|
+
)
|
|
3001
|
+
] })
|
|
3002
|
+
] }),
|
|
3003
|
+
/* @__PURE__ */ jsxs16(Button, { onClick: () => void handleSearch(), disabled: isLoading || !threadId.trim(), children: [
|
|
3004
|
+
isLoading ? /* @__PURE__ */ jsx21(Loader25, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3005
|
+
"Inspect"
|
|
3006
|
+
] })
|
|
3007
|
+
] }),
|
|
3008
|
+
error && /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3009
|
+
!hasSearched ? /* @__PURE__ */ jsxs16("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3010
|
+
/* @__PURE__ */ jsx21(Activity2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3011
|
+
/* @__PURE__ */ jsx21("p", { className: "mt-3 text-sm text-muted-foreground", children: "Enter a thread ID to inspect its next pending queue event." })
|
|
3012
|
+
] }) : isLoading ? /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx21(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : !event ? /* @__PURE__ */ jsxs16("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3013
|
+
/* @__PURE__ */ jsx21(Activity2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3014
|
+
/* @__PURE__ */ jsx21("p", { className: "mt-3 text-sm text-muted-foreground", children: "No pending events found for this thread." })
|
|
3015
|
+
] }) : /* @__PURE__ */ jsxs16("div", { className: "rounded-lg border bg-card p-5 space-y-4", children: [
|
|
3016
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-3", children: [
|
|
3017
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
3018
|
+
/* @__PURE__ */ jsx21("p", { className: "font-medium", children: event.eventType }),
|
|
3019
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground font-mono mt-1", children: event.id })
|
|
3020
|
+
] }),
|
|
3021
|
+
/* @__PURE__ */ jsx21(Badge, { variant: STATUS_VARIANTS[event.status] ?? "outline", children: event.status })
|
|
3022
|
+
] }),
|
|
3023
|
+
/* @__PURE__ */ jsxs16("div", { className: "grid gap-3 sm:grid-cols-2 text-sm", children: [
|
|
3024
|
+
event.traceId && /* @__PURE__ */ jsxs16("div", { children: [
|
|
3025
|
+
/* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Trace:" }),
|
|
3026
|
+
" ",
|
|
3027
|
+
/* @__PURE__ */ jsx21("span", { className: "font-mono text-xs", children: event.traceId })
|
|
3028
|
+
] }),
|
|
3029
|
+
event.parentEventId && /* @__PURE__ */ jsxs16("div", { children: [
|
|
3030
|
+
/* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Parent:" }),
|
|
3031
|
+
" ",
|
|
3032
|
+
/* @__PURE__ */ jsx21("span", { className: "font-mono text-xs", children: event.parentEventId })
|
|
3033
|
+
] }),
|
|
3034
|
+
event.priority != null && /* @__PURE__ */ jsxs16("div", { children: [
|
|
3035
|
+
/* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Priority:" }),
|
|
3036
|
+
" ",
|
|
3037
|
+
event.priority
|
|
3038
|
+
] }),
|
|
3039
|
+
event.createdAt && /* @__PURE__ */ jsxs16("div", { children: [
|
|
3040
|
+
/* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Created:" }),
|
|
3041
|
+
" ",
|
|
3042
|
+
formatTimestamp2(event.createdAt)
|
|
3043
|
+
] })
|
|
3044
|
+
] }),
|
|
3045
|
+
event.payload != null && /* @__PURE__ */ jsxs16("div", { children: [
|
|
3046
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Payload" }),
|
|
3047
|
+
/* @__PURE__ */ jsx21("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(event.payload, null, 2) })
|
|
3048
|
+
] }),
|
|
3049
|
+
event.metadata != null && Object.keys(event.metadata).length > 0 && /* @__PURE__ */ jsxs16("div", { children: [
|
|
3050
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Metadata" }),
|
|
3051
|
+
/* @__PURE__ */ jsx21("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-40", children: JSON.stringify(event.metadata, null, 2) })
|
|
3052
|
+
] })
|
|
3053
|
+
] })
|
|
3054
|
+
] });
|
|
3055
|
+
};
|
|
3056
|
+
function formatTimestamp2(value) {
|
|
3057
|
+
const date = new Date(value);
|
|
3058
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
3059
|
+
return date.toLocaleString(void 0, {
|
|
3060
|
+
month: "short",
|
|
3061
|
+
day: "numeric",
|
|
3062
|
+
hour: "numeric",
|
|
3063
|
+
minute: "2-digit",
|
|
3064
|
+
second: "2-digit"
|
|
3065
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
|
|
1980
3068
|
// src/CopilotzAdmin.tsx
|
|
1981
|
-
import { jsx as
|
|
3069
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1982
3070
|
var CopilotzAdmin = ({
|
|
1983
3071
|
config: userConfig,
|
|
1984
3072
|
className
|
|
@@ -1987,69 +3075,101 @@ var CopilotzAdmin = ({
|
|
|
1987
3075
|
() => mergeAdminConfig(defaultAdminConfig, userConfig),
|
|
1988
3076
|
[userConfig]
|
|
1989
3077
|
);
|
|
1990
|
-
const [route, setRoute] =
|
|
1991
|
-
const [
|
|
1992
|
-
const [
|
|
1993
|
-
const [
|
|
3078
|
+
const [route, setRoute] = useState9({ page: config.defaultPage });
|
|
3079
|
+
const [namespace, setNamespace] = useState9(config.namespace);
|
|
3080
|
+
const [collections, setCollections] = useState9([]);
|
|
3081
|
+
const [threadSearch, setThreadSearch] = useState9("");
|
|
3082
|
+
const [participantSearch, setParticipantSearch] = useState9("");
|
|
3083
|
+
const [agentSearch, setAgentSearch] = useState9("");
|
|
1994
3084
|
const deferredThreadSearch = useDeferredValue(threadSearch);
|
|
1995
3085
|
const deferredParticipantSearch = useDeferredValue(participantSearch);
|
|
1996
3086
|
const deferredAgentSearch = useDeferredValue(agentSearch);
|
|
1997
3087
|
const admin = useCopilotzAdmin({
|
|
1998
3088
|
baseUrl: config.baseUrl,
|
|
1999
3089
|
getRequestHeaders: config.getRequestHeaders,
|
|
2000
|
-
namespace
|
|
3090
|
+
namespace,
|
|
2001
3091
|
range: config.initialRange,
|
|
2002
3092
|
interval: config.initialInterval,
|
|
2003
3093
|
threadSearch: deferredThreadSearch,
|
|
2004
3094
|
participantSearch: deferredParticipantSearch,
|
|
2005
3095
|
agentSearch: deferredAgentSearch
|
|
2006
3096
|
});
|
|
2007
|
-
|
|
3097
|
+
useEffect9(() => {
|
|
3098
|
+
if (!config.features.showCollections) return;
|
|
3099
|
+
fetchCollectionNames({
|
|
3100
|
+
baseUrl: config.baseUrl,
|
|
3101
|
+
getRequestHeaders: config.getRequestHeaders
|
|
3102
|
+
}).then(setCollections).catch(() => setCollections([]));
|
|
3103
|
+
}, [config.baseUrl, config.getRequestHeaders, config.features.showCollections]);
|
|
3104
|
+
const navigate = useCallback8(
|
|
2008
3105
|
(next) => {
|
|
2009
3106
|
setRoute(next);
|
|
2010
3107
|
config.onNavigate?.(next);
|
|
2011
3108
|
},
|
|
2012
3109
|
[config]
|
|
2013
3110
|
);
|
|
2014
|
-
const handleSidebarNavigate =
|
|
3111
|
+
const handleSidebarNavigate = useCallback8(
|
|
2015
3112
|
(page) => navigate({ page }),
|
|
2016
3113
|
[navigate]
|
|
2017
3114
|
);
|
|
2018
|
-
const
|
|
3115
|
+
const handleSidebarRouteNavigate = useCallback8(
|
|
3116
|
+
(r) => navigate(r),
|
|
3117
|
+
[navigate]
|
|
3118
|
+
);
|
|
3119
|
+
const handleThreadClick = useCallback8(
|
|
2019
3120
|
(threadId) => navigate({ page: "thread-detail", resourceId: threadId }),
|
|
2020
3121
|
[navigate]
|
|
2021
3122
|
);
|
|
2022
|
-
const handleBackToThreads =
|
|
2023
|
-
|
|
3123
|
+
const handleBackToThreads = useCallback8(() => navigate({ page: "threads" }), [navigate]);
|
|
3124
|
+
const handleParticipantClick = useCallback8(
|
|
3125
|
+
(id) => navigate({ page: "participant-detail", resourceId: id }),
|
|
2024
3126
|
[navigate]
|
|
2025
3127
|
);
|
|
2026
|
-
const
|
|
3128
|
+
const handleBackToParticipants = useCallback8(() => navigate({ page: "participants" }), [navigate]);
|
|
3129
|
+
const handleAgentClick = useCallback8(
|
|
3130
|
+
(id) => navigate({ page: "agent-detail", resourceId: id }),
|
|
3131
|
+
[navigate]
|
|
3132
|
+
);
|
|
3133
|
+
const handleBackToAgents = useCallback8(() => navigate({ page: "agents" }), [navigate]);
|
|
3134
|
+
const handleCollectionItemClick = useCallback8(
|
|
3135
|
+
(itemId) => navigate({ page: "collection-item-detail", resourceId: itemId, collection: route.collection }),
|
|
3136
|
+
[navigate, route.collection]
|
|
3137
|
+
);
|
|
3138
|
+
const handleCollectionCreateNew = useCallback8(
|
|
3139
|
+
() => navigate({ page: "collection-item-detail", resourceId: void 0, collection: route.collection }),
|
|
3140
|
+
[navigate, route.collection]
|
|
3141
|
+
);
|
|
3142
|
+
const handleBackToCollectionItems = useCallback8(
|
|
3143
|
+
() => navigate({ page: "collection-items", collection: route.collection }),
|
|
3144
|
+
[navigate, route.collection]
|
|
3145
|
+
);
|
|
3146
|
+
const sidebarPage = (() => {
|
|
3147
|
+
switch (route.page) {
|
|
3148
|
+
case "thread-detail":
|
|
3149
|
+
return "threads";
|
|
3150
|
+
case "participant-detail":
|
|
3151
|
+
return "participants";
|
|
3152
|
+
case "agent-detail":
|
|
3153
|
+
return "agents";
|
|
3154
|
+
case "collection-item-detail":
|
|
3155
|
+
return "collection-items";
|
|
3156
|
+
default:
|
|
3157
|
+
return route.page;
|
|
3158
|
+
}
|
|
3159
|
+
})();
|
|
2027
3160
|
if (admin.isLoading && !admin.overview) {
|
|
2028
|
-
return /* @__PURE__ */
|
|
3161
|
+
return /* @__PURE__ */ jsx22(Card, { className: cn("border-border", className), children: /* @__PURE__ */ jsx22(CardContent, { className: "text-muted-foreground flex items-center justify-center min-h-[200px]", children: config.labels.loading }) });
|
|
2029
3162
|
}
|
|
2030
3163
|
if (admin.error && !admin.overview) {
|
|
2031
|
-
return /* @__PURE__ */
|
|
2032
|
-
|
|
2033
|
-
{
|
|
2034
|
-
|
|
2035
|
-
children: /* @__PURE__ */ jsxs10(CardContent, { className: "space-y-4", children: [
|
|
2036
|
-
/* @__PURE__ */ jsx14("p", { className: "text-base font-semibold text-destructive", children: admin.error.message }),
|
|
2037
|
-
/* @__PURE__ */ jsx14(
|
|
2038
|
-
Button,
|
|
2039
|
-
{
|
|
2040
|
-
variant: "destructive",
|
|
2041
|
-
onClick: () => void admin.refresh(),
|
|
2042
|
-
children: config.labels.retry
|
|
2043
|
-
}
|
|
2044
|
-
)
|
|
2045
|
-
] })
|
|
2046
|
-
}
|
|
2047
|
-
);
|
|
3164
|
+
return /* @__PURE__ */ jsx22(Card, { className: cn("border-destructive/50 bg-destructive/10", className), children: /* @__PURE__ */ jsxs17(CardContent, { className: "space-y-4", children: [
|
|
3165
|
+
/* @__PURE__ */ jsx22("p", { className: "text-base font-semibold text-destructive", children: admin.error.message }),
|
|
3166
|
+
/* @__PURE__ */ jsx22(Button, { variant: "destructive", onClick: () => void admin.refresh(), children: config.labels.retry })
|
|
3167
|
+
] }) });
|
|
2048
3168
|
}
|
|
2049
3169
|
const renderCurrentView = () => {
|
|
2050
3170
|
switch (route.page) {
|
|
2051
3171
|
case "dashboard":
|
|
2052
|
-
return /* @__PURE__ */
|
|
3172
|
+
return /* @__PURE__ */ jsx22(
|
|
2053
3173
|
DashboardView,
|
|
2054
3174
|
{
|
|
2055
3175
|
config,
|
|
@@ -2069,7 +3189,7 @@ var CopilotzAdmin = ({
|
|
|
2069
3189
|
}
|
|
2070
3190
|
);
|
|
2071
3191
|
case "threads":
|
|
2072
|
-
return /* @__PURE__ */
|
|
3192
|
+
return /* @__PURE__ */ jsx22(
|
|
2073
3193
|
ThreadsView,
|
|
2074
3194
|
{
|
|
2075
3195
|
config,
|
|
@@ -2080,34 +3200,62 @@ var CopilotzAdmin = ({
|
|
|
2080
3200
|
}
|
|
2081
3201
|
);
|
|
2082
3202
|
case "thread-detail":
|
|
2083
|
-
return route.resourceId ? /* @__PURE__ */
|
|
2084
|
-
|
|
3203
|
+
return route.resourceId ? /* @__PURE__ */ jsx22(ThreadDetailView, { threadId: route.resourceId, config, onBack: handleBackToThreads }) : null;
|
|
3204
|
+
case "participants":
|
|
3205
|
+
return /* @__PURE__ */ jsx22(
|
|
3206
|
+
ParticipantsView,
|
|
2085
3207
|
{
|
|
2086
|
-
threadId: route.resourceId,
|
|
2087
3208
|
config,
|
|
2088
|
-
|
|
3209
|
+
participants: admin.participants,
|
|
3210
|
+
searchValue: participantSearch,
|
|
3211
|
+
onSearchChange: setParticipantSearch,
|
|
3212
|
+
onParticipantClick: handleParticipantClick
|
|
2089
3213
|
}
|
|
2090
|
-
)
|
|
2091
|
-
case "
|
|
2092
|
-
return /* @__PURE__ */
|
|
2093
|
-
/* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold", children: config.labels.participantsTitle }),
|
|
2094
|
-
/* @__PURE__ */ jsx14("p", { className: "mt-2 text-sm text-muted-foreground", children: "Detailed participant management coming soon." })
|
|
2095
|
-
] });
|
|
3214
|
+
);
|
|
3215
|
+
case "participant-detail":
|
|
3216
|
+
return route.resourceId ? /* @__PURE__ */ jsx22(ParticipantDetailView, { participantId: route.resourceId, config, onBack: handleBackToParticipants }) : null;
|
|
2096
3217
|
case "agents":
|
|
2097
|
-
return /* @__PURE__ */
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
3218
|
+
return /* @__PURE__ */ jsx22(
|
|
3219
|
+
AgentsView,
|
|
3220
|
+
{
|
|
3221
|
+
config,
|
|
3222
|
+
agents: admin.agents,
|
|
3223
|
+
searchValue: agentSearch,
|
|
3224
|
+
onSearchChange: setAgentSearch,
|
|
3225
|
+
onAgentClick: handleAgentClick
|
|
3226
|
+
}
|
|
3227
|
+
);
|
|
3228
|
+
case "agent-detail":
|
|
3229
|
+
return route.resourceId ? /* @__PURE__ */ jsx22(AgentDetailView, { agentId: route.resourceId, config, agents: admin.agents, onBack: handleBackToAgents }) : null;
|
|
3230
|
+
case "collection-items":
|
|
3231
|
+
return route.collection ? /* @__PURE__ */ jsx22(
|
|
3232
|
+
CollectionItemsView,
|
|
3233
|
+
{
|
|
3234
|
+
collection: route.collection,
|
|
3235
|
+
config,
|
|
3236
|
+
namespace,
|
|
3237
|
+
onItemClick: handleCollectionItemClick,
|
|
3238
|
+
onCreateNew: handleCollectionCreateNew
|
|
3239
|
+
}
|
|
3240
|
+
) : null;
|
|
3241
|
+
case "collection-item-detail":
|
|
3242
|
+
return route.collection ? /* @__PURE__ */ jsx22(
|
|
3243
|
+
CollectionItemDetailView,
|
|
3244
|
+
{
|
|
3245
|
+
collection: route.collection,
|
|
3246
|
+
itemId: route.resourceId ?? null,
|
|
3247
|
+
config,
|
|
3248
|
+
namespace,
|
|
3249
|
+
onBack: handleBackToCollectionItems
|
|
3250
|
+
}
|
|
3251
|
+
) : null;
|
|
2101
3252
|
case "events":
|
|
2102
|
-
return /* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold", children: config.labels.eventsTitle }),
|
|
2104
|
-
/* @__PURE__ */ jsx14("p", { className: "mt-2 text-sm text-muted-foreground", children: "Event inspector coming soon." })
|
|
2105
|
-
] });
|
|
3253
|
+
return /* @__PURE__ */ jsx22(EventsView, { config });
|
|
2106
3254
|
default:
|
|
2107
3255
|
return null;
|
|
2108
3256
|
}
|
|
2109
3257
|
};
|
|
2110
|
-
return /* @__PURE__ */
|
|
3258
|
+
return /* @__PURE__ */ jsx22(TooltipProvider, { children: /* @__PURE__ */ jsx22(SidebarProvider, { defaultOpen: config.sidebar.defaultOpen, children: /* @__PURE__ */ jsxs17(
|
|
2111
3259
|
"div",
|
|
2112
3260
|
{
|
|
2113
3261
|
className: cn(
|
|
@@ -2115,20 +3263,25 @@ var CopilotzAdmin = ({
|
|
|
2115
3263
|
className
|
|
2116
3264
|
),
|
|
2117
3265
|
children: [
|
|
2118
|
-
/* @__PURE__ */
|
|
3266
|
+
/* @__PURE__ */ jsx22(
|
|
2119
3267
|
AdminSidebar,
|
|
2120
3268
|
{
|
|
2121
3269
|
config,
|
|
2122
3270
|
currentPage: sidebarPage,
|
|
2123
|
-
|
|
3271
|
+
currentRoute: route,
|
|
3272
|
+
onNavigate: handleSidebarNavigate,
|
|
3273
|
+
onNavigateRoute: handleSidebarRouteNavigate,
|
|
3274
|
+
collections,
|
|
3275
|
+
namespace,
|
|
3276
|
+
onNamespaceChange: setNamespace
|
|
2124
3277
|
}
|
|
2125
3278
|
),
|
|
2126
|
-
/* @__PURE__ */
|
|
2127
|
-
/* @__PURE__ */
|
|
3279
|
+
/* @__PURE__ */ jsx22(SidebarInset, { children: /* @__PURE__ */ jsxs17("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
3280
|
+
/* @__PURE__ */ jsx22(
|
|
2128
3281
|
AdminHeader,
|
|
2129
3282
|
{
|
|
2130
3283
|
config,
|
|
2131
|
-
|
|
3284
|
+
currentRoute: route,
|
|
2132
3285
|
range: admin.filters.range,
|
|
2133
3286
|
interval: admin.filters.interval,
|
|
2134
3287
|
onRangeChange: admin.setRange,
|
|
@@ -2137,7 +3290,7 @@ var CopilotzAdmin = ({
|
|
|
2137
3290
|
isLoading: admin.isLoading
|
|
2138
3291
|
}
|
|
2139
3292
|
),
|
|
2140
|
-
/* @__PURE__ */
|
|
3293
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 overflow-auto p-6", children: renderCurrentView() })
|
|
2141
3294
|
] }) })
|
|
2142
3295
|
]
|
|
2143
3296
|
}
|
|
@@ -2145,13 +3298,22 @@ var CopilotzAdmin = ({
|
|
|
2145
3298
|
};
|
|
2146
3299
|
export {
|
|
2147
3300
|
CopilotzAdmin,
|
|
3301
|
+
createCollectionItem,
|
|
2148
3302
|
defaultAdminConfig,
|
|
3303
|
+
deleteCollectionItem,
|
|
2149
3304
|
fetchAdminActivity,
|
|
2150
3305
|
fetchAdminAgents,
|
|
2151
3306
|
fetchAdminOverview,
|
|
2152
3307
|
fetchAdminParticipants,
|
|
2153
3308
|
fetchAdminThreads,
|
|
3309
|
+
fetchCollectionItem,
|
|
3310
|
+
fetchCollectionItems,
|
|
3311
|
+
fetchCollectionNames,
|
|
3312
|
+
fetchParticipantDetail,
|
|
3313
|
+
fetchThreadEvents,
|
|
2154
3314
|
mergeAdminConfig,
|
|
3315
|
+
updateCollectionItem,
|
|
3316
|
+
updateParticipant,
|
|
2155
3317
|
useCopilotzAdmin
|
|
2156
3318
|
};
|
|
2157
3319
|
//# sourceMappingURL=index.js.map
|