agentid-sdk 0.1.40 → 0.1.42
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 +83 -2
- package/dist/{agentid-BWlN5KCq.d.mts → agentid-DbTWrLnN.d.mts} +30 -0
- package/dist/{agentid-BWlN5KCq.d.ts → agentid-DbTWrLnN.d.ts} +30 -0
- package/dist/{chunk-25SZBEYX.mjs → chunk-C5U4L4JY.mjs} +706 -537
- package/dist/index.d.mts +27 -3
- package/dist/index.d.ts +27 -3
- package/dist/index.js +738 -541
- package/dist/index.mjs +32 -5
- package/dist/langchain.d.mts +8 -1
- package/dist/langchain.d.ts +8 -1
- package/dist/langchain.js +301 -71
- package/dist/langchain.mjs +129 -44
- package/dist/transparency-badge.d.mts +1 -1
- package/dist/transparency-badge.d.ts +1 -1
- package/package.json +2 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// src/adapters.ts
|
|
2
|
+
var MAX_GUARD_ATTACHMENTS = 4;
|
|
3
|
+
var MAX_PROMPT_CONTEXT_CHARS = 64e3;
|
|
2
4
|
function getLastUserMessage(req) {
|
|
3
5
|
const messages = req?.messages;
|
|
4
6
|
if (!Array.isArray(messages)) return null;
|
|
@@ -78,31 +80,79 @@ function normalizeImageAttachment(part) {
|
|
|
78
80
|
content_base64: imageUrl
|
|
79
81
|
};
|
|
80
82
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
function truncatePromptContext(value) {
|
|
84
|
+
if (value.length <= MAX_PROMPT_CONTEXT_CHARS) {
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
const headChars = Math.floor((MAX_PROMPT_CONTEXT_CHARS - 32) / 2);
|
|
88
|
+
const tailChars = MAX_PROMPT_CONTEXT_CHARS - headChars - 32;
|
|
89
|
+
return `${value.slice(0, headChars)}
|
|
90
|
+
[...TRUNCATED CONTEXT...]
|
|
91
|
+
${value.slice(-tailChars)}`;
|
|
92
|
+
}
|
|
93
|
+
function formatPromptContextRole(role) {
|
|
94
|
+
return typeof role === "string" && role.trim().length > 0 ? role.trim() : "message";
|
|
95
|
+
}
|
|
96
|
+
function extractTextParts(content) {
|
|
97
|
+
if (typeof content === "string" && content.length > 0) {
|
|
98
|
+
return [content];
|
|
99
|
+
}
|
|
100
|
+
if (!Array.isArray(content)) {
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
const parts = [];
|
|
104
|
+
for (const part of content) {
|
|
105
|
+
if (!part || typeof part !== "object") {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (typeof part.text === "string") {
|
|
109
|
+
const text = part.text;
|
|
110
|
+
if (text.length > 0) {
|
|
111
|
+
parts.push(text);
|
|
93
112
|
}
|
|
94
|
-
return parts.length ? parts.join("") : null;
|
|
95
113
|
}
|
|
96
|
-
return null;
|
|
97
114
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
115
|
+
return parts;
|
|
116
|
+
}
|
|
117
|
+
function extractAttachmentPlaceholders(content) {
|
|
118
|
+
if (!Array.isArray(content)) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
const placeholders = [];
|
|
122
|
+
for (const part of content) {
|
|
123
|
+
if (!part || typeof part !== "object") {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const typedPart = part;
|
|
127
|
+
if (typedPart.type === "file") {
|
|
128
|
+
placeholders.push(
|
|
129
|
+
`[attachment:${normalizeFilename(typedPart.file?.filename, "attachment.bin")}]`
|
|
130
|
+
);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (typedPart.type === "image_url") {
|
|
134
|
+
const imageUrl = typedPart.image_url?.url;
|
|
135
|
+
placeholders.push(
|
|
136
|
+
imageUrl?.startsWith("data:") ? "[attachment:image]" : "[attachment:image_url]"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return placeholders;
|
|
141
|
+
}
|
|
142
|
+
function collectUserAttachments(req) {
|
|
143
|
+
const messages = req?.messages;
|
|
144
|
+
if (!Array.isArray(messages)) {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
const attachments = [];
|
|
148
|
+
for (const message of messages) {
|
|
149
|
+
if (!message || typeof message !== "object" || message.role !== "user") {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const content = message.content;
|
|
102
153
|
if (!Array.isArray(content)) {
|
|
103
|
-
|
|
154
|
+
continue;
|
|
104
155
|
}
|
|
105
|
-
const attachments = [];
|
|
106
156
|
for (const part of content) {
|
|
107
157
|
if (!part || typeof part !== "object") {
|
|
108
158
|
continue;
|
|
@@ -121,7 +171,57 @@ var OpenAIAdapter = class {
|
|
|
121
171
|
}
|
|
122
172
|
}
|
|
123
173
|
}
|
|
124
|
-
|
|
174
|
+
}
|
|
175
|
+
return attachments.slice(-MAX_GUARD_ATTACHMENTS);
|
|
176
|
+
}
|
|
177
|
+
function serializeOpenAIPromptContext(req) {
|
|
178
|
+
const messages = req?.messages;
|
|
179
|
+
if (!Array.isArray(messages)) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
const entries = [];
|
|
183
|
+
for (const message of messages) {
|
|
184
|
+
if (!message || typeof message !== "object") {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const role = formatPromptContextRole(message.role);
|
|
188
|
+
const content = message.content;
|
|
189
|
+
const fragments = [
|
|
190
|
+
...extractTextParts(content),
|
|
191
|
+
...extractAttachmentPlaceholders(content)
|
|
192
|
+
].filter((fragment) => fragment.length > 0);
|
|
193
|
+
if (fragments.length === 0) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
entries.push(`[${role}] ${fragments.join("\n")}`);
|
|
197
|
+
}
|
|
198
|
+
if (entries.length === 0) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
return truncatePromptContext(entries.join("\n\n"));
|
|
202
|
+
}
|
|
203
|
+
var OpenAIAdapter = class {
|
|
204
|
+
extractInput(req) {
|
|
205
|
+
const lastUser = getLastUserMessage(req);
|
|
206
|
+
if (!lastUser) return null;
|
|
207
|
+
const content = lastUser.content;
|
|
208
|
+
if (typeof content === "string") return content;
|
|
209
|
+
if (Array.isArray(content)) {
|
|
210
|
+
const parts = [];
|
|
211
|
+
for (const part of content) {
|
|
212
|
+
if (part && typeof part === "object" && typeof part.text === "string") {
|
|
213
|
+
parts.push(part.text);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return parts.length ? parts.join("") : null;
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
extractAttachments(req) {
|
|
221
|
+
return collectUserAttachments(req);
|
|
222
|
+
}
|
|
223
|
+
extractPromptContext(req) {
|
|
224
|
+
return serializeOpenAIPromptContext(req);
|
|
125
225
|
}
|
|
126
226
|
getModelName(req, res) {
|
|
127
227
|
const model = res?.model ?? req?.model ?? "unknown";
|
|
@@ -1006,49 +1106,49 @@ function detectNationalIdentifiers(text, options = {}) {
|
|
|
1006
1106
|
var SDK_SECRET_PATTERN_DEFINITIONS = [
|
|
1007
1107
|
{
|
|
1008
1108
|
id: "openai_api_key",
|
|
1009
|
-
placeholderType: "
|
|
1109
|
+
placeholderType: "SECRET",
|
|
1010
1110
|
patternSource: "\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b",
|
|
1011
1111
|
flags: "iu",
|
|
1012
1112
|
prefilterTerms: ["sk-", "proj-", "openai"]
|
|
1013
1113
|
},
|
|
1014
1114
|
{
|
|
1015
1115
|
id: "aws_access_key",
|
|
1016
|
-
placeholderType: "
|
|
1116
|
+
placeholderType: "SECRET",
|
|
1017
1117
|
patternSource: "\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b",
|
|
1018
1118
|
flags: "iu",
|
|
1019
1119
|
prefilterTerms: ["akia", "asia", "aws"]
|
|
1020
1120
|
},
|
|
1021
1121
|
{
|
|
1022
1122
|
id: "github_token",
|
|
1023
|
-
placeholderType: "
|
|
1123
|
+
placeholderType: "SECRET",
|
|
1024
1124
|
patternSource: "\\b(?:gh[pousr]_[A-Za-z0-9]{24,255}|github_pat_[A-Za-z0-9_]{20,255})\\b",
|
|
1025
1125
|
flags: "iu",
|
|
1026
1126
|
prefilterTerms: ["ghp_", "gho_", "ghu_", "ghs_", "ghr_", "github_pat_"]
|
|
1027
1127
|
},
|
|
1028
1128
|
{
|
|
1029
1129
|
id: "slack_token",
|
|
1030
|
-
placeholderType: "
|
|
1130
|
+
placeholderType: "SECRET",
|
|
1031
1131
|
patternSource: "\\bxox(?:a|b|p|r|s)-[A-Za-z0-9-]{10,200}\\b",
|
|
1032
1132
|
flags: "iu",
|
|
1033
1133
|
prefilterTerms: ["xoxa-", "xoxb-", "xoxp-", "xoxr-", "xoxs-", "slack"]
|
|
1034
1134
|
},
|
|
1035
1135
|
{
|
|
1036
1136
|
id: "slack_webhook_url",
|
|
1037
|
-
placeholderType: "
|
|
1137
|
+
placeholderType: "SECRET",
|
|
1038
1138
|
patternSource: "https:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Za-z0-9/_-]{20,}",
|
|
1039
1139
|
flags: "iu",
|
|
1040
1140
|
prefilterTerms: ["hooks.slack.com/services", "slack"]
|
|
1041
1141
|
},
|
|
1042
1142
|
{
|
|
1043
1143
|
id: "discord_webhook_url",
|
|
1044
|
-
placeholderType: "
|
|
1144
|
+
placeholderType: "SECRET",
|
|
1045
1145
|
patternSource: "https:\\/\\/discord(?:app)?\\.com\\/api\\/webhooks\\/\\d+\\/[A-Za-z0-9_-]{16,}",
|
|
1046
1146
|
flags: "iu",
|
|
1047
1147
|
prefilterTerms: ["discord.com/api/webhooks", "discordapp.com/api/webhooks", "discord"]
|
|
1048
1148
|
},
|
|
1049
1149
|
{
|
|
1050
1150
|
id: "stripe_secret_key",
|
|
1051
|
-
placeholderType: "
|
|
1151
|
+
placeholderType: "SECRET",
|
|
1052
1152
|
patternSource: "\\b(?:sk|pk|ak|rk)_(?:live|test)_[A-Za-z0-9]+\\b",
|
|
1053
1153
|
flags: "iu",
|
|
1054
1154
|
prefilterTerms: [
|
|
@@ -1065,49 +1165,49 @@ var SDK_SECRET_PATTERN_DEFINITIONS = [
|
|
|
1065
1165
|
},
|
|
1066
1166
|
{
|
|
1067
1167
|
id: "google_api_key",
|
|
1068
|
-
placeholderType: "
|
|
1168
|
+
placeholderType: "SECRET",
|
|
1069
1169
|
patternSource: "\\bAIza[0-9A-Za-z_-]{35}\\b",
|
|
1070
1170
|
flags: "iu",
|
|
1071
1171
|
prefilterTerms: ["aiza", "google"]
|
|
1072
1172
|
},
|
|
1073
1173
|
{
|
|
1074
1174
|
id: "anthropic_api_key",
|
|
1075
|
-
placeholderType: "
|
|
1175
|
+
placeholderType: "SECRET",
|
|
1076
1176
|
patternSource: "\\bsk-ant-(?:api\\d{2}-)?[A-Za-z0-9_-]{20,}\\b",
|
|
1077
1177
|
flags: "iu",
|
|
1078
1178
|
prefilterTerms: ["sk-ant-", "anthropic"]
|
|
1079
1179
|
},
|
|
1080
1180
|
{
|
|
1081
1181
|
id: "evm_private_key",
|
|
1082
|
-
placeholderType: "
|
|
1182
|
+
placeholderType: "SECRET",
|
|
1083
1183
|
patternSource: "\\b0x[a-fA-F0-9]{64}\\b",
|
|
1084
1184
|
flags: "iu",
|
|
1085
1185
|
prefilterTerms: ["0x", "ethereum", "evm", "private key"]
|
|
1086
1186
|
},
|
|
1087
1187
|
{
|
|
1088
1188
|
id: "jwt_token",
|
|
1089
|
-
placeholderType: "
|
|
1189
|
+
placeholderType: "SECRET",
|
|
1090
1190
|
patternSource: "\\beyJ[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b",
|
|
1091
1191
|
flags: "iu",
|
|
1092
1192
|
prefilterTerms: ["eyj", "jwt", "bearer"]
|
|
1093
1193
|
},
|
|
1094
1194
|
{
|
|
1095
1195
|
id: "bearer_token",
|
|
1096
|
-
placeholderType: "
|
|
1196
|
+
placeholderType: "SECRET",
|
|
1097
1197
|
patternSource: "\\bauthorization\\b\\s*[:=]\\s*bearer\\s+[A-Za-z0-9._~+\\/-]{16,}|\\bbearer\\s+[A-Za-z0-9._~+\\/-]{24,}",
|
|
1098
1198
|
flags: "iu",
|
|
1099
1199
|
prefilterTerms: ["authorization", "bearer"]
|
|
1100
1200
|
},
|
|
1101
1201
|
{
|
|
1102
1202
|
id: "api_key_header",
|
|
1103
|
-
placeholderType: "
|
|
1203
|
+
placeholderType: "SECRET",
|
|
1104
1204
|
patternSource: "\\bx[-_]?api[-_]?key\\b\\s*[:=]\\s*[A-Za-z0-9._~+\\/-]{16,}",
|
|
1105
1205
|
flags: "iu",
|
|
1106
1206
|
prefilterTerms: ["x-api-key", "api-key", "x_api_key", "api_key"]
|
|
1107
1207
|
},
|
|
1108
1208
|
{
|
|
1109
1209
|
id: "credential_assignment",
|
|
1110
|
-
placeholderType: "
|
|
1210
|
+
placeholderType: "SECRET",
|
|
1111
1211
|
patternSource: `(?:\\b|["'])(?:api(?:[_-]?|\\s+)key|access(?:[_-]?|\\s+)token|auth(?:[_-]?|\\s+)token|client(?:[_-]?|\\s+)secret|private(?:[_-]?|\\s+)key)(?:\\b|["'])\\s*(?::|=|=>)\\s*(?:"[A-Za-z0-9._~+\\/=:-]{16,}"|'[A-Za-z0-9._~+\\/=:-]{16,}'|[A-Za-z0-9._~+\\/=:-]{16,})`,
|
|
1112
1212
|
flags: "iu",
|
|
1113
1213
|
prefilterTerms: [
|
|
@@ -1123,28 +1223,28 @@ var SDK_SECRET_PATTERN_DEFINITIONS = [
|
|
|
1123
1223
|
},
|
|
1124
1224
|
{
|
|
1125
1225
|
id: "password_assignment",
|
|
1126
|
-
placeholderType: "
|
|
1226
|
+
placeholderType: "PASSWORD",
|
|
1127
1227
|
patternSource: `(?:\\b|["'])(?:password|passwd|pwd|heslo)(?:\\b|["'])\\s*(?:(?::|=|=>)|(?:is|are|was|were|je)\\b)?\\s*(?:"[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}"|'[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}'|[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,})`,
|
|
1128
1228
|
flags: "iu",
|
|
1129
1229
|
prefilterTerms: ["password", "passwd", "pwd", "heslo"]
|
|
1130
1230
|
},
|
|
1131
1231
|
{
|
|
1132
1232
|
id: "private_key_material",
|
|
1133
|
-
placeholderType: "
|
|
1233
|
+
placeholderType: "SECRET",
|
|
1134
1234
|
patternSource: "-----BEGIN (?:(?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY|PGP PRIVATE KEY BLOCK|CERTIFICATE)-----[\\s\\S]{20,12000}(?:-----END (?:(?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY|PGP PRIVATE KEY BLOCK|CERTIFICATE)-----|$)",
|
|
1135
1235
|
flags: "iu",
|
|
1136
1236
|
prefilterTerms: ["begin private key", "begin pgp private key block", "private key"]
|
|
1137
1237
|
},
|
|
1138
1238
|
{
|
|
1139
1239
|
id: "azure_connection_string",
|
|
1140
|
-
placeholderType: "
|
|
1240
|
+
placeholderType: "SECRET",
|
|
1141
1241
|
patternSource: "\\bDefaultEndpointsProtocol=https;AccountName=[A-Za-z0-9.-]{3,};AccountKey=[A-Za-z0-9+/=]{20,}(?:;EndpointSuffix=[A-Za-z0-9.-]+)?\\b",
|
|
1142
1242
|
flags: "iu",
|
|
1143
1243
|
prefilterTerms: ["defaultendpointsprotocol", "accountname", "accountkey", "azure"]
|
|
1144
1244
|
},
|
|
1145
1245
|
{
|
|
1146
1246
|
id: "azure_sas_token",
|
|
1147
|
-
placeholderType: "
|
|
1247
|
+
placeholderType: "SECRET",
|
|
1148
1248
|
patternSource: "\\bsv=[^\\s&]{2,}&[^\\s]{0,200}\\bsig=[A-Za-z0-9%/+_-]{16,}",
|
|
1149
1249
|
flags: "iu",
|
|
1150
1250
|
prefilterTerms: ["sv=", "sig=", "accountkey", "azure"]
|
|
@@ -1207,19 +1307,70 @@ function rangesOverlap(left, right) {
|
|
|
1207
1307
|
return left.start < right.end && right.start < left.end;
|
|
1208
1308
|
}
|
|
1209
1309
|
function detectionPriority(type) {
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
)) {
|
|
1310
|
+
const normalizedType = toPlaceholderType(type);
|
|
1311
|
+
if (normalizedType === "SECRET") {
|
|
1213
1312
|
return 100;
|
|
1214
1313
|
}
|
|
1215
|
-
if (
|
|
1314
|
+
if (normalizedType === "PASSWORD") {
|
|
1315
|
+
return 90;
|
|
1316
|
+
}
|
|
1317
|
+
if (/^(?:CREDENTIAL_ASSIGNMENT|PRIVATE_KEY_MATERIAL|ENV_SECRET_ASSIGNMENT)$/u.test(
|
|
1318
|
+
normalizedType
|
|
1319
|
+
)) {
|
|
1216
1320
|
return 80;
|
|
1217
1321
|
}
|
|
1218
|
-
if (
|
|
1322
|
+
if (normalizedType === "PERSON_NAME" || normalizedType === "PERSON") {
|
|
1219
1323
|
return 10;
|
|
1220
1324
|
}
|
|
1221
1325
|
return 50;
|
|
1222
1326
|
}
|
|
1327
|
+
function isPasswordPlaceholderType(type) {
|
|
1328
|
+
return /^(?:PASSWORD_ASSIGNMENT|BASIC_AUTH_PASSWORD)$/u.test(type);
|
|
1329
|
+
}
|
|
1330
|
+
function isGenericSecretPlaceholderType(type) {
|
|
1331
|
+
return /^(?:OPENAI_API_KEY|AWS_ACCESS_KEY|GITHUB_TOKEN|SLACK_TOKEN|SLACK_WEBHOOK_URL|DISCORD_WEBHOOK_URL|STRIPE_SECRET_KEY|GOOGLE_API_KEY|ANTHROPIC_API_KEY|EVM_PRIVATE_KEY|JWT_TOKEN|BEARER_TOKEN|API_KEY_HEADER|CREDENTIAL_ASSIGNMENT|PRIVATE_KEY_MATERIAL|ENV_SECRET_ASSIGNMENT|AZURE_CONNECTION_STRING|AZURE_SAS_TOKEN|DISCORD_WEBHOOK_TOKEN)$/u.test(
|
|
1332
|
+
type
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
function toPlaceholderType(type) {
|
|
1336
|
+
const normalized = String(type ?? "").trim().toUpperCase();
|
|
1337
|
+
if (isPasswordPlaceholderType(normalized)) {
|
|
1338
|
+
return "PASSWORD";
|
|
1339
|
+
}
|
|
1340
|
+
if (isGenericSecretPlaceholderType(normalized)) {
|
|
1341
|
+
return "SECRET";
|
|
1342
|
+
}
|
|
1343
|
+
return normalized || "PII";
|
|
1344
|
+
}
|
|
1345
|
+
function trimLeadingAddressContext(value) {
|
|
1346
|
+
const trimmed = value.replace(
|
|
1347
|
+
/^(?:(?:na\s+)?adrese|(?:se\s+)?(?:s[ií]dlem|bydli[sš]t[ěe]m|bytem|adresa(?:\s+bydli[sš]t[ěe])?))\s*[:,-]?\s*/iu,
|
|
1348
|
+
""
|
|
1349
|
+
);
|
|
1350
|
+
if (!trimmed || trimmed === value) {
|
|
1351
|
+
return { text: value, offset: 0 };
|
|
1352
|
+
}
|
|
1353
|
+
return {
|
|
1354
|
+
text: trimmed,
|
|
1355
|
+
offset: value.indexOf(trimmed)
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
function normalizeDetection(detection) {
|
|
1359
|
+
if (detection.type !== "ADDRESS") {
|
|
1360
|
+
return detection;
|
|
1361
|
+
}
|
|
1362
|
+
const trimmed = trimLeadingAddressContext(detection.text);
|
|
1363
|
+
if (trimmed.offset <= 0 || trimmed.text === detection.text) {
|
|
1364
|
+
return detection;
|
|
1365
|
+
}
|
|
1366
|
+
const start = detection.start + trimmed.offset;
|
|
1367
|
+
return {
|
|
1368
|
+
...detection,
|
|
1369
|
+
start,
|
|
1370
|
+
end: start + trimmed.text.length,
|
|
1371
|
+
text: trimmed.text
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1223
1374
|
var PHONE_CONTEXT_KEYWORDS = [
|
|
1224
1375
|
"tel",
|
|
1225
1376
|
"phone",
|
|
@@ -1334,6 +1485,19 @@ var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
|
|
|
1334
1485
|
"security",
|
|
1335
1486
|
"instructions",
|
|
1336
1487
|
"instruction",
|
|
1488
|
+
"authorized",
|
|
1489
|
+
"audit",
|
|
1490
|
+
"article",
|
|
1491
|
+
"compliance",
|
|
1492
|
+
"global",
|
|
1493
|
+
"governance",
|
|
1494
|
+
"charter",
|
|
1495
|
+
"initialization",
|
|
1496
|
+
"sequence",
|
|
1497
|
+
"prefix",
|
|
1498
|
+
"prefixes",
|
|
1499
|
+
"priority",
|
|
1500
|
+
"violation",
|
|
1337
1501
|
"google",
|
|
1338
1502
|
"form",
|
|
1339
1503
|
"forms",
|
|
@@ -1408,6 +1572,21 @@ var TECHNICAL_CONTEXT_SYMBOL_REGEX = /:\/\/|`|\{|\}|\[|\]|\(|\)|;|\$|=>|::|\/\//
|
|
|
1408
1572
|
var NAME_LABEL_QUESTION_CONTEXT_REGEX = /\b(?:jak(?:e|y|a|ou)|kter(?:e|y|a|ou)|co|what|which|whose|wie|welch(?:e|er|es|en|em)?|quel(?:le|s|les)?|que|cual(?:es)?|wat|welke|jaki|jakie|jaka)\b[\s\S]{0,80}\b(?:jmeno|prijmeni|name|names|namen|nom|nombre|nome|naam|imie|nazwisko|meno)\b[\s\S]{0,96}\b(?:napsal\p{L}*|napsan\p{L}*|psal\p{L}*|pouzil\p{L}*|pouzili\p{L}*|write|wrote|written|type|typed|enter(?:ed)?|use(?:d)?|say|said|geschrieben|getippt|eingetragen|ecrit|escrib\p{L}*|scritt\p{L}*)\b/iu;
|
|
1409
1573
|
var NAME_VALUE_ASSIGNMENT_BEFORE_CANDIDATE_REGEX = /(?:[:=]|=>|-|\b(?:is|was|je|jsou|jmenuje|called|named|ist|sind|lautet|est|es)\b)\s*$/iu;
|
|
1410
1574
|
var BIRTH_NUMBER_CONTEXT_RE = /\b(?:rodn[eé]\s*(?:č[ií]slo|cislo)|r\.?\s*c\.?|birth\s+number)\b[^0-9]{0,80}(\d{6}(?:\/?\d{3,4})?)\b/giu;
|
|
1575
|
+
var ADDRESS_HOUSE_NUMBER_PATTERN = String.raw`\d{1,5}(?:\/\d{1,5}[A-Za-z]?)?[A-Za-z]?`;
|
|
1576
|
+
var ADDRESS_POSTAL_CODE_PATTERN = String.raw`(?:\d{3}\s?\d{2}|\d{5})`;
|
|
1577
|
+
var ADDRESS_STREET_LABEL_PATTERN = String.raw`(?:ulici|ulice|ul\.?|street|st\.?|road|rd\.?|avenue|ave\.?|n[aá]m[eě]st[ií]|t[řr][íi]da|alej|n[aá]b[řr]ež[ií])`;
|
|
1578
|
+
var ADDRESS_WITH_ANCHOR_RE = new RegExp(
|
|
1579
|
+
String.raw`\b(?:bydl[ií]m\s+na|bydlim\s+na|bytem|bydli[sš]t[eě]|adresa|na\s+ulici|v\s+ulici|doru[cč]ovac[ií]\s+adresa|koresponden[cč]n[ií]\s+adresa|faktura[cč]n[ií]\s+adresa|se\s+s[ií]dlem|z[ií]ju\s+v|ziju\s+v|zjiu\s+v)\b[\s,:-]{0,12}((?:(?:${ADDRESS_STREET_LABEL_PATTERN})\s+)?(?:\p{L}[\p{L}'’-]{2,}\s+){0,4}${ADDRESS_HOUSE_NUMBER_PATTERN}(?:(?:,\s*|\s+)(?:${ADDRESS_POSTAL_CODE_PATTERN}))?(?:(?:,\s*|\s+)(?:v|ve)\s+)?(?:(?:,\s*|\s+)(?:\p{L}[\p{L}'’-]{2,})(?:\s+\p{L}[\p{L}'’-]{2,}){0,2})?)`,
|
|
1580
|
+
"giu"
|
|
1581
|
+
);
|
|
1582
|
+
var ADDRESS_CITY_NUMBER_WITH_ANCHOR_RE = new RegExp(
|
|
1583
|
+
String.raw`\b(?:z[ií]ju\s+v|ziju\s+v|zjiu\s+v|v\s+obci|v\s+katastru\s+obce)\b[\s,:-]{0,12}((?:\p{L}[\p{L}'’-]{2,})(?:\s+\p{L}[\p{L}'’-]{2,}){0,2}\s+${ADDRESS_HOUSE_NUMBER_PATTERN})`,
|
|
1584
|
+
"giu"
|
|
1585
|
+
);
|
|
1586
|
+
var ADDRESS_STANDALONE_RE = new RegExp(
|
|
1587
|
+
String.raw`\b((?:(?:${ADDRESS_STREET_LABEL_PATTERN})\s+)?(?:\p{L}[\p{L}'’-]{2,}\s+){0,4}${ADDRESS_HOUSE_NUMBER_PATTERN}(?:,\s*|\s+)(?:${ADDRESS_POSTAL_CODE_PATTERN})(?:,\s*|\s+)(?:\p{L}[\p{L}'’-]{2,}(?:\s+\p{L}[\p{L}'’-]{2,}){0,2}))`,
|
|
1588
|
+
"gu"
|
|
1589
|
+
);
|
|
1411
1590
|
function hasPhoneContext(text, matchStartIndex, windowSize = 50) {
|
|
1412
1591
|
const start = Math.max(0, matchStartIndex - windowSize);
|
|
1413
1592
|
const windowLower = text.slice(start, matchStartIndex).toLowerCase();
|
|
@@ -1459,6 +1638,26 @@ function isLikelyPersonNameCandidate(candidate, contextWindow) {
|
|
|
1459
1638
|
}
|
|
1460
1639
|
return true;
|
|
1461
1640
|
}
|
|
1641
|
+
function isLikelyAddressCandidate(candidate) {
|
|
1642
|
+
if (!/\d/u.test(candidate)) {
|
|
1643
|
+
return false;
|
|
1644
|
+
}
|
|
1645
|
+
const normalized = normalizePersonWord(candidate);
|
|
1646
|
+
const words = candidate.trim().split(/\s+/).filter(Boolean);
|
|
1647
|
+
if (words.length < 2) {
|
|
1648
|
+
return false;
|
|
1649
|
+
}
|
|
1650
|
+
const numberIndex = words.findIndex((word) => /\d/u.test(word));
|
|
1651
|
+
if (numberIndex <= 0) {
|
|
1652
|
+
return false;
|
|
1653
|
+
}
|
|
1654
|
+
const letterWordRe = /^\p{L}[\p{L}'’-]*$/u;
|
|
1655
|
+
const beforeCount = words.slice(0, numberIndex).filter((word) => letterWordRe.test(word)).length;
|
|
1656
|
+
const afterCount = words.slice(numberIndex + 1).filter((word) => letterWordRe.test(word)).length;
|
|
1657
|
+
return /\b(?:ulici|ulice|ul\.|street|road|avenue|namesti|trida|alej|nabrezi)\b/iu.test(
|
|
1658
|
+
normalized
|
|
1659
|
+
) || /\b\d{3}\s?\d{2}\b|\b\d{5}\b/u.test(candidate) || beforeCount >= 1 && afterCount >= 1;
|
|
1660
|
+
}
|
|
1462
1661
|
var PIIManager = class {
|
|
1463
1662
|
/**
|
|
1464
1663
|
* Reversible local-first masking using <TYPE_INDEX> placeholders.
|
|
@@ -1539,13 +1738,55 @@ var PIIManager = class {
|
|
|
1539
1738
|
});
|
|
1540
1739
|
for (const match of nationalIdMatches) {
|
|
1541
1740
|
if (match.start < 0 || match.end <= match.start) continue;
|
|
1741
|
+
const detectionType = match.type === "address_postal" ? "ADDRESS" : match.type === "birth_number" ? "BIRTH_NUMBER" : "NATIONAL_ID";
|
|
1542
1742
|
detections.push({
|
|
1543
1743
|
start: match.start,
|
|
1544
1744
|
end: match.end,
|
|
1545
|
-
type:
|
|
1745
|
+
type: detectionType,
|
|
1546
1746
|
text: text.slice(match.start, match.end)
|
|
1547
1747
|
});
|
|
1548
1748
|
}
|
|
1749
|
+
ADDRESS_WITH_ANCHOR_RE.lastIndex = 0;
|
|
1750
|
+
for (const match of text.matchAll(ADDRESS_WITH_ANCHOR_RE)) {
|
|
1751
|
+
if (match.index == null) continue;
|
|
1752
|
+
const value = match[1] ?? "";
|
|
1753
|
+
if (!value || !isLikelyAddressCandidate(value)) continue;
|
|
1754
|
+
const localIndex = match[0].lastIndexOf(value);
|
|
1755
|
+
const start = match.index + Math.max(0, localIndex);
|
|
1756
|
+
detections.push({
|
|
1757
|
+
start,
|
|
1758
|
+
end: start + value.length,
|
|
1759
|
+
type: "ADDRESS",
|
|
1760
|
+
text: value
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1763
|
+
ADDRESS_CITY_NUMBER_WITH_ANCHOR_RE.lastIndex = 0;
|
|
1764
|
+
for (const match of text.matchAll(ADDRESS_CITY_NUMBER_WITH_ANCHOR_RE)) {
|
|
1765
|
+
if (match.index == null) continue;
|
|
1766
|
+
const value = match[1] ?? "";
|
|
1767
|
+
if (!value || !isLikelyAddressCandidate(value)) continue;
|
|
1768
|
+
const localIndex = match[0].lastIndexOf(value);
|
|
1769
|
+
const start = match.index + Math.max(0, localIndex);
|
|
1770
|
+
detections.push({
|
|
1771
|
+
start,
|
|
1772
|
+
end: start + value.length,
|
|
1773
|
+
type: "ADDRESS",
|
|
1774
|
+
text: value
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
ADDRESS_STANDALONE_RE.lastIndex = 0;
|
|
1778
|
+
for (const match of text.matchAll(ADDRESS_STANDALONE_RE)) {
|
|
1779
|
+
if (match.index == null) continue;
|
|
1780
|
+
const value = match[1] ?? match[0];
|
|
1781
|
+
if (!value || !isLikelyAddressCandidate(value)) continue;
|
|
1782
|
+
const start = match.index;
|
|
1783
|
+
detections.push({
|
|
1784
|
+
start,
|
|
1785
|
+
end: start + value.length,
|
|
1786
|
+
type: "ADDRESS",
|
|
1787
|
+
text: value
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1549
1790
|
}
|
|
1550
1791
|
if (resolvedOptions.secrets) {
|
|
1551
1792
|
BASIC_AUTH_PASSWORD_RE.lastIndex = 0;
|
|
@@ -1595,13 +1836,17 @@ var PIIManager = class {
|
|
|
1595
1836
|
}
|
|
1596
1837
|
}
|
|
1597
1838
|
}
|
|
1598
|
-
const kept = normalizeDetections(
|
|
1839
|
+
const kept = normalizeDetections(
|
|
1840
|
+
text,
|
|
1841
|
+
detections.map((detection) => normalizeDetection(detection))
|
|
1842
|
+
);
|
|
1599
1843
|
if (!kept.length) return { maskedText: text, mapping: {} };
|
|
1600
1844
|
const counters = {};
|
|
1601
1845
|
const mapping = {};
|
|
1602
1846
|
const replacements = kept.map((d) => {
|
|
1603
|
-
|
|
1604
|
-
|
|
1847
|
+
const placeholderType = toPlaceholderType(d.type);
|
|
1848
|
+
counters[placeholderType] = (counters[placeholderType] ?? 0) + 1;
|
|
1849
|
+
const placeholder = `<${placeholderType}_${counters[placeholderType]}>`;
|
|
1605
1850
|
mapping[placeholder] = d.text;
|
|
1606
1851
|
return { ...d, placeholder };
|
|
1607
1852
|
});
|
|
@@ -1707,7 +1952,6 @@ var MAX_ANALYSIS_WINDOW = 8192;
|
|
|
1707
1952
|
var WINDOW_SLICE_SIZE = 4e3;
|
|
1708
1953
|
var WORD_BOUNDARY_SCAN = 120;
|
|
1709
1954
|
var AI_TIMEOUT_MS = 2e3;
|
|
1710
|
-
var TELEMETRY_SNIPPET_LIMIT = 4e3;
|
|
1711
1955
|
var AI_OPENAI_MODEL = "gpt-4o-mini";
|
|
1712
1956
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1713
1957
|
var EN_STOPWORDS = /* @__PURE__ */ new Set([
|
|
@@ -1892,143 +2136,6 @@ function getOpenAiApiKey() {
|
|
|
1892
2136
|
}
|
|
1893
2137
|
return key.trim();
|
|
1894
2138
|
}
|
|
1895
|
-
async function sha256Hex(text) {
|
|
1896
|
-
const data = new TextEncoder().encode(text ?? "");
|
|
1897
|
-
const subtle = globalThis.crypto?.subtle;
|
|
1898
|
-
if (subtle?.digest) {
|
|
1899
|
-
const buf = await subtle.digest("SHA-256", data);
|
|
1900
|
-
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1901
|
-
}
|
|
1902
|
-
return sha256HexFallback(data);
|
|
1903
|
-
}
|
|
1904
|
-
function sha256HexFallback(data) {
|
|
1905
|
-
const K = [
|
|
1906
|
-
1116352408,
|
|
1907
|
-
1899447441,
|
|
1908
|
-
3049323471,
|
|
1909
|
-
3921009573,
|
|
1910
|
-
961987163,
|
|
1911
|
-
1508970993,
|
|
1912
|
-
2453635748,
|
|
1913
|
-
2870763221,
|
|
1914
|
-
3624381080,
|
|
1915
|
-
310598401,
|
|
1916
|
-
607225278,
|
|
1917
|
-
1426881987,
|
|
1918
|
-
1925078388,
|
|
1919
|
-
2162078206,
|
|
1920
|
-
2614888103,
|
|
1921
|
-
3248222580,
|
|
1922
|
-
3835390401,
|
|
1923
|
-
4022224774,
|
|
1924
|
-
264347078,
|
|
1925
|
-
604807628,
|
|
1926
|
-
770255983,
|
|
1927
|
-
1249150122,
|
|
1928
|
-
1555081692,
|
|
1929
|
-
1996064986,
|
|
1930
|
-
2554220882,
|
|
1931
|
-
2821834349,
|
|
1932
|
-
2952996808,
|
|
1933
|
-
3210313671,
|
|
1934
|
-
3336571891,
|
|
1935
|
-
3584528711,
|
|
1936
|
-
113926993,
|
|
1937
|
-
338241895,
|
|
1938
|
-
666307205,
|
|
1939
|
-
773529912,
|
|
1940
|
-
1294757372,
|
|
1941
|
-
1396182291,
|
|
1942
|
-
1695183700,
|
|
1943
|
-
1986661051,
|
|
1944
|
-
2177026350,
|
|
1945
|
-
2456956037,
|
|
1946
|
-
2730485921,
|
|
1947
|
-
2820302411,
|
|
1948
|
-
3259730800,
|
|
1949
|
-
3345764771,
|
|
1950
|
-
3516065817,
|
|
1951
|
-
3600352804,
|
|
1952
|
-
4094571909,
|
|
1953
|
-
275423344,
|
|
1954
|
-
430227734,
|
|
1955
|
-
506948616,
|
|
1956
|
-
659060556,
|
|
1957
|
-
883997877,
|
|
1958
|
-
958139571,
|
|
1959
|
-
1322822218,
|
|
1960
|
-
1537002063,
|
|
1961
|
-
1747873779,
|
|
1962
|
-
1955562222,
|
|
1963
|
-
2024104815,
|
|
1964
|
-
2227730452,
|
|
1965
|
-
2361852424,
|
|
1966
|
-
2428436474,
|
|
1967
|
-
2756734187,
|
|
1968
|
-
3204031479,
|
|
1969
|
-
3329325298
|
|
1970
|
-
];
|
|
1971
|
-
const H = [
|
|
1972
|
-
1779033703,
|
|
1973
|
-
3144134277,
|
|
1974
|
-
1013904242,
|
|
1975
|
-
2773480762,
|
|
1976
|
-
1359893119,
|
|
1977
|
-
2600822924,
|
|
1978
|
-
528734635,
|
|
1979
|
-
1541459225
|
|
1980
|
-
];
|
|
1981
|
-
const length = data.length;
|
|
1982
|
-
const bitLengthHi = Math.floor(length * 8 / 4294967296);
|
|
1983
|
-
const bitLengthLo = length * 8 >>> 0;
|
|
1984
|
-
const paddedLength = length + 9 + 63 >> 6 << 6 >>> 0;
|
|
1985
|
-
const padded = new Uint8Array(paddedLength);
|
|
1986
|
-
padded.set(data);
|
|
1987
|
-
padded[length] = 128;
|
|
1988
|
-
const view = new DataView(padded.buffer);
|
|
1989
|
-
view.setUint32(paddedLength - 8, bitLengthHi, false);
|
|
1990
|
-
view.setUint32(paddedLength - 4, bitLengthLo, false);
|
|
1991
|
-
const w = new Uint32Array(64);
|
|
1992
|
-
for (let offset = 0; offset < paddedLength; offset += 64) {
|
|
1993
|
-
for (let i = 0; i < 16; i += 1) {
|
|
1994
|
-
w[i] = view.getUint32(offset + i * 4, false);
|
|
1995
|
-
}
|
|
1996
|
-
for (let i = 16; i < 64; i += 1) {
|
|
1997
|
-
const s0 = rightRotate(w[i - 15], 7) ^ rightRotate(w[i - 15], 18) ^ w[i - 15] >>> 3;
|
|
1998
|
-
const s1 = rightRotate(w[i - 2], 17) ^ rightRotate(w[i - 2], 19) ^ w[i - 2] >>> 10;
|
|
1999
|
-
w[i] = (w[i - 16] + s0 >>> 0) + (w[i - 7] + s1 >>> 0) >>> 0;
|
|
2000
|
-
}
|
|
2001
|
-
let [a, b, c, d, e, f, g, h] = H;
|
|
2002
|
-
for (let i = 0; i < 64; i += 1) {
|
|
2003
|
-
const S1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25);
|
|
2004
|
-
const ch = e & f ^ ~e & g;
|
|
2005
|
-
const temp1 = ((h + S1 >>> 0) + (ch + K[i] >>> 0) >>> 0) + w[i] >>> 0;
|
|
2006
|
-
const S0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22);
|
|
2007
|
-
const maj = a & b ^ a & c ^ b & c;
|
|
2008
|
-
const temp2 = S0 + maj >>> 0;
|
|
2009
|
-
h = g;
|
|
2010
|
-
g = f;
|
|
2011
|
-
f = e;
|
|
2012
|
-
e = d + temp1 >>> 0;
|
|
2013
|
-
d = c;
|
|
2014
|
-
c = b;
|
|
2015
|
-
b = a;
|
|
2016
|
-
a = temp1 + temp2 >>> 0;
|
|
2017
|
-
}
|
|
2018
|
-
H[0] = H[0] + a >>> 0;
|
|
2019
|
-
H[1] = H[1] + b >>> 0;
|
|
2020
|
-
H[2] = H[2] + c >>> 0;
|
|
2021
|
-
H[3] = H[3] + d >>> 0;
|
|
2022
|
-
H[4] = H[4] + e >>> 0;
|
|
2023
|
-
H[5] = H[5] + f >>> 0;
|
|
2024
|
-
H[6] = H[6] + g >>> 0;
|
|
2025
|
-
H[7] = H[7] + h >>> 0;
|
|
2026
|
-
}
|
|
2027
|
-
return H.map((value) => value.toString(16).padStart(8, "0")).join("");
|
|
2028
|
-
}
|
|
2029
|
-
function rightRotate(value, shift) {
|
|
2030
|
-
return value >>> shift | value << 32 - shift;
|
|
2031
|
-
}
|
|
2032
2139
|
function safeJsonParse(raw) {
|
|
2033
2140
|
try {
|
|
2034
2141
|
return JSON.parse(raw);
|
|
@@ -2104,22 +2211,11 @@ async function runAICheck(anonymizedWindow) {
|
|
|
2104
2211
|
clearTimeout(timeout);
|
|
2105
2212
|
}
|
|
2106
2213
|
}
|
|
2107
|
-
function truncateSnippet(value) {
|
|
2108
|
-
if (!value) {
|
|
2109
|
-
return "";
|
|
2110
|
-
}
|
|
2111
|
-
if (value.length <= TELEMETRY_SNIPPET_LIMIT) {
|
|
2112
|
-
return value;
|
|
2113
|
-
}
|
|
2114
|
-
return value.slice(0, TELEMETRY_SNIPPET_LIMIT);
|
|
2115
|
-
}
|
|
2116
2214
|
async function reportSecurityEvent(options) {
|
|
2117
2215
|
if (typeof fetch !== "function") {
|
|
2118
2216
|
return;
|
|
2119
2217
|
}
|
|
2120
|
-
const
|
|
2121
|
-
const snippetHash = snippet ? await sha256Hex(snippet) : "";
|
|
2122
|
-
const inputValue = options.storePii ? snippet : snippetHash;
|
|
2218
|
+
const inputValue = "[REDACTED]";
|
|
2123
2219
|
const eventId = createEventId(options.eventId ?? options.clientEventId);
|
|
2124
2220
|
const metadata = {
|
|
2125
2221
|
...options.telemetryMetadata ?? {},
|
|
@@ -2129,13 +2225,9 @@ async function reportSecurityEvent(options) {
|
|
|
2129
2225
|
language: options.language,
|
|
2130
2226
|
ai_scan_status: options.aiStatus ?? null,
|
|
2131
2227
|
reason: options.reason ?? null,
|
|
2132
|
-
client_event_id: eventId
|
|
2228
|
+
client_event_id: eventId,
|
|
2229
|
+
transformed_input: "[REDACTED]"
|
|
2133
2230
|
};
|
|
2134
|
-
if (options.storePii) {
|
|
2135
|
-
metadata.snippet = snippet;
|
|
2136
|
-
} else {
|
|
2137
|
-
metadata.snippet_hash = snippetHash;
|
|
2138
|
-
}
|
|
2139
2231
|
const payload = {
|
|
2140
2232
|
event_id: eventId,
|
|
2141
2233
|
system_id: options.systemId,
|
|
@@ -2290,7 +2382,7 @@ function getInjectionScanner() {
|
|
|
2290
2382
|
|
|
2291
2383
|
// src/sdk-version.ts
|
|
2292
2384
|
var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
|
|
2293
|
-
var AGENTID_SDK_VERSION_HEADER = "js-0.1.
|
|
2385
|
+
var AGENTID_SDK_VERSION_HEADER = "js-0.1.42".trim().length > 0 ? "js-0.1.42" : FALLBACK_SDK_VERSION;
|
|
2294
2386
|
|
|
2295
2387
|
// src/local-security-enforcer.ts
|
|
2296
2388
|
var DEFAULT_FAIL_OPEN_CONFIG = {
|
|
@@ -2708,7 +2800,7 @@ var GUARD_MAX_ATTEMPTS = 3;
|
|
|
2708
2800
|
var GUARD_RETRY_DELAYS_MS = [250, 500];
|
|
2709
2801
|
var INGEST_MAX_ATTEMPTS = 3;
|
|
2710
2802
|
var INGEST_RETRY_DELAYS_MS = [250, 500];
|
|
2711
|
-
var GUARD_VERDICT_CACHE_TTL_MS =
|
|
2803
|
+
var GUARD_VERDICT_CACHE_TTL_MS = 1500;
|
|
2712
2804
|
var MAX_INGEST_TEXT_CHARS = 32e3;
|
|
2713
2805
|
var OPENAI_TELEMETRY_FIELD = "agentid_telemetry";
|
|
2714
2806
|
function normalizeBaseUrl3(baseUrl) {
|
|
@@ -2824,8 +2916,8 @@ function isInfrastructureGuardReason(reason) {
|
|
|
2824
2916
|
if (!reason) return false;
|
|
2825
2917
|
return reason === "system_failure" || reason === "system_failure_db_unavailable" || reason === "logging_failed" || reason === "server_error" || reason === "guard_unreachable" || reason === "api_key_pepper_missing" || reason === "encryption_key_missing";
|
|
2826
2918
|
}
|
|
2827
|
-
function
|
|
2828
|
-
return reason === "
|
|
2919
|
+
function isFailOpenGuardBypassReason(reason) {
|
|
2920
|
+
return reason === "timeout_fallback" || reason === "guard_unreachable" || reason === "system_failure_fail_open";
|
|
2829
2921
|
}
|
|
2830
2922
|
function isFailCloseIngestReason(reason) {
|
|
2831
2923
|
if (!reason) return false;
|
|
@@ -2860,6 +2952,14 @@ function sanitizeIngestText(value) {
|
|
|
2860
2952
|
const text = typeof value === "string" ? value : String(value ?? "");
|
|
2861
2953
|
return text.slice(0, MAX_INGEST_TEXT_CHARS);
|
|
2862
2954
|
}
|
|
2955
|
+
function getZeroRetentionInput(rawInput, candidateInput) {
|
|
2956
|
+
const raw = typeof rawInput === "string" ? rawInput : "";
|
|
2957
|
+
const candidate = typeof candidateInput === "string" ? candidateInput : "";
|
|
2958
|
+
if (candidate.length > 0 && candidate !== raw) {
|
|
2959
|
+
return candidate;
|
|
2960
|
+
}
|
|
2961
|
+
return "[REDACTED]";
|
|
2962
|
+
}
|
|
2863
2963
|
function normalizeExpectedLanguages(value) {
|
|
2864
2964
|
if (!Array.isArray(value)) {
|
|
2865
2965
|
return void 0;
|
|
@@ -3535,6 +3635,29 @@ function textContainsMappingPlaceholder(text, mapping) {
|
|
|
3535
3635
|
}
|
|
3536
3636
|
return Object.keys(mapping).some((placeholder) => placeholder.length > 0 && text.includes(placeholder));
|
|
3537
3637
|
}
|
|
3638
|
+
function isSecretPlaceholder(placeholder) {
|
|
3639
|
+
const normalized = placeholder.replace(/[<>]/g, "").replace(/_\d+$/u, "").toUpperCase();
|
|
3640
|
+
return normalized.includes("PASSWORD") || normalized.includes("SECRET") || normalized.includes("TOKEN") || normalized.includes("API_KEY") || normalized.includes("CREDENTIAL") || normalized.includes("PRIVATE_KEY");
|
|
3641
|
+
}
|
|
3642
|
+
function getMaskingTelemetryFromMapping(mapping) {
|
|
3643
|
+
const placeholders = Object.keys(mapping ?? {}).filter((placeholder) => placeholder.length > 0);
|
|
3644
|
+
return {
|
|
3645
|
+
piiApplied: placeholders.some((placeholder) => !isSecretPlaceholder(placeholder)),
|
|
3646
|
+
secretApplied: placeholders.some(isSecretPlaceholder)
|
|
3647
|
+
};
|
|
3648
|
+
}
|
|
3649
|
+
function normalizePiiMapping(value) {
|
|
3650
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3651
|
+
return void 0;
|
|
3652
|
+
}
|
|
3653
|
+
const entries = Object.entries(value).filter(
|
|
3654
|
+
([placeholder, replacement]) => placeholder.length > 0 && typeof replacement === "string"
|
|
3655
|
+
);
|
|
3656
|
+
if (entries.length === 0) {
|
|
3657
|
+
return void 0;
|
|
3658
|
+
}
|
|
3659
|
+
return Object.fromEntries(entries);
|
|
3660
|
+
}
|
|
3538
3661
|
var SecurityBlockError = class extends Error {
|
|
3539
3662
|
constructor(reason = "guard_denied") {
|
|
3540
3663
|
super(`AgentID: Security Blocked (${reason})`);
|
|
@@ -3556,6 +3679,7 @@ var AgentID = class {
|
|
|
3556
3679
|
constructor(config = {}) {
|
|
3557
3680
|
this.injectionScanner = getInjectionScanner();
|
|
3558
3681
|
this.recentGuardVerdicts = /* @__PURE__ */ new Map();
|
|
3682
|
+
this.pendingGuardRequests = /* @__PURE__ */ new Map();
|
|
3559
3683
|
this.apiKey = resolveConfiguredApiKey(config.apiKey);
|
|
3560
3684
|
this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
|
|
3561
3685
|
this.configuredPiiMasking = typeof config.piiMasking === "boolean" ? config.piiMasking : null;
|
|
@@ -3611,16 +3735,18 @@ var AgentID = class {
|
|
|
3611
3735
|
getEffectiveSecretMaskingForConfig(capabilityConfig) {
|
|
3612
3736
|
return this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3613
3737
|
}
|
|
3614
|
-
buildClientCapabilities(framework = "js_sdk", hasFeedbackHandler = false, capabilityConfig) {
|
|
3738
|
+
buildClientCapabilities(framework = "js_sdk", hasFeedbackHandler = false, capabilityConfig, appliedMasking) {
|
|
3739
|
+
const piiMaskingEnabled = typeof appliedMasking?.piiApplied === "boolean" ? appliedMasking.piiApplied : this.resolveEffectivePiiMasking(
|
|
3740
|
+
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
3741
|
+
);
|
|
3742
|
+
const secretMaskingEnabled = typeof appliedMasking?.secretApplied === "boolean" ? appliedMasking.secretApplied : this.resolveEffectiveSecretMasking(
|
|
3743
|
+
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
3744
|
+
);
|
|
3615
3745
|
return {
|
|
3616
3746
|
capabilities: {
|
|
3617
3747
|
has_feedback_handler: hasFeedbackHandler,
|
|
3618
|
-
pii_masking_enabled:
|
|
3619
|
-
|
|
3620
|
-
),
|
|
3621
|
-
secret_masking_enabled: this.resolveEffectiveSecretMasking(
|
|
3622
|
-
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
3623
|
-
),
|
|
3748
|
+
pii_masking_enabled: piiMaskingEnabled,
|
|
3749
|
+
secret_masking_enabled: secretMaskingEnabled,
|
|
3624
3750
|
framework
|
|
3625
3751
|
}
|
|
3626
3752
|
};
|
|
@@ -3646,13 +3772,15 @@ var AgentID = class {
|
|
|
3646
3772
|
}
|
|
3647
3773
|
return createEventId2();
|
|
3648
3774
|
}
|
|
3649
|
-
buildGuardCacheKey(params) {
|
|
3650
|
-
|
|
3775
|
+
buildGuardCacheKey(params, apiKey) {
|
|
3776
|
+
const cacheInputSource = typeof params.prompt_context === "string" && params.prompt_context.trim().length > 0 ? params.prompt_context : params.input;
|
|
3777
|
+
if (!params.system_id || !cacheInputSource) {
|
|
3651
3778
|
return null;
|
|
3652
3779
|
}
|
|
3653
3780
|
const userId = params.user_id?.trim() ?? "";
|
|
3654
|
-
const normalizedInput =
|
|
3655
|
-
|
|
3781
|
+
const normalizedInput = cacheInputSource.trim().replace(/\s+/g, " ").slice(0, 2048);
|
|
3782
|
+
const keyPrefix = apiKey?.slice(0, 24) ?? "";
|
|
3783
|
+
return `${keyPrefix}|${params.system_id}|${userId}|${normalizedInput.length}|${normalizedInput}`;
|
|
3656
3784
|
}
|
|
3657
3785
|
readCachedGuardVerdict(cacheKey) {
|
|
3658
3786
|
if (!cacheKey) return null;
|
|
@@ -3665,7 +3793,7 @@ var AgentID = class {
|
|
|
3665
3793
|
return cached.verdict;
|
|
3666
3794
|
}
|
|
3667
3795
|
cacheGuardVerdict(cacheKey, verdict) {
|
|
3668
|
-
if (!cacheKey ||
|
|
3796
|
+
if (!cacheKey || GUARD_VERDICT_CACHE_TTL_MS <= 0) {
|
|
3669
3797
|
return;
|
|
3670
3798
|
}
|
|
3671
3799
|
this.recentGuardVerdicts.set(cacheKey, {
|
|
@@ -3714,20 +3842,7 @@ var AgentID = class {
|
|
|
3714
3842
|
return config.strict_security_mode || config.failure_mode === "fail_close";
|
|
3715
3843
|
}
|
|
3716
3844
|
buildFailOpenGuardVerdict(reason, input, options) {
|
|
3717
|
-
const capabilityConfig = this.getCachedCapabilityConfig(options);
|
|
3718
|
-
const shouldMaskPii = capabilityConfig.block_pii_leakage || this.resolveEffectivePiiMasking(capabilityConfig);
|
|
3719
|
-
const shouldMaskSecrets = capabilityConfig.block_secret_leakage === true || this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3720
3845
|
const response = { allowed: true, reason };
|
|
3721
|
-
if (input && (shouldMaskPii || shouldMaskSecrets)) {
|
|
3722
|
-
const masked = this.pii.anonymize(input, {
|
|
3723
|
-
pii: shouldMaskPii,
|
|
3724
|
-
secrets: shouldMaskSecrets
|
|
3725
|
-
});
|
|
3726
|
-
if (masked.maskedText !== input) {
|
|
3727
|
-
response.transformed_input = masked.maskedText;
|
|
3728
|
-
response.detected_pii = Object.keys(masked.mapping).length > 0;
|
|
3729
|
-
}
|
|
3730
|
-
}
|
|
3731
3846
|
return response;
|
|
3732
3847
|
}
|
|
3733
3848
|
maybeRaiseStrictIngestDependencyError(params) {
|
|
@@ -3756,6 +3871,43 @@ var AgentID = class {
|
|
|
3756
3871
|
}
|
|
3757
3872
|
return config.block_on_heuristic;
|
|
3758
3873
|
}
|
|
3874
|
+
buildInlineAttachmentPromptScanInput(attachments, maxChars = 6e3) {
|
|
3875
|
+
if (!Array.isArray(attachments) || attachments.length === 0) {
|
|
3876
|
+
return "";
|
|
3877
|
+
}
|
|
3878
|
+
const text = attachments.slice(0, 4).map((attachment) => {
|
|
3879
|
+
const attachmentText = typeof attachment?.text === "string" ? attachment.text.trim() : "";
|
|
3880
|
+
if (!attachmentText) {
|
|
3881
|
+
return "";
|
|
3882
|
+
}
|
|
3883
|
+
const filename = typeof attachment.filename === "string" && attachment.filename.trim().length > 0 ? attachment.filename.trim() : "attachment";
|
|
3884
|
+
return `[Attachment: ${filename}]
|
|
3885
|
+
${attachmentText}`;
|
|
3886
|
+
}).filter(Boolean).join("\n\n");
|
|
3887
|
+
if (!text || text.length <= maxChars) {
|
|
3888
|
+
return text;
|
|
3889
|
+
}
|
|
3890
|
+
const headBudget = Math.max(256, Math.floor(maxChars * 0.55));
|
|
3891
|
+
const tailBudget = Math.max(128, maxChars - headBudget - 16);
|
|
3892
|
+
return `${text.slice(0, headBudget)}
|
|
3893
|
+
|
|
3894
|
+
[...]
|
|
3895
|
+
|
|
3896
|
+
${text.slice(-tailBudget)}`;
|
|
3897
|
+
}
|
|
3898
|
+
buildPromptInjectionScanInput(params) {
|
|
3899
|
+
const source = typeof params.promptContext === "string" && params.promptContext.trim().length > 0 ? params.promptContext : params.input;
|
|
3900
|
+
const attachmentInput = this.buildInlineAttachmentPromptScanInput(params.attachments);
|
|
3901
|
+
if (!source) {
|
|
3902
|
+
return attachmentInput;
|
|
3903
|
+
}
|
|
3904
|
+
if (!attachmentInput) {
|
|
3905
|
+
return source;
|
|
3906
|
+
}
|
|
3907
|
+
return `${source}
|
|
3908
|
+
|
|
3909
|
+
${attachmentInput}`;
|
|
3910
|
+
}
|
|
3759
3911
|
async refreshCapabilityConfigBeforeClientControl(params) {
|
|
3760
3912
|
const refreshed = await this.getCapabilityConfigWithTelemetry(true, params.options);
|
|
3761
3913
|
return {
|
|
@@ -3765,9 +3917,14 @@ var AgentID = class {
|
|
|
3765
3917
|
}
|
|
3766
3918
|
async applyLocalPolicyChecks(params) {
|
|
3767
3919
|
const localScanStartedAt = Date.now();
|
|
3768
|
-
|
|
3920
|
+
const promptScanInput = this.buildPromptInjectionScanInput({
|
|
3921
|
+
input: params.input,
|
|
3922
|
+
promptContext: params.promptContext,
|
|
3923
|
+
capabilityConfig: params.capabilityConfig
|
|
3924
|
+
});
|
|
3925
|
+
if (params.runPromptInjectionCheck && promptScanInput && this.shouldRunLocalInjectionScan(params.capabilityConfig)) {
|
|
3769
3926
|
await this.injectionScanner.scan({
|
|
3770
|
-
prompt:
|
|
3927
|
+
prompt: promptScanInput,
|
|
3771
3928
|
apiKey: params.apiKey,
|
|
3772
3929
|
baseUrl: this.baseUrl,
|
|
3773
3930
|
aiScanEnabled: this.aiScanEnabled,
|
|
@@ -3794,6 +3951,9 @@ var AgentID = class {
|
|
|
3794
3951
|
});
|
|
3795
3952
|
const sdkLocalScanMs = Math.max(0, Date.now() - localScanStartedAt);
|
|
3796
3953
|
for (const event of enforced.events) {
|
|
3954
|
+
if (event.violationType === "PII_LEAKAGE_STRICT" && event.actionTaken === "REDACTED") {
|
|
3955
|
+
continue;
|
|
3956
|
+
}
|
|
3797
3957
|
this.logSecurityPolicyViolation({
|
|
3798
3958
|
systemId: params.systemId,
|
|
3799
3959
|
violationType: event.violationType,
|
|
@@ -3805,7 +3965,9 @@ var AgentID = class {
|
|
|
3805
3965
|
});
|
|
3806
3966
|
}
|
|
3807
3967
|
return {
|
|
3808
|
-
sanitizedInput: enforced.
|
|
3968
|
+
sanitizedInput: enforced.events.some(
|
|
3969
|
+
(event) => event.violationType === "PII_LEAKAGE_STRICT" && event.actionTaken === "REDACTED"
|
|
3970
|
+
) ? params.input : enforced.sanitizedInput,
|
|
3809
3971
|
sdkLocalScanMs
|
|
3810
3972
|
};
|
|
3811
3973
|
} catch (error) {
|
|
@@ -3841,22 +4003,6 @@ var AgentID = class {
|
|
|
3841
4003
|
sdkConfigFetchMs = refreshed.sdkConfigFetchMs;
|
|
3842
4004
|
}
|
|
3843
4005
|
if (!this.clientFastFail) {
|
|
3844
|
-
const effectivePiiMasking2 = this.resolveEffectivePiiMasking(capabilityConfig);
|
|
3845
|
-
const effectiveSecretMasking2 = this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3846
|
-
if (!capabilityConfig.block_pii_leakage && effectivePiiMasking2 || !capabilityConfig.block_secret_leakage && effectiveSecretMasking2) {
|
|
3847
|
-
const masked = this.pii.anonymize(sanitizedInput, {
|
|
3848
|
-
pii: !capabilityConfig.block_pii_leakage && effectivePiiMasking2,
|
|
3849
|
-
secrets: !capabilityConfig.block_secret_leakage && effectiveSecretMasking2
|
|
3850
|
-
});
|
|
3851
|
-
return {
|
|
3852
|
-
sanitizedInput: masked.maskedText,
|
|
3853
|
-
capabilityConfig,
|
|
3854
|
-
sdkConfigFetchMs,
|
|
3855
|
-
sdkLocalScanMs,
|
|
3856
|
-
piiMapping: masked.mapping,
|
|
3857
|
-
shouldDeanonymize: Object.keys(masked.mapping).length > 0
|
|
3858
|
-
};
|
|
3859
|
-
}
|
|
3860
4006
|
return {
|
|
3861
4007
|
sanitizedInput,
|
|
3862
4008
|
capabilityConfig,
|
|
@@ -3873,6 +4019,7 @@ var AgentID = class {
|
|
|
3873
4019
|
sdkConfigFetchMs = refreshedConfig.sdkConfigFetchMs;
|
|
3874
4020
|
const enforced = await this.applyLocalPolicyChecks({
|
|
3875
4021
|
input: params.input,
|
|
4022
|
+
promptContext: params.promptContext,
|
|
3876
4023
|
systemId: params.systemId,
|
|
3877
4024
|
stream: params.stream,
|
|
3878
4025
|
capabilityConfig,
|
|
@@ -3884,22 +4031,6 @@ var AgentID = class {
|
|
|
3884
4031
|
});
|
|
3885
4032
|
sanitizedInput = enforced.sanitizedInput;
|
|
3886
4033
|
sdkLocalScanMs = enforced.sdkLocalScanMs;
|
|
3887
|
-
const effectivePiiMasking = this.resolveEffectivePiiMasking(capabilityConfig);
|
|
3888
|
-
const effectiveSecretMasking = this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3889
|
-
if (!capabilityConfig.block_pii_leakage && effectivePiiMasking || !capabilityConfig.block_secret_leakage && effectiveSecretMasking) {
|
|
3890
|
-
const masked = this.pii.anonymize(sanitizedInput, {
|
|
3891
|
-
pii: !capabilityConfig.block_pii_leakage && effectivePiiMasking,
|
|
3892
|
-
secrets: !capabilityConfig.block_secret_leakage && effectiveSecretMasking
|
|
3893
|
-
});
|
|
3894
|
-
return {
|
|
3895
|
-
sanitizedInput: masked.maskedText,
|
|
3896
|
-
capabilityConfig,
|
|
3897
|
-
sdkConfigFetchMs,
|
|
3898
|
-
sdkLocalScanMs,
|
|
3899
|
-
piiMapping: masked.mapping,
|
|
3900
|
-
shouldDeanonymize: Object.keys(masked.mapping).length > 0
|
|
3901
|
-
};
|
|
3902
|
-
}
|
|
3903
4034
|
return {
|
|
3904
4035
|
sanitizedInput,
|
|
3905
4036
|
capabilityConfig,
|
|
@@ -3920,6 +4051,7 @@ var AgentID = class {
|
|
|
3920
4051
|
});
|
|
3921
4052
|
const enforced = await this.applyLocalPolicyChecks({
|
|
3922
4053
|
input: params.input,
|
|
4054
|
+
promptContext: params.promptContext,
|
|
3923
4055
|
systemId: params.systemId,
|
|
3924
4056
|
stream: params.stream,
|
|
3925
4057
|
capabilityConfig: refreshedConfig.capabilityConfig,
|
|
@@ -3936,77 +4068,71 @@ var AgentID = class {
|
|
|
3936
4068
|
sdkLocalScanMs: enforced.sdkLocalScanMs
|
|
3937
4069
|
};
|
|
3938
4070
|
}
|
|
4071
|
+
async runLocalPromptInjectionFallback(params, options) {
|
|
4072
|
+
const effectiveApiKey = this.resolveApiKey(options?.apiKey);
|
|
4073
|
+
const resolvedConfig = params.capabilityConfig && typeof params.sdkConfigFetchMs === "number" ? {
|
|
4074
|
+
capabilityConfig: params.capabilityConfig,
|
|
4075
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs
|
|
4076
|
+
} : await this.getCapabilityConfigWithTelemetry(false, options);
|
|
4077
|
+
const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
|
|
4078
|
+
capabilityConfig: resolvedConfig.capabilityConfig,
|
|
4079
|
+
sdkConfigFetchMs: resolvedConfig.sdkConfigFetchMs,
|
|
4080
|
+
options
|
|
4081
|
+
});
|
|
4082
|
+
const localScanStartedAt = Date.now();
|
|
4083
|
+
const promptScanInput = this.buildPromptInjectionScanInput({
|
|
4084
|
+
input: params.input,
|
|
4085
|
+
promptContext: params.promptContext,
|
|
4086
|
+
capabilityConfig: refreshedConfig.capabilityConfig,
|
|
4087
|
+
attachments: params.attachments
|
|
4088
|
+
});
|
|
4089
|
+
if (promptScanInput && this.shouldRunLocalInjectionScan(refreshedConfig.capabilityConfig)) {
|
|
4090
|
+
await this.injectionScanner.scan({
|
|
4091
|
+
prompt: promptScanInput,
|
|
4092
|
+
apiKey: effectiveApiKey,
|
|
4093
|
+
baseUrl: this.baseUrl,
|
|
4094
|
+
aiScanEnabled: this.aiScanEnabled,
|
|
4095
|
+
storePii: this.storePii,
|
|
4096
|
+
piiManager: this.pii,
|
|
4097
|
+
source: "js_sdk",
|
|
4098
|
+
systemId: params.systemId,
|
|
4099
|
+
eventId: params.clientEventId,
|
|
4100
|
+
clientEventId: params.clientEventId,
|
|
4101
|
+
telemetryMetadata: mergeTelemetryContexts(
|
|
4102
|
+
params.telemetryMetadata,
|
|
4103
|
+
buildSdkTimingMetadata({
|
|
4104
|
+
sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs,
|
|
4105
|
+
sdkConfigVersion: refreshedConfig.capabilityConfig.version
|
|
4106
|
+
})
|
|
4107
|
+
)
|
|
4108
|
+
});
|
|
4109
|
+
}
|
|
4110
|
+
return {
|
|
4111
|
+
capabilityConfig: refreshedConfig.capabilityConfig,
|
|
4112
|
+
sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs,
|
|
4113
|
+
sdkLocalScanMs: Math.max(0, Date.now() - localScanStartedAt)
|
|
4114
|
+
};
|
|
4115
|
+
}
|
|
3939
4116
|
async scanPromptInjection(input, options) {
|
|
3940
4117
|
if (!input) {
|
|
3941
4118
|
return;
|
|
3942
4119
|
}
|
|
3943
|
-
|
|
3944
|
-
|
|
4120
|
+
await this.runLocalPromptInjectionFallback(
|
|
4121
|
+
{
|
|
4122
|
+
input,
|
|
4123
|
+
attachments: options?.attachments,
|
|
4124
|
+
systemId: options?.systemId,
|
|
4125
|
+
clientEventId: options?.clientEventId
|
|
4126
|
+
},
|
|
3945
4127
|
options
|
|
3946
4128
|
);
|
|
3947
|
-
const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
|
|
3948
|
-
capabilityConfig: initialConfig.capabilityConfig,
|
|
3949
|
-
sdkConfigFetchMs: initialConfig.sdkConfigFetchMs,
|
|
3950
|
-
options
|
|
3951
|
-
});
|
|
3952
|
-
if (!this.shouldRunLocalInjectionScan(refreshedConfig.capabilityConfig)) {
|
|
3953
|
-
return;
|
|
3954
|
-
}
|
|
3955
|
-
const effectiveApiKey = this.resolveApiKey(options?.apiKey);
|
|
3956
|
-
await this.injectionScanner.scan({
|
|
3957
|
-
prompt: input,
|
|
3958
|
-
apiKey: effectiveApiKey,
|
|
3959
|
-
baseUrl: this.baseUrl,
|
|
3960
|
-
aiScanEnabled: this.aiScanEnabled,
|
|
3961
|
-
storePii: this.storePii,
|
|
3962
|
-
piiManager: this.pii,
|
|
3963
|
-
source: "js_sdk",
|
|
3964
|
-
systemId: options?.systemId,
|
|
3965
|
-
eventId: options?.clientEventId,
|
|
3966
|
-
clientEventId: options?.clientEventId,
|
|
3967
|
-
telemetryMetadata: buildSdkTimingMetadata({
|
|
3968
|
-
sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs,
|
|
3969
|
-
sdkConfigVersion: refreshedConfig.capabilityConfig.version
|
|
3970
|
-
})
|
|
3971
|
-
});
|
|
3972
4129
|
}
|
|
3973
|
-
withMaskedOpenAIRequest(req, maskedText
|
|
4130
|
+
withMaskedOpenAIRequest(req, maskedText) {
|
|
3974
4131
|
const messages = Array.isArray(req?.messages) ? req.messages : null;
|
|
3975
4132
|
if (!messages) {
|
|
3976
4133
|
return req;
|
|
3977
4134
|
}
|
|
3978
|
-
const newMessages = messages.map((message2) =>
|
|
3979
|
-
if (!message2 || typeof message2 !== "object") {
|
|
3980
|
-
return message2;
|
|
3981
|
-
}
|
|
3982
|
-
const typedMessage = message2;
|
|
3983
|
-
const currentContent2 = typedMessage.content;
|
|
3984
|
-
if (typeof currentContent2 === "string") {
|
|
3985
|
-
return {
|
|
3986
|
-
...typedMessage,
|
|
3987
|
-
content: this.pii.anonymize(currentContent2, options).maskedText
|
|
3988
|
-
};
|
|
3989
|
-
}
|
|
3990
|
-
if (Array.isArray(currentContent2)) {
|
|
3991
|
-
return {
|
|
3992
|
-
...typedMessage,
|
|
3993
|
-
content: currentContent2.map((part) => {
|
|
3994
|
-
if (!part || typeof part !== "object") {
|
|
3995
|
-
return part;
|
|
3996
|
-
}
|
|
3997
|
-
const typedPart = part;
|
|
3998
|
-
if (typeof typedPart.text !== "string") {
|
|
3999
|
-
return part;
|
|
4000
|
-
}
|
|
4001
|
-
return {
|
|
4002
|
-
...typedPart,
|
|
4003
|
-
text: this.pii.anonymize(typedPart.text, options).maskedText
|
|
4004
|
-
};
|
|
4005
|
-
})
|
|
4006
|
-
};
|
|
4007
|
-
}
|
|
4008
|
-
return message2;
|
|
4009
|
-
});
|
|
4135
|
+
const newMessages = messages.map((message2) => message2);
|
|
4010
4136
|
let lastUserIdx = null;
|
|
4011
4137
|
for (let i = 0; i < newMessages.length; i += 1) {
|
|
4012
4138
|
const msg = newMessages[i];
|
|
@@ -4040,7 +4166,7 @@ var AgentID = class {
|
|
|
4040
4166
|
text: maskedText
|
|
4041
4167
|
});
|
|
4042
4168
|
}
|
|
4043
|
-
nextContent = textReplaced ? preservedParts : [{ type: "text", text: maskedText }, ...currentContent];
|
|
4169
|
+
nextContent = textReplaced ? preservedParts : maskedText.length > 0 ? [{ type: "text", text: maskedText }, ...currentContent] : currentContent;
|
|
4044
4170
|
}
|
|
4045
4171
|
newMessages[lastUserIdx] = {
|
|
4046
4172
|
...message,
|
|
@@ -4057,7 +4183,7 @@ var AgentID = class {
|
|
|
4057
4183
|
logSecurityPolicyViolation(params) {
|
|
4058
4184
|
this.log({
|
|
4059
4185
|
system_id: params.systemId,
|
|
4060
|
-
input: "[
|
|
4186
|
+
input: "[REDACTED]",
|
|
4061
4187
|
output: "",
|
|
4062
4188
|
model: "agentid.policy.enforcer",
|
|
4063
4189
|
event_type: "security_policy_violation",
|
|
@@ -4068,7 +4194,7 @@ var AgentID = class {
|
|
|
4068
4194
|
severity: "high",
|
|
4069
4195
|
system_id: params.systemId,
|
|
4070
4196
|
violation_type: params.violationType,
|
|
4071
|
-
input_snippet: "[
|
|
4197
|
+
input_snippet: "[REDACTED]",
|
|
4072
4198
|
action_taken: params.actionTaken,
|
|
4073
4199
|
...buildSdkTimingMetadata({
|
|
4074
4200
|
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
@@ -4081,17 +4207,19 @@ var AgentID = class {
|
|
|
4081
4207
|
}, { apiKey: params.apiKey });
|
|
4082
4208
|
}
|
|
4083
4209
|
logGuardFallback(params) {
|
|
4210
|
+
const retainedInput = getZeroRetentionInput(params.guardParams.input, void 0);
|
|
4084
4211
|
this.log(
|
|
4085
4212
|
{
|
|
4086
4213
|
system_id: params.guardParams.system_id,
|
|
4087
4214
|
user_id: params.guardParams.user_id,
|
|
4088
|
-
input:
|
|
4215
|
+
input: retainedInput,
|
|
4089
4216
|
output: "",
|
|
4090
4217
|
model: params.guardParams.model ?? "unknown",
|
|
4091
4218
|
event_type: "security_alert",
|
|
4092
4219
|
severity: "warning",
|
|
4093
4220
|
metadata: {
|
|
4094
4221
|
...params.guardParams.metadata ?? {},
|
|
4222
|
+
transformed_input: retainedInput,
|
|
4095
4223
|
source: "guard",
|
|
4096
4224
|
status: params.status,
|
|
4097
4225
|
guard_reason: params.reason,
|
|
@@ -4163,98 +4291,122 @@ var AgentID = class {
|
|
|
4163
4291
|
...params,
|
|
4164
4292
|
client_capabilities: params.client_capabilities ?? this.buildClientCapabilities()
|
|
4165
4293
|
};
|
|
4166
|
-
const guardCacheKey = this.buildGuardCacheKey(payload);
|
|
4294
|
+
const guardCacheKey = this.buildGuardCacheKey(payload, effectiveApiKey);
|
|
4167
4295
|
const cachedVerdict = this.readCachedGuardVerdict(guardCacheKey);
|
|
4168
4296
|
if (cachedVerdict) {
|
|
4169
4297
|
return withGuardLatency(cachedVerdict);
|
|
4170
4298
|
}
|
|
4171
|
-
const
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
const
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
"
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
if (
|
|
4299
|
+
const pendingGuardRequest = guardCacheKey ? this.pendingGuardRequests.get(guardCacheKey) : void 0;
|
|
4300
|
+
if (pendingGuardRequest) {
|
|
4301
|
+
return withGuardLatency(await pendingGuardRequest.promise);
|
|
4302
|
+
}
|
|
4303
|
+
const executeGuardRequest = async () => {
|
|
4304
|
+
const correlationId = createCorrelationId(payload.client_event_id);
|
|
4305
|
+
let lastStatusCode = null;
|
|
4306
|
+
let lastAbort = false;
|
|
4307
|
+
let lastError = null;
|
|
4308
|
+
for (let attempt = 0; attempt < GUARD_MAX_ATTEMPTS; attempt += 1) {
|
|
4309
|
+
const controller = new AbortController();
|
|
4310
|
+
const timeoutId = setTimeout(() => controller.abort(), this.guardTimeoutMs);
|
|
4311
|
+
try {
|
|
4312
|
+
const res = await fetch(`${this.baseUrl}/guard`, {
|
|
4313
|
+
method: "POST",
|
|
4314
|
+
headers: {
|
|
4315
|
+
"Content-Type": "application/json",
|
|
4316
|
+
"x-agentid-api-key": effectiveApiKey,
|
|
4317
|
+
"X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER,
|
|
4318
|
+
"x-correlation-id": correlationId
|
|
4319
|
+
},
|
|
4320
|
+
body: JSON.stringify(payload),
|
|
4321
|
+
signal: controller.signal
|
|
4322
|
+
});
|
|
4323
|
+
lastStatusCode = res.status;
|
|
4324
|
+
const responseBody = await safeReadJson2(res);
|
|
4325
|
+
if (responseBody && typeof responseBody.allowed === "boolean") {
|
|
4326
|
+
const rawVerdict = responseBody;
|
|
4327
|
+
const transparency = coerceTransparencyMetadata(rawVerdict.transparency);
|
|
4328
|
+
const verdict = {
|
|
4329
|
+
...rawVerdict,
|
|
4330
|
+
...transparency ? { transparency } : {}
|
|
4331
|
+
};
|
|
4332
|
+
const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || !verdict.reason && res.status >= 500);
|
|
4333
|
+
if (infrastructureFailure) {
|
|
4334
|
+
if (attempt < GUARD_MAX_ATTEMPTS - 1) {
|
|
4335
|
+
await waitForRetry(attempt);
|
|
4336
|
+
continue;
|
|
4337
|
+
}
|
|
4338
|
+
if (effectiveStrictMode) {
|
|
4339
|
+
console.warn(
|
|
4340
|
+
`[AgentID] Guard API infrastructure failure in strict mode (${verdict.reason ?? `http_${res.status}`}). Blocking request.`
|
|
4341
|
+
);
|
|
4342
|
+
return withGuardLatency({
|
|
4343
|
+
allowed: false,
|
|
4344
|
+
reason: verdict.reason ?? "network_error_strict_mode"
|
|
4345
|
+
});
|
|
4346
|
+
}
|
|
4206
4347
|
console.warn(
|
|
4207
|
-
`[AgentID] Guard API infrastructure
|
|
4348
|
+
`[AgentID] Guard API infrastructure fallback in fail-open mode (${verdict.reason ?? `http_${res.status}`}).`
|
|
4208
4349
|
);
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4350
|
+
this.logGuardFallback({
|
|
4351
|
+
reason: verdict.reason ?? `http_${res.status}`,
|
|
4352
|
+
status: "upstream_error",
|
|
4353
|
+
guardParams: params,
|
|
4354
|
+
apiKey: effectiveApiKey
|
|
4212
4355
|
});
|
|
4356
|
+
return withGuardLatency(
|
|
4357
|
+
this.buildFailOpenGuardVerdict(
|
|
4358
|
+
"system_failure_fail_open",
|
|
4359
|
+
params.input,
|
|
4360
|
+
{ apiKey: effectiveApiKey }
|
|
4361
|
+
)
|
|
4362
|
+
);
|
|
4213
4363
|
}
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4364
|
+
this.cacheGuardVerdict(guardCacheKey, verdict);
|
|
4365
|
+
return withGuardLatency(verdict);
|
|
4366
|
+
}
|
|
4367
|
+
if (!res.ok) {
|
|
4368
|
+
if (res.status >= 500 && attempt < GUARD_MAX_ATTEMPTS - 1) {
|
|
4369
|
+
await waitForRetry(attempt);
|
|
4370
|
+
continue;
|
|
4371
|
+
}
|
|
4372
|
+
throw new Error(`API Error ${res.status}`);
|
|
4373
|
+
}
|
|
4374
|
+
throw new Error("Invalid guard response");
|
|
4375
|
+
} catch (error) {
|
|
4376
|
+
lastError = error;
|
|
4377
|
+
const isAbortError2 = Boolean(
|
|
4378
|
+
error && typeof error === "object" && error.name === "AbortError"
|
|
4379
|
+
);
|
|
4380
|
+
lastAbort = isAbortError2;
|
|
4381
|
+
if (attempt < GUARD_MAX_ATTEMPTS - 1) {
|
|
4382
|
+
await waitForRetry(attempt);
|
|
4383
|
+
continue;
|
|
4384
|
+
}
|
|
4385
|
+
if (isAbortError2) {
|
|
4386
|
+
const timeoutMessage = "AgentID API Warning: Connection timeout exceeded.";
|
|
4387
|
+
console.warn(timeoutMessage);
|
|
4217
4388
|
this.logGuardFallback({
|
|
4218
|
-
reason:
|
|
4219
|
-
status: "
|
|
4389
|
+
reason: "timeout_fallback",
|
|
4390
|
+
status: "latency_timeout",
|
|
4220
4391
|
guardParams: params,
|
|
4221
4392
|
apiKey: effectiveApiKey
|
|
4222
4393
|
});
|
|
4394
|
+
if (effectiveStrictMode) {
|
|
4395
|
+
return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
|
|
4396
|
+
}
|
|
4223
4397
|
return withGuardLatency(
|
|
4224
|
-
this.buildFailOpenGuardVerdict(
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
{ apiKey: effectiveApiKey }
|
|
4228
|
-
)
|
|
4398
|
+
this.buildFailOpenGuardVerdict("timeout_fallback", params.input, {
|
|
4399
|
+
apiKey: effectiveApiKey
|
|
4400
|
+
})
|
|
4229
4401
|
);
|
|
4230
4402
|
}
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
if (res.status >= 500 && attempt < GUARD_MAX_ATTEMPTS - 1) {
|
|
4236
|
-
await waitForRetry(attempt);
|
|
4237
|
-
continue;
|
|
4238
|
-
}
|
|
4239
|
-
throw new Error(`API Error ${res.status}`);
|
|
4240
|
-
}
|
|
4241
|
-
throw new Error("Invalid guard response");
|
|
4242
|
-
} catch (error) {
|
|
4243
|
-
lastError = error;
|
|
4244
|
-
const isAbortError2 = Boolean(
|
|
4245
|
-
error && typeof error === "object" && error.name === "AbortError"
|
|
4246
|
-
);
|
|
4247
|
-
lastAbort = isAbortError2;
|
|
4248
|
-
if (attempt < GUARD_MAX_ATTEMPTS - 1) {
|
|
4249
|
-
await waitForRetry(attempt);
|
|
4250
|
-
continue;
|
|
4251
|
-
}
|
|
4252
|
-
if (isAbortError2) {
|
|
4253
|
-
const timeoutMessage = "AgentID API Warning: Connection timeout exceeded.";
|
|
4254
|
-
console.warn(timeoutMessage);
|
|
4403
|
+
console.warn(
|
|
4404
|
+
effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
|
|
4405
|
+
error
|
|
4406
|
+
);
|
|
4255
4407
|
this.logGuardFallback({
|
|
4256
|
-
reason: "
|
|
4257
|
-
status: "
|
|
4408
|
+
reason: "guard_unreachable",
|
|
4409
|
+
status: "guard_unreachable",
|
|
4258
4410
|
guardParams: params,
|
|
4259
4411
|
apiKey: effectiveApiKey
|
|
4260
4412
|
});
|
|
@@ -4262,67 +4414,62 @@ var AgentID = class {
|
|
|
4262
4414
|
return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
|
|
4263
4415
|
}
|
|
4264
4416
|
return withGuardLatency(
|
|
4265
|
-
this.buildFailOpenGuardVerdict("
|
|
4417
|
+
this.buildFailOpenGuardVerdict("guard_unreachable", params.input, {
|
|
4266
4418
|
apiKey: effectiveApiKey
|
|
4267
4419
|
})
|
|
4268
4420
|
);
|
|
4421
|
+
} finally {
|
|
4422
|
+
clearTimeout(timeoutId);
|
|
4269
4423
|
}
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
error
|
|
4273
|
-
);
|
|
4274
|
-
this.logGuardFallback({
|
|
4275
|
-
reason: "guard_unreachable",
|
|
4276
|
-
status: "guard_unreachable",
|
|
4277
|
-
guardParams: params,
|
|
4278
|
-
apiKey: effectiveApiKey
|
|
4279
|
-
});
|
|
4424
|
+
}
|
|
4425
|
+
if (lastAbort) {
|
|
4280
4426
|
if (effectiveStrictMode) {
|
|
4281
4427
|
return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
|
|
4282
4428
|
}
|
|
4283
4429
|
return withGuardLatency(
|
|
4284
|
-
this.buildFailOpenGuardVerdict("
|
|
4430
|
+
this.buildFailOpenGuardVerdict("timeout_fallback", params.input, {
|
|
4285
4431
|
apiKey: effectiveApiKey
|
|
4286
4432
|
})
|
|
4287
4433
|
);
|
|
4288
|
-
} finally {
|
|
4289
|
-
clearTimeout(timeoutId);
|
|
4290
4434
|
}
|
|
4291
|
-
|
|
4292
|
-
|
|
4435
|
+
if (typeof lastStatusCode === "number" && lastStatusCode >= 500) {
|
|
4436
|
+
if (effectiveStrictMode) {
|
|
4437
|
+
return withGuardLatency({ allowed: false, reason: "server_error" });
|
|
4438
|
+
}
|
|
4439
|
+
return withGuardLatency(
|
|
4440
|
+
this.buildFailOpenGuardVerdict(
|
|
4441
|
+
"system_failure_fail_open",
|
|
4442
|
+
params.input,
|
|
4443
|
+
{ apiKey: effectiveApiKey }
|
|
4444
|
+
)
|
|
4445
|
+
);
|
|
4446
|
+
}
|
|
4447
|
+
console.warn(
|
|
4448
|
+
effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
|
|
4449
|
+
lastError
|
|
4450
|
+
);
|
|
4293
4451
|
if (effectiveStrictMode) {
|
|
4294
4452
|
return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
|
|
4295
4453
|
}
|
|
4296
4454
|
return withGuardLatency(
|
|
4297
|
-
this.buildFailOpenGuardVerdict("
|
|
4455
|
+
this.buildFailOpenGuardVerdict("guard_unreachable", params.input, {
|
|
4298
4456
|
apiKey: effectiveApiKey
|
|
4299
4457
|
})
|
|
4300
4458
|
);
|
|
4459
|
+
};
|
|
4460
|
+
if (!guardCacheKey) {
|
|
4461
|
+
return executeGuardRequest();
|
|
4301
4462
|
}
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4463
|
+
const promise = executeGuardRequest();
|
|
4464
|
+
this.pendingGuardRequests.set(guardCacheKey, { promise });
|
|
4465
|
+
try {
|
|
4466
|
+
return await promise;
|
|
4467
|
+
} finally {
|
|
4468
|
+
const pending = this.pendingGuardRequests.get(guardCacheKey);
|
|
4469
|
+
if (pending?.promise === promise) {
|
|
4470
|
+
this.pendingGuardRequests.delete(guardCacheKey);
|
|
4305
4471
|
}
|
|
4306
|
-
return withGuardLatency(
|
|
4307
|
-
this.buildFailOpenGuardVerdict(
|
|
4308
|
-
"system_failure_fail_open",
|
|
4309
|
-
params.input,
|
|
4310
|
-
{ apiKey: effectiveApiKey }
|
|
4311
|
-
)
|
|
4312
|
-
);
|
|
4313
4472
|
}
|
|
4314
|
-
console.warn(
|
|
4315
|
-
effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
|
|
4316
|
-
lastError
|
|
4317
|
-
);
|
|
4318
|
-
if (effectiveStrictMode) {
|
|
4319
|
-
return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
|
|
4320
|
-
}
|
|
4321
|
-
return withGuardLatency(
|
|
4322
|
-
this.buildFailOpenGuardVerdict("guard_unreachable", params.input, {
|
|
4323
|
-
apiKey: effectiveApiKey
|
|
4324
|
-
})
|
|
4325
|
-
);
|
|
4326
4473
|
}
|
|
4327
4474
|
async sendIngest(params, options, internal) {
|
|
4328
4475
|
const ingestStartedAt = Date.now();
|
|
@@ -4566,11 +4713,12 @@ var AgentID = class {
|
|
|
4566
4713
|
completion,
|
|
4567
4714
|
options?.piiMapping
|
|
4568
4715
|
);
|
|
4716
|
+
const transformedOutput = options?.deanonymizeForClient === true && options.piiMapping ? this.pii.deanonymize(completion, options.piiMapping) : masked.maskedText;
|
|
4569
4717
|
return {
|
|
4570
4718
|
mode: "static",
|
|
4571
4719
|
rawOutput: completion,
|
|
4572
|
-
transformedOutput
|
|
4573
|
-
outputMasked:
|
|
4720
|
+
transformedOutput,
|
|
4721
|
+
outputMasked: transformedOutput !== completion || placeholderOutputMasked
|
|
4574
4722
|
};
|
|
4575
4723
|
}
|
|
4576
4724
|
if (!isAsyncIterable(completion)) {
|
|
@@ -4580,11 +4728,12 @@ var AgentID = class {
|
|
|
4580
4728
|
asText,
|
|
4581
4729
|
options?.piiMapping
|
|
4582
4730
|
);
|
|
4731
|
+
const transformedOutput = options?.deanonymizeForClient === true && options.piiMapping ? this.pii.deanonymize(asText, options.piiMapping) : masked.maskedText;
|
|
4583
4732
|
return {
|
|
4584
4733
|
mode: "static",
|
|
4585
4734
|
rawOutput: asText,
|
|
4586
|
-
transformedOutput
|
|
4587
|
-
outputMasked:
|
|
4735
|
+
transformedOutput,
|
|
4736
|
+
outputMasked: transformedOutput !== asText || placeholderOutputMasked
|
|
4588
4737
|
};
|
|
4589
4738
|
}
|
|
4590
4739
|
const source = completion;
|
|
@@ -4779,6 +4928,7 @@ var AgentID = class {
|
|
|
4779
4928
|
*/
|
|
4780
4929
|
wrapOpenAI(openai, options) {
|
|
4781
4930
|
const systemId = options.system_id;
|
|
4931
|
+
const deanonymizeOutputForClient = options.deanonymizeOutputForClient === true || options.deanonymize_output_for_client === true;
|
|
4782
4932
|
const expectedLanguages = normalizeExpectedLanguages(
|
|
4783
4933
|
options.expected_languages ?? options.expectedLanguages
|
|
4784
4934
|
);
|
|
@@ -4819,38 +4969,48 @@ var AgentID = class {
|
|
|
4819
4969
|
const stream = adapter.isStream(providerReq);
|
|
4820
4970
|
let capabilityConfig = this.getCachedCapabilityConfig(requestOptions);
|
|
4821
4971
|
const userText = adapter.extractInput(providerReq);
|
|
4822
|
-
const
|
|
4972
|
+
const rawPromptContext = adapter.extractPromptContext(providerReq);
|
|
4973
|
+
let requestAttachments = adapter.extractAttachments(providerReq);
|
|
4823
4974
|
const hasGuardContent = userText !== null || requestAttachments.length > 0;
|
|
4824
4975
|
let maskedText = userText ?? "";
|
|
4825
4976
|
let maskedReq = providerReq;
|
|
4826
4977
|
let createArgs = providerReq === rawReq ? normalizedCreateArgs : [{ ...providerReq }, ...normalizedCreateArgs.slice(1)];
|
|
4827
4978
|
let mapping = {};
|
|
4979
|
+
let clientInputMaskingTelemetry = {
|
|
4980
|
+
piiApplied: false,
|
|
4981
|
+
secretApplied: false
|
|
4982
|
+
};
|
|
4828
4983
|
let sdkConfigFetchMs = 0;
|
|
4829
4984
|
let sdkLocalScanMs = 0;
|
|
4830
|
-
let providerMaskingOptions;
|
|
4831
4985
|
if (hasGuardContent) {
|
|
4832
4986
|
const prepared = await this.prepareInputForDispatch({
|
|
4833
4987
|
input: userText ?? "",
|
|
4988
|
+
promptContext: rawPromptContext ?? void 0,
|
|
4834
4989
|
systemId,
|
|
4835
4990
|
stream,
|
|
4836
4991
|
clientEventId,
|
|
4837
4992
|
telemetryMetadata
|
|
4838
4993
|
}, requestOptions);
|
|
4839
4994
|
capabilityConfig = prepared.capabilityConfig;
|
|
4840
|
-
providerMaskingOptions = {
|
|
4841
|
-
pii: !capabilityConfig.block_pii_leakage && this.resolveEffectivePiiMasking(capabilityConfig),
|
|
4842
|
-
secrets: !capabilityConfig.block_secret_leakage && this.resolveEffectiveSecretMasking(capabilityConfig)
|
|
4843
|
-
};
|
|
4844
4995
|
maskedText = prepared.sanitizedInput;
|
|
4845
|
-
|
|
4996
|
+
const preparedPiiMapping = normalizePiiMapping(prepared.piiMapping);
|
|
4997
|
+
const preparedMaskingTelemetry = getMaskingTelemetryFromMapping(
|
|
4998
|
+
preparedPiiMapping
|
|
4999
|
+
);
|
|
5000
|
+
clientInputMaskingTelemetry = {
|
|
5001
|
+
piiApplied: preparedMaskingTelemetry.piiApplied || maskedText !== (userText ?? ""),
|
|
5002
|
+
secretApplied: preparedMaskingTelemetry.secretApplied
|
|
5003
|
+
};
|
|
5004
|
+
mapping = preparedPiiMapping ?? {};
|
|
4846
5005
|
sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
|
|
4847
5006
|
sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
|
|
4848
|
-
|
|
5007
|
+
const shouldProtectRequestHistory = maskedText !== (userText ?? "");
|
|
5008
|
+
if (shouldProtectRequestHistory) {
|
|
4849
5009
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
4850
5010
|
providerReq,
|
|
4851
|
-
maskedText
|
|
4852
|
-
providerMaskingOptions
|
|
5011
|
+
maskedText
|
|
4853
5012
|
);
|
|
5013
|
+
requestAttachments = adapter.extractAttachments(maskedReq);
|
|
4854
5014
|
const nextCreateArgs = [...createArgs];
|
|
4855
5015
|
nextCreateArgs[0] = maskedReq;
|
|
4856
5016
|
createArgs = nextCreateArgs;
|
|
@@ -4861,8 +5021,16 @@ var AgentID = class {
|
|
|
4861
5021
|
"AgentID: No user message or supported inline attachment found. Security guard requires prompt content."
|
|
4862
5022
|
);
|
|
4863
5023
|
}
|
|
5024
|
+
const promptContextForGuard = adapter.extractPromptContext(maskedReq) ?? rawPromptContext ?? void 0;
|
|
5025
|
+
const clientCapabilities = this.buildClientCapabilities(
|
|
5026
|
+
"openai",
|
|
5027
|
+
false,
|
|
5028
|
+
capabilityConfig,
|
|
5029
|
+
clientInputMaskingTelemetry
|
|
5030
|
+
);
|
|
4864
5031
|
const verdict = await this.guard({
|
|
4865
5032
|
input: maskedText,
|
|
5033
|
+
prompt_context: promptContextForGuard,
|
|
4866
5034
|
system_id: systemId,
|
|
4867
5035
|
model: adapter.getModelName(maskedReq),
|
|
4868
5036
|
user_id: options.user_id,
|
|
@@ -4871,63 +5039,54 @@ var AgentID = class {
|
|
|
4871
5039
|
request_identity: options.request_identity,
|
|
4872
5040
|
metadata: telemetryMetadata,
|
|
4873
5041
|
attachments: requestAttachments,
|
|
4874
|
-
client_capabilities:
|
|
4875
|
-
"openai",
|
|
4876
|
-
false,
|
|
4877
|
-
capabilityConfig
|
|
4878
|
-
)
|
|
5042
|
+
client_capabilities: clientCapabilities
|
|
4879
5043
|
}, requestOptions);
|
|
4880
5044
|
let localFallbackApplied = false;
|
|
4881
5045
|
let localFallbackReason = null;
|
|
4882
5046
|
if (!verdict.allowed) {
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
requestOptions
|
|
4921
|
-
);
|
|
4922
|
-
throw new SecurityBlockError(verdict.reason ?? "guard_denied");
|
|
4923
|
-
}
|
|
5047
|
+
await this.logPromptPreflightStep(
|
|
5048
|
+
{
|
|
5049
|
+
system_id: systemId,
|
|
5050
|
+
user_id: options.user_id,
|
|
5051
|
+
request_identity: options.request_identity,
|
|
5052
|
+
input: getZeroRetentionInput(userText ?? "", maskedText),
|
|
5053
|
+
telemetry: telemetryMetadata,
|
|
5054
|
+
verdict,
|
|
5055
|
+
guard_event_id: verdict.guard_event_id ?? null,
|
|
5056
|
+
guard_latency_ms: typeof verdict.guard_latency_ms === "number" && Number.isFinite(verdict.guard_latency_ms) ? Math.max(0, Math.trunc(verdict.guard_latency_ms)) : Math.max(0, Date.now() - pipelineStartedAt),
|
|
5057
|
+
preflight_for_client_event_id: typeof verdict.client_event_id === "string" && isUuidLike2(verdict.client_event_id) ? verdict.client_event_id : clientEventId,
|
|
5058
|
+
client_capabilities: clientCapabilities,
|
|
5059
|
+
runtime_surface: "openai_sdk_guard"
|
|
5060
|
+
},
|
|
5061
|
+
requestOptions
|
|
5062
|
+
);
|
|
5063
|
+
throw new SecurityBlockError(verdict.reason ?? "guard_denied");
|
|
5064
|
+
}
|
|
5065
|
+
if (isFailOpenGuardBypassReason(verdict.reason)) {
|
|
5066
|
+
const fallback = await this.runLocalPromptInjectionFallback(
|
|
5067
|
+
{
|
|
5068
|
+
input: userText ?? "",
|
|
5069
|
+
promptContext: rawPromptContext ?? void 0,
|
|
5070
|
+
attachments: requestAttachments,
|
|
5071
|
+
systemId,
|
|
5072
|
+
clientEventId,
|
|
5073
|
+
capabilityConfig,
|
|
5074
|
+
sdkConfigFetchMs,
|
|
5075
|
+
telemetryMetadata
|
|
5076
|
+
},
|
|
5077
|
+
requestOptions
|
|
5078
|
+
);
|
|
5079
|
+
capabilityConfig = fallback.capabilityConfig;
|
|
5080
|
+
sdkConfigFetchMs = fallback.sdkConfigFetchMs;
|
|
5081
|
+
sdkLocalScanMs += fallback.sdkLocalScanMs;
|
|
5082
|
+
localFallbackApplied = true;
|
|
5083
|
+
localFallbackReason = verdict.reason ?? null;
|
|
4924
5084
|
}
|
|
4925
5085
|
const currentRequestInput = adapter.extractInput(maskedReq) ?? "";
|
|
4926
|
-
if (maskedText !== currentRequestInput
|
|
5086
|
+
if (maskedText !== currentRequestInput) {
|
|
4927
5087
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
4928
5088
|
providerReq,
|
|
4929
|
-
maskedText
|
|
4930
|
-
providerMaskingOptions
|
|
5089
|
+
maskedText
|
|
4931
5090
|
);
|
|
4932
5091
|
const nextCreateArgs = [...createArgs];
|
|
4933
5092
|
nextCreateArgs[0] = maskedReq;
|
|
@@ -4950,29 +5109,29 @@ var AgentID = class {
|
|
|
4950
5109
|
maskedText = transformedInput;
|
|
4951
5110
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
4952
5111
|
providerReq,
|
|
4953
|
-
transformedInput
|
|
4954
|
-
providerMaskingOptions
|
|
5112
|
+
transformedInput
|
|
4955
5113
|
);
|
|
4956
5114
|
const nextCreateArgs = [...createArgs];
|
|
4957
5115
|
nextCreateArgs[0] = maskedReq;
|
|
4958
5116
|
createArgs = nextCreateArgs;
|
|
4959
5117
|
}
|
|
5118
|
+
const shouldDeanonymizeForClient = deanonymizeOutputForClient && !isShadowMode && Object.keys(mapping).length > 0;
|
|
5119
|
+
const retainedInputForLogs = getZeroRetentionInput(
|
|
5120
|
+
userText ?? "",
|
|
5121
|
+
maskedText
|
|
5122
|
+
);
|
|
4960
5123
|
await this.logPromptPreflightStep(
|
|
4961
5124
|
{
|
|
4962
5125
|
system_id: systemId,
|
|
4963
5126
|
user_id: options.user_id,
|
|
4964
5127
|
request_identity: options.request_identity,
|
|
4965
|
-
input:
|
|
5128
|
+
input: retainedInputForLogs,
|
|
4966
5129
|
telemetry: telemetryMetadata,
|
|
4967
5130
|
verdict,
|
|
4968
5131
|
guard_event_id: guardEventId,
|
|
4969
5132
|
guard_latency_ms: guardLatencyMs,
|
|
4970
5133
|
preflight_for_client_event_id: canonicalClientEventId,
|
|
4971
|
-
client_capabilities:
|
|
4972
|
-
"openai",
|
|
4973
|
-
false,
|
|
4974
|
-
capabilityConfig
|
|
4975
|
-
),
|
|
5134
|
+
client_capabilities: clientCapabilities,
|
|
4976
5135
|
local_fallback_applied: localFallbackApplied,
|
|
4977
5136
|
local_fallback_reason: localFallbackReason,
|
|
4978
5137
|
runtime_surface: "openai_sdk_guard"
|
|
@@ -4990,12 +5149,13 @@ var AgentID = class {
|
|
|
4990
5149
|
})(),
|
|
4991
5150
|
{
|
|
4992
5151
|
piiMapping: mapping,
|
|
4993
|
-
deanonymizeForClient:
|
|
4994
|
-
maskForClient: !isShadowMode
|
|
5152
|
+
deanonymizeForClient: shouldDeanonymizeForClient,
|
|
5153
|
+
maskForClient: !isShadowMode && !shouldDeanonymizeForClient
|
|
4995
5154
|
}
|
|
4996
5155
|
);
|
|
4997
5156
|
if (maskedText && wrappedCompletion.mode === "stream") {
|
|
4998
5157
|
void wrappedCompletion.done.then(async (result) => {
|
|
5158
|
+
const effectiveInputMaskingTelemetry = getMaskingTelemetryFromMapping(mapping);
|
|
4999
5159
|
const modelLatencyMs2 = Math.max(0, Date.now() - modelStartedAt2);
|
|
5000
5160
|
const totalPipelineLatencyMs2 = Math.max(0, Date.now() - pipelineStartedAt);
|
|
5001
5161
|
const outputForLog = result.transformedOutput;
|
|
@@ -5004,7 +5164,7 @@ var AgentID = class {
|
|
|
5004
5164
|
system_id: systemId,
|
|
5005
5165
|
user_id: options.user_id,
|
|
5006
5166
|
request_identity: options.request_identity,
|
|
5007
|
-
input:
|
|
5167
|
+
input: retainedInputForLogs,
|
|
5008
5168
|
output: outputForLog,
|
|
5009
5169
|
model: adapter.getModelName(maskedReq),
|
|
5010
5170
|
usage: result.usage,
|
|
@@ -5013,9 +5173,17 @@ var AgentID = class {
|
|
|
5013
5173
|
metadata: mergeTelemetryContexts(
|
|
5014
5174
|
telemetryMetadata,
|
|
5015
5175
|
{
|
|
5016
|
-
transformed_input:
|
|
5176
|
+
transformed_input: retainedInputForLogs,
|
|
5017
5177
|
transformed_output: result.transformedOutput,
|
|
5018
5178
|
output_masked: result.outputMasked,
|
|
5179
|
+
client_side_pii_masking_applied: clientInputMaskingTelemetry.piiApplied,
|
|
5180
|
+
client_side_secret_masking_applied: clientInputMaskingTelemetry.secretApplied,
|
|
5181
|
+
server_side_pii_masking_applied: effectiveInputMaskingTelemetry.piiApplied && !clientInputMaskingTelemetry.piiApplied,
|
|
5182
|
+
server_side_secret_masking_applied: effectiveInputMaskingTelemetry.secretApplied && !clientInputMaskingTelemetry.secretApplied,
|
|
5183
|
+
effective_pii_masking_applied: effectiveInputMaskingTelemetry.piiApplied,
|
|
5184
|
+
effective_secret_masking_applied: effectiveInputMaskingTelemetry.secretApplied,
|
|
5185
|
+
effective_input_was_transformed: retainedInputForLogs !== "[REDACTED]",
|
|
5186
|
+
effective_output_was_transformed: result.outputMasked,
|
|
5019
5187
|
shadow_mode: isShadowMode,
|
|
5020
5188
|
simulated_decision: verdict.simulated_decision ?? null,
|
|
5021
5189
|
simulated_output_decision: isShadowMode && result.outputMasked ? "masked" : "allowed",
|
|
@@ -5036,11 +5204,7 @@ var AgentID = class {
|
|
|
5036
5204
|
sdkConfigVersion: capabilityConfig.version
|
|
5037
5205
|
})
|
|
5038
5206
|
),
|
|
5039
|
-
client_capabilities:
|
|
5040
|
-
"openai",
|
|
5041
|
-
false,
|
|
5042
|
-
capabilityConfig
|
|
5043
|
-
)
|
|
5207
|
+
client_capabilities: clientCapabilities
|
|
5044
5208
|
}, requestOptions);
|
|
5045
5209
|
if (!ingestResult.ok) {
|
|
5046
5210
|
this.maybeRaiseStrictIngestDependencyError({
|
|
@@ -5065,6 +5229,7 @@ var AgentID = class {
|
|
|
5065
5229
|
const modelLatencyMs = Math.max(0, Date.now() - modelStartedAt);
|
|
5066
5230
|
const totalPipelineLatencyMs = Math.max(0, Date.now() - pipelineStartedAt);
|
|
5067
5231
|
if (maskedText) {
|
|
5232
|
+
const effectiveInputMaskingTelemetry = getMaskingTelemetryFromMapping(mapping);
|
|
5068
5233
|
const output = adapter.extractOutput(res);
|
|
5069
5234
|
const wrappedCompletion = this.wrapCompletion(output, {
|
|
5070
5235
|
piiMapping: mapping,
|
|
@@ -5078,7 +5243,7 @@ var AgentID = class {
|
|
|
5078
5243
|
system_id: systemId,
|
|
5079
5244
|
user_id: options.user_id,
|
|
5080
5245
|
request_identity: options.request_identity,
|
|
5081
|
-
input:
|
|
5246
|
+
input: retainedInputForLogs,
|
|
5082
5247
|
output: outputForLog,
|
|
5083
5248
|
model,
|
|
5084
5249
|
usage,
|
|
@@ -5087,9 +5252,17 @@ var AgentID = class {
|
|
|
5087
5252
|
metadata: mergeTelemetryContexts(
|
|
5088
5253
|
telemetryMetadata,
|
|
5089
5254
|
{
|
|
5090
|
-
transformed_input:
|
|
5255
|
+
transformed_input: retainedInputForLogs,
|
|
5091
5256
|
transformed_output: wrappedCompletion.transformedOutput,
|
|
5092
5257
|
output_masked: wrappedCompletion.outputMasked,
|
|
5258
|
+
client_side_pii_masking_applied: clientInputMaskingTelemetry.piiApplied,
|
|
5259
|
+
client_side_secret_masking_applied: clientInputMaskingTelemetry.secretApplied,
|
|
5260
|
+
server_side_pii_masking_applied: effectiveInputMaskingTelemetry.piiApplied && !clientInputMaskingTelemetry.piiApplied,
|
|
5261
|
+
server_side_secret_masking_applied: effectiveInputMaskingTelemetry.secretApplied && !clientInputMaskingTelemetry.secretApplied,
|
|
5262
|
+
effective_pii_masking_applied: effectiveInputMaskingTelemetry.piiApplied,
|
|
5263
|
+
effective_secret_masking_applied: effectiveInputMaskingTelemetry.secretApplied,
|
|
5264
|
+
effective_input_was_transformed: retainedInputForLogs !== "[REDACTED]",
|
|
5265
|
+
effective_output_was_transformed: wrappedCompletion.outputMasked,
|
|
5093
5266
|
shadow_mode: isShadowMode,
|
|
5094
5267
|
simulated_decision: verdict.simulated_decision ?? null,
|
|
5095
5268
|
simulated_output_decision: isShadowMode && wrappedCompletion.outputMasked ? "masked" : "allowed",
|
|
@@ -5110,11 +5283,7 @@ var AgentID = class {
|
|
|
5110
5283
|
sdkConfigVersion: capabilityConfig.version
|
|
5111
5284
|
})
|
|
5112
5285
|
),
|
|
5113
|
-
client_capabilities:
|
|
5114
|
-
"openai",
|
|
5115
|
-
false,
|
|
5116
|
-
capabilityConfig
|
|
5117
|
-
)
|
|
5286
|
+
client_capabilities: clientCapabilities
|
|
5118
5287
|
}, requestOptions);
|
|
5119
5288
|
if (!ingestResult.ok) {
|
|
5120
5289
|
this.maybeRaiseStrictIngestDependencyError({
|
|
@@ -5128,7 +5297,7 @@ var AgentID = class {
|
|
|
5128
5297
|
}
|
|
5129
5298
|
if (!isShadowMode && maskedText) {
|
|
5130
5299
|
const output = adapter.extractOutput(res);
|
|
5131
|
-
const
|
|
5300
|
+
const clientFacingOutput = shouldDeanonymizeForClient ? this.pii.deanonymize(String(output ?? ""), mapping) : this.wrapCompletion(output, {
|
|
5132
5301
|
piiMapping: mapping,
|
|
5133
5302
|
deanonymizeForClient: false
|
|
5134
5303
|
}).transformedOutput;
|
|
@@ -5137,10 +5306,10 @@ var AgentID = class {
|
|
|
5137
5306
|
for (const choice of res.choices) {
|
|
5138
5307
|
const typedChoice = choice;
|
|
5139
5308
|
if (typedChoice?.message && typeof typedChoice.message.content === "string") {
|
|
5140
|
-
typedChoice.message.content =
|
|
5309
|
+
typedChoice.message.content = clientFacingOutput;
|
|
5141
5310
|
}
|
|
5142
5311
|
if (typedChoice?.delta && typeof typedChoice.delta.content === "string") {
|
|
5143
|
-
typedChoice.delta.content =
|
|
5312
|
+
typedChoice.delta.content = clientFacingOutput;
|
|
5144
5313
|
}
|
|
5145
5314
|
}
|
|
5146
5315
|
}
|