agentid-sdk 0.1.37 → 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 +203 -48
- package/dist/agentid-CxVUF_eo.d.mts +399 -0
- package/dist/agentid-CxVUF_eo.d.ts +399 -0
- package/dist/{chunk-HWES3LI2.mjs → chunk-AIGMQSAV.mjs} +1495 -154
- package/dist/index.d.mts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +1500 -153
- 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,6 +3579,9 @@ 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) {
|
|
2607
3586
|
if (config?.enable_sdk_pii_masking === true) {
|
|
2608
3587
|
return true;
|
|
@@ -2612,12 +3591,24 @@ var AgentID = class {
|
|
|
2612
3591
|
}
|
|
2613
3592
|
return false;
|
|
2614
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;
|
|
3602
|
+
}
|
|
2615
3603
|
getEffectivePiiMasking(options) {
|
|
2616
3604
|
return this.resolveEffectivePiiMasking(this.getCachedCapabilityConfig(options));
|
|
2617
3605
|
}
|
|
2618
3606
|
getEffectivePiiMaskingForConfig(capabilityConfig) {
|
|
2619
3607
|
return this.resolveEffectivePiiMasking(capabilityConfig);
|
|
2620
3608
|
}
|
|
3609
|
+
getEffectiveSecretMaskingForConfig(capabilityConfig) {
|
|
3610
|
+
return this.resolveEffectiveSecretMasking(capabilityConfig);
|
|
3611
|
+
}
|
|
2621
3612
|
buildClientCapabilities(framework = "js_sdk", hasFeedbackHandler = false, capabilityConfig) {
|
|
2622
3613
|
return {
|
|
2623
3614
|
capabilities: {
|
|
@@ -2625,6 +3616,9 @@ var AgentID = class {
|
|
|
2625
3616
|
pii_masking_enabled: this.resolveEffectivePiiMasking(
|
|
2626
3617
|
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
2627
3618
|
),
|
|
3619
|
+
secret_masking_enabled: this.resolveEffectiveSecretMasking(
|
|
3620
|
+
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
3621
|
+
),
|
|
2628
3622
|
framework
|
|
2629
3623
|
}
|
|
2630
3624
|
};
|
|
@@ -2764,10 +3758,13 @@ var AgentID = class {
|
|
|
2764
3758
|
systemId: params.systemId,
|
|
2765
3759
|
eventId: params.clientEventId,
|
|
2766
3760
|
clientEventId: params.clientEventId,
|
|
2767
|
-
telemetryMetadata:
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
3761
|
+
telemetryMetadata: mergeTelemetryContexts(
|
|
3762
|
+
params.telemetryMetadata,
|
|
3763
|
+
buildSdkTimingMetadata({
|
|
3764
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
3765
|
+
sdkConfigVersion: params.capabilityConfig.version
|
|
3766
|
+
})
|
|
3767
|
+
)
|
|
2771
3768
|
});
|
|
2772
3769
|
}
|
|
2773
3770
|
try {
|
|
@@ -2784,7 +3781,8 @@ var AgentID = class {
|
|
|
2784
3781
|
actionTaken: event.actionTaken,
|
|
2785
3782
|
apiKey: params.apiKey,
|
|
2786
3783
|
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
2787
|
-
sdkLocalScanMs
|
|
3784
|
+
sdkLocalScanMs,
|
|
3785
|
+
telemetryMetadata: params.telemetryMetadata
|
|
2788
3786
|
});
|
|
2789
3787
|
}
|
|
2790
3788
|
return {
|
|
@@ -2799,7 +3797,8 @@ var AgentID = class {
|
|
|
2799
3797
|
actionTaken: error.actionTaken,
|
|
2800
3798
|
apiKey: params.apiKey,
|
|
2801
3799
|
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
2802
|
-
sdkLocalScanMs: Math.max(0, Date.now() - localScanStartedAt)
|
|
3800
|
+
sdkLocalScanMs: Math.max(0, Date.now() - localScanStartedAt),
|
|
3801
|
+
telemetryMetadata: params.telemetryMetadata
|
|
2803
3802
|
});
|
|
2804
3803
|
}
|
|
2805
3804
|
throw error;
|
|
@@ -2813,7 +3812,7 @@ var AgentID = class {
|
|
|
2813
3812
|
);
|
|
2814
3813
|
let sanitizedInput = params.input;
|
|
2815
3814
|
let sdkLocalScanMs = 0;
|
|
2816
|
-
if (this.configuredPiiMasking === null) {
|
|
3815
|
+
if (this.configuredPiiMasking === null || this.configuredSecretMasking === null) {
|
|
2817
3816
|
const refreshed = await this.refreshCapabilityConfigBeforeClientControl({
|
|
2818
3817
|
capabilityConfig,
|
|
2819
3818
|
sdkConfigFetchMs,
|
|
@@ -2824,8 +3823,12 @@ var AgentID = class {
|
|
|
2824
3823
|
}
|
|
2825
3824
|
if (!this.clientFastFail) {
|
|
2826
3825
|
const effectivePiiMasking2 = this.resolveEffectivePiiMasking(capabilityConfig);
|
|
2827
|
-
|
|
2828
|
-
|
|
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
|
+
});
|
|
2829
3832
|
return {
|
|
2830
3833
|
sanitizedInput: masked.maskedText,
|
|
2831
3834
|
capabilityConfig,
|
|
@@ -2857,13 +3860,18 @@ var AgentID = class {
|
|
|
2857
3860
|
apiKey: effectiveApiKey,
|
|
2858
3861
|
clientEventId: params.clientEventId,
|
|
2859
3862
|
sdkConfigFetchMs,
|
|
3863
|
+
telemetryMetadata: params.telemetryMetadata,
|
|
2860
3864
|
runPromptInjectionCheck: !params.skipInjectionScan
|
|
2861
3865
|
});
|
|
2862
3866
|
sanitizedInput = enforced.sanitizedInput;
|
|
2863
3867
|
sdkLocalScanMs = enforced.sdkLocalScanMs;
|
|
2864
3868
|
const effectivePiiMasking = this.resolveEffectivePiiMasking(capabilityConfig);
|
|
2865
|
-
|
|
2866
|
-
|
|
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
|
+
});
|
|
2867
3875
|
return {
|
|
2868
3876
|
sanitizedInput: masked.maskedText,
|
|
2869
3877
|
capabilityConfig,
|
|
@@ -2899,6 +3907,7 @@ var AgentID = class {
|
|
|
2899
3907
|
apiKey: effectiveApiKey,
|
|
2900
3908
|
clientEventId: params.clientEventId,
|
|
2901
3909
|
sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs,
|
|
3910
|
+
telemetryMetadata: params.telemetryMetadata,
|
|
2902
3911
|
runPromptInjectionCheck: true
|
|
2903
3912
|
});
|
|
2904
3913
|
return {
|
|
@@ -2962,9 +3971,30 @@ var AgentID = class {
|
|
|
2962
3971
|
if (!message || typeof message !== "object") {
|
|
2963
3972
|
return req;
|
|
2964
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
|
+
}
|
|
2965
3995
|
newMessages[lastUserIdx] = {
|
|
2966
3996
|
...message,
|
|
2967
|
-
content:
|
|
3997
|
+
content: nextContent
|
|
2968
3998
|
};
|
|
2969
3999
|
if (!req || typeof req !== "object") {
|
|
2970
4000
|
return req;
|
|
@@ -2983,6 +4013,7 @@ var AgentID = class {
|
|
|
2983
4013
|
event_type: "security_policy_violation",
|
|
2984
4014
|
severity: "high",
|
|
2985
4015
|
metadata: {
|
|
4016
|
+
...params.telemetryMetadata ?? {},
|
|
2986
4017
|
event_type: "security_policy_violation",
|
|
2987
4018
|
severity: "high",
|
|
2988
4019
|
system_id: params.systemId,
|
|
@@ -3010,6 +4041,7 @@ var AgentID = class {
|
|
|
3010
4041
|
event_type: "security_alert",
|
|
3011
4042
|
severity: "warning",
|
|
3012
4043
|
metadata: {
|
|
4044
|
+
...params.guardParams.metadata ?? {},
|
|
3013
4045
|
source: "guard",
|
|
3014
4046
|
status: params.status,
|
|
3015
4047
|
guard_reason: params.reason,
|
|
@@ -3452,21 +4484,29 @@ var AgentID = class {
|
|
|
3452
4484
|
wrapCompletion(completion, options) {
|
|
3453
4485
|
if (typeof completion === "string") {
|
|
3454
4486
|
const masked = this.pii.anonymize(completion);
|
|
4487
|
+
const placeholderOutputMasked = textContainsMappingPlaceholder(
|
|
4488
|
+
completion,
|
|
4489
|
+
options?.piiMapping
|
|
4490
|
+
);
|
|
3455
4491
|
return {
|
|
3456
4492
|
mode: "static",
|
|
3457
4493
|
rawOutput: completion,
|
|
3458
4494
|
transformedOutput: masked.maskedText,
|
|
3459
|
-
outputMasked: masked.maskedText !== completion
|
|
4495
|
+
outputMasked: masked.maskedText !== completion || placeholderOutputMasked
|
|
3460
4496
|
};
|
|
3461
4497
|
}
|
|
3462
4498
|
if (!isAsyncIterable(completion)) {
|
|
3463
4499
|
const asText = String(completion ?? "");
|
|
3464
4500
|
const masked = this.pii.anonymize(asText);
|
|
4501
|
+
const placeholderOutputMasked = textContainsMappingPlaceholder(
|
|
4502
|
+
asText,
|
|
4503
|
+
options?.piiMapping
|
|
4504
|
+
);
|
|
3465
4505
|
return {
|
|
3466
4506
|
mode: "static",
|
|
3467
4507
|
rawOutput: asText,
|
|
3468
4508
|
transformedOutput: masked.maskedText,
|
|
3469
|
-
outputMasked: masked.maskedText !== asText
|
|
4509
|
+
outputMasked: masked.maskedText !== asText || placeholderOutputMasked
|
|
3470
4510
|
};
|
|
3471
4511
|
}
|
|
3472
4512
|
const source = completion;
|
|
@@ -3476,8 +4516,10 @@ var AgentID = class {
|
|
|
3476
4516
|
const isOpenAIStreamFinishChunk = this.isOpenAIStreamFinishChunk.bind(this);
|
|
3477
4517
|
const rewriteOpenAIStreamChunkForClient = this.rewriteOpenAIStreamChunkForClient.bind(this);
|
|
3478
4518
|
const createSyntheticOpenAIStreamChunk = this.createSyntheticOpenAIStreamChunk.bind(this);
|
|
4519
|
+
const setOpenAIStreamChunkText = this.setOpenAIStreamChunkText.bind(this);
|
|
3479
4520
|
const piiManager = this.pii;
|
|
3480
4521
|
const streamRewriter = options?.deanonymizeForClient === true && options.piiMapping ? createStreamingPlaceholderRewriter(piiManager, options.piiMapping) : null;
|
|
4522
|
+
const maskForClient = options?.maskForClient === true && streamRewriter === null;
|
|
3481
4523
|
let lastUsage;
|
|
3482
4524
|
let resolveDone = null;
|
|
3483
4525
|
let rejectDone = null;
|
|
@@ -3490,12 +4532,17 @@ var AgentID = class {
|
|
|
3490
4532
|
try {
|
|
3491
4533
|
let finishChunkFlushed = false;
|
|
3492
4534
|
let lastChunkTemplate;
|
|
4535
|
+
let clientRawText = "";
|
|
4536
|
+
let clientMaskFlushed = false;
|
|
3493
4537
|
for await (const chunk of source) {
|
|
3494
4538
|
const chunkText = extractStreamChunkText(chunk);
|
|
3495
|
-
const isFinishChunk = streamRewriter ? isOpenAIStreamFinishChunk(chunk) : false;
|
|
4539
|
+
const isFinishChunk = streamRewriter || maskForClient ? isOpenAIStreamFinishChunk(chunk) : false;
|
|
3496
4540
|
if (chunkText) {
|
|
3497
4541
|
await collector.push(chunkText);
|
|
3498
4542
|
lastChunkTemplate = chunk;
|
|
4543
|
+
if (maskForClient) {
|
|
4544
|
+
clientRawText += chunkText;
|
|
4545
|
+
}
|
|
3499
4546
|
}
|
|
3500
4547
|
const chunkUsage = extractStreamChunkUsage(chunk);
|
|
3501
4548
|
if (chunkUsage) {
|
|
@@ -3515,6 +4562,28 @@ var AgentID = class {
|
|
|
3515
4562
|
}
|
|
3516
4563
|
continue;
|
|
3517
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
|
+
}
|
|
3518
4587
|
yield chunk;
|
|
3519
4588
|
}
|
|
3520
4589
|
if (streamRewriter && !finishChunkFlushed) {
|
|
@@ -3526,14 +4595,27 @@ var AgentID = class {
|
|
|
3526
4595
|
);
|
|
3527
4596
|
}
|
|
3528
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
|
+
}
|
|
3529
4607
|
await collector.close();
|
|
3530
4608
|
const rawOutput = await collector.result;
|
|
3531
4609
|
const masked = piiManager.anonymize(rawOutput);
|
|
4610
|
+
const placeholderOutputMasked = textContainsMappingPlaceholder(
|
|
4611
|
+
rawOutput,
|
|
4612
|
+
options?.piiMapping
|
|
4613
|
+
);
|
|
3532
4614
|
resolveDone?.({
|
|
3533
4615
|
mode: "static",
|
|
3534
4616
|
rawOutput,
|
|
3535
4617
|
transformedOutput: masked.maskedText,
|
|
3536
|
-
outputMasked: masked.maskedText !== rawOutput,
|
|
4618
|
+
outputMasked: masked.maskedText !== rawOutput || placeholderOutputMasked,
|
|
3537
4619
|
usage: lastUsage
|
|
3538
4620
|
});
|
|
3539
4621
|
} catch (error) {
|
|
@@ -3568,6 +4650,37 @@ var AgentID = class {
|
|
|
3568
4650
|
);
|
|
3569
4651
|
}
|
|
3570
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
|
+
}
|
|
3571
4684
|
/**
|
|
3572
4685
|
* Analytics alias for telemetry logging.
|
|
3573
4686
|
*/
|
|
@@ -3612,49 +4725,56 @@ var AgentID = class {
|
|
|
3612
4725
|
if (typeof originalCreate !== "function") return originalCreate;
|
|
3613
4726
|
return async (...args) => {
|
|
3614
4727
|
const normalizedCreateArgs = normalizeOpenAICreateArgs(args);
|
|
3615
|
-
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);
|
|
3616
4735
|
const pipelineStartedAt = Date.now();
|
|
3617
|
-
const requestLevelApiKey = options.resolveApiKey?.(
|
|
4736
|
+
const requestLevelApiKey = options.resolveApiKey?.(rawReq) ?? options.apiKey ?? options.api_key;
|
|
3618
4737
|
const effectiveApiKey = this.resolveApiKey(requestLevelApiKey);
|
|
3619
4738
|
const requestOptions = { apiKey: effectiveApiKey };
|
|
3620
|
-
const clientEventId = this.resolveClientEventId(
|
|
4739
|
+
const clientEventId = this.resolveClientEventId(rawReq);
|
|
3621
4740
|
const effectiveStrictMode = await this.resolveEffectiveStrictMode(requestOptions);
|
|
3622
|
-
const stream = adapter.isStream(
|
|
4741
|
+
const stream = adapter.isStream(providerReq);
|
|
3623
4742
|
let capabilityConfig = this.getCachedCapabilityConfig(requestOptions);
|
|
3624
|
-
const userText = adapter.extractInput(
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
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)];
|
|
3628
4749
|
let mapping = {};
|
|
3629
|
-
let shouldDeanonymize = false;
|
|
3630
4750
|
let sdkConfigFetchMs = 0;
|
|
3631
4751
|
let sdkLocalScanMs = 0;
|
|
3632
|
-
if (
|
|
4752
|
+
if (hasGuardContent) {
|
|
3633
4753
|
const prepared = await this.prepareInputForDispatch({
|
|
3634
|
-
input: userText,
|
|
4754
|
+
input: userText ?? "",
|
|
3635
4755
|
systemId,
|
|
3636
4756
|
stream,
|
|
3637
|
-
clientEventId
|
|
4757
|
+
clientEventId,
|
|
4758
|
+
telemetryMetadata
|
|
3638
4759
|
}, requestOptions);
|
|
3639
4760
|
capabilityConfig = prepared.capabilityConfig;
|
|
3640
4761
|
maskedText = prepared.sanitizedInput;
|
|
3641
4762
|
mapping = prepared.piiMapping ?? {};
|
|
3642
|
-
shouldDeanonymize = prepared.shouldDeanonymize === true;
|
|
3643
4763
|
sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
|
|
3644
4764
|
sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
|
|
3645
|
-
if (maskedText !== userText) {
|
|
4765
|
+
if (maskedText !== (userText ?? "")) {
|
|
3646
4766
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
3647
|
-
|
|
4767
|
+
providerReq,
|
|
3648
4768
|
maskedText
|
|
3649
4769
|
);
|
|
3650
|
-
const nextCreateArgs = [...
|
|
4770
|
+
const nextCreateArgs = [...createArgs];
|
|
3651
4771
|
nextCreateArgs[0] = maskedReq;
|
|
3652
4772
|
createArgs = nextCreateArgs;
|
|
3653
4773
|
}
|
|
3654
4774
|
}
|
|
3655
|
-
if (!
|
|
4775
|
+
if (!hasGuardContent) {
|
|
3656
4776
|
throw new Error(
|
|
3657
|
-
"AgentID: No user message found. Security guard requires
|
|
4777
|
+
"AgentID: No user message or supported inline attachment found. Security guard requires prompt content."
|
|
3658
4778
|
);
|
|
3659
4779
|
}
|
|
3660
4780
|
const verdict = await this.guard({
|
|
@@ -3665,6 +4785,8 @@ var AgentID = class {
|
|
|
3665
4785
|
client_event_id: clientEventId,
|
|
3666
4786
|
expected_languages: expectedLanguages,
|
|
3667
4787
|
request_identity: options.request_identity,
|
|
4788
|
+
metadata: telemetryMetadata,
|
|
4789
|
+
attachments: requestAttachments,
|
|
3668
4790
|
client_capabilities: this.buildClientCapabilities(
|
|
3669
4791
|
"openai",
|
|
3670
4792
|
false,
|
|
@@ -3686,22 +4808,43 @@ var AgentID = class {
|
|
|
3686
4808
|
apiKey: effectiveApiKey,
|
|
3687
4809
|
clientEventId,
|
|
3688
4810
|
sdkConfigFetchMs,
|
|
4811
|
+
telemetryMetadata,
|
|
3689
4812
|
runPromptInjectionCheck: true
|
|
3690
4813
|
});
|
|
3691
4814
|
maskedText = fallback.sanitizedInput;
|
|
3692
4815
|
sdkLocalScanMs = fallback.sdkLocalScanMs;
|
|
3693
4816
|
}
|
|
3694
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
|
+
);
|
|
3695
4838
|
throw new SecurityBlockError(verdict.reason ?? "guard_denied");
|
|
3696
4839
|
}
|
|
3697
4840
|
}
|
|
3698
|
-
const currentRequestInput = adapter.extractInput(maskedReq);
|
|
4841
|
+
const currentRequestInput = adapter.extractInput(maskedReq) ?? "";
|
|
3699
4842
|
if (maskedText !== currentRequestInput) {
|
|
3700
4843
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
3701
|
-
|
|
4844
|
+
providerReq,
|
|
3702
4845
|
maskedText
|
|
3703
4846
|
);
|
|
3704
|
-
const nextCreateArgs = [...
|
|
4847
|
+
const nextCreateArgs = [...createArgs];
|
|
3705
4848
|
nextCreateArgs[0] = maskedReq;
|
|
3706
4849
|
createArgs = nextCreateArgs;
|
|
3707
4850
|
}
|
|
@@ -3712,15 +4855,44 @@ var AgentID = class {
|
|
|
3712
4855
|
const isShadowMode = verdict.shadow_mode === true;
|
|
3713
4856
|
const transformedInput = isShadowMode ? maskedText : typeof verdict.transformed_input === "string" && verdict.transformed_input.length > 0 ? verdict.transformed_input : maskedText;
|
|
3714
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
|
+
}
|
|
3715
4865
|
maskedText = transformedInput;
|
|
3716
4866
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
3717
|
-
|
|
4867
|
+
providerReq,
|
|
3718
4868
|
transformedInput
|
|
3719
4869
|
);
|
|
3720
|
-
const nextCreateArgs = [...
|
|
4870
|
+
const nextCreateArgs = [...createArgs];
|
|
3721
4871
|
nextCreateArgs[0] = maskedReq;
|
|
3722
4872
|
createArgs = nextCreateArgs;
|
|
3723
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
|
+
);
|
|
3724
4896
|
if (stream) {
|
|
3725
4897
|
const modelStartedAt2 = Date.now();
|
|
3726
4898
|
const streamResponse = await originalCreate.apply(compTarget, createArgs);
|
|
@@ -3732,7 +4904,8 @@ var AgentID = class {
|
|
|
3732
4904
|
})(),
|
|
3733
4905
|
{
|
|
3734
4906
|
piiMapping: mapping,
|
|
3735
|
-
deanonymizeForClient:
|
|
4907
|
+
deanonymizeForClient: false,
|
|
4908
|
+
maskForClient: !isShadowMode
|
|
3736
4909
|
}
|
|
3737
4910
|
);
|
|
3738
4911
|
if (maskedText && wrappedCompletion.mode === "stream") {
|
|
@@ -3751,29 +4924,32 @@ var AgentID = class {
|
|
|
3751
4924
|
usage: result.usage,
|
|
3752
4925
|
latency: modelLatencyMs2,
|
|
3753
4926
|
event_type: "complete",
|
|
3754
|
-
metadata:
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
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({
|
|
3771
4947
|
sdkConfigFetchMs,
|
|
3772
4948
|
sdkLocalScanMs,
|
|
3773
4949
|
sdkGuardMs: guardLatencyMs,
|
|
3774
4950
|
sdkConfigVersion: capabilityConfig.version
|
|
3775
4951
|
})
|
|
3776
|
-
|
|
4952
|
+
),
|
|
3777
4953
|
client_capabilities: this.buildClientCapabilities(
|
|
3778
4954
|
"openai",
|
|
3779
4955
|
false,
|
|
@@ -3804,7 +4980,10 @@ var AgentID = class {
|
|
|
3804
4980
|
const totalPipelineLatencyMs = Math.max(0, Date.now() - pipelineStartedAt);
|
|
3805
4981
|
if (maskedText) {
|
|
3806
4982
|
const output = adapter.extractOutput(res);
|
|
3807
|
-
const wrappedCompletion = this.wrapCompletion(output
|
|
4983
|
+
const wrappedCompletion = this.wrapCompletion(output, {
|
|
4984
|
+
piiMapping: mapping,
|
|
4985
|
+
deanonymizeForClient: false
|
|
4986
|
+
});
|
|
3808
4987
|
const model = adapter.getModelName(maskedReq, res);
|
|
3809
4988
|
const usage = adapter.getTokenUsage(res);
|
|
3810
4989
|
const outputForLog = isShadowMode ? wrappedCompletion.rawOutput : wrappedCompletion.transformedOutput;
|
|
@@ -3819,29 +4998,32 @@ var AgentID = class {
|
|
|
3819
4998
|
usage,
|
|
3820
4999
|
latency: modelLatencyMs,
|
|
3821
5000
|
event_type: "complete",
|
|
3822
|
-
metadata:
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
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({
|
|
3839
5021
|
sdkConfigFetchMs,
|
|
3840
5022
|
sdkLocalScanMs,
|
|
3841
5023
|
sdkGuardMs: guardLatencyMs,
|
|
3842
5024
|
sdkConfigVersion: capabilityConfig.version
|
|
3843
5025
|
})
|
|
3844
|
-
|
|
5026
|
+
),
|
|
3845
5027
|
client_capabilities: this.buildClientCapabilities(
|
|
3846
5028
|
"openai",
|
|
3847
5029
|
false,
|
|
@@ -3858,17 +5040,21 @@ var AgentID = class {
|
|
|
3858
5040
|
);
|
|
3859
5041
|
}
|
|
3860
5042
|
}
|
|
3861
|
-
if (!
|
|
3862
|
-
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;
|
|
3863
5049
|
try {
|
|
3864
5050
|
if (Array.isArray(res?.choices)) {
|
|
3865
5051
|
for (const choice of res.choices) {
|
|
3866
5052
|
const typedChoice = choice;
|
|
3867
5053
|
if (typedChoice?.message && typeof typedChoice.message.content === "string") {
|
|
3868
|
-
typedChoice.message.content =
|
|
5054
|
+
typedChoice.message.content = maskedOutput;
|
|
3869
5055
|
}
|
|
3870
5056
|
if (typedChoice?.delta && typeof typedChoice.delta.content === "string") {
|
|
3871
|
-
typedChoice.delta.content =
|
|
5057
|
+
typedChoice.delta.content = maskedOutput;
|
|
3872
5058
|
}
|
|
3873
5059
|
}
|
|
3874
5060
|
}
|
|
@@ -3893,6 +5079,155 @@ var AgentID = class {
|
|
|
3893
5079
|
});
|
|
3894
5080
|
}
|
|
3895
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
|
+
}
|
|
3896
5231
|
|
|
3897
5232
|
export {
|
|
3898
5233
|
OpenAIAdapter,
|
|
@@ -3900,7 +5235,13 @@ export {
|
|
|
3900
5235
|
scanWithRegex,
|
|
3901
5236
|
InjectionScanner,
|
|
3902
5237
|
getInjectionScanner,
|
|
5238
|
+
createAgentIdCorrelationId,
|
|
5239
|
+
createAgentIdTelemetryContext,
|
|
5240
|
+
createAgentIdOperationLog,
|
|
3903
5241
|
SecurityBlockError,
|
|
3904
5242
|
DependencyError,
|
|
3905
|
-
AgentID
|
|
5243
|
+
AgentID,
|
|
5244
|
+
AgentIDWorkflowStep,
|
|
5245
|
+
AgentIDWorkflowTrail,
|
|
5246
|
+
createAgentIdWorkflowTrail
|
|
3906
5247
|
};
|