agentid-sdk 0.1.34 → 0.1.35

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;
@@ -152,7 +169,7 @@ declare class AgentID {
152
169
  private resolveEffectiveStrictMode;
153
170
  private maybeRaiseStrictIngestDependencyError;
154
171
  private shouldRunLocalInjectionScan;
155
- private refreshCapabilityConfigBeforeLocalEnforcement;
172
+ private refreshCapabilityConfigBeforeClientControl;
156
173
  private applyLocalPolicyChecks;
157
174
  prepareInputForDispatch(params: {
158
175
  input: string;
@@ -183,6 +200,10 @@ declare class AgentID {
183
200
  private sendIngest;
184
201
  private extractStreamChunkText;
185
202
  private extractStreamChunkUsage;
203
+ private isOpenAIStreamFinishChunk;
204
+ private setOpenAIStreamChunkText;
205
+ private createSyntheticOpenAIStreamChunk;
206
+ private rewriteOpenAIStreamChunkForClient;
186
207
  private wrapCompletion;
187
208
  /**
188
209
  * LOG: Sends telemetry after execution.
@@ -215,4 +236,4 @@ declare class AgentID {
215
236
  }): T;
216
237
  }
217
238
 
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 };
239
+ 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;
@@ -152,7 +169,7 @@ declare class AgentID {
152
169
  private resolveEffectiveStrictMode;
153
170
  private maybeRaiseStrictIngestDependencyError;
154
171
  private shouldRunLocalInjectionScan;
155
- private refreshCapabilityConfigBeforeLocalEnforcement;
172
+ private refreshCapabilityConfigBeforeClientControl;
156
173
  private applyLocalPolicyChecks;
157
174
  prepareInputForDispatch(params: {
158
175
  input: string;
@@ -183,6 +200,10 @@ declare class AgentID {
183
200
  private sendIngest;
184
201
  private extractStreamChunkText;
185
202
  private extractStreamChunkUsage;
203
+ private isOpenAIStreamFinishChunk;
204
+ private setOpenAIStreamChunkText;
205
+ private createSyntheticOpenAIStreamChunk;
206
+ private rewriteOpenAIStreamChunkForClient;
186
207
  private wrapCompletion;
187
208
  /**
188
209
  * LOG: Sends telemetry after execution.
@@ -215,4 +236,4 @@ declare class AgentID {
215
236
  }): T;
216
237
  }
217
238
 
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 };
239
+ 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.35".trim().length > 0 ? "js-0.1.35" : 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})`);
@@ -2662,7 +2737,7 @@ var AgentID = class {
2662
2737
  }
2663
2738
  return config.block_on_heuristic;
2664
2739
  }
2665
- async refreshCapabilityConfigBeforeLocalEnforcement(params) {
2740
+ async refreshCapabilityConfigBeforeClientControl(params) {
2666
2741
  const refreshed = await this.getCapabilityConfigWithTelemetry(true, params.options);
2667
2742
  return {
2668
2743
  capabilityConfig: refreshed.capabilityConfig,
@@ -2684,7 +2759,8 @@ var AgentID = class {
2684
2759
  eventId: params.clientEventId,
2685
2760
  clientEventId: params.clientEventId,
2686
2761
  telemetryMetadata: buildSdkTimingMetadata({
2687
- sdkConfigFetchMs: params.sdkConfigFetchMs
2762
+ sdkConfigFetchMs: params.sdkConfigFetchMs,
2763
+ sdkConfigVersion: params.capabilityConfig.version
2688
2764
  })
2689
2765
  });
2690
2766
  }
@@ -2729,15 +2805,38 @@ var AgentID = class {
2729
2805
  false,
2730
2806
  options
2731
2807
  );
2808
+ let sanitizedInput = params.input;
2809
+ let sdkLocalScanMs = 0;
2810
+ if (this.configuredPiiMasking === null) {
2811
+ const refreshed = await this.refreshCapabilityConfigBeforeClientControl({
2812
+ capabilityConfig,
2813
+ sdkConfigFetchMs,
2814
+ options
2815
+ });
2816
+ capabilityConfig = refreshed.capabilityConfig;
2817
+ sdkConfigFetchMs = refreshed.sdkConfigFetchMs;
2818
+ }
2732
2819
  if (!this.clientFastFail) {
2820
+ const effectivePiiMasking2 = this.resolveEffectivePiiMasking(capabilityConfig);
2821
+ if (!capabilityConfig.block_pii_leakage && effectivePiiMasking2) {
2822
+ const masked = this.pii.anonymize(sanitizedInput);
2823
+ return {
2824
+ sanitizedInput: masked.maskedText,
2825
+ capabilityConfig,
2826
+ sdkConfigFetchMs,
2827
+ sdkLocalScanMs,
2828
+ piiMapping: masked.mapping,
2829
+ shouldDeanonymize: Object.keys(masked.mapping).length > 0
2830
+ };
2831
+ }
2733
2832
  return {
2734
- sanitizedInput: params.input,
2833
+ sanitizedInput,
2735
2834
  capabilityConfig,
2736
2835
  sdkConfigFetchMs,
2737
- sdkLocalScanMs: 0
2836
+ sdkLocalScanMs
2738
2837
  };
2739
2838
  }
2740
- const refreshedConfig = await this.refreshCapabilityConfigBeforeLocalEnforcement({
2839
+ const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
2741
2840
  capabilityConfig,
2742
2841
  sdkConfigFetchMs,
2743
2842
  options
@@ -2754,11 +2853,25 @@ var AgentID = class {
2754
2853
  sdkConfigFetchMs,
2755
2854
  runPromptInjectionCheck: !params.skipInjectionScan
2756
2855
  });
2856
+ sanitizedInput = enforced.sanitizedInput;
2857
+ sdkLocalScanMs = enforced.sdkLocalScanMs;
2858
+ const effectivePiiMasking = this.resolveEffectivePiiMasking(capabilityConfig);
2859
+ if (!capabilityConfig.block_pii_leakage && effectivePiiMasking) {
2860
+ const masked = this.pii.anonymize(sanitizedInput);
2861
+ return {
2862
+ sanitizedInput: masked.maskedText,
2863
+ capabilityConfig,
2864
+ sdkConfigFetchMs,
2865
+ sdkLocalScanMs,
2866
+ piiMapping: masked.mapping,
2867
+ shouldDeanonymize: Object.keys(masked.mapping).length > 0
2868
+ };
2869
+ }
2757
2870
  return {
2758
- sanitizedInput: enforced.sanitizedInput,
2871
+ sanitizedInput,
2759
2872
  capabilityConfig,
2760
2873
  sdkConfigFetchMs,
2761
- sdkLocalScanMs: enforced.sdkLocalScanMs
2874
+ sdkLocalScanMs
2762
2875
  };
2763
2876
  }
2764
2877
  async applyLocalFallbackForGuardFailure(params, options) {
@@ -2767,7 +2880,7 @@ var AgentID = class {
2767
2880
  capabilityConfig: params.capabilityConfig,
2768
2881
  sdkConfigFetchMs: params.sdkConfigFetchMs
2769
2882
  } : await this.getCapabilityConfigWithTelemetry(false, options);
2770
- const refreshedConfig = await this.refreshCapabilityConfigBeforeLocalEnforcement({
2883
+ const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
2771
2884
  capabilityConfig: resolvedConfig.capabilityConfig,
2772
2885
  sdkConfigFetchMs: resolvedConfig.sdkConfigFetchMs,
2773
2886
  options
@@ -2797,7 +2910,7 @@ var AgentID = class {
2797
2910
  false,
2798
2911
  options
2799
2912
  );
2800
- const refreshedConfig = await this.refreshCapabilityConfigBeforeLocalEnforcement({
2913
+ const refreshedConfig = await this.refreshCapabilityConfigBeforeClientControl({
2801
2914
  capabilityConfig: initialConfig.capabilityConfig,
2802
2915
  sdkConfigFetchMs: initialConfig.sdkConfigFetchMs,
2803
2916
  options
@@ -2818,7 +2931,8 @@ var AgentID = class {
2818
2931
  eventId: options?.clientEventId,
2819
2932
  clientEventId: options?.clientEventId,
2820
2933
  telemetryMetadata: buildSdkTimingMetadata({
2821
- sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs
2934
+ sdkConfigFetchMs: refreshedConfig.sdkConfigFetchMs,
2935
+ sdkConfigVersion: refreshedConfig.capabilityConfig.version
2822
2936
  })
2823
2937
  });
2824
2938
  }
@@ -2871,7 +2985,10 @@ var AgentID = class {
2871
2985
  action_taken: params.actionTaken,
2872
2986
  ...buildSdkTimingMetadata({
2873
2987
  sdkConfigFetchMs: params.sdkConfigFetchMs,
2874
- sdkLocalScanMs: params.sdkLocalScanMs
2988
+ sdkLocalScanMs: params.sdkLocalScanMs,
2989
+ sdkConfigVersion: this.getCachedCapabilityConfig({
2990
+ apiKey: params.apiKey
2991
+ }).version
2875
2992
  })
2876
2993
  }
2877
2994
  }, { apiKey: params.apiKey });
@@ -3210,7 +3327,123 @@ var AgentID = class {
3210
3327
  const usage = chunk.usage;
3211
3328
  return usage && typeof usage === "object" && !Array.isArray(usage) ? usage : void 0;
3212
3329
  }
3213
- wrapCompletion(completion) {
3330
+ isOpenAIStreamFinishChunk(chunk) {
3331
+ if (!chunk || typeof chunk !== "object") {
3332
+ return false;
3333
+ }
3334
+ const choices = chunk.choices;
3335
+ if (!Array.isArray(choices)) {
3336
+ return false;
3337
+ }
3338
+ return choices.some(
3339
+ (choice) => choice && typeof choice === "object" && typeof choice.finish_reason === "string" && (choice.finish_reason ?? "").length > 0
3340
+ );
3341
+ }
3342
+ setOpenAIStreamChunkText(chunk, text) {
3343
+ if (!chunk || typeof chunk !== "object") {
3344
+ return false;
3345
+ }
3346
+ const choices = chunk.choices;
3347
+ if (!Array.isArray(choices)) {
3348
+ return false;
3349
+ }
3350
+ let assigned = false;
3351
+ const replaceInContainer = (container) => {
3352
+ if (!container || typeof container !== "object") {
3353
+ return false;
3354
+ }
3355
+ const content = container.content;
3356
+ if (typeof content === "string") {
3357
+ if (!assigned) {
3358
+ container.content = text;
3359
+ assigned = true;
3360
+ } else {
3361
+ container.content = "";
3362
+ }
3363
+ return true;
3364
+ }
3365
+ if (Array.isArray(content)) {
3366
+ let replacedInArray = false;
3367
+ for (const part of content) {
3368
+ if (!part || typeof part !== "object") continue;
3369
+ const typedPart = part;
3370
+ if (typeof typedPart.text !== "string") continue;
3371
+ if (!assigned && !replacedInArray) {
3372
+ typedPart.text = text;
3373
+ assigned = true;
3374
+ replacedInArray = true;
3375
+ } else {
3376
+ typedPart.text = "";
3377
+ }
3378
+ }
3379
+ if (!assigned && text.length > 0) {
3380
+ content.unshift({ type: "text", text });
3381
+ assigned = true;
3382
+ }
3383
+ return replacedInArray || assigned;
3384
+ }
3385
+ if (!assigned && text.length > 0) {
3386
+ container.content = text;
3387
+ assigned = true;
3388
+ return true;
3389
+ }
3390
+ return false;
3391
+ };
3392
+ for (const choice of choices) {
3393
+ if (!choice || typeof choice !== "object") {
3394
+ continue;
3395
+ }
3396
+ const typedChoice = choice;
3397
+ const replacedDelta = replaceInContainer(typedChoice.delta);
3398
+ const replacedMessage = replaceInContainer(typedChoice.message);
3399
+ if (!replacedDelta && !replacedMessage && !assigned && text.length > 0) {
3400
+ if (!typedChoice.delta || typeof typedChoice.delta !== "object") {
3401
+ typedChoice.delta = {};
3402
+ }
3403
+ typedChoice.delta.content = text;
3404
+ assigned = true;
3405
+ }
3406
+ }
3407
+ return assigned;
3408
+ }
3409
+ createSyntheticOpenAIStreamChunk(text, template) {
3410
+ const synthetic = {};
3411
+ if (template && typeof template === "object" && !Array.isArray(template)) {
3412
+ const typedTemplate = template;
3413
+ for (const key of ["id", "object", "created", "model"]) {
3414
+ if (Object.prototype.hasOwnProperty.call(typedTemplate, key)) {
3415
+ synthetic[key] = typedTemplate[key];
3416
+ }
3417
+ }
3418
+ }
3419
+ synthetic.choices = [
3420
+ {
3421
+ index: 0,
3422
+ delta: { content: text },
3423
+ finish_reason: null
3424
+ }
3425
+ ];
3426
+ return synthetic;
3427
+ }
3428
+ rewriteOpenAIStreamChunkForClient(chunk, rewriter, isFinishChunk) {
3429
+ const rawText = this.extractStreamChunkText(chunk);
3430
+ const rewrittenText = rawText ? rewriter.consume(rawText) : "";
3431
+ const finalText = isFinishChunk ? `${rewrittenText}${rewriter.flush()}` : rewrittenText;
3432
+ if (typeof chunk === "string") {
3433
+ return finalText ? [finalText] : [];
3434
+ }
3435
+ if (rawText) {
3436
+ if (this.setOpenAIStreamChunkText(chunk, finalText)) {
3437
+ return [chunk];
3438
+ }
3439
+ return finalText.length > 0 ? [this.createSyntheticOpenAIStreamChunk(finalText, chunk), chunk] : [chunk];
3440
+ }
3441
+ if (isFinishChunk && finalText.length > 0) {
3442
+ return [this.createSyntheticOpenAIStreamChunk(finalText, chunk), chunk];
3443
+ }
3444
+ return [chunk];
3445
+ }
3446
+ wrapCompletion(completion, options) {
3214
3447
  if (typeof completion === "string") {
3215
3448
  const masked = this.pii.anonymize(completion);
3216
3449
  return {
@@ -3234,7 +3467,11 @@ var AgentID = class {
3234
3467
  const collector = createCompletionChunkCollector();
3235
3468
  const extractStreamChunkText = this.extractStreamChunkText.bind(this);
3236
3469
  const extractStreamChunkUsage = this.extractStreamChunkUsage.bind(this);
3470
+ const isOpenAIStreamFinishChunk = this.isOpenAIStreamFinishChunk.bind(this);
3471
+ const rewriteOpenAIStreamChunkForClient = this.rewriteOpenAIStreamChunkForClient.bind(this);
3472
+ const createSyntheticOpenAIStreamChunk = this.createSyntheticOpenAIStreamChunk.bind(this);
3237
3473
  const piiManager = this.pii;
3474
+ const streamRewriter = options?.deanonymizeForClient === true && options.piiMapping ? createStreamingPlaceholderRewriter(piiManager, options.piiMapping) : null;
3238
3475
  let lastUsage;
3239
3476
  let resolveDone = null;
3240
3477
  let rejectDone = null;
@@ -3245,17 +3482,44 @@ var AgentID = class {
3245
3482
  const wrapped = {
3246
3483
  [Symbol.asyncIterator]: async function* () {
3247
3484
  try {
3485
+ let finishChunkFlushed = false;
3486
+ let lastChunkTemplate;
3248
3487
  for await (const chunk of source) {
3249
3488
  const chunkText = extractStreamChunkText(chunk);
3489
+ const isFinishChunk = streamRewriter ? isOpenAIStreamFinishChunk(chunk) : false;
3250
3490
  if (chunkText) {
3251
3491
  await collector.push(chunkText);
3492
+ lastChunkTemplate = chunk;
3252
3493
  }
3253
3494
  const chunkUsage = extractStreamChunkUsage(chunk);
3254
3495
  if (chunkUsage) {
3255
3496
  lastUsage = chunkUsage;
3256
3497
  }
3498
+ if (streamRewriter) {
3499
+ const rewrittenChunks = rewriteOpenAIStreamChunkForClient(
3500
+ chunk,
3501
+ streamRewriter,
3502
+ isFinishChunk
3503
+ );
3504
+ if (isFinishChunk) {
3505
+ finishChunkFlushed = true;
3506
+ }
3507
+ for (const rewrittenChunk of rewrittenChunks) {
3508
+ yield rewrittenChunk;
3509
+ }
3510
+ continue;
3511
+ }
3257
3512
  yield chunk;
3258
3513
  }
3514
+ if (streamRewriter && !finishChunkFlushed) {
3515
+ const trailingText = streamRewriter.flush();
3516
+ if (trailingText.length > 0) {
3517
+ yield createSyntheticOpenAIStreamChunk(
3518
+ trailingText,
3519
+ lastChunkTemplate
3520
+ );
3521
+ }
3522
+ }
3259
3523
  await collector.close();
3260
3524
  const rawOutput = await collector.result;
3261
3525
  const masked = piiManager.anonymize(rawOutput);
@@ -3368,6 +3632,8 @@ var AgentID = class {
3368
3632
  }, requestOptions);
3369
3633
  capabilityConfig = prepared.capabilityConfig;
3370
3634
  maskedText = prepared.sanitizedInput;
3635
+ mapping = prepared.piiMapping ?? {};
3636
+ shouldDeanonymize = prepared.shouldDeanonymize === true;
3371
3637
  sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
3372
3638
  sdkLocalScanMs = prepared.sdkLocalScanMs ?? 0;
3373
3639
  if (maskedText !== userText) {
@@ -3379,24 +3645,6 @@ var AgentID = class {
3379
3645
  nextCreateArgs[0] = maskedReq;
3380
3646
  createArgs = nextCreateArgs;
3381
3647
  }
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
3648
  }
3401
3649
  if (!maskedText) {
3402
3650
  throw new Error(
@@ -3475,7 +3723,11 @@ var AgentID = class {
3475
3723
  if (typeof streamResponse !== "undefined") {
3476
3724
  yield streamResponse;
3477
3725
  }
3478
- })()
3726
+ })(),
3727
+ {
3728
+ piiMapping: mapping,
3729
+ deanonymizeForClient: shouldDeanonymize
3730
+ }
3479
3731
  );
3480
3732
  if (maskedText && wrappedCompletion.mode === "stream") {
3481
3733
  void wrappedCompletion.done.then(async (result) => {
@@ -3512,7 +3764,8 @@ var AgentID = class {
3512
3764
  ...buildSdkTimingMetadata({
3513
3765
  sdkConfigFetchMs,
3514
3766
  sdkLocalScanMs,
3515
- sdkGuardMs: guardLatencyMs
3767
+ sdkGuardMs: guardLatencyMs,
3768
+ sdkConfigVersion: capabilityConfig.version
3516
3769
  })
3517
3770
  },
3518
3771
  client_capabilities: this.buildClientCapabilities(
@@ -3579,7 +3832,8 @@ var AgentID = class {
3579
3832
  ...buildSdkTimingMetadata({
3580
3833
  sdkConfigFetchMs,
3581
3834
  sdkLocalScanMs,
3582
- sdkGuardMs: guardLatencyMs
3835
+ sdkGuardMs: guardLatencyMs,
3836
+ sdkConfigVersion: capabilityConfig.version
3583
3837
  })
3584
3838
  },
3585
3839
  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-IonlG0NB.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-IonlG0NB.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-IonlG0NB.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-IonlG0NB.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 };