@brizz/sdk 0.1.21 → 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
  }
@@ -258,6 +340,716 @@ var import_instrumentation_pinecone = require("@traceloop/instrumentation-pineco
258
340
  var import_instrumentation_qdrant = require("@traceloop/instrumentation-qdrant");
259
341
  var import_instrumentation_together = require("@traceloop/instrumentation-together");
260
342
  var import_instrumentation_vertexai = require("@traceloop/instrumentation-vertexai");
343
+
344
+ // src/internal/instrumentation/mcp/instrumentation.ts
345
+ var import_openinference_instrumentation_mcp = require("@arizeai/openinference-instrumentation-mcp");
346
+ var import_api7 = require("@opentelemetry/api");
347
+ var import_instrumentation = require("@opentelemetry/instrumentation");
348
+
349
+ // src/internal/instrumentation/mcp/patches/protocol.ts
350
+ var import_api6 = require("@opentelemetry/api");
351
+
352
+ // src/internal/instrumentation/mcp/schemas.ts
353
+ var import_api3 = require("@opentelemetry/api");
354
+
355
+ // src/internal/semantic-conventions.ts
356
+ var import_api2 = require("@opentelemetry/api");
357
+ var BRIZZ = "brizz";
358
+ var PROPERTIES = "properties";
359
+ var SESSION_ID = "session.id";
360
+ var PROPERTIES_CONTEXT_KEY = (0, import_api2.createContextKey)(PROPERTIES);
361
+ var SESSION_OBJECT_CONTEXT_KEY = (0, import_api2.createContextKey)("brizz.session.object");
362
+
363
+ // src/internal/instrumentation/mcp/semantic-conventions.ts
364
+ var MCP_TOOL_NAME = "mcp.tool.name";
365
+ var MCP_TOOL_ARGUMENTS = "mcp.tool.arguments";
366
+ var MCP_TOOL_RESULT = "mcp.tool.result";
367
+ var MCP_COMPONENT_TYPE = "mcp.component.type";
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";
374
+ var MCP_METHOD_NAME = "mcp.method.name";
375
+ var MCP_REQUEST_ID = "mcp.request.id";
376
+ var MCP_SESSION_ID = "mcp.session.id";
377
+ var MCP_PROTOCOL_VERSION = "mcp.protocol.version";
378
+ var MCP_RESOURCE_URI = "mcp.resource.uri";
379
+ var RPC_SYSTEM = "rpc.system";
380
+ var RPC_SYSTEM_MCP = "mcp";
381
+ var RPC_RESPONSE_STATUS_CODE = "rpc.response.status_code";
382
+ var GEN_AI_TOOL_NAME = "gen_ai.tool.name";
383
+ var GEN_AI_PROMPT_NAME = "gen_ai.prompt.name";
384
+ var GEN_AI_OPERATION_NAME = "gen_ai.operation.name";
385
+ var GEN_AI_OPERATION_EXECUTE_TOOL = "execute_tool";
386
+ var NETWORK_TRANSPORT = "network.transport";
387
+ var ERROR_TYPE = "error.type";
388
+ var ERROR_TYPE_TOOL = "tool_error";
389
+ var JSONRPC_REQUEST_ID = "jsonrpc.request.id";
390
+ var SPAN_NAME_TOOLS_CALL = "tools/call";
391
+ var MAX_ATTRIBUTE_LENGTH = 32 * 1024;
392
+ var TRUNCATION_SUFFIX = "\u2026(truncated)";
393
+ var METHOD_TOOLS_CALL = "tools/call";
394
+ var METHOD_TOOLS_LIST = "tools/list";
395
+ var METHOD_RESOURCES_READ = "resources/read";
396
+ var METHOD_PROMPTS_GET = "prompts/get";
397
+ var METHOD_INITIALIZE = "initialize";
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
+
501
+ // src/internal/instrumentation/mcp/patches/attributes.ts
502
+ var import_api5 = require("@opentelemetry/api");
503
+ function deriveSpanName(method, params) {
504
+ try {
505
+ if (method === METHOD_TOOLS_CALL) {
506
+ const name = typeof params?.["name"] === "string" ? params["name"] : "";
507
+ return name ? `${SPAN_NAME_TOOLS_CALL} ${name}` : SPAN_NAME_TOOLS_CALL;
508
+ }
509
+ if (method === METHOD_RESOURCES_READ) {
510
+ const uri = typeof params?.["uri"] === "string" ? params["uri"] : "";
511
+ return uri ? `${METHOD_RESOURCES_READ} ${uri}` : METHOD_RESOURCES_READ;
512
+ }
513
+ if (method === METHOD_PROMPTS_GET) {
514
+ const name = typeof params?.["name"] === "string" ? params["name"] : "";
515
+ return name ? `${METHOD_PROMPTS_GET} ${name}` : METHOD_PROMPTS_GET;
516
+ }
517
+ return method;
518
+ } catch {
519
+ return method || "mcp";
520
+ }
521
+ }
522
+ function applyBaseAttributes(span, request) {
523
+ span.setAttribute(RPC_SYSTEM, RPC_SYSTEM_MCP);
524
+ if (request.method) {
525
+ span.setAttribute(MCP_METHOD_NAME, request.method);
526
+ }
527
+ if (request.id !== void 0 && request.id !== null) {
528
+ const id = String(request.id);
529
+ span.setAttribute(MCP_REQUEST_ID, id);
530
+ span.setAttribute(JSONRPC_REQUEST_ID, id);
531
+ }
532
+ }
533
+ function applyClientRequestAttributes(span, request, transportName) {
534
+ applyBaseAttributes(span, request);
535
+ applyMethodSpecificRequestAttributes(span, request);
536
+ if (transportName) {
537
+ const transport = normalizeTransport(transportName);
538
+ if (transport) {
539
+ span.setAttribute(NETWORK_TRANSPORT, transport);
540
+ }
541
+ }
542
+ }
543
+ function applyServerRequestAttributes(span, request, protocol) {
544
+ applyBaseAttributes(span, request);
545
+ applyMethodSpecificRequestAttributes(span, request);
546
+ if (request.method === METHOD_TOOLS_CALL) {
547
+ const args = request.params?.["arguments"];
548
+ if (args !== void 0) {
549
+ span.setAttribute(MCP_TOOL_ARGUMENTS, serializeForAttribute(args));
550
+ }
551
+ }
552
+ const sessionId = protocol.sessionId ?? protocol._transport?.sessionId;
553
+ if (sessionId) {
554
+ span.setAttribute(MCP_SESSION_ID, String(sessionId));
555
+ }
556
+ }
557
+ function applyMethodSpecificRequestAttributes(span, request) {
558
+ const params = request.params ?? {};
559
+ switch (request.method) {
560
+ case METHOD_TOOLS_CALL: {
561
+ const name = typeof params["name"] === "string" ? params["name"] : "";
562
+ if (name) {
563
+ span.setAttribute(MCP_TOOL_NAME, name);
564
+ span.setAttribute(GEN_AI_TOOL_NAME, name);
565
+ }
566
+ span.setAttribute(MCP_COMPONENT_TYPE, MCP_COMPONENT_TOOL);
567
+ span.setAttribute(GEN_AI_OPERATION_NAME, GEN_AI_OPERATION_EXECUTE_TOOL);
568
+ break;
569
+ }
570
+ case METHOD_RESOURCES_READ: {
571
+ const uri = typeof params["uri"] === "string" ? params["uri"] : "";
572
+ if (uri) {
573
+ span.setAttribute(MCP_RESOURCE_URI, uri);
574
+ }
575
+ break;
576
+ }
577
+ case METHOD_PROMPTS_GET: {
578
+ const name = typeof params["name"] === "string" ? params["name"] : "";
579
+ if (name) {
580
+ span.setAttribute(GEN_AI_PROMPT_NAME, name);
581
+ }
582
+ break;
583
+ }
584
+ default:
585
+ break;
586
+ }
587
+ }
588
+ function applyResultAttributes(span, method, result) {
589
+ if (method === METHOD_INITIALIZE && result && typeof result === "object") {
590
+ const protocolVersion = result["protocolVersion"];
591
+ if (typeof protocolVersion === "string") {
592
+ span.setAttribute(MCP_PROTOCOL_VERSION, protocolVersion);
593
+ }
594
+ return;
595
+ }
596
+ if (method !== METHOD_TOOLS_CALL) {
597
+ return;
598
+ }
599
+ const obj = result && typeof result === "object" ? result : null;
600
+ const content = obj?.["content"] ?? result;
601
+ span.setAttribute(MCP_TOOL_RESULT, serializeForAttribute(content));
602
+ if (obj && obj["isError"] === true) {
603
+ span.setAttribute(ERROR_TYPE, ERROR_TYPE_TOOL);
604
+ const message = extractToolErrorMessage(obj);
605
+ span.setStatus({ code: import_api5.SpanStatusCode.ERROR, message });
606
+ }
607
+ }
608
+ function applyErrorAttributes(span, err) {
609
+ const error = err;
610
+ const code = error?.code;
611
+ if (typeof code === "number") {
612
+ span.setAttribute(RPC_RESPONSE_STATUS_CODE, code);
613
+ span.setAttribute(ERROR_TYPE, String(code));
614
+ } else if (error?.name === "AbortError") {
615
+ span.setAttribute(ERROR_TYPE, "cancelled");
616
+ } else if (error?.name === "TimeoutError") {
617
+ span.setAttribute(ERROR_TYPE, "timeout");
618
+ } else {
619
+ span.setAttribute(
620
+ ERROR_TYPE,
621
+ error?.constructor?.name || error?.name || "Error"
622
+ );
623
+ }
624
+ try {
625
+ span.recordException(error);
626
+ } catch {
627
+ }
628
+ span.setStatus({
629
+ code: import_api5.SpanStatusCode.ERROR,
630
+ message: typeof error?.message === "string" ? error.message : void 0
631
+ });
632
+ }
633
+ function serializeForAttribute(value) {
634
+ const raw = rawSerialize(value);
635
+ if (raw.length <= MAX_ATTRIBUTE_LENGTH) {
636
+ return raw;
637
+ }
638
+ return raw.slice(0, MAX_ATTRIBUTE_LENGTH - TRUNCATION_SUFFIX.length) + TRUNCATION_SUFFIX;
639
+ }
640
+ function rawSerialize(value) {
641
+ if (value === null || value === void 0) {
642
+ return "";
643
+ }
644
+ if (typeof value === "string") {
645
+ return value;
646
+ }
647
+ try {
648
+ return JSON.stringify(value);
649
+ } catch {
650
+ try {
651
+ if (value === null || value === void 0) {
652
+ return "";
653
+ }
654
+ const tag = Object.prototype.toString.call(value);
655
+ return typeof value.toString === "function" ? (
656
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
657
+ String(value)
658
+ ) : tag;
659
+ } catch {
660
+ return "";
661
+ }
662
+ }
663
+ }
664
+ function extractToolErrorMessage(result) {
665
+ const content = result["content"];
666
+ if (Array.isArray(content)) {
667
+ for (const item of content) {
668
+ if (item && typeof item === "object") {
669
+ const text = item["text"];
670
+ if (typeof text === "string") {
671
+ return text;
672
+ }
673
+ }
674
+ }
675
+ }
676
+ return void 0;
677
+ }
678
+ function normalizeTransport(ctorName) {
679
+ const name = ctorName.toLowerCase();
680
+ if (name.includes("stdio")) {
681
+ return "stdio";
682
+ }
683
+ if (name.includes("sse")) {
684
+ return "sse";
685
+ }
686
+ if (name.includes("streamablehttp") || name.includes("http")) {
687
+ return "http";
688
+ }
689
+ return null;
690
+ }
691
+
692
+ // src/internal/instrumentation/mcp/patches/protocol.ts
693
+ var PATCHED_FLAG = /* @__PURE__ */ Symbol("brizz.mcp.protocol-patched");
694
+ function patchProtocolPrototype(prototype, tracer) {
695
+ if (!prototype || typeof prototype !== "object") {
696
+ return false;
697
+ }
698
+ const proto = prototype;
699
+ if (proto[PATCHED_FLAG]) {
700
+ logger.debug("Brizz MCP: Protocol.prototype already patched, skipping");
701
+ return false;
702
+ }
703
+ const originalRequest = proto["request"];
704
+ const originalOnRequest = proto["_onrequest"];
705
+ if (typeof originalRequest === "function") {
706
+ proto["request"] = wrapRequest(originalRequest, tracer);
707
+ } else {
708
+ logger.debug(
709
+ "Brizz MCP: Protocol.prototype.request missing \u2014 skipping CLIENT patch"
710
+ );
711
+ }
712
+ if (typeof originalOnRequest === "function") {
713
+ proto["_onrequest"] = wrapOnRequest(
714
+ originalOnRequest,
715
+ tracer
716
+ );
717
+ } else {
718
+ logger.debug(
719
+ "Brizz MCP: Protocol.prototype._onrequest missing \u2014 skipping SERVER patch"
720
+ );
721
+ }
722
+ proto[PATCHED_FLAG] = true;
723
+ return true;
724
+ }
725
+ function wrapRequest(original, tracer) {
726
+ return function wrappedRequest(...args) {
727
+ const request = args[0];
728
+ if (!request || typeof request !== "object" || !request.method) {
729
+ return original.apply(this, args);
730
+ }
731
+ const span = safeStartClientSpan(tracer, request, this);
732
+ if (!span) {
733
+ return original.apply(this, args);
734
+ }
735
+ return executeAroundSpan(span, request.method, () => {
736
+ const ctx = import_api6.trace.setSpan(import_api6.context.active(), span);
737
+ return import_api6.context.with(ctx, () => original.apply(this, args));
738
+ });
739
+ };
740
+ }
741
+ function wrapOnRequest(original, tracer) {
742
+ return function wrappedOnRequest(...args) {
743
+ const request = args[0];
744
+ if (!request || typeof request !== "object" || !request.method) {
745
+ return original.apply(this, args);
746
+ }
747
+ const handlers = this._requestHandlers;
748
+ if (!handlers || typeof handlers.get !== "function") {
749
+ return original.apply(this, args);
750
+ }
751
+ const method = request.method;
752
+ const handler = handlers.get(method) ?? this.fallbackRequestHandler;
753
+ if (!handler) {
754
+ return original.apply(this, args);
755
+ }
756
+ const started = safeStartServerSpan(tracer, request, this);
757
+ if (!started) {
758
+ return original.apply(this, args);
759
+ }
760
+ const { span, spanCtx } = started;
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
+ );
775
+ const hadEntry = handlers.has(method);
776
+ const prev = handlers.get(method);
777
+ handlers.set(method, wrappedHandler);
778
+ const usedFallback = !hadEntry && this.fallbackRequestHandler === handler;
779
+ const fallbackPrev = usedFallback ? this.fallbackRequestHandler : void 0;
780
+ if (usedFallback) {
781
+ this.fallbackRequestHandler = wrappedHandler;
782
+ }
783
+ try {
784
+ return original.apply(this, args);
785
+ } finally {
786
+ if (hadEntry) {
787
+ handlers.set(method, prev);
788
+ } else {
789
+ handlers.delete(method);
790
+ }
791
+ if (usedFallback) {
792
+ this.fallbackRequestHandler = fallbackPrev;
793
+ }
794
+ }
795
+ };
796
+ }
797
+ function executeAroundSpan(span, method, run, postResult) {
798
+ let result;
799
+ try {
800
+ result = run();
801
+ } catch (error) {
802
+ safeApplyErrorAttributes(span, error);
803
+ safeEnd(span);
804
+ throw error;
805
+ }
806
+ if (!isThenable(result)) {
807
+ safeApplyResultAttributes(span, method, result);
808
+ if (postResult) {
809
+ postResult(result);
810
+ }
811
+ safeEnd(span);
812
+ return result;
813
+ }
814
+ return result.then(
815
+ (value) => {
816
+ safeApplyResultAttributes(span, method, value);
817
+ if (postResult) {
818
+ postResult(value);
819
+ }
820
+ safeEnd(span);
821
+ return value;
822
+ },
823
+ (error) => {
824
+ safeApplyErrorAttributes(span, error);
825
+ safeEnd(span);
826
+ throw error;
827
+ }
828
+ );
829
+ }
830
+ function executeHandler(span, method, handler, req, extra, postResult) {
831
+ return executeAroundSpan(span, method, () => handler(req, extra), postResult);
832
+ }
833
+ function safeStartClientSpan(tracer, request, protocol) {
834
+ try {
835
+ const spanName = deriveSpanName(request.method, request.params);
836
+ const span = tracer.startSpan(spanName, { kind: import_api6.SpanKind.CLIENT });
837
+ applyClientRequestAttributes(
838
+ span,
839
+ request,
840
+ protocol._transport?.constructor?.name
841
+ );
842
+ return span;
843
+ } catch (error) {
844
+ logger.debug(`Brizz MCP: failed to open CLIENT span: ${String(error)}`);
845
+ return null;
846
+ }
847
+ }
848
+ function safeStartServerSpan(tracer, request, protocol) {
849
+ try {
850
+ const parentCtx = extractParentContext(request);
851
+ const spanName = deriveSpanName(request.method, request.params);
852
+ const span = tracer.startSpan(
853
+ spanName,
854
+ { kind: import_api6.SpanKind.SERVER },
855
+ parentCtx
856
+ );
857
+ applyServerRequestAttributes(span, request, protocol);
858
+ const sessionId = protocol.sessionId ?? protocol._transport?.sessionId;
859
+ const { context: sessCtx } = stampAndPropagateSession(span, sessionId, parentCtx);
860
+ return { span, spanCtx: import_api6.trace.setSpan(sessCtx, span) };
861
+ } catch (error) {
862
+ logger.debug(`Brizz MCP: failed to open SERVER span: ${String(error)}`);
863
+ return null;
864
+ }
865
+ }
866
+ function extractParentContext(request) {
867
+ try {
868
+ const meta = request.params?._meta;
869
+ if (meta && typeof meta === "object") {
870
+ return import_api6.propagation.extract(import_api6.context.active(), meta);
871
+ }
872
+ } catch (error) {
873
+ logger.debug(
874
+ `Brizz MCP: failed to extract parent context from _meta: ${String(error)}`
875
+ );
876
+ }
877
+ return import_api6.context.active();
878
+ }
879
+ function isThenable(value) {
880
+ return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
881
+ }
882
+ function safeApplyResultAttributes(span, method, value) {
883
+ try {
884
+ applyResultAttributes(span, method, value);
885
+ } catch (error) {
886
+ logger.debug(
887
+ `Brizz MCP: failed to apply result attributes: ${String(error)}`
888
+ );
889
+ }
890
+ }
891
+ function safeApplyErrorAttributes(span, err) {
892
+ try {
893
+ applyErrorAttributes(span, err);
894
+ } catch (error) {
895
+ logger.debug(
896
+ `Brizz MCP: failed to apply error attributes: ${String(error)}`
897
+ );
898
+ }
899
+ }
900
+ function safeEnd(span) {
901
+ try {
902
+ span.end();
903
+ } catch (error) {
904
+ logger.debug(`Brizz MCP: failed to end span: ${String(error)}`);
905
+ }
906
+ }
907
+
908
+ // src/internal/version.ts
909
+ function getSDKVersion() {
910
+ return "0.1.25";
911
+ }
912
+
913
+ // src/internal/instrumentation/mcp/version.ts
914
+ var INSTRUMENTATION_NAME = "@brizz/sdk/mcp";
915
+ var INSTRUMENTATION_VERSION = getSDKVersion();
916
+
917
+ // src/internal/instrumentation/mcp/instrumentation.ts
918
+ var PROTOCOL_MODULE_NAME = "@modelcontextprotocol/sdk/shared/protocol.js";
919
+ var PROTOCOL_SUPPORTED_VERSIONS = [">=1.0.0 <2"];
920
+ var MCPInstrumentation = class extends import_openinference_instrumentation_mcp.MCPInstrumentation {
921
+ /**
922
+ * Dedicated Brizz-named tracer for our SERVER + CLIENT spans.
923
+ *
924
+ * Why a separate tracer from the parent class's one: Arize's inherited
925
+ * transport patches don't emit spans (they only inject propagation
926
+ * headers), so using our own tracer here keeps Brizz spans attributed to
927
+ * `@brizz/sdk/mcp` in the dashboard. The parent's `tracer` is a
928
+ * `protected get` (no setter), so fighting it with assignment is the
929
+ * wrong tool.
930
+ */
931
+ brizzTracer;
932
+ constructor(_config) {
933
+ super({ instrumentationConfig: _config?.instrumentationConfig });
934
+ this.brizzTracer = import_api7.trace.getTracer(INSTRUMENTATION_NAME, INSTRUMENTATION_VERSION);
935
+ }
936
+ /**
937
+ * Extend `super.init()` with our protocol-layer module definition.
938
+ *
939
+ * Arize's `init()` returns definitions for the six transport modules
940
+ * (SSE client/server, stdio client/server, streamable-HTTP client/server)
941
+ * whose `send`/`start` methods get patched for W3C trace-context
942
+ * injection. We append one more: `@modelcontextprotocol/sdk/shared/protocol.js`
943
+ * where our patches open SERVER/CLIENT spans around the handler + outgoing
944
+ * request. If `super.init()` throws (unlikely but possible across Arize
945
+ * versions), we gracefully degrade to protocol-only instrumentation.
946
+ *
947
+ * The cast at the end satisfies the parent's strongly-typed generic
948
+ * without leaking the cast into call sites.
949
+ */
950
+ init() {
951
+ let base;
952
+ try {
953
+ base = super.init() ?? [];
954
+ } catch (error) {
955
+ logger.warn(
956
+ `Brizz MCP: base Arize init() failed \u2014 transport context propagation disabled: ${String(error)}`
957
+ );
958
+ base = [];
959
+ }
960
+ const baseArr = Array.isArray(base) ? base : [base];
961
+ const brizzDef = new import_instrumentation.InstrumentationNodeModuleDefinition(
962
+ PROTOCOL_MODULE_NAME,
963
+ PROTOCOL_SUPPORTED_VERSIONS,
964
+ (module3) => {
965
+ this.patchProtocolModule(module3);
966
+ return module3;
967
+ },
968
+ (module3) => {
969
+ this.unpatchProtocolModule(module3);
970
+ return module3;
971
+ }
972
+ );
973
+ return [...baseArr, brizzDef];
974
+ }
975
+ /**
976
+ * Manually instrument MCP modules for Next.js/Webpack where the
977
+ * auto-instrumentation module-load hook doesn't fire.
978
+ *
979
+ * Forwards the six transport module fields to the inherited Arize
980
+ * `manuallyInstrument(...)` (context propagation) and applies our
981
+ * protocol patch if `protocolModule` is provided (SERVER/CLIENT spans).
982
+ * Both legs are try/catch-guarded — a failure in one shouldn't prevent
983
+ * the other from taking effect.
984
+ */
985
+ manuallyInstrument(modules) {
986
+ const {
987
+ clientSSEModule,
988
+ serverSSEModule,
989
+ clientStdioModule,
990
+ serverStdioModule,
991
+ clientStreamableHTTPModule,
992
+ serverStreamableHTTPModule,
993
+ protocolModule
994
+ } = modules;
995
+ try {
996
+ super.manuallyInstrument({
997
+ clientSSEModule,
998
+ serverSSEModule,
999
+ clientStdioModule,
1000
+ serverStdioModule,
1001
+ clientStreamableHTTPModule,
1002
+ serverStreamableHTTPModule
1003
+ });
1004
+ } catch (error) {
1005
+ logger.warn(`Brizz MCP: Arize manuallyInstrument(...) failed: ${String(error)}`);
1006
+ }
1007
+ if (protocolModule) {
1008
+ try {
1009
+ this.patchProtocolModule(protocolModule);
1010
+ } catch (error) {
1011
+ logger.warn(
1012
+ `Brizz MCP: failed to manually patch Protocol module: ${String(error)}`
1013
+ );
1014
+ }
1015
+ }
1016
+ }
1017
+ /**
1018
+ * Apply the SERVER + CLIENT patch to a loaded `protocol.js` module. Shared
1019
+ * by both the automatic module-load callback in `init()` and the manual
1020
+ * `manuallyInstrument(...)` path above so there's exactly one place that
1021
+ * calls `patchProtocolPrototype`.
1022
+ */
1023
+ patchProtocolModule(module3) {
1024
+ const proto = module3?.Protocol?.prototype;
1025
+ if (!proto) {
1026
+ logger.debug(
1027
+ "Brizz MCP: module does not expose Protocol.prototype \u2014 skipping protocol patches"
1028
+ );
1029
+ return;
1030
+ }
1031
+ const ok = patchProtocolPrototype(proto, this.brizzTracer);
1032
+ if (ok) {
1033
+ logger.debug("Brizz MCP: patched Protocol.prototype for SERVER+CLIENT spans");
1034
+ }
1035
+ }
1036
+ /**
1037
+ * Unpatch is intentionally a no-op.
1038
+ *
1039
+ * `patchProtocolPrototype` wraps methods in place and sets a PATCHED_FLAG
1040
+ * Symbol on the prototype to prevent double-patching. Restoring the
1041
+ * originals would require us to hold references across module unloads,
1042
+ * which isn't a pattern we need — instrumentation rarely gets torn down
1043
+ * at runtime, and a process reload is the canonical way to detach.
1044
+ */
1045
+ unpatchProtocolModule(_module) {
1046
+ logger.debug(
1047
+ "Brizz MCP: unpatch is a no-op \u2014 reload the process to cleanly detach"
1048
+ );
1049
+ }
1050
+ };
1051
+
1052
+ // src/internal/instrumentation/registry.ts
261
1053
  var InstrumentationRegistry = class _InstrumentationRegistry {
262
1054
  static instance;
263
1055
  manualModules = null;
@@ -362,6 +1154,14 @@ var InstrumentationRegistry = class _InstrumentationRegistry {
362
1154
  }
363
1155
  })();
364
1156
  }
1157
+ if (this.manualModules?.mcp) {
1158
+ try {
1159
+ new MCPInstrumentation({ exceptionLogger }).manuallyInstrument(this.manualModules.mcp);
1160
+ logger.debug("Manual instrumentation enabled for MCP");
1161
+ } catch (error) {
1162
+ logger.error(`Failed to apply MCP instrumentation: ${String(error)}`);
1163
+ }
1164
+ }
365
1165
  }
366
1166
  };
367
1167
 
@@ -371,32 +1171,17 @@ var import_exporter_logs_otlp_http = require("@opentelemetry/exporter-logs-otlp-
371
1171
  var import_resources = require("@opentelemetry/resources");
372
1172
  var import_sdk_logs2 = require("@opentelemetry/sdk-logs");
373
1173
 
374
- // src/internal/version.ts
375
- function getSDKVersion() {
376
- return "0.1.21";
377
- }
378
-
379
1174
  // src/internal/log/processors/log-processor.ts
380
- var import_api3 = require("@opentelemetry/api");
1175
+ var import_api8 = require("@opentelemetry/api");
381
1176
  var import_sdk_logs = require("@opentelemetry/sdk-logs");
382
1177
 
383
1178
  // src/internal/masking/patterns.ts
384
1179
  var DEFAULT_PII_PATTERNS = [
385
- // Email addresses
386
- {
387
- name: "email_addresses",
388
- pattern: String.raw`\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`
389
- },
390
1180
  // Phone numbers (US format)
391
1181
  {
392
1182
  name: "us_phone_numbers",
393
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]|$)`
394
1184
  },
395
- // Social Security Numbers
396
- {
397
- name: "ssn",
398
- pattern: String.raw`\b(?!000|666|9\d{2})\d{3}[-\s]?(?!00)\d{2}[-\s]?(?!0000)\d{4}\b`
399
- },
400
1185
  // Credit card numbers
401
1186
  {
402
1187
  name: "credit_cards",
@@ -420,19 +1205,11 @@ var DEFAULT_PII_PATTERNS = [
420
1205
  name: "openai_keys",
421
1206
  pattern: String.raw`\bsk[-_][a-zA-Z0-9]{20,}\b`
422
1207
  },
423
- {
424
- name: "base64_secrets",
425
- pattern: String.raw`\b[A-Za-z0-9+/]{64,}={0,2}\b`
426
- },
427
1208
  // AWS Keys
428
1209
  {
429
1210
  name: "aws_access_keys",
430
1211
  pattern: String.raw`\b(?:AKIA|ABIA|ACCA|ASIA)[0-9A-Z]{16}\b`
431
1212
  },
432
- {
433
- name: "aws_secret_keys",
434
- 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`
435
- },
436
1213
  // GitHub tokens
437
1214
  {
438
1215
  name: "github_tokens",
@@ -463,11 +1240,6 @@ var DEFAULT_PII_PATTERNS = [
463
1240
  name: "ipv6_addresses",
464
1241
  pattern: String.raw`\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b`
465
1242
  },
466
- // Medical records
467
- {
468
- name: "medical_record_numbers",
469
- pattern: String.raw`\b(?:[Mm][Rr][Nn])[-\s]?\d{6,10}\b`
470
- },
471
1243
  // Bitcoin addresses
472
1244
  {
473
1245
  name: "bitcoin_addresses",
@@ -478,11 +1250,6 @@ var DEFAULT_PII_PATTERNS = [
478
1250
  name: "ethereum_addresses",
479
1251
  pattern: String.raw`\b0x[a-fA-F0-9]{40}(?![a-fA-F0-9])\b`
480
1252
  },
481
- // UUIDs
482
- {
483
- name: "uuids",
484
- 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`
485
- },
486
1253
  // Database connection strings
487
1254
  {
488
1255
  name: "database_connections",
@@ -501,90 +1268,6 @@ var DEFAULT_PII_PATTERNS = [
501
1268
  name: "certificates",
502
1269
  pattern: "-----BEGIN CERTIFICATE-----"
503
1270
  },
504
- // Date of birth patterns
505
- {
506
- name: "date_of_birth_us",
507
- pattern: String.raw`\b(?:0[1-9]|1[0-2])[-/](?:0[1-9]|[12]\\d|3[01])[-/](?:19|20)\\d{2}\b`
508
- },
509
- {
510
- name: "date_of_birth_iso",
511
- pattern: String.raw`\b(?:19|20)\\d{2}[-/](?:0[1-9]|1[0-2])[-/](?:0[1-9]|[12]\\d|3[01])\b`
512
- },
513
- // US Identification Numbers
514
- {
515
- name: "us_passport_numbers",
516
- pattern: String.raw`\b[A-Z]?\\d{6,9}\b`
517
- },
518
- {
519
- name: "drivers_license",
520
- 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`
521
- },
522
- {
523
- name: "bank_account_numbers",
524
- pattern: String.raw`\b\\d{10,17}\b`
525
- },
526
- {
527
- name: "aba_routing_numbers",
528
- 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`
529
- },
530
- {
531
- name: "health_insurance_numbers",
532
- pattern: String.raw`\b\\d{10}[A-Z]\b`
533
- },
534
- {
535
- name: "employee_ids",
536
- pattern: String.raw`\b(?:[Ee][Mm][Pp]|[Ee][Mm][Pp][Ll][Oo][Yy][Ee][Ee]|[Ee])[-\s]?\\d{5,8}\b`
537
- },
538
- {
539
- name: "tax_ein",
540
- pattern: String.raw`\b\\d{2}-\\d{7}\b`
541
- },
542
- {
543
- name: "medicare_beneficiary_id",
544
- 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`
545
- },
546
- {
547
- name: "national_provider_id",
548
- pattern: String.raw`\b1\\d{9}\b`
549
- },
550
- {
551
- name: "dea_numbers",
552
- pattern: String.raw`\b[A-Z]{2}\\d{7}\b`
553
- },
554
- {
555
- name: "itin",
556
- pattern: String.raw`\b9\\d{2}(?:[ \\-]?)[7,8]\\d(?:[ \\-]?)\\d{4}\b`
557
- },
558
- // Vehicle and Location
559
- {
560
- name: "vin_numbers",
561
- pattern: String.raw`\b[A-HJ-NPR-Z0-9]{17}\b`
562
- },
563
- {
564
- name: "coordinates",
565
- pattern: String.raw`\b[-+]?(?:[0-8]?\\d(?:\\.\\d+)?|90(?:\\.0+)?),\\s*[-+]?(?:1[0-7]\\d(?:\\.\\d+)?|180(?:\\.0+)?|[0-9]?\\d(?:\\.\\d+)?)\b`
566
- },
567
- {
568
- name: "us_license_plates",
569
- 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`
570
- },
571
- {
572
- name: "us_zip_codes",
573
- pattern: String.raw`\b(\\d{5}-\\d{4}|\\d{5})\b`
574
- },
575
- {
576
- name: "us_street_addresses",
577
- 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`
578
- },
579
- // International Banking
580
- {
581
- name: "iban",
582
- pattern: String.raw`\b[A-Z]{2}\d{2}[A-Z0-9]{4}\d{7}([A-Z0-9]?){0,16}\b`
583
- },
584
- {
585
- name: "swift_bic",
586
- pattern: String.raw`\b[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?\b`
587
- },
588
1271
  // Additional API Keys and Tokens
589
1272
  {
590
1273
  name: "google_oauth",
@@ -647,73 +1330,6 @@ var DEFAULT_PII_PATTERNS = [
647
1330
  name: "putty_ssh_keys",
648
1331
  pattern: String.raw`PuTTY-User-Key-File-2: ssh-(?:rsa|dss)\s*Encryption: none(?:.|\s?)*?Private-MAC:`
649
1332
  },
650
- // International Phone Numbers
651
- {
652
- name: "france_phone_numbers",
653
- pattern: String.raw`\b([0O]?[1lI][1lI])?[3E][3E][0O]?[\\dOIlZEASB]{9}\b`
654
- },
655
- {
656
- name: "german_phone_numbers",
657
- pattern: String.raw`\b[\d\w]\d{2}[\d\w]{6}\d[\d\w]\b`
658
- },
659
- {
660
- name: "uk_phone_numbers",
661
- pattern: String.raw`\b([0O]?[1lI][1lI])?[4A][4A][\\dOIlZEASB]{10,11}\b`
662
- },
663
- // International IDs
664
- {
665
- name: "uk_drivers_license",
666
- pattern: String.raw`\b[A-Z]{5}\d{6}[A-Z]{2}\d{1}[A-Z]{2}\b`
667
- },
668
- {
669
- name: "uk_passport",
670
- pattern: String.raw`\b\\d{10}GB[RP]\\d{7}[UMF]{1}\\d{9}\b`
671
- },
672
- {
673
- name: "argentina_dni",
674
- pattern: String.raw`\b\\d{2}\\.\\d{3}\\.\\d{3}\b`
675
- },
676
- {
677
- name: "australia_tfn",
678
- pattern: String.raw`\b[Tt][Ff][Nn](:|:\\s|\\s|)(\\d{8,9})\b`
679
- },
680
- {
681
- name: "canada_passport",
682
- pattern: String.raw`\b[\\w]{2}[\\d]{6}\b`
683
- },
684
- {
685
- name: "croatia_vat",
686
- pattern: String.raw`\bHR\\d{11}\b`
687
- },
688
- {
689
- name: "czech_vat",
690
- pattern: String.raw`\bCZ\\d{8,10}\b`
691
- },
692
- {
693
- name: "denmark_personal_id",
694
- pattern: String.raw`\b(?:\\d{10}|\\d{6}[-\\s]\\d{4})\b`
695
- },
696
- {
697
- name: "france_national_id",
698
- pattern: String.raw`\b\\d{12}\b`
699
- },
700
- {
701
- name: "france_ssn",
702
- pattern: String.raw`\b(?:\\d{13}|\\d{13}\\s\\d{2})\b`
703
- },
704
- {
705
- name: "france_passport",
706
- pattern: String.raw`\b\\d{2}11\\d{5}\b`
707
- },
708
- {
709
- name: "california_drivers_license",
710
- pattern: String.raw`\b[A-Z]{1}\\d{7}\b`
711
- },
712
- // Medical and Healthcare
713
- {
714
- name: "hipaa_ndc",
715
- pattern: String.raw`\b\\d{4,5}-\\d{3,4}-\\d{1,2}\b`
716
- },
717
1333
  // Security and Network
718
1334
  {
719
1335
  name: "cve_numbers",
@@ -747,44 +1363,6 @@ var DEFAULT_PII_PATTERNS = [
747
1363
  {
748
1364
  name: "discover_cards",
749
1365
  pattern: String.raw`\b65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}\b`
750
- },
751
- {
752
- name: "enhanced_credit_cards",
753
- 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`
754
- },
755
- // Bank Routing Numbers (US specific)
756
- {
757
- name: "bbva_routing_ca",
758
- pattern: String.raw`\\b321170538\\b`
759
- },
760
- {
761
- name: "boa_routing_ca",
762
- pattern: String.raw`\\b(?:121|026)00(?:0|9)(?:358|593)\\b`
763
- },
764
- {
765
- name: "chase_routing_ca",
766
- pattern: String.raw`\\b322271627\\b`
767
- },
768
- {
769
- name: "citibank_routing_ca",
770
- pattern: String.raw`\\b32(?:11|22)71(?:18|72)4\\b`
771
- },
772
- {
773
- name: "usbank_routing_ca",
774
- pattern: String.raw`\\b12(?:1122676|2235821)\\b`
775
- },
776
- {
777
- name: "united_bank_routing_ca",
778
- pattern: String.raw`\\b122243350\\b`
779
- },
780
- {
781
- name: "wells_fargo_routing_ca",
782
- pattern: String.raw`\\b121042882\\b`
783
- },
784
- // Unrealistic alphanumeric identifiers
785
- {
786
- name: "generic_non_usual",
787
- pattern: String.raw`(?:^|\s)(?=[A-Za-z0-9_\)\*\=@]*[A-Za-z])(?=[A-Za-z0-9_\)\*\=@]*[0-9])([A-Za-z0-9_\)\*\=@]{5,})(?=\s|$)`
788
1366
  }
789
1367
  ];
790
1368
 
@@ -1004,13 +1582,6 @@ function maskAttributes(attributes, rules, outputOriginalValue = false) {
1004
1582
  return maskedAttributes;
1005
1583
  }
1006
1584
 
1007
- // src/internal/semantic-conventions.ts
1008
- var import_api2 = require("@opentelemetry/api");
1009
- var BRIZZ = "brizz";
1010
- var PROPERTIES = "properties";
1011
- var PROPERTIES_CONTEXT_KEY = (0, import_api2.createContextKey)(PROPERTIES);
1012
- var SESSION_OBJECT_CONTEXT_KEY = (0, import_api2.createContextKey)("brizz.session.object");
1013
-
1014
1585
  // src/internal/log/processors/log-processor.ts
1015
1586
  var DEFAULT_LOG_MASKING_RULES = [
1016
1587
  {
@@ -1030,7 +1601,7 @@ var BrizzSimpleLogRecordProcessor = class extends import_sdk_logs.SimpleLogRecor
1030
1601
  if (maskingConfig) {
1031
1602
  maskLog(logRecord, maskingConfig);
1032
1603
  }
1033
- const associationProperties = import_api3.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1604
+ const associationProperties = import_api8.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1034
1605
  if (associationProperties) {
1035
1606
  for (const [key, value] of Object.entries(associationProperties)) {
1036
1607
  logRecord.setAttribute(`${BRIZZ}.${key}`, value);
@@ -1050,7 +1621,7 @@ var BrizzBatchLogRecordProcessor = class extends import_sdk_logs.BatchLogRecordP
1050
1621
  if (maskingConfig) {
1051
1622
  maskLog(logRecord, maskingConfig);
1052
1623
  }
1053
- const associationProperties = import_api3.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1624
+ const associationProperties = import_api8.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1054
1625
  if (associationProperties) {
1055
1626
  for (const [key, value] of Object.entries(associationProperties)) {
1056
1627
  logRecord.setAttribute(`${BRIZZ}.${key}`, value);
@@ -1437,10 +2008,10 @@ var BrizzSpanExporter = class {
1437
2008
  };
1438
2009
 
1439
2010
  // src/internal/trace/processors/span-processor.ts
1440
- var import_api4 = require("@opentelemetry/api");
2011
+ var import_api9 = require("@opentelemetry/api");
1441
2012
  var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
1442
2013
  function applyContextAttributes(span) {
1443
- const sessionProperties = import_api4.context.active().getValue(PROPERTIES_CONTEXT_KEY);
2014
+ const sessionProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1444
2015
  if (sessionProperties) {
1445
2016
  for (const [key, value] of Object.entries(sessionProperties)) {
1446
2017
  span.setAttribute(`${BRIZZ}.${key}`, value);
@@ -1450,12 +2021,6 @@ function applyContextAttributes(span) {
1450
2021
  var DEFAULT_MASKING_RULES = [
1451
2022
  {
1452
2023
  mode: "partial",
1453
- attributePattern: "gen_ai.prompt",
1454
- patterns: DEFAULT_PII_PATTERNS
1455
- },
1456
- {
1457
- mode: "partial",
1458
- attributePattern: "gen_ai.completion",
1459
2024
  patterns: DEFAULT_PII_PATTERNS
1460
2025
  }
1461
2026
  ];
@@ -1465,24 +2030,16 @@ var BrizzSimpleSpanProcessor = class extends import_sdk_trace_base.SimpleSpanPro
1465
2030
  super(spanExporter);
1466
2031
  this.config = config;
1467
2032
  }
1468
- // Will work with the following code:
1469
- // const span = tracer.startSpan('sensitive-operation',{attributes:{
1470
- // 'user.password': 'secret123',
1471
- // 'user.email': 'user@example.com',
1472
- // }});
1473
- //
1474
- // Won't work because onStart is called before attributes are set:
1475
- // span.setAttributes({
1476
- // 'user.password': 'secret123',
1477
- // 'user.email': 'user@example.com'
1478
- // });
1479
2033
  onStart(span, parentContext) {
2034
+ applyContextAttributes(span);
2035
+ super.onStart(span, parentContext);
2036
+ }
2037
+ onEnd(span) {
1480
2038
  const maskingConfig = this.config.masking?.spanMasking;
1481
2039
  if (maskingConfig) {
1482
- maskSpan(span, maskingConfig);
2040
+ maskReadableSpan(span, maskingConfig);
1483
2041
  }
1484
- applyContextAttributes(span);
1485
- super.onStart(span, parentContext);
2042
+ super.onEnd(span);
1486
2043
  }
1487
2044
  };
1488
2045
  var BrizzBatchSpanProcessor = class extends import_sdk_trace_base.BatchSpanProcessor {
@@ -1492,39 +2049,39 @@ var BrizzBatchSpanProcessor = class extends import_sdk_trace_base.BatchSpanProce
1492
2049
  this.config = config;
1493
2050
  }
1494
2051
  onStart(span, parentContext) {
2052
+ applyContextAttributes(span);
2053
+ super.onStart(span, parentContext);
2054
+ }
2055
+ onEnd(span) {
1495
2056
  const maskingConfig = this.config.masking?.spanMasking;
1496
2057
  if (maskingConfig) {
1497
- maskSpan(span, maskingConfig);
2058
+ maskReadableSpan(span, maskingConfig);
1498
2059
  }
1499
- applyContextAttributes(span);
1500
- super.onStart(span, parentContext);
2060
+ super.onEnd(span);
1501
2061
  }
1502
2062
  };
1503
- function maskSpan(span, config) {
1504
- if (!span.attributes || Object.keys(span.attributes).length === 0) {
1505
- return span;
2063
+ function maskReadableSpan(span, config) {
2064
+ const attrs = span.attributes;
2065
+ if (!attrs || Object.keys(attrs).length === 0) {
2066
+ return;
1506
2067
  }
1507
- let rules = config.rules || [];
2068
+ let rules = config.rules ? [...config.rules] : [];
1508
2069
  if (!config.disableDefaultRules) {
1509
- rules = [...DEFAULT_MASKING_RULES, ...rules];
2070
+ rules = [...rules, ...DEFAULT_MASKING_RULES];
1510
2071
  }
1511
2072
  try {
1512
- const attributesRecord = {};
1513
- for (const [key, value] of Object.entries(span.attributes)) {
1514
- attributesRecord[key] = value;
1515
- }
1516
- const maskedAttributes = maskAttributes(attributesRecord, rules);
1517
- if (maskedAttributes && Object.keys(maskedAttributes).length > 0) {
1518
- const merged = { ...span.attributes };
1519
- for (const [key, value] of Object.entries(maskedAttributes)) {
1520
- 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;
1521
2081
  }
1522
- span.setAttributes(merged);
1523
2082
  }
1524
- return span;
1525
2083
  } catch (error) {
1526
- logger.error("Error masking span:", error);
1527
- return span;
2084
+ logger.error("Error masking span", { err: error });
1528
2085
  }
1529
2086
  }
1530
2087
 
@@ -1637,7 +2194,7 @@ function getSpanProcessor() {
1637
2194
  }
1638
2195
 
1639
2196
  // src/internal/trace/session.ts
1640
- var import_api5 = require("@opentelemetry/api");
2197
+ var import_api10 = require("@opentelemetry/api");
1641
2198
 
1642
2199
  // src/internal/sdk.ts
1643
2200
  var _Brizz = class __Brizz {
@@ -1970,15 +2527,18 @@ if (runtime.isESM && runtime.supportsLoaderAPI) {
1970
2527
  maybeRegisterESMLoader();
1971
2528
  }
1972
2529
  try {
1973
- Brizz.initialize({
1974
- apiKey: process.env["BRIZZ_API_KEY"],
1975
- baseUrl: process.env["BRIZZ_BASE_URL"],
1976
- appName: process.env["BRIZZ_APP_NAME"] || process.env["OTEL_SERVICE_NAME"],
1977
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1978
- logLevel: process.env["BRIZZ_LOG_LEVEL"] || DEFAULT_LOG_LEVEL.toString(),
1979
- // Enable auto-instrumentation by default in preload mode
1980
- disableNodeSdk: false
1981
- });
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
+ }
1982
2542
  logger.info(`SDK auto-initialized for ${runtime.isESM ? "ESM" : "CJS"} runtime`);
1983
2543
  } catch (error) {
1984
2544
  logger.warn("Failed to auto-initialize SDK:", { error });