@truefoundry/trueforge-ui 0.1.0 → 0.2.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 +34 -15
- package/README.md +38 -38
- package/dist/{ConnectorSettings-H37ZFC6Z.js → ConnectorSettings-XEO5ZQO5.js} +8 -6
- package/dist/{ConnectorSettings-H37ZFC6Z.js.map → ConnectorSettings-XEO5ZQO5.js.map} +1 -1
- package/dist/{DockLayout-KEMFRWIR.js → DockLayout-F2KYSY4U.js} +10 -8
- package/dist/{DockLayout-KEMFRWIR.js.map → DockLayout-F2KYSY4U.js.map} +1 -1
- package/dist/{DrawerLayout-ZVWCKEIS.js → DrawerLayout-FJ7XC2FU.js} +12 -9
- package/dist/{DrawerLayout-ZVWCKEIS.js.map → DrawerLayout-FJ7XC2FU.js.map} +1 -1
- package/dist/{ModelSettings-QJMYHCMD.js → ModelSettings-2QB7LE22.js} +8 -6
- package/dist/{ModelSettings-QJMYHCMD.js.map → ModelSettings-2QB7LE22.js.map} +1 -1
- package/dist/OpenUiFenceBlock-3EFPY4JW.js +9 -0
- package/dist/{SandboxSettings-BUBMLW7Q.js → SandboxSettings-QDDIPRBP.js} +8 -6
- package/dist/{SandboxSettings-BUBMLW7Q.js.map → SandboxSettings-QDDIPRBP.js.map} +1 -1
- package/dist/{SettingsBuilder-26XSGIHK.js → SettingsBuilder-4NF3Y7UZ.js} +10 -8
- package/dist/{SettingsBuilder-26XSGIHK.js.map → SettingsBuilder-4NF3Y7UZ.js.map} +1 -1
- package/dist/ShellRouteSync-T4WLY57Q.js +172 -0
- package/dist/ShellRouteSync-T4WLY57Q.js.map +1 -0
- package/dist/{SidebarLayout-F3XFXW7B.js → SidebarLayout-KX6RSJTP.js} +12 -9
- package/dist/{SidebarLayout-F3XFXW7B.js.map → SidebarLayout-KX6RSJTP.js.map} +1 -1
- package/dist/{SkillSettings-IRMGDFRG.js → SkillSettings-5EETEEDI.js} +8 -6
- package/dist/{SkillSettings-IRMGDFRG.js.map → SkillSettings-5EETEEDI.js.map} +1 -1
- package/dist/TrueForgeUIWithRouter-IAQQTD5V.js +30 -0
- package/dist/TrueForgeUIWithRouter-IAQQTD5V.js.map +1 -0
- package/dist/{WidgetLayout-SZMABKIR.js → WidgetLayout-S6EK62TZ.js} +10 -8
- package/dist/{WidgetLayout-SZMABKIR.js.map → WidgetLayout-S6EK62TZ.js.map} +1 -1
- package/dist/chunk-72LC2M3R.js +567 -0
- package/dist/chunk-72LC2M3R.js.map +1 -0
- package/dist/chunk-EKVN6QSO.js +493 -0
- package/dist/chunk-EKVN6QSO.js.map +1 -0
- package/dist/chunk-FXCYLEFB.js +64 -0
- package/dist/chunk-FXCYLEFB.js.map +1 -0
- package/dist/chunk-IFLE7OMM.js +527 -0
- package/dist/chunk-IFLE7OMM.js.map +1 -0
- package/dist/{chunk-HT5HKQXE.js → chunk-JRRCAKEP.js} +2 -2
- package/dist/{chunk-7EEOWDLE.js → chunk-PTYEOSHT.js} +10 -8
- package/dist/{chunk-7EEOWDLE.js.map → chunk-PTYEOSHT.js.map} +1 -1
- package/dist/{chunk-H7DR64W3.js → chunk-UACLSDNL.js} +39 -94
- package/dist/chunk-UACLSDNL.js.map +1 -0
- package/dist/{chunk-QGNLP2EE.js → chunk-UU7C5DQ3.js} +18 -8
- package/dist/chunk-UU7C5DQ3.js.map +1 -0
- package/dist/chunk-WQULF5AT.js +460 -0
- package/dist/chunk-WQULF5AT.js.map +1 -0
- package/dist/{chunk-LRQHHZDX.js → chunk-X6U2Q7X5.js} +7 -5
- package/dist/{chunk-LRQHHZDX.js.map → chunk-X6U2Q7X5.js.map} +1 -1
- package/dist/chunk-YIWUG6MC.js +101 -0
- package/dist/chunk-YIWUG6MC.js.map +1 -0
- package/dist/index.d.ts +57 -9
- package/dist/index.js +41 -428
- package/dist/index.js.map +1 -1
- package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +9 -6
- package/dist/OpenUiFenceBlock-XFBUGPKQ.js +0 -9
- package/dist/chunk-DTF7ZMUJ.js +0 -567
- package/dist/chunk-DTF7ZMUJ.js.map +0 -1
- package/dist/chunk-H7DR64W3.js.map +0 -1
- package/dist/chunk-QGNLP2EE.js.map +0 -1
- package/dist/chunk-XAZ5HJXV.js +0 -862
- package/dist/chunk-XAZ5HJXV.js.map +0 -1
- /package/dist/{OpenUiFenceBlock-XFBUGPKQ.js.map → OpenUiFenceBlock-3EFPY4JW.js.map} +0 -0
- /package/dist/{chunk-HT5HKQXE.js.map → chunk-JRRCAKEP.js.map} +0 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
// src/server/ServerContext.tsx
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var ServerContext = createContext(null);
|
|
5
|
+
var ServerCapabilitiesContext = createContext(null);
|
|
6
|
+
function ServerProvider({ server, children }) {
|
|
7
|
+
const [capabilities, setCapabilities] = useState(null);
|
|
8
|
+
const cancelActiveRequestRef = useRef(null);
|
|
9
|
+
const refreshCapabilities = useCallback(() => {
|
|
10
|
+
cancelActiveRequestRef.current?.();
|
|
11
|
+
let cancelled = false;
|
|
12
|
+
cancelActiveRequestRef.current = () => {
|
|
13
|
+
cancelled = true;
|
|
14
|
+
};
|
|
15
|
+
void server.getCapabilities().then((response) => {
|
|
16
|
+
if (!cancelled) setCapabilities(response.data);
|
|
17
|
+
}).catch(() => {
|
|
18
|
+
});
|
|
19
|
+
}, [server]);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
setCapabilities(null);
|
|
22
|
+
refreshCapabilities();
|
|
23
|
+
return () => {
|
|
24
|
+
cancelActiveRequestRef.current?.();
|
|
25
|
+
};
|
|
26
|
+
}, [refreshCapabilities]);
|
|
27
|
+
const capabilitiesValue = useMemo(
|
|
28
|
+
() => ({ capabilities, refresh: refreshCapabilities }),
|
|
29
|
+
[capabilities, refreshCapabilities]
|
|
30
|
+
);
|
|
31
|
+
return /* @__PURE__ */ jsx(ServerContext.Provider, { value: server, children: /* @__PURE__ */ jsx(ServerCapabilitiesContext.Provider, { value: capabilitiesValue, children }) });
|
|
32
|
+
}
|
|
33
|
+
function useServer() {
|
|
34
|
+
const server = useContext(ServerContext);
|
|
35
|
+
if (server == null) {
|
|
36
|
+
throw new Error("useServer must be used within a ServerProvider.");
|
|
37
|
+
}
|
|
38
|
+
return server;
|
|
39
|
+
}
|
|
40
|
+
function useOptionalServer() {
|
|
41
|
+
return useContext(ServerContext);
|
|
42
|
+
}
|
|
43
|
+
function useServerCapabilities() {
|
|
44
|
+
return useContext(ServerCapabilitiesContext)?.capabilities ?? null;
|
|
45
|
+
}
|
|
46
|
+
function useOptionalRefreshServerCapabilities() {
|
|
47
|
+
return useContext(ServerCapabilitiesContext)?.refresh ?? null;
|
|
48
|
+
}
|
|
49
|
+
function useCatalogServer() {
|
|
50
|
+
const server = useServer();
|
|
51
|
+
if (server.catalog == null) {
|
|
52
|
+
throw new Error("useCatalogServer requires AgentUIServer.catalog. Pass catalog to createTrueFoundryServer.");
|
|
53
|
+
}
|
|
54
|
+
return server.catalog;
|
|
55
|
+
}
|
|
56
|
+
function useOptionalCatalogServer() {
|
|
57
|
+
return useOptionalServer()?.catalog ?? null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/server/ShellModeContext.tsx
|
|
61
|
+
import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
62
|
+
|
|
63
|
+
// src/server/draftSpecPreferences.ts
|
|
64
|
+
var DRAFT_SPEC_PREFERENCES_STORAGE_KEY = "tfy-aui-draft-spec-preferences";
|
|
65
|
+
function isObject(value) {
|
|
66
|
+
return typeof value === "object" && value !== null;
|
|
67
|
+
}
|
|
68
|
+
function isMountList(value) {
|
|
69
|
+
return Array.isArray(value) && value.every(isObject);
|
|
70
|
+
}
|
|
71
|
+
function isAgentSpec(value) {
|
|
72
|
+
if (!isObject(value)) return false;
|
|
73
|
+
const model = Reflect.get(value, "model");
|
|
74
|
+
if (!isObject(model) || typeof Reflect.get(model, "name") !== "string") return false;
|
|
75
|
+
const params = Reflect.get(model, "params");
|
|
76
|
+
if (params !== void 0 && !isObject(params)) return false;
|
|
77
|
+
const skills = Reflect.get(value, "skills");
|
|
78
|
+
if (skills !== void 0 && !isMountList(skills)) return false;
|
|
79
|
+
const mcpServers = Reflect.get(value, "mcpServers");
|
|
80
|
+
if (mcpServers !== void 0 && !isMountList(mcpServers)) return false;
|
|
81
|
+
const config = Reflect.get(value, "config");
|
|
82
|
+
return config === void 0 || isObject(config);
|
|
83
|
+
}
|
|
84
|
+
function isStoredDraftSpecPreferences(value) {
|
|
85
|
+
return isObject(value) && Reflect.get(value, "version") === 1 && isAgentSpec(Reflect.get(value, "spec"));
|
|
86
|
+
}
|
|
87
|
+
function selectDraftSpecPreferences(spec) {
|
|
88
|
+
return {
|
|
89
|
+
model: spec.model,
|
|
90
|
+
...spec.skills !== void 0 ? { skills: spec.skills } : {},
|
|
91
|
+
...spec.mcpServers !== void 0 ? { mcpServers: spec.mcpServers } : {},
|
|
92
|
+
...spec.config !== void 0 ? { config: spec.config } : {}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function readSandboxEnabled(spec) {
|
|
96
|
+
if (spec.config === void 0) return void 0;
|
|
97
|
+
const sandbox = Reflect.get(spec.config, "sandbox");
|
|
98
|
+
if (!isObject(sandbox)) return void 0;
|
|
99
|
+
const enabled = Reflect.get(sandbox, "enabled");
|
|
100
|
+
return typeof enabled === "boolean" ? enabled : void 0;
|
|
101
|
+
}
|
|
102
|
+
function withCapabilitiesSandbox(spec, sandboxEnabled) {
|
|
103
|
+
if (sandboxEnabled == null) return spec;
|
|
104
|
+
if (readSandboxEnabled(spec) === sandboxEnabled) return spec;
|
|
105
|
+
const config = {
|
|
106
|
+
...spec.config,
|
|
107
|
+
sandbox: { enabled: sandboxEnabled }
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
...spec,
|
|
111
|
+
config
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function readDraftSpecPreferences() {
|
|
115
|
+
if (typeof window === "undefined") return null;
|
|
116
|
+
try {
|
|
117
|
+
const stored = JSON.parse(window.localStorage.getItem(DRAFT_SPEC_PREFERENCES_STORAGE_KEY) ?? "null");
|
|
118
|
+
return isStoredDraftSpecPreferences(stored) ? stored.spec : null;
|
|
119
|
+
} catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function writeDraftSpecPreferences(spec) {
|
|
124
|
+
if (typeof window === "undefined") return;
|
|
125
|
+
try {
|
|
126
|
+
const stored = {
|
|
127
|
+
version: 1,
|
|
128
|
+
spec: selectDraftSpecPreferences(spec)
|
|
129
|
+
};
|
|
130
|
+
window.localStorage.setItem(DRAFT_SPEC_PREFERENCES_STORAGE_KEY, JSON.stringify(stored));
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/server/ShellModeContext.tsx
|
|
136
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
137
|
+
var DEFAULT_AGENT_CONFIG = {
|
|
138
|
+
mode: "AgentLibraryWithComposer"
|
|
139
|
+
};
|
|
140
|
+
var ShellModeContext = createContext2(null);
|
|
141
|
+
var FALLBACK_MUTABLE_SPEC = {
|
|
142
|
+
model: { name: "openai-main/gpt-4.1" }
|
|
143
|
+
};
|
|
144
|
+
function mutableSeedFromConfig(config) {
|
|
145
|
+
if (config.mode === "AgentComposer" || config.mode === "AgentLibraryWithComposer") {
|
|
146
|
+
return config.defaultAgentSpec ?? FALLBACK_MUTABLE_SPEC;
|
|
147
|
+
}
|
|
148
|
+
return FALLBACK_MUTABLE_SPEC;
|
|
149
|
+
}
|
|
150
|
+
function initialMode(config, mutableSeed) {
|
|
151
|
+
switch (config.mode) {
|
|
152
|
+
case "SingleAgent":
|
|
153
|
+
return {
|
|
154
|
+
status: "active",
|
|
155
|
+
isMutable: false,
|
|
156
|
+
agentId: config.name,
|
|
157
|
+
agentName: config.name,
|
|
158
|
+
locked: true
|
|
159
|
+
};
|
|
160
|
+
case "AgentLibrary":
|
|
161
|
+
return { status: "idle" };
|
|
162
|
+
case "AgentComposer":
|
|
163
|
+
case "AgentLibraryWithComposer":
|
|
164
|
+
return {
|
|
165
|
+
status: "active",
|
|
166
|
+
isMutable: true,
|
|
167
|
+
agentSpec: mutableSeed,
|
|
168
|
+
locked: false
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function libraryAgentId(agent) {
|
|
173
|
+
return agent.agentId ?? agent.name;
|
|
174
|
+
}
|
|
175
|
+
function ShellModeProvider({
|
|
176
|
+
agentConfig = DEFAULT_AGENT_CONFIG,
|
|
177
|
+
initialSettingsOpen = false,
|
|
178
|
+
children
|
|
179
|
+
}) {
|
|
180
|
+
const capabilities = useServerCapabilities();
|
|
181
|
+
const refreshCapabilities = useOptionalRefreshServerCapabilities();
|
|
182
|
+
const rememberedSpecRef = useRef2(readDraftSpecPreferences());
|
|
183
|
+
const mutableSeedRef = useRef2(rememberedSpecRef.current ?? mutableSeedFromConfig(agentConfig));
|
|
184
|
+
if (rememberedSpecRef.current == null && (agentConfig.mode === "AgentComposer" || agentConfig.mode === "AgentLibraryWithComposer") && agentConfig.defaultAgentSpec != null) {
|
|
185
|
+
mutableSeedRef.current = agentConfig.defaultAgentSpec;
|
|
186
|
+
}
|
|
187
|
+
const mutableSeed = mutableSeedRef.current;
|
|
188
|
+
const isLibraryEnabled = agentConfig.mode === "AgentLibrary" || agentConfig.mode === "AgentLibraryWithComposer";
|
|
189
|
+
const isComposerEnabled = agentConfig.mode === "AgentComposer" || agentConfig.mode === "AgentLibraryWithComposer";
|
|
190
|
+
const isNewChatEnabled = agentConfig.mode !== "AgentLibrary";
|
|
191
|
+
const locked = agentConfig.mode === "SingleAgent";
|
|
192
|
+
const [mode, setMode] = useState2(() => initialMode(agentConfig, mutableSeed));
|
|
193
|
+
const [mutableEpoch, setMutableEpoch] = useState2(0);
|
|
194
|
+
const [clearEpoch, setClearEpoch] = useState2(0);
|
|
195
|
+
const [agentsListEpoch, setAgentsListEpoch] = useState2(0);
|
|
196
|
+
const [settingsOpenState, setSettingsOpenState] = useState2(initialSettingsOpen);
|
|
197
|
+
const [settingsSection, setSettingsSection] = useState2("models");
|
|
198
|
+
const [historyAgentFilter, setHistoryAgentFilter] = useState2(null);
|
|
199
|
+
const [pendingSessionId, setPendingSessionId] = useState2(void 0);
|
|
200
|
+
const settingsEnabled = capabilities?.settings?.enabled !== false;
|
|
201
|
+
const settingsOpen = settingsEnabled && settingsOpenState;
|
|
202
|
+
const setSettingsOpen = useCallback2(
|
|
203
|
+
(open, section) => {
|
|
204
|
+
if (section !== void 0) {
|
|
205
|
+
setSettingsSection(section);
|
|
206
|
+
}
|
|
207
|
+
setSettingsOpenState(settingsEnabled && open);
|
|
208
|
+
},
|
|
209
|
+
[settingsEnabled]
|
|
210
|
+
);
|
|
211
|
+
useEffect2(() => {
|
|
212
|
+
if (!settingsEnabled) {
|
|
213
|
+
setSettingsOpenState(false);
|
|
214
|
+
}
|
|
215
|
+
}, [settingsEnabled]);
|
|
216
|
+
const invalidateAgentsList = useCallback2(() => {
|
|
217
|
+
setAgentsListEpoch((n) => n + 1);
|
|
218
|
+
}, []);
|
|
219
|
+
const lockedAgentName = agentConfig.mode === "SingleAgent" ? agentConfig.name : "";
|
|
220
|
+
const effectiveMode = useMemo2(() => {
|
|
221
|
+
if (!locked) return mode;
|
|
222
|
+
return {
|
|
223
|
+
status: "active",
|
|
224
|
+
isMutable: false,
|
|
225
|
+
agentId: lockedAgentName,
|
|
226
|
+
agentName: lockedAgentName,
|
|
227
|
+
locked: true
|
|
228
|
+
};
|
|
229
|
+
}, [locked, lockedAgentName, mode]);
|
|
230
|
+
const listSessionsAgentId = useMemo2(() => {
|
|
231
|
+
if (locked) return lockedAgentName;
|
|
232
|
+
if (!isLibraryEnabled) return void 0;
|
|
233
|
+
return historyAgentFilter ?? void 0;
|
|
234
|
+
}, [locked, lockedAgentName, isLibraryEnabled, historyAgentFilter]);
|
|
235
|
+
const bumpEpoch = useCallback2((isMutable) => {
|
|
236
|
+
if (isMutable) setMutableEpoch((n) => n + 1);
|
|
237
|
+
else setClearEpoch((n) => n + 1);
|
|
238
|
+
}, []);
|
|
239
|
+
const selectLibraryAgent = useCallback2(
|
|
240
|
+
(req) => {
|
|
241
|
+
if (req.isMutable) {
|
|
242
|
+
if (!isComposerEnabled) return;
|
|
243
|
+
setSettingsOpen(false);
|
|
244
|
+
setPendingSessionId(void 0);
|
|
245
|
+
setMode({
|
|
246
|
+
status: "active",
|
|
247
|
+
isMutable: true,
|
|
248
|
+
agentId: req.agentId,
|
|
249
|
+
agentName: req.agentName,
|
|
250
|
+
agentSpec: req.agentSpec ?? mutableSeedRef.current,
|
|
251
|
+
locked: false
|
|
252
|
+
});
|
|
253
|
+
bumpEpoch(true);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (!isLibraryEnabled) return;
|
|
257
|
+
const agentName = req.agentName ?? req.agentId;
|
|
258
|
+
if (agentName == null) return;
|
|
259
|
+
setSettingsOpen(false);
|
|
260
|
+
setPendingSessionId(void 0);
|
|
261
|
+
setMode({
|
|
262
|
+
status: "active",
|
|
263
|
+
isMutable: false,
|
|
264
|
+
agentId: req.agentId ?? agentName,
|
|
265
|
+
agentName,
|
|
266
|
+
locked: false
|
|
267
|
+
});
|
|
268
|
+
bumpEpoch(false);
|
|
269
|
+
},
|
|
270
|
+
[isComposerEnabled, isLibraryEnabled, bumpEpoch, setSettingsOpen]
|
|
271
|
+
);
|
|
272
|
+
const bindMutableAgent = useCallback2(
|
|
273
|
+
(req) => {
|
|
274
|
+
if (!isComposerEnabled) return;
|
|
275
|
+
setMode((prev) => {
|
|
276
|
+
if (prev.status !== "active" || !prev.isMutable) return prev;
|
|
277
|
+
return {
|
|
278
|
+
status: "active",
|
|
279
|
+
isMutable: true,
|
|
280
|
+
agentId: req.agentId,
|
|
281
|
+
agentName: req.agentName,
|
|
282
|
+
agentSpec: req.agentSpec,
|
|
283
|
+
locked: false
|
|
284
|
+
};
|
|
285
|
+
});
|
|
286
|
+
},
|
|
287
|
+
[isComposerEnabled]
|
|
288
|
+
);
|
|
289
|
+
const selectAgent = useCallback2(
|
|
290
|
+
(name) => {
|
|
291
|
+
selectLibraryAgent({ isMutable: false, agentId: name, agentName: name });
|
|
292
|
+
},
|
|
293
|
+
[selectLibraryAgent]
|
|
294
|
+
);
|
|
295
|
+
const openDraft = useCallback2(() => {
|
|
296
|
+
if (!isComposerEnabled) return;
|
|
297
|
+
refreshCapabilities?.();
|
|
298
|
+
selectLibraryAgent({ isMutable: true, agentSpec: mutableSeedRef.current });
|
|
299
|
+
}, [isComposerEnabled, refreshCapabilities, selectLibraryAgent]);
|
|
300
|
+
const sandboxEnabled = capabilities?.sandbox.enabled;
|
|
301
|
+
const rememberDraftSpec = useCallback2(
|
|
302
|
+
(agentSpec) => {
|
|
303
|
+
const preferences = withCapabilitiesSandbox(selectDraftSpecPreferences(agentSpec), sandboxEnabled);
|
|
304
|
+
rememberedSpecRef.current = preferences;
|
|
305
|
+
mutableSeedRef.current = preferences;
|
|
306
|
+
writeDraftSpecPreferences(preferences);
|
|
307
|
+
},
|
|
308
|
+
[sandboxEnabled]
|
|
309
|
+
);
|
|
310
|
+
const openHistorySession = useCallback2(
|
|
311
|
+
({
|
|
312
|
+
sessionId,
|
|
313
|
+
agentName,
|
|
314
|
+
isMutable: isMutableOpt
|
|
315
|
+
}) => {
|
|
316
|
+
setSettingsOpen(false);
|
|
317
|
+
setPendingSessionId(sessionId);
|
|
318
|
+
const isMutable = isMutableOpt ?? agentName == null;
|
|
319
|
+
if (isMutable) {
|
|
320
|
+
if (!isComposerEnabled) return;
|
|
321
|
+
setMode({
|
|
322
|
+
status: "active",
|
|
323
|
+
isMutable: true,
|
|
324
|
+
agentSpec: mutableSeedRef.current,
|
|
325
|
+
locked: false
|
|
326
|
+
});
|
|
327
|
+
bumpEpoch(true);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (locked) {
|
|
331
|
+
if (agentName == null || lockedAgentName !== agentName) return;
|
|
332
|
+
} else if (!isLibraryEnabled) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
setMode({
|
|
336
|
+
status: "active",
|
|
337
|
+
isMutable: false,
|
|
338
|
+
locked: false,
|
|
339
|
+
...agentName != null ? { agentId: agentName, agentName } : {}
|
|
340
|
+
});
|
|
341
|
+
bumpEpoch(false);
|
|
342
|
+
},
|
|
343
|
+
[isLibraryEnabled, isComposerEnabled, locked, lockedAgentName, bumpEpoch, setSettingsOpen]
|
|
344
|
+
);
|
|
345
|
+
const clearChat = useCallback2(() => {
|
|
346
|
+
if (effectiveMode.status === "idle") return;
|
|
347
|
+
setPendingSessionId(void 0);
|
|
348
|
+
if (effectiveMode.isMutable) {
|
|
349
|
+
setMode({
|
|
350
|
+
status: "active",
|
|
351
|
+
isMutable: true,
|
|
352
|
+
agentId: effectiveMode.agentId,
|
|
353
|
+
agentName: effectiveMode.agentName,
|
|
354
|
+
agentSpec: effectiveMode.agentSpec ?? mutableSeedRef.current,
|
|
355
|
+
locked: false
|
|
356
|
+
});
|
|
357
|
+
bumpEpoch(true);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
bumpEpoch(false);
|
|
361
|
+
}, [effectiveMode, bumpEpoch]);
|
|
362
|
+
const openLibraryHome = useCallback2(() => {
|
|
363
|
+
if (!isLibraryEnabled || isComposerEnabled) return;
|
|
364
|
+
setPendingSessionId(void 0);
|
|
365
|
+
setSettingsOpen(false);
|
|
366
|
+
setMode({ status: "idle" });
|
|
367
|
+
bumpEpoch(false);
|
|
368
|
+
}, [isLibraryEnabled, isComposerEnabled, setSettingsOpen, bumpEpoch]);
|
|
369
|
+
const runtimeKey = useMemo2(() => {
|
|
370
|
+
if (effectiveMode.status === "idle") return "idle";
|
|
371
|
+
if (effectiveMode.isMutable) {
|
|
372
|
+
return `mut:${pendingSessionId ?? ""}:${mutableEpoch}`;
|
|
373
|
+
}
|
|
374
|
+
const id = effectiveMode.agentId ?? effectiveMode.agentName ?? "";
|
|
375
|
+
return `immut:${id}:${pendingSessionId ?? ""}:${clearEpoch}`;
|
|
376
|
+
}, [effectiveMode, mutableEpoch, clearEpoch, pendingSessionId]);
|
|
377
|
+
const value = useMemo2(
|
|
378
|
+
() => ({
|
|
379
|
+
mode: effectiveMode,
|
|
380
|
+
agentConfigMode: agentConfig.mode,
|
|
381
|
+
isLibraryEnabled,
|
|
382
|
+
isComposerEnabled,
|
|
383
|
+
isNewChatEnabled,
|
|
384
|
+
settingsOpen,
|
|
385
|
+
settingsSection,
|
|
386
|
+
setSettingsOpen,
|
|
387
|
+
selectLibraryAgent,
|
|
388
|
+
bindMutableAgent,
|
|
389
|
+
selectAgent,
|
|
390
|
+
openDraft,
|
|
391
|
+
rememberDraftSpec,
|
|
392
|
+
openHistorySession,
|
|
393
|
+
clearChat,
|
|
394
|
+
openLibraryHome,
|
|
395
|
+
runtimeKey,
|
|
396
|
+
historyAgentFilter,
|
|
397
|
+
setHistoryAgentFilter,
|
|
398
|
+
listSessionsAgentId,
|
|
399
|
+
pendingSessionId,
|
|
400
|
+
agentsListEpoch,
|
|
401
|
+
invalidateAgentsList
|
|
402
|
+
}),
|
|
403
|
+
[
|
|
404
|
+
effectiveMode,
|
|
405
|
+
agentConfig.mode,
|
|
406
|
+
isLibraryEnabled,
|
|
407
|
+
isComposerEnabled,
|
|
408
|
+
isNewChatEnabled,
|
|
409
|
+
settingsOpen,
|
|
410
|
+
settingsSection,
|
|
411
|
+
setSettingsOpen,
|
|
412
|
+
selectLibraryAgent,
|
|
413
|
+
bindMutableAgent,
|
|
414
|
+
selectAgent,
|
|
415
|
+
openDraft,
|
|
416
|
+
rememberDraftSpec,
|
|
417
|
+
openHistorySession,
|
|
418
|
+
clearChat,
|
|
419
|
+
openLibraryHome,
|
|
420
|
+
runtimeKey,
|
|
421
|
+
historyAgentFilter,
|
|
422
|
+
listSessionsAgentId,
|
|
423
|
+
pendingSessionId,
|
|
424
|
+
agentsListEpoch,
|
|
425
|
+
invalidateAgentsList
|
|
426
|
+
]
|
|
427
|
+
);
|
|
428
|
+
return /* @__PURE__ */ jsx2(ShellModeContext.Provider, { value, children });
|
|
429
|
+
}
|
|
430
|
+
function useShellMode() {
|
|
431
|
+
const ctx = useContext2(ShellModeContext);
|
|
432
|
+
if (ctx == null) {
|
|
433
|
+
throw new Error("useShellMode must be used within a ShellModeProvider.");
|
|
434
|
+
}
|
|
435
|
+
return ctx;
|
|
436
|
+
}
|
|
437
|
+
function useOptionalShellMode() {
|
|
438
|
+
return useContext2(ShellModeContext);
|
|
439
|
+
}
|
|
440
|
+
function shellIsMutable(mode) {
|
|
441
|
+
return mode.status === "active" && mode.isMutable;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export {
|
|
445
|
+
withCapabilitiesSandbox,
|
|
446
|
+
ServerProvider,
|
|
447
|
+
useServer,
|
|
448
|
+
useOptionalServer,
|
|
449
|
+
useServerCapabilities,
|
|
450
|
+
useOptionalRefreshServerCapabilities,
|
|
451
|
+
useCatalogServer,
|
|
452
|
+
useOptionalCatalogServer,
|
|
453
|
+
DEFAULT_AGENT_CONFIG,
|
|
454
|
+
libraryAgentId,
|
|
455
|
+
ShellModeProvider,
|
|
456
|
+
useShellMode,
|
|
457
|
+
useOptionalShellMode,
|
|
458
|
+
shellIsMutable
|
|
459
|
+
};
|
|
460
|
+
//# sourceMappingURL=chunk-WQULF5AT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/ServerContext.tsx","../src/server/ShellModeContext.tsx","../src/server/draftSpecPreferences.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport type { AgentBuilderCapabilitiesResponse, AgentUIServer, CatalogServer } from './types.js';\n\nconst ServerContext = createContext<AgentUIServer | null>(null);\nconst ServerCapabilitiesContext = createContext<{\n capabilities: AgentBuilderCapabilitiesResponse['data'] | null;\n refresh: () => void;\n} | null>(null);\n\nexport function ServerProvider({ server, children }: { server: AgentUIServer; children: ReactNode }) {\n const [capabilities, setCapabilities] = useState<AgentBuilderCapabilitiesResponse['data'] | null>(null);\n const cancelActiveRequestRef = useRef<(() => void) | null>(null);\n const refreshCapabilities = useCallback(() => {\n cancelActiveRequestRef.current?.();\n let cancelled = false;\n cancelActiveRequestRef.current = () => {\n cancelled = true;\n };\n void server\n .getCapabilities()\n .then(response => {\n if (!cancelled) setCapabilities(response.data);\n })\n .catch(() => {\n // Preserve the last known capabilities when a refresh fails.\n });\n }, [server]);\n\n useEffect(() => {\n setCapabilities(null);\n refreshCapabilities();\n return () => {\n cancelActiveRequestRef.current?.();\n };\n }, [refreshCapabilities]);\n\n const capabilitiesValue = useMemo(\n () => ({ capabilities, refresh: refreshCapabilities }),\n [capabilities, refreshCapabilities],\n );\n\n return (\n <ServerContext.Provider value={server}>\n <ServerCapabilitiesContext.Provider value={capabilitiesValue}>{children}</ServerCapabilitiesContext.Provider>\n </ServerContext.Provider>\n );\n}\n\nexport function useServer(): AgentUIServer {\n const server = useContext(ServerContext);\n if (server == null) {\n throw new Error('useServer must be used within a ServerProvider.');\n }\n return server;\n}\n\nexport function useOptionalServer(): AgentUIServer | null {\n return useContext(ServerContext);\n}\n\nexport function useServerCapabilities(): AgentBuilderCapabilitiesResponse['data'] | null {\n return useContext(ServerCapabilitiesContext)?.capabilities ?? null;\n}\n\nexport function useOptionalRefreshServerCapabilities(): (() => void) | null {\n return useContext(ServerCapabilitiesContext)?.refresh ?? null;\n}\n\nexport function useCatalogServer(): CatalogServer {\n const server = useServer();\n if (server.catalog == null) {\n throw new Error('useCatalogServer requires AgentUIServer.catalog. Pass catalog to createTrueFoundryServer.');\n }\n return server.catalog;\n}\n\nexport function useOptionalCatalogServer(): CatalogServer | null {\n return useOptionalServer()?.catalog ?? null;\n}\n","'use client';\n\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport {\n readDraftSpecPreferences,\n selectDraftSpecPreferences,\n withCapabilitiesSandbox,\n writeDraftSpecPreferences,\n} from './draftSpecPreferences.js';\nimport { useOptionalRefreshServerCapabilities, useServerCapabilities } from './ServerContext.js';\nimport type { AgentLibraryEntry, AgentSpec } from './types.js';\n\n/** Host-facing shell configuration for agent / library / composer chrome. */\nexport type AgentConfig =\n | { mode: 'SingleAgent'; name: string }\n | { mode: 'AgentLibrary' }\n | { mode: 'AgentComposer'; defaultAgentSpec?: AgentSpec }\n | { mode: 'AgentLibraryWithComposer'; defaultAgentSpec?: AgentSpec };\n\nexport const DEFAULT_AGENT_CONFIG: AgentConfig = {\n mode: 'AgentLibraryWithComposer',\n};\n\n/**\n * Active chat binding. Mutability (`isMutable`) decides composer / Save / updateSession —\n * not a parallel draft|named shell type.\n */\nexport type ShellMode =\n | { status: 'idle' }\n | {\n status: 'active';\n isMutable: boolean;\n /** Identity for immutable bind + history filter. */\n agentId?: string;\n /** Display / welcome label (often same as agentId). */\n agentName?: string;\n /** Seed for mutable (draft) runtime. */\n agentSpec?: AgentSpec;\n locked: boolean;\n };\n\n/** Library / New Chat create intent. */\nexport type SelectLibraryAgentRequest = {\n isMutable: boolean;\n agentId?: string;\n agentName?: string;\n agentSpec?: AgentSpec;\n};\n\nexport type SettingsSection = 'models' | 'connectors' | 'skills' | 'sandbox';\n\ntype ShellModeContextValue = {\n mode: ShellMode;\n /** Host agentConfig mode (capabilities source). */\n agentConfigMode: AgentConfig['mode'];\n /** Agents Library chrome. */\n isLibraryEnabled: boolean;\n /** Mutable composer / Save Agent chrome (host capability). */\n isComposerEnabled: boolean;\n /** Sidebar / list New Chat control. */\n isNewChatEnabled: boolean;\n settingsOpen: boolean;\n settingsSection: SettingsSection;\n setSettingsOpen: (open: boolean, section?: SettingsSection) => void;\n /**\n * Bind from the Agents Library (Try = immutable, Edit = mutable + agentSpec).\n * Prefer this over `selectAgent` / `openDraft` when both fields are available.\n */\n selectLibraryAgent: (req: SelectLibraryAgentRequest) => void;\n /**\n * Attach identity + agentSpec to the *current* mutable chat without remounting.\n * Used after `saveAgent` so the same draft session continues as an editable agent.\n */\n bindMutableAgent: (req: { agentId: string; agentName: string; agentSpec: AgentSpec }) => void;\n /** @deprecated Prefer `selectLibraryAgent({ isMutable: false, agentName })`. */\n selectAgent: (agentName: string) => void;\n /** @deprecated Prefer `selectLibraryAgent({ isMutable: true, agentSpec })`. */\n openDraft: () => void;\n /** Remember plain-draft composer choices as the seed for future new chats. */\n rememberDraftSpec: (agentSpec: AgentSpec) => void;\n /**\n * Open a history session, remounting when mutability/identity changes.\n * Prefer explicit `isMutable` from the session row; when omitted, agentName\n * present → immutable and agentName absent → mutable. Immutable rows may omit\n * `agentName` when the registry agent was deleted.\n */\n openHistorySession: (req: { sessionId: string; agentName?: string; isMutable?: boolean }) => void;\n /** Reset current chat; no-op when idle. */\n clearChat: () => void;\n /** Return pure Agents Library to its idle landing; no-op in other modes. */\n openLibraryHome: () => void;\n /** Remount key for the chat runtime when binding changes. */\n runtimeKey: string;\n /**\n * History list filter forwarded as `listSessions({ agentId })`.\n * `null` = All chats. Only meaningful when `isLibraryEnabled`.\n */\n historyAgentFilter: string | null;\n setHistoryAgentFilter: (agentId: string | null) => void;\n /** Effective `listSessionsAgentId` for the runtime (SingleAgent locks to name). */\n listSessionsAgentId: string | undefined;\n /** Session to open after a binding remount (history click across mutability). */\n pendingSessionId: string | undefined;\n /**\n * Bumped when the Agents Library catalog may have changed (e.g. after saveAgent).\n * Library chrome should re-fetch when this changes.\n */\n agentsListEpoch: number;\n invalidateAgentsList: () => void;\n};\n\nconst ShellModeContext = createContext<ShellModeContextValue | null>(null);\n\nconst FALLBACK_MUTABLE_SPEC: AgentSpec = {\n model: { name: 'openai-main/gpt-4.1' },\n};\n\nfunction mutableSeedFromConfig(config: AgentConfig): AgentSpec {\n if (config.mode === 'AgentComposer' || config.mode === 'AgentLibraryWithComposer') {\n return config.defaultAgentSpec ?? FALLBACK_MUTABLE_SPEC;\n }\n return FALLBACK_MUTABLE_SPEC;\n}\n\nfunction initialMode(config: AgentConfig, mutableSeed: AgentSpec): ShellMode {\n switch (config.mode) {\n case 'SingleAgent':\n return {\n status: 'active',\n isMutable: false,\n agentId: config.name,\n agentName: config.name,\n locked: true,\n };\n case 'AgentLibrary':\n return { status: 'idle' };\n case 'AgentComposer':\n case 'AgentLibraryWithComposer':\n return {\n status: 'active',\n isMutable: true,\n agentSpec: mutableSeed,\n locked: false,\n };\n }\n}\n\nfunction libraryAgentId(agent: Pick<AgentLibraryEntry, 'agentId' | 'name'>): string {\n return agent.agentId ?? agent.name;\n}\n\nexport function ShellModeProvider({\n agentConfig = DEFAULT_AGENT_CONFIG,\n initialSettingsOpen = false,\n children,\n}: {\n agentConfig?: AgentConfig;\n /** Open settings on first paint (e.g. host boot with no models). Does not re-open later. */\n initialSettingsOpen?: boolean;\n children: ReactNode;\n}) {\n const capabilities = useServerCapabilities();\n const refreshCapabilities = useOptionalRefreshServerCapabilities();\n const rememberedSpecRef = useRef<AgentSpec | null>(readDraftSpecPreferences());\n const mutableSeedRef = useRef(rememberedSpecRef.current ?? mutableSeedFromConfig(agentConfig));\n if (\n rememberedSpecRef.current == null &&\n (agentConfig.mode === 'AgentComposer' || agentConfig.mode === 'AgentLibraryWithComposer') &&\n agentConfig.defaultAgentSpec != null\n ) {\n mutableSeedRef.current = agentConfig.defaultAgentSpec;\n }\n const mutableSeed = mutableSeedRef.current;\n\n const isLibraryEnabled = agentConfig.mode === 'AgentLibrary' || agentConfig.mode === 'AgentLibraryWithComposer';\n const isComposerEnabled = agentConfig.mode === 'AgentComposer' || agentConfig.mode === 'AgentLibraryWithComposer';\n const isNewChatEnabled = agentConfig.mode !== 'AgentLibrary';\n const locked = agentConfig.mode === 'SingleAgent';\n\n const [mode, setMode] = useState<ShellMode>(() => initialMode(agentConfig, mutableSeed));\n const [mutableEpoch, setMutableEpoch] = useState(0);\n const [clearEpoch, setClearEpoch] = useState(0);\n const [agentsListEpoch, setAgentsListEpoch] = useState(0);\n const [settingsOpenState, setSettingsOpenState] = useState(initialSettingsOpen);\n const [settingsSection, setSettingsSection] = useState<SettingsSection>('models');\n const [historyAgentFilter, setHistoryAgentFilter] = useState<string | null>(null);\n const [pendingSessionId, setPendingSessionId] = useState<string | undefined>(undefined);\n const settingsEnabled = capabilities?.settings?.enabled !== false;\n const settingsOpen = settingsEnabled && settingsOpenState;\n const setSettingsOpen = useCallback(\n (open: boolean, section?: SettingsSection) => {\n if (section !== undefined) {\n setSettingsSection(section);\n }\n setSettingsOpenState(settingsEnabled && open);\n },\n [settingsEnabled],\n );\n\n useEffect(() => {\n if (!settingsEnabled) {\n setSettingsOpenState(false);\n }\n }, [settingsEnabled]);\n\n const invalidateAgentsList = useCallback(() => {\n setAgentsListEpoch(n => n + 1);\n }, []);\n\n const lockedAgentName = agentConfig.mode === 'SingleAgent' ? agentConfig.name : '';\n const effectiveMode: ShellMode = useMemo(() => {\n if (!locked) return mode;\n return {\n status: 'active',\n isMutable: false,\n agentId: lockedAgentName,\n agentName: lockedAgentName,\n locked: true,\n };\n }, [locked, lockedAgentName, mode]);\n\n const listSessionsAgentId = useMemo(() => {\n if (locked) return lockedAgentName;\n if (!isLibraryEnabled) return undefined;\n return historyAgentFilter ?? undefined;\n }, [locked, lockedAgentName, isLibraryEnabled, historyAgentFilter]);\n\n const bumpEpoch = useCallback((isMutable: boolean) => {\n if (isMutable) setMutableEpoch(n => n + 1);\n else setClearEpoch(n => n + 1);\n }, []);\n\n const selectLibraryAgent = useCallback(\n (req: SelectLibraryAgentRequest) => {\n if (req.isMutable) {\n if (!isComposerEnabled) return;\n setSettingsOpen(false);\n setPendingSessionId(undefined);\n setMode({\n status: 'active',\n isMutable: true,\n agentId: req.agentId,\n agentName: req.agentName,\n agentSpec: req.agentSpec ?? mutableSeedRef.current,\n locked: false,\n });\n bumpEpoch(true);\n return;\n }\n if (!isLibraryEnabled) return;\n const agentName = req.agentName ?? req.agentId;\n if (agentName == null) return;\n setSettingsOpen(false);\n setPendingSessionId(undefined);\n setMode({\n status: 'active',\n isMutable: false,\n agentId: req.agentId ?? agentName,\n agentName,\n locked: false,\n });\n bumpEpoch(false);\n },\n [isComposerEnabled, isLibraryEnabled, bumpEpoch, setSettingsOpen],\n );\n\n const bindMutableAgent = useCallback(\n (req: { agentId: string; agentName: string; agentSpec: AgentSpec }) => {\n if (!isComposerEnabled) return;\n setMode(prev => {\n if (prev.status !== 'active' || !prev.isMutable) return prev;\n return {\n status: 'active',\n isMutable: true,\n agentId: req.agentId,\n agentName: req.agentName,\n agentSpec: req.agentSpec,\n locked: false,\n };\n });\n },\n [isComposerEnabled],\n );\n\n const selectAgent = useCallback(\n (name: string) => {\n selectLibraryAgent({ isMutable: false, agentId: name, agentName: name });\n },\n [selectLibraryAgent],\n );\n\n const openDraft = useCallback(() => {\n if (!isComposerEnabled) return;\n refreshCapabilities?.();\n selectLibraryAgent({ isMutable: true, agentSpec: mutableSeedRef.current });\n }, [isComposerEnabled, refreshCapabilities, selectLibraryAgent]);\n\n const sandboxEnabled = capabilities?.sandbox.enabled;\n const rememberDraftSpec = useCallback(\n (agentSpec: AgentSpec) => {\n const preferences = withCapabilitiesSandbox(selectDraftSpecPreferences(agentSpec), sandboxEnabled);\n rememberedSpecRef.current = preferences;\n mutableSeedRef.current = preferences;\n writeDraftSpecPreferences(preferences);\n },\n [sandboxEnabled],\n );\n\n const openHistorySession = useCallback(\n ({\n sessionId,\n agentName,\n isMutable: isMutableOpt,\n }: {\n sessionId: string;\n agentName?: string;\n isMutable?: boolean;\n }) => {\n setSettingsOpen(false);\n setPendingSessionId(sessionId);\n const isMutable = isMutableOpt ?? agentName == null;\n if (isMutable) {\n if (!isComposerEnabled) return;\n setMode({\n status: 'active',\n isMutable: true,\n agentSpec: mutableSeedRef.current,\n locked: false,\n });\n bumpEpoch(true);\n return;\n }\n // Immutable: allow orphaned refs (deleted agent → no agentName).\n if (locked) {\n if (agentName == null || lockedAgentName !== agentName) return;\n } else if (!isLibraryEnabled) {\n return;\n }\n setMode({\n status: 'active',\n isMutable: false,\n locked: false,\n ...(agentName != null ? { agentId: agentName, agentName } : {}),\n });\n bumpEpoch(false);\n },\n [isLibraryEnabled, isComposerEnabled, locked, lockedAgentName, bumpEpoch, setSettingsOpen],\n );\n\n const clearChat = useCallback(() => {\n if (effectiveMode.status === 'idle') return;\n setPendingSessionId(undefined);\n if (effectiveMode.isMutable) {\n // Preserve Edit binding (name + seeded spec); blank drafts fall back to host seed.\n setMode({\n status: 'active',\n isMutable: true,\n agentId: effectiveMode.agentId,\n agentName: effectiveMode.agentName,\n agentSpec: effectiveMode.agentSpec ?? mutableSeedRef.current,\n locked: false,\n });\n bumpEpoch(true);\n return;\n }\n bumpEpoch(false);\n }, [effectiveMode, bumpEpoch]);\n\n const openLibraryHome = useCallback(() => {\n // Only pure Agents Library has an idle landing; other modes root via openDraft / clearChat.\n if (!isLibraryEnabled || isComposerEnabled) return;\n setPendingSessionId(undefined);\n setSettingsOpen(false);\n setMode({ status: 'idle' });\n bumpEpoch(false);\n }, [isLibraryEnabled, isComposerEnabled, setSettingsOpen, bumpEpoch]);\n\n // Mutable remounts are driven only by mutableEpoch (library Edit / New Chat / Clear).\n // Agent id and model must not be in the key — saveAgent binds those onto the same draft.\n const runtimeKey = useMemo(() => {\n if (effectiveMode.status === 'idle') return 'idle';\n if (effectiveMode.isMutable) {\n return `mut:${pendingSessionId ?? ''}:${mutableEpoch}`;\n }\n const id = effectiveMode.agentId ?? effectiveMode.agentName ?? '';\n return `immut:${id}:${pendingSessionId ?? ''}:${clearEpoch}`;\n }, [effectiveMode, mutableEpoch, clearEpoch, pendingSessionId]);\n\n const value = useMemo<ShellModeContextValue>(\n () => ({\n mode: effectiveMode,\n agentConfigMode: agentConfig.mode,\n isLibraryEnabled,\n isComposerEnabled,\n isNewChatEnabled,\n settingsOpen,\n settingsSection,\n setSettingsOpen,\n selectLibraryAgent,\n bindMutableAgent,\n selectAgent,\n openDraft,\n rememberDraftSpec,\n openHistorySession,\n clearChat,\n openLibraryHome,\n runtimeKey,\n historyAgentFilter,\n setHistoryAgentFilter,\n listSessionsAgentId,\n pendingSessionId,\n agentsListEpoch,\n invalidateAgentsList,\n }),\n [\n effectiveMode,\n agentConfig.mode,\n isLibraryEnabled,\n isComposerEnabled,\n isNewChatEnabled,\n settingsOpen,\n settingsSection,\n setSettingsOpen,\n selectLibraryAgent,\n bindMutableAgent,\n selectAgent,\n openDraft,\n rememberDraftSpec,\n openHistorySession,\n clearChat,\n openLibraryHome,\n runtimeKey,\n historyAgentFilter,\n listSessionsAgentId,\n pendingSessionId,\n agentsListEpoch,\n invalidateAgentsList,\n ],\n );\n\n return <ShellModeContext.Provider value={value}>{children}</ShellModeContext.Provider>;\n}\n\nexport function useShellMode(): ShellModeContextValue {\n const ctx = useContext(ShellModeContext);\n if (ctx == null) {\n throw new Error('useShellMode must be used within a ShellModeProvider.');\n }\n return ctx;\n}\n\nexport function useOptionalShellMode(): ShellModeContextValue | null {\n return useContext(ShellModeContext);\n}\n\n/** True when the shell is bound to a mutable (editable) agentSpec. */\nexport function shellIsMutable(mode: ShellMode): boolean {\n return mode.status === 'active' && mode.isMutable;\n}\n\nexport { libraryAgentId };\n","import type { AgentSpec } from './types.js';\n\nexport const DRAFT_SPEC_PREFERENCES_STORAGE_KEY = 'tfy-aui-draft-spec-preferences';\n\ntype StoredDraftSpecPreferences = {\n version: 1;\n spec: AgentSpec;\n};\n\nfunction isObject(value: unknown): value is object {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isMountList(value: unknown): boolean {\n return Array.isArray(value) && value.every(isObject);\n}\n\nfunction isAgentSpec(value: unknown): value is AgentSpec {\n if (!isObject(value)) return false;\n const model = Reflect.get(value, 'model');\n if (!isObject(model) || typeof Reflect.get(model, 'name') !== 'string') return false;\n\n const params = Reflect.get(model, 'params');\n if (params !== undefined && !isObject(params)) return false;\n\n const skills = Reflect.get(value, 'skills');\n if (skills !== undefined && !isMountList(skills)) return false;\n\n const mcpServers = Reflect.get(value, 'mcpServers');\n if (mcpServers !== undefined && !isMountList(mcpServers)) return false;\n\n const config = Reflect.get(value, 'config');\n return config === undefined || isObject(config);\n}\n\nfunction isStoredDraftSpecPreferences(value: unknown): value is StoredDraftSpecPreferences {\n return isObject(value) && Reflect.get(value, 'version') === 1 && isAgentSpec(Reflect.get(value, 'spec'));\n}\n\n/** Keep only composer choices that should seed future new chats. */\nexport function selectDraftSpecPreferences(spec: AgentSpec): AgentSpec {\n return {\n model: spec.model,\n ...(spec.skills !== undefined ? { skills: spec.skills } : {}),\n ...(spec.mcpServers !== undefined ? { mcpServers: spec.mcpServers } : {}),\n ...(spec.config !== undefined ? { config: spec.config } : {}),\n };\n}\n\nfunction readSandboxEnabled(spec: AgentSpec): boolean | undefined {\n if (spec.config === undefined) return undefined;\n // `sandbox` is persisted on draft config but is not part of AgentRuntimeConfig.\n const sandbox = Reflect.get(spec.config, 'sandbox');\n if (!isObject(sandbox)) return undefined;\n const enabled = Reflect.get(sandbox, 'enabled');\n return typeof enabled === 'boolean' ? enabled : undefined;\n}\n\n/** Align draft `config.sandbox.enabled` with loaded server capabilities; no-op while unknown. */\nexport function withCapabilitiesSandbox(spec: AgentSpec, sandboxEnabled: boolean | null | undefined): AgentSpec {\n if (sandboxEnabled == null) return spec;\n if (readSandboxEnabled(spec) === sandboxEnabled) return spec;\n const config = {\n ...spec.config,\n sandbox: { enabled: sandboxEnabled },\n };\n return {\n ...spec,\n config,\n };\n}\n\nexport function readDraftSpecPreferences(): AgentSpec | null {\n if (typeof window === 'undefined') return null;\n try {\n const stored: unknown = JSON.parse(window.localStorage.getItem(DRAFT_SPEC_PREFERENCES_STORAGE_KEY) ?? 'null');\n return isStoredDraftSpecPreferences(stored) ? stored.spec : null;\n } catch {\n return null;\n }\n}\n\nexport function writeDraftSpecPreferences(spec: AgentSpec): void {\n if (typeof window === 'undefined') return;\n try {\n const stored: StoredDraftSpecPreferences = {\n version: 1,\n spec: selectDraftSpecPreferences(spec),\n };\n window.localStorage.setItem(DRAFT_SPEC_PREFERENCES_STORAGE_KEY, JSON.stringify(stored));\n } catch {\n // Storage can be unavailable or full; in-memory carry-over still works.\n }\n}\n"],"mappings":"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","names":["createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","jsx","createContext","useRef","useState","useCallback","useEffect","useMemo","useContext"]}
|
|
@@ -2,18 +2,20 @@ import {
|
|
|
2
2
|
Tooltip,
|
|
3
3
|
useNamedAgentHeaderState,
|
|
4
4
|
useSlot
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UU7C5DQ3.js";
|
|
6
6
|
import {
|
|
7
7
|
Icon,
|
|
8
|
-
auiButtonClass
|
|
8
|
+
auiButtonClass
|
|
9
|
+
} from "./chunk-IFLE7OMM.js";
|
|
10
|
+
import {
|
|
9
11
|
useOptionalCatalogServer,
|
|
10
12
|
useOptionalShellMode,
|
|
11
13
|
useServerCapabilities
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WQULF5AT.js";
|
|
13
15
|
import {
|
|
14
16
|
cn,
|
|
15
17
|
useTheme
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-72LC2M3R.js";
|
|
17
19
|
|
|
18
20
|
// src/atoms/NamedAgentHeaderLabel.tsx
|
|
19
21
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -70,4 +72,4 @@ export {
|
|
|
70
72
|
NamedAgentHeaderLabel,
|
|
71
73
|
ShellActions
|
|
72
74
|
};
|
|
73
|
-
//# sourceMappingURL=chunk-
|
|
75
|
+
//# sourceMappingURL=chunk-X6U2Q7X5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/NamedAgentHeaderLabel.tsx","../src/atoms/ShellActions.tsx"],"sourcesContent":["'use client';\n\nimport { useNamedAgentHeaderState } from '../hooks/useChatChromeActionsVisible.js';\nimport { Icon } from '../icons/Icon.js';\nimport { cn } from './lib/cn.js';\nimport { Tooltip } from './primitives/Tooltip.js';\n\n/** Left-of-header title for a named agent, including its mutable edit state. */\nexport function NamedAgentHeaderLabel({ className }: { className?: string }) {\n const state = useNamedAgentHeaderState();\n if (state === null) return null;\n\n return (\n <h1 className={cn('flex min-w-0 items-center gap-1.5 px-1 text-sm font-medium text-text-primary', className)}>\n <Icon name=\"robot\" className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\" title={state.name}>\n {state.name}\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 { useSlot } from '../theme/SlotsProvider.js';\nimport { useTheme } from '../theme/ThemeProvider.js';\nimport { auiButtonClass } from './lib/buttonClasses.js';\nimport { cn } from './lib/cn.js';\n\nexport function ShellActions({ className }: { className?: string }) {\n const shell = useOptionalShellMode();\n const catalog = useOptionalCatalogServer();\n const capabilities = useServerCapabilities();\n const { mode, setTheme } = useTheme();\n const ActionSlot = useSlot('ShellActionsActionSlot');\n\n return (\n <div className={cn('flex shrink-0 items-center gap-1 text-text-primary', className)}>\n <button\n type=\"button\"\n aria-label={mode === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'}\n title={mode === 'dark' ? 'Light theme' : 'Dark theme'}\n className={auiButtonClass({ variant: 'ghost', size: 'icon' })}\n onClick={() => setTheme(mode === 'dark' ? 'light' : 'dark')}\n >\n <Icon name={mode === 'dark' ? 'sun' : 'moon'} />\n </button>\n {shell != null && catalog != null && capabilities?.settings?.enabled !== false ? (\n <button\n type=\"button\"\n aria-label=\"Settings\"\n title=\"Settings\"\n aria-expanded={shell.settingsOpen}\n className={auiButtonClass({ variant: 'ghost', size: 'icon' })}\n onClick={() => shell.setSettingsOpen(true)}\n >\n <Icon name=\"settings\" />\n </button>\n ) : null}\n <ActionSlot />\n </div>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/atoms/NamedAgentHeaderLabel.tsx","../src/atoms/ShellActions.tsx"],"sourcesContent":["'use client';\n\nimport { useNamedAgentHeaderState } from '../hooks/useChatChromeActionsVisible.js';\nimport { Icon } from '../icons/Icon.js';\nimport { cn } from './lib/cn.js';\nimport { Tooltip } from './primitives/Tooltip.js';\n\n/** Left-of-header title for a named agent, including its mutable edit state. */\nexport function NamedAgentHeaderLabel({ className }: { className?: string }) {\n const state = useNamedAgentHeaderState();\n if (state === null) return null;\n\n return (\n <h1 className={cn('flex min-w-0 items-center gap-1.5 px-1 text-sm font-medium text-text-primary', className)}>\n <Icon name=\"robot\" className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\" title={state.name}>\n {state.name}\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 { useSlot } from '../theme/SlotsProvider.js';\nimport { useTheme } from '../theme/ThemeProvider.js';\nimport { auiButtonClass } from './lib/buttonClasses.js';\nimport { cn } from './lib/cn.js';\n\nexport function ShellActions({ className }: { className?: string }) {\n const shell = useOptionalShellMode();\n const catalog = useOptionalCatalogServer();\n const capabilities = useServerCapabilities();\n const { mode, setTheme } = useTheme();\n const ActionSlot = useSlot('ShellActionsActionSlot');\n\n return (\n <div className={cn('flex shrink-0 items-center gap-1 text-text-primary', className)}>\n <button\n type=\"button\"\n aria-label={mode === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'}\n title={mode === 'dark' ? 'Light theme' : 'Dark theme'}\n className={auiButtonClass({ variant: 'ghost', size: 'icon' })}\n onClick={() => setTheme(mode === 'dark' ? 'light' : 'dark')}\n >\n <Icon name={mode === 'dark' ? 'sun' : 'moon'} />\n </button>\n {shell != null && catalog != null && capabilities?.settings?.enabled !== false ? (\n <button\n type=\"button\"\n aria-label=\"Settings\"\n title=\"Settings\"\n aria-expanded={shell.settingsOpen}\n className={auiButtonClass({ variant: 'ghost', size: 'icon' })}\n onClick={() => shell.setSettingsOpen(true)}\n >\n <Icon name=\"settings\" />\n </button>\n ) : null}\n <ActionSlot />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAcM,cAMI,YANJ;AANC,SAAS,sBAAsB,EAAE,UAAU,GAA2B;AAC3E,QAAM,QAAQ,yBAAyB;AACvC,MAAI,UAAU,KAAM,QAAO;AAE3B,SACE,qBAAC,QAAG,WAAW,GAAG,gFAAgF,SAAS,GACzG;AAAA,wBAAC,QAAK,MAAK,SAAQ,WAAU,qBAAoB;AAAA,IACjD,oBAAC,UAAK,WAAU,YAAW,OAAO,MAAM,MACrC,gBAAM,MACT;AAAA,IACC,MAAM,YACL,oBAAC,WAAQ,SAAQ,uDAAsD,MAAK,UAC1E,+BAAC,UAAK,WAAU,qJACd;AAAA,0BAAC,QAAK,MAAK,UAAS,WAAU,UAAS;AAAA,MAAE;AAAA,OAE3C,GACF,IACE;AAAA,KACN;AAEJ;;;ACVI,SAQI,OAAAA,MARJ,QAAAC,aAAA;AARG,SAAS,aAAa,EAAE,UAAU,GAA2B;AAClE,QAAM,QAAQ,qBAAqB;AACnC,QAAM,UAAU,yBAAyB;AACzC,QAAM,eAAe,sBAAsB;AAC3C,QAAM,EAAE,MAAM,SAAS,IAAI,SAAS;AACpC,QAAM,aAAa,QAAQ,wBAAwB;AAEnD,SACE,gBAAAA,MAAC,SAAI,WAAW,GAAG,sDAAsD,SAAS,GAChF;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY,SAAS,SAAS,0BAA0B;AAAA,QACxD,OAAO,SAAS,SAAS,gBAAgB;AAAA,QACzC,WAAW,eAAe,EAAE,SAAS,SAAS,MAAM,OAAO,CAAC;AAAA,QAC5D,SAAS,MAAM,SAAS,SAAS,SAAS,UAAU,MAAM;AAAA,QAE1D,0BAAAA,KAAC,QAAK,MAAM,SAAS,SAAS,QAAQ,QAAQ;AAAA;AAAA,IAChD;AAAA,IACC,SAAS,QAAQ,WAAW,QAAQ,cAAc,UAAU,YAAY,QACvE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,OAAM;AAAA,QACN,iBAAe,MAAM;AAAA,QACrB,WAAW,eAAe,EAAE,SAAS,SAAS,MAAM,OAAO,CAAC;AAAA,QAC5D,SAAS,MAAM,MAAM,gBAAgB,IAAI;AAAA,QAEzC,0BAAAA,KAAC,QAAK,MAAK,YAAW;AAAA;AAAA,IACxB,IACE;AAAA,IACJ,gBAAAA,KAAC,cAAW;AAAA,KACd;AAEJ;","names":["jsx","jsxs"]}
|