agentid-sdk 0.1.22 → 0.1.24

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.
@@ -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
- detections.push({ start: m.index, end: m.index + m[0].length, type: "PERSON", text: m[0] });
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,120}\b(instruction(?:s)?|previous|system|developer|policy|rules|guardrails|safety|instrukce|pokyny|pravidla|syst[eé]m|bezpecnost|politika)\b/i
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|guardrails|safety|instrukce|pokyny|pravidla|syst[eé]m|bezpecnost|politika)\b[\s\S]{0,120}\b(ignore|disregard|forget|override|bypass|disable|jailbreak|dan|ignoruj|zapomen|obejdi|prepis)\b/i
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,140}\b(system prompt|system instruction(?:s)?|developer message|hidden prompt|internal instruction(?:s)?|policy|guardrails|intern[ií] instrukce)\b/i
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(prompt);
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.22".trim().length > 0 ? "js-0.1.22" : FALLBACK_SDK_VERSION;
1558
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.24".trim().length > 0 ? "js-0.1.24" : FALLBACK_SDK_VERSION;
1466
1559
 
1467
1560
  // src/local-security-enforcer.ts
1468
1561
  var DEFAULT_FAIL_OPEN_CONFIG = {
@@ -1470,12 +1563,21 @@ var DEFAULT_FAIL_OPEN_CONFIG = {
1470
1563
  strict_security_mode: false,
1471
1564
  failure_mode: "fail_open",
1472
1565
  block_on_heuristic: false,
1566
+ inject_transparency_metadata: false,
1473
1567
  block_pii_leakage: false,
1474
1568
  block_db_access: false,
1475
1569
  block_code_execution: false,
1476
1570
  block_toxicity: false
1477
1571
  };
1478
1572
  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;
1573
+ var NOSQL_DATABASE_ACCESS_PATTERNS = [
1574
+ /\bdb\.[A-Za-z_][A-Za-z0-9_]*\.(find|findOne|aggregate|updateOne|updateMany|deleteOne|deleteMany|insertOne|insertMany)\s*\(/i,
1575
+ /\b(collection|mongodb)\.(find|findOne|aggregate|updateOne|updateMany|deleteOne|deleteMany|insertOne|insertMany)\s*\(/i,
1576
+ /\b\$where\b/i,
1577
+ /\b\$expr\b/i,
1578
+ /\b\$regex\b/i,
1579
+ /\bMongoClient\.connect\s*\(/i
1580
+ ];
1479
1581
  var PYTHON_GENERAL_RCE_PATTERN = /(import\s+(os|sys|subprocess)|from\s+(os|sys|subprocess)\s+import|exec\s*\(|eval\s*\(|__import__)/i;
1480
1582
  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
1583
  var JAVASCRIPT_RCE_PATTERN = /(new\s+Function\(|process\.env|child_process)/i;
@@ -1489,8 +1591,15 @@ var SecurityPolicyViolationError = class extends Error {
1489
1591
  }
1490
1592
  };
1491
1593
  function detectCapabilityViolation(text, config) {
1492
- if (config.block_db_access && SQL_DATABASE_ACCESS_PATTERN.test(text)) {
1493
- return "SQL_INJECTION_ATTEMPT";
1594
+ if (config.block_db_access) {
1595
+ if (SQL_DATABASE_ACCESS_PATTERN.test(text)) {
1596
+ return "SQL_INJECTION_ATTEMPT";
1597
+ }
1598
+ for (const pattern of NOSQL_DATABASE_ACCESS_PATTERNS) {
1599
+ if (pattern.test(text)) {
1600
+ return "SQL_INJECTION_ATTEMPT";
1601
+ }
1602
+ }
1494
1603
  }
1495
1604
  if (config.block_code_execution && (PYTHON_GENERAL_RCE_PATTERN.test(text) || SHELL_BASH_RCE_PATTERN.test(text) || JAVASCRIPT_RCE_PATTERN.test(text))) {
1496
1605
  return "RCE_ATTEMPT";
@@ -1637,6 +1746,11 @@ function normalizeCapabilityConfig(payload) {
1637
1746
  strict_security_mode: effectiveStrictMode,
1638
1747
  failure_mode: effectiveStrictMode ? "fail_close" : "fail_open",
1639
1748
  block_on_heuristic: blockOnHeuristic,
1749
+ inject_transparency_metadata: readOptionalBooleanAliases(
1750
+ body,
1751
+ ["inject_transparency_metadata", "transparency_metadata_enabled"],
1752
+ false
1753
+ ),
1640
1754
  block_pii_leakage: readBooleanField(body, "block_pii_leakage", "block_pii"),
1641
1755
  block_db_access: readBooleanField(body, "block_db_access", "block_db"),
1642
1756
  block_code_execution: readBooleanField(
@@ -1951,6 +2065,53 @@ async function safeReadJson2(response) {
1951
2065
  return null;
1952
2066
  }
1953
2067
  }
2068
+ function coerceTransparencyMetadata(value) {
2069
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2070
+ return void 0;
2071
+ }
2072
+ const raw = value;
2073
+ if (raw.is_ai_generated !== true) {
2074
+ return void 0;
2075
+ }
2076
+ if (raw.disclosure !== "You are interacting with an AI.") {
2077
+ return void 0;
2078
+ }
2079
+ if (raw.article !== "EU_AI_ACT_ARTICLE_50") {
2080
+ return void 0;
2081
+ }
2082
+ if (raw.injection_mode !== "deterministic") {
2083
+ return void 0;
2084
+ }
2085
+ return {
2086
+ is_ai_generated: true,
2087
+ disclosure: "You are interacting with an AI.",
2088
+ article: "EU_AI_ACT_ARTICLE_50",
2089
+ injection_mode: "deterministic"
2090
+ };
2091
+ }
2092
+ function attachTransparencyMetadata(target, transparency) {
2093
+ if (!transparency) {
2094
+ return target;
2095
+ }
2096
+ if (!target || typeof target !== "object" && typeof target !== "function") {
2097
+ return target;
2098
+ }
2099
+ try {
2100
+ Object.defineProperty(target, "agentid_transparency", {
2101
+ value: transparency,
2102
+ enumerable: false,
2103
+ configurable: true,
2104
+ writable: false
2105
+ });
2106
+ return target;
2107
+ } catch {
2108
+ try {
2109
+ target.agentid_transparency = transparency;
2110
+ } catch {
2111
+ }
2112
+ return target;
2113
+ }
2114
+ }
1954
2115
  function createCompletionChunkCollector() {
1955
2116
  if (typeof TransformStream === "function") {
1956
2117
  const stream = new TransformStream({
@@ -2275,6 +2436,16 @@ var AgentID = class {
2275
2436
  * strictMode=true: FAIL-CLOSED and throws on connectivity/timeouts.
2276
2437
  */
2277
2438
  async guard(params, options) {
2439
+ const guardStartedAt = Date.now();
2440
+ const withGuardLatency = (response) => {
2441
+ if (typeof response.guard_latency_ms === "number" && Number.isFinite(response.guard_latency_ms)) {
2442
+ return response;
2443
+ }
2444
+ return {
2445
+ ...response,
2446
+ guard_latency_ms: Math.max(0, Date.now() - guardStartedAt)
2447
+ };
2448
+ };
2278
2449
  const effectiveApiKey = this.resolveApiKey(options?.apiKey);
2279
2450
  const effectiveStrictMode = await this.resolveEffectiveStrictMode({
2280
2451
  apiKey: effectiveApiKey
@@ -2286,7 +2457,7 @@ var AgentID = class {
2286
2457
  const guardCacheKey = this.buildGuardCacheKey(payload);
2287
2458
  const cachedVerdict = this.readCachedGuardVerdict(guardCacheKey);
2288
2459
  if (cachedVerdict) {
2289
- return cachedVerdict;
2460
+ return withGuardLatency(cachedVerdict);
2290
2461
  }
2291
2462
  const correlationId = createCorrelationId(payload.client_event_id);
2292
2463
  let lastStatusCode = null;
@@ -2310,7 +2481,12 @@ var AgentID = class {
2310
2481
  lastStatusCode = res.status;
2311
2482
  const responseBody = await safeReadJson2(res);
2312
2483
  if (responseBody && typeof responseBody.allowed === "boolean") {
2313
- const verdict = responseBody;
2484
+ const rawVerdict = responseBody;
2485
+ const transparency = coerceTransparencyMetadata(rawVerdict.transparency);
2486
+ const verdict = {
2487
+ ...rawVerdict,
2488
+ ...transparency ? { transparency } : {}
2489
+ };
2314
2490
  const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || !verdict.reason && res.status >= 500);
2315
2491
  if (infrastructureFailure) {
2316
2492
  if (attempt < GUARD_MAX_ATTEMPTS - 1) {
@@ -2321,7 +2497,10 @@ var AgentID = class {
2321
2497
  console.warn(
2322
2498
  `[AgentID] Guard API infrastructure failure in strict mode (${verdict.reason ?? `http_${res.status}`}). Blocking request.`
2323
2499
  );
2324
- return { allowed: false, reason: verdict.reason ?? "network_error_strict_mode" };
2500
+ return withGuardLatency({
2501
+ allowed: false,
2502
+ reason: verdict.reason ?? "network_error_strict_mode"
2503
+ });
2325
2504
  }
2326
2505
  console.warn(
2327
2506
  `[AgentID] Guard API infrastructure fallback in fail-open mode (${verdict.reason ?? `http_${res.status}`}).`
@@ -2332,10 +2511,10 @@ var AgentID = class {
2332
2511
  guardParams: params,
2333
2512
  apiKey: effectiveApiKey
2334
2513
  });
2335
- return { allowed: true, reason: "system_failure_fail_open" };
2514
+ return withGuardLatency({ allowed: true, reason: "system_failure_fail_open" });
2336
2515
  }
2337
2516
  this.cacheGuardVerdict(guardCacheKey, verdict);
2338
- return verdict;
2517
+ return withGuardLatency(verdict);
2339
2518
  }
2340
2519
  if (!res.ok) {
2341
2520
  if (res.status >= 500 && attempt < GUARD_MAX_ATTEMPTS - 1) {
@@ -2365,9 +2544,9 @@ var AgentID = class {
2365
2544
  apiKey: effectiveApiKey
2366
2545
  });
2367
2546
  if (effectiveStrictMode) {
2368
- return { allowed: false, reason: "network_error_strict_mode" };
2547
+ return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
2369
2548
  }
2370
- return { allowed: true, reason: "timeout_fallback" };
2549
+ return withGuardLatency({ allowed: true, reason: "timeout_fallback" });
2371
2550
  }
2372
2551
  console.warn(
2373
2552
  effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
@@ -2380,33 +2559,33 @@ var AgentID = class {
2380
2559
  apiKey: effectiveApiKey
2381
2560
  });
2382
2561
  if (effectiveStrictMode) {
2383
- return { allowed: false, reason: "network_error_strict_mode" };
2562
+ return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
2384
2563
  }
2385
- return { allowed: true, reason: "guard_unreachable" };
2564
+ return withGuardLatency({ allowed: true, reason: "guard_unreachable" });
2386
2565
  } finally {
2387
2566
  clearTimeout(timeoutId);
2388
2567
  }
2389
2568
  }
2390
2569
  if (lastAbort) {
2391
2570
  if (effectiveStrictMode) {
2392
- return { allowed: false, reason: "network_error_strict_mode" };
2571
+ return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
2393
2572
  }
2394
- return { allowed: true, reason: "timeout_fallback" };
2573
+ return withGuardLatency({ allowed: true, reason: "timeout_fallback" });
2395
2574
  }
2396
2575
  if (typeof lastStatusCode === "number" && lastStatusCode >= 500) {
2397
2576
  if (effectiveStrictMode) {
2398
- return { allowed: false, reason: "server_error" };
2577
+ return withGuardLatency({ allowed: false, reason: "server_error" });
2399
2578
  }
2400
- return { allowed: true, reason: "system_failure_fail_open" };
2579
+ return withGuardLatency({ allowed: true, reason: "system_failure_fail_open" });
2401
2580
  }
2402
2581
  console.warn(
2403
2582
  effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2404
2583
  lastError
2405
2584
  );
2406
2585
  if (effectiveStrictMode) {
2407
- return { allowed: false, reason: "network_error_strict_mode" };
2586
+ return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
2408
2587
  }
2409
- return { allowed: true, reason: "guard_unreachable" };
2588
+ return withGuardLatency({ allowed: true, reason: "guard_unreachable" });
2410
2589
  }
2411
2590
  async sendIngest(params, options) {
2412
2591
  const effectiveApiKey = this.resolveApiKey(options?.apiKey);
@@ -2415,13 +2594,18 @@ var AgentID = class {
2415
2594
  const metadata = {
2416
2595
  ...params.metadata ?? {}
2417
2596
  };
2597
+ const metadataClientEventId = typeof metadata.client_event_id === "string" && isUuidLike(metadata.client_event_id) ? metadata.client_event_id : null;
2598
+ const canonicalClientEventId = metadataClientEventId ?? eventId;
2599
+ if (!metadataClientEventId) {
2600
+ metadata.client_event_id = canonicalClientEventId;
2601
+ }
2418
2602
  if (!Object.prototype.hasOwnProperty.call(metadata, "agentid_base_url")) {
2419
2603
  metadata.agentid_base_url = this.baseUrl;
2420
2604
  }
2421
2605
  void this.getCapabilityConfig(false, { apiKey: effectiveApiKey }).catch(() => void 0);
2422
2606
  const payload = {
2423
2607
  ...params,
2424
- event_id: eventId,
2608
+ event_id: canonicalClientEventId,
2425
2609
  timestamp,
2426
2610
  input: sanitizeIngestText(params.input),
2427
2611
  output: sanitizeIngestText(params.output),
@@ -2438,6 +2622,7 @@ var AgentID = class {
2438
2622
  headers: {
2439
2623
  "Content-Type": "application/json",
2440
2624
  "x-agentid-api-key": effectiveApiKey,
2625
+ "x-correlation-id": canonicalClientEventId,
2441
2626
  "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER
2442
2627
  },
2443
2628
  body: JSON.stringify(payload),
@@ -2621,6 +2806,7 @@ var AgentID = class {
2621
2806
  return async (...args) => {
2622
2807
  const normalizedCreateArgs = normalizeOpenAICreateArgs(args);
2623
2808
  const req = normalizedCreateArgs?.[0] ?? {};
2809
+ const pipelineStartedAt = Date.now();
2624
2810
  const requestLevelApiKey = options.resolveApiKey?.(req) ?? options.apiKey ?? options.api_key;
2625
2811
  const effectiveApiKey = this.resolveApiKey(requestLevelApiKey);
2626
2812
  const requestOptions = { apiKey: effectiveApiKey };
@@ -2688,6 +2874,8 @@ var AgentID = class {
2688
2874
  }
2689
2875
  const canonicalClientEventId = typeof verdict.client_event_id === "string" && isUuidLike(verdict.client_event_id) ? verdict.client_event_id : clientEventId;
2690
2876
  const guardEventId = typeof verdict.guard_event_id === "string" && verdict.guard_event_id.length > 0 ? verdict.guard_event_id : null;
2877
+ const guardLatencyMs = typeof verdict.guard_latency_ms === "number" && Number.isFinite(verdict.guard_latency_ms) ? Math.max(0, Math.trunc(verdict.guard_latency_ms)) : Math.max(0, Date.now() - pipelineStartedAt);
2878
+ const transparency = coerceTransparencyMetadata(verdict.transparency);
2691
2879
  const isShadowMode = verdict.shadow_mode === true;
2692
2880
  const transformedInput = isShadowMode ? maskedText : typeof verdict.transformed_input === "string" && verdict.transformed_input.length > 0 ? verdict.transformed_input : maskedText;
2693
2881
  if (transformedInput !== maskedText) {
@@ -2701,6 +2889,7 @@ var AgentID = class {
2701
2889
  createArgs = nextCreateArgs;
2702
2890
  }
2703
2891
  if (stream) {
2892
+ const modelStartedAt2 = Date.now();
2704
2893
  const streamResponse = await originalCreate.apply(compTarget, createArgs);
2705
2894
  const wrappedCompletion = this.wrapCompletion(
2706
2895
  isAsyncIterable(streamResponse) ? streamResponse : (async function* () {
@@ -2711,6 +2900,8 @@ var AgentID = class {
2711
2900
  );
2712
2901
  if (maskedText && wrappedCompletion.mode === "stream") {
2713
2902
  void wrappedCompletion.done.then(async (result) => {
2903
+ const modelLatencyMs2 = Math.max(0, Date.now() - modelStartedAt2);
2904
+ const totalPipelineLatencyMs2 = Math.max(0, Date.now() - pipelineStartedAt);
2714
2905
  const outputForLog = isShadowMode ? result.rawOutput : result.transformedOutput;
2715
2906
  const ingestResult = await this.sendIngest({
2716
2907
  event_id: canonicalClientEventId,
@@ -2720,7 +2911,7 @@ var AgentID = class {
2720
2911
  output: outputForLog,
2721
2912
  model: adapter.getModelName(maskedReq),
2722
2913
  usage: void 0,
2723
- latency: void 0,
2914
+ latency: modelLatencyMs2,
2724
2915
  event_type: "complete",
2725
2916
  metadata: {
2726
2917
  transformed_input: maskedText,
@@ -2730,8 +2921,12 @@ var AgentID = class {
2730
2921
  simulated_decision: verdict.simulated_decision ?? null,
2731
2922
  simulated_output_decision: isShadowMode && result.outputMasked ? "masked" : "allowed",
2732
2923
  response_streamed: true,
2924
+ guard_latency_ms: guardLatencyMs,
2925
+ model_latency_ms: modelLatencyMs2,
2926
+ total_pipeline_latency_ms: totalPipelineLatencyMs2,
2733
2927
  guard_event_id: guardEventId,
2734
- client_event_id: canonicalClientEventId
2928
+ client_event_id: canonicalClientEventId,
2929
+ transparency
2735
2930
  },
2736
2931
  client_capabilities: this.buildClientCapabilities("openai", false)
2737
2932
  }, requestOptions);
@@ -2744,11 +2939,15 @@ var AgentID = class {
2744
2939
  console.error("[AgentID] Stream completion wrapping failed:", error);
2745
2940
  });
2746
2941
  }
2747
- return wrappedCompletion.mode === "stream" ? wrappedCompletion.completion : streamResponse;
2942
+ if (wrappedCompletion.mode === "stream") {
2943
+ return attachTransparencyMetadata(wrappedCompletion.completion, transparency);
2944
+ }
2945
+ return attachTransparencyMetadata(streamResponse, transparency);
2748
2946
  }
2749
- const start = Date.now();
2947
+ const modelStartedAt = Date.now();
2750
2948
  const res = await originalCreate.apply(compTarget, createArgs);
2751
- const latency = Date.now() - start;
2949
+ const modelLatencyMs = Math.max(0, Date.now() - modelStartedAt);
2950
+ const totalPipelineLatencyMs = Math.max(0, Date.now() - pipelineStartedAt);
2752
2951
  if (maskedText) {
2753
2952
  const output = adapter.extractOutput(res);
2754
2953
  const wrappedCompletion = this.wrapCompletion(output);
@@ -2763,7 +2962,7 @@ var AgentID = class {
2763
2962
  output: outputForLog,
2764
2963
  model,
2765
2964
  usage,
2766
- latency,
2965
+ latency: modelLatencyMs,
2767
2966
  event_type: "complete",
2768
2967
  metadata: {
2769
2968
  transformed_input: maskedText,
@@ -2773,8 +2972,12 @@ var AgentID = class {
2773
2972
  simulated_decision: verdict.simulated_decision ?? null,
2774
2973
  simulated_output_decision: isShadowMode && wrappedCompletion.outputMasked ? "masked" : "allowed",
2775
2974
  response_streamed: false,
2975
+ guard_latency_ms: guardLatencyMs,
2976
+ model_latency_ms: modelLatencyMs,
2977
+ total_pipeline_latency_ms: totalPipelineLatencyMs,
2776
2978
  guard_event_id: guardEventId,
2777
- client_event_id: canonicalClientEventId
2979
+ client_event_id: canonicalClientEventId,
2980
+ transparency
2778
2981
  },
2779
2982
  client_capabilities: this.buildClientCapabilities("openai", false)
2780
2983
  }, requestOptions);
@@ -2801,7 +3004,7 @@ var AgentID = class {
2801
3004
  } catch {
2802
3005
  }
2803
3006
  }
2804
- return res;
3007
+ return attachTransparencyMetadata(res, transparency);
2805
3008
  };
2806
3009
  }
2807
3010
  });
package/dist/index.d.mts CHANGED
@@ -1,4 +1,6 @@
1
- export { A as AgentID, G as GuardParams, a as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions, S as SecurityBlockError } from './agentid-BmsXTOCc.mjs';
1
+ import { T as TransparencyMetadata } from './agentid-BGCUoYV7.mjs';
2
+ export { A as AgentID, G as GuardParams, a as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions, S as SecurityBlockError } from './agentid-BGCUoYV7.mjs';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
4
 
3
5
  type PIIMapping = Record<string, string>;
4
6
  declare class PIIManager {
@@ -52,4 +54,25 @@ declare class InjectionScanner {
52
54
  }
53
55
  declare function getInjectionScanner(): InjectionScanner;
54
56
 
55
- export { type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type PIIMapping, type TokenUsage, getInjectionScanner, scanWithRegex };
57
+ type AgentIDTransparencyBadgeTelemetry = {
58
+ systemId: string;
59
+ apiKey?: string;
60
+ ingestUrl?: string;
61
+ baseUrl?: string;
62
+ userId?: string;
63
+ model?: string;
64
+ headers?: Record<string, string>;
65
+ metadata?: Record<string, unknown>;
66
+ onError?: (error: unknown) => void;
67
+ };
68
+ type AgentIDTransparencyBadgeProps = {
69
+ telemetry: AgentIDTransparencyBadgeTelemetry;
70
+ metadata?: TransparencyMetadata | null;
71
+ message?: string;
72
+ placement?: "chat-header" | "watermark-overlay";
73
+ fixed?: boolean;
74
+ className?: string;
75
+ };
76
+ declare function AgentIDTransparencyBadge(props: AgentIDTransparencyBadgeProps): react_jsx_runtime.JSX.Element;
77
+
78
+ export { AgentIDTransparencyBadge, type AgentIDTransparencyBadgeProps, type AgentIDTransparencyBadgeTelemetry, type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type PIIMapping, type TokenUsage, TransparencyMetadata, getInjectionScanner, scanWithRegex };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export { A as AgentID, G as GuardParams, a as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions, S as SecurityBlockError } from './agentid-BmsXTOCc.js';
1
+ import { T as TransparencyMetadata } from './agentid-BGCUoYV7.js';
2
+ export { A as AgentID, G as GuardParams, a as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions, S as SecurityBlockError } from './agentid-BGCUoYV7.js';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
4
 
3
5
  type PIIMapping = Record<string, string>;
4
6
  declare class PIIManager {
@@ -52,4 +54,25 @@ declare class InjectionScanner {
52
54
  }
53
55
  declare function getInjectionScanner(): InjectionScanner;
54
56
 
55
- export { type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type PIIMapping, type TokenUsage, getInjectionScanner, scanWithRegex };
57
+ type AgentIDTransparencyBadgeTelemetry = {
58
+ systemId: string;
59
+ apiKey?: string;
60
+ ingestUrl?: string;
61
+ baseUrl?: string;
62
+ userId?: string;
63
+ model?: string;
64
+ headers?: Record<string, string>;
65
+ metadata?: Record<string, unknown>;
66
+ onError?: (error: unknown) => void;
67
+ };
68
+ type AgentIDTransparencyBadgeProps = {
69
+ telemetry: AgentIDTransparencyBadgeTelemetry;
70
+ metadata?: TransparencyMetadata | null;
71
+ message?: string;
72
+ placement?: "chat-header" | "watermark-overlay";
73
+ fixed?: boolean;
74
+ className?: string;
75
+ };
76
+ declare function AgentIDTransparencyBadge(props: AgentIDTransparencyBadgeProps): react_jsx_runtime.JSX.Element;
77
+
78
+ export { AgentIDTransparencyBadge, type AgentIDTransparencyBadgeProps, type AgentIDTransparencyBadgeTelemetry, type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type PIIMapping, type TokenUsage, TransparencyMetadata, getInjectionScanner, scanWithRegex };