@truefoundry/trueforge-ui 0.2.4 → 0.3.0-rc.1
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/CHANGELOG.md +85 -0
- package/README.md +55 -23
- package/dist/AgentCodeSnippets-NZOFJE57.js +74 -0
- package/dist/AgentCodeSnippets-NZOFJE57.js.map +1 -0
- package/dist/AgentMetricChart-JPU3MFQ2.js +15 -0
- package/dist/AgentOverview-EEBHJC32.js +167 -0
- package/dist/AgentOverview-EEBHJC32.js.map +1 -0
- package/dist/AgentSessionEventTimeline-26Z6IB3B.js +79 -0
- package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +1 -0
- package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js +504 -0
- package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +1 -0
- package/dist/AgentSessions-3MPDZASK.js +275 -0
- package/dist/AgentSessions-3MPDZASK.js.map +1 -0
- package/dist/{ConnectorSettings-ODC3LVHN.js → ConnectorSettings-MXFRWWR6.js} +8 -6
- package/dist/{ConnectorSettings-ODC3LVHN.js.map → ConnectorSettings-MXFRWWR6.js.map} +1 -1
- package/dist/{DockLayout-TEOWEMSV.js → DockLayout-LM4AFMFY.js} +12 -11
- package/dist/{DockLayout-TEOWEMSV.js.map → DockLayout-LM4AFMFY.js.map} +1 -1
- package/dist/DrawerLayout-JR3O6RRB.js +184 -0
- package/dist/DrawerLayout-JR3O6RRB.js.map +1 -0
- package/dist/{ModelSettings-CKQ5CVAC.js → ModelSettings-G7IFNC2Y.js} +8 -6
- package/dist/{ModelSettings-CKQ5CVAC.js.map → ModelSettings-G7IFNC2Y.js.map} +1 -1
- package/dist/OpenUiFenceBlock-2TV5TQ6P.js +9 -0
- package/dist/OpenUiFenceBlock-2TV5TQ6P.js.map +1 -0
- package/dist/{SandboxSettings-HSCPYUOC.js → SandboxSettings-NXAANMAX.js} +8 -6
- package/dist/{SandboxSettings-HSCPYUOC.js.map → SandboxSettings-NXAANMAX.js.map} +1 -1
- package/dist/SchedulesPage-KKLUDO6B.js +15 -0
- package/dist/SchedulesPage-KKLUDO6B.js.map +1 -0
- package/dist/{SettingsBuilder-MYWRFXRI.js → SettingsBuilder-L34IQ56S.js} +26 -22
- package/dist/SettingsBuilder-L34IQ56S.js.map +1 -0
- package/dist/{ShellRouteSync-T4WLY57Q.js → ShellRouteSync-CEBETGEJ.js} +95 -22
- package/dist/ShellRouteSync-CEBETGEJ.js.map +1 -0
- package/dist/SidebarLayout-A2HJPPHS.js +308 -0
- package/dist/SidebarLayout-A2HJPPHS.js.map +1 -0
- package/dist/{SkillSettings-ECH6SHZ7.js → SkillSettings-FGGMSUNO.js} +8 -6
- package/dist/{SkillSettings-ECH6SHZ7.js.map → SkillSettings-FGGMSUNO.js.map} +1 -1
- package/dist/{TrueForgeUIWithRouter-KMHPOKLN.js → TrueForgeUIWithRouter-MZVJWJMB.js} +15 -11
- package/dist/{TrueForgeUIWithRouter-KMHPOKLN.js.map → TrueForgeUIWithRouter-MZVJWJMB.js.map} +1 -1
- package/dist/{WidgetLayout-4ZIG3RXV.js → WidgetLayout-6QM45OQQ.js} +19 -15
- package/dist/WidgetLayout-6QM45OQQ.js.map +1 -0
- package/dist/chunk-2XPPBEYF.js +74 -0
- package/dist/chunk-2XPPBEYF.js.map +1 -0
- package/dist/chunk-6O6FWUDW.js +1376 -0
- package/dist/chunk-6O6FWUDW.js.map +1 -0
- package/dist/chunk-7Z2C2K7F.js +578 -0
- package/dist/chunk-7Z2C2K7F.js.map +1 -0
- package/dist/{chunk-FXCYLEFB.js → chunk-BSIPI3KV.js} +18 -2
- package/dist/chunk-BSIPI3KV.js.map +1 -0
- package/dist/{chunk-255AE5NI.js → chunk-CYHJDKFB.js} +118 -33
- package/dist/chunk-CYHJDKFB.js.map +1 -0
- package/dist/chunk-DJUFS2BW.js +27 -0
- package/dist/chunk-DJUFS2BW.js.map +1 -0
- package/dist/chunk-DMMZSZTN.js +252 -0
- package/dist/chunk-DMMZSZTN.js.map +1 -0
- package/dist/chunk-FJW36PD7.js +180 -0
- package/dist/chunk-FJW36PD7.js.map +1 -0
- package/dist/chunk-M62XY4NC.js +555 -0
- package/dist/chunk-M62XY4NC.js.map +1 -0
- package/dist/{chunk-JRRCAKEP.js → chunk-MPNSO7E6.js} +2 -2
- package/dist/{chunk-CFLVPV5M.js → chunk-QC42MLAK.js} +7 -2
- package/dist/chunk-QC42MLAK.js.map +1 -0
- package/dist/chunk-RDXBMTP5.js +32 -0
- package/dist/chunk-RDXBMTP5.js.map +1 -0
- package/dist/chunk-SFZNIO6U.js +18 -0
- package/dist/chunk-SFZNIO6U.js.map +1 -0
- package/dist/chunk-U7KURWW3.js +840 -0
- package/dist/chunk-U7KURWW3.js.map +1 -0
- package/dist/chunk-WVE3F724.js +200 -0
- package/dist/chunk-WVE3F724.js.map +1 -0
- package/dist/{chunk-IFLE7OMM.js → chunk-XAU7QFG3.js} +180 -38
- package/dist/chunk-XAU7QFG3.js.map +1 -0
- package/dist/chunk-Y6S4OVVQ.js +16 -0
- package/dist/chunk-Y6S4OVVQ.js.map +1 -0
- package/dist/chunk-ZKNUMH2M.js +119 -0
- package/dist/chunk-ZKNUMH2M.js.map +1 -0
- package/dist/chunk-ZTMKFZQ3.js +13214 -0
- package/dist/chunk-ZTMKFZQ3.js.map +1 -0
- package/dist/{createTrueFoundryServer-B72bU-J7.d.ts → createTrueFoundryServer-CmZnBh_l.d.ts} +15 -4
- package/dist/index.d.ts +1199 -161
- package/dist/index.js +699 -69
- package/dist/index.js.map +1 -1
- package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +552 -12
- package/dist/plugins/trueforge-agent-server-adapter/index.js +506 -188
- package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +11 -10
- package/dist/DrawerLayout-2JOQ4EDZ.js +0 -159
- package/dist/DrawerLayout-2JOQ4EDZ.js.map +0 -1
- package/dist/OpenUiFenceBlock-3EFPY4JW.js +0 -9
- package/dist/SettingsBuilder-MYWRFXRI.js.map +0 -1
- package/dist/ShellRouteSync-T4WLY57Q.js.map +0 -1
- package/dist/SidebarLayout-6MHQYW45.js +0 -239
- package/dist/SidebarLayout-6MHQYW45.js.map +0 -1
- package/dist/WidgetLayout-4ZIG3RXV.js.map +0 -1
- package/dist/chunk-255AE5NI.js.map +0 -1
- package/dist/chunk-72LC2M3R.js +0 -567
- package/dist/chunk-72LC2M3R.js.map +0 -1
- package/dist/chunk-CFLVPV5M.js.map +0 -1
- package/dist/chunk-FXCYLEFB.js.map +0 -1
- package/dist/chunk-IFLE7OMM.js.map +0 -1
- package/dist/chunk-IWPDSPVA.js +0 -2068
- package/dist/chunk-IWPDSPVA.js.map +0 -1
- package/dist/chunk-OZTNBS6V.js +0 -75
- package/dist/chunk-OZTNBS6V.js.map +0 -1
- package/dist/chunk-PUFYHFND.js +0 -91
- package/dist/chunk-PUFYHFND.js.map +0 -1
- package/dist/chunk-WQULF5AT.js +0 -460
- package/dist/chunk-WQULF5AT.js.map +0 -1
- package/dist/chunk-XRTTKGKN.js +0 -6825
- package/dist/chunk-XRTTKGKN.js.map +0 -1
- package/dist/chunk-YIWUG6MC.js +0 -101
- package/dist/chunk-YIWUG6MC.js.map +0 -1
- /package/dist/{OpenUiFenceBlock-3EFPY4JW.js.map → AgentMetricChart-JPU3MFQ2.js.map} +0 -0
- /package/dist/{chunk-JRRCAKEP.js.map → chunk-MPNSO7E6.js.map} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useOptionalServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-U7KURWW3.js";
|
|
4
4
|
import {
|
|
5
5
|
ThemeContext,
|
|
6
6
|
cn
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7Z2C2K7F.js";
|
|
8
8
|
|
|
9
9
|
// src/icons/Icon.tsx
|
|
10
10
|
import { createElement, isValidElement, useContext } from "react";
|
|
@@ -19,6 +19,9 @@ import {
|
|
|
19
19
|
Bot,
|
|
20
20
|
Box,
|
|
21
21
|
Brain,
|
|
22
|
+
Calendar,
|
|
23
|
+
CalendarClock,
|
|
24
|
+
CalendarPlus,
|
|
22
25
|
Check,
|
|
23
26
|
ChevronDown,
|
|
24
27
|
ChevronLeft,
|
|
@@ -32,12 +35,17 @@ import {
|
|
|
32
35
|
Cpu,
|
|
33
36
|
Download,
|
|
34
37
|
Ellipsis,
|
|
38
|
+
EllipsisVertical,
|
|
35
39
|
ExternalLink,
|
|
36
40
|
File,
|
|
37
41
|
Github,
|
|
42
|
+
GripVertical,
|
|
38
43
|
History,
|
|
39
44
|
Info,
|
|
45
|
+
LibraryBig,
|
|
40
46
|
Lightbulb,
|
|
47
|
+
LineChart,
|
|
48
|
+
Link2,
|
|
41
49
|
ListChecks,
|
|
42
50
|
ListFilter,
|
|
43
51
|
ListOrdered,
|
|
@@ -46,11 +54,13 @@ import {
|
|
|
46
54
|
LogOut,
|
|
47
55
|
Maximize2,
|
|
48
56
|
Menu,
|
|
57
|
+
MessageSquareText,
|
|
49
58
|
Minimize2,
|
|
50
59
|
Moon,
|
|
51
60
|
PanelLeftClose,
|
|
52
61
|
PanelLeftOpen,
|
|
53
62
|
Paperclip,
|
|
63
|
+
Pause,
|
|
54
64
|
Pencil,
|
|
55
65
|
Play,
|
|
56
66
|
Plug,
|
|
@@ -59,7 +69,9 @@ import {
|
|
|
59
69
|
Save,
|
|
60
70
|
Search,
|
|
61
71
|
Settings,
|
|
72
|
+
SlidersHorizontal,
|
|
62
73
|
Sparkle,
|
|
74
|
+
SquareArrowOutUpRight,
|
|
63
75
|
SquarePen,
|
|
64
76
|
Sun,
|
|
65
77
|
Terminal,
|
|
@@ -111,10 +123,16 @@ var defaults = {
|
|
|
111
123
|
check: Check,
|
|
112
124
|
pencil: Pencil,
|
|
113
125
|
play: Play,
|
|
126
|
+
pause: Pause,
|
|
127
|
+
calendar: Calendar,
|
|
128
|
+
"calendar-clock": CalendarClock,
|
|
129
|
+
"calendar-plus": CalendarPlus,
|
|
130
|
+
"grip-vertical": GripVertical,
|
|
114
131
|
"square-pen": SquarePen,
|
|
115
132
|
"rotate-right": RotateCw,
|
|
116
133
|
broom: Broom,
|
|
117
134
|
ellipsis: Ellipsis,
|
|
135
|
+
"ellipsis-vertical": EllipsisVertical,
|
|
118
136
|
trash: Trash2,
|
|
119
137
|
"box-archive": Archive,
|
|
120
138
|
"clock-rotate-left": History,
|
|
@@ -135,6 +153,7 @@ var defaults = {
|
|
|
135
153
|
sun: Sun,
|
|
136
154
|
moon: Moon,
|
|
137
155
|
settings: Settings,
|
|
156
|
+
sliders: SlidersHorizontal,
|
|
138
157
|
"log-out": LogOut,
|
|
139
158
|
search: Search,
|
|
140
159
|
clock: Clock,
|
|
@@ -145,12 +164,16 @@ var defaults = {
|
|
|
145
164
|
"oauth-loading": Loader2,
|
|
146
165
|
"welcome-sparkle": Sparkle,
|
|
147
166
|
robot: Bot,
|
|
167
|
+
bot: Bot,
|
|
168
|
+
"library-big": LibraryBig,
|
|
169
|
+
"message-square-text": MessageSquareText,
|
|
148
170
|
"book-open": BookOpen,
|
|
149
171
|
funnel: ListFilter,
|
|
150
172
|
plug: Plug,
|
|
151
173
|
"list-check": ListChecks,
|
|
152
174
|
lock: Lock,
|
|
153
175
|
lightbulb: Lightbulb,
|
|
176
|
+
link: Link2,
|
|
154
177
|
wrench: Wrench,
|
|
155
178
|
cpu: Cpu,
|
|
156
179
|
cube: Box,
|
|
@@ -160,10 +183,12 @@ var defaults = {
|
|
|
160
183
|
brain: Brain,
|
|
161
184
|
terminal: Terminal,
|
|
162
185
|
code: Code2,
|
|
186
|
+
chart: LineChart,
|
|
163
187
|
expand: Maximize2,
|
|
164
188
|
"expand-alt": Maximize2,
|
|
165
189
|
compress: Minimize2,
|
|
166
190
|
"external-link": ExternalLink,
|
|
191
|
+
"square-arrow-out-up-right": SquareArrowOutUpRight,
|
|
167
192
|
github: Github
|
|
168
193
|
};
|
|
169
194
|
for (const [name, icon] of Object.entries(defaults)) {
|
|
@@ -252,11 +277,11 @@ var variantClasses = {
|
|
|
252
277
|
};
|
|
253
278
|
var sizeClasses = {
|
|
254
279
|
default: "h-9 px-4 py-2 text-sm",
|
|
255
|
-
sm: "h-8 rounded-md px-
|
|
280
|
+
sm: "h-8 rounded-md px-2 text-xs",
|
|
256
281
|
lg: "h-10 rounded-md px-8 text-base",
|
|
257
282
|
icon: "h-8 w-8"
|
|
258
283
|
};
|
|
259
|
-
var baseClasses = "inline-flex cursor-pointer items-center justify-center gap-
|
|
284
|
+
var baseClasses = "inline-flex cursor-pointer items-center justify-center gap-1 whitespace-nowrap rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-focus-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
260
285
|
function auiButtonClass({
|
|
261
286
|
variant = "default",
|
|
262
287
|
size = "default",
|
|
@@ -402,98 +427,209 @@ function getErrorMessage(error, fallback) {
|
|
|
402
427
|
return stringifyError(error);
|
|
403
428
|
}
|
|
404
429
|
|
|
430
|
+
// src/atoms/PageHeader.tsx
|
|
431
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
432
|
+
var pageHeaderTitleClassName = "text-text-primary min-w-0 truncate text-md font-semibold";
|
|
433
|
+
function PageHeader({ title, start, end, children, className }) {
|
|
434
|
+
return /* @__PURE__ */ jsxs2(
|
|
435
|
+
"header",
|
|
436
|
+
{
|
|
437
|
+
className: cn(
|
|
438
|
+
"flex min-h-14 shrink-0 flex-wrap items-center gap-2 border-b border-border px-4 md:px-6",
|
|
439
|
+
className
|
|
440
|
+
),
|
|
441
|
+
children: [
|
|
442
|
+
start,
|
|
443
|
+
typeof title === "string" ? /* @__PURE__ */ jsx4("h1", { className: pageHeaderTitleClassName, children: title }) : title,
|
|
444
|
+
children,
|
|
445
|
+
end != null ? /* @__PURE__ */ jsx4("div", { className: "ml-auto flex min-w-0 flex-wrap items-center gap-2", children: end }) : null
|
|
446
|
+
]
|
|
447
|
+
}
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
405
451
|
// src/atoms/lib/CompactLayoutContext.tsx
|
|
406
452
|
import { createContext, useContext as useContext2 } from "react";
|
|
407
|
-
import { jsx as
|
|
453
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
408
454
|
var CompactLayoutContext = createContext(false);
|
|
409
455
|
function CompactLayoutProvider({ children }) {
|
|
410
|
-
return /* @__PURE__ */
|
|
456
|
+
return /* @__PURE__ */ jsx5(CompactLayoutContext.Provider, { value: true, children });
|
|
411
457
|
}
|
|
412
458
|
function useCompactLayout() {
|
|
413
459
|
return useContext2(CompactLayoutContext);
|
|
414
460
|
}
|
|
415
461
|
|
|
416
462
|
// src/atoms/draft/DraftCatalogProvider.tsx
|
|
417
|
-
import { createContext as createContext2, useCallback, useContext as useContext3, useEffect, useMemo, useState } from "react";
|
|
418
|
-
import { jsx as
|
|
463
|
+
import { createContext as createContext2, useCallback, useContext as useContext3, useEffect, useMemo, useRef, useState } from "react";
|
|
464
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
465
|
+
var MCP_CONNECTORS_PAGE_SIZE = 50;
|
|
419
466
|
var DraftCatalogContext = createContext2(null);
|
|
420
467
|
var IDLE_ENSURE = () => void 0;
|
|
421
468
|
var IDLE_REFRESH = async () => void 0;
|
|
469
|
+
function appendConnectors({
|
|
470
|
+
previous,
|
|
471
|
+
next
|
|
472
|
+
}) {
|
|
473
|
+
if (next.length === 0) return previous;
|
|
474
|
+
const seen = new Set(previous.map((connector) => connector.id));
|
|
475
|
+
const appended = next.filter((connector) => !seen.has(connector.id));
|
|
476
|
+
return appended.length === 0 ? previous : [...previous, ...appended];
|
|
477
|
+
}
|
|
478
|
+
async function fetchMcpPage({
|
|
479
|
+
server,
|
|
480
|
+
pageToken
|
|
481
|
+
}) {
|
|
482
|
+
if (server.listMcp != null) {
|
|
483
|
+
return server.listMcp({
|
|
484
|
+
limit: MCP_CONNECTORS_PAGE_SIZE,
|
|
485
|
+
...pageToken === void 0 ? {} : { pageToken }
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
const data = await server.getMcp();
|
|
489
|
+
return { data };
|
|
490
|
+
}
|
|
422
491
|
function DraftCatalogProvider({ children }) {
|
|
423
492
|
const server = useOptionalServer();
|
|
424
493
|
const existing = useContext3(DraftCatalogContext);
|
|
425
494
|
if (existing?.server === server) {
|
|
426
495
|
return children;
|
|
427
496
|
}
|
|
428
|
-
return /* @__PURE__ */
|
|
497
|
+
return /* @__PURE__ */ jsx6(DraftCatalogStore, { server, children });
|
|
429
498
|
}
|
|
430
499
|
function DraftCatalogStore({ server, children }) {
|
|
431
500
|
const [requestEpoch, setRequestEpoch] = useState(null);
|
|
432
501
|
const [models, setModels] = useState([]);
|
|
433
502
|
const [skills, setSkills] = useState([]);
|
|
434
503
|
const [connectors, setConnectors] = useState([]);
|
|
504
|
+
const [connectorsNextPageToken, setConnectorsNextPageToken] = useState(void 0);
|
|
505
|
+
const [connectorsLoadMoreFailed, setConnectorsLoadMoreFailed] = useState(false);
|
|
506
|
+
const [connectorsLoadingMore, setConnectorsLoadingMore] = useState(false);
|
|
435
507
|
const [completedEpoch, setCompletedEpoch] = useState(null);
|
|
436
508
|
const [loading, setLoading] = useState(false);
|
|
437
509
|
const [error, setError] = useState(null);
|
|
510
|
+
const connectorsNextPageTokenRef = useRef(connectorsNextPageToken);
|
|
511
|
+
const connectorsLoadingMoreRef = useRef(connectorsLoadingMore);
|
|
512
|
+
const loadMoreFailedRef = useRef(false);
|
|
513
|
+
connectorsNextPageTokenRef.current = connectorsNextPageToken;
|
|
514
|
+
connectorsLoadingMoreRef.current = connectorsLoadingMore;
|
|
438
515
|
const ensureLoaded = useCallback(() => {
|
|
439
516
|
setRequestEpoch((current) => current ?? 0);
|
|
440
517
|
}, []);
|
|
441
518
|
const refresh = useCallback(() => {
|
|
519
|
+
loadMoreFailedRef.current = false;
|
|
520
|
+
setConnectorsLoadMoreFailed(false);
|
|
442
521
|
setRequestEpoch((current) => (current ?? -1) + 1);
|
|
443
522
|
}, []);
|
|
444
523
|
const refreshConnectors = useCallback(async () => {
|
|
445
524
|
if (!server) return;
|
|
446
525
|
setLoading(true);
|
|
447
526
|
setError(null);
|
|
527
|
+
loadMoreFailedRef.current = false;
|
|
528
|
+
setConnectorsLoadMoreFailed(false);
|
|
448
529
|
try {
|
|
449
|
-
const
|
|
450
|
-
setConnectors(
|
|
530
|
+
const page = await fetchMcpPage({ server });
|
|
531
|
+
setConnectors(page.data);
|
|
532
|
+
setConnectorsNextPageToken(page.nextPageToken);
|
|
451
533
|
} catch (reason) {
|
|
452
534
|
setError(getErrorMessage(reason, "Failed to load connectors."));
|
|
453
535
|
} finally {
|
|
454
536
|
setLoading(false);
|
|
455
537
|
}
|
|
456
538
|
}, [server]);
|
|
539
|
+
const loadMoreConnectors = useCallback(() => {
|
|
540
|
+
if (!server) return;
|
|
541
|
+
const pageToken = connectorsNextPageTokenRef.current;
|
|
542
|
+
if (pageToken == null || pageToken.length === 0 || connectorsLoadingMoreRef.current) return;
|
|
543
|
+
setConnectorsLoadMoreFailed(false);
|
|
544
|
+
setConnectorsLoadingMore(true);
|
|
545
|
+
void fetchMcpPage({ server, pageToken }).then((page) => {
|
|
546
|
+
setConnectors((previous) => appendConnectors({ previous, next: page.data }));
|
|
547
|
+
setConnectorsNextPageToken(page.nextPageToken);
|
|
548
|
+
if (loadMoreFailedRef.current) {
|
|
549
|
+
loadMoreFailedRef.current = false;
|
|
550
|
+
setError(null);
|
|
551
|
+
}
|
|
552
|
+
}).catch((reason) => {
|
|
553
|
+
loadMoreFailedRef.current = true;
|
|
554
|
+
setConnectorsLoadMoreFailed(true);
|
|
555
|
+
setError(getErrorMessage(reason, "Failed to load more connectors."));
|
|
556
|
+
}).finally(() => {
|
|
557
|
+
setConnectorsLoadingMore(false);
|
|
558
|
+
});
|
|
559
|
+
}, [server]);
|
|
457
560
|
useEffect(() => {
|
|
458
561
|
if (requestEpoch === null || !server) return;
|
|
459
562
|
let cancelled = false;
|
|
460
563
|
setLoading(true);
|
|
461
564
|
setError(null);
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
565
|
+
loadMoreFailedRef.current = false;
|
|
566
|
+
setConnectorsLoadMoreFailed(false);
|
|
567
|
+
void Promise.allSettled([server.getModels(), server.getSkills(), fetchMcpPage({ server })]).then(
|
|
568
|
+
([modelsResult, skillsResult, mcpResult]) => {
|
|
569
|
+
if (cancelled) return;
|
|
570
|
+
const errors = [];
|
|
571
|
+
if (modelsResult.status === "fulfilled") {
|
|
572
|
+
setModels(modelsResult.value);
|
|
573
|
+
} else {
|
|
574
|
+
errors.push(getErrorMessage(modelsResult.reason, "Failed to load models."));
|
|
575
|
+
}
|
|
576
|
+
if (skillsResult.status === "fulfilled") {
|
|
577
|
+
setSkills(skillsResult.value);
|
|
578
|
+
} else {
|
|
579
|
+
errors.push(getErrorMessage(skillsResult.reason, "Failed to load skills."));
|
|
580
|
+
}
|
|
581
|
+
if (mcpResult.status === "fulfilled") {
|
|
582
|
+
setConnectors(mcpResult.value.data);
|
|
583
|
+
setConnectorsNextPageToken(mcpResult.value.nextPageToken);
|
|
584
|
+
} else {
|
|
585
|
+
errors.push(getErrorMessage(mcpResult.reason, "Failed to load connectors."));
|
|
586
|
+
}
|
|
587
|
+
setError(errors[0] ?? null);
|
|
483
588
|
setCompletedEpoch(requestEpoch);
|
|
484
589
|
setLoading(false);
|
|
485
590
|
}
|
|
486
|
-
|
|
591
|
+
);
|
|
487
592
|
return () => {
|
|
488
593
|
cancelled = true;
|
|
489
594
|
};
|
|
490
595
|
}, [requestEpoch, server]);
|
|
596
|
+
const connectorsHasMore = connectorsNextPageToken != null && connectorsNextPageToken.length > 0;
|
|
491
597
|
const loaded = requestEpoch !== null && completedEpoch === requestEpoch;
|
|
492
598
|
const value = useMemo(
|
|
493
|
-
() => ({
|
|
494
|
-
|
|
599
|
+
() => ({
|
|
600
|
+
server,
|
|
601
|
+
models,
|
|
602
|
+
skills,
|
|
603
|
+
connectors,
|
|
604
|
+
connectorsHasMore,
|
|
605
|
+
connectorsLoadMoreFailed,
|
|
606
|
+
connectorsLoadingMore,
|
|
607
|
+
loaded,
|
|
608
|
+
loading,
|
|
609
|
+
error,
|
|
610
|
+
ensureLoaded,
|
|
611
|
+
refresh,
|
|
612
|
+
refreshConnectors,
|
|
613
|
+
loadMoreConnectors
|
|
614
|
+
}),
|
|
615
|
+
[
|
|
616
|
+
server,
|
|
617
|
+
models,
|
|
618
|
+
skills,
|
|
619
|
+
connectors,
|
|
620
|
+
connectorsHasMore,
|
|
621
|
+
connectorsLoadMoreFailed,
|
|
622
|
+
connectorsLoadingMore,
|
|
623
|
+
loaded,
|
|
624
|
+
loading,
|
|
625
|
+
error,
|
|
626
|
+
ensureLoaded,
|
|
627
|
+
refresh,
|
|
628
|
+
refreshConnectors,
|
|
629
|
+
loadMoreConnectors
|
|
630
|
+
]
|
|
495
631
|
);
|
|
496
|
-
return /* @__PURE__ */
|
|
632
|
+
return /* @__PURE__ */ jsx6(DraftCatalogContext.Provider, { value, children });
|
|
497
633
|
}
|
|
498
634
|
function useDraftCatalog() {
|
|
499
635
|
const ctx = useContext3(DraftCatalogContext);
|
|
@@ -502,12 +638,16 @@ function useDraftCatalog() {
|
|
|
502
638
|
models: [],
|
|
503
639
|
skills: [],
|
|
504
640
|
connectors: [],
|
|
641
|
+
connectorsHasMore: false,
|
|
642
|
+
connectorsLoadMoreFailed: false,
|
|
643
|
+
connectorsLoadingMore: false,
|
|
505
644
|
loaded: false,
|
|
506
645
|
loading: false,
|
|
507
646
|
error: null,
|
|
508
647
|
ensureLoaded: IDLE_ENSURE,
|
|
509
648
|
refresh: IDLE_ENSURE,
|
|
510
|
-
refreshConnectors: IDLE_REFRESH
|
|
649
|
+
refreshConnectors: IDLE_REFRESH,
|
|
650
|
+
loadMoreConnectors: IDLE_ENSURE
|
|
511
651
|
};
|
|
512
652
|
}
|
|
513
653
|
return ctx;
|
|
@@ -519,9 +659,11 @@ export {
|
|
|
519
659
|
Spinner,
|
|
520
660
|
auiButtonClass,
|
|
521
661
|
getErrorMessage,
|
|
662
|
+
pageHeaderTitleClassName,
|
|
663
|
+
PageHeader,
|
|
522
664
|
CompactLayoutProvider,
|
|
523
665
|
useCompactLayout,
|
|
524
666
|
DraftCatalogProvider,
|
|
525
667
|
useDraftCatalog
|
|
526
668
|
};
|
|
527
|
-
//# sourceMappingURL=chunk-
|
|
669
|
+
//# sourceMappingURL=chunk-XAU7QFG3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/icons/Icon.tsx","../src/icons/IconRegistry.tsx","../src/atoms/primitives/Spinner.tsx","../src/atoms/lib/buttonClasses.ts","../src/utils/getErrorMessage.ts","../src/atoms/PageHeader.tsx","../src/atoms/lib/CompactLayoutContext.tsx","../src/atoms/draft/DraftCatalogProvider.tsx"],"sourcesContent":["import { createElement, isValidElement, useContext, type CSSProperties, type ReactNode } from 'react';\n\nimport { cn } from '../atoms/lib/cn.js';\nimport { ThemeContext } from '../theme/ThemeProvider.js';\nimport type { IconComponent, IconEntry, IconProps as ThemeIconProps } from '../theme/types.js';\nimport { lookupIcon, resolveIconName } from './IconRegistry.js';\n\nexport type IconProps = ThemeIconProps & {\n name: string | readonly string[];\n};\n\ntype IconRenderProps = {\n className?: string;\n style?: CSSProperties;\n size?: string | number;\n width?: string | number;\n height?: string | number;\n role?: string;\n} & Pick<IconProps, 'aria-hidden' | 'aria-label' | 'data-testid'>;\n\nfunction isComponent(entry: IconEntry): entry is IconComponent {\n if (typeof entry === 'function') return true;\n // Lucide (and other) icons are forwardRef objects, not functions\n return (\n typeof entry === 'object' &&\n entry !== null &&\n !isValidElement(entry) &&\n !Array.isArray(entry) &&\n '$$typeof' in entry\n );\n}\n\nfunction renderEntry(entry: IconEntry, props: IconRenderProps): ReactNode {\n if (isComponent(entry)) {\n const { size, className, style, ...aria } = props;\n return createElement(entry, {\n className: cn('inline-block shrink-0', className),\n style,\n size,\n width: size,\n height: size,\n 'aria-hidden': aria['aria-label'] ? undefined : (aria['aria-hidden'] ?? true),\n 'aria-label': aria['aria-label'],\n ...(aria['data-testid'] === undefined ? {} : { 'data-testid': aria['data-testid'] }),\n role: aria['aria-label'] ? 'img' : undefined,\n });\n }\n return entry;\n}\n\nexport function Icon({ name, className, style, size = '1em', ...aria }: IconProps) {\n const themeIcons = useContext(ThemeContext)?.icons;\n const resolved = resolveIconName(name);\n const entry = lookupIcon(resolved, themeIcons);\n if (!entry) return null;\n return <>{renderEntry(entry, { className, style, size, ...aria })}</>;\n}\n\nexport function useIcon(name: string | readonly string[]): IconEntry | undefined {\n const themeIcons = useContext(ThemeContext)?.icons;\n return lookupIcon(resolveIconName(name), themeIcons);\n}\n","import {\n Archive,\n ArrowDown,\n ArrowLeft,\n ArrowUp,\n BookOpen,\n Bot,\n Box,\n Brain,\n Calendar,\n CalendarClock,\n CalendarPlus,\n Check,\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n CircleAlert,\n CircleCheck,\n CircleX,\n Clock,\n Code2,\n Copy,\n Cpu,\n Download,\n Ellipsis,\n EllipsisVertical,\n ExternalLink,\n File,\n Github,\n GripVertical,\n History,\n Info,\n LibraryBig,\n Lightbulb,\n LineChart,\n Link2,\n ListChecks,\n ListFilter,\n ListOrdered,\n Loader2,\n Lock,\n LogOut,\n Maximize2,\n Menu,\n MessageSquareText,\n Minimize2,\n Moon,\n PanelLeftClose,\n PanelLeftOpen,\n Paperclip,\n Pause,\n Pencil,\n Play,\n Plug,\n Plus,\n RotateCw,\n Save,\n Search,\n Settings,\n SlidersHorizontal,\n Sparkle,\n SquareArrowOutUpRight,\n SquarePen,\n Sun,\n Terminal,\n Trash2,\n TriangleAlert,\n Wrench,\n X,\n} from 'lucide-react';\nimport type { SVGProps } from 'react';\n\nimport type { IconEntry, IconMap } from '../theme/types.js';\n\n/** Lucide `broom` (https://lucide.dev/icons/broom) — not in lucide-react 0.x. */\nfunction Broom({ size = 24, ...props }: SVGProps<SVGSVGElement> & { size?: string | number }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <path d=\"M13.5 10.5 22 2\" />\n <path d=\"M14.734 13.841a2 2 0 00-.314-2.42L12.58 9.58a2 2 0 00-2.421-.314l-7.657 4.461A1 1 0 002.3 15.3l6.403 6.403a1 1 0 001.571-.204z\" />\n <path d=\"m5 18 2-2\" />\n <path d=\"m7.699 10.7 5.602 5.601\" />\n </svg>\n );\n}\n\nconst registry = new Map<string, IconEntry>();\n\nexport function registerIcon(name: string, icon: IconEntry): void {\n registry.set(name, icon);\n}\n\nexport function registerIcons(icons: IconMap): void {\n for (const [name, icon] of Object.entries(icons)) {\n registry.set(name, icon);\n }\n}\n\nexport function getIcon(name: string): IconEntry | undefined {\n return registry.get(name);\n}\n\nexport function resolveIconName(icon: string | readonly string[]): string {\n if (typeof icon === 'string') return icon;\n // e.g. [\"far\", \"clone\"] → \"clone\"\n return icon[icon.length - 1] ?? '';\n}\n\nconst defaults: Record<string, IconEntry> = {\n paperclip: Paperclip,\n 'arrow-up': ArrowUp,\n 'arrow-down': ArrowDown,\n 'arrow-left': ArrowLeft,\n xmark: X,\n check: Check,\n pencil: Pencil,\n play: Play,\n pause: Pause,\n calendar: Calendar,\n 'calendar-clock': CalendarClock,\n 'calendar-plus': CalendarPlus,\n 'grip-vertical': GripVertical,\n 'square-pen': SquarePen,\n 'rotate-right': RotateCw,\n broom: Broom,\n ellipsis: Ellipsis,\n 'ellipsis-vertical': EllipsisVertical,\n trash: Trash2,\n 'box-archive': Archive,\n 'clock-rotate-left': History,\n 'circle-exclamation': CircleAlert,\n info: Info,\n 'triangle-exclamation': TriangleAlert,\n 'chevron-down': ChevronDown,\n 'chevron-left': ChevronLeft,\n 'chevron-right': ChevronRight,\n loader: Loader2,\n file: File,\n clone: Copy,\n copy: Copy,\n bars: Menu,\n 'panel-left-close': PanelLeftClose,\n 'panel-left-open': PanelLeftOpen,\n plus: Plus,\n sun: Sun,\n moon: Moon,\n settings: Settings,\n sliders: SlidersHorizontal,\n 'log-out': LogOut,\n search: Search,\n clock: Clock,\n 'circle-check': CircleCheck,\n 'circle-xmark': CircleX,\n 'oauth-success': CircleCheck,\n 'oauth-error': CircleX,\n 'oauth-loading': Loader2,\n 'welcome-sparkle': Sparkle,\n robot: Bot,\n bot: Bot,\n 'library-big': LibraryBig,\n 'message-square-text': MessageSquareText,\n 'book-open': BookOpen,\n funnel: ListFilter,\n plug: Plug,\n 'list-check': ListChecks,\n lock: Lock,\n lightbulb: Lightbulb,\n link: Link2,\n wrench: Wrench,\n cpu: Cpu,\n cube: Box,\n 'list-ol': ListOrdered,\n download: Download,\n save: Save,\n brain: Brain,\n terminal: Terminal,\n code: Code2,\n chart: LineChart,\n expand: Maximize2,\n 'expand-alt': Maximize2,\n compress: Minimize2,\n 'external-link': ExternalLink,\n 'square-arrow-out-up-right': SquareArrowOutUpRight,\n github: Github,\n};\n\nfor (const [name, icon] of Object.entries(defaults)) {\n registry.set(name, icon);\n}\n\n/** Merge host `theme.icons` over the registry for a single lookup (does not mutate). */\nexport function lookupIcon(name: string, themeIcons?: IconMap): IconEntry | undefined {\n if (themeIcons && name in themeIcons) {\n return themeIcons[name];\n }\n return registry.get(name);\n}\n","import React from 'react';\n\nimport { cn } from '../lib/cn.js';\n\nexport type SpinnerProps = React.SVGProps<SVGSVGElement> & {\n size?: number;\n};\n\nexport function Spinner({ size = 16, className, ...props }: SpinnerProps) {\n const r = (size / 2) * 0.75;\n const cx = size / 2;\n const circumference = 2 * Math.PI * r;\n\n return (\n <svg\n role=\"status\"\n aria-label=\"Loading\"\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n fill=\"none\"\n className={cn('animate-spin', className)}\n {...props}\n >\n <circle\n cx={cx}\n cy={cx}\n r={r}\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeDasharray={`${circumference * 0.75} ${circumference * 0.25}`}\n opacity={0.8}\n />\n </svg>\n );\n}\n","import { cn } from './cn.js';\n\nexport type AuiButtonVariant = 'default' | 'secondary' | 'ghost' | 'destructive' | 'outline';\nexport type AuiButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\nconst variantClasses: Record<AuiButtonVariant, string> = {\n default: 'bg-primary-button-bg text-primary-button-text shadow hover:bg-primary-button-hover',\n secondary:\n 'border border-input-border bg-secondary-button-bg text-secondary-button-text shadow-sm hover:bg-secondary-button-hover',\n ghost: 'bg-ghost-button-bg text-ghost-button-text hover:bg-ghost-button-hover',\n destructive: 'bg-failure-bg text-failure-text shadow-sm hover:bg-failure-bg/90',\n outline:\n 'border border-input-border bg-secondary-button-bg text-secondary-button-text shadow-sm hover:bg-secondary-button-hover',\n};\n\nconst sizeClasses: Record<AuiButtonSize, string> = {\n default: 'h-9 px-4 py-2 text-sm',\n sm: 'h-8 rounded-md px-2 text-xs',\n lg: 'h-10 rounded-md px-8 text-base',\n icon: 'h-8 w-8',\n};\n\nconst baseClasses =\n 'inline-flex cursor-pointer items-center justify-center gap-1 whitespace-nowrap rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-focus-ring disabled:cursor-not-allowed disabled:opacity-50';\n\n/** Shared Button / native `<button>` className helper (SDK utilities are layered). */\nexport function auiButtonClass({\n variant = 'default',\n size = 'default',\n className,\n}: {\n variant?: AuiButtonVariant;\n size?: AuiButtonSize;\n className?: string;\n} = {}): string {\n return cn(baseClasses, variantClasses[variant], sizeClasses[size], className);\n}\n","function isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === 'object';\n}\n\nfunction readNonEmptyString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() !== '' ? value : undefined;\n}\n\nconst LITERAL_ESCAPE_PATTERN = /\\\\(?:[nrtbfv0'\"\\\\]|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{2})/; // literal escape sequences like \\n, \\t, \\b, \\f, \\v, \\uXXXX, \\xHH\nconst REAL_CONTROL_PATTERN = /[\\n\\t\\b\\f\\v]/; // real control characters like \\n, \\t, \\b, \\f, \\v\n\nfunction decodeLiteralEscapes(text: string): string {\n let out = '';\n for (let i = 0; i < text.length; i += 1) {\n const char = text[i];\n if (char !== '\\\\' || i + 1 >= text.length) {\n out += char;\n continue;\n }\n\n const next = text[i + 1];\n switch (next) {\n case 'n':\n out += '\\n';\n i += 1;\n break;\n case 't':\n out += '\\t';\n i += 1;\n break;\n case 'r':\n out += '\\r';\n i += 1;\n break;\n case 'b':\n out += '\\b';\n i += 1;\n break;\n case 'f':\n out += '\\f';\n i += 1;\n break;\n case 'v':\n out += '\\v';\n i += 1;\n break;\n case '0':\n out += '\\0';\n i += 1;\n break;\n case '\\\\':\n out += '\\\\';\n i += 1;\n break;\n case '\"':\n out += '\"';\n i += 1;\n break;\n case \"'\":\n out += \"'\";\n i += 1;\n break;\n case 'u': {\n const hex = text.slice(i + 2, i + 6);\n if (/^[0-9a-fA-F]{4}$/.test(hex)) {\n out += String.fromCharCode(Number.parseInt(hex, 16));\n i += 5;\n } else {\n out += char;\n }\n break;\n }\n case 'x': {\n const hex = text.slice(i + 2, i + 4);\n if (/^[0-9a-fA-F]{2}$/.test(hex)) {\n out += String.fromCharCode(Number.parseInt(hex, 16));\n i += 3;\n } else {\n out += char;\n }\n break;\n }\n default:\n out += char;\n break;\n }\n }\n return out;\n}\n\n// Decodes JSON/C-style escape sequences (e.g., \\n, \\t) in error messages, preserving real control characters and normalizing line endings.\nexport function decodeErrorMessageEscapes(text: string): string {\n const normalized = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n if (REAL_CONTROL_PATTERN.test(normalized) || !LITERAL_ESCAPE_PATTERN.test(normalized)) {\n // If the string contains real control characters or no literal escape sequences, return the normalized string.\n return normalized;\n }\n // else decode the literal escape sequences and normalize line endings\n return decodeLiteralEscapes(normalized).replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n}\n\n/**\n * Reads a display string from API-shaped errors: `message`, then nested\n * `error.message`. When neither exists, stringifies the value.\n */\nfunction messageFromErrorShaped(value: unknown): string | undefined {\n if (!isRecord(value)) return undefined;\n const direct = readNonEmptyString(value.message);\n if (direct != null) return direct;\n if (isRecord(value.error)) {\n return readNonEmptyString(value.error.message);\n }\n return undefined;\n}\n\nfunction stringifyError(error: unknown): string {\n if (typeof error === 'string') return error;\n if (isRecord(error)) {\n try {\n return JSON.stringify(error);\n } catch {\n return Object.prototype.toString.call(error);\n }\n }\n return String(error);\n}\n\n/**\n * User-facing error text. Prefers HTTP body `{ error: { message } }` when\n * present (e.g. TrueForgeError), then `error.message` / `error.error.message`,\n * then `fallback`, then a string form of the value.\n *\n * Escape sequences (`\\n`, `\\t`, `\\r`, `\\uXXXX`, …) are decoded for display when\n * still present as literal text.\n */\nexport function getErrorMessage(error: unknown, fallback?: string): string {\n if (typeof error === 'string') {\n const trimmed = error.trim();\n if (trimmed !== '') return decodeErrorMessageEscapes(error);\n return fallback != null ? decodeErrorMessageEscapes(fallback) : decodeErrorMessageEscapes(error);\n }\n\n if (isRecord(error) && 'body' in error) {\n const fromBody = messageFromErrorShaped(error.body);\n if (fromBody != null) return decodeErrorMessageEscapes(fromBody);\n if (error.body != null) {\n if (typeof error.body === 'string') {\n const trimmed = error.body.trim();\n if (trimmed !== '') return decodeErrorMessageEscapes(error.body);\n } else {\n return stringifyError(error.body);\n }\n }\n }\n\n const fromShape = messageFromErrorShaped(error);\n if (fromShape != null) return decodeErrorMessageEscapes(fromShape);\n\n if (fallback != null) return decodeErrorMessageEscapes(fallback);\n return stringifyError(error);\n}\n","'use client';\n\nimport type { ReactNode } from 'react';\n\nimport { cn } from './lib/cn.js';\n\n/** Shared title styles for page / chat chrome headers. */\nexport const pageHeaderTitleClassName = 'text-text-primary min-w-0 truncate text-md font-semibold';\n\nexport type PageHeaderProps = {\n /** Page name, or a custom title node (e.g. `NamedAgentHeaderLabel`). Strings use the shared h1 styles. */\n title?: ReactNode;\n /** Leading chrome (back / menu). */\n start?: ReactNode;\n /** Trailing actions; pushed to the end. */\n end?: ReactNode;\n /** Extra content between title and end (prefer `start` / `end` when possible). */\n children?: ReactNode;\n className?: string;\n};\n\n/** Shared shell/page header bar used by chat chrome and list pages.\n * `min-h-14` keeps a single-row bar aligned with Agent Config; wrapping end actions can grow the bar.\n */\nexport function PageHeader({ title, start, end, children, className }: PageHeaderProps) {\n return (\n <header\n className={cn(\n 'flex min-h-14 shrink-0 flex-wrap items-center gap-2 border-b border-border px-4 md:px-6',\n className,\n )}\n >\n {start}\n {typeof title === 'string' ? <h1 className={pageHeaderTitleClassName}>{title}</h1> : title}\n {children}\n {end != null ? <div className=\"ml-auto flex min-w-0 flex-wrap items-center gap-2\">{end}</div> : null}\n </header>\n );\n}\n","'use client';\n\nimport { createContext, useContext, type ReactNode } from 'react';\n\nconst CompactLayoutContext = createContext(false);\n\nexport function CompactLayoutProvider({ children }: { children: ReactNode }) {\n return <CompactLayoutContext.Provider value>{children}</CompactLayoutContext.Provider>;\n}\n\nexport function useCompactLayout() {\n return useContext(CompactLayoutContext);\n}\n","'use client';\n\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport { useOptionalServer } from '../../server/ServerContext.js';\nimport type { AgentSkill, AgentUIServer, ConnectorState, ListResult, ModelSelection } from '../../server/types.js';\nimport { getErrorMessage } from '../../utils/getErrorMessage.js';\n\n/** Picker page size for MCP infinite scroll. */\nexport const MCP_CONNECTORS_PAGE_SIZE = 50;\n\ntype DraftCatalogValue = {\n models: ModelSelection[];\n skills: AgentSkill[];\n connectors: ConnectorState[];\n connectorsHasMore: boolean;\n connectorsLoadMoreFailed: boolean;\n connectorsLoadingMore: boolean;\n loaded: boolean;\n loading: boolean;\n error: string | null;\n /** Kick off catalog fetch (idempotent). Call when a picker opens. */\n ensureLoaded: () => void;\n /** Reload all collections after settings mutate catalog-backed configuration. */\n refresh: () => void;\n /** Refresh connector auth state without reloading unrelated catalogs. */\n refreshConnectors: () => Promise<void>;\n /** Append the next MCP page when `connectorsHasMore`. */\n loadMoreConnectors: () => void;\n};\n\ntype DraftCatalogContextValue = DraftCatalogValue & {\n server: AgentUIServer | null;\n};\n\nconst DraftCatalogContext = createContext<DraftCatalogContextValue | null>(null);\n\nconst IDLE_ENSURE = () => undefined;\nconst IDLE_REFRESH = async () => undefined;\n\nfunction appendConnectors({\n previous,\n next,\n}: {\n previous: ConnectorState[];\n next: ConnectorState[];\n}): ConnectorState[] {\n if (next.length === 0) return previous;\n const seen = new Set(previous.map(connector => connector.id));\n const appended = next.filter(connector => !seen.has(connector.id));\n return appended.length === 0 ? previous : [...previous, ...appended];\n}\n\nasync function fetchMcpPage({\n server,\n pageToken,\n}: {\n server: AgentUIServer;\n pageToken?: string;\n}): Promise<ListResult<ConnectorState>> {\n if (server.listMcp != null) {\n return server.listMcp({\n limit: MCP_CONNECTORS_PAGE_SIZE,\n ...(pageToken === undefined ? {} : { pageToken }),\n });\n }\n const data = await server.getMcp();\n return { data };\n}\n\nexport function DraftCatalogProvider({ children }: { children: ReactNode }) {\n const server = useOptionalServer();\n const existing = useContext(DraftCatalogContext);\n if (existing?.server === server) {\n return children;\n }\n return <DraftCatalogStore server={server}>{children}</DraftCatalogStore>;\n}\n\nfunction DraftCatalogStore({ server, children }: { server: AgentUIServer | null; children: ReactNode }) {\n const [requestEpoch, setRequestEpoch] = useState<number | null>(null);\n const [models, setModels] = useState<ModelSelection[]>([]);\n const [skills, setSkills] = useState<AgentSkill[]>([]);\n const [connectors, setConnectors] = useState<ConnectorState[]>([]);\n const [connectorsNextPageToken, setConnectorsNextPageToken] = useState<string | undefined>(undefined);\n const [connectorsLoadMoreFailed, setConnectorsLoadMoreFailed] = useState(false);\n const [connectorsLoadingMore, setConnectorsLoadingMore] = useState(false);\n const [completedEpoch, setCompletedEpoch] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const connectorsNextPageTokenRef = useRef(connectorsNextPageToken);\n const connectorsLoadingMoreRef = useRef(connectorsLoadingMore);\n const loadMoreFailedRef = useRef(false);\n connectorsNextPageTokenRef.current = connectorsNextPageToken;\n connectorsLoadingMoreRef.current = connectorsLoadingMore;\n\n const ensureLoaded = useCallback(() => {\n setRequestEpoch(current => current ?? 0);\n }, []);\n\n const refresh = useCallback(() => {\n loadMoreFailedRef.current = false;\n setConnectorsLoadMoreFailed(false);\n setRequestEpoch(current => (current ?? -1) + 1);\n }, []);\n\n const refreshConnectors = useCallback(async () => {\n if (!server) return;\n setLoading(true);\n setError(null);\n loadMoreFailedRef.current = false;\n setConnectorsLoadMoreFailed(false);\n try {\n const page = await fetchMcpPage({ server });\n setConnectors(page.data);\n setConnectorsNextPageToken(page.nextPageToken);\n } catch (reason: unknown) {\n setError(getErrorMessage(reason, 'Failed to load connectors.'));\n } finally {\n setLoading(false);\n }\n }, [server]);\n\n const loadMoreConnectors = useCallback(() => {\n if (!server) return;\n const pageToken = connectorsNextPageTokenRef.current;\n if (pageToken == null || pageToken.length === 0 || connectorsLoadingMoreRef.current) return;\n\n setConnectorsLoadMoreFailed(false);\n setConnectorsLoadingMore(true);\n void fetchMcpPage({ server, pageToken })\n .then(page => {\n setConnectors(previous => appendConnectors({ previous, next: page.data }));\n setConnectorsNextPageToken(page.nextPageToken);\n // Clear a stale load-more failure once a retry succeeds.\n if (loadMoreFailedRef.current) {\n loadMoreFailedRef.current = false;\n setError(null);\n }\n })\n .catch((reason: unknown) => {\n loadMoreFailedRef.current = true;\n setConnectorsLoadMoreFailed(true);\n setError(getErrorMessage(reason, 'Failed to load more connectors.'));\n })\n .finally(() => {\n setConnectorsLoadingMore(false);\n });\n }, [server]);\n\n useEffect(() => {\n if (requestEpoch === null || !server) return;\n let cancelled = false;\n setLoading(true);\n setError(null);\n loadMoreFailedRef.current = false;\n setConnectorsLoadMoreFailed(false);\n // Settle each list alone so one failing picker does not blank the others.\n void Promise.allSettled([server.getModels(), server.getSkills(), fetchMcpPage({ server })]).then(\n ([modelsResult, skillsResult, mcpResult]) => {\n if (cancelled) return;\n const errors: string[] = [];\n if (modelsResult.status === 'fulfilled') {\n setModels(modelsResult.value);\n } else {\n errors.push(getErrorMessage(modelsResult.reason, 'Failed to load models.'));\n }\n if (skillsResult.status === 'fulfilled') {\n setSkills(skillsResult.value);\n } else {\n errors.push(getErrorMessage(skillsResult.reason, 'Failed to load skills.'));\n }\n if (mcpResult.status === 'fulfilled') {\n setConnectors(mcpResult.value.data);\n setConnectorsNextPageToken(mcpResult.value.nextPageToken);\n } else {\n errors.push(getErrorMessage(mcpResult.reason, 'Failed to load connectors.'));\n }\n setError(errors[0] ?? null);\n setCompletedEpoch(requestEpoch);\n setLoading(false);\n },\n );\n return () => {\n cancelled = true;\n };\n }, [requestEpoch, server]);\n\n const connectorsHasMore = connectorsNextPageToken != null && connectorsNextPageToken.length > 0;\n const loaded = requestEpoch !== null && completedEpoch === requestEpoch;\n const value = useMemo(\n () => ({\n server,\n models,\n skills,\n connectors,\n connectorsHasMore,\n connectorsLoadMoreFailed,\n connectorsLoadingMore,\n loaded,\n loading,\n error,\n ensureLoaded,\n refresh,\n refreshConnectors,\n loadMoreConnectors,\n }),\n [\n server,\n models,\n skills,\n connectors,\n connectorsHasMore,\n connectorsLoadMoreFailed,\n connectorsLoadingMore,\n loaded,\n loading,\n error,\n ensureLoaded,\n refresh,\n refreshConnectors,\n loadMoreConnectors,\n ],\n );\n\n return <DraftCatalogContext.Provider value={value}>{children}</DraftCatalogContext.Provider>;\n}\n\nexport function useDraftCatalog(): DraftCatalogValue {\n const ctx = useContext(DraftCatalogContext);\n if (ctx == null) {\n return {\n models: [],\n skills: [],\n connectors: [],\n connectorsHasMore: false,\n connectorsLoadMoreFailed: false,\n connectorsLoadingMore: false,\n loaded: false,\n loading: false,\n error: null,\n ensureLoaded: IDLE_ENSURE,\n refresh: IDLE_ENSURE,\n refreshConnectors: IDLE_REFRESH,\n loadMoreConnectors: IDLE_ENSURE,\n };\n }\n return ctx;\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,eAAe,gBAAgB,kBAAsD;;;ACA9F;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAQH,SAYE,KAZF;AAFJ,SAAS,MAAM,EAAE,OAAO,IAAI,GAAG,MAAM,GAAyD;AAC5F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACd,GAAG;AAAA,MAEJ;AAAA,4BAAC,UAAK,GAAE,mBAAkB;AAAA,QAC1B,oBAAC,UAAK,GAAE,kIAAiI;AAAA,QACzI,oBAAC,UAAK,GAAE,aAAY;AAAA,QACpB,oBAAC,UAAK,GAAE,2BAA0B;AAAA;AAAA;AAAA,EACpC;AAEJ;AAEA,IAAM,WAAW,oBAAI,IAAuB;AAMrC,SAAS,cAAc,OAAsB;AAClD,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,aAAS,IAAI,MAAM,IAAI;AAAA,EACzB;AACF;AAMO,SAAS,gBAAgB,MAA0C;AACxE,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,SAAO,KAAK,KAAK,SAAS,CAAC,KAAK;AAClC;AAEA,IAAM,WAAsC;AAAA,EAC1C,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EACd,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,OAAO;AAAA,EACP,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,MAAM;AAAA,EACN,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,KAAK;AAAA,EACL,eAAe;AAAA,EACf,uBAAuB;AAAA,EACvB,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,MAAM;AAAA,EACN,WAAW;AAAA,EACX,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,6BAA6B;AAAA,EAC7B,QAAQ;AACV;AAEA,WAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,WAAS,IAAI,MAAM,IAAI;AACzB;AAGO,SAAS,WAAW,MAAc,YAA6C;AACpF,MAAI,cAAc,QAAQ,YAAY;AACpC,WAAO,WAAW,IAAI;AAAA,EACxB;AACA,SAAO,SAAS,IAAI,IAAI;AAC1B;;;ADxJS,0BAAAA,YAAA;AAnCT,SAAS,YAAY,OAA0C;AAC7D,MAAI,OAAO,UAAU,WAAY,QAAO;AAExC,SACE,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,eAAe,KAAK,KACrB,CAAC,MAAM,QAAQ,KAAK,KACpB,cAAc;AAElB;AAEA,SAAS,YAAY,OAAkB,OAAmC;AACxE,MAAI,YAAY,KAAK,GAAG;AACtB,UAAM,EAAE,MAAM,WAAW,OAAO,GAAG,KAAK,IAAI;AAC5C,WAAO,cAAc,OAAO;AAAA,MAC1B,WAAW,GAAG,yBAAyB,SAAS;AAAA,MAChD;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,eAAe,KAAK,YAAY,IAAI,SAAa,KAAK,aAAa,KAAK;AAAA,MACxE,cAAc,KAAK,YAAY;AAAA,MAC/B,GAAI,KAAK,aAAa,MAAM,SAAY,CAAC,IAAI,EAAE,eAAe,KAAK,aAAa,EAAE;AAAA,MAClF,MAAM,KAAK,YAAY,IAAI,QAAQ;AAAA,IACrC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,SAAS,KAAK,EAAE,MAAM,WAAW,OAAO,OAAO,OAAO,GAAG,KAAK,GAAc;AACjF,QAAM,aAAa,WAAW,YAAY,GAAG;AAC7C,QAAM,WAAW,gBAAgB,IAAI;AACrC,QAAM,QAAQ,WAAW,UAAU,UAAU;AAC7C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,gBAAAA,KAAA,YAAG,sBAAY,OAAO,EAAE,WAAW,OAAO,MAAM,GAAG,KAAK,CAAC,GAAE;AACpE;;;AExDA,OAAkB;AAwBZ,gBAAAC,YAAA;AAhBC,SAAS,QAAQ,EAAE,OAAO,IAAI,WAAW,GAAG,MAAM,GAAiB;AACxE,QAAM,IAAK,OAAO,IAAK;AACvB,QAAM,KAAK,OAAO;AAClB,QAAM,gBAAgB,IAAI,KAAK,KAAK;AAEpC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAW;AAAA,MACX,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS,OAAO,IAAI,IAAI,IAAI;AAAA,MAC5B,MAAK;AAAA,MACL,WAAW,GAAG,gBAAgB,SAAS;AAAA,MACtC,GAAG;AAAA,MAEJ,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,IAAI;AAAA,UACJ;AAAA,UACA,QAAO;AAAA,UACP,aAAa;AAAA,UACb,eAAc;AAAA,UACd,iBAAiB,GAAG,gBAAgB,IAAI,IAAI,gBAAgB,IAAI;AAAA,UAChE,SAAS;AAAA;AAAA,MACX;AAAA;AAAA,EACF;AAEJ;;;AC/BA,IAAM,iBAAmD;AAAA,EACvD,SAAS;AAAA,EACT,WACE;AAAA,EACF,OAAO;AAAA,EACP,aAAa;AAAA,EACb,SACE;AACJ;AAEA,IAAM,cAA6C;AAAA,EACjD,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR;AAEA,IAAM,cACJ;AAGK,SAAS,eAAe;AAAA,EAC7B,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,IAII,CAAC,GAAW;AACd,SAAO,GAAG,aAAa,eAAe,OAAO,GAAG,YAAY,IAAI,GAAG,SAAS;AAC9E;;;ACpCA,SAAS,SAAS,OAAkD;AAClE,SAAO,SAAS,QAAQ,OAAO,UAAU;AAC3C;AAEA,SAAS,mBAAmB,OAAoC;AAC9D,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,KAAK,QAAQ;AACpE;AAEA,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAE7B,SAAS,qBAAqB,MAAsB;AAClD,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,OAAO,KAAK,CAAC;AACnB,QAAI,SAAS,QAAQ,IAAI,KAAK,KAAK,QAAQ;AACzC,aAAO;AACP;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,IAAI,CAAC;AACvB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK;AACH,eAAO;AACP,aAAK;AACL;AAAA,MACF,KAAK,KAAK;AACR,cAAM,MAAM,KAAK,MAAM,IAAI,GAAG,IAAI,CAAC;AACnC,YAAI,mBAAmB,KAAK,GAAG,GAAG;AAChC,iBAAO,OAAO,aAAa,OAAO,SAAS,KAAK,EAAE,CAAC;AACnD,eAAK;AAAA,QACP,OAAO;AACL,iBAAO;AAAA,QACT;AACA;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,cAAM,MAAM,KAAK,MAAM,IAAI,GAAG,IAAI,CAAC;AACnC,YAAI,mBAAmB,KAAK,GAAG,GAAG;AAChC,iBAAO,OAAO,aAAa,OAAO,SAAS,KAAK,EAAE,CAAC;AACnD,eAAK;AAAA,QACP,OAAO;AACL,iBAAO;AAAA,QACT;AACA;AAAA,MACF;AAAA,MACA;AACE,eAAO;AACP;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,0BAA0B,MAAsB;AAC9D,QAAM,aAAa,KAAK,QAAQ,SAAS,IAAI,EAAE,QAAQ,OAAO,IAAI;AAClE,MAAI,qBAAqB,KAAK,UAAU,KAAK,CAAC,uBAAuB,KAAK,UAAU,GAAG;AAErF,WAAO;AAAA,EACT;AAEA,SAAO,qBAAqB,UAAU,EAAE,QAAQ,SAAS,IAAI,EAAE,QAAQ,OAAO,IAAI;AACpF;AAMA,SAAS,uBAAuB,OAAoC;AAClE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,SAAS,mBAAmB,MAAM,OAAO;AAC/C,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,SAAS,MAAM,KAAK,GAAG;AACzB,WAAO,mBAAmB,MAAM,MAAM,OAAO;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAwB;AAC9C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,SAAS,KAAK,GAAG;AACnB,QAAI;AACF,aAAO,KAAK,UAAU,KAAK;AAAA,IAC7B,QAAQ;AACN,aAAO,OAAO,UAAU,SAAS,KAAK,KAAK;AAAA,IAC7C;AAAA,EACF;AACA,SAAO,OAAO,KAAK;AACrB;AAUO,SAAS,gBAAgB,OAAgB,UAA2B;AACzE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,YAAY,GAAI,QAAO,0BAA0B,KAAK;AAC1D,WAAO,YAAY,OAAO,0BAA0B,QAAQ,IAAI,0BAA0B,KAAK;AAAA,EACjG;AAEA,MAAI,SAAS,KAAK,KAAK,UAAU,OAAO;AACtC,UAAM,WAAW,uBAAuB,MAAM,IAAI;AAClD,QAAI,YAAY,KAAM,QAAO,0BAA0B,QAAQ;AAC/D,QAAI,MAAM,QAAQ,MAAM;AACtB,UAAI,OAAO,MAAM,SAAS,UAAU;AAClC,cAAM,UAAU,MAAM,KAAK,KAAK;AAChC,YAAI,YAAY,GAAI,QAAO,0BAA0B,MAAM,IAAI;AAAA,MACjE,OAAO;AACL,eAAO,eAAe,MAAM,IAAI;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,uBAAuB,KAAK;AAC9C,MAAI,aAAa,KAAM,QAAO,0BAA0B,SAAS;AAEjE,MAAI,YAAY,KAAM,QAAO,0BAA0B,QAAQ;AAC/D,SAAO,eAAe,KAAK;AAC7B;;;ACtII,SAO+B,OAAAC,MAP/B,QAAAC,aAAA;AAnBG,IAAM,2BAA2B;AAiBjC,SAAS,WAAW,EAAE,OAAO,OAAO,KAAK,UAAU,UAAU,GAAoB;AACtF,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,QACA,OAAO,UAAU,WAAW,gBAAAD,KAAC,QAAG,WAAW,0BAA2B,iBAAM,IAAQ;AAAA,QACpF;AAAA,QACA,OAAO,OAAO,gBAAAA,KAAC,SAAI,WAAU,qDAAqD,eAAI,IAAS;AAAA;AAAA;AAAA,EAClG;AAEJ;;;ACpCA,SAAS,eAAe,cAAAE,mBAAkC;AAKjD,gBAAAC,YAAA;AAHT,IAAM,uBAAuB,cAAc,KAAK;AAEzC,SAAS,sBAAsB,EAAE,SAAS,GAA4B;AAC3E,SAAO,gBAAAA,KAAC,qBAAqB,UAArB,EAA8B,OAAK,MAAE,UAAS;AACxD;AAEO,SAAS,mBAAmB;AACjC,SAAOD,YAAW,oBAAoB;AACxC;;;ACVA,SAAS,iBAAAE,gBAAe,aAAa,cAAAC,aAAY,WAAW,SAAS,QAAQ,gBAAgC;AA0EpG,gBAAAC,YAAA;AAnEF,IAAM,2BAA2B;AA0BxC,IAAM,sBAAsBC,eAA+C,IAAI;AAE/E,IAAM,cAAc,MAAM;AAC1B,IAAM,eAAe,YAAY;AAEjC,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AACF,GAGqB;AACnB,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,OAAO,IAAI,IAAI,SAAS,IAAI,eAAa,UAAU,EAAE,CAAC;AAC5D,QAAM,WAAW,KAAK,OAAO,eAAa,CAAC,KAAK,IAAI,UAAU,EAAE,CAAC;AACjE,SAAO,SAAS,WAAW,IAAI,WAAW,CAAC,GAAG,UAAU,GAAG,QAAQ;AACrE;AAEA,eAAe,aAAa;AAAA,EAC1B;AAAA,EACA;AACF,GAGwC;AACtC,MAAI,OAAO,WAAW,MAAM;AAC1B,WAAO,OAAO,QAAQ;AAAA,MACpB,OAAO;AAAA,MACP,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IACjD,CAAC;AAAA,EACH;AACA,QAAM,OAAO,MAAM,OAAO,OAAO;AACjC,SAAO,EAAE,KAAK;AAChB;AAEO,SAAS,qBAAqB,EAAE,SAAS,GAA4B;AAC1E,QAAM,SAAS,kBAAkB;AACjC,QAAM,WAAWC,YAAW,mBAAmB;AAC/C,MAAI,UAAU,WAAW,QAAQ;AAC/B,WAAO;AAAA,EACT;AACA,SAAO,gBAAAF,KAAC,qBAAkB,QAAiB,UAAS;AACtD;AAEA,SAAS,kBAAkB,EAAE,QAAQ,SAAS,GAA0D;AACtG,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AACpE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA2B,CAAC,CAAC;AACzD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAuB,CAAC,CAAC;AACrD,QAAM,CAAC,YAAY,aAAa,IAAI,SAA2B,CAAC,CAAC;AACjE,QAAM,CAAC,yBAAyB,0BAA0B,IAAI,SAA6B,MAAS;AACpG,QAAM,CAAC,0BAA0B,2BAA2B,IAAI,SAAS,KAAK;AAC9E,QAAM,CAAC,uBAAuB,wBAAwB,IAAI,SAAS,KAAK;AACxE,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAwB,IAAI;AACxE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAEtD,QAAM,6BAA6B,OAAO,uBAAuB;AACjE,QAAM,2BAA2B,OAAO,qBAAqB;AAC7D,QAAM,oBAAoB,OAAO,KAAK;AACtC,6BAA2B,UAAU;AACrC,2BAAyB,UAAU;AAEnC,QAAM,eAAe,YAAY,MAAM;AACrC,oBAAgB,aAAW,WAAW,CAAC;AAAA,EACzC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM;AAChC,sBAAkB,UAAU;AAC5B,gCAA4B,KAAK;AACjC,oBAAgB,cAAY,WAAW,MAAM,CAAC;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,YAAY,YAAY;AAChD,QAAI,CAAC,OAAQ;AACb,eAAW,IAAI;AACf,aAAS,IAAI;AACb,sBAAkB,UAAU;AAC5B,gCAA4B,KAAK;AACjC,QAAI;AACF,YAAM,OAAO,MAAM,aAAa,EAAE,OAAO,CAAC;AAC1C,oBAAc,KAAK,IAAI;AACvB,iCAA2B,KAAK,aAAa;AAAA,IAC/C,SAAS,QAAiB;AACxB,eAAS,gBAAgB,QAAQ,4BAA4B,CAAC;AAAA,IAChE,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,qBAAqB,YAAY,MAAM;AAC3C,QAAI,CAAC,OAAQ;AACb,UAAM,YAAY,2BAA2B;AAC7C,QAAI,aAAa,QAAQ,UAAU,WAAW,KAAK,yBAAyB,QAAS;AAErF,gCAA4B,KAAK;AACjC,6BAAyB,IAAI;AAC7B,SAAK,aAAa,EAAE,QAAQ,UAAU,CAAC,EACpC,KAAK,UAAQ;AACZ,oBAAc,cAAY,iBAAiB,EAAE,UAAU,MAAM,KAAK,KAAK,CAAC,CAAC;AACzE,iCAA2B,KAAK,aAAa;AAE7C,UAAI,kBAAkB,SAAS;AAC7B,0BAAkB,UAAU;AAC5B,iBAAS,IAAI;AAAA,MACf;AAAA,IACF,CAAC,EACA,MAAM,CAAC,WAAoB;AAC1B,wBAAkB,UAAU;AAC5B,kCAA4B,IAAI;AAChC,eAAS,gBAAgB,QAAQ,iCAAiC,CAAC;AAAA,IACrE,CAAC,EACA,QAAQ,MAAM;AACb,+BAAyB,KAAK;AAAA,IAChC,CAAC;AAAA,EACL,GAAG,CAAC,MAAM,CAAC;AAEX,YAAU,MAAM;AACd,QAAI,iBAAiB,QAAQ,CAAC,OAAQ;AACtC,QAAI,YAAY;AAChB,eAAW,IAAI;AACf,aAAS,IAAI;AACb,sBAAkB,UAAU;AAC5B,gCAA4B,KAAK;AAEjC,SAAK,QAAQ,WAAW,CAAC,OAAO,UAAU,GAAG,OAAO,UAAU,GAAG,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE;AAAA,MAC1F,CAAC,CAAC,cAAc,cAAc,SAAS,MAAM;AAC3C,YAAI,UAAW;AACf,cAAM,SAAmB,CAAC;AAC1B,YAAI,aAAa,WAAW,aAAa;AACvC,oBAAU,aAAa,KAAK;AAAA,QAC9B,OAAO;AACL,iBAAO,KAAK,gBAAgB,aAAa,QAAQ,wBAAwB,CAAC;AAAA,QAC5E;AACA,YAAI,aAAa,WAAW,aAAa;AACvC,oBAAU,aAAa,KAAK;AAAA,QAC9B,OAAO;AACL,iBAAO,KAAK,gBAAgB,aAAa,QAAQ,wBAAwB,CAAC;AAAA,QAC5E;AACA,YAAI,UAAU,WAAW,aAAa;AACpC,wBAAc,UAAU,MAAM,IAAI;AAClC,qCAA2B,UAAU,MAAM,aAAa;AAAA,QAC1D,OAAO;AACL,iBAAO,KAAK,gBAAgB,UAAU,QAAQ,4BAA4B,CAAC;AAAA,QAC7E;AACA,iBAAS,OAAO,CAAC,KAAK,IAAI;AAC1B,0BAAkB,YAAY;AAC9B,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF;AACA,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,cAAc,MAAM,CAAC;AAEzB,QAAM,oBAAoB,2BAA2B,QAAQ,wBAAwB,SAAS;AAC9F,QAAM,SAAS,iBAAiB,QAAQ,mBAAmB;AAC3D,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,gBAAAA,KAAC,oBAAoB,UAApB,EAA6B,OAAe,UAAS;AAC/D;AAEO,SAAS,kBAAqC;AACnD,QAAM,MAAME,YAAW,mBAAmB;AAC1C,MAAI,OAAO,MAAM;AACf,WAAO;AAAA,MACL,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,MACT,YAAY,CAAC;AAAA,MACb,mBAAmB;AAAA,MACnB,0BAA0B;AAAA,MAC1B,uBAAuB;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,OAAO;AAAA,MACP,cAAc;AAAA,MACd,SAAS;AAAA,MACT,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AACT;","names":["jsx","jsx","jsx","jsxs","useContext","jsx","createContext","useContext","jsx","createContext","useContext"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/routing/ResolvedRoutesContext.tsx
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var ResolvedRoutesContext = createContext(null);
|
|
5
|
+
function ResolvedRoutesProvider({ routes, children }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(ResolvedRoutesContext.Provider, { value: routes, children });
|
|
7
|
+
}
|
|
8
|
+
function useOptionalResolvedRoutes() {
|
|
9
|
+
return useContext(ResolvedRoutesContext);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
ResolvedRoutesProvider,
|
|
14
|
+
useOptionalResolvedRoutes
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=chunk-Y6S4OVVQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/routing/ResolvedRoutesContext.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, type ReactNode } from 'react';\n\nimport type { ResolvedRoutes } from './types.js';\n\nconst ResolvedRoutesContext = createContext<ResolvedRoutes | null>(null);\n\n/** Present only when the shell is mounted under `withRouter`. */\nexport function ResolvedRoutesProvider({ routes, children }: { routes: ResolvedRoutes; children: ReactNode }) {\n return <ResolvedRoutesContext.Provider value={routes}>{children}</ResolvedRoutesContext.Provider>;\n}\n\nexport function useOptionalResolvedRoutes(): ResolvedRoutes | null {\n return useContext(ResolvedRoutesContext);\n}\n"],"mappings":";AAEA,SAAS,eAAe,kBAAkC;AAQjD;AAJT,IAAM,wBAAwB,cAAqC,IAAI;AAGhE,SAAS,uBAAuB,EAAE,QAAQ,SAAS,GAAoD;AAC5G,SAAO,oBAAC,sBAAsB,UAAtB,EAA+B,OAAO,QAAS,UAAS;AAClE;AAEO,SAAS,4BAAmD;AACjE,SAAO,WAAW,qBAAqB;AACzC;","names":[]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatCostUsd,
|
|
3
|
+
formatDurationMs,
|
|
4
|
+
useThemeMode
|
|
5
|
+
} from "./chunk-ZTMKFZQ3.js";
|
|
6
|
+
|
|
7
|
+
// src/atoms/agent-details/AgentMetricChart.tsx
|
|
8
|
+
import {
|
|
9
|
+
CategoryScale,
|
|
10
|
+
Chart as ChartJS,
|
|
11
|
+
Legend,
|
|
12
|
+
LinearScale,
|
|
13
|
+
LineElement,
|
|
14
|
+
PointElement,
|
|
15
|
+
Tooltip
|
|
16
|
+
} from "chart.js";
|
|
17
|
+
import { useMemo } from "react";
|
|
18
|
+
import { Line } from "react-chartjs-2";
|
|
19
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
20
|
+
ChartJS.register(CategoryScale, LinearScale, LineElement, PointElement, Legend, Tooltip);
|
|
21
|
+
var LIGHT_COLORS = ["#2563eb", "#16a34a", "#9333ea", "#ea580c", "#0891b2"];
|
|
22
|
+
var DARK_COLORS = ["#60a5fa", "#4ade80", "#c084fc", "#fb923c", "#22d3ee"];
|
|
23
|
+
var numberFormatter = new Intl.NumberFormat(void 0, { maximumFractionDigits: 4 });
|
|
24
|
+
var timestampFormatter = new Intl.DateTimeFormat(void 0, {
|
|
25
|
+
month: "short",
|
|
26
|
+
day: "numeric",
|
|
27
|
+
hour: "numeric",
|
|
28
|
+
minute: "2-digit"
|
|
29
|
+
});
|
|
30
|
+
function formatValue(value, unit) {
|
|
31
|
+
if (unit === "$") return formatCostUsd(value);
|
|
32
|
+
if (unit === "ms") return formatDurationMs(value);
|
|
33
|
+
return `${numberFormatter.format(value)}${unit === "count" || unit.length === 0 ? "" : ` ${unit}`}`;
|
|
34
|
+
}
|
|
35
|
+
function formatTimestamp(timestamp) {
|
|
36
|
+
const date = new Date(timestamp);
|
|
37
|
+
return Number.isNaN(date.getTime()) ? timestamp : timestampFormatter.format(date);
|
|
38
|
+
}
|
|
39
|
+
function AgentMetricChart({ graph, definition, error }) {
|
|
40
|
+
const mode = useThemeMode();
|
|
41
|
+
const colors = mode === "dark" ? DARK_COLORS : LIGHT_COLORS;
|
|
42
|
+
const axisColor = mode === "dark" ? "#a1a1aa" : "#71717a";
|
|
43
|
+
const gridColor = mode === "dark" ? "#27272a" : "#e4e4e7";
|
|
44
|
+
const labels = useMemo(
|
|
45
|
+
() => graph == null ? [] : [...new Set(graph.graphLines.flatMap((line) => line.values.map((point) => point.timestamp)))].sort(),
|
|
46
|
+
[graph]
|
|
47
|
+
);
|
|
48
|
+
const data = useMemo(
|
|
49
|
+
() => ({
|
|
50
|
+
labels: labels.map(formatTimestamp),
|
|
51
|
+
datasets: graph?.graphLines.map((line, index) => {
|
|
52
|
+
const valuesByTimestamp = new Map(line.values.map((point) => [point.timestamp, point.value]));
|
|
53
|
+
const color = colors[index % colors.length];
|
|
54
|
+
return {
|
|
55
|
+
label: line.name,
|
|
56
|
+
data: labels.map((timestamp) => valuesByTimestamp.get(timestamp) ?? null),
|
|
57
|
+
borderColor: color,
|
|
58
|
+
backgroundColor: color,
|
|
59
|
+
pointRadius: 2,
|
|
60
|
+
pointHoverRadius: 4,
|
|
61
|
+
borderWidth: 2,
|
|
62
|
+
tension: 0.25,
|
|
63
|
+
spanGaps: true
|
|
64
|
+
};
|
|
65
|
+
}) ?? []
|
|
66
|
+
}),
|
|
67
|
+
[colors, graph, labels]
|
|
68
|
+
);
|
|
69
|
+
const options = useMemo(
|
|
70
|
+
() => ({
|
|
71
|
+
responsive: true,
|
|
72
|
+
maintainAspectRatio: false,
|
|
73
|
+
animation: false,
|
|
74
|
+
interaction: { intersect: false, mode: "index" },
|
|
75
|
+
plugins: {
|
|
76
|
+
legend: {
|
|
77
|
+
display: (graph?.graphLines.length ?? 0) > 1,
|
|
78
|
+
labels: { color: axisColor, boxWidth: 10, boxHeight: 2 }
|
|
79
|
+
},
|
|
80
|
+
tooltip: {
|
|
81
|
+
callbacks: {
|
|
82
|
+
label: (context) => {
|
|
83
|
+
const value = context.parsed.y;
|
|
84
|
+
return `${context.dataset.label ?? ""}: ${value == null ? "\u2014" : formatValue(value, graph?.unit ?? "")}`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
scales: {
|
|
90
|
+
x: {
|
|
91
|
+
grid: { display: false },
|
|
92
|
+
border: { color: gridColor },
|
|
93
|
+
ticks: { color: axisColor, maxRotation: 0, autoSkip: true, maxTicksLimit: 8 }
|
|
94
|
+
},
|
|
95
|
+
y: {
|
|
96
|
+
beginAtZero: true,
|
|
97
|
+
grid: { color: gridColor },
|
|
98
|
+
border: { display: false },
|
|
99
|
+
ticks: {
|
|
100
|
+
color: axisColor,
|
|
101
|
+
callback: (value) => formatValue(Number(value), graph?.unit ?? "")
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}),
|
|
106
|
+
[axisColor, graph, gridColor]
|
|
107
|
+
);
|
|
108
|
+
const hasData = graph?.graphLines.some((line) => line.values.length > 0) === true;
|
|
109
|
+
return /* @__PURE__ */ jsxs("section", { className: "min-w-0 rounded-lg border border-border bg-card-bg p-4", "data-slot": "agent-metric-chart", children: [
|
|
110
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-text-primary", children: graph?.displayName ?? definition.displayName }),
|
|
111
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-text-secondary", children: graph?.description ?? definition.description }),
|
|
112
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 h-64", children: error != null ? /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-sm text-failure-bg", children: error }) : hasData ? /* @__PURE__ */ jsx(Line, { data, options }) : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-sm text-text-secondary", children: "No data" }) })
|
|
113
|
+
] });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export {
|
|
117
|
+
AgentMetricChart
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=chunk-ZKNUMH2M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/atoms/agent-details/AgentMetricChart.tsx"],"sourcesContent":["'use client';\n\nimport {\n CategoryScale,\n Chart as ChartJS,\n Legend,\n LinearScale,\n LineElement,\n PointElement,\n Tooltip,\n type ChartData,\n type ChartOptions,\n} from 'chart.js';\nimport { useMemo, type ComponentType } from 'react';\nimport { Line } from 'react-chartjs-2';\n\nimport { useThemeMode } from '../../theme/SlotsProvider.js';\nimport { formatCostUsd, formatDurationMs } from '../../utils/sessionDisplayFormat.js';\nimport type { AgentMetricChartProps } from './types.js';\n\nChartJS.register(CategoryScale, LinearScale, LineElement, PointElement, Legend, Tooltip);\n\nconst LIGHT_COLORS = ['#2563eb', '#16a34a', '#9333ea', '#ea580c', '#0891b2'];\nconst DARK_COLORS = ['#60a5fa', '#4ade80', '#c084fc', '#fb923c', '#22d3ee'];\nconst numberFormatter = new Intl.NumberFormat(undefined, { maximumFractionDigits: 4 });\nconst timestampFormatter = new Intl.DateTimeFormat(undefined, {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n});\n\nfunction formatValue(value: number, unit: string): string {\n if (unit === '$') return formatCostUsd(value);\n if (unit === 'ms') return formatDurationMs(value);\n return `${numberFormatter.format(value)}${unit === 'count' || unit.length === 0 ? '' : ` ${unit}`}`;\n}\n\nfunction formatTimestamp(timestamp: string): string {\n const date = new Date(timestamp);\n return Number.isNaN(date.getTime()) ? timestamp : timestampFormatter.format(date);\n}\n\nexport function AgentMetricChart({ graph, definition, error }: AgentMetricChartProps) {\n const mode = useThemeMode();\n const colors = mode === 'dark' ? DARK_COLORS : LIGHT_COLORS;\n const axisColor = mode === 'dark' ? '#a1a1aa' : '#71717a';\n const gridColor = mode === 'dark' ? '#27272a' : '#e4e4e7';\n const labels = useMemo(\n () =>\n graph == null\n ? []\n : [...new Set(graph.graphLines.flatMap(line => line.values.map(point => point.timestamp)))].sort(),\n [graph],\n );\n const data = useMemo<ChartData<'line', Array<number | null>, string>>(\n () => ({\n labels: labels.map(formatTimestamp),\n datasets:\n graph?.graphLines.map((line, index) => {\n const valuesByTimestamp = new Map(line.values.map(point => [point.timestamp, point.value]));\n const color = colors[index % colors.length];\n return {\n label: line.name,\n data: labels.map(timestamp => valuesByTimestamp.get(timestamp) ?? null),\n borderColor: color,\n backgroundColor: color,\n pointRadius: 2,\n pointHoverRadius: 4,\n borderWidth: 2,\n tension: 0.25,\n spanGaps: true,\n };\n }) ?? [],\n }),\n [colors, graph, labels],\n );\n const options = useMemo<ChartOptions<'line'>>(\n () => ({\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n interaction: { intersect: false, mode: 'index' },\n plugins: {\n legend: {\n display: (graph?.graphLines.length ?? 0) > 1,\n labels: { color: axisColor, boxWidth: 10, boxHeight: 2 },\n },\n tooltip: {\n callbacks: {\n label: context => {\n const value = context.parsed.y;\n return `${context.dataset.label ?? ''}: ${value == null ? '—' : formatValue(value, graph?.unit ?? '')}`;\n },\n },\n },\n },\n scales: {\n x: {\n grid: { display: false },\n border: { color: gridColor },\n ticks: { color: axisColor, maxRotation: 0, autoSkip: true, maxTicksLimit: 8 },\n },\n y: {\n beginAtZero: true,\n grid: { color: gridColor },\n border: { display: false },\n ticks: {\n color: axisColor,\n callback: value => formatValue(Number(value), graph?.unit ?? ''),\n },\n },\n },\n }),\n [axisColor, graph, gridColor],\n );\n const hasData = graph?.graphLines.some(line => line.values.length > 0) === true;\n\n return (\n <section className=\"min-w-0 rounded-lg border border-border bg-card-bg p-4\" data-slot=\"agent-metric-chart\">\n <h3 className=\"text-sm font-semibold text-text-primary\">{graph?.displayName ?? definition.displayName}</h3>\n <p className=\"mt-1 text-xs text-text-secondary\">{graph?.description ?? definition.description}</p>\n <div className=\"mt-4 h-64\">\n {error != null ? (\n <div className=\"flex h-full items-center justify-center text-sm text-failure-bg\">{error}</div>\n ) : hasData ? (\n <Line data={data} options={options} />\n ) : (\n <div className=\"flex h-full items-center justify-center text-sm text-text-secondary\">No data</div>\n )}\n </div>\n </section>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentMetricChart: ComponentType<AgentMetricChartProps>;\n }\n}\n"],"mappings":"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","names":[]}
|