@kenhkl/agent-moss 0.7.5 → 0.7.6
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/cli.js +30 -22
- package/dist/cli.js.map +1 -1
- package/dist/skills/browser_web_access_guard.md +31 -0
- package/dist/skills/data_exfiltration_guard.md +33 -0
- package/dist/skills/email_operation_guard.md +30 -0
- package/dist/skills/file_access_guard.md +33 -0
- package/dist/skills/general_tool_risk_guard.md +33 -0
- package/dist/skills/intent_deviation_guard.md +39 -0
- package/dist/skills/lateral_movement_guard.md +31 -0
- package/dist/skills/persistence_backdoor_guard.md +32 -0
- package/dist/skills/resource_exhaustion_guard.md +32 -0
- package/dist/skills/script_execution_guard.md +37 -0
- package/dist/skills/skill_installation_guard.md +30 -0
- package/dist/skills/supply_chain_guard.md +31 -0
- package/dist/templates/policy_mapping.md +87 -0
- package/dist/templates/prompt1_template.txt +62 -0
- package/dist/templates/prompt2_template.txt +45 -0
- package/dist/templates/security_judge_template.txt +71 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -747,16 +747,17 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
747
747
|
function loadAllSkills() {
|
|
748
748
|
if (cachedSkills) return cachedSkills;
|
|
749
749
|
cachedSkills = {};
|
|
750
|
-
|
|
751
|
-
|
|
750
|
+
const dir = existsSync2(SKILLS_DIR) ? SKILLS_DIR : SKILLS_DIR_FALLBACK;
|
|
751
|
+
if (!existsSync2(dir)) {
|
|
752
|
+
console.warn("[AgentMoss] Skills directory not found:", SKILLS_DIR, "and fallback:", SKILLS_DIR_FALLBACK);
|
|
752
753
|
return cachedSkills;
|
|
753
754
|
}
|
|
754
|
-
const files = readdirSync(
|
|
755
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".md"));
|
|
755
756
|
for (const f of files) {
|
|
756
757
|
const name = f.replace(".md", "");
|
|
757
|
-
cachedSkills[name] = readFileSync(resolve(
|
|
758
|
+
cachedSkills[name] = readFileSync(resolve(dir, f), "utf-8");
|
|
758
759
|
}
|
|
759
|
-
console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills`);
|
|
760
|
+
console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills from ${dir}`);
|
|
760
761
|
return cachedSkills;
|
|
761
762
|
}
|
|
762
763
|
function matchSkills(actionType, actionDetail, reason, maxSkills = 3) {
|
|
@@ -808,14 +809,15 @@ function formatSkillsForPrompt(skills) {
|
|
|
808
809
|
${s.skillContent}`
|
|
809
810
|
).join("\n\n---\n\n");
|
|
810
811
|
}
|
|
811
|
-
var __filename2, __dirname2, SKILLS_DIR, SKILL_KEYWORD_MAP, cachedSkills;
|
|
812
|
+
var __filename2, __dirname2, SKILLS_DIR, SKILLS_DIR_FALLBACK, SKILL_KEYWORD_MAP, cachedSkills;
|
|
812
813
|
var init_skill_loader = __esm({
|
|
813
814
|
"src/engine/skill-loader.ts"() {
|
|
814
815
|
"use strict";
|
|
815
816
|
init_esm_shims();
|
|
816
817
|
__filename2 = fileURLToPath2(import.meta.url);
|
|
817
818
|
__dirname2 = dirname(__filename2);
|
|
818
|
-
SKILLS_DIR = resolve(__dirname2, "
|
|
819
|
+
SKILLS_DIR = resolve(__dirname2, "../skills");
|
|
820
|
+
SKILLS_DIR_FALLBACK = resolve(__dirname2, "../../agent_moss/skills");
|
|
819
821
|
SKILL_KEYWORD_MAP = {
|
|
820
822
|
"file_access_guard": ["file", "\u6587\u4EF6", "path", "\u8DEF\u5F84", "read", "write", "cat", "open", "access", "\u8BBF\u95EE", "\u8BFB\u5199", "copy", "cp", "mv", "move"],
|
|
821
823
|
"script_execution_guard": ["command", "shell", "bash", "exec", "execute", "\u6267\u884C", "\u547D\u4EE4", "script", "\u811A\u672C", "run", "\u8FD0\u884C", "subprocess", "system", "eval", "compile", "\u5B89\u88C5", "install", "pip", "npm"],
|
|
@@ -825,7 +827,9 @@ var init_skill_loader = __esm({
|
|
|
825
827
|
"general_tool_risk_guard": ["tool", "\u5DE5\u5177", "api", "invoke", "\u8C03\u7528", "function", "\u51FD\u6570"],
|
|
826
828
|
"lateral_movement_guard": ["ssh", "scp", "ftp", "sftp", "rdp", "vnc", "telnet", "\u5185\u7F51", "\u6A2A\u5411", "tunnel", "\u4EE3\u7406", "proxy", "port", "\u7AEF\u53E3", "scan", "\u626B\u63CF", "ping", "traceroute", "nslookup"],
|
|
827
829
|
"persistence_backdoor_guard": ["cron", "crontab", "\u5B9A\u65F6", "scheduled", "startup", "\u542F\u52A8\u9879", "service", "\u670D\u52A1", "daemon", "\u5B88\u62A4", "registry", "\u6CE8\u518C\u8868", "backdoor", "\u540E\u95E8", "persist", "\u6301\u4E45\u5316", "authorized_keys", "bashrc", "zshrc", "profile", ".rc", "shell config", "shell \u914D\u7F6E"],
|
|
828
|
-
|
|
830
|
+
// 注意:避免裸 'memory'/'内存'/'dd'——会误命中 memory-addMemory(写记忆工具,
|
|
831
|
+
// 'dd' 是 'addMemory' 的子串)等无害操作。用组合词/命令前缀精准匹配攻击场景。
|
|
832
|
+
"resource_exhaustion_guard": ["fork", "bomb", "\u70B8\u5F39", "memory bomb", "oom", "out of memory", "\u5185\u5B58\u6EA2\u51FA", "\u5185\u5B58\u8017\u5C3D", "\u5185\u5B58\u6CC4\u6F0F", "disk", "\u78C1\u76D8", "cpu", "process", "\u8FDB\u7A0B", "dd if=", "/dev/zero", "/dev/null", "yes >", "while true", "\u65E0\u9650\u5FAA\u73AF", "\u8017\u5C3D", "exhaust", "\u8D44\u6E90"],
|
|
829
833
|
"skill_installation_guard": ["skill", "plugin", "\u63D2\u4EF6", "extension", "\u6269\u5C55", "install skill", "\u5B89\u88C5\u63D2\u4EF6", "\u5B89\u88C5\u6280\u80FD", "marketplace", "\u5546\u5E97"],
|
|
830
834
|
"supply_chain_guard": ["dependency", "\u4F9D\u8D56", "package", "\u5305", "npm install", "pip install", "requirements", "import", "library", "\u5E93", "registry", "\u4ED3\u5E93", "supply", "\u4F9B\u5E94\u94FE", "typosquatting"],
|
|
831
835
|
"intent_deviation_guard": ["rm", "del", "delete", "remove", "\u5220\u9664", "format", "\u683C\u5F0F\u5316", "drop", "truncate", "\u6E05\u7A7A", "wipe", "\u64E6\u9664", "\u91CD\u7F6E", "reset", "sudo", "root", "admin", "\u7BA1\u7406\u5458", "privilege", "\u63D0\u6743"]
|
|
@@ -841,28 +845,30 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
841
845
|
function loadTemplates() {
|
|
842
846
|
if (cachedTemplates) return cachedTemplates;
|
|
843
847
|
cachedTemplates = {};
|
|
844
|
-
|
|
845
|
-
|
|
848
|
+
const dir = existsSync3(TEMPLATES_DIR) ? TEMPLATES_DIR : TEMPLATES_DIR_FALLBACK;
|
|
849
|
+
if (!existsSync3(dir)) {
|
|
850
|
+
console.warn("[AgentMoss] Templates directory not found:", TEMPLATES_DIR, "and fallback:", TEMPLATES_DIR_FALLBACK);
|
|
846
851
|
return cachedTemplates;
|
|
847
852
|
}
|
|
848
853
|
for (const file of TEMPLATE_FILES) {
|
|
849
|
-
const filePath = resolve2(
|
|
854
|
+
const filePath = resolve2(dir, file);
|
|
850
855
|
if (existsSync3(filePath)) {
|
|
851
856
|
const key = file.replace(".txt", "").replace("_template", "");
|
|
852
857
|
cachedTemplates[key] = readFileSync2(filePath, "utf-8");
|
|
853
858
|
}
|
|
854
859
|
}
|
|
855
|
-
console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates`);
|
|
860
|
+
console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates from ${dir}`);
|
|
856
861
|
return cachedTemplates;
|
|
857
862
|
}
|
|
858
|
-
var __filename3, __dirname3, TEMPLATES_DIR, TEMPLATE_FILES, cachedTemplates;
|
|
863
|
+
var __filename3, __dirname3, TEMPLATES_DIR, TEMPLATES_DIR_FALLBACK, TEMPLATE_FILES, cachedTemplates;
|
|
859
864
|
var init_template_loader = __esm({
|
|
860
865
|
"src/engine/template-loader.ts"() {
|
|
861
866
|
"use strict";
|
|
862
867
|
init_esm_shims();
|
|
863
868
|
__filename3 = fileURLToPath3(import.meta.url);
|
|
864
869
|
__dirname3 = dirname2(__filename3);
|
|
865
|
-
TEMPLATES_DIR = resolve2(__dirname3, "
|
|
870
|
+
TEMPLATES_DIR = resolve2(__dirname3, "../templates");
|
|
871
|
+
TEMPLATES_DIR_FALLBACK = resolve2(__dirname3, "../../agent_moss/templates");
|
|
866
872
|
TEMPLATE_FILES = ["prompt1_template.txt", "prompt2_template.txt", "security_judge_template.txt"];
|
|
867
873
|
cachedTemplates = null;
|
|
868
874
|
}
|
|
@@ -1100,13 +1106,14 @@ async function runLLMAnalysis(input, previous) {
|
|
|
1100
1106
|
function buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis) {
|
|
1101
1107
|
const skillsText = formatSkillsForPrompt(matchedSkills);
|
|
1102
1108
|
const historyStr = input.actionHistory.map((h, i) => `${i + 1}. ${h.actionType}: ${h.actionDetail}`).join("\n") || "(\u65E0\u5386\u53F2\u64CD\u4F5C)";
|
|
1103
|
-
const templateName = previous.heuristic || previous.logic ? "prompt2" : "prompt1";
|
|
1104
|
-
const baseTemplate = templates[templateName] || templates["prompt1"] || "";
|
|
1105
1109
|
const scriptAnalysisText = scriptAnalysis ? formatScriptAnalysisForPrompt(scriptAnalysis) : "";
|
|
1106
1110
|
const hintsText = formatHints(previous);
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1111
|
+
const securityJudgeTemplate = templates["security_judge"];
|
|
1112
|
+
if (securityJudgeTemplate) {
|
|
1113
|
+
return securityJudgeTemplate.replaceAll("{prompt_session}", input.promptSession || "\uFF08\u672A\u63D0\u4F9B\uFF09").replaceAll("{action_history}", historyStr).replaceAll("{action_type}", input.aNext.actionType).replaceAll("{action_detail}", input.aNext.actionDetail).replaceAll("{reason}", input.reason || "\u672A\u8BF4\u660E").replaceAll("{skills_text}", skillsText).replaceAll("{hints_text}", hintsText).replaceAll("{script_analysis_text}", scriptAnalysisText).replaceAll("{{", "{").replaceAll("}}", "}");
|
|
1114
|
+
}
|
|
1115
|
+
console.warn("[AgentMoss] security_judge template missing, using sparse fallback prompt");
|
|
1116
|
+
return `## \u5F53\u524D\u64CD\u4F5C\u4E0A\u4E0B\u6587
|
|
1110
1117
|
- \u4F1A\u8BDD ID: ${input.sessionId}
|
|
1111
1118
|
- \u7528\u6237\u4EFB\u52A1: ${input.promptSession || "\u672A\u6307\u5B9A"}
|
|
1112
1119
|
- \u64CD\u4F5C\u7CFB\u7EDF: ${input.osType}
|
|
@@ -1128,8 +1135,7 @@ ${scriptAnalysisText ? `
|
|
|
1128
1135
|
## \u811A\u672C\u5185\u5BB9\u5206\u6790
|
|
1129
1136
|
${scriptAnalysisText}` : ""}
|
|
1130
1137
|
|
|
1131
|
-
\u8BF7\u6839\u636E\u4EE5\u4E0A\u4FE1\u606F\uFF0C\u5BF9\u5373\u5C06\u6267\u884C\u7684\u64CD\u4F5C\u8FDB\u884C\u5B89\u5168\u5224\u65AD\u3002\u4F60\u5FC5\u987B\u8F93\u51FA\u4E25\u683C\u7684 JSON \u683C\u5F0F\uFF0C
|
|
1132
|
-
\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3001\u6CE8\u91CA\u6216 markdown \u6807\u8BB0\u3002
|
|
1138
|
+
\u8BF7\u6839\u636E\u4EE5\u4E0A\u4FE1\u606F\uFF0C\u5BF9\u5373\u5C06\u6267\u884C\u7684\u64CD\u4F5C\u8FDB\u884C\u5B89\u5168\u5224\u65AD\u3002\u524D\u7F6E\u68C0\u6D4B\u4E3A low/medium \u4E14\u6709\u5408\u7406\u6267\u884C\u7406\u7531\u65F6\u5E94\u5F53\u5141\u8BB8\u3002\u4F60\u5FC5\u987B\u8F93\u51FA\u4E25\u683C\u7684 JSON \u683C\u5F0F\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3001\u6CE8\u91CA\u6216 markdown \u6807\u8BB0\u3002
|
|
1133
1139
|
|
|
1134
1140
|
\u8F93\u51FA\u683C\u5F0F:
|
|
1135
1141
|
{"allowed": true/false, "reason": "\u5224\u65AD\u7406\u7531", "riskLevel": "low|medium|high|critical", "riskType": "\u98CE\u9669\u7C7B\u578B", "confidence": 0-100}`;
|
|
@@ -1176,7 +1182,9 @@ async function analyzeWithLLM(prompt, config) {
|
|
|
1176
1182
|
temperature: config.temperature || 0.1,
|
|
1177
1183
|
max_tokens: config.maxTokens || 1024,
|
|
1178
1184
|
messages: [
|
|
1179
|
-
|
|
1185
|
+
// security_judge 模板自带角色定义与判断规则,system 仅做输出格式约束,
|
|
1186
|
+
// 避免与模板里的"你是 xiaoO Audit Agent 安全审计员"角色定义冲突(对齐 Python:无独立 system)。
|
|
1187
|
+
{ role: "system", content: "\u53EA\u8F93\u51FA\u7EAF JSON\uFF0C\u4E0D\u8981\u5305\u542B markdown \u6807\u8BB0\u3001\u4EE3\u7801\u5757\u6216\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3002" },
|
|
1180
1188
|
{ role: "user", content: prompt }
|
|
1181
1189
|
]
|
|
1182
1190
|
});
|