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/dist/langchain.js CHANGED
@@ -27,7 +27,7 @@ var import_base = require("@langchain/core/callbacks/base");
27
27
 
28
28
  // src/sdk-version.ts
29
29
  var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
30
- var AGENTID_SDK_VERSION_HEADER = "js-0.1.37".trim().length > 0 ? "js-0.1.37" : FALLBACK_SDK_VERSION;
30
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.38".trim().length > 0 ? "js-0.1.38" : FALLBACK_SDK_VERSION;
31
31
 
32
32
  // src/pii-national-identifiers.ts
33
33
  var MAX_CANDIDATES_PER_RULE = 256;
@@ -891,8 +891,173 @@ function detectNationalIdentifiers(text, options = {}) {
891
891
  return results;
892
892
  }
893
893
 
894
+ // src/secret-patterns.ts
895
+ var SDK_SECRET_PATTERN_DEFINITIONS = [
896
+ {
897
+ id: "openai_api_key",
898
+ placeholderType: "OPENAI_API_KEY",
899
+ patternSource: "\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b",
900
+ flags: "iu",
901
+ prefilterTerms: ["sk-", "proj-", "openai"]
902
+ },
903
+ {
904
+ id: "aws_access_key",
905
+ placeholderType: "AWS_ACCESS_KEY",
906
+ patternSource: "\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b",
907
+ flags: "iu",
908
+ prefilterTerms: ["akia", "asia", "aws"]
909
+ },
910
+ {
911
+ id: "github_token",
912
+ placeholderType: "GITHUB_TOKEN",
913
+ patternSource: "\\b(?:gh[pousr]_[A-Za-z0-9]{24,255}|github_pat_[A-Za-z0-9_]{20,255})\\b",
914
+ flags: "iu",
915
+ prefilterTerms: ["ghp_", "gho_", "ghu_", "ghs_", "ghr_", "github_pat_"]
916
+ },
917
+ {
918
+ id: "slack_token",
919
+ placeholderType: "SLACK_TOKEN",
920
+ patternSource: "\\bxox(?:a|b|p|r|s)-[A-Za-z0-9-]{10,200}\\b",
921
+ flags: "iu",
922
+ prefilterTerms: ["xoxa-", "xoxb-", "xoxp-", "xoxr-", "xoxs-", "slack"]
923
+ },
924
+ {
925
+ id: "slack_webhook_url",
926
+ placeholderType: "SLACK_WEBHOOK_URL",
927
+ patternSource: "https:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Za-z0-9/_-]{20,}",
928
+ flags: "iu",
929
+ prefilterTerms: ["hooks.slack.com/services", "slack"]
930
+ },
931
+ {
932
+ id: "discord_webhook_url",
933
+ placeholderType: "DISCORD_WEBHOOK_URL",
934
+ patternSource: "https:\\/\\/discord(?:app)?\\.com\\/api\\/webhooks\\/\\d+\\/[A-Za-z0-9_-]{16,}",
935
+ flags: "iu",
936
+ prefilterTerms: ["discord.com/api/webhooks", "discordapp.com/api/webhooks", "discord"]
937
+ },
938
+ {
939
+ id: "stripe_secret_key",
940
+ placeholderType: "STRIPE_SECRET_KEY",
941
+ patternSource: "\\b(?:sk|pk|ak|rk)_(?:live|test)_[A-Za-z0-9]+\\b",
942
+ flags: "iu",
943
+ prefilterTerms: [
944
+ "sk_live_",
945
+ "pk_live_",
946
+ "sk_test_",
947
+ "pk_test_",
948
+ "ak_live_",
949
+ "ak_test_",
950
+ "rk_live_",
951
+ "rk_test_",
952
+ "stripe"
953
+ ]
954
+ },
955
+ {
956
+ id: "google_api_key",
957
+ placeholderType: "GOOGLE_API_KEY",
958
+ patternSource: "\\bAIza[0-9A-Za-z_-]{35}\\b",
959
+ flags: "iu",
960
+ prefilterTerms: ["aiza", "google"]
961
+ },
962
+ {
963
+ id: "anthropic_api_key",
964
+ placeholderType: "ANTHROPIC_API_KEY",
965
+ patternSource: "\\bsk-ant-(?:api\\d{2}-)?[A-Za-z0-9_-]{20,}\\b",
966
+ flags: "iu",
967
+ prefilterTerms: ["sk-ant-", "anthropic"]
968
+ },
969
+ {
970
+ id: "evm_private_key",
971
+ placeholderType: "EVM_PRIVATE_KEY",
972
+ patternSource: "\\b0x[a-fA-F0-9]{64}\\b",
973
+ flags: "iu",
974
+ prefilterTerms: ["0x", "ethereum", "evm", "private key"]
975
+ },
976
+ {
977
+ id: "jwt_token",
978
+ placeholderType: "JWT_TOKEN",
979
+ patternSource: "\\beyJ[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b",
980
+ flags: "iu",
981
+ prefilterTerms: ["eyj", "jwt", "bearer"]
982
+ },
983
+ {
984
+ id: "bearer_token",
985
+ placeholderType: "BEARER_TOKEN",
986
+ patternSource: "\\bauthorization\\b\\s*[:=]\\s*bearer\\s+[A-Za-z0-9._~+\\/-]{16,}|\\bbearer\\s+[A-Za-z0-9._~+\\/-]{24,}",
987
+ flags: "iu",
988
+ prefilterTerms: ["authorization", "bearer"]
989
+ },
990
+ {
991
+ id: "api_key_header",
992
+ placeholderType: "API_KEY_HEADER",
993
+ patternSource: "\\bx[-_]?api[-_]?key\\b\\s*[:=]\\s*[A-Za-z0-9._~+\\/-]{16,}",
994
+ flags: "iu",
995
+ prefilterTerms: ["x-api-key", "api-key", "x_api_key", "api_key"]
996
+ },
997
+ {
998
+ id: "credential_assignment",
999
+ placeholderType: "CREDENTIAL_ASSIGNMENT",
1000
+ 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,})`,
1001
+ flags: "iu",
1002
+ prefilterTerms: [
1003
+ "api key",
1004
+ "apikey",
1005
+ "api_key",
1006
+ "access token",
1007
+ "access_token",
1008
+ "auth token",
1009
+ "client secret",
1010
+ "private key"
1011
+ ]
1012
+ },
1013
+ {
1014
+ id: "password_assignment",
1015
+ placeholderType: "PASSWORD_ASSIGNMENT",
1016
+ 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,})`,
1017
+ flags: "iu",
1018
+ prefilterTerms: ["password", "passwd", "pwd"]
1019
+ },
1020
+ {
1021
+ id: "private_key_material",
1022
+ placeholderType: "PRIVATE_KEY_MATERIAL",
1023
+ 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)-----|$)",
1024
+ flags: "iu",
1025
+ prefilterTerms: ["begin private key", "begin pgp private key block", "private key"]
1026
+ },
1027
+ {
1028
+ id: "azure_connection_string",
1029
+ placeholderType: "AZURE_CONNECTION_STRING",
1030
+ patternSource: "\\bDefaultEndpointsProtocol=https;AccountName=[A-Za-z0-9.-]{3,};AccountKey=[A-Za-z0-9+/=]{20,}(?:;EndpointSuffix=[A-Za-z0-9.-]+)?\\b",
1031
+ flags: "iu",
1032
+ prefilterTerms: ["defaultendpointsprotocol", "accountname", "accountkey", "azure"]
1033
+ },
1034
+ {
1035
+ id: "azure_sas_token",
1036
+ placeholderType: "AZURE_SAS_TOKEN",
1037
+ patternSource: "\\bsv=[^\\s&]{2,}&[^\\s]{0,200}\\bsig=[A-Za-z0-9%/+_-]{16,}",
1038
+ flags: "iu",
1039
+ prefilterTerms: ["sv=", "sig=", "accountkey", "azure"]
1040
+ }
1041
+ ];
1042
+ function ensureGlobalFlag(flags) {
1043
+ const normalized = new Set(flags.split(""));
1044
+ normalized.add("g");
1045
+ return [...normalized].join("");
1046
+ }
1047
+ var COMPILED_SDK_SECRET_PATTERNS = SDK_SECRET_PATTERN_DEFINITIONS.map((definition) => ({
1048
+ ...definition,
1049
+ scanRegex: new RegExp(definition.patternSource, ensureGlobalFlag(definition.flags)),
1050
+ prefilterTermsLower: definition.prefilterTerms.map((term) => term.toLowerCase())
1051
+ }));
1052
+ function getSdkSecretDetectionMatchers() {
1053
+ return COMPILED_SDK_SECRET_PATTERNS;
1054
+ }
1055
+
894
1056
  // src/pii.ts
895
1057
  var defaultScanDeadlineMs = 100;
1058
+ var sdkSecretMatchers = getSdkSecretDetectionMatchers();
1059
+ var DISCORD_WEBHOOK_TOKEN_RE = /https:\/\/discord(?:app)?\.com\/api\/webhooks\/\d+\/([A-Za-z0-9_-]{16,})/giu;
1060
+ var BASIC_AUTH_PASSWORD_RE = /\/\/[^:\s/?#@]+:([^@\s/?#]+)@/giu;
896
1061
  function countDigits2(value) {
897
1062
  let count = 0;
898
1063
  for (const ch of value) {
@@ -917,15 +1082,32 @@ function luhnCheck(value) {
917
1082
  return sum % 10 === 0;
918
1083
  }
919
1084
  function normalizeDetections(text, detections) {
920
- const sorted = detections.filter((d) => d.start >= 0 && d.end > d.start && d.end <= text.length).sort((a, b) => a.start - b.start || b.end - b.start - (a.end - a.start));
1085
+ const sorted = detections.filter((d) => d.start >= 0 && d.end > d.start && d.end <= text.length).sort(
1086
+ (a, b) => detectionPriority(b.type) - detectionPriority(a.type) || a.start - b.start || b.end - b.start - (a.end - a.start)
1087
+ );
921
1088
  const kept = [];
922
- let cursor = 0;
923
1089
  for (const d of sorted) {
924
- if (d.start < cursor) continue;
1090
+ if (kept.some((candidate) => rangesOverlap(candidate, d))) continue;
925
1091
  kept.push(d);
926
- cursor = d.end;
927
1092
  }
928
- return kept;
1093
+ return kept.sort((a, b) => a.start - b.start || a.end - b.end);
1094
+ }
1095
+ function rangesOverlap(left, right) {
1096
+ return left.start < right.end && right.start < left.end;
1097
+ }
1098
+ function detectionPriority(type) {
1099
+ 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(
1100
+ type
1101
+ )) {
1102
+ return 100;
1103
+ }
1104
+ if (/^(?:CREDENTIAL_ASSIGNMENT|PASSWORD_ASSIGNMENT|PRIVATE_KEY_MATERIAL|ENV_SECRET_ASSIGNMENT)$/u.test(type)) {
1105
+ return 80;
1106
+ }
1107
+ if (type === "PERSON_NAME" || type === "PERSON") {
1108
+ return 10;
1109
+ }
1110
+ return 50;
929
1111
  }
930
1112
  var PHONE_CONTEXT_KEYWORDS = [
931
1113
  "tel",
@@ -960,6 +1142,59 @@ var PHONE_CONTEXT_RE = new RegExp(
960
1142
  "iu"
961
1143
  );
962
1144
  var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
1145
+ "name",
1146
+ "names",
1147
+ "namen",
1148
+ "firstname",
1149
+ "lastname",
1150
+ "first",
1151
+ "last",
1152
+ "forename",
1153
+ "surname",
1154
+ "family",
1155
+ "given",
1156
+ "jmeno",
1157
+ "jake",
1158
+ "jaky",
1159
+ "jaka",
1160
+ "jsem",
1161
+ "jsme",
1162
+ "napsal",
1163
+ "napsali",
1164
+ "napsala",
1165
+ "napsane",
1166
+ "pouzil",
1167
+ "pouzili",
1168
+ "prijmeni",
1169
+ "vorname",
1170
+ "nachname",
1171
+ "familienname",
1172
+ "what",
1173
+ "which",
1174
+ "whose",
1175
+ "did",
1176
+ "we",
1177
+ "write",
1178
+ "wrote",
1179
+ "written",
1180
+ "type",
1181
+ "typed",
1182
+ "use",
1183
+ "used",
1184
+ "wie",
1185
+ "welchen",
1186
+ "welche",
1187
+ "welches",
1188
+ "haben",
1189
+ "wir",
1190
+ "geschrieben",
1191
+ "getippt",
1192
+ "quel",
1193
+ "quelle",
1194
+ "nom",
1195
+ "que",
1196
+ "cual",
1197
+ "nombre",
963
1198
  "write",
964
1199
  "code",
965
1200
  "script",
@@ -986,6 +1221,52 @@ var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
986
1221
  "security",
987
1222
  "instructions",
988
1223
  "instruction",
1224
+ "google",
1225
+ "form",
1226
+ "forms",
1227
+ "engineering",
1228
+ "leadership",
1229
+ "weekly",
1230
+ "daily",
1231
+ "monthly",
1232
+ "quarterly",
1233
+ "sync",
1234
+ "office",
1235
+ "updates",
1236
+ "update",
1237
+ "meeting",
1238
+ "meetings",
1239
+ "agenda",
1240
+ "minutes",
1241
+ "subject",
1242
+ "calendar",
1243
+ "roadmap",
1244
+ "platform",
1245
+ "product",
1246
+ "design",
1247
+ "operations",
1248
+ "business",
1249
+ "newsletter",
1250
+ "report",
1251
+ "reports",
1252
+ "amazon",
1253
+ "web",
1254
+ "services",
1255
+ "aws",
1256
+ "velka",
1257
+ "transformace",
1258
+ "project",
1259
+ "projekt",
1260
+ "program",
1261
+ "initiative",
1262
+ "iniciativa",
1263
+ "migration",
1264
+ "migrace",
1265
+ "test",
1266
+ "uuid",
1267
+ "fixture",
1268
+ "data",
1269
+ "firma",
989
1270
  "rules",
990
1271
  "rule",
991
1272
  "json",
@@ -998,10 +1279,22 @@ var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
998
1279
  "agentid",
999
1280
  "risk",
1000
1281
  "score",
1001
- "summary"
1282
+ "summary",
1283
+ "hi",
1284
+ "hello",
1285
+ "hey",
1286
+ "dear",
1287
+ "team",
1288
+ "ahoj",
1289
+ "dobry",
1290
+ "dobryden",
1291
+ "zdravim"
1002
1292
  ]);
1003
1293
  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;
1004
1294
  var TECHNICAL_CONTEXT_SYMBOL_REGEX = /:\/\/|`|\{|\}|\[|\]|\(|\)|;|\$|=>|::|\/\//;
1295
+ 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;
1296
+ var NAME_VALUE_ASSIGNMENT_BEFORE_CANDIDATE_REGEX = /(?:[:=]|=>|-|\b(?:is|was|je|jsou|jmenuje|called|named|ist|sind|lautet|est|es)\b)\s*$/iu;
1297
+ 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;
1005
1298
  function hasPhoneContext(text, matchStartIndex, windowSize = 50) {
1006
1299
  const start = Math.max(0, matchStartIndex - windowSize);
1007
1300
  const windowLower = text.slice(start, matchStartIndex).toLowerCase();
@@ -1018,6 +1311,16 @@ function buildContextWindow(source, index, length) {
1018
1311
  function isTechnicalContext(contextWindow) {
1019
1312
  return TECHNICAL_CONTEXT_WORD_REGEX.test(contextWindow) || TECHNICAL_CONTEXT_SYMBOL_REGEX.test(contextWindow);
1020
1313
  }
1314
+ function isNameLabelQuestionContext(contextWindow) {
1315
+ const normalized = normalizePersonWord(contextWindow);
1316
+ if (!normalized.trim()) {
1317
+ return false;
1318
+ }
1319
+ if (!NAME_LABEL_QUESTION_CONTEXT_REGEX.test(normalized)) {
1320
+ return false;
1321
+ }
1322
+ return !NAME_VALUE_ASSIGNMENT_BEFORE_CANDIDATE_REGEX.test(normalized.slice(-32));
1323
+ }
1021
1324
  function isLikelyPersonNameCandidate(candidate, contextWindow) {
1022
1325
  const words = candidate.trim().split(/\s+/);
1023
1326
  if (words.length !== 2) {
@@ -1026,6 +1329,9 @@ function isLikelyPersonNameCandidate(candidate, contextWindow) {
1026
1329
  if (isTechnicalContext(contextWindow)) {
1027
1330
  return false;
1028
1331
  }
1332
+ if (isNameLabelQuestionContext(contextWindow)) {
1333
+ return false;
1334
+ }
1029
1335
  for (const rawWord of words) {
1030
1336
  const normalized = normalizePersonWord(rawWord);
1031
1337
  if (normalized.length < 2) {
@@ -1046,63 +1352,135 @@ var PIIManager = class {
1046
1352
  *
1047
1353
  * Zero-dependency fallback with strict checksum validation for CEE national IDs.
1048
1354
  */
1049
- anonymize(text) {
1355
+ anonymize(text, options) {
1050
1356
  if (!text) return { maskedText: text, mapping: {} };
1051
1357
  try {
1052
1358
  const detections = [];
1053
- const emailRe = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
1054
- for (const m of text.matchAll(emailRe)) {
1055
- if (m.index == null) continue;
1056
- detections.push({ start: m.index, end: m.index + m[0].length, type: "EMAIL", text: m[0] });
1359
+ const loweredText = text.toLowerCase();
1360
+ const resolvedOptions = {
1361
+ pii: options?.pii !== false,
1362
+ secrets: options?.secrets !== false
1363
+ };
1364
+ if (!resolvedOptions.pii && !resolvedOptions.secrets) {
1365
+ return { maskedText: text, mapping: {} };
1057
1366
  }
1058
- const ibanRe = /\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b/gi;
1059
- for (const m of text.matchAll(ibanRe)) {
1060
- if (m.index == null) continue;
1061
- detections.push({ start: m.index, end: m.index + m[0].length, type: "IBAN", text: m[0] });
1062
- }
1063
- const ccRe = /(?:\b\d[\d -]{10,22}\d\b)/g;
1064
- for (const m of text.matchAll(ccRe)) {
1065
- if (m.index == null) continue;
1066
- const digits = countDigits2(m[0]);
1067
- if (digits < 12 || digits > 19) continue;
1068
- if (!luhnCheck(m[0])) continue;
1069
- detections.push({ start: m.index, end: m.index + m[0].length, type: "CREDIT_CARD", text: m[0] });
1070
- }
1071
- const phoneRe = /(?<!\d)(?:\+?\d[\d\s().-]{7,}\d)(?!\d)/g;
1072
- for (const m of text.matchAll(phoneRe)) {
1073
- if (m.index == null) continue;
1074
- const candidate = m[0];
1075
- const digits = countDigits2(candidate);
1076
- if (digits < 9 || digits > 15) continue;
1077
- const isStrongInternational = candidate.startsWith("+") || candidate.startsWith("00");
1078
- if (!isStrongInternational) {
1079
- const hasContext = hasPhoneContext(text, m.index);
1080
- if (!hasContext) continue;
1367
+ if (resolvedOptions.pii) {
1368
+ const emailRe = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
1369
+ for (const m of text.matchAll(emailRe)) {
1370
+ if (m.index == null) continue;
1371
+ detections.push({ start: m.index, end: m.index + m[0].length, type: "EMAIL", text: m[0] });
1081
1372
  }
1082
- detections.push({ start: m.index, end: m.index + m[0].length, type: "PHONE", text: m[0] });
1083
- }
1084
- const personRe = /(?<!\p{L})\p{Lu}\p{Ll}{2,}\s+\p{Lu}\p{Ll}{2,}(?!\p{L})/gu;
1085
- for (const m of text.matchAll(personRe)) {
1086
- if (m.index == null) continue;
1087
- const candidate = m[0];
1088
- const contextWindow = buildContextWindow(text, m.index, candidate.length);
1089
- if (!isLikelyPersonNameCandidate(candidate, contextWindow)) {
1090
- continue;
1373
+ const ibanRe = /\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b/gi;
1374
+ for (const m of text.matchAll(ibanRe)) {
1375
+ if (m.index == null) continue;
1376
+ detections.push({ start: m.index, end: m.index + m[0].length, type: "IBAN", text: m[0] });
1091
1377
  }
1092
- detections.push({ start: m.index, end: m.index + candidate.length, type: "PERSON", text: candidate });
1093
- }
1094
- const nationalIdMatches = detectNationalIdentifiers(text, {
1095
- deadlineMs: defaultScanDeadlineMs,
1096
- allowContextBirthNumberFallback: false
1097
- });
1098
- for (const match of nationalIdMatches) {
1099
- if (match.start < 0 || match.end <= match.start) continue;
1100
- detections.push({
1101
- start: match.start,
1102
- end: match.end,
1103
- type: "NATIONAL_ID",
1104
- text: text.slice(match.start, match.end)
1378
+ const ccRe = /(?:\b\d[\d -]{10,22}\d\b)/g;
1379
+ for (const m of text.matchAll(ccRe)) {
1380
+ if (m.index == null) continue;
1381
+ const digits = countDigits2(m[0]);
1382
+ if (digits < 12 || digits > 19) continue;
1383
+ if (!luhnCheck(m[0])) continue;
1384
+ detections.push({ start: m.index, end: m.index + m[0].length, type: "CREDIT_CARD", text: m[0] });
1385
+ }
1386
+ const phoneRe = /(?<!\d)(?:\+?\d[\d\s().-]{7,}\d)(?!\d)/g;
1387
+ for (const m of text.matchAll(phoneRe)) {
1388
+ if (m.index == null) continue;
1389
+ const candidate = m[0];
1390
+ const digits = countDigits2(candidate);
1391
+ if (digits < 9 || digits > 15) continue;
1392
+ const isStrongInternational = candidate.startsWith("+") || candidate.startsWith("00");
1393
+ if (!isStrongInternational) {
1394
+ const hasContext = hasPhoneContext(text, m.index);
1395
+ if (!hasContext) continue;
1396
+ }
1397
+ detections.push({ start: m.index, end: m.index + m[0].length, type: "PHONE", text: m[0] });
1398
+ }
1399
+ const personRe = /(?<!\p{L})\p{Lu}\p{Ll}{2,}\s+\p{Lu}\p{Ll}{2,}(?!\p{L})/gu;
1400
+ for (const m of text.matchAll(personRe)) {
1401
+ if (m.index == null) continue;
1402
+ const candidate = m[0];
1403
+ const contextWindow = buildContextWindow(text, m.index, candidate.length);
1404
+ if (!isLikelyPersonNameCandidate(candidate, contextWindow)) {
1405
+ continue;
1406
+ }
1407
+ detections.push({ start: m.index, end: m.index + candidate.length, type: "PERSON", text: candidate });
1408
+ }
1409
+ BIRTH_NUMBER_CONTEXT_RE.lastIndex = 0;
1410
+ for (const match of text.matchAll(BIRTH_NUMBER_CONTEXT_RE)) {
1411
+ if (match.index == null) continue;
1412
+ const value = match[1] ?? "";
1413
+ if (!/^\d{6}(?:\/?\d{3,4})?$/.test(value)) continue;
1414
+ const localIndex = match[0].lastIndexOf(value);
1415
+ const start = match.index + Math.max(0, localIndex);
1416
+ detections.push({
1417
+ start,
1418
+ end: start + value.length,
1419
+ type: "BIRTH_NUMBER",
1420
+ text: value
1421
+ });
1422
+ }
1423
+ const nationalIdMatches = detectNationalIdentifiers(text, {
1424
+ deadlineMs: defaultScanDeadlineMs,
1425
+ allowContextBirthNumberFallback: false
1105
1426
  });
1427
+ for (const match of nationalIdMatches) {
1428
+ if (match.start < 0 || match.end <= match.start) continue;
1429
+ detections.push({
1430
+ start: match.start,
1431
+ end: match.end,
1432
+ type: "NATIONAL_ID",
1433
+ text: text.slice(match.start, match.end)
1434
+ });
1435
+ }
1436
+ }
1437
+ if (resolvedOptions.secrets) {
1438
+ BASIC_AUTH_PASSWORD_RE.lastIndex = 0;
1439
+ for (const match of text.matchAll(BASIC_AUTH_PASSWORD_RE)) {
1440
+ if (match.index == null) continue;
1441
+ const password = match[1] ?? "";
1442
+ if (!password) continue;
1443
+ const localIndex = match[0].lastIndexOf(password);
1444
+ const start = match.index + Math.max(0, localIndex);
1445
+ detections.push({
1446
+ start,
1447
+ end: start + password.length,
1448
+ type: "BASIC_AUTH_PASSWORD",
1449
+ text: password
1450
+ });
1451
+ }
1452
+ DISCORD_WEBHOOK_TOKEN_RE.lastIndex = 0;
1453
+ for (const match of text.matchAll(DISCORD_WEBHOOK_TOKEN_RE)) {
1454
+ if (match.index == null) continue;
1455
+ const token = match[1] ?? "";
1456
+ if (!token) continue;
1457
+ const localIndex = match[0].lastIndexOf(token);
1458
+ const start = match.index + Math.max(0, localIndex);
1459
+ detections.push({
1460
+ start,
1461
+ end: start + token.length,
1462
+ type: "DISCORD_WEBHOOK_TOKEN",
1463
+ text: token
1464
+ });
1465
+ }
1466
+ for (const matcher of sdkSecretMatchers) {
1467
+ if (matcher.id === "discord_webhook_url") {
1468
+ continue;
1469
+ }
1470
+ if (matcher.prefilterTermsLower.length > 0 && !matcher.prefilterTermsLower.some((term) => loweredText.includes(term))) {
1471
+ continue;
1472
+ }
1473
+ matcher.scanRegex.lastIndex = 0;
1474
+ for (const match of text.matchAll(matcher.scanRegex)) {
1475
+ if (match.index == null) continue;
1476
+ detections.push({
1477
+ start: match.index,
1478
+ end: match.index + match[0].length,
1479
+ type: matcher.placeholderType,
1480
+ text: match[0]
1481
+ });
1482
+ }
1483
+ }
1106
1484
  }
1107
1485
  const kept = normalizeDetections(text, detections);
1108
1486
  if (!kept.length) return { maskedText: text, mapping: {} };
@@ -1143,6 +1521,109 @@ var CONFIG_TTL_MS = 15 * 1e3;
1143
1521
  var CONFIG_FAILURE_FALLBACK_TTL_MS = 2 * 1e3;
1144
1522
 
1145
1523
  // src/agentid.ts
1524
+ function getObjectString(value, ...keys) {
1525
+ for (const key of keys) {
1526
+ const candidate = value?.[key];
1527
+ if (typeof candidate === "string" && candidate.trim().length > 0) {
1528
+ return candidate.trim();
1529
+ }
1530
+ }
1531
+ return void 0;
1532
+ }
1533
+ function getObjectNumber(value, ...keys) {
1534
+ for (const key of keys) {
1535
+ const candidate = value?.[key];
1536
+ if (typeof candidate === "number" && Number.isFinite(candidate)) {
1537
+ return candidate;
1538
+ }
1539
+ if (typeof candidate === "string" && candidate.trim().length > 0) {
1540
+ const parsed = Number(candidate);
1541
+ if (Number.isFinite(parsed)) {
1542
+ return parsed;
1543
+ }
1544
+ }
1545
+ }
1546
+ return void 0;
1547
+ }
1548
+ function createAgentIdTelemetryContext(value) {
1549
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1550
+ return void 0;
1551
+ }
1552
+ const raw = { ...value };
1553
+ const normalized = {};
1554
+ const assignString = (key, ...aliases) => {
1555
+ const next = getObjectString(raw, key, ...aliases);
1556
+ if (next) {
1557
+ normalized[key] = next;
1558
+ }
1559
+ };
1560
+ const assignNumber = (key, ...aliases) => {
1561
+ const next = getObjectNumber(raw, key, ...aliases);
1562
+ if (typeof next === "number") {
1563
+ normalized[key] = next;
1564
+ }
1565
+ };
1566
+ assignString("workflow_id", "workflowId");
1567
+ assignString("workflow_run_id", "workflowRunId");
1568
+ assignString("workflow_step_id", "workflowStepId");
1569
+ assignString("workflow_name", "workflowName");
1570
+ assignString("workflow_step_name", "workflowStepName");
1571
+ assignNumber("workflow_step_index", "workflowStepIndex");
1572
+ assignString("parent_event_id", "parentEventId");
1573
+ assignString("tool_name", "toolName");
1574
+ assignString("tool_target", "toolTarget");
1575
+ assignString("tool_target_type", "toolTargetType");
1576
+ assignString("event_title", "eventTitle");
1577
+ assignString("event_status", "eventStatus");
1578
+ assignString("event_category", "eventCategory");
1579
+ assignString("event_subtype", "eventSubtype");
1580
+ const consumedKeys = /* @__PURE__ */ new Set([
1581
+ "workflow_id",
1582
+ "workflowId",
1583
+ "workflow_run_id",
1584
+ "workflowRunId",
1585
+ "workflow_step_id",
1586
+ "workflowStepId",
1587
+ "workflow_name",
1588
+ "workflowName",
1589
+ "workflow_step_name",
1590
+ "workflowStepName",
1591
+ "workflow_step_index",
1592
+ "workflowStepIndex",
1593
+ "parent_event_id",
1594
+ "parentEventId",
1595
+ "tool_name",
1596
+ "toolName",
1597
+ "tool_target",
1598
+ "toolTarget",
1599
+ "tool_target_type",
1600
+ "toolTargetType",
1601
+ "event_title",
1602
+ "eventTitle",
1603
+ "event_status",
1604
+ "eventStatus",
1605
+ "event_category",
1606
+ "eventCategory",
1607
+ "event_subtype",
1608
+ "eventSubtype"
1609
+ ]);
1610
+ for (const [key, entry] of Object.entries(raw)) {
1611
+ if (consumedKeys.has(key) || entry === void 0) {
1612
+ continue;
1613
+ }
1614
+ if (typeof entry === "string") {
1615
+ if (entry.trim().length > 0) {
1616
+ normalized[key] = entry.trim();
1617
+ }
1618
+ continue;
1619
+ }
1620
+ normalized[key] = entry;
1621
+ }
1622
+ if (typeof normalized.workflow_id !== "string" && typeof normalized.workflow_run_id === "string") {
1623
+ normalized.workflow_id = normalized.workflow_run_id;
1624
+ }
1625
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
1626
+ }
1146
1627
  var SecurityBlockError = class extends Error {
1147
1628
  constructor(reason = "guard_denied") {
1148
1629
  super(`AgentID: Security Blocked (${reason})`);
@@ -1153,9 +1634,18 @@ var SecurityBlockError = class extends Error {
1153
1634
 
1154
1635
  // src/langchain.ts
1155
1636
  var piiManager = new PIIManager();
1637
+ var LANGCHAIN_TELEMETRY_FIELD = "agentid_telemetry";
1156
1638
  function safeString(val) {
1157
1639
  return typeof val === "string" ? val : "";
1158
1640
  }
1641
+ function firstNonEmptyString(...values) {
1642
+ for (const value of values) {
1643
+ if (typeof value === "string" && value.trim().length > 0) {
1644
+ return value.trim();
1645
+ }
1646
+ }
1647
+ return void 0;
1648
+ }
1159
1649
  function normalizeExpectedLanguages(value) {
1160
1650
  if (!Array.isArray(value)) {
1161
1651
  return void 0;
@@ -1165,6 +1655,121 @@ function normalizeExpectedLanguages(value) {
1165
1655
  )];
1166
1656
  return normalized.length > 0 ? normalized : void 0;
1167
1657
  }
1658
+ function isPlainRecord(value) {
1659
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
1660
+ }
1661
+ function hasKnownTelemetryField(record) {
1662
+ const knownKeys = [
1663
+ "workflow_id",
1664
+ "workflowId",
1665
+ "workflow_run_id",
1666
+ "workflowRunId",
1667
+ "workflow_step_id",
1668
+ "workflowStepId",
1669
+ "workflow_name",
1670
+ "workflowName",
1671
+ "workflow_step_name",
1672
+ "workflowStepName",
1673
+ "workflow_step_index",
1674
+ "workflowStepIndex",
1675
+ "parent_event_id",
1676
+ "parentEventId",
1677
+ "tool_name",
1678
+ "toolName",
1679
+ "tool_target",
1680
+ "toolTarget",
1681
+ "tool_target_type",
1682
+ "toolTargetType",
1683
+ "event_title",
1684
+ "eventTitle",
1685
+ "event_status",
1686
+ "eventStatus",
1687
+ "event_category",
1688
+ "eventCategory",
1689
+ "event_subtype",
1690
+ "eventSubtype"
1691
+ ];
1692
+ return knownKeys.some((key) => Object.prototype.hasOwnProperty.call(record, key));
1693
+ }
1694
+ function asTelemetryContext(value) {
1695
+ if (!isPlainRecord(value)) {
1696
+ return void 0;
1697
+ }
1698
+ return createAgentIdTelemetryContext(value);
1699
+ }
1700
+ function mergeTelemetryContexts(...contexts) {
1701
+ const merged = {};
1702
+ let hasValues = false;
1703
+ for (const context of contexts) {
1704
+ const normalized = createAgentIdTelemetryContext(context);
1705
+ if (!normalized) {
1706
+ continue;
1707
+ }
1708
+ Object.assign(merged, normalized);
1709
+ hasValues = true;
1710
+ }
1711
+ return hasValues ? createAgentIdTelemetryContext(merged) : void 0;
1712
+ }
1713
+ function extractTelemetryFromRecord(record) {
1714
+ const candidates = [];
1715
+ const add = (value) => {
1716
+ const telemetry = asTelemetryContext(value);
1717
+ if (telemetry) {
1718
+ candidates.push(telemetry);
1719
+ }
1720
+ };
1721
+ add(record[LANGCHAIN_TELEMETRY_FIELD]);
1722
+ add(record.agentidTelemetry);
1723
+ const agentid = record.agentid;
1724
+ if (isPlainRecord(agentid)) {
1725
+ add(agentid.telemetry);
1726
+ add(agentid.telemetryMetadata);
1727
+ }
1728
+ if (hasKnownTelemetryField(record)) {
1729
+ add(record);
1730
+ }
1731
+ return mergeTelemetryContexts(...candidates);
1732
+ }
1733
+ function extractLangChainTelemetryContext(extraParams) {
1734
+ if (!isPlainRecord(extraParams)) {
1735
+ return void 0;
1736
+ }
1737
+ const contexts = [];
1738
+ const addFromRecord = (record) => {
1739
+ if (!isPlainRecord(record)) {
1740
+ return;
1741
+ }
1742
+ const telemetry = extractTelemetryFromRecord(record);
1743
+ if (telemetry) {
1744
+ contexts.push(telemetry);
1745
+ }
1746
+ };
1747
+ addFromRecord(extraParams);
1748
+ addFromRecord(extraParams.metadata);
1749
+ addFromRecord(extraParams.options);
1750
+ if (isPlainRecord(extraParams.options)) {
1751
+ addFromRecord(extraParams.options.metadata);
1752
+ }
1753
+ addFromRecord(extraParams.invocation_params);
1754
+ if (isPlainRecord(extraParams.invocation_params)) {
1755
+ addFromRecord(extraParams.invocation_params.metadata);
1756
+ }
1757
+ addFromRecord(extraParams.kwargs);
1758
+ if (isPlainRecord(extraParams.kwargs)) {
1759
+ addFromRecord(extraParams.kwargs.metadata);
1760
+ }
1761
+ return mergeTelemetryContexts(...contexts);
1762
+ }
1763
+ function extractTelemetryFromValues(...values) {
1764
+ const contexts = [];
1765
+ for (const value of values) {
1766
+ const telemetry = extractLangChainTelemetryContext(value);
1767
+ if (telemetry) {
1768
+ contexts.push(telemetry);
1769
+ }
1770
+ }
1771
+ return mergeTelemetryContexts(...contexts);
1772
+ }
1168
1773
  function coerceTransparencyMetadata(value) {
1169
1774
  if (!value || typeof value !== "object" || Array.isArray(value)) {
1170
1775
  return void 0;
@@ -1335,6 +1940,40 @@ function extractModel(serialized, kwargs) {
1335
1940
  if (typeof name === "string" && name) return name;
1336
1941
  return void 0;
1337
1942
  }
1943
+ function extractToolName(serialized, extras, telemetry) {
1944
+ const serializedRecord = serialized && typeof serialized === "object" ? serialized : void 0;
1945
+ const extraName = extras.find(
1946
+ (value) => typeof value === "string" && value.trim().length > 0
1947
+ );
1948
+ return firstNonEmptyString(
1949
+ telemetry?.tool_name,
1950
+ telemetry?.toolName,
1951
+ serializedRecord?.name,
1952
+ serializedRecord?.id,
1953
+ serializedRecord?.tool_name,
1954
+ serializedRecord?.toolName,
1955
+ extraName
1956
+ );
1957
+ }
1958
+ function extractWorkflowName(serialized, extras, telemetry) {
1959
+ const serializedRecord = serialized && typeof serialized === "object" ? serialized : void 0;
1960
+ const extraName = extras.find(
1961
+ (value) => typeof value === "string" && value.trim().length > 0
1962
+ );
1963
+ return firstNonEmptyString(
1964
+ telemetry?.workflow_step_name,
1965
+ telemetry?.workflowStepName,
1966
+ telemetry?.workflow_name,
1967
+ telemetry?.workflowName,
1968
+ telemetry?.event_title,
1969
+ telemetry?.eventTitle,
1970
+ serializedRecord?.name,
1971
+ serializedRecord?.id,
1972
+ serializedRecord?.chain_name,
1973
+ serializedRecord?.chainName,
1974
+ extraName
1975
+ );
1976
+ }
1338
1977
  function extractModelFromOutput(output) {
1339
1978
  const llmOutput = output?.llmOutput ?? output?.llm_output;
1340
1979
  const llmModel = llmOutput?.model ?? llmOutput?.model_name ?? llmOutput?.modelName;
@@ -1485,22 +2124,28 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1485
2124
  super();
1486
2125
  this.name = "agentid_callback_handler";
1487
2126
  this.runs = /* @__PURE__ */ new Map();
2127
+ this.toolRuns = /* @__PURE__ */ new Map();
2128
+ this.chainRuns = /* @__PURE__ */ new Map();
1488
2129
  this.agent = agent;
1489
2130
  this.systemId = options.system_id;
1490
2131
  this.expectedLanguages = normalizeExpectedLanguages(
1491
2132
  options.expected_languages ?? options.expectedLanguages
1492
2133
  );
1493
2134
  this.apiKeyOverride = options.apiKey?.trim() || options.api_key?.trim() || void 0;
2135
+ this.telemetry = createAgentIdTelemetryContext(options.telemetry);
1494
2136
  }
1495
2137
  get requestOptions() {
1496
2138
  return this.apiKeyOverride ? { apiKey: this.apiKeyOverride } : void 0;
1497
2139
  }
1498
- getLangchainCapabilities(piiMaskingEnabled) {
2140
+ getLangchainCapabilities(piiMaskingEnabled, secretMaskingEnabled) {
1499
2141
  const resolvedPiiMaskingEnabled = typeof piiMaskingEnabled === "boolean" ? piiMaskingEnabled : this.agent.getEffectivePiiMasking(this.requestOptions);
2142
+ const agentWithResolvedSecret = this.agent;
2143
+ const resolvedSecretMaskingEnabled = typeof secretMaskingEnabled === "boolean" ? secretMaskingEnabled : typeof agentWithResolvedSecret.getEffectiveSecretMaskingForConfig === "function" ? agentWithResolvedSecret.getEffectiveSecretMaskingForConfig() : false;
1500
2144
  return {
1501
2145
  capabilities: {
1502
2146
  has_feedback_handler: true,
1503
2147
  pii_masking_enabled: resolvedPiiMaskingEnabled,
2148
+ secret_masking_enabled: resolvedSecretMaskingEnabled,
1504
2149
  framework: "langchain"
1505
2150
  }
1506
2151
  };
@@ -1512,15 +2157,76 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1512
2157
  }
1513
2158
  return this.agent.getEffectivePiiMasking(this.requestOptions);
1514
2159
  }
1515
- async preflight(input, stream, clientEventId) {
2160
+ resolvePreparedSecretMaskingEnabled(prepared) {
2161
+ const agentWithResolvedConfig = this.agent;
2162
+ if (typeof agentWithResolvedConfig.getEffectiveSecretMaskingForConfig === "function") {
2163
+ return agentWithResolvedConfig.getEffectiveSecretMaskingForConfig(
2164
+ prepared.capabilityConfig
2165
+ );
2166
+ }
2167
+ return false;
2168
+ }
2169
+ async preflight(input, stream, clientEventId, telemetryMetadata) {
1516
2170
  const prepared = await this.agent.prepareInputForDispatch({
1517
2171
  input,
1518
2172
  systemId: this.systemId,
1519
2173
  stream,
1520
- clientEventId
2174
+ clientEventId,
2175
+ telemetryMetadata
1521
2176
  }, this.requestOptions);
1522
2177
  return prepared;
1523
2178
  }
2179
+ resolveTelemetry(extraParams) {
2180
+ return mergeTelemetryContexts(
2181
+ this.telemetry,
2182
+ extractLangChainTelemetryContext(extraParams)
2183
+ );
2184
+ }
2185
+ resolveParentEventContext(parentRunId) {
2186
+ const parentId = String(parentRunId ?? "");
2187
+ const llmRun = this.runs.get(parentId);
2188
+ if (llmRun) {
2189
+ return {
2190
+ parentEventId: llmRun.clientEventId,
2191
+ piiMaskingEnabled: llmRun.piiMaskingEnabled,
2192
+ secretMaskingEnabled: llmRun.secretMaskingEnabled
2193
+ };
2194
+ }
2195
+ const toolRun = this.toolRuns.get(parentId);
2196
+ if (toolRun) {
2197
+ return {
2198
+ parentEventId: toolRun.startEventId,
2199
+ piiMaskingEnabled: toolRun.piiMaskingEnabled,
2200
+ secretMaskingEnabled: toolRun.secretMaskingEnabled
2201
+ };
2202
+ }
2203
+ const chainRun = this.chainRuns.get(parentId);
2204
+ if (chainRun) {
2205
+ return {
2206
+ parentEventId: chainRun.startEventId,
2207
+ piiMaskingEnabled: chainRun.piiMaskingEnabled,
2208
+ secretMaskingEnabled: chainRun.secretMaskingEnabled
2209
+ };
2210
+ }
2211
+ return {};
2212
+ }
2213
+ async logWorkflowOperation(params, capabilityHints) {
2214
+ const payload = this.agent.buildOperationLogParams({
2215
+ system_id: this.systemId,
2216
+ telemetry: params.telemetry,
2217
+ metadata: params.metadata,
2218
+ event_type: params.event_type,
2219
+ event_status: params.event_status,
2220
+ severity: params.severity,
2221
+ latency: params.latency,
2222
+ client_capabilities: this.getLangchainCapabilities(
2223
+ capabilityHints?.piiMaskingEnabled,
2224
+ capabilityHints?.secretMaskingEnabled
2225
+ )
2226
+ });
2227
+ await this.agent.log(payload, this.requestOptions);
2228
+ return payload;
2229
+ }
1524
2230
  async handleLLMStart(serialized, prompts, runId, _parentRunId, extraParams) {
1525
2231
  const input = extractPromptFromPrompts(prompts);
1526
2232
  const id = String(runId ?? "");
@@ -1530,9 +2236,16 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1530
2236
  }
1531
2237
  const requestedClientEventId = isUuidLike(id) ? id.trim() : createClientEventId();
1532
2238
  const stream = extractStreamFlag(serialized, extraParams);
1533
- const prepared = await this.preflight(input, stream, requestedClientEventId);
2239
+ const telemetryMetadata = this.resolveTelemetry(extraParams);
2240
+ const prepared = await this.preflight(
2241
+ input,
2242
+ stream,
2243
+ requestedClientEventId,
2244
+ telemetryMetadata
2245
+ );
1534
2246
  const sanitizedInput = prepared.sanitizedInput;
1535
2247
  const piiMaskingEnabled = this.resolvePreparedPiiMaskingEnabled(prepared);
2248
+ const secretMaskingEnabled = this.resolvePreparedSecretMaskingEnabled(prepared);
1536
2249
  if (sanitizedInput !== input) {
1537
2250
  const mutated = setPromptInPrompts(prompts, sanitizedInput);
1538
2251
  if (!mutated) {
@@ -1549,7 +2262,11 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1549
2262
  model: modelName,
1550
2263
  client_event_id: requestedClientEventId,
1551
2264
  expected_languages: this.expectedLanguages,
1552
- client_capabilities: this.getLangchainCapabilities(piiMaskingEnabled)
2265
+ metadata: telemetryMetadata,
2266
+ client_capabilities: this.getLangchainCapabilities(
2267
+ piiMaskingEnabled,
2268
+ secretMaskingEnabled
2269
+ )
1553
2270
  }, this.requestOptions);
1554
2271
  let transformedForRun = sanitizedInput;
1555
2272
  let sdkLocalScanMs = prepared.sdkLocalScanMs;
@@ -1564,7 +2281,8 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1564
2281
  stream,
1565
2282
  clientEventId: requestedClientEventId,
1566
2283
  capabilityConfig: prepared.capabilityConfig,
1567
- sdkConfigFetchMs: prepared.sdkConfigFetchMs
2284
+ sdkConfigFetchMs: prepared.sdkConfigFetchMs,
2285
+ telemetryMetadata
1568
2286
  }, this.requestOptions);
1569
2287
  transformedForRun = fallback.sanitizedInput;
1570
2288
  sdkLocalScanMs = fallback.sdkLocalScanMs;
@@ -1603,12 +2321,14 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1603
2321
  model: modelName,
1604
2322
  clientEventId: canonicalClientEventId,
1605
2323
  guardEventId,
2324
+ telemetryMetadata,
1606
2325
  transparency,
1607
2326
  piiMapping: normalizePiiMapping(prepared.piiMapping),
1608
2327
  shouldDeanonymize: prepared.shouldDeanonymize === true,
1609
2328
  responseStreamed: stream,
1610
2329
  sdkConfigVersion: prepared.capabilityConfig?.version ?? null,
1611
- piiMaskingEnabled
2330
+ piiMaskingEnabled,
2331
+ secretMaskingEnabled
1612
2332
  });
1613
2333
  logCallbackDebug("handleLLMStart state_set", {
1614
2334
  runId: id,
@@ -1625,9 +2345,16 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1625
2345
  }
1626
2346
  const requestedClientEventId = isUuidLike(id) ? id.trim() : createClientEventId();
1627
2347
  const stream = extractStreamFlag(serialized, extraParams);
1628
- const prepared = await this.preflight(input, stream, requestedClientEventId);
2348
+ const telemetryMetadata = this.resolveTelemetry(extraParams);
2349
+ const prepared = await this.preflight(
2350
+ input,
2351
+ stream,
2352
+ requestedClientEventId,
2353
+ telemetryMetadata
2354
+ );
1629
2355
  const sanitizedInput = prepared.sanitizedInput;
1630
2356
  const piiMaskingEnabled = this.resolvePreparedPiiMaskingEnabled(prepared);
2357
+ const secretMaskingEnabled = this.resolvePreparedSecretMaskingEnabled(prepared);
1631
2358
  if (sanitizedInput !== input) {
1632
2359
  const mutated = setPromptInMessages(messages, sanitizedInput);
1633
2360
  if (!mutated) {
@@ -1644,7 +2371,11 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1644
2371
  model: modelName,
1645
2372
  client_event_id: requestedClientEventId,
1646
2373
  expected_languages: this.expectedLanguages,
1647
- client_capabilities: this.getLangchainCapabilities(piiMaskingEnabled)
2374
+ metadata: telemetryMetadata,
2375
+ client_capabilities: this.getLangchainCapabilities(
2376
+ piiMaskingEnabled,
2377
+ secretMaskingEnabled
2378
+ )
1648
2379
  }, this.requestOptions);
1649
2380
  let transformedForRun = sanitizedInput;
1650
2381
  let sdkLocalScanMs = prepared.sdkLocalScanMs;
@@ -1659,7 +2390,8 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1659
2390
  stream,
1660
2391
  clientEventId: requestedClientEventId,
1661
2392
  capabilityConfig: prepared.capabilityConfig,
1662
- sdkConfigFetchMs: prepared.sdkConfigFetchMs
2393
+ sdkConfigFetchMs: prepared.sdkConfigFetchMs,
2394
+ telemetryMetadata
1663
2395
  }, this.requestOptions);
1664
2396
  transformedForRun = fallback.sanitizedInput;
1665
2397
  sdkLocalScanMs = fallback.sdkLocalScanMs;
@@ -1698,12 +2430,14 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1698
2430
  model: modelName,
1699
2431
  clientEventId: canonicalClientEventId,
1700
2432
  guardEventId,
2433
+ telemetryMetadata,
1701
2434
  transparency,
1702
2435
  piiMapping: normalizePiiMapping(prepared.piiMapping),
1703
2436
  shouldDeanonymize: prepared.shouldDeanonymize === true,
1704
2437
  responseStreamed: stream,
1705
2438
  sdkConfigVersion: prepared.capabilityConfig?.version ?? null,
1706
- piiMaskingEnabled
2439
+ piiMaskingEnabled,
2440
+ secretMaskingEnabled
1707
2441
  });
1708
2442
  logCallbackDebug("handleChatModelStart state_set", {
1709
2443
  runId: id,
@@ -1731,7 +2465,9 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1731
2465
  }
1732
2466
  const clientOutputText = extractOutputText(output);
1733
2467
  const usage = extractTokenUsage(output);
1734
- const metadata = {};
2468
+ const metadata = {
2469
+ ...state.telemetryMetadata ?? {}
2470
+ };
1735
2471
  if (state.clientEventId) {
1736
2472
  metadata.client_event_id = state.clientEventId;
1737
2473
  }
@@ -1767,7 +2503,10 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1767
2503
  usage,
1768
2504
  latency: modelLatencyMs,
1769
2505
  metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
1770
- client_capabilities: this.getLangchainCapabilities(state.piiMaskingEnabled)
2506
+ client_capabilities: this.getLangchainCapabilities(
2507
+ state.piiMaskingEnabled,
2508
+ state.secretMaskingEnabled
2509
+ )
1771
2510
  }, this.requestOptions);
1772
2511
  logCallbackDebug("handleLLMEnd logged", {
1773
2512
  runId: id,
@@ -1781,6 +2520,7 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1781
2520
  if (state) this.runs.delete(id);
1782
2521
  const message = err && typeof err === "object" && "message" in err ? String(err.message) : String(err ?? "");
1783
2522
  const metadata = {
2523
+ ...state?.telemetryMetadata ?? {},
1784
2524
  error_message: message
1785
2525
  };
1786
2526
  if (state?.clientEventId) {
@@ -1809,9 +2549,184 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
1809
2549
  event_type: "error",
1810
2550
  severity: "error",
1811
2551
  metadata,
1812
- client_capabilities: this.getLangchainCapabilities(state?.piiMaskingEnabled)
2552
+ client_capabilities: this.getLangchainCapabilities(
2553
+ state?.piiMaskingEnabled,
2554
+ state?.secretMaskingEnabled
2555
+ )
1813
2556
  }, this.requestOptions);
1814
2557
  }
2558
+ async handleToolStart(serialized, _input, runId, parentRunId, ...rest) {
2559
+ const id = String(runId ?? "");
2560
+ const parentContext = this.resolveParentEventContext(parentRunId);
2561
+ const baseTelemetry = extractTelemetryFromValues(...rest);
2562
+ const toolName = extractToolName(serialized, rest, baseTelemetry);
2563
+ const workflowStepId = firstNonEmptyString(baseTelemetry?.workflow_step_id, baseTelemetry?.workflowStepId) ?? createClientEventId();
2564
+ const telemetry = mergeTelemetryContexts(
2565
+ this.telemetry,
2566
+ baseTelemetry,
2567
+ createAgentIdTelemetryContext({
2568
+ workflow_step_id: workflowStepId,
2569
+ parent_event_id: parentContext.parentEventId,
2570
+ tool_name: toolName
2571
+ })
2572
+ );
2573
+ const startedAtMs = Date.now();
2574
+ const payload = await this.logWorkflowOperation(
2575
+ {
2576
+ telemetry,
2577
+ event_type: "start",
2578
+ event_status: "started"
2579
+ },
2580
+ parentContext
2581
+ );
2582
+ this.toolRuns.set(id, {
2583
+ startedAtMs,
2584
+ workflowStepId,
2585
+ startEventId: payload.event_id ?? createClientEventId(),
2586
+ telemetryMetadata: telemetry,
2587
+ piiMaskingEnabled: parentContext.piiMaskingEnabled,
2588
+ secretMaskingEnabled: parentContext.secretMaskingEnabled
2589
+ });
2590
+ }
2591
+ async handleToolEnd(_output, runId) {
2592
+ const id = String(runId ?? "");
2593
+ const state = this.toolRuns.get(id);
2594
+ if (!state) {
2595
+ return;
2596
+ }
2597
+ this.toolRuns.delete(id);
2598
+ await this.logWorkflowOperation(
2599
+ {
2600
+ telemetry: mergeTelemetryContexts(
2601
+ state.telemetryMetadata,
2602
+ createAgentIdTelemetryContext({
2603
+ workflow_step_id: state.workflowStepId,
2604
+ parent_event_id: state.startEventId
2605
+ })
2606
+ ),
2607
+ event_type: "complete",
2608
+ event_status: "completed",
2609
+ latency: Math.max(0, Date.now() - state.startedAtMs)
2610
+ },
2611
+ state
2612
+ );
2613
+ }
2614
+ async handleToolError(err, runId) {
2615
+ const id = String(runId ?? "");
2616
+ const state = this.toolRuns.get(id);
2617
+ if (!state) {
2618
+ return;
2619
+ }
2620
+ this.toolRuns.delete(id);
2621
+ const errorMessage = err instanceof Error ? err.message : typeof err === "undefined" ? "" : String(err);
2622
+ await this.logWorkflowOperation(
2623
+ {
2624
+ telemetry: mergeTelemetryContexts(
2625
+ state?.telemetryMetadata,
2626
+ createAgentIdTelemetryContext({
2627
+ workflow_step_id: state?.workflowStepId,
2628
+ parent_event_id: state?.startEventId
2629
+ })
2630
+ ),
2631
+ metadata: errorMessage.trim().length > 0 ? {
2632
+ error_message: errorMessage.trim(),
2633
+ ...err instanceof Error && err.name ? { error_name: err.name } : {}
2634
+ } : void 0,
2635
+ event_type: "error",
2636
+ event_status: "failed",
2637
+ severity: "error",
2638
+ latency: typeof state?.startedAtMs === "number" ? Math.max(0, Date.now() - state.startedAtMs) : void 0
2639
+ },
2640
+ state
2641
+ );
2642
+ }
2643
+ async handleChainStart(serialized, _inputs, runId, parentRunId, ...rest) {
2644
+ const id = String(runId ?? "");
2645
+ const parentContext = this.resolveParentEventContext(parentRunId);
2646
+ const baseTelemetry = extractTelemetryFromValues(...rest);
2647
+ const workflowName = extractWorkflowName(serialized, rest, baseTelemetry);
2648
+ const workflowStepId = firstNonEmptyString(baseTelemetry?.workflow_step_id, baseTelemetry?.workflowStepId) ?? createClientEventId();
2649
+ const resolvedCategory = firstNonEmptyString(baseTelemetry?.event_category, baseTelemetry?.eventCategory) ?? "workflow";
2650
+ const telemetry = mergeTelemetryContexts(
2651
+ this.telemetry,
2652
+ baseTelemetry,
2653
+ createAgentIdTelemetryContext({
2654
+ workflow_step_id: workflowStepId,
2655
+ workflow_step_name: workflowName,
2656
+ parent_event_id: parentContext.parentEventId,
2657
+ event_category: resolvedCategory
2658
+ })
2659
+ );
2660
+ const startedAtMs = Date.now();
2661
+ const payload = await this.logWorkflowOperation(
2662
+ {
2663
+ telemetry,
2664
+ event_type: "start",
2665
+ event_status: "started"
2666
+ },
2667
+ parentContext
2668
+ );
2669
+ this.chainRuns.set(id, {
2670
+ startedAtMs,
2671
+ workflowStepId,
2672
+ startEventId: payload.event_id ?? createClientEventId(),
2673
+ telemetryMetadata: telemetry,
2674
+ piiMaskingEnabled: parentContext.piiMaskingEnabled,
2675
+ secretMaskingEnabled: parentContext.secretMaskingEnabled
2676
+ });
2677
+ }
2678
+ async handleChainEnd(_outputs, runId) {
2679
+ const id = String(runId ?? "");
2680
+ const state = this.chainRuns.get(id);
2681
+ if (!state) {
2682
+ return;
2683
+ }
2684
+ this.chainRuns.delete(id);
2685
+ await this.logWorkflowOperation(
2686
+ {
2687
+ telemetry: mergeTelemetryContexts(
2688
+ state.telemetryMetadata,
2689
+ createAgentIdTelemetryContext({
2690
+ workflow_step_id: state.workflowStepId,
2691
+ parent_event_id: state.startEventId
2692
+ })
2693
+ ),
2694
+ event_type: "complete",
2695
+ event_status: "completed",
2696
+ latency: Math.max(0, Date.now() - state.startedAtMs)
2697
+ },
2698
+ state
2699
+ );
2700
+ }
2701
+ async handleChainError(err, runId) {
2702
+ const id = String(runId ?? "");
2703
+ const state = this.chainRuns.get(id);
2704
+ if (!state) {
2705
+ return;
2706
+ }
2707
+ this.chainRuns.delete(id);
2708
+ const errorMessage = err instanceof Error ? err.message : typeof err === "undefined" ? "" : String(err);
2709
+ await this.logWorkflowOperation(
2710
+ {
2711
+ telemetry: mergeTelemetryContexts(
2712
+ state.telemetryMetadata,
2713
+ createAgentIdTelemetryContext({
2714
+ workflow_step_id: state.workflowStepId,
2715
+ parent_event_id: state.startEventId
2716
+ })
2717
+ ),
2718
+ metadata: errorMessage.trim().length > 0 ? {
2719
+ error_message: errorMessage.trim(),
2720
+ ...err instanceof Error && err.name ? { error_name: err.name } : {}
2721
+ } : void 0,
2722
+ event_type: "error",
2723
+ event_status: "failed",
2724
+ severity: "error",
2725
+ latency: Math.max(0, Date.now() - state.startedAtMs)
2726
+ },
2727
+ state
2728
+ );
2729
+ }
1815
2730
  };
1816
2731
  // Annotate the CommonJS export names for ESM import in node:
1817
2732
  0 && (module.exports = {