@solidxai/core-ui 0.1.19 → 0.1.20-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.d.ts.map +1 -1
- package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.js +3 -10
- package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.js.map +1 -1
- package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.tsx +3 -8
- package/dist/components/layout/AdminHeaderActions.d.ts.map +1 -1
- package/dist/components/layout/AdminHeaderActions.js +1 -29
- package/dist/components/layout/AdminHeaderActions.js.map +1 -1
- package/dist/components/layout/AdminHeaderActions.tsx +0 -42
- package/dist/components/layout/SolidAiStudioLayout.d.ts +0 -1
- package/dist/components/layout/SolidAiStudioLayout.d.ts.map +1 -1
- package/dist/components/layout/SolidAiStudioLayout.js +9 -161
- package/dist/components/layout/SolidAiStudioLayout.js.map +1 -1
- package/dist/components/layout/SolidAiStudioLayout.tsx +7 -136
- package/dist/routes/AppEventListener.d.ts.map +1 -1
- package/dist/routes/AppEventListener.js +3 -3
- package/dist/routes/AppEventListener.js.map +1 -1
- package/dist/routes/AppEventListener.tsx +1 -2
- package/dist/routes/pages/admin/core/AgentHubTagsField.css +21 -0
- package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts +17 -0
- package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts.map +1 -0
- package/dist/routes/pages/admin/core/AgentHubTagsField.js +171 -0
- package/dist/routes/pages/admin/core/AgentHubTagsField.js.map +1 -0
- package/dist/routes/pages/admin/core/AgentHubTagsField.tsx +125 -0
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.css +7 -0
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js +65 -52
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.tsx +53 -11
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js +14 -69
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.tsx +15 -83
- package/dist/routes/pages/admin/core/AgentToolActivationDialog.d.ts +11 -0
- package/dist/routes/pages/admin/core/AgentToolActivationDialog.d.ts.map +1 -0
- package/dist/routes/pages/admin/core/AgentToolActivationDialog.js +166 -0
- package/dist/routes/pages/admin/core/AgentToolActivationDialog.js.map +1 -0
- package/dist/routes/pages/admin/core/AgentToolActivationDialog.tsx +140 -0
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.css +26 -0
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js +94 -71
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.tsx +60 -52
- package/package.json +1 -1
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { ArrowLeft,
|
|
2
|
+
import { ArrowLeft, RefreshCw } from "lucide-react";
|
|
3
3
|
import { useDispatch } from "react-redux";
|
|
4
4
|
import { useNavigate, useParams } from "react-router-dom";
|
|
5
5
|
import { createSolidEntityApi } from "../../../../redux/api/solidEntityApi";
|
|
6
6
|
import { showToast } from "../../../../redux/features/toastSlice";
|
|
7
|
+
import { solidPatch } from "../../../../http/solidHttp";
|
|
7
8
|
import { AgentRegistryAuditPanel } from "./AgentRegistryAuditPanel";
|
|
9
|
+
import { AgentHubTagsField, agentHubTagsFrom, agentHubTagsPayload, type AgentHubTag } from "./AgentHubTagsField";
|
|
10
|
+
import { AgentToolActivationDialog } from "./AgentToolActivationDialog";
|
|
8
11
|
import { AgentToolSessionsPanel } from "../../../../components/core/extension/solid-core/agentToolRegistry/AgentToolSessionsPanel";
|
|
9
12
|
import { AgentRegistryCardWidget } from "../../../../components/core/extension/solid-core/agentRegistry/card/AgentRegistryCardWidget";
|
|
10
13
|
import { SolidButton, SolidCodeEditor, SolidDialog, SolidDialogBody, SolidIconPicker, SolidInput, SolidTabGroup } from "../../../../components/shad-cn-ui";
|
|
@@ -19,11 +22,12 @@ type ToolRecord = {
|
|
|
19
22
|
name?: string;
|
|
20
23
|
iconName?: string | null;
|
|
21
24
|
description?: string;
|
|
22
|
-
tags?:
|
|
25
|
+
tags?: AgentHubTag[];
|
|
23
26
|
type?: string;
|
|
24
27
|
status?: string | null;
|
|
25
28
|
lastLoadError?: string | null;
|
|
26
29
|
sourceCode?: string;
|
|
30
|
+
checksum?: string;
|
|
27
31
|
agentTools?: AgentToolLink[] | AgentToolLink | null;
|
|
28
32
|
};
|
|
29
33
|
|
|
@@ -38,17 +42,6 @@ function extractEntityRecord(response: unknown): Record<string, any> | undefined
|
|
|
38
42
|
return candidate && typeof candidate === "object" ? candidate as Record<string, any> : undefined;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
function parseTags(value: unknown): string[] {
|
|
42
|
-
if (Array.isArray(value)) return value.map(String).map((tag) => tag.trim()).filter(Boolean);
|
|
43
|
-
if (typeof value !== "string" || !value.trim()) return [];
|
|
44
|
-
try {
|
|
45
|
-
const parsed = JSON.parse(value);
|
|
46
|
-
return Array.isArray(parsed) ? parsed.map(String).map((tag) => tag.trim()).filter(Boolean) : [];
|
|
47
|
-
} catch {
|
|
48
|
-
return value === "{}" ? [] : value.split(",").map((tag) => tag.trim()).filter(Boolean);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
45
|
async function sha256Hex(value: string): Promise<string> {
|
|
53
46
|
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value));
|
|
54
47
|
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
@@ -86,7 +79,7 @@ export function AgentToolRegistryEditorPage() {
|
|
|
86
79
|
const entityApi = React.useMemo(() => createSolidEntityApi("agentToolRegistry"), []);
|
|
87
80
|
const { useCreateSolidEntityMutation, useGetSolidEntityByIdQuery, useUpdateSolidEntityMutation } = entityApi;
|
|
88
81
|
const { data: response, isLoading, isFetching, refetch } = useGetSolidEntityByIdQuery(
|
|
89
|
-
{ id, qs: "populate[0]=agentTools&populate[1]=agentTools.agentRegistry" },
|
|
82
|
+
{ id, qs: "populate[0]=agentTools&populate[1]=agentTools.agentRegistry&populate[2]=tags" },
|
|
90
83
|
{ skip: !id || id === "new" },
|
|
91
84
|
);
|
|
92
85
|
const [createTool, { isLoading: isCreating }] = useCreateSolidEntityMutation();
|
|
@@ -98,44 +91,38 @@ export function AgentToolRegistryEditorPage() {
|
|
|
98
91
|
const [description, setDescription] = React.useState("");
|
|
99
92
|
const [type, setType] = React.useState("custom");
|
|
100
93
|
const [sourceCode, setSourceCode] = React.useState("");
|
|
101
|
-
const [tags, setTags] = React.useState<
|
|
102
|
-
const [
|
|
94
|
+
const [tags, setTags] = React.useState<AgentHubTag[]>([]);
|
|
95
|
+
const [creatingTag, setCreatingTag] = React.useState(false);
|
|
103
96
|
const [fieldErrors, setFieldErrors] = React.useState<Record<string, string>>({});
|
|
104
97
|
const [auditRefreshVersion, setAuditRefreshVersion] = React.useState(0);
|
|
105
98
|
const [confirmRefresh, setConfirmRefresh] = React.useState(false);
|
|
99
|
+
const [activationOpen, setActivationOpen] = React.useState(false);
|
|
100
|
+
const [activationTool, setActivationTool] = React.useState<{ id: number; checksum: string; name: string } | null>(null);
|
|
101
|
+
const preparingActivation = React.useRef(false);
|
|
106
102
|
const baseline = React.useRef("");
|
|
107
103
|
|
|
108
|
-
const currentForm = () => JSON.stringify({ name, iconName, description, type, sourceCode, tags
|
|
104
|
+
const currentForm = () => JSON.stringify({ name, iconName, description, type, sourceCode, tags });
|
|
109
105
|
|
|
110
106
|
React.useEffect(() => {
|
|
111
|
-
const nextTags =
|
|
107
|
+
const nextTags = agentHubTagsFrom(record?.tags);
|
|
112
108
|
setName(record?.name ?? "");
|
|
113
109
|
setIconName(record?.iconName ?? "");
|
|
114
110
|
setDescription(record?.description ?? "");
|
|
115
111
|
setType(record?.type ?? "custom");
|
|
116
112
|
setSourceCode(record?.sourceCode ?? "");
|
|
117
113
|
setTags(nextTags);
|
|
118
|
-
|
|
119
|
-
baseline.current = JSON.stringify({ name: record?.name ?? "", iconName: record?.iconName ?? "", description: record?.description ?? "", type: record?.type ?? "custom", sourceCode: record?.sourceCode ?? "", tags: nextTags, tagDraft: "" });
|
|
114
|
+
baseline.current = JSON.stringify({ name: record?.name ?? "", iconName: record?.iconName ?? "", description: record?.description ?? "", type: record?.type ?? "custom", sourceCode: record?.sourceCode ?? "", tags: nextTags });
|
|
120
115
|
}, [record]);
|
|
121
116
|
|
|
122
117
|
const isReadOnly = record?.type === "solidx";
|
|
123
118
|
const isDirty = Boolean(record?.id) && currentForm() !== baseline.current;
|
|
124
119
|
const requestRefresh = () => isDirty ? setConfirmRefresh(true) : void refetch();
|
|
125
120
|
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
if (!next) return;
|
|
129
|
-
if (!tags.some((tag) => tag.toLowerCase() === next.toLowerCase())) setTags((current) => [...current, next]);
|
|
130
|
-
setTagDraft("");
|
|
131
|
-
setFieldErrors((current) => ({ ...current, tags: "" }));
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const save = async (nextStatus?: "active" | "inactive") => {
|
|
121
|
+
const save = async (nextStatus?: "inactive") => {
|
|
122
|
+
if (creatingTag) return;
|
|
135
123
|
const nextErrors: Record<string, string> = {};
|
|
136
124
|
if (!name.trim()) nextErrors.name = "Name is required.";
|
|
137
125
|
if (!description.trim()) nextErrors.description = "Description is required.";
|
|
138
|
-
if (tags.length === 0) nextErrors.tags = "At least one tag is required.";
|
|
139
126
|
if (!type.trim()) nextErrors.type = "Tool type is required.";
|
|
140
127
|
if (!sourceCode.trim()) nextErrors.sourceCode = "Tool source code is required.";
|
|
141
128
|
|
|
@@ -147,19 +134,18 @@ export function AgentToolRegistryEditorPage() {
|
|
|
147
134
|
}
|
|
148
135
|
const payload = {
|
|
149
136
|
name: name.trim(), iconName: iconName || null, description: description.trim(), type,
|
|
150
|
-
sourceCode,
|
|
151
|
-
...(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
status: nextStatus ?? (record?.status === "load_failed" ? "active" : record?.status ?? "active"),
|
|
155
|
-
...((nextStatus === "active" || (!nextStatus && record?.status === "load_failed")) ? { lastLoadError: null } : {}),
|
|
137
|
+
sourceCode, ...agentHubTagsPayload(tags),
|
|
138
|
+
...(["custom", "thirdparty"].includes(type) ? { checksum: await sha256Hex(sourceCode) } : {}),
|
|
139
|
+
status: nextStatus ?? (record && (sourceCode !== record.sourceCode || name.trim() !== record.name || type !== record.type)
|
|
140
|
+
? "inactive" : record?.status ?? "inactive"),
|
|
156
141
|
};
|
|
157
142
|
try {
|
|
158
143
|
if (record?.id) {
|
|
159
|
-
await updateTool({ id: record.id, data: payload }).unwrap();
|
|
144
|
+
const result = await updateTool({ id: record.id, data: payload }).unwrap();
|
|
160
145
|
dispatch(showToast({ severity: "success", summary: nextStatus ? "Tool status updated" : "Saved", detail: nextStatus ? `Tool moved to ${nextStatus}. Restart linked agent processes to apply the change.` : "Tool updated successfully." }));
|
|
161
146
|
setAuditRefreshVersion((version) => version + 1);
|
|
162
147
|
refetch();
|
|
148
|
+
return (extractEntityRecord(result) ?? { ...record, ...payload }) as ToolRecord;
|
|
163
149
|
} else {
|
|
164
150
|
const result: any = await createTool(payload).unwrap();
|
|
165
151
|
const createdId = result?.data?.id ?? result?.id;
|
|
@@ -170,7 +156,7 @@ export function AgentToolRegistryEditorPage() {
|
|
|
170
156
|
const errorDetail = getSaveErrorMessage(error);
|
|
171
157
|
const serverFieldErrors: Record<string, string> = {};
|
|
172
158
|
if (/required|not be empty|cannot be empty|should not be empty/i.test(errorDetail)) {
|
|
173
|
-
for (const field of ["name", "description", "
|
|
159
|
+
for (const field of ["name", "description", "type", "sourceCode"]) {
|
|
174
160
|
if (!new RegExp(`\\b${field}\\b`, "i").test(errorDetail)) continue;
|
|
175
161
|
const label = field === "sourceCode" ? "Tool source code" : field[0].toUpperCase() + field.slice(1);
|
|
176
162
|
serverFieldErrors[field] = `${label} is required.`;
|
|
@@ -184,6 +170,23 @@ export function AgentToolRegistryEditorPage() {
|
|
|
184
170
|
}
|
|
185
171
|
};
|
|
186
172
|
|
|
173
|
+
const beginActivation = async () => {
|
|
174
|
+
if (isReadOnly) return;
|
|
175
|
+
if (!record || activationOpen || isSaving || preparingActivation.current) return;
|
|
176
|
+
preparingActivation.current = true;
|
|
177
|
+
try {
|
|
178
|
+
const saved = isDirty || record.status === "load_failed" ? await save("inactive") : record;
|
|
179
|
+
if (!saved?.id) return;
|
|
180
|
+
const checksum = await sha256Hex(saved.sourceCode ?? sourceCode);
|
|
181
|
+
setActivationTool({ id: saved.id, checksum, name: saved.name ?? name });
|
|
182
|
+
setActivationOpen(true);
|
|
183
|
+
} catch {
|
|
184
|
+
dispatch(showToast({ severity: "error", summary: "Activation failed", detail: "Could not prepare the saved tool source for checks." }));
|
|
185
|
+
} finally {
|
|
186
|
+
preparingActivation.current = false;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
187
190
|
const agents = React.useMemo(() => {
|
|
188
191
|
const relatedTools = record?.agentTools;
|
|
189
192
|
const links = Array.isArray(relatedTools) ? relatedTools : relatedTools ? [relatedTools] : [];
|
|
@@ -212,36 +215,33 @@ export function AgentToolRegistryEditorPage() {
|
|
|
212
215
|
<div className="agent-tool-editor__field"><span>Icon</span><SolidIconPicker value={iconName} onChange={setIconName} /></div>
|
|
213
216
|
<label className="agent-tool-editor__field"><span>Description <b>*</b></span><SolidInput value={description} aria-invalid={Boolean(fieldErrors.description)} aria-describedby={fieldErrors.description ? "agent-tool-description-error" : undefined} className={fieldErrors.description ? "agent-tool-editor__input--invalid" : undefined} onChange={(e) => { setDescription(e.target.value); setFieldErrors((current) => ({ ...current, description: "" })); }} />{fieldErrors.description && <small id="agent-tool-description-error" className="agent-tool-editor__field-error">{fieldErrors.description}</small>}</label>
|
|
214
217
|
</div>
|
|
218
|
+
{!record?.id && <label className="agent-tool-editor__field"><span>Tool status</span><select value="inactive" disabled aria-label="Tool status"><option value="inactive">Inactive</option></select><small>New tools start inactive. Run configuration and initialization checks to activate.</small></label>}
|
|
215
219
|
<label className="agent-tool-editor__field"><span>Tool type <b>*</b></span><select value={type} aria-invalid={Boolean(fieldErrors.type)} aria-describedby={fieldErrors.type ? "agent-tool-type-error" : undefined} className={fieldErrors.type ? "agent-tool-editor__input--invalid" : undefined} onChange={(e) => { setType(e.target.value); setFieldErrors((current) => ({ ...current, type: "" })); }}>
|
|
216
220
|
{isReadOnly && <option value="solidx">SolidX</option>}<option value="thirdparty">Third Party</option><option value="custom">Custom</option>
|
|
217
221
|
</select>{fieldErrors.type && <small id="agent-tool-type-error" className="agent-tool-editor__field-error">{fieldErrors.type}</small>}</label>
|
|
218
|
-
<
|
|
219
|
-
{tags.map((tag, index) => <span className="agent-tool-editor__tag" key={`${tag}-${index}`}>{tag}<button type="button" aria-label={`Remove ${tag}`} onClick={() => setTags((current) => { const next = current.filter((_, i) => i !== index); if (next.length) setFieldErrors((errors) => ({ ...errors, tags: "" })); return next; })}><X size={13} /></button></span>)}
|
|
220
|
-
<input value={tagDraft} aria-label="Add a tag" placeholder="Type a tag and press Enter" onChange={(e) => setTagDraft(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); addTag(); } }} />
|
|
221
|
-
<SolidButton type="button" variant="secondary" size="small" onClick={addTag}><Plus size={14} /> Add</SolidButton>
|
|
222
|
-
</div>{fieldErrors.tags && <small className="agent-tool-editor__field-error">{fieldErrors.tags}</small>}<small>Tags are saved as a JSON array.</small></div>
|
|
222
|
+
<AgentHubTagsField value={tags} onChange={setTags} disabled={isReadOnly || isCreating || isSaving} onBusyChange={setCreatingTag} />
|
|
223
223
|
{record?.id && <section className="agent-tool-editor__workflow" aria-labelledby="agent-tool-lifecycle-title">
|
|
224
|
-
<div className="agent-tool-editor__workflow-head"><div><h2 id="agent-tool-lifecycle-title">Tool lifecycle</h2><p>
|
|
225
|
-
<div className="agent-tool-editor__workflow-stages" aria-label={`Current tool stage: ${(record.status ?? "
|
|
224
|
+
<div className="agent-tool-editor__workflow-head"><div><h2 id="agent-tool-lifecycle-title">Tool lifecycle</h2><p>Configuration and initialization must pass before this tool can be activated.</p></div></div>
|
|
225
|
+
<div className="agent-tool-editor__workflow-stages" aria-label={`Current tool stage: ${(record.status ?? "inactive").replace(/[_-]+/g, " ")}`}>
|
|
226
226
|
{([ ["active", "Active", "Enabled for loading into linked agents."], ["inactive", "Inactive", "Not loaded for linked agents."], ["load_failed", "Load failed", "AgentHub could not load this tool."] ] as const).map(([value, label, description], index) => {
|
|
227
|
-
const currentStatus = record.status ?? "
|
|
227
|
+
const currentStatus = record.status ?? "inactive";
|
|
228
228
|
const isCurrent = currentStatus === value;
|
|
229
229
|
const canRetry = value === "load_failed" && isCurrent;
|
|
230
|
-
const disabled = isCreating || isSaving || (!canRetry && (value === "load_failed" || isCurrent));
|
|
230
|
+
const disabled = isReadOnly || activationOpen || isCreating || isSaving || (!canRetry && (value === "load_failed" || isCurrent));
|
|
231
231
|
return <React.Fragment key={value}>
|
|
232
232
|
{index > 0 && <div className="agent-tool-editor__workflow-connector" aria-hidden="true" />}
|
|
233
233
|
<button type="button" className={`agent-tool-editor__workflow-stage agent-tool-editor__workflow-stage--${value}${isCurrent ? " is-current" : ""}`}
|
|
234
234
|
aria-current={isCurrent ? "step" : undefined} aria-pressed={isCurrent} disabled={disabled}
|
|
235
|
-
onClick={() =>
|
|
235
|
+
onClick={() => value === "inactive" ? void save("inactive") : void beginActivation()}>
|
|
236
236
|
<span className="agent-tool-editor__workflow-mark">{index + 1}</span>
|
|
237
|
-
<span className="agent-tool-editor__workflow-copy"><strong>{label}</strong><small>{description}</small><small className="agent-tool-editor__workflow-cta">{canRetry ? "
|
|
237
|
+
<span className="agent-tool-editor__workflow-copy"><strong>{label}</strong><small>{description}</small><small className="agent-tool-editor__workflow-cta">{canRetry ? "Run checks and retry activation" : isCurrent ? "Current stage" : value === "load_failed" ? "Set automatically by AgentHub" : value === "active" ? "Run checks to activate" : "Click to deactivate"}</small></span>
|
|
238
238
|
{isCurrent && <span className="agent-tool-editor__workflow-current">Current</span>}
|
|
239
239
|
</button>
|
|
240
240
|
</React.Fragment>;
|
|
241
241
|
})}
|
|
242
242
|
</div>
|
|
243
|
-
{record.status === "load_failed" && <small className="agent-tool-editor__workflow-hint">Fix the source or checksum
|
|
244
|
-
<small className="agent-tool-editor__workflow-hint">
|
|
243
|
+
{record.status === "load_failed" && <small className="agent-tool-editor__workflow-hint">Fix the source or checksum, then run configuration and initialization checks before retrying activation.</small>}
|
|
244
|
+
<small className="agent-tool-editor__workflow-hint">Activation checks use the saved tool configuration. Restart linked agent processes to apply status changes.</small>
|
|
245
245
|
</section>}
|
|
246
246
|
</fieldset> },
|
|
247
247
|
{ value: "tool", label: "Tool", content: <div className="agent-tool-editor__tool">
|
|
@@ -260,12 +260,20 @@ export function AgentToolRegistryEditorPage() {
|
|
|
260
260
|
return <main className="agent-tool-editor">
|
|
261
261
|
<header className="agent-tool-editor__header"><div><div className="agent-tool-editor__heading-with-refresh"><h1>{record ? "Edit Tool" : "Create Tool"}</h1>{record?.id && <button type="button" className={`agent-tool-editor__refresh${isFetching ? " is-loading" : ""}`} aria-label="Refresh tool" title="Refresh tool" disabled={isFetching || isSaving} onClick={requestRefresh}><RefreshCw size={14} /></button>}</div></div><div className="agent-tool-editor__actions">
|
|
262
262
|
<SolidButton variant="secondary" leftIcon={<ArrowLeft size={16} />} onClick={() => navigate(-1)}>Back</SolidButton>
|
|
263
|
-
{!isReadOnly && <SolidButton loading={isCreating || isSaving} onClick={() => void save()}>Save Tool</SolidButton>}
|
|
263
|
+
{!isReadOnly && <SolidButton disabled={activationOpen || creatingTag} loading={isCreating || isSaving} onClick={() => void save()}>Save Tool</SolidButton>}
|
|
264
264
|
</div></header>
|
|
265
265
|
<SolidDialog open={confirmRefresh} onOpenChange={setConfirmRefresh} header="Discard unsaved changes?" style={{ width: "min(28rem, 94vw)" }}
|
|
266
266
|
footer={<><SolidButton type="button" variant="secondary" onClick={() => setConfirmRefresh(false)}>Cancel</SolidButton><SolidButton type="button" disabled={isFetching} onClick={() => { setConfirmRefresh(false); void refetch(); }}>Refresh and discard</SolidButton></>}>
|
|
267
267
|
<SolidDialogBody><p>You have unsaved changes. Refreshing will discard them and load the latest tool content.</p></SolidDialogBody>
|
|
268
268
|
</SolidDialog>
|
|
269
|
+
{activationOpen && activationTool && <AgentToolActivationDialog open={activationOpen} onOpenChange={setActivationOpen}
|
|
270
|
+
toolId={activationTool.id} checksum={activationTool.checksum} toolName={activationTool.name}
|
|
271
|
+
onActivated={async () => {
|
|
272
|
+
await solidPatch(`/agent-tool-registry/${activationTool.id}`, { status: "active", checksum: activationTool.checksum });
|
|
273
|
+
setAuditRefreshVersion((version) => version + 1);
|
|
274
|
+
void refetch();
|
|
275
|
+
dispatch(showToast({ severity: "success", summary: "Tool activated", detail: "Configuration and initialization checks passed." }));
|
|
276
|
+
}} />}
|
|
269
277
|
{isLoading ? <div className="agent-tool-editor__loading">Loading tool…</div> : record?.id ? (
|
|
270
278
|
<AgentRegistryAuditPanel modelSingularName="agentToolRegistry" recordId={record.id} refreshVersion={auditRefreshVersion} modelUserKey={record.name}>
|
|
271
279
|
<SolidTabGroup tabs={tabs} value={activeTab} onValueChange={setActiveTab} className="agent-tool-editor__tabs" listClassName="agent-tool-editor__tab-list" panelClassName="agent-tool-editor__tab-panel" />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidxai/core-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20-beta.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build:tailwind": "tailwindcss -i ./src/resources/solid-tailwind.css -o ./src/resources/solid-tailwind-generated.css -c ./tailwind.config.js --minify",
|
|
6
6
|
"prebuild": "npm run build:tailwind && npm run copy-resources && npm run copy-styles",
|