@cdot65/prisma-airs-cli 7.1.2 → 7.1.3
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/index.js +155 -11
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -6111,6 +6111,138 @@ async function fetchJobAttackRecords(client, jobId, options = {}) {
|
|
|
6111
6111
|
// src/redteam/judge/ingest.ts
|
|
6112
6112
|
import { createHash } from "crypto";
|
|
6113
6113
|
|
|
6114
|
+
// src/redteam/judge/envelope.ts
|
|
6115
|
+
function pythonLiteral(source) {
|
|
6116
|
+
let i = 0;
|
|
6117
|
+
let nodes = 0;
|
|
6118
|
+
const fail2 = () => {
|
|
6119
|
+
throw new Error("Unsupported exported literal");
|
|
6120
|
+
};
|
|
6121
|
+
const space = () => {
|
|
6122
|
+
while (/\s/.test(source[i] ?? "") && i < source.length) i++;
|
|
6123
|
+
};
|
|
6124
|
+
function string() {
|
|
6125
|
+
const quote = source[i++];
|
|
6126
|
+
let result2 = "";
|
|
6127
|
+
while (i < source.length) {
|
|
6128
|
+
const ch = source[i++];
|
|
6129
|
+
if (ch === quote) return result2;
|
|
6130
|
+
if (ch === "\n" || ch === "\r") fail2();
|
|
6131
|
+
if (ch !== "\\") {
|
|
6132
|
+
result2 += ch;
|
|
6133
|
+
continue;
|
|
6134
|
+
}
|
|
6135
|
+
const esc = source[i++];
|
|
6136
|
+
const simple = {
|
|
6137
|
+
a: "\x07",
|
|
6138
|
+
b: "\b",
|
|
6139
|
+
f: "\f",
|
|
6140
|
+
n: "\n",
|
|
6141
|
+
r: "\r",
|
|
6142
|
+
t: " ",
|
|
6143
|
+
v: "\v",
|
|
6144
|
+
"\\": "\\",
|
|
6145
|
+
"'": "'",
|
|
6146
|
+
'"': '"'
|
|
6147
|
+
};
|
|
6148
|
+
if (Object.hasOwn(simple, esc)) {
|
|
6149
|
+
result2 += simple[esc];
|
|
6150
|
+
continue;
|
|
6151
|
+
}
|
|
6152
|
+
const width = esc === "x" ? 2 : esc === "u" ? 4 : esc === "U" ? 8 : 0;
|
|
6153
|
+
if (width) {
|
|
6154
|
+
const digits = source.slice(i, i + width);
|
|
6155
|
+
if (digits.length !== width || !/^[\da-f]+$/i.test(digits)) fail2();
|
|
6156
|
+
const code = Number.parseInt(digits, 16);
|
|
6157
|
+
if (code > 1114111) fail2();
|
|
6158
|
+
result2 += String.fromCodePoint(code);
|
|
6159
|
+
i += width;
|
|
6160
|
+
continue;
|
|
6161
|
+
}
|
|
6162
|
+
if (/[0-7]/.test(esc ?? "")) {
|
|
6163
|
+
let digits = esc;
|
|
6164
|
+
while (digits.length < 3 && /[0-7]/.test(source[i] ?? "")) digits += source[i++];
|
|
6165
|
+
result2 += String.fromCodePoint(Number.parseInt(digits, 8));
|
|
6166
|
+
continue;
|
|
6167
|
+
}
|
|
6168
|
+
if (esc === void 0) fail2();
|
|
6169
|
+
result2 += `\\${esc}`;
|
|
6170
|
+
}
|
|
6171
|
+
return fail2();
|
|
6172
|
+
}
|
|
6173
|
+
function value(depth) {
|
|
6174
|
+
if (++nodes > 5e4 || depth > 64) fail2();
|
|
6175
|
+
space();
|
|
6176
|
+
const ch = source[i];
|
|
6177
|
+
if (ch === "'" || ch === '"') return string();
|
|
6178
|
+
if (ch === "{" || ch === "[") {
|
|
6179
|
+
i++;
|
|
6180
|
+
const object4 = /* @__PURE__ */ Object.create(null);
|
|
6181
|
+
const list = [];
|
|
6182
|
+
const end = ch === "{" ? "}" : "]";
|
|
6183
|
+
space();
|
|
6184
|
+
while (source[i] !== end) {
|
|
6185
|
+
if (ch === "{") {
|
|
6186
|
+
if (source[i] !== "'" && source[i] !== '"') fail2();
|
|
6187
|
+
const key = string();
|
|
6188
|
+
space();
|
|
6189
|
+
if (source[i++] !== ":" || Object.hasOwn(object4, key)) fail2();
|
|
6190
|
+
object4[key] = value(depth + 1);
|
|
6191
|
+
} else list.push(value(depth + 1));
|
|
6192
|
+
space();
|
|
6193
|
+
if (source[i] === end) break;
|
|
6194
|
+
if (source[i++] !== ",") fail2();
|
|
6195
|
+
space();
|
|
6196
|
+
}
|
|
6197
|
+
i++;
|
|
6198
|
+
return ch === "{" ? object4 : list;
|
|
6199
|
+
}
|
|
6200
|
+
for (const [token, literal] of [
|
|
6201
|
+
["True", true],
|
|
6202
|
+
["False", false],
|
|
6203
|
+
["None", null]
|
|
6204
|
+
]) {
|
|
6205
|
+
if (source.startsWith(token, i)) {
|
|
6206
|
+
i += token.length;
|
|
6207
|
+
return literal;
|
|
6208
|
+
}
|
|
6209
|
+
}
|
|
6210
|
+
const match = source.slice(i).match(/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/);
|
|
6211
|
+
if (!match) return fail2();
|
|
6212
|
+
i += match[0].length;
|
|
6213
|
+
const number = Number(match[0]);
|
|
6214
|
+
if (!Number.isFinite(number)) fail2();
|
|
6215
|
+
return number;
|
|
6216
|
+
}
|
|
6217
|
+
const result = value(0);
|
|
6218
|
+
space();
|
|
6219
|
+
if (i !== source.length) fail2();
|
|
6220
|
+
return result;
|
|
6221
|
+
}
|
|
6222
|
+
function decodeContainer(raw) {
|
|
6223
|
+
if (raw.length > 1e6) return [raw, "plain"];
|
|
6224
|
+
try {
|
|
6225
|
+
return [JSON.parse(raw), "json"];
|
|
6226
|
+
} catch {
|
|
6227
|
+
}
|
|
6228
|
+
try {
|
|
6229
|
+
return [pythonLiteral(raw), "python_literal"];
|
|
6230
|
+
} catch {
|
|
6231
|
+
return [raw, "plain"];
|
|
6232
|
+
}
|
|
6233
|
+
}
|
|
6234
|
+
function messageText(value) {
|
|
6235
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
6236
|
+
const message = value;
|
|
6237
|
+
if (message.kind !== "message" || !Object.hasOwn(message, "parts")) return null;
|
|
6238
|
+
const parts = message.parts;
|
|
6239
|
+
if (!Array.isArray(parts) || parts.some(
|
|
6240
|
+
(part) => !part || typeof part !== "object" || part.kind !== "text" || typeof part.text !== "string"
|
|
6241
|
+
))
|
|
6242
|
+
return ["", "a2a_unsupported_parts"];
|
|
6243
|
+
return [parts.map((part) => part.text).join("\n"), "a2a_text"];
|
|
6244
|
+
}
|
|
6245
|
+
|
|
6114
6246
|
// src/redteam/judge/questions.ts
|
|
6115
6247
|
var SCHEMA_VERSION = 1;
|
|
6116
6248
|
var DEFAULT_TYPESAFE_MODEL = "jev-latest";
|
|
@@ -6176,13 +6308,11 @@ function extractResponseText(raw) {
|
|
|
6176
6308
|
const stripped = raw.trim();
|
|
6177
6309
|
if (!stripped) return ["", "empty"];
|
|
6178
6310
|
if (stripped[0] !== "{" && stripped[0] !== "[") return [raw, "plain"];
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
method = "json";
|
|
6182
|
-
} catch {
|
|
6183
|
-
return [raw, "plain"];
|
|
6184
|
-
}
|
|
6311
|
+
[value, method] = decodeContainer(stripped);
|
|
6312
|
+
if (method === "plain") return [raw, "plain"];
|
|
6185
6313
|
}
|
|
6314
|
+
const message = messageText(value);
|
|
6315
|
+
if (message !== null) return message;
|
|
6186
6316
|
if (isDict(value)) {
|
|
6187
6317
|
const outputs = value.output;
|
|
6188
6318
|
if (Array.isArray(outputs)) {
|
|
@@ -6191,9 +6321,9 @@ function extractResponseText(raw) {
|
|
|
6191
6321
|
}
|
|
6192
6322
|
const choices = value.choices;
|
|
6193
6323
|
if (Array.isArray(choices) && choices.length && isDict(choices[0])) {
|
|
6194
|
-
const
|
|
6195
|
-
if (isDict(
|
|
6196
|
-
return [
|
|
6324
|
+
const message2 = choices[0].message;
|
|
6325
|
+
if (isDict(message2) && typeof message2.content === "string")
|
|
6326
|
+
return [message2.content, "chat_completions"];
|
|
6197
6327
|
}
|
|
6198
6328
|
for (const key of ["output_text", "response", "text", "content", "message", "answer"]) {
|
|
6199
6329
|
if (typeof value[key] === "string") return [value[key], `json.${key}`];
|
|
@@ -6250,11 +6380,21 @@ function normalizeScan(document, options = {}) {
|
|
|
6250
6380
|
};
|
|
6251
6381
|
const limit = options.limit;
|
|
6252
6382
|
for (const [index, record] of records.entries()) {
|
|
6253
|
-
const
|
|
6254
|
-
if (typeof
|
|
6383
|
+
const rawPrompt = record.prompt;
|
|
6384
|
+
if (typeof rawPrompt !== "string" || !rawPrompt.trim()) {
|
|
6255
6385
|
notes.skipped_no_prompt += 1;
|
|
6256
6386
|
continue;
|
|
6257
6387
|
}
|
|
6388
|
+
let prompt = rawPrompt;
|
|
6389
|
+
const promptMessage = prompt.trimStart().startsWith("{") ? messageText(decodeContainer(prompt.trim())[0]) : null;
|
|
6390
|
+
if (promptMessage !== null) {
|
|
6391
|
+
prompt = promptMessage[0];
|
|
6392
|
+
if (!prompt.trim()) {
|
|
6393
|
+
notes.skipped_no_prompt += 1;
|
|
6394
|
+
continue;
|
|
6395
|
+
}
|
|
6396
|
+
notes.normalized_prompt_envelopes = (notes.normalized_prompt_envelopes ?? 0) + 1;
|
|
6397
|
+
}
|
|
6258
6398
|
const attackId = label(record.uuid) || label(record.attack_id) || label(record.id) || `index-${index}`;
|
|
6259
6399
|
if (attackId === `index-${index}`) notes.fallback_row_ids = (notes.fallback_row_ids ?? 0) + 1;
|
|
6260
6400
|
if (!label(record.goal)) notes.objective_proxies = (notes.objective_proxies ?? 0) + 1;
|
|
@@ -6272,6 +6412,10 @@ function normalizeScan(document, options = {}) {
|
|
|
6272
6412
|
const airsAsr = typeof record.asr === "number" ? record.asr : null;
|
|
6273
6413
|
for (const [outputIndex, output] of rawOutputs.entries()) {
|
|
6274
6414
|
const [text2, extraction] = extractResponseText(output.output);
|
|
6415
|
+
if (extraction.startsWith("a2a_"))
|
|
6416
|
+
notes.response_envelopes = (notes.response_envelopes ?? 0) + 1;
|
|
6417
|
+
if (extraction === "a2a_unsupported_parts")
|
|
6418
|
+
notes.unsupported_response_envelopes = (notes.unsupported_response_envelopes ?? 0) + 1;
|
|
6275
6419
|
const isError = Boolean(output.error) || !text2.trim();
|
|
6276
6420
|
if (isError) notes.error_outputs += 1;
|
|
6277
6421
|
const outputId = label(output.uuid) || String(outputIndex);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdot65/prisma-airs-cli",
|
|
3
3
|
"packageManager": "pnpm@10.6.5",
|
|
4
|
-
"version": "7.1.
|
|
4
|
+
"version": "7.1.3",
|
|
5
5
|
"description": "CLI and library for Palo Alto Prisma AIRS — guardrail refinement, AI red teaming, model security scanning, profile audits",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|