@infuro/cms-core 1.0.20 → 1.0.21

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/admin.cjs CHANGED
@@ -401,7 +401,7 @@ var defaultValue = {
401
401
  var AdminConfigContext = (0, import_react4.createContext)(defaultValue);
402
402
 
403
403
  // src/lib/cms-version.ts
404
- var CMS_VERSION = true ? "1.0.20" : "0.0.0";
404
+ var CMS_VERSION = true ? "1.0.21" : "0.0.0";
405
405
 
406
406
  // src/components/Admin/Sidebar.tsx
407
407
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -546,10 +546,6 @@ function AdminSidebar({ variant = "sidebar" }) {
546
546
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.Shield, { className: `h-4 w-4 mr-2 ${isActive("/admin/roles") ? iconActive : iconInactive}` }),
547
547
  "Roles"
548
548
  ] }) }),
549
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_link2.default, { href: "/admin/llm_agents", className: `${linkCls} ${isActive("/admin/llm_agents") ? linkActive : linkInactive}`, children: [
550
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.Bot, { className: `h-4 w-4 mr-2 ${isActive("/admin/llm_agents") ? iconActive : iconInactive}` }),
551
- "LLM agents"
552
- ] }) }),
553
549
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_link2.default, { href: "/admin/plugins", className: `${linkCls} ${isActive("/admin/plugins") ? linkActive : linkInactive}`, children: [
554
550
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.Puzzle, { className: `h-4 w-4 mr-2 ${isActive("/admin/plugins") ? iconActive : iconInactive}` }),
555
551
  "Plugins"
@@ -6527,7 +6523,7 @@ function DashboardPage() {
6527
6523
 
6528
6524
  // src/admin/pages/AdminPageResolver.tsx
6529
6525
  var import_react48 = require("react");
6530
- var import_navigation21 = require("next/navigation");
6526
+ var import_navigation22 = require("next/navigation");
6531
6527
 
6532
6528
  // src/admin/pages/SubmissionDetailPage.tsx
6533
6529
  var import_react33 = require("react");
@@ -9256,6 +9252,7 @@ function PageBuilderPage({ pageId }) {
9256
9252
 
9257
9253
  // src/admin/pages/PluginsPage.tsx
9258
9254
  var import_react41 = require("react");
9255
+ var import_navigation18 = require("next/navigation");
9259
9256
  var import_lucide_react32 = require("lucide-react");
9260
9257
 
9261
9258
  // src/lib/email-recipients.ts
@@ -9480,6 +9477,7 @@ function PluginSettingsPanel({
9480
9477
  const [agentValidationJson, setAgentValidationJson] = (0, import_react41.useState)("");
9481
9478
  const [agentLoading, setAgentLoading] = (0, import_react41.useState)(false);
9482
9479
  const [agentSaving, setAgentSaving] = (0, import_react41.useState)(false);
9480
+ const [agentProvisionError, setAgentProvisionError] = (0, import_react41.useState)(null);
9483
9481
  const [kbCatalog, setKbCatalog] = (0, import_react41.useState)([]);
9484
9482
  const [attachedAgentKnowledge, setAttachedAgentKnowledge] = (0, import_react41.useState)([]);
9485
9483
  const [attachedKbLoading, setAttachedKbLoading] = (0, import_react41.useState)(false);
@@ -9636,31 +9634,112 @@ function PluginSettingsPanel({
9636
9634
  setAttachedKbLoading(false);
9637
9635
  }
9638
9636
  }, []);
9637
+ const bootstrapLlmAgentForPlugins = (0, import_react41.useCallback)(async () => {
9638
+ setAgentProvisionError(null);
9639
+ const listRes = await fetch("/api/llm_agents?limit=100&sortField=name&sortOrder=asc");
9640
+ if (!listRes.ok) {
9641
+ const errBody = await listRes.json().catch(() => ({}));
9642
+ const message = errBody.error ?? `Could not load agents (HTTP ${listRes.status}). Ensure your app uses the latest @infuro/cms-core and your admin user can read entity "llm_agents".`;
9643
+ setAgentProvisionError(message);
9644
+ await fetchLlmAgents();
9645
+ return { ok: false, message };
9646
+ }
9647
+ const listJ = await listRes.json();
9648
+ if (listJ.data?.length) {
9649
+ await fetchLlmAgents();
9650
+ return { ok: true };
9651
+ }
9652
+ const defaultName = botName.trim() || "Assistant";
9653
+ const defaultSlug = slugifyAgentKey(defaultName);
9654
+ const createRes = await fetch("/api/llm_agents", {
9655
+ method: "POST",
9656
+ headers: { "Content-Type": "application/json" },
9657
+ body: JSON.stringify({ name: defaultName, slug: defaultSlug, systemInstruction: "", enabled: true })
9658
+ });
9659
+ if (!createRes.ok) {
9660
+ const errBody = await createRes.json().catch(() => ({}));
9661
+ const message = errBody.error ?? `Could not create default agent (HTTP ${createRes.status}). Check create permission for "llm_agents".`;
9662
+ setAgentProvisionError(message);
9663
+ await fetchLlmAgents();
9664
+ return { ok: false, message };
9665
+ }
9666
+ await fetchLlmAgents();
9667
+ return { ok: true };
9668
+ }, [botName, fetchLlmAgents]);
9669
+ const handleRetryBootstrapAgent = async () => {
9670
+ setAgentLoading(true);
9671
+ try {
9672
+ const r = await bootstrapLlmAgentForPlugins();
9673
+ if (r.ok) {
9674
+ import_sonner7.toast.success("Assistant agent ready \u2014 you can upload knowledge files below.");
9675
+ } else {
9676
+ import_sonner7.toast.error(r.message);
9677
+ }
9678
+ } finally {
9679
+ setAgentLoading(false);
9680
+ }
9681
+ };
9682
+ const handleCreateAssistantFromForm = async () => {
9683
+ const name = agentName.trim() || botName.trim();
9684
+ if (!name) {
9685
+ import_sonner7.toast.error("Enter an assistant name");
9686
+ return;
9687
+ }
9688
+ const tempRaw = agentTemp.trim();
9689
+ const maxRaw = agentMaxTokens.trim();
9690
+ const temperature = tempRaw === "" ? null : Number(tempRaw);
9691
+ const maxTokens = maxRaw === "" ? null : parseInt(maxRaw, 10);
9692
+ if (tempRaw !== "" && !Number.isFinite(temperature)) {
9693
+ import_sonner7.toast.error("Temperature must be a number");
9694
+ return;
9695
+ }
9696
+ if (maxRaw !== "" && (!Number.isFinite(maxTokens) || maxTokens < 1)) {
9697
+ import_sonner7.toast.error("Max tokens must be a positive integer");
9698
+ return;
9699
+ }
9700
+ const slug = slugifyAgentKey(name);
9701
+ setAgentSaving(true);
9702
+ try {
9703
+ const res = await fetch("/api/llm_agents", {
9704
+ method: "POST",
9705
+ headers: { "Content-Type": "application/json" },
9706
+ body: JSON.stringify({
9707
+ name,
9708
+ slug,
9709
+ systemInstruction: agentSystem.trim(),
9710
+ model: agentModel.trim() || null,
9711
+ temperature,
9712
+ maxTokens,
9713
+ validationRules: agentValidationJson.trim() || null,
9714
+ enabled: true
9715
+ })
9716
+ });
9717
+ if (!res.ok) {
9718
+ const err = await res.json().catch(() => ({}));
9719
+ import_sonner7.toast.error(err.error || "Failed to create assistant");
9720
+ return;
9721
+ }
9722
+ setAgentProvisionError(null);
9723
+ setAttachedAgentSlug(slug);
9724
+ await fetchLlmAgents();
9725
+ import_sonner7.toast.success("Assistant created \u2014 add knowledge files below.");
9726
+ } catch {
9727
+ import_sonner7.toast.error("Failed to create assistant");
9728
+ } finally {
9729
+ setAgentSaving(false);
9730
+ }
9731
+ };
9639
9732
  (0, import_react41.useEffect)(() => {
9640
9733
  if (!isLlm || loading || chatMode !== "llm") return;
9641
9734
  setAgentLoading(true);
9642
9735
  void (async () => {
9643
9736
  try {
9644
- await fetchLlmAgents();
9645
- const listRes = await fetch("/api/llm_agents?limit=1");
9646
- const listJ = listRes.ok ? await listRes.json() : { data: [] };
9647
- if (!listJ.data?.length) {
9648
- const defaultName = botName.trim() || "Assistant";
9649
- const defaultSlug = slugifyAgentKey(defaultName);
9650
- const createRes = await fetch("/api/llm_agents", {
9651
- method: "POST",
9652
- headers: { "Content-Type": "application/json" },
9653
- body: JSON.stringify({ name: defaultName, slug: defaultSlug, systemInstruction: "", enabled: true })
9654
- });
9655
- if (createRes.ok) {
9656
- await fetchLlmAgents();
9657
- }
9658
- }
9737
+ await bootstrapLlmAgentForPlugins();
9659
9738
  } finally {
9660
9739
  setAgentLoading(false);
9661
9740
  }
9662
9741
  })();
9663
- }, [isLlm, loading, chatMode]);
9742
+ }, [isLlm, loading, chatMode, bootstrapLlmAgentForPlugins]);
9664
9743
  (0, import_react41.useEffect)(() => {
9665
9744
  if (!isLlm || loading || chatMode !== "llm") return;
9666
9745
  void fetchKbCatalog();
@@ -9675,6 +9754,12 @@ function PluginSettingsPanel({
9675
9754
  (0, import_react41.useEffect)(() => {
9676
9755
  setAttachExistingDocId("__none__");
9677
9756
  }, [attachedAgentSlug]);
9757
+ (0, import_react41.useEffect)(() => {
9758
+ if (!isLlm || loading || chatMode !== "llm" || agentLoading || agentId) return;
9759
+ if (!agentName.trim() && botName.trim()) {
9760
+ setAgentName(botName.trim());
9761
+ }
9762
+ }, [isLlm, loading, chatMode, agentLoading, agentId, agentName, botName]);
9678
9763
  const buildPayload = () => {
9679
9764
  if (isErp) {
9680
9765
  const sortedIds = [...new Set(erpOpportunityFormIds.filter((n) => Number.isInteger(n) && n > 0))].sort(
@@ -9826,7 +9911,16 @@ function PluginSettingsPanel({
9826
9911
  import_sonner7.toast.error(err.error || "Upload failed");
9827
9912
  return;
9828
9913
  }
9829
- import_sonner7.toast.success("Knowledge added and linked");
9914
+ const ingest = await r.json().catch(() => ({}));
9915
+ if (ingest.warning) {
9916
+ import_sonner7.toast.warning(ingest.detail ? `${ingest.warning} (${ingest.detail})` : ingest.warning);
9917
+ } else if (ingest.embeddingAttempted && (ingest.embeddingsWritten ?? 0) === 0 && (ingest.chunkCount ?? 0) > 0) {
9918
+ import_sonner7.toast.warning(
9919
+ "Document saved but no embeddings were written. Set LLM_GATEWAY_URL + LLM_API_KEY, and ensure EMBEDDING_PROVIDER / EMBEDDING_MODEL match knowledge_base_chunks.embedding dimensions (see server logs)."
9920
+ );
9921
+ } else {
9922
+ import_sonner7.toast.success("Knowledge added and linked");
9923
+ }
9830
9924
  setAttachedKbInputKey((k) => k + 1);
9831
9925
  await fetchAttachedKnowledge(slug);
9832
9926
  await fetchKbCatalog();
@@ -9862,7 +9956,16 @@ function PluginSettingsPanel({
9862
9956
  import_sonner7.toast.error(err.error || "Attach failed");
9863
9957
  return;
9864
9958
  }
9865
- import_sonner7.toast.success("Document attached");
9959
+ const ingest = await r.json().catch(() => ({}));
9960
+ if (ingest.warning) {
9961
+ import_sonner7.toast.warning(ingest.detail ? `${ingest.warning} (${ingest.detail})` : ingest.warning);
9962
+ } else if (ingest.embeddingAttempted && (ingest.embeddingsWritten ?? 0) === 0 && ((ingest.chunksQueuedForEmbedding ?? 0) > 0 || (ingest.chunkCount ?? 0) > 0)) {
9963
+ import_sonner7.toast.warning(
9964
+ "Document attached but no embeddings were written. Configure the LLM/embed gateway, then attach again to fill NULL embeddings."
9965
+ );
9966
+ } else {
9967
+ import_sonner7.toast.success("Document attached");
9968
+ }
9866
9969
  setAttachExistingDocId("__none__");
9867
9970
  await fetchAttachedKnowledge(slug);
9868
9971
  } finally {
@@ -10322,23 +10425,27 @@ function PluginSettingsPanel({
10322
10425
  ] }),
10323
10426
  chatMode === "llm" && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
10324
10427
  /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "rounded-lg border border-gray-200 dark:border-gray-600 bg-gray-50/80 dark:bg-gray-800/40 p-3 space-y-3", children: [
10325
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2 text-sm font-medium text-gray-900 dark:text-white", children: [
10326
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Bot, { className: "h-4 w-4" }),
10327
- "Chat assistant agent"
10428
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
10429
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2 text-sm font-medium text-gray-900 dark:text-white", children: [
10430
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Bot, { className: "h-4 w-4" }),
10431
+ "Chat assistant (single agent)"
10432
+ ] }),
10433
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-[11px] text-gray-500 dark:text-gray-400", children: "Configure one assistant for this site here. After it exists, attach knowledge files in the section below." })
10328
10434
  ] }),
10329
10435
  agentLoading ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
10330
10436
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Loader2, { className: "h-4 w-4 animate-spin" }),
10331
- "Loading agent\u2026"
10332
- ] }) : !agentId ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "No agent found. Save settings to auto-create one." }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
10437
+ "Loading assistant\u2026"
10438
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
10439
+ agentProvisionError ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "rounded border border-amber-200 bg-amber-50 p-2 text-xs text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100", children: agentProvisionError }) : null,
10333
10440
  /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
10334
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: "agent-name", className: "text-sm", children: "Name" }),
10441
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: "agent-name", className: "text-sm", children: "Assistant name" }),
10335
10442
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10336
10443
  Input,
10337
10444
  {
10338
10445
  id: "agent-name",
10339
10446
  value: agentName,
10340
10447
  onChange: (e) => setAgentName(e.target.value),
10341
- placeholder: "e.g. Sales assistant",
10448
+ placeholder: "e.g. JM Buddy",
10342
10449
  className: "h-8 text-sm"
10343
10450
  }
10344
10451
  )
@@ -10349,12 +10456,12 @@ function PluginSettingsPanel({
10349
10456
  Input,
10350
10457
  {
10351
10458
  id: "agent-slug",
10352
- value: agentSlug,
10459
+ value: agentId ? agentSlug : slugifyAgentKey((agentName || botName).trim() || "assistant"),
10353
10460
  disabled: true,
10354
10461
  className: "h-8 text-sm font-mono bg-gray-100 dark:bg-gray-700"
10355
10462
  }
10356
10463
  ),
10357
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-[11px] text-gray-500", children: "Auto-generated. Used in API routes." })
10464
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-[11px] text-gray-500", children: "Derived from the name. Used in API routes." })
10358
10465
  ] }),
10359
10466
  /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
10360
10467
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: "agent-system", className: "text-sm", children: "System instruction" }),
@@ -10425,7 +10532,37 @@ function PluginSettingsPanel({
10425
10532
  }
10426
10533
  )
10427
10534
  ] }),
10428
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10535
+ !agentId ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
10536
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10537
+ Button,
10538
+ {
10539
+ type: "button",
10540
+ size: "sm",
10541
+ className: "gap-1",
10542
+ disabled: agentSaving,
10543
+ onClick: () => void handleCreateAssistantFromForm(),
10544
+ children: agentSaving ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
10545
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
10546
+ "Creating\u2026"
10547
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
10548
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Bot, { className: "h-3.5 w-3.5" }),
10549
+ "Create assistant"
10550
+ ] })
10551
+ }
10552
+ ),
10553
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10554
+ Button,
10555
+ {
10556
+ type: "button",
10557
+ size: "sm",
10558
+ variant: "secondary",
10559
+ className: "gap-1",
10560
+ disabled: agentSaving || agentLoading,
10561
+ onClick: () => void handleRetryBootstrapAgent(),
10562
+ children: "Retry auto-setup"
10563
+ }
10564
+ )
10565
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10429
10566
  Button,
10430
10567
  {
10431
10568
  type: "button",
@@ -10438,7 +10575,7 @@ function PluginSettingsPanel({
10438
10575
  "Saving\u2026"
10439
10576
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
10440
10577
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Save, { className: "h-3.5 w-3.5" }),
10441
- "Save agent"
10578
+ "Save assistant"
10442
10579
  ] })
10443
10580
  }
10444
10581
  )
@@ -10690,8 +10827,14 @@ function PluginListItem({
10690
10827
  }
10691
10828
  function PluginsPage() {
10692
10829
  const { pluginDescriptors = [] } = (0, import_react41.useContext)(AdminConfigContext);
10830
+ const searchParams = (0, import_navigation18.useSearchParams)();
10693
10831
  const [selectedName, setSelectedName] = (0, import_react41.useState)(null);
10694
10832
  const [enabledMap, setEnabledMap] = (0, import_react41.useState)({});
10833
+ (0, import_react41.useEffect)(() => {
10834
+ if (searchParams.get("plugin") !== "llm") return;
10835
+ const llmDesc = pluginDescriptors.find((p) => p.settingsGroup === "llm");
10836
+ if (llmDesc) setSelectedName(llmDesc.name);
10837
+ }, [searchParams, pluginDescriptors]);
10695
10838
  (0, import_react41.useEffect)(() => {
10696
10839
  pluginDescriptors.forEach((p) => {
10697
10840
  if (!p.settingsGroup) return;
@@ -10754,7 +10897,7 @@ function PluginsPage() {
10754
10897
 
10755
10898
  // src/admin/pages/BrandEditPage.tsx
10756
10899
  var import_react42 = require("react");
10757
- var import_navigation18 = require("next/navigation");
10900
+ var import_navigation19 = require("next/navigation");
10758
10901
  var import_lucide_react33 = require("lucide-react");
10759
10902
 
10760
10903
  // src/components/Admin/SeoSection.tsx
@@ -10849,7 +10992,7 @@ async function fetchSeo(seoId) {
10849
10992
  var import_jsx_runtime58 = require("react/jsx-runtime");
10850
10993
  var isCreate = (id) => id === "create";
10851
10994
  function BrandEditPage({ brandId }) {
10852
- const router = (0, import_navigation18.useRouter)();
10995
+ const router = (0, import_navigation19.useRouter)();
10853
10996
  const create = isCreate(brandId);
10854
10997
  const [loading, setLoading] = (0, import_react42.useState)(!create);
10855
10998
  const [saving, setSaving] = (0, import_react42.useState)(false);
@@ -11052,7 +11195,7 @@ function BrandEditPage({ brandId }) {
11052
11195
 
11053
11196
  // src/admin/pages/ProductEditPage.tsx
11054
11197
  var import_react44 = require("react");
11055
- var import_navigation19 = require("next/navigation");
11198
+ var import_navigation20 = require("next/navigation");
11056
11199
  var import_lucide_react34 = require("lucide-react");
11057
11200
 
11058
11201
  // src/components/Admin/AttributeFacetNameInput.tsx
@@ -11231,7 +11374,7 @@ function pickOtherMetadata(m) {
11231
11374
  return rest;
11232
11375
  }
11233
11376
  function ProductEditPage({ productId }) {
11234
- const router = (0, import_navigation19.useRouter)();
11377
+ const router = (0, import_navigation20.useRouter)();
11235
11378
  const create = isCreate2(productId);
11236
11379
  const [loading, setLoading] = (0, import_react44.useState)(!create);
11237
11380
  const [saving, setSaving] = (0, import_react44.useState)(false);
@@ -11919,7 +12062,7 @@ function ProductEditPage({ productId }) {
11919
12062
 
11920
12063
  // src/admin/pages/CollectionEditPage.tsx
11921
12064
  var import_react45 = require("react");
11922
- var import_navigation20 = require("next/navigation");
12065
+ var import_navigation21 = require("next/navigation");
11923
12066
  var import_lucide_react35 = require("lucide-react");
11924
12067
  var import_jsx_runtime61 = require("react/jsx-runtime");
11925
12068
  var isCreate3 = (id) => id === "create";
@@ -11929,7 +12072,7 @@ var sectionCls2 = "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4
11929
12072
  var labelCls2 = "block text-xs font-medium text-gray-600 mb-1";
11930
12073
  var inputCls2 = "w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm";
11931
12074
  function CollectionEditPage({ collectionId }) {
11932
- const router = (0, import_navigation20.useRouter)();
12075
+ const router = (0, import_navigation21.useRouter)();
11933
12076
  const create = isCreate3(collectionId);
11934
12077
  const [loading, setLoading] = (0, import_react45.useState)(!create);
11935
12078
  const [saving, setSaving] = (0, import_react45.useState)(false);
@@ -12856,39 +12999,6 @@ var CRUD_CONFIGS = {
12856
12999
  { field: "createdAt", displayName: "Created", type: "date" }
12857
13000
  ],
12858
13001
  addEditPageUrl: ""
12859
- },
12860
- llm_agents: {
12861
- title: "LLM agents",
12862
- apiEndpoint: "/api/llm_agents",
12863
- defaultSortField: "name",
12864
- defaultSortOrder: "asc",
12865
- columns: [
12866
- { field: "name", displayName: "Name" },
12867
- { field: "slug", displayName: "Slug" },
12868
- {
12869
- field: "systemInstruction",
12870
- displayName: "System instruction",
12871
- type: "textarea",
12872
- hideInTable: true,
12873
- textareaRows: 10,
12874
- placeholder: "How the model should behave for this agent (sent as system prompt to the LLM)."
12875
- },
12876
- { field: "model", displayName: "Model", placeholder: "Optional gateway model id" },
12877
- { field: "temperature", displayName: "Temperature", type: "number" },
12878
- { field: "maxTokens", displayName: "Max tokens", type: "number" },
12879
- {
12880
- field: "validationRules",
12881
- displayName: "Validation & output guardrails",
12882
- type: "textarea",
12883
- hideInTable: true,
12884
- textareaRows: 8,
12885
- placeholder: "Plain text: rules appended to the system prompt. Or JSON: guardrails, maxUserChars, blockedSubstrings, etc."
12886
- },
12887
- { field: "enabled", displayName: "Enabled", type: "boolean" },
12888
- { field: "createdAt", displayName: "Created", type: "date", hideInForm: true },
12889
- { field: "updatedAt", displayName: "Updated", type: "datetime", hideInForm: true }
12890
- ],
12891
- addEditPageUrl: ""
12892
13002
  }
12893
13003
  };
12894
13004
  function BlogEditorWrapper({ blogId }) {
@@ -12907,13 +13017,16 @@ function BlogEditorWrapper({ blogId }) {
12907
13017
  return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BlogEditor, { existingBlog: blog });
12908
13018
  }
12909
13019
  function AdminPageResolver({ slug }) {
12910
- const router = (0, import_navigation21.useRouter)();
13020
+ const router = (0, import_navigation22.useRouter)();
12911
13021
  const { customCrudConfigs, storeEnabled } = (0, import_react48.useContext)(AdminConfigContext);
12912
13022
  const key = slug?.[0] || "dashboard";
12913
13023
  (0, import_react48.useEffect)(() => {
12914
13024
  if (key === "layout-settings") {
12915
13025
  router.replace("/admin/settings?tab=navbar");
12916
13026
  }
13027
+ if (key === "llm_agents") {
13028
+ router.replace("/admin/plugins?plugin=llm");
13029
+ }
12917
13030
  }, [key, router]);
12918
13031
  if (key === "layout-settings") {
12919
13032
  return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex justify-center py-8", children: [
@@ -12921,6 +13034,12 @@ function AdminPageResolver({ slug }) {
12921
13034
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "ml-2", children: "Redirecting..." })
12922
13035
  ] });
12923
13036
  }
13037
+ if (key === "llm_agents") {
13038
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex justify-center py-8", children: [
13039
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "animate-spin rounded-full h-6 w-6 border-2 border-gray-300 border-t-gray-600" }),
13040
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "ml-2", children: "Opening Plugins\u2026" })
13041
+ ] });
13042
+ }
12924
13043
  const Page = PAGE_MAP[key];
12925
13044
  if (Page) {
12926
13045
  return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Page, {});