agentid-sdk 0.1.16 → 0.1.18

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
@@ -82,6 +82,10 @@ var OpenAIAdapter = class {
82
82
  }
83
83
  };
84
84
 
85
+ // src/sdk-version.ts
86
+ var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
87
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.18".trim().length > 0 ? "js-0.1.18" : FALLBACK_SDK_VERSION;
88
+
85
89
  // src/pii-national-identifiers.ts
86
90
  var MAX_CANDIDATES_PER_RULE = 256;
87
91
  var MAX_PREFILTER_HITS = 512;
@@ -1204,7 +1208,6 @@ var CONFIG_TTL_MS = 5 * 60 * 1e3;
1204
1208
  var CONFIG_TIMEOUT_MS = 8e3;
1205
1209
  var CONFIG_RETRY_DELAY_MS = 1e3;
1206
1210
  var MAX_CAPABILITY_CACHE_ENTRIES = 500;
1207
- var AGENTID_SDK_VERSION_HEADER = "js-1.0.8";
1208
1211
  var CapabilityConfigFetchError = class extends Error {
1209
1212
  constructor(message, params) {
1210
1213
  super(message);
@@ -1803,7 +1806,6 @@ function getInjectionScanner() {
1803
1806
  }
1804
1807
 
1805
1808
  // src/agentid.ts
1806
- var AGENTID_SDK_VERSION_HEADER2 = "js-1.0.8";
1807
1809
  var DEFAULT_GUARD_TIMEOUT_MS = 1e4;
1808
1810
  var MIN_GUARD_TIMEOUT_MS = 500;
1809
1811
  var MAX_GUARD_TIMEOUT_MS = 15e3;
@@ -1811,7 +1813,7 @@ var GUARD_MAX_ATTEMPTS = 3;
1811
1813
  var GUARD_RETRY_DELAYS_MS = [250, 500];
1812
1814
  var INGEST_MAX_ATTEMPTS = 3;
1813
1815
  var INGEST_RETRY_DELAYS_MS = [250, 500];
1814
- var GUARD_VERDICT_CACHE_TTL_MS = 15e3;
1816
+ var GUARD_VERDICT_CACHE_TTL_MS = 0;
1815
1817
  var MAX_INGEST_TEXT_CHARS = 32e3;
1816
1818
  function normalizeBaseUrl3(baseUrl) {
1817
1819
  return baseUrl.replace(/\/+$/, "");
@@ -1995,7 +1997,6 @@ function createCompletionChunkCollector() {
1995
1997
  var AgentID = class {
1996
1998
  constructor(config) {
1997
1999
  this.injectionScanner = getInjectionScanner();
1998
- this.requestClientEventIds = /* @__PURE__ */ new WeakMap();
1999
2000
  this.recentGuardVerdicts = /* @__PURE__ */ new Map();
2000
2001
  this.apiKey = config.apiKey.trim();
2001
2002
  this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
@@ -2037,13 +2038,7 @@ var AgentID = class {
2037
2038
  return metadataClientEventId;
2038
2039
  }
2039
2040
  }
2040
- const cached = this.requestClientEventIds.get(requestBody);
2041
- if (cached) {
2042
- return cached;
2043
- }
2044
- const generated = createEventId();
2045
- this.requestClientEventIds.set(requestBody, generated);
2046
- return generated;
2041
+ return createEventId();
2047
2042
  }
2048
2043
  buildGuardCacheKey(params) {
2049
2044
  if (!params.system_id || !params.input) {
@@ -2064,7 +2059,7 @@ var AgentID = class {
2064
2059
  return cached.verdict;
2065
2060
  }
2066
2061
  cacheGuardVerdict(cacheKey, verdict) {
2067
- if (!cacheKey || !verdict.allowed) {
2062
+ if (!cacheKey || !verdict.allowed || GUARD_VERDICT_CACHE_TTL_MS <= 0) {
2068
2063
  return;
2069
2064
  }
2070
2065
  this.recentGuardVerdicts.set(cacheKey, {
@@ -2254,7 +2249,7 @@ var AgentID = class {
2254
2249
  headers: {
2255
2250
  "Content-Type": "application/json",
2256
2251
  "x-agentid-api-key": effectiveApiKey,
2257
- "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER2,
2252
+ "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER,
2258
2253
  "x-correlation-id": correlationId
2259
2254
  },
2260
2255
  body: JSON.stringify(payload),
@@ -2264,7 +2259,7 @@ var AgentID = class {
2264
2259
  const responseBody = await safeReadJson2(res);
2265
2260
  if (responseBody && typeof responseBody.allowed === "boolean") {
2266
2261
  const verdict = responseBody;
2267
- const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || res.status >= 500);
2262
+ const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || !verdict.reason && res.status >= 500);
2268
2263
  if (infrastructureFailure) {
2269
2264
  if (attempt < GUARD_MAX_ATTEMPTS - 1) {
2270
2265
  await waitForRetry(attempt);
@@ -2389,7 +2384,7 @@ var AgentID = class {
2389
2384
  headers: {
2390
2385
  "Content-Type": "application/json",
2391
2386
  "x-agentid-api-key": effectiveApiKey,
2392
- "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER2
2387
+ "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER
2393
2388
  },
2394
2389
  body: JSON.stringify(payload)
2395
2390
  });
@@ -2472,7 +2467,8 @@ var AgentID = class {
2472
2467
  }
2473
2468
  const source = completion;
2474
2469
  const collector = createCompletionChunkCollector();
2475
- const self = this;
2470
+ const extractStreamChunkText = this.extractStreamChunkText.bind(this);
2471
+ const piiManager = this.pii;
2476
2472
  let resolveDone = null;
2477
2473
  let rejectDone = null;
2478
2474
  const done = new Promise((resolve, reject) => {
@@ -2483,7 +2479,7 @@ var AgentID = class {
2483
2479
  [Symbol.asyncIterator]: async function* () {
2484
2480
  try {
2485
2481
  for await (const chunk of source) {
2486
- const chunkText = self.extractStreamChunkText(chunk);
2482
+ const chunkText = extractStreamChunkText(chunk);
2487
2483
  if (chunkText) {
2488
2484
  await collector.push(chunkText);
2489
2485
  }
@@ -2491,7 +2487,7 @@ var AgentID = class {
2491
2487
  }
2492
2488
  await collector.close();
2493
2489
  const rawOutput = await collector.result;
2494
- const masked = self.pii.anonymize(rawOutput);
2490
+ const masked = piiManager.anonymize(rawOutput);
2495
2491
  resolveDone?.({
2496
2492
  mode: "static",
2497
2493
  rawOutput,
@@ -2513,31 +2509,27 @@ var AgentID = class {
2513
2509
  }
2514
2510
  /**
2515
2511
  * LOG: Sends telemetry after execution.
2516
- * Non-blocking / Fire-and-forget.
2512
+ * Returns a Promise so callers can await persistence when needed.
2517
2513
  */
2518
- log(params, options) {
2519
- queueMicrotask(() => {
2520
- void (async () => {
2521
- const result = await this.sendIngest(params, options);
2522
- if (!result.ok) {
2523
- console.warn(
2524
- `[AgentID] Ingest telemetry failed (status=${result.status ?? "network"}, reason=${result.reason ?? "unknown"}).`
2525
- );
2526
- }
2527
- })();
2528
- });
2514
+ async log(params, options) {
2515
+ const result = await this.sendIngest(params, options);
2516
+ if (!result.ok) {
2517
+ console.warn(
2518
+ `[AgentID] Ingest telemetry failed (status=${result.status ?? "network"}, reason=${result.reason ?? "unknown"}).`
2519
+ );
2520
+ }
2529
2521
  }
2530
2522
  /**
2531
2523
  * Analytics alias for telemetry logging.
2532
2524
  */
2533
2525
  analytics(params, options) {
2534
- this.log(params, options);
2526
+ return this.log(params, options);
2535
2527
  }
2536
2528
  /**
2537
2529
  * Trace alias for telemetry logging.
2538
2530
  */
2539
2531
  trace(params, options) {
2540
- this.log(params, options);
2532
+ return this.log(params, options);
2541
2533
  }
2542
2534
  /**
2543
2535
  * Wrap an OpenAI client once; AgentID will automatically:
@@ -2771,9 +2763,68 @@ var AgentID = class {
2771
2763
  };
2772
2764
 
2773
2765
  // src/langchain.ts
2766
+ var import_base = require("@langchain/core/callbacks/base");
2774
2767
  function safeString(val) {
2775
2768
  return typeof val === "string" ? val : "";
2776
2769
  }
2770
+ function callbackDebugEnabled() {
2771
+ try {
2772
+ return typeof process !== "undefined" && process?.env?.AGENTID_DEBUG_CALLBACK === "1";
2773
+ } catch {
2774
+ return false;
2775
+ }
2776
+ }
2777
+ function logCallbackDebug(message, details) {
2778
+ if (!callbackDebugEnabled()) return;
2779
+ if (details) {
2780
+ console.log(`[AgentID][LC] ${message}`, details);
2781
+ return;
2782
+ }
2783
+ console.log(`[AgentID][LC] ${message}`);
2784
+ }
2785
+ function extractTextFromContent(content) {
2786
+ if (typeof content === "string") {
2787
+ return content;
2788
+ }
2789
+ if (Array.isArray(content)) {
2790
+ const parts = content.map((item) => {
2791
+ if (typeof item === "string") return item;
2792
+ if (!item || typeof item !== "object") return "";
2793
+ const record = item;
2794
+ if (typeof record.text === "string") return record.text;
2795
+ if (typeof record.content === "string") return record.content;
2796
+ return "";
2797
+ }).filter((part) => part.length > 0);
2798
+ return parts.join("\n");
2799
+ }
2800
+ if (content && typeof content === "object") {
2801
+ const record = content;
2802
+ if (typeof record.text === "string") return record.text;
2803
+ if (typeof record.content === "string") return record.content;
2804
+ }
2805
+ return "";
2806
+ }
2807
+ function getMessageRole(msg) {
2808
+ if (!msg || typeof msg !== "object") return null;
2809
+ const typed = msg;
2810
+ if (typeof typed.role === "string") return typed.role;
2811
+ if (typeof typed.type === "string") return typed.type;
2812
+ if (typeof typed._getType === "function") {
2813
+ try {
2814
+ const role = typed._getType();
2815
+ if (typeof role === "string") return role;
2816
+ } catch {
2817
+ }
2818
+ }
2819
+ if (typeof typed.getType === "function") {
2820
+ try {
2821
+ const role = typed.getType();
2822
+ if (typeof role === "string") return role;
2823
+ } catch {
2824
+ }
2825
+ }
2826
+ return null;
2827
+ }
2777
2828
  function extractPromptFromPrompts(prompts) {
2778
2829
  if (Array.isArray(prompts) && prompts.length > 0) {
2779
2830
  return safeString(prompts[prompts.length - 1]);
@@ -2794,7 +2845,7 @@ function extractPromptFromMessages(messages) {
2794
2845
  let last = null;
2795
2846
  for (const msg of flat) {
2796
2847
  const typed = msg;
2797
- const role = typed?.role ?? typed?.type;
2848
+ const role = getMessageRole(msg);
2798
2849
  if (role === "user" || role === "human") {
2799
2850
  last = typed;
2800
2851
  }
@@ -2803,7 +2854,7 @@ function extractPromptFromMessages(messages) {
2803
2854
  return "";
2804
2855
  }
2805
2856
  const typedLast = last;
2806
- return safeString(typedLast.content ?? typedLast.text);
2857
+ return extractTextFromContent(typedLast.content ?? typedLast.text);
2807
2858
  }
2808
2859
  function setPromptInPrompts(prompts, sanitizedInput) {
2809
2860
  if (!Array.isArray(prompts) || prompts.length === 0) {
@@ -2849,13 +2900,33 @@ function setPromptInMessages(messages, sanitizedInput) {
2849
2900
  }
2850
2901
  function extractModel(serialized, kwargs) {
2851
2902
  const kw = (kwargs && typeof kwargs === "object" ? kwargs : null) ?? null;
2852
- const model = kw?.model ?? kw?.model_name ?? kw?.modelName;
2853
- if (typeof model === "string" && model) return model;
2903
+ const directModel = kw?.model ?? kw?.model_name ?? kw?.modelName;
2904
+ if (typeof directModel === "string" && directModel) return directModel;
2905
+ const invocationModel = kw?.invocation_params?.model ?? kw?.invocation_params?.model_name ?? kw?.invocation_params?.modelName;
2906
+ if (typeof invocationModel === "string" && invocationModel) return invocationModel;
2907
+ const nestedModel = kw?.options?.model ?? kw?.options?.model_name ?? kw?.options?.modelName ?? kw?.kwargs?.model ?? kw?.kwargs?.model_name ?? kw?.kwargs?.modelName;
2908
+ if (typeof nestedModel === "string" && nestedModel) return nestedModel;
2854
2909
  const ser = (serialized && typeof serialized === "object" ? serialized : null) ?? null;
2910
+ const serKw = (ser?.kwargs && typeof ser.kwargs === "object" ? ser.kwargs : null) ?? null;
2911
+ const serModel = serKw?.model ?? serKw?.model_name ?? serKw?.modelName;
2912
+ if (typeof serModel === "string" && serModel) return serModel;
2855
2913
  const name = ser?.name ?? ser?.id;
2856
2914
  if (typeof name === "string" && name) return name;
2857
2915
  return void 0;
2858
2916
  }
2917
+ function extractModelFromOutput(output) {
2918
+ const llmOutput = output?.llmOutput ?? output?.llm_output;
2919
+ const llmModel = llmOutput?.model ?? llmOutput?.model_name ?? llmOutput?.modelName;
2920
+ if (typeof llmModel === "string" && llmModel) return llmModel;
2921
+ const first = output?.generations?.[0]?.[0];
2922
+ const responseMeta = first?.message?.response_metadata ?? first?.message?.responseMetadata;
2923
+ const responseModel = responseMeta?.model_name ?? responseMeta?.model ?? responseMeta?.modelName;
2924
+ if (typeof responseModel === "string" && responseModel) return responseModel;
2925
+ const generationInfo = first?.generation_info ?? first?.generationInfo;
2926
+ const genModel = generationInfo?.model_name ?? generationInfo?.model ?? generationInfo?.modelName;
2927
+ if (typeof genModel === "string" && genModel) return genModel;
2928
+ return void 0;
2929
+ }
2859
2930
  function extractOutputText(output) {
2860
2931
  const gens = output?.generations;
2861
2932
  const first = gens?.[0]?.[0];
@@ -2865,7 +2936,33 @@ function extractOutputText(output) {
2865
2936
  function extractTokenUsage(output) {
2866
2937
  const llmOutput = output?.llmOutput ?? output?.llm_output;
2867
2938
  const usage = llmOutput?.tokenUsage ?? llmOutput?.token_usage ?? llmOutput?.usage ?? void 0;
2868
- return usage && typeof usage === "object" ? usage : void 0;
2939
+ if (usage && typeof usage === "object") {
2940
+ return usage;
2941
+ }
2942
+ const first = output?.generations?.[0]?.[0];
2943
+ const usageMetadata = first?.message?.usage_metadata;
2944
+ if (usageMetadata && typeof usageMetadata === "object") {
2945
+ return usageMetadata;
2946
+ }
2947
+ const responseTokenUsage = first?.message?.response_metadata?.token_usage ?? first?.message?.response_metadata?.tokenUsage ?? void 0;
2948
+ if (responseTokenUsage && typeof responseTokenUsage === "object") {
2949
+ return responseTokenUsage;
2950
+ }
2951
+ const generationTokenUsage = first?.generation_info?.token_usage ?? first?.generation_info?.tokenUsage ?? void 0;
2952
+ if (generationTokenUsage && typeof generationTokenUsage === "object") {
2953
+ return generationTokenUsage;
2954
+ }
2955
+ return void 0;
2956
+ }
2957
+ function isUuidLike2(value) {
2958
+ return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value.trim());
2959
+ }
2960
+ function createClientEventId() {
2961
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
2962
+ return crypto.randomUUID();
2963
+ }
2964
+ const segment = () => Math.floor((1 + Math.random()) * 65536).toString(16).slice(1);
2965
+ return `${segment()}${segment()}-${segment()}-4${segment().slice(1)}-a${segment().slice(1)}-${segment()}${segment()}${segment()}`;
2869
2966
  }
2870
2967
  function readBooleanField2(value) {
2871
2968
  return typeof value === "boolean" ? value : null;
@@ -2885,8 +2982,10 @@ function extractStreamFlag(serialized, extraParams) {
2885
2982
  const kwargs = serializedRecord?.kwargs && typeof serializedRecord.kwargs === "object" ? serializedRecord.kwargs : null;
2886
2983
  return readBooleanField2(kwargs?.stream) ?? readBooleanField2(kwargs?.streaming) ?? false;
2887
2984
  }
2888
- var AgentIDCallbackHandler = class {
2985
+ var AgentIDCallbackHandler = class extends import_base.BaseCallbackHandler {
2889
2986
  constructor(agent, options) {
2987
+ super();
2988
+ this.name = "agentid_callback_handler";
2890
2989
  this.runs = /* @__PURE__ */ new Map();
2891
2990
  this.agent = agent;
2892
2991
  this.systemId = options.system_id;
@@ -2920,8 +3019,9 @@ var AgentIDCallbackHandler = class {
2920
3019
  async handleLLMStart(serialized, prompts, runId, _parentRunId, extraParams) {
2921
3020
  const input = extractPromptFromPrompts(prompts);
2922
3021
  const id = String(runId ?? "");
3022
+ logCallbackDebug("handleLLMStart", { runId: id, hasInput: input.length > 0 });
2923
3023
  if (!input) {
2924
- throw new Error("AgentID: No prompt found. Security guard requires string input.");
3024
+ return;
2925
3025
  }
2926
3026
  const stream = extractStreamFlag(serialized, extraParams);
2927
3027
  const sanitizedInput = await this.preflight(input, stream);
@@ -2933,34 +3033,46 @@ var AgentIDCallbackHandler = class {
2933
3033
  );
2934
3034
  }
2935
3035
  }
3036
+ const requestedClientEventId = isUuidLike2(id) ? id.trim() : createClientEventId();
3037
+ const modelName = extractModel(serialized, extraParams);
2936
3038
  const verdict = await this.agent.guard({
2937
3039
  input: sanitizedInput,
2938
3040
  system_id: this.systemId,
3041
+ model: modelName,
3042
+ client_event_id: requestedClientEventId,
2939
3043
  client_capabilities: this.getLangchainCapabilities()
2940
3044
  }, this.requestOptions);
2941
3045
  if (!verdict.allowed) {
2942
3046
  throw new Error(`AgentID: Security Blocked (${verdict.reason ?? "guard_denied"})`);
2943
3047
  }
2944
- const transformedInput = typeof verdict.transformed_input === "string" && verdict.transformed_input.length > 0 ? verdict.transformed_input : sanitizedInput;
3048
+ const canonicalClientEventId = isUuidLike2(verdict.client_event_id) ? verdict.client_event_id.trim() : requestedClientEventId;
3049
+ const guardEventId = typeof verdict.guard_event_id === "string" && verdict.guard_event_id.length > 0 ? verdict.guard_event_id : void 0;
3050
+ let transformedInput = typeof verdict.transformed_input === "string" && verdict.transformed_input.length > 0 ? verdict.transformed_input : sanitizedInput;
2945
3051
  if (transformedInput !== sanitizedInput) {
2946
3052
  const mutated = setPromptInPrompts(prompts, transformedInput);
2947
3053
  if (!mutated) {
2948
- throw new Error(
2949
- "AgentID: Guard transformed input could not be applied to LangChain prompt payload."
2950
- );
3054
+ transformedInput = sanitizedInput;
2951
3055
  }
2952
3056
  }
2953
3057
  this.runs.set(id, {
2954
3058
  input: transformedInput,
2955
3059
  startedAtMs: Date.now(),
2956
- model: extractModel(serialized, extraParams)
3060
+ model: modelName,
3061
+ clientEventId: canonicalClientEventId,
3062
+ guardEventId
3063
+ });
3064
+ logCallbackDebug("handleLLMStart state_set", {
3065
+ runId: id,
3066
+ clientEventId: canonicalClientEventId,
3067
+ guardEventId: guardEventId ?? null
2957
3068
  });
2958
3069
  }
2959
3070
  async handleChatModelStart(serialized, messages, runId, _parentRunId, extraParams) {
2960
3071
  const input = extractPromptFromMessages(messages);
2961
3072
  const id = String(runId ?? "");
3073
+ logCallbackDebug("handleChatModelStart", { runId: id, hasInput: input.length > 0 });
2962
3074
  if (!input) {
2963
- throw new Error("AgentID: No user message found. Security guard requires string input.");
3075
+ return;
2964
3076
  }
2965
3077
  const stream = extractStreamFlag(serialized, extraParams);
2966
3078
  const sanitizedInput = await this.preflight(input, stream);
@@ -2972,62 +3084,100 @@ var AgentIDCallbackHandler = class {
2972
3084
  );
2973
3085
  }
2974
3086
  }
3087
+ const requestedClientEventId = isUuidLike2(id) ? id.trim() : createClientEventId();
3088
+ const modelName = extractModel(serialized, extraParams);
2975
3089
  const verdict = await this.agent.guard({
2976
3090
  input: sanitizedInput,
2977
3091
  system_id: this.systemId,
3092
+ model: modelName,
3093
+ client_event_id: requestedClientEventId,
2978
3094
  client_capabilities: this.getLangchainCapabilities()
2979
3095
  }, this.requestOptions);
2980
3096
  if (!verdict.allowed) {
2981
3097
  throw new Error(`AgentID: Security Blocked (${verdict.reason ?? "guard_denied"})`);
2982
3098
  }
2983
- const transformedInput = typeof verdict.transformed_input === "string" && verdict.transformed_input.length > 0 ? verdict.transformed_input : sanitizedInput;
3099
+ const canonicalClientEventId = isUuidLike2(verdict.client_event_id) ? verdict.client_event_id.trim() : requestedClientEventId;
3100
+ const guardEventId = typeof verdict.guard_event_id === "string" && verdict.guard_event_id.length > 0 ? verdict.guard_event_id : void 0;
3101
+ let transformedInput = typeof verdict.transformed_input === "string" && verdict.transformed_input.length > 0 ? verdict.transformed_input : sanitizedInput;
2984
3102
  if (transformedInput !== sanitizedInput) {
2985
3103
  const mutated = setPromptInMessages(messages, transformedInput);
2986
3104
  if (!mutated) {
2987
- throw new Error(
2988
- "AgentID: Guard transformed input could not be applied to LangChain message payload."
2989
- );
3105
+ transformedInput = sanitizedInput;
2990
3106
  }
2991
3107
  }
2992
3108
  this.runs.set(id, {
2993
3109
  input: transformedInput,
2994
3110
  startedAtMs: Date.now(),
2995
- model: extractModel(serialized, extraParams)
3111
+ model: modelName,
3112
+ clientEventId: canonicalClientEventId,
3113
+ guardEventId
3114
+ });
3115
+ logCallbackDebug("handleChatModelStart state_set", {
3116
+ runId: id,
3117
+ clientEventId: canonicalClientEventId,
3118
+ guardEventId: guardEventId ?? null
2996
3119
  });
2997
3120
  }
2998
3121
  async handleLLMEnd(output, runId) {
2999
3122
  const id = String(runId ?? "");
3123
+ logCallbackDebug("handleLLMEnd", { runId: id });
3000
3124
  const state = this.runs.get(id);
3001
- if (!state) return;
3125
+ if (!state) {
3126
+ logCallbackDebug("handleLLMEnd missing_state", { runId: id });
3127
+ return;
3128
+ }
3002
3129
  this.runs.delete(id);
3003
3130
  const latency = Date.now() - state.startedAtMs;
3004
3131
  const outText = extractOutputText(output);
3005
3132
  const usage = extractTokenUsage(output);
3006
- this.agent.log({
3133
+ const metadata = {};
3134
+ if (state.clientEventId) {
3135
+ metadata.client_event_id = state.clientEventId;
3136
+ }
3137
+ if (state.guardEventId) {
3138
+ metadata.guard_event_id = state.guardEventId;
3139
+ }
3140
+ const resolvedModel = state.model ?? extractModelFromOutput(output) ?? "unknown";
3141
+ await this.agent.log({
3007
3142
  system_id: this.systemId,
3008
3143
  input: state.input,
3009
3144
  output: outText,
3010
- model: state.model ?? "unknown",
3145
+ event_id: state.clientEventId,
3146
+ model: resolvedModel,
3011
3147
  usage,
3012
3148
  latency,
3149
+ metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
3013
3150
  client_capabilities: this.getLangchainCapabilities()
3014
3151
  }, this.requestOptions);
3152
+ logCallbackDebug("handleLLMEnd logged", {
3153
+ runId: id,
3154
+ clientEventId: state.clientEventId ?? null
3155
+ });
3015
3156
  }
3016
3157
  async handleLLMError(err, runId) {
3017
3158
  const id = String(runId ?? "");
3159
+ logCallbackDebug("handleLLMError", { runId: id });
3018
3160
  const state = this.runs.get(id);
3019
3161
  if (state) this.runs.delete(id);
3020
3162
  const message = err && typeof err === "object" && "message" in err ? String(err.message) : String(err ?? "");
3021
- this.agent.log({
3163
+ const metadata = {
3164
+ error_message: message
3165
+ };
3166
+ if (state?.clientEventId) {
3167
+ metadata.client_event_id = state.clientEventId;
3168
+ }
3169
+ if (state?.guardEventId) {
3170
+ metadata.guard_event_id = state.guardEventId;
3171
+ }
3172
+ await this.agent.log({
3022
3173
  system_id: this.systemId,
3023
3174
  input: state?.input ?? "",
3024
3175
  output: "",
3176
+ event_id: state?.clientEventId,
3025
3177
  model: state?.model ?? "unknown",
3026
3178
  event_type: "error",
3027
3179
  severity: "error",
3028
- metadata: {
3029
- error_message: message
3030
- },
3180
+ metadata,
3031
3181
  client_capabilities: this.getLangchainCapabilities()
3032
3182
  }, this.requestOptions);
3033
3183
  }
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AgentIDCallbackHandler
3
- } from "./chunk-DXUA5DKG.mjs";
3
+ } from "./chunk-6YR4ECGB.mjs";
4
4
 
5
5
  // src/adapters.ts
6
6
  var OpenAIAdapter = class {
@@ -44,6 +44,10 @@ var OpenAIAdapter = class {
44
44
  }
45
45
  };
46
46
 
47
+ // src/sdk-version.ts
48
+ var FALLBACK_SDK_VERSION = "js-0.0.0-dev";
49
+ var AGENTID_SDK_VERSION_HEADER = "js-0.1.18".trim().length > 0 ? "js-0.1.18" : FALLBACK_SDK_VERSION;
50
+
47
51
  // src/pii-national-identifiers.ts
48
52
  var MAX_CANDIDATES_PER_RULE = 256;
49
53
  var MAX_PREFILTER_HITS = 512;
@@ -1166,7 +1170,6 @@ var CONFIG_TTL_MS = 5 * 60 * 1e3;
1166
1170
  var CONFIG_TIMEOUT_MS = 8e3;
1167
1171
  var CONFIG_RETRY_DELAY_MS = 1e3;
1168
1172
  var MAX_CAPABILITY_CACHE_ENTRIES = 500;
1169
- var AGENTID_SDK_VERSION_HEADER = "js-1.0.8";
1170
1173
  var CapabilityConfigFetchError = class extends Error {
1171
1174
  constructor(message, params) {
1172
1175
  super(message);
@@ -1765,7 +1768,6 @@ function getInjectionScanner() {
1765
1768
  }
1766
1769
 
1767
1770
  // src/agentid.ts
1768
- var AGENTID_SDK_VERSION_HEADER2 = "js-1.0.8";
1769
1771
  var DEFAULT_GUARD_TIMEOUT_MS = 1e4;
1770
1772
  var MIN_GUARD_TIMEOUT_MS = 500;
1771
1773
  var MAX_GUARD_TIMEOUT_MS = 15e3;
@@ -1773,7 +1775,7 @@ var GUARD_MAX_ATTEMPTS = 3;
1773
1775
  var GUARD_RETRY_DELAYS_MS = [250, 500];
1774
1776
  var INGEST_MAX_ATTEMPTS = 3;
1775
1777
  var INGEST_RETRY_DELAYS_MS = [250, 500];
1776
- var GUARD_VERDICT_CACHE_TTL_MS = 15e3;
1778
+ var GUARD_VERDICT_CACHE_TTL_MS = 0;
1777
1779
  var MAX_INGEST_TEXT_CHARS = 32e3;
1778
1780
  function normalizeBaseUrl3(baseUrl) {
1779
1781
  return baseUrl.replace(/\/+$/, "");
@@ -1957,7 +1959,6 @@ function createCompletionChunkCollector() {
1957
1959
  var AgentID = class {
1958
1960
  constructor(config) {
1959
1961
  this.injectionScanner = getInjectionScanner();
1960
- this.requestClientEventIds = /* @__PURE__ */ new WeakMap();
1961
1962
  this.recentGuardVerdicts = /* @__PURE__ */ new Map();
1962
1963
  this.apiKey = config.apiKey.trim();
1963
1964
  this.baseUrl = normalizeBaseUrl3(config.baseUrl ?? "https://app.getagentid.com/api/v1");
@@ -1999,13 +2000,7 @@ var AgentID = class {
1999
2000
  return metadataClientEventId;
2000
2001
  }
2001
2002
  }
2002
- const cached = this.requestClientEventIds.get(requestBody);
2003
- if (cached) {
2004
- return cached;
2005
- }
2006
- const generated = createEventId();
2007
- this.requestClientEventIds.set(requestBody, generated);
2008
- return generated;
2003
+ return createEventId();
2009
2004
  }
2010
2005
  buildGuardCacheKey(params) {
2011
2006
  if (!params.system_id || !params.input) {
@@ -2026,7 +2021,7 @@ var AgentID = class {
2026
2021
  return cached.verdict;
2027
2022
  }
2028
2023
  cacheGuardVerdict(cacheKey, verdict) {
2029
- if (!cacheKey || !verdict.allowed) {
2024
+ if (!cacheKey || !verdict.allowed || GUARD_VERDICT_CACHE_TTL_MS <= 0) {
2030
2025
  return;
2031
2026
  }
2032
2027
  this.recentGuardVerdicts.set(cacheKey, {
@@ -2216,7 +2211,7 @@ var AgentID = class {
2216
2211
  headers: {
2217
2212
  "Content-Type": "application/json",
2218
2213
  "x-agentid-api-key": effectiveApiKey,
2219
- "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER2,
2214
+ "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER,
2220
2215
  "x-correlation-id": correlationId
2221
2216
  },
2222
2217
  body: JSON.stringify(payload),
@@ -2226,7 +2221,7 @@ var AgentID = class {
2226
2221
  const responseBody = await safeReadJson2(res);
2227
2222
  if (responseBody && typeof responseBody.allowed === "boolean") {
2228
2223
  const verdict = responseBody;
2229
- const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || res.status >= 500);
2224
+ const infrastructureFailure = verdict.allowed === false && (isInfrastructureGuardReason(verdict.reason) || !verdict.reason && res.status >= 500);
2230
2225
  if (infrastructureFailure) {
2231
2226
  if (attempt < GUARD_MAX_ATTEMPTS - 1) {
2232
2227
  await waitForRetry(attempt);
@@ -2351,7 +2346,7 @@ var AgentID = class {
2351
2346
  headers: {
2352
2347
  "Content-Type": "application/json",
2353
2348
  "x-agentid-api-key": effectiveApiKey,
2354
- "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER2
2349
+ "X-AgentID-SDK-Version": AGENTID_SDK_VERSION_HEADER
2355
2350
  },
2356
2351
  body: JSON.stringify(payload)
2357
2352
  });
@@ -2434,7 +2429,8 @@ var AgentID = class {
2434
2429
  }
2435
2430
  const source = completion;
2436
2431
  const collector = createCompletionChunkCollector();
2437
- const self = this;
2432
+ const extractStreamChunkText = this.extractStreamChunkText.bind(this);
2433
+ const piiManager = this.pii;
2438
2434
  let resolveDone = null;
2439
2435
  let rejectDone = null;
2440
2436
  const done = new Promise((resolve, reject) => {
@@ -2445,7 +2441,7 @@ var AgentID = class {
2445
2441
  [Symbol.asyncIterator]: async function* () {
2446
2442
  try {
2447
2443
  for await (const chunk of source) {
2448
- const chunkText = self.extractStreamChunkText(chunk);
2444
+ const chunkText = extractStreamChunkText(chunk);
2449
2445
  if (chunkText) {
2450
2446
  await collector.push(chunkText);
2451
2447
  }
@@ -2453,7 +2449,7 @@ var AgentID = class {
2453
2449
  }
2454
2450
  await collector.close();
2455
2451
  const rawOutput = await collector.result;
2456
- const masked = self.pii.anonymize(rawOutput);
2452
+ const masked = piiManager.anonymize(rawOutput);
2457
2453
  resolveDone?.({
2458
2454
  mode: "static",
2459
2455
  rawOutput,
@@ -2475,31 +2471,27 @@ var AgentID = class {
2475
2471
  }
2476
2472
  /**
2477
2473
  * LOG: Sends telemetry after execution.
2478
- * Non-blocking / Fire-and-forget.
2474
+ * Returns a Promise so callers can await persistence when needed.
2479
2475
  */
2480
- log(params, options) {
2481
- queueMicrotask(() => {
2482
- void (async () => {
2483
- const result = await this.sendIngest(params, options);
2484
- if (!result.ok) {
2485
- console.warn(
2486
- `[AgentID] Ingest telemetry failed (status=${result.status ?? "network"}, reason=${result.reason ?? "unknown"}).`
2487
- );
2488
- }
2489
- })();
2490
- });
2476
+ async log(params, options) {
2477
+ const result = await this.sendIngest(params, options);
2478
+ if (!result.ok) {
2479
+ console.warn(
2480
+ `[AgentID] Ingest telemetry failed (status=${result.status ?? "network"}, reason=${result.reason ?? "unknown"}).`
2481
+ );
2482
+ }
2491
2483
  }
2492
2484
  /**
2493
2485
  * Analytics alias for telemetry logging.
2494
2486
  */
2495
2487
  analytics(params, options) {
2496
- this.log(params, options);
2488
+ return this.log(params, options);
2497
2489
  }
2498
2490
  /**
2499
2491
  * Trace alias for telemetry logging.
2500
2492
  */
2501
2493
  trace(params, options) {
2502
- this.log(params, options);
2494
+ return this.log(params, options);
2503
2495
  }
2504
2496
  /**
2505
2497
  * Wrap an OpenAI client once; AgentID will automatically: