@silmaril-security/sdk 0.7.7 → 0.7.8
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/CHANGELOG.md +9 -1
- package/README.md +52 -3
- package/dist/adapters/deepagents.cjs +19 -0
- package/dist/adapters/deepagents.cjs.map +1 -1
- package/dist/adapters/deepagents.d.cts +1 -1
- package/dist/adapters/deepagents.d.ts +1 -1
- package/dist/adapters/deepagents.js +19 -0
- package/dist/adapters/deepagents.js.map +1 -1
- package/dist/adapters/langchain.cjs +19 -0
- package/dist/adapters/langchain.cjs.map +1 -1
- package/dist/adapters/langchain.d.cts +1 -1
- package/dist/adapters/langchain.d.ts +1 -1
- package/dist/adapters/langchain.js +19 -0
- package/dist/adapters/langchain.js.map +1 -1
- package/dist/adapters/vercel.cjs.map +1 -1
- package/dist/adapters/vercel.d.cts +1 -1
- package/dist/adapters/vercel.d.ts +1 -1
- package/dist/adapters/vercel.js.map +1 -1
- package/dist/{firewall-CueYday8.d.cts → firewall-DqjD6aXD.d.cts} +11 -1
- package/dist/{firewall-CueYday8.d.ts → firewall-DqjD6aXD.d.ts} +11 -1
- package/dist/index.cjs +81 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +80 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,19 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
|
|
38
38
|
// src/exceptions.ts
|
|
39
|
+
function isReviewCompatibilityError(error) {
|
|
40
|
+
if (typeof error !== "object" && typeof error !== "function" || error === null) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
return Object.getOwnPropertyDescriptor(
|
|
45
|
+
error,
|
|
46
|
+
REVIEW_COMPATIBILITY_ERROR_BRAND
|
|
47
|
+
)?.value === true;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
39
52
|
function parseErrorBody(body) {
|
|
40
53
|
try {
|
|
41
54
|
const parsed = JSON.parse(body);
|
|
@@ -52,7 +65,7 @@ function parseErrorBody(body) {
|
|
|
52
65
|
return { details: void 0, error: void 0, apiMessage: void 0 };
|
|
53
66
|
}
|
|
54
67
|
}
|
|
55
|
-
var MAX_PROMPT_DISPLAY_LEN, FirewallBlockedException, PromptBlockedException, SilmarilApiError;
|
|
68
|
+
var MAX_PROMPT_DISPLAY_LEN, FirewallBlockedException, PromptBlockedException, REVIEW_COMPATIBILITY_ERROR_BRAND, ReviewCompatibilityError, SilmarilApiError;
|
|
56
69
|
var init_exceptions = __esm({
|
|
57
70
|
"src/exceptions.ts"() {
|
|
58
71
|
"use strict";
|
|
@@ -88,6 +101,27 @@ var init_exceptions = __esm({
|
|
|
88
101
|
}
|
|
89
102
|
};
|
|
90
103
|
PromptBlockedException = FirewallBlockedException;
|
|
104
|
+
REVIEW_COMPATIBILITY_ERROR_BRAND = /* @__PURE__ */ Symbol.for(
|
|
105
|
+
"@silmaril-security/sdk/ReviewCompatibilityError"
|
|
106
|
+
);
|
|
107
|
+
ReviewCompatibilityError = class _ReviewCompatibilityError extends Error {
|
|
108
|
+
requestedReview;
|
|
109
|
+
acknowledgedReview;
|
|
110
|
+
constructor(requestedReview, acknowledgedReview) {
|
|
111
|
+
const detail = acknowledgedReview === void 0 ? "the response omitted its acknowledgement" : "the response acknowledgement did not match";
|
|
112
|
+
super(`Silmaril review compatibility error: ${detail} for requested ${requestedReview} review`);
|
|
113
|
+
this.name = "ReviewCompatibilityError";
|
|
114
|
+
this.requestedReview = requestedReview;
|
|
115
|
+
this.acknowledgedReview = acknowledgedReview;
|
|
116
|
+
Object.defineProperty(this, REVIEW_COMPATIBILITY_ERROR_BRAND, {
|
|
117
|
+
value: true,
|
|
118
|
+
enumerable: false,
|
|
119
|
+
configurable: false,
|
|
120
|
+
writable: false
|
|
121
|
+
});
|
|
122
|
+
Object.setPrototypeOf(this, _ReviewCompatibilityError.prototype);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
91
125
|
SilmarilApiError = class _SilmarilApiError extends Error {
|
|
92
126
|
status;
|
|
93
127
|
statusText;
|
|
@@ -304,6 +338,9 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
304
338
|
...toolName !== void 0 ? { toolName } : {}
|
|
305
339
|
});
|
|
306
340
|
} catch (err) {
|
|
341
|
+
if (isReviewCompatibilityError(err)) {
|
|
342
|
+
throw err;
|
|
343
|
+
}
|
|
307
344
|
if (!failOpen) {
|
|
308
345
|
throw err;
|
|
309
346
|
}
|
|
@@ -458,6 +495,7 @@ __export(src_exports, {
|
|
|
458
495
|
Outcome: () => Outcome,
|
|
459
496
|
PRIMARY_OUTCOMES: () => PRIMARY_OUTCOMES,
|
|
460
497
|
PromptBlockedException: () => PromptBlockedException,
|
|
498
|
+
ReviewCompatibilityError: () => ReviewCompatibilityError,
|
|
461
499
|
SilmarilApiError: () => SilmarilApiError,
|
|
462
500
|
isHarmfulOutcome: () => isHarmfulOutcome,
|
|
463
501
|
isPrimaryOutcome: () => isPrimaryOutcome,
|
|
@@ -818,12 +856,32 @@ function sanitizeText(text) {
|
|
|
818
856
|
}
|
|
819
857
|
|
|
820
858
|
// src/firewall.ts
|
|
821
|
-
var SDK_VERSION = "0.7.
|
|
859
|
+
var SDK_VERSION = "0.7.8";
|
|
822
860
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
823
861
|
var DEFAULT_MAX_RETRIES = 5;
|
|
824
862
|
var MAX_BACKOFF_SECONDS = 30;
|
|
825
863
|
var MAX_ERROR_BODY_BYTES = 1 << 16;
|
|
826
864
|
var MAX_TIMEOUT_MS = 2147483647;
|
|
865
|
+
function validateReview(value, name) {
|
|
866
|
+
if (value === void 0) {
|
|
867
|
+
return void 0;
|
|
868
|
+
}
|
|
869
|
+
if (value !== "standard" && value !== "deep") {
|
|
870
|
+
throw new Error(`Firewall: ${name} must be standard or deep`);
|
|
871
|
+
}
|
|
872
|
+
return value;
|
|
873
|
+
}
|
|
874
|
+
function resolveReview(perCallReview, clientReview) {
|
|
875
|
+
return perCallReview === void 0 ? clientReview : validateReview(perCallReview, "review");
|
|
876
|
+
}
|
|
877
|
+
function verifyReviewAcknowledgement(acknowledgedReview, requestedReview) {
|
|
878
|
+
if (requestedReview !== void 0 && acknowledgedReview !== requestedReview) {
|
|
879
|
+
throw new ReviewCompatibilityError(requestedReview, acknowledgedReview);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
function reviewAcknowledgementFromResponse(response) {
|
|
883
|
+
return isRecord2(response) ? response.review : void 0;
|
|
884
|
+
}
|
|
827
885
|
function resolveMode(value, requestedMode) {
|
|
828
886
|
let responseMode;
|
|
829
887
|
if (value === "shadow" || value === "warn" || value === "block") {
|
|
@@ -836,7 +894,7 @@ function resolveMode(value, requestedMode) {
|
|
|
836
894
|
function legacyMode(shadowMode) {
|
|
837
895
|
return shadowMode === void 0 ? void 0 : shadowMode ? "shadow" : "block";
|
|
838
896
|
}
|
|
839
|
-
function blockResultFromResponse(data, requestedMode) {
|
|
897
|
+
function blockResultFromResponse(data, requestedMode, requestedReview) {
|
|
840
898
|
if (data.prediction !== "BENIGN" && data.prediction !== "MALICIOUS") {
|
|
841
899
|
throw new Error("Firewall: response prediction must be BENIGN or MALICIOUS");
|
|
842
900
|
}
|
|
@@ -845,6 +903,9 @@ function blockResultFromResponse(data, requestedMode) {
|
|
|
845
903
|
score: Number(data.score),
|
|
846
904
|
threshold: Number(data.threshold)
|
|
847
905
|
};
|
|
906
|
+
if (requestedReview !== void 0) {
|
|
907
|
+
result.review = requestedReview;
|
|
908
|
+
}
|
|
848
909
|
const mode = resolveMode(data.mode, requestedMode);
|
|
849
910
|
if (mode !== void 0) {
|
|
850
911
|
result.mode = mode;
|
|
@@ -1119,6 +1180,7 @@ var Firewall = class {
|
|
|
1119
1180
|
timeoutMs;
|
|
1120
1181
|
shadowMode;
|
|
1121
1182
|
mode;
|
|
1183
|
+
review;
|
|
1122
1184
|
headers;
|
|
1123
1185
|
constructor(options) {
|
|
1124
1186
|
if (!options.apiKey) {
|
|
@@ -1139,6 +1201,7 @@ var Firewall = class {
|
|
|
1139
1201
|
);
|
|
1140
1202
|
}
|
|
1141
1203
|
this.mode = options.mode ?? legacyMode(options.shadowMode);
|
|
1204
|
+
this.review = validateReview(options.review, "review");
|
|
1142
1205
|
this.shadowMode = this.mode === "shadow";
|
|
1143
1206
|
this.headers = Object.freeze({
|
|
1144
1207
|
"x-api-key": this.apiKey,
|
|
@@ -1178,9 +1241,13 @@ var Firewall = class {
|
|
|
1178
1241
|
texts: texts.map((text) => sanitizeText(text))
|
|
1179
1242
|
};
|
|
1180
1243
|
const requestedMode = options.mode ?? this.mode;
|
|
1244
|
+
const requestedReview = resolveReview(options.review, this.review);
|
|
1181
1245
|
if (requestedMode !== void 0) {
|
|
1182
1246
|
payload.mode = requestedMode;
|
|
1183
1247
|
}
|
|
1248
|
+
if (requestedReview !== void 0) {
|
|
1249
|
+
payload.review = requestedReview;
|
|
1250
|
+
}
|
|
1184
1251
|
if (options.hooks && options.hooks.length > 0) {
|
|
1185
1252
|
payload.hooks = options.hooks.map((h) => String(h));
|
|
1186
1253
|
}
|
|
@@ -1200,6 +1267,7 @@ var Firewall = class {
|
|
|
1200
1267
|
);
|
|
1201
1268
|
}
|
|
1202
1269
|
const data = await this.postWithRetry(payload, options.signal);
|
|
1270
|
+
verifyReviewAcknowledgement(reviewAcknowledgementFromResponse(data), requestedReview);
|
|
1203
1271
|
if (!Array.isArray(data.predictions)) {
|
|
1204
1272
|
throw new Error("Firewall: response predictions must be an array");
|
|
1205
1273
|
}
|
|
@@ -1208,7 +1276,9 @@ var Firewall = class {
|
|
|
1208
1276
|
`Firewall: response predictions length ${data.predictions.length} does not match submitted texts length ${payload.texts.length}`
|
|
1209
1277
|
);
|
|
1210
1278
|
}
|
|
1211
|
-
return data.predictions.map(
|
|
1279
|
+
return data.predictions.map(
|
|
1280
|
+
(p) => blockResultFromResponse(p, requestedMode, requestedReview)
|
|
1281
|
+
);
|
|
1212
1282
|
}
|
|
1213
1283
|
asLangChainHandler(options = {}) {
|
|
1214
1284
|
return Promise.resolve().then(() => (init_langchain(), langchain_exports)).then(
|
|
@@ -1258,9 +1328,13 @@ var Firewall = class {
|
|
|
1258
1328
|
async classifySingle(text, options, metadataInfo) {
|
|
1259
1329
|
const payload = { text };
|
|
1260
1330
|
const requestedMode = options.mode ?? this.mode;
|
|
1331
|
+
const requestedReview = resolveReview(options.review, this.review);
|
|
1261
1332
|
if (requestedMode !== void 0) {
|
|
1262
1333
|
payload.mode = requestedMode;
|
|
1263
1334
|
}
|
|
1335
|
+
if (requestedReview !== void 0) {
|
|
1336
|
+
payload.review = requestedReview;
|
|
1337
|
+
}
|
|
1264
1338
|
if (options.hook !== void 0) {
|
|
1265
1339
|
payload.hook = options.hook;
|
|
1266
1340
|
}
|
|
@@ -1275,7 +1349,8 @@ var Firewall = class {
|
|
|
1275
1349
|
...options.governance === void 0 ? {} : { governance: options.governance }
|
|
1276
1350
|
});
|
|
1277
1351
|
const data = await this.postWithRetry(payload, options.signal);
|
|
1278
|
-
|
|
1352
|
+
verifyReviewAcknowledgement(reviewAcknowledgementFromResponse(data), requestedReview);
|
|
1353
|
+
return blockResultFromResponse(data, requestedMode, requestedReview);
|
|
1279
1354
|
}
|
|
1280
1355
|
};
|
|
1281
1356
|
|
|
@@ -1299,6 +1374,7 @@ init_hooks();
|
|
|
1299
1374
|
Outcome,
|
|
1300
1375
|
PRIMARY_OUTCOMES,
|
|
1301
1376
|
PromptBlockedException,
|
|
1377
|
+
ReviewCompatibilityError,
|
|
1302
1378
|
SilmarilApiError,
|
|
1303
1379
|
isHarmfulOutcome,
|
|
1304
1380
|
isPrimaryOutcome,
|