agentid-sdk 0.1.38 → 0.1.41

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/dist/index.js CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  createAgentIdTelemetryContext: () => createAgentIdTelemetryContext,
34
34
  createAgentIdWorkflowTrail: () => createAgentIdWorkflowTrail,
35
35
  getInjectionScanner: () => getInjectionScanner,
36
+ protectMessageHistory: () => protectMessageHistory,
36
37
  scanWithRegex: () => scanWithRegex
37
38
  });
38
39
  module.exports = __toCommonJS(index_exports);
@@ -181,7 +182,7 @@ var OpenAIAdapter = class {
181
182
 
182
183
  // src/sdk-version.ts
183
184
  var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
184
- var AGENTID_SDK_VERSION_HEADER = "js-0.1.38".trim().length > 0 ? "js-0.1.38" : FALLBACK_SDK_VERSION;
185
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.41".trim().length > 0 ? "js-0.1.41" : FALLBACK_SDK_VERSION;
185
186
 
186
187
  // src/pii-national-identifiers.ts
187
188
  var MAX_CANDIDATES_PER_RULE = 256;
@@ -1167,9 +1168,9 @@ var SDK_SECRET_PATTERN_DEFINITIONS = [
1167
1168
  {
1168
1169
  id: "password_assignment",
1169
1170
  placeholderType: "PASSWORD_ASSIGNMENT",
1170
- patternSource: `(?:\\b|["'])(?:password|passwd|pwd)(?:\\b|["'])\\s*(?:(?::|=|=>)|(?:is|are|was|were)\\b)\\s*(?:"[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}"|'[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}'|[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,})`,
1171
+ patternSource: `(?:\\b|["'])(?:password|passwd|pwd|heslo)(?:\\b|["'])\\s*(?:(?::|=|=>)|(?:is|are|was|were|je)\\b)?\\s*(?:"[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}"|'[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,}'|[A-Za-z0-9._~!@#$%^&*+=\\/-]{8,})`,
1171
1172
  flags: "iu",
1172
- prefilterTerms: ["password", "passwd", "pwd"]
1173
+ prefilterTerms: ["password", "passwd", "pwd", "heslo"]
1173
1174
  },
1174
1175
  {
1175
1176
  id: "private_key_material",
@@ -1271,6 +1272,8 @@ var PHONE_CONTEXT_KEYWORDS = [
1271
1272
  "call",
1272
1273
  "contact",
1273
1274
  "number",
1275
+ "cislo",
1276
+ "\u010D\xEDslo",
1274
1277
  "hotline",
1275
1278
  "support",
1276
1279
  "infoline",
@@ -1679,9 +1682,9 @@ var DEFAULT_FAIL_OPEN_CONFIG = {
1679
1682
  block_on_heuristic: false,
1680
1683
  inject_transparency_metadata: false,
1681
1684
  block_pii_leakage: false,
1682
- enable_sdk_pii_masking: false,
1685
+ enable_sdk_pii_masking: true,
1683
1686
  block_secret_leakage: false,
1684
- enable_sdk_secret_masking: false,
1687
+ enable_sdk_secret_masking: true,
1685
1688
  block_db_access: false,
1686
1689
  block_code_execution: false,
1687
1690
  block_toxicity: false
@@ -2745,7 +2748,7 @@ var GUARD_MAX_ATTEMPTS = 3;
2745
2748
  var GUARD_RETRY_DELAYS_MS = [250, 500];
2746
2749
  var INGEST_MAX_ATTEMPTS = 3;
2747
2750
  var INGEST_RETRY_DELAYS_MS = [250, 500];
2748
- var GUARD_VERDICT_CACHE_TTL_MS = 0;
2751
+ var GUARD_VERDICT_CACHE_TTL_MS = 1500;
2749
2752
  var MAX_INGEST_TEXT_CHARS = 32e3;
2750
2753
  var OPENAI_TELEMETRY_FIELD = "agentid_telemetry";
2751
2754
  function normalizeBaseUrl3(baseUrl) {
@@ -3593,6 +3596,7 @@ var AgentID = class {
3593
3596
  constructor(config = {}) {
3594
3597
  this.injectionScanner = getInjectionScanner();
3595
3598
  this.recentGuardVerdicts = /* @__PURE__ */ new Map();
3599
+ this.pendingGuardRequests = /* @__PURE__ */ new Map();
3596
3600
  this.apiKey = resolveConfiguredApiKey(config.apiKey);
3597
3601
  this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
3598
3602
  this.configuredPiiMasking = typeof config.piiMasking === "boolean" ? config.piiMasking : null;
@@ -3683,13 +3687,14 @@ var AgentID = class {
3683
3687
  }
3684
3688
  return createEventId2();
3685
3689
  }
3686
- buildGuardCacheKey(params) {
3690
+ buildGuardCacheKey(params, apiKey) {
3687
3691
  if (!params.system_id || !params.input) {
3688
3692
  return null;
3689
3693
  }
3690
3694
  const userId = params.user_id?.trim() ?? "";
3691
- const normalizedInput = params.input.slice(0, 2048);
3692
- return `${params.system_id}|${userId}|${normalizedInput.length}|${normalizedInput}`;
3695
+ const normalizedInput = params.input.trim().replace(/\s+/g, " ").slice(0, 2048);
3696
+ const keyPrefix = apiKey?.slice(0, 24) ?? "";
3697
+ return `${keyPrefix}|${params.system_id}|${userId}|${normalizedInput.length}|${normalizedInput}`;
3693
3698
  }
3694
3699
  readCachedGuardVerdict(cacheKey) {
3695
3700
  if (!cacheKey) return null;
@@ -3702,7 +3707,7 @@ var AgentID = class {
3702
3707
  return cached.verdict;
3703
3708
  }
3704
3709
  cacheGuardVerdict(cacheKey, verdict) {
3705
- if (!cacheKey || !verdict.allowed || GUARD_VERDICT_CACHE_TTL_MS <= 0) {
3710
+ if (!cacheKey || GUARD_VERDICT_CACHE_TTL_MS <= 0) {
3706
3711
  return;
3707
3712
  }
3708
3713
  this.recentGuardVerdicts.set(cacheKey, {
@@ -3750,6 +3755,23 @@ var AgentID = class {
3750
3755
  const config = await this.getCapabilityConfig(false, options);
3751
3756
  return config.strict_security_mode || config.failure_mode === "fail_close";
3752
3757
  }
3758
+ buildFailOpenGuardVerdict(reason, input, options) {
3759
+ const capabilityConfig = this.getCachedCapabilityConfig(options);
3760
+ const shouldMaskPii = capabilityConfig.block_pii_leakage || this.resolveEffectivePiiMasking(capabilityConfig);
3761
+ const shouldMaskSecrets = capabilityConfig.block_secret_leakage === true || this.resolveEffectiveSecretMasking(capabilityConfig);
3762
+ const response = { allowed: true, reason };
3763
+ if (input && (shouldMaskPii || shouldMaskSecrets)) {
3764
+ const masked = this.pii.anonymize(input, {
3765
+ pii: shouldMaskPii,
3766
+ secrets: shouldMaskSecrets
3767
+ });
3768
+ if (masked.maskedText !== input) {
3769
+ response.transformed_input = masked.maskedText;
3770
+ response.detected_pii = Object.keys(masked.mapping).length > 0;
3771
+ }
3772
+ }
3773
+ return response;
3774
+ }
3753
3775
  maybeRaiseStrictIngestDependencyError(params) {
3754
3776
  if (params.result.ok) {
3755
3777
  return;
@@ -3990,12 +4012,43 @@ var AgentID = class {
3990
4012
  })
3991
4013
  });
3992
4014
  }
3993
- withMaskedOpenAIRequest(req, maskedText) {
4015
+ withMaskedOpenAIRequest(req, maskedText, options) {
3994
4016
  const messages = Array.isArray(req?.messages) ? req.messages : null;
3995
4017
  if (!messages) {
3996
4018
  return req;
3997
4019
  }
3998
- const newMessages = [...messages];
4020
+ const newMessages = messages.map((message2) => {
4021
+ if (!message2 || typeof message2 !== "object") {
4022
+ return message2;
4023
+ }
4024
+ const typedMessage = message2;
4025
+ const currentContent2 = typedMessage.content;
4026
+ if (typeof currentContent2 === "string") {
4027
+ return {
4028
+ ...typedMessage,
4029
+ content: this.pii.anonymize(currentContent2, options).maskedText
4030
+ };
4031
+ }
4032
+ if (Array.isArray(currentContent2)) {
4033
+ return {
4034
+ ...typedMessage,
4035
+ content: currentContent2.map((part) => {
4036
+ if (!part || typeof part !== "object") {
4037
+ return part;
4038
+ }
4039
+ const typedPart = part;
4040
+ if (typeof typedPart.text !== "string") {
4041
+ return part;
4042
+ }
4043
+ return {
4044
+ ...typedPart,
4045
+ text: this.pii.anonymize(typedPart.text, options).maskedText
4046
+ };
4047
+ })
4048
+ };
4049
+ }
4050
+ return message2;
4051
+ });
3999
4052
  let lastUserIdx = null;
4000
4053
  for (let i = 0; i < newMessages.length; i += 1) {
4001
4054
  const msg = newMessages[i];
@@ -4152,138 +4205,185 @@ var AgentID = class {
4152
4205
  ...params,
4153
4206
  client_capabilities: params.client_capabilities ?? this.buildClientCapabilities()
4154
4207
  };
4155
- const guardCacheKey = this.buildGuardCacheKey(payload);
4208
+ const guardCacheKey = this.buildGuardCacheKey(payload, effectiveApiKey);
4156
4209
  const cachedVerdict = this.readCachedGuardVerdict(guardCacheKey);
4157
4210
  if (cachedVerdict) {
4158
4211
  return withGuardLatency(cachedVerdict);
4159
4212
  }
4160
- const correlationId = createCorrelationId(payload.client_event_id);
4161
- let lastStatusCode = null;
4162
- let lastAbort = false;
4163
- let lastError = null;
4164
- for (let attempt = 0; attempt < GUARD_MAX_ATTEMPTS; attempt += 1) {
4165
- const controller = new AbortController();
4166
- const timeoutId = setTimeout(() => controller.abort(), this.guardTimeoutMs);
4167
- try {
4168
- const res = await fetch(`${this.baseUrl}/guard`, {
4169
- method: "POST",
4170
- headers: {
4171
- "Content-Type": "application/json",
4172
- "x-agentid-api-key": effectiveApiKey,
4173
- "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER,
4174
- "x-correlation-id": correlationId
4175
- },
4176
- body: JSON.stringify(payload),
4177
- signal: controller.signal
4178
- });
4179
- lastStatusCode = res.status;
4180
- const responseBody = await safeReadJson2(res);
4181
- if (responseBody && typeof responseBody.allowed === "boolean") {
4182
- const rawVerdict = responseBody;
4183
- const transparency = coerceTransparencyMetadata(rawVerdict.transparency);
4184
- const verdict = {
4185
- ...rawVerdict,
4186
- ...transparency ? { transparency } : {}
4187
- };
4188
- const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || !verdict.reason && res.status >= 500);
4189
- if (infrastructureFailure) {
4190
- if (attempt < GUARD_MAX_ATTEMPTS - 1) {
4191
- await waitForRetry(attempt);
4192
- continue;
4193
- }
4194
- if (effectiveStrictMode) {
4213
+ const pendingGuardRequest = guardCacheKey ? this.pendingGuardRequests.get(guardCacheKey) : void 0;
4214
+ if (pendingGuardRequest) {
4215
+ return withGuardLatency(await pendingGuardRequest.promise);
4216
+ }
4217
+ const executeGuardRequest = async () => {
4218
+ const correlationId = createCorrelationId(payload.client_event_id);
4219
+ let lastStatusCode = null;
4220
+ let lastAbort = false;
4221
+ let lastError = null;
4222
+ for (let attempt = 0; attempt < GUARD_MAX_ATTEMPTS; attempt += 1) {
4223
+ const controller = new AbortController();
4224
+ const timeoutId = setTimeout(() => controller.abort(), this.guardTimeoutMs);
4225
+ try {
4226
+ const res = await fetch(`${this.baseUrl}/guard`, {
4227
+ method: "POST",
4228
+ headers: {
4229
+ "Content-Type": "application/json",
4230
+ "x-agentid-api-key": effectiveApiKey,
4231
+ "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER,
4232
+ "x-correlation-id": correlationId
4233
+ },
4234
+ body: JSON.stringify(payload),
4235
+ signal: controller.signal
4236
+ });
4237
+ lastStatusCode = res.status;
4238
+ const responseBody = await safeReadJson2(res);
4239
+ if (responseBody && typeof responseBody.allowed === "boolean") {
4240
+ const rawVerdict = responseBody;
4241
+ const transparency = coerceTransparencyMetadata(rawVerdict.transparency);
4242
+ const verdict = {
4243
+ ...rawVerdict,
4244
+ ...transparency ? { transparency } : {}
4245
+ };
4246
+ const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || !verdict.reason && res.status >= 500);
4247
+ if (infrastructureFailure) {
4248
+ if (attempt < GUARD_MAX_ATTEMPTS - 1) {
4249
+ await waitForRetry(attempt);
4250
+ continue;
4251
+ }
4252
+ if (effectiveStrictMode) {
4253
+ console.warn(
4254
+ `[AgentID] Guard API infrastructure failure in strict mode (${verdict.reason ?? `http_${res.status}`}). Blocking request.`
4255
+ );
4256
+ return withGuardLatency({
4257
+ allowed: false,
4258
+ reason: verdict.reason ?? "network_error_strict_mode"
4259
+ });
4260
+ }
4195
4261
  console.warn(
4196
- `[AgentID] Guard API infrastructure failure in strict mode (${verdict.reason ?? `http_${res.status}`}). Blocking request.`
4262
+ `[AgentID] Guard API infrastructure fallback in fail-open mode (${verdict.reason ?? `http_${res.status}`}).`
4197
4263
  );
4198
- return withGuardLatency({
4199
- allowed: false,
4200
- reason: verdict.reason ?? "network_error_strict_mode"
4264
+ this.logGuardFallback({
4265
+ reason: verdict.reason ?? `http_${res.status}`,
4266
+ status: "upstream_error",
4267
+ guardParams: params,
4268
+ apiKey: effectiveApiKey
4201
4269
  });
4270
+ return withGuardLatency(
4271
+ this.buildFailOpenGuardVerdict(
4272
+ "system_failure_fail_open",
4273
+ params.input,
4274
+ { apiKey: effectiveApiKey }
4275
+ )
4276
+ );
4202
4277
  }
4203
- console.warn(
4204
- `[AgentID] Guard API infrastructure fallback in fail-open mode (${verdict.reason ?? `http_${res.status}`}).`
4205
- );
4278
+ this.cacheGuardVerdict(guardCacheKey, verdict);
4279
+ return withGuardLatency(verdict);
4280
+ }
4281
+ if (!res.ok) {
4282
+ if (res.status >= 500 && attempt < GUARD_MAX_ATTEMPTS - 1) {
4283
+ await waitForRetry(attempt);
4284
+ continue;
4285
+ }
4286
+ throw new Error(`API Error ${res.status}`);
4287
+ }
4288
+ throw new Error("Invalid guard response");
4289
+ } catch (error) {
4290
+ lastError = error;
4291
+ const isAbortError2 = Boolean(
4292
+ error && typeof error === "object" && error.name === "AbortError"
4293
+ );
4294
+ lastAbort = isAbortError2;
4295
+ if (attempt < GUARD_MAX_ATTEMPTS - 1) {
4296
+ await waitForRetry(attempt);
4297
+ continue;
4298
+ }
4299
+ if (isAbortError2) {
4300
+ const timeoutMessage = "AgentID API Warning: Connection timeout exceeded.";
4301
+ console.warn(timeoutMessage);
4206
4302
  this.logGuardFallback({
4207
- reason: verdict.reason ?? `http_${res.status}`,
4208
- status: "upstream_error",
4303
+ reason: "timeout_fallback",
4304
+ status: "latency_timeout",
4209
4305
  guardParams: params,
4210
4306
  apiKey: effectiveApiKey
4211
4307
  });
4212
- return withGuardLatency({ allowed: true, reason: "system_failure_fail_open" });
4213
- }
4214
- this.cacheGuardVerdict(guardCacheKey, verdict);
4215
- return withGuardLatency(verdict);
4216
- }
4217
- if (!res.ok) {
4218
- if (res.status >= 500 && attempt < GUARD_MAX_ATTEMPTS - 1) {
4219
- await waitForRetry(attempt);
4220
- continue;
4308
+ if (effectiveStrictMode) {
4309
+ return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
4310
+ }
4311
+ return withGuardLatency(
4312
+ this.buildFailOpenGuardVerdict("timeout_fallback", params.input, {
4313
+ apiKey: effectiveApiKey
4314
+ })
4315
+ );
4221
4316
  }
4222
- throw new Error(`API Error ${res.status}`);
4223
- }
4224
- throw new Error("Invalid guard response");
4225
- } catch (error) {
4226
- lastError = error;
4227
- const isAbortError2 = Boolean(
4228
- error && typeof error === "object" && error.name === "AbortError"
4229
- );
4230
- lastAbort = isAbortError2;
4231
- if (attempt < GUARD_MAX_ATTEMPTS - 1) {
4232
- await waitForRetry(attempt);
4233
- continue;
4234
- }
4235
- if (isAbortError2) {
4236
- const timeoutMessage = "AgentID API Warning: Connection timeout exceeded.";
4237
- console.warn(timeoutMessage);
4317
+ console.warn(
4318
+ effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
4319
+ error
4320
+ );
4238
4321
  this.logGuardFallback({
4239
- reason: "timeout_fallback",
4240
- status: "latency_timeout",
4322
+ reason: "guard_unreachable",
4323
+ status: "guard_unreachable",
4241
4324
  guardParams: params,
4242
4325
  apiKey: effectiveApiKey
4243
4326
  });
4244
4327
  if (effectiveStrictMode) {
4245
4328
  return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
4246
4329
  }
4247
- return withGuardLatency({ allowed: true, reason: "timeout_fallback" });
4330
+ return withGuardLatency(
4331
+ this.buildFailOpenGuardVerdict("guard_unreachable", params.input, {
4332
+ apiKey: effectiveApiKey
4333
+ })
4334
+ );
4335
+ } finally {
4336
+ clearTimeout(timeoutId);
4248
4337
  }
4249
- console.warn(
4250
- effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
4251
- error
4252
- );
4253
- this.logGuardFallback({
4254
- reason: "guard_unreachable",
4255
- status: "guard_unreachable",
4256
- guardParams: params,
4257
- apiKey: effectiveApiKey
4258
- });
4338
+ }
4339
+ if (lastAbort) {
4259
4340
  if (effectiveStrictMode) {
4260
4341
  return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
4261
4342
  }
4262
- return withGuardLatency({ allowed: true, reason: "guard_unreachable" });
4263
- } finally {
4264
- clearTimeout(timeoutId);
4343
+ return withGuardLatency(
4344
+ this.buildFailOpenGuardVerdict("timeout_fallback", params.input, {
4345
+ apiKey: effectiveApiKey
4346
+ })
4347
+ );
4265
4348
  }
4266
- }
4267
- if (lastAbort) {
4349
+ if (typeof lastStatusCode === "number" && lastStatusCode >= 500) {
4350
+ if (effectiveStrictMode) {
4351
+ return withGuardLatency({ allowed: false, reason: "server_error" });
4352
+ }
4353
+ return withGuardLatency(
4354
+ this.buildFailOpenGuardVerdict(
4355
+ "system_failure_fail_open",
4356
+ params.input,
4357
+ { apiKey: effectiveApiKey }
4358
+ )
4359
+ );
4360
+ }
4361
+ console.warn(
4362
+ effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
4363
+ lastError
4364
+ );
4268
4365
  if (effectiveStrictMode) {
4269
4366
  return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
4270
4367
  }
4271
- return withGuardLatency({ allowed: true, reason: "timeout_fallback" });
4368
+ return withGuardLatency(
4369
+ this.buildFailOpenGuardVerdict("guard_unreachable", params.input, {
4370
+ apiKey: effectiveApiKey
4371
+ })
4372
+ );
4373
+ };
4374
+ if (!guardCacheKey) {
4375
+ return executeGuardRequest();
4272
4376
  }
4273
- if (typeof lastStatusCode === "number" && lastStatusCode >= 500) {
4274
- if (effectiveStrictMode) {
4275
- return withGuardLatency({ allowed: false, reason: "server_error" });
4377
+ const promise = executeGuardRequest();
4378
+ this.pendingGuardRequests.set(guardCacheKey, { promise });
4379
+ try {
4380
+ return await promise;
4381
+ } finally {
4382
+ const pending = this.pendingGuardRequests.get(guardCacheKey);
4383
+ if (pending?.promise === promise) {
4384
+ this.pendingGuardRequests.delete(guardCacheKey);
4276
4385
  }
4277
- return withGuardLatency({ allowed: true, reason: "system_failure_fail_open" });
4278
4386
  }
4279
- console.warn(
4280
- effectiveStrictMode ? "[AgentID] Guard check failed (Strict mode active):" : "[AgentID] Guard check failed (Fail-Open active):",
4281
- lastError
4282
- );
4283
- if (effectiveStrictMode) {
4284
- return withGuardLatency({ allowed: false, reason: "network_error_strict_mode" });
4285
- }
4286
- return withGuardLatency({ allowed: true, reason: "guard_unreachable" });
4287
4387
  }
4288
4388
  async sendIngest(params, options, internal) {
4289
4389
  const ingestStartedAt = Date.now();
@@ -4788,6 +4888,7 @@ var AgentID = class {
4788
4888
  let mapping = {};
4789
4889
  let sdkConfigFetchMs = 0;
4790
4890
  let sdkLocalScanMs = 0;
4891
+ let providerMaskingOptions;
4791
4892
  if (hasGuardContent) {
4792
4893
  const prepared = await this.prepareInputForDispatch({
4793
4894
  input: userText ?? "",
@@ -4797,6 +4898,10 @@ var AgentID = class {
4797
4898
  telemetryMetadata
4798
4899
  }, requestOptions);
4799
4900
  capabilityConfig = prepared.capabilityConfig;
4901
+ providerMaskingOptions = {
4902
+ pii: !capabilityConfig.block_pii_leakage && this.resolveEffectivePiiMasking(capabilityConfig),
4903
+ secrets: !capabilityConfig.block_secret_leakage && this.resolveEffectiveSecretMasking(capabilityConfig)
4904
+ };
4800
4905
  maskedText = prepared.sanitizedInput;
4801
4906
  mapping = prepared.piiMapping ?? {};
4802
4907
  sdkConfigFetchMs = prepared.sdkConfigFetchMs ?? 0;
@@ -4804,7 +4909,8 @@ var AgentID = class {
4804
4909
  if (maskedText !== (userText ?? "")) {
4805
4910
  maskedReq = this.withMaskedOpenAIRequest(
4806
4911
  providerReq,
4807
- maskedText
4912
+ maskedText,
4913
+ providerMaskingOptions
4808
4914
  );
4809
4915
  const nextCreateArgs = [...createArgs];
4810
4916
  nextCreateArgs[0] = maskedReq;
@@ -4878,10 +4984,11 @@ var AgentID = class {
4878
4984
  }
4879
4985
  }
4880
4986
  const currentRequestInput = adapter.extractInput(maskedReq) ?? "";
4881
- if (maskedText !== currentRequestInput) {
4987
+ if (maskedText !== currentRequestInput || providerMaskingOptions?.pii === true || providerMaskingOptions?.secrets === true) {
4882
4988
  maskedReq = this.withMaskedOpenAIRequest(
4883
4989
  providerReq,
4884
- maskedText
4990
+ maskedText,
4991
+ providerMaskingOptions
4885
4992
  );
4886
4993
  const nextCreateArgs = [...createArgs];
4887
4994
  nextCreateArgs[0] = maskedReq;
@@ -4904,7 +5011,8 @@ var AgentID = class {
4904
5011
  maskedText = transformedInput;
4905
5012
  maskedReq = this.withMaskedOpenAIRequest(
4906
5013
  providerReq,
4907
- transformedInput
5014
+ transformedInput,
5015
+ providerMaskingOptions
4908
5016
  );
4909
5017
  const nextCreateArgs = [...createArgs];
4910
5018
  nextCreateArgs[0] = maskedReq;
@@ -4951,7 +5059,7 @@ var AgentID = class {
4951
5059
  void wrappedCompletion.done.then(async (result) => {
4952
5060
  const modelLatencyMs2 = Math.max(0, Date.now() - modelStartedAt2);
4953
5061
  const totalPipelineLatencyMs2 = Math.max(0, Date.now() - pipelineStartedAt);
4954
- const outputForLog = isShadowMode ? result.rawOutput : result.transformedOutput;
5062
+ const outputForLog = result.transformedOutput;
4955
5063
  const ingestResult = await this.sendIngest({
4956
5064
  event_id: canonicalClientEventId,
4957
5065
  system_id: systemId,
@@ -5025,7 +5133,7 @@ var AgentID = class {
5025
5133
  });
5026
5134
  const model = adapter.getModelName(maskedReq, res);
5027
5135
  const usage = adapter.getTokenUsage(res);
5028
- const outputForLog = isShadowMode ? wrappedCompletion.rawOutput : wrappedCompletion.transformedOutput;
5136
+ const outputForLog = wrappedCompletion.transformedOutput;
5029
5137
  const ingestResult = await this.sendIngest({
5030
5138
  event_id: canonicalClientEventId,
5031
5139
  system_id: systemId,
@@ -5267,6 +5375,58 @@ var AgentIDWorkflowTrail = class {
5267
5375
  function createAgentIdWorkflowTrail(options) {
5268
5376
  return new AgentIDWorkflowTrail(options);
5269
5377
  }
5378
+
5379
+ // src/message-history.ts
5380
+ function isPlainRecord(value) {
5381
+ if (!value || typeof value !== "object") return false;
5382
+ const proto = Object.getPrototypeOf(value);
5383
+ return proto === Object.prototype || proto === null;
5384
+ }
5385
+ function protectMessageHistory(messages, options = { pii: true, secrets: true }) {
5386
+ const piiManager = new PIIManager();
5387
+ let textPartsCount = 0;
5388
+ let transformedTextPartsCount = 0;
5389
+ const protectString = (value) => {
5390
+ textPartsCount += 1;
5391
+ const masked = piiManager.anonymize(value, options).maskedText;
5392
+ if (masked !== value) {
5393
+ transformedTextPartsCount += 1;
5394
+ }
5395
+ return masked;
5396
+ };
5397
+ const visit = (value, key) => {
5398
+ if (typeof value === "string") {
5399
+ return key === "content" || key === "text" ? protectString(value) : value;
5400
+ }
5401
+ if (Array.isArray(value)) {
5402
+ let changed = false;
5403
+ const next = value.map((item) => {
5404
+ const protectedItem = visit(item);
5405
+ if (protectedItem !== item) changed = true;
5406
+ return protectedItem;
5407
+ });
5408
+ return changed ? next : value;
5409
+ }
5410
+ if (isPlainRecord(value)) {
5411
+ let changed = false;
5412
+ const next = {};
5413
+ for (const [entryKey, entryValue] of Object.entries(value)) {
5414
+ const protectedValue = visit(entryValue, entryKey);
5415
+ next[entryKey] = protectedValue;
5416
+ if (protectedValue !== entryValue) changed = true;
5417
+ }
5418
+ return changed ? next : value;
5419
+ }
5420
+ return value;
5421
+ };
5422
+ const protectedMessages = visit(messages);
5423
+ return {
5424
+ messages: protectedMessages,
5425
+ transformed: protectedMessages !== messages,
5426
+ textPartsCount,
5427
+ transformedTextPartsCount
5428
+ };
5429
+ }
5270
5430
  // Annotate the CommonJS export names for ESM import in node:
5271
5431
  0 && (module.exports = {
5272
5432
  AgentID,
@@ -5282,5 +5442,6 @@ function createAgentIdWorkflowTrail(options) {
5282
5442
  createAgentIdTelemetryContext,
5283
5443
  createAgentIdWorkflowTrail,
5284
5444
  getInjectionScanner,
5445
+ protectMessageHistory,
5285
5446
  scanWithRegex
5286
5447
  });
package/dist/index.mjs CHANGED
@@ -13,7 +13,59 @@ import {
13
13
  createAgentIdWorkflowTrail,
14
14
  getInjectionScanner,
15
15
  scanWithRegex
16
- } from "./chunk-AIGMQSAV.mjs";
16
+ } from "./chunk-L2WVWRAC.mjs";
17
+
18
+ // src/message-history.ts
19
+ function isPlainRecord(value) {
20
+ if (!value || typeof value !== "object") return false;
21
+ const proto = Object.getPrototypeOf(value);
22
+ return proto === Object.prototype || proto === null;
23
+ }
24
+ function protectMessageHistory(messages, options = { pii: true, secrets: true }) {
25
+ const piiManager = new PIIManager();
26
+ let textPartsCount = 0;
27
+ let transformedTextPartsCount = 0;
28
+ const protectString = (value) => {
29
+ textPartsCount += 1;
30
+ const masked = piiManager.anonymize(value, options).maskedText;
31
+ if (masked !== value) {
32
+ transformedTextPartsCount += 1;
33
+ }
34
+ return masked;
35
+ };
36
+ const visit = (value, key) => {
37
+ if (typeof value === "string") {
38
+ return key === "content" || key === "text" ? protectString(value) : value;
39
+ }
40
+ if (Array.isArray(value)) {
41
+ let changed = false;
42
+ const next = value.map((item) => {
43
+ const protectedItem = visit(item);
44
+ if (protectedItem !== item) changed = true;
45
+ return protectedItem;
46
+ });
47
+ return changed ? next : value;
48
+ }
49
+ if (isPlainRecord(value)) {
50
+ let changed = false;
51
+ const next = {};
52
+ for (const [entryKey, entryValue] of Object.entries(value)) {
53
+ const protectedValue = visit(entryValue, entryKey);
54
+ next[entryKey] = protectedValue;
55
+ if (protectedValue !== entryValue) changed = true;
56
+ }
57
+ return changed ? next : value;
58
+ }
59
+ return value;
60
+ };
61
+ const protectedMessages = visit(messages);
62
+ return {
63
+ messages: protectedMessages,
64
+ transformed: protectedMessages !== messages,
65
+ textPartsCount,
66
+ transformedTextPartsCount
67
+ };
68
+ }
17
69
  export {
18
70
  AgentID,
19
71
  AgentIDWorkflowStep,
@@ -28,5 +80,6 @@ export {
28
80
  createAgentIdTelemetryContext,
29
81
  createAgentIdWorkflowTrail,
30
82
  getInjectionScanner,
83
+ protectMessageHistory,
31
84
  scanWithRegex
32
85
  };
@@ -1,5 +1,5 @@
1
1
  import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
2
- import { a as AgentID, i as AgentTelemetryContext } from './agentid-CxVUF_eo.mjs';
2
+ import { b as AgentID, j as AgentTelemetryContext } from './agentid-Mjh8rXn0.mjs';
3
3
 
4
4
  /**
5
5
  * LangChainJS callback handler (dependency-free shape).
@@ -1,5 +1,5 @@
1
1
  import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
2
- import { a as AgentID, i as AgentTelemetryContext } from './agentid-CxVUF_eo.js';
2
+ import { b as AgentID, j as AgentTelemetryContext } from './agentid-Mjh8rXn0.js';
3
3
 
4
4
  /**
5
5
  * LangChainJS callback handler (dependency-free shape).