@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/index.js CHANGED
@@ -186,43 +186,8 @@ var init_semantic_conventions = __esm({
186
186
  }
187
187
  });
188
188
 
189
- // src/internal/instrumentation/mcp/session.ts
190
- import { context } from "@opentelemetry/api";
191
- function stampAndPropagateSession(span, sessionId, baseContext = context.active()) {
192
- if (!sessionId) {
193
- return { context: baseContext, sessionId: null };
194
- }
195
- if (span.isRecording()) {
196
- try {
197
- span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
198
- } catch (error) {
199
- logger.warn(
200
- `Brizz MCP: failed to stamp session id on span: ${String(error)}`
201
- );
202
- }
203
- }
204
- try {
205
- const prev = baseContext.getValue(PROPERTIES_CONTEXT_KEY);
206
- const merged = prev ? { ...prev, [SESSION_ID]: sessionId } : { [SESSION_ID]: sessionId };
207
- return {
208
- context: baseContext.setValue(PROPERTIES_CONTEXT_KEY, merged),
209
- sessionId
210
- };
211
- } catch (error) {
212
- logger.warn(`Brizz MCP: failed to attach session context: ${String(error)}`);
213
- return { context: baseContext, sessionId };
214
- }
215
- }
216
- var init_session = __esm({
217
- "src/internal/instrumentation/mcp/session.ts"() {
218
- "use strict";
219
- init_logger();
220
- init_semantic_conventions();
221
- }
222
- });
223
-
224
189
  // src/internal/instrumentation/mcp/semantic-conventions.ts
225
- var MCP_TOOL_NAME, MCP_TOOL_ARGUMENTS, MCP_TOOL_RESULT, MCP_COMPONENT_TYPE, MCP_COMPONENT_TOOL, MCP_METHOD_NAME, MCP_REQUEST_ID, MCP_SESSION_ID, MCP_PROTOCOL_VERSION, MCP_RESOURCE_URI, RPC_SYSTEM, RPC_SYSTEM_MCP, RPC_RESPONSE_STATUS_CODE, GEN_AI_TOOL_NAME, GEN_AI_PROMPT_NAME, GEN_AI_OPERATION_NAME, GEN_AI_OPERATION_EXECUTE_TOOL, NETWORK_TRANSPORT, ERROR_TYPE, ERROR_TYPE_TOOL, JSONRPC_REQUEST_ID, SPAN_NAME_TOOLS_CALL, MAX_ATTRIBUTE_LENGTH, TRUNCATION_SUFFIX, METHOD_TOOLS_CALL, METHOD_RESOURCES_READ, METHOD_PROMPTS_GET, METHOD_INITIALIZE;
190
+ var MCP_TOOL_NAME, MCP_TOOL_ARGUMENTS, MCP_TOOL_RESULT, MCP_COMPONENT_TYPE, MCP_COMPONENT_TOOL, MCP_COMPONENT_TOOL_SCHEMA, MCP_TOOL_SCHEMA_PARAMETERS, MCP_TOOL_SCHEMA_OUTPUT, MCP_TOOL_DESCRIPTION, SPAN_NAME_TOOL_REGISTER, MCP_METHOD_NAME, MCP_REQUEST_ID, MCP_SESSION_ID, MCP_PROTOCOL_VERSION, MCP_RESOURCE_URI, RPC_SYSTEM, RPC_SYSTEM_MCP, RPC_RESPONSE_STATUS_CODE, GEN_AI_TOOL_NAME, GEN_AI_PROMPT_NAME, GEN_AI_OPERATION_NAME, GEN_AI_OPERATION_EXECUTE_TOOL, NETWORK_TRANSPORT, ERROR_TYPE, ERROR_TYPE_TOOL, JSONRPC_REQUEST_ID, SPAN_NAME_TOOLS_CALL, MAX_ATTRIBUTE_LENGTH, TRUNCATION_SUFFIX, METHOD_TOOLS_CALL, METHOD_TOOLS_LIST, METHOD_RESOURCES_READ, METHOD_PROMPTS_GET, METHOD_INITIALIZE;
226
191
  var init_semantic_conventions2 = __esm({
227
192
  "src/internal/instrumentation/mcp/semantic-conventions.ts"() {
228
193
  "use strict";
@@ -231,6 +196,11 @@ var init_semantic_conventions2 = __esm({
231
196
  MCP_TOOL_RESULT = "mcp.tool.result";
232
197
  MCP_COMPONENT_TYPE = "mcp.component.type";
233
198
  MCP_COMPONENT_TOOL = "tool";
199
+ MCP_COMPONENT_TOOL_SCHEMA = "tool_schema";
200
+ MCP_TOOL_SCHEMA_PARAMETERS = "mcp.tool.schema.parameters";
201
+ MCP_TOOL_SCHEMA_OUTPUT = "mcp.tool.schema.output";
202
+ MCP_TOOL_DESCRIPTION = "mcp.tool.description";
203
+ SPAN_NAME_TOOL_REGISTER = "mcp.tool.register";
234
204
  MCP_METHOD_NAME = "mcp.method.name";
235
205
  MCP_REQUEST_ID = "mcp.request.id";
236
206
  MCP_SESSION_ID = "mcp.session.id";
@@ -251,14 +221,134 @@ var init_semantic_conventions2 = __esm({
251
221
  MAX_ATTRIBUTE_LENGTH = 32 * 1024;
252
222
  TRUNCATION_SUFFIX = "\u2026(truncated)";
253
223
  METHOD_TOOLS_CALL = "tools/call";
224
+ METHOD_TOOLS_LIST = "tools/list";
254
225
  METHOD_RESOURCES_READ = "resources/read";
255
226
  METHOD_PROMPTS_GET = "prompts/get";
256
227
  METHOD_INITIALIZE = "initialize";
257
228
  }
258
229
  });
259
230
 
231
+ // src/internal/instrumentation/mcp/schemas.ts
232
+ import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
233
+ function truncateSchemaAttr(value) {
234
+ if (value.length <= _MAX_SCHEMA_ATTR_BYTES) {
235
+ return value;
236
+ }
237
+ return `{"_truncated":true,"original_length":${value.length}}`;
238
+ }
239
+ function safeStringify(value) {
240
+ if (value === null || value === void 0) {
241
+ return "";
242
+ }
243
+ try {
244
+ return JSON.stringify(value);
245
+ } catch {
246
+ return "";
247
+ }
248
+ }
249
+ function emitSchemaSpansFromListResponse(result, transportSessionId, tracer) {
250
+ if (!transportSessionId) {
251
+ return;
252
+ }
253
+ const tools = extractTools(result);
254
+ if (tools === void 0) {
255
+ return;
256
+ }
257
+ for (const tool of tools) {
258
+ const name = typeof tool.name === "string" ? tool.name : void 0;
259
+ if (!name) {
260
+ continue;
261
+ }
262
+ const span = tracer.startSpan(`${SPAN_NAME_TOOL_REGISTER} ${name}`, {
263
+ kind: SpanKind.INTERNAL
264
+ });
265
+ try {
266
+ stampSchemaAttributes(span, name, transportSessionId, tool);
267
+ span.setStatus({ code: SpanStatusCode.OK });
268
+ } finally {
269
+ span.end();
270
+ }
271
+ }
272
+ }
273
+ function stampSchemaAttributes(span, toolName, transportSessionId, tool) {
274
+ if (!span.isRecording()) {
275
+ logger.warn(
276
+ `Brizz MCP: schema span is not recording; dropping attributes for ${toolName}`
277
+ );
278
+ return;
279
+ }
280
+ const description = typeof tool.description === "string" ? tool.description : "";
281
+ const parameters = truncateSchemaAttr(safeStringify(tool.inputSchema));
282
+ const outputSchema = tool.outputSchema !== void 0 && tool.outputSchema !== null ? truncateSchemaAttr(safeStringify(tool.outputSchema)) : "";
283
+ span.setAttribute(RPC_SYSTEM, RPC_SYSTEM_MCP);
284
+ span.setAttribute(MCP_COMPONENT_TYPE, MCP_COMPONENT_TOOL_SCHEMA);
285
+ span.setAttribute(MCP_SESSION_ID, transportSessionId);
286
+ span.setAttribute(`${BRIZZ}.${SESSION_ID}`, transportSessionId);
287
+ span.setAttribute(MCP_TOOL_NAME, toolName);
288
+ span.setAttribute(MCP_TOOL_SCHEMA_PARAMETERS, parameters);
289
+ span.setAttribute(MCP_TOOL_SCHEMA_OUTPUT, outputSchema);
290
+ span.setAttribute(MCP_TOOL_DESCRIPTION, description);
291
+ }
292
+ function extractTools(result) {
293
+ if (!result || typeof result !== "object") {
294
+ return void 0;
295
+ }
296
+ const tools = result.tools;
297
+ if (!Array.isArray(tools)) {
298
+ return void 0;
299
+ }
300
+ return tools.filter(
301
+ (t) => t !== null && typeof t === "object"
302
+ );
303
+ }
304
+ var _MAX_SCHEMA_ATTR_BYTES;
305
+ var init_schemas = __esm({
306
+ "src/internal/instrumentation/mcp/schemas.ts"() {
307
+ "use strict";
308
+ init_logger();
309
+ init_semantic_conventions();
310
+ init_semantic_conventions2();
311
+ _MAX_SCHEMA_ATTR_BYTES = 4e3;
312
+ }
313
+ });
314
+
315
+ // src/internal/instrumentation/mcp/session.ts
316
+ import { context } from "@opentelemetry/api";
317
+ function stampAndPropagateSession(span, sessionId, baseContext = context.active()) {
318
+ if (!sessionId) {
319
+ return { context: baseContext, sessionId: null };
320
+ }
321
+ if (span.isRecording()) {
322
+ try {
323
+ span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
324
+ } catch (error) {
325
+ logger.warn(
326
+ `Brizz MCP: failed to stamp session id on span: ${String(error)}`
327
+ );
328
+ }
329
+ }
330
+ try {
331
+ const prev = baseContext.getValue(PROPERTIES_CONTEXT_KEY);
332
+ const merged = prev ? { ...prev, [SESSION_ID]: sessionId } : { [SESSION_ID]: sessionId };
333
+ return {
334
+ context: baseContext.setValue(PROPERTIES_CONTEXT_KEY, merged),
335
+ sessionId
336
+ };
337
+ } catch (error) {
338
+ logger.warn(`Brizz MCP: failed to attach session context: ${String(error)}`);
339
+ return { context: baseContext, sessionId };
340
+ }
341
+ }
342
+ var init_session = __esm({
343
+ "src/internal/instrumentation/mcp/session.ts"() {
344
+ "use strict";
345
+ init_logger();
346
+ init_semantic_conventions();
347
+ }
348
+ });
349
+
260
350
  // src/internal/instrumentation/mcp/patches/attributes.ts
261
- import { SpanStatusCode } from "@opentelemetry/api";
351
+ import { SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
262
352
  function deriveSpanName(method, params) {
263
353
  try {
264
354
  if (method === METHOD_TOOLS_CALL) {
@@ -361,7 +451,7 @@ function applyResultAttributes(span, method, result) {
361
451
  if (obj && obj["isError"] === true) {
362
452
  span.setAttribute(ERROR_TYPE, ERROR_TYPE_TOOL);
363
453
  const message = extractToolErrorMessage(obj);
364
- span.setStatus({ code: SpanStatusCode.ERROR, message });
454
+ span.setStatus({ code: SpanStatusCode2.ERROR, message });
365
455
  }
366
456
  }
367
457
  function applyErrorAttributes(span, err) {
@@ -385,7 +475,7 @@ function applyErrorAttributes(span, err) {
385
475
  } catch {
386
476
  }
387
477
  span.setStatus({
388
- code: SpanStatusCode.ERROR,
478
+ code: SpanStatusCode2.ERROR,
389
479
  message: typeof error?.message === "string" ? error.message : void 0
390
480
  });
391
481
  }
@@ -455,7 +545,7 @@ var init_attributes = __esm({
455
545
  });
456
546
 
457
547
  // src/internal/instrumentation/mcp/patches/protocol.ts
458
- import { context as context2, propagation, SpanKind, trace } from "@opentelemetry/api";
548
+ import { context as context2, propagation, SpanKind as SpanKind2, trace } from "@opentelemetry/api";
459
549
  function patchProtocolPrototype(prototype, tracer) {
460
550
  if (!prototype || typeof prototype !== "object") {
461
551
  return false;
@@ -523,7 +613,20 @@ function wrapOnRequest(original, tracer) {
523
613
  return original.apply(this, args);
524
614
  }
525
615
  const { span, spanCtx } = started;
526
- const wrappedHandler = (req, extra) => context2.with(spanCtx, () => executeHandler(span, method, handler, req, extra));
616
+ const transportSessionId = this.sessionId ?? this._transport?.sessionId;
617
+ const postResult = method === METHOD_TOOLS_LIST ? (result) => {
618
+ try {
619
+ emitSchemaSpansFromListResponse(result, transportSessionId, tracer);
620
+ } catch (error) {
621
+ logger.warn(
622
+ `Brizz MCP: failed to emit tools/list schema spans: ${String(error)}`
623
+ );
624
+ }
625
+ } : void 0;
626
+ const wrappedHandler = (req, extra) => context2.with(
627
+ spanCtx,
628
+ () => executeHandler(span, method, handler, req, extra, postResult)
629
+ );
527
630
  const hadEntry = handlers.has(method);
528
631
  const prev = handlers.get(method);
529
632
  handlers.set(method, wrappedHandler);
@@ -546,7 +649,7 @@ function wrapOnRequest(original, tracer) {
546
649
  }
547
650
  };
548
651
  }
549
- function executeAroundSpan(span, method, run) {
652
+ function executeAroundSpan(span, method, run, postResult) {
550
653
  let result;
551
654
  try {
552
655
  result = run();
@@ -557,12 +660,18 @@ function executeAroundSpan(span, method, run) {
557
660
  }
558
661
  if (!isThenable(result)) {
559
662
  safeApplyResultAttributes(span, method, result);
663
+ if (postResult) {
664
+ postResult(result);
665
+ }
560
666
  safeEnd(span);
561
667
  return result;
562
668
  }
563
669
  return result.then(
564
670
  (value) => {
565
671
  safeApplyResultAttributes(span, method, value);
672
+ if (postResult) {
673
+ postResult(value);
674
+ }
566
675
  safeEnd(span);
567
676
  return value;
568
677
  },
@@ -573,13 +682,13 @@ function executeAroundSpan(span, method, run) {
573
682
  }
574
683
  );
575
684
  }
576
- function executeHandler(span, method, handler, req, extra) {
577
- return executeAroundSpan(span, method, () => handler(req, extra));
685
+ function executeHandler(span, method, handler, req, extra, postResult) {
686
+ return executeAroundSpan(span, method, () => handler(req, extra), postResult);
578
687
  }
579
688
  function safeStartClientSpan(tracer, request, protocol) {
580
689
  try {
581
690
  const spanName = deriveSpanName(request.method, request.params);
582
- const span = tracer.startSpan(spanName, { kind: SpanKind.CLIENT });
691
+ const span = tracer.startSpan(spanName, { kind: SpanKind2.CLIENT });
583
692
  applyClientRequestAttributes(
584
693
  span,
585
694
  request,
@@ -597,7 +706,7 @@ function safeStartServerSpan(tracer, request, protocol) {
597
706
  const spanName = deriveSpanName(request.method, request.params);
598
707
  const span = tracer.startSpan(
599
708
  spanName,
600
- { kind: SpanKind.SERVER },
709
+ { kind: SpanKind2.SERVER },
601
710
  parentCtx
602
711
  );
603
712
  applyServerRequestAttributes(span, request, protocol);
@@ -655,6 +764,8 @@ var init_protocol = __esm({
655
764
  "src/internal/instrumentation/mcp/patches/protocol.ts"() {
656
765
  "use strict";
657
766
  init_logger();
767
+ init_schemas();
768
+ init_semantic_conventions2();
658
769
  init_session();
659
770
  init_attributes();
660
771
  PATCHED_FLAG = /* @__PURE__ */ Symbol("brizz.mcp.protocol-patched");
@@ -663,7 +774,7 @@ var init_protocol = __esm({
663
774
 
664
775
  // src/internal/version.ts
665
776
  function getSDKVersion() {
666
- return "0.1.22";
777
+ return "0.1.25";
667
778
  }
668
779
  var init_version = __esm({
669
780
  "src/internal/version.ts"() {
@@ -948,6 +1059,38 @@ autoInitializeInstrumentations();
948
1059
  import { resourceFromAttributes as resourceFromAttributes3 } from "@opentelemetry/resources";
949
1060
  import { NodeSDK } from "@opentelemetry/sdk-node";
950
1061
 
1062
+ // src/internal/dsn.ts
1063
+ var PLACEHOLDER_SERVICE = "<service-name>";
1064
+ var SERVICE_NAME_HEADER = "X-Brizz-Service-Name";
1065
+ function parseDSN(dsn) {
1066
+ let parsed;
1067
+ try {
1068
+ parsed = new globalThis.URL(dsn);
1069
+ } catch {
1070
+ return null;
1071
+ }
1072
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || !parsed.username || !parsed.host) {
1073
+ return null;
1074
+ }
1075
+ const scheme = parsed.protocol === "https:" ? "https" : "http";
1076
+ let service;
1077
+ try {
1078
+ service = decodeURIComponent(parsed.pathname.replace(/^\//, ""));
1079
+ } catch {
1080
+ return null;
1081
+ }
1082
+ if (service === "" || service === PLACEHOLDER_SERVICE) {
1083
+ return null;
1084
+ }
1085
+ return {
1086
+ scheme,
1087
+ host: parsed.host,
1088
+ bearer: decodeURIComponent(parsed.username),
1089
+ service,
1090
+ baseUrl: `${scheme}://${parsed.host}`
1091
+ };
1092
+ }
1093
+
951
1094
  // src/internal/config.ts
952
1095
  init_logger();
953
1096
  function resolveConfig(options) {
@@ -975,6 +1118,7 @@ function resolveConfig(options) {
975
1118
  appName: options.appName,
976
1119
  baseUrl: options.baseUrl,
977
1120
  hasApiKey: !!options.apiKey,
1121
+ dsnProvided: !!(process.env["BRIZZ_DSN"] || options.dsn),
978
1122
  disableBatch: options.disableBatch,
979
1123
  logLevel: resolvedLogLevel,
980
1124
  headersCount: Object.keys(options.headers || {}).length,
@@ -1002,7 +1146,42 @@ function resolveConfig(options) {
1002
1146
  logLevel: resolvedLogLevel,
1003
1147
  masking: resolvedMasking
1004
1148
  };
1005
- if (resolvedConfig.apiKey) {
1149
+ const dsnInput = process.env["BRIZZ_DSN"] || options.dsn;
1150
+ let parsedDSN = null;
1151
+ if (dsnInput) {
1152
+ const kwargConflicts = [];
1153
+ if (options.apiKey !== void 0) {
1154
+ kwargConflicts.push("apiKey");
1155
+ }
1156
+ if (options.baseUrl !== void 0) {
1157
+ kwargConflicts.push("baseUrl");
1158
+ }
1159
+ if (options.appName !== void 0) {
1160
+ kwargConflicts.push("appName");
1161
+ }
1162
+ if (kwargConflicts.length > 0) {
1163
+ throw new Error(
1164
+ `dsn cannot be combined with kwargs ${kwargConflicts.join(", ")}. The DSN bundles bearer, gateway URL, and service name \u2014 choose one configuration style.`
1165
+ );
1166
+ }
1167
+ const envConflicts = ["BRIZZ_API_KEY", "BRIZZ_BASE_URL", "BRIZZ_APP_NAME"].filter(
1168
+ (name) => process.env[name] !== void 0
1169
+ );
1170
+ if (envConflicts.length > 0) {
1171
+ logger.warn(
1172
+ `Ignoring ${envConflicts.join(", ")} \u2014 dsn / BRIZZ_DSN takes precedence.`
1173
+ );
1174
+ }
1175
+ resolvedConfig.apiKey = void 0;
1176
+ resolvedConfig.baseUrl = "https://telemetry.brizz.dev";
1177
+ resolvedConfig.appName = "unknown-app";
1178
+ parsedDSN = parseDSN(dsnInput);
1179
+ if (parsedDSN) {
1180
+ resolvedConfig.appName = parsedDSN.service;
1181
+ resolvedConfig.baseUrl = parsedDSN.baseUrl;
1182
+ resolvedConfig.apiKey = parsedDSN.bearer;
1183
+ }
1184
+ } else if (resolvedConfig.apiKey) {
1006
1185
  resolvedConfig.headers["Authorization"] = `Bearer ${resolvedConfig.apiKey}`;
1007
1186
  }
1008
1187
  if (process.env["BRIZZ_HEADERS"]) {
@@ -1017,14 +1196,28 @@ function resolveConfig(options) {
1017
1196
  throw new Error("Invalid JSON in BRIZZ_HEADERS environment variable", { cause: error });
1018
1197
  }
1019
1198
  }
1199
+ if (dsnInput) {
1200
+ const authHeaderKeys = /* @__PURE__ */ new Set(["authorization", SERVICE_NAME_HEADER.toLowerCase()]);
1201
+ resolvedConfig.headers = Object.fromEntries(
1202
+ Object.entries(resolvedConfig.headers).filter(
1203
+ ([key]) => !authHeaderKeys.has(key.toLowerCase())
1204
+ )
1205
+ );
1206
+ if (parsedDSN) {
1207
+ resolvedConfig.headers["Authorization"] = `Bearer ${parsedDSN.bearer}`;
1208
+ resolvedConfig.headers[SERVICE_NAME_HEADER] = parsedDSN.service;
1209
+ }
1210
+ }
1020
1211
  logger.debug("Configuration resolved with environment variables", {
1021
1212
  appName: resolvedConfig.appName,
1022
1213
  baseUrl: resolvedConfig.baseUrl,
1023
1214
  hasApiKey: !!resolvedConfig.apiKey,
1215
+ dsnProvided: !!dsnInput,
1024
1216
  disableBatch: resolvedConfig.disableBatch,
1025
1217
  envOverrides: {
1026
1218
  hasEnvApiKey: !!process.env["BRIZZ_API_KEY"],
1027
1219
  hasEnvBaseUrl: !!process.env["BRIZZ_BASE_URL"],
1220
+ hasEnvDsn: !!process.env["BRIZZ_DSN"],
1028
1221
  hasEnvBatch: !!process.env["BRIZZ_DISABLE_BATCH"],
1029
1222
  hasEnvHeaders: !!process.env["BRIZZ_HEADERS"]
1030
1223
  }
@@ -1182,21 +1375,11 @@ import { BatchLogRecordProcessor, SimpleLogRecordProcessor } from "@opentelemetr
1182
1375
 
1183
1376
  // src/internal/masking/patterns.ts
1184
1377
  var DEFAULT_PII_PATTERNS = [
1185
- // Email addresses
1186
- {
1187
- name: "email_addresses",
1188
- pattern: String.raw`\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`
1189
- },
1190
1378
  // Phone numbers (US format)
1191
1379
  {
1192
1380
  name: "us_phone_numbers",
1193
1381
  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]|$)`
1194
1382
  },
1195
- // Social Security Numbers
1196
- {
1197
- name: "ssn",
1198
- pattern: String.raw`\b(?!000|666|9\d{2})\d{3}[-\s]?(?!00)\d{2}[-\s]?(?!0000)\d{4}\b`
1199
- },
1200
1383
  // Credit card numbers
1201
1384
  {
1202
1385
  name: "credit_cards",
@@ -1220,19 +1403,11 @@ var DEFAULT_PII_PATTERNS = [
1220
1403
  name: "openai_keys",
1221
1404
  pattern: String.raw`\bsk[-_][a-zA-Z0-9]{20,}\b`
1222
1405
  },
1223
- {
1224
- name: "base64_secrets",
1225
- pattern: String.raw`\b[A-Za-z0-9+/]{64,}={0,2}\b`
1226
- },
1227
1406
  // AWS Keys
1228
1407
  {
1229
1408
  name: "aws_access_keys",
1230
1409
  pattern: String.raw`\b(?:AKIA|ABIA|ACCA|ASIA)[0-9A-Z]{16}\b`
1231
1410
  },
1232
- {
1233
- name: "aws_secret_keys",
1234
- 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`
1235
- },
1236
1411
  // GitHub tokens
1237
1412
  {
1238
1413
  name: "github_tokens",
@@ -1263,11 +1438,6 @@ var DEFAULT_PII_PATTERNS = [
1263
1438
  name: "ipv6_addresses",
1264
1439
  pattern: String.raw`\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b`
1265
1440
  },
1266
- // Medical records
1267
- {
1268
- name: "medical_record_numbers",
1269
- pattern: String.raw`\b(?:[Mm][Rr][Nn])[-\s]?\d{6,10}\b`
1270
- },
1271
1441
  // Bitcoin addresses
1272
1442
  {
1273
1443
  name: "bitcoin_addresses",
@@ -1278,11 +1448,6 @@ var DEFAULT_PII_PATTERNS = [
1278
1448
  name: "ethereum_addresses",
1279
1449
  pattern: String.raw`\b0x[a-fA-F0-9]{40}(?![a-fA-F0-9])\b`
1280
1450
  },
1281
- // UUIDs
1282
- {
1283
- name: "uuids",
1284
- 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`
1285
- },
1286
1451
  // Database connection strings
1287
1452
  {
1288
1453
  name: "database_connections",
@@ -1301,90 +1466,6 @@ var DEFAULT_PII_PATTERNS = [
1301
1466
  name: "certificates",
1302
1467
  pattern: "-----BEGIN CERTIFICATE-----"
1303
1468
  },
1304
- // Date of birth patterns
1305
- {
1306
- name: "date_of_birth_us",
1307
- pattern: String.raw`\b(?:0[1-9]|1[0-2])[-/](?:0[1-9]|[12]\\d|3[01])[-/](?:19|20)\\d{2}\b`
1308
- },
1309
- {
1310
- name: "date_of_birth_iso",
1311
- pattern: String.raw`\b(?:19|20)\\d{2}[-/](?:0[1-9]|1[0-2])[-/](?:0[1-9]|[12]\\d|3[01])\b`
1312
- },
1313
- // US Identification Numbers
1314
- {
1315
- name: "us_passport_numbers",
1316
- pattern: String.raw`\b[A-Z]?\\d{6,9}\b`
1317
- },
1318
- {
1319
- name: "drivers_license",
1320
- 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`
1321
- },
1322
- {
1323
- name: "bank_account_numbers",
1324
- pattern: String.raw`\b\\d{10,17}\b`
1325
- },
1326
- {
1327
- name: "aba_routing_numbers",
1328
- 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`
1329
- },
1330
- {
1331
- name: "health_insurance_numbers",
1332
- pattern: String.raw`\b\\d{10}[A-Z]\b`
1333
- },
1334
- {
1335
- name: "employee_ids",
1336
- pattern: String.raw`\b(?:[Ee][Mm][Pp]|[Ee][Mm][Pp][Ll][Oo][Yy][Ee][Ee]|[Ee])[-\s]?\\d{5,8}\b`
1337
- },
1338
- {
1339
- name: "tax_ein",
1340
- pattern: String.raw`\b\\d{2}-\\d{7}\b`
1341
- },
1342
- {
1343
- name: "medicare_beneficiary_id",
1344
- 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`
1345
- },
1346
- {
1347
- name: "national_provider_id",
1348
- pattern: String.raw`\b1\\d{9}\b`
1349
- },
1350
- {
1351
- name: "dea_numbers",
1352
- pattern: String.raw`\b[A-Z]{2}\\d{7}\b`
1353
- },
1354
- {
1355
- name: "itin",
1356
- pattern: String.raw`\b9\\d{2}(?:[ \\-]?)[7,8]\\d(?:[ \\-]?)\\d{4}\b`
1357
- },
1358
- // Vehicle and Location
1359
- {
1360
- name: "vin_numbers",
1361
- pattern: String.raw`\b[A-HJ-NPR-Z0-9]{17}\b`
1362
- },
1363
- {
1364
- name: "coordinates",
1365
- pattern: String.raw`\b[-+]?(?:[0-8]?\\d(?:\\.\\d+)?|90(?:\\.0+)?),\\s*[-+]?(?:1[0-7]\\d(?:\\.\\d+)?|180(?:\\.0+)?|[0-9]?\\d(?:\\.\\d+)?)\b`
1366
- },
1367
- {
1368
- name: "us_license_plates",
1369
- 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`
1370
- },
1371
- {
1372
- name: "us_zip_codes",
1373
- pattern: String.raw`\b(\\d{5}-\\d{4}|\\d{5})\b`
1374
- },
1375
- {
1376
- name: "us_street_addresses",
1377
- 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`
1378
- },
1379
- // International Banking
1380
- {
1381
- name: "iban",
1382
- pattern: String.raw`\b[A-Z]{2}\d{2}[A-Z0-9]{4}\d{7}([A-Z0-9]?){0,16}\b`
1383
- },
1384
- {
1385
- name: "swift_bic",
1386
- pattern: String.raw`\b[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?\b`
1387
- },
1388
1469
  // Additional API Keys and Tokens
1389
1470
  {
1390
1471
  name: "google_oauth",
@@ -1447,73 +1528,6 @@ var DEFAULT_PII_PATTERNS = [
1447
1528
  name: "putty_ssh_keys",
1448
1529
  pattern: String.raw`PuTTY-User-Key-File-2: ssh-(?:rsa|dss)\s*Encryption: none(?:.|\s?)*?Private-MAC:`
1449
1530
  },
1450
- // International Phone Numbers
1451
- {
1452
- name: "france_phone_numbers",
1453
- pattern: String.raw`\b([0O]?[1lI][1lI])?[3E][3E][0O]?[\\dOIlZEASB]{9}\b`
1454
- },
1455
- {
1456
- name: "german_phone_numbers",
1457
- pattern: String.raw`\b[\d\w]\d{2}[\d\w]{6}\d[\d\w]\b`
1458
- },
1459
- {
1460
- name: "uk_phone_numbers",
1461
- pattern: String.raw`\b([0O]?[1lI][1lI])?[4A][4A][\\dOIlZEASB]{10,11}\b`
1462
- },
1463
- // International IDs
1464
- {
1465
- name: "uk_drivers_license",
1466
- pattern: String.raw`\b[A-Z]{5}\d{6}[A-Z]{2}\d{1}[A-Z]{2}\b`
1467
- },
1468
- {
1469
- name: "uk_passport",
1470
- pattern: String.raw`\b\\d{10}GB[RP]\\d{7}[UMF]{1}\\d{9}\b`
1471
- },
1472
- {
1473
- name: "argentina_dni",
1474
- pattern: String.raw`\b\\d{2}\\.\\d{3}\\.\\d{3}\b`
1475
- },
1476
- {
1477
- name: "australia_tfn",
1478
- pattern: String.raw`\b[Tt][Ff][Nn](:|:\\s|\\s|)(\\d{8,9})\b`
1479
- },
1480
- {
1481
- name: "canada_passport",
1482
- pattern: String.raw`\b[\\w]{2}[\\d]{6}\b`
1483
- },
1484
- {
1485
- name: "croatia_vat",
1486
- pattern: String.raw`\bHR\\d{11}\b`
1487
- },
1488
- {
1489
- name: "czech_vat",
1490
- pattern: String.raw`\bCZ\\d{8,10}\b`
1491
- },
1492
- {
1493
- name: "denmark_personal_id",
1494
- pattern: String.raw`\b(?:\\d{10}|\\d{6}[-\\s]\\d{4})\b`
1495
- },
1496
- {
1497
- name: "france_national_id",
1498
- pattern: String.raw`\b\\d{12}\b`
1499
- },
1500
- {
1501
- name: "france_ssn",
1502
- pattern: String.raw`\b(?:\\d{13}|\\d{13}\\s\\d{2})\b`
1503
- },
1504
- {
1505
- name: "france_passport",
1506
- pattern: String.raw`\b\\d{2}11\\d{5}\b`
1507
- },
1508
- {
1509
- name: "california_drivers_license",
1510
- pattern: String.raw`\b[A-Z]{1}\\d{7}\b`
1511
- },
1512
- // Medical and Healthcare
1513
- {
1514
- name: "hipaa_ndc",
1515
- pattern: String.raw`\b\\d{4,5}-\\d{3,4}-\\d{1,2}\b`
1516
- },
1517
1531
  // Security and Network
1518
1532
  {
1519
1533
  name: "cve_numbers",
@@ -1547,44 +1561,6 @@ var DEFAULT_PII_PATTERNS = [
1547
1561
  {
1548
1562
  name: "discover_cards",
1549
1563
  pattern: String.raw`\b65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}\b`
1550
- },
1551
- {
1552
- name: "enhanced_credit_cards",
1553
- 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`
1554
- },
1555
- // Bank Routing Numbers (US specific)
1556
- {
1557
- name: "bbva_routing_ca",
1558
- pattern: String.raw`\\b321170538\\b`
1559
- },
1560
- {
1561
- name: "boa_routing_ca",
1562
- pattern: String.raw`\\b(?:121|026)00(?:0|9)(?:358|593)\\b`
1563
- },
1564
- {
1565
- name: "chase_routing_ca",
1566
- pattern: String.raw`\\b322271627\\b`
1567
- },
1568
- {
1569
- name: "citibank_routing_ca",
1570
- pattern: String.raw`\\b32(?:11|22)71(?:18|72)4\\b`
1571
- },
1572
- {
1573
- name: "usbank_routing_ca",
1574
- pattern: String.raw`\\b12(?:1122676|2235821)\\b`
1575
- },
1576
- {
1577
- name: "united_bank_routing_ca",
1578
- pattern: String.raw`\\b122243350\\b`
1579
- },
1580
- {
1581
- name: "wells_fargo_routing_ca",
1582
- pattern: String.raw`\\b121042882\\b`
1583
- },
1584
- // Unrealistic alphanumeric identifiers
1585
- {
1586
- name: "generic_non_usual",
1587
- pattern: String.raw`(?:^|\s)(?=[A-Za-z0-9_\)\*\=@]*[A-Za-z])(?=[A-Za-z0-9_\)\*\=@]*[0-9])([A-Za-z0-9_\)\*\=@]{5,})(?=\s|$)`
1588
1564
  }
1589
1565
  ];
1590
1566
 
@@ -2263,12 +2239,6 @@ function applyContextAttributes(span) {
2263
2239
  var DEFAULT_MASKING_RULES = [
2264
2240
  {
2265
2241
  mode: "partial",
2266
- attributePattern: "gen_ai.prompt",
2267
- patterns: DEFAULT_PII_PATTERNS
2268
- },
2269
- {
2270
- mode: "partial",
2271
- attributePattern: "gen_ai.completion",
2272
2242
  patterns: DEFAULT_PII_PATTERNS
2273
2243
  }
2274
2244
  ];
@@ -2278,24 +2248,16 @@ var BrizzSimpleSpanProcessor = class extends SimpleSpanProcessor {
2278
2248
  super(spanExporter);
2279
2249
  this.config = config;
2280
2250
  }
2281
- // Will work with the following code:
2282
- // const span = tracer.startSpan('sensitive-operation',{attributes:{
2283
- // 'user.password': 'secret123',
2284
- // 'user.email': 'user@example.com',
2285
- // }});
2286
- //
2287
- // Won't work because onStart is called before attributes are set:
2288
- // span.setAttributes({
2289
- // 'user.password': 'secret123',
2290
- // 'user.email': 'user@example.com'
2291
- // });
2292
2251
  onStart(span, parentContext) {
2252
+ applyContextAttributes(span);
2253
+ super.onStart(span, parentContext);
2254
+ }
2255
+ onEnd(span) {
2293
2256
  const maskingConfig = this.config.masking?.spanMasking;
2294
2257
  if (maskingConfig) {
2295
- maskSpan(span, maskingConfig);
2258
+ maskReadableSpan(span, maskingConfig);
2296
2259
  }
2297
- applyContextAttributes(span);
2298
- super.onStart(span, parentContext);
2260
+ super.onEnd(span);
2299
2261
  }
2300
2262
  };
2301
2263
  var BrizzBatchSpanProcessor = class extends BatchSpanProcessor {
@@ -2305,39 +2267,39 @@ var BrizzBatchSpanProcessor = class extends BatchSpanProcessor {
2305
2267
  this.config = config;
2306
2268
  }
2307
2269
  onStart(span, parentContext) {
2270
+ applyContextAttributes(span);
2271
+ super.onStart(span, parentContext);
2272
+ }
2273
+ onEnd(span) {
2308
2274
  const maskingConfig = this.config.masking?.spanMasking;
2309
2275
  if (maskingConfig) {
2310
- maskSpan(span, maskingConfig);
2276
+ maskReadableSpan(span, maskingConfig);
2311
2277
  }
2312
- applyContextAttributes(span);
2313
- super.onStart(span, parentContext);
2278
+ super.onEnd(span);
2314
2279
  }
2315
2280
  };
2316
- function maskSpan(span, config) {
2317
- if (!span.attributes || Object.keys(span.attributes).length === 0) {
2318
- return span;
2281
+ function maskReadableSpan(span, config) {
2282
+ const attrs = span.attributes;
2283
+ if (!attrs || Object.keys(attrs).length === 0) {
2284
+ return;
2319
2285
  }
2320
- let rules = config.rules || [];
2286
+ let rules = config.rules ? [...config.rules] : [];
2321
2287
  if (!config.disableDefaultRules) {
2322
- rules = [...DEFAULT_MASKING_RULES, ...rules];
2288
+ rules = [...rules, ...DEFAULT_MASKING_RULES];
2323
2289
  }
2324
2290
  try {
2325
- const attributesRecord = {};
2326
- for (const [key, value] of Object.entries(span.attributes)) {
2327
- attributesRecord[key] = value;
2328
- }
2329
- const maskedAttributes = maskAttributes(attributesRecord, rules);
2330
- if (maskedAttributes && Object.keys(maskedAttributes).length > 0) {
2331
- const merged = { ...span.attributes };
2332
- for (const [key, value] of Object.entries(maskedAttributes)) {
2333
- merged[key] = value;
2291
+ const input = {};
2292
+ for (const [k, v] of Object.entries(attrs)) {
2293
+ input[k] = v;
2294
+ }
2295
+ const masked = maskAttributes(input, rules);
2296
+ for (const [k, v] of Object.entries(masked ?? {})) {
2297
+ if (attrs[k] !== v) {
2298
+ attrs[k] = v;
2334
2299
  }
2335
- span.setAttributes(merged);
2336
2300
  }
2337
- return span;
2338
2301
  } catch (error) {
2339
- logger.error("Error masking span:", error);
2340
- return span;
2302
+ logger.error("Error masking span", { err: error });
2341
2303
  }
2342
2304
  }
2343
2305
 
@@ -2454,7 +2416,7 @@ function getSpanProcessor() {
2454
2416
 
2455
2417
  // src/internal/trace/session.ts
2456
2418
  init_semantic_conventions();
2457
- import { context as context5, trace as trace3, SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
2419
+ import { context as context5, trace as trace3, SpanStatusCode as SpanStatusCode3 } from "@opentelemetry/api";
2458
2420
  function setCurrentSpanCustomProperties(properties) {
2459
2421
  const current = trace3.getActiveSpan();
2460
2422
  if (!current || !current.isRecording()) {
@@ -2605,7 +2567,7 @@ function startSession(sessionId, callback, extraProperties, options) {
2605
2567
  return value;
2606
2568
  }).catch((error) => {
2607
2569
  span.recordException(error);
2608
- span.setStatus({ code: SpanStatusCode2.ERROR });
2570
+ span.setStatus({ code: SpanStatusCode3.ERROR });
2609
2571
  span.end();
2610
2572
  throw error;
2611
2573
  });
@@ -2614,7 +2576,7 @@ function startSession(sessionId, callback, extraProperties, options) {
2614
2576
  return result;
2615
2577
  } catch (error) {
2616
2578
  span.recordException(error);
2617
- span.setStatus({ code: SpanStatusCode2.ERROR });
2579
+ span.setStatus({ code: SpanStatusCode3.ERROR });
2618
2580
  span.end();
2619
2581
  throw error;
2620
2582
  }
@@ -2643,7 +2605,7 @@ function startSessionTitle(callback, options) {
2643
2605
  return value;
2644
2606
  }).catch((error) => {
2645
2607
  span.recordException(error);
2646
- span.setStatus({ code: SpanStatusCode2.ERROR });
2608
+ span.setStatus({ code: SpanStatusCode3.ERROR });
2647
2609
  span.end();
2648
2610
  throw error;
2649
2611
  });
@@ -2652,7 +2614,7 @@ function startSessionTitle(callback, options) {
2652
2614
  return result;
2653
2615
  } catch (error) {
2654
2616
  span.recordException(error);
2655
- span.setStatus({ code: SpanStatusCode2.ERROR });
2617
+ span.setStatus({ code: SpanStatusCode3.ERROR });
2656
2618
  span.end();
2657
2619
  throw error;
2658
2620
  }