From 246edc38ceb54c00b73c45e3e14c2f5e59173a33 Mon Sep 17 00:00:00 2001 From: Timothy Carambat Date: Fri, 10 Apr 2026 13:20:47 -0700 Subject: [PATCH] Add automatic agent skill aproval via ENV Flag (#5405) * add autoapproval env flag * persist flag --- docker/.env.example | 6 +++- server/.env.example | 4 +++ .../agents/aibitat/plugins/http-socket.js | 9 ++++- .../utils/agents/aibitat/plugins/websocket.js | 8 +++++ server/utils/helpers/agents.js | 35 +++++++++++++++++++ server/utils/helpers/updateENV.js | 3 ++ 6 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 server/utils/helpers/agents.js diff --git a/docker/.env.example b/docker/.env.example index b774e13a..8efd57cb 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -444,4 +444,8 @@ GID='1000' # Set to "true" to enable. This can reduce token costs by 80% when you have # many tools/MCP servers enabled. # AGENT_SKILL_RERANKER_ENABLED="true" -# AGENT_SKILL_RERANKER_TOP_N=15 # (optional) Number of top tools to keep after reranking (default: 15) \ No newline at end of file +# AGENT_SKILL_RERANKER_TOP_N=15 # (optional) Number of top tools to keep after reranking (default: 15) + +# (optional) Comma-separated list of skills that are auto-approved. +# This will allow the skill to be invoked without user interaction. +# AGENT_AUTO_APPROVED_SKILLS=create-pdf-file,create-word-file \ No newline at end of file diff --git a/server/.env.example b/server/.env.example index 3d08207c..bf5e519a 100644 --- a/server/.env.example +++ b/server/.env.example @@ -454,3 +454,7 @@ TTS_PROVIDER="native" # many tools/MCP servers enabled. # AGENT_SKILL_RERANKER_ENABLED="true" # AGENT_SKILL_RERANKER_TOP_N=15 # (optional) Number of top tools to keep after reranking (default: 15) + +# (optional) Comma-separated list of skills that are auto-approved. +# This will allow the skill to be invoked without user interaction. +# AGENT_AUTO_APPROVED_SKILLS=create-pdf-file,create-word-file \ No newline at end of file diff --git a/server/utils/agents/aibitat/plugins/http-socket.js b/server/utils/agents/aibitat/plugins/http-socket.js index af443c58..2ef479bf 100644 --- a/server/utils/agents/aibitat/plugins/http-socket.js +++ b/server/utils/agents/aibitat/plugins/http-socket.js @@ -1,6 +1,7 @@ const chalk = require("chalk"); const { Telemetry } = require("../../../../models/telemetry"); const { v4: uuidv4 } = require("uuid"); +const { skillIsAutoApproved } = require("../../../helpers/agents"); const TOOL_APPROVAL_TIMEOUT_MS = 120 * 1_000; // 2 mins for tool approval /** @@ -118,7 +119,13 @@ const httpSocket = { payload = {}, description = null, }) { - // Check whitelist first + if (skillIsAutoApproved({ skillName })) { + return { + approved: true, + message: "Skill is auto-approved.", + }; + } + const { AgentSkillWhitelist, } = require("../../../../models/agentSkillWhitelist"); diff --git a/server/utils/agents/aibitat/plugins/websocket.js b/server/utils/agents/aibitat/plugins/websocket.js index b64407fd..188aefb0 100644 --- a/server/utils/agents/aibitat/plugins/websocket.js +++ b/server/utils/agents/aibitat/plugins/websocket.js @@ -2,6 +2,7 @@ const chalk = require("chalk"); const { Telemetry } = require("../../../../models/telemetry"); const { v4: uuidv4 } = require("uuid"); const { safeJsonParse } = require("../../../http"); +const { skillIsAutoApproved } = require("../../../helpers/agents"); const SOCKET_TIMEOUT_MS = 300 * 1_000; // 5 mins const TOOL_APPROVAL_TIMEOUT_MS = 120 * 1_000; // 2 mins for tool approval @@ -100,6 +101,13 @@ const websocket = { payload = {}, description = null, }) { + if (skillIsAutoApproved({ skillName })) { + return { + approved: true, + message: "Skill is auto-approved.", + }; + } + const { AgentSkillWhitelist, } = require("../../../../models/agentSkillWhitelist"); diff --git a/server/utils/helpers/agents.js b/server/utils/helpers/agents.js new file mode 100644 index 00000000..567b2c54 --- /dev/null +++ b/server/utils/helpers/agents.js @@ -0,0 +1,35 @@ +const chalk = require("chalk"); + +/** + * Checks if a skill is auto-approved by the ENV variable AGENT_AUTO_APPROVED_SKILLS. + * which is a comma-separated list of skill names. This property applies globally to all users + * so that all invocations of the skill are auto-approved without user interaction. + * @param {Object} options - The options object + * @param {string} options.skillName - The name of the skill + * @returns {boolean} True if the skill is auto-approved, false otherwise + */ +function skillIsAutoApproved({ skillName }) { + if ((!"AGENT_AUTO_APPROVED_SKILLS") in process.env) return false; + const autoApprovedSkills = String(process.env.AGENT_AUTO_APPROVED_SKILLS) + .split(",") + .map((skill) => skill.trim()) + .filter((skill) => !!skill); + + // If the list contains , then all skills are auto-approved + // This is a special case and overrides any other items in the list. + if (autoApprovedSkills.includes("")) return true; + + if (!autoApprovedSkills.length || !autoApprovedSkills.includes(skillName)) + return false; + + console.log( + chalk.green( + `Skill ${skillName} is auto-approved by the ENV variable AGENT_AUTO_APPROVED_SKILLS.` + ) + ); + return true; +} + +module.exports = { + skillIsAutoApproved, +}; diff --git a/server/utils/helpers/updateENV.js b/server/utils/helpers/updateENV.js index e0154c8c..070c8e0c 100644 --- a/server/utils/helpers/updateENV.js +++ b/server/utils/helpers/updateENV.js @@ -1336,6 +1336,9 @@ function dumpENV() { // Allow native tool calling for specific providers. "PROVIDER_SUPPORTS_NATIVE_TOOL_CALLING", + + // Allow auto-approval of skills + "AGENT_AUTO_APPROVED_SKILLS", ]; // Simple sanitization of each value to prevent ENV injection via newline or quote escaping.