agentid-sdk 0.1.24 → 0.1.26
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 +28 -5
- package/dist/{agentid-BGCUoYV7.d.mts → agentid-DviYzyAM.d.mts} +49 -4
- package/dist/{agentid-BGCUoYV7.d.ts → agentid-DviYzyAM.d.ts} +49 -4
- package/dist/{chunk-JLHAS2EE.mjs → chunk-JIQGHFHI.mjs} +493 -54
- package/dist/index.d.mts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +496 -56
- package/dist/index.mjs +3 -1
- package/dist/langchain.d.mts +4 -1
- package/dist/langchain.d.ts +4 -1
- package/dist/langchain.js +111 -20
- package/dist/langchain.mjs +111 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AgentID: () => AgentID,
|
|
34
34
|
AgentIDTransparencyBadge: () => AgentIDTransparencyBadge,
|
|
35
|
+
DependencyError: () => DependencyError,
|
|
35
36
|
InjectionScanner: () => InjectionScanner,
|
|
36
37
|
OpenAIAdapter: () => OpenAIAdapter,
|
|
37
38
|
PIIManager: () => PIIManager,
|
|
@@ -85,7 +86,7 @@ var OpenAIAdapter = class {
|
|
|
85
86
|
|
|
86
87
|
// src/sdk-version.ts
|
|
87
88
|
var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
|
|
88
|
-
var AGENTID_SDK_VERSION_HEADER = "js-0.1.
|
|
89
|
+
var AGENTID_SDK_VERSION_HEADER = "js-0.1.26".trim().length > 0 ? "js-0.1.26" : FALLBACK_SDK_VERSION;
|
|
89
90
|
|
|
90
91
|
// src/pii-national-identifiers.ts
|
|
91
92
|
var MAX_CANDIDATES_PER_RULE = 256;
|
|
@@ -1204,6 +1205,7 @@ var DEFAULT_FAIL_OPEN_CONFIG = {
|
|
|
1204
1205
|
block_on_heuristic: false,
|
|
1205
1206
|
inject_transparency_metadata: false,
|
|
1206
1207
|
block_pii_leakage: false,
|
|
1208
|
+
enable_sdk_pii_masking: false,
|
|
1207
1209
|
block_db_access: false,
|
|
1208
1210
|
block_code_execution: false,
|
|
1209
1211
|
block_toxicity: false
|
|
@@ -1306,8 +1308,8 @@ var LocalSecurityEnforcer = class {
|
|
|
1306
1308
|
|
|
1307
1309
|
// src/capability-config.ts
|
|
1308
1310
|
var CONFIG_TTL_MS = 5 * 60 * 1e3;
|
|
1309
|
-
var CONFIG_TIMEOUT_MS =
|
|
1310
|
-
var CONFIG_RETRY_DELAY_MS =
|
|
1311
|
+
var CONFIG_TIMEOUT_MS = 1500;
|
|
1312
|
+
var CONFIG_RETRY_DELAY_MS = 150;
|
|
1311
1313
|
var MAX_CAPABILITY_CACHE_ENTRIES = 500;
|
|
1312
1314
|
var CapabilityConfigFetchError = class extends Error {
|
|
1313
1315
|
constructor(message, params) {
|
|
@@ -1391,6 +1393,11 @@ function normalizeCapabilityConfig(payload) {
|
|
|
1391
1393
|
false
|
|
1392
1394
|
),
|
|
1393
1395
|
block_pii_leakage: readBooleanField(body, "block_pii_leakage", "block_pii"),
|
|
1396
|
+
enable_sdk_pii_masking: readOptionalBooleanField(
|
|
1397
|
+
body,
|
|
1398
|
+
"enable_sdk_pii_masking",
|
|
1399
|
+
false
|
|
1400
|
+
),
|
|
1394
1401
|
block_db_access: readBooleanField(body, "block_db_access", "block_db"),
|
|
1395
1402
|
block_code_execution: readBooleanField(
|
|
1396
1403
|
body,
|
|
@@ -1554,6 +1561,79 @@ async function ensureCapabilityConfig(params) {
|
|
|
1554
1561
|
return pending;
|
|
1555
1562
|
}
|
|
1556
1563
|
|
|
1564
|
+
// src/context-intent.ts
|
|
1565
|
+
var EDUCATIONAL_MARKERS = [
|
|
1566
|
+
"explain",
|
|
1567
|
+
"analysis",
|
|
1568
|
+
"analyze",
|
|
1569
|
+
"analyse",
|
|
1570
|
+
"review",
|
|
1571
|
+
"summarize",
|
|
1572
|
+
"summarise",
|
|
1573
|
+
"summary",
|
|
1574
|
+
"plain-language explanation",
|
|
1575
|
+
"red flags",
|
|
1576
|
+
"security workshop",
|
|
1577
|
+
"training",
|
|
1578
|
+
"lesson",
|
|
1579
|
+
"quoted attack",
|
|
1580
|
+
"quoted example",
|
|
1581
|
+
"attack example",
|
|
1582
|
+
"security event",
|
|
1583
|
+
"security log",
|
|
1584
|
+
"audit log",
|
|
1585
|
+
"incident report",
|
|
1586
|
+
"trace timeline"
|
|
1587
|
+
];
|
|
1588
|
+
var WARNING_MARKERS = [
|
|
1589
|
+
"dangerous",
|
|
1590
|
+
"risky",
|
|
1591
|
+
"risk",
|
|
1592
|
+
"warning",
|
|
1593
|
+
"warn",
|
|
1594
|
+
"malicious",
|
|
1595
|
+
"security indicator",
|
|
1596
|
+
"red flags"
|
|
1597
|
+
];
|
|
1598
|
+
var NON_EXECUTION_MARKERS = [
|
|
1599
|
+
"do not execute",
|
|
1600
|
+
"do not run",
|
|
1601
|
+
"do not return commands",
|
|
1602
|
+
"do not output commands",
|
|
1603
|
+
"do not provide executable steps",
|
|
1604
|
+
"for explanation only",
|
|
1605
|
+
"non-executable"
|
|
1606
|
+
];
|
|
1607
|
+
function normalizeIntentInput(input) {
|
|
1608
|
+
return input.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\s+/g, " ").trim();
|
|
1609
|
+
}
|
|
1610
|
+
function hasAnyMarker(input, markers) {
|
|
1611
|
+
return markers.some((marker) => input.includes(marker));
|
|
1612
|
+
}
|
|
1613
|
+
function classifyInjectionContextIntent(input) {
|
|
1614
|
+
const normalized = normalizeIntentInput(input ?? "");
|
|
1615
|
+
if (!normalized) {
|
|
1616
|
+
return {
|
|
1617
|
+
educational: false,
|
|
1618
|
+
quotedExample: false,
|
|
1619
|
+
warningOnly: false,
|
|
1620
|
+
nonExecutableConstraint: false,
|
|
1621
|
+
promptInjectionExempt: false
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
const educational = hasAnyMarker(normalized, EDUCATIONAL_MARKERS);
|
|
1625
|
+
const warningOnly = hasAnyMarker(normalized, WARNING_MARKERS);
|
|
1626
|
+
const nonExecutableConstraint = hasAnyMarker(normalized, NON_EXECUTION_MARKERS);
|
|
1627
|
+
const quotedExample = /["'`]/.test(input) || normalized.includes("quoted") || normalized.includes("quote") || normalized.includes("phrase") || normalized.includes("attack example");
|
|
1628
|
+
return {
|
|
1629
|
+
educational,
|
|
1630
|
+
quotedExample,
|
|
1631
|
+
warningOnly,
|
|
1632
|
+
nonExecutableConstraint,
|
|
1633
|
+
promptInjectionExempt: educational && (quotedExample || warningOnly || nonExecutableConstraint || normalized.includes("prompt injection indicator") || normalized.includes("jailbreak prompt"))
|
|
1634
|
+
};
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1557
1637
|
// src/security.ts
|
|
1558
1638
|
var MAX_ANALYSIS_WINDOW = 8192;
|
|
1559
1639
|
var WINDOW_SLICE_SIZE = 4e3;
|
|
@@ -1561,6 +1641,7 @@ var WORD_BOUNDARY_SCAN = 120;
|
|
|
1561
1641
|
var AI_TIMEOUT_MS = 2e3;
|
|
1562
1642
|
var TELEMETRY_SNIPPET_LIMIT = 4e3;
|
|
1563
1643
|
var AI_OPENAI_MODEL = "gpt-4o-mini";
|
|
1644
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1564
1645
|
var EN_STOPWORDS = /* @__PURE__ */ new Set([
|
|
1565
1646
|
"the",
|
|
1566
1647
|
"and",
|
|
@@ -1608,6 +1689,25 @@ var piiSingleton = null;
|
|
|
1608
1689
|
function normalizeBaseUrl2(baseUrl) {
|
|
1609
1690
|
return (baseUrl || "").replace(/\/+$/, "");
|
|
1610
1691
|
}
|
|
1692
|
+
function createPseudoUuidV4() {
|
|
1693
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
1694
|
+
const random = Math.floor(Math.random() * 16);
|
|
1695
|
+
const nibble = char === "x" ? random : random & 3 | 8;
|
|
1696
|
+
return nibble.toString(16);
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
function isUuidLike(value) {
|
|
1700
|
+
return typeof value === "string" && UUID_RE.test(value);
|
|
1701
|
+
}
|
|
1702
|
+
function createEventId(seed) {
|
|
1703
|
+
if (isUuidLike(seed)) {
|
|
1704
|
+
return seed;
|
|
1705
|
+
}
|
|
1706
|
+
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
1707
|
+
return globalThis.crypto.randomUUID();
|
|
1708
|
+
}
|
|
1709
|
+
return createPseudoUuidV4();
|
|
1710
|
+
}
|
|
1611
1711
|
function getSharedPIIManager() {
|
|
1612
1712
|
if (!piiSingleton) {
|
|
1613
1713
|
piiSingleton = new PIIManager();
|
|
@@ -1696,6 +1796,10 @@ function findRegexMatch(prompt) {
|
|
|
1696
1796
|
if (!prompt) {
|
|
1697
1797
|
return null;
|
|
1698
1798
|
}
|
|
1799
|
+
const contextIntent = classifyInjectionContextIntent(prompt);
|
|
1800
|
+
if (contextIntent.promptInjectionExempt) {
|
|
1801
|
+
return null;
|
|
1802
|
+
}
|
|
1699
1803
|
const normalizedPrompt = normalizeForHeuristics(prompt);
|
|
1700
1804
|
for (const rule of HEURISTIC_RULES) {
|
|
1701
1805
|
try {
|
|
@@ -1821,13 +1925,16 @@ async function reportSecurityEvent(options) {
|
|
|
1821
1925
|
const snippet = truncateSnippet(options.snippet);
|
|
1822
1926
|
const snippetHash = snippet ? await sha256Hex(snippet) : "";
|
|
1823
1927
|
const inputValue = options.storePii ? snippet : snippetHash;
|
|
1928
|
+
const eventId = createEventId(options.eventId ?? options.clientEventId);
|
|
1824
1929
|
const metadata = {
|
|
1825
1930
|
source: options.source,
|
|
1826
1931
|
detector: options.detector,
|
|
1827
1932
|
trigger_rule: options.triggerRule,
|
|
1828
1933
|
language: options.language,
|
|
1829
1934
|
ai_scan_status: options.aiStatus ?? null,
|
|
1830
|
-
reason: options.reason ?? null
|
|
1935
|
+
reason: options.reason ?? null,
|
|
1936
|
+
client_event_id: eventId,
|
|
1937
|
+
...options.telemetryMetadata ?? {}
|
|
1831
1938
|
};
|
|
1832
1939
|
if (options.storePii) {
|
|
1833
1940
|
metadata.snippet = snippet;
|
|
@@ -1835,11 +1942,14 @@ async function reportSecurityEvent(options) {
|
|
|
1835
1942
|
metadata.snippet_hash = snippetHash;
|
|
1836
1943
|
}
|
|
1837
1944
|
const payload = {
|
|
1945
|
+
event_id: eventId,
|
|
1946
|
+
system_id: options.systemId,
|
|
1838
1947
|
input: inputValue,
|
|
1839
1948
|
output: "",
|
|
1840
1949
|
model: "agentid.local_injection_scanner",
|
|
1841
1950
|
event_type: options.outcome === "blocked" ? "security_block" : "security_alert",
|
|
1842
1951
|
severity: options.outcome === "blocked" ? "error" : "warning",
|
|
1952
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1843
1953
|
metadata
|
|
1844
1954
|
};
|
|
1845
1955
|
void fetch(`${normalizeBaseUrl2(options.baseUrl)}/ingest`, {
|
|
@@ -1869,7 +1979,11 @@ var InjectionScanner = class _InjectionScanner {
|
|
|
1869
1979
|
aiScanEnabled: options?.aiScanEnabled,
|
|
1870
1980
|
storePii: options?.storePii,
|
|
1871
1981
|
piiManager: options?.piiManager,
|
|
1872
|
-
source: options?.source
|
|
1982
|
+
source: options?.source,
|
|
1983
|
+
systemId: options?.systemId,
|
|
1984
|
+
eventId: options?.eventId,
|
|
1985
|
+
clientEventId: options?.clientEventId,
|
|
1986
|
+
telemetryMetadata: options?.telemetryMetadata
|
|
1873
1987
|
});
|
|
1874
1988
|
}
|
|
1875
1989
|
async scan(params) {
|
|
@@ -1881,6 +1995,11 @@ var InjectionScanner = class _InjectionScanner {
|
|
|
1881
1995
|
const storePii = params.storePii === true;
|
|
1882
1996
|
const aiScanEnabled = params.aiScanEnabled !== false;
|
|
1883
1997
|
const language = detectLanguageTag(prompt);
|
|
1998
|
+
const scanStartedAt = Date.now();
|
|
1999
|
+
const buildTelemetryMetadata = () => ({
|
|
2000
|
+
...params.telemetryMetadata ?? {},
|
|
2001
|
+
sdk_local_scan_ms: Math.max(0, Date.now() - scanStartedAt)
|
|
2002
|
+
});
|
|
1884
2003
|
const regexMatch = findRegexMatch(prompt);
|
|
1885
2004
|
if (regexMatch) {
|
|
1886
2005
|
await reportSecurityEvent({
|
|
@@ -1892,7 +2011,11 @@ var InjectionScanner = class _InjectionScanner {
|
|
|
1892
2011
|
triggerRule: regexMatch.rule,
|
|
1893
2012
|
snippet: regexMatch.snippet,
|
|
1894
2013
|
storePii,
|
|
1895
|
-
language
|
|
2014
|
+
language,
|
|
2015
|
+
systemId: params.systemId,
|
|
2016
|
+
eventId: params.eventId,
|
|
2017
|
+
clientEventId: params.clientEventId,
|
|
2018
|
+
telemetryMetadata: buildTelemetryMetadata()
|
|
1896
2019
|
});
|
|
1897
2020
|
throw new Error(`AgentID: Prompt injection blocked (${regexMatch.rule})`);
|
|
1898
2021
|
}
|
|
@@ -1913,7 +2036,11 @@ var InjectionScanner = class _InjectionScanner {
|
|
|
1913
2036
|
storePii,
|
|
1914
2037
|
language,
|
|
1915
2038
|
aiStatus: "skipped",
|
|
1916
|
-
reason: "ai_scan_disabled_for_high_risk_language"
|
|
2039
|
+
reason: "ai_scan_disabled_for_high_risk_language",
|
|
2040
|
+
systemId: params.systemId,
|
|
2041
|
+
eventId: params.eventId,
|
|
2042
|
+
clientEventId: params.clientEventId,
|
|
2043
|
+
telemetryMetadata: buildTelemetryMetadata()
|
|
1917
2044
|
});
|
|
1918
2045
|
return;
|
|
1919
2046
|
}
|
|
@@ -1932,7 +2059,11 @@ var InjectionScanner = class _InjectionScanner {
|
|
|
1932
2059
|
storePii,
|
|
1933
2060
|
language,
|
|
1934
2061
|
aiStatus: aiResult.status,
|
|
1935
|
-
reason: aiResult.reason
|
|
2062
|
+
reason: aiResult.reason,
|
|
2063
|
+
systemId: params.systemId,
|
|
2064
|
+
eventId: params.eventId,
|
|
2065
|
+
clientEventId: params.clientEventId,
|
|
2066
|
+
telemetryMetadata: buildTelemetryMetadata()
|
|
1936
2067
|
});
|
|
1937
2068
|
return;
|
|
1938
2069
|
}
|
|
@@ -1948,7 +2079,11 @@ var InjectionScanner = class _InjectionScanner {
|
|
|
1948
2079
|
storePii,
|
|
1949
2080
|
language,
|
|
1950
2081
|
aiStatus: aiResult.status,
|
|
1951
|
-
reason: aiResult.reason
|
|
2082
|
+
reason: aiResult.reason,
|
|
2083
|
+
systemId: params.systemId,
|
|
2084
|
+
eventId: params.eventId,
|
|
2085
|
+
clientEventId: params.clientEventId,
|
|
2086
|
+
telemetryMetadata: buildTelemetryMetadata()
|
|
1952
2087
|
});
|
|
1953
2088
|
throw new Error(`AgentID: Prompt injection blocked (${aiResult.reason})`);
|
|
1954
2089
|
}
|
|
@@ -2047,6 +2182,19 @@ function normalizeIngestTimeoutMs(value) {
|
|
|
2047
2182
|
}
|
|
2048
2183
|
return rounded;
|
|
2049
2184
|
}
|
|
2185
|
+
function setFiniteDurationMetadata(metadata, key, value) {
|
|
2186
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2187
|
+
metadata[key] = Math.max(0, Math.trunc(value));
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
function buildSdkTimingMetadata(params) {
|
|
2191
|
+
const metadata = {};
|
|
2192
|
+
setFiniteDurationMetadata(metadata, "sdk_config_fetch_ms", params.sdkConfigFetchMs);
|
|
2193
|
+
setFiniteDurationMetadata(metadata, "sdk_local_scan_ms", params.sdkLocalScanMs);
|
|
2194
|
+
setFiniteDurationMetadata(metadata, "sdk_guard_ms", params.sdkGuardMs);
|
|
2195
|
+
setFiniteDurationMetadata(metadata, "sdk_ingest_ms", params.sdkIngestMs);
|
|
2196
|
+
return metadata;
|
|
2197
|
+
}
|
|
2050
2198
|
function resolveConfiguredApiKey(value) {
|
|
2051
2199
|
const explicit = typeof value === "string" ? value.trim() : "";
|
|
2052
2200
|
const fromEnv = globalThis.process?.env?.AGENTID_API_KEY ?? "";
|
|
@@ -2060,13 +2208,32 @@ function isInfrastructureGuardReason(reason) {
|
|
|
2060
2208
|
if (!reason) return false;
|
|
2061
2209
|
return reason === "system_failure" || reason === "system_failure_db_unavailable" || reason === "logging_failed" || reason === "server_error" || reason === "guard_unreachable" || reason === "api_key_pepper_missing" || reason === "encryption_key_missing";
|
|
2062
2210
|
}
|
|
2063
|
-
function
|
|
2211
|
+
function isGuardFailureEligibleForLocalFallback(reason) {
|
|
2212
|
+
return reason === "network_error_strict_mode" || reason === "server_error" || isInfrastructureGuardReason(reason);
|
|
2213
|
+
}
|
|
2214
|
+
function isFailCloseIngestReason(reason) {
|
|
2215
|
+
if (!reason) return false;
|
|
2216
|
+
return reason === "system_failure" || reason === "system_failure_db_unavailable" || reason === "server_error" || reason === "redis_rate_limit_unavailable" || reason === "redis_quota_unavailable" || reason === "redis_token_quota_unavailable";
|
|
2217
|
+
}
|
|
2218
|
+
function shouldEscalateIngestFailure(params) {
|
|
2219
|
+
if (!params.strictMode) {
|
|
2220
|
+
return false;
|
|
2221
|
+
}
|
|
2222
|
+
if (params.status === null) {
|
|
2223
|
+
return true;
|
|
2224
|
+
}
|
|
2225
|
+
if (params.status >= 500) {
|
|
2226
|
+
return true;
|
|
2227
|
+
}
|
|
2228
|
+
return isFailCloseIngestReason(params.reason);
|
|
2229
|
+
}
|
|
2230
|
+
function isUuidLike2(value) {
|
|
2064
2231
|
if (!value) return false;
|
|
2065
2232
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
|
|
2066
2233
|
value
|
|
2067
2234
|
);
|
|
2068
2235
|
}
|
|
2069
|
-
function
|
|
2236
|
+
function createPseudoUuidV42() {
|
|
2070
2237
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (token) => {
|
|
2071
2238
|
const rand = Math.floor(Math.random() * 16);
|
|
2072
2239
|
const value = token === "x" ? rand : rand & 3 | 8;
|
|
@@ -2077,19 +2244,28 @@ function sanitizeIngestText(value) {
|
|
|
2077
2244
|
const text = typeof value === "string" ? value : String(value ?? "");
|
|
2078
2245
|
return text.slice(0, MAX_INGEST_TEXT_CHARS);
|
|
2079
2246
|
}
|
|
2080
|
-
function
|
|
2081
|
-
if (
|
|
2247
|
+
function normalizeExpectedLanguages(value) {
|
|
2248
|
+
if (!Array.isArray(value)) {
|
|
2249
|
+
return void 0;
|
|
2250
|
+
}
|
|
2251
|
+
const normalized = [...new Set(
|
|
2252
|
+
value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter((entry) => entry.length > 0)
|
|
2253
|
+
)];
|
|
2254
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
2255
|
+
}
|
|
2256
|
+
function createEventId2(seed) {
|
|
2257
|
+
if (isUuidLike2(seed)) return seed;
|
|
2082
2258
|
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
2083
2259
|
return globalThis.crypto.randomUUID();
|
|
2084
2260
|
}
|
|
2085
|
-
return
|
|
2261
|
+
return createPseudoUuidV42();
|
|
2086
2262
|
}
|
|
2087
2263
|
function createCorrelationId(seed) {
|
|
2088
|
-
if (
|
|
2264
|
+
if (isUuidLike2(seed)) return seed;
|
|
2089
2265
|
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
2090
2266
|
return globalThis.crypto.randomUUID();
|
|
2091
2267
|
}
|
|
2092
|
-
return
|
|
2268
|
+
return createPseudoUuidV42();
|
|
2093
2269
|
}
|
|
2094
2270
|
async function waitForRetry(attemptIndex) {
|
|
2095
2271
|
const delay = GUARD_RETRY_DELAYS_MS[attemptIndex];
|
|
@@ -2226,28 +2402,60 @@ var SecurityBlockError = class extends Error {
|
|
|
2226
2402
|
this.reason = reason;
|
|
2227
2403
|
}
|
|
2228
2404
|
};
|
|
2405
|
+
var DependencyError = class extends Error {
|
|
2406
|
+
constructor(params) {
|
|
2407
|
+
const statusLabel = typeof params.status === "number" ? String(params.status) : "network";
|
|
2408
|
+
super(`AgentID dependency failure (${params.dependency}): ${params.reason} [${statusLabel}]`);
|
|
2409
|
+
this.name = "DependencyError";
|
|
2410
|
+
this.dependency = params.dependency;
|
|
2411
|
+
this.reason = params.reason;
|
|
2412
|
+
this.status = params.status;
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2229
2415
|
var AgentID = class {
|
|
2230
2416
|
constructor(config = {}) {
|
|
2231
2417
|
this.injectionScanner = getInjectionScanner();
|
|
2232
2418
|
this.recentGuardVerdicts = /* @__PURE__ */ new Map();
|
|
2233
2419
|
this.apiKey = resolveConfiguredApiKey(config.apiKey);
|
|
2234
2420
|
this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
|
|
2235
|
-
this.
|
|
2421
|
+
this.configuredPiiMasking = typeof config.piiMasking === "boolean" ? config.piiMasking : null;
|
|
2236
2422
|
this.checkInjection = config.checkInjection !== false;
|
|
2423
|
+
this.clientFastFail = config.clientFastFail === true || config.client_fast_fail === true;
|
|
2237
2424
|
this.aiScanEnabled = config.aiScanEnabled !== false;
|
|
2238
2425
|
this.storePii = config.storePii === true;
|
|
2239
2426
|
this.strictMode = config.strictMode === true;
|
|
2427
|
+
if (typeof config.failureMode !== "undefined" && config.failureMode !== "fail_open" && config.failureMode !== "fail_close") {
|
|
2428
|
+
throw new Error("AgentID invalid failureMode. Use 'fail_open' or 'fail_close'.");
|
|
2429
|
+
}
|
|
2430
|
+
if (this.strictMode && config.failureMode === "fail_open") {
|
|
2431
|
+
throw new Error("AgentID strictMode=true conflicts with failureMode='fail_open'.");
|
|
2432
|
+
}
|
|
2433
|
+
this.configuredFailureMode = this.strictMode ? "fail_close" : config.failureMode ?? null;
|
|
2240
2434
|
this.guardTimeoutMs = normalizeGuardTimeoutMs(config.guardTimeoutMs);
|
|
2241
2435
|
this.ingestTimeoutMs = normalizeIngestTimeoutMs(config.ingestTimeoutMs);
|
|
2242
2436
|
this.pii = new PIIManager();
|
|
2243
2437
|
this.localEnforcer = new LocalSecurityEnforcer(this.pii);
|
|
2244
2438
|
void this.getCapabilityConfig();
|
|
2245
2439
|
}
|
|
2246
|
-
|
|
2440
|
+
get piiMasking() {
|
|
2441
|
+
return this.configuredPiiMasking ?? void 0;
|
|
2442
|
+
}
|
|
2443
|
+
resolveEffectivePiiMasking(config) {
|
|
2444
|
+
if (this.configuredPiiMasking !== null) {
|
|
2445
|
+
return this.configuredPiiMasking;
|
|
2446
|
+
}
|
|
2447
|
+
return config?.enable_sdk_pii_masking === true;
|
|
2448
|
+
}
|
|
2449
|
+
getEffectivePiiMasking(options) {
|
|
2450
|
+
return this.resolveEffectivePiiMasking(this.getCachedCapabilityConfig(options));
|
|
2451
|
+
}
|
|
2452
|
+
buildClientCapabilities(framework = "js_sdk", hasFeedbackHandler = false, capabilityConfig) {
|
|
2247
2453
|
return {
|
|
2248
2454
|
capabilities: {
|
|
2249
2455
|
has_feedback_handler: hasFeedbackHandler,
|
|
2250
|
-
pii_masking_enabled: this.
|
|
2456
|
+
pii_masking_enabled: this.resolveEffectivePiiMasking(
|
|
2457
|
+
capabilityConfig ?? this.getCachedCapabilityConfig()
|
|
2458
|
+
),
|
|
2251
2459
|
framework
|
|
2252
2460
|
}
|
|
2253
2461
|
};
|
|
@@ -2261,17 +2469,17 @@ var AgentID = class {
|
|
|
2261
2469
|
}
|
|
2262
2470
|
resolveClientEventId(requestBody) {
|
|
2263
2471
|
const directClientEventId = requestBody.client_event_id;
|
|
2264
|
-
if (typeof directClientEventId === "string" &&
|
|
2472
|
+
if (typeof directClientEventId === "string" && isUuidLike2(directClientEventId)) {
|
|
2265
2473
|
return directClientEventId;
|
|
2266
2474
|
}
|
|
2267
2475
|
const metadata = requestBody.metadata;
|
|
2268
2476
|
if (metadata && typeof metadata === "object" && !Array.isArray(metadata)) {
|
|
2269
2477
|
const metadataClientEventId = metadata.client_event_id;
|
|
2270
|
-
if (typeof metadataClientEventId === "string" &&
|
|
2478
|
+
if (typeof metadataClientEventId === "string" && isUuidLike2(metadataClientEventId)) {
|
|
2271
2479
|
return metadataClientEventId;
|
|
2272
2480
|
}
|
|
2273
2481
|
}
|
|
2274
|
-
return
|
|
2482
|
+
return createEventId2();
|
|
2275
2483
|
}
|
|
2276
2484
|
buildGuardCacheKey(params) {
|
|
2277
2485
|
if (!params.system_id || !params.input) {
|
|
@@ -2315,6 +2523,14 @@ var AgentID = class {
|
|
|
2315
2523
|
force
|
|
2316
2524
|
});
|
|
2317
2525
|
}
|
|
2526
|
+
async getCapabilityConfigWithTelemetry(force = false, options) {
|
|
2527
|
+
const configStartedAt = Date.now();
|
|
2528
|
+
const capabilityConfig = await this.getCapabilityConfig(force, options);
|
|
2529
|
+
return {
|
|
2530
|
+
capabilityConfig,
|
|
2531
|
+
sdkConfigFetchMs: Math.max(0, Date.now() - configStartedAt)
|
|
2532
|
+
};
|
|
2533
|
+
}
|
|
2318
2534
|
getCachedCapabilityConfig(options) {
|
|
2319
2535
|
const effectiveApiKey = this.resolveApiKey(options?.apiKey);
|
|
2320
2536
|
return getCachedCapabilityConfig({
|
|
@@ -2323,12 +2539,32 @@ var AgentID = class {
|
|
|
2323
2539
|
});
|
|
2324
2540
|
}
|
|
2325
2541
|
async resolveEffectiveStrictMode(options) {
|
|
2326
|
-
if (this.strictMode) {
|
|
2542
|
+
if (this.strictMode || this.configuredFailureMode === "fail_close") {
|
|
2327
2543
|
return true;
|
|
2328
2544
|
}
|
|
2545
|
+
if (this.configuredFailureMode === "fail_open") {
|
|
2546
|
+
return false;
|
|
2547
|
+
}
|
|
2329
2548
|
const config = await this.getCapabilityConfig(false, options);
|
|
2330
2549
|
return config.strict_security_mode || config.failure_mode === "fail_close";
|
|
2331
2550
|
}
|
|
2551
|
+
maybeRaiseStrictIngestDependencyError(params) {
|
|
2552
|
+
if (params.result.ok) {
|
|
2553
|
+
return;
|
|
2554
|
+
}
|
|
2555
|
+
if (!shouldEscalateIngestFailure({
|
|
2556
|
+
strictMode: params.strictMode,
|
|
2557
|
+
status: params.result.status,
|
|
2558
|
+
reason: params.result.reason
|
|
2559
|
+
})) {
|
|
2560
|
+
return;
|
|
2561
|
+
}
|
|
2562
|
+
throw new DependencyError({
|
|
2563
|
+
dependency: "ingest",
|
|
2564
|
+
reason: params.result.reason ?? "ingest_failed",
|
|
2565
|
+
status: params.result.status
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2332
2568
|
shouldRunLocalInjectionScan(config) {
|
|
2333
2569
|
if (!this.checkInjection) {
|
|
2334
2570
|
return false;
|
|
@@ -2338,37 +2574,45 @@ var AgentID = class {
|
|
|
2338
2574
|
}
|
|
2339
2575
|
return config.block_on_heuristic;
|
|
2340
2576
|
}
|
|
2341
|
-
async
|
|
2342
|
-
const
|
|
2343
|
-
|
|
2344
|
-
if (!params.skipInjectionScan && params.input && this.shouldRunLocalInjectionScan(capabilityConfig)) {
|
|
2577
|
+
async applyLocalPolicyChecks(params) {
|
|
2578
|
+
const localScanStartedAt = Date.now();
|
|
2579
|
+
if (params.runPromptInjectionCheck && params.input && this.shouldRunLocalInjectionScan(params.capabilityConfig)) {
|
|
2345
2580
|
await this.injectionScanner.scan({
|
|
2346
2581
|
prompt: params.input,
|
|
2347
|
-
apiKey:
|
|
2582
|
+
apiKey: params.apiKey,
|
|
2348
2583
|
baseUrl: this.baseUrl,
|
|
2349
2584
|
aiScanEnabled: this.aiScanEnabled,
|
|
2350
2585
|
storePii: this.storePii,
|
|
2351
2586
|
piiManager: this.pii,
|
|
2352
|
-
source: "js_sdk"
|
|
2587
|
+
source: "js_sdk",
|
|
2588
|
+
systemId: params.systemId,
|
|
2589
|
+
eventId: params.clientEventId,
|
|
2590
|
+
clientEventId: params.clientEventId,
|
|
2591
|
+
telemetryMetadata: buildSdkTimingMetadata({
|
|
2592
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs
|
|
2593
|
+
})
|
|
2353
2594
|
});
|
|
2354
2595
|
}
|
|
2355
2596
|
try {
|
|
2356
2597
|
const enforced = this.localEnforcer.enforce({
|
|
2357
2598
|
input: params.input,
|
|
2358
2599
|
stream: params.stream,
|
|
2359
|
-
config: capabilityConfig
|
|
2600
|
+
config: params.capabilityConfig
|
|
2360
2601
|
});
|
|
2602
|
+
const sdkLocalScanMs = Math.max(0, Date.now() - localScanStartedAt);
|
|
2361
2603
|
for (const event of enforced.events) {
|
|
2362
2604
|
this.logSecurityPolicyViolation({
|
|
2363
2605
|
systemId: params.systemId,
|
|
2364
2606
|
violationType: event.violationType,
|
|
2365
2607
|
actionTaken: event.actionTaken,
|
|
2366
|
-
apiKey:
|
|
2608
|
+
apiKey: params.apiKey,
|
|
2609
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
2610
|
+
sdkLocalScanMs
|
|
2367
2611
|
});
|
|
2368
2612
|
}
|
|
2369
2613
|
return {
|
|
2370
2614
|
sanitizedInput: enforced.sanitizedInput,
|
|
2371
|
-
|
|
2615
|
+
sdkLocalScanMs
|
|
2372
2616
|
};
|
|
2373
2617
|
} catch (error) {
|
|
2374
2618
|
if (error instanceof SecurityPolicyViolationError) {
|
|
@@ -2376,17 +2620,76 @@ var AgentID = class {
|
|
|
2376
2620
|
systemId: params.systemId,
|
|
2377
2621
|
violationType: error.violationType,
|
|
2378
2622
|
actionTaken: error.actionTaken,
|
|
2379
|
-
apiKey:
|
|
2623
|
+
apiKey: params.apiKey,
|
|
2624
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
2625
|
+
sdkLocalScanMs: Math.max(0, Date.now() - localScanStartedAt)
|
|
2380
2626
|
});
|
|
2381
2627
|
}
|
|
2382
2628
|
throw error;
|
|
2383
2629
|
}
|
|
2384
2630
|
}
|
|
2631
|
+
async prepareInputForDispatch(params, options) {
|
|
2632
|
+
const effectiveApiKey = this.resolveApiKey(options?.apiKey);
|
|
2633
|
+
const { capabilityConfig, sdkConfigFetchMs } = await this.getCapabilityConfigWithTelemetry(
|
|
2634
|
+
false,
|
|
2635
|
+
options
|
|
2636
|
+
);
|
|
2637
|
+
if (!this.clientFastFail) {
|
|
2638
|
+
return {
|
|
2639
|
+
sanitizedInput: params.input,
|
|
2640
|
+
capabilityConfig,
|
|
2641
|
+
sdkConfigFetchMs,
|
|
2642
|
+
sdkLocalScanMs: 0
|
|
2643
|
+
};
|
|
2644
|
+
}
|
|
2645
|
+
const enforced = await this.applyLocalPolicyChecks({
|
|
2646
|
+
input: params.input,
|
|
2647
|
+
systemId: params.systemId,
|
|
2648
|
+
stream: params.stream,
|
|
2649
|
+
capabilityConfig,
|
|
2650
|
+
apiKey: effectiveApiKey,
|
|
2651
|
+
clientEventId: params.clientEventId,
|
|
2652
|
+
sdkConfigFetchMs,
|
|
2653
|
+
runPromptInjectionCheck: !params.skipInjectionScan
|
|
2654
|
+
});
|
|
2655
|
+
return {
|
|
2656
|
+
sanitizedInput: enforced.sanitizedInput,
|
|
2657
|
+
capabilityConfig,
|
|
2658
|
+
sdkConfigFetchMs,
|
|
2659
|
+
sdkLocalScanMs: enforced.sdkLocalScanMs
|
|
2660
|
+
};
|
|
2661
|
+
}
|
|
2662
|
+
async applyLocalFallbackForGuardFailure(params, options) {
|
|
2663
|
+
const effectiveApiKey = this.resolveApiKey(options?.apiKey);
|
|
2664
|
+
const resolvedConfig = params.capabilityConfig && typeof params.sdkConfigFetchMs === "number" ? {
|
|
2665
|
+
capabilityConfig: params.capabilityConfig,
|
|
2666
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs
|
|
2667
|
+
} : await this.getCapabilityConfigWithTelemetry(false, options);
|
|
2668
|
+
const enforced = await this.applyLocalPolicyChecks({
|
|
2669
|
+
input: params.input,
|
|
2670
|
+
systemId: params.systemId,
|
|
2671
|
+
stream: params.stream,
|
|
2672
|
+
capabilityConfig: resolvedConfig.capabilityConfig,
|
|
2673
|
+
apiKey: effectiveApiKey,
|
|
2674
|
+
clientEventId: params.clientEventId,
|
|
2675
|
+
sdkConfigFetchMs: resolvedConfig.sdkConfigFetchMs,
|
|
2676
|
+
runPromptInjectionCheck: true
|
|
2677
|
+
});
|
|
2678
|
+
return {
|
|
2679
|
+
sanitizedInput: enforced.sanitizedInput,
|
|
2680
|
+
capabilityConfig: resolvedConfig.capabilityConfig,
|
|
2681
|
+
sdkConfigFetchMs: resolvedConfig.sdkConfigFetchMs,
|
|
2682
|
+
sdkLocalScanMs: enforced.sdkLocalScanMs
|
|
2683
|
+
};
|
|
2684
|
+
}
|
|
2385
2685
|
async scanPromptInjection(input, options) {
|
|
2386
2686
|
if (!input) {
|
|
2387
2687
|
return;
|
|
2388
2688
|
}
|
|
2389
|
-
const capabilityConfig = await this.
|
|
2689
|
+
const { capabilityConfig, sdkConfigFetchMs } = await this.getCapabilityConfigWithTelemetry(
|
|
2690
|
+
false,
|
|
2691
|
+
options
|
|
2692
|
+
);
|
|
2390
2693
|
if (!this.shouldRunLocalInjectionScan(capabilityConfig)) {
|
|
2391
2694
|
return;
|
|
2392
2695
|
}
|
|
@@ -2398,7 +2701,13 @@ var AgentID = class {
|
|
|
2398
2701
|
aiScanEnabled: this.aiScanEnabled,
|
|
2399
2702
|
storePii: this.storePii,
|
|
2400
2703
|
piiManager: this.pii,
|
|
2401
|
-
source: "js_sdk"
|
|
2704
|
+
source: "js_sdk",
|
|
2705
|
+
systemId: options?.systemId,
|
|
2706
|
+
eventId: options?.clientEventId,
|
|
2707
|
+
clientEventId: options?.clientEventId,
|
|
2708
|
+
telemetryMetadata: buildSdkTimingMetadata({
|
|
2709
|
+
sdkConfigFetchMs
|
|
2710
|
+
})
|
|
2402
2711
|
});
|
|
2403
2712
|
}
|
|
2404
2713
|
withMaskedOpenAIRequest(req, maskedText) {
|
|
@@ -2447,7 +2756,11 @@ var AgentID = class {
|
|
|
2447
2756
|
system_id: params.systemId,
|
|
2448
2757
|
violation_type: params.violationType,
|
|
2449
2758
|
input_snippet: "[REDACTED_SAMPLE]",
|
|
2450
|
-
action_taken: params.actionTaken
|
|
2759
|
+
action_taken: params.actionTaken,
|
|
2760
|
+
...buildSdkTimingMetadata({
|
|
2761
|
+
sdkConfigFetchMs: params.sdkConfigFetchMs,
|
|
2762
|
+
sdkLocalScanMs: params.sdkLocalScanMs
|
|
2763
|
+
})
|
|
2451
2764
|
}
|
|
2452
2765
|
}, { apiKey: params.apiKey });
|
|
2453
2766
|
}
|
|
@@ -2473,6 +2786,42 @@ var AgentID = class {
|
|
|
2473
2786
|
{ apiKey: params.apiKey }
|
|
2474
2787
|
);
|
|
2475
2788
|
}
|
|
2789
|
+
async finalizeIngestTelemetry(params) {
|
|
2790
|
+
const controller = new AbortController();
|
|
2791
|
+
const timeoutId = setTimeout(
|
|
2792
|
+
() => controller.abort(),
|
|
2793
|
+
Math.min(this.ingestTimeoutMs, 2e3)
|
|
2794
|
+
);
|
|
2795
|
+
try {
|
|
2796
|
+
const response = await fetch(`${this.baseUrl}/ingest/finalize`, {
|
|
2797
|
+
method: "POST",
|
|
2798
|
+
headers: {
|
|
2799
|
+
"Content-Type": "application/json",
|
|
2800
|
+
"x-agentid-api-key": params.apiKey,
|
|
2801
|
+
"x-correlation-id": params.clientEventId,
|
|
2802
|
+
"X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER
|
|
2803
|
+
},
|
|
2804
|
+
body: JSON.stringify({
|
|
2805
|
+
client_event_id: params.clientEventId,
|
|
2806
|
+
system_id: params.systemId,
|
|
2807
|
+
sdk_ingest_ms: params.sdkIngestMs
|
|
2808
|
+
}),
|
|
2809
|
+
signal: controller.signal
|
|
2810
|
+
});
|
|
2811
|
+
if (!response.ok) {
|
|
2812
|
+
console.warn(
|
|
2813
|
+
`[AgentID] Ingest telemetry finalize failed (status=${response.status}, client_event_id=${params.clientEventId}).`
|
|
2814
|
+
);
|
|
2815
|
+
}
|
|
2816
|
+
} catch (error) {
|
|
2817
|
+
const label = error && typeof error === "object" && error.name === "AbortError" ? "timeout" : "network";
|
|
2818
|
+
console.warn(
|
|
2819
|
+
`[AgentID] Ingest telemetry finalize failed (${label}, client_event_id=${params.clientEventId}).`
|
|
2820
|
+
);
|
|
2821
|
+
} finally {
|
|
2822
|
+
clearTimeout(timeoutId);
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2476
2825
|
/**
|
|
2477
2826
|
* GUARD: Checks limits, PII, and security before execution.
|
|
2478
2827
|
* strictMode=false (default): FAIL-OPEN on connectivity/timeouts.
|
|
@@ -2630,15 +2979,16 @@ var AgentID = class {
|
|
|
2630
2979
|
}
|
|
2631
2980
|
return withGuardLatency({ allowed: true, reason: "guard_unreachable" });
|
|
2632
2981
|
}
|
|
2633
|
-
async sendIngest(params, options) {
|
|
2982
|
+
async sendIngest(params, options, internal) {
|
|
2983
|
+
const ingestStartedAt = Date.now();
|
|
2634
2984
|
const effectiveApiKey = this.resolveApiKey(options?.apiKey);
|
|
2635
|
-
const
|
|
2985
|
+
const transportEventId = createEventId2(internal?.transportEventId ?? params.event_id);
|
|
2636
2986
|
const timestamp = params.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2637
2987
|
const metadata = {
|
|
2638
2988
|
...params.metadata ?? {}
|
|
2639
2989
|
};
|
|
2640
|
-
const metadataClientEventId = typeof metadata.client_event_id === "string" &&
|
|
2641
|
-
const canonicalClientEventId = metadataClientEventId ??
|
|
2990
|
+
const metadataClientEventId = typeof metadata.client_event_id === "string" && isUuidLike2(metadata.client_event_id) ? metadata.client_event_id : null;
|
|
2991
|
+
const canonicalClientEventId = metadataClientEventId ?? transportEventId;
|
|
2642
2992
|
if (!metadataClientEventId) {
|
|
2643
2993
|
metadata.client_event_id = canonicalClientEventId;
|
|
2644
2994
|
}
|
|
@@ -2648,7 +2998,7 @@ var AgentID = class {
|
|
|
2648
2998
|
void this.getCapabilityConfig(false, { apiKey: effectiveApiKey }).catch(() => void 0);
|
|
2649
2999
|
const payload = {
|
|
2650
3000
|
...params,
|
|
2651
|
-
event_id: canonicalClientEventId,
|
|
3001
|
+
event_id: internal?.transportEventId ? transportEventId : canonicalClientEventId,
|
|
2652
3002
|
timestamp,
|
|
2653
3003
|
input: sanitizeIngestText(params.input),
|
|
2654
3004
|
output: sanitizeIngestText(params.output),
|
|
@@ -2673,6 +3023,14 @@ var AgentID = class {
|
|
|
2673
3023
|
});
|
|
2674
3024
|
const responseBody = await safeReadJson2(response);
|
|
2675
3025
|
if (response.ok) {
|
|
3026
|
+
if (!internal?.disableFinalize) {
|
|
3027
|
+
void this.finalizeIngestTelemetry({
|
|
3028
|
+
apiKey: effectiveApiKey,
|
|
3029
|
+
clientEventId: canonicalClientEventId,
|
|
3030
|
+
systemId: params.system_id,
|
|
3031
|
+
sdkIngestMs: Math.max(0, Date.now() - ingestStartedAt)
|
|
3032
|
+
});
|
|
3033
|
+
}
|
|
2676
3034
|
return { ok: true, status: response.status, reason: null };
|
|
2677
3035
|
}
|
|
2678
3036
|
const reason = responseBody && typeof responseBody === "object" && typeof responseBody.reason === "string" ? responseBody.reason ?? null : null;
|
|
@@ -2800,8 +3158,15 @@ var AgentID = class {
|
|
|
2800
3158
|
* Returns a Promise so callers can await persistence when needed.
|
|
2801
3159
|
*/
|
|
2802
3160
|
async log(params, options) {
|
|
2803
|
-
const
|
|
3161
|
+
const effectiveApiKey = this.resolveApiKey(options?.apiKey);
|
|
3162
|
+
const requestOptions = { apiKey: effectiveApiKey };
|
|
3163
|
+
const effectiveStrictMode = await this.resolveEffectiveStrictMode(requestOptions);
|
|
3164
|
+
const result = await this.sendIngest(params, requestOptions);
|
|
2804
3165
|
if (!result.ok) {
|
|
3166
|
+
this.maybeRaiseStrictIngestDependencyError({
|
|
3167
|
+
strictMode: effectiveStrictMode,
|
|
3168
|
+
result
|
|
3169
|
+
});
|
|
2805
3170
|
console.warn(
|
|
2806
3171
|
`[AgentID] Ingest telemetry failed (status=${result.status ?? "network"}, reason=${result.reason ?? "unknown"}).`
|
|
2807
3172
|
);
|
|
@@ -2827,6 +3192,9 @@ var AgentID = class {
|
|
|
2827
3192
|
*/
|
|
2828
3193
|
wrapOpenAI(openai, options) {
|
|
2829
3194
|
const systemId = options.system_id;
|
|
3195
|
+
const expectedLanguages = normalizeExpectedLanguages(
|
|
3196
|
+
options.expected_languages ?? options.expectedLanguages
|
|
3197
|
+
);
|
|
2830
3198
|
const adapter = new OpenAIAdapter();
|
|
2831
3199
|
const wrapChatCompletions = (chatObj) => {
|
|
2832
3200
|
if (!chatObj || typeof chatObj !== "object") return chatObj;
|
|
@@ -2853,6 +3221,8 @@ var AgentID = class {
|
|
|
2853
3221
|
const requestLevelApiKey = options.resolveApiKey?.(req) ?? options.apiKey ?? options.api_key;
|
|
2854
3222
|
const effectiveApiKey = this.resolveApiKey(requestLevelApiKey);
|
|
2855
3223
|
const requestOptions = { apiKey: effectiveApiKey };
|
|
3224
|
+
const clientEventId = this.resolveClientEventId(req);
|
|
3225
|
+
const effectiveStrictMode = await this.resolveEffectiveStrictMode(requestOptions);
|
|
2856
3226
|
const stream = adapter.isStream(req);
|
|
2857
3227
|
let capabilityConfig = this.getCachedCapabilityConfig(requestOptions);
|
|
2858
3228
|
const userText = adapter.extractInput(req);
|
|
@@ -2861,16 +3231,19 @@ var AgentID = class {
|
|
|
2861
3231
|
let createArgs = normalizedCreateArgs;
|
|
2862
3232
|
let mapping = {};
|
|
2863
3233
|
let shouldDeanonymize = false;
|
|
3234
|
+
let sdkConfigFetchMs = 0;
|
|
3235
|
+
let sdkLocalScanMs = 0;
|
|
2864
3236
|
if (userText) {
|
|
2865
|
-
await this.scanPromptInjection(userText, requestOptions);
|
|
2866
3237
|
const prepared = await this.prepareInputForDispatch({
|
|
2867
3238
|
input: userText,
|
|
2868
3239
|
systemId,
|
|
2869
3240
|
stream,
|
|
2870
|
-
|
|
3241
|
+
clientEventId
|
|
2871
3242
|
}, requestOptions);
|
|
2872
3243
|
capabilityConfig = prepared.capabilityConfig;
|
|
2873
3244
|
maskedText = prepared.sanitizedInput;
|
|
3245
|
+
sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
|
|
3246
|
+
sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
|
|
2874
3247
|
if (maskedText !== userText) {
|
|
2875
3248
|
maskedReq = this.withMaskedOpenAIRequest(
|
|
2876
3249
|
req,
|
|
@@ -2880,7 +3253,8 @@ var AgentID = class {
|
|
|
2880
3253
|
nextCreateArgs[0] = maskedReq;
|
|
2881
3254
|
createArgs = nextCreateArgs;
|
|
2882
3255
|
}
|
|
2883
|
-
|
|
3256
|
+
const effectivePiiMasking = this.resolveEffectivePiiMasking(capabilityConfig);
|
|
3257
|
+
if (!capabilityConfig.block_pii_leakage && effectivePiiMasking) {
|
|
2884
3258
|
if (stream) {
|
|
2885
3259
|
console.warn("AgentID: PII masking is disabled for streaming responses.");
|
|
2886
3260
|
} else {
|
|
@@ -2903,19 +3277,54 @@ var AgentID = class {
|
|
|
2903
3277
|
"AgentID: No user message found. Security guard requires string input."
|
|
2904
3278
|
);
|
|
2905
3279
|
}
|
|
2906
|
-
const clientEventId = this.resolveClientEventId(req);
|
|
2907
3280
|
const verdict = await this.guard({
|
|
2908
3281
|
input: maskedText,
|
|
2909
3282
|
system_id: systemId,
|
|
2910
3283
|
model: adapter.getModelName(maskedReq),
|
|
2911
3284
|
user_id: options.user_id,
|
|
2912
3285
|
client_event_id: clientEventId,
|
|
2913
|
-
|
|
3286
|
+
expected_languages: expectedLanguages,
|
|
3287
|
+
client_capabilities: this.buildClientCapabilities(
|
|
3288
|
+
"openai",
|
|
3289
|
+
false,
|
|
3290
|
+
capabilityConfig
|
|
3291
|
+
)
|
|
2914
3292
|
}, requestOptions);
|
|
3293
|
+
let localFallbackApplied = false;
|
|
3294
|
+
let localFallbackReason = null;
|
|
2915
3295
|
if (!verdict.allowed) {
|
|
2916
|
-
|
|
3296
|
+
if (effectiveStrictMode && isGuardFailureEligibleForLocalFallback(verdict.reason)) {
|
|
3297
|
+
localFallbackApplied = true;
|
|
3298
|
+
localFallbackReason = verdict.reason ?? "guard_unreachable";
|
|
3299
|
+
if (sdkLocalScanMs === 0) {
|
|
3300
|
+
const fallback = await this.applyLocalPolicyChecks({
|
|
3301
|
+
input: maskedText,
|
|
3302
|
+
systemId,
|
|
3303
|
+
stream,
|
|
3304
|
+
capabilityConfig,
|
|
3305
|
+
apiKey: effectiveApiKey,
|
|
3306
|
+
clientEventId,
|
|
3307
|
+
sdkConfigFetchMs,
|
|
3308
|
+
runPromptInjectionCheck: true
|
|
3309
|
+
});
|
|
3310
|
+
maskedText = fallback.sanitizedInput;
|
|
3311
|
+
sdkLocalScanMs = fallback.sdkLocalScanMs;
|
|
3312
|
+
}
|
|
3313
|
+
} else {
|
|
3314
|
+
throw new SecurityBlockError(verdict.reason ?? "guard_denied");
|
|
3315
|
+
}
|
|
2917
3316
|
}
|
|
2918
|
-
const
|
|
3317
|
+
const currentRequestInput = adapter.extractInput(maskedReq);
|
|
3318
|
+
if (maskedText !== currentRequestInput) {
|
|
3319
|
+
maskedReq = this.withMaskedOpenAIRequest(
|
|
3320
|
+
req,
|
|
3321
|
+
maskedText
|
|
3322
|
+
);
|
|
3323
|
+
const nextCreateArgs = [...normalizedCreateArgs];
|
|
3324
|
+
nextCreateArgs[0] = maskedReq;
|
|
3325
|
+
createArgs = nextCreateArgs;
|
|
3326
|
+
}
|
|
3327
|
+
const canonicalClientEventId = typeof verdict.client_event_id === "string" && isUuidLike2(verdict.client_event_id) ? verdict.client_event_id : clientEventId;
|
|
2919
3328
|
const guardEventId = typeof verdict.guard_event_id === "string" && verdict.guard_event_id.length > 0 ? verdict.guard_event_id : null;
|
|
2920
3329
|
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);
|
|
2921
3330
|
const transparency = coerceTransparencyMetadata(verdict.transparency);
|
|
@@ -2964,16 +3373,31 @@ var AgentID = class {
|
|
|
2964
3373
|
simulated_decision: verdict.simulated_decision ?? null,
|
|
2965
3374
|
simulated_output_decision: isShadowMode && result.outputMasked ? "masked" : "allowed",
|
|
2966
3375
|
response_streamed: true,
|
|
3376
|
+
sdk_local_fallback_applied: localFallbackApplied,
|
|
3377
|
+
sdk_local_fallback_reason: localFallbackReason,
|
|
2967
3378
|
guard_latency_ms: guardLatencyMs,
|
|
2968
3379
|
model_latency_ms: modelLatencyMs2,
|
|
2969
3380
|
total_pipeline_latency_ms: totalPipelineLatencyMs2,
|
|
2970
3381
|
guard_event_id: guardEventId,
|
|
2971
3382
|
client_event_id: canonicalClientEventId,
|
|
2972
|
-
transparency
|
|
3383
|
+
transparency,
|
|
3384
|
+
...buildSdkTimingMetadata({
|
|
3385
|
+
sdkConfigFetchMs,
|
|
3386
|
+
sdkLocalScanMs,
|
|
3387
|
+
sdkGuardMs: guardLatencyMs
|
|
3388
|
+
})
|
|
2973
3389
|
},
|
|
2974
|
-
client_capabilities: this.buildClientCapabilities(
|
|
3390
|
+
client_capabilities: this.buildClientCapabilities(
|
|
3391
|
+
"openai",
|
|
3392
|
+
false,
|
|
3393
|
+
capabilityConfig
|
|
3394
|
+
)
|
|
2975
3395
|
}, requestOptions);
|
|
2976
3396
|
if (!ingestResult.ok) {
|
|
3397
|
+
this.maybeRaiseStrictIngestDependencyError({
|
|
3398
|
+
strictMode: effectiveStrictMode,
|
|
3399
|
+
result: ingestResult
|
|
3400
|
+
});
|
|
2977
3401
|
console.warn(
|
|
2978
3402
|
`[AgentID] Stream ingest telemetry failed (status=${ingestResult.status ?? "network"}, reason=${ingestResult.reason ?? "unknown"}).`
|
|
2979
3403
|
);
|
|
@@ -3015,22 +3439,37 @@ var AgentID = class {
|
|
|
3015
3439
|
simulated_decision: verdict.simulated_decision ?? null,
|
|
3016
3440
|
simulated_output_decision: isShadowMode && wrappedCompletion.outputMasked ? "masked" : "allowed",
|
|
3017
3441
|
response_streamed: false,
|
|
3442
|
+
sdk_local_fallback_applied: localFallbackApplied,
|
|
3443
|
+
sdk_local_fallback_reason: localFallbackReason,
|
|
3018
3444
|
guard_latency_ms: guardLatencyMs,
|
|
3019
3445
|
model_latency_ms: modelLatencyMs,
|
|
3020
3446
|
total_pipeline_latency_ms: totalPipelineLatencyMs,
|
|
3021
3447
|
guard_event_id: guardEventId,
|
|
3022
3448
|
client_event_id: canonicalClientEventId,
|
|
3023
|
-
transparency
|
|
3449
|
+
transparency,
|
|
3450
|
+
...buildSdkTimingMetadata({
|
|
3451
|
+
sdkConfigFetchMs,
|
|
3452
|
+
sdkLocalScanMs,
|
|
3453
|
+
sdkGuardMs: guardLatencyMs
|
|
3454
|
+
})
|
|
3024
3455
|
},
|
|
3025
|
-
client_capabilities: this.buildClientCapabilities(
|
|
3456
|
+
client_capabilities: this.buildClientCapabilities(
|
|
3457
|
+
"openai",
|
|
3458
|
+
false,
|
|
3459
|
+
capabilityConfig
|
|
3460
|
+
)
|
|
3026
3461
|
}, requestOptions);
|
|
3027
3462
|
if (!ingestResult.ok) {
|
|
3463
|
+
this.maybeRaiseStrictIngestDependencyError({
|
|
3464
|
+
strictMode: effectiveStrictMode,
|
|
3465
|
+
result: ingestResult
|
|
3466
|
+
});
|
|
3028
3467
|
console.warn(
|
|
3029
3468
|
`[AgentID] Ingest telemetry failed (status=${ingestResult.status ?? "network"}, reason=${ingestResult.reason ?? "unknown"}).`
|
|
3030
3469
|
);
|
|
3031
3470
|
}
|
|
3032
3471
|
}
|
|
3033
|
-
if (!capabilityConfig.block_pii_leakage && this.
|
|
3472
|
+
if (!capabilityConfig.block_pii_leakage && this.resolveEffectivePiiMasking(capabilityConfig) && shouldDeanonymize) {
|
|
3034
3473
|
const deanon = this.pii.deanonymize(adapter.extractOutput(res), mapping);
|
|
3035
3474
|
try {
|
|
3036
3475
|
if (Array.isArray(res?.choices)) {
|
|
@@ -3084,7 +3523,7 @@ function normalizeBaseUrl4(baseUrl) {
|
|
|
3084
3523
|
const candidate = typeof baseUrl === "string" && baseUrl.trim().length > 0 ? baseUrl.trim() : DEFAULT_BASE_URL;
|
|
3085
3524
|
return candidate.replace(/\/+$/, "");
|
|
3086
3525
|
}
|
|
3087
|
-
function
|
|
3526
|
+
function createEventId3() {
|
|
3088
3527
|
try {
|
|
3089
3528
|
if (typeof globalThis !== "undefined" && globalThis.crypto?.randomUUID) {
|
|
3090
3529
|
return globalThis.crypto.randomUUID();
|
|
@@ -3096,7 +3535,7 @@ function createEventId2() {
|
|
|
3096
3535
|
}
|
|
3097
3536
|
async function sendTransparencyBadgeRenderedTelemetry(params) {
|
|
3098
3537
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3099
|
-
const eventId =
|
|
3538
|
+
const eventId = createEventId3();
|
|
3100
3539
|
const payload = {
|
|
3101
3540
|
event_id: eventId,
|
|
3102
3541
|
system_id: params.telemetry.systemId,
|
|
@@ -3228,6 +3667,7 @@ function AgentIDTransparencyBadge(props) {
|
|
|
3228
3667
|
0 && (module.exports = {
|
|
3229
3668
|
AgentID,
|
|
3230
3669
|
AgentIDTransparencyBadge,
|
|
3670
|
+
DependencyError,
|
|
3231
3671
|
InjectionScanner,
|
|
3232
3672
|
OpenAIAdapter,
|
|
3233
3673
|
PIIManager,
|