agentid-sdk 0.1.34 → 0.1.36

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.
@@ -1,4 +1,19 @@
1
+ type PIIMapping = Record<string, string>;
2
+ declare class PIIManager {
3
+ /**
4
+ * Reversible local-first masking using <TYPE_INDEX> placeholders.
5
+ *
6
+ * Zero-dependency fallback with strict checksum validation for CEE national IDs.
7
+ */
8
+ anonymize(text: string): {
9
+ maskedText: string;
10
+ mapping: PIIMapping;
11
+ };
12
+ deanonymize(text: string, mapping: PIIMapping): string;
13
+ }
14
+
1
15
  type CapabilityConfig = {
16
+ version?: number | null;
2
17
  shadow_mode: boolean;
3
18
  strict_security_mode: boolean;
4
19
  failure_mode: "fail_open" | "fail_close";
@@ -105,6 +120,8 @@ type PreparedInput = {
105
120
  capabilityConfig: CapabilityConfig;
106
121
  sdkConfigFetchMs?: number;
107
122
  sdkLocalScanMs?: number;
123
+ piiMapping?: PIIMapping;
124
+ shouldDeanonymize?: boolean;
108
125
  };
109
126
  declare class SecurityBlockError extends Error {
110
127
  reason: string;
@@ -140,6 +157,7 @@ declare class AgentID {
140
157
  get piiMasking(): boolean | undefined;
141
158
  private resolveEffectivePiiMasking;
142
159
  getEffectivePiiMasking(options?: RequestOptions): boolean;
160
+ getEffectivePiiMaskingForConfig(capabilityConfig?: CapabilityConfig): boolean;
143
161
  private buildClientCapabilities;
144
162
  private resolveApiKey;
145
163
  private resolveClientEventId;
@@ -152,7 +170,7 @@ declare class AgentID {
152
170
  private resolveEffectiveStrictMode;
153
171
  private maybeRaiseStrictIngestDependencyError;
154
172
  private shouldRunLocalInjectionScan;
155
- private refreshCapabilityConfigBeforeLocalEnforcement;
173
+ private refreshCapabilityConfigBeforeClientControl;
156
174
  private applyLocalPolicyChecks;
157
175
  prepareInputForDispatch(params: {
158
176
  input: string;
@@ -183,6 +201,10 @@ declare class AgentID {
183
201
  private sendIngest;
184
202
  private extractStreamChunkText;
185
203
  private extractStreamChunkUsage;
204
+ private isOpenAIStreamFinishChunk;
205
+ private setOpenAIStreamChunkText;
206
+ private createSyntheticOpenAIStreamChunk;
207
+ private rewriteOpenAIStreamChunkForClient;
186
208
  private wrapCompletion;
187
209
  /**
188
210
  * LOG: Sends telemetry after execution.
@@ -215,4 +237,4 @@ declare class AgentID {
215
237
  }): T;
216
238
  }
217
239
 
218
- export { AgentID as A, DependencyError as D, type GuardParams as G, type LogParams as L, type PreparedInput as P, type RequestOptions as R, SecurityBlockError as S, type TransparencyMetadata as T, type GuardResponse as a };
240
+ export { AgentID as A, DependencyError as D, type GuardParams as G, type LogParams as L, PIIManager as P, type RequestOptions as R, SecurityBlockError as S, type TransparencyMetadata as T, type GuardResponse as a, type PIIMapping as b, type PreparedInput as c };
@@ -1,4 +1,19 @@
1
+ type PIIMapping = Record<string, string>;
2
+ declare class PIIManager {
3
+ /**
4
+ * Reversible local-first masking using <TYPE_INDEX> placeholders.
5
+ *
6
+ * Zero-dependency fallback with strict checksum validation for CEE national IDs.
7
+ */
8
+ anonymize(text: string): {
9
+ maskedText: string;
10
+ mapping: PIIMapping;
11
+ };
12
+ deanonymize(text: string, mapping: PIIMapping): string;
13
+ }
14
+
1
15
  type CapabilityConfig = {
16
+ version?: number | null;
2
17
  shadow_mode: boolean;
3
18
  strict_security_mode: boolean;
4
19
  failure_mode: "fail_open" | "fail_close";
@@ -105,6 +120,8 @@ type PreparedInput = {
105
120
  capabilityConfig: CapabilityConfig;
106
121
  sdkConfigFetchMs?: number;
107
122
  sdkLocalScanMs?: number;
123
+ piiMapping?: PIIMapping;
124
+ shouldDeanonymize?: boolean;
108
125
  };
109
126
  declare class SecurityBlockError extends Error {
110
127
  reason: string;
@@ -140,6 +157,7 @@ declare class AgentID {
140
157
  get piiMasking(): boolean | undefined;
141
158
  private resolveEffectivePiiMasking;
142
159
  getEffectivePiiMasking(options?: RequestOptions): boolean;
160
+ getEffectivePiiMaskingForConfig(capabilityConfig?: CapabilityConfig): boolean;
143
161
  private buildClientCapabilities;
144
162
  private resolveApiKey;
145
163
  private resolveClientEventId;
@@ -152,7 +170,7 @@ declare class AgentID {
152
170
  private resolveEffectiveStrictMode;
153
171
  private maybeRaiseStrictIngestDependencyError;
154
172
  private shouldRunLocalInjectionScan;
155
- private refreshCapabilityConfigBeforeLocalEnforcement;
173
+ private refreshCapabilityConfigBeforeClientControl;
156
174
  private applyLocalPolicyChecks;
157
175
  prepareInputForDispatch(params: {
158
176
  input: string;
@@ -183,6 +201,10 @@ declare class AgentID {
183
201
  private sendIngest;
184
202
  private extractStreamChunkText;
185
203
  private extractStreamChunkUsage;
204
+ private isOpenAIStreamFinishChunk;
205
+ private setOpenAIStreamChunkText;
206
+ private createSyntheticOpenAIStreamChunk;
207
+ private rewriteOpenAIStreamChunkForClient;
186
208
  private wrapCompletion;
187
209
  /**
188
210
  * LOG: Sends telemetry after execution.
@@ -215,4 +237,4 @@ declare class AgentID {
215
237
  }): T;
216
238
  }
217
239
 
218
- export { AgentID as A, DependencyError as D, type GuardParams as G, type LogParams as L, type PreparedInput as P, type RequestOptions as R, SecurityBlockError as S, type TransparencyMetadata as T, type GuardResponse as a };
240
+ export { AgentID as A, DependencyError as D, type GuardParams as G, type LogParams as L, PIIManager as P, type RequestOptions as R, SecurityBlockError as S, type TransparencyMetadata as T, type GuardResponse as a, type PIIMapping as b, type PreparedInput as c };
@@ -1810,10 +1810,11 @@ function getInjectionScanner() {
1810
1810
 
1811
1811
  // src/sdk-version.ts
1812
1812
  var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
1813
- var AGENTID_SDK_VERSION_HEADER = "js-0.1.34".trim().length > 0 ? "js-0.1.34" : FALLBACK_SDK_VERSION;
1813
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.36".trim().length > 0 ? "js-0.1.36" : FALLBACK_SDK_VERSION;
1814
1814
 
1815
1815
  // src/local-security-enforcer.ts
1816
1816
  var DEFAULT_FAIL_OPEN_CONFIG = {
1817
+ version: null,
1817
1818
  shadow_mode: false,
1818
1819
  strict_security_mode: false,
1819
1820
  failure_mode: "fail_open",
@@ -1982,6 +1983,25 @@ function readOptionalFailureModeField(body, fallback) {
1982
1983
  }
1983
1984
  return fallback;
1984
1985
  }
1986
+ function readOptionalVersionField(body) {
1987
+ if (!("version" in body)) {
1988
+ return null;
1989
+ }
1990
+ const value = body.version;
1991
+ if (value === null || value === void 0 || value === "") {
1992
+ return null;
1993
+ }
1994
+ if (typeof value === "number" && Number.isFinite(value)) {
1995
+ return Math.trunc(value);
1996
+ }
1997
+ if (typeof value === "string") {
1998
+ const parsed = Number.parseInt(value, 10);
1999
+ if (Number.isFinite(parsed)) {
2000
+ return parsed;
2001
+ }
2002
+ }
2003
+ throw new Error("Invalid config field: version");
2004
+ }
1985
2005
  function normalizeCapabilityConfig(payload) {
1986
2006
  if (!payload || typeof payload !== "object") {
1987
2007
  throw new Error("Invalid config payload");
@@ -1999,6 +2019,7 @@ function normalizeCapabilityConfig(payload) {
1999
2019
  false
2000
2020
  );
2001
2021
  return {
2022
+ version: readOptionalVersionField(body),
2002
2023
  shadow_mode: readOptionalBooleanField(body, "shadow_mode", false),
2003
2024
  strict_security_mode: effectiveStrictMode,
2004
2025
  failure_mode: effectiveStrictMode ? "fail_close" : "fail_open",
@@ -2281,6 +2302,9 @@ function buildSdkTimingMetadata(params) {
2281
2302
  setFiniteDurationMetadata(metadata, "sdk_local_scan_ms", params.sdkLocalScanMs);
2282
2303
  setFiniteDurationMetadata(metadata, "sdk_guard_ms", params.sdkGuardMs);
2283
2304
  setFiniteDurationMetadata(metadata, "sdk_ingest_ms", params.sdkIngestMs);
2305
+ if (typeof params.sdkConfigVersion === "number" && Number.isFinite(params.sdkConfigVersion)) {
2306
+ metadata.sdk_config_version = Math.trunc(params.sdkConfigVersion);
2307
+ }
2284
2308
  return metadata;
2285
2309
  }
2286
2310
  function resolveConfiguredApiKey(value) {
@@ -2483,6 +2507,57 @@ function createCompletionChunkCollector() {
2483
2507
  result
2484
2508
  };
2485
2509
  }
2510
+ function getStreamingPlaceholderCarryLength(buffer, placeholders) {
2511
+ if (!buffer || placeholders.length === 0) {
2512
+ return 0;
2513
+ }
2514
+ let maxPlaceholderLength = 0;
2515
+ for (const placeholder of placeholders) {
2516
+ if (placeholder.length > maxPlaceholderLength) {
2517
+ maxPlaceholderLength = placeholder.length;
2518
+ }
2519
+ }
2520
+ const maxCarryLength = Math.min(buffer.length, Math.max(0, maxPlaceholderLength - 1));
2521
+ let carryLength = 0;
2522
+ for (let candidateLength = 1; candidateLength <= maxCarryLength; candidateLength += 1) {
2523
+ const suffix = buffer.slice(-candidateLength);
2524
+ if (placeholders.some((placeholder) => placeholder.startsWith(suffix))) {
2525
+ carryLength = candidateLength;
2526
+ }
2527
+ }
2528
+ return carryLength;
2529
+ }
2530
+ function createStreamingPlaceholderRewriter(piiManager, mapping) {
2531
+ const placeholders = Object.keys(mapping).filter((placeholder) => placeholder.length > 0);
2532
+ if (placeholders.length === 0) {
2533
+ return null;
2534
+ }
2535
+ let pending = "";
2536
+ return {
2537
+ consume(chunk) {
2538
+ if (!chunk) {
2539
+ return "";
2540
+ }
2541
+ pending += chunk;
2542
+ const carryLength = getStreamingPlaceholderCarryLength(pending, placeholders);
2543
+ const flushLength = Math.max(0, pending.length - carryLength);
2544
+ if (flushLength === 0) {
2545
+ return "";
2546
+ }
2547
+ const flushable = pending.slice(0, flushLength);
2548
+ pending = pending.slice(flushLength);
2549
+ return piiManager.deanonymize(flushable, mapping);
2550
+ },
2551
+ flush() {
2552
+ if (!pending) {
2553
+ return "";
2554
+ }
2555
+ const remaining = piiManager.deanonymize(pending, mapping);
2556
+ pending = "";
2557
+ return remaining;
2558
+ }
2559
+ };
2560
+ }
2486
2561
  var SecurityBlockError = class extends Error {
2487
2562
  constructor(reason = "guard_denied") {
2488
2563
  super(`AgentID: Security Blocked (${reason})`);
@@ -2537,6 +2612,9 @@ var AgentID = class {
2537
2612
  getEffectivePiiMasking(options) {
2538
2613
  return this.resolveEffectivePiiMasking(this.getCachedCapabilityConfig(options));
2539
2614
  }
2615
+ getEffectivePiiMaskingForConfig(capabilityConfig) {
2616
+ return this.resolveEffectivePiiMasking(capabilityConfig);
2617
+ }
2540
2618
  buildClientCapabilities(framework = "js_sdk", hasFeedbackHandler = false, capabilityConfig) {
2541
2619
  return {
2542
2620
  capabilities: {
@@ -2662,7 +2740,7 @@ var AgentID = class {
2662
2740
  }
2663
2741
  return config.block_on_heuristic;
2664
2742
  }
2665
- async refreshCapabilityConfigBeforeLocalEnforcement(params) {
2743
+ async refreshCapabilityConfigBeforeClientControl(params) {
2666
2744
  const refreshed = await this.getCapabilityConfigWithTelemetry(true, params.options);
2667
2745
  return {
2668
2746
  capabilityConfig: refreshed.capabilityConfig,
@@ -2684,7 +2762,8 @@ var AgentID = class {
2684
2762
  eventId: params.clientEventId,
2685
2763
  clientEventId: params.clientEventId,
2686
2764
  telemetryMetadata: buildSdkTimingMetadata({
2687
- sdkConfigFetchMs: params.sdkConfigFetchMs
2765
+ sdkConfigFetchMs: params.sdkConfigFetchMs,
2766
+ sdkConfigVersion: params.capabilityConfig.version
2688
2767
  })
2689
2768
  });
2690
2769
  }
@@ -2729,15 +2808,38 @@ var AgentID = class {
2729
2808
  false,
2730
2809
  options
2731
2810
  );
2811
+ let sanitizedInput = params.input;
2812
+ let sdkLocalScanMs = 0;
2813
+ if (this.configuredPiiMasking === null) {
2814
+ const refreshed = await this.refreshCapabilityConfigBeforeClientControl({
2815
+ capabilityConfig,
2816
+ sdkConfigFetchMs,
2817
+ options
2818
+ });
2819
+ capabilityConfig = refreshed.capabilityConfig;
2820
+ sdkConfigFetchMs = refreshed.sdkConfigFetchMs;
2821
+ }
2732
2822
  if (!this.clientFastFail) {
2823
+ const effectivePiiMasking2 = this.resolveEffectivePiiMasking(capabilityConfig);
2824
+ if (!capabilityConfig.block_pii_leakage && effectivePiiMasking2) {
2825
+ const masked = this.pii.anonymize(sanitizedInput);
2826
+ return {
2827
+ sanitizedInput: masked.maskedText,
2828
+ capabilityConfig,
2829
+ sdkConfigFetchMs,
2830
+ sdkLocalScanMs,
2831
+ piiMapping: masked.mapping,
2832
+ shouldDeanonymize: Object.keys(masked.mapping).length > 0
2833
+ };
2834
+ }
2733
2835
  return {
2734
- sanitizedInput: params.input,
2836
+ sanitizedInput,
2735
2837
  capabilityConfig,
2736
2838
  sdkConfigFetchMs,
2737
- sdkLocalScanMs: 0
2839
+ sdkLocalScanMs
2738
2840
  };
2739
2841
  }
2740
- const refreshedConfig = await this.refreshCapabilityConfigBeforeLocalEnforcement({
2842
+ const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
2741
2843
  capabilityConfig,
2742
2844
  sdkConfigFetchMs,
2743
2845
  options
@@ -2754,11 +2856,25 @@ var AgentID = class {
2754
2856
  sdkConfigFetchMs,
2755
2857
  runPromptInjectionCheck: !params.skipInjectionScan
2756
2858
  });
2859
+ sanitizedInput = enforced.sanitizedInput;
2860
+ sdkLocalScanMs = enforced.sdkLocalScanMs;
2861
+ const effectivePiiMasking = this.resolveEffectivePiiMasking(capabilityConfig);
2862
+ if (!capabilityConfig.block_pii_leakage && effectivePiiMasking) {
2863
+ const masked = this.pii.anonymize(sanitizedInput);
2864
+ return {
2865
+ sanitizedInput: masked.maskedText,
2866
+ capabilityConfig,
2867
+ sdkConfigFetchMs,
2868
+ sdkLocalScanMs,
2869
+ piiMapping: masked.mapping,
2870
+ shouldDeanonymize: Object.keys(masked.mapping).length > 0
2871
+ };
2872
+ }
2757
2873
  return {
2758
- sanitizedInput: enforced.sanitizedInput,
2874
+ sanitizedInput,
2759
2875
  capabilityConfig,
2760
2876
  sdkConfigFetchMs,
2761
- sdkLocalScanMs: enforced.sdkLocalScanMs
2877
+ sdkLocalScanMs
2762
2878
  };
2763
2879
  }
2764
2880
  async applyLocalFallbackForGuardFailure(params, options) {
@@ -2767,7 +2883,7 @@ var AgentID = class {
2767
2883
  capabilityConfig: params.capabilityConfig,
2768
2884
  sdkConfigFetchMs: params.sdkConfigFetchMs
2769
2885
  } : await this.getCapabilityConfigWithTelemetry(false, options);
2770
- const refreshedConfig = await this.refreshCapabilityConfigBeforeLocalEnforcement({
2886
+ const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
2771
2887
  capabilityConfig: resolvedConfig.capabilityConfig,
2772
2888
  sdkConfigFetchMs: resolvedConfig.sdkConfigFetchMs,
2773
2889
  options
@@ -2797,7 +2913,7 @@ var AgentID = class {
2797
2913
  false,
2798
2914
  options
2799
2915
  );
2800
- const refreshedConfig = await this.refreshCapabilityConfigBeforeLocalEnforcement({
2916
+ const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
2801
2917
  capabilityConfig: initialConfig.capabilityConfig,
2802
2918
  sdkConfigFetchMs: initialConfig.sdkConfigFetchMs,
2803
2919
  options
@@ -2818,7 +2934,8 @@ var AgentID = class {
2818
2934
  eventId: options?.clientEventId,
2819
2935
  clientEventId: options?.clientEventId,
2820
2936
  telemetryMetadata: buildSdkTimingMetadata({
2821
- sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs
2937
+ sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs,
2938
+ sdkConfigVersion: refreshedConfig.capabilityConfig.version
2822
2939
  })
2823
2940
  });
2824
2941
  }
@@ -2871,7 +2988,10 @@ var AgentID = class {
2871
2988
  action_taken: params.actionTaken,
2872
2989
  ...buildSdkTimingMetadata({
2873
2990
  sdkConfigFetchMs: params.sdkConfigFetchMs,
2874
- sdkLocalScanMs: params.sdkLocalScanMs
2991
+ sdkLocalScanMs: params.sdkLocalScanMs,
2992
+ sdkConfigVersion: this.getCachedCapabilityConfig({
2993
+ apiKey: params.apiKey
2994
+ }).version
2875
2995
  })
2876
2996
  }
2877
2997
  }, { apiKey: params.apiKey });
@@ -3210,7 +3330,123 @@ var AgentID = class {
3210
3330
  const usage = chunk.usage;
3211
3331
  return usage && typeof usage === "object" && !Array.isArray(usage) ? usage : void 0;
3212
3332
  }
3213
- wrapCompletion(completion) {
3333
+ isOpenAIStreamFinishChunk(chunk) {
3334
+ if (!chunk || typeof chunk !== "object") {
3335
+ return false;
3336
+ }
3337
+ const choices = chunk.choices;
3338
+ if (!Array.isArray(choices)) {
3339
+ return false;
3340
+ }
3341
+ return choices.some(
3342
+ (choice) => choice && typeof choice === "object" && typeof choice.finish_reason === "string" && (choice.finish_reason ?? "").length > 0
3343
+ );
3344
+ }
3345
+ setOpenAIStreamChunkText(chunk, text) {
3346
+ if (!chunk || typeof chunk !== "object") {
3347
+ return false;
3348
+ }
3349
+ const choices = chunk.choices;
3350
+ if (!Array.isArray(choices)) {
3351
+ return false;
3352
+ }
3353
+ let assigned = false;
3354
+ const replaceInContainer = (container) => {
3355
+ if (!container || typeof container !== "object") {
3356
+ return false;
3357
+ }
3358
+ const content = container.content;
3359
+ if (typeof content === "string") {
3360
+ if (!assigned) {
3361
+ container.content = text;
3362
+ assigned = true;
3363
+ } else {
3364
+ container.content = "";
3365
+ }
3366
+ return true;
3367
+ }
3368
+ if (Array.isArray(content)) {
3369
+ let replacedInArray = false;
3370
+ for (const part of content) {
3371
+ if (!part || typeof part !== "object") continue;
3372
+ const typedPart = part;
3373
+ if (typeof typedPart.text !== "string") continue;
3374
+ if (!assigned && !replacedInArray) {
3375
+ typedPart.text = text;
3376
+ assigned = true;
3377
+ replacedInArray = true;
3378
+ } else {
3379
+ typedPart.text = "";
3380
+ }
3381
+ }
3382
+ if (!assigned && text.length > 0) {
3383
+ content.unshift({ type: "text", text });
3384
+ assigned = true;
3385
+ }
3386
+ return replacedInArray || assigned;
3387
+ }
3388
+ if (!assigned && text.length > 0) {
3389
+ container.content = text;
3390
+ assigned = true;
3391
+ return true;
3392
+ }
3393
+ return false;
3394
+ };
3395
+ for (const choice of choices) {
3396
+ if (!choice || typeof choice !== "object") {
3397
+ continue;
3398
+ }
3399
+ const typedChoice = choice;
3400
+ const replacedDelta = replaceInContainer(typedChoice.delta);
3401
+ const replacedMessage = replaceInContainer(typedChoice.message);
3402
+ if (!replacedDelta && !replacedMessage && !assigned && text.length > 0) {
3403
+ if (!typedChoice.delta || typeof typedChoice.delta !== "object") {
3404
+ typedChoice.delta = {};
3405
+ }
3406
+ typedChoice.delta.content = text;
3407
+ assigned = true;
3408
+ }
3409
+ }
3410
+ return assigned;
3411
+ }
3412
+ createSyntheticOpenAIStreamChunk(text, template) {
3413
+ const synthetic = {};
3414
+ if (template && typeof template === "object" && !Array.isArray(template)) {
3415
+ const typedTemplate = template;
3416
+ for (const key of ["id", "object", "created", "model"]) {
3417
+ if (Object.prototype.hasOwnProperty.call(typedTemplate, key)) {
3418
+ synthetic[key] = typedTemplate[key];
3419
+ }
3420
+ }
3421
+ }
3422
+ synthetic.choices = [
3423
+ {
3424
+ index: 0,
3425
+ delta: { content: text },
3426
+ finish_reason: null
3427
+ }
3428
+ ];
3429
+ return synthetic;
3430
+ }
3431
+ rewriteOpenAIStreamChunkForClient(chunk, rewriter, isFinishChunk) {
3432
+ const rawText = this.extractStreamChunkText(chunk);
3433
+ const rewrittenText = rawText ? rewriter.consume(rawText) : "";
3434
+ const finalText = isFinishChunk ? `${rewrittenText}${rewriter.flush()}` : rewrittenText;
3435
+ if (typeof chunk === "string") {
3436
+ return finalText ? [finalText] : [];
3437
+ }
3438
+ if (rawText) {
3439
+ if (this.setOpenAIStreamChunkText(chunk, finalText)) {
3440
+ return [chunk];
3441
+ }
3442
+ return finalText.length > 0 ? [this.createSyntheticOpenAIStreamChunk(finalText, chunk), chunk] : [chunk];
3443
+ }
3444
+ if (isFinishChunk && finalText.length > 0) {
3445
+ return [this.createSyntheticOpenAIStreamChunk(finalText, chunk), chunk];
3446
+ }
3447
+ return [chunk];
3448
+ }
3449
+ wrapCompletion(completion, options) {
3214
3450
  if (typeof completion === "string") {
3215
3451
  const masked = this.pii.anonymize(completion);
3216
3452
  return {
@@ -3234,7 +3470,11 @@ var AgentID = class {
3234
3470
  const collector = createCompletionChunkCollector();
3235
3471
  const extractStreamChunkText = this.extractStreamChunkText.bind(this);
3236
3472
  const extractStreamChunkUsage = this.extractStreamChunkUsage.bind(this);
3473
+ const isOpenAIStreamFinishChunk = this.isOpenAIStreamFinishChunk.bind(this);
3474
+ const rewriteOpenAIStreamChunkForClient = this.rewriteOpenAIStreamChunkForClient.bind(this);
3475
+ const createSyntheticOpenAIStreamChunk = this.createSyntheticOpenAIStreamChunk.bind(this);
3237
3476
  const piiManager = this.pii;
3477
+ const streamRewriter = options?.deanonymizeForClient === true && options.piiMapping ? createStreamingPlaceholderRewriter(piiManager, options.piiMapping) : null;
3238
3478
  let lastUsage;
3239
3479
  let resolveDone = null;
3240
3480
  let rejectDone = null;
@@ -3245,17 +3485,44 @@ var AgentID = class {
3245
3485
  const wrapped = {
3246
3486
  [Symbol.asyncIterator]: async function* () {
3247
3487
  try {
3488
+ let finishChunkFlushed = false;
3489
+ let lastChunkTemplate;
3248
3490
  for await (const chunk of source) {
3249
3491
  const chunkText = extractStreamChunkText(chunk);
3492
+ const isFinishChunk = streamRewriter ? isOpenAIStreamFinishChunk(chunk) : false;
3250
3493
  if (chunkText) {
3251
3494
  await collector.push(chunkText);
3495
+ lastChunkTemplate = chunk;
3252
3496
  }
3253
3497
  const chunkUsage = extractStreamChunkUsage(chunk);
3254
3498
  if (chunkUsage) {
3255
3499
  lastUsage = chunkUsage;
3256
3500
  }
3501
+ if (streamRewriter) {
3502
+ const rewrittenChunks = rewriteOpenAIStreamChunkForClient(
3503
+ chunk,
3504
+ streamRewriter,
3505
+ isFinishChunk
3506
+ );
3507
+ if (isFinishChunk) {
3508
+ finishChunkFlushed = true;
3509
+ }
3510
+ for (const rewrittenChunk of rewrittenChunks) {
3511
+ yield rewrittenChunk;
3512
+ }
3513
+ continue;
3514
+ }
3257
3515
  yield chunk;
3258
3516
  }
3517
+ if (streamRewriter && !finishChunkFlushed) {
3518
+ const trailingText = streamRewriter.flush();
3519
+ if (trailingText.length > 0) {
3520
+ yield createSyntheticOpenAIStreamChunk(
3521
+ trailingText,
3522
+ lastChunkTemplate
3523
+ );
3524
+ }
3525
+ }
3259
3526
  await collector.close();
3260
3527
  const rawOutput = await collector.result;
3261
3528
  const masked = piiManager.anonymize(rawOutput);
@@ -3368,6 +3635,8 @@ var AgentID = class {
3368
3635
  }, requestOptions);
3369
3636
  capabilityConfig = prepared.capabilityConfig;
3370
3637
  maskedText = prepared.sanitizedInput;
3638
+ mapping = prepared.piiMapping ?? {};
3639
+ shouldDeanonymize = prepared.shouldDeanonymize === true;
3371
3640
  sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
3372
3641
  sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
3373
3642
  if (maskedText !== userText) {
@@ -3379,24 +3648,6 @@ var AgentID = class {
3379
3648
  nextCreateArgs[0] = maskedReq;
3380
3649
  createArgs = nextCreateArgs;
3381
3650
  }
3382
- const effectivePiiMasking = this.resolveEffectivePiiMasking(capabilityConfig);
3383
- if (!capabilityConfig.block_pii_leakage && effectivePiiMasking) {
3384
- if (stream) {
3385
- console.warn("AgentID: PII masking is disabled for streaming responses.");
3386
- } else {
3387
- const masked = this.pii.anonymize(maskedText);
3388
- maskedText = masked.maskedText;
3389
- mapping = masked.mapping;
3390
- shouldDeanonymize = Object.keys(mapping).length > 0;
3391
- maskedReq = this.withMaskedOpenAIRequest(
3392
- req,
3393
- maskedText
3394
- );
3395
- const nextCreateArgs = [...normalizedCreateArgs];
3396
- nextCreateArgs[0] = maskedReq;
3397
- createArgs = nextCreateArgs;
3398
- }
3399
- }
3400
3651
  }
3401
3652
  if (!maskedText) {
3402
3653
  throw new Error(
@@ -3475,7 +3726,11 @@ var AgentID = class {
3475
3726
  if (typeof streamResponse !== "undefined") {
3476
3727
  yield streamResponse;
3477
3728
  }
3478
- })()
3729
+ })(),
3730
+ {
3731
+ piiMapping: mapping,
3732
+ deanonymizeForClient: shouldDeanonymize
3733
+ }
3479
3734
  );
3480
3735
  if (maskedText && wrappedCompletion.mode === "stream") {
3481
3736
  void wrappedCompletion.done.then(async (result) => {
@@ -3512,7 +3767,8 @@ var AgentID = class {
3512
3767
  ...buildSdkTimingMetadata({
3513
3768
  sdkConfigFetchMs,
3514
3769
  sdkLocalScanMs,
3515
- sdkGuardMs: guardLatencyMs
3770
+ sdkGuardMs: guardLatencyMs,
3771
+ sdkConfigVersion: capabilityConfig.version
3516
3772
  })
3517
3773
  },
3518
3774
  client_capabilities: this.buildClientCapabilities(
@@ -3579,7 +3835,8 @@ var AgentID = class {
3579
3835
  ...buildSdkTimingMetadata({
3580
3836
  sdkConfigFetchMs,
3581
3837
  sdkLocalScanMs,
3582
- sdkGuardMs: guardLatencyMs
3838
+ sdkGuardMs: guardLatencyMs,
3839
+ sdkConfigVersion: capabilityConfig.version
3583
3840
  })
3584
3841
  },
3585
3842
  client_capabilities: this.buildClientCapabilities(
package/dist/index.d.mts CHANGED
@@ -1,18 +1,5 @@
1
- export { A as AgentID, D as DependencyError, G as GuardParams, a as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions, S as SecurityBlockError, T as TransparencyMetadata } from './agentid-M5I7-YqI.mjs';
2
-
3
- type PIIMapping = Record<string, string>;
4
- declare class PIIManager {
5
- /**
6
- * Reversible local-first masking using <TYPE_INDEX> placeholders.
7
- *
8
- * Zero-dependency fallback with strict checksum validation for CEE national IDs.
9
- */
10
- anonymize(text: string): {
11
- maskedText: string;
12
- mapping: PIIMapping;
13
- };
14
- deanonymize(text: string, mapping: PIIMapping): string;
15
- }
1
+ import { P as PIIManager } from './agentid-JQx2Iy7B.mjs';
2
+ export { A as AgentID, D as DependencyError, G as GuardParams, a as GuardResponse, L as LogParams, b as PIIMapping, c as PreparedInput, R as RequestOptions, S as SecurityBlockError, T as TransparencyMetadata } from './agentid-JQx2Iy7B.mjs';
16
3
 
17
4
  type TokenUsage = Record<string, unknown>;
18
5
  interface LLMAdapter {
@@ -60,4 +47,4 @@ declare class InjectionScanner {
60
47
  }
61
48
  declare function getInjectionScanner(): InjectionScanner;
62
49
 
63
- export { type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type PIIMapping, type TokenUsage, getInjectionScanner, scanWithRegex };
50
+ export { type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type TokenUsage, getInjectionScanner, scanWithRegex };
package/dist/index.d.ts CHANGED
@@ -1,18 +1,5 @@
1
- export { A as AgentID, D as DependencyError, G as GuardParams, a as GuardResponse, L as LogParams, P as PreparedInput, R as RequestOptions, S as SecurityBlockError, T as TransparencyMetadata } from './agentid-M5I7-YqI.js';
2
-
3
- type PIIMapping = Record<string, string>;
4
- declare class PIIManager {
5
- /**
6
- * Reversible local-first masking using <TYPE_INDEX> placeholders.
7
- *
8
- * Zero-dependency fallback with strict checksum validation for CEE national IDs.
9
- */
10
- anonymize(text: string): {
11
- maskedText: string;
12
- mapping: PIIMapping;
13
- };
14
- deanonymize(text: string, mapping: PIIMapping): string;
15
- }
1
+ import { P as PIIManager } from './agentid-JQx2Iy7B.js';
2
+ export { A as AgentID, D as DependencyError, G as GuardParams, a as GuardResponse, L as LogParams, b as PIIMapping, c as PreparedInput, R as RequestOptions, S as SecurityBlockError, T as TransparencyMetadata } from './agentid-JQx2Iy7B.js';
16
3
 
17
4
  type TokenUsage = Record<string, unknown>;
18
5
  interface LLMAdapter {
@@ -60,4 +47,4 @@ declare class InjectionScanner {
60
47
  }
61
48
  declare function getInjectionScanner(): InjectionScanner;
62
49
 
63
- export { type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type PIIMapping, type TokenUsage, getInjectionScanner, scanWithRegex };
50
+ export { type InjectionScanParams, InjectionScanner, type LLMAdapter, OpenAIAdapter, PIIManager, type TokenUsage, getInjectionScanner, scanWithRegex };