-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
89 lines (76 loc) · 2.83 KB
/
index.js
File metadata and controls
89 lines (76 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
const core = require('@actions/core');
const { Guard } = require('@ny-squared/guard');
async function run() {
try {
// Get inputs
const prompt = core.getInput('prompt', { required: true });
const threshold = parseFloat(core.getInput('threshold') || '0.7');
const failOnBlock = core.getInput('fail_on_block') !== 'false';
const apiKey = core.getInput('api_key');
// Validate threshold
if (isNaN(threshold) || threshold < 0 || threshold > 1) {
throw new Error(`Invalid threshold: "${core.getInput('threshold')}". Must be between 0.0 and 1.0`);
}
// Initialize Guard
const config = {};
if (apiKey) {
config.apiKey = apiKey;
}
const guard = new Guard(config);
// Scan the prompt
core.info(`Scanning prompt (${prompt.length} chars) with threshold ${threshold}...`);
const result = await guard.scan(prompt);
// Calculate risk score (highest threat confidence)
const riskScore = result.threats && result.threats.length > 0
? Math.max(...result.threats.map(t => t.confidence))
: 0;
// Determine risk type
let riskType = 'none';
if (result.threats && result.threats.length > 0) {
// Pick the type of the highest-confidence threat
const topThreat = result.threats.reduce((max, t) =>
t.confidence > max.confidence ? t : max
, result.threats[0]);
riskType = topThreat.type || 'unknown';
}
// Determine if blocked
const blocked = riskScore >= threshold;
// Set outputs
core.setOutput('risk_score', riskScore.toFixed(2));
core.setOutput('blocked', blocked.toString());
core.setOutput('risk_type', riskType);
core.setOutput('details', JSON.stringify({
risk_score: riskScore,
blocked,
risk_type: riskType,
threats: result.threats || [],
is_safe: result.isSafe,
latency_ms: result.latencyMs,
threshold,
prompt_length: prompt.length,
}));
// Log results
core.info(`Risk score: ${riskScore.toFixed(2)}`);
core.info(`Risk type: ${riskType}`);
core.info(`Blocked: ${blocked}`);
core.info(`Threats found: ${(result.threats || []).length}`);
core.info(`Scan latency: ${result.latencyMs}ms`);
if (result.threats && result.threats.length > 0) {
core.warning('Threats detected:');
for (const threat of result.threats) {
core.warning(` - [${threat.type}] confidence: ${threat.confidence} | ${threat.detail}`);
}
}
// Fail if blocked and fail_on_block is true
if (blocked && failOnBlock) {
core.setFailed(
`Prompt blocked: risk score ${riskScore.toFixed(2)} exceeds threshold ${threshold}. ` +
`Risk type: ${riskType}. ` +
`Use fail_on_block: 'false' to prevent workflow failure.`
);
}
} catch (error) {
core.setFailed(`Guard Action failed: ${error.message}`);
}
}
run();