@solidxai/core-ui 0.1.19-beta.1 → 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.
Files changed (43) hide show
  1. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.d.ts.map +1 -1
  2. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.js +3 -10
  3. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.js.map +1 -1
  4. package/dist/components/core/extension/solid-core/agentRegistry/card/AgentResourceCardWidget.tsx +3 -8
  5. package/dist/components/layout/AdminHeaderActions.d.ts.map +1 -1
  6. package/dist/components/layout/AdminHeaderActions.js +1 -29
  7. package/dist/components/layout/AdminHeaderActions.js.map +1 -1
  8. package/dist/components/layout/AdminHeaderActions.tsx +0 -42
  9. package/dist/components/layout/SolidAiStudioLayout.d.ts +0 -1
  10. package/dist/components/layout/SolidAiStudioLayout.d.ts.map +1 -1
  11. package/dist/components/layout/SolidAiStudioLayout.js +9 -161
  12. package/dist/components/layout/SolidAiStudioLayout.js.map +1 -1
  13. package/dist/components/layout/SolidAiStudioLayout.tsx +7 -136
  14. package/dist/routes/AppEventListener.d.ts.map +1 -1
  15. package/dist/routes/AppEventListener.js +3 -3
  16. package/dist/routes/AppEventListener.js.map +1 -1
  17. package/dist/routes/AppEventListener.tsx +1 -2
  18. package/dist/routes/pages/admin/core/AgentHubTagsField.css +21 -0
  19. package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts +17 -0
  20. package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts.map +1 -0
  21. package/dist/routes/pages/admin/core/AgentHubTagsField.js +171 -0
  22. package/dist/routes/pages/admin/core/AgentHubTagsField.js.map +1 -0
  23. package/dist/routes/pages/admin/core/AgentHubTagsField.tsx +125 -0
  24. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.css +7 -0
  25. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.d.ts.map +1 -1
  26. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js +65 -52
  27. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js.map +1 -1
  28. package/dist/routes/pages/admin/core/AgentRegistryEditorPage.tsx +53 -11
  29. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.d.ts.map +1 -1
  30. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js +14 -69
  31. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js.map +1 -1
  32. package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.tsx +15 -83
  33. package/dist/routes/pages/admin/core/AgentToolActivationDialog.d.ts +11 -0
  34. package/dist/routes/pages/admin/core/AgentToolActivationDialog.d.ts.map +1 -0
  35. package/dist/routes/pages/admin/core/AgentToolActivationDialog.js +166 -0
  36. package/dist/routes/pages/admin/core/AgentToolActivationDialog.js.map +1 -0
  37. package/dist/routes/pages/admin/core/AgentToolActivationDialog.tsx +140 -0
  38. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.css +26 -0
  39. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.d.ts.map +1 -1
  40. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js +94 -71
  41. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js.map +1 -1
  42. package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.tsx +60 -52
  43. package/package.json +1 -1
@@ -1,10 +1,13 @@
1
1
  import React from "react";
2
- import { ArrowLeft, Plus, RefreshCw, X } from "lucide-react";
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?: unknown;
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<string[]>([]);
102
- const [tagDraft, setTagDraft] = React.useState("");
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, tagDraft });
104
+ const currentForm = () => JSON.stringify({ name, iconName, description, type, sourceCode, tags });
109
105
 
110
106
  React.useEffect(() => {
111
- const nextTags = parseTags(record?.tags);
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
- setTagDraft("");
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 addTag = () => {
127
- const next = tagDraft.trim();
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, tags: JSON.stringify(tags),
151
- ...(type === "custom" ? { checksum: await sha256Hex(sourceCode) } : {}),
152
- // Status is required by the agentToolRegistry metadata, including partial
153
- // updates. Preserve the current lifecycle state for ordinary saves.
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", "tags", "type", "sourceCode"]) {
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
- <div className="agent-tool-editor__field"><span>Tags <b>*</b></span><div className={`agent-tool-editor__tag-input${fieldErrors.tags ? " agent-tool-editor__tag-input--invalid" : ""}`}>
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>Activate or deactivate this tool for linked agents. Load failures are reported by AgentHub.</p></div></div>
225
- <div className="agent-tool-editor__workflow-stages" aria-label={`Current tool stage: ${(record.status ?? "active").replace(/[_-]+/g, " ")}`}>
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 ?? "active";
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={() => void save(value === "load_failed" ? "active" : value)}>
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 ? "Click to retry loading" : isCurrent ? "Current stage" : value === "load_failed" ? "Set automatically by AgentHub" : "Click to move to this stage"}</small></span>
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 first. Retrying saves the current tool configuration and clears the reported error; restart linked agent processes to load the updated tool.</small>}
244
- <small className="agent-tool-editor__workflow-hint">Changing stage saves the current tool configuration. Restart linked agent processes to apply the change.</small>
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.19-beta.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",