θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dev-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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/*'
Expand Down
26 changes: 25 additions & 1 deletion frontend/src/pages/Admin/Agents/DefaultSkillPanel/index.jsx
Original file line number Diff line number Diff line change
@@ -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]">
Expand All @@ -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>
Expand Down
120 changes: 95 additions & 25 deletions frontend/src/pages/Admin/Agents/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]">
Expand All @@ -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
Expand Down Expand Up @@ -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])}
/>
</>
)}
</>
) : (
Expand Down Expand Up @@ -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]">
Expand All @@ -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
Expand Down Expand Up @@ -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])}
/>
</>
)}
</>
) : (
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/pages/Admin/Agents/skills.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
};

Expand Down
9 changes: 9 additions & 0 deletions server/endpoints/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 ||
Expand Down
11 changes: 11 additions & 0 deletions server/models/systemSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",

Expand Down Expand Up @@ -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,
Expand Down
Loading