@truefoundry/trueforge-ui 0.3.0-rc.1 → 0.3.0-rc.11
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 +156 -0
- package/README.md +23 -8
- package/dist/{AgentCodeSnippets-NZOFJE57.js → AgentCodeSnippets-CHDVZHHK.js} +38 -23
- package/dist/AgentCodeSnippets-CHDVZHHK.js.map +1 -0
- package/dist/AgentMetricChart-6RGWFMJE.js +15 -0
- package/dist/AgentOverview-3LJZ6MO7.js +311 -0
- package/dist/AgentOverview-3LJZ6MO7.js.map +1 -0
- package/dist/{AgentSessionEventTimeline-26Z6IB3B.js → AgentSessionEventTimeline-5GOJKT7D.js} +19 -10
- package/dist/AgentSessionEventTimeline-5GOJKT7D.js.map +1 -0
- package/dist/{AgentSessionEventTimelineChart-CGCU7WBK.js → AgentSessionEventTimelineChart-UYG3JQMP.js} +144 -57
- package/dist/AgentSessionEventTimelineChart-UYG3JQMP.js.map +1 -0
- package/dist/{AgentSessions-3MPDZASK.js → AgentSessions-KUABCQ4W.js} +140 -27
- package/dist/AgentSessions-KUABCQ4W.js.map +1 -0
- package/dist/{ConnectorSettings-MXFRWWR6.js → ConnectorSettings-PED5C2P7.js} +162 -126
- package/dist/ConnectorSettings-PED5C2P7.js.map +1 -0
- package/dist/{DockLayout-LM4AFMFY.js → DockLayout-ACM7BVIH.js} +10 -10
- package/dist/{DrawerLayout-JR3O6RRB.js → DrawerLayout-SGBYRKHI.js} +14 -12
- package/dist/DrawerLayout-SGBYRKHI.js.map +1 -0
- package/dist/{ModelSettings-G7IFNC2Y.js → ModelSettings-GJTVFXFY.js} +22 -28
- package/dist/ModelSettings-GJTVFXFY.js.map +1 -0
- package/dist/OpenUiFenceBlock-MJTC2VJ5.js +9 -0
- package/dist/{SandboxSettings-NXAANMAX.js → SandboxSettings-VETQ7UPE.js} +17 -21
- package/dist/SandboxSettings-VETQ7UPE.js.map +1 -0
- package/dist/SchedulesPage-LHJ3U2VM.js +15 -0
- package/dist/{SettingsBuilder-L34IQ56S.js → SettingsBuilder-5ZCU66FF.js} +9 -9
- package/dist/{SettingsBuilder-L34IQ56S.js.map → SettingsBuilder-5ZCU66FF.js.map} +1 -1
- package/dist/{ShellRouteSync-CEBETGEJ.js → ShellRouteSync-SJXFKUAJ.js} +171 -26
- package/dist/ShellRouteSync-SJXFKUAJ.js.map +1 -0
- package/dist/{SidebarLayout-A2HJPPHS.js → SidebarLayout-TR5CAB6Q.js} +80 -58
- package/dist/SidebarLayout-TR5CAB6Q.js.map +1 -0
- package/dist/{SkillSettings-FGGMSUNO.js → SkillSettings-TRTY2YH3.js} +24 -22
- package/dist/SkillSettings-TRTY2YH3.js.map +1 -0
- package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js → TrueForgeUIWithRouter-GZUSRZIR.js} +9 -9
- package/dist/{WidgetLayout-6QM45OQQ.js → WidgetLayout-2TM6I4LJ.js} +10 -10
- package/dist/{chunk-U7KURWW3.js → chunk-2GIZY3JJ.js} +276 -54
- package/dist/chunk-2GIZY3JJ.js.map +1 -0
- package/dist/{chunk-ZKNUMH2M.js → chunk-2MUK3SMR.js} +13 -11
- package/dist/chunk-2MUK3SMR.js.map +1 -0
- package/dist/{chunk-WVE3F724.js → chunk-2QTH6JHX.js} +21 -4
- package/dist/chunk-2QTH6JHX.js.map +1 -0
- package/dist/{chunk-XAU7QFG3.js → chunk-5N5V7YLO.js} +72 -256
- package/dist/chunk-5N5V7YLO.js.map +1 -0
- package/dist/{chunk-CYHJDKFB.js → chunk-75YEQUUD.js} +189 -52
- package/dist/chunk-75YEQUUD.js.map +1 -0
- package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
- package/dist/chunk-7AAO4UDQ.js.map +1 -0
- package/dist/{chunk-M62XY4NC.js → chunk-BXG6XN2S.js} +235 -108
- package/dist/chunk-BXG6XN2S.js.map +1 -0
- package/dist/chunk-GKXDRULM.js +587 -0
- package/dist/chunk-GKXDRULM.js.map +1 -0
- package/dist/{chunk-ZTMKFZQ3.js → chunk-OH357IHR.js} +5572 -3367
- package/dist/chunk-OH357IHR.js.map +1 -0
- package/dist/{chunk-DMMZSZTN.js → chunk-P6MZDITS.js} +60 -16
- package/dist/chunk-P6MZDITS.js.map +1 -0
- package/dist/{chunk-MPNSO7E6.js → chunk-SLMFEG7X.js} +2 -2
- package/dist/chunk-T6QQV5LK.js +238 -0
- package/dist/chunk-T6QQV5LK.js.map +1 -0
- package/dist/{chunk-6O6FWUDW.js → chunk-UWLL327M.js} +641 -388
- package/dist/chunk-UWLL327M.js.map +1 -0
- package/dist/{chunk-FJW36PD7.js → chunk-VAOCM3QQ.js} +28 -24
- package/dist/chunk-VAOCM3QQ.js.map +1 -0
- package/dist/chunk-Y7O6CMC7.js +517 -0
- package/dist/chunk-Y7O6CMC7.js.map +1 -0
- package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
- package/dist/index.d.ts +377 -108
- package/dist/index.js +69 -488
- package/dist/index.js.map +1 -1
- package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +49 -14
- package/dist/plugins/trueforge-agent-server-adapter/index.js +161 -60
- package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -4
- package/dist/AgentCodeSnippets-NZOFJE57.js.map +0 -1
- package/dist/AgentMetricChart-JPU3MFQ2.js +0 -15
- package/dist/AgentOverview-EEBHJC32.js +0 -167
- package/dist/AgentOverview-EEBHJC32.js.map +0 -1
- package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +0 -1
- package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +0 -1
- package/dist/AgentSessions-3MPDZASK.js.map +0 -1
- package/dist/ConnectorSettings-MXFRWWR6.js.map +0 -1
- package/dist/DrawerLayout-JR3O6RRB.js.map +0 -1
- package/dist/ModelSettings-G7IFNC2Y.js.map +0 -1
- package/dist/OpenUiFenceBlock-2TV5TQ6P.js +0 -9
- package/dist/SandboxSettings-NXAANMAX.js.map +0 -1
- package/dist/SchedulesPage-KKLUDO6B.js +0 -15
- package/dist/ShellRouteSync-CEBETGEJ.js.map +0 -1
- package/dist/SidebarLayout-A2HJPPHS.js.map +0 -1
- package/dist/SkillSettings-FGGMSUNO.js.map +0 -1
- package/dist/chunk-2XPPBEYF.js +0 -74
- package/dist/chunk-2XPPBEYF.js.map +0 -1
- package/dist/chunk-6O6FWUDW.js.map +0 -1
- package/dist/chunk-7Z2C2K7F.js +0 -578
- package/dist/chunk-7Z2C2K7F.js.map +0 -1
- package/dist/chunk-CYHJDKFB.js.map +0 -1
- package/dist/chunk-DMMZSZTN.js.map +0 -1
- package/dist/chunk-FJW36PD7.js.map +0 -1
- package/dist/chunk-M62XY4NC.js.map +0 -1
- package/dist/chunk-QC42MLAK.js.map +0 -1
- package/dist/chunk-SFZNIO6U.js +0 -18
- package/dist/chunk-SFZNIO6U.js.map +0 -1
- package/dist/chunk-U7KURWW3.js.map +0 -1
- package/dist/chunk-WVE3F724.js.map +0 -1
- package/dist/chunk-XAU7QFG3.js.map +0 -1
- package/dist/chunk-ZKNUMH2M.js.map +0 -1
- package/dist/chunk-ZTMKFZQ3.js.map +0 -1
- /package/dist/{AgentMetricChart-JPU3MFQ2.js.map → AgentMetricChart-6RGWFMJE.js.map} +0 -0
- /package/dist/{DockLayout-LM4AFMFY.js.map → DockLayout-ACM7BVIH.js.map} +0 -0
- /package/dist/{OpenUiFenceBlock-2TV5TQ6P.js.map → OpenUiFenceBlock-MJTC2VJ5.js.map} +0 -0
- /package/dist/{SchedulesPage-KKLUDO6B.js.map → SchedulesPage-LHJ3U2VM.js.map} +0 -0
- /package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js.map → TrueForgeUIWithRouter-GZUSRZIR.js.map} +0 -0
- /package/dist/{WidgetLayout-6QM45OQQ.js.map → WidgetLayout-2TM6I4LJ.js.map} +0 -0
- /package/dist/{chunk-MPNSO7E6.js.map → chunk-SLMFEG7X.js.map} +0 -0
|
@@ -2,15 +2,17 @@ import {
|
|
|
2
2
|
Tooltip,
|
|
3
3
|
useAgentConfigInstructions,
|
|
4
4
|
useNamedAgentHeaderState,
|
|
5
|
+
useResourcePermissions,
|
|
5
6
|
useSlot,
|
|
6
7
|
withInitialUserMessages
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-OH357IHR.js";
|
|
8
9
|
import {
|
|
9
10
|
Icon,
|
|
10
11
|
auiButtonClass,
|
|
11
12
|
pageHeaderTitleClassName,
|
|
13
|
+
sidebarRailButtonClassName,
|
|
12
14
|
useDraftCatalog
|
|
13
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-5N5V7YLO.js";
|
|
14
16
|
import {
|
|
15
17
|
isSettingsChromeEnabled,
|
|
16
18
|
shellIsCreateAgent,
|
|
@@ -19,14 +21,14 @@ import {
|
|
|
19
21
|
useOptionalShellMode,
|
|
20
22
|
useServerCapabilities,
|
|
21
23
|
useShellMode
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-2GIZY3JJ.js";
|
|
23
25
|
import {
|
|
24
26
|
useAuiState
|
|
25
27
|
} from "./chunk-M6MHLVSO.js";
|
|
26
28
|
import {
|
|
27
29
|
cn,
|
|
28
30
|
useTheme
|
|
29
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-GKXDRULM.js";
|
|
30
32
|
|
|
31
33
|
// src/atoms/NamedAgentHeaderLabel.tsx
|
|
32
34
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -56,17 +58,35 @@ function ShellActions({ className, labeled = false }) {
|
|
|
56
58
|
const isDark = mode === "dark";
|
|
57
59
|
const themeLabel = isDark ? "Light" : "Dark";
|
|
58
60
|
const settingsChromeEnabled = isSettingsChromeEnabled({ catalog, capabilities });
|
|
59
|
-
const labeledButtonClass = "h-auto w-full flex-col gap-1.5 whitespace-normal px-1 py-3 text-[0.625rem] leading-tight !justify-center";
|
|
60
61
|
const hoverClass = "hover:bg-secondary-button-hover hover:text-ghost-button-text";
|
|
61
62
|
return /* @__PURE__ */ jsxs2(
|
|
62
63
|
"div",
|
|
63
64
|
{
|
|
64
65
|
className: cn(
|
|
65
|
-
"flex shrink-0 items-center gap-1
|
|
66
|
-
labeled
|
|
66
|
+
"flex shrink-0 items-center gap-1",
|
|
67
|
+
labeled ? "w-full flex-col items-center gap-1 text-sidebar-text" : "text-text-primary",
|
|
67
68
|
className
|
|
68
69
|
),
|
|
69
70
|
children: [
|
|
71
|
+
/* @__PURE__ */ jsxs2(
|
|
72
|
+
"a",
|
|
73
|
+
{
|
|
74
|
+
href: "https://trueforge.dev",
|
|
75
|
+
target: "_blank",
|
|
76
|
+
rel: "noopener noreferrer",
|
|
77
|
+
"aria-label": "Documentation",
|
|
78
|
+
title: "Documentation",
|
|
79
|
+
className: auiButtonClass({
|
|
80
|
+
variant: "ghost",
|
|
81
|
+
size: labeled ? void 0 : "icon",
|
|
82
|
+
className: cn(hoverClass, labeled && sidebarRailButtonClassName)
|
|
83
|
+
}),
|
|
84
|
+
children: [
|
|
85
|
+
/* @__PURE__ */ jsx2(Icon, { name: "book-open", size: labeled ? 14 : void 0 }),
|
|
86
|
+
labeled ? /* @__PURE__ */ jsx2("span", { className: "text-center", children: "Docs" }) : null
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
),
|
|
70
90
|
/* @__PURE__ */ jsxs2(
|
|
71
91
|
"button",
|
|
72
92
|
{
|
|
@@ -76,11 +96,11 @@ function ShellActions({ className, labeled = false }) {
|
|
|
76
96
|
className: auiButtonClass({
|
|
77
97
|
variant: "ghost",
|
|
78
98
|
size: labeled ? void 0 : "icon",
|
|
79
|
-
className: cn(hoverClass, labeled &&
|
|
99
|
+
className: cn(hoverClass, labeled && sidebarRailButtonClassName)
|
|
80
100
|
}),
|
|
81
101
|
onClick: () => setTheme(isDark ? "light" : "dark"),
|
|
82
102
|
children: [
|
|
83
|
-
/* @__PURE__ */ jsx2(Icon, { name: isDark ? "sun" : "moon", size: labeled ?
|
|
103
|
+
/* @__PURE__ */ jsx2(Icon, { name: isDark ? "sun" : "moon", size: labeled ? 14 : void 0 }),
|
|
84
104
|
labeled ? /* @__PURE__ */ jsx2("span", { className: "text-center", children: themeLabel }) : null
|
|
85
105
|
]
|
|
86
106
|
}
|
|
@@ -98,13 +118,13 @@ function ShellActions({ className, labeled = false }) {
|
|
|
98
118
|
size: labeled ? void 0 : "icon",
|
|
99
119
|
className: cn(
|
|
100
120
|
hoverClass,
|
|
101
|
-
labeled &&
|
|
102
|
-
shell.settingsOpen && "bg-primary-button-bg text-primary-button-text hover:bg-primary-button-hover hover:text-primary-button-text"
|
|
121
|
+
labeled && sidebarRailButtonClassName,
|
|
122
|
+
shell.settingsOpen && "bg-primary-button-bg font-medium text-primary-button-text hover:bg-primary-button-hover hover:text-primary-button-text"
|
|
103
123
|
)
|
|
104
124
|
}),
|
|
105
125
|
onClick: () => shell.setSettingsOpen(true),
|
|
106
126
|
children: [
|
|
107
|
-
/* @__PURE__ */ jsx2(Icon, { name: "settings", size: labeled ?
|
|
127
|
+
/* @__PURE__ */ jsx2(Icon, { name: "settings", size: labeled ? 14 : void 0 }),
|
|
108
128
|
labeled ? /* @__PURE__ */ jsx2("span", { className: "text-center", children: "Settings" }) : null
|
|
109
129
|
]
|
|
110
130
|
}
|
|
@@ -128,6 +148,12 @@ function AgentConfigDrawerContainer({ showClose = false }) {
|
|
|
128
148
|
const updateAgentSpec = useTrueFoundryUpdateAgentSpec();
|
|
129
149
|
const flushAgentSpec = useTrueFoundryFlushAgentSpec();
|
|
130
150
|
const shell = useShellMode();
|
|
151
|
+
const agentId = shell.mode.status === "active" ? shell.mode.agentId : void 0;
|
|
152
|
+
const { allows } = useResourcePermissions({
|
|
153
|
+
resourceType: "agent",
|
|
154
|
+
resourceIds: agentId == null ? [] : [agentId]
|
|
155
|
+
});
|
|
156
|
+
const canManageAgent = allows(agentId, "MANAGE");
|
|
131
157
|
const server = useOptionalServer();
|
|
132
158
|
const capabilities = useServerCapabilities();
|
|
133
159
|
const catalog = useDraftCatalog();
|
|
@@ -144,10 +170,13 @@ function AgentConfigDrawerContainer({ showClose = false }) {
|
|
|
144
170
|
useEffect(() => {
|
|
145
171
|
if (isBuilder) catalog.ensureLoaded();
|
|
146
172
|
}, [catalog, isBuilder]);
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
if (!canManageAgent) setEditor(null);
|
|
175
|
+
}, [canManageAgent]);
|
|
147
176
|
useEffect(() => {
|
|
148
177
|
if (!showClose || !shell.agentConfigOpen) return;
|
|
149
178
|
const onKeyDown = (event) => {
|
|
150
|
-
if (event.key === "Escape" && editor === null && document.querySelector("dialog[open]") === null) {
|
|
179
|
+
if (!event.defaultPrevented && event.key === "Escape" && editor === null && document.querySelector("dialog[open]") === null) {
|
|
151
180
|
closeDrawer();
|
|
152
181
|
}
|
|
153
182
|
};
|
|
@@ -166,6 +195,7 @@ function AgentConfigDrawerContainer({ showClose = false }) {
|
|
|
166
195
|
);
|
|
167
196
|
const commitSpec = useCallback(
|
|
168
197
|
({ next, instructions }) => {
|
|
198
|
+
if (!canManageAgent) return;
|
|
169
199
|
if (next.skills && next.skills.length > 0 && capabilities?.sandbox.enabled === true) {
|
|
170
200
|
updateAgentSpec?.({
|
|
171
201
|
...next,
|
|
@@ -179,7 +209,7 @@ function AgentConfigDrawerContainer({ showClose = false }) {
|
|
|
179
209
|
}
|
|
180
210
|
updateAgentSpec?.({ ...next, instructions: instructions || void 0 });
|
|
181
211
|
},
|
|
182
|
-
[capabilities?.sandbox.enabled, updateAgentSpec]
|
|
212
|
+
[canManageAgent, capabilities?.sandbox.enabled, updateAgentSpec]
|
|
183
213
|
);
|
|
184
214
|
const updateSpec = useCallback(
|
|
185
215
|
(next) => {
|
|
@@ -204,6 +234,12 @@ function AgentConfigDrawerContainer({ showClose = false }) {
|
|
|
204
234
|
},
|
|
205
235
|
[server]
|
|
206
236
|
);
|
|
237
|
+
const loadMcpConnector = useCallback(
|
|
238
|
+
async (connectorId) => {
|
|
239
|
+
return server?.getMcpConnector?.({ connectorId });
|
|
240
|
+
},
|
|
241
|
+
[server]
|
|
242
|
+
);
|
|
207
243
|
if (!isBuilder || agentSpec === null || showClose && !shell.agentConfigOpen) {
|
|
208
244
|
return null;
|
|
209
245
|
}
|
|
@@ -214,10 +250,17 @@ function AgentConfigDrawerContainer({ showClose = false }) {
|
|
|
214
250
|
{
|
|
215
251
|
spec: agentSpec,
|
|
216
252
|
model,
|
|
253
|
+
models: catalog.models,
|
|
254
|
+
modelsLoading: catalog.loading,
|
|
255
|
+
modelsError: catalog.error,
|
|
256
|
+
skills: catalog.skills,
|
|
217
257
|
skillsAvailable: capabilities?.skill.enabled === true,
|
|
218
258
|
instructions: instructionDraft,
|
|
219
|
-
onOpenEditor:
|
|
259
|
+
onOpenEditor: (nextEditor) => {
|
|
260
|
+
if (canManageAgent) setEditor(nextEditor);
|
|
261
|
+
},
|
|
220
262
|
onChange: updateSpec,
|
|
263
|
+
disabled: !canManageAgent,
|
|
221
264
|
onClose: showClose ? closeDrawer : void 0
|
|
222
265
|
}
|
|
223
266
|
),
|
|
@@ -235,6 +278,7 @@ function AgentConfigDrawerContainer({ showClose = false }) {
|
|
|
235
278
|
sandboxAvailable: capabilities?.sandbox.enabled === true,
|
|
236
279
|
instructions: instructionDraft,
|
|
237
280
|
onInstructionsSave: saveInstructions,
|
|
281
|
+
...server?.getMcpConnector === void 0 ? {} : { loadMcpConnector },
|
|
238
282
|
loadMcpTools,
|
|
239
283
|
onRefreshConnectors: catalog.refreshConnectors,
|
|
240
284
|
onChange: updateSpec,
|
|
@@ -249,4 +293,4 @@ export {
|
|
|
249
293
|
ShellActions,
|
|
250
294
|
AgentConfigDrawerContainer
|
|
251
295
|
};
|
|
252
|
-
//# sourceMappingURL=chunk-
|
|
296
|
+
//# sourceMappingURL=chunk-P6MZDITS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/atoms/NamedAgentHeaderLabel.tsx","../src/atoms/ShellActions.tsx","../src/containers/AgentConfigDrawerContainer.tsx"],"sourcesContent":["'use client';\n\nimport { useAuiState } from '../assistant-ui.js';\nimport { useNamedAgentHeaderState } from '../hooks/useChatChromeActionsVisible.js';\nimport { Icon } from '../icons/Icon.js';\nimport { cn } from './lib/cn.js';\nimport { pageHeaderTitleClassName } from './PageHeader.js';\nimport { Tooltip } from './primitives/Tooltip.js';\n\n/** Dynamic chat title for named agents and New Chat / New Agent drafts. */\nexport function NamedAgentHeaderLabel({ className }: { className?: string }) {\n const state = useNamedAgentHeaderState();\n const threadTitle = useAuiState(s => s.threadListItem.title);\n if (state === null) return null;\n\n const syncedTitle = threadTitle?.trim() ?? '';\n const displayName = state.allowThreadTitle && syncedTitle.length > 0 ? syncedTitle : state.name;\n\n return (\n <h1 className={cn('flex min-w-0 items-center gap-1.5', pageHeaderTitleClassName, className)}>\n <span className=\"truncate\" title={displayName}>\n {displayName}\n </span>\n {state.isEditing ? (\n <Tooltip content=\"Try changes here, then choose Update agent to save.\" side=\"bottom\">\n <span className=\"border-warning-bg/40 bg-warning-bg/10 text-warning-bg inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium\">\n <Icon name=\"pencil\" className=\"size-3\" />\n Editing\n </span>\n </Tooltip>\n ) : null}\n </h1>\n );\n}\n","'use client';\n\nimport { Icon } from '../icons/Icon.js';\nimport { useOptionalCatalogServer, useServerCapabilities } from '../server/ServerContext.js';\nimport { useOptionalShellMode } from '../server/ShellModeContext.js';\nimport { isSettingsChromeEnabled } from '../server/serverChrome.js';\nimport { useSlot } from '../theme/SlotsProvider.js';\nimport { useTheme } from '../theme/ThemeProvider.js';\nimport { auiButtonClass, sidebarRailButtonClassName } from './lib/buttonClasses.js';\nimport { cn } from './lib/cn.js';\n\nexport function ShellActions({ className, labeled = false }: { className?: string; labeled?: boolean }) {\n const shell = useOptionalShellMode();\n const catalog = useOptionalCatalogServer();\n const capabilities = useServerCapabilities();\n const { mode, setTheme } = useTheme();\n const ActionSlot = useSlot('ShellActionsActionSlot');\n const isDark = mode === 'dark';\n const themeLabel = isDark ? 'Light' : 'Dark';\n const settingsChromeEnabled = isSettingsChromeEnabled({ catalog, capabilities });\n\n const hoverClass = 'hover:bg-secondary-button-hover hover:text-ghost-button-text';\n\n return (\n <div\n className={cn(\n 'flex shrink-0 items-center gap-1',\n labeled ? 'w-full flex-col items-center gap-1 text-sidebar-text' : 'text-text-primary',\n className,\n )}\n >\n <a\n href=\"https://trueforge.dev\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Documentation\"\n title=\"Documentation\"\n className={auiButtonClass({\n variant: 'ghost',\n size: labeled ? undefined : 'icon',\n className: cn(hoverClass, labeled && sidebarRailButtonClassName),\n })}\n >\n <Icon name=\"book-open\" size={labeled ? 14 : undefined} />\n {labeled ? <span className=\"text-center\">Docs</span> : null}\n </a>\n <button\n type=\"button\"\n aria-label={isDark ? 'Switch to light theme' : 'Switch to dark theme'}\n title={isDark ? 'Light theme' : 'Dark theme'}\n className={auiButtonClass({\n variant: 'ghost',\n size: labeled ? undefined : 'icon',\n className: cn(hoverClass, labeled && sidebarRailButtonClassName),\n })}\n onClick={() => setTheme(isDark ? 'light' : 'dark')}\n >\n <Icon name={isDark ? 'sun' : 'moon'} size={labeled ? 14 : undefined} />\n {labeled ? <span className=\"text-center\">{themeLabel}</span> : null}\n </button>\n {shell != null && settingsChromeEnabled ? (\n <button\n type=\"button\"\n aria-label=\"Settings\"\n title=\"Settings\"\n aria-expanded={shell.settingsOpen}\n aria-current={shell.settingsOpen ? 'page' : undefined}\n className={auiButtonClass({\n variant: 'ghost',\n size: labeled ? undefined : 'icon',\n className: cn(\n hoverClass,\n labeled && sidebarRailButtonClassName,\n shell.settingsOpen &&\n 'bg-primary-button-bg font-medium text-primary-button-text hover:bg-primary-button-hover hover:text-primary-button-text',\n ),\n })}\n onClick={() => shell.setSettingsOpen(true)}\n >\n <Icon name=\"settings\" size={labeled ? 14 : undefined} />\n {labeled ? <span className=\"text-center\">Settings</span> : null}\n </button>\n ) : null}\n <ActionSlot />\n </div>\n );\n}\n","'use client';\n\nimport {\n useTrueFoundryAgentSpec,\n useTrueFoundryFlushAgentSpec,\n useTrueFoundryUpdateAgentSpec,\n} from '@truefoundry/assistant-ui-runtime';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport type { AgentConfigEditor } from '../atoms/draft/AgentConfigEditors.js';\nimport { useAgentConfigInstructions } from '../atoms/draft/AgentConfigInstructionsContext.js';\nimport type { AgentInstructionsDraft } from '../atoms/draft/AgentInstructionsDrawer.js';\nimport { useDraftCatalog } from '../atoms/draft/DraftCatalogProvider.js';\nimport { withInitialUserMessages } from '../atoms/draft/agentConfigMessages.js';\nimport { useResourcePermissions } from '../hooks/useResourcePermissions.js';\nimport { useOptionalServer, useServerCapabilities } from '../server/ServerContext.js';\nimport { shellIsCreateAgent, useShellMode } from '../server/ShellModeContext.js';\nimport type { AgentSpec, ConnectorState, McpToolSelection } from '../server/types.js';\nimport { useSlot } from '../theme/SlotsProvider.js';\n\nexport function AgentConfigDrawerContainer({ showClose = false }: { showClose?: boolean }) {\n const { agentSpec } = useTrueFoundryAgentSpec();\n const updateAgentSpec = useTrueFoundryUpdateAgentSpec();\n const flushAgentSpec = useTrueFoundryFlushAgentSpec();\n const shell = useShellMode();\n const agentId = shell.mode.status === 'active' ? shell.mode.agentId : undefined;\n const { allows } = useResourcePermissions({\n resourceType: 'agent',\n resourceIds: agentId == null ? [] : [agentId],\n });\n const canManageAgent = allows(agentId, 'MANAGE');\n const server = useOptionalServer();\n const capabilities = useServerCapabilities();\n const catalog = useDraftCatalog();\n const AgentConfigPanel = useSlot('AgentConfigPanel');\n const AgentConfigEditors = useSlot('AgentConfigEditors');\n const [editor, setEditor] = useState<AgentConfigEditor | null>(null);\n const isBuilder = shellIsCreateAgent(shell.mode);\n const { draft: instructionDraft, flush: flushInstructions } = useAgentConfigInstructions();\n const closeDrawer = useCallback(() => {\n flushInstructions();\n void flushAgentSpec();\n shell.setAgentConfigOpen(false);\n }, [flushAgentSpec, flushInstructions, shell]);\n\n useEffect(() => {\n if (isBuilder) catalog.ensureLoaded();\n }, [catalog, isBuilder]);\n\n useEffect(() => {\n if (!canManageAgent) setEditor(null);\n }, [canManageAgent]);\n\n useEffect(() => {\n if (!showClose || !shell.agentConfigOpen) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (\n !event.defaultPrevented &&\n event.key === 'Escape' &&\n editor === null &&\n document.querySelector('dialog[open]') === null\n ) {\n closeDrawer();\n }\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [closeDrawer, editor, shell.agentConfigOpen, showClose]);\n\n // Flush pending edits on unmount. ChatProvider remount (runtimeKey) tears the\n // runtime down first — flush then throws; ignore so the new draft can mount.\n useEffect(\n () => () => {\n flushInstructions();\n try {\n void flushAgentSpec();\n } catch {\n // Runtime already gone.\n }\n },\n [flushAgentSpec, flushInstructions],\n );\n\n const commitSpec = useCallback(\n ({ next, instructions }: { next: AgentSpec; instructions: string }) => {\n if (!canManageAgent) return;\n if (next.skills && next.skills.length > 0 && capabilities?.sandbox.enabled === true) {\n updateAgentSpec?.({\n ...next,\n instructions: instructions || undefined,\n config: {\n ...next.config,\n sandbox: { ...next.config?.sandbox, enabled: true },\n },\n });\n return;\n }\n updateAgentSpec?.({ ...next, instructions: instructions || undefined });\n },\n [canManageAgent, capabilities?.sandbox.enabled, updateAgentSpec],\n );\n\n const updateSpec = useCallback(\n (next: AgentSpec) => {\n commitSpec({ next, instructions: instructionDraft });\n },\n [commitSpec, instructionDraft],\n );\n\n const saveInstructions = useCallback(\n (draft: AgentInstructionsDraft) => {\n if (agentSpec === null) return;\n commitSpec({\n next: withInitialUserMessages({ spec: agentSpec, messages: draft.messages }),\n instructions: draft.instructions,\n });\n },\n [agentSpec, commitSpec],\n );\n\n const loadMcpTools = useCallback(\n async (connectorId: string): Promise<McpToolSelection[]> => {\n if (server?.getMcpTools === undefined) return [];\n return server.getMcpTools({ connectorId });\n },\n [server],\n );\n const loadMcpConnector = useCallback(\n async (connectorId: string): Promise<ConnectorState | undefined> => {\n return server?.getMcpConnector?.({ connectorId });\n },\n [server],\n );\n\n if (!isBuilder || agentSpec === null || (showClose && !shell.agentConfigOpen)) {\n return null;\n }\n\n const model = catalog.models.find(item => item.name === agentSpec.model.name);\n\n return (\n <>\n <AgentConfigPanel\n spec={agentSpec}\n model={model}\n models={catalog.models}\n modelsLoading={catalog.loading}\n modelsError={catalog.error}\n skills={catalog.skills}\n skillsAvailable={capabilities?.skill.enabled === true}\n instructions={instructionDraft}\n onOpenEditor={nextEditor => {\n if (canManageAgent) setEditor(nextEditor);\n }}\n onChange={updateSpec}\n disabled={!canManageAgent}\n onClose={showClose ? closeDrawer : undefined}\n />\n <AgentConfigEditors\n editor={editor}\n spec={agentSpec}\n models={catalog.models}\n connectors={catalog.connectors}\n skills={catalog.skills}\n loading={catalog.loading}\n error={catalog.error}\n skillsDisabled={capabilities?.skill.enabled !== true}\n sandboxAvailable={capabilities?.sandbox.enabled === true}\n instructions={instructionDraft}\n onInstructionsSave={saveInstructions}\n {...(server?.getMcpConnector === undefined ? {} : { loadMcpConnector })}\n loadMcpTools={loadMcpTools}\n onRefreshConnectors={catalog.refreshConnectors}\n onChange={updateSpec}\n onClose={() => setEditor(null)}\n />\n </>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cn,
|
|
3
3
|
useOptionalContentClassNames
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GKXDRULM.js";
|
|
5
5
|
|
|
6
6
|
// src/atoms/OpenUiFenceBlock.tsx
|
|
7
7
|
import { Renderer } from "@openuidev/react-lang";
|
|
@@ -21,4 +21,4 @@ function OpenUiFenceBlock({ content, isStreaming, darkTheme }) {
|
|
|
21
21
|
export {
|
|
22
22
|
OpenUiFenceBlock
|
|
23
23
|
};
|
|
24
|
-
//# sourceMappingURL=chunk-
|
|
24
|
+
//# sourceMappingURL=chunk-SLMFEG7X.js.map
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getErrorMessage,
|
|
3
|
+
useOptionalServer
|
|
4
|
+
} from "./chunk-2GIZY3JJ.js";
|
|
5
|
+
|
|
6
|
+
// src/atoms/lib/useSearchAgentsList.ts
|
|
7
|
+
import { useCallback, useEffect as useEffect2, useRef, useState as useState2 } from "react";
|
|
8
|
+
|
|
9
|
+
// src/atoms/lib/useDebouncedValue.ts
|
|
10
|
+
import { useEffect, useState } from "react";
|
|
11
|
+
function useDebouncedValue(value, delayMs) {
|
|
12
|
+
const [debounced, setDebounced] = useState(value);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const id = window.setTimeout(() => setDebounced(value), delayMs);
|
|
15
|
+
return () => window.clearTimeout(id);
|
|
16
|
+
}, [value, delayMs]);
|
|
17
|
+
return debounced;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/atoms/lib/useSearchAgentsList.ts
|
|
21
|
+
var SEARCH_AGENTS_PAGE_SIZE = 50;
|
|
22
|
+
var SEARCH_AGENTS_PAGE_MAX = 100;
|
|
23
|
+
var DEFAULT_DEBOUNCE_MS = 300;
|
|
24
|
+
var LOAD_MORE_ROOT_MARGIN = "48px";
|
|
25
|
+
function clampPageSize(size) {
|
|
26
|
+
return Math.min(Math.max(size, 1), SEARCH_AGENTS_PAGE_MAX);
|
|
27
|
+
}
|
|
28
|
+
async function searchAllAgents(server, offset = 0) {
|
|
29
|
+
const rows = await server.searchAgents({ limit: SEARCH_AGENTS_PAGE_SIZE, offset });
|
|
30
|
+
if (rows.length < SEARCH_AGENTS_PAGE_SIZE) return rows;
|
|
31
|
+
return [...rows, ...await searchAllAgents(server, offset + rows.length)];
|
|
32
|
+
}
|
|
33
|
+
async function findAgentByName({
|
|
34
|
+
server,
|
|
35
|
+
agentName,
|
|
36
|
+
offset = 0
|
|
37
|
+
}) {
|
|
38
|
+
const rows = await server.searchAgents({ query: agentName, limit: SEARCH_AGENTS_PAGE_SIZE, offset });
|
|
39
|
+
const match = rows.find((agent) => agent.name === agentName);
|
|
40
|
+
if (match != null || rows.length < SEARCH_AGENTS_PAGE_SIZE) return match;
|
|
41
|
+
return findAgentByName({ server, agentName, offset: offset + rows.length });
|
|
42
|
+
}
|
|
43
|
+
async function findLibraryAgent({
|
|
44
|
+
server,
|
|
45
|
+
agentKey,
|
|
46
|
+
offset = 0
|
|
47
|
+
}) {
|
|
48
|
+
const rows = await server.searchAgents({ limit: SEARCH_AGENTS_PAGE_SIZE, offset });
|
|
49
|
+
const match = rows.find((agent) => agent.name === agentKey || agent.agentId === agentKey);
|
|
50
|
+
if (match != null || rows.length < SEARCH_AGENTS_PAGE_SIZE) return match;
|
|
51
|
+
return findLibraryAgent({ server, agentKey, offset: offset + rows.length });
|
|
52
|
+
}
|
|
53
|
+
function useSearchAgentsList({
|
|
54
|
+
enabled,
|
|
55
|
+
query,
|
|
56
|
+
refreshKey = 0,
|
|
57
|
+
limit: limitOption = SEARCH_AGENTS_PAGE_SIZE,
|
|
58
|
+
debounceMs = DEFAULT_DEBOUNCE_MS,
|
|
59
|
+
mode = "infinite"
|
|
60
|
+
}) {
|
|
61
|
+
const server = useOptionalServer();
|
|
62
|
+
const debouncedQuery = useDebouncedValue(query, enabled ? debounceMs : 0);
|
|
63
|
+
const [agents, setAgents] = useState2([]);
|
|
64
|
+
const [loading, setLoading] = useState2(false);
|
|
65
|
+
const [loadingMore, setLoadingMore] = useState2(false);
|
|
66
|
+
const [error, setError] = useState2(null);
|
|
67
|
+
const [hasMore, setHasMore] = useState2(false);
|
|
68
|
+
const [pageSize, setPageSizeState] = useState2(() => clampPageSize(limitOption));
|
|
69
|
+
const [offset, setOffset] = useState2(0);
|
|
70
|
+
const genRef = useRef(0);
|
|
71
|
+
const loadMoreInflightRef = useRef(false);
|
|
72
|
+
const hasMoreRef = useRef(false);
|
|
73
|
+
const agentsLenRef = useRef(0);
|
|
74
|
+
const listElRef = useRef(null);
|
|
75
|
+
const sentinelElRef = useRef(null);
|
|
76
|
+
const [listEl, setListEl] = useState2(null);
|
|
77
|
+
const [sentinelEl, setSentinelEl] = useState2(null);
|
|
78
|
+
const limit = mode === "paged" ? pageSize : clampPageSize(limitOption);
|
|
79
|
+
hasMoreRef.current = hasMore;
|
|
80
|
+
agentsLenRef.current = agents.length;
|
|
81
|
+
const listRef = useCallback((node) => {
|
|
82
|
+
listElRef.current = node;
|
|
83
|
+
setListEl(node);
|
|
84
|
+
}, []);
|
|
85
|
+
const sentinelRef = useCallback((node) => {
|
|
86
|
+
sentinelElRef.current = node;
|
|
87
|
+
setSentinelEl(node);
|
|
88
|
+
}, []);
|
|
89
|
+
const searchQuery = debouncedQuery.trim() || void 0;
|
|
90
|
+
useEffect2(() => {
|
|
91
|
+
if (mode !== "paged") return;
|
|
92
|
+
setOffset(0);
|
|
93
|
+
}, [mode, searchQuery, refreshKey]);
|
|
94
|
+
useEffect2(() => {
|
|
95
|
+
if (!enabled || server == null) return;
|
|
96
|
+
const gen = ++genRef.current;
|
|
97
|
+
loadMoreInflightRef.current = false;
|
|
98
|
+
setLoading(true);
|
|
99
|
+
setError(null);
|
|
100
|
+
const fetchOffset = mode === "paged" ? offset : 0;
|
|
101
|
+
void server.searchAgents({ query: searchQuery, limit, offset: fetchOffset }).then((rows) => {
|
|
102
|
+
if (gen !== genRef.current) return;
|
|
103
|
+
setAgents(rows);
|
|
104
|
+
setHasMore(rows.length >= limit);
|
|
105
|
+
}).catch((err) => {
|
|
106
|
+
if (gen !== genRef.current) return;
|
|
107
|
+
setAgents([]);
|
|
108
|
+
setHasMore(false);
|
|
109
|
+
setError(getErrorMessage(err, "Failed to load agents."));
|
|
110
|
+
}).finally(() => {
|
|
111
|
+
if (gen === genRef.current) setLoading(false);
|
|
112
|
+
});
|
|
113
|
+
return () => {
|
|
114
|
+
genRef.current += 1;
|
|
115
|
+
};
|
|
116
|
+
}, [enabled, server, searchQuery, limit, refreshKey, mode, offset]);
|
|
117
|
+
const loadMore = useCallback(() => {
|
|
118
|
+
if (mode !== "infinite") return;
|
|
119
|
+
if (!enabled || server == null || !hasMoreRef.current || loadMoreInflightRef.current || loading) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const gen = genRef.current;
|
|
123
|
+
const nextOffset = agentsLenRef.current;
|
|
124
|
+
loadMoreInflightRef.current = true;
|
|
125
|
+
setLoadingMore(true);
|
|
126
|
+
void server.searchAgents({ query: searchQuery, limit, offset: nextOffset }).then((rows) => {
|
|
127
|
+
if (gen !== genRef.current) return;
|
|
128
|
+
setAgents((prev) => [...prev, ...rows]);
|
|
129
|
+
setHasMore(rows.length >= limit);
|
|
130
|
+
}).catch(() => {
|
|
131
|
+
if (gen !== genRef.current) return;
|
|
132
|
+
setHasMore(false);
|
|
133
|
+
}).finally(() => {
|
|
134
|
+
loadMoreInflightRef.current = false;
|
|
135
|
+
if (gen === genRef.current) setLoadingMore(false);
|
|
136
|
+
});
|
|
137
|
+
}, [enabled, server, searchQuery, limit, loading, mode]);
|
|
138
|
+
useEffect2(() => {
|
|
139
|
+
if (mode !== "infinite" || !enabled || !hasMore || listEl == null || sentinelEl == null) return;
|
|
140
|
+
const observer = new IntersectionObserver(
|
|
141
|
+
(entries) => {
|
|
142
|
+
if (entries.some((entry) => entry.isIntersecting)) {
|
|
143
|
+
loadMore();
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
{ root: listEl, rootMargin: LOAD_MORE_ROOT_MARGIN }
|
|
147
|
+
);
|
|
148
|
+
observer.observe(sentinelEl);
|
|
149
|
+
return () => observer.disconnect();
|
|
150
|
+
}, [mode, enabled, hasMore, listEl, sentinelEl, loadMore, agents.length]);
|
|
151
|
+
const setPageSize = useCallback((size) => {
|
|
152
|
+
setPageSizeState(clampPageSize(size));
|
|
153
|
+
setOffset(0);
|
|
154
|
+
}, []);
|
|
155
|
+
const goNext = useCallback(() => {
|
|
156
|
+
if (mode !== "paged" || !hasMoreRef.current || loading) return;
|
|
157
|
+
setOffset((current) => current + pageSize);
|
|
158
|
+
}, [mode, loading, pageSize]);
|
|
159
|
+
const goPrev = useCallback(() => {
|
|
160
|
+
if (mode !== "paged" || loading) return;
|
|
161
|
+
setOffset((current) => Math.max(0, current - pageSize));
|
|
162
|
+
}, [mode, loading, pageSize]);
|
|
163
|
+
return {
|
|
164
|
+
agents,
|
|
165
|
+
isInitialLoading: loading && agents.length === 0,
|
|
166
|
+
isSearching: loading && agents.length > 0,
|
|
167
|
+
loadingMore,
|
|
168
|
+
error,
|
|
169
|
+
hasMore,
|
|
170
|
+
listRef,
|
|
171
|
+
sentinelRef,
|
|
172
|
+
pageSize,
|
|
173
|
+
setPageSize,
|
|
174
|
+
canPrev: mode === "paged" && offset > 0,
|
|
175
|
+
canNext: mode === "paged" && hasMore,
|
|
176
|
+
goPrev,
|
|
177
|
+
goNext
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/utils/scheduleShareUrl.ts
|
|
182
|
+
var SCHEDULE_AGENT_QUERY = "agent";
|
|
183
|
+
var SCHEDULE_STATUS_QUERY = "status";
|
|
184
|
+
var SCHEDULE_NAME_QUERY = "q";
|
|
185
|
+
var SCHEDULE_IS_NEW_QUERY = "isNew";
|
|
186
|
+
var SCHEDULE_SHARE_CHANGE_EVENT = "trueforge-schedule-share";
|
|
187
|
+
function nonEmpty(value) {
|
|
188
|
+
return value != null && value.length > 0 ? value : null;
|
|
189
|
+
}
|
|
190
|
+
function parseStatus(value) {
|
|
191
|
+
if (value === "active" || value === "paused") return value;
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
function readScheduleShareSearch(search) {
|
|
195
|
+
const params = new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
|
|
196
|
+
return {
|
|
197
|
+
agent: nonEmpty(params.get(SCHEDULE_AGENT_QUERY)),
|
|
198
|
+
status: parseStatus(params.get(SCHEDULE_STATUS_QUERY)),
|
|
199
|
+
q: nonEmpty(params.get(SCHEDULE_NAME_QUERY)),
|
|
200
|
+
isNew: params.get(SCHEDULE_IS_NEW_QUERY) === "true"
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function writeScheduleShareSearch(params, next) {
|
|
204
|
+
if (next.agent === null) params.delete(SCHEDULE_AGENT_QUERY);
|
|
205
|
+
else if (next.agent != null) params.set(SCHEDULE_AGENT_QUERY, next.agent);
|
|
206
|
+
if (next.status === null) params.delete(SCHEDULE_STATUS_QUERY);
|
|
207
|
+
else if (next.status != null) params.set(SCHEDULE_STATUS_QUERY, next.status);
|
|
208
|
+
if (next.q === null) params.delete(SCHEDULE_NAME_QUERY);
|
|
209
|
+
else if (next.q != null) params.set(SCHEDULE_NAME_QUERY, next.q);
|
|
210
|
+
if (next.isNew === null || next.isNew === false) params.delete(SCHEDULE_IS_NEW_QUERY);
|
|
211
|
+
else if (next.isNew === true) params.set(SCHEDULE_IS_NEW_QUERY, "true");
|
|
212
|
+
}
|
|
213
|
+
function clearScheduleShareSearch(params) {
|
|
214
|
+
params.delete(SCHEDULE_AGENT_QUERY);
|
|
215
|
+
params.delete(SCHEDULE_STATUS_QUERY);
|
|
216
|
+
params.delete(SCHEDULE_NAME_QUERY);
|
|
217
|
+
params.delete(SCHEDULE_IS_NEW_QUERY);
|
|
218
|
+
}
|
|
219
|
+
function replaceScheduleShareSearch(next) {
|
|
220
|
+
const url = new URL(window.location.href);
|
|
221
|
+
writeScheduleShareSearch(url.searchParams, next);
|
|
222
|
+
window.history.replaceState(window.history.state, "", url);
|
|
223
|
+
window.dispatchEvent(new Event(SCHEDULE_SHARE_CHANGE_EVENT));
|
|
224
|
+
return url.search;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export {
|
|
228
|
+
SEARCH_AGENTS_PAGE_SIZE,
|
|
229
|
+
searchAllAgents,
|
|
230
|
+
findAgentByName,
|
|
231
|
+
findLibraryAgent,
|
|
232
|
+
useSearchAgentsList,
|
|
233
|
+
readScheduleShareSearch,
|
|
234
|
+
writeScheduleShareSearch,
|
|
235
|
+
clearScheduleShareSearch,
|
|
236
|
+
replaceScheduleShareSearch
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=chunk-T6QQV5LK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/atoms/lib/useSearchAgentsList.ts","../src/atoms/lib/useDebouncedValue.ts","../src/utils/scheduleShareUrl.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useOptionalServer } from '../../server/ServerContext.js';\nimport type { AgentBuilderServer, AgentLibraryEntry } from '../../server/types.js';\nimport { getErrorMessage } from '../../utils/getErrorMessage.js';\nimport { useDebouncedValue } from './useDebouncedValue.js';\n\n/** Matches API AGENTS_PAGE_DEFAULT / AGENTS_PAGE_LIMIT. */\nexport const SEARCH_AGENTS_PAGE_SIZE = 50;\nexport const SEARCH_AGENTS_PAGE_MAX = 100;\nconst DEFAULT_DEBOUNCE_MS = 300;\nconst LOAD_MORE_ROOT_MARGIN = '48px';\n\nfunction clampPageSize(size: number): number {\n return Math.min(Math.max(size, 1), SEARCH_AGENTS_PAGE_MAX);\n}\n\n/** Drain every `searchAgents` page (offset pagination). */\nexport async function searchAllAgents(\n server: Pick<AgentBuilderServer, 'searchAgents'>,\n offset = 0,\n): Promise<AgentLibraryEntry[]> {\n const rows = await server.searchAgents({ limit: SEARCH_AGENTS_PAGE_SIZE, offset });\n if (rows.length < SEARCH_AGENTS_PAGE_SIZE) return rows;\n return [...rows, ...(await searchAllAgents(server, offset + rows.length))];\n}\n\n/** Exact-name lookup walks server-filtered pages until a precise match is found. */\nexport async function findAgentByName({\n server,\n agentName,\n offset = 0,\n}: {\n server: Pick<AgentBuilderServer, 'searchAgents'>;\n agentName: string;\n offset?: number;\n}): Promise<AgentLibraryEntry | undefined> {\n const rows = await server.searchAgents({ query: agentName, limit: SEARCH_AGENTS_PAGE_SIZE, offset });\n const match = rows.find(agent => agent.name === agentName);\n if (match != null || rows.length < SEARCH_AGENTS_PAGE_SIZE) return match;\n return findAgentByName({ server, agentName, offset: offset + rows.length });\n}\n\n/** Resolve by agent id or exact name by walking unfiltered pages (ids are not name-searchable). */\nexport async function findLibraryAgent({\n server,\n agentKey,\n offset = 0,\n}: {\n server: Pick<AgentBuilderServer, 'searchAgents'>;\n agentKey: string;\n offset?: number;\n}): Promise<AgentLibraryEntry | undefined> {\n const rows = await server.searchAgents({ limit: SEARCH_AGENTS_PAGE_SIZE, offset });\n const match = rows.find(agent => agent.name === agentKey || agent.agentId === agentKey);\n if (match != null || rows.length < SEARCH_AGENTS_PAGE_SIZE) return match;\n return findLibraryAgent({ server, agentKey, offset: offset + rows.length });\n}\n\nexport type UseSearchAgentsListOptions = {\n /** When false, no fetches run. */\n enabled: boolean;\n query: string;\n /** Bump to force a replace fetch (e.g. agentsListEpoch). */\n refreshKey?: number;\n /** Page size for infinite mode, or initial size for paged mode. Capped at 100. */\n limit?: number;\n debounceMs?: number;\n /**\n * `infinite` — append via IntersectionObserver sentinel (default).\n * `paged` — replace rows; navigate with goPrev / goNext.\n */\n mode?: 'infinite' | 'paged';\n};\n\nexport type UseSearchAgentsListResult = {\n agents: AgentLibraryEntry[];\n /** True while the replace fetch is in flight and the list is still empty. */\n isInitialLoading: boolean;\n /** True while replacing results that are already on screen (softer than a skeleton wipe). */\n isSearching: boolean;\n loadingMore: boolean;\n error: string | null;\n hasMore: boolean;\n listRef: (node: HTMLElement | null) => void;\n sentinelRef: (node: HTMLElement | null) => void;\n pageSize: number;\n setPageSize: (pageSize: number) => void;\n canPrev: boolean;\n canNext: boolean;\n goPrev: () => void;\n goNext: () => void;\n};\n\n/**\n * Debounced `searchAgents` with offset pagination.\n * Infinite mode: attach `listRef` / `sentinelRef` for IntersectionObserver load-more.\n * Paged mode: use `goPrev` / `goNext` / `setPageSize` (rows replaced each fetch).\n */\nexport function useSearchAgentsList({\n enabled,\n query,\n refreshKey = 0,\n limit: limitOption = SEARCH_AGENTS_PAGE_SIZE,\n debounceMs = DEFAULT_DEBOUNCE_MS,\n mode = 'infinite',\n}: UseSearchAgentsListOptions): UseSearchAgentsListResult {\n const server = useOptionalServer();\n // While closed, sync immediately so reopen never fetches a stale query.\n const debouncedQuery = useDebouncedValue(query, enabled ? debounceMs : 0);\n\n const [agents, setAgents] = useState<AgentLibraryEntry[]>([]);\n const [loading, setLoading] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [hasMore, setHasMore] = useState(false);\n const [pageSize, setPageSizeState] = useState(() => clampPageSize(limitOption));\n const [offset, setOffset] = useState(0);\n\n const genRef = useRef(0);\n const loadMoreInflightRef = useRef(false);\n const hasMoreRef = useRef(false);\n const agentsLenRef = useRef(0);\n const listElRef = useRef<HTMLElement | null>(null);\n const sentinelElRef = useRef<HTMLElement | null>(null);\n const [listEl, setListEl] = useState<HTMLElement | null>(null);\n const [sentinelEl, setSentinelEl] = useState<HTMLElement | null>(null);\n\n const limit = mode === 'paged' ? pageSize : clampPageSize(limitOption);\n\n hasMoreRef.current = hasMore;\n agentsLenRef.current = agents.length;\n\n const listRef = useCallback((node: HTMLElement | null) => {\n listElRef.current = node;\n setListEl(node);\n }, []);\n\n const sentinelRef = useCallback((node: HTMLElement | null) => {\n sentinelElRef.current = node;\n setSentinelEl(node);\n }, []);\n\n const searchQuery = debouncedQuery.trim() || undefined;\n\n // Reset to first page when the query or catalog epoch changes.\n useEffect(() => {\n if (mode !== 'paged') return;\n setOffset(0);\n }, [mode, searchQuery, refreshKey]);\n\n useEffect(() => {\n if (!enabled || server == null) return;\n\n const gen = ++genRef.current;\n loadMoreInflightRef.current = false;\n setLoading(true);\n setError(null);\n\n const fetchOffset = mode === 'paged' ? offset : 0;\n\n void server\n .searchAgents({ query: searchQuery, limit, offset: fetchOffset })\n .then(rows => {\n if (gen !== genRef.current) return;\n setAgents(rows);\n setHasMore(rows.length >= limit);\n })\n .catch((err: unknown) => {\n if (gen !== genRef.current) return;\n setAgents([]);\n setHasMore(false);\n setError(getErrorMessage(err, 'Failed to load agents.'));\n })\n .finally(() => {\n if (gen === genRef.current) setLoading(false);\n });\n\n return () => {\n genRef.current += 1;\n };\n }, [enabled, server, searchQuery, limit, refreshKey, mode, offset]);\n\n const loadMore = useCallback(() => {\n if (mode !== 'infinite') return;\n if (!enabled || server == null || !hasMoreRef.current || loadMoreInflightRef.current || loading) {\n return;\n }\n\n const gen = genRef.current;\n const nextOffset = agentsLenRef.current;\n loadMoreInflightRef.current = true;\n setLoadingMore(true);\n\n void server\n .searchAgents({ query: searchQuery, limit, offset: nextOffset })\n .then(rows => {\n if (gen !== genRef.current) return;\n setAgents(prev => [...prev, ...rows]);\n setHasMore(rows.length >= limit);\n })\n .catch(() => {\n if (gen !== genRef.current) return;\n setHasMore(false);\n })\n .finally(() => {\n loadMoreInflightRef.current = false;\n if (gen === genRef.current) setLoadingMore(false);\n });\n }, [enabled, server, searchQuery, limit, loading, mode]);\n\n useEffect(() => {\n if (mode !== 'infinite' || !enabled || !hasMore || listEl == null || sentinelEl == null) return;\n\n const observer = new IntersectionObserver(\n entries => {\n if (entries.some(entry => entry.isIntersecting)) {\n loadMore();\n }\n },\n { root: listEl, rootMargin: LOAD_MORE_ROOT_MARGIN },\n );\n observer.observe(sentinelEl);\n return () => observer.disconnect();\n }, [mode, enabled, hasMore, listEl, sentinelEl, loadMore, agents.length]);\n\n const setPageSize = useCallback((size: number) => {\n setPageSizeState(clampPageSize(size));\n setOffset(0);\n }, []);\n\n const goNext = useCallback(() => {\n if (mode !== 'paged' || !hasMoreRef.current || loading) return;\n setOffset(current => current + pageSize);\n }, [mode, loading, pageSize]);\n\n const goPrev = useCallback(() => {\n if (mode !== 'paged' || loading) return;\n setOffset(current => Math.max(0, current - pageSize));\n }, [mode, loading, pageSize]);\n\n return {\n agents,\n isInitialLoading: loading && agents.length === 0,\n isSearching: loading && agents.length > 0,\n loadingMore,\n error,\n hasMore,\n listRef,\n sentinelRef,\n pageSize,\n setPageSize,\n canPrev: mode === 'paged' && offset > 0,\n canNext: mode === 'paged' && hasMore,\n goPrev,\n goNext,\n };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\n\n/** Returns `value` immediately on first render; subsequent changes apply after `delayMs`. */\nexport function useDebouncedValue<T>(value: T, delayMs: number): T {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const id = window.setTimeout(() => setDebounced(value), delayMs);\n return () => window.clearTimeout(id);\n }, [value, delayMs]);\n\n return debounced;\n}\n","import type { ScheduleStatus } from '../server/types.js';\nimport { writeSessionShareSearch } from './sessionShareUrl.js';\n\nexport const SCHEDULE_AGENT_QUERY = 'agent';\nexport const SCHEDULE_STATUS_QUERY = 'status';\nexport const SCHEDULE_NAME_QUERY = 'q';\nexport const SCHEDULE_IS_NEW_QUERY = 'isNew';\n\nexport const SCHEDULE_SHARE_CHANGE_EVENT = 'trueforge-schedule-share';\n\nexport type ScheduleShareSearch = {\n /** Agent id filter; `null` means all agents. */\n agent: string | null;\n /** Status filter; `null` means all statuses. */\n status: ScheduleStatus | null;\n /** Name search; `null` when empty. */\n q: string | null;\n /** One-shot flag to open the create schedule drawer. */\n isNew: boolean;\n};\n\nexport type ScheduleShareWrite = {\n agent?: string | null;\n status?: ScheduleStatus | null;\n q?: string | null;\n isNew?: boolean | null;\n};\n\nfunction nonEmpty(value: string | null): string | null {\n return value != null && value.length > 0 ? value : null;\n}\n\nfunction parseStatus(value: string | null): ScheduleStatus | null {\n if (value === 'active' || value === 'paused') return value;\n return null;\n}\n\nexport function readScheduleShareSearch(search: string): ScheduleShareSearch {\n const params = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search);\n return {\n agent: nonEmpty(params.get(SCHEDULE_AGENT_QUERY)),\n status: parseStatus(params.get(SCHEDULE_STATUS_QUERY)),\n q: nonEmpty(params.get(SCHEDULE_NAME_QUERY)),\n isNew: params.get(SCHEDULE_IS_NEW_QUERY) === 'true',\n };\n}\n\nexport function writeScheduleShareSearch(params: URLSearchParams, next: ScheduleShareWrite): void {\n if (next.agent === null) params.delete(SCHEDULE_AGENT_QUERY);\n else if (next.agent != null) params.set(SCHEDULE_AGENT_QUERY, next.agent);\n if (next.status === null) params.delete(SCHEDULE_STATUS_QUERY);\n else if (next.status != null) params.set(SCHEDULE_STATUS_QUERY, next.status);\n if (next.q === null) params.delete(SCHEDULE_NAME_QUERY);\n else if (next.q != null) params.set(SCHEDULE_NAME_QUERY, next.q);\n if (next.isNew === null || next.isNew === false) params.delete(SCHEDULE_IS_NEW_QUERY);\n else if (next.isNew === true) params.set(SCHEDULE_IS_NEW_QUERY, 'true');\n}\n\n/** Drop all schedules-owned query keys (used when leaving the schedules place). */\nexport function clearScheduleShareSearch(params: URLSearchParams): void {\n params.delete(SCHEDULE_AGENT_QUERY);\n params.delete(SCHEDULE_STATUS_QUERY);\n params.delete(SCHEDULE_NAME_QUERY);\n params.delete(SCHEDULE_IS_NEW_QUERY);\n}\n\nexport function replaceScheduleShareSearch(next: ScheduleShareWrite): string {\n const url = new URL(window.location.href);\n writeScheduleShareSearch(url.searchParams, next);\n window.history.replaceState(window.history.state, '', url);\n window.dispatchEvent(new Event(SCHEDULE_SHARE_CHANGE_EVENT));\n return url.search;\n}\n\n/**\n * Point the address bar at schedules filtered to `agentId` (clears library agent\n * share keys). Caller still opens the schedules place via shell.\n */\nexport function writeOpenSchedulesForAgentSearch({ agentId, isNew }: { agentId: string; isNew?: boolean }): void {\n const url = new URL(window.location.href);\n writeSessionShareSearch(url.searchParams, {\n sessionId: null,\n agentId: null,\n tab: null,\n view: null,\n timeRange: null,\n });\n writeScheduleShareSearch(url.searchParams, {\n agent: agentId,\n status: null,\n q: null,\n isNew: isNew === true ? true : null,\n });\n window.history.replaceState(window.history.state, '', url);\n}\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect"]}
|