mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2025-03-13 05:32:24 +00:00
Add ability to disable default agent skills (#3041)
* Add ability to disable default agent skills * debug build
This commit is contained in:
parent
75790e7e90
commit
6aa1854155
7 changed files with 175 additions and 39 deletions
.github/workflows
frontend/src/pages/Admin/Agents
server
2
.github/workflows/dev-build.yaml
vendored
2
.github/workflows/dev-build.yaml
vendored
|
@ -6,7 +6,7 @@ concurrency:
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: ['arm-runner-test'] # put your current branch to create a build. Core team only.
|
||||
branches: ['disable-default-agent-skills'] # put your current branch to create a build. Core team only.
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'cloud-deployments/*'
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import React from "react";
|
||||
import { DefaultBadge } from "../Badges/default";
|
||||
|
||||
export default function DefaultSkillPanel({ title, description, image, icon }) {
|
||||
export default function DefaultSkillPanel({
|
||||
title,
|
||||
description,
|
||||
image,
|
||||
icon,
|
||||
enabled = true,
|
||||
toggleSkill,
|
||||
skill,
|
||||
}) {
|
||||
return (
|
||||
<div className="p-2">
|
||||
<div className="flex flex-col gap-y-[18px] max-w-[500px]">
|
||||
|
@ -21,10 +29,26 @@ export default function DefaultSkillPanel({ title, description, image, icon }) {
|
|||
</label>
|
||||
<DefaultBadge title={title} />
|
||||
</div>
|
||||
<label
|
||||
className={`border-none relative inline-flex items-center ml-auto cursor-pointer`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="peer sr-only"
|
||||
checked={enabled}
|
||||
onChange={() => toggleSkill(skill)}
|
||||
/>
|
||||
<div className="peer-disabled:opacity-50 pointer-events-none peer h-6 w-11 rounded-full bg-[#CFCFD0] after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border-none after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-[#32D583] peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-transparent"></div>
|
||||
<span className="ml-3 text-sm font-medium"></span>
|
||||
</label>
|
||||
</div>
|
||||
<img src={image} alt={title} className="w-full rounded-md" />
|
||||
<p className="text-theme-text-secondary text-opacity-60 text-xs font-medium py-1.5">
|
||||
{description}
|
||||
<br />
|
||||
<br />
|
||||
By default, this skill is enabled, but you can disable it if you don't
|
||||
want it to be available to the agent.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -15,14 +15,16 @@ import ImportedSkillConfig from "./Imported/ImportedSkillConfig";
|
|||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
export default function AdminAgents() {
|
||||
const formEl = useRef(null);
|
||||
const [hasChanges, setHasChanges] = useState(false);
|
||||
const [settings, setSettings] = useState({});
|
||||
const [selectedSkill, setSelectedSkill] = useState("");
|
||||
const [agentSkills, setAgentSkills] = useState([]);
|
||||
const [importedSkills, setImportedSkills] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [showSkillModal, setShowSkillModal] = useState(false);
|
||||
const formEl = useRef(null);
|
||||
|
||||
const [agentSkills, setAgentSkills] = useState([]);
|
||||
const [importedSkills, setImportedSkills] = useState([]);
|
||||
const [disabledAgentSkills, setDisabledAgentSkills] = useState([]);
|
||||
|
||||
// Alert user if they try to leave the page with unsaved changes
|
||||
useEffect(() => {
|
||||
|
@ -42,17 +44,31 @@ export default function AdminAgents() {
|
|||
async function fetchSettings() {
|
||||
const _settings = await System.keys();
|
||||
const _preferences = await Admin.systemPreferencesByFields([
|
||||
"disabled_agent_skills",
|
||||
"default_agent_skills",
|
||||
"imported_agent_skills",
|
||||
]);
|
||||
setSettings({ ..._settings, preferences: _preferences.settings } ?? {});
|
||||
setAgentSkills(_preferences.settings?.default_agent_skills ?? []);
|
||||
setDisabledAgentSkills(
|
||||
_preferences.settings?.disabled_agent_skills ?? []
|
||||
);
|
||||
setImportedSkills(_preferences.settings?.imported_agent_skills ?? []);
|
||||
setLoading(false);
|
||||
}
|
||||
fetchSettings();
|
||||
}, []);
|
||||
|
||||
const toggleDefaultSkill = (skillName) => {
|
||||
setDisabledAgentSkills((prev) => {
|
||||
const updatedSkills = prev.includes(skillName)
|
||||
? prev.filter((name) => name !== skillName)
|
||||
: [...prev, skillName];
|
||||
setHasChanges(true);
|
||||
return updatedSkills;
|
||||
});
|
||||
};
|
||||
|
||||
const toggleAgentSkill = (skillName) => {
|
||||
setAgentSkills((prev) => {
|
||||
const updatedSkills = prev.includes(skillName)
|
||||
|
@ -93,11 +109,15 @@ export default function AdminAgents() {
|
|||
if (success) {
|
||||
const _settings = await System.keys();
|
||||
const _preferences = await Admin.systemPreferencesByFields([
|
||||
"disabled_agent_skills",
|
||||
"default_agent_skills",
|
||||
"imported_agent_skills",
|
||||
]);
|
||||
setSettings({ ..._settings, preferences: _preferences.settings } ?? {});
|
||||
setAgentSkills(_preferences.settings?.default_agent_skills ?? []);
|
||||
setDisabledAgentSkills(
|
||||
_preferences.settings?.disabled_agent_skills ?? []
|
||||
);
|
||||
setImportedSkills(_preferences.settings?.imported_agent_skills ?? []);
|
||||
showToast(`Agent preferences saved successfully.`, "success", {
|
||||
clear: true,
|
||||
|
@ -143,6 +163,11 @@ export default function AdminAgents() {
|
|||
type="hidden"
|
||||
value={agentSkills.join(",")}
|
||||
/>
|
||||
<input
|
||||
name="system::disabled_agent_skills"
|
||||
type="hidden"
|
||||
value={disabledAgentSkills.join(",")}
|
||||
/>
|
||||
|
||||
{/* Skill settings nav */}
|
||||
<div hidden={showSkillModal} className="flex flex-col gap-y-[18px]">
|
||||
|
@ -152,13 +177,15 @@ export default function AdminAgents() {
|
|||
</div>
|
||||
{/* Default skills */}
|
||||
<SkillList
|
||||
isDefault={true}
|
||||
skills={defaultSkills}
|
||||
selectedSkill={selectedSkill}
|
||||
handleClick={(skill) => {
|
||||
setSelectedSkill(skill);
|
||||
setShowSkillModal(true);
|
||||
}}
|
||||
activeSkills={Object.keys(defaultSkills).filter(
|
||||
(skill) => !disabledAgentSkills.includes(skill)
|
||||
)}
|
||||
/>
|
||||
{/* Configurable skills */}
|
||||
<SkillList
|
||||
|
@ -212,6 +239,23 @@ export default function AdminAgents() {
|
|||
setImportedSkills={setImportedSkills}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{defaultSkills?.[selectedSkill] ? (
|
||||
// The selected skill is a default skill - show the default skill panel
|
||||
<SelectedSkillComponent
|
||||
skill={defaultSkills[selectedSkill]?.skill}
|
||||
settings={settings}
|
||||
toggleSkill={toggleDefaultSkill}
|
||||
enabled={
|
||||
!disabledAgentSkills.includes(
|
||||
defaultSkills[selectedSkill]?.skill
|
||||
)
|
||||
}
|
||||
setHasChanges={setHasChanges}
|
||||
{...defaultSkills[selectedSkill]}
|
||||
/>
|
||||
) : (
|
||||
// The selected skill is a configurable skill - show the configurable skill panel
|
||||
<SelectedSkillComponent
|
||||
skill={configurableSkills[selectedSkill]?.skill}
|
||||
settings={settings}
|
||||
|
@ -220,11 +264,12 @@ export default function AdminAgents() {
|
|||
configurableSkills[selectedSkill]?.skill
|
||||
)}
|
||||
setHasChanges={setHasChanges}
|
||||
{...(configurableSkills[selectedSkill] ||
|
||||
defaultSkills[selectedSkill])}
|
||||
{...configurableSkills[selectedSkill]}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full text-theme-text-secondary">
|
||||
<Robot size={40} />
|
||||
|
@ -258,6 +303,11 @@ export default function AdminAgents() {
|
|||
type="hidden"
|
||||
value={agentSkills.join(",")}
|
||||
/>
|
||||
<input
|
||||
name="system::disabled_agent_skills"
|
||||
type="hidden"
|
||||
value={disabledAgentSkills.join(",")}
|
||||
/>
|
||||
|
||||
{/* Skill settings nav */}
|
||||
<div className="flex flex-col gap-y-[18px]">
|
||||
|
@ -268,10 +318,12 @@ export default function AdminAgents() {
|
|||
|
||||
{/* Default skills list */}
|
||||
<SkillList
|
||||
isDefault={true}
|
||||
skills={defaultSkills}
|
||||
selectedSkill={selectedSkill}
|
||||
handleClick={setSelectedSkill}
|
||||
activeSkills={Object.keys(defaultSkills).filter(
|
||||
(skill) => !disabledAgentSkills.includes(skill)
|
||||
)}
|
||||
/>
|
||||
{/* Configurable skills */}
|
||||
<SkillList
|
||||
|
@ -304,6 +356,23 @@ export default function AdminAgents() {
|
|||
setImportedSkills={setImportedSkills}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{defaultSkills?.[selectedSkill] ? (
|
||||
// The selected skill is a default skill - show the default skill panel
|
||||
<SelectedSkillComponent
|
||||
skill={defaultSkills[selectedSkill]?.skill}
|
||||
settings={settings}
|
||||
toggleSkill={toggleDefaultSkill}
|
||||
enabled={
|
||||
!disabledAgentSkills.includes(
|
||||
defaultSkills[selectedSkill]?.skill
|
||||
)
|
||||
}
|
||||
setHasChanges={setHasChanges}
|
||||
{...defaultSkills[selectedSkill]}
|
||||
/>
|
||||
) : (
|
||||
// The selected skill is a configurable skill - show the configurable skill panel
|
||||
<SelectedSkillComponent
|
||||
skill={configurableSkills[selectedSkill]?.skill}
|
||||
settings={settings}
|
||||
|
@ -312,11 +381,12 @@ export default function AdminAgents() {
|
|||
configurableSkills[selectedSkill]?.skill
|
||||
)}
|
||||
setHasChanges={setHasChanges}
|
||||
{...(configurableSkills[selectedSkill] ||
|
||||
defaultSkills[selectedSkill])}
|
||||
{...configurableSkills[selectedSkill]}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full text-theme-text-secondary">
|
||||
<Robot size={40} />
|
||||
|
|
|
@ -23,21 +23,24 @@ export const defaultSkills = {
|
|||
component: DefaultSkillPanel,
|
||||
icon: Brain,
|
||||
image: RAGImage,
|
||||
skill: "rag-memory",
|
||||
},
|
||||
"view-summarize": {
|
||||
"document-summarizer": {
|
||||
title: "View & summarize documents",
|
||||
description:
|
||||
"Allow the agent to list and summarize the content of workspace files currently embedded.",
|
||||
component: DefaultSkillPanel,
|
||||
icon: File,
|
||||
image: SummarizeImage,
|
||||
skill: "document-summarizer",
|
||||
},
|
||||
"scrape-websites": {
|
||||
"web-scraping": {
|
||||
title: "Scrape websites",
|
||||
description: "Allow the agent to visit and scrape the content of websites.",
|
||||
component: DefaultSkillPanel,
|
||||
icon: Browser,
|
||||
image: ScrapeWebsitesImage,
|
||||
skill: "web-scraping",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -374,6 +374,9 @@ function adminEndpoints(app) {
|
|||
case "default_agent_skills":
|
||||
requestedSettings[label] = safeJsonParse(setting?.value, []);
|
||||
break;
|
||||
case "disabled_agent_skills":
|
||||
requestedSettings[label] = safeJsonParse(setting?.value, []);
|
||||
break;
|
||||
case "imported_agent_skills":
|
||||
requestedSettings[label] = ImportedPlugin.listImportedPlugins();
|
||||
break;
|
||||
|
@ -440,6 +443,12 @@ function adminEndpoints(app) {
|
|||
?.value,
|
||||
[]
|
||||
) || [],
|
||||
disabled_agent_skills:
|
||||
safeJsonParse(
|
||||
(await SystemSettings.get({ label: "disabled_agent_skills" }))
|
||||
?.value,
|
||||
[]
|
||||
) || [],
|
||||
imported_agent_skills: ImportedPlugin.listImportedPlugins(),
|
||||
custom_app_name:
|
||||
(await SystemSettings.get({ label: "custom_app_name" }))?.value ||
|
||||
|
|
|
@ -24,6 +24,7 @@ const SystemSettings = {
|
|||
"agent_search_provider",
|
||||
"agent_sql_connections",
|
||||
"default_agent_skills",
|
||||
"disabled_agent_skills",
|
||||
"imported_agent_skills",
|
||||
"custom_app_name",
|
||||
"feature_flags",
|
||||
|
@ -40,6 +41,7 @@ const SystemSettings = {
|
|||
"text_splitter_chunk_overlap",
|
||||
"agent_search_provider",
|
||||
"default_agent_skills",
|
||||
"disabled_agent_skills",
|
||||
"agent_sql_connections",
|
||||
"custom_app_name",
|
||||
|
||||
|
@ -125,6 +127,15 @@ const SystemSettings = {
|
|||
return JSON.stringify([]);
|
||||
}
|
||||
},
|
||||
disabled_agent_skills: (updates) => {
|
||||
try {
|
||||
const skills = updates.split(",").filter((skill) => !!skill);
|
||||
return JSON.stringify(skills);
|
||||
} catch (e) {
|
||||
console.error(`Could not validate disabled agent skills.`);
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
},
|
||||
agent_sql_connections: async (updates) => {
|
||||
const existingConnections = safeJsonParse(
|
||||
(await SystemSettings.get({ label: "agent_sql_connections" }))?.value,
|
||||
|
|
|
@ -4,6 +4,13 @@ const { safeJsonParse } = require("../http");
|
|||
const Provider = require("./aibitat/providers/ai-provider");
|
||||
const ImportedPlugin = require("./imported");
|
||||
|
||||
// This is a list of skills that are built-in and default enabled.
|
||||
const DEFAULT_SKILLS = [
|
||||
AgentPlugins.memory.name,
|
||||
AgentPlugins.docSummarizer.name,
|
||||
AgentPlugins.webScraping.name,
|
||||
];
|
||||
|
||||
const USER_AGENT = {
|
||||
name: "USER",
|
||||
getDefinition: async () => {
|
||||
|
@ -17,16 +24,9 @@ const USER_AGENT = {
|
|||
const WORKSPACE_AGENT = {
|
||||
name: "@agent",
|
||||
getDefinition: async (provider = null) => {
|
||||
const defaultFunctions = [
|
||||
AgentPlugins.memory.name, // RAG
|
||||
AgentPlugins.docSummarizer.name, // Doc Summary
|
||||
AgentPlugins.webScraping.name, // Collector web-scraping
|
||||
];
|
||||
|
||||
return {
|
||||
role: Provider.systemPrompt(provider),
|
||||
functions: [
|
||||
...defaultFunctions,
|
||||
...(await agentSkillsFromSystemSettings()),
|
||||
...(await ImportedPlugin.activeImportedPlugins()),
|
||||
],
|
||||
|
@ -41,10 +41,29 @@ const WORKSPACE_AGENT = {
|
|||
*/
|
||||
async function agentSkillsFromSystemSettings() {
|
||||
const systemFunctions = [];
|
||||
const _setting = (await SystemSettings.get({ label: "default_agent_skills" }))
|
||||
?.value;
|
||||
|
||||
safeJsonParse(_setting, []).forEach((skillName) => {
|
||||
// Load non-imported built-in skills that are configurable, but are default enabled.
|
||||
const _disabledDefaultSkills = safeJsonParse(
|
||||
await SystemSettings.getValueOrFallback(
|
||||
{ label: "disabled_agent_skills" },
|
||||
"[]"
|
||||
),
|
||||
[]
|
||||
);
|
||||
DEFAULT_SKILLS.forEach((skill) => {
|
||||
if (!_disabledDefaultSkills.includes(skill))
|
||||
systemFunctions.push(AgentPlugins[skill].name);
|
||||
});
|
||||
|
||||
// Load non-imported built-in skills that are configurable.
|
||||
const _setting = safeJsonParse(
|
||||
await SystemSettings.getValueOrFallback(
|
||||
{ label: "default_agent_skills" },
|
||||
"[]"
|
||||
),
|
||||
[]
|
||||
);
|
||||
_setting.forEach((skillName) => {
|
||||
if (!AgentPlugins.hasOwnProperty(skillName)) return;
|
||||
|
||||
// This is a plugin module with many sub-children plugins who
|
||||
|
|
Loading…
Add table
Reference in a new issue