agentid-sdk 0.1.41 → 0.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.41".trim().length > 0 ? "js-0.1.41" : FALLBACK_SDK_VERSION;
30
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.42".trim().length > 0 ? "js-0.1.42" : FALLBACK_SDK_VERSION;
31
31
 
32
32
  // src/pii-national-identifiers.ts
33
33
  var MAX_CANDIDATES_PER_RULE = 256;
@@ -895,49 +895,49 @@ function detectNationalIdentifiers(text, options = {}) {
895
895
  var SDK_SECRET_PATTERN_DEFINITIONS = [
896
896
  {
897
897
  id: "openai_api_key",
898
- placeholderType: "OPENAI_API_KEY",
898
+ placeholderType: "SECRET",
899
899
  patternSource: "\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b",
900
900
  flags: "iu",
901
901
  prefilterTerms: ["sk-", "proj-", "openai"]
902
902
  },
903
903
  {
904
904
  id: "aws_access_key",
905
- placeholderType: "AWS_ACCESS_KEY",
905
+ placeholderType: "SECRET",
906
906
  patternSource: "\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b",
907
907
  flags: "iu",
908
908
  prefilterTerms: ["akia", "asia", "aws"]
909
909
  },
910
910
  {
911
911
  id: "github_token",
912
- placeholderType: "GITHUB_TOKEN",
912
+ placeholderType: "SECRET",
913
913
  patternSource: "\\b(?:gh[pousr]_[A-Za-z0-9]{24,255}|github_pat_[A-Za-z0-9_]{20,255})\\b",
914
914
  flags: "iu",
915
915
  prefilterTerms: ["ghp_", "gho_", "ghu_", "ghs_", "ghr_", "github_pat_"]
916
916
  },
917
917
  {
918
918
  id: "slack_token",
919
- placeholderType: "SLACK_TOKEN",
919
+ placeholderType: "SECRET",
920
920
  patternSource: "\\bxox(?:a|b|p|r|s)-[A-Za-z0-9-]{10,200}\\b",
921
921
  flags: "iu",
922
922
  prefilterTerms: ["xoxa-", "xoxb-", "xoxp-", "xoxr-", "xoxs-", "slack"]
923
923
  },
924
924
  {
925
925
  id: "slack_webhook_url",
926
- placeholderType: "SLACK_WEBHOOK_URL",
926
+ placeholderType: "SECRET",
927
927
  patternSource: "https:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Za-z0-9/_-]{20,}",
928
928
  flags: "iu",
929
929
  prefilterTerms: ["hooks.slack.com/services", "slack"]
930
930
  },
931
931
  {
932
932
  id: "discord_webhook_url",
933
- placeholderType: "DISCORD_WEBHOOK_URL",
933
+ placeholderType: "SECRET",
934
934
  patternSource: "https:\\/\\/discord(?:app)?\\.com\\/api\\/webhooks\\/\\d+\\/[A-Za-z0-9_-]{16,}",
935
935
  flags: "iu",
936
936
  prefilterTerms: ["discord.com/api/webhooks", "discordapp.com/api/webhooks", "discord"]
937
937
  },
938
938
  {
939
939
  id: "stripe_secret_key",
940
- placeholderType: "STRIPE_SECRET_KEY",
940
+ placeholderType: "SECRET",
941
941
  patternSource: "\\b(?:sk|pk|ak|rk)_(?:live|test)_[A-Za-z0-9]+\\b",
942
942
  flags: "iu",
943
943
  prefilterTerms: [
@@ -954,49 +954,49 @@ var SDK_SECRET_PATTERN_DEFINITIONS = [
954
954
  },
955
955
  {
956
956
  id: "google_api_key",
957
- placeholderType: "GOOGLE_API_KEY",
957
+ placeholderType: "SECRET",
958
958
  patternSource: "\\bAIza[0-9A-Za-z_-]{35}\\b",
959
959
  flags: "iu",
960
960
  prefilterTerms: ["aiza", "google"]
961
961
  },
962
962
  {
963
963
  id: "anthropic_api_key",
964
- placeholderType: "ANTHROPIC_API_KEY",
964
+ placeholderType: "SECRET",
965
965
  patternSource: "\\bsk-ant-(?:api\\d{2}-)?[A-Za-z0-9_-]{20,}\\b",
966
966
  flags: "iu",
967
967
  prefilterTerms: ["sk-ant-", "anthropic"]
968
968
  },
969
969
  {
970
970
  id: "evm_private_key",
971
- placeholderType: "EVM_PRIVATE_KEY",
971
+ placeholderType: "SECRET",
972
972
  patternSource: "\\b0x[a-fA-F0-9]{64}\\b",
973
973
  flags: "iu",
974
974
  prefilterTerms: ["0x", "ethereum", "evm", "private key"]
975
975
  },
976
976
  {
977
977
  id: "jwt_token",
978
- placeholderType: "JWT_TOKEN",
978
+ placeholderType: "SECRET",
979
979
  patternSource: "\\beyJ[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b",
980
980
  flags: "iu",
981
981
  prefilterTerms: ["eyj", "jwt", "bearer"]
982
982
  },
983
983
  {
984
984
  id: "bearer_token",
985
- placeholderType: "BEARER_TOKEN",
985
+ placeholderType: "SECRET",
986
986
  patternSource: "\\bauthorization\\b\\s*[:=]\\s*bearer\\s+[A-Za-z0-9._~+\\/-]{16,}|\\bbearer\\s+[A-Za-z0-9._~+\\/-]{24,}",
987
987
  flags: "iu",
988
988
  prefilterTerms: ["authorization", "bearer"]
989
989
  },
990
990
  {
991
991
  id: "api_key_header",
992
- placeholderType: "API_KEY_HEADER",
992
+ placeholderType: "SECRET",
993
993
  patternSource: "\\bx[-_]?api[-_]?key\\b\\s*[:=]\\s*[A-Za-z0-9._~+\\/-]{16,}",
994
994
  flags: "iu",
995
995
  prefilterTerms: ["x-api-key", "api-key", "x_api_key", "api_key"]
996
996
  },
997
997
  {
998
998
  id: "credential_assignment",
999
- placeholderType: "CREDENTIAL_ASSIGNMENT",
999
+ placeholderType: "SECRET",
1000
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
1001
  flags: "iu",
1002
1002
  prefilterTerms: [
@@ -1012,28 +1012,28 @@ var SDK_SECRET_PATTERN_DEFINITIONS = [
1012
1012
  },
1013
1013
  {
1014
1014
  id: "password_assignment",
1015
- placeholderType: "PASSWORD_ASSIGNMENT",
1015
+ placeholderType: "PASSWORD",
1016
1016
  patternSource: `(?:\\b|["'])(?:password|passwd|pwd|heslo)(?:\\b|["'])\\s*(?:(?::|=|=>)|(?:is|are|was|were|je)\\b)?\\s*(?:"[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}"|'[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}'|[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,})`,
1017
1017
  flags: "iu",
1018
1018
  prefilterTerms: ["password", "passwd", "pwd", "heslo"]
1019
1019
  },
1020
1020
  {
1021
1021
  id: "private_key_material",
1022
- placeholderType: "PRIVATE_KEY_MATERIAL",
1022
+ placeholderType: "SECRET",
1023
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
1024
  flags: "iu",
1025
1025
  prefilterTerms: ["begin private key", "begin pgp private key block", "private key"]
1026
1026
  },
1027
1027
  {
1028
1028
  id: "azure_connection_string",
1029
- placeholderType: "AZURE_CONNECTION_STRING",
1029
+ placeholderType: "SECRET",
1030
1030
  patternSource: "\\bDefaultEndpointsProtocol=https;AccountName=[A-Za-z0-9.-]{3,};AccountKey=[A-Za-z0-9+/=]{20,}(?:;EndpointSuffix=[A-Za-z0-9.-]+)?\\b",
1031
1031
  flags: "iu",
1032
1032
  prefilterTerms: ["defaultendpointsprotocol", "accountname", "accountkey", "azure"]
1033
1033
  },
1034
1034
  {
1035
1035
  id: "azure_sas_token",
1036
- placeholderType: "AZURE_SAS_TOKEN",
1036
+ placeholderType: "SECRET",
1037
1037
  patternSource: "\\bsv=[^\\s&]{2,}&[^\\s]{0,200}\\bsig=[A-Za-z0-9%/+_-]{16,}",
1038
1038
  flags: "iu",
1039
1039
  prefilterTerms: ["sv=", "sig=", "accountkey", "azure"]
@@ -1096,19 +1096,70 @@ function rangesOverlap(left, right) {
1096
1096
  return left.start < right.end && right.start < left.end;
1097
1097
  }
1098
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
- )) {
1099
+ const normalizedType = toPlaceholderType(type);
1100
+ if (normalizedType === "SECRET") {
1102
1101
  return 100;
1103
1102
  }
1104
- if (/^(?:CREDENTIAL_ASSIGNMENT|PASSWORD_ASSIGNMENT|PRIVATE_KEY_MATERIAL|ENV_SECRET_ASSIGNMENT)$/u.test(type)) {
1103
+ if (normalizedType === "PASSWORD") {
1104
+ return 90;
1105
+ }
1106
+ if (/^(?:CREDENTIAL_ASSIGNMENT|PRIVATE_KEY_MATERIAL|ENV_SECRET_ASSIGNMENT)$/u.test(
1107
+ normalizedType
1108
+ )) {
1105
1109
  return 80;
1106
1110
  }
1107
- if (type === "PERSON_NAME" || type === "PERSON") {
1111
+ if (normalizedType === "PERSON_NAME" || normalizedType === "PERSON") {
1108
1112
  return 10;
1109
1113
  }
1110
1114
  return 50;
1111
1115
  }
1116
+ function isPasswordPlaceholderType(type) {
1117
+ return /^(?:PASSWORD_ASSIGNMENT|BASIC_AUTH_PASSWORD)$/u.test(type);
1118
+ }
1119
+ function isGenericSecretPlaceholderType(type) {
1120
+ return /^(?:OPENAI_API_KEY|AWS_ACCESS_KEY|GITHUB_TOKEN|SLACK_TOKEN|SLACK_WEBHOOK_URL|DISCORD_WEBHOOK_URL|STRIPE_SECRET_KEY|GOOGLE_API_KEY|ANTHROPIC_API_KEY|EVM_PRIVATE_KEY|JWT_TOKEN|BEARER_TOKEN|API_KEY_HEADER|CREDENTIAL_ASSIGNMENT|PRIVATE_KEY_MATERIAL|ENV_SECRET_ASSIGNMENT|AZURE_CONNECTION_STRING|AZURE_SAS_TOKEN|DISCORD_WEBHOOK_TOKEN)$/u.test(
1121
+ type
1122
+ );
1123
+ }
1124
+ function toPlaceholderType(type) {
1125
+ const normalized = String(type ?? "").trim().toUpperCase();
1126
+ if (isPasswordPlaceholderType(normalized)) {
1127
+ return "PASSWORD";
1128
+ }
1129
+ if (isGenericSecretPlaceholderType(normalized)) {
1130
+ return "SECRET";
1131
+ }
1132
+ return normalized || "PII";
1133
+ }
1134
+ function trimLeadingAddressContext(value) {
1135
+ const trimmed = value.replace(
1136
+ /^(?:(?:na\s+)?adrese|(?:se\s+)?(?:s[ií]dlem|bydli[sš]t[ěe]m|bytem|adresa(?:\s+bydli[sš]t[ěe])?))\s*[:,-]?\s*/iu,
1137
+ ""
1138
+ );
1139
+ if (!trimmed || trimmed === value) {
1140
+ return { text: value, offset: 0 };
1141
+ }
1142
+ return {
1143
+ text: trimmed,
1144
+ offset: value.indexOf(trimmed)
1145
+ };
1146
+ }
1147
+ function normalizeDetection(detection) {
1148
+ if (detection.type !== "ADDRESS") {
1149
+ return detection;
1150
+ }
1151
+ const trimmed = trimLeadingAddressContext(detection.text);
1152
+ if (trimmed.offset <= 0 || trimmed.text === detection.text) {
1153
+ return detection;
1154
+ }
1155
+ const start = detection.start + trimmed.offset;
1156
+ return {
1157
+ ...detection,
1158
+ start,
1159
+ end: start + trimmed.text.length,
1160
+ text: trimmed.text
1161
+ };
1162
+ }
1112
1163
  var PHONE_CONTEXT_KEYWORDS = [
1113
1164
  "tel",
1114
1165
  "phone",
@@ -1223,6 +1274,19 @@ var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
1223
1274
  "security",
1224
1275
  "instructions",
1225
1276
  "instruction",
1277
+ "authorized",
1278
+ "audit",
1279
+ "article",
1280
+ "compliance",
1281
+ "global",
1282
+ "governance",
1283
+ "charter",
1284
+ "initialization",
1285
+ "sequence",
1286
+ "prefix",
1287
+ "prefixes",
1288
+ "priority",
1289
+ "violation",
1226
1290
  "google",
1227
1291
  "form",
1228
1292
  "forms",
@@ -1297,6 +1361,21 @@ var TECHNICAL_CONTEXT_SYMBOL_REGEX = /:\/\/|`|\{|\}|\[|\]|\(|\)|;|\$|=>|::|\/\//
1297
1361
  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;
1298
1362
  var NAME_VALUE_ASSIGNMENT_BEFORE_CANDIDATE_REGEX = /(?:[:=]|=>|-|\b(?:is|was|je|jsou|jmenuje|called|named|ist|sind|lautet|est|es)\b)\s*$/iu;
1299
1363
  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;
1364
+ var ADDRESS_HOUSE_NUMBER_PATTERN = String.raw`\d{1,5}(?:\/\d{1,5}[A-Za-z]?)?[A-Za-z]?`;
1365
+ var ADDRESS_POSTAL_CODE_PATTERN = String.raw`(?:\d{3}\s?\d{2}|\d{5})`;
1366
+ var ADDRESS_STREET_LABEL_PATTERN = String.raw`(?:ulici|ulice|ul\.?|street|st\.?|road|rd\.?|avenue|ave\.?|n[aá]m[eě]st[ií]|t[řr][íi]da|alej|n[aá]b[řr]ež[ií])`;
1367
+ var ADDRESS_WITH_ANCHOR_RE = new RegExp(
1368
+ String.raw`\b(?:bydl[ií]m\s+na|bydlim\s+na|bytem|bydli[sš]t[eě]|adresa|na\s+ulici|v\s+ulici|doru[cč]ovac[ií]\s+adresa|koresponden[cč]n[ií]\s+adresa|faktura[cč]n[ií]\s+adresa|se\s+s[ií]dlem|z[ií]ju\s+v|ziju\s+v|zjiu\s+v)\b[\s,:-]{0,12}((?:(?:${ADDRESS_STREET_LABEL_PATTERN})\s+)?(?:\p{L}[\p{L}'’-]{2,}\s+){0,4}${ADDRESS_HOUSE_NUMBER_PATTERN}(?:(?:,\s*|\s+)(?:${ADDRESS_POSTAL_CODE_PATTERN}))?(?:(?:,\s*|\s+)(?:v|ve)\s+)?(?:(?:,\s*|\s+)(?:\p{L}[\p{L}'’-]{2,})(?:\s+\p{L}[\p{L}'’-]{2,}){0,2})?)`,
1369
+ "giu"
1370
+ );
1371
+ var ADDRESS_CITY_NUMBER_WITH_ANCHOR_RE = new RegExp(
1372
+ String.raw`\b(?:z[ií]ju\s+v|ziju\s+v|zjiu\s+v|v\s+obci|v\s+katastru\s+obce)\b[\s,:-]{0,12}((?:\p{L}[\p{L}'’-]{2,})(?:\s+\p{L}[\p{L}'’-]{2,}){0,2}\s+${ADDRESS_HOUSE_NUMBER_PATTERN})`,
1373
+ "giu"
1374
+ );
1375
+ var ADDRESS_STANDALONE_RE = new RegExp(
1376
+ String.raw`\b((?:(?:${ADDRESS_STREET_LABEL_PATTERN})\s+)?(?:\p{L}[\p{L}'’-]{2,}\s+){0,4}${ADDRESS_HOUSE_NUMBER_PATTERN}(?:,\s*|\s+)(?:${ADDRESS_POSTAL_CODE_PATTERN})(?:,\s*|\s+)(?:\p{L}[\p{L}'’-]{2,}(?:\s+\p{L}[\p{L}'’-]{2,}){0,2}))`,
1377
+ "gu"
1378
+ );
1300
1379
  function hasPhoneContext(text, matchStartIndex, windowSize = 50) {
1301
1380
  const start = Math.max(0, matchStartIndex - windowSize);
1302
1381
  const windowLower = text.slice(start, matchStartIndex).toLowerCase();
@@ -1348,6 +1427,26 @@ function isLikelyPersonNameCandidate(candidate, contextWindow) {
1348
1427
  }
1349
1428
  return true;
1350
1429
  }
1430
+ function isLikelyAddressCandidate(candidate) {
1431
+ if (!/\d/u.test(candidate)) {
1432
+ return false;
1433
+ }
1434
+ const normalized = normalizePersonWord(candidate);
1435
+ const words = candidate.trim().split(/\s+/).filter(Boolean);
1436
+ if (words.length < 2) {
1437
+ return false;
1438
+ }
1439
+ const numberIndex = words.findIndex((word) => /\d/u.test(word));
1440
+ if (numberIndex <= 0) {
1441
+ return false;
1442
+ }
1443
+ const letterWordRe = /^\p{L}[\p{L}'’-]*$/u;
1444
+ const beforeCount = words.slice(0, numberIndex).filter((word) => letterWordRe.test(word)).length;
1445
+ const afterCount = words.slice(numberIndex + 1).filter((word) => letterWordRe.test(word)).length;
1446
+ return /\b(?:ulici|ulice|ul\.|street|road|avenue|namesti|trida|alej|nabrezi)\b/iu.test(
1447
+ normalized
1448
+ ) || /\b\d{3}\s?\d{2}\b|\b\d{5}\b/u.test(candidate) || beforeCount >= 1 && afterCount >= 1;
1449
+ }
1351
1450
  var PIIManager = class {
1352
1451
  /**
1353
1452
  * Reversible local-first masking using <TYPE_INDEX> placeholders.
@@ -1428,13 +1527,55 @@ var PIIManager = class {
1428
1527
  });
1429
1528
  for (const match of nationalIdMatches) {
1430
1529
  if (match.start < 0 || match.end <= match.start) continue;
1530
+ const detectionType = match.type === "address_postal" ? "ADDRESS" : match.type === "birth_number" ? "BIRTH_NUMBER" : "NATIONAL_ID";
1431
1531
  detections.push({
1432
1532
  start: match.start,
1433
1533
  end: match.end,
1434
- type: "NATIONAL_ID",
1534
+ type: detectionType,
1435
1535
  text: text.slice(match.start, match.end)
1436
1536
  });
1437
1537
  }
1538
+ ADDRESS_WITH_ANCHOR_RE.lastIndex = 0;
1539
+ for (const match of text.matchAll(ADDRESS_WITH_ANCHOR_RE)) {
1540
+ if (match.index == null) continue;
1541
+ const value = match[1] ?? "";
1542
+ if (!value || !isLikelyAddressCandidate(value)) continue;
1543
+ const localIndex = match[0].lastIndexOf(value);
1544
+ const start = match.index + Math.max(0, localIndex);
1545
+ detections.push({
1546
+ start,
1547
+ end: start + value.length,
1548
+ type: "ADDRESS",
1549
+ text: value
1550
+ });
1551
+ }
1552
+ ADDRESS_CITY_NUMBER_WITH_ANCHOR_RE.lastIndex = 0;
1553
+ for (const match of text.matchAll(ADDRESS_CITY_NUMBER_WITH_ANCHOR_RE)) {
1554
+ if (match.index == null) continue;
1555
+ const value = match[1] ?? "";
1556
+ if (!value || !isLikelyAddressCandidate(value)) continue;
1557
+ const localIndex = match[0].lastIndexOf(value);
1558
+ const start = match.index + Math.max(0, localIndex);
1559
+ detections.push({
1560
+ start,
1561
+ end: start + value.length,
1562
+ type: "ADDRESS",
1563
+ text: value
1564
+ });
1565
+ }
1566
+ ADDRESS_STANDALONE_RE.lastIndex = 0;
1567
+ for (const match of text.matchAll(ADDRESS_STANDALONE_RE)) {
1568
+ if (match.index == null) continue;
1569
+ const value = match[1] ?? match[0];
1570
+ if (!value || !isLikelyAddressCandidate(value)) continue;
1571
+ const start = match.index;
1572
+ detections.push({
1573
+ start,
1574
+ end: start + value.length,
1575
+ type: "ADDRESS",
1576
+ text: value
1577
+ });
1578
+ }
1438
1579
  }
1439
1580
  if (resolvedOptions.secrets) {
1440
1581
  BASIC_AUTH_PASSWORD_RE.lastIndex = 0;
@@ -1484,13 +1625,17 @@ var PIIManager = class {
1484
1625
  }
1485
1626
  }
1486
1627
  }
1487
- const kept = normalizeDetections(text, detections);
1628
+ const kept = normalizeDetections(
1629
+ text,
1630
+ detections.map((detection) => normalizeDetection(detection))
1631
+ );
1488
1632
  if (!kept.length) return { maskedText: text, mapping: {} };
1489
1633
  const counters = {};
1490
1634
  const mapping = {};
1491
1635
  const replacements = kept.map((d) => {
1492
- counters[d.type] = (counters[d.type] ?? 0) + 1;
1493
- const placeholder = `<${d.type}_${counters[d.type]}>`;
1636
+ const placeholderType = toPlaceholderType(d.type);
1637
+ counters[placeholderType] = (counters[placeholderType] ?? 0) + 1;
1638
+ const placeholder = `<${placeholderType}_${counters[placeholderType]}>`;
1494
1639
  mapping[placeholder] = d.text;
1495
1640
  return { ...d, placeholder };
1496
1641
  });
@@ -1637,6 +1782,18 @@ var SecurityBlockError = class extends Error {
1637
1782
  // src/langchain.ts
1638
1783
  var piiManager = new PIIManager();
1639
1784
  var LANGCHAIN_TELEMETRY_FIELD = "agentid_telemetry";
1785
+ var MAX_PROMPT_CONTEXT_CHARS = 64e3;
1786
+ function getZeroRetentionInput(rawInput, candidateInput) {
1787
+ const raw = typeof rawInput === "string" ? rawInput : "";
1788
+ const candidate = typeof candidateInput === "string" ? candidateInput : "";
1789
+ if (candidate.length > 0 && candidate !== raw) {
1790
+ return candidate;
1791
+ }
1792
+ return "[REDACTED]";
1793
+ }
1794
+ function isFailOpenGuardBypassReason(reason) {
1795
+ return reason === "timeout_fallback" || reason === "guard_unreachable" || reason === "system_failure_fail_open";
1796
+ }
1640
1797
  function safeString(val) {
1641
1798
  return typeof val === "string" ? val : "";
1642
1799
  }
@@ -1807,9 +1964,6 @@ function setFiniteDurationMetadata(metadata, key, value) {
1807
1964
  metadata[key] = Math.max(0, Math.trunc(value));
1808
1965
  }
1809
1966
  }
1810
- function isGuardFailureEligibleForLocalFallback(reason) {
1811
- return reason === "network_error_strict_mode" || reason === "server_error" || reason === "system_failure" || reason === "system_failure_db_unavailable" || reason === "logging_failed" || reason === "guard_unreachable" || reason === "api_key_pepper_missing" || reason === "encryption_key_missing";
1812
- }
1813
1967
  function extractTextFromContent(content) {
1814
1968
  if (typeof content === "string") {
1815
1969
  return content;
@@ -1859,6 +2013,26 @@ function extractPromptFromPrompts(prompts) {
1859
2013
  }
1860
2014
  return "";
1861
2015
  }
2016
+ function truncatePromptContext(value) {
2017
+ if (value.length <= MAX_PROMPT_CONTEXT_CHARS) {
2018
+ return value;
2019
+ }
2020
+ const headChars = Math.floor((MAX_PROMPT_CONTEXT_CHARS - 32) / 2);
2021
+ const tailChars = MAX_PROMPT_CONTEXT_CHARS - headChars - 32;
2022
+ return `${value.slice(0, headChars)}
2023
+ [...TRUNCATED CONTEXT...]
2024
+ ${value.slice(-tailChars)}`;
2025
+ }
2026
+ function extractPromptContextFromPrompts(prompts) {
2027
+ if (!Array.isArray(prompts)) {
2028
+ return "";
2029
+ }
2030
+ const sections = prompts.map((prompt, index) => {
2031
+ const text = safeString(prompt);
2032
+ return text ? `[prompt_${index + 1}] ${text}` : null;
2033
+ }).filter((section) => section !== null);
2034
+ return sections.length > 0 ? truncatePromptContext(sections.join("\n\n")) : "";
2035
+ }
1862
2036
  function extractPromptFromMessages(messages) {
1863
2037
  const flat = [];
1864
2038
  if (Array.isArray(messages)) {
@@ -1884,6 +2058,28 @@ function extractPromptFromMessages(messages) {
1884
2058
  const typedLast = last;
1885
2059
  return extractTextFromContent(typedLast.content ?? typedLast.text);
1886
2060
  }
2061
+ function extractPromptContextFromMessages(messages) {
2062
+ const flat = [];
2063
+ if (Array.isArray(messages)) {
2064
+ for (const item of messages) {
2065
+ if (Array.isArray(item)) {
2066
+ flat.push(...item);
2067
+ } else {
2068
+ flat.push(item);
2069
+ }
2070
+ }
2071
+ }
2072
+ const sections = flat.map((message) => {
2073
+ const role = getMessageRole(message) ?? "message";
2074
+ const typed = message;
2075
+ const text = extractTextFromContent(typed?.content ?? typed?.text);
2076
+ return text ? `[${role}] ${text}` : null;
2077
+ }).filter((section) => section !== null);
2078
+ return sections.length > 0 ? truncatePromptContext(sections.join("\n\n")) : "";
2079
+ }
2080
+ function maskPromptContext(promptContext, options) {
2081
+ return promptContext;
2082
+ }
1887
2083
  function setPromptInPrompts(prompts, sanitizedInput) {
1888
2084
  if (!Array.isArray(prompts) || prompts.length === 0) {
1889
2085
  return false;
@@ -2013,6 +2209,12 @@ function deanonymizeText(text, mapping) {
2013
2209
  }
2014
2210
  return piiManager.deanonymize(text, mapping);
2015
2211
  }
2212
+ function textContainsMappingPlaceholder(text, mapping) {
2213
+ if (!text || !mapping) {
2214
+ return false;
2215
+ }
2216
+ return Object.keys(mapping).some((placeholder) => placeholder.length > 0 && text.includes(placeholder));
2217
+ }
2016
2218
  function deanonymizeContent(content, mapping) {
2017
2219
  if (!mapping) {
2018
2220
  return content;
@@ -2135,6 +2337,7 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2135
2337
  );
2136
2338
  this.apiKeyOverride = options.apiKey?.trim() || options.api_key?.trim() || void 0;
2137
2339
  this.telemetry = createAgentIdTelemetryContext(options.telemetry);
2340
+ this.deanonymizeOutputForClient = options.deanonymizeOutputForClient === true || options.deanonymize_output_for_client === true;
2138
2341
  }
2139
2342
  get requestOptions() {
2140
2343
  return this.apiKeyOverride ? { apiKey: this.apiKeyOverride } : void 0;
@@ -2168,9 +2371,10 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2168
2371
  }
2169
2372
  return false;
2170
2373
  }
2171
- async preflight(input, stream, clientEventId, telemetryMetadata) {
2374
+ async preflight(input, stream, clientEventId, telemetryMetadata, promptContext) {
2172
2375
  const prepared = await this.agent.prepareInputForDispatch({
2173
2376
  input,
2377
+ promptContext,
2174
2378
  systemId: this.systemId,
2175
2379
  stream,
2176
2380
  clientEventId,
@@ -2231,6 +2435,7 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2231
2435
  }
2232
2436
  async handleLLMStart(serialized, prompts, runId, _parentRunId, extraParams) {
2233
2437
  const input = extractPromptFromPrompts(prompts);
2438
+ const rawPromptContext = extractPromptContextFromPrompts(prompts);
2234
2439
  const id = String(runId ?? "");
2235
2440
  logCallbackDebug("handleLLMStart", { runId: id, hasInput: input.length > 0 });
2236
2441
  if (!input) {
@@ -2243,7 +2448,8 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2243
2448
  input,
2244
2449
  stream,
2245
2450
  requestedClientEventId,
2246
- telemetryMetadata
2451
+ telemetryMetadata,
2452
+ rawPromptContext
2247
2453
  );
2248
2454
  const sanitizedInput = prepared.sanitizedInput;
2249
2455
  const piiMaskingEnabled = this.resolvePreparedPiiMaskingEnabled(prepared);
@@ -2256,10 +2462,18 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2256
2462
  );
2257
2463
  }
2258
2464
  }
2465
+ const promptContextForGuard = maskPromptContext(
2466
+ extractPromptContextFromPrompts(prompts),
2467
+ {
2468
+ pii: piiMaskingEnabled,
2469
+ secrets: secretMaskingEnabled
2470
+ }
2471
+ );
2259
2472
  const modelName = extractModel(serialized, extraParams);
2260
2473
  const pipelineStartedAtMs = Date.now();
2261
2474
  const verdict = await this.agent.guard({
2262
2475
  input: sanitizedInput,
2476
+ prompt_context: promptContextForGuard || void 0,
2263
2477
  system_id: this.systemId,
2264
2478
  model: modelName,
2265
2479
  client_event_id: requestedClientEventId,
@@ -2271,28 +2485,30 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2271
2485
  )
2272
2486
  }, this.requestOptions);
2273
2487
  let transformedForRun = sanitizedInput;
2274
- let sdkLocalScanMs = prepared.sdkLocalScanMs;
2488
+ let sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
2489
+ let sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
2275
2490
  let localFallbackApplied = false;
2276
2491
  let localFallbackReason = null;
2277
2492
  if (!verdict.allowed) {
2278
- const fallbackEligible = isGuardFailureEligibleForLocalFallback(verdict.reason) && verdict.reason !== "guard_denied";
2279
- if (fallbackEligible) {
2280
- const fallback = await this.agent.applyLocalFallbackForGuardFailure({
2281
- input: sanitizedInput,
2493
+ throw new SecurityBlockError(verdict.reason ?? "guard_denied");
2494
+ }
2495
+ if (isFailOpenGuardBypassReason(verdict.reason)) {
2496
+ const fallback = await this.agent.runLocalPromptInjectionFallback(
2497
+ {
2498
+ input,
2499
+ promptContext: rawPromptContext,
2282
2500
  systemId: this.systemId,
2283
- stream,
2284
2501
  clientEventId: requestedClientEventId,
2285
2502
  capabilityConfig: prepared.capabilityConfig,
2286
- sdkConfigFetchMs: prepared.sdkConfigFetchMs,
2503
+ sdkConfigFetchMs,
2287
2504
  telemetryMetadata
2288
- }, this.requestOptions);
2289
- transformedForRun = fallback.sanitizedInput;
2290
- sdkLocalScanMs = fallback.sdkLocalScanMs;
2291
- localFallbackApplied = true;
2292
- localFallbackReason = verdict.reason ?? "guard_unreachable";
2293
- } else {
2294
- throw new SecurityBlockError(verdict.reason ?? "guard_denied");
2295
- }
2505
+ },
2506
+ this.requestOptions
2507
+ );
2508
+ sdkConfigFetchMs = fallback.sdkConfigFetchMs;
2509
+ sdkLocalScanMs += fallback.sdkLocalScanMs;
2510
+ localFallbackApplied = true;
2511
+ localFallbackReason = verdict.reason ?? null;
2296
2512
  }
2297
2513
  if (transformedForRun !== sanitizedInput) {
2298
2514
  const mutated = setPromptInPrompts(prompts, transformedForRun);
@@ -2311,12 +2527,13 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2311
2527
  transformedInput = transformedForRun;
2312
2528
  }
2313
2529
  }
2530
+ const retainedInput = getZeroRetentionInput(input, transformedInput);
2314
2531
  this.runs.set(id, {
2315
- input: transformedInput,
2532
+ input: retainedInput,
2316
2533
  startedAtMs: Date.now(),
2317
2534
  pipelineStartedAtMs,
2318
2535
  guardLatencyMs,
2319
- sdkConfigFetchMs: prepared.sdkConfigFetchMs,
2536
+ sdkConfigFetchMs,
2320
2537
  sdkLocalScanMs,
2321
2538
  localFallbackApplied,
2322
2539
  localFallbackReason,
@@ -2326,7 +2543,7 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2326
2543
  telemetryMetadata,
2327
2544
  transparency,
2328
2545
  piiMapping: normalizePiiMapping(prepared.piiMapping),
2329
- shouldDeanonymize: prepared.shouldDeanonymize === true,
2546
+ shouldDeanonymize: this.deanonymizeOutputForClient && prepared.shouldDeanonymize === true,
2330
2547
  responseStreamed: stream,
2331
2548
  sdkConfigVersion: prepared.capabilityConfig?.version ?? null,
2332
2549
  piiMaskingEnabled,
@@ -2340,6 +2557,7 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2340
2557
  }
2341
2558
  async handleChatModelStart(serialized, messages, runId, _parentRunId, extraParams) {
2342
2559
  const input = extractPromptFromMessages(messages);
2560
+ const rawPromptContext = extractPromptContextFromMessages(messages);
2343
2561
  const id = String(runId ?? "");
2344
2562
  logCallbackDebug("handleChatModelStart", { runId: id, hasInput: input.length > 0 });
2345
2563
  if (!input) {
@@ -2352,7 +2570,8 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2352
2570
  input,
2353
2571
  stream,
2354
2572
  requestedClientEventId,
2355
- telemetryMetadata
2573
+ telemetryMetadata,
2574
+ rawPromptContext
2356
2575
  );
2357
2576
  const sanitizedInput = prepared.sanitizedInput;
2358
2577
  const piiMaskingEnabled = this.resolvePreparedPiiMaskingEnabled(prepared);
@@ -2365,10 +2584,18 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2365
2584
  );
2366
2585
  }
2367
2586
  }
2587
+ const promptContextForGuard = maskPromptContext(
2588
+ extractPromptContextFromMessages(messages),
2589
+ {
2590
+ pii: piiMaskingEnabled,
2591
+ secrets: secretMaskingEnabled
2592
+ }
2593
+ );
2368
2594
  const modelName = extractModel(serialized, extraParams);
2369
2595
  const pipelineStartedAtMs = Date.now();
2370
2596
  const verdict = await this.agent.guard({
2371
2597
  input: sanitizedInput,
2598
+ prompt_context: promptContextForGuard || void 0,
2372
2599
  system_id: this.systemId,
2373
2600
  model: modelName,
2374
2601
  client_event_id: requestedClientEventId,
@@ -2380,28 +2607,30 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2380
2607
  )
2381
2608
  }, this.requestOptions);
2382
2609
  let transformedForRun = sanitizedInput;
2383
- let sdkLocalScanMs = prepared.sdkLocalScanMs;
2610
+ let sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
2611
+ let sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
2384
2612
  let localFallbackApplied = false;
2385
2613
  let localFallbackReason = null;
2386
2614
  if (!verdict.allowed) {
2387
- const fallbackEligible = isGuardFailureEligibleForLocalFallback(verdict.reason) && verdict.reason !== "guard_denied";
2388
- if (fallbackEligible) {
2389
- const fallback = await this.agent.applyLocalFallbackForGuardFailure({
2390
- input: sanitizedInput,
2615
+ throw new SecurityBlockError(verdict.reason ?? "guard_denied");
2616
+ }
2617
+ if (isFailOpenGuardBypassReason(verdict.reason)) {
2618
+ const fallback = await this.agent.runLocalPromptInjectionFallback(
2619
+ {
2620
+ input,
2621
+ promptContext: rawPromptContext,
2391
2622
  systemId: this.systemId,
2392
- stream,
2393
2623
  clientEventId: requestedClientEventId,
2394
2624
  capabilityConfig: prepared.capabilityConfig,
2395
- sdkConfigFetchMs: prepared.sdkConfigFetchMs,
2625
+ sdkConfigFetchMs,
2396
2626
  telemetryMetadata
2397
- }, this.requestOptions);
2398
- transformedForRun = fallback.sanitizedInput;
2399
- sdkLocalScanMs = fallback.sdkLocalScanMs;
2400
- localFallbackApplied = true;
2401
- localFallbackReason = verdict.reason ?? "guard_unreachable";
2402
- } else {
2403
- throw new SecurityBlockError(verdict.reason ?? "guard_denied");
2404
- }
2627
+ },
2628
+ this.requestOptions
2629
+ );
2630
+ sdkConfigFetchMs = fallback.sdkConfigFetchMs;
2631
+ sdkLocalScanMs += fallback.sdkLocalScanMs;
2632
+ localFallbackApplied = true;
2633
+ localFallbackReason = verdict.reason ?? null;
2405
2634
  }
2406
2635
  if (transformedForRun !== sanitizedInput) {
2407
2636
  const mutated = setPromptInMessages(messages, transformedForRun);
@@ -2420,12 +2649,13 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2420
2649
  transformedInput = transformedForRun;
2421
2650
  }
2422
2651
  }
2652
+ const retainedInput = getZeroRetentionInput(input, transformedInput);
2423
2653
  this.runs.set(id, {
2424
- input: transformedInput,
2654
+ input: retainedInput,
2425
2655
  startedAtMs: Date.now(),
2426
2656
  pipelineStartedAtMs,
2427
2657
  guardLatencyMs,
2428
- sdkConfigFetchMs: prepared.sdkConfigFetchMs,
2658
+ sdkConfigFetchMs,
2429
2659
  sdkLocalScanMs,
2430
2660
  localFallbackApplied,
2431
2661
  localFallbackReason,
@@ -2435,7 +2665,7 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2435
2665
  telemetryMetadata,
2436
2666
  transparency,
2437
2667
  piiMapping: normalizePiiMapping(prepared.piiMapping),
2438
- shouldDeanonymize: prepared.shouldDeanonymize === true,
2668
+ shouldDeanonymize: this.deanonymizeOutputForClient && prepared.shouldDeanonymize === true,
2439
2669
  responseStreamed: stream,
2440
2670
  sdkConfigVersion: prepared.capabilityConfig?.version ?? null,
2441
2671
  piiMaskingEnabled,
@@ -2492,7 +2722,7 @@ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2492
2722
  }
2493
2723
  metadata.response_streamed = state.responseStreamed === true;
2494
2724
  metadata.transformed_output = maskedOutputText;
2495
- metadata.output_masked = maskedOutputText !== clientOutputText;
2725
+ metadata.output_masked = maskedOutputText !== clientOutputText || textContainsMappingPlaceholder(maskedOutputText, state.piiMapping);
2496
2726
  metadata.model_latency_ms = modelLatencyMs;
2497
2727
  metadata.total_pipeline_latency_ms = totalPipelineLatencyMs;
2498
2728
  const resolvedModel = state.model ?? extractModelFromOutput(output) ?? "unknown";