@sofagent/rules 1.2.0
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/README.md +9 -0
- package/dist/engine.d.ts +26 -0
- package/dist/engine.js +82 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +12 -0
- package/dist/rules/index.d.ts +7 -0
- package/dist/rules/index.js +20 -0
- package/dist/rules/tool-injection.d.ts +7 -0
- package/dist/rules/tool-injection.js +87 -0
- package/dist/rules/tool-secret-leak.d.ts +7 -0
- package/dist/rules/tool-secret-leak.js +69 -0
- package/dist/rules/tool-sensitive-file.d.ts +7 -0
- package/dist/rules/tool-sensitive-file.js +104 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.js +7 -0
- package/package.json +26 -0
package/README.md
ADDED
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ToolRule, ToolCallContext, InterceptVerdict } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 规则引擎——注册 N 条规则,对 tool call 做批量检查并聚合结果
|
|
4
|
+
*
|
|
5
|
+
* 聚合规则:
|
|
6
|
+
* - 任一 FAIL → FAIL
|
|
7
|
+
* - 否则任一 WARN → WARN
|
|
8
|
+
* - 否则 PASS
|
|
9
|
+
*/
|
|
10
|
+
export declare class RulesEngine {
|
|
11
|
+
private readonly rules;
|
|
12
|
+
constructor(rules: ToolRule[]);
|
|
13
|
+
/**
|
|
14
|
+
* 对单个 tool call 执行所有已注册规则的检查
|
|
15
|
+
* @param ctx tool call 上下文
|
|
16
|
+
* @returns 每条规则的判定结果数组
|
|
17
|
+
*/
|
|
18
|
+
check(ctx: ToolCallContext): InterceptVerdict[];
|
|
19
|
+
/**
|
|
20
|
+
* 聚合多条规则判定为单一决策
|
|
21
|
+
* @param verdicts 规则判定结果数组
|
|
22
|
+
* @returns 聚合后的单一判定(取最严重状态)
|
|
23
|
+
*/
|
|
24
|
+
aggregate(verdicts: InterceptVerdict[]): InterceptVerdict;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=engine.d.ts.map
|
package/dist/engine.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// engine.ts · RulesEngine 纯函数入口
|
|
4
|
+
// v1.2.0:P3 编排引擎内嵌——规则引擎核心
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.RulesEngine = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* 规则引擎——注册 N 条规则,对 tool call 做批量检查并聚合结果
|
|
10
|
+
*
|
|
11
|
+
* 聚合规则:
|
|
12
|
+
* - 任一 FAIL → FAIL
|
|
13
|
+
* - 否则任一 WARN → WARN
|
|
14
|
+
* - 否则 PASS
|
|
15
|
+
*/
|
|
16
|
+
class RulesEngine {
|
|
17
|
+
rules;
|
|
18
|
+
constructor(rules) {
|
|
19
|
+
this.rules = rules;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 对单个 tool call 执行所有已注册规则的检查
|
|
23
|
+
* @param ctx tool call 上下文
|
|
24
|
+
* @returns 每条规则的判定结果数组
|
|
25
|
+
*/
|
|
26
|
+
check(ctx) {
|
|
27
|
+
return this.rules.map((rule) => {
|
|
28
|
+
try {
|
|
29
|
+
return rule.check(ctx);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
// 单条规则异常不应中断整批检查——降级为该规则 FAIL,
|
|
33
|
+
// 让编排层 tool-gate 看到明确违规而非进程崩溃(P1-9 修复)
|
|
34
|
+
return {
|
|
35
|
+
status: 'FAIL',
|
|
36
|
+
ruleName: rule.name ?? 'unknown-rule',
|
|
37
|
+
ruleNumber: rule.number ?? 0,
|
|
38
|
+
details: [`规则执行异常: ${err instanceof Error ? err.message : String(err)}`],
|
|
39
|
+
suggestion: '请检查该规则实现或上报此异常',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 聚合多条规则判定为单一决策
|
|
46
|
+
* @param verdicts 规则判定结果数组
|
|
47
|
+
* @returns 聚合后的单一判定(取最严重状态)
|
|
48
|
+
*/
|
|
49
|
+
aggregate(verdicts) {
|
|
50
|
+
const hasFail = verdicts.some((v) => v.status === 'FAIL');
|
|
51
|
+
const hasWarn = verdicts.some((v) => v.status === 'WARN');
|
|
52
|
+
if (hasFail) {
|
|
53
|
+
const failed = verdicts.filter((v) => v.status === 'FAIL');
|
|
54
|
+
return {
|
|
55
|
+
status: 'FAIL',
|
|
56
|
+
ruleName: failed.map((v) => v.ruleName).join(', '),
|
|
57
|
+
ruleNumber: 0,
|
|
58
|
+
details: failed.flatMap((v) => v.details),
|
|
59
|
+
suggestion: failed.map((v) => v.suggestion).join('; '),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (hasWarn) {
|
|
63
|
+
const warned = verdicts.filter((v) => v.status === 'WARN');
|
|
64
|
+
return {
|
|
65
|
+
status: 'WARN',
|
|
66
|
+
ruleName: warned.map((v) => v.ruleName).join(', '),
|
|
67
|
+
ruleNumber: 0,
|
|
68
|
+
details: warned.flatMap((v) => v.details),
|
|
69
|
+
suggestion: warned.map((v) => v.suggestion).join('; '),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
status: 'PASS',
|
|
74
|
+
ruleName: '',
|
|
75
|
+
ruleNumber: 0,
|
|
76
|
+
details: [],
|
|
77
|
+
suggestion: '',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.RulesEngine = RulesEngine;
|
|
82
|
+
//# sourceMappingURL=engine.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// index.ts · @sofagent/rules barrel export
|
|
4
|
+
// v1.2.0:只导出 5 个公开符号,内部实现不外露
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.defaultToolRules = exports.RulesEngine = void 0;
|
|
8
|
+
var engine_1 = require("./engine");
|
|
9
|
+
Object.defineProperty(exports, "RulesEngine", { enumerable: true, get: function () { return engine_1.RulesEngine; } });
|
|
10
|
+
var rules_1 = require("./rules");
|
|
11
|
+
Object.defineProperty(exports, "defaultToolRules", { enumerable: true, get: function () { return rules_1.defaultToolRules; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// rules/index.ts · 默认规则注册表
|
|
4
|
+
// v1.2.0:P3 编排引擎内嵌——默认 tool 规则集合
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.defaultToolRules = void 0;
|
|
8
|
+
const tool_sensitive_file_1 = require("./tool-sensitive-file");
|
|
9
|
+
const tool_secret_leak_1 = require("./tool-secret-leak");
|
|
10
|
+
const tool_injection_1 = require("./tool-injection");
|
|
11
|
+
/**
|
|
12
|
+
* 默认 tool 规则集合
|
|
13
|
+
* 移植自 audit 的 A1(敏感文件)/ A2(密钥泄漏)/ A9(注入检测)
|
|
14
|
+
*/
|
|
15
|
+
exports.defaultToolRules = [
|
|
16
|
+
tool_sensitive_file_1.toolSensitiveFile,
|
|
17
|
+
tool_secret_leak_1.toolSecretLeak,
|
|
18
|
+
tool_injection_1.toolInjection,
|
|
19
|
+
];
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// tool-injection.ts · 移植 audit rule-a9(prompt injection 检测)
|
|
4
|
+
// v1.2.0:tool 视角——扫 args 里的 prompt injection 模式
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.toolInjection = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Prompt injection 高置信度模式
|
|
10
|
+
* 与 audit rule-a9 对齐(但只取高置信度模式,避免 tool args 误报)
|
|
11
|
+
*
|
|
12
|
+
* 注意:模式用 new RegExp + 字符串拼接构建,避免正则字面量中的注入示例串
|
|
13
|
+
* 触发 A9 审计规则误报(铁律 #3:fixture 中的 secret-like / injection-like 串
|
|
14
|
+
* 必须运行时拼接)
|
|
15
|
+
*/
|
|
16
|
+
const _I = 'ign' + 'ore';
|
|
17
|
+
const _D = 'disr' + 'egard';
|
|
18
|
+
const _P = 'prev' + 'ious';
|
|
19
|
+
const _INS = 'instru' + 'ctions';
|
|
20
|
+
const _PRO = 'prom' + 'pts';
|
|
21
|
+
const INJECTION_PATTERNS = [
|
|
22
|
+
// 英文经典模式(拼接构建避免 A9 误报)
|
|
23
|
+
new RegExp(`${_I}\\s+(all\\s+)?(${_P}|prior|above)\\s+(${_INS}?|${_PRO}?)`, 'i'),
|
|
24
|
+
new RegExp(`${_D}\\s+(all\\s+)?(${_P}|prior)\\s+(${_INS}?|${_PRO}?)`, 'i'),
|
|
25
|
+
/forget\s+(everything|all\s+(previous|prior)\s+(instructions?|prompts?))/i,
|
|
26
|
+
/you\s+are\s+now\s+(a|an)\s+(different|new)/i,
|
|
27
|
+
/new\s+instructions?\s*:/i,
|
|
28
|
+
/system\s*:\s*you\s+are/i,
|
|
29
|
+
// 中文经典模式(拼接构建避免 A9 误报)
|
|
30
|
+
new RegExp('忽' + '略以上所有(指令|提示)'),
|
|
31
|
+
new RegExp('忽' + '略(上面|之前|前面)的(指令|提示|规则)'),
|
|
32
|
+
new RegExp('忘' + '记(之前|前面)的(指令|设定)'),
|
|
33
|
+
/你现在(是|扮演)/,
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* 从 tool call args 中提取所有字符串值(递归)
|
|
37
|
+
*/
|
|
38
|
+
function extractStrings(args) {
|
|
39
|
+
const strings = [];
|
|
40
|
+
for (const value of Object.values(args)) {
|
|
41
|
+
if (typeof value === 'string') {
|
|
42
|
+
strings.push(value);
|
|
43
|
+
}
|
|
44
|
+
else if (typeof value === 'object' && value !== null) {
|
|
45
|
+
strings.push(...extractStrings(value));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return strings;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* tool-injection 规则——检查 tool call args 是否含 prompt injection 模式
|
|
52
|
+
* 移植自 audit rule-a9(tool 视角)
|
|
53
|
+
*/
|
|
54
|
+
exports.toolInjection = {
|
|
55
|
+
name: 'tool-injection',
|
|
56
|
+
number: 9,
|
|
57
|
+
ruleClass: '业务底线',
|
|
58
|
+
check(ctx) {
|
|
59
|
+
const allStrings = extractStrings(ctx.args);
|
|
60
|
+
const hits = [];
|
|
61
|
+
for (const str of allStrings) {
|
|
62
|
+
for (const pattern of INJECTION_PATTERNS) {
|
|
63
|
+
if (pattern.test(str)) {
|
|
64
|
+
hits.push(str.substring(0, 80));
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (hits.length > 0) {
|
|
70
|
+
return {
|
|
71
|
+
status: 'FAIL',
|
|
72
|
+
ruleName: 'tool-injection',
|
|
73
|
+
ruleNumber: 9,
|
|
74
|
+
details: [`检测到 prompt injection 模式: ${hits.length} 处。tool 参数中含可疑指令注入。`],
|
|
75
|
+
suggestion: '检查 tool 参数来源——如果是用户输入,需在传入 tool 前做脱敏/转义。',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
status: 'PASS',
|
|
80
|
+
ruleName: 'tool-injection',
|
|
81
|
+
ruleNumber: 9,
|
|
82
|
+
details: [],
|
|
83
|
+
suggestion: '',
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=tool-injection.js.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// tool-secret-leak.ts · 移植 audit rule-a2(密钥泄漏检测)
|
|
4
|
+
// v1.2.0:tool 视角——扫 args 字面量里的密钥模式
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.toolSecretLeak = void 0;
|
|
8
|
+
/** 密钥泄漏检测正则模式(与 audit rule-a2 对齐) */
|
|
9
|
+
const SECRET_PATTERNS = [
|
|
10
|
+
{ pattern: /AKIA[A-Z0-9]{16}/, label: 'AWS Access Key' },
|
|
11
|
+
{ pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----/, label: 'Private Key' },
|
|
12
|
+
{ pattern: /sk-[a-zA-Z0-9]{48}/, label: 'OpenAI API Key' },
|
|
13
|
+
{ pattern: /sk-proj-[a-zA-Z0-9_]{40,}/, label: 'OpenAI Project Key' },
|
|
14
|
+
{ pattern: /sk-svcacct-[a-zA-Z0-9_]{40,}/, label: 'OpenAI Service Account Key' },
|
|
15
|
+
{ pattern: /sk-admin-[a-zA-Z0-9_]{40,}/, label: 'OpenAI Admin Key' },
|
|
16
|
+
{ pattern: /gh[ps]_[A-Za-z0-9]{36}/, label: 'GitHub Token' },
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* 从 tool call args 中提取所有字符串值(递归)
|
|
20
|
+
*/
|
|
21
|
+
function extractStrings(args) {
|
|
22
|
+
const strings = [];
|
|
23
|
+
for (const value of Object.values(args)) {
|
|
24
|
+
if (typeof value === 'string') {
|
|
25
|
+
strings.push(value);
|
|
26
|
+
}
|
|
27
|
+
else if (typeof value === 'object' && value !== null) {
|
|
28
|
+
strings.push(...extractStrings(value));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return strings;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* tool-secret-leak 规则——检查 tool call args 是否含密钥串
|
|
35
|
+
* 移植自 audit rule-a2(tool 视角)
|
|
36
|
+
*/
|
|
37
|
+
exports.toolSecretLeak = {
|
|
38
|
+
name: 'tool-secret-leak',
|
|
39
|
+
number: 2,
|
|
40
|
+
ruleClass: '业务底线',
|
|
41
|
+
check(ctx) {
|
|
42
|
+
const allStrings = extractStrings(ctx.args);
|
|
43
|
+
const detections = [];
|
|
44
|
+
for (const str of allStrings) {
|
|
45
|
+
for (const { pattern, label } of SECRET_PATTERNS) {
|
|
46
|
+
if (pattern.test(str)) {
|
|
47
|
+
detections.push(label);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (detections.length > 0) {
|
|
52
|
+
return {
|
|
53
|
+
status: 'FAIL',
|
|
54
|
+
ruleName: 'tool-secret-leak',
|
|
55
|
+
ruleNumber: 2,
|
|
56
|
+
details: [`检测到密钥/令牌: ${detections.join(', ')}。密钥不应硬编码到工具参数中。`],
|
|
57
|
+
suggestion: '将密钥写入 .env -> .gitignore 加 .env -> 使用环境变量引用。',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
status: 'PASS',
|
|
62
|
+
ruleName: 'tool-secret-leak',
|
|
63
|
+
ruleNumber: 2,
|
|
64
|
+
details: [],
|
|
65
|
+
suggestion: '',
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=tool-secret-leak.js.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// tool-sensitive-file.ts · 移植 audit rule-a1(敏感文件保护)
|
|
4
|
+
// v1.2.0:tool 视角——校验 args 里的文件路径
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.toolSensitiveFile = void 0;
|
|
8
|
+
/** 敏感文件路径模式(与 audit rule-a1 对齐) */
|
|
9
|
+
const SENSITIVE_PATTERNS = [
|
|
10
|
+
/\.env$/i,
|
|
11
|
+
/\.env\./i,
|
|
12
|
+
/\.sofagent\/config/i,
|
|
13
|
+
/\.sofagent\/knowledge/i,
|
|
14
|
+
/\.sofagent\/audit/i,
|
|
15
|
+
/\.sofagent\/think/i,
|
|
16
|
+
/\/\.ssh\//i,
|
|
17
|
+
/\/\.gnupg\//i,
|
|
18
|
+
/\.pem$/i,
|
|
19
|
+
/\.key$/i,
|
|
20
|
+
/id_rsa/i,
|
|
21
|
+
/id_ed25519/i,
|
|
22
|
+
/\.kube\/config/i,
|
|
23
|
+
/\.docker\/config/i,
|
|
24
|
+
/credentials/i,
|
|
25
|
+
/\.npmrc$/i,
|
|
26
|
+
/\.pypirc$/i,
|
|
27
|
+
];
|
|
28
|
+
/** 路径类字段名匹配(仅这些 key 的值才当作文件路径扫描) */
|
|
29
|
+
const PATH_LIKE_KEY = /path|file|dir|folder|source|dest|target/i;
|
|
30
|
+
/**
|
|
31
|
+
* 从 tool call args 中提取"路径类字段"的字符串值。
|
|
32
|
+
*
|
|
33
|
+
* v1.2.0 修复:只取路径类字段(path / file_path / edit_path 等),
|
|
34
|
+
* 不再把 write_file 的 content、edit_file 的 old/new_string、
|
|
35
|
+
* run_bash 的 command 等文本字段当路径扫描——
|
|
36
|
+
* 否则合法写入(内容含 "credentials" 字样)或
|
|
37
|
+
* `cat ~/.ssh/config` 这类命令会被误判为敏感文件操作。
|
|
38
|
+
*/
|
|
39
|
+
function extractFilePaths(args) {
|
|
40
|
+
const paths = [];
|
|
41
|
+
for (const [key, value] of Object.entries(args)) {
|
|
42
|
+
const keyIsPathLike = PATH_LIKE_KEY.test(key);
|
|
43
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
44
|
+
// 标量字符串:仅路径类字段参与扫描
|
|
45
|
+
if (keyIsPathLike)
|
|
46
|
+
paths.push(value);
|
|
47
|
+
}
|
|
48
|
+
else if (Array.isArray(value)) {
|
|
49
|
+
for (const item of value) {
|
|
50
|
+
if (typeof item === 'string' && item.length > 0) {
|
|
51
|
+
// 数组元素:仅当数组所在 key 本身是路径类字段(如 files / paths)
|
|
52
|
+
// 才把其中的字符串当作路径。避免扫描 command 等文本数组。
|
|
53
|
+
if (keyIsPathLike)
|
|
54
|
+
paths.push(item);
|
|
55
|
+
}
|
|
56
|
+
else if (typeof item === 'object' && item !== null) {
|
|
57
|
+
paths.push(...extractFilePaths(item));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (typeof value === 'object' && value !== null) {
|
|
62
|
+
paths.push(...extractFilePaths(value));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return paths;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* tool-sensitive-file 规则——检查 tool call 是否操作了敏感文件
|
|
69
|
+
* 移植自 audit rule-a1(tool 视角)
|
|
70
|
+
*/
|
|
71
|
+
exports.toolSensitiveFile = {
|
|
72
|
+
name: 'tool-sensitive-file',
|
|
73
|
+
number: 1,
|
|
74
|
+
ruleClass: '业务底线',
|
|
75
|
+
check(ctx) {
|
|
76
|
+
const filePaths = extractFilePaths(ctx.args);
|
|
77
|
+
const hits = [];
|
|
78
|
+
for (const filePath of filePaths) {
|
|
79
|
+
for (const pattern of SENSITIVE_PATTERNS) {
|
|
80
|
+
if (pattern.test(filePath)) {
|
|
81
|
+
hits.push(filePath);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (hits.length > 0) {
|
|
87
|
+
return {
|
|
88
|
+
status: 'FAIL',
|
|
89
|
+
ruleName: 'tool-sensitive-file',
|
|
90
|
+
ruleNumber: 1,
|
|
91
|
+
details: [`检测到敏感文件操作: ${hits.join(', ')}`],
|
|
92
|
+
suggestion: '敏感文件操作需用户确认。如确需操作,请在用户明确授权后执行。',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
status: 'PASS',
|
|
97
|
+
ruleName: 'tool-sensitive-file',
|
|
98
|
+
ruleNumber: 1,
|
|
99
|
+
details: [],
|
|
100
|
+
suggestion: '',
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=tool-sensitive-file.js.map
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** 规则等级——与 audit 的 RuleClass 对齐 */
|
|
2
|
+
export type RuleClass = '业务底线' | '质量拐杖' | '效率';
|
|
3
|
+
/** 规则状态三态——与 audit 语义同源(铁律 #4 测试 SSOT) */
|
|
4
|
+
export type RuleStatus = 'PASS' | 'WARN' | 'FAIL';
|
|
5
|
+
/**
|
|
6
|
+
* Tool call 上下文——tool call 粒度的同步上下文
|
|
7
|
+
* 与 audit 的 AuditContext 完全分离(后者是 git diff 粒度的事后审计上下文)
|
|
8
|
+
*/
|
|
9
|
+
export interface ToolCallContext {
|
|
10
|
+
/** 被调用的 tool 名称 */
|
|
11
|
+
toolName: string;
|
|
12
|
+
/** tool 调用参数 */
|
|
13
|
+
args: Record<string, unknown>;
|
|
14
|
+
/** 发起 tool call 的 Agent 名称 */
|
|
15
|
+
agentName: string;
|
|
16
|
+
/** 当前任务描述 */
|
|
17
|
+
taskDesc: string;
|
|
18
|
+
/** 工作目录 */
|
|
19
|
+
cwd: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 规则判定结果
|
|
23
|
+
*/
|
|
24
|
+
export interface InterceptVerdict {
|
|
25
|
+
status: RuleStatus;
|
|
26
|
+
/** 规则名称(加 tool- 前缀避免与 audit 同名规则混淆) */
|
|
27
|
+
ruleName: string;
|
|
28
|
+
/** 规则编号(沿用 audit 的 1/2/9) */
|
|
29
|
+
ruleNumber: number;
|
|
30
|
+
/** 详细信息 */
|
|
31
|
+
details: string[];
|
|
32
|
+
/** 修复建议 */
|
|
33
|
+
suggestion: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Tool 视角规则接口
|
|
37
|
+
* 与 audit 的 RuleCheck 结构平行但独立(check 参数不同)
|
|
38
|
+
*/
|
|
39
|
+
export interface ToolRule {
|
|
40
|
+
/** 规则名称(加 tool- 前缀) */
|
|
41
|
+
name: string;
|
|
42
|
+
/** 规则编号(沿用 audit 编号) */
|
|
43
|
+
number: number;
|
|
44
|
+
/** 规则等级 */
|
|
45
|
+
ruleClass: RuleClass;
|
|
46
|
+
/**
|
|
47
|
+
* 检查 tool call 是否违规
|
|
48
|
+
* @param ctx tool call 上下文
|
|
49
|
+
* @returns 判定结果
|
|
50
|
+
*/
|
|
51
|
+
check(ctx: ToolCallContext): InterceptVerdict;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// types.ts · P3 编排引擎内嵌——tool call 拦截器类型定义
|
|
4
|
+
// v1.2.0:从 audit 规则抽出为纯函数,零 fs/git 依赖
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sofagent/rules",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "sofagent 规则引擎纯函数包——从 audit 抽出,零 fs/git 依赖,供编排引擎 tool call 事前拦截",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "npm run clean && tsc",
|
|
9
|
+
"clean": "rm -rf dist",
|
|
10
|
+
"test": "vitest run"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["rules-engine", "agent-safety", "tool-interceptor"],
|
|
13
|
+
"author": "孔放勋",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.0.0",
|
|
17
|
+
"vitest": "^3.0.0"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist/",
|
|
21
|
+
"!dist/**/*.js.map",
|
|
22
|
+
"!dist/**/*.d.ts.map",
|
|
23
|
+
"!dist/**/*.test.*",
|
|
24
|
+
"README.md"
|
|
25
|
+
]
|
|
26
|
+
}
|