Add ability to disable default agent skills ()

* Add ability to disable default agent skills

* debug build
This commit is contained in:
Timothy Carambat 2025-01-27 16:52:43 -08:00 committed by GitHub
parent 75790e7e90
commit 6aa1854155
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 175 additions and 39 deletions
.github/workflows
frontend/src/pages/Admin/Agents
server
endpoints
models
utils/agents

View file

@ -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/*'

View file

@ -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>

View file

@ -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,17 +239,35 @@ export default function AdminAgents() {
setImportedSkills={setImportedSkills}
/>
) : (
<SelectedSkillComponent
skill={configurableSkills[selectedSkill]?.skill}
settings={settings}
toggleSkill={toggleAgentSkill}
enabled={agentSkills.includes(
configurableSkills[selectedSkill]?.skill
<>
{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}
toggleSkill={toggleAgentSkill}
enabled={agentSkills.includes(
configurableSkills[selectedSkill]?.skill
)}
setHasChanges={setHasChanges}
{...configurableSkills[selectedSkill]}
/>
)}
setHasChanges={setHasChanges}
{...(configurableSkills[selectedSkill] ||
defaultSkills[selectedSkill])}
/>
</>
)}
</>
) : (
@ -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,17 +356,35 @@ export default function AdminAgents() {
setImportedSkills={setImportedSkills}
/>
) : (
<SelectedSkillComponent
skill={configurableSkills[selectedSkill]?.skill}
settings={settings}
toggleSkill={toggleAgentSkill}
enabled={agentSkills.includes(
configurableSkills[selectedSkill]?.skill
<>
{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}
toggleSkill={toggleAgentSkill}
enabled={agentSkills.includes(
configurableSkills[selectedSkill]?.skill
)}
setHasChanges={setHasChanges}
{...configurableSkills[selectedSkill]}
/>
)}
setHasChanges={setHasChanges}
{...(configurableSkills[selectedSkill] ||
defaultSkills[selectedSkill])}
/>
</>
)}
</>
) : (

View file

@ -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",
},
};

View file

@ -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 ||

View file

@ -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,

View file

@ -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