agentid-sdk 0.1.18 → 0.1.19

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 CHANGED
@@ -1,65 +1,197 @@
1
- # 🛡️ AgentID: Enterprise AI Governance & PII Shield
1
+ # agentid-sdk (Node.js / TypeScript)
2
2
 
3
- AgentID je inteligentní brána (gateway) pro vaše LLM aplikace. Monitoruje náklady, filtruje PII (osobní údaje) v reálném čase a zajišťuje soulad s GDPR.
3
+ [![npm version](https://img.shields.io/npm/v/agentid-sdk.svg)](https://www.npmjs.com/package/agentid-sdk)
4
+ [![Node](https://img.shields.io/node/v/agentid-sdk.svg)](https://www.npmjs.com/package/agentid-sdk)
5
+ [![Node >=18](https://img.shields.io/badge/node-%3E%3D18-339933.svg)](https://nodejs.org/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
7
 
5
- ## 🚀 Rychlý start (60 sekund)
8
+ ## 1. Introduction
6
9
 
7
- ### 1. Instalace
10
+ `agentid-sdk` is the official Node.js/TypeScript SDK for AgentID, an AI security and compliance System of Record. It allows you to gate LLM traffic through guard checks, enforce policy before execution, and capture durable telemetry for audit and governance workflows.
8
11
 
9
- ```bash
10
- # Pro Python projekty
11
- pip install agentid-sdk
12
+ ## 2. Installation
12
13
 
13
- # Pro JavaScript/TypeScript projekty
14
+ ```bash
14
15
  npm install agentid-sdk
15
16
  ```
16
17
 
17
- ### 2. Integrace (Python)
18
+ ## 3. Prerequisites
19
+
20
+ 1. Create an account at `https://app.getagentid.com`.
21
+ 2. Create an AI system and copy:
22
+ - `AGENTID_API_KEY` (for example `sk_live_...`)
23
+ - `AGENTID_SYSTEM_ID` (UUID)
24
+ 3. If using OpenAI/LangChain, set:
25
+ - `OPENAI_API_KEY`
26
+
27
+ ```bash
28
+ export AGENTID_API_KEY="sk_live_..."
29
+ export AGENTID_SYSTEM_ID="00000000-0000-0000-0000-000000000000"
30
+ export OPENAI_API_KEY="sk-proj-..."
31
+ ```
18
32
 
19
- Stačí zabalit vašeho stávajícího OpenAI klienta.
33
+ ## 4. Quickstart
20
34
 
21
- ```python
22
- from openai import OpenAI
23
- from agentid import AgentID
35
+ ```ts
36
+ import { AgentID } from "agentid-sdk";
24
37
 
25
- client = OpenAI(api_key="your_openai_key")
26
- agent = AgentID(api_key="ag_prod_...")
38
+ const agent = new AgentID(); // auto-loads AGENTID_API_KEY
39
+ const systemId = process.env.AGENTID_SYSTEM_ID!;
27
40
 
28
- # Automaticky filtruje PII a loguje metriky
29
- response = agent.wrap_openai(client, system_id="sys_...").chat.completions.create(
30
- model="gpt-4",
31
- messages=[{"role": "user", "content": "Můj email je jan.novak@firma.cz"}]
32
- )
41
+ const verdict = await agent.guard({
42
+ system_id: systemId,
43
+ input: "Summarize this ticket in one sentence.",
44
+ model: "gpt-4o-mini",
45
+ user_id: "quickstart-user",
46
+ });
47
+ if (!verdict.allowed) throw new Error(`Blocked: ${verdict.reason}`);
48
+
49
+ await agent.log({
50
+ system_id: systemId,
51
+ event_id: verdict.client_event_id,
52
+ model: "gpt-4o-mini",
53
+ input: "Summarize this ticket in one sentence.",
54
+ output: "Summary generated.",
55
+ metadata: { agent_role: "support-assistant" },
56
+ });
33
57
  ```
34
58
 
35
- ### 3. Integrace (Node.js)
59
+ ## 5. Core Integrations
60
+
61
+ ### OpenAI Wrapper
62
+
63
+ ```bash
64
+ npm install agentid-sdk openai
65
+ ```
36
66
 
37
67
  ```ts
38
- import { AgentID } from "agentid-sdk";
39
68
  import OpenAI from "openai";
69
+ import { AgentID } from "agentid-sdk";
40
70
 
41
- const openai = new OpenAI();
42
71
  const agent = new AgentID({
43
- apiKey: "ag_prod_...",
44
- strictMode: false, // default (fail-open on timeout/unreachable AgentID API)
45
- guardTimeoutMs: 6000, // optional: timeout for AgentID /guard call in ms
46
- // strictMode: true, // fail-closed for high-risk workloads
72
+ piiMasking: true,
73
+ });
74
+
75
+ const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY! });
76
+ const secured = agent.wrapOpenAI(openai, {
77
+ system_id: process.env.AGENTID_SYSTEM_ID!,
78
+ user_id: "customer-123",
79
+ });
80
+
81
+ const response = await secured.chat.completions.create({
82
+ model: "gpt-4o-mini",
83
+ messages: [{ role: "user", content: "What is the capital of the Czech Republic?" }],
84
+ });
85
+
86
+ console.log(response.choices[0]?.message?.content ?? "");
87
+ ```
88
+
89
+ ### LangChain Integration
90
+
91
+ ```bash
92
+ npm install agentid-sdk openai @langchain/core @langchain/openai
93
+ ```
94
+
95
+ ```ts
96
+ import { AgentID } from "agentid-sdk";
97
+ import { AgentIDCallbackHandler } from "agentid-sdk/langchain";
98
+ import { ChatOpenAI } from "@langchain/openai";
99
+ import { ChatPromptTemplate } from "@langchain/core/prompts";
100
+ import { StringOutputParser } from "@langchain/core/output_parsers";
101
+
102
+ const agent = new AgentID();
103
+ const handler = new AgentIDCallbackHandler(agent, {
104
+ system_id: process.env.AGENTID_SYSTEM_ID!,
47
105
  });
48
106
 
49
- const proxiedOpenAI = agent.wrapOpenAI(openai, {
50
- system_id: "sys_...",
51
- user_id: "system-auto-summary", // optional service/user identity
107
+ const prompt = ChatPromptTemplate.fromTemplate("Answer in one sentence: {question}");
108
+ const model = new ChatOpenAI({
109
+ apiKey: process.env.OPENAI_API_KEY!,
110
+ model: "gpt-4o-mini",
52
111
  });
112
+ const chain = prompt.pipe(model).pipe(new StringOutputParser());
113
+
114
+ const result = await chain.invoke(
115
+ { question: "What is the capital of the Czech Republic?" },
116
+ { callbacks: [handler] }
117
+ );
118
+ console.log(result);
53
119
  ```
54
120
 
55
- ## 🔒 Klíčové vlastnosti
121
+ ### Raw Ingest API (Telemetry Only)
122
+
123
+ ```ts
124
+ import { AgentID } from "agentid-sdk";
125
+
126
+ const agent = new AgentID();
127
+
128
+ await agent.log({
129
+ system_id: process.env.AGENTID_SYSTEM_ID!,
130
+ event_type: "complete",
131
+ severity: "info",
132
+ model: "gpt-4o-mini",
133
+ input: "Raw telemetry prompt",
134
+ output: '{"ok": true}',
135
+ metadata: { agent_role: "batch-worker", channel: "manual_ingest" },
136
+ });
137
+ ```
138
+
139
+ ## 6. Advanced Configuration
140
+
141
+ ### Custom identity / role metadata
142
+
143
+ ```ts
144
+ await agent.guard({
145
+ system_id: process.env.AGENTID_SYSTEM_ID!,
146
+ input: "Process user request",
147
+ user_id: "service:billing-agent",
148
+ model: "gpt-4o-mini",
149
+ });
150
+
151
+ await agent.log({
152
+ system_id: process.env.AGENTID_SYSTEM_ID!,
153
+ model: "gpt-4o-mini",
154
+ input: "Process user request",
155
+ output: "Done",
156
+ metadata: { agent_role: "billing-agent", environment: "prod" },
157
+ });
158
+ ```
159
+
160
+ ### Strict mode and timeout tuning
161
+
162
+ ```ts
163
+ const agent = new AgentID({
164
+ strictMode: true, // fail-closed on guard connectivity/timeouts
165
+ guardTimeoutMs: 10000, // default guard timeout is 10000ms
166
+ });
167
+ ```
168
+
169
+ ### Error handling behavior
170
+
171
+ - `guard()` returns a verdict (`allowed`, `reason`); handle deny paths explicitly.
172
+ - `wrapOpenAI()` throws `Error("AgentID: Security Blocked (...)")` when blocked.
173
+ - Default mode is fail-open for connectivity/timeouts (`timeout_fallback`, `guard_unreachable`, `system_failure_fail_open`).
174
+ - If `strictMode` is not explicitly set in SDK code, runtime behavior follows the system configuration from AgentID (`strict_security_mode` / `failure_mode`).
175
+ - Set `strictMode: true` to fail-closed (`network_error_strict_mode` / `server_error`) in high-sensitivity environments.
176
+ - Ingest retries transient failures (5xx/429) and logs warnings if persistence fails.
177
+
178
+ ## 7. Security & Compliance
179
+
180
+ - Optional local PII masking and local policy enforcement before model dispatch.
181
+ - Prompt-injection scanning in the SDK request path.
182
+ - Guard checks run pre-execution; ingest telemetry captures prompt/output lifecycle.
183
+ - Safe for server and serverless runtimes (including async completion flows).
184
+ - Supports compliance and forensics workflows with durable event records.
185
+
186
+ ## 8. Support
187
+
188
+ - Dashboard: `https://app.getagentid.com`
189
+ - Repository: `https://github.com/ondrejsukac-rgb/agentid/tree/main/js-sdk`
190
+ - Issues: `https://github.com/ondrejsukac-rgb/agentid/issues`
56
191
 
57
- - PII Scrubbing: Automatická redakce e-mailů, rodných čísel a hesel před odesláním do cloudu.
58
- - Crypto-Shredding: Možnost nenávratně smazat citlivá data z logů na žádost uživatele (GDPR).
59
- - Fail-Safe architektura: Inteligentní přepínání mezi bezpečností a dostupností (Fail-Open/Closed).
60
- - Strict mode: při timeoutu Guard API můžeš vynutit fail-closed (`strictMode: true`).
192
+ ## 9. Publishing Notes (NPM)
61
193
 
62
- ## Guard transformed input
194
+ NPM automatically renders `README.md` from the package root during `npm publish`.
63
195
 
64
- If `/guard` returns `transformed_input`, the OpenAI and LangChain wrappers automatically
65
- forward that transformed value to the downstream LLM call.
196
+ - File location: next to `package.json` in `js-sdk/`.
197
+ - No additional NPM config is required for README rendering.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AgentID, a as AgentIDCallbackHandler, G as GuardParams, b as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions } from './langchain-BykeB2WB.mjs';
1
+ export { A as AgentID, a as AgentIDCallbackHandler, G as GuardParams, b as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions } from './langchain-DJDqqpbT.mjs';
2
2
  import '@langchain/core/callbacks/base';
3
3
 
4
4
  type PIIMapping = Record<string, string>;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AgentID, a as AgentIDCallbackHandler, G as GuardParams, b as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions } from './langchain-BykeB2WB.js';
1
+ export { A as AgentID, a as AgentIDCallbackHandler, G as GuardParams, b as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions } from './langchain-DJDqqpbT.js';
2
2
  import '@langchain/core/callbacks/base';
3
3
 
4
4
  type PIIMapping = Record<string, string>;
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.18".trim().length > 0 ? "js-0.1.18" : FALLBACK_SDK_VERSION;
87
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.19".trim().length > 0 ? "js-0.1.19" : FALLBACK_SDK_VERSION;
88
88
 
89
89
  // src/pii-national-identifiers.ts
90
90
  var MAX_CANDIDATES_PER_RULE = 256;
@@ -1115,12 +1115,14 @@ var PIIManager = class {
1115
1115
  };
1116
1116
 
1117
1117
  // src/local-security-enforcer.ts
1118
- var DEFAULT_STRICT_CONFIG = {
1118
+ var DEFAULT_FAIL_OPEN_CONFIG = {
1119
1119
  shadow_mode: false,
1120
- block_pii_leakage: true,
1121
- block_db_access: true,
1122
- block_code_execution: true,
1123
- block_toxicity: true
1120
+ strict_security_mode: false,
1121
+ failure_mode: "fail_open",
1122
+ block_pii_leakage: false,
1123
+ block_db_access: false,
1124
+ block_code_execution: false,
1125
+ block_toxicity: false
1124
1126
  };
1125
1127
  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;
1126
1128
  var PYTHON_GENERAL_RCE_PATTERN = /(import\s+(os|sys|subprocess)|from\s+(os|sys|subprocess)\s+import|exec\s*\(|eval\s*\(|__import__)/i;
@@ -1243,13 +1245,28 @@ function readOptionalBooleanField(body, key, fallback) {
1243
1245
  }
1244
1246
  throw new Error(`Invalid config field: ${key}`);
1245
1247
  }
1248
+ function readOptionalFailureModeField(body, fallback) {
1249
+ const value = body.failure_mode;
1250
+ if (value === "fail_open" || value === "fail_close") {
1251
+ return value;
1252
+ }
1253
+ return fallback;
1254
+ }
1246
1255
  function normalizeCapabilityConfig(payload) {
1247
1256
  if (!payload || typeof payload !== "object") {
1248
1257
  throw new Error("Invalid config payload");
1249
1258
  }
1250
1259
  const body = payload;
1260
+ const strictSecurityMode = readOptionalBooleanField(body, "strict_security_mode", false);
1261
+ const failureMode = readOptionalFailureModeField(
1262
+ body,
1263
+ strictSecurityMode ? "fail_close" : "fail_open"
1264
+ );
1265
+ const effectiveStrictMode = strictSecurityMode || failureMode === "fail_close";
1251
1266
  return {
1252
1267
  shadow_mode: readOptionalBooleanField(body, "shadow_mode", false),
1268
+ strict_security_mode: effectiveStrictMode,
1269
+ failure_mode: effectiveStrictMode ? "fail_close" : "fail_open",
1253
1270
  block_pii_leakage: readBooleanField(body, "block_pii_leakage", "block_pii"),
1254
1271
  block_db_access: readBooleanField(body, "block_db_access", "block_db"),
1255
1272
  block_code_execution: readBooleanField(
@@ -1353,7 +1370,7 @@ async function fetchCapabilityConfigWithTimeout(params) {
1353
1370
  function getCachedCapabilityConfig(params) {
1354
1371
  const key = getCacheKey(params.apiKey, params.baseUrl);
1355
1372
  const entry = getGlobalCache().get(key);
1356
- return entry?.config ?? DEFAULT_STRICT_CONFIG;
1373
+ return entry?.config ?? DEFAULT_FAIL_OPEN_CONFIG;
1357
1374
  }
1358
1375
  async function ensureCapabilityConfig(params) {
1359
1376
  const ttlMs = params.ttlMs ?? CONFIG_TTL_MS;
@@ -1382,14 +1399,15 @@ async function ensureCapabilityConfig(params) {
1382
1399
  return resolved;
1383
1400
  }).catch((error) => {
1384
1401
  const message = error instanceof Error ? error.message : String(error);
1385
- console.warn("AgentID Config unreachable. Defaulting to STRICT MODE.", message);
1402
+ const fallbackConfig = existing?.config ?? DEFAULT_FAIL_OPEN_CONFIG;
1403
+ console.warn("AgentID Config unreachable. Defaulting to FAIL-OPEN MODE.", message);
1386
1404
  cache.set(key, {
1387
- config: DEFAULT_STRICT_CONFIG,
1405
+ config: fallbackConfig,
1388
1406
  expiresAt: Date.now() + ttlMs,
1389
1407
  promise: null
1390
1408
  });
1391
1409
  enforceCacheBound(cache);
1392
- return DEFAULT_STRICT_CONFIG;
1410
+ return fallbackConfig;
1393
1411
  }).finally(() => {
1394
1412
  const latest = cache.get(key);
1395
1413
  if (!latest) {
@@ -1405,7 +1423,7 @@ async function ensureCapabilityConfig(params) {
1405
1423
  }
1406
1424
  });
1407
1425
  cache.set(key, {
1408
- config: existing?.config ?? DEFAULT_STRICT_CONFIG,
1426
+ config: existing?.config ?? DEFAULT_FAIL_OPEN_CONFIG,
1409
1427
  expiresAt: existing?.expiresAt ?? 0,
1410
1428
  promise: pending
1411
1429
  });
@@ -1878,6 +1896,15 @@ function normalizeGuardTimeoutMs(value) {
1878
1896
  }
1879
1897
  return rounded;
1880
1898
  }
1899
+ function resolveConfiguredApiKey(value) {
1900
+ const explicit = typeof value === "string" ? value.trim() : "";
1901
+ const fromEnv = globalThis.process?.env?.AGENTID_API_KEY ?? "";
1902
+ const resolved = explicit || fromEnv.trim();
1903
+ if (!resolved) {
1904
+ throw new Error("AgentID API key missing. Pass apiKey or set AGENTID_API_KEY.");
1905
+ }
1906
+ return resolved;
1907
+ }
1881
1908
  function isInfrastructureGuardReason(reason) {
1882
1909
  if (!reason) return false;
1883
1910
  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";
@@ -1995,10 +2022,10 @@ function createCompletionChunkCollector() {
1995
2022
  };
1996
2023
  }
1997
2024
  var AgentID = class {
1998
- constructor(config) {
2025
+ constructor(config = {}) {
1999
2026
  this.injectionScanner = getInjectionScanner();
2000
2027
  this.recentGuardVerdicts = /* @__PURE__ */ new Map();
2001
- this.apiKey = config.apiKey.trim();
2028
+ this.apiKey = resolveConfiguredApiKey(config.apiKey);
2002
2029
  this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
2003
2030
  this.piiMasking = Boolean(config.piiMasking);
2004
2031
  this.checkInjection = config.checkInjection !== false;
@@ -2089,6 +2116,13 @@ var AgentID = class {
2089
2116
  baseUrl: this.baseUrl
2090
2117
  });
2091
2118
  }
2119
+ async resolveEffectiveStrictMode(options) {
2120
+ if (this.strictMode) {
2121
+ return true;
2122
+ }
2123
+ const config = await this.getCapabilityConfig(false, options);
2124
+ return config.strict_security_mode || config.failure_mode === "fail_close";
2125
+ }
2092
2126
  async prepareInputForDispatch(params, options) {
2093
2127
  const effectiveApiKey = this.resolveApiKey(options?.apiKey);
2094
2128
  if (this.checkInjection && !params.skipInjectionScan && params.input) {
@@ -2227,6 +2261,9 @@ var AgentID = class {
2227
2261
  */
2228
2262
  async guard(params, options) {
2229
2263
  const effectiveApiKey = this.resolveApiKey(options?.apiKey);
2264
+ const effectiveStrictMode = await this.resolveEffectiveStrictMode({
2265
+ apiKey: effectiveApiKey
2266
+ });
2230
2267
  const payload = {
2231
2268
  ...params,
2232
2269
  client_capabilities: params.client_capabilities ?? this.buildClientCapabilities()
@@ -2265,7 +2302,7 @@ var AgentID = class {
2265
2302
  await waitForRetry(attempt);
2266
2303
  continue;
2267
2304
  }
2268
- if (this.strictMode) {
2305
+ if (effectiveStrictMode) {
2269
2306
  console.warn(
2270
2307
  `[AgentID] Guard API infrastructure failure in strict mode (${verdict.reason ?? `http_${res.status}`}). Blocking request.`
2271
2308
  );
@@ -2312,13 +2349,13 @@ var AgentID = class {
2312
2349
  guardParams: params,
2313
2350
  apiKey: effectiveApiKey
2314
2351
  });
2315
- if (this.strictMode) {
2352
+ if (effectiveStrictMode) {
2316
2353
  return { allowed: false, reason: "network_error_strict_mode" };
2317
2354
  }
2318
2355
  return { allowed: true, reason: "timeout_fallback" };
2319
2356
  }
2320
2357
  console.warn(
2321
- this.strictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2358
+ effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2322
2359
  error
2323
2360
  );
2324
2361
  this.logGuardFallback({
@@ -2327,7 +2364,7 @@ var AgentID = class {
2327
2364
  guardParams: params,
2328
2365
  apiKey: effectiveApiKey
2329
2366
  });
2330
- if (this.strictMode) {
2367
+ if (effectiveStrictMode) {
2331
2368
  return { allowed: false, reason: "network_error_strict_mode" };
2332
2369
  }
2333
2370
  return { allowed: true, reason: "guard_unreachable" };
@@ -2336,22 +2373,22 @@ var AgentID = class {
2336
2373
  }
2337
2374
  }
2338
2375
  if (lastAbort) {
2339
- if (this.strictMode) {
2376
+ if (effectiveStrictMode) {
2340
2377
  return { allowed: false, reason: "network_error_strict_mode" };
2341
2378
  }
2342
2379
  return { allowed: true, reason: "timeout_fallback" };
2343
2380
  }
2344
2381
  if (typeof lastStatusCode === "number" && lastStatusCode >= 500) {
2345
- if (this.strictMode) {
2382
+ if (effectiveStrictMode) {
2346
2383
  return { allowed: false, reason: "server_error" };
2347
2384
  }
2348
2385
  return { allowed: true, reason: "system_failure_fail_open" };
2349
2386
  }
2350
2387
  console.warn(
2351
- this.strictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2388
+ effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2352
2389
  lastError
2353
2390
  );
2354
- if (this.strictMode) {
2391
+ if (effectiveStrictMode) {
2355
2392
  return { allowed: false, reason: "network_error_strict_mode" };
2356
2393
  }
2357
2394
  return { allowed: true, reason: "guard_unreachable" };
package/dist/index.mjs CHANGED
@@ -46,7 +46,7 @@ var OpenAIAdapter = class {
46
46
 
47
47
  // src/sdk-version.ts
48
48
  var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
49
- var AGENTID_SDK_VERSION_HEADER = "js-0.1.18".trim().length > 0 ? "js-0.1.18" : FALLBACK_SDK_VERSION;
49
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.19".trim().length > 0 ? "js-0.1.19" : FALLBACK_SDK_VERSION;
50
50
 
51
51
  // src/pii-national-identifiers.ts
52
52
  var MAX_CANDIDATES_PER_RULE = 256;
@@ -1077,12 +1077,14 @@ var PIIManager = class {
1077
1077
  };
1078
1078
 
1079
1079
  // src/local-security-enforcer.ts
1080
- var DEFAULT_STRICT_CONFIG = {
1080
+ var DEFAULT_FAIL_OPEN_CONFIG = {
1081
1081
  shadow_mode: false,
1082
- block_pii_leakage: true,
1083
- block_db_access: true,
1084
- block_code_execution: true,
1085
- block_toxicity: true
1082
+ strict_security_mode: false,
1083
+ failure_mode: "fail_open",
1084
+ block_pii_leakage: false,
1085
+ block_db_access: false,
1086
+ block_code_execution: false,
1087
+ block_toxicity: false
1086
1088
  };
1087
1089
  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;
1088
1090
  var PYTHON_GENERAL_RCE_PATTERN = /(import\s+(os|sys|subprocess)|from\s+(os|sys|subprocess)\s+import|exec\s*\(|eval\s*\(|__import__)/i;
@@ -1205,13 +1207,28 @@ function readOptionalBooleanField(body, key, fallback) {
1205
1207
  }
1206
1208
  throw new Error(`Invalid config field: ${key}`);
1207
1209
  }
1210
+ function readOptionalFailureModeField(body, fallback) {
1211
+ const value = body.failure_mode;
1212
+ if (value === "fail_open" || value === "fail_close") {
1213
+ return value;
1214
+ }
1215
+ return fallback;
1216
+ }
1208
1217
  function normalizeCapabilityConfig(payload) {
1209
1218
  if (!payload || typeof payload !== "object") {
1210
1219
  throw new Error("Invalid config payload");
1211
1220
  }
1212
1221
  const body = payload;
1222
+ const strictSecurityMode = readOptionalBooleanField(body, "strict_security_mode", false);
1223
+ const failureMode = readOptionalFailureModeField(
1224
+ body,
1225
+ strictSecurityMode ? "fail_close" : "fail_open"
1226
+ );
1227
+ const effectiveStrictMode = strictSecurityMode || failureMode === "fail_close";
1213
1228
  return {
1214
1229
  shadow_mode: readOptionalBooleanField(body, "shadow_mode", false),
1230
+ strict_security_mode: effectiveStrictMode,
1231
+ failure_mode: effectiveStrictMode ? "fail_close" : "fail_open",
1215
1232
  block_pii_leakage: readBooleanField(body, "block_pii_leakage", "block_pii"),
1216
1233
  block_db_access: readBooleanField(body, "block_db_access", "block_db"),
1217
1234
  block_code_execution: readBooleanField(
@@ -1315,7 +1332,7 @@ async function fetchCapabilityConfigWithTimeout(params) {
1315
1332
  function getCachedCapabilityConfig(params) {
1316
1333
  const key = getCacheKey(params.apiKey, params.baseUrl);
1317
1334
  const entry = getGlobalCache().get(key);
1318
- return entry?.config ?? DEFAULT_STRICT_CONFIG;
1335
+ return entry?.config ?? DEFAULT_FAIL_OPEN_CONFIG;
1319
1336
  }
1320
1337
  async function ensureCapabilityConfig(params) {
1321
1338
  const ttlMs = params.ttlMs ?? CONFIG_TTL_MS;
@@ -1344,14 +1361,15 @@ async function ensureCapabilityConfig(params) {
1344
1361
  return resolved;
1345
1362
  }).catch((error) => {
1346
1363
  const message = error instanceof Error ? error.message : String(error);
1347
- console.warn("AgentID Config unreachable. Defaulting to STRICT MODE.", message);
1364
+ const fallbackConfig = existing?.config ?? DEFAULT_FAIL_OPEN_CONFIG;
1365
+ console.warn("AgentID Config unreachable. Defaulting to FAIL-OPEN MODE.", message);
1348
1366
  cache.set(key, {
1349
- config: DEFAULT_STRICT_CONFIG,
1367
+ config: fallbackConfig,
1350
1368
  expiresAt: Date.now() + ttlMs,
1351
1369
  promise: null
1352
1370
  });
1353
1371
  enforceCacheBound(cache);
1354
- return DEFAULT_STRICT_CONFIG;
1372
+ return fallbackConfig;
1355
1373
  }).finally(() => {
1356
1374
  const latest = cache.get(key);
1357
1375
  if (!latest) {
@@ -1367,7 +1385,7 @@ async function ensureCapabilityConfig(params) {
1367
1385
  }
1368
1386
  });
1369
1387
  cache.set(key, {
1370
- config: existing?.config ?? DEFAULT_STRICT_CONFIG,
1388
+ config: existing?.config ?? DEFAULT_FAIL_OPEN_CONFIG,
1371
1389
  expiresAt: existing?.expiresAt ?? 0,
1372
1390
  promise: pending
1373
1391
  });
@@ -1840,6 +1858,15 @@ function normalizeGuardTimeoutMs(value) {
1840
1858
  }
1841
1859
  return rounded;
1842
1860
  }
1861
+ function resolveConfiguredApiKey(value) {
1862
+ const explicit = typeof value === "string" ? value.trim() : "";
1863
+ const fromEnv = globalThis.process?.env?.AGENTID_API_KEY ?? "";
1864
+ const resolved = explicit || fromEnv.trim();
1865
+ if (!resolved) {
1866
+ throw new Error("AgentID API key missing. Pass apiKey or set AGENTID_API_KEY.");
1867
+ }
1868
+ return resolved;
1869
+ }
1843
1870
  function isInfrastructureGuardReason(reason) {
1844
1871
  if (!reason) return false;
1845
1872
  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";
@@ -1957,10 +1984,10 @@ function createCompletionChunkCollector() {
1957
1984
  };
1958
1985
  }
1959
1986
  var AgentID = class {
1960
- constructor(config) {
1987
+ constructor(config = {}) {
1961
1988
  this.injectionScanner = getInjectionScanner();
1962
1989
  this.recentGuardVerdicts = /* @__PURE__ */ new Map();
1963
- this.apiKey = config.apiKey.trim();
1990
+ this.apiKey = resolveConfiguredApiKey(config.apiKey);
1964
1991
  this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
1965
1992
  this.piiMasking = Boolean(config.piiMasking);
1966
1993
  this.checkInjection = config.checkInjection !== false;
@@ -2051,6 +2078,13 @@ var AgentID = class {
2051
2078
  baseUrl: this.baseUrl
2052
2079
  });
2053
2080
  }
2081
+ async resolveEffectiveStrictMode(options) {
2082
+ if (this.strictMode) {
2083
+ return true;
2084
+ }
2085
+ const config = await this.getCapabilityConfig(false, options);
2086
+ return config.strict_security_mode || config.failure_mode === "fail_close";
2087
+ }
2054
2088
  async prepareInputForDispatch(params, options) {
2055
2089
  const effectiveApiKey = this.resolveApiKey(options?.apiKey);
2056
2090
  if (this.checkInjection && !params.skipInjectionScan && params.input) {
@@ -2189,6 +2223,9 @@ var AgentID = class {
2189
2223
  */
2190
2224
  async guard(params, options) {
2191
2225
  const effectiveApiKey = this.resolveApiKey(options?.apiKey);
2226
+ const effectiveStrictMode = await this.resolveEffectiveStrictMode({
2227
+ apiKey: effectiveApiKey
2228
+ });
2192
2229
  const payload = {
2193
2230
  ...params,
2194
2231
  client_capabilities: params.client_capabilities ?? this.buildClientCapabilities()
@@ -2227,7 +2264,7 @@ var AgentID = class {
2227
2264
  await waitForRetry(attempt);
2228
2265
  continue;
2229
2266
  }
2230
- if (this.strictMode) {
2267
+ if (effectiveStrictMode) {
2231
2268
  console.warn(
2232
2269
  `[AgentID] Guard API infrastructure failure in strict mode (${verdict.reason ?? `http_${res.status}`}). Blocking request.`
2233
2270
  );
@@ -2274,13 +2311,13 @@ var AgentID = class {
2274
2311
  guardParams: params,
2275
2312
  apiKey: effectiveApiKey
2276
2313
  });
2277
- if (this.strictMode) {
2314
+ if (effectiveStrictMode) {
2278
2315
  return { allowed: false, reason: "network_error_strict_mode" };
2279
2316
  }
2280
2317
  return { allowed: true, reason: "timeout_fallback" };
2281
2318
  }
2282
2319
  console.warn(
2283
- this.strictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2320
+ effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2284
2321
  error
2285
2322
  );
2286
2323
  this.logGuardFallback({
@@ -2289,7 +2326,7 @@ var AgentID = class {
2289
2326
  guardParams: params,
2290
2327
  apiKey: effectiveApiKey
2291
2328
  });
2292
- if (this.strictMode) {
2329
+ if (effectiveStrictMode) {
2293
2330
  return { allowed: false, reason: "network_error_strict_mode" };
2294
2331
  }
2295
2332
  return { allowed: true, reason: "guard_unreachable" };
@@ -2298,22 +2335,22 @@ var AgentID = class {
2298
2335
  }
2299
2336
  }
2300
2337
  if (lastAbort) {
2301
- if (this.strictMode) {
2338
+ if (effectiveStrictMode) {
2302
2339
  return { allowed: false, reason: "network_error_strict_mode" };
2303
2340
  }
2304
2341
  return { allowed: true, reason: "timeout_fallback" };
2305
2342
  }
2306
2343
  if (typeof lastStatusCode === "number" && lastStatusCode >= 500) {
2307
- if (this.strictMode) {
2344
+ if (effectiveStrictMode) {
2308
2345
  return { allowed: false, reason: "server_error" };
2309
2346
  }
2310
2347
  return { allowed: true, reason: "system_failure_fail_open" };
2311
2348
  }
2312
2349
  console.warn(
2313
- this.strictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2350
+ effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
2314
2351
  lastError
2315
2352
  );
2316
- if (this.strictMode) {
2353
+ if (effectiveStrictMode) {
2317
2354
  return { allowed: false, reason: "network_error_strict_mode" };
2318
2355
  }
2319
2356
  return { allowed: true, reason: "guard_unreachable" };
@@ -2,6 +2,8 @@ import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
2
2
 
3
3
  type CapabilityConfig = {
4
4
  shadow_mode: boolean;
5
+ strict_security_mode: boolean;
6
+ failure_mode: "fail_open" | "fail_close";
5
7
  block_pii_leakage: boolean;
6
8
  block_db_access: boolean;
7
9
  block_code_execution: boolean;
@@ -58,7 +60,7 @@ interface LogParams {
58
60
  };
59
61
  }
60
62
  type AgentIDConfig = {
61
- apiKey: string;
63
+ apiKey?: string;
62
64
  baseUrl?: string;
63
65
  piiMasking?: boolean;
64
66
  checkInjection?: boolean;
@@ -85,7 +87,7 @@ declare class AgentID {
85
87
  private localEnforcer;
86
88
  private injectionScanner;
87
89
  private recentGuardVerdicts;
88
- constructor(config: AgentIDConfig);
90
+ constructor(config?: AgentIDConfig);
89
91
  private buildClientCapabilities;
90
92
  private resolveApiKey;
91
93
  private resolveClientEventId;
@@ -94,6 +96,7 @@ declare class AgentID {
94
96
  private cacheGuardVerdict;
95
97
  getCapabilityConfig(force?: boolean, options?: RequestOptions): Promise<CapabilityConfig>;
96
98
  private getCachedCapabilityConfig;
99
+ private resolveEffectiveStrictMode;
97
100
  prepareInputForDispatch(params: {
98
101
  input: string;
99
102
  systemId: string;
@@ -2,6 +2,8 @@ import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
2
2
 
3
3
  type CapabilityConfig = {
4
4
  shadow_mode: boolean;
5
+ strict_security_mode: boolean;
6
+ failure_mode: "fail_open" | "fail_close";
5
7
  block_pii_leakage: boolean;
6
8
  block_db_access: boolean;
7
9
  block_code_execution: boolean;
@@ -58,7 +60,7 @@ interface LogParams {
58
60
  };
59
61
  }
60
62
  type AgentIDConfig = {
61
- apiKey: string;
63
+ apiKey?: string;
62
64
  baseUrl?: string;
63
65
  piiMasking?: boolean;
64
66
  checkInjection?: boolean;
@@ -85,7 +87,7 @@ declare class AgentID {
85
87
  private localEnforcer;
86
88
  private injectionScanner;
87
89
  private recentGuardVerdicts;
88
- constructor(config: AgentIDConfig);
90
+ constructor(config?: AgentIDConfig);
89
91
  private buildClientCapabilities;
90
92
  private resolveApiKey;
91
93
  private resolveClientEventId;
@@ -94,6 +96,7 @@ declare class AgentID {
94
96
  private cacheGuardVerdict;
95
97
  getCapabilityConfig(force?: boolean, options?: RequestOptions): Promise<CapabilityConfig>;
96
98
  private getCachedCapabilityConfig;
99
+ private resolveEffectiveStrictMode;
97
100
  prepareInputForDispatch(params: {
98
101
  input: string;
99
102
  systemId: string;
@@ -1,2 +1,2 @@
1
1
  import '@langchain/core/callbacks/base';
2
- export { a as AgentIDCallbackHandler } from './langchain-BykeB2WB.mjs';
2
+ export { a as AgentIDCallbackHandler } from './langchain-DJDqqpbT.mjs';
@@ -1,2 +1,2 @@
1
1
  import '@langchain/core/callbacks/base';
2
- export { a as AgentIDCallbackHandler } from './langchain-BykeB2WB.js';
2
+ export { a as AgentIDCallbackHandler } from './langchain-DJDqqpbT.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentid-sdk",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "AgentID JavaScript/TypeScript SDK for guard, ingest, tracing, and analytics.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://agentid.ai",