agentid-sdk 0.1.22 → 0.1.23
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 +50 -0
- package/dist/{chunk-FVTL572H.mjs → chunk-4FSEYTEC.mjs} +123 -9
- package/dist/index.js +123 -9
- package/dist/index.mjs +1 -1
- package/dist/langchain.js +1 -1
- package/dist/langchain.mjs +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -205,6 +205,56 @@ By default, AgentID is designed to keep your application running if the AgentID
|
|
|
205
205
|
- Local prompt-injection heuristics are enabled only when dashboard policy enables injection blocking (`block_on_heuristic` / legacy injection flags). `strictMode` does not force local heuristic blocking.
|
|
206
206
|
- Ingest retries transient failures (5xx/429) and logs warnings if persistence fails.
|
|
207
207
|
|
|
208
|
+
### Event Identity Model
|
|
209
|
+
|
|
210
|
+
For consistent lifecycle correlation in Activity/Prompts, use this model:
|
|
211
|
+
|
|
212
|
+
- `client_event_id`: external correlation ID for one end-to-end action.
|
|
213
|
+
- `guard_event_id`: ID of the preflight guard event returned by `guard()`.
|
|
214
|
+
- `event_id` on `log()`: idempotency key for ingest. In the JS SDK it is canonicalized to `client_event_id` for stable one-row lifecycle updates.
|
|
215
|
+
|
|
216
|
+
SDK behavior:
|
|
217
|
+
|
|
218
|
+
- `guard()` sends `client_event_id` and returns canonical `client_event_id` + `guard_event_id`.
|
|
219
|
+
- `log()` sends:
|
|
220
|
+
- `event_id = canonical client_event_id`
|
|
221
|
+
- `metadata.client_event_id`
|
|
222
|
+
- `metadata.guard_event_id` (when available from wrappers/callbacks)
|
|
223
|
+
- `x-correlation-id = client_event_id`
|
|
224
|
+
- SDK requests include `x-agentid-sdk-version` for telemetry/version diagnostics.
|
|
225
|
+
|
|
226
|
+
This keeps Guard + Complete linked under one correlation key while preserving internal event linkage in the dashboard.
|
|
227
|
+
|
|
228
|
+
### Policy-Pack Runtime Telemetry
|
|
229
|
+
|
|
230
|
+
When the backend uses compiled policy packs, runtime metadata includes:
|
|
231
|
+
|
|
232
|
+
- `policy_pack_version`: active compiled artifact version.
|
|
233
|
+
- `policy_pack_fallback`: `true` means fallback detector path was used.
|
|
234
|
+
- `policy_pack_details`: optional diagnostic detail for fallback/decision trace.
|
|
235
|
+
|
|
236
|
+
Latency interpretation:
|
|
237
|
+
|
|
238
|
+
- Activity `Latency (ms)` maps to synchronous processing (`processing_time_ms`).
|
|
239
|
+
- Async AI audit time is separate (`ai_audit_duration_ms`) and can be higher.
|
|
240
|
+
- First request after warm-up boundaries can be slower than steady-state requests.
|
|
241
|
+
|
|
242
|
+
### Monorepo QA Commands (Maintainers)
|
|
243
|
+
|
|
244
|
+
If you are validating runtime in the AgentID monorepo:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
npm run qa:policy-pack-bootstrap -- --base-url=http://127.0.0.1:3000/api/v1 --system-id=<SYSTEM_UUID>
|
|
248
|
+
npm run bench:policy-pack-hotpath
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
PowerShell diagnostics:
|
|
252
|
+
|
|
253
|
+
```powershell
|
|
254
|
+
powershell -ExecutionPolicy Bypass -File .\scripts\qa\run-guard-diagnostic.ps1 -BaseUrl http://127.0.0.1:3000/api/v1 -ApiKey $env:AGENTID_API_KEY -SystemId $env:AGENTID_SYSTEM_ID -SkipBenchmark
|
|
255
|
+
powershell -ExecutionPolicy Bypass -File .\scripts\qa\run-ai-label-audit-check.ps1 -BaseUrl http://127.0.0.1:3000/api/v1 -ApiKey $env:AGENTID_API_KEY -SystemId $env:AGENTID_SYSTEM_ID -Model gpt-4o-mini
|
|
256
|
+
```
|
|
257
|
+
|
|
208
258
|
## 7. Security & Compliance
|
|
209
259
|
|
|
210
260
|
- Optional local PII masking and local policy enforcement before model dispatch.
|
|
@@ -970,11 +970,87 @@ var PHONE_CONTEXT_RE = new RegExp(
|
|
|
970
970
|
`(?:^|[^\\p{L}])(?:${PHONE_CONTEXT_KEYWORDS.map(escapeRegex).join("|")})(?:$|[^\\p{L}])`,
|
|
971
971
|
"iu"
|
|
972
972
|
);
|
|
973
|
+
var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
|
|
974
|
+
"write",
|
|
975
|
+
"code",
|
|
976
|
+
"script",
|
|
977
|
+
"query",
|
|
978
|
+
"curl",
|
|
979
|
+
"http",
|
|
980
|
+
"https",
|
|
981
|
+
"import",
|
|
982
|
+
"python",
|
|
983
|
+
"javascript",
|
|
984
|
+
"typescript",
|
|
985
|
+
"node",
|
|
986
|
+
"bash",
|
|
987
|
+
"powershell",
|
|
988
|
+
"shell",
|
|
989
|
+
"command",
|
|
990
|
+
"example",
|
|
991
|
+
"demo",
|
|
992
|
+
"developer",
|
|
993
|
+
"mode",
|
|
994
|
+
"system",
|
|
995
|
+
"prompt",
|
|
996
|
+
"policy",
|
|
997
|
+
"security",
|
|
998
|
+
"instructions",
|
|
999
|
+
"instruction",
|
|
1000
|
+
"rules",
|
|
1001
|
+
"rule",
|
|
1002
|
+
"json",
|
|
1003
|
+
"output",
|
|
1004
|
+
"input",
|
|
1005
|
+
"database",
|
|
1006
|
+
"sql",
|
|
1007
|
+
"mongo",
|
|
1008
|
+
"openai",
|
|
1009
|
+
"agentid",
|
|
1010
|
+
"risk",
|
|
1011
|
+
"score",
|
|
1012
|
+
"summary"
|
|
1013
|
+
]);
|
|
1014
|
+
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
|
+
var TECHNICAL_CONTEXT_SYMBOL_REGEX = /:\/\/|`|\{|\}|\[|\]|\(|\)|;|\$|=>|::|\/\//;
|
|
973
1016
|
function hasPhoneContext(text, matchStartIndex, windowSize = 50) {
|
|
974
1017
|
const start = Math.max(0, matchStartIndex - windowSize);
|
|
975
1018
|
const windowLower = text.slice(start, matchStartIndex).toLowerCase();
|
|
976
1019
|
return PHONE_CONTEXT_RE.test(windowLower);
|
|
977
1020
|
}
|
|
1021
|
+
function normalizePersonWord(value) {
|
|
1022
|
+
return value.normalize("NFD").replace(/\p{M}+/gu, "").toLowerCase();
|
|
1023
|
+
}
|
|
1024
|
+
function buildContextWindow(source, index, length) {
|
|
1025
|
+
const start = Math.max(0, index - 28);
|
|
1026
|
+
const end = Math.min(source.length, index + length + 28);
|
|
1027
|
+
return source.slice(start, end);
|
|
1028
|
+
}
|
|
1029
|
+
function isTechnicalContext(contextWindow) {
|
|
1030
|
+
return TECHNICAL_CONTEXT_WORD_REGEX.test(contextWindow) || TECHNICAL_CONTEXT_SYMBOL_REGEX.test(contextWindow);
|
|
1031
|
+
}
|
|
1032
|
+
function isLikelyPersonNameCandidate(candidate, contextWindow) {
|
|
1033
|
+
const words = candidate.trim().split(/\s+/);
|
|
1034
|
+
if (words.length !== 2) {
|
|
1035
|
+
return false;
|
|
1036
|
+
}
|
|
1037
|
+
if (isTechnicalContext(contextWindow)) {
|
|
1038
|
+
return false;
|
|
1039
|
+
}
|
|
1040
|
+
for (const rawWord of words) {
|
|
1041
|
+
const normalized = normalizePersonWord(rawWord);
|
|
1042
|
+
if (normalized.length < 2) {
|
|
1043
|
+
return false;
|
|
1044
|
+
}
|
|
1045
|
+
if (PERSON_NAME_STOPWORDS.has(normalized)) {
|
|
1046
|
+
return false;
|
|
1047
|
+
}
|
|
1048
|
+
if (!/^\p{L}[\p{L}'-]+$/u.test(rawWord)) {
|
|
1049
|
+
return false;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
return true;
|
|
1053
|
+
}
|
|
978
1054
|
var PIIManager = class {
|
|
979
1055
|
/**
|
|
980
1056
|
* Reversible local-first masking using <TYPE_INDEX> placeholders.
|
|
@@ -1019,7 +1095,12 @@ var PIIManager = class {
|
|
|
1019
1095
|
const personRe = /(?<!\p{L})\p{Lu}\p{Ll}{2,}\s+\p{Lu}\p{Ll}{2,}(?!\p{L})/gu;
|
|
1020
1096
|
for (const m of text.matchAll(personRe)) {
|
|
1021
1097
|
if (m.index == null) continue;
|
|
1022
|
-
|
|
1098
|
+
const candidate = m[0];
|
|
1099
|
+
const contextWindow = buildContextWindow(text, m.index, candidate.length);
|
|
1100
|
+
if (!isLikelyPersonNameCandidate(candidate, contextWindow)) {
|
|
1101
|
+
continue;
|
|
1102
|
+
}
|
|
1103
|
+
detections.push({ start: m.index, end: m.index + candidate.length, type: "PERSON", text: candidate });
|
|
1023
1104
|
}
|
|
1024
1105
|
const nationalIdMatches = detectNationalIdentifiers(text, {
|
|
1025
1106
|
deadlineMs: defaultScanDeadlineMs,
|
|
@@ -1090,15 +1171,15 @@ var DE_STOPWORDS = /* @__PURE__ */ new Set(["bitte", "anweisung", "system", "reg
|
|
|
1090
1171
|
var HEURISTIC_RULES = [
|
|
1091
1172
|
{
|
|
1092
1173
|
name: "heuristic_combo_ignore_instructions",
|
|
1093
|
-
re: /\b(ignore|disregard|forget|override|bypass|disable|jailbreak|dan|ignoruj|zapomen|obejdi|prepis)\b[\s\S]{0,
|
|
1174
|
+
re: /\b(ignore|disregard|forget|override|bypass|disable|jailbreak|dan|ignoruj|zapomen|obejdi|prepis)\b[\s\S]{0,160}\b(instruction(?:s)?|previous|system|developer|policy|rules?|guardrails|safety|instrukce|pokyny|pravidla|systemove?|bezpecnost(?:ni)?|politika)\b/i
|
|
1094
1175
|
},
|
|
1095
1176
|
{
|
|
1096
1177
|
name: "heuristic_combo_instruction_override_reverse",
|
|
1097
|
-
re: /\b(instruction(?:s)?|previous|system|developer|policy|rules
|
|
1178
|
+
re: /\b(instruction(?:s)?|previous|system|developer|policy|rules?|guardrails|safety|instrukce|pokyny|pravidla|systemove?|bezpecnost(?:ni)?|politika)\b[\s\S]{0,160}\b(ignore|disregard|forget|override|bypass|disable|jailbreak|dan|ignoruj|zapomen|obejdi|prepis)\b/i
|
|
1098
1179
|
},
|
|
1099
1180
|
{
|
|
1100
1181
|
name: "heuristic_combo_exfil_system_prompt",
|
|
1101
|
-
re: /\b(show|reveal|print|dump|leak|display|expose|tell|extract|ukaz|zobraz|vypis|odhal|prozrad)\b[\s\S]{0,
|
|
1182
|
+
re: /\b(show|reveal|print|dump|leak|display|expose|tell|extract|ukaz|zobraz|vypis|odhal|prozrad)\b[\s\S]{0,180}\b(system prompt|system instruction(?:s)?|developer message|hidden prompt|internal instruction(?:s)?|policy|guardrails|interni instrukce|systemove nastaveni)\b/i
|
|
1102
1183
|
},
|
|
1103
1184
|
{
|
|
1104
1185
|
name: "heuristic_role_prefix_system_developer",
|
|
@@ -1107,6 +1188,14 @@ var HEURISTIC_RULES = [
|
|
|
1107
1188
|
{
|
|
1108
1189
|
name: "heuristic_delimiter_system_prompt",
|
|
1109
1190
|
re: /\b(begin|start)\s+(system|developer)\s+prompt\b|\bend\s+(system|developer)\s+prompt\b/i
|
|
1191
|
+
},
|
|
1192
|
+
{
|
|
1193
|
+
name: "heuristic_developer_mode_override",
|
|
1194
|
+
re: /\b(developer\s*mode|dev\s*mode)\b[\s\S]{0,200}\b(ignore|bypass|disable|override|ignoruj|obejdi|zapomen)\b/i
|
|
1195
|
+
},
|
|
1196
|
+
{
|
|
1197
|
+
name: "heuristic_czech_injection_phrase",
|
|
1198
|
+
re: /\b(zapomen|ignoruj)\b[\s\S]{0,220}\b(predchozi\s+instrukce|bezpecnostni\s+pravidla|systemove\s+nastaveni)\b/i
|
|
1110
1199
|
}
|
|
1111
1200
|
];
|
|
1112
1201
|
var scannerSingleton = null;
|
|
@@ -1157,6 +1246,9 @@ ${input.slice(-WINDOW_SLICE_SIZE)}`;
|
|
|
1157
1246
|
[...]
|
|
1158
1247
|
${input.slice(tailStart)}`;
|
|
1159
1248
|
}
|
|
1249
|
+
function normalizeForHeuristics(input) {
|
|
1250
|
+
return input.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\s+/g, " ").trim();
|
|
1251
|
+
}
|
|
1160
1252
|
function scoreStopwords(tokens, stopwords) {
|
|
1161
1253
|
let score = 0;
|
|
1162
1254
|
for (const token of tokens) {
|
|
@@ -1199,9 +1291,10 @@ function findRegexMatch(prompt) {
|
|
|
1199
1291
|
if (!prompt) {
|
|
1200
1292
|
return null;
|
|
1201
1293
|
}
|
|
1294
|
+
const normalizedPrompt = normalizeForHeuristics(prompt);
|
|
1202
1295
|
for (const rule of HEURISTIC_RULES) {
|
|
1203
1296
|
try {
|
|
1204
|
-
const match = rule.re.exec(
|
|
1297
|
+
const match = rule.re.exec(normalizedPrompt);
|
|
1205
1298
|
if (match && typeof match[0] === "string" && match[0].trim()) {
|
|
1206
1299
|
return {
|
|
1207
1300
|
rule: rule.name,
|
|
@@ -1462,7 +1555,7 @@ function getInjectionScanner() {
|
|
|
1462
1555
|
|
|
1463
1556
|
// src/sdk-version.ts
|
|
1464
1557
|
var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
|
|
1465
|
-
var AGENTID_SDK_VERSION_HEADER = "js-0.1.
|
|
1558
|
+
var AGENTID_SDK_VERSION_HEADER = "js-0.1.23".trim().length > 0 ? "js-0.1.23" : FALLBACK_SDK_VERSION;
|
|
1466
1559
|
|
|
1467
1560
|
// src/local-security-enforcer.ts
|
|
1468
1561
|
var DEFAULT_FAIL_OPEN_CONFIG = {
|
|
@@ -1476,6 +1569,14 @@ var DEFAULT_FAIL_OPEN_CONFIG = {
|
|
|
1476
1569
|
block_toxicity: false
|
|
1477
1570
|
};
|
|
1478
1571
|
var SQL_DATABASE_ACCESS_PATTERN = /\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER)\b[\s\S]+?\b(FROM|INTO|TABLE|DATABASE|VIEW|INDEX)\b/i;
|
|
1572
|
+
var NOSQL_DATABASE_ACCESS_PATTERNS = [
|
|
1573
|
+
/\bdb\.[A-Za-z_][A-Za-z0-9_]*\.(find|findOne|aggregate|updateOne|updateMany|deleteOne|deleteMany|insertOne|insertMany)\s*\(/i,
|
|
1574
|
+
/\b(collection|mongodb)\.(find|findOne|aggregate|updateOne|updateMany|deleteOne|deleteMany|insertOne|insertMany)\s*\(/i,
|
|
1575
|
+
/\b\$where\b/i,
|
|
1576
|
+
/\b\$expr\b/i,
|
|
1577
|
+
/\b\$regex\b/i,
|
|
1578
|
+
/\bMongoClient\.connect\s*\(/i
|
|
1579
|
+
];
|
|
1479
1580
|
var PYTHON_GENERAL_RCE_PATTERN = /(import\s+(os|sys|subprocess)|from\s+(os|sys|subprocess)\s+import|exec\s*\(|eval\s*\(|__import__)/i;
|
|
1480
1581
|
var SHELL_BASH_RCE_PATTERN = /(wget\s+|curl\s+|rm\s+-rf|chmod\s+\+x|cat\s+\/etc\/passwd|\/bin\/sh|\/bin\/bash)/i;
|
|
1481
1582
|
var JAVASCRIPT_RCE_PATTERN = /(new\s+Function\(|process\.env|child_process)/i;
|
|
@@ -1489,8 +1590,15 @@ var SecurityPolicyViolationError = class extends Error {
|
|
|
1489
1590
|
}
|
|
1490
1591
|
};
|
|
1491
1592
|
function detectCapabilityViolation(text, config) {
|
|
1492
|
-
if (config.block_db_access
|
|
1493
|
-
|
|
1593
|
+
if (config.block_db_access) {
|
|
1594
|
+
if (SQL_DATABASE_ACCESS_PATTERN.test(text)) {
|
|
1595
|
+
return "SQL_INJECTION_ATTEMPT";
|
|
1596
|
+
}
|
|
1597
|
+
for (const pattern of NOSQL_DATABASE_ACCESS_PATTERNS) {
|
|
1598
|
+
if (pattern.test(text)) {
|
|
1599
|
+
return "SQL_INJECTION_ATTEMPT";
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1494
1602
|
}
|
|
1495
1603
|
if (config.block_code_execution && (PYTHON_GENERAL_RCE_PATTERN.test(text) || SHELL_BASH_RCE_PATTERN.test(text) || JAVASCRIPT_RCE_PATTERN.test(text))) {
|
|
1496
1604
|
return "RCE_ATTEMPT";
|
|
@@ -2415,13 +2523,18 @@ var AgentID = class {
|
|
|
2415
2523
|
const metadata = {
|
|
2416
2524
|
...params.metadata ?? {}
|
|
2417
2525
|
};
|
|
2526
|
+
const metadataClientEventId = typeof metadata.client_event_id === "string" && isUuidLike(metadata.client_event_id) ? metadata.client_event_id : null;
|
|
2527
|
+
const canonicalClientEventId = metadataClientEventId ?? eventId;
|
|
2528
|
+
if (!metadataClientEventId) {
|
|
2529
|
+
metadata.client_event_id = canonicalClientEventId;
|
|
2530
|
+
}
|
|
2418
2531
|
if (!Object.prototype.hasOwnProperty.call(metadata, "agentid_base_url")) {
|
|
2419
2532
|
metadata.agentid_base_url = this.baseUrl;
|
|
2420
2533
|
}
|
|
2421
2534
|
void this.getCapabilityConfig(false, { apiKey: effectiveApiKey }).catch(() => void 0);
|
|
2422
2535
|
const payload = {
|
|
2423
2536
|
...params,
|
|
2424
|
-
event_id:
|
|
2537
|
+
event_id: canonicalClientEventId,
|
|
2425
2538
|
timestamp,
|
|
2426
2539
|
input: sanitizeIngestText(params.input),
|
|
2427
2540
|
output: sanitizeIngestText(params.output),
|
|
@@ -2438,6 +2551,7 @@ var AgentID = class {
|
|
|
2438
2551
|
headers: {
|
|
2439
2552
|
"Content-Type": "application/json",
|
|
2440
2553
|
"x-agentid-api-key": effectiveApiKey,
|
|
2554
|
+
"x-correlation-id": canonicalClientEventId,
|
|
2441
2555
|
"X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER
|
|
2442
2556
|
},
|
|
2443
2557
|
body: JSON.stringify(payload),
|
package/dist/index.js
CHANGED
|
@@ -84,7 +84,7 @@ var OpenAIAdapter = class {
|
|
|
84
84
|
|
|
85
85
|
// src/sdk-version.ts
|
|
86
86
|
var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
|
|
87
|
-
var AGENTID_SDK_VERSION_HEADER = "js-0.1.
|
|
87
|
+
var AGENTID_SDK_VERSION_HEADER = "js-0.1.23".trim().length > 0 ? "js-0.1.23" : FALLBACK_SDK_VERSION;
|
|
88
88
|
|
|
89
89
|
// src/pii-national-identifiers.ts
|
|
90
90
|
var MAX_CANDIDATES_PER_RULE = 256;
|
|
@@ -1016,11 +1016,87 @@ var PHONE_CONTEXT_RE = new RegExp(
|
|
|
1016
1016
|
`(?:^|[^\\p{L}])(?:${PHONE_CONTEXT_KEYWORDS.map(escapeRegex).join("|")})(?:$|[^\\p{L}])`,
|
|
1017
1017
|
"iu"
|
|
1018
1018
|
);
|
|
1019
|
+
var PERSON_NAME_STOPWORDS = /* @__PURE__ */ new Set([
|
|
1020
|
+
"write",
|
|
1021
|
+
"code",
|
|
1022
|
+
"script",
|
|
1023
|
+
"query",
|
|
1024
|
+
"curl",
|
|
1025
|
+
"http",
|
|
1026
|
+
"https",
|
|
1027
|
+
"import",
|
|
1028
|
+
"python",
|
|
1029
|
+
"javascript",
|
|
1030
|
+
"typescript",
|
|
1031
|
+
"node",
|
|
1032
|
+
"bash",
|
|
1033
|
+
"powershell",
|
|
1034
|
+
"shell",
|
|
1035
|
+
"command",
|
|
1036
|
+
"example",
|
|
1037
|
+
"demo",
|
|
1038
|
+
"developer",
|
|
1039
|
+
"mode",
|
|
1040
|
+
"system",
|
|
1041
|
+
"prompt",
|
|
1042
|
+
"policy",
|
|
1043
|
+
"security",
|
|
1044
|
+
"instructions",
|
|
1045
|
+
"instruction",
|
|
1046
|
+
"rules",
|
|
1047
|
+
"rule",
|
|
1048
|
+
"json",
|
|
1049
|
+
"output",
|
|
1050
|
+
"input",
|
|
1051
|
+
"database",
|
|
1052
|
+
"sql",
|
|
1053
|
+
"mongo",
|
|
1054
|
+
"openai",
|
|
1055
|
+
"agentid",
|
|
1056
|
+
"risk",
|
|
1057
|
+
"score",
|
|
1058
|
+
"summary"
|
|
1059
|
+
]);
|
|
1060
|
+
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;
|
|
1061
|
+
var TECHNICAL_CONTEXT_SYMBOL_REGEX = /:\/\/|`|\{|\}|\[|\]|\(|\)|;|\$|=>|::|\/\//;
|
|
1019
1062
|
function hasPhoneContext(text, matchStartIndex, windowSize = 50) {
|
|
1020
1063
|
const start = Math.max(0, matchStartIndex - windowSize);
|
|
1021
1064
|
const windowLower = text.slice(start, matchStartIndex).toLowerCase();
|
|
1022
1065
|
return PHONE_CONTEXT_RE.test(windowLower);
|
|
1023
1066
|
}
|
|
1067
|
+
function normalizePersonWord(value) {
|
|
1068
|
+
return value.normalize("NFD").replace(/\p{M}+/gu, "").toLowerCase();
|
|
1069
|
+
}
|
|
1070
|
+
function buildContextWindow(source, index, length) {
|
|
1071
|
+
const start = Math.max(0, index - 28);
|
|
1072
|
+
const end = Math.min(source.length, index + length + 28);
|
|
1073
|
+
return source.slice(start, end);
|
|
1074
|
+
}
|
|
1075
|
+
function isTechnicalContext(contextWindow) {
|
|
1076
|
+
return TECHNICAL_CONTEXT_WORD_REGEX.test(contextWindow) || TECHNICAL_CONTEXT_SYMBOL_REGEX.test(contextWindow);
|
|
1077
|
+
}
|
|
1078
|
+
function isLikelyPersonNameCandidate(candidate, contextWindow) {
|
|
1079
|
+
const words = candidate.trim().split(/\s+/);
|
|
1080
|
+
if (words.length !== 2) {
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
if (isTechnicalContext(contextWindow)) {
|
|
1084
|
+
return false;
|
|
1085
|
+
}
|
|
1086
|
+
for (const rawWord of words) {
|
|
1087
|
+
const normalized = normalizePersonWord(rawWord);
|
|
1088
|
+
if (normalized.length < 2) {
|
|
1089
|
+
return false;
|
|
1090
|
+
}
|
|
1091
|
+
if (PERSON_NAME_STOPWORDS.has(normalized)) {
|
|
1092
|
+
return false;
|
|
1093
|
+
}
|
|
1094
|
+
if (!/^\p{L}[\p{L}'-]+$/u.test(rawWord)) {
|
|
1095
|
+
return false;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
return true;
|
|
1099
|
+
}
|
|
1024
1100
|
var PIIManager = class {
|
|
1025
1101
|
/**
|
|
1026
1102
|
* Reversible local-first masking using <TYPE_INDEX> placeholders.
|
|
@@ -1065,7 +1141,12 @@ var PIIManager = class {
|
|
|
1065
1141
|
const personRe = /(?<!\p{L})\p{Lu}\p{Ll}{2,}\s+\p{Lu}\p{Ll}{2,}(?!\p{L})/gu;
|
|
1066
1142
|
for (const m of text.matchAll(personRe)) {
|
|
1067
1143
|
if (m.index == null) continue;
|
|
1068
|
-
|
|
1144
|
+
const candidate = m[0];
|
|
1145
|
+
const contextWindow = buildContextWindow(text, m.index, candidate.length);
|
|
1146
|
+
if (!isLikelyPersonNameCandidate(candidate, contextWindow)) {
|
|
1147
|
+
continue;
|
|
1148
|
+
}
|
|
1149
|
+
detections.push({ start: m.index, end: m.index + candidate.length, type: "PERSON", text: candidate });
|
|
1069
1150
|
}
|
|
1070
1151
|
const nationalIdMatches = detectNationalIdentifiers(text, {
|
|
1071
1152
|
deadlineMs: defaultScanDeadlineMs,
|
|
@@ -1126,6 +1207,14 @@ var DEFAULT_FAIL_OPEN_CONFIG = {
|
|
|
1126
1207
|
block_toxicity: false
|
|
1127
1208
|
};
|
|
1128
1209
|
var SQL_DATABASE_ACCESS_PATTERN = /\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER)\b[\s\S]+?\b(FROM|INTO|TABLE|DATABASE|VIEW|INDEX)\b/i;
|
|
1210
|
+
var NOSQL_DATABASE_ACCESS_PATTERNS = [
|
|
1211
|
+
/\bdb\.[A-Za-z_][A-Za-z0-9_]*\.(find|findOne|aggregate|updateOne|updateMany|deleteOne|deleteMany|insertOne|insertMany)\s*\(/i,
|
|
1212
|
+
/\b(collection|mongodb)\.(find|findOne|aggregate|updateOne|updateMany|deleteOne|deleteMany|insertOne|insertMany)\s*\(/i,
|
|
1213
|
+
/\b\$where\b/i,
|
|
1214
|
+
/\b\$expr\b/i,
|
|
1215
|
+
/\b\$regex\b/i,
|
|
1216
|
+
/\bMongoClient\.connect\s*\(/i
|
|
1217
|
+
];
|
|
1129
1218
|
var PYTHON_GENERAL_RCE_PATTERN = /(import\s+(os|sys|subprocess)|from\s+(os|sys|subprocess)\s+import|exec\s*\(|eval\s*\(|__import__)/i;
|
|
1130
1219
|
var SHELL_BASH_RCE_PATTERN = /(wget\s+|curl\s+|rm\s+-rf|chmod\s+\+x|cat\s+\/etc\/passwd|\/bin\/sh|\/bin\/bash)/i;
|
|
1131
1220
|
var JAVASCRIPT_RCE_PATTERN = /(new\s+Function\(|process\.env|child_process)/i;
|
|
@@ -1139,8 +1228,15 @@ var SecurityPolicyViolationError = class extends Error {
|
|
|
1139
1228
|
}
|
|
1140
1229
|
};
|
|
1141
1230
|
function detectCapabilityViolation(text, config) {
|
|
1142
|
-
if (config.block_db_access
|
|
1143
|
-
|
|
1231
|
+
if (config.block_db_access) {
|
|
1232
|
+
if (SQL_DATABASE_ACCESS_PATTERN.test(text)) {
|
|
1233
|
+
return "SQL_INJECTION_ATTEMPT";
|
|
1234
|
+
}
|
|
1235
|
+
for (const pattern of NOSQL_DATABASE_ACCESS_PATTERNS) {
|
|
1236
|
+
if (pattern.test(text)) {
|
|
1237
|
+
return "SQL_INJECTION_ATTEMPT";
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1144
1240
|
}
|
|
1145
1241
|
if (config.block_code_execution && (PYTHON_GENERAL_RCE_PATTERN.test(text) || SHELL_BASH_RCE_PATTERN.test(text) || JAVASCRIPT_RCE_PATTERN.test(text))) {
|
|
1146
1242
|
return "RCE_ATTEMPT";
|
|
@@ -1473,15 +1569,15 @@ var DE_STOPWORDS = /* @__PURE__ */ new Set(["bitte", "anweisung", "system", "reg
|
|
|
1473
1569
|
var HEURISTIC_RULES = [
|
|
1474
1570
|
{
|
|
1475
1571
|
name: "heuristic_combo_ignore_instructions",
|
|
1476
|
-
re: /\b(ignore|disregard|forget|override|bypass|disable|jailbreak|dan|ignoruj|zapomen|obejdi|prepis)\b[\s\S]{0,
|
|
1572
|
+
re: /\b(ignore|disregard|forget|override|bypass|disable|jailbreak|dan|ignoruj|zapomen|obejdi|prepis)\b[\s\S]{0,160}\b(instruction(?:s)?|previous|system|developer|policy|rules?|guardrails|safety|instrukce|pokyny|pravidla|systemove?|bezpecnost(?:ni)?|politika)\b/i
|
|
1477
1573
|
},
|
|
1478
1574
|
{
|
|
1479
1575
|
name: "heuristic_combo_instruction_override_reverse",
|
|
1480
|
-
re: /\b(instruction(?:s)?|previous|system|developer|policy|rules
|
|
1576
|
+
re: /\b(instruction(?:s)?|previous|system|developer|policy|rules?|guardrails|safety|instrukce|pokyny|pravidla|systemove?|bezpecnost(?:ni)?|politika)\b[\s\S]{0,160}\b(ignore|disregard|forget|override|bypass|disable|jailbreak|dan|ignoruj|zapomen|obejdi|prepis)\b/i
|
|
1481
1577
|
},
|
|
1482
1578
|
{
|
|
1483
1579
|
name: "heuristic_combo_exfil_system_prompt",
|
|
1484
|
-
re: /\b(show|reveal|print|dump|leak|display|expose|tell|extract|ukaz|zobraz|vypis|odhal|prozrad)\b[\s\S]{0,
|
|
1580
|
+
re: /\b(show|reveal|print|dump|leak|display|expose|tell|extract|ukaz|zobraz|vypis|odhal|prozrad)\b[\s\S]{0,180}\b(system prompt|system instruction(?:s)?|developer message|hidden prompt|internal instruction(?:s)?|policy|guardrails|interni instrukce|systemove nastaveni)\b/i
|
|
1485
1581
|
},
|
|
1486
1582
|
{
|
|
1487
1583
|
name: "heuristic_role_prefix_system_developer",
|
|
@@ -1490,6 +1586,14 @@ var HEURISTIC_RULES = [
|
|
|
1490
1586
|
{
|
|
1491
1587
|
name: "heuristic_delimiter_system_prompt",
|
|
1492
1588
|
re: /\b(begin|start)\s+(system|developer)\s+prompt\b|\bend\s+(system|developer)\s+prompt\b/i
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
name: "heuristic_developer_mode_override",
|
|
1592
|
+
re: /\b(developer\s*mode|dev\s*mode)\b[\s\S]{0,200}\b(ignore|bypass|disable|override|ignoruj|obejdi|zapomen)\b/i
|
|
1593
|
+
},
|
|
1594
|
+
{
|
|
1595
|
+
name: "heuristic_czech_injection_phrase",
|
|
1596
|
+
re: /\b(zapomen|ignoruj)\b[\s\S]{0,220}\b(predchozi\s+instrukce|bezpecnostni\s+pravidla|systemove\s+nastaveni)\b/i
|
|
1493
1597
|
}
|
|
1494
1598
|
];
|
|
1495
1599
|
var scannerSingleton = null;
|
|
@@ -1540,6 +1644,9 @@ ${input.slice(-WINDOW_SLICE_SIZE)}`;
|
|
|
1540
1644
|
[...]
|
|
1541
1645
|
${input.slice(tailStart)}`;
|
|
1542
1646
|
}
|
|
1647
|
+
function normalizeForHeuristics(input) {
|
|
1648
|
+
return input.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\s+/g, " ").trim();
|
|
1649
|
+
}
|
|
1543
1650
|
function scoreStopwords(tokens, stopwords) {
|
|
1544
1651
|
let score = 0;
|
|
1545
1652
|
for (const token of tokens) {
|
|
@@ -1582,9 +1689,10 @@ function findRegexMatch(prompt) {
|
|
|
1582
1689
|
if (!prompt) {
|
|
1583
1690
|
return null;
|
|
1584
1691
|
}
|
|
1692
|
+
const normalizedPrompt = normalizeForHeuristics(prompt);
|
|
1585
1693
|
for (const rule of HEURISTIC_RULES) {
|
|
1586
1694
|
try {
|
|
1587
|
-
const match = rule.re.exec(
|
|
1695
|
+
const match = rule.re.exec(normalizedPrompt);
|
|
1588
1696
|
if (match && typeof match[0] === "string" && match[0].trim()) {
|
|
1589
1697
|
return {
|
|
1590
1698
|
rule: rule.name,
|
|
@@ -2457,13 +2565,18 @@ var AgentID = class {
|
|
|
2457
2565
|
const metadata = {
|
|
2458
2566
|
...params.metadata ?? {}
|
|
2459
2567
|
};
|
|
2568
|
+
const metadataClientEventId = typeof metadata.client_event_id === "string" && isUuidLike(metadata.client_event_id) ? metadata.client_event_id : null;
|
|
2569
|
+
const canonicalClientEventId = metadataClientEventId ?? eventId;
|
|
2570
|
+
if (!metadataClientEventId) {
|
|
2571
|
+
metadata.client_event_id = canonicalClientEventId;
|
|
2572
|
+
}
|
|
2460
2573
|
if (!Object.prototype.hasOwnProperty.call(metadata, "agentid_base_url")) {
|
|
2461
2574
|
metadata.agentid_base_url = this.baseUrl;
|
|
2462
2575
|
}
|
|
2463
2576
|
void this.getCapabilityConfig(false, { apiKey: effectiveApiKey }).catch(() => void 0);
|
|
2464
2577
|
const payload = {
|
|
2465
2578
|
...params,
|
|
2466
|
-
event_id:
|
|
2579
|
+
event_id: canonicalClientEventId,
|
|
2467
2580
|
timestamp,
|
|
2468
2581
|
input: sanitizeIngestText(params.input),
|
|
2469
2582
|
output: sanitizeIngestText(params.output),
|
|
@@ -2480,6 +2593,7 @@ var AgentID = class {
|
|
|
2480
2593
|
headers: {
|
|
2481
2594
|
"Content-Type": "application/json",
|
|
2482
2595
|
"x-agentid-api-key": effectiveApiKey,
|
|
2596
|
+
"x-correlation-id": canonicalClientEventId,
|
|
2483
2597
|
"X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER
|
|
2484
2598
|
},
|
|
2485
2599
|
body: JSON.stringify(payload),
|
package/dist/index.mjs
CHANGED
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.
|
|
30
|
+
var AGENTID_SDK_VERSION_HEADER = "js-0.1.23".trim().length > 0 ? "js-0.1.23" : FALLBACK_SDK_VERSION;
|
|
31
31
|
|
|
32
32
|
// src/pii-national-identifiers.ts
|
|
33
33
|
var REGION_ANCHORS = {
|
package/dist/langchain.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentid-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "AgentID JavaScript/TypeScript SDK for guard, ingest, tracing, and analytics.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://agentid.ai",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@langchain/core": "^0.3.0 || ^1.0.0",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
43
|
+
"langchain": "^0.1.0",
|
|
44
|
+
"openai": "^4.0.0 || ^5.0.0 || ^6.0.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"@langchain/core": {
|
|
@@ -54,5 +54,8 @@
|
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"tsup": "^8.3.5",
|
|
56
56
|
"typescript": "^5.0.0"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"agentid-sdk": "^0.1.21"
|
|
57
60
|
}
|
|
58
61
|
}
|