agentid-sdk 0.1.36 → 0.1.38
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 +221 -64
- package/dist/agentid-CxVUF_eo.d.mts +399 -0
- package/dist/agentid-CxVUF_eo.d.ts +399 -0
- package/dist/{chunk-TY4AXWGS.mjs → chunk-AIGMQSAV.mjs} +1499 -155
- package/dist/index.d.mts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +1504 -154
- package/dist/index.mjs +13 -1
- package/dist/langchain.d.mts +15 -1
- package/dist/langchain.d.ts +15 -1
- package/dist/langchain.js +986 -71
- package/dist/langchain.mjs +451 -16
- package/dist/transparency-badge.d.mts +1 -1
- package/dist/transparency-badge.d.ts +1 -1
- package/package.json +9 -5
- package/dist/agentid-JQx2Iy7B.d.mts +0 -240
- package/dist/agentid-JQx2Iy7B.d.ts +0 -240
|
@@ -1,14 +1,86 @@
|
|
|
1
1
|
// src/adapters.ts
|
|
2
|
+
function getLastUserMessage(req) {
|
|
3
|
+
const messages = req?.messages;
|
|
4
|
+
if (!Array.isArray(messages)) return null;
|
|
5
|
+
let lastUser = null;
|
|
6
|
+
for (const msg of messages) {
|
|
7
|
+
if (msg && typeof msg === "object" && msg.role === "user") {
|
|
8
|
+
lastUser = msg;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return lastUser;
|
|
12
|
+
}
|
|
13
|
+
function normalizeFilename(value, fallback) {
|
|
14
|
+
if (typeof value !== "string") {
|
|
15
|
+
return fallback;
|
|
16
|
+
}
|
|
17
|
+
const trimmed = value.trim();
|
|
18
|
+
return trimmed.length > 0 ? trimmed : fallback;
|
|
19
|
+
}
|
|
20
|
+
function parseDataUrl(value) {
|
|
21
|
+
if (!value.startsWith("data:")) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const commaIndex = value.indexOf(",");
|
|
25
|
+
if (commaIndex === -1) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const header = value.slice(5, commaIndex);
|
|
29
|
+
if (!/;base64/i.test(header)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const mimeType = header.split(";")[0]?.trim().toLowerCase() || null;
|
|
33
|
+
return { mimeType };
|
|
34
|
+
}
|
|
35
|
+
function inferAttachmentExtension(mimeType) {
|
|
36
|
+
switch (mimeType) {
|
|
37
|
+
case "application/pdf":
|
|
38
|
+
return "pdf";
|
|
39
|
+
case "image/png":
|
|
40
|
+
return "png";
|
|
41
|
+
case "image/jpeg":
|
|
42
|
+
return "jpg";
|
|
43
|
+
case "image/webp":
|
|
44
|
+
return "webp";
|
|
45
|
+
case "image/gif":
|
|
46
|
+
return "gif";
|
|
47
|
+
case "text/plain":
|
|
48
|
+
return "txt";
|
|
49
|
+
default:
|
|
50
|
+
return "bin";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function defaultFilenameForMimeType(mimeType) {
|
|
54
|
+
return `attachment.${inferAttachmentExtension(mimeType)}`;
|
|
55
|
+
}
|
|
56
|
+
function normalizeFileAttachment(part) {
|
|
57
|
+
const file = part?.file;
|
|
58
|
+
const rawContent = typeof file?.file_data === "string" && file.file_data.trim().length > 0 ? file.file_data.trim() : null;
|
|
59
|
+
if (!rawContent) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const detectedMimeType = parseDataUrl(rawContent)?.mimeType ?? null;
|
|
63
|
+
return {
|
|
64
|
+
filename: normalizeFilename(file?.filename, defaultFilenameForMimeType(detectedMimeType)),
|
|
65
|
+
...detectedMimeType ? { mime_type: detectedMimeType } : {},
|
|
66
|
+
content_base64: rawContent
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function normalizeImageAttachment(part) {
|
|
70
|
+
const imageUrl = typeof part?.image_url?.url === "string" && part.image_url.url.trim().length > 0 ? part.image_url.url.trim() : null;
|
|
71
|
+
if (!imageUrl || !imageUrl.startsWith("data:")) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const detectedMimeType = parseDataUrl(imageUrl)?.mimeType ?? "image/png";
|
|
75
|
+
return {
|
|
76
|
+
filename: defaultFilenameForMimeType(detectedMimeType),
|
|
77
|
+
mime_type: detectedMimeType,
|
|
78
|
+
content_base64: imageUrl
|
|
79
|
+
};
|
|
80
|
+
}
|
|
2
81
|
var OpenAIAdapter = class {
|
|
3
82
|
extractInput(req) {
|
|
4
|
-
const
|
|
5
|
-
if (!Array.isArray(messages)) return null;
|
|
6
|
-
let lastUser = null;
|
|
7
|
-
for (const msg of messages) {
|
|
8
|
-
if (msg && typeof msg === "object" && msg.role === "user") {
|
|
9
|
-
lastUser = msg;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
83
|
+
const lastUser = getLastUserMessage(req);
|
|
12
84
|
if (!lastUser) return null;
|
|
13
85
|
const content = lastUser.content;
|
|
14
86
|
if (typeof content === "string") return content;
|
|
@@ -23,6 +95,34 @@ var OpenAIAdapter = class {
|
|
|
23
95
|
}
|
|
24
96
|
return null;
|
|
25
97
|
}
|
|
98
|
+
extractAttachments(req) {
|
|
99
|
+
const lastUser = getLastUserMessage(req);
|
|
100
|
+
if (!lastUser) return [];
|
|
101
|
+
const content = lastUser?.content;
|
|
102
|
+
if (!Array.isArray(content)) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
const attachments = [];
|
|
106
|
+
for (const part of content) {
|
|
107
|
+
if (!part || typeof part !== "object") {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (part.type === "file") {
|
|
111
|
+
const attachment = normalizeFileAttachment(part);
|
|
112
|
+
if (attachment) {
|
|
113
|
+
attachments.push(attachment);
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (part.type === "image_url") {
|
|
118
|
+
const attachment = normalizeImageAttachment(part);
|
|
119
|
+
if (attachment) {
|
|
120
|
+
attachments.push(attachment);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return attachments;
|
|
125
|
+
}
|
|
26
126
|
getModelName(req, res) {
|
|
27
127
|
const model = res?.model ?? req?.model ?? "unknown";
|
|
28
128
|
return String(model);
|
|
@@ -902,8 +1002,173 @@ function detectNationalIdentifiers(text, options = {}) {
|
|
|
902
1002
|
return results;
|
|
903
1003
|
}
|
|
904
1004
|
|
|
1005
|
+
// src/secret-patterns.ts
|
|
1006
|
+
var SDK_SECRET_PATTERN_DEFINITIONS = [
|
|
1007
|
+
{
|
|
1008
|
+
id: "openai_api_key",
|
|
1009
|
+
placeholderType: "OPENAI_API_KEY",
|
|
1010
|
+
patternSource: "\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b",
|
|
1011
|
+
flags: "iu",
|
|
1012
|
+
prefilterTerms: ["sk-", "proj-", "openai"]
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
id: "aws_access_key",
|
|
1016
|
+
placeholderType: "AWS_ACCESS_KEY",
|
|
1017
|
+
patternSource: "\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b",
|
|
1018
|
+
flags: "iu",
|
|
1019
|
+
prefilterTerms: ["akia", "asia", "aws"]
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
id: "github_token",
|
|
1023
|
+
placeholderType: "GITHUB_TOKEN",
|
|
1024
|
+
patternSource: "\\b(?:gh[pousr]_[A-Za-z0-9]{24,255}|github_pat_[A-Za-z0-9_]{20,255})\\b",
|
|
1025
|
+
flags: "iu",
|
|
1026
|
+
prefilterTerms: ["ghp_", "gho_", "ghu_", "ghs_", "ghr_", "github_pat_"]
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
id: "slack_token",
|
|
1030
|
+
placeholderType: "SLACK_TOKEN",
|
|
1031
|
+
patternSource: "\\bxox(?:a|b|p|r|s)-[A-Za-z0-9-]{10,200}\\b",
|
|
1032
|
+
flags: "iu",
|
|
1033
|
+
prefilterTerms: ["xoxa-", "xoxb-", "xoxp-", "xoxr-", "xoxs-", "slack"]
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
id: "slack_webhook_url",
|
|
1037
|
+
placeholderType: "SLACK_WEBHOOK_URL",
|
|
1038
|
+
patternSource: "https:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Za-z0-9/_-]{20,}",
|
|
1039
|
+
flags: "iu",
|
|
1040
|
+
prefilterTerms: ["hooks.slack.com/services", "slack"]
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
id: "discord_webhook_url",
|
|
1044
|
+
placeholderType: "DISCORD_WEBHOOK_URL",
|
|
1045
|
+
patternSource: "https:\\/\\/discord(?:app)?\\.com\\/api\\/webhooks\\/\\d+\\/[A-Za-z0-9_-]{16,}",
|
|
1046
|
+
flags: "iu",
|
|
1047
|
+
prefilterTerms: ["discord.com/api/webhooks", "discordapp.com/api/webhooks", "discord"]
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
id: "stripe_secret_key",
|
|
1051
|
+
placeholderType: "STRIPE_SECRET_KEY",
|
|
1052
|
+
patternSource: "\\b(?:sk|pk|ak|rk)_(?:live|test)_[A-Za-z0-9]+\\b",
|
|
1053
|
+
flags: "iu",
|
|
1054
|
+
prefilterTerms: [
|
|
1055
|
+
"sk_live_",
|
|
1056
|
+
"pk_live_",
|
|
1057
|
+
"sk_test_",
|
|
1058
|
+
"pk_test_",
|
|
1059
|
+
"ak_live_",
|
|
1060
|
+
"ak_test_",
|
|
1061
|
+
"rk_live_",
|
|
1062
|
+
"rk_test_",
|
|
1063
|
+
"stripe"
|
|
1064
|
+
]
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
id: "google_api_key",
|
|
1068
|
+
placeholderType: "GOOGLE_API_KEY",
|
|
1069
|
+
patternSource: "\\bAIza[0-9A-Za-z_-]{35}\\b",
|
|
1070
|
+
flags: "iu",
|
|
1071
|
+
prefilterTerms: ["aiza", "google"]
|
|
1072
|
+
},
|
|
1073
|
+
{
|
|
1074
|
+
id: "anthropic_api_key",
|
|
1075
|
+
placeholderType: "ANTHROPIC_API_KEY",
|
|
1076
|
+
patternSource: "\\bsk-ant-(?:api\\d{2}-)?[A-Za-z0-9_-]{20,}\\b",
|
|
1077
|
+
flags: "iu",
|
|
1078
|
+
prefilterTerms: ["sk-ant-", "anthropic"]
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
id: "evm_private_key",
|
|
1082
|
+
placeholderType: "EVM_PRIVATE_KEY",
|
|
1083
|
+
patternSource: "\\b0x[a-fA-F0-9]{64}\\b",
|
|
1084
|
+
flags: "iu",
|
|
1085
|
+
prefilterTerms: ["0x", "ethereum", "evm", "private key"]
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
id: "jwt_token",
|
|
1089
|
+
placeholderType: "JWT_TOKEN",
|
|
1090
|
+
patternSource: "\\beyJ[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b",
|
|
1091
|
+
flags: "iu",
|
|
1092
|
+
prefilterTerms: ["eyj", "jwt", "bearer"]
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
id: "bearer_token",
|
|
1096
|
+
placeholderType: "BEARER_TOKEN",
|
|
1097
|
+
patternSource: "\\bauthorization\\b\\s*[:=]\\s*bearer\\s+[A-Za-z0-9._~+\\/-]{16,}|\\bbearer\\s+[A-Za-z0-9._~+\\/-]{24,}",
|
|
1098
|
+
flags: "iu",
|
|
1099
|
+
prefilterTerms: ["authorization", "bearer"]
|
|
1100
|
+
},
|
|
1101
|
+
{
|
|
1102
|
+
id: "api_key_header",
|
|
1103
|
+
placeholderType: "API_KEY_HEADER",
|
|
1104
|
+
patternSource: "\\bx[-_]?api[-_]?key\\b\\s*[:=]\\s*[A-Za-z0-9._~+\\/-]{16,}",
|
|
1105
|
+
flags: "iu",
|
|
1106
|
+
prefilterTerms: ["x-api-key", "api-key", "x_api_key", "api_key"]
|
|
1107
|
+
},
|
|
1108
|
+
{
|
|
1109
|
+
id: "credential_assignment",
|
|
1110
|
+
placeholderType: "CREDENTIAL_ASSIGNMENT",
|
|
1111
|
+
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
|
+
flags: "iu",
|
|
1113
|
+
prefilterTerms: [
|
|
1114
|
+
"api key",
|
|
1115
|
+
"apikey",
|
|
1116
|
+
"api_key",
|
|
1117
|
+
"access token",
|
|
1118
|
+
"access_token",
|
|
1119
|
+
"auth token",
|
|
1120
|
+
"client secret",
|
|
1121
|
+
"private key"
|
|
1122
|
+
]
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
id: "password_assignment",
|
|
1126
|
+
placeholderType: "PASSWORD_ASSIGNMENT",
|
|
1127
|
+
patternSource: `(?:\\b|["'])(?:password|passwd|pwd)(?:\\b|["'])\\s*(?:(?::|=|=>)|(?:is|are|was|were)\\b)\\s*(?:"[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}"|'[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}'|[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,})`,
|
|
1128
|
+
flags: "iu",
|
|
1129
|
+
prefilterTerms: ["password", "passwd", "pwd"]
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
id: "private_key_material",
|
|
1133
|
+
placeholderType: "PRIVATE_KEY_MATERIAL",
|
|
1134
|
+
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
|
+
flags: "iu",
|
|
1136
|
+
prefilterTerms: ["begin private key", "begin pgp private key block", "private key"]
|
|
1137
|
+
},
|
|
1138
|
+
{
|
|
1139
|
+
id: "azure_connection_string",
|
|
1140
|
+
placeholderType: "AZURE_CONNECTION_STRING",
|
|
1141
|
+
patternSource: "\\bDefaultEndpointsProtocol=https;AccountName=[A-Za-z0-9.-]{3,};AccountKey=[A-Za-z0-9+/=]{20,}(?:;EndpointSuffix=[A-Za-z0-9.-]+)?\\b",
|
|
1142
|
+
flags: "iu",
|
|
1143
|
+
prefilterTerms: ["defaultendpointsprotocol", "accountname", "accountkey", "azure"]
|
|
1144
|
+
},
|
|
1145
|
+
{
|
|
1146
|
+
id: "azure_sas_token",
|
|
1147
|
+
placeholderType: "AZURE_SAS_TOKEN",
|
|
1148
|
+
patternSource: "\\bsv=[^\\s&]{2,}&[^\\s]{0,200}\\bsig=[A-Za-z0-9%/+_-]{16,}",
|
|
1149
|
+
flags: "iu",
|
|
1150
|
+
prefilterTerms: ["sv=", "sig=", "accountkey", "azure"]
|
|
1151
|
+
}
|
|
1152
|
+
];
|
|
1153
|
+
function ensureGlobalFlag(flags) {
|
|
1154
|
+
const normalized = new Set(flags.split(""));
|
|
1155
|
+
normalized.add("g");
|
|
1156
|
+
return [...normalized].join("");
|
|
1157
|
+
}
|
|
1158
|
+
var COMPILED_SDK_SECRET_PATTERNS = SDK_SECRET_PATTERN_DEFINITIONS.map((definition) => ({
|
|
1159
|
+
...definition,
|
|
1160
|
+
scanRegex: new RegExp(definition.patternSource, ensureGlobalFlag(definition.flags)),
|
|
1161
|
+
prefilterTermsLower: definition.prefilterTerms.map((term) => term.toLowerCase())
|
|
1162
|
+
}));
|
|
1163
|
+
function getSdkSecretDetectionMatchers() {
|
|
1164
|
+
return COMPILED_SDK_SECRET_PATTERNS;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
905
1167
|
// src/pii.ts
|
|
906
1168
|
var defaultScanDeadlineMs = 100;
|
|
1169
|
+
var sdkSecretMatchers = getSdkSecretDetectionMatchers();
|
|
1170
|
+
var DISCORD_WEBHOOK_TOKEN_RE = /https:\/\/discord(?:app)?\.com\/api\/webhooks\/\d+\/([A-Za-z0-9_-]{16,})/giu;
|
|
1171
|
+
var BASIC_AUTH_PASSWORD_RE = /\/\/[^:\s/?#@]+:([^@\s/?#]+)@/giu;
|
|
907
1172
|
function countDigits2(value) {
|
|
908
1173
|
let count = 0;
|
|
909
1174
|
for (const ch of value) {
|
|
@@ -928,15 +1193,32 @@ function luhnCheck(value) {
|
|
|
928
1193
|
return sum % 10 === 0;
|
|
929
1194
|
}
|
|
930
1195
|
function normalizeDetections(text, detections) {
|
|
931
|
-
const sorted = detections.filter((d) => d.start >= 0 && d.end > d.start && d.end <= text.length).sort(
|
|
1196
|
+
const sorted = detections.filter((d) => d.start >= 0 && d.end > d.start && d.end <= text.length).sort(
|
|
1197
|
+
(a, b) => detectionPriority(b.type) - detectionPriority(a.type) || a.start - b.start || b.end - b.start - (a.end - a.start)
|
|
1198
|
+
);
|
|
932
1199
|
const kept = [];
|
|
933
|
-
let cursor = 0;
|
|
934
1200
|
for (const d of sorted) {
|
|
935
|
-
if (
|
|
1201
|
+
if (kept.some((candidate) => rangesOverlap(candidate, d))) continue;
|
|
936
1202
|
kept.push(d);
|
|
937
|
-
cursor = d.end;
|
|
938
1203
|
}
|
|
939
|
-
return kept;
|
|
1204
|
+
return kept.sort((a, b) => a.start - b.start || a.end - b.end);
|
|
1205
|
+
}
|
|
1206
|
+
function rangesOverlap(left, right) {
|
|
1207
|
+
return left.start < right.end && right.start < left.end;
|
|
1208
|
+
}
|
|
1209
|
+
function detectionPriority(type) {
|
|
1210
|
+
if (/^(?: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|AZURE_CONNECTION_STRING|AZURE_SAS_TOKEN)$/u.test(
|
|
1211
|
+
type
|
|
1212
|
+
)) {
|
|
1213
|
+
return 100;
|
|
1214
|
+
}
|
|
1215
|
+
if (/^(?:CREDENTIAL_ASSIGNMENT|PASSWORD_ASSIGNMENT|PRIVATE_KEY_MATERIAL|ENV_SECRET_ASSIGNMENT)$/u.test(type)) {
|
|
1216
|
+
return 80;
|
|
1217
|
+
}
|
|
1218
|
+
if (type === "PERSON_NAME" || type === "PERSON") {
|
|
1219
|
+
return 10;
|
|
1220
|
+
}
|
|
1221
|
+
return 50;
|
|
940
1222
|
}
|
|
941
1223
|
var PHONE_CONTEXT_KEYWORDS = [
|
|
942
1224
|
"tel",
|
|
@@ -971,6 +1253,59 @@ var PHONE_CONTEXT_RE = new RegExp(
|
|
|
971
1253
|
"iu"
|
|
972
1254
|
);
|
|
973
1255
|
var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
|
|
1256
|
+
"name",
|
|
1257
|
+
"names",
|
|
1258
|
+
"namen",
|
|
1259
|
+
"firstname",
|
|
1260
|
+
"lastname",
|
|
1261
|
+
"first",
|
|
1262
|
+
"last",
|
|
1263
|
+
"forename",
|
|
1264
|
+
"surname",
|
|
1265
|
+
"family",
|
|
1266
|
+
"given",
|
|
1267
|
+
"jmeno",
|
|
1268
|
+
"jake",
|
|
1269
|
+
"jaky",
|
|
1270
|
+
"jaka",
|
|
1271
|
+
"jsem",
|
|
1272
|
+
"jsme",
|
|
1273
|
+
"napsal",
|
|
1274
|
+
"napsali",
|
|
1275
|
+
"napsala",
|
|
1276
|
+
"napsane",
|
|
1277
|
+
"pouzil",
|
|
1278
|
+
"pouzili",
|
|
1279
|
+
"prijmeni",
|
|
1280
|
+
"vorname",
|
|
1281
|
+
"nachname",
|
|
1282
|
+
"familienname",
|
|
1283
|
+
"what",
|
|
1284
|
+
"which",
|
|
1285
|
+
"whose",
|
|
1286
|
+
"did",
|
|
1287
|
+
"we",
|
|
1288
|
+
"write",
|
|
1289
|
+
"wrote",
|
|
1290
|
+
"written",
|
|
1291
|
+
"type",
|
|
1292
|
+
"typed",
|
|
1293
|
+
"use",
|
|
1294
|
+
"used",
|
|
1295
|
+
"wie",
|
|
1296
|
+
"welchen",
|
|
1297
|
+
"welche",
|
|
1298
|
+
"welches",
|
|
1299
|
+
"haben",
|
|
1300
|
+
"wir",
|
|
1301
|
+
"geschrieben",
|
|
1302
|
+
"getippt",
|
|
1303
|
+
"quel",
|
|
1304
|
+
"quelle",
|
|
1305
|
+
"nom",
|
|
1306
|
+
"que",
|
|
1307
|
+
"cual",
|
|
1308
|
+
"nombre",
|
|
974
1309
|
"write",
|
|
975
1310
|
"code",
|
|
976
1311
|
"script",
|
|
@@ -997,6 +1332,52 @@ var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
|
|
|
997
1332
|
"security",
|
|
998
1333
|
"instructions",
|
|
999
1334
|
"instruction",
|
|
1335
|
+
"google",
|
|
1336
|
+
"form",
|
|
1337
|
+
"forms",
|
|
1338
|
+
"engineering",
|
|
1339
|
+
"leadership",
|
|
1340
|
+
"weekly",
|
|
1341
|
+
"daily",
|
|
1342
|
+
"monthly",
|
|
1343
|
+
"quarterly",
|
|
1344
|
+
"sync",
|
|
1345
|
+
"office",
|
|
1346
|
+
"updates",
|
|
1347
|
+
"update",
|
|
1348
|
+
"meeting",
|
|
1349
|
+
"meetings",
|
|
1350
|
+
"agenda",
|
|
1351
|
+
"minutes",
|
|
1352
|
+
"subject",
|
|
1353
|
+
"calendar",
|
|
1354
|
+
"roadmap",
|
|
1355
|
+
"platform",
|
|
1356
|
+
"product",
|
|
1357
|
+
"design",
|
|
1358
|
+
"operations",
|
|
1359
|
+
"business",
|
|
1360
|
+
"newsletter",
|
|
1361
|
+
"report",
|
|
1362
|
+
"reports",
|
|
1363
|
+
"amazon",
|
|
1364
|
+
"web",
|
|
1365
|
+
"services",
|
|
1366
|
+
"aws",
|
|
1367
|
+
"velka",
|
|
1368
|
+
"transformace",
|
|
1369
|
+
"project",
|
|
1370
|
+
"projekt",
|
|
1371
|
+
"program",
|
|
1372
|
+
"initiative",
|
|
1373
|
+
"iniciativa",
|
|
1374
|
+
"migration",
|
|
1375
|
+
"migrace",
|
|
1376
|
+
"test",
|
|
1377
|
+
"uuid",
|
|
1378
|
+
"fixture",
|
|
1379
|
+
"data",
|
|
1380
|
+
"firma",
|
|
1000
1381
|
"rules",
|
|
1001
1382
|
"rule",
|
|
1002
1383
|
"json",
|
|
@@ -1009,10 +1390,22 @@ var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
|
|
|
1009
1390
|
"agentid",
|
|
1010
1391
|
"risk",
|
|
1011
1392
|
"score",
|
|
1012
|
-
"summary"
|
|
1393
|
+
"summary",
|
|
1394
|
+
"hi",
|
|
1395
|
+
"hello",
|
|
1396
|
+
"hey",
|
|
1397
|
+
"dear",
|
|
1398
|
+
"team",
|
|
1399
|
+
"ahoj",
|
|
1400
|
+
"dobry",
|
|
1401
|
+
"dobryden",
|
|
1402
|
+
"zdravim"
|
|
1013
1403
|
]);
|
|
1014
1404
|
var TECHNICAL_CONTEXT_WORD_REGEX = /\b(?:curl|http|https|import|python|javascript|typescript|sql|nosql|mongo|database|query|script|code|os\.system|eval|exec|node|npm|api|endpoint|regex|json|xml|yaml|bash|powershell)\b/i;
|
|
1015
1405
|
var TECHNICAL_CONTEXT_SYMBOL_REGEX = /:\/\/|`|\{|\}|\[|\]|\(|\)|;|\$|=>|::|\/\//;
|
|
1406
|
+
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;
|
|
1407
|
+
var NAME_VALUE_ASSIGNMENT_BEFORE_CANDIDATE_REGEX = /(?:[:=]|=>|-|\b(?:is|was|je|jsou|jmenuje|called|named|ist|sind|lautet|est|es)\b)\s*$/iu;
|
|
1408
|
+
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;
|
|
1016
1409
|
function hasPhoneContext(text, matchStartIndex, windowSize = 50) {
|
|
1017
1410
|
const start = Math.max(0, matchStartIndex - windowSize);
|
|
1018
1411
|
const windowLower = text.slice(start, matchStartIndex).toLowerCase();
|
|
@@ -1029,6 +1422,16 @@ function buildContextWindow(source, index, length) {
|
|
|
1029
1422
|
function isTechnicalContext(contextWindow) {
|
|
1030
1423
|
return TECHNICAL_CONTEXT_WORD_REGEX.test(contextWindow) || TECHNICAL_CONTEXT_SYMBOL_REGEX.test(contextWindow);
|
|
1031
1424
|
}
|
|
1425
|
+
function isNameLabelQuestionContext(contextWindow) {
|
|
1426
|
+
const normalized = normalizePersonWord(contextWindow);
|
|
1427
|
+
if (!normalized.trim()) {
|
|
1428
|
+
return false;
|
|
1429
|
+
}
|
|
1430
|
+
if (!NAME_LABEL_QUESTION_CONTEXT_REGEX.test(normalized)) {
|
|
1431
|
+
return false;
|
|
1432
|
+
}
|
|
1433
|
+
return !NAME_VALUE_ASSIGNMENT_BEFORE_CANDIDATE_REGEX.test(normalized.slice(-32));
|
|
1434
|
+
}
|
|
1032
1435
|
function isLikelyPersonNameCandidate(candidate, contextWindow) {
|
|
1033
1436
|
const words = candidate.trim().split(/\s+/);
|
|
1034
1437
|
if (words.length !== 2) {
|
|
@@ -1037,6 +1440,9 @@ function isLikelyPersonNameCandidate(candidate, contextWindow) {
|
|
|
1037
1440
|
if (isTechnicalContext(contextWindow)) {
|
|
1038
1441
|
return false;
|
|
1039
1442
|
}
|
|
1443
|
+
if (isNameLabelQuestionContext(contextWindow)) {
|
|
1444
|
+
return false;
|
|
1445
|
+
}
|
|
1040
1446
|
for (const rawWord of words) {
|
|
1041
1447
|
const normalized = normalizePersonWord(rawWord);
|
|
1042
1448
|
if (normalized.length < 2) {
|
|
@@ -1057,63 +1463,135 @@ var PIIManager = class {
|
|
|
1057
1463
|
*
|
|
1058
1464
|
* Zero-dependency fallback with strict checksum validation for CEE national IDs.
|
|
1059
1465
|
*/
|
|
1060
|
-
anonymize(text) {
|
|
1466
|
+
anonymize(text, options) {
|
|
1061
1467
|
if (!text) return { maskedText: text, mapping: {} };
|
|
1062
1468
|
try {
|
|
1063
1469
|
const detections = [];
|
|
1064
|
-
const
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
if (m.index == null) continue;
|
|
1072
|
-
detections.push({ start: m.index, end: m.index + m[0].length, type: "IBAN", text: m[0] });
|
|
1073
|
-
}
|
|
1074
|
-
const ccRe = /(?:\b\d[\d -]{10,22}\d\b)/g;
|
|
1075
|
-
for (const m of text.matchAll(ccRe)) {
|
|
1076
|
-
if (m.index == null) continue;
|
|
1077
|
-
const digits = countDigits2(m[0]);
|
|
1078
|
-
if (digits < 12 || digits > 19) continue;
|
|
1079
|
-
if (!luhnCheck(m[0])) continue;
|
|
1080
|
-
detections.push({ start: m.index, end: m.index + m[0].length, type: "CREDIT_CARD", text: m[0] });
|
|
1470
|
+
const loweredText = text.toLowerCase();
|
|
1471
|
+
const resolvedOptions = {
|
|
1472
|
+
pii: options?.pii !== false,
|
|
1473
|
+
secrets: options?.secrets !== false
|
|
1474
|
+
};
|
|
1475
|
+
if (!resolvedOptions.pii && !resolvedOptions.secrets) {
|
|
1476
|
+
return { maskedText: text, mapping: {} };
|
|
1081
1477
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
if (digits < 9 || digits > 15) continue;
|
|
1088
|
-
const isStrongInternational = candidate.startsWith("+") || candidate.startsWith("00");
|
|
1089
|
-
if (!isStrongInternational) {
|
|
1090
|
-
const hasContext = hasPhoneContext(text, m.index);
|
|
1091
|
-
if (!hasContext) continue;
|
|
1478
|
+
if (resolvedOptions.pii) {
|
|
1479
|
+
const emailRe = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
|
|
1480
|
+
for (const m of text.matchAll(emailRe)) {
|
|
1481
|
+
if (m.index == null) continue;
|
|
1482
|
+
detections.push({ start: m.index, end: m.index + m[0].length, type: "EMAIL", text: m[0] });
|
|
1092
1483
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
if (m.index == null) continue;
|
|
1098
|
-
const candidate = m[0];
|
|
1099
|
-
const contextWindow = buildContextWindow(text, m.index, candidate.length);
|
|
1100
|
-
if (!isLikelyPersonNameCandidate(candidate, contextWindow)) {
|
|
1101
|
-
continue;
|
|
1484
|
+
const ibanRe = /\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b/gi;
|
|
1485
|
+
for (const m of text.matchAll(ibanRe)) {
|
|
1486
|
+
if (m.index == null) continue;
|
|
1487
|
+
detections.push({ start: m.index, end: m.index + m[0].length, type: "IBAN", text: m[0] });
|
|
1102
1488
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1489
|
+
const ccRe = /(?:\b\d[\d -]{10,22}\d\b)/g;
|
|
1490
|
+
for (const m of text.matchAll(ccRe)) {
|
|
1491
|
+
if (m.index == null) continue;
|
|
1492
|
+
const digits = countDigits2(m[0]);
|
|
1493
|
+
if (digits < 12 || digits > 19) continue;
|
|
1494
|
+
if (!luhnCheck(m[0])) continue;
|
|
1495
|
+
detections.push({ start: m.index, end: m.index + m[0].length, type: "CREDIT_CARD", text: m[0] });
|
|
1496
|
+
}
|
|
1497
|
+
const phoneRe = /(?<!\d)(?:\+?\d[\d\s().-]{7,}\d)(?!\d)/g;
|
|
1498
|
+
for (const m of text.matchAll(phoneRe)) {
|
|
1499
|
+
if (m.index == null) continue;
|
|
1500
|
+
const candidate = m[0];
|
|
1501
|
+
const digits = countDigits2(candidate);
|
|
1502
|
+
if (digits < 9 || digits > 15) continue;
|
|
1503
|
+
const isStrongInternational = candidate.startsWith("+") || candidate.startsWith("00");
|
|
1504
|
+
if (!isStrongInternational) {
|
|
1505
|
+
const hasContext = hasPhoneContext(text, m.index);
|
|
1506
|
+
if (!hasContext) continue;
|
|
1507
|
+
}
|
|
1508
|
+
detections.push({ start: m.index, end: m.index + m[0].length, type: "PHONE", text: m[0] });
|
|
1509
|
+
}
|
|
1510
|
+
const personRe = /(?<!\p{L})\p{Lu}\p{Ll}{2,}\s+\p{Lu}\p{Ll}{2,}(?!\p{L})/gu;
|
|
1511
|
+
for (const m of text.matchAll(personRe)) {
|
|
1512
|
+
if (m.index == null) continue;
|
|
1513
|
+
const candidate = m[0];
|
|
1514
|
+
const contextWindow = buildContextWindow(text, m.index, candidate.length);
|
|
1515
|
+
if (!isLikelyPersonNameCandidate(candidate, contextWindow)) {
|
|
1516
|
+
continue;
|
|
1517
|
+
}
|
|
1518
|
+
detections.push({ start: m.index, end: m.index + candidate.length, type: "PERSON", text: candidate });
|
|
1519
|
+
}
|
|
1520
|
+
BIRTH_NUMBER_CONTEXT_RE.lastIndex = 0;
|
|
1521
|
+
for (const match of text.matchAll(BIRTH_NUMBER_CONTEXT_RE)) {
|
|
1522
|
+
if (match.index == null) continue;
|
|
1523
|
+
const value = match[1] ?? "";
|
|
1524
|
+
if (!/^\d{6}(?:\/?\d{3,4})?$/.test(value)) continue;
|
|
1525
|
+
const localIndex = match[0].lastIndexOf(value);
|
|
1526
|
+
const start = match.index + Math.max(0, localIndex);
|
|
1527
|
+
detections.push({
|
|
1528
|
+
start,
|
|
1529
|
+
end: start + value.length,
|
|
1530
|
+
type: "BIRTH_NUMBER",
|
|
1531
|
+
text: value
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
const nationalIdMatches = detectNationalIdentifiers(text, {
|
|
1535
|
+
deadlineMs: defaultScanDeadlineMs,
|
|
1536
|
+
allowContextBirthNumberFallback: false
|
|
1116
1537
|
});
|
|
1538
|
+
for (const match of nationalIdMatches) {
|
|
1539
|
+
if (match.start < 0 || match.end <= match.start) continue;
|
|
1540
|
+
detections.push({
|
|
1541
|
+
start: match.start,
|
|
1542
|
+
end: match.end,
|
|
1543
|
+
type: "NATIONAL_ID",
|
|
1544
|
+
text: text.slice(match.start, match.end)
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
if (resolvedOptions.secrets) {
|
|
1549
|
+
BASIC_AUTH_PASSWORD_RE.lastIndex = 0;
|
|
1550
|
+
for (const match of text.matchAll(BASIC_AUTH_PASSWORD_RE)) {
|
|
1551
|
+
if (match.index == null) continue;
|
|
1552
|
+
const password = match[1] ?? "";
|
|
1553
|
+
if (!password) continue;
|
|
1554
|
+
const localIndex = match[0].lastIndexOf(password);
|
|
1555
|
+
const start = match.index + Math.max(0, localIndex);
|
|
1556
|
+
detections.push({
|
|
1557
|
+
start,
|
|
1558
|
+
end: start + password.length,
|
|
1559
|
+
type: "BASIC_AUTH_PASSWORD",
|
|
1560
|
+
text: password
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
DISCORD_WEBHOOK_TOKEN_RE.lastIndex = 0;
|
|
1564
|
+
for (const match of text.matchAll(DISCORD_WEBHOOK_TOKEN_RE)) {
|
|
1565
|
+
if (match.index == null) continue;
|
|
1566
|
+
const token = match[1] ?? "";
|
|
1567
|
+
if (!token) continue;
|
|
1568
|
+
const localIndex = match[0].lastIndexOf(token);
|
|
1569
|
+
const start = match.index + Math.max(0, localIndex);
|
|
1570
|
+
detections.push({
|
|
1571
|
+
start,
|
|
1572
|
+
end: start + token.length,
|
|
1573
|
+
type: "DISCORD_WEBHOOK_TOKEN",
|
|
1574
|
+
text: token
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
for (const matcher of sdkSecretMatchers) {
|
|
1578
|
+
if (matcher.id === "discord_webhook_url") {
|
|
1579
|
+
continue;
|
|
1580
|
+
}
|
|
1581
|
+
if (matcher.prefilterTermsLower.length > 0 && !matcher.prefilterTermsLower.some((term) => loweredText.includes(term))) {
|
|
1582
|
+
continue;
|
|
1583
|
+
}
|
|
1584
|
+
matcher.scanRegex.lastIndex = 0;
|
|
1585
|
+
for (const match of text.matchAll(matcher.scanRegex)) {
|
|
1586
|
+
if (match.index == null) continue;
|
|
1587
|
+
detections.push({
|
|
1588
|
+
start: match.index,
|
|
1589
|
+
end: match.index + match[0].length,
|
|
1590
|
+
type: matcher.placeholderType,
|
|
1591
|
+
text: match[0]
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1117
1595
|
}
|
|
1118
1596
|
const kept = normalizeDetections(text, detections);
|
|
1119
1597
|
if (!kept.length) return { maskedText: text, mapping: {} };
|
|
@@ -1642,14 +2120,14 @@ async function reportSecurityEvent(options) {
|
|
|
1642
2120
|
const inputValue = options.storePii ? snippet : snippetHash;
|
|
1643
2121
|
const eventId = createEventId(options.eventId ?? options.clientEventId);
|
|
1644
2122
|
const metadata = {
|
|
2123
|
+
...options.telemetryMetadata ?? {},
|
|
1645
2124
|
source: options.source,
|
|
1646
2125
|
detector: options.detector,
|
|
1647
2126
|
trigger_rule: options.triggerRule,
|
|
1648
2127
|
language: options.language,
|
|
1649
2128
|
ai_scan_status: options.aiStatus ?? null,
|
|
1650
2129
|
reason: options.reason ?? null,
|
|
1651
|
-
client_event_id: eventId
|
|
1652
|
-
...options.telemetryMetadata ?? {}
|
|
2130
|
+
client_event_id: eventId
|
|
1653
2131
|
};
|
|
1654
2132
|
if (options.storePii) {
|
|
1655
2133
|
metadata.snippet = snippet;
|
|
@@ -1810,7 +2288,7 @@ function getInjectionScanner() {
|
|
|
1810
2288
|
|
|
1811
2289
|
// src/sdk-version.ts
|
|
1812
2290
|
var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
|
|
1813
|
-
var AGENTID_SDK_VERSION_HEADER = "js-0.1.
|
|
2291
|
+
var AGENTID_SDK_VERSION_HEADER = "js-0.1.38".trim().length > 0 ? "js-0.1.38" : FALLBACK_SDK_VERSION;
|
|
1814
2292
|
|
|
1815
2293
|
// src/local-security-enforcer.ts
|
|
1816
2294
|
var DEFAULT_FAIL_OPEN_CONFIG = {
|
|
@@ -1822,6 +2300,8 @@ var DEFAULT_FAIL_OPEN_CONFIG = {
|
|
|
1822
2300
|
inject_transparency_metadata: false,
|
|
1823
2301
|
block_pii_leakage: false,
|
|
1824
2302
|
enable_sdk_pii_masking: false,
|
|
2303
|
+
block_secret_leakage: false,
|
|
2304
|
+
enable_sdk_secret_masking: false,
|
|
1825
2305
|
block_db_access: false,
|
|
1826
2306
|
block_code_execution: false,
|
|
1827
2307
|
block_toxicity: false
|
|
@@ -1863,11 +2343,11 @@ function detectCapabilityViolation(text, config) {
|
|
|
1863
2343
|
}
|
|
1864
2344
|
return null;
|
|
1865
2345
|
}
|
|
1866
|
-
function redactPiiStrict(pii, text) {
|
|
2346
|
+
function redactPiiStrict(pii, text, options) {
|
|
1867
2347
|
if (!text) {
|
|
1868
2348
|
return { redactedText: text, changed: false };
|
|
1869
2349
|
}
|
|
1870
|
-
const masked = pii.anonymize(text);
|
|
2350
|
+
const masked = pii.anonymize(text, options);
|
|
1871
2351
|
let redactedText = masked.maskedText;
|
|
1872
2352
|
const placeholders = Object.keys(masked.mapping).sort((a, b) => b.length - a.length);
|
|
1873
2353
|
for (const placeholder of placeholders) {
|
|
@@ -1896,7 +2376,7 @@ var LocalSecurityEnforcer = class {
|
|
|
1896
2376
|
`AgentID: Security policy blocked (${violationType})`
|
|
1897
2377
|
);
|
|
1898
2378
|
}
|
|
1899
|
-
if (!config.block_pii_leakage) {
|
|
2379
|
+
if (!config.block_pii_leakage && !config.block_secret_leakage) {
|
|
1900
2380
|
return {
|
|
1901
2381
|
sanitizedInput: input,
|
|
1902
2382
|
events: []
|
|
@@ -1906,10 +2386,13 @@ var LocalSecurityEnforcer = class {
|
|
|
1906
2386
|
throw new SecurityPolicyViolationError(
|
|
1907
2387
|
"PII_LEAKAGE_STRICT",
|
|
1908
2388
|
"BLOCKED",
|
|
1909
|
-
"AgentID: Streaming is not supported when
|
|
2389
|
+
"AgentID: Streaming is not supported when strict masking/blocking mode is enabled. Please disable streaming or adjust security settings."
|
|
1910
2390
|
);
|
|
1911
2391
|
}
|
|
1912
|
-
const strictRedaction = redactPiiStrict(this.pii, input
|
|
2392
|
+
const strictRedaction = redactPiiStrict(this.pii, input, {
|
|
2393
|
+
pii: config.block_pii_leakage,
|
|
2394
|
+
secrets: config.block_secret_leakage
|
|
2395
|
+
});
|
|
1913
2396
|
return {
|
|
1914
2397
|
sanitizedInput: strictRedaction.redactedText,
|
|
1915
2398
|
events: strictRedaction.changed ? [
|
|
@@ -2035,6 +2518,16 @@ function normalizeCapabilityConfig(payload) {
|
|
|
2035
2518
|
"enable_sdk_pii_masking",
|
|
2036
2519
|
false
|
|
2037
2520
|
),
|
|
2521
|
+
block_secret_leakage: readOptionalBooleanField(
|
|
2522
|
+
body,
|
|
2523
|
+
"block_secret_leakage",
|
|
2524
|
+
false
|
|
2525
|
+
),
|
|
2526
|
+
enable_sdk_secret_masking: readOptionalBooleanField(
|
|
2527
|
+
body,
|
|
2528
|
+
"enable_sdk_secret_masking",
|
|
2529
|
+
false
|
|
2530
|
+
),
|
|
2038
2531
|
block_db_access: readBooleanField(body, "block_db_access", "block_db"),
|
|
2039
2532
|
block_code_execution: readBooleanField(
|
|
2040
2533
|
body,
|
|
@@ -2215,9 +2708,18 @@ var INGEST_MAX_ATTEMPTS = 3;
|
|
|
2215
2708
|
var INGEST_RETRY_DELAYS_MS = [250, 500];
|
|
2216
2709
|
var GUARD_VERDICT_CACHE_TTL_MS = 0;
|
|
2217
2710
|
var MAX_INGEST_TEXT_CHARS = 32e3;
|
|
2711
|
+
var OPENAI_TELEMETRY_FIELD = "agentid_telemetry";
|
|
2218
2712
|
function normalizeBaseUrl3(baseUrl) {
|
|
2219
2713
|
return baseUrl.replace(/\/+$/, "");
|
|
2220
2714
|
}
|
|
2715
|
+
function firstNonEmptyString(...values) {
|
|
2716
|
+
for (const value of values) {
|
|
2717
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
2718
|
+
return value.trim();
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
return void 0;
|
|
2722
|
+
}
|
|
2221
2723
|
function isAbortSignalLike(value) {
|
|
2222
2724
|
if (!value || typeof value !== "object") return false;
|
|
2223
2725
|
const candidate = value;
|
|
@@ -2379,6 +2881,424 @@ function createCorrelationId(seed) {
|
|
|
2379
2881
|
}
|
|
2380
2882
|
return createPseudoUuidV42();
|
|
2381
2883
|
}
|
|
2884
|
+
function getObjectString(value, ...keys) {
|
|
2885
|
+
for (const key of keys) {
|
|
2886
|
+
const candidate = value?.[key];
|
|
2887
|
+
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
2888
|
+
return candidate.trim();
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
return void 0;
|
|
2892
|
+
}
|
|
2893
|
+
function getObjectNumber(value, ...keys) {
|
|
2894
|
+
for (const key of keys) {
|
|
2895
|
+
const candidate = value?.[key];
|
|
2896
|
+
if (typeof candidate === "number" && Number.isFinite(candidate)) {
|
|
2897
|
+
return candidate;
|
|
2898
|
+
}
|
|
2899
|
+
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
2900
|
+
const parsed = Number(candidate);
|
|
2901
|
+
if (Number.isFinite(parsed)) {
|
|
2902
|
+
return parsed;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
return void 0;
|
|
2907
|
+
}
|
|
2908
|
+
function normalizeTelemetryString(value) {
|
|
2909
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
2910
|
+
}
|
|
2911
|
+
function normalizeTelemetryCategory(value) {
|
|
2912
|
+
const normalized = normalizeTelemetryString(value);
|
|
2913
|
+
if (!normalized) return void 0;
|
|
2914
|
+
return normalized.toLowerCase().replace(/[\s-]+/g, "_");
|
|
2915
|
+
}
|
|
2916
|
+
function toSnakeToken(value) {
|
|
2917
|
+
return value.trim().replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").replace(/_+/g, "_").toLowerCase();
|
|
2918
|
+
}
|
|
2919
|
+
function hasUsageSignals(value) {
|
|
2920
|
+
if (!value) return false;
|
|
2921
|
+
for (const entry of Object.values(value)) {
|
|
2922
|
+
if (typeof entry === "number" && Number.isFinite(entry) && entry > 0) {
|
|
2923
|
+
return true;
|
|
2924
|
+
}
|
|
2925
|
+
if (typeof entry === "string" && entry.trim().length > 0) {
|
|
2926
|
+
const parsed = Number(entry);
|
|
2927
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
2928
|
+
return true;
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
return false;
|
|
2933
|
+
}
|
|
2934
|
+
function truncatePromptPreflightPreview(value, maxChars = 280) {
|
|
2935
|
+
const normalized = value.trim();
|
|
2936
|
+
if (normalized.length <= maxChars) {
|
|
2937
|
+
return normalized;
|
|
2938
|
+
}
|
|
2939
|
+
return `${normalized.slice(0, Math.max(0, maxChars - 1)).trimEnd()}\u2026`;
|
|
2940
|
+
}
|
|
2941
|
+
function formatPromptPreflightReason(reason) {
|
|
2942
|
+
const normalized = normalizeTelemetryString(reason);
|
|
2943
|
+
if (!normalized) {
|
|
2944
|
+
return void 0;
|
|
2945
|
+
}
|
|
2946
|
+
return normalized.replace(/[_-]+/g, " ");
|
|
2947
|
+
}
|
|
2948
|
+
function summarizePromptPreflightResult(params) {
|
|
2949
|
+
const reason = formatPromptPreflightReason(
|
|
2950
|
+
params.localFallbackApplied ? params.localFallbackReason ?? void 0 : params.verdict.reason
|
|
2951
|
+
) ?? "policy evaluation";
|
|
2952
|
+
if (!params.verdict.allowed && !params.localFallbackApplied) {
|
|
2953
|
+
return `Blocked the prompt before model execution because ${reason}.`;
|
|
2954
|
+
}
|
|
2955
|
+
if (params.localFallbackApplied) {
|
|
2956
|
+
return `Guard preflight degraded, so the SDK applied local fallback checks before model execution (${reason}).`;
|
|
2957
|
+
}
|
|
2958
|
+
if (params.verdict.shadow_mode && params.verdict.shadow_blocked) {
|
|
2959
|
+
return "Evaluated the prompt in shadow mode before model execution; shadow policy would have blocked it.";
|
|
2960
|
+
}
|
|
2961
|
+
if (params.verdict.simulated_decision === "masked" || params.verdict.detected_pii) {
|
|
2962
|
+
return "Evaluated the prompt before model execution and masked sensitive content where needed.";
|
|
2963
|
+
}
|
|
2964
|
+
return "Evaluated the prompt and attachments against guardrails before model execution.";
|
|
2965
|
+
}
|
|
2966
|
+
function buildPromptPreflightTelemetry(params) {
|
|
2967
|
+
const baseTelemetry = createAgentIdTelemetryContext(params.telemetry);
|
|
2968
|
+
const baseStepName = firstNonEmptyString(
|
|
2969
|
+
baseTelemetry?.workflow_step_name,
|
|
2970
|
+
baseTelemetry?.workflowStepName
|
|
2971
|
+
);
|
|
2972
|
+
const stepName = baseStepName ? `${toSnakeToken(baseStepName)}_preflight` : "prompt_preflight";
|
|
2973
|
+
const summary = summarizePromptPreflightResult({
|
|
2974
|
+
verdict: params.verdict,
|
|
2975
|
+
localFallbackApplied: params.local_fallback_applied,
|
|
2976
|
+
localFallbackReason: params.local_fallback_reason
|
|
2977
|
+
});
|
|
2978
|
+
return mergeTelemetryContexts(baseTelemetry, {
|
|
2979
|
+
workflow_step_id: createAgentIdCorrelationId(),
|
|
2980
|
+
workflow_step_name: stepName,
|
|
2981
|
+
event_title: "Prompt Preflight Evaluated",
|
|
2982
|
+
event_category: "guard",
|
|
2983
|
+
event_subtype: "prompt_preflight_evaluated",
|
|
2984
|
+
event_status: !params.verdict.allowed && !params.local_fallback_applied ? "blocked" : "completed",
|
|
2985
|
+
step_summary: summary,
|
|
2986
|
+
input_preview: truncatePromptPreflightPreview(params.input),
|
|
2987
|
+
output_preview: summary,
|
|
2988
|
+
runtime_surface: params.runtime_surface ?? "openai_sdk_guard",
|
|
2989
|
+
guard_event_id: params.guard_event_id ?? void 0,
|
|
2990
|
+
guard_latency_ms: params.guard_latency_ms ?? void 0,
|
|
2991
|
+
preflight_for_client_event_id: params.preflight_for_client_event_id,
|
|
2992
|
+
preflight_logged_via_sdk: true,
|
|
2993
|
+
lifecycle_status: "preflight_only"
|
|
2994
|
+
});
|
|
2995
|
+
}
|
|
2996
|
+
function inferOperationCategory(telemetry, eventType) {
|
|
2997
|
+
const explicitCategory = normalizeTelemetryCategory(
|
|
2998
|
+
telemetry?.event_category ?? telemetry?.eventCategory
|
|
2999
|
+
);
|
|
3000
|
+
if (explicitCategory === "ai" || explicitCategory === "llm" || explicitCategory === "inference") {
|
|
3001
|
+
return "ai";
|
|
3002
|
+
}
|
|
3003
|
+
if (explicitCategory === "guard" || explicitCategory === "security") {
|
|
3004
|
+
return "guard";
|
|
3005
|
+
}
|
|
3006
|
+
if (explicitCategory === "tool") return "tool";
|
|
3007
|
+
if (explicitCategory === "delivery" || explicitCategory === "send") return "delivery";
|
|
3008
|
+
if (explicitCategory === "inbox" || explicitCategory === "reply") return "inbox";
|
|
3009
|
+
if (explicitCategory === "workflow" || explicitCategory === "agent") return "workflow";
|
|
3010
|
+
if (explicitCategory === "compliance" || explicitCategory === "transparency") {
|
|
3011
|
+
return "compliance";
|
|
3012
|
+
}
|
|
3013
|
+
if (explicitCategory === "operational" || explicitCategory === "ops") {
|
|
3014
|
+
return "operational";
|
|
3015
|
+
}
|
|
3016
|
+
const haystack = [
|
|
3017
|
+
eventType,
|
|
3018
|
+
telemetry?.event_subtype,
|
|
3019
|
+
telemetry?.eventSubtype,
|
|
3020
|
+
telemetry?.tool_name,
|
|
3021
|
+
telemetry?.toolName,
|
|
3022
|
+
telemetry?.tool_target_type,
|
|
3023
|
+
telemetry?.toolTargetType,
|
|
3024
|
+
telemetry?.workflow_name,
|
|
3025
|
+
telemetry?.workflowName,
|
|
3026
|
+
telemetry?.workflow_step_name,
|
|
3027
|
+
telemetry?.workflowStepName,
|
|
3028
|
+
getObjectString(telemetry, "operation_family", "domain")
|
|
3029
|
+
].filter((entry) => typeof entry === "string" && entry.trim().length > 0).join(" ").replace(/[_./-]+/g, " ").toLowerCase();
|
|
3030
|
+
if (/\b(llm|ai|inference|completion|summary|classification|draft)\b/.test(haystack)) {
|
|
3031
|
+
return "ai";
|
|
3032
|
+
}
|
|
3033
|
+
if (/\b(guard|security|policy|pii|prompt[_ ]?injection|review)\b/.test(haystack)) {
|
|
3034
|
+
return "guard";
|
|
3035
|
+
}
|
|
3036
|
+
if (/\b(reply|inbox|inbound|received|bounce|opened|followup)\b/.test(haystack)) {
|
|
3037
|
+
return "inbox";
|
|
3038
|
+
}
|
|
3039
|
+
if (/\b(email|mail|send|delivery|delivered|slack|sms|webhook|notification)\b/.test(haystack)) {
|
|
3040
|
+
return "delivery";
|
|
3041
|
+
}
|
|
3042
|
+
if (/\b(workflow|step|run|agent)\b/.test(haystack)) {
|
|
3043
|
+
return "workflow";
|
|
3044
|
+
}
|
|
3045
|
+
if (/\b(compliance|transparency|audit|evidence)\b/.test(haystack)) {
|
|
3046
|
+
return "compliance";
|
|
3047
|
+
}
|
|
3048
|
+
if (/\b(tool|lookup|search|query|retrieve|fetch|crm|invoice|payment|ledger|expense|payroll|tax|finance|cv|resume|candidate|applicant|recruit|interview|screen|document|file|attachment|extract|parse|ocr|classify|sync|import|export|record|database|sql|shell|terminal|script)\b/.test(
|
|
3049
|
+
haystack
|
|
3050
|
+
)) {
|
|
3051
|
+
return "tool";
|
|
3052
|
+
}
|
|
3053
|
+
return "operational";
|
|
3054
|
+
}
|
|
3055
|
+
function inferOperationStatus(params) {
|
|
3056
|
+
const explicitStatus = normalizeTelemetryString(params.eventStatus)?.toLowerCase();
|
|
3057
|
+
if (explicitStatus === "started" || explicitStatus === "completed" || explicitStatus === "failed") {
|
|
3058
|
+
return explicitStatus;
|
|
3059
|
+
}
|
|
3060
|
+
if (explicitStatus === "blocked" || explicitStatus === "skipped") {
|
|
3061
|
+
return explicitStatus;
|
|
3062
|
+
}
|
|
3063
|
+
const normalizedEventType = normalizeTelemetryString(params.eventType)?.toLowerCase();
|
|
3064
|
+
if (normalizedEventType === "start") return "started";
|
|
3065
|
+
if (normalizedEventType === "error") return "failed";
|
|
3066
|
+
if (normalizedEventType === "security_block") return "blocked";
|
|
3067
|
+
if (normalizedEventType === "human_override") return "completed";
|
|
3068
|
+
if (normalizedEventType === "complete") return "completed";
|
|
3069
|
+
return params.severity === "error" ? "failed" : "completed";
|
|
3070
|
+
}
|
|
3071
|
+
function deriveOperationEventType(params) {
|
|
3072
|
+
const explicit = normalizeTelemetryString(params.explicitEventType);
|
|
3073
|
+
if (explicit) {
|
|
3074
|
+
return explicit;
|
|
3075
|
+
}
|
|
3076
|
+
if (params.status === "started") return "start";
|
|
3077
|
+
if (params.status === "failed") return "error";
|
|
3078
|
+
if (params.status === "blocked") {
|
|
3079
|
+
return params.category === "guard" ? "security_block" : "error";
|
|
3080
|
+
}
|
|
3081
|
+
return "complete";
|
|
3082
|
+
}
|
|
3083
|
+
function deriveSubtypeBase(telemetry) {
|
|
3084
|
+
const toolName = normalizeTelemetryString(telemetry?.tool_name ?? telemetry?.toolName);
|
|
3085
|
+
if (toolName) {
|
|
3086
|
+
const tokens = toSnakeToken(toolName).split("_").filter(Boolean);
|
|
3087
|
+
if (tokens.length > 1 && ["workflow", "agent", "operation", "ops", "hr", "finance", "compliance"].includes(tokens[0])) {
|
|
3088
|
+
return tokens.slice(1).join("_");
|
|
3089
|
+
}
|
|
3090
|
+
return tokens.join("_");
|
|
3091
|
+
}
|
|
3092
|
+
const workflowName = normalizeTelemetryString(
|
|
3093
|
+
telemetry?.workflow_step_name ?? telemetry?.workflowStepName ?? telemetry?.workflow_name ?? telemetry?.workflowName
|
|
3094
|
+
);
|
|
3095
|
+
if (workflowName) {
|
|
3096
|
+
return toSnakeToken(workflowName);
|
|
3097
|
+
}
|
|
3098
|
+
return void 0;
|
|
3099
|
+
}
|
|
3100
|
+
function deriveOperationSubtype(params) {
|
|
3101
|
+
const explicitSubtype = normalizeTelemetryString(params.explicitSubtype);
|
|
3102
|
+
if (explicitSubtype) {
|
|
3103
|
+
return toSnakeToken(explicitSubtype);
|
|
3104
|
+
}
|
|
3105
|
+
const base = deriveSubtypeBase(params.telemetry);
|
|
3106
|
+
const suffix = params.status === "started" ? "started" : params.status === "failed" ? "failed" : params.status === "blocked" ? "blocked" : params.status === "skipped" ? "skipped" : "completed";
|
|
3107
|
+
if (base) {
|
|
3108
|
+
return `${base}_${suffix}`;
|
|
3109
|
+
}
|
|
3110
|
+
if (params.eventType === "start") return `${params.category}_started`;
|
|
3111
|
+
if (params.eventType === "error") return `${params.category}_failed`;
|
|
3112
|
+
if (params.eventType === "security_block") return `${params.category}_blocked`;
|
|
3113
|
+
return `${params.category}_completed`;
|
|
3114
|
+
}
|
|
3115
|
+
function inferOperationSeverity(params) {
|
|
3116
|
+
if (params.explicitSeverity) {
|
|
3117
|
+
return params.explicitSeverity;
|
|
3118
|
+
}
|
|
3119
|
+
if (params.status === "failed" || params.status === "blocked") {
|
|
3120
|
+
return "error";
|
|
3121
|
+
}
|
|
3122
|
+
if (params.status === "skipped") {
|
|
3123
|
+
return "warning";
|
|
3124
|
+
}
|
|
3125
|
+
return "info";
|
|
3126
|
+
}
|
|
3127
|
+
function createAgentIdCorrelationId(seed) {
|
|
3128
|
+
return createCorrelationId(seed);
|
|
3129
|
+
}
|
|
3130
|
+
function createAgentIdTelemetryContext(value) {
|
|
3131
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3132
|
+
return void 0;
|
|
3133
|
+
}
|
|
3134
|
+
const raw = { ...value };
|
|
3135
|
+
const normalized = {};
|
|
3136
|
+
const assignString = (key, ...aliases) => {
|
|
3137
|
+
const next = getObjectString(raw, key, ...aliases);
|
|
3138
|
+
if (next) {
|
|
3139
|
+
normalized[key] = next;
|
|
3140
|
+
}
|
|
3141
|
+
};
|
|
3142
|
+
const assignNumber = (key, ...aliases) => {
|
|
3143
|
+
const next = getObjectNumber(raw, key, ...aliases);
|
|
3144
|
+
if (typeof next === "number") {
|
|
3145
|
+
normalized[key] = next;
|
|
3146
|
+
}
|
|
3147
|
+
};
|
|
3148
|
+
assignString("workflow_id", "workflowId");
|
|
3149
|
+
assignString("workflow_run_id", "workflowRunId");
|
|
3150
|
+
assignString("workflow_step_id", "workflowStepId");
|
|
3151
|
+
assignString("workflow_name", "workflowName");
|
|
3152
|
+
assignString("workflow_step_name", "workflowStepName");
|
|
3153
|
+
assignNumber("workflow_step_index", "workflowStepIndex");
|
|
3154
|
+
assignString("parent_event_id", "parentEventId");
|
|
3155
|
+
assignString("tool_name", "toolName");
|
|
3156
|
+
assignString("tool_target", "toolTarget");
|
|
3157
|
+
assignString("tool_target_type", "toolTargetType");
|
|
3158
|
+
assignString("event_title", "eventTitle");
|
|
3159
|
+
assignString("event_status", "eventStatus");
|
|
3160
|
+
assignString("event_category", "eventCategory");
|
|
3161
|
+
assignString("event_subtype", "eventSubtype");
|
|
3162
|
+
const consumedKeys = /* @__PURE__ */ new Set([
|
|
3163
|
+
"workflow_id",
|
|
3164
|
+
"workflowId",
|
|
3165
|
+
"workflow_run_id",
|
|
3166
|
+
"workflowRunId",
|
|
3167
|
+
"workflow_step_id",
|
|
3168
|
+
"workflowStepId",
|
|
3169
|
+
"workflow_name",
|
|
3170
|
+
"workflowName",
|
|
3171
|
+
"workflow_step_name",
|
|
3172
|
+
"workflowStepName",
|
|
3173
|
+
"workflow_step_index",
|
|
3174
|
+
"workflowStepIndex",
|
|
3175
|
+
"parent_event_id",
|
|
3176
|
+
"parentEventId",
|
|
3177
|
+
"tool_name",
|
|
3178
|
+
"toolName",
|
|
3179
|
+
"tool_target",
|
|
3180
|
+
"toolTarget",
|
|
3181
|
+
"tool_target_type",
|
|
3182
|
+
"toolTargetType",
|
|
3183
|
+
"event_title",
|
|
3184
|
+
"eventTitle",
|
|
3185
|
+
"event_status",
|
|
3186
|
+
"eventStatus",
|
|
3187
|
+
"event_category",
|
|
3188
|
+
"eventCategory",
|
|
3189
|
+
"event_subtype",
|
|
3190
|
+
"eventSubtype"
|
|
3191
|
+
]);
|
|
3192
|
+
for (const [key, entry] of Object.entries(raw)) {
|
|
3193
|
+
if (consumedKeys.has(key) || entry === void 0) {
|
|
3194
|
+
continue;
|
|
3195
|
+
}
|
|
3196
|
+
if (typeof entry === "string") {
|
|
3197
|
+
if (entry.trim().length > 0) {
|
|
3198
|
+
normalized[key] = entry.trim();
|
|
3199
|
+
}
|
|
3200
|
+
continue;
|
|
3201
|
+
}
|
|
3202
|
+
normalized[key] = entry;
|
|
3203
|
+
}
|
|
3204
|
+
if (typeof normalized.workflow_id !== "string" && typeof normalized.workflow_run_id === "string") {
|
|
3205
|
+
normalized.workflow_id = normalized.workflow_run_id;
|
|
3206
|
+
}
|
|
3207
|
+
return Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
3208
|
+
}
|
|
3209
|
+
function createAgentIdOperationLog(params) {
|
|
3210
|
+
const telemetry = createAgentIdTelemetryContext(params.telemetry);
|
|
3211
|
+
const category = inferOperationCategory(
|
|
3212
|
+
createAgentIdTelemetryContext({
|
|
3213
|
+
...telemetry ?? {},
|
|
3214
|
+
event_category: params.event_category ?? telemetry?.event_category
|
|
3215
|
+
}),
|
|
3216
|
+
params.event_type
|
|
3217
|
+
);
|
|
3218
|
+
const status = inferOperationStatus({
|
|
3219
|
+
eventStatus: normalizeTelemetryString(params.event_status) ?? normalizeTelemetryString(telemetry?.event_status ?? telemetry?.eventStatus),
|
|
3220
|
+
eventType: params.event_type,
|
|
3221
|
+
severity: params.severity
|
|
3222
|
+
});
|
|
3223
|
+
const eventType = deriveOperationEventType({
|
|
3224
|
+
explicitEventType: params.event_type,
|
|
3225
|
+
status,
|
|
3226
|
+
category
|
|
3227
|
+
});
|
|
3228
|
+
const subtype = deriveOperationSubtype({
|
|
3229
|
+
explicitSubtype: normalizeTelemetryString(params.event_subtype) ?? normalizeTelemetryString(telemetry?.event_subtype ?? telemetry?.eventSubtype),
|
|
3230
|
+
telemetry,
|
|
3231
|
+
category,
|
|
3232
|
+
status,
|
|
3233
|
+
eventType
|
|
3234
|
+
});
|
|
3235
|
+
const severity = inferOperationSeverity({
|
|
3236
|
+
explicitSeverity: params.severity,
|
|
3237
|
+
status
|
|
3238
|
+
});
|
|
3239
|
+
const usage = params.usage;
|
|
3240
|
+
const clientEventId = normalizeTelemetryString(params.client_event_id) ?? normalizeTelemetryString(telemetry?.client_event_id);
|
|
3241
|
+
const modelUsed = category === "ai" || hasUsageSignals(usage) || typeof params.model === "string" && params.model.trim().length > 0 && params.model.trim().toLowerCase() !== "not_applicable";
|
|
3242
|
+
const metadata = {
|
|
3243
|
+
...params.metadata ?? {},
|
|
3244
|
+
...telemetry ?? {},
|
|
3245
|
+
event_category: category,
|
|
3246
|
+
event_subtype: subtype,
|
|
3247
|
+
event_status: status,
|
|
3248
|
+
status,
|
|
3249
|
+
model_used: modelUsed,
|
|
3250
|
+
spend_bearing: category === "ai" && hasUsageSignals(usage)
|
|
3251
|
+
};
|
|
3252
|
+
if (clientEventId && typeof metadata.client_event_id !== "string") {
|
|
3253
|
+
metadata.client_event_id = clientEventId;
|
|
3254
|
+
}
|
|
3255
|
+
return {
|
|
3256
|
+
event_id: normalizeTelemetryString(params.event_id) ?? createEventId2(),
|
|
3257
|
+
system_id: params.system_id,
|
|
3258
|
+
user_id: params.user_id,
|
|
3259
|
+
request_identity: params.request_identity,
|
|
3260
|
+
input: params.input ?? "",
|
|
3261
|
+
output: params.output ?? "",
|
|
3262
|
+
model: normalizeTelemetryString(params.model) ?? "not_applicable",
|
|
3263
|
+
usage,
|
|
3264
|
+
tokens: params.tokens,
|
|
3265
|
+
latency: params.latency,
|
|
3266
|
+
metadata,
|
|
3267
|
+
event_type: eventType,
|
|
3268
|
+
severity,
|
|
3269
|
+
timestamp: params.timestamp,
|
|
3270
|
+
client_capabilities: params.client_capabilities
|
|
3271
|
+
};
|
|
3272
|
+
}
|
|
3273
|
+
function asTelemetryContext(value) {
|
|
3274
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3275
|
+
return void 0;
|
|
3276
|
+
}
|
|
3277
|
+
return createAgentIdTelemetryContext(value);
|
|
3278
|
+
}
|
|
3279
|
+
function mergeTelemetryContexts(...contexts) {
|
|
3280
|
+
const merged = {};
|
|
3281
|
+
let hasValues = false;
|
|
3282
|
+
for (const context of contexts) {
|
|
3283
|
+
if (!context) {
|
|
3284
|
+
continue;
|
|
3285
|
+
}
|
|
3286
|
+
Object.assign(merged, createAgentIdTelemetryContext(context));
|
|
3287
|
+
hasValues = true;
|
|
3288
|
+
}
|
|
3289
|
+
return hasValues ? createAgentIdTelemetryContext(merged) : void 0;
|
|
3290
|
+
}
|
|
3291
|
+
function extractRequestTelemetryContext(requestBody) {
|
|
3292
|
+
return asTelemetryContext(requestBody[OPENAI_TELEMETRY_FIELD]);
|
|
3293
|
+
}
|
|
3294
|
+
function stripRequestTelemetryContext(requestBody) {
|
|
3295
|
+
if (!Object.prototype.hasOwnProperty.call(requestBody, OPENAI_TELEMETRY_FIELD)) {
|
|
3296
|
+
return requestBody;
|
|
3297
|
+
}
|
|
3298
|
+
const nextRequestBody = { ...requestBody };
|
|
3299
|
+
delete nextRequestBody[OPENAI_TELEMETRY_FIELD];
|
|
3300
|
+
return nextRequestBody;
|
|
3301
|
+
}
|
|
2382
3302
|
async function waitForRetry(attemptIndex) {
|
|
2383
3303
|
const delay = GUARD_RETRY_DELAYS_MS[attemptIndex];
|
|
2384
3304
|
if (!delay) return;
|
|
@@ -2558,6 +3478,61 @@ function createStreamingPlaceholderRewriter(piiManager, mapping) {
|
|
|
2558
3478
|
}
|
|
2559
3479
|
};
|
|
2560
3480
|
}
|
|
3481
|
+
var TYPED_PLACEHOLDER_RE = /<[A-Z][A-Z0-9_]*_\d+>/g;
|
|
3482
|
+
function derivePlaceholderMappingFromTransform(source, transformed) {
|
|
3483
|
+
if (!source || !transformed || source === transformed) {
|
|
3484
|
+
return {};
|
|
3485
|
+
}
|
|
3486
|
+
const placeholders = [...transformed.matchAll(TYPED_PLACEHOLDER_RE)].map((match) => ({
|
|
3487
|
+
token: match[0],
|
|
3488
|
+
start: match.index ?? 0,
|
|
3489
|
+
end: (match.index ?? 0) + match[0].length
|
|
3490
|
+
}));
|
|
3491
|
+
if (placeholders.length === 0) {
|
|
3492
|
+
return {};
|
|
3493
|
+
}
|
|
3494
|
+
const mapping = {};
|
|
3495
|
+
let sourceCursor = 0;
|
|
3496
|
+
let transformedCursor = 0;
|
|
3497
|
+
for (const placeholder of placeholders) {
|
|
3498
|
+
const literalBefore = transformed.slice(transformedCursor, placeholder.start);
|
|
3499
|
+
if (literalBefore) {
|
|
3500
|
+
const literalIndex = source.indexOf(literalBefore, sourceCursor);
|
|
3501
|
+
if (literalIndex < 0) {
|
|
3502
|
+
return {};
|
|
3503
|
+
}
|
|
3504
|
+
sourceCursor = literalIndex + literalBefore.length;
|
|
3505
|
+
}
|
|
3506
|
+
const nextPlaceholderStart = placeholders.find((candidate) => candidate.start > placeholder.start)?.start ?? transformed.length;
|
|
3507
|
+
const literalAfter = transformed.slice(placeholder.end, nextPlaceholderStart);
|
|
3508
|
+
const nextLiteralIndex = literalAfter ? source.indexOf(literalAfter, sourceCursor) : nextPlaceholderStart >= transformed.length ? source.length : sourceCursor;
|
|
3509
|
+
if (nextLiteralIndex < sourceCursor) {
|
|
3510
|
+
return {};
|
|
3511
|
+
}
|
|
3512
|
+
const originalValue = source.slice(sourceCursor, nextLiteralIndex);
|
|
3513
|
+
if (originalValue.length > 0 && typeof mapping[placeholder.token] !== "string") {
|
|
3514
|
+
mapping[placeholder.token] = originalValue;
|
|
3515
|
+
}
|
|
3516
|
+
sourceCursor = nextLiteralIndex;
|
|
3517
|
+
transformedCursor = placeholder.end;
|
|
3518
|
+
}
|
|
3519
|
+
return mapping;
|
|
3520
|
+
}
|
|
3521
|
+
function mergePiiMappings(primary, fallback) {
|
|
3522
|
+
const merged = { ...primary };
|
|
3523
|
+
for (const [placeholder, value] of Object.entries(fallback)) {
|
|
3524
|
+
if (typeof merged[placeholder] !== "string" && typeof value === "string") {
|
|
3525
|
+
merged[placeholder] = value;
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
return merged;
|
|
3529
|
+
}
|
|
3530
|
+
function textContainsMappingPlaceholder(text, mapping) {
|
|
3531
|
+
if (!text || !mapping) {
|
|
3532
|
+
return false;
|
|
3533
|
+
}
|
|
3534
|
+
return Object.keys(mapping).some((placeholder) => placeholder.length > 0 && text.includes(placeholder));
|
|
3535
|
+
}
|
|
2561
3536
|
var SecurityBlockError = class extends Error {
|
|
2562
3537
|
constructor(reason = "guard_denied") {
|
|
2563
3538
|
super(`AgentID: Security Blocked (${reason})`);
|
|
@@ -2582,6 +3557,7 @@ var AgentID = class {
|
|
|
2582
3557
|
this.apiKey = resolveConfiguredApiKey(config.apiKey);
|
|
2583
3558
|
this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
|
|
2584
3559
|
this.configuredPiiMasking = typeof config.piiMasking === "boolean" ? config.piiMasking : null;
|
|
3560
|
+
this.configuredSecretMasking = typeof config.secretMasking === "boolean" ? config.secretMasking : null;
|
|
2585
3561
|
this.checkInjection = config.checkInjection !== false;
|
|
2586
3562
|
this.clientFastFail = config.clientFastFail === true || config.client_fast_fail === true;
|
|
2587
3563
|
this.aiScanEnabled = config.aiScanEnabled !== false;
|
|
@@ -2603,11 +3579,26 @@ var AgentID = class {
|
|
|
2603
3579
|
get piiMasking() {
|
|
2604
3580
|
return this.configuredPiiMasking ?? void 0;
|
|
2605
3581
|
}
|
|
3582
|
+
get secretMasking() {
|
|
3583
|
+
return this.configuredSecretMasking ?? void 0;
|
|
3584
|
+
}
|
|
2606
3585
|
resolveEffectivePiiMasking(config) {
|
|
3586
|
+
if (config?.enable_sdk_pii_masking === true) {
|
|
3587
|
+
return true;
|
|
3588
|
+
}
|
|
2607
3589
|
if (this.configuredPiiMasking !== null) {
|
|
2608
3590
|
return this.configuredPiiMasking;
|
|
2609
3591
|
}
|
|
2610
|
-
return
|
|
3592
|
+
return false;
|
|
3593
|
+
}
|
|
3594
|
+
resolveEffectiveSecretMasking(config) {
|
|
3595
|
+
if (config?.enable_sdk_secret_masking === true || config?.enable_sdk_pii_masking === true) {
|
|
3596
|
+
return true;
|
|
3597
|
+
}
|
|
3598
|
+
if (this.configuredSecretMasking !== null) {
|
|
3599
|
+
return this.configuredSecretMasking;
|
|
3600
|
+
}
|
|
3601
|
+
return false;
|
|
2611
3602
|
}
|
|
2612
3603
|
getEffectivePiiMasking(options) {
|
|
2613
3604
|
return this.resolveEffectivePiiMasking(this.getCachedCapabilityConfig(options));
|
|
@@ -2615,6 +3606,9 @@ var AgentID = class {
|
|
|
2615
3606
|
getEffectivePiiMaskingForConfig(capabilityConfig) {
|
|
2616
3607
|
return this.resolveEffectivePiiMasking(capabilityConfig);
|
|
2617
3608
|
}
|
|
3609
|
+
getEffectiveSecretMaskingForConfig(capabilityConfig) {
|
|
3610
|
+
return this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3611
|
+
}
|
|
2618
3612
|
buildClientCapabilities(framework = "js_sdk", hasFeedbackHandler = false, capabilityConfig) {
|
|
2619
3613
|
return {
|
|
2620
3614
|
capabilities: {
|
|
@@ -2622,6 +3616,9 @@ var AgentID = class {
|
|
|
2622
3616
|
pii_masking_enabled: this.resolveEffectivePiiMasking(
|
|
2623
3617
|
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
2624
3618
|
),
|
|
3619
|
+
secret_masking_enabled: this.resolveEffectiveSecretMasking(
|
|
3620
|
+
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
3621
|
+
),
|
|
2625
3622
|
framework
|
|
2626
3623
|
}
|
|
2627
3624
|
};
|
|
@@ -2761,10 +3758,13 @@ var AgentID = class {
|
|
|
2761
3758
|
systemId: params.systemId,
|
|
2762
3759
|
eventId: params.clientEventId,
|
|
2763
3760
|
clientEventId: params.clientEventId,
|
|
2764
|
-
telemetryMetadata:
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
3761
|
+
telemetryMetadata: mergeTelemetryContexts(
|
|
3762
|
+
params.telemetryMetadata,
|
|
3763
|
+
buildSdkTimingMetadata({
|
|
3764
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
3765
|
+
sdkConfigVersion: params.capabilityConfig.version
|
|
3766
|
+
})
|
|
3767
|
+
)
|
|
2768
3768
|
});
|
|
2769
3769
|
}
|
|
2770
3770
|
try {
|
|
@@ -2781,7 +3781,8 @@ var AgentID = class {
|
|
|
2781
3781
|
actionTaken: event.actionTaken,
|
|
2782
3782
|
apiKey: params.apiKey,
|
|
2783
3783
|
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
2784
|
-
sdkLocalScanMs
|
|
3784
|
+
sdkLocalScanMs,
|
|
3785
|
+
telemetryMetadata: params.telemetryMetadata
|
|
2785
3786
|
});
|
|
2786
3787
|
}
|
|
2787
3788
|
return {
|
|
@@ -2796,7 +3797,8 @@ var AgentID = class {
|
|
|
2796
3797
|
actionTaken: error.actionTaken,
|
|
2797
3798
|
apiKey: params.apiKey,
|
|
2798
3799
|
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
2799
|
-
sdkLocalScanMs: Math.max(0, Date.now() - localScanStartedAt)
|
|
3800
|
+
sdkLocalScanMs: Math.max(0, Date.now() - localScanStartedAt),
|
|
3801
|
+
telemetryMetadata: params.telemetryMetadata
|
|
2800
3802
|
});
|
|
2801
3803
|
}
|
|
2802
3804
|
throw error;
|
|
@@ -2810,7 +3812,7 @@ var AgentID = class {
|
|
|
2810
3812
|
);
|
|
2811
3813
|
let sanitizedInput = params.input;
|
|
2812
3814
|
let sdkLocalScanMs = 0;
|
|
2813
|
-
if (this.configuredPiiMasking === null) {
|
|
3815
|
+
if (this.configuredPiiMasking === null || this.configuredSecretMasking === null) {
|
|
2814
3816
|
const refreshed = await this.refreshCapabilityConfigBeforeClientControl({
|
|
2815
3817
|
capabilityConfig,
|
|
2816
3818
|
sdkConfigFetchMs,
|
|
@@ -2821,8 +3823,12 @@ var AgentID = class {
|
|
|
2821
3823
|
}
|
|
2822
3824
|
if (!this.clientFastFail) {
|
|
2823
3825
|
const effectivePiiMasking2 = this.resolveEffectivePiiMasking(capabilityConfig);
|
|
2824
|
-
|
|
2825
|
-
|
|
3826
|
+
const effectiveSecretMasking2 = this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3827
|
+
if (!capabilityConfig.block_pii_leakage && effectivePiiMasking2 || !capabilityConfig.block_secret_leakage && effectiveSecretMasking2) {
|
|
3828
|
+
const masked = this.pii.anonymize(sanitizedInput, {
|
|
3829
|
+
pii: !capabilityConfig.block_pii_leakage && effectivePiiMasking2,
|
|
3830
|
+
secrets: !capabilityConfig.block_secret_leakage && effectiveSecretMasking2
|
|
3831
|
+
});
|
|
2826
3832
|
return {
|
|
2827
3833
|
sanitizedInput: masked.maskedText,
|
|
2828
3834
|
capabilityConfig,
|
|
@@ -2854,13 +3860,18 @@ var AgentID = class {
|
|
|
2854
3860
|
apiKey: effectiveApiKey,
|
|
2855
3861
|
clientEventId: params.clientEventId,
|
|
2856
3862
|
sdkConfigFetchMs,
|
|
3863
|
+
telemetryMetadata: params.telemetryMetadata,
|
|
2857
3864
|
runPromptInjectionCheck: !params.skipInjectionScan
|
|
2858
3865
|
});
|
|
2859
3866
|
sanitizedInput = enforced.sanitizedInput;
|
|
2860
3867
|
sdkLocalScanMs = enforced.sdkLocalScanMs;
|
|
2861
3868
|
const effectivePiiMasking = this.resolveEffectivePiiMasking(capabilityConfig);
|
|
2862
|
-
|
|
2863
|
-
|
|
3869
|
+
const effectiveSecretMasking = this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3870
|
+
if (!capabilityConfig.block_pii_leakage && effectivePiiMasking || !capabilityConfig.block_secret_leakage && effectiveSecretMasking) {
|
|
3871
|
+
const masked = this.pii.anonymize(sanitizedInput, {
|
|
3872
|
+
pii: !capabilityConfig.block_pii_leakage && effectivePiiMasking,
|
|
3873
|
+
secrets: !capabilityConfig.block_secret_leakage && effectiveSecretMasking
|
|
3874
|
+
});
|
|
2864
3875
|
return {
|
|
2865
3876
|
sanitizedInput: masked.maskedText,
|
|
2866
3877
|
capabilityConfig,
|
|
@@ -2896,6 +3907,7 @@ var AgentID = class {
|
|
|
2896
3907
|
apiKey: effectiveApiKey,
|
|
2897
3908
|
clientEventId: params.clientEventId,
|
|
2898
3909
|
sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs,
|
|
3910
|
+
telemetryMetadata: params.telemetryMetadata,
|
|
2899
3911
|
runPromptInjectionCheck: true
|
|
2900
3912
|
});
|
|
2901
3913
|
return {
|
|
@@ -2959,9 +3971,30 @@ var AgentID = class {
|
|
|
2959
3971
|
if (!message || typeof message !== "object") {
|
|
2960
3972
|
return req;
|
|
2961
3973
|
}
|
|
3974
|
+
const currentContent = message.content;
|
|
3975
|
+
let nextContent = maskedText;
|
|
3976
|
+
if (Array.isArray(currentContent)) {
|
|
3977
|
+
let textReplaced = false;
|
|
3978
|
+
const preservedParts = [];
|
|
3979
|
+
for (const part of currentContent) {
|
|
3980
|
+
if (!part || typeof part !== "object" || part.type !== "text" || typeof part.text !== "string") {
|
|
3981
|
+
preservedParts.push(part);
|
|
3982
|
+
continue;
|
|
3983
|
+
}
|
|
3984
|
+
if (textReplaced) {
|
|
3985
|
+
continue;
|
|
3986
|
+
}
|
|
3987
|
+
textReplaced = true;
|
|
3988
|
+
preservedParts.push({
|
|
3989
|
+
...part,
|
|
3990
|
+
text: maskedText
|
|
3991
|
+
});
|
|
3992
|
+
}
|
|
3993
|
+
nextContent = textReplaced ? preservedParts : [{ type: "text", text: maskedText }, ...currentContent];
|
|
3994
|
+
}
|
|
2962
3995
|
newMessages[lastUserIdx] = {
|
|
2963
3996
|
...message,
|
|
2964
|
-
content:
|
|
3997
|
+
content: nextContent
|
|
2965
3998
|
};
|
|
2966
3999
|
if (!req || typeof req !== "object") {
|
|
2967
4000
|
return req;
|
|
@@ -2980,6 +4013,7 @@ var AgentID = class {
|
|
|
2980
4013
|
event_type: "security_policy_violation",
|
|
2981
4014
|
severity: "high",
|
|
2982
4015
|
metadata: {
|
|
4016
|
+
...params.telemetryMetadata ?? {},
|
|
2983
4017
|
event_type: "security_policy_violation",
|
|
2984
4018
|
severity: "high",
|
|
2985
4019
|
system_id: params.systemId,
|
|
@@ -3007,6 +4041,7 @@ var AgentID = class {
|
|
|
3007
4041
|
event_type: "security_alert",
|
|
3008
4042
|
severity: "warning",
|
|
3009
4043
|
metadata: {
|
|
4044
|
+
...params.guardParams.metadata ?? {},
|
|
3010
4045
|
source: "guard",
|
|
3011
4046
|
status: params.status,
|
|
3012
4047
|
guard_reason: params.reason,
|
|
@@ -3449,21 +4484,29 @@ var AgentID = class {
|
|
|
3449
4484
|
wrapCompletion(completion, options) {
|
|
3450
4485
|
if (typeof completion === "string") {
|
|
3451
4486
|
const masked = this.pii.anonymize(completion);
|
|
4487
|
+
const placeholderOutputMasked = textContainsMappingPlaceholder(
|
|
4488
|
+
completion,
|
|
4489
|
+
options?.piiMapping
|
|
4490
|
+
);
|
|
3452
4491
|
return {
|
|
3453
4492
|
mode: "static",
|
|
3454
4493
|
rawOutput: completion,
|
|
3455
4494
|
transformedOutput: masked.maskedText,
|
|
3456
|
-
outputMasked: masked.maskedText !== completion
|
|
4495
|
+
outputMasked: masked.maskedText !== completion || placeholderOutputMasked
|
|
3457
4496
|
};
|
|
3458
4497
|
}
|
|
3459
4498
|
if (!isAsyncIterable(completion)) {
|
|
3460
4499
|
const asText = String(completion ?? "");
|
|
3461
4500
|
const masked = this.pii.anonymize(asText);
|
|
4501
|
+
const placeholderOutputMasked = textContainsMappingPlaceholder(
|
|
4502
|
+
asText,
|
|
4503
|
+
options?.piiMapping
|
|
4504
|
+
);
|
|
3462
4505
|
return {
|
|
3463
4506
|
mode: "static",
|
|
3464
4507
|
rawOutput: asText,
|
|
3465
4508
|
transformedOutput: masked.maskedText,
|
|
3466
|
-
outputMasked: masked.maskedText !== asText
|
|
4509
|
+
outputMasked: masked.maskedText !== asText || placeholderOutputMasked
|
|
3467
4510
|
};
|
|
3468
4511
|
}
|
|
3469
4512
|
const source = completion;
|
|
@@ -3473,8 +4516,10 @@ var AgentID = class {
|
|
|
3473
4516
|
const isOpenAIStreamFinishChunk = this.isOpenAIStreamFinishChunk.bind(this);
|
|
3474
4517
|
const rewriteOpenAIStreamChunkForClient = this.rewriteOpenAIStreamChunkForClient.bind(this);
|
|
3475
4518
|
const createSyntheticOpenAIStreamChunk = this.createSyntheticOpenAIStreamChunk.bind(this);
|
|
4519
|
+
const setOpenAIStreamChunkText = this.setOpenAIStreamChunkText.bind(this);
|
|
3476
4520
|
const piiManager = this.pii;
|
|
3477
4521
|
const streamRewriter = options?.deanonymizeForClient === true && options.piiMapping ? createStreamingPlaceholderRewriter(piiManager, options.piiMapping) : null;
|
|
4522
|
+
const maskForClient = options?.maskForClient === true && streamRewriter === null;
|
|
3478
4523
|
let lastUsage;
|
|
3479
4524
|
let resolveDone = null;
|
|
3480
4525
|
let rejectDone = null;
|
|
@@ -3487,12 +4532,17 @@ var AgentID = class {
|
|
|
3487
4532
|
try {
|
|
3488
4533
|
let finishChunkFlushed = false;
|
|
3489
4534
|
let lastChunkTemplate;
|
|
4535
|
+
let clientRawText = "";
|
|
4536
|
+
let clientMaskFlushed = false;
|
|
3490
4537
|
for await (const chunk of source) {
|
|
3491
4538
|
const chunkText = extractStreamChunkText(chunk);
|
|
3492
|
-
const isFinishChunk = streamRewriter ? isOpenAIStreamFinishChunk(chunk) : false;
|
|
4539
|
+
const isFinishChunk = streamRewriter || maskForClient ? isOpenAIStreamFinishChunk(chunk) : false;
|
|
3493
4540
|
if (chunkText) {
|
|
3494
4541
|
await collector.push(chunkText);
|
|
3495
4542
|
lastChunkTemplate = chunk;
|
|
4543
|
+
if (maskForClient) {
|
|
4544
|
+
clientRawText += chunkText;
|
|
4545
|
+
}
|
|
3496
4546
|
}
|
|
3497
4547
|
const chunkUsage = extractStreamChunkUsage(chunk);
|
|
3498
4548
|
if (chunkUsage) {
|
|
@@ -3512,6 +4562,28 @@ var AgentID = class {
|
|
|
3512
4562
|
}
|
|
3513
4563
|
continue;
|
|
3514
4564
|
}
|
|
4565
|
+
if (maskForClient) {
|
|
4566
|
+
if (isFinishChunk) {
|
|
4567
|
+
const maskedClientText = piiManager.anonymize(clientRawText).maskedText;
|
|
4568
|
+
clientMaskFlushed = true;
|
|
4569
|
+
if (maskedClientText.length > 0) {
|
|
4570
|
+
yield createSyntheticOpenAIStreamChunk(
|
|
4571
|
+
maskedClientText,
|
|
4572
|
+
lastChunkTemplate ?? chunk
|
|
4573
|
+
);
|
|
4574
|
+
}
|
|
4575
|
+
if (chunkText) {
|
|
4576
|
+
setOpenAIStreamChunkText(chunk, "");
|
|
4577
|
+
}
|
|
4578
|
+
yield chunk;
|
|
4579
|
+
finishChunkFlushed = true;
|
|
4580
|
+
continue;
|
|
4581
|
+
}
|
|
4582
|
+
if (!chunkText) {
|
|
4583
|
+
yield chunk;
|
|
4584
|
+
}
|
|
4585
|
+
continue;
|
|
4586
|
+
}
|
|
3515
4587
|
yield chunk;
|
|
3516
4588
|
}
|
|
3517
4589
|
if (streamRewriter && !finishChunkFlushed) {
|
|
@@ -3523,14 +4595,27 @@ var AgentID = class {
|
|
|
3523
4595
|
);
|
|
3524
4596
|
}
|
|
3525
4597
|
}
|
|
4598
|
+
if (maskForClient && !clientMaskFlushed) {
|
|
4599
|
+
const maskedClientText = piiManager.anonymize(clientRawText).maskedText;
|
|
4600
|
+
if (maskedClientText.length > 0) {
|
|
4601
|
+
yield createSyntheticOpenAIStreamChunk(
|
|
4602
|
+
maskedClientText,
|
|
4603
|
+
lastChunkTemplate
|
|
4604
|
+
);
|
|
4605
|
+
}
|
|
4606
|
+
}
|
|
3526
4607
|
await collector.close();
|
|
3527
4608
|
const rawOutput = await collector.result;
|
|
3528
4609
|
const masked = piiManager.anonymize(rawOutput);
|
|
4610
|
+
const placeholderOutputMasked = textContainsMappingPlaceholder(
|
|
4611
|
+
rawOutput,
|
|
4612
|
+
options?.piiMapping
|
|
4613
|
+
);
|
|
3529
4614
|
resolveDone?.({
|
|
3530
4615
|
mode: "static",
|
|
3531
4616
|
rawOutput,
|
|
3532
4617
|
transformedOutput: masked.maskedText,
|
|
3533
|
-
outputMasked: masked.maskedText !== rawOutput,
|
|
4618
|
+
outputMasked: masked.maskedText !== rawOutput || placeholderOutputMasked,
|
|
3534
4619
|
usage: lastUsage
|
|
3535
4620
|
});
|
|
3536
4621
|
} catch (error) {
|
|
@@ -3565,6 +4650,37 @@ var AgentID = class {
|
|
|
3565
4650
|
);
|
|
3566
4651
|
}
|
|
3567
4652
|
}
|
|
4653
|
+
buildOperationLogParams(params) {
|
|
4654
|
+
return createAgentIdOperationLog(params);
|
|
4655
|
+
}
|
|
4656
|
+
async logOperation(params, options) {
|
|
4657
|
+
return this.log(this.buildOperationLogParams(params), options);
|
|
4658
|
+
}
|
|
4659
|
+
async logPromptPreflightStep(params, options) {
|
|
4660
|
+
const telemetry = buildPromptPreflightTelemetry(params);
|
|
4661
|
+
const summary = firstNonEmptyString(telemetry?.step_summary, telemetry?.stepSummary) ?? summarizePromptPreflightResult({
|
|
4662
|
+
verdict: params.verdict,
|
|
4663
|
+
localFallbackApplied: params.local_fallback_applied,
|
|
4664
|
+
localFallbackReason: params.local_fallback_reason
|
|
4665
|
+
});
|
|
4666
|
+
await this.logOperation(
|
|
4667
|
+
{
|
|
4668
|
+
system_id: params.system_id,
|
|
4669
|
+
user_id: params.user_id,
|
|
4670
|
+
request_identity: params.request_identity,
|
|
4671
|
+
input: params.input,
|
|
4672
|
+
output: summary,
|
|
4673
|
+
model: "not_applicable",
|
|
4674
|
+
latency: params.guard_latency_ms ?? void 0,
|
|
4675
|
+
telemetry,
|
|
4676
|
+
client_capabilities: params.client_capabilities
|
|
4677
|
+
},
|
|
4678
|
+
options
|
|
4679
|
+
);
|
|
4680
|
+
}
|
|
4681
|
+
operation(params, options) {
|
|
4682
|
+
return this.logOperation(params, options);
|
|
4683
|
+
}
|
|
3568
4684
|
/**
|
|
3569
4685
|
* Analytics alias for telemetry logging.
|
|
3570
4686
|
*/
|
|
@@ -3609,49 +4725,56 @@ var AgentID = class {
|
|
|
3609
4725
|
if (typeof originalCreate !== "function") return originalCreate;
|
|
3610
4726
|
return async (...args) => {
|
|
3611
4727
|
const normalizedCreateArgs = normalizeOpenAICreateArgs(args);
|
|
3612
|
-
const
|
|
4728
|
+
const rawReq = normalizedCreateArgs?.[0] ?? {};
|
|
4729
|
+
const requestTelemetry = extractRequestTelemetryContext(rawReq);
|
|
4730
|
+
const telemetryMetadata = mergeTelemetryContexts(
|
|
4731
|
+
options.telemetry,
|
|
4732
|
+
requestTelemetry
|
|
4733
|
+
);
|
|
4734
|
+
const providerReq = stripRequestTelemetryContext(rawReq);
|
|
3613
4735
|
const pipelineStartedAt = Date.now();
|
|
3614
|
-
const requestLevelApiKey = options.resolveApiKey?.(
|
|
4736
|
+
const requestLevelApiKey = options.resolveApiKey?.(rawReq) ?? options.apiKey ?? options.api_key;
|
|
3615
4737
|
const effectiveApiKey = this.resolveApiKey(requestLevelApiKey);
|
|
3616
4738
|
const requestOptions = { apiKey: effectiveApiKey };
|
|
3617
|
-
const clientEventId = this.resolveClientEventId(
|
|
4739
|
+
const clientEventId = this.resolveClientEventId(rawReq);
|
|
3618
4740
|
const effectiveStrictMode = await this.resolveEffectiveStrictMode(requestOptions);
|
|
3619
|
-
const stream = adapter.isStream(
|
|
4741
|
+
const stream = adapter.isStream(providerReq);
|
|
3620
4742
|
let capabilityConfig = this.getCachedCapabilityConfig(requestOptions);
|
|
3621
|
-
const userText = adapter.extractInput(
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
let
|
|
4743
|
+
const userText = adapter.extractInput(providerReq);
|
|
4744
|
+
const requestAttachments = adapter.extractAttachments(providerReq);
|
|
4745
|
+
const hasGuardContent = userText !== null || requestAttachments.length > 0;
|
|
4746
|
+
let maskedText = userText ?? "";
|
|
4747
|
+
let maskedReq = providerReq;
|
|
4748
|
+
let createArgs = providerReq === rawReq ? normalizedCreateArgs : [{ ...providerReq }, ...normalizedCreateArgs.slice(1)];
|
|
3625
4749
|
let mapping = {};
|
|
3626
|
-
let shouldDeanonymize = false;
|
|
3627
4750
|
let sdkConfigFetchMs = 0;
|
|
3628
4751
|
let sdkLocalScanMs = 0;
|
|
3629
|
-
if (
|
|
4752
|
+
if (hasGuardContent) {
|
|
3630
4753
|
const prepared = await this.prepareInputForDispatch({
|
|
3631
|
-
input: userText,
|
|
4754
|
+
input: userText ?? "",
|
|
3632
4755
|
systemId,
|
|
3633
4756
|
stream,
|
|
3634
|
-
clientEventId
|
|
4757
|
+
clientEventId,
|
|
4758
|
+
telemetryMetadata
|
|
3635
4759
|
}, requestOptions);
|
|
3636
4760
|
capabilityConfig = prepared.capabilityConfig;
|
|
3637
4761
|
maskedText = prepared.sanitizedInput;
|
|
3638
4762
|
mapping = prepared.piiMapping ?? {};
|
|
3639
|
-
shouldDeanonymize = prepared.shouldDeanonymize === true;
|
|
3640
4763
|
sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
|
|
3641
4764
|
sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
|
|
3642
|
-
if (maskedText !== userText) {
|
|
4765
|
+
if (maskedText !== (userText ?? "")) {
|
|
3643
4766
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
3644
|
-
|
|
4767
|
+
providerReq,
|
|
3645
4768
|
maskedText
|
|
3646
4769
|
);
|
|
3647
|
-
const nextCreateArgs = [...
|
|
4770
|
+
const nextCreateArgs = [...createArgs];
|
|
3648
4771
|
nextCreateArgs[0] = maskedReq;
|
|
3649
4772
|
createArgs = nextCreateArgs;
|
|
3650
4773
|
}
|
|
3651
4774
|
}
|
|
3652
|
-
if (!
|
|
4775
|
+
if (!hasGuardContent) {
|
|
3653
4776
|
throw new Error(
|
|
3654
|
-
"AgentID: No user message found. Security guard requires
|
|
4777
|
+
"AgentID: No user message or supported inline attachment found. Security guard requires prompt content."
|
|
3655
4778
|
);
|
|
3656
4779
|
}
|
|
3657
4780
|
const verdict = await this.guard({
|
|
@@ -3662,6 +4785,8 @@ var AgentID = class {
|
|
|
3662
4785
|
client_event_id: clientEventId,
|
|
3663
4786
|
expected_languages: expectedLanguages,
|
|
3664
4787
|
request_identity: options.request_identity,
|
|
4788
|
+
metadata: telemetryMetadata,
|
|
4789
|
+
attachments: requestAttachments,
|
|
3665
4790
|
client_capabilities: this.buildClientCapabilities(
|
|
3666
4791
|
"openai",
|
|
3667
4792
|
false,
|
|
@@ -3683,22 +4808,43 @@ var AgentID = class {
|
|
|
3683
4808
|
apiKey: effectiveApiKey,
|
|
3684
4809
|
clientEventId,
|
|
3685
4810
|
sdkConfigFetchMs,
|
|
4811
|
+
telemetryMetadata,
|
|
3686
4812
|
runPromptInjectionCheck: true
|
|
3687
4813
|
});
|
|
3688
4814
|
maskedText = fallback.sanitizedInput;
|
|
3689
4815
|
sdkLocalScanMs = fallback.sdkLocalScanMs;
|
|
3690
4816
|
}
|
|
3691
4817
|
} else {
|
|
4818
|
+
await this.logPromptPreflightStep(
|
|
4819
|
+
{
|
|
4820
|
+
system_id: systemId,
|
|
4821
|
+
user_id: options.user_id,
|
|
4822
|
+
request_identity: options.request_identity,
|
|
4823
|
+
input: maskedText,
|
|
4824
|
+
telemetry: telemetryMetadata,
|
|
4825
|
+
verdict,
|
|
4826
|
+
guard_event_id: verdict.guard_event_id ?? null,
|
|
4827
|
+
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),
|
|
4828
|
+
preflight_for_client_event_id: typeof verdict.client_event_id === "string" && isUuidLike2(verdict.client_event_id) ? verdict.client_event_id : clientEventId,
|
|
4829
|
+
client_capabilities: this.buildClientCapabilities(
|
|
4830
|
+
"openai",
|
|
4831
|
+
false,
|
|
4832
|
+
capabilityConfig
|
|
4833
|
+
),
|
|
4834
|
+
runtime_surface: "openai_sdk_guard"
|
|
4835
|
+
},
|
|
4836
|
+
requestOptions
|
|
4837
|
+
);
|
|
3692
4838
|
throw new SecurityBlockError(verdict.reason ?? "guard_denied");
|
|
3693
4839
|
}
|
|
3694
4840
|
}
|
|
3695
|
-
const currentRequestInput = adapter.extractInput(maskedReq);
|
|
4841
|
+
const currentRequestInput = adapter.extractInput(maskedReq) ?? "";
|
|
3696
4842
|
if (maskedText !== currentRequestInput) {
|
|
3697
4843
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
3698
|
-
|
|
4844
|
+
providerReq,
|
|
3699
4845
|
maskedText
|
|
3700
4846
|
);
|
|
3701
|
-
const nextCreateArgs = [...
|
|
4847
|
+
const nextCreateArgs = [...createArgs];
|
|
3702
4848
|
nextCreateArgs[0] = maskedReq;
|
|
3703
4849
|
createArgs = nextCreateArgs;
|
|
3704
4850
|
}
|
|
@@ -3709,15 +4855,44 @@ var AgentID = class {
|
|
|
3709
4855
|
const isShadowMode = verdict.shadow_mode === true;
|
|
3710
4856
|
const transformedInput = isShadowMode ? maskedText : typeof verdict.transformed_input === "string" && verdict.transformed_input.length > 0 ? verdict.transformed_input : maskedText;
|
|
3711
4857
|
if (transformedInput !== maskedText) {
|
|
4858
|
+
const serverDerivedMapping = derivePlaceholderMappingFromTransform(
|
|
4859
|
+
maskedText,
|
|
4860
|
+
transformedInput
|
|
4861
|
+
);
|
|
4862
|
+
if (Object.keys(serverDerivedMapping).length > 0) {
|
|
4863
|
+
mapping = mergePiiMappings(mapping, serverDerivedMapping);
|
|
4864
|
+
}
|
|
3712
4865
|
maskedText = transformedInput;
|
|
3713
4866
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
3714
|
-
|
|
4867
|
+
providerReq,
|
|
3715
4868
|
transformedInput
|
|
3716
4869
|
);
|
|
3717
|
-
const nextCreateArgs = [...
|
|
4870
|
+
const nextCreateArgs = [...createArgs];
|
|
3718
4871
|
nextCreateArgs[0] = maskedReq;
|
|
3719
4872
|
createArgs = nextCreateArgs;
|
|
3720
4873
|
}
|
|
4874
|
+
await this.logPromptPreflightStep(
|
|
4875
|
+
{
|
|
4876
|
+
system_id: systemId,
|
|
4877
|
+
user_id: options.user_id,
|
|
4878
|
+
request_identity: options.request_identity,
|
|
4879
|
+
input: maskedText,
|
|
4880
|
+
telemetry: telemetryMetadata,
|
|
4881
|
+
verdict,
|
|
4882
|
+
guard_event_id: guardEventId,
|
|
4883
|
+
guard_latency_ms: guardLatencyMs,
|
|
4884
|
+
preflight_for_client_event_id: canonicalClientEventId,
|
|
4885
|
+
client_capabilities: this.buildClientCapabilities(
|
|
4886
|
+
"openai",
|
|
4887
|
+
false,
|
|
4888
|
+
capabilityConfig
|
|
4889
|
+
),
|
|
4890
|
+
local_fallback_applied: localFallbackApplied,
|
|
4891
|
+
local_fallback_reason: localFallbackReason,
|
|
4892
|
+
runtime_surface: "openai_sdk_guard"
|
|
4893
|
+
},
|
|
4894
|
+
requestOptions
|
|
4895
|
+
);
|
|
3721
4896
|
if (stream) {
|
|
3722
4897
|
const modelStartedAt2 = Date.now();
|
|
3723
4898
|
const streamResponse = await originalCreate.apply(compTarget, createArgs);
|
|
@@ -3729,7 +4904,8 @@ var AgentID = class {
|
|
|
3729
4904
|
})(),
|
|
3730
4905
|
{
|
|
3731
4906
|
piiMapping: mapping,
|
|
3732
|
-
deanonymizeForClient:
|
|
4907
|
+
deanonymizeForClient: false,
|
|
4908
|
+
maskForClient: !isShadowMode
|
|
3733
4909
|
}
|
|
3734
4910
|
);
|
|
3735
4911
|
if (maskedText && wrappedCompletion.mode === "stream") {
|
|
@@ -3748,29 +4924,32 @@ var AgentID = class {
|
|
|
3748
4924
|
usage: result.usage,
|
|
3749
4925
|
latency: modelLatencyMs2,
|
|
3750
4926
|
event_type: "complete",
|
|
3751
|
-
metadata:
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
4927
|
+
metadata: mergeTelemetryContexts(
|
|
4928
|
+
telemetryMetadata,
|
|
4929
|
+
{
|
|
4930
|
+
transformed_input: maskedText,
|
|
4931
|
+
transformed_output: result.transformedOutput,
|
|
4932
|
+
output_masked: result.outputMasked,
|
|
4933
|
+
shadow_mode: isShadowMode,
|
|
4934
|
+
simulated_decision: verdict.simulated_decision ?? null,
|
|
4935
|
+
simulated_output_decision: isShadowMode && result.outputMasked ? "masked" : "allowed",
|
|
4936
|
+
response_streamed: true,
|
|
4937
|
+
sdk_local_fallback_applied: localFallbackApplied,
|
|
4938
|
+
sdk_local_fallback_reason: localFallbackReason,
|
|
4939
|
+
guard_latency_ms: guardLatencyMs,
|
|
4940
|
+
model_latency_ms: modelLatencyMs2,
|
|
4941
|
+
total_pipeline_latency_ms: totalPipelineLatencyMs2,
|
|
4942
|
+
guard_event_id: guardEventId,
|
|
4943
|
+
client_event_id: canonicalClientEventId,
|
|
4944
|
+
transparency
|
|
4945
|
+
},
|
|
4946
|
+
buildSdkTimingMetadata({
|
|
3768
4947
|
sdkConfigFetchMs,
|
|
3769
4948
|
sdkLocalScanMs,
|
|
3770
4949
|
sdkGuardMs: guardLatencyMs,
|
|
3771
4950
|
sdkConfigVersion: capabilityConfig.version
|
|
3772
4951
|
})
|
|
3773
|
-
|
|
4952
|
+
),
|
|
3774
4953
|
client_capabilities: this.buildClientCapabilities(
|
|
3775
4954
|
"openai",
|
|
3776
4955
|
false,
|
|
@@ -3801,7 +4980,10 @@ var AgentID = class {
|
|
|
3801
4980
|
const totalPipelineLatencyMs = Math.max(0, Date.now() - pipelineStartedAt);
|
|
3802
4981
|
if (maskedText) {
|
|
3803
4982
|
const output = adapter.extractOutput(res);
|
|
3804
|
-
const wrappedCompletion = this.wrapCompletion(output
|
|
4983
|
+
const wrappedCompletion = this.wrapCompletion(output, {
|
|
4984
|
+
piiMapping: mapping,
|
|
4985
|
+
deanonymizeForClient: false
|
|
4986
|
+
});
|
|
3805
4987
|
const model = adapter.getModelName(maskedReq, res);
|
|
3806
4988
|
const usage = adapter.getTokenUsage(res);
|
|
3807
4989
|
const outputForLog = isShadowMode ? wrappedCompletion.rawOutput : wrappedCompletion.transformedOutput;
|
|
@@ -3816,29 +4998,32 @@ var AgentID = class {
|
|
|
3816
4998
|
usage,
|
|
3817
4999
|
latency: modelLatencyMs,
|
|
3818
5000
|
event_type: "complete",
|
|
3819
|
-
metadata:
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
5001
|
+
metadata: mergeTelemetryContexts(
|
|
5002
|
+
telemetryMetadata,
|
|
5003
|
+
{
|
|
5004
|
+
transformed_input: maskedText,
|
|
5005
|
+
transformed_output: wrappedCompletion.transformedOutput,
|
|
5006
|
+
output_masked: wrappedCompletion.outputMasked,
|
|
5007
|
+
shadow_mode: isShadowMode,
|
|
5008
|
+
simulated_decision: verdict.simulated_decision ?? null,
|
|
5009
|
+
simulated_output_decision: isShadowMode && wrappedCompletion.outputMasked ? "masked" : "allowed",
|
|
5010
|
+
response_streamed: false,
|
|
5011
|
+
sdk_local_fallback_applied: localFallbackApplied,
|
|
5012
|
+
sdk_local_fallback_reason: localFallbackReason,
|
|
5013
|
+
guard_latency_ms: guardLatencyMs,
|
|
5014
|
+
model_latency_ms: modelLatencyMs,
|
|
5015
|
+
total_pipeline_latency_ms: totalPipelineLatencyMs,
|
|
5016
|
+
guard_event_id: guardEventId,
|
|
5017
|
+
client_event_id: canonicalClientEventId,
|
|
5018
|
+
transparency
|
|
5019
|
+
},
|
|
5020
|
+
buildSdkTimingMetadata({
|
|
3836
5021
|
sdkConfigFetchMs,
|
|
3837
5022
|
sdkLocalScanMs,
|
|
3838
5023
|
sdkGuardMs: guardLatencyMs,
|
|
3839
5024
|
sdkConfigVersion: capabilityConfig.version
|
|
3840
5025
|
})
|
|
3841
|
-
|
|
5026
|
+
),
|
|
3842
5027
|
client_capabilities: this.buildClientCapabilities(
|
|
3843
5028
|
"openai",
|
|
3844
5029
|
false,
|
|
@@ -3855,17 +5040,21 @@ var AgentID = class {
|
|
|
3855
5040
|
);
|
|
3856
5041
|
}
|
|
3857
5042
|
}
|
|
3858
|
-
if (!
|
|
3859
|
-
const
|
|
5043
|
+
if (!isShadowMode && maskedText) {
|
|
5044
|
+
const output = adapter.extractOutput(res);
|
|
5045
|
+
const maskedOutput = this.wrapCompletion(output, {
|
|
5046
|
+
piiMapping: mapping,
|
|
5047
|
+
deanonymizeForClient: false
|
|
5048
|
+
}).transformedOutput;
|
|
3860
5049
|
try {
|
|
3861
5050
|
if (Array.isArray(res?.choices)) {
|
|
3862
5051
|
for (const choice of res.choices) {
|
|
3863
5052
|
const typedChoice = choice;
|
|
3864
5053
|
if (typedChoice?.message && typeof typedChoice.message.content === "string") {
|
|
3865
|
-
typedChoice.message.content =
|
|
5054
|
+
typedChoice.message.content = maskedOutput;
|
|
3866
5055
|
}
|
|
3867
5056
|
if (typedChoice?.delta && typeof typedChoice.delta.content === "string") {
|
|
3868
|
-
typedChoice.delta.content =
|
|
5057
|
+
typedChoice.delta.content = maskedOutput;
|
|
3869
5058
|
}
|
|
3870
5059
|
}
|
|
3871
5060
|
}
|
|
@@ -3890,6 +5079,155 @@ var AgentID = class {
|
|
|
3890
5079
|
});
|
|
3891
5080
|
}
|
|
3892
5081
|
};
|
|
5082
|
+
function mergeWorkflowTrailRequestOptions(base, override) {
|
|
5083
|
+
const apiKey = firstNonEmptyString(override?.apiKey, base?.apiKey);
|
|
5084
|
+
return apiKey ? { apiKey } : void 0;
|
|
5085
|
+
}
|
|
5086
|
+
function appendWorkflowErrorMetadata(metadata, error) {
|
|
5087
|
+
const nextMetadata = { ...metadata ?? {} };
|
|
5088
|
+
if (error instanceof Error) {
|
|
5089
|
+
if (typeof nextMetadata.error_name !== "string") {
|
|
5090
|
+
nextMetadata.error_name = error.name;
|
|
5091
|
+
}
|
|
5092
|
+
if (typeof nextMetadata.error_message !== "string" && error.message.trim().length > 0) {
|
|
5093
|
+
nextMetadata.error_message = error.message.trim();
|
|
5094
|
+
}
|
|
5095
|
+
return Object.keys(nextMetadata).length > 0 ? nextMetadata : void 0;
|
|
5096
|
+
}
|
|
5097
|
+
if (typeof nextMetadata.error_message !== "string" && typeof error !== "undefined") {
|
|
5098
|
+
const errorMessage = String(error).trim();
|
|
5099
|
+
if (errorMessage.length > 0) {
|
|
5100
|
+
nextMetadata.error_message = errorMessage;
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5103
|
+
return Object.keys(nextMetadata).length > 0 ? nextMetadata : void 0;
|
|
5104
|
+
}
|
|
5105
|
+
var AgentIDWorkflowStep = class {
|
|
5106
|
+
constructor(params) {
|
|
5107
|
+
this.trail = params.trail;
|
|
5108
|
+
this.workflowStepId = params.workflowStepId;
|
|
5109
|
+
this.startEventId = params.startEventId;
|
|
5110
|
+
this.telemetry = params.telemetry;
|
|
5111
|
+
this.startedAtMs = params.startedAtMs;
|
|
5112
|
+
}
|
|
5113
|
+
resolveStepTelemetry(telemetry) {
|
|
5114
|
+
return mergeTelemetryContexts(
|
|
5115
|
+
this.telemetry,
|
|
5116
|
+
createAgentIdTelemetryContext({
|
|
5117
|
+
workflow_step_id: this.workflowStepId,
|
|
5118
|
+
parent_event_id: this.startEventId
|
|
5119
|
+
}),
|
|
5120
|
+
telemetry
|
|
5121
|
+
);
|
|
5122
|
+
}
|
|
5123
|
+
async log(params = {}, options) {
|
|
5124
|
+
return this.trail.logStep(
|
|
5125
|
+
{
|
|
5126
|
+
...params,
|
|
5127
|
+
telemetry: this.resolveStepTelemetry(params.telemetry)
|
|
5128
|
+
},
|
|
5129
|
+
options
|
|
5130
|
+
);
|
|
5131
|
+
}
|
|
5132
|
+
async complete(params = {}, options) {
|
|
5133
|
+
return this.log(
|
|
5134
|
+
{
|
|
5135
|
+
...params,
|
|
5136
|
+
latency: typeof params.latency === "number" ? params.latency : Math.max(0, Date.now() - this.startedAtMs),
|
|
5137
|
+
event_status: params.event_status ?? "completed"
|
|
5138
|
+
},
|
|
5139
|
+
options
|
|
5140
|
+
);
|
|
5141
|
+
}
|
|
5142
|
+
async fail(error, params = {}, options) {
|
|
5143
|
+
return this.log(
|
|
5144
|
+
{
|
|
5145
|
+
...params,
|
|
5146
|
+
latency: typeof params.latency === "number" ? params.latency : Math.max(0, Date.now() - this.startedAtMs),
|
|
5147
|
+
metadata: appendWorkflowErrorMetadata(params.metadata, error),
|
|
5148
|
+
event_type: params.event_type ?? "error",
|
|
5149
|
+
event_status: params.event_status ?? "failed",
|
|
5150
|
+
severity: params.severity ?? "error"
|
|
5151
|
+
},
|
|
5152
|
+
options
|
|
5153
|
+
);
|
|
5154
|
+
}
|
|
5155
|
+
};
|
|
5156
|
+
var AgentIDWorkflowTrail = class {
|
|
5157
|
+
constructor(options) {
|
|
5158
|
+
this.agent = options.agent;
|
|
5159
|
+
this.systemId = options.system_id;
|
|
5160
|
+
this.userId = options.user_id;
|
|
5161
|
+
this.requestIdentity = options.request_identity;
|
|
5162
|
+
this.telemetry = createAgentIdTelemetryContext(options.telemetry);
|
|
5163
|
+
this.clientCapabilities = options.client_capabilities;
|
|
5164
|
+
this.requestOptions = options.requestOptions;
|
|
5165
|
+
}
|
|
5166
|
+
async logStep(params = {}, options) {
|
|
5167
|
+
const payload = this.agent.buildOperationLogParams({
|
|
5168
|
+
...params,
|
|
5169
|
+
system_id: this.systemId,
|
|
5170
|
+
user_id: this.userId,
|
|
5171
|
+
request_identity: this.requestIdentity,
|
|
5172
|
+
telemetry: mergeTelemetryContexts(this.telemetry, params.telemetry),
|
|
5173
|
+
client_capabilities: params.client_capabilities ?? this.clientCapabilities
|
|
5174
|
+
});
|
|
5175
|
+
await this.agent.log(
|
|
5176
|
+
payload,
|
|
5177
|
+
mergeWorkflowTrailRequestOptions(this.requestOptions, options)
|
|
5178
|
+
);
|
|
5179
|
+
return payload;
|
|
5180
|
+
}
|
|
5181
|
+
async startStep(params = {}, options) {
|
|
5182
|
+
const startedAtMs = Date.now();
|
|
5183
|
+
const requestedTelemetry = createAgentIdTelemetryContext(params.telemetry);
|
|
5184
|
+
const workflowStepId = firstNonEmptyString(requestedTelemetry?.workflow_step_id, requestedTelemetry?.workflowStepId) ?? createAgentIdCorrelationId();
|
|
5185
|
+
const startTelemetry = mergeTelemetryContexts(
|
|
5186
|
+
requestedTelemetry,
|
|
5187
|
+
createAgentIdTelemetryContext({
|
|
5188
|
+
workflow_step_id: workflowStepId
|
|
5189
|
+
})
|
|
5190
|
+
);
|
|
5191
|
+
const startPayload = await this.logStep(
|
|
5192
|
+
{
|
|
5193
|
+
...params,
|
|
5194
|
+
telemetry: startTelemetry,
|
|
5195
|
+
event_type: params.event_type ?? "start",
|
|
5196
|
+
event_status: params.event_status ?? "started"
|
|
5197
|
+
},
|
|
5198
|
+
options
|
|
5199
|
+
);
|
|
5200
|
+
return new AgentIDWorkflowStep({
|
|
5201
|
+
trail: this,
|
|
5202
|
+
workflowStepId,
|
|
5203
|
+
startEventId: startPayload.event_id ?? createEventId2(),
|
|
5204
|
+
telemetry: startTelemetry,
|
|
5205
|
+
startedAtMs
|
|
5206
|
+
});
|
|
5207
|
+
}
|
|
5208
|
+
async runStep(params, run, hooks, options) {
|
|
5209
|
+
const step = await this.startStep(params, options);
|
|
5210
|
+
try {
|
|
5211
|
+
const result = await run();
|
|
5212
|
+
const completeParams = {
|
|
5213
|
+
...hooks?.complete ?? {},
|
|
5214
|
+
...hooks?.onComplete?.(result) ?? {}
|
|
5215
|
+
};
|
|
5216
|
+
await step.complete(completeParams, options);
|
|
5217
|
+
return result;
|
|
5218
|
+
} catch (error) {
|
|
5219
|
+
const failParams = {
|
|
5220
|
+
...hooks?.fail ?? {},
|
|
5221
|
+
...hooks?.onError?.(error) ?? {}
|
|
5222
|
+
};
|
|
5223
|
+
await step.fail(error, failParams, options);
|
|
5224
|
+
throw error;
|
|
5225
|
+
}
|
|
5226
|
+
}
|
|
5227
|
+
};
|
|
5228
|
+
function createAgentIdWorkflowTrail(options) {
|
|
5229
|
+
return new AgentIDWorkflowTrail(options);
|
|
5230
|
+
}
|
|
3893
5231
|
|
|
3894
5232
|
export {
|
|
3895
5233
|
OpenAIAdapter,
|
|
@@ -3897,7 +5235,13 @@ export {
|
|
|
3897
5235
|
scanWithRegex,
|
|
3898
5236
|
InjectionScanner,
|
|
3899
5237
|
getInjectionScanner,
|
|
5238
|
+
createAgentIdCorrelationId,
|
|
5239
|
+
createAgentIdTelemetryContext,
|
|
5240
|
+
createAgentIdOperationLog,
|
|
3900
5241
|
SecurityBlockError,
|
|
3901
5242
|
DependencyError,
|
|
3902
|
-
AgentID
|
|
5243
|
+
AgentID,
|
|
5244
|
+
AgentIDWorkflowStep,
|
|
5245
|
+
AgentIDWorkflowTrail,
|
|
5246
|
+
createAgentIdWorkflowTrail
|
|
3903
5247
|
};
|