@brizz/sdk 0.1.27 → 0.1.29

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.cjs CHANGED
@@ -305,7 +305,7 @@ var init_schemas = __esm({
305
305
  });
306
306
 
307
307
  // src/internal/semantic-conventions.ts
308
- var import_api3, BRIZZ, PROPERTIES, SESSION_ID, PROPERTIES_CONTEXT_KEY, SESSION_OBJECT_CONTEXT_KEY, SESSION_INPUT, SESSION_OUTPUT, SESSION_INPUT_CONTEXT, SESSION_OUTPUT_CONTEXT, SESSION_SPAN_NAME, SESSION_TITLE_SPAN_NAME, SESSION_TITLE_GENERATION, SESSION_TITLE, INTERRUPT_TOOLS;
308
+ var import_api3, BRIZZ, PROPERTIES, SESSION_ID, PROPERTIES_CONTEXT_KEY, SESSION_OBJECT_CONTEXT_KEY, SESSION_INPUT, SESSION_OUTPUT, SESSION_INPUT_CONTEXT, SESSION_OUTPUT_CONTEXT, SESSION_SPAN_NAME, MUTE_INPUT, MUTE_OUTPUT, SESSION_TITLE_SPAN_NAME, SESSION_TITLE_GENERATION, SESSION_TITLE, INTERRUPT_TOOLS, INTERNAL_EVENT_PREFIX, EXTERNAL_LINK_EVENT_NAME, EXTERNAL_LINK_URL, EXTERNAL_LINK_TITLE, EXTERNAL_LINK_TYPE;
309
309
  var init_semantic_conventions2 = __esm({
310
310
  "src/internal/semantic-conventions.ts"() {
311
311
  "use strict";
@@ -320,10 +320,17 @@ var init_semantic_conventions2 = __esm({
320
320
  SESSION_INPUT_CONTEXT = "brizz.session.input.context";
321
321
  SESSION_OUTPUT_CONTEXT = "brizz.session.output.context";
322
322
  SESSION_SPAN_NAME = "brizz.start_session";
323
+ MUTE_INPUT = "mute.input";
324
+ MUTE_OUTPUT = "mute.output";
323
325
  SESSION_TITLE_SPAN_NAME = "brizz.session_title";
324
326
  SESSION_TITLE_GENERATION = "session.title_generation";
325
327
  SESSION_TITLE = "brizz.session.title";
326
328
  INTERRUPT_TOOLS = "brizz.internal.interrupt";
329
+ INTERNAL_EVENT_PREFIX = "brizz.internal.";
330
+ EXTERNAL_LINK_EVENT_NAME = "brizz.internal.external_link";
331
+ EXTERNAL_LINK_URL = "brizz.internal.external_link.url";
332
+ EXTERNAL_LINK_TITLE = "brizz.internal.external_link.title";
333
+ EXTERNAL_LINK_TYPE = "brizz.internal.external_link.type";
327
334
  }
328
335
  });
329
336
 
@@ -791,7 +798,7 @@ var init_protocol = __esm({
791
798
 
792
799
  // src/internal/version.ts
793
800
  function getSDKVersion() {
794
- return "0.1.27";
801
+ return "0.1.29";
795
802
  }
796
803
  var init_version = __esm({
797
804
  "src/internal/version.ts"() {
@@ -1076,10 +1083,13 @@ __export(src_exports, {
1076
1083
  Session: () => Session,
1077
1084
  SessionTitle: () => SessionTitle,
1078
1085
  SeverityNumber: () => import_api_logs2.SeverityNumber,
1086
+ addExternalLink: () => addExternalLink,
1087
+ callWithMute: () => callWithMute,
1079
1088
  callWithProperties: () => callWithProperties,
1080
1089
  callWithSessionId: () => callWithSessionId,
1081
1090
  detectRuntime: () => detectRuntime,
1082
1091
  emitEvent: () => emitEvent,
1092
+ emitEventWithSessionId: () => emitEventWithSessionId,
1083
1093
  getActiveSession: () => getActiveSession,
1084
1094
  getLogLevel: () => getLogLevel,
1085
1095
  getMetricsExporter: () => getMetricsExporter,
@@ -1094,6 +1104,7 @@ __export(src_exports, {
1094
1104
  setLogLevel: () => setLogLevel,
1095
1105
  startSession: () => startSession,
1096
1106
  startSessionTitle: () => startSessionTitle,
1107
+ withMute: () => withMute,
1097
1108
  withProperties: () => withProperties,
1098
1109
  withSessionId: () => withSessionId
1099
1110
  });
@@ -1531,10 +1542,282 @@ var import_exporter_logs_otlp_http = require("@opentelemetry/exporter-logs-otlp-
1531
1542
  var import_resources = require("@opentelemetry/resources");
1532
1543
  var import_sdk_logs2 = require("@opentelemetry/sdk-logs");
1533
1544
  init_logger();
1545
+
1546
+ // src/internal/trace/session.ts
1547
+ var import_api9 = require("@opentelemetry/api");
1548
+ init_logger();
1549
+ init_semantic_conventions2();
1550
+ function setCurrentSpanCustomProperties(properties) {
1551
+ const current = import_api9.trace.getActiveSpan();
1552
+ if (!current || !current.isRecording()) {
1553
+ return;
1554
+ }
1555
+ for (const [key, value] of Object.entries(properties)) {
1556
+ try {
1557
+ current.setAttribute(`${BRIZZ}.${key}`, value);
1558
+ } catch {
1559
+ }
1560
+ }
1561
+ }
1562
+ function callWithProperties(properties, fn, thisArg, ...args) {
1563
+ const base = import_api9.context.active();
1564
+ const prev = base.getValue(PROPERTIES_CONTEXT_KEY);
1565
+ const merged = prev ? { ...prev, ...properties } : properties;
1566
+ const next = base.setValue(PROPERTIES_CONTEXT_KEY, merged);
1567
+ return import_api9.context.with(next, fn, thisArg, ...args);
1568
+ }
1569
+ function withProperties(properties, fn, thisArg) {
1570
+ return function wrapped(...args) {
1571
+ return callWithProperties(
1572
+ properties,
1573
+ fn,
1574
+ thisArg !== void 0 ? thisArg : this,
1575
+ ...args
1576
+ );
1577
+ };
1578
+ }
1579
+ function muteProperties(options) {
1580
+ const { input = true, output = true } = options;
1581
+ const properties = {};
1582
+ if (input) {
1583
+ properties[MUTE_INPUT] = "true";
1584
+ }
1585
+ if (output) {
1586
+ properties[MUTE_OUTPUT] = "true";
1587
+ }
1588
+ return properties;
1589
+ }
1590
+ function callWithMute(options, fn, thisArg, ...args) {
1591
+ return callWithProperties(muteProperties(options), fn, thisArg, ...args);
1592
+ }
1593
+ function withMute(options, fn, thisArg) {
1594
+ return withProperties(muteProperties(options), fn, thisArg);
1595
+ }
1596
+ function withSessionId(sessionId, fn, thisArg, extraProperties) {
1597
+ const properties = { [SESSION_ID]: sessionId, ...extraProperties };
1598
+ return withProperties(properties, fn, thisArg);
1599
+ }
1600
+ function callWithSessionId(sessionId, fn, thisArg, ...args) {
1601
+ return callWithProperties({ [SESSION_ID]: sessionId }, fn, thisArg, ...args);
1602
+ }
1603
+ var Session = class {
1604
+ sessionId;
1605
+ span;
1606
+ inputs = [];
1607
+ outputs = [];
1608
+ inputContexts = [];
1609
+ outputContexts = [];
1610
+ constructor(sessionId, span) {
1611
+ this.sessionId = sessionId;
1612
+ this.span = span;
1613
+ }
1614
+ /**
1615
+ * Append a user turn to session input tracking.
1616
+ *
1617
+ * Each call appends one element to `brizz.session.input` (the text) AND one
1618
+ * element to `brizz.session.input.context` (the per-turn context bag). The
1619
+ * two arrays stay index-aligned — the ingestion pipeline zips them together
1620
+ * so the i-th context bag lands on the i-th user_display conversation item's
1621
+ * `span_attributes` map.
1622
+ *
1623
+ * @param text - Text to append (null becomes a null/"hide marker")
1624
+ * @param context - Optional per-turn context bag to attach to this turn
1625
+ */
1626
+ setInput(text, context6) {
1627
+ this.inputs.push(text);
1628
+ this.inputContexts.push(context6 ?? {});
1629
+ this.span.setAttribute(SESSION_INPUT, JSON.stringify(this.inputs));
1630
+ this.span.setAttribute(SESSION_INPUT_CONTEXT, JSON.stringify(this.inputContexts));
1631
+ }
1632
+ /**
1633
+ * Append an assistant turn to session output tracking.
1634
+ *
1635
+ * Symmetric to {@link setInput} — appends one text element and one
1636
+ * context-bag element to the index-aligned `brizz.session.output` /
1637
+ * `brizz.session.output.context` arrays.
1638
+ *
1639
+ * @param text - Text to append (null becomes a null/"hide marker")
1640
+ * @param context - Optional per-turn context bag to attach to this turn
1641
+ */
1642
+ setOutput(text, context6) {
1643
+ this.outputs.push(text);
1644
+ this.outputContexts.push(context6 ?? {});
1645
+ this.span.setAttribute(SESSION_OUTPUT, JSON.stringify(this.outputs));
1646
+ this.span.setAttribute(SESSION_OUTPUT_CONTEXT, JSON.stringify(this.outputContexts));
1647
+ }
1648
+ /**
1649
+ * Set the session title on the span.
1650
+ *
1651
+ * @param title - The generated title string
1652
+ */
1653
+ setTitle(title) {
1654
+ this.span.setAttribute(SESSION_TITLE, title);
1655
+ }
1656
+ /**
1657
+ * Update custom properties on the session span.
1658
+ * Properties are prefixed with 'brizz.'.
1659
+ *
1660
+ * @param properties - Key-value properties to set on the session
1661
+ */
1662
+ updateProperties(properties) {
1663
+ for (const [key, value] of Object.entries(properties)) {
1664
+ this.span.setAttribute(`${BRIZZ}.${key}`, value);
1665
+ }
1666
+ }
1667
+ /**
1668
+ * Attach an external link (URL) to this session.
1669
+ *
1670
+ * The link surfaces on the session's detail panel in Brizz — use it to
1671
+ * correlate a session with an external record such as a Datadog trace,
1672
+ * Sentry issue, or internal dashboard. Re-sending the same URL is idempotent;
1673
+ * distinct URLs add separate links.
1674
+ *
1675
+ * @param url - The link target
1676
+ * @param options - Optional `title` (defaults to the URL host) and `linkType`
1677
+ * (free-form category, defaults to `'generic'`)
1678
+ */
1679
+ addExternalLink(url, options) {
1680
+ emitExternalLink(this.sessionId, url, options?.title, options?.linkType);
1681
+ }
1682
+ };
1683
+ var SessionTitle = class {
1684
+ span;
1685
+ constructor(span) {
1686
+ this.span = span;
1687
+ }
1688
+ /**
1689
+ * Set the generated title on the wrapper span.
1690
+ *
1691
+ * @param title - The generated title string
1692
+ */
1693
+ setTitle(title) {
1694
+ this.span.setAttribute(SESSION_TITLE, title);
1695
+ }
1696
+ };
1697
+ function getActiveSession() {
1698
+ return import_api9.context.active().getValue(SESSION_OBJECT_CONTEXT_KEY);
1699
+ }
1700
+ function resolveSessionIdFromContext() {
1701
+ const active = getActiveSession();
1702
+ if (active) {
1703
+ return active.sessionId;
1704
+ }
1705
+ const props = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1706
+ return props?.[SESSION_ID];
1707
+ }
1708
+ function emitExternalLink(sessionId, url, title, linkType) {
1709
+ try {
1710
+ emitEventWithSessionId(sessionId, EXTERNAL_LINK_EVENT_NAME, {
1711
+ [EXTERNAL_LINK_URL]: url,
1712
+ [EXTERNAL_LINK_TITLE]: title ?? "",
1713
+ [EXTERNAL_LINK_TYPE]: linkType ?? "generic"
1714
+ });
1715
+ } catch (error) {
1716
+ logger.warn("addExternalLink: failed to emit external link", error);
1717
+ }
1718
+ }
1719
+ function addExternalLink(url, options) {
1720
+ const sessionId = options?.sessionId ?? resolveSessionIdFromContext();
1721
+ if (!sessionId) {
1722
+ logger.warn(
1723
+ "addExternalLink called without a resolvable session id; link dropped. Pass options.sessionId or call inside a startSession/callWithSessionId scope."
1724
+ );
1725
+ return;
1726
+ }
1727
+ emitExternalLink(sessionId, url, options?.title, options?.linkType);
1728
+ }
1729
+ function startSession(sessionId, callback, extraProperties, options) {
1730
+ const isTitle = options?.mode === "title";
1731
+ const spanName = isTitle ? SESSION_TITLE_SPAN_NAME : SESSION_SPAN_NAME;
1732
+ const tracer = import_api9.trace.getTracer("@brizz/sdk");
1733
+ return tracer.startActiveSpan(spanName, (span) => {
1734
+ span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
1735
+ if (extraProperties) {
1736
+ for (const [key, value] of Object.entries(extraProperties)) {
1737
+ span.setAttribute(`${BRIZZ}.${key}`, value);
1738
+ }
1739
+ }
1740
+ const session = new Session(sessionId, span);
1741
+ const contextProperties = { [SESSION_ID]: sessionId };
1742
+ if (isTitle) {
1743
+ contextProperties[SESSION_TITLE_GENERATION] = "true";
1744
+ }
1745
+ if (extraProperties) {
1746
+ for (const [key, value] of Object.entries(extraProperties)) {
1747
+ contextProperties[key] = String(value);
1748
+ }
1749
+ }
1750
+ return callWithProperties(contextProperties, () => {
1751
+ const sessionCtx = import_api9.context.active().setValue(SESSION_OBJECT_CONTEXT_KEY, session);
1752
+ return import_api9.context.with(sessionCtx, () => {
1753
+ try {
1754
+ const result = callback(session);
1755
+ if (result && typeof result.then === "function") {
1756
+ return result.then((value) => {
1757
+ span.end();
1758
+ return value;
1759
+ }).catch((error) => {
1760
+ span.recordException(error);
1761
+ span.setStatus({ code: import_api9.SpanStatusCode.ERROR });
1762
+ span.end();
1763
+ throw error;
1764
+ });
1765
+ }
1766
+ span.end();
1767
+ return result;
1768
+ } catch (error) {
1769
+ span.recordException(error);
1770
+ span.setStatus({ code: import_api9.SpanStatusCode.ERROR });
1771
+ span.end();
1772
+ throw error;
1773
+ }
1774
+ });
1775
+ });
1776
+ });
1777
+ }
1778
+ function startSessionTitle(callback, options) {
1779
+ const resolvedSessionId = options?.sessionId ?? getActiveSession()?.sessionId;
1780
+ const tracer = import_api9.trace.getTracer("@brizz/sdk");
1781
+ return tracer.startActiveSpan(SESSION_TITLE_SPAN_NAME, (span) => {
1782
+ if (resolvedSessionId) {
1783
+ span.setAttribute(`${BRIZZ}.${SESSION_ID}`, resolvedSessionId);
1784
+ }
1785
+ const sessionTitle = new SessionTitle(span);
1786
+ const properties = { [SESSION_TITLE_GENERATION]: "true" };
1787
+ if (resolvedSessionId) {
1788
+ properties[SESSION_ID] = resolvedSessionId;
1789
+ }
1790
+ return callWithProperties(properties, () => {
1791
+ try {
1792
+ const result = callback(sessionTitle);
1793
+ if (result && typeof result.then === "function") {
1794
+ return result.then((value) => {
1795
+ span.end();
1796
+ return value;
1797
+ }).catch((error) => {
1798
+ span.recordException(error);
1799
+ span.setStatus({ code: import_api9.SpanStatusCode.ERROR });
1800
+ span.end();
1801
+ throw error;
1802
+ });
1803
+ }
1804
+ span.end();
1805
+ return result;
1806
+ } catch (error) {
1807
+ span.recordException(error);
1808
+ span.setStatus({ code: import_api9.SpanStatusCode.ERROR });
1809
+ span.end();
1810
+ throw error;
1811
+ }
1812
+ });
1813
+ });
1814
+ }
1815
+
1816
+ // src/internal/log/logging.ts
1534
1817
  init_version();
1535
1818
 
1536
1819
  // src/internal/log/processors/log-processor.ts
1537
- var import_api9 = require("@opentelemetry/api");
1820
+ var import_api10 = require("@opentelemetry/api");
1538
1821
  var import_sdk_logs = require("@opentelemetry/sdk-logs");
1539
1822
  init_logger();
1540
1823
 
@@ -1627,10 +1910,6 @@ var DEFAULT_PII_PATTERNS = [
1627
1910
  name: "pgp_private_keys",
1628
1911
  pattern: "-----BEGIN PGP PRIVATE KEY BLOCK-----"
1629
1912
  },
1630
- {
1631
- name: "certificates",
1632
- pattern: "-----BEGIN CERTIFICATE-----"
1633
- },
1634
1913
  // Additional API Keys and Tokens
1635
1914
  {
1636
1915
  name: "google_oauth",
@@ -1679,7 +1958,7 @@ var DEFAULT_PII_PATTERNS = [
1679
1958
  },
1680
1959
  {
1681
1960
  name: "ssl_certificates",
1682
- pattern: String.raw`-----BEGIN CERTIFICATE-----(?:.|\n)+?\s-----END CERTIFICATE-----`
1961
+ pattern: String.raw`-----BEGIN CERTIFICATE-----(?:.|\n)+?\s*-----END CERTIFICATE-----`
1683
1962
  },
1684
1963
  {
1685
1964
  name: "ssh_dss_public",
@@ -1738,8 +2017,9 @@ function isLikelyReDoSPattern(pattern) {
1738
2017
  const dangerousPatterns = [
1739
2018
  // Nested quantifiers like (a+)+, (a*)+, (a+)*
1740
2019
  /\([^)]*[+*]\)[+*]/,
1741
- // Alternation with overlapping groups like (a|a)*
1742
- /\([^)]*\|[^)]*\)[+*]/,
2020
+ // Overlapping alternation under an outer quantifier like (a|a)+, (\w|\d)+. Scoped to
2021
+ // capturing groups so the lazy (?:…)+? built-ins aren't false-flagged.
2022
+ /\((?!\?)[^)]*\|[^)]*\)[+*]/,
1743
2023
  // Complex backtracking patterns - but more specific
1744
2024
  /\([^)]*[+*][^)]*[+*][^)]*\)[+*]/
1745
2025
  ];
@@ -1808,6 +2088,16 @@ function compilePatternEntries(patternEntries) {
1808
2088
  return null;
1809
2089
  }
1810
2090
  }
2091
+ var compiledPatternCache = /* @__PURE__ */ new WeakMap();
2092
+ function getCompiledPatternsForRule(rule) {
2093
+ const key = rule.patterns;
2094
+ if (compiledPatternCache.has(key)) {
2095
+ return compiledPatternCache.get(key) ?? null;
2096
+ }
2097
+ const compiled = compilePatternEntries(convertPatternsToPatternEntries(rule.patterns));
2098
+ compiledPatternCache.set(key, compiled);
2099
+ return compiled;
2100
+ }
1811
2101
  function getCompiledAttributeNamePattern(rule) {
1812
2102
  if (!rule.attributePattern) {
1813
2103
  logger.debug("No attribute pattern provided, using default .*");
@@ -1901,7 +2191,7 @@ function maskStringByPatternBasedRule(value, rule) {
1901
2191
  if (!patternEntries || patternEntries.length === 0) {
1902
2192
  return mode === "partial" && value ? value[0] + "*****" : "*****";
1903
2193
  }
1904
- const compiledPatterns = compilePatternEntries(patternEntries);
2194
+ const compiledPatterns = getCompiledPatternsForRule(rule);
1905
2195
  if (!compiledPatterns) {
1906
2196
  return value;
1907
2197
  }
@@ -1966,7 +2256,7 @@ var BrizzSimpleLogRecordProcessor = class extends import_sdk_logs.SimpleLogRecor
1966
2256
  if (maskingConfig) {
1967
2257
  maskLog(logRecord, maskingConfig);
1968
2258
  }
1969
- const associationProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
2259
+ const associationProperties = import_api10.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1970
2260
  if (associationProperties) {
1971
2261
  for (const [key, value] of Object.entries(associationProperties)) {
1972
2262
  logRecord.setAttribute(`${BRIZZ}.${key}`, value);
@@ -1986,7 +2276,7 @@ var BrizzBatchLogRecordProcessor = class extends import_sdk_logs.BatchLogRecordP
1986
2276
  if (maskingConfig) {
1987
2277
  maskLog(logRecord, maskingConfig);
1988
2278
  }
1989
- const associationProperties = import_api9.context.active().getValue(PROPERTIES_CONTEXT_KEY);
2279
+ const associationProperties = import_api10.context.active().getValue(PROPERTIES_CONTEXT_KEY);
1990
2280
  if (associationProperties) {
1991
2281
  for (const [key, value] of Object.entries(associationProperties)) {
1992
2282
  logRecord.setAttribute(`${BRIZZ}.${key}`, value);
@@ -2015,6 +2305,11 @@ function maskLog(logRecord, config) {
2015
2305
  for (const [key, value] of Object.entries(maskedAttributes)) {
2016
2306
  newAttributes[key] = value;
2017
2307
  }
2308
+ for (const [key, value] of Object.entries(logRecord.attributes)) {
2309
+ if (key.startsWith(INTERNAL_EVENT_PREFIX)) {
2310
+ newAttributes[key] = value;
2311
+ }
2312
+ }
2018
2313
  logRecord.setAttributes(newAttributes);
2019
2314
  }
2020
2315
  }
@@ -2204,6 +2499,11 @@ var LoggingModule = class _LoggingModule {
2204
2499
  function emitEvent(name, attributes, body, severityNumber = import_api_logs.SeverityNumber.INFO) {
2205
2500
  return LoggingModule.getInstance().emitEvent(name, attributes, body, severityNumber);
2206
2501
  }
2502
+ function emitEventWithSessionId(sessionId, name, attributes, body, severityNumber = import_api_logs.SeverityNumber.INFO) {
2503
+ return callWithSessionId(sessionId, () => {
2504
+ LoggingModule.getInstance().emitEvent(name, attributes, body, severityNumber);
2505
+ });
2506
+ }
2207
2507
 
2208
2508
  // src/internal/sdk.ts
2209
2509
  init_logger();
@@ -2386,12 +2686,12 @@ var BrizzSpanExporter = class {
2386
2686
  };
2387
2687
 
2388
2688
  // src/internal/trace/processors/span-processor.ts
2389
- var import_api10 = require("@opentelemetry/api");
2689
+ var import_api11 = require("@opentelemetry/api");
2390
2690
  var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
2391
2691
  init_logger();
2392
2692
  init_semantic_conventions2();
2393
2693
  function applyContextAttributes(span) {
2394
- const sessionProperties = import_api10.context.active().getValue(PROPERTIES_CONTEXT_KEY);
2694
+ const sessionProperties = import_api11.context.active().getValue(PROPERTIES_CONTEXT_KEY);
2395
2695
  if (sessionProperties) {
2396
2696
  for (const [key, value] of Object.entries(sessionProperties)) {
2397
2697
  span.setAttribute(`${BRIZZ}.${key}`, value);
@@ -2576,214 +2876,6 @@ function getSpanProcessor() {
2576
2876
  return TracingModule.getInstance().getSpanProcessor();
2577
2877
  }
2578
2878
 
2579
- // src/internal/trace/session.ts
2580
- var import_api11 = require("@opentelemetry/api");
2581
- init_semantic_conventions2();
2582
- function setCurrentSpanCustomProperties(properties) {
2583
- const current = import_api11.trace.getActiveSpan();
2584
- if (!current || !current.isRecording()) {
2585
- return;
2586
- }
2587
- for (const [key, value] of Object.entries(properties)) {
2588
- try {
2589
- current.setAttribute(`${BRIZZ}.${key}`, value);
2590
- } catch {
2591
- }
2592
- }
2593
- }
2594
- function callWithProperties(properties, fn, thisArg, ...args) {
2595
- const base = import_api11.context.active();
2596
- const prev = base.getValue(PROPERTIES_CONTEXT_KEY);
2597
- const merged = prev ? { ...prev, ...properties } : properties;
2598
- const next = base.setValue(PROPERTIES_CONTEXT_KEY, merged);
2599
- return import_api11.context.with(next, fn, thisArg, ...args);
2600
- }
2601
- function withProperties(properties, fn, thisArg) {
2602
- return function wrapped(...args) {
2603
- return callWithProperties(
2604
- properties,
2605
- fn,
2606
- thisArg !== void 0 ? thisArg : this,
2607
- ...args
2608
- );
2609
- };
2610
- }
2611
- function withSessionId(sessionId, fn, thisArg, extraProperties) {
2612
- const properties = { [SESSION_ID]: sessionId, ...extraProperties };
2613
- return withProperties(properties, fn, thisArg);
2614
- }
2615
- function callWithSessionId(sessionId, fn, thisArg, ...args) {
2616
- return callWithProperties({ [SESSION_ID]: sessionId }, fn, thisArg, ...args);
2617
- }
2618
- var Session = class {
2619
- sessionId;
2620
- span;
2621
- inputs = [];
2622
- outputs = [];
2623
- inputContexts = [];
2624
- outputContexts = [];
2625
- constructor(sessionId, span) {
2626
- this.sessionId = sessionId;
2627
- this.span = span;
2628
- }
2629
- /**
2630
- * Append a user turn to session input tracking.
2631
- *
2632
- * Each call appends one element to `brizz.session.input` (the text) AND one
2633
- * element to `brizz.session.input.context` (the per-turn context bag). The
2634
- * two arrays stay index-aligned — the ingestion pipeline zips them together
2635
- * so the i-th context bag lands on the i-th user_display conversation item's
2636
- * `span_attributes` map.
2637
- *
2638
- * @param text - Text to append (null becomes a null/"hide marker")
2639
- * @param context - Optional per-turn context bag to attach to this turn
2640
- */
2641
- setInput(text, context6) {
2642
- this.inputs.push(text);
2643
- this.inputContexts.push(context6 ?? {});
2644
- this.span.setAttribute(SESSION_INPUT, JSON.stringify(this.inputs));
2645
- this.span.setAttribute(SESSION_INPUT_CONTEXT, JSON.stringify(this.inputContexts));
2646
- }
2647
- /**
2648
- * Append an assistant turn to session output tracking.
2649
- *
2650
- * Symmetric to {@link setInput} — appends one text element and one
2651
- * context-bag element to the index-aligned `brizz.session.output` /
2652
- * `brizz.session.output.context` arrays.
2653
- *
2654
- * @param text - Text to append (null becomes a null/"hide marker")
2655
- * @param context - Optional per-turn context bag to attach to this turn
2656
- */
2657
- setOutput(text, context6) {
2658
- this.outputs.push(text);
2659
- this.outputContexts.push(context6 ?? {});
2660
- this.span.setAttribute(SESSION_OUTPUT, JSON.stringify(this.outputs));
2661
- this.span.setAttribute(SESSION_OUTPUT_CONTEXT, JSON.stringify(this.outputContexts));
2662
- }
2663
- /**
2664
- * Set the session title on the span.
2665
- *
2666
- * @param title - The generated title string
2667
- */
2668
- setTitle(title) {
2669
- this.span.setAttribute(SESSION_TITLE, title);
2670
- }
2671
- /**
2672
- * Update custom properties on the session span.
2673
- * Properties are prefixed with 'brizz.'.
2674
- *
2675
- * @param properties - Key-value properties to set on the session
2676
- */
2677
- updateProperties(properties) {
2678
- for (const [key, value] of Object.entries(properties)) {
2679
- this.span.setAttribute(`${BRIZZ}.${key}`, value);
2680
- }
2681
- }
2682
- };
2683
- var SessionTitle = class {
2684
- span;
2685
- constructor(span) {
2686
- this.span = span;
2687
- }
2688
- /**
2689
- * Set the generated title on the wrapper span.
2690
- *
2691
- * @param title - The generated title string
2692
- */
2693
- setTitle(title) {
2694
- this.span.setAttribute(SESSION_TITLE, title);
2695
- }
2696
- };
2697
- function getActiveSession() {
2698
- return import_api11.context.active().getValue(SESSION_OBJECT_CONTEXT_KEY);
2699
- }
2700
- function startSession(sessionId, callback, extraProperties, options) {
2701
- const isTitle = options?.mode === "title";
2702
- const spanName = isTitle ? SESSION_TITLE_SPAN_NAME : SESSION_SPAN_NAME;
2703
- const tracer = import_api11.trace.getTracer("@brizz/sdk");
2704
- return tracer.startActiveSpan(spanName, (span) => {
2705
- span.setAttribute(`${BRIZZ}.${SESSION_ID}`, sessionId);
2706
- if (extraProperties) {
2707
- for (const [key, value] of Object.entries(extraProperties)) {
2708
- span.setAttribute(`${BRIZZ}.${key}`, value);
2709
- }
2710
- }
2711
- const session = new Session(sessionId, span);
2712
- const contextProperties = { [SESSION_ID]: sessionId };
2713
- if (isTitle) {
2714
- contextProperties[SESSION_TITLE_GENERATION] = "true";
2715
- }
2716
- if (extraProperties) {
2717
- for (const [key, value] of Object.entries(extraProperties)) {
2718
- contextProperties[key] = String(value);
2719
- }
2720
- }
2721
- return callWithProperties(contextProperties, () => {
2722
- const sessionCtx = import_api11.context.active().setValue(SESSION_OBJECT_CONTEXT_KEY, session);
2723
- return import_api11.context.with(sessionCtx, () => {
2724
- try {
2725
- const result = callback(session);
2726
- if (result && typeof result.then === "function") {
2727
- return result.then((value) => {
2728
- span.end();
2729
- return value;
2730
- }).catch((error) => {
2731
- span.recordException(error);
2732
- span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
2733
- span.end();
2734
- throw error;
2735
- });
2736
- }
2737
- span.end();
2738
- return result;
2739
- } catch (error) {
2740
- span.recordException(error);
2741
- span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
2742
- span.end();
2743
- throw error;
2744
- }
2745
- });
2746
- });
2747
- });
2748
- }
2749
- function startSessionTitle(callback, options) {
2750
- const resolvedSessionId = options?.sessionId ?? getActiveSession()?.sessionId;
2751
- const tracer = import_api11.trace.getTracer("@brizz/sdk");
2752
- return tracer.startActiveSpan(SESSION_TITLE_SPAN_NAME, (span) => {
2753
- if (resolvedSessionId) {
2754
- span.setAttribute(`${BRIZZ}.${SESSION_ID}`, resolvedSessionId);
2755
- }
2756
- const sessionTitle = new SessionTitle(span);
2757
- const properties = { [SESSION_TITLE_GENERATION]: "true" };
2758
- if (resolvedSessionId) {
2759
- properties[SESSION_ID] = resolvedSessionId;
2760
- }
2761
- return callWithProperties(properties, () => {
2762
- try {
2763
- const result = callback(sessionTitle);
2764
- if (result && typeof result.then === "function") {
2765
- return result.then((value) => {
2766
- span.end();
2767
- return value;
2768
- }).catch((error) => {
2769
- span.recordException(error);
2770
- span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
2771
- span.end();
2772
- throw error;
2773
- });
2774
- }
2775
- span.end();
2776
- return result;
2777
- } catch (error) {
2778
- span.recordException(error);
2779
- span.setStatus({ code: import_api11.SpanStatusCode.ERROR });
2780
- span.end();
2781
- throw error;
2782
- }
2783
- });
2784
- });
2785
- }
2786
-
2787
2879
  // src/internal/sdk.ts
2788
2880
  init_version();
2789
2881
  var _Brizz = class __Brizz {
@@ -3043,10 +3135,13 @@ var init_exports = {};
3043
3135
  Session,
3044
3136
  SessionTitle,
3045
3137
  SeverityNumber,
3138
+ addExternalLink,
3139
+ callWithMute,
3046
3140
  callWithProperties,
3047
3141
  callWithSessionId,
3048
3142
  detectRuntime,
3049
3143
  emitEvent,
3144
+ emitEventWithSessionId,
3050
3145
  getActiveSession,
3051
3146
  getLogLevel,
3052
3147
  getMetricsExporter,
@@ -3061,6 +3156,7 @@ var init_exports = {};
3061
3156
  setLogLevel,
3062
3157
  startSession,
3063
3158
  startSessionTitle,
3159
+ withMute,
3064
3160
  withProperties,
3065
3161
  withSessionId
3066
3162
  });