@brizz/sdk 0.1.22 → 0.1.25

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/preload.cjs CHANGED
@@ -159,6 +159,38 @@ function setLogLevel(level) {
159
159
  var import_resources3 = require("@opentelemetry/resources");
160
160
  var import_sdk_node = require("@opentelemetry/sdk-node");
161
161
 
162
+ // src/internal/dsn.ts
163
+ var PLACEHOLDER_SERVICE = "<service-name>";
164
+ var SERVICE_NAME_HEADER = "X-Brizz-Service-Name";
165
+ function parseDSN(dsn) {
166
+ let parsed;
167
+ try {
168
+ parsed = new globalThis.URL(dsn);
169
+ } catch {
170
+ return null;
171
+ }
172
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || !parsed.username || !parsed.host) {
173
+ return null;
174
+ }
175
+ const scheme = parsed.protocol === "https:" ? "https" : "http";
176
+ let service;
177
+ try {
178
+ service = decodeURIComponent(parsed.pathname.replace(/^\//, ""));
179
+ } catch {
180
+ return null;
181
+ }
182
+ if (service === "" || service === PLACEHOLDER_SERVICE) {
183
+ return null;
184
+ }
185
+ return {
186
+ scheme,
187
+ host: parsed.host,
188
+ bearer: decodeURIComponent(parsed.username),
189
+ service,
190
+ baseUrl: `${scheme}://${parsed.host}`
191
+ };
192
+ }
193
+
162
194
  // src/internal/config.ts
163
195
  function resolveConfig(options) {
164
196
  const envLogLevel = process.env["BRIZZ_LOG_LEVEL"] || options.logLevel?.toString() || DEFAULT_LOG_LEVEL.toString();
@@ -185,6 +217,7 @@ function resolveConfig(options) {
185
217
  appName: options.appName,
186
218
  baseUrl: options.baseUrl,
187
219
  hasApiKey: !!options.apiKey,
220
+ dsnProvided: !!(process.env["BRIZZ_DSN"] || options.dsn),
188
221
  disableBatch: options.disableBatch,
189
222
  logLevel: resolvedLogLevel,
190
223
  headersCount: Object.keys(options.headers || {}).length,
@@ -212,7 +245,42 @@ function resolveConfig(options) {
212
245
  logLevel: resolvedLogLevel,
213
246
  masking: resolvedMasking
214
247
  };
215
- if (resolvedConfig.apiKey) {
248
+ const dsnInput = process.env["BRIZZ_DSN"] || options.dsn;
249
+ let parsedDSN = null;
250
+ if (dsnInput) {
251
+ const kwargConflicts = [];
252
+ if (options.apiKey !== void 0) {
253
+ kwargConflicts.push("apiKey");
254
+ }
255
+ if (options.baseUrl !== void 0) {
256
+ kwargConflicts.push("baseUrl");
257
+ }
258
+ if (options.appName !== void 0) {
259
+ kwargConflicts.push("appName");
260
+ }
261
+ if (kwargConflicts.length > 0) {
262
+ throw new Error(
263
+ `dsn cannot be combined with kwargs ${kwargConflicts.join(", ")}. The DSN bundles bearer, gateway URL, and service name \u2014 choose one configuration style.`
264
+ );
265
+ }
266
+ const envConflicts = ["BRIZZ_API_KEY", "BRIZZ_BASE_URL", "BRIZZ_APP_NAME"].filter(
267
+ (name) => process.env[name] !== void 0
268
+ );
269
+ if (envConflicts.length > 0) {
270
+ logger.warn(
271
+ `Ignoring ${envConflicts.join(", ")} \u2014 dsn / BRIZZ_DSN takes precedence.`
272
+ );
273
+ }
274
+ resolvedConfig.apiKey = void 0;
275
+ resolvedConfig.baseUrl = "https://telemetry.brizz.dev";
276
+ resolvedConfig.appName = "unknown-app";
277
+ parsedDSN = parseDSN(dsnInput);
278
+ if (parsedDSN) {
279
+ resolvedConfig.appName = parsedDSN.service;
280
+ resolvedConfig.baseUrl = parsedDSN.baseUrl;
281
+ resolvedConfig.apiKey = parsedDSN.bearer;
282
+ }
283
+ } else if (resolvedConfig.apiKey) {
216
284
  resolvedConfig.headers["Authorization"] = `Bearer ${resolvedConfig.apiKey}`;
217
285
  }
218
286
  if (process.env["BRIZZ_HEADERS"]) {
@@ -227,14 +295,28 @@ function resolveConfig(options) {
227
295
  throw new Error("Invalid JSON in BRIZZ_HEADERS environment variable", { cause: error });
228
296
  }
229
297
  }
298
+ if (dsnInput) {
299
+ const authHeaderKeys = /* @__PURE__ */ new Set(["authorization", SERVICE_NAME_HEADER.toLowerCase()]);
300
+ resolvedConfig.headers = Object.fromEntries(
301
+ Object.entries(resolvedConfig.headers).filter(
302
+ ([key]) => !authHeaderKeys.has(key.toLowerCase())
303
+ )
304
+ );
305
+ if (parsedDSN) {
306
+ resolvedConfig.headers["Authorization"] = `Bearer ${parsedDSN.bearer}`;
307
+ resolvedConfig.headers[SERVICE_NAME_HEADER] = parsedDSN.service;
308
+ }
309
+ }
230
310
  logger.debug("Configuration resolved with environment variables", {
231
311
  appName: resolvedConfig.appName,
232
312
  baseUrl: resolvedConfig.baseUrl,
233
313
  hasApiKey: !!resolvedConfig.apiKey,
314
+ dsnProvided: !!dsnInput,
234
315
  disableBatch: resolvedConfig.disableBatch,
235
316
  envOverrides: {
236
317
  hasEnvApiKey: !!process.env["BRIZZ_API_KEY"],
237
318
  hasEnvBaseUrl: !!process.env["BRIZZ_BASE_URL"],
319
+ hasEnvDsn: !!process.env["BRIZZ_DSN"],
238
320
  hasEnvBatch: !!process.env["BRIZZ_DISABLE_BATCH"],
239
321
  hasEnvHeaders: !!process.env["BRIZZ_HEADERS"]
240
322
  }
@@ -261,13 +343,13 @@ var import_instrumentation_vertexai = require("@traceloop/instrumentation-vertex
261
343
 
262
344
  // src/internal/instrumentation/mcp/instrumentation.ts
263
345
  var import_openinference_instrumentation_mcp = require("@arizeai/openinference-instrumentation-mcp");
264
- var import_api6 = require("@opentelemetry/api");
346
+ var import_api7 = require("@opentelemetry/api");
265
347
  var import_instrumentation = require("@opentelemetry/instrumentation");
266
348
 
267
349
  // src/internal/instrumentation/mcp/patches/protocol.ts
268
- var import_api5 = require("@opentelemetry/api");
350
+ var import_api6 = require("@opentelemetry/api");
269
351
 
270
- // src/internal/instrumentation/mcp/session.ts
352
+ // src/internal/instrumentation/mcp/schemas.ts
271
353
  var import_api3 = require("@opentelemetry/api");
272
354
 
273
355
  // src/internal/semantic-conventions.ts
@@ -278,42 +360,17 @@ var SESSION_ID = "session.id";
278
360
  var PROPERTIES_CONTEXT_KEY = (0, import_api2.createContextKey)(PROPERTIES);
279
361
  var SESSION_OBJECT_CONTEXT_KEY = (0, import_api2.createContextKey)("brizz.session.object");
280
362
 
281
- // src/internal/instrumentation/mcp/session.ts
282
- function stampAndPropagateSession(span, sessionId, baseContext = import_api3.context.active()) {
283
- if (!sessionId) {
284
- return { context: baseContext, sessionId: null };
285
- }
286
- if (span.isRecording()) {
287
- try {
288
- span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
289
- } catch (error) {
290
- logger.warn(
291
- `Brizz MCP: failed to stamp session id on span: ${String(error)}`
292
- );
293
- }
294
- }
295
- try {
296
- const prev = baseContext.getValue(PROPERTIES_CONTEXT_KEY);
297
- const merged = prev ? { ...prev, [SESSION_ID]: sessionId } : { [SESSION_ID]: sessionId };
298
- return {
299
- context: baseContext.setValue(PROPERTIES_CONTEXT_KEY, merged),
300
- sessionId
301
- };
302
- } catch (error) {
303
- logger.warn(`Brizz MCP: failed to attach session context: ${String(error)}`);
304
- return { context: baseContext, sessionId };
305
- }
306
- }
307
-
308
- // src/internal/instrumentation/mcp/patches/attributes.ts
309
- var import_api4 = require("@opentelemetry/api");
310
-
311
363
  // src/internal/instrumentation/mcp/semantic-conventions.ts
312
364
  var MCP_TOOL_NAME = "mcp.tool.name";
313
365
  var MCP_TOOL_ARGUMENTS = "mcp.tool.arguments";
314
366
  var MCP_TOOL_RESULT = "mcp.tool.result";
315
367
  var MCP_COMPONENT_TYPE = "mcp.component.type";
316
368
  var MCP_COMPONENT_TOOL = "tool";
369
+ var MCP_COMPONENT_TOOL_SCHEMA = "tool_schema";
370
+ var MCP_TOOL_SCHEMA_PARAMETERS = "mcp.tool.schema.parameters";
371
+ var MCP_TOOL_SCHEMA_OUTPUT = "mcp.tool.schema.output";
372
+ var MCP_TOOL_DESCRIPTION = "mcp.tool.description";
373
+ var SPAN_NAME_TOOL_REGISTER = "mcp.tool.register";
317
374
  var MCP_METHOD_NAME = "mcp.method.name";
318
375
  var MCP_REQUEST_ID = "mcp.request.id";
319
376
  var MCP_SESSION_ID = "mcp.session.id";
@@ -334,11 +391,115 @@ var SPAN_NAME_TOOLS_CALL = "tools/call";
334
391
  var MAX_ATTRIBUTE_LENGTH = 32 * 1024;
335
392
  var TRUNCATION_SUFFIX = "\u2026(truncated)";
336
393
  var METHOD_TOOLS_CALL = "tools/call";
394
+ var METHOD_TOOLS_LIST = "tools/list";
337
395
  var METHOD_RESOURCES_READ = "resources/read";
338
396
  var METHOD_PROMPTS_GET = "prompts/get";
339
397
  var METHOD_INITIALIZE = "initialize";
340
398
 
399
+ // src/internal/instrumentation/mcp/schemas.ts
400
+ var _MAX_SCHEMA_ATTR_BYTES = 4e3;
401
+ function truncateSchemaAttr(value) {
402
+ if (value.length <= _MAX_SCHEMA_ATTR_BYTES) {
403
+ return value;
404
+ }
405
+ return `{"_truncated":true,"original_length":${value.length}}`;
406
+ }
407
+ function safeStringify(value) {
408
+ if (value === null || value === void 0) {
409
+ return "";
410
+ }
411
+ try {
412
+ return JSON.stringify(value);
413
+ } catch {
414
+ return "";
415
+ }
416
+ }
417
+ function emitSchemaSpansFromListResponse(result, transportSessionId, tracer) {
418
+ if (!transportSessionId) {
419
+ return;
420
+ }
421
+ const tools = extractTools(result);
422
+ if (tools === void 0) {
423
+ return;
424
+ }
425
+ for (const tool of tools) {
426
+ const name = typeof tool.name === "string" ? tool.name : void 0;
427
+ if (!name) {
428
+ continue;
429
+ }
430
+ const span = tracer.startSpan(`${SPAN_NAME_TOOL_REGISTER} ${name}`, {
431
+ kind: import_api3.SpanKind.INTERNAL
432
+ });
433
+ try {
434
+ stampSchemaAttributes(span, name, transportSessionId, tool);
435
+ span.setStatus({ code: import_api3.SpanStatusCode.OK });
436
+ } finally {
437
+ span.end();
438
+ }
439
+ }
440
+ }
441
+ function stampSchemaAttributes(span, toolName, transportSessionId, tool) {
442
+ if (!span.isRecording()) {
443
+ logger.warn(
444
+ `Brizz MCP: schema span is not recording; dropping attributes for ${toolName}`
445
+ );
446
+ return;
447
+ }
448
+ const description = typeof tool.description === "string" ? tool.description : "";
449
+ const parameters = truncateSchemaAttr(safeStringify(tool.inputSchema));
450
+ const outputSchema = tool.outputSchema !== void 0 && tool.outputSchema !== null ? truncateSchemaAttr(safeStringify(tool.outputSchema)) : "";
451
+ span.setAttribute(RPC_SYSTEM, RPC_SYSTEM_MCP);
452
+ span.setAttribute(MCP_COMPONENT_TYPE, MCP_COMPONENT_TOOL_SCHEMA);
453
+ span.setAttribute(MCP_SESSION_ID, transportSessionId);
454
+ span.setAttribute(`${BRIZZ}.${SESSION_ID}`, transportSessionId);
455
+ span.setAttribute(MCP_TOOL_NAME, toolName);
456
+ span.setAttribute(MCP_TOOL_SCHEMA_PARAMETERS, parameters);
457
+ span.setAttribute(MCP_TOOL_SCHEMA_OUTPUT, outputSchema);
458
+ span.setAttribute(MCP_TOOL_DESCRIPTION, description);
459
+ }
460
+ function extractTools(result) {
461
+ if (!result || typeof result !== "object") {
462
+ return void 0;
463
+ }
464
+ const tools = result.tools;
465
+ if (!Array.isArray(tools)) {
466
+ return void 0;
467
+ }
468
+ return tools.filter(
469
+ (t) => t !== null && typeof t === "object"
470
+ );
471
+ }
472
+
473
+ // src/internal/instrumentation/mcp/session.ts
474
+ var import_api4 = require("@opentelemetry/api");
475
+ function stampAndPropagateSession(span, sessionId, baseContext = import_api4.context.active()) {
476
+ if (!sessionId) {
477
+ return { context: baseContext, sessionId: null };
478
+ }
479
+ if (span.isRecording()) {
480
+ try {
481
+ span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
482
+ } catch (error) {
483
+ logger.warn(
484
+ `Brizz MCP: failed to stamp session id on span: ${String(error)}`
485
+ );
486
+ }
487
+ }
488
+ try {
489
+ const prev = baseContext.getValue(PROPERTIES_CONTEXT_KEY);
490
+ const merged = prev ? { ...prev, [SESSION_ID]: sessionId } : { [SESSION_ID]: sessionId };
491
+ return {
492
+ context: baseContext.setValue(PROPERTIES_CONTEXT_KEY, merged),
493
+ sessionId
494
+ };
495
+ } catch (error) {
496
+ logger.warn(`Brizz MCP: failed to attach session context: ${String(error)}`);
497
+ return { context: baseContext, sessionId };
498
+ }
499
+ }
500
+
341
501
  // src/internal/instrumentation/mcp/patches/attributes.ts
502
+ var import_api5 = require("@opentelemetry/api");
342
503
  function deriveSpanName(method, params) {
343
504
  try {
344
505
  if (method === METHOD_TOOLS_CALL) {
@@ -441,7 +602,7 @@ function applyResultAttributes(span, method, result) {
441
602
  if (obj && obj["isError"] === true) {
442
603
  span.setAttribute(ERROR_TYPE, ERROR_TYPE_TOOL);
443
604
  const message = extractToolErrorMessage(obj);
444
- span.setStatus({ code: import_api4.SpanStatusCode.ERROR, message });
605
+ span.setStatus({ code: import_api5.SpanStatusCode.ERROR, message });
445
606
  }
446
607
  }
447
608
  function applyErrorAttributes(span, err) {
@@ -465,7 +626,7 @@ function applyErrorAttributes(span, err) {
465
626
  } catch {
466
627
  }
467
628
  span.setStatus({
468
- code: import_api4.SpanStatusCode.ERROR,
629
+ code: import_api5.SpanStatusCode.ERROR,
469
630
  message: typeof error?.message === "string" ? error.message : void 0
470
631
  });
471
632
  }
@@ -572,8 +733,8 @@ function wrapRequest(original, tracer) {
572
733
  return original.apply(this, args);
573
734
  }
574
735
  return executeAroundSpan(span, request.method, () => {
575
- const ctx = import_api5.trace.setSpan(import_api5.context.active(), span);
576
- return import_api5.context.with(ctx, () => original.apply(this, args));
736
+ const ctx = import_api6.trace.setSpan(import_api6.context.active(), span);
737
+ return import_api6.context.with(ctx, () => original.apply(this, args));
577
738
  });
578
739
  };
579
740
  }
@@ -597,7 +758,20 @@ function wrapOnRequest(original, tracer) {
597
758
  return original.apply(this, args);
598
759
  }
599
760
  const { span, spanCtx } = started;
600
- const wrappedHandler = (req, extra) => import_api5.context.with(spanCtx, () => executeHandler(span, method, handler, req, extra));
761
+ const transportSessionId = this.sessionId ?? this._transport?.sessionId;
762
+ const postResult = method === METHOD_TOOLS_LIST ? (result) => {
763
+ try {
764
+ emitSchemaSpansFromListResponse(result, transportSessionId, tracer);
765
+ } catch (error) {
766
+ logger.warn(
767
+ `Brizz MCP: failed to emit tools/list schema spans: ${String(error)}`
768
+ );
769
+ }
770
+ } : void 0;
771
+ const wrappedHandler = (req, extra) => import_api6.context.with(
772
+ spanCtx,
773
+ () => executeHandler(span, method, handler, req, extra, postResult)
774
+ );
601
775
  const hadEntry = handlers.has(method);
602
776
  const prev = handlers.get(method);
603
777
  handlers.set(method, wrappedHandler);
@@ -620,7 +794,7 @@ function wrapOnRequest(original, tracer) {
620
794
  }
621
795
  };
622
796
  }
623
- function executeAroundSpan(span, method, run) {
797
+ function executeAroundSpan(span, method, run, postResult) {
624
798
  let result;
625
799
  try {
626
800
  result = run();
@@ -631,12 +805,18 @@ function executeAroundSpan(span, method, run) {
631
805
  }
632
806
  if (!isThenable(result)) {
633
807
  safeApplyResultAttributes(span, method, result);
808
+ if (postResult) {
809
+ postResult(result);
810
+ }
634
811
  safeEnd(span);
635
812
  return result;
636
813
  }
637
814
  return result.then(
638
815
  (value) => {
639
816
  safeApplyResultAttributes(span, method, value);
817
+ if (postResult) {
818
+ postResult(value);
819
+ }
640
820
  safeEnd(span);
641
821
  return value;
642
822
  },
@@ -647,13 +827,13 @@ function executeAroundSpan(span, method, run) {
647
827
  }
648
828
  );
649
829
  }
650
- function executeHandler(span, method, handler, req, extra) {
651
- return executeAroundSpan(span, method, () => handler(req, extra));
830
+ function executeHandler(span, method, handler, req, extra, postResult) {
831
+ return executeAroundSpan(span, method, () => handler(req, extra), postResult);
652
832
  }
653
833
  function safeStartClientSpan(tracer, request, protocol) {
654
834
  try {
655
835
  const spanName = deriveSpanName(request.method, request.params);
656
- const span = tracer.startSpan(spanName, { kind: import_api5.SpanKind.CLIENT });
836
+ const span = tracer.startSpan(spanName, { kind: import_api6.SpanKind.CLIENT });
657
837
  applyClientRequestAttributes(
658
838
  span,
659
839
  request,
@@ -671,13 +851,13 @@ function safeStartServerSpan(tracer, request, protocol) {
671
851
  const spanName = deriveSpanName(request.method, request.params);
672
852
  const span = tracer.startSpan(
673
853
  spanName,
674
- { kind: import_api5.SpanKind.SERVER },
854
+ { kind: import_api6.SpanKind.SERVER },
675
855
  parentCtx
676
856
  );
677
857
  applyServerRequestAttributes(span, request, protocol);
678
858
  const sessionId = protocol.sessionId ?? protocol._transport?.sessionId;
679
859
  const { context: sessCtx } = stampAndPropagateSession(span, sessionId, parentCtx);
680
- return { span, spanCtx: import_api5.trace.setSpan(sessCtx, span) };
860
+ return { span, spanCtx: import_api6.trace.setSpan(sessCtx, span) };
681
861
  } catch (error) {
682
862
  logger.debug(`Brizz MCP: failed to open SERVER span: ${String(error)}`);
683
863
  return null;
@@ -687,14 +867,14 @@ function extractParentContext(request) {
687
867
  try {
688
868
  const meta = request.params?._meta;
689
869
  if (meta && typeof meta === "object") {
690
- return import_api5.propagation.extract(import_api5.context.active(), meta);
870
+ return import_api6.propagation.extract(import_api6.context.active(), meta);
691
871
  }
692
872
  } catch (error) {
693
873
  logger.debug(
694
874
  `Brizz MCP: failed to extract parent context from _meta: ${String(error)}`
695
875
  );
696
876
  }
697
- return import_api5.context.active();
877
+ return import_api6.context.active();
698
878
  }
699
879
  function isThenable(value) {
700
880
  return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
@@ -727,7 +907,7 @@ function safeEnd(span) {
727
907
 
728
908
  // src/internal/version.ts
729
909
  function getSDKVersion() {
730
- return "0.1.22";
910
+ return "0.1.25";
731
911
  }
732
912
 
733
913
  // src/internal/instrumentation/mcp/version.ts
@@ -751,7 +931,7 @@ var MCPInstrumentation = class extends import_openinference_instrumentation_mcp.
751
931
  brizzTracer;
752
932
  constructor(_config) {
753
933
  super({ instrumentationConfig: _config?.instrumentationConfig });
754
- this.brizzTracer = import_api6.trace.getTracer(INSTRUMENTATION_NAME, INSTRUMENTATION_VERSION);
934
+ this.brizzTracer = import_api7.trace.getTracer(INSTRUMENTATION_NAME, INSTRUMENTATION_VERSION);
755
935
  }
756
936
  /**
757
937
  * Extend `super.init()` with our protocol-layer module definition.
@@ -992,26 +1172,16 @@ var import_resources = require("@opentelemetry/resources");
992
1172
  var import_sdk_logs2 = require("@opentelemetry/sdk-logs");
993
1173
 
994
1174
  // src/internal/log/processors/log-processor.ts
995
- var import_api7 = require("@opentelemetry/api");
1175
+ var import_api8 = require("@opentelemetry/api");
996
1176
  var import_sdk_logs = require("@opentelemetry/sdk-logs");
997
1177
 
998
1178
  // src/internal/masking/patterns.ts
999
1179
  var DEFAULT_PII_PATTERNS = [
1000
- // Email addresses
1001
- {
1002
- name: "email_addresses",
1003
- pattern: String.raw`\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`
1004
- },
1005
1180
  // Phone numbers (US format)
1006
1181
  {
1007
1182
  name: "us_phone_numbers",
1008
1183
  pattern: String.raw`(?:^|[\s])(?:\+?1[-.\s]*)?(?:\([0-9]{3}\)\s?[0-9]{3}[-.\s]?[0-9]{4}|[0-9]{3}[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}|[0-9]{10})(?=[\s]|$)`
1009
1184
  },
1010
- // Social Security Numbers
1011
- {
1012
- name: "ssn",
1013
- pattern: String.raw`\b(?!000|666|9\d{2})\d{3}[-\s]?(?!00)\d{2}[-\s]?(?!0000)\d{4}\b`
1014
- },
1015
1185
  // Credit card numbers
1016
1186
  {
1017
1187
  name: "credit_cards",
@@ -1035,19 +1205,11 @@ var DEFAULT_PII_PATTERNS = [
1035
1205
  name: "openai_keys",
1036
1206
  pattern: String.raw`\bsk[-_][a-zA-Z0-9]{20,}\b`
1037
1207
  },
1038
- {
1039
- name: "base64_secrets",
1040
- pattern: String.raw`\b[A-Za-z0-9+/]{64,}={0,2}\b`
1041
- },
1042
1208
  // AWS Keys
1043
1209
  {
1044
1210
  name: "aws_access_keys",
1045
1211
  pattern: String.raw`\b(?:AKIA|ABIA|ACCA|ASIA)[0-9A-Z]{16}\b`
1046
1212
  },
1047
- {
1048
- name: "aws_secret_keys",
1049
- pattern: String.raw`\b[A-Za-z0-9/+=]*[A-Z][A-Za-z0-9/+=]*[a-z][A-Za-z0-9/+=]*[/+=][A-Za-z0-9/+=]{30,}\b`
1050
- },
1051
1213
  // GitHub tokens
1052
1214
  {
1053
1215
  name: "github_tokens",
@@ -1078,11 +1240,6 @@ var DEFAULT_PII_PATTERNS = [
1078
1240
  name: "ipv6_addresses",
1079
1241
  pattern: String.raw`\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b`
1080
1242
  },
1081
- // Medical records
1082
- {
1083
- name: "medical_record_numbers",
1084
- pattern: String.raw`\b(?:[Mm][Rr][Nn])[-\s]?\d{6,10}\b`
1085
- },
1086
1243
  // Bitcoin addresses
1087
1244
  {
1088
1245
  name: "bitcoin_addresses",
@@ -1093,11 +1250,6 @@ var DEFAULT_PII_PATTERNS = [
1093
1250
  name: "ethereum_addresses",
1094
1251
  pattern: String.raw`\b0x[a-fA-F0-9]{40}(?![a-fA-F0-9])\b`
1095
1252
  },
1096
- // UUIDs
1097
- {
1098
- name: "uuids",
1099
- pattern: String.raw`\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}(?![0-9a-fA-F-])\b`
1100
- },
1101
1253
  // Database connection strings
1102
1254
  {
1103
1255
  name: "database_connections",
@@ -1116,90 +1268,6 @@ var DEFAULT_PII_PATTERNS = [
1116
1268
  name: "certificates",
1117
1269
  pattern: "-----BEGIN CERTIFICATE-----"
1118
1270
  },
1119
- // Date of birth patterns
1120
- {
1121
- name: "date_of_birth_us",
1122
- pattern: String.raw`\b(?:0[1-9]|1[0-2])[-/](?:0[1-9]|[12]\\d|3[01])[-/](?:19|20)\\d{2}\b`
1123
- },
1124
- {
1125
- name: "date_of_birth_iso",
1126
- pattern: String.raw`\b(?:19|20)\\d{2}[-/](?:0[1-9]|1[0-2])[-/](?:0[1-9]|[12]\\d|3[01])\b`
1127
- },
1128
- // US Identification Numbers
1129
- {
1130
- name: "us_passport_numbers",
1131
- pattern: String.raw`\b[A-Z]?\\d{6,9}\b`
1132
- },
1133
- {
1134
- name: "drivers_license",
1135
- pattern: String.raw`\b[A-Z]{1,2}\\d{3,8}[-\s]?\\d{2,5}[-\s]?\\d{2,5}[-\s]?\\d{1,5}[-\s]?\\d?\b`
1136
- },
1137
- {
1138
- name: "bank_account_numbers",
1139
- pattern: String.raw`\b\\d{10,17}\b`
1140
- },
1141
- {
1142
- name: "aba_routing_numbers",
1143
- pattern: String.raw`\b((0[0-9])|(1[0-2])|(2[1-9])|(3[0-2])|(6[1-9])|(7[0-2])|80)([0-9]{7})\b`
1144
- },
1145
- {
1146
- name: "health_insurance_numbers",
1147
- pattern: String.raw`\b\\d{10}[A-Z]\b`
1148
- },
1149
- {
1150
- name: "employee_ids",
1151
- pattern: String.raw`\b(?:[Ee][Mm][Pp]|[Ee][Mm][Pp][Ll][Oo][Yy][Ee][Ee]|[Ee])[-\s]?\\d{5,8}\b`
1152
- },
1153
- {
1154
- name: "tax_ein",
1155
- pattern: String.raw`\b\\d{2}-\\d{7}\b`
1156
- },
1157
- {
1158
- name: "medicare_beneficiary_id",
1159
- pattern: String.raw`\b[1-9][A-Z][A-Z0-9]\\d-[A-Z][A-Z0-9]\\d-[A-Z][A-Z0-9]\\d{2}\b`
1160
- },
1161
- {
1162
- name: "national_provider_id",
1163
- pattern: String.raw`\b1\\d{9}\b`
1164
- },
1165
- {
1166
- name: "dea_numbers",
1167
- pattern: String.raw`\b[A-Z]{2}\\d{7}\b`
1168
- },
1169
- {
1170
- name: "itin",
1171
- pattern: String.raw`\b9\\d{2}(?:[ \\-]?)[7,8]\\d(?:[ \\-]?)\\d{4}\b`
1172
- },
1173
- // Vehicle and Location
1174
- {
1175
- name: "vin_numbers",
1176
- pattern: String.raw`\b[A-HJ-NPR-Z0-9]{17}\b`
1177
- },
1178
- {
1179
- name: "coordinates",
1180
- pattern: String.raw`\b[-+]?(?:[0-8]?\\d(?:\\.\\d+)?|90(?:\\.0+)?),\\s*[-+]?(?:1[0-7]\\d(?:\\.\\d+)?|180(?:\\.0+)?|[0-9]?\\d(?:\\.\\d+)?)\b`
1181
- },
1182
- {
1183
- name: "us_license_plates",
1184
- pattern: String.raw`\b[A-Z]{1,3}[-\s]\\d{1,4}[A-Z]?\b|\b\\d{1,2}[A-Z]{1,3}\\d{1,4}\b`
1185
- },
1186
- {
1187
- name: "us_zip_codes",
1188
- pattern: String.raw`\b(\\d{5}-\\d{4}|\\d{5})\b`
1189
- },
1190
- {
1191
- name: "us_street_addresses",
1192
- pattern: String.raw`\b\\d{1,8}\b[\\s\\S]{10,100}?\b(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NC|ND|NE|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VT|WA|WI|WV|WY)\b\\s\\d{5}\b`
1193
- },
1194
- // International Banking
1195
- {
1196
- name: "iban",
1197
- pattern: String.raw`\b[A-Z]{2}\d{2}[A-Z0-9]{4}\d{7}([A-Z0-9]?){0,16}\b`
1198
- },
1199
- {
1200
- name: "swift_bic",
1201
- pattern: String.raw`\b[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?\b`
1202
- },
1203
1271
  // Additional API Keys and Tokens
1204
1272
  {
1205
1273
  name: "google_oauth",
@@ -1262,73 +1330,6 @@ var DEFAULT_PII_PATTERNS = [
1262
1330
  name: "putty_ssh_keys",
1263
1331
  pattern: String.raw`PuTTY-User-Key-File-2: ssh-(?:rsa|dss)\s*Encryption: none(?:.|\s?)*?Private-MAC:`
1264
1332
  },
1265
- // International Phone Numbers
1266
- {
1267
- name: "france_phone_numbers",
1268
- pattern: String.raw`\b([0O]?[1lI][1lI])?[3E][3E][0O]?[\\dOIlZEASB]{9}\b`
1269
- },
1270
- {
1271
- name: "german_phone_numbers",
1272
- pattern: String.raw`\b[\d\w]\d{2}[\d\w]{6}\d[\d\w]\b`
1273
- },
1274
- {
1275
- name: "uk_phone_numbers",
1276
- pattern: String.raw`\b([0O]?[1lI][1lI])?[4A][4A][\\dOIlZEASB]{10,11}\b`
1277
- },
1278
- // International IDs
1279
- {
1280
- name: "uk_drivers_license",
1281
- pattern: String.raw`\b[A-Z]{5}\d{6}[A-Z]{2}\d{1}[A-Z]{2}\b`
1282
- },
1283
- {
1284
- name: "uk_passport",
1285
- pattern: String.raw`\b\\d{10}GB[RP]\\d{7}[UMF]{1}\\d{9}\b`
1286
- },
1287
- {
1288
- name: "argentina_dni",
1289
- pattern: String.raw`\b\\d{2}\\.\\d{3}\\.\\d{3}\b`
1290
- },
1291
- {
1292
- name: "australia_tfn",
1293
- pattern: String.raw`\b[Tt][Ff][Nn](:|:\\s|\\s|)(\\d{8,9})\b`
1294
- },
1295
- {
1296
- name: "canada_passport",
1297
- pattern: String.raw`\b[\\w]{2}[\\d]{6}\b`
1298
- },
1299
- {
1300
- name: "croatia_vat",
1301
- pattern: String.raw`\bHR\\d{11}\b`
1302
- },
1303
- {
1304
- name: "czech_vat",
1305
- pattern: String.raw`\bCZ\\d{8,10}\b`
1306
- },
1307
- {
1308
- name: "denmark_personal_id",
1309
- pattern: String.raw`\b(?:\\d{10}|\\d{6}[-\\s]\\d{4})\b`
1310
- },
1311
- {
1312
- name: "france_national_id",
1313
- pattern: String.raw`\b\\d{12}\b`
1314
- },
1315
- {
1316
- name: "france_ssn",
1317
- pattern: String.raw`\b(?:\\d{13}|\\d{13}\\s\\d{2})\b`
1318
- },
1319
- {
1320
- name: "france_passport",
1321
- pattern: String.raw`\b\\d{2}11\\d{5}\b`
1322
- },
1323
- {
1324
- name: "california_drivers_license",
1325
- pattern: String.raw`\b[A-Z]{1}\\d{7}\b`
1326
- },
1327
- // Medical and Healthcare
1328
- {
1329
- name: "hipaa_ndc",
1330
- pattern: String.raw`\b\\d{4,5}-\\d{3,4}-\\d{1,2}\b`
1331
- },
1332
1333
  // Security and Network
1333
1334
  {
1334
1335
  name: "cve_numbers",
@@ -1362,44 +1363,6 @@ var DEFAULT_PII_PATTERNS = [
1362
1363
  {
1363
1364
  name: "discover_cards",
1364
1365
  pattern: String.raw`\b65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}\b`
1365
- },
1366
- {
1367
- name: "enhanced_credit_cards",
1368
- pattern: String.raw`\b((4\\d{3}|5[1-5]\\d{2}|2\\d{3}|3[47]\\d{1,2})[\\s\\-]?\\d{4,6}[\\s\\-]?\\d{4,6}?([\\s\\-]\\d{3,4})?(\\d{3})?)\b`
1369
- },
1370
- // Bank Routing Numbers (US specific)
1371
- {
1372
- name: "bbva_routing_ca",
1373
- pattern: String.raw`\\b321170538\\b`
1374
- },
1375
- {
1376
- name: "boa_routing_ca",
1377
- pattern: String.raw`\\b(?:121|026)00(?:0|9)(?:358|593)\\b`
1378
- },
1379
- {
1380
- name: "chase_routing_ca",
1381
- pattern: String.raw`\\b322271627\\b`
1382
- },
1383
- {
1384
- name: "citibank_routing_ca",
1385
- pattern: String.raw`\\b32(?:11|22)71(?:18|72)4\\b`
1386
- },
1387
- {
1388
- name: "usbank_routing_ca",
1389
- pattern: String.raw`\\b12(?:1122676|2235821)\\b`
1390
- },
1391
- {
1392
- name: "united_bank_routing_ca",
1393
- pattern: String.raw`\\b122243350\\b`
1394
- },
1395
- {
1396
- name: "wells_fargo_routing_ca",
1397
- pattern: String.raw`\\b121042882\\b`
1398
- },
1399
- // Unrealistic alphanumeric identifiers
1400
- {
1401
- name: "generic_non_usual",
1402
- pattern: String.raw`(?:^|\s)(?=[A-Za-z0-9_\)\*\=@]*[A-Za-z])(?=[A-Za-z0-9_\)\*\=@]*[0-9])([A-Za-z0-9_\)\*\=@]{5,})(?=\s|$)`
1403
1366
  }
1404
1367
  ];
1405
1368
 
@@ -1638,7 +1601,7 @@ var BrizzSimpleLogRecordProcessor = class extends import_sdk_logs.SimpleLogRecor
1638
1601
  if (maskingConfig) {
1639
1602
  maskLog(logRecord, maskingConfig);
1640
1603
  }
1641
- const associationProperties = import_api7.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1604
+ const associationProperties = import_api8.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1642
1605
  if (associationProperties) {
1643
1606
  for (const [key, value] of Object.entries(associationProperties)) {
1644
1607
  logRecord.setAttribute(`${BRIZZ}.${key}`, value);
@@ -1658,7 +1621,7 @@ var BrizzBatchLogRecordProcessor = class extends import_sdk_logs.BatchLogRecordP
1658
1621
  if (maskingConfig) {
1659
1622
  maskLog(logRecord, maskingConfig);
1660
1623
  }
1661
- const associationProperties = import_api7.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1624
+ const associationProperties = import_api8.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1662
1625
  if (associationProperties) {
1663
1626
  for (const [key, value] of Object.entries(associationProperties)) {
1664
1627
  logRecord.setAttribute(`${BRIZZ}.${key}`, value);
@@ -2045,10 +2008,10 @@ var BrizzSpanExporter = class {
2045
2008
  };
2046
2009
 
2047
2010
  // src/internal/trace/processors/span-processor.ts
2048
- var import_api8 = require("@opentelemetry/api");
2011
+ var import_api9 = require("@opentelemetry/api");
2049
2012
  var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
2050
2013
  function applyContextAttributes(span) {
2051
- const sessionProperties = import_api8.context.active().getValue(PROPERTIES_CONTEXT_KEY);
2014
+ const sessionProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
2052
2015
  if (sessionProperties) {
2053
2016
  for (const [key, value] of Object.entries(sessionProperties)) {
2054
2017
  span.setAttribute(`${BRIZZ}.${key}`, value);
@@ -2058,12 +2021,6 @@ function applyContextAttributes(span) {
2058
2021
  var DEFAULT_MASKING_RULES = [
2059
2022
  {
2060
2023
  mode: "partial",
2061
- attributePattern: "gen_ai.prompt",
2062
- patterns: DEFAULT_PII_PATTERNS
2063
- },
2064
- {
2065
- mode: "partial",
2066
- attributePattern: "gen_ai.completion",
2067
2024
  patterns: DEFAULT_PII_PATTERNS
2068
2025
  }
2069
2026
  ];
@@ -2073,24 +2030,16 @@ var BrizzSimpleSpanProcessor = class extends import_sdk_trace_base.SimpleSpanPro
2073
2030
  super(spanExporter);
2074
2031
  this.config = config;
2075
2032
  }
2076
- // Will work with the following code:
2077
- // const span = tracer.startSpan('sensitive-operation',{attributes:{
2078
- // 'user.password': 'secret123',
2079
- // 'user.email': 'user@example.com',
2080
- // }});
2081
- //
2082
- // Won't work because onStart is called before attributes are set:
2083
- // span.setAttributes({
2084
- // 'user.password': 'secret123',
2085
- // 'user.email': 'user@example.com'
2086
- // });
2087
2033
  onStart(span, parentContext) {
2034
+ applyContextAttributes(span);
2035
+ super.onStart(span, parentContext);
2036
+ }
2037
+ onEnd(span) {
2088
2038
  const maskingConfig = this.config.masking?.spanMasking;
2089
2039
  if (maskingConfig) {
2090
- maskSpan(span, maskingConfig);
2040
+ maskReadableSpan(span, maskingConfig);
2091
2041
  }
2092
- applyContextAttributes(span);
2093
- super.onStart(span, parentContext);
2042
+ super.onEnd(span);
2094
2043
  }
2095
2044
  };
2096
2045
  var BrizzBatchSpanProcessor = class extends import_sdk_trace_base.BatchSpanProcessor {
@@ -2100,39 +2049,39 @@ var BrizzBatchSpanProcessor = class extends import_sdk_trace_base.BatchSpanProce
2100
2049
  this.config = config;
2101
2050
  }
2102
2051
  onStart(span, parentContext) {
2052
+ applyContextAttributes(span);
2053
+ super.onStart(span, parentContext);
2054
+ }
2055
+ onEnd(span) {
2103
2056
  const maskingConfig = this.config.masking?.spanMasking;
2104
2057
  if (maskingConfig) {
2105
- maskSpan(span, maskingConfig);
2058
+ maskReadableSpan(span, maskingConfig);
2106
2059
  }
2107
- applyContextAttributes(span);
2108
- super.onStart(span, parentContext);
2060
+ super.onEnd(span);
2109
2061
  }
2110
2062
  };
2111
- function maskSpan(span, config) {
2112
- if (!span.attributes || Object.keys(span.attributes).length === 0) {
2113
- return span;
2063
+ function maskReadableSpan(span, config) {
2064
+ const attrs = span.attributes;
2065
+ if (!attrs || Object.keys(attrs).length === 0) {
2066
+ return;
2114
2067
  }
2115
- let rules = config.rules || [];
2068
+ let rules = config.rules ? [...config.rules] : [];
2116
2069
  if (!config.disableDefaultRules) {
2117
- rules = [...DEFAULT_MASKING_RULES, ...rules];
2070
+ rules = [...rules, ...DEFAULT_MASKING_RULES];
2118
2071
  }
2119
2072
  try {
2120
- const attributesRecord = {};
2121
- for (const [key, value] of Object.entries(span.attributes)) {
2122
- attributesRecord[key] = value;
2123
- }
2124
- const maskedAttributes = maskAttributes(attributesRecord, rules);
2125
- if (maskedAttributes && Object.keys(maskedAttributes).length > 0) {
2126
- const merged = { ...span.attributes };
2127
- for (const [key, value] of Object.entries(maskedAttributes)) {
2128
- merged[key] = value;
2073
+ const input = {};
2074
+ for (const [k, v] of Object.entries(attrs)) {
2075
+ input[k] = v;
2076
+ }
2077
+ const masked = maskAttributes(input, rules);
2078
+ for (const [k, v] of Object.entries(masked ?? {})) {
2079
+ if (attrs[k] !== v) {
2080
+ attrs[k] = v;
2129
2081
  }
2130
- span.setAttributes(merged);
2131
2082
  }
2132
- return span;
2133
2083
  } catch (error) {
2134
- logger.error("Error masking span:", error);
2135
- return span;
2084
+ logger.error("Error masking span", { err: error });
2136
2085
  }
2137
2086
  }
2138
2087
 
@@ -2245,7 +2194,7 @@ function getSpanProcessor() {
2245
2194
  }
2246
2195
 
2247
2196
  // src/internal/trace/session.ts
2248
- var import_api9 = require("@opentelemetry/api");
2197
+ var import_api10 = require("@opentelemetry/api");
2249
2198
 
2250
2199
  // src/internal/sdk.ts
2251
2200
  var _Brizz = class __Brizz {
@@ -2578,15 +2527,18 @@ if (runtime.isESM && runtime.supportsLoaderAPI) {
2578
2527
  maybeRegisterESMLoader();
2579
2528
  }
2580
2529
  try {
2581
- Brizz.initialize({
2582
- apiKey: process.env["BRIZZ_API_KEY"],
2583
- baseUrl: process.env["BRIZZ_BASE_URL"],
2584
- appName: process.env["BRIZZ_APP_NAME"] || process.env["OTEL_SERVICE_NAME"],
2585
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2586
- logLevel: process.env["BRIZZ_LOG_LEVEL"] || DEFAULT_LOG_LEVEL.toString(),
2587
- // Enable auto-instrumentation by default in preload mode
2588
- disableNodeSdk: false
2589
- });
2530
+ const logLevel = process.env["BRIZZ_LOG_LEVEL"] || DEFAULT_LOG_LEVEL.toString();
2531
+ if (process.env["BRIZZ_DSN"]) {
2532
+ Brizz.initialize({ logLevel, disableNodeSdk: false });
2533
+ } else {
2534
+ Brizz.initialize({
2535
+ apiKey: process.env["BRIZZ_API_KEY"],
2536
+ baseUrl: process.env["BRIZZ_BASE_URL"],
2537
+ appName: process.env["BRIZZ_APP_NAME"] || process.env["OTEL_SERVICE_NAME"],
2538
+ logLevel,
2539
+ disableNodeSdk: false
2540
+ });
2541
+ }
2590
2542
  logger.info(`SDK auto-initialized for ${runtime.isESM ? "ESM" : "CJS"} runtime`);
2591
2543
  } catch (error) {
2592
2544
  logger.warn("Failed to auto-initialize SDK:", { error });