agentid-sdk 0.1.25 → 0.1.28

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
@@ -110,6 +110,8 @@ const response = await secured.chat.completions.create({
110
110
  console.log(response.choices[0]?.message?.content ?? "");
111
111
  ```
112
112
 
113
+ Wrapped OpenAI calls persist telemetry for both regular and streamed completions. For `stream: true`, logging happens when the stream finishes.
114
+
113
115
  > Scope note: AgentID compliance/risk controls apply to the specific SDK-wrapped LLM calls (`guard()`, `wrapOpenAI()`, LangChain callback-wrapped flows). They do not automatically classify unrelated code paths in your whole monolithic application.
114
116
 
115
117
  ### LangChain Integration
@@ -145,6 +147,8 @@ const result = await chain.invoke(
145
147
  console.log(result);
146
148
  ```
147
149
 
150
+ LangChain callbacks log on run completion. Token/cost telemetry for streamed chains depends on the provider exposing usage in the final LangChain result.
151
+
148
152
  ### Raw Ingest API (Telemetry Only)
149
153
 
150
154
  ```ts
@@ -215,6 +219,15 @@ const agent = new AgentID({
215
219
  });
216
220
  ```
217
221
 
222
+ ### Optional client-side fast fail
223
+
224
+ ```ts
225
+ const agent = new AgentID({
226
+ failureMode: "fail_close",
227
+ clientFastFail: true, // opt-in local preflight before /guard
228
+ });
229
+ ```
230
+
218
231
  ### Error Handling & Strict Mode
219
232
 
220
233
  By default, AgentID is designed to keep your application running if the AgentID API has a timeout or is temporarily unreachable.
@@ -222,12 +235,14 @@ By default, AgentID is designed to keep your application running if the AgentID
222
235
  | Mode | Connectivity Failure | LLM Execution | Best For |
223
236
  | :--- | :--- | :--- | :--- |
224
237
  | **Default** (Strict Off) | API Timeout / Unreachable | **Fail-Open** (continues) | Standard SaaS, chatbots |
225
- | **Strict Mode** (`strictMode: true`) | API Timeout / Unreachable | **Fail-Closed** (blocks) | Healthcare, FinTech, high-risk |
238
+ | **Strict Mode** (`strictMode: true`) | API Timeout / Unreachable | Direct `guard()` denies; wrapped flows can apply local fallback first | Healthcare, FinTech, high-risk |
226
239
 
227
240
  - `guard()` returns a verdict (`allowed`, `reason`); handle deny paths explicitly.
228
241
  - `wrapOpenAI()` and LangChain handlers throw `SecurityBlockError` when a prompt is blocked.
242
+ - Backend `/guard` is the default authority for prompt injection, DB access, code execution, and PII leakage in SDK-wrapped flows.
243
+ - `clientFastFail` / `client_fast_fail` is optional and disabled by default. Enable it only when you explicitly want local preflight before the backend call.
244
+ - If backend guard is unreachable and the effective failure mode is `fail_close`, wrapped OpenAI/LangChain flows can run local fallback enforcement. Local hits still block; otherwise the request can continue with fallback telemetry attached.
229
245
  - If `strictMode` is not explicitly set in SDK code, runtime behavior follows the system configuration from AgentID (`strict_security_mode` / `failure_mode`).
230
- - Local prompt-injection heuristics are enabled only when dashboard policy enables injection blocking (`block_on_heuristic` / legacy injection flags). `strictMode` does not force local heuristic blocking.
231
246
  - Ingest retries transient failures (5xx/429) and logs warnings if persistence fails.
232
247
 
233
248
  ### Event Identity Model
@@ -246,10 +261,20 @@ SDK behavior:
246
261
  - `metadata.client_event_id`
247
262
  - `metadata.guard_event_id` (when available from wrappers/callbacks)
248
263
  - `x-correlation-id = client_event_id`
264
+ - after a successful primary ingest, SDK wrappers can call `/ingest/finalize` with the same `client_event_id` to attach `sdk_ingest_ms`
249
265
  - SDK requests include `x-agentid-sdk-version` for telemetry/version diagnostics.
250
266
 
251
267
  This keeps Guard + Complete linked under one correlation key while preserving internal event linkage in the dashboard.
252
268
 
269
+ ### SDK Timing Telemetry
270
+
271
+ SDK-managed metadata can include:
272
+
273
+ - `sdk_config_fetch_ms`: capability/config fetch time before dispatch.
274
+ - `sdk_local_scan_ms`: optional local enforcement time (`clientFastFail` or fail-close fallback path).
275
+ - `sdk_guard_ms`: backend `/guard` round-trip time observed by the SDK wrapper.
276
+ - `sdk_ingest_ms`: post-ingest transport timing finalized by the SDK through `/ingest/finalize` after a successful primary `/ingest`.
277
+
253
278
  ### Policy-Pack Runtime Telemetry
254
279
 
255
280
  When the backend uses compiled policy packs, runtime metadata includes:
@@ -282,9 +307,9 @@ powershell -ExecutionPolicy Bypass -File .\scripts\qa\run-ai-label-audit-check.p
282
307
 
283
308
  ## 7. Security & Compliance
284
309
 
285
- - Optional local PII masking and local policy enforcement before model dispatch.
286
- - Prompt-injection scanning in the SDK request path.
287
- - Guard checks run pre-execution; ingest telemetry captures prompt/output lifecycle.
310
+ - Backend `/guard` remains the primary enforcement authority by default.
311
+ - Optional local PII masking and opt-in `clientFastFail` are available for edge cases.
312
+ - Guard checks run pre-execution; ingest + finalize telemetry captures prompt/output lifecycle and SDK timing breakdowns.
288
313
  - Safe for server and serverless runtimes (including async completion flows).
289
314
  - Supports compliance and forensics workflows with durable event records.
290
315
 
@@ -18,6 +18,7 @@ interface GuardParams {
18
18
  user_id?: string;
19
19
  client_event_id?: string;
20
20
  expected_languages?: string[];
21
+ request_identity?: Record<string, unknown>;
21
22
  client_capabilities?: {
22
23
  capabilities: {
23
24
  has_feedback_handler: boolean;
@@ -67,10 +68,11 @@ interface LogParams {
67
68
  input: string;
68
69
  output: string;
69
70
  model: string;
70
- usage?: Record<string, number>;
71
- tokens?: Record<string, number>;
71
+ usage?: Record<string, unknown>;
72
+ tokens?: Record<string, unknown>;
72
73
  latency?: number;
73
74
  user_id?: string;
75
+ request_identity?: Record<string, unknown>;
74
76
  metadata?: Record<string, unknown>;
75
77
  event_type?: "start" | "complete" | "error" | "human_override" | "security_alert" | "security_block" | "security_policy_violation" | "transparency_badge_rendered";
76
78
  severity?: "info" | "warning" | "error" | "high";
@@ -88,6 +90,8 @@ type AgentIDConfig = {
88
90
  baseUrl?: string;
89
91
  piiMasking?: boolean;
90
92
  checkInjection?: boolean;
93
+ clientFastFail?: boolean;
94
+ client_fast_fail?: boolean;
91
95
  aiScanEnabled?: boolean;
92
96
  storePii?: boolean;
93
97
  strictMode?: boolean;
@@ -99,6 +103,8 @@ type AgentIDConfig = {
99
103
  type PreparedInput = {
100
104
  sanitizedInput: string;
101
105
  capabilityConfig: CapabilityConfig;
106
+ sdkConfigFetchMs?: number;
107
+ sdkLocalScanMs?: number;
102
108
  };
103
109
  declare class SecurityBlockError extends Error {
104
110
  reason: string;
@@ -119,6 +125,7 @@ declare class AgentID {
119
125
  private apiKey;
120
126
  private configuredPiiMasking;
121
127
  private checkInjection;
128
+ private clientFastFail;
122
129
  private aiScanEnabled;
123
130
  private storePii;
124
131
  private strictMode;
@@ -140,20 +147,32 @@ declare class AgentID {
140
147
  private readCachedGuardVerdict;
141
148
  private cacheGuardVerdict;
142
149
  getCapabilityConfig(force?: boolean, options?: RequestOptions): Promise<CapabilityConfig>;
150
+ private getCapabilityConfigWithTelemetry;
143
151
  private getCachedCapabilityConfig;
144
152
  private resolveEffectiveStrictMode;
145
153
  private maybeRaiseStrictIngestDependencyError;
146
154
  private shouldRunLocalInjectionScan;
155
+ private applyLocalPolicyChecks;
147
156
  prepareInputForDispatch(params: {
148
157
  input: string;
149
158
  systemId: string;
150
159
  stream: boolean;
151
160
  skipInjectionScan?: boolean;
161
+ clientEventId?: string;
162
+ }, options?: RequestOptions): Promise<PreparedInput>;
163
+ applyLocalFallbackForGuardFailure(params: {
164
+ input: string;
165
+ systemId: string;
166
+ stream: boolean;
167
+ clientEventId?: string;
168
+ capabilityConfig?: CapabilityConfig;
169
+ sdkConfigFetchMs?: number;
152
170
  }, options?: RequestOptions): Promise<PreparedInput>;
153
171
  scanPromptInjection(input: string, options?: InjectionScanRequestOptions): Promise<void>;
154
172
  private withMaskedOpenAIRequest;
155
173
  private logSecurityPolicyViolation;
156
174
  private logGuardFallback;
175
+ private finalizeIngestTelemetry;
157
176
  /**
158
177
  * GUARD: Checks limits, PII, and security before execution.
159
178
  * strictMode=false (default): FAIL-OPEN on connectivity/timeouts.
@@ -162,6 +181,7 @@ declare class AgentID {
162
181
  guard(params: GuardParams, options?: RequestOptions): Promise<GuardResponse>;
163
182
  private sendIngest;
164
183
  private extractStreamChunkText;
184
+ private extractStreamChunkUsage;
165
185
  private wrapCompletion;
166
186
  /**
167
187
  * LOG: Sends telemetry after execution.
@@ -180,13 +200,14 @@ declare class AgentID {
180
200
  * Wrap an OpenAI client once; AgentID will automatically:
181
201
  * - run guard() before chat.completions.create
182
202
  * - measure latency
183
- * - fire-and-forget ingest logging
203
+ * - persist ingest telemetry for the wrapped call
184
204
  */
185
205
  wrapOpenAI<T>(openai: T, options: {
186
206
  system_id: string;
187
207
  user_id?: string;
188
208
  expected_languages?: string[];
189
209
  expectedLanguages?: string[];
210
+ request_identity?: Record<string, unknown>;
190
211
  apiKey?: string;
191
212
  api_key?: string;
192
213
  resolveApiKey?: (request: Record<string, unknown>) => string | undefined;
@@ -18,6 +18,7 @@ interface GuardParams {
18
18
  user_id?: string;
19
19
  client_event_id?: string;
20
20
  expected_languages?: string[];
21
+ request_identity?: Record<string, unknown>;
21
22
  client_capabilities?: {
22
23
  capabilities: {
23
24
  has_feedback_handler: boolean;
@@ -67,10 +68,11 @@ interface LogParams {
67
68
  input: string;
68
69
  output: string;
69
70
  model: string;
70
- usage?: Record<string, number>;
71
- tokens?: Record<string, number>;
71
+ usage?: Record<string, unknown>;
72
+ tokens?: Record<string, unknown>;
72
73
  latency?: number;
73
74
  user_id?: string;
75
+ request_identity?: Record<string, unknown>;
74
76
  metadata?: Record<string, unknown>;
75
77
  event_type?: "start" | "complete" | "error" | "human_override" | "security_alert" | "security_block" | "security_policy_violation" | "transparency_badge_rendered";
76
78
  severity?: "info" | "warning" | "error" | "high";
@@ -88,6 +90,8 @@ type AgentIDConfig = {
88
90
  baseUrl?: string;
89
91
  piiMasking?: boolean;
90
92
  checkInjection?: boolean;
93
+ clientFastFail?: boolean;
94
+ client_fast_fail?: boolean;
91
95
  aiScanEnabled?: boolean;
92
96
  storePii?: boolean;
93
97
  strictMode?: boolean;
@@ -99,6 +103,8 @@ type AgentIDConfig = {
99
103
  type PreparedInput = {
100
104
  sanitizedInput: string;
101
105
  capabilityConfig: CapabilityConfig;
106
+ sdkConfigFetchMs?: number;
107
+ sdkLocalScanMs?: number;
102
108
  };
103
109
  declare class SecurityBlockError extends Error {
104
110
  reason: string;
@@ -119,6 +125,7 @@ declare class AgentID {
119
125
  private apiKey;
120
126
  private configuredPiiMasking;
121
127
  private checkInjection;
128
+ private clientFastFail;
122
129
  private aiScanEnabled;
123
130
  private storePii;
124
131
  private strictMode;
@@ -140,20 +147,32 @@ declare class AgentID {
140
147
  private readCachedGuardVerdict;
141
148
  private cacheGuardVerdict;
142
149
  getCapabilityConfig(force?: boolean, options?: RequestOptions): Promise<CapabilityConfig>;
150
+ private getCapabilityConfigWithTelemetry;
143
151
  private getCachedCapabilityConfig;
144
152
  private resolveEffectiveStrictMode;
145
153
  private maybeRaiseStrictIngestDependencyError;
146
154
  private shouldRunLocalInjectionScan;
155
+ private applyLocalPolicyChecks;
147
156
  prepareInputForDispatch(params: {
148
157
  input: string;
149
158
  systemId: string;
150
159
  stream: boolean;
151
160
  skipInjectionScan?: boolean;
161
+ clientEventId?: string;
162
+ }, options?: RequestOptions): Promise<PreparedInput>;
163
+ applyLocalFallbackForGuardFailure(params: {
164
+ input: string;
165
+ systemId: string;
166
+ stream: boolean;
167
+ clientEventId?: string;
168
+ capabilityConfig?: CapabilityConfig;
169
+ sdkConfigFetchMs?: number;
152
170
  }, options?: RequestOptions): Promise<PreparedInput>;
153
171
  scanPromptInjection(input: string, options?: InjectionScanRequestOptions): Promise<void>;
154
172
  private withMaskedOpenAIRequest;
155
173
  private logSecurityPolicyViolation;
156
174
  private logGuardFallback;
175
+ private finalizeIngestTelemetry;
157
176
  /**
158
177
  * GUARD: Checks limits, PII, and security before execution.
159
178
  * strictMode=false (default): FAIL-OPEN on connectivity/timeouts.
@@ -162,6 +181,7 @@ declare class AgentID {
162
181
  guard(params: GuardParams, options?: RequestOptions): Promise<GuardResponse>;
163
182
  private sendIngest;
164
183
  private extractStreamChunkText;
184
+ private extractStreamChunkUsage;
165
185
  private wrapCompletion;
166
186
  /**
167
187
  * LOG: Sends telemetry after execution.
@@ -180,13 +200,14 @@ declare class AgentID {
180
200
  * Wrap an OpenAI client once; AgentID will automatically:
181
201
  * - run guard() before chat.completions.create
182
202
  * - measure latency
183
- * - fire-and-forget ingest logging
203
+ * - persist ingest telemetry for the wrapped call
184
204
  */
185
205
  wrapOpenAI<T>(openai: T, options: {
186
206
  system_id: string;
187
207
  user_id?: string;
188
208
  expected_languages?: string[];
189
209
  expectedLanguages?: string[];
210
+ request_identity?: Record<string, unknown>;
190
211
  apiKey?: string;
191
212
  api_key?: string;
192
213
  resolveApiKey?: (request: Record<string, unknown>) => string | undefined;