@brizz/sdk 0.1.4 → 0.1.5

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/README.md CHANGED
@@ -334,6 +334,18 @@ const sessionedProcess = withSessionId(
334
334
  **Note:** The arrow function approach (Option 1) is recommended as it's more explicit, avoids lint
335
335
  warnings, and is less prone to `this` binding issues.
336
336
 
337
+ ## Deployment Environment
338
+
339
+ Optionally specify the deployment environment for better filtering and organization:
340
+
341
+ ```typescript
342
+ Brizz.initialize({
343
+ apiKey: 'your-api-key',
344
+ appName: 'my-app',
345
+ environment: 'production', // Optional: 'dev', 'staging', 'production', etc.
346
+ });
347
+ ```
348
+
337
349
  ## Custom Events & Logging
338
350
 
339
351
  Emit custom events and structured logs:
package/dist/index.cjs CHANGED
@@ -326,6 +326,7 @@ function resolveConfig(options) {
326
326
  headers: { ...options.headers },
327
327
  apiKey: process.env["BRIZZ_API_KEY"] || options.apiKey,
328
328
  disableBatch: process.env["BRIZZ_DISABLE_BATCH"] === "true" || !!options.disableBatch,
329
+ environment: process.env["BRIZZ_ENVIRONMENT"] || options.environment,
329
330
  logLevel: resolvedLogLevel,
330
331
  masking: resolvedMasking
331
332
  };
@@ -1020,7 +1021,7 @@ function maskStringByPattern(value, pattern, mode = "full") {
1020
1021
  logger.warn("Regex execution failed, skipping masking", error);
1021
1022
  return value;
1022
1023
  }
1023
- for (const matchInfo of matches.reverse()) {
1024
+ for (const matchInfo of matches.toReversed()) {
1024
1025
  let patternName = "unknown";
1025
1026
  if (matchInfo.groups) {
1026
1027
  for (const [groupName, groupValue] of Object.entries(matchInfo.groups)) {
@@ -1266,9 +1267,13 @@ var LoggingModule = class _LoggingModule {
1266
1267
  logger.debug("Creating resource with service name", {
1267
1268
  serviceName: config.appName
1268
1269
  });
1269
- const resource = (0, import_resources.resourceFromAttributes)({
1270
+ const resourceAttributes = {
1270
1271
  "service.name": config.appName
1271
- });
1272
+ };
1273
+ if (config.environment) {
1274
+ resourceAttributes["deployment.environment"] = config.environment;
1275
+ }
1276
+ const resource = (0, import_resources.resourceFromAttributes)(resourceAttributes);
1272
1277
  logger.debug("Creating logger provider with resource");
1273
1278
  this.loggerProvider = new import_sdk_logs2.LoggerProvider({
1274
1279
  resource,
@@ -1459,130 +1464,6 @@ var import_exporter_trace_otlp_http = require("@opentelemetry/exporter-trace-otl
1459
1464
  // src/internal/trace/processors/span-processor.ts
1460
1465
  var import_api4 = require("@opentelemetry/api");
1461
1466
  var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
1462
-
1463
- // src/internal/trace/transformations/vercel-ai.ts
1464
- var import_ai_semantic_conventions = require("@traceloop/ai-semantic-conventions");
1465
- var AI_GENERATE_TEXT_DO_GENERATE = "ai.generateText.doGenerate";
1466
- var AI_STREAM_TEXT_DO_STREAM = "ai.streamText.doStream";
1467
- var HANDLED_SPAN_NAMES = {
1468
- [AI_GENERATE_TEXT_DO_GENERATE]: "gen_ai.chat",
1469
- [AI_STREAM_TEXT_DO_STREAM]: "gen_ai.chat",
1470
- "ai.streamText": "ai.streamText",
1471
- "ai.toolCall": (span) => {
1472
- const toolName = span.attributes["ai.toolCall.name"];
1473
- return `${String(toolName ?? "unknown")}.tool`;
1474
- }
1475
- };
1476
- var AI_RESPONSE_TEXT = "ai.response.text";
1477
- var AI_PROMPT_MESSAGES = "ai.prompt.messages";
1478
- var AI_USAGE_PROMPT_TOKENS = "ai.usage.promptTokens";
1479
- var AI_USAGE_COMPLETION_TOKENS = "ai.usage.completionTokens";
1480
- var AI_MODEL_PROVIDER = "ai.model.provider";
1481
- var transformAiSdkSpanName = (span) => {
1482
- if (span.name in HANDLED_SPAN_NAMES) {
1483
- const handler = HANDLED_SPAN_NAMES[span.name];
1484
- if (typeof handler === "function") {
1485
- span.name = handler(span);
1486
- } else if (handler) {
1487
- span.name = handler;
1488
- }
1489
- }
1490
- };
1491
- var transformResponseText = (attributes) => {
1492
- if (AI_RESPONSE_TEXT in attributes) {
1493
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_COMPLETIONS}.0.content`] = attributes[AI_RESPONSE_TEXT];
1494
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_COMPLETIONS}.0.role`] = "assistant";
1495
- delete attributes[AI_RESPONSE_TEXT];
1496
- }
1497
- };
1498
- var transformPromptMessages = (attributes) => {
1499
- if (AI_PROMPT_MESSAGES in attributes) {
1500
- try {
1501
- const messages = JSON.parse(attributes[AI_PROMPT_MESSAGES]);
1502
- for (const [index, msg] of messages.entries()) {
1503
- const message = msg;
1504
- logger.debug("Transforming prompt message", { msg: message, type: typeof message.content });
1505
- if (typeof message.content === "string") {
1506
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_PROMPTS}.${index}.content`] = message.content;
1507
- } else {
1508
- if (Array.isArray(message.content) && message.content.length > 0) {
1509
- const lastContent = message.content.at(-1);
1510
- if (lastContent?.text) {
1511
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_PROMPTS}.${index}.content`] = lastContent.text;
1512
- }
1513
- } else {
1514
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_PROMPTS}.${index}.content`] = JSON.stringify(
1515
- message.content
1516
- );
1517
- }
1518
- }
1519
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_PROMPTS}.${index}.role`] = message.role;
1520
- }
1521
- delete attributes[AI_PROMPT_MESSAGES];
1522
- } catch (error) {
1523
- logger.debug("Skipping prompt messages transformation because of JSON parsing error", {
1524
- e: error
1525
- });
1526
- }
1527
- }
1528
- };
1529
- var transformPromptTokens = (attributes) => {
1530
- if (AI_USAGE_PROMPT_TOKENS in attributes) {
1531
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_PROMPT_TOKENS}`] = attributes[AI_USAGE_PROMPT_TOKENS];
1532
- delete attributes[AI_USAGE_PROMPT_TOKENS];
1533
- }
1534
- };
1535
- var transformCompletionTokens = (attributes) => {
1536
- if (AI_USAGE_COMPLETION_TOKENS in attributes) {
1537
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_COMPLETION_TOKENS}`] = attributes[AI_USAGE_COMPLETION_TOKENS];
1538
- delete attributes[AI_USAGE_COMPLETION_TOKENS];
1539
- }
1540
- };
1541
- var calculateTotalTokens = (attributes) => {
1542
- const promptTokens = attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_PROMPT_TOKENS}`];
1543
- const completionTokens = attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_COMPLETION_TOKENS}`];
1544
- if (promptTokens && completionTokens) {
1545
- attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_TOTAL_TOKENS}`] = Number(promptTokens) + Number(completionTokens);
1546
- }
1547
- };
1548
- var transformVendor = (attributes) => {
1549
- if (AI_MODEL_PROVIDER in attributes) {
1550
- const vendor = attributes[AI_MODEL_PROVIDER];
1551
- attributes[import_ai_semantic_conventions.SpanAttributes.LLM_SYSTEM] = vendor && vendor.startsWith("openai") ? "OpenAI" : vendor;
1552
- delete attributes[AI_MODEL_PROVIDER];
1553
- }
1554
- };
1555
- var transformAiSdkAttributes = (attributes) => {
1556
- transformResponseText(attributes);
1557
- transformPromptMessages(attributes);
1558
- transformPromptTokens(attributes);
1559
- transformCompletionTokens(attributes);
1560
- calculateTotalTokens(attributes);
1561
- transformVendor(attributes);
1562
- };
1563
- var shouldHandleSpan = (span) => {
1564
- return span.name in HANDLED_SPAN_NAMES;
1565
- };
1566
- var transformAiSdkSpan = (span) => {
1567
- if (!shouldHandleSpan(span)) {
1568
- logger.debug("Skipping span transformation", { spanName: span.name });
1569
- return;
1570
- }
1571
- for (const key in span.attributes) {
1572
- if (Number.isNaN(span.attributes[key])) {
1573
- span.attributes[key] = 0;
1574
- }
1575
- }
1576
- logger.debug("Transforming AI SDK span", {
1577
- spanName: span.name,
1578
- spanContext: span.spanContext(),
1579
- attributes: span.attributes
1580
- });
1581
- transformAiSdkSpanName(span);
1582
- transformAiSdkAttributes(span.attributes);
1583
- };
1584
-
1585
- // src/internal/trace/processors/span-processor.ts
1586
1467
  var DEFAULT_MASKING_RULES = [
1587
1468
  {
1588
1469
  mode: "partial",
@@ -1625,10 +1506,6 @@ var BrizzSimpleSpanProcessor = class extends import_sdk_trace_base.SimpleSpanPro
1625
1506
  }
1626
1507
  super.onStart(span, parentContext);
1627
1508
  }
1628
- onEnd(span) {
1629
- transformAiSdkSpan(span);
1630
- super.onEnd(span);
1631
- }
1632
1509
  };
1633
1510
  var BrizzBatchSpanProcessor = class extends import_sdk_trace_base.BatchSpanProcessor {
1634
1511
  config;
@@ -1649,10 +1526,6 @@ var BrizzBatchSpanProcessor = class extends import_sdk_trace_base.BatchSpanProce
1649
1526
  }
1650
1527
  super.onStart(span, parentContext);
1651
1528
  }
1652
- onEnd(span) {
1653
- transformAiSdkSpan(span);
1654
- super.onEnd(span);
1655
- }
1656
1529
  };
1657
1530
  function maskSpan(span, config) {
1658
1531
  if (!span.attributes || Object.keys(span.attributes).length === 0) {
@@ -1796,7 +1669,10 @@ function withSessionId(sessionId, fn, thisArg) {
1796
1669
  return function wrapped(...args) {
1797
1670
  const base = import_api5.context.active();
1798
1671
  const prev = base.getValue(PROPERTIES_CONTEXT_KEY);
1799
- const next = base.setValue(PROPERTIES_CONTEXT_KEY, prev ? { ...prev, [SESSION_ID]: sessionId } : { [SESSION_ID]: sessionId });
1672
+ const next = base.setValue(
1673
+ PROPERTIES_CONTEXT_KEY,
1674
+ prev ? { ...prev, [SESSION_ID]: sessionId } : { [SESSION_ID]: sessionId }
1675
+ );
1800
1676
  return import_api5.context.with(next, fn, thisArg ?? this, ...args);
1801
1677
  };
1802
1678
  }
@@ -1874,12 +1750,16 @@ var _Brizz = class __Brizz {
1874
1750
  }
1875
1751
  const registry = InstrumentationRegistry.getInstance();
1876
1752
  const manualInstrumentations = registry.getManualInstrumentations();
1753
+ const resourceAttributes = {
1754
+ "service.name": resolvedConfig.appName
1755
+ };
1756
+ if (resolvedConfig.environment) {
1757
+ resourceAttributes["deployment.environment"] = resolvedConfig.environment;
1758
+ }
1877
1759
  this._sdk = new import_sdk_node.NodeSDK({
1878
1760
  spanProcessors: [getSpanProcessor()],
1879
1761
  metricReader: getMetricsReader(),
1880
- resource: (0, import_resources2.resourceFromAttributes)({
1881
- "service.name": resolvedConfig.appName
1882
- }),
1762
+ resource: (0, import_resources2.resourceFromAttributes)(resourceAttributes),
1883
1763
  instrumentations: manualInstrumentations
1884
1764
  });
1885
1765
  this._sdk.start();
@@ -2003,7 +1883,10 @@ function detectRuntime() {
2003
1883
  const isESM = noNodeJSGlobals && noModuleSystem;
2004
1884
  const isCJS = hasRequire && typeof module !== "undefined" && typeof exports !== "undefined" && typeof __filename === "string" && typeof __dirname === "string";
2005
1885
  const supportsLoaderAPI = (major ?? 0) >= 21 || (major ?? 0) === 20 && (minor ?? 0) >= 6 || (major ?? 0) === 18 && (minor ?? 0) >= 19;
2006
- const supportsRegister = !!process.features?.typescript || !!globalThis.module?.register;
1886
+ const supportsRegister = (
1887
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1888
+ !!process.features?.typescript || !!globalThis.module?.register
1889
+ );
2007
1890
  logger.debug("Runtime detection results:", {
2008
1891
  nodeVersion: `${major ?? 0}.${minor ?? 0}`,
2009
1892
  isESM,
@@ -2024,6 +1907,7 @@ function detectRuntime() {
2024
1907
  module: typeof module,
2025
1908
  exports: typeof exports,
2026
1909
  "process.features": process.features,
1910
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2027
1911
  "globalThis.module": globalThis.module
2028
1912
  }
2029
1913
  });