@brizz/sdk 0.1.17 → 0.1.19

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.d.cts CHANGED
@@ -1,11 +1,13 @@
1
+ import { AttributeValue, Span } from '@opentelemetry/api';
2
+ export { AttributeValue } from '@opentelemetry/api';
1
3
  import { LogRecordExporter } from '@opentelemetry/sdk-logs';
2
4
  import { MetricReader } from '@opentelemetry/sdk-metrics';
3
- import { SpanExporter } from '@opentelemetry/sdk-trace-base';
5
+ import { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';
6
+ export { ReadableSpan } from '@opentelemetry/sdk-trace-base';
4
7
  import { LogBody, SeverityNumber } from '@opentelemetry/api-logs';
5
8
  export { SeverityNumber } from '@opentelemetry/api-logs';
6
9
  import { SpanProcessor } from '@opentelemetry/sdk-trace-node';
7
10
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
8
- import { Span, AttributeValue } from '@opentelemetry/api';
9
11
 
10
12
  interface IInstrumentModules {
11
13
  openAI?: unknown;
@@ -83,6 +85,7 @@ declare function maskAttributes(attributes: Record<string, unknown>, rules: read
83
85
 
84
86
  interface IBrizzInitializeOptions {
85
87
  appName?: string;
88
+ appVersion?: string;
86
89
  baseUrl?: string;
87
90
  apiKey?: string;
88
91
  headers?: Record<string, string>;
@@ -96,6 +99,8 @@ interface IBrizzInitializeOptions {
96
99
  customLogExporter?: LogRecordExporter;
97
100
  customMetricReader?: MetricReader;
98
101
  disableSpanExporter?: boolean;
102
+ resourceAttributes?: Record<string, AttributeValue>;
103
+ beforeSendSpan?: (span: ReadableSpan) => boolean | Promise<boolean>;
99
104
  }
100
105
  declare class _Brizz {
101
106
  private static instance;
@@ -130,9 +135,11 @@ declare class Session {
130
135
  private readonly span;
131
136
  private inputs;
132
137
  private outputs;
138
+ private inputContexts;
139
+ private outputContexts;
133
140
  constructor(sessionId: string, span: Span);
134
- setInput(text: string | null): void;
135
- setOutput(text: string | null): void;
141
+ setInput(text: string | null, context?: Record<string, AttributeValue>): void;
142
+ setOutput(text: string | null, context?: Record<string, AttributeValue>): void;
136
143
  setTitle(title: string): void;
137
144
  updateProperties(properties: Record<string, AttributeValue>): void;
138
145
  }
package/dist/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
+ import { AttributeValue, Span } from '@opentelemetry/api';
2
+ export { AttributeValue } from '@opentelemetry/api';
1
3
  import { LogRecordExporter } from '@opentelemetry/sdk-logs';
2
4
  import { MetricReader } from '@opentelemetry/sdk-metrics';
3
- import { SpanExporter } from '@opentelemetry/sdk-trace-base';
5
+ import { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';
6
+ export { ReadableSpan } from '@opentelemetry/sdk-trace-base';
4
7
  import { LogBody, SeverityNumber } from '@opentelemetry/api-logs';
5
8
  export { SeverityNumber } from '@opentelemetry/api-logs';
6
9
  import { SpanProcessor } from '@opentelemetry/sdk-trace-node';
7
10
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
8
- import { Span, AttributeValue } from '@opentelemetry/api';
9
11
 
10
12
  interface IInstrumentModules {
11
13
  openAI?: unknown;
@@ -83,6 +85,7 @@ declare function maskAttributes(attributes: Record<string, unknown>, rules: read
83
85
 
84
86
  interface IBrizzInitializeOptions {
85
87
  appName?: string;
88
+ appVersion?: string;
86
89
  baseUrl?: string;
87
90
  apiKey?: string;
88
91
  headers?: Record<string, string>;
@@ -96,6 +99,8 @@ interface IBrizzInitializeOptions {
96
99
  customLogExporter?: LogRecordExporter;
97
100
  customMetricReader?: MetricReader;
98
101
  disableSpanExporter?: boolean;
102
+ resourceAttributes?: Record<string, AttributeValue>;
103
+ beforeSendSpan?: (span: ReadableSpan) => boolean | Promise<boolean>;
99
104
  }
100
105
  declare class _Brizz {
101
106
  private static instance;
@@ -130,9 +135,11 @@ declare class Session {
130
135
  private readonly span;
131
136
  private inputs;
132
137
  private outputs;
138
+ private inputContexts;
139
+ private outputContexts;
133
140
  constructor(sessionId: string, span: Span);
134
- setInput(text: string | null): void;
135
- setOutput(text: string | null): void;
141
+ setInput(text: string | null, context?: Record<string, AttributeValue>): void;
142
+ setOutput(text: string | null, context?: Record<string, AttributeValue>): void;
136
143
  setTitle(title: string): void;
137
144
  updateProperties(properties: Record<string, AttributeValue>): void;
138
145
  }
package/dist/index.js CHANGED
@@ -170,7 +170,14 @@ var exceptionLogger = (error) => {
170
170
  };
171
171
  function loadNodeAutoInstrumentations() {
172
172
  try {
173
- const nodeInstrumentations = getNodeAutoInstrumentations();
173
+ const nodeInstrumentations = getNodeAutoInstrumentations({
174
+ // Disabled because @traceloop/instrumentation-openai wraps the same OpenAI
175
+ // prototype with richer span attributes (gen_ai.input.messages /
176
+ // gen_ai.output.messages). Leaving both enabled lets the official one win
177
+ // and route content to log events instead of span attributes, leaving the
178
+ // Brizz backend parser with no payload to read.
179
+ "@opentelemetry/instrumentation-openai": { enabled: false }
180
+ });
174
181
  registerInstrumentations({ instrumentations: nodeInstrumentations });
175
182
  return nodeInstrumentations;
176
183
  } catch (error) {
@@ -274,6 +281,7 @@ function resolveConfig(options) {
274
281
  const resolvedConfig = {
275
282
  ...options,
276
283
  appName: process.env["BRIZZ_APP_NAME"] || options.appName || "unknown-app",
284
+ appVersion: process.env["BRIZZ_APP_VERSION"] || options.appVersion,
277
285
  baseUrl: process.env["BRIZZ_BASE_URL"] || options.baseUrl || "https://telemetry.brizz.dev",
278
286
  headers: { ...options.headers },
279
287
  apiKey: process.env["BRIZZ_API_KEY"] || options.apiKey,
@@ -446,7 +454,7 @@ import {
446
454
 
447
455
  // src/internal/version.ts
448
456
  function getSDKVersion() {
449
- return "0.1.17";
457
+ return "0.1.19";
450
458
  }
451
459
 
452
460
  // src/internal/log/processors/log-processor.ts
@@ -1086,6 +1094,8 @@ var PROPERTIES_CONTEXT_KEY = createContextKey(PROPERTIES);
1086
1094
  var SESSION_OBJECT_CONTEXT_KEY = createContextKey("brizz.session.object");
1087
1095
  var SESSION_INPUT = "brizz.session.input";
1088
1096
  var SESSION_OUTPUT = "brizz.session.output";
1097
+ var SESSION_INPUT_CONTEXT = "brizz.session.input.context";
1098
+ var SESSION_OUTPUT_CONTEXT = "brizz.session.output.context";
1089
1099
  var SESSION_SPAN_NAME = "brizz.start_session";
1090
1100
  var SESSION_TITLE_SPAN_NAME = "brizz.session_title";
1091
1101
  var SESSION_TITLE_GENERATION = "session.title_generation";
@@ -1255,6 +1265,7 @@ var LoggingModule = class _LoggingModule {
1255
1265
  serviceName: config.appName
1256
1266
  });
1257
1267
  const resourceAttributes = {
1268
+ ...config.resourceAttributes,
1258
1269
  "service.name": config.appName,
1259
1270
  [BRIZZ_SDK_VERSION]: getSDKVersion(),
1260
1271
  [BRIZZ_SDK_LANGUAGE]: SDK_LANGUAGE
@@ -1262,6 +1273,9 @@ var LoggingModule = class _LoggingModule {
1262
1273
  if (config.environment) {
1263
1274
  resourceAttributes["deployment.environment"] = config.environment;
1264
1275
  }
1276
+ if (config.appVersion) {
1277
+ resourceAttributes["service.version"] = config.appVersion;
1278
+ }
1265
1279
  const resource = resourceFromAttributes(resourceAttributes);
1266
1280
  logger.debug("Creating logger provider with resource");
1267
1281
  this.loggerProvider = new LoggerProvider({
@@ -1451,13 +1465,16 @@ function getMetricsReader() {
1451
1465
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
1452
1466
 
1453
1467
  // src/internal/trace/exporters/span-exporter.ts
1468
+ import { ExportResultCode } from "@opentelemetry/core";
1454
1469
  import { resourceFromAttributes as resourceFromAttributes2 } from "@opentelemetry/resources";
1455
1470
  var BrizzSpanExporter = class {
1456
1471
  _delegate;
1457
1472
  _brizzResource;
1473
+ _beforeSendSpan;
1458
1474
  constructor(delegate, config) {
1459
1475
  this._delegate = delegate;
1460
1476
  const resourceAttrs = {
1477
+ ...config.resourceAttributes,
1461
1478
  "service.name": config.appName,
1462
1479
  [BRIZZ_SDK_VERSION]: getSDKVersion(),
1463
1480
  [BRIZZ_SDK_LANGUAGE]: SDK_LANGUAGE
@@ -1465,15 +1482,47 @@ var BrizzSpanExporter = class {
1465
1482
  if (config.environment) {
1466
1483
  resourceAttrs["deployment.environment"] = config.environment;
1467
1484
  }
1485
+ if (config.appVersion) {
1486
+ resourceAttrs["service.version"] = config.appVersion;
1487
+ }
1468
1488
  this._brizzResource = resourceFromAttributes2(resourceAttrs);
1489
+ this._beforeSendSpan = config.beforeSendSpan;
1469
1490
  }
1470
1491
  export(spans, resultCallback) {
1492
+ if (spans.length === 0) {
1493
+ resultCallback({ code: ExportResultCode.SUCCESS });
1494
+ return;
1495
+ }
1471
1496
  const patchedSpans = spans.map((span) => ({
1472
1497
  ...span,
1473
1498
  resource: span.resource.merge(this._brizzResource),
1474
1499
  spanContext: span.spanContext.bind(span)
1475
1500
  }));
1476
- this._delegate.export(patchedSpans, resultCallback);
1501
+ const filter = this._beforeSendSpan;
1502
+ if (!filter) {
1503
+ this._delegate.export(patchedSpans, resultCallback);
1504
+ return;
1505
+ }
1506
+ const verdicts = patchedSpans.map((span) => {
1507
+ try {
1508
+ return Promise.resolve(filter(span));
1509
+ } catch (error) {
1510
+ logger.warn("beforeSendSpan threw; span will be kept", { error });
1511
+ return Promise.resolve(true);
1512
+ }
1513
+ });
1514
+ Promise.all(verdicts).then((keep) => {
1515
+ const filtered = patchedSpans.filter((_, i) => keep[i] !== false);
1516
+ if (filtered.length === 0) {
1517
+ resultCallback({ code: ExportResultCode.SUCCESS });
1518
+ return;
1519
+ }
1520
+ this._delegate.export(filtered, resultCallback);
1521
+ return;
1522
+ }).catch((error) => {
1523
+ logger.warn("beforeSendSpan rejected; all spans will be kept", { error });
1524
+ this._delegate.export(patchedSpans, resultCallback);
1525
+ });
1477
1526
  }
1478
1527
  async shutdown() {
1479
1528
  return this._delegate.shutdown();
@@ -1489,6 +1538,14 @@ import {
1489
1538
  BatchSpanProcessor,
1490
1539
  SimpleSpanProcessor
1491
1540
  } from "@opentelemetry/sdk-trace-base";
1541
+ function applyContextAttributes(span) {
1542
+ const sessionProperties = context2.active().getValue(PROPERTIES_CONTEXT_KEY);
1543
+ if (sessionProperties) {
1544
+ for (const [key, value] of Object.entries(sessionProperties)) {
1545
+ span.setAttribute(`${BRIZZ}.${key}`, value);
1546
+ }
1547
+ }
1548
+ }
1492
1549
  var DEFAULT_MASKING_RULES = [
1493
1550
  {
1494
1551
  mode: "partial",
@@ -1523,12 +1580,7 @@ var BrizzSimpleSpanProcessor = class extends SimpleSpanProcessor {
1523
1580
  if (maskingConfig) {
1524
1581
  maskSpan(span, maskingConfig);
1525
1582
  }
1526
- const associationProperties = context2.active().getValue(PROPERTIES_CONTEXT_KEY);
1527
- if (associationProperties) {
1528
- for (const [key, value] of Object.entries(associationProperties)) {
1529
- span.setAttribute(`${BRIZZ}.${key}`, value);
1530
- }
1531
- }
1583
+ applyContextAttributes(span);
1532
1584
  super.onStart(span, parentContext);
1533
1585
  }
1534
1586
  };
@@ -1543,12 +1595,7 @@ var BrizzBatchSpanProcessor = class extends BatchSpanProcessor {
1543
1595
  if (maskingConfig) {
1544
1596
  maskSpan(span, maskingConfig);
1545
1597
  }
1546
- const associationProperties = context2.active().getValue(PROPERTIES_CONTEXT_KEY);
1547
- if (associationProperties) {
1548
- for (const [key, value] of Object.entries(associationProperties)) {
1549
- span.setAttribute(`${BRIZZ}.${key}`, value);
1550
- }
1551
- }
1598
+ applyContextAttributes(span);
1552
1599
  super.onStart(span, parentContext);
1553
1600
  }
1554
1601
  };
@@ -1722,31 +1769,45 @@ var Session = class {
1722
1769
  span;
1723
1770
  inputs = [];
1724
1771
  outputs = [];
1772
+ inputContexts = [];
1773
+ outputContexts = [];
1725
1774
  constructor(sessionId, span) {
1726
1775
  this.sessionId = sessionId;
1727
1776
  this.span = span;
1728
1777
  }
1729
1778
  /**
1730
- * (Optional) Append text to session input tracking.
1731
- * Use when you need to track specific input data that differs from what's sent to the LLM.
1732
- * Multiple calls accumulate in an array.
1779
+ * Append a user turn to session input tracking.
1733
1780
  *
1734
- * @param text - Text to append to session input, or null to append null
1781
+ * Each call appends one element to `brizz.session.input` (the text) AND one
1782
+ * element to `brizz.session.input.context` (the per-turn context bag). The
1783
+ * two arrays stay index-aligned — the ingestion pipeline zips them together
1784
+ * so the i-th context bag lands on the i-th user_display conversation item's
1785
+ * `span_attributes` map.
1786
+ *
1787
+ * @param text - Text to append (null becomes a null/"hide marker")
1788
+ * @param context - Optional per-turn context bag to attach to this turn
1735
1789
  */
1736
- setInput(text) {
1790
+ setInput(text, context4) {
1737
1791
  this.inputs.push(text);
1792
+ this.inputContexts.push(context4 ?? {});
1738
1793
  this.span.setAttribute(SESSION_INPUT, JSON.stringify(this.inputs));
1794
+ this.span.setAttribute(SESSION_INPUT_CONTEXT, JSON.stringify(this.inputContexts));
1739
1795
  }
1740
1796
  /**
1741
- * (Optional) Append text to session output tracking.
1742
- * Use when you need to track specific output data that differs from what's received from the LLM.
1743
- * Multiple calls accumulate in an array.
1797
+ * Append an assistant turn to session output tracking.
1798
+ *
1799
+ * Symmetric to {@link setInput} appends one text element and one
1800
+ * context-bag element to the index-aligned `brizz.session.output` /
1801
+ * `brizz.session.output.context` arrays.
1744
1802
  *
1745
- * @param text - Text to append to session output, or null to append null
1803
+ * @param text - Text to append (null becomes a null/"hide marker")
1804
+ * @param context - Optional per-turn context bag to attach to this turn
1746
1805
  */
1747
- setOutput(text) {
1806
+ setOutput(text, context4) {
1748
1807
  this.outputs.push(text);
1808
+ this.outputContexts.push(context4 ?? {});
1749
1809
  this.span.setAttribute(SESSION_OUTPUT, JSON.stringify(this.outputs));
1810
+ this.span.setAttribute(SESSION_OUTPUT_CONTEXT, JSON.stringify(this.outputContexts));
1750
1811
  }
1751
1812
  /**
1752
1813
  * Set the session title on the span.
@@ -1943,6 +2004,7 @@ var _Brizz = class __Brizz {
1943
2004
  const registry = InstrumentationRegistry.getInstance();
1944
2005
  const manualInstrumentations = registry.getManualInstrumentations();
1945
2006
  const resourceAttributes = {
2007
+ ...resolvedConfig.resourceAttributes,
1946
2008
  "service.name": resolvedConfig.appName,
1947
2009
  [BRIZZ_SDK_VERSION]: getSDKVersion(),
1948
2010
  [BRIZZ_SDK_LANGUAGE]: SDK_LANGUAGE
@@ -1950,6 +2012,9 @@ var _Brizz = class __Brizz {
1950
2012
  if (resolvedConfig.environment) {
1951
2013
  resourceAttributes["deployment.environment"] = resolvedConfig.environment;
1952
2014
  }
2015
+ if (resolvedConfig.appVersion) {
2016
+ resourceAttributes["service.version"] = resolvedConfig.appVersion;
2017
+ }
1953
2018
  this._sdk = new NodeSDK({
1954
2019
  spanProcessors: resolvedConfig.disableSpanExporter ? [] : [getSpanProcessor()],
1955
2020
  metricReader: getMetricsReader(),