braintrust 3.25.0 → 3.27.0

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.
Files changed (79) hide show
  1. package/NOTICE +6 -0
  2. package/dev/dist/index.d.mts +130 -2
  3. package/dev/dist/index.d.ts +130 -2
  4. package/dev/dist/index.js +4133 -1421
  5. package/dev/dist/index.mjs +3242 -530
  6. package/dist/apply-auto-instrumentation.js +526 -426
  7. package/dist/apply-auto-instrumentation.mjs +329 -229
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +1198 -364
  9. package/dist/auto-instrumentations/bundler/esbuild.d.mts +4 -4
  10. package/dist/auto-instrumentations/bundler/esbuild.d.ts +4 -4
  11. package/dist/auto-instrumentations/bundler/esbuild.mjs +6 -8
  12. package/dist/auto-instrumentations/bundler/next.cjs +1227 -413
  13. package/dist/auto-instrumentations/bundler/next.mjs +7 -29
  14. package/dist/auto-instrumentations/bundler/rollup.cjs +1198 -364
  15. package/dist/auto-instrumentations/bundler/rollup.d.mts +4 -4
  16. package/dist/auto-instrumentations/bundler/rollup.d.ts +4 -4
  17. package/dist/auto-instrumentations/bundler/rollup.mjs +6 -8
  18. package/dist/auto-instrumentations/bundler/vite.cjs +1249 -387
  19. package/dist/auto-instrumentations/bundler/vite.d.mts +4 -4
  20. package/dist/auto-instrumentations/bundler/vite.d.ts +4 -4
  21. package/dist/auto-instrumentations/bundler/vite.mjs +34 -8
  22. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +1368 -324
  23. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +20 -12
  24. package/dist/auto-instrumentations/bundler/webpack.cjs +1198 -364
  25. package/dist/auto-instrumentations/bundler/webpack.d.mts +4 -4
  26. package/dist/auto-instrumentations/bundler/webpack.d.ts +4 -4
  27. package/dist/auto-instrumentations/bundler/webpack.mjs +6 -4
  28. package/dist/auto-instrumentations/chunk-2AMDGD65.mjs +1396 -0
  29. package/dist/auto-instrumentations/{chunk-7P6563SW.mjs → chunk-BW33ULMW.mjs} +2 -6
  30. package/dist/auto-instrumentations/{chunk-M6DLIJ2Z.mjs → chunk-I55G56ZL.mjs} +114 -221
  31. package/dist/auto-instrumentations/chunk-JPUFNW7X.mjs +649 -0
  32. package/dist/auto-instrumentations/{chunk-JPVCUKTY.mjs → chunk-XEYKUBLY.mjs} +191 -73
  33. package/dist/auto-instrumentations/{chunk-CZ24KNHT.mjs → chunk-ZNHTSSGI.mjs} +231 -69
  34. package/dist/auto-instrumentations/hook.mjs +406 -183
  35. package/dist/auto-instrumentations/index.cjs +853 -49
  36. package/dist/auto-instrumentations/index.d.mts +10 -2
  37. package/dist/auto-instrumentations/index.d.ts +10 -2
  38. package/dist/auto-instrumentations/index.mjs +10 -1
  39. package/dist/auto-instrumentations/loader/cjs-patch.cjs +566 -221
  40. package/dist/auto-instrumentations/loader/cjs-patch.d.mts +2 -2
  41. package/dist/auto-instrumentations/loader/cjs-patch.d.ts +2 -2
  42. package/dist/auto-instrumentations/loader/cjs-patch.mjs +3 -2
  43. package/dist/auto-instrumentations/loader/esm-hook.mjs +1 -1
  44. package/dist/auto-instrumentations/plugin-B-aZh7EP.d.ts +30 -0
  45. package/dist/auto-instrumentations/plugin-Bnj4E_6B.d.mts +30 -0
  46. package/dist/auto-instrumentations/{types-RNPaKi9o.d.mts → types-C1fVeiCp.d.mts} +1 -1
  47. package/dist/auto-instrumentations/{types-RNPaKi9o.d.ts → types-C1fVeiCp.d.ts} +1 -1
  48. package/dist/browser.d.mts +871 -199
  49. package/dist/browser.d.ts +871 -199
  50. package/dist/browser.js +3737 -549
  51. package/dist/browser.mjs +3737 -549
  52. package/dist/{chunk-ABR2QWDP.mjs → chunk-CZM5JIQL.mjs} +788 -132
  53. package/dist/{chunk-P25IOOU4.js → chunk-MF7NU6BT.js} +795 -139
  54. package/dist/{chunk-GSIDVFE6.js → chunk-QRHGVBKU.js} +3580 -1463
  55. package/dist/{chunk-2SANLSWX.mjs → chunk-YKD22IMR.mjs} +2505 -388
  56. package/dist/cli.js +3244 -533
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +3737 -552
  60. package/dist/edge-light.mjs +3737 -552
  61. package/dist/index.d.mts +871 -199
  62. package/dist/index.d.ts +871 -199
  63. package/dist/index.js +893 -446
  64. package/dist/index.mjs +463 -16
  65. package/dist/instrumentation/index.d.mts +138 -6
  66. package/dist/instrumentation/index.d.ts +138 -6
  67. package/dist/instrumentation/index.js +3362 -559
  68. package/dist/instrumentation/index.mjs +3362 -559
  69. package/dist/vitest-evals-reporter.js +45 -43
  70. package/dist/vitest-evals-reporter.mjs +5 -3
  71. package/dist/workerd.d.mts +1 -1
  72. package/dist/workerd.d.ts +1 -1
  73. package/dist/workerd.js +3737 -552
  74. package/dist/workerd.mjs +3737 -552
  75. package/licenses/node-diagnostics-channel/LICENSE +19 -0
  76. package/package.json +34 -35
  77. package/dist/auto-instrumentations/chunk-VT6DDNKM.mjs +0 -856
  78. package/dist/auto-instrumentations/plugin-D0KHwSJv.d.mts +0 -44
  79. package/dist/auto-instrumentations/plugin-G6fgxk1b.d.ts +0 -44
package/dist/cli.js CHANGED
@@ -1236,7 +1236,7 @@ var require_package = __commonJS({
1236
1236
  "package.json"(exports2, module2) {
1237
1237
  module2.exports = {
1238
1238
  name: "braintrust",
1239
- version: "3.25.0",
1239
+ version: "3.27.0",
1240
1240
  description: "SDK for integrating Braintrust",
1241
1241
  repository: {
1242
1242
  type: "git",
@@ -1434,7 +1434,7 @@ var require_package = __commonJS({
1434
1434
  "eslint-plugin-node-import": "^1.0.5",
1435
1435
  openai: "6.25.0",
1436
1436
  rollup: "^4.60.3",
1437
- tar: "^7.5.19",
1437
+ tar: "^7.5.22",
1438
1438
  tinybench: "^4.0.1",
1439
1439
  "ts-declaration-location": "^1.0.7",
1440
1440
  tsup: "^8.5.1",
@@ -1460,7 +1460,6 @@ var require_package = __commonJS({
1460
1460
  "cli-progress": "^3.12.0",
1461
1461
  "cli-table3": "^0.6.5",
1462
1462
  cors: "^2.8.5",
1463
- "dc-browser": "^1.0.4",
1464
1463
  dotenv: "^16.4.5",
1465
1464
  esbuild: "0.28.1",
1466
1465
  esquery: "^1.7.0",
@@ -1524,84 +1523,668 @@ var import_pluralize4 = __toESM(require("pluralize"));
1524
1523
  // src/logger.ts
1525
1524
  var import_uuid2 = require("uuid");
1526
1525
 
1527
- // src/isomorph.ts
1528
- var DefaultAsyncLocalStorage = class {
1529
- constructor() {
1530
- }
1531
- enterWith(_) {
1532
- }
1533
- run(_, callback) {
1534
- return callback();
1526
+ // src/global-instrumentation-hooks.ts
1527
+ var GLOBAL_INSTRUMENTATION_HOOKS_KEY = "__braintrust_instrumentation_hooks";
1528
+ var GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION = 1;
1529
+ var GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND = "braintrust.global-instrumentation-hooks.registry";
1530
+ var GLOBAL_INSTRUMENTATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.hook";
1531
+ var GLOBAL_INVOCATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.invocation-hook";
1532
+ var registryBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND);
1533
+ var hookBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOK_BRAND);
1534
+ var invocationHookBrand = Symbol.for(GLOBAL_INVOCATION_HOOK_BRAND);
1535
+ var errorReporter;
1536
+ function setGlobalHookErrorReporter(reporter) {
1537
+ const previousReporter = errorReporter;
1538
+ errorReporter = reporter;
1539
+ return () => {
1540
+ if (errorReporter === reporter) {
1541
+ errorReporter = previousReporter;
1542
+ }
1543
+ };
1544
+ }
1545
+ function reportError(error2) {
1546
+ try {
1547
+ errorReporter?.(error2);
1548
+ } catch {
1535
1549
  }
1536
- getStore() {
1537
- return void 0;
1550
+ }
1551
+ function setContextValue(context2, key, value) {
1552
+ try {
1553
+ context2[key] = value;
1554
+ } catch (error2) {
1555
+ reportError(error2);
1538
1556
  }
1539
- };
1540
- var DefaultChannel = class {
1557
+ }
1558
+ function wrapStoreRun(store, message, next, transform) {
1559
+ return () => {
1560
+ let context2;
1561
+ try {
1562
+ context2 = transform ? transform(message) : message;
1563
+ } catch (error2) {
1564
+ reportError(error2);
1565
+ return next();
1566
+ }
1567
+ let called = false;
1568
+ let result;
1569
+ let providerError;
1570
+ let providerThrew = false;
1571
+ const runNext = () => {
1572
+ if (called) {
1573
+ reportError(
1574
+ new Error(
1575
+ "Instrumentation store invoked its callback more than once"
1576
+ )
1577
+ );
1578
+ if (providerThrew) {
1579
+ throw providerError;
1580
+ }
1581
+ return result;
1582
+ }
1583
+ called = true;
1584
+ try {
1585
+ result = next();
1586
+ return result;
1587
+ } catch (error2) {
1588
+ providerThrew = true;
1589
+ providerError = error2;
1590
+ throw error2;
1591
+ }
1592
+ };
1593
+ try {
1594
+ store.run(context2, runNext);
1595
+ } catch (error2) {
1596
+ if (!providerThrew || error2 !== providerError) {
1597
+ reportError(error2);
1598
+ }
1599
+ }
1600
+ if (!called) {
1601
+ reportError(
1602
+ new Error("Instrumentation store did not invoke its callback")
1603
+ );
1604
+ return runNext();
1605
+ }
1606
+ if (providerThrew) {
1607
+ throw providerError;
1608
+ }
1609
+ return result;
1610
+ };
1611
+ }
1612
+ var HookChannel = class {
1541
1613
  constructor(name) {
1542
1614
  this.name = name;
1543
1615
  }
1544
1616
  name;
1545
- hasSubscribers = false;
1546
- subscribe(_subscription) {
1617
+ subscribers = [];
1618
+ stores = /* @__PURE__ */ new Map();
1619
+ get hasSubscribers() {
1620
+ return this.subscribers.length > 0 || this.stores.size > 0;
1547
1621
  }
1548
- unsubscribe(_subscription) {
1549
- return false;
1622
+ subscribe(subscription) {
1623
+ if (typeof subscription !== "function") {
1624
+ throw new TypeError("subscription must be a function");
1625
+ }
1626
+ this.subscribers = [...this.subscribers, subscription];
1550
1627
  }
1551
- bindStore(_store, _transform) {
1628
+ unsubscribe(subscription) {
1629
+ const index = this.subscribers.indexOf(subscription);
1630
+ if (index === -1) {
1631
+ return false;
1632
+ }
1633
+ this.subscribers = [
1634
+ ...this.subscribers.slice(0, index),
1635
+ ...this.subscribers.slice(index + 1)
1636
+ ];
1637
+ return true;
1552
1638
  }
1553
- unbindStore(_store) {
1554
- return false;
1639
+ bindStore(store, transform) {
1640
+ if (!store || typeof store.run !== "function") {
1641
+ throw new TypeError("store must have a run method");
1642
+ }
1643
+ this.stores.set(
1644
+ store,
1645
+ transform
1646
+ );
1555
1647
  }
1556
- publish(_message) {
1648
+ unbindStore(store) {
1649
+ return this.stores.delete(store);
1557
1650
  }
1558
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1559
- runStores(_message, fn, thisArg, ...args) {
1560
- return fn.apply(thisArg, args);
1651
+ publish(message) {
1652
+ const subscribers = this.subscribers;
1653
+ for (const subscriber of subscribers) {
1654
+ try {
1655
+ subscriber(message, this.name);
1656
+ } catch (error2) {
1657
+ reportError(error2);
1658
+ }
1659
+ }
1660
+ }
1661
+ runStores(message, fn, thisArg, ...args) {
1662
+ let run2 = () => {
1663
+ this.publish(message);
1664
+ return Reflect.apply(fn, thisArg, args);
1665
+ };
1666
+ for (const [store, transform] of this.stores.entries()) {
1667
+ run2 = wrapStoreRun(store, message, run2, transform);
1668
+ }
1669
+ return run2();
1670
+ }
1671
+ };
1672
+ var traceEvents = [
1673
+ "start",
1674
+ "end",
1675
+ "asyncStart",
1676
+ "asyncEnd",
1677
+ "error"
1678
+ ];
1679
+ function traceInvocation(hook, operator, target, thisArg, args, additional, callbackIndex = -1) {
1680
+ const context2 = {
1681
+ ...additional,
1682
+ arguments: args,
1683
+ self: thisArg
1684
+ };
1685
+ const invoke2 = () => hook.invoke(target, thisArg, args, additional);
1686
+ if (operator === "traceCallback") {
1687
+ return hook.traceCallback(invoke2, callbackIndex, context2);
1688
+ }
1689
+ if (operator === "tracePromise") {
1690
+ return hook.tracePromise(invoke2, context2);
1691
+ }
1692
+ return hook.traceSync(invoke2, context2);
1693
+ }
1694
+ var InvocationHook = class {
1695
+ interceptors = [];
1696
+ get hasInterceptors() {
1697
+ return this.interceptors.length > 0;
1698
+ }
1699
+ intercept(interceptor) {
1700
+ if (typeof interceptor !== "function") {
1701
+ throw new TypeError("interceptor must be a function");
1702
+ }
1703
+ this.interceptors = [...this.interceptors, interceptor];
1704
+ let active = true;
1705
+ return () => {
1706
+ if (!active) {
1707
+ return;
1708
+ }
1709
+ active = false;
1710
+ const index = this.interceptors.indexOf(interceptor);
1711
+ if (index !== -1) {
1712
+ this.interceptors = [
1713
+ ...this.interceptors.slice(0, index),
1714
+ ...this.interceptors.slice(index + 1)
1715
+ ];
1716
+ }
1717
+ };
1718
+ }
1719
+ invoke(target, thisArg, args, additional) {
1720
+ const interceptors = this.interceptors;
1721
+ if (interceptors.length === 0) {
1722
+ return Reflect.apply(target, thisArg, args);
1723
+ }
1724
+ let next = target;
1725
+ for (let index = interceptors.length - 1; index >= 0; index -= 1) {
1726
+ const interceptor = interceptors[index];
1727
+ const downstream = next;
1728
+ next = function(...nextArgs) {
1729
+ return interceptor(downstream, this, nextArgs, additional);
1730
+ };
1731
+ }
1732
+ return Reflect.apply(next, thisArg, args);
1561
1733
  }
1562
1734
  };
1563
- var DefaultTracingChannel = class {
1735
+ var TracingHook = class {
1564
1736
  start;
1565
1737
  end;
1566
1738
  asyncStart;
1567
1739
  asyncEnd;
1568
1740
  error;
1741
+ invocationHook = new InvocationHook();
1569
1742
  constructor(nameOrChannels) {
1743
+ Object.defineProperty(this, hookBrand, {
1744
+ configurable: false,
1745
+ enumerable: false,
1746
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
1747
+ writable: false
1748
+ });
1749
+ Object.defineProperty(this, invocationHookBrand, {
1750
+ configurable: false,
1751
+ enumerable: false,
1752
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
1753
+ writable: false
1754
+ });
1570
1755
  if (typeof nameOrChannels === "string") {
1571
- this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
1572
- this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
1573
- this.asyncStart = new DefaultChannel(
1574
- `tracing:${nameOrChannels}:asyncStart`
1575
- );
1576
- this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
1577
- this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
1756
+ this.start = new HookChannel(`tracing:${nameOrChannels}:start`);
1757
+ this.end = new HookChannel(`tracing:${nameOrChannels}:end`);
1758
+ this.asyncStart = new HookChannel(`tracing:${nameOrChannels}:asyncStart`);
1759
+ this.asyncEnd = new HookChannel(`tracing:${nameOrChannels}:asyncEnd`);
1760
+ this.error = new HookChannel(`tracing:${nameOrChannels}:error`);
1578
1761
  return;
1579
1762
  }
1580
- this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
1581
- this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
1582
- this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
1583
- this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
1584
- this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
1763
+ this.start = nameOrChannels.start ?? new HookChannel("tracing:start");
1764
+ this.end = nameOrChannels.end ?? new HookChannel("tracing:end");
1765
+ this.asyncStart = nameOrChannels.asyncStart ?? new HookChannel("tracing:asyncStart");
1766
+ this.asyncEnd = nameOrChannels.asyncEnd ?? new HookChannel("tracing:asyncEnd");
1767
+ this.error = nameOrChannels.error ?? new HookChannel("tracing:error");
1585
1768
  }
1586
1769
  get hasSubscribers() {
1587
1770
  return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
1588
1771
  }
1589
- subscribe(_handlers) {
1772
+ get hasInterceptors() {
1773
+ return this.invocationHook.hasInterceptors;
1774
+ }
1775
+ intercept(interceptor) {
1776
+ return this.invocationHook.intercept(interceptor);
1777
+ }
1778
+ invoke(target, thisArg, args, additional) {
1779
+ return this.invocationHook.invoke(target, thisArg, args, additional);
1780
+ }
1781
+ traceInvocation(operator, target, thisArg, args, additional, callbackIndex = -1) {
1782
+ return traceInvocation(
1783
+ this,
1784
+ operator,
1785
+ target,
1786
+ thisArg,
1787
+ args,
1788
+ additional,
1789
+ callbackIndex
1790
+ );
1791
+ }
1792
+ subscribe(handlers) {
1793
+ for (const eventName of traceEvents) {
1794
+ const handler = handlers[eventName];
1795
+ if (handler) {
1796
+ this[eventName].subscribe(handler);
1797
+ }
1798
+ }
1799
+ }
1800
+ unsubscribe(handlers) {
1801
+ let done = true;
1802
+ for (const eventName of traceEvents) {
1803
+ const handler = handlers[eventName];
1804
+ if (handler && !this[eventName].unsubscribe(handler)) {
1805
+ done = false;
1806
+ }
1807
+ }
1808
+ return done;
1809
+ }
1810
+ traceSync(fn, message = {}, thisArg, ...args) {
1811
+ if (!this.hasSubscribers) {
1812
+ return Reflect.apply(fn, thisArg, args);
1813
+ }
1814
+ const context2 = message;
1815
+ return this.start.runStores(message, () => {
1816
+ try {
1817
+ const result = Reflect.apply(fn, thisArg, args);
1818
+ setContextValue(context2, "result", result);
1819
+ return result;
1820
+ } catch (error2) {
1821
+ setContextValue(context2, "error", error2);
1822
+ this.error.publish(message);
1823
+ throw error2;
1824
+ } finally {
1825
+ this.end.publish(message);
1826
+ }
1827
+ });
1828
+ }
1829
+ tracePromise(fn, message = {}, thisArg, ...args) {
1830
+ if (!this.hasSubscribers) {
1831
+ return Reflect.apply(fn, thisArg, args);
1832
+ }
1833
+ const context2 = message;
1834
+ return this.start.runStores(message, () => {
1835
+ let result;
1836
+ try {
1837
+ result = Reflect.apply(fn, thisArg, args);
1838
+ } catch (error2) {
1839
+ setContextValue(context2, "error", error2);
1840
+ this.error.publish(message);
1841
+ this.end.publish(message);
1842
+ throw error2;
1843
+ }
1844
+ this.end.publish(message);
1845
+ if (!result || typeof result !== "object" && typeof result !== "function") {
1846
+ setContextValue(context2, "result", result);
1847
+ this.asyncStart.publish(message);
1848
+ this.asyncEnd.publish(message);
1849
+ return result;
1850
+ }
1851
+ let terminalPublished = false;
1852
+ const finishUnobservedResult = (error2) => {
1853
+ reportError(error2);
1854
+ if (!terminalPublished) {
1855
+ terminalPublished = true;
1856
+ setContextValue(context2, "result", result);
1857
+ this.asyncStart.publish(message);
1858
+ this.asyncEnd.publish(message);
1859
+ }
1860
+ return result;
1861
+ };
1862
+ let then;
1863
+ try {
1864
+ then = result.then;
1865
+ } catch (error2) {
1866
+ return finishUnobservedResult(error2);
1867
+ }
1868
+ if (typeof then !== "function") {
1869
+ setContextValue(context2, "result", result);
1870
+ this.asyncStart.publish(message);
1871
+ this.asyncEnd.publish(message);
1872
+ return result;
1873
+ }
1874
+ const resolve2 = (resolved) => {
1875
+ if (!terminalPublished) {
1876
+ terminalPublished = true;
1877
+ setContextValue(context2, "result", resolved);
1878
+ this.asyncStart.publish(message);
1879
+ this.asyncEnd.publish(message);
1880
+ }
1881
+ return resolved;
1882
+ };
1883
+ let rejectionThrown = false;
1884
+ let rejectionError;
1885
+ const reject2 = (error2) => {
1886
+ if (!terminalPublished) {
1887
+ terminalPublished = true;
1888
+ setContextValue(context2, "error", error2);
1889
+ this.error.publish(message);
1890
+ this.asyncStart.publish(message);
1891
+ this.asyncEnd.publish(message);
1892
+ }
1893
+ rejectionThrown = true;
1894
+ rejectionError = error2;
1895
+ throw error2;
1896
+ };
1897
+ let isPlainPromise;
1898
+ try {
1899
+ isPlainPromise = result instanceof Promise && result.constructor === Promise;
1900
+ } catch (error2) {
1901
+ return finishUnobservedResult(error2);
1902
+ }
1903
+ try {
1904
+ if (isPlainPromise) {
1905
+ return Reflect.apply(then, result, [resolve2, reject2]);
1906
+ }
1907
+ Reflect.apply(then, result, [
1908
+ resolve2,
1909
+ (error2) => {
1910
+ try {
1911
+ reject2(error2);
1912
+ } catch {
1913
+ }
1914
+ }
1915
+ ]);
1916
+ } catch (error2) {
1917
+ if (rejectionThrown && error2 === rejectionError) {
1918
+ return result;
1919
+ }
1920
+ return finishUnobservedResult(error2);
1921
+ }
1922
+ return result;
1923
+ });
1924
+ }
1925
+ traceCallback(fn, position = -1, message = {}, thisArg, ...args) {
1926
+ if (!this.hasSubscribers) {
1927
+ return Reflect.apply(fn, thisArg, args);
1928
+ }
1929
+ const context2 = message;
1930
+ const callArgs = args.length > 0 ? args : context2.arguments ?? args;
1931
+ const callback = Array.prototype.at.call(callArgs, position);
1932
+ if (typeof callback !== "function") {
1933
+ return Reflect.apply(fn, thisArg, args);
1934
+ }
1935
+ const { asyncStart, asyncEnd, error: errorChannel } = this;
1936
+ function wrappedCallback(error2, result) {
1937
+ if (error2) {
1938
+ setContextValue(context2, "error", error2);
1939
+ errorChannel.publish(message);
1940
+ } else {
1941
+ setContextValue(context2, "result", result);
1942
+ }
1943
+ return asyncStart.runStores(message, () => {
1944
+ try {
1945
+ return Reflect.apply(callback, this, arguments);
1946
+ } finally {
1947
+ asyncEnd.publish(message);
1948
+ }
1949
+ });
1950
+ }
1951
+ Array.prototype.splice.call(callArgs, position, 1, wrappedCallback);
1952
+ return this.start.runStores(message, () => {
1953
+ try {
1954
+ return Reflect.apply(fn, thisArg, args);
1955
+ } catch (error2) {
1956
+ setContextValue(context2, "error", error2);
1957
+ this.error.publish(message);
1958
+ throw error2;
1959
+ } finally {
1960
+ this.end.publish(message);
1961
+ }
1962
+ });
1590
1963
  }
1591
- unsubscribe(_handlers) {
1964
+ };
1965
+ var inertChannel = Object.freeze({
1966
+ name: "braintrust:inert",
1967
+ hasSubscribers: false,
1968
+ subscribe() {
1969
+ },
1970
+ unsubscribe() {
1971
+ return false;
1972
+ },
1973
+ bindStore() {
1974
+ },
1975
+ unbindStore() {
1592
1976
  return false;
1977
+ },
1978
+ publish() {
1979
+ },
1980
+ runStores(_message, fn, thisArg, ...args) {
1981
+ return Reflect.apply(fn, thisArg, args);
1593
1982
  }
1594
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1595
- traceSync(fn, _message, thisArg, ...args) {
1596
- return fn.apply(thisArg, args);
1983
+ });
1984
+ var inertTracingHook = new TracingHook({
1985
+ start: inertChannel,
1986
+ end: inertChannel,
1987
+ asyncStart: inertChannel,
1988
+ asyncEnd: inertChannel,
1989
+ error: inertChannel
1990
+ });
1991
+ function isHookChannel(value) {
1992
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
1993
+ return false;
1597
1994
  }
1598
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1599
- tracePromise(fn, _message, thisArg, ...args) {
1600
- return fn.apply(thisArg, args);
1995
+ try {
1996
+ const channel2 = value;
1997
+ return typeof channel2.hasSubscribers === "boolean" && typeof channel2.subscribe === "function" && typeof channel2.unsubscribe === "function" && typeof channel2.bindStore === "function" && typeof channel2.unbindStore === "function" && typeof channel2.publish === "function" && typeof channel2.runStores === "function";
1998
+ } catch {
1999
+ return false;
1601
2000
  }
1602
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1603
- traceCallback(fn, _position, _message, thisArg, ...args) {
1604
- return fn.apply(thisArg, args);
2001
+ }
2002
+ function hasTracingHookShape(value) {
2003
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
2004
+ return false;
2005
+ }
2006
+ try {
2007
+ const hook = value;
2008
+ return typeof hook.hasSubscribers === "boolean" && typeof hook.subscribe === "function" && typeof hook.unsubscribe === "function" && typeof hook.traceSync === "function" && typeof hook.tracePromise === "function" && typeof hook.traceCallback === "function" && isHookChannel(hook.start) && isHookChannel(hook.end) && isHookChannel(hook.asyncStart) && isHookChannel(hook.asyncEnd) && isHookChannel(hook.error);
2009
+ } catch {
2010
+ return false;
2011
+ }
2012
+ }
2013
+ function hasInvocationHookShape(value) {
2014
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
2015
+ return false;
2016
+ }
2017
+ try {
2018
+ const hook = value;
2019
+ return value[invocationHookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && typeof hook.hasInterceptors === "boolean" && typeof hook.intercept === "function" && typeof hook.invoke === "function";
2020
+ } catch {
2021
+ return false;
2022
+ }
2023
+ }
2024
+ function installInvocationHook(value) {
2025
+ const hasInvocationHook = hasInvocationHookShape(value);
2026
+ const invocationHook = new InvocationHook();
2027
+ try {
2028
+ if (!hasInvocationHook) {
2029
+ Object.defineProperties(value, {
2030
+ [invocationHookBrand]: {
2031
+ configurable: false,
2032
+ enumerable: false,
2033
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
2034
+ writable: false
2035
+ },
2036
+ hasInterceptors: {
2037
+ configurable: false,
2038
+ enumerable: false,
2039
+ get: () => invocationHook.hasInterceptors
2040
+ },
2041
+ intercept: {
2042
+ configurable: false,
2043
+ enumerable: false,
2044
+ value: invocationHook.intercept.bind(invocationHook),
2045
+ writable: false
2046
+ },
2047
+ invoke: {
2048
+ configurable: false,
2049
+ enumerable: false,
2050
+ value: invocationHook.invoke.bind(invocationHook),
2051
+ writable: false
2052
+ }
2053
+ });
2054
+ }
2055
+ if (typeof value.traceInvocation !== "function") {
2056
+ Object.defineProperty(value, "traceInvocation", {
2057
+ configurable: false,
2058
+ enumerable: false,
2059
+ value: traceInvocation.bind(void 0, value),
2060
+ writable: false
2061
+ });
2062
+ }
2063
+ } catch (error2) {
2064
+ reportError(error2);
2065
+ }
2066
+ }
2067
+ function isCompatibleTracingHook(value) {
2068
+ try {
2069
+ return value[hookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && hasTracingHookShape(value);
2070
+ } catch {
2071
+ return false;
2072
+ }
2073
+ }
2074
+ function isCompatibleHookRegistry(value) {
2075
+ try {
2076
+ return value instanceof Map && value[registryBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION;
2077
+ } catch {
2078
+ return false;
2079
+ }
2080
+ }
2081
+ function getHookRegistry() {
2082
+ let descriptor;
2083
+ try {
2084
+ descriptor = Object.getOwnPropertyDescriptor(
2085
+ globalThis,
2086
+ GLOBAL_INSTRUMENTATION_HOOKS_KEY
2087
+ );
2088
+ } catch (error2) {
2089
+ reportError(error2);
2090
+ return void 0;
2091
+ }
2092
+ if (descriptor && "value" in descriptor && isCompatibleHookRegistry(descriptor.value) && (descriptor.configurable || descriptor.enumerable === false)) {
2093
+ if (descriptor.configurable || descriptor.writable) {
2094
+ try {
2095
+ Object.defineProperty(globalThis, GLOBAL_INSTRUMENTATION_HOOKS_KEY, {
2096
+ configurable: false,
2097
+ enumerable: false,
2098
+ value: descriptor.value,
2099
+ writable: false
2100
+ });
2101
+ } catch (error2) {
2102
+ reportError(error2);
2103
+ return void 0;
2104
+ }
2105
+ }
2106
+ return descriptor.value;
2107
+ }
2108
+ if (descriptor && !descriptor.configurable) {
2109
+ reportError(new Error("Incompatible global instrumentation hook registry"));
2110
+ return void 0;
2111
+ }
2112
+ const registry2 = /* @__PURE__ */ new Map();
2113
+ try {
2114
+ Object.defineProperty(registry2, registryBrand, {
2115
+ configurable: false,
2116
+ enumerable: false,
2117
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
2118
+ writable: false
2119
+ });
2120
+ } catch (error2) {
2121
+ reportError(error2);
2122
+ return void 0;
2123
+ }
2124
+ try {
2125
+ Object.defineProperty(globalThis, GLOBAL_INSTRUMENTATION_HOOKS_KEY, {
2126
+ configurable: false,
2127
+ enumerable: false,
2128
+ value: registry2,
2129
+ writable: false
2130
+ });
2131
+ return registry2;
2132
+ } catch (error2) {
2133
+ reportError(error2);
2134
+ return void 0;
2135
+ }
2136
+ }
2137
+ function newGlobalTracingChannel(nameOrChannels) {
2138
+ if (typeof nameOrChannels !== "string") {
2139
+ return new TracingHook(nameOrChannels);
2140
+ }
2141
+ const registry2 = getHookRegistry();
2142
+ if (!registry2) {
2143
+ return inertTracingHook;
2144
+ }
2145
+ let existing;
2146
+ try {
2147
+ existing = Map.prototype.get.call(registry2, nameOrChannels);
2148
+ } catch (error2) {
2149
+ reportError(error2);
2150
+ return inertTracingHook;
2151
+ }
2152
+ if (isCompatibleTracingHook(existing)) {
2153
+ installInvocationHook(existing);
2154
+ return existing;
2155
+ }
2156
+ if (existing !== void 0) {
2157
+ reportError(
2158
+ new Error(`Invalid global instrumentation hook: ${nameOrChannels}`)
2159
+ );
2160
+ try {
2161
+ Map.prototype.delete.call(registry2, nameOrChannels);
2162
+ } catch (error2) {
2163
+ reportError(error2);
2164
+ return inertTracingHook;
2165
+ }
2166
+ }
2167
+ const hook = new TracingHook(nameOrChannels);
2168
+ try {
2169
+ Map.prototype.set.call(registry2, nameOrChannels, hook);
2170
+ } catch (error2) {
2171
+ reportError(error2);
2172
+ return inertTracingHook;
2173
+ }
2174
+ return hook;
2175
+ }
2176
+
2177
+ // src/isomorph.ts
2178
+ var DefaultAsyncLocalStorage = class {
2179
+ constructor() {
2180
+ }
2181
+ enterWith(_) {
2182
+ }
2183
+ run(_, callback) {
2184
+ return callback();
2185
+ }
2186
+ getStore() {
2187
+ return void 0;
1605
2188
  }
1606
2189
  };
1607
2190
  var iso = {
@@ -1614,7 +2197,7 @@ var iso = {
1614
2197
  getCallerLocation: () => void 0,
1615
2198
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
1616
2199
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1617
- newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
2200
+ newTracingChannel: (nameOrChannels) => newGlobalTracingChannel(nameOrChannels),
1618
2201
  processOn: (_0, _1) => {
1619
2202
  },
1620
2203
  basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
@@ -1727,6 +2310,9 @@ var debugLogger = {
1727
2310
  return createDebugLogger(state);
1728
2311
  }
1729
2312
  };
2313
+ setGlobalHookErrorReporter((error2) => {
2314
+ debugLogger.error("Global instrumentation hook error:", error2);
2315
+ });
1730
2316
 
1731
2317
  // src/queue.ts
1732
2318
  var DEFAULT_QUEUE_SIZE = 15e3;
@@ -3538,7 +4124,8 @@ var ApiKey = import_v36.z.object({
3538
4124
  user_email: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3539
4125
  user_given_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3540
4126
  user_family_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3541
- org_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
4127
+ org_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4128
+ expires_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
3542
4129
  });
3543
4130
  var TriggeredFunctionState = import_v36.z.object({
3544
4131
  triggered_xact_id: import_v36.z.string(),
@@ -3658,6 +4245,7 @@ var TopicMapData = import_v36.z.object({
3658
4245
  topic_names: import_v36.z.record(import_v36.z.string()).optional(),
3659
4246
  generation_settings: TopicMapGenerationSettings.optional(),
3660
4247
  disable_reconciliation: import_v36.z.boolean().optional(),
4248
+ reconcile_mode: import_v36.z.enum(["evolve", "names_only"]).optional(),
3661
4249
  distance_threshold: import_v36.z.number().optional(),
3662
4250
  btql_filter: import_v36.z.string().optional(),
3663
4251
  automation_btql_filter: import_v36.z.string().optional()
@@ -4238,7 +4826,12 @@ var ModelParams = import_v36.z.union([
4238
4826
  }).partial().passthrough()
4239
4827
  ]);
4240
4828
  var PromptOptionsNullish = import_v36.z.union([
4241
- import_v36.z.object({ model: import_v36.z.string(), params: ModelParams, position: import_v36.z.string() }).partial(),
4829
+ import_v36.z.object({
4830
+ model: import_v36.z.string(),
4831
+ params: ModelParams,
4832
+ position: import_v36.z.string(),
4833
+ endpoint_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()])
4834
+ }).partial(),
4242
4835
  import_v36.z.null()
4243
4836
  ]);
4244
4837
  var PromptParserNullish = import_v36.z.union([
@@ -4252,11 +4845,25 @@ var PromptParserNullish = import_v36.z.union([
4252
4845
  }),
4253
4846
  import_v36.z.null()
4254
4847
  ]);
4848
+ var PreprocessorSavedFunctionId = import_v36.z.union([
4849
+ import_v36.z.object({
4850
+ type: import_v36.z.literal("function"),
4851
+ id: import_v36.z.string(),
4852
+ version: import_v36.z.string().optional()
4853
+ }),
4854
+ import_v36.z.object({
4855
+ type: import_v36.z.literal("global"),
4856
+ name: import_v36.z.string(),
4857
+ function_type: import_v36.z.literal("preprocessor").optional().default("preprocessor")
4858
+ }),
4859
+ import_v36.z.null()
4860
+ ]);
4255
4861
  var PromptDataNullish = import_v36.z.union([
4256
4862
  import_v36.z.object({
4257
4863
  prompt: PromptBlockDataNullish,
4258
4864
  options: PromptOptionsNullish,
4259
4865
  parser: PromptParserNullish,
4866
+ preprocessor: PreprocessorSavedFunctionId,
4260
4867
  tool_functions: import_v36.z.union([import_v36.z.array(SavedFunctionId), import_v36.z.null()]),
4261
4868
  template_format: import_v36.z.union([
4262
4869
  import_v36.z.enum(["mustache", "nunjucks", "none"]),
@@ -4458,6 +5065,7 @@ var PromptData = import_v36.z.object({
4458
5065
  prompt: PromptBlockDataNullish,
4459
5066
  options: PromptOptionsNullish,
4460
5067
  parser: PromptParserNullish,
5068
+ preprocessor: PreprocessorSavedFunctionId,
4461
5069
  tool_functions: import_v36.z.union([import_v36.z.array(SavedFunctionId), import_v36.z.null()]),
4462
5070
  template_format: import_v36.z.union([
4463
5071
  import_v36.z.enum(["mustache", "nunjucks", "none"]),
@@ -4620,7 +5228,8 @@ var InvokeFunction = FunctionId.and(
4620
5228
  mode: StreamingMode,
4621
5229
  strict: import_v36.z.union([import_v36.z.boolean(), import_v36.z.null()]),
4622
5230
  mcp_auth: import_v36.z.record(import_v36.z.object({ oauth_token: import_v36.z.string() }).partial()),
4623
- overrides: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()])
5231
+ overrides: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]),
5232
+ endpoint_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()])
4624
5233
  }).partial()
4625
5234
  );
4626
5235
  var MCPServer = import_v36.z.object({
@@ -4684,6 +5293,24 @@ var Organization = import_v36.z.object({
4684
5293
  created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4685
5294
  image_rendering_mode: ImageRenderingMode.optional()
4686
5295
  });
5296
+ var RetentionObjectType = import_v36.z.enum([
5297
+ "project_logs",
5298
+ "experiment",
5299
+ "dataset"
5300
+ ]);
5301
+ var OrgAutomation = import_v36.z.object({
5302
+ id: import_v36.z.string().uuid(),
5303
+ org_id: import_v36.z.string().uuid(),
5304
+ user_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5305
+ created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5306
+ name: import_v36.z.string(),
5307
+ description: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5308
+ config: import_v36.z.object({
5309
+ event_type: import_v36.z.literal("retention"),
5310
+ object_type: RetentionObjectType,
5311
+ retention_days: import_v36.z.number().int().gte(0)
5312
+ })
5313
+ });
4687
5314
  var ProjectSettings = import_v36.z.union([
4688
5315
  import_v36.z.object({
4689
5316
  comparison_key: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
@@ -4710,6 +5337,7 @@ var ProjectSettings = import_v36.z.union([
4710
5337
  import_v36.z.null()
4711
5338
  ]),
4712
5339
  disable_realtime_queries: import_v36.z.union([import_v36.z.boolean(), import_v36.z.null()]),
5340
+ monitor_charts_use_metrics_start: import_v36.z.union([import_v36.z.boolean(), import_v36.z.null()]),
4713
5341
  default_preprocessor: NullableSavedFunctionId
4714
5342
  }).partial(),
4715
5343
  import_v36.z.null()
@@ -4724,11 +5352,6 @@ var Project = import_v36.z.object({
4724
5352
  user_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4725
5353
  settings: ProjectSettings.optional()
4726
5354
  });
4727
- var RetentionObjectType = import_v36.z.enum([
4728
- "project_logs",
4729
- "experiment",
4730
- "dataset"
4731
- ]);
4732
5355
  var TopicAutomationFacetModel = import_v36.z.union([
4733
5356
  import_v36.z.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
4734
5357
  import_v36.z.null()
@@ -4839,7 +5462,7 @@ var ProjectAutomation = import_v36.z.object({
4839
5462
  import_v36.z.object({
4840
5463
  event_type: import_v36.z.literal("retention"),
4841
5464
  object_type: RetentionObjectType,
4842
- retention_days: import_v36.z.number().gte(0)
5465
+ retention_days: import_v36.z.number().int().gte(0)
4843
5466
  }),
4844
5467
  import_v36.z.object({
4845
5468
  event_type: import_v36.z.literal("environment_update"),
@@ -5011,7 +5634,12 @@ var Prompt = import_v36.z.object({
5011
5634
  metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
5012
5635
  function_type: FunctionTypeEnumNullish.optional()
5013
5636
  });
5014
- var PromptOptions = import_v36.z.object({ model: import_v36.z.string(), params: ModelParams, position: import_v36.z.string() }).partial();
5637
+ var PromptOptions = import_v36.z.object({
5638
+ model: import_v36.z.string(),
5639
+ params: ModelParams,
5640
+ position: import_v36.z.string(),
5641
+ endpoint_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()])
5642
+ }).partial();
5015
5643
  var PromptSessionEvent = import_v36.z.object({
5016
5644
  id: import_v36.z.string(),
5017
5645
  _xact_id: import_v36.z.string(),
@@ -5094,7 +5722,8 @@ var RunEval = import_v36.z.object({
5094
5722
  stop_token: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5095
5723
  extra_messages: import_v36.z.string().optional(),
5096
5724
  tags: import_v36.z.array(import_v36.z.string()).optional(),
5097
- mcp_auth: import_v36.z.record(import_v36.z.object({ oauth_token: import_v36.z.string() }).partial()).optional()
5725
+ mcp_auth: import_v36.z.record(import_v36.z.object({ oauth_token: import_v36.z.string() }).partial()).optional(),
5726
+ endpoint_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
5098
5727
  });
5099
5728
  var ServiceToken = import_v36.z.object({
5100
5729
  id: import_v36.z.string().uuid(),
@@ -5104,7 +5733,8 @@ var ServiceToken = import_v36.z.object({
5104
5733
  service_account_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5105
5734
  service_account_email: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5106
5735
  service_account_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5107
- org_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
5736
+ org_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
5737
+ expires_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
5108
5738
  });
5109
5739
  var SpanIFrame = import_v36.z.object({
5110
5740
  id: import_v36.z.string().uuid(),
@@ -5226,6 +5856,13 @@ var ViewOptions = import_v36.z.union([
5226
5856
  }),
5227
5857
  import_v36.z.null()
5228
5858
  ]),
5859
+ pointSizeMetric: import_v36.z.union([
5860
+ import_v36.z.object({
5861
+ type: import_v36.z.enum(["none", "score", "metric", "metadata"]),
5862
+ value: import_v36.z.string()
5863
+ }),
5864
+ import_v36.z.null()
5865
+ ]),
5229
5866
  xAxisAggregation: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
5230
5867
  chartAnnotations: import_v36.z.union([
5231
5868
  import_v36.z.array(import_v36.z.object({ id: import_v36.z.string(), text: import_v36.z.string() })),
@@ -6367,6 +7004,9 @@ var INSTRUMENTATION_NAMES = {
6367
7004
  BEDROCK_RUNTIME: "bedrock-runtime",
6368
7005
  BRAINTRUST_JS_LOGGER: "braintrust-js-logger",
6369
7006
  CLAUDE_AGENT_SDK: "claude-agent-sdk",
7007
+ CLOUDFLARE_AI_CHAT: "cloudflare-ai-chat",
7008
+ CLOUDFLARE_AGENTS: "cloudflare-agents",
7009
+ CLOUDFLARE_THINK: "cloudflare-think",
6370
7010
  COHERE: "cohere",
6371
7011
  CURSOR_SDK: "cursor-sdk",
6372
7012
  EVE: "eve",
@@ -6381,6 +7021,7 @@ var INSTRUMENTATION_NAMES = {
6381
7021
  LANGSMITH: "langsmith",
6382
7022
  MASTRA: "mastra",
6383
7023
  MISTRAL: "mistral",
7024
+ OLLAMA: "ollama",
6384
7025
  OPENAI: "openai",
6385
7026
  OPENAI_AGENTS: "openai-agents",
6386
7027
  OPENAI_CODEX: "openai-codex",
@@ -6392,7 +7033,7 @@ var INSTRUMENTATION_NAMES = {
6392
7033
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
6393
7034
  "braintrust.spanInstrumentationName"
6394
7035
  );
6395
- var SDK_VERSION = true ? "3.25.0" : "0.0.0";
7036
+ var SDK_VERSION = true ? "3.27.0" : "0.0.0";
6396
7037
  function withSpanInstrumentationName(args, instrumentationName) {
6397
7038
  return {
6398
7039
  ...args,
@@ -6587,12 +7228,13 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
6587
7228
  var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
6588
7229
  "braintrust.initial-span-write-as-merge"
6589
7230
  );
7231
+ var INTERNAL_SPAN_CONTEXT = /* @__PURE__ */ Symbol("braintrust.internal-span-context");
6590
7232
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
6591
7233
  "braintrust.currentSpanStore"
6592
7234
  );
6593
7235
  var ContextManager = class {
6594
7236
  /**
6595
- * Returns the value to store in the ALS bound to a TracingChannel's start event.
7237
+ * Returns the value to store in the ALS bound to a global hook's start event.
6596
7238
  * In default mode this is the Span itself; in OTEL mode it is the OTEL Context
6597
7239
  * containing the span so that OTEL's own ALS stores a proper Context object.
6598
7240
  */
@@ -9654,6 +10296,12 @@ function _internalStartSpanWithInitialMerge(args) {
9654
10296
  [INITIAL_SPAN_WRITE_AS_MERGE]: true
9655
10297
  }).span;
9656
10298
  }
10299
+ function _internalStartSpanWithContext(args, context2) {
10300
+ return startSpanAndIsLogger({
10301
+ ...args,
10302
+ [INTERNAL_SPAN_CONTEXT]: context2
10303
+ }).span;
10304
+ }
9657
10305
  async function flush(options) {
9658
10306
  const state = options?.state ?? _globalState;
9659
10307
  return await state.bgLogger().flush();
@@ -10506,7 +11154,7 @@ var SpanImpl = class _SpanImpl {
10506
11154
  start: args.startTime ?? getCurrentUnixTimestamp()
10507
11155
  },
10508
11156
  context: mergeSpanOriginContext(
10509
- { ...callerLocation },
11157
+ { ...callerLocation, ...args[INTERNAL_SPAN_CONTEXT] },
10510
11158
  instrumentationName,
10511
11159
  this._state.spanOriginEnvironment
10512
11160
  ),
@@ -14469,96 +15117,7 @@ var fancyReporter = {
14469
15117
 
14470
15118
  // src/node/config.ts
14471
15119
  var import_node_async_hooks = require("node:async_hooks");
14472
- var diagnostics_channel = __toESM(require("node:diagnostics_channel"));
14473
15120
  var path = __toESM(require("node:path"));
14474
-
14475
- // src/auto-instrumentations/patch-tracing-channel.ts
14476
- function patchTracingChannel(tracingChannelFn) {
14477
- const dummyChannel = tracingChannelFn("__braintrust_probe__");
14478
- const TracingChannel = dummyChannel?.constructor;
14479
- if (!TracingChannel?.prototype) {
14480
- return;
14481
- }
14482
- if (!Object.getOwnPropertyDescriptor(TracingChannel.prototype, "hasSubscribers")) {
14483
- Object.defineProperty(TracingChannel.prototype, "hasSubscribers", {
14484
- configurable: true,
14485
- enumerable: false,
14486
- get() {
14487
- return Boolean(
14488
- this.start?.hasSubscribers || this.end?.hasSubscribers || this.asyncStart?.hasSubscribers || this.asyncEnd?.hasSubscribers || this.error?.hasSubscribers
14489
- );
14490
- }
14491
- });
14492
- }
14493
- if (TracingChannel.prototype.tracePromise) {
14494
- TracingChannel.prototype.tracePromise = function(fn, context2 = {}, thisArg, ...args) {
14495
- const start = this.start;
14496
- const end = this.end;
14497
- const asyncStart = this.asyncStart;
14498
- const asyncEnd = this.asyncEnd;
14499
- const error2 = this.error;
14500
- function publishRejected(err) {
14501
- context2.error = err;
14502
- error2?.publish(context2);
14503
- asyncStart?.publish(context2);
14504
- asyncEnd?.publish(context2);
14505
- }
14506
- function publishResolved(result) {
14507
- context2.result = result;
14508
- asyncStart?.publish(context2);
14509
- asyncEnd?.publish(context2);
14510
- }
14511
- return start.runStores(context2, () => {
14512
- try {
14513
- const result = Reflect.apply(fn, thisArg, args);
14514
- end?.publish(context2);
14515
- if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
14516
- if (result.constructor === Promise) {
14517
- return result.then(
14518
- (res) => {
14519
- publishResolved(res);
14520
- return res;
14521
- },
14522
- (err) => {
14523
- publishRejected(err);
14524
- return Promise.reject(err);
14525
- }
14526
- );
14527
- }
14528
- void result.then(
14529
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14530
- (resolved) => {
14531
- try {
14532
- publishResolved(resolved);
14533
- } catch {
14534
- }
14535
- },
14536
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14537
- (err) => {
14538
- try {
14539
- publishRejected(err);
14540
- } catch {
14541
- }
14542
- }
14543
- );
14544
- return result;
14545
- }
14546
- context2.result = result;
14547
- asyncStart?.publish(context2);
14548
- asyncEnd?.publish(context2);
14549
- return result;
14550
- } catch (err) {
14551
- context2.error = err;
14552
- error2?.publish(context2);
14553
- end?.publish(context2);
14554
- throw err;
14555
- }
14556
- });
14557
- };
14558
- }
14559
- }
14560
-
14561
- // src/node/config.ts
14562
15121
  var fs = __toESM(require("node:fs/promises"));
14563
15122
  var os = __toESM(require("node:os"));
14564
15123
  var fsSync = __toESM(require("node:fs"));
@@ -14805,6 +15364,34 @@ function patchStreamIfNeeded(stream, options) {
14805
15364
  );
14806
15365
  return stream;
14807
15366
  }
15367
+ const chunks = [];
15368
+ let completed = false;
15369
+ const notifyCancellation = async () => {
15370
+ try {
15371
+ await (options.onCancel ?? options.onComplete)(chunks);
15372
+ } catch (error2) {
15373
+ debugLogger.error("Error in stream cancellation handler:", error2);
15374
+ }
15375
+ };
15376
+ const patchAbortIfPresent = () => {
15377
+ try {
15378
+ if ("abort" in stream && typeof stream.abort === "function") {
15379
+ const originalAbort = stream.abort.bind(stream);
15380
+ stream.abort = (...args) => {
15381
+ try {
15382
+ return originalAbort(...args);
15383
+ } finally {
15384
+ if (!completed) {
15385
+ completed = true;
15386
+ void notifyCancellation();
15387
+ }
15388
+ }
15389
+ };
15390
+ }
15391
+ } catch (error2) {
15392
+ debugLogger.warn("Failed to patch stream abort method:", error2);
15393
+ }
15394
+ };
14808
15395
  if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
14809
15396
  if ("__braintrust_patched_iterator_methods" in stream) {
14810
15397
  return stream;
@@ -14813,8 +15400,6 @@ function patchStreamIfNeeded(stream, options) {
14813
15400
  const originalNext = stream.next.bind(stream);
14814
15401
  const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
14815
15402
  const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
14816
- const chunks = [];
14817
- let completed = false;
14818
15403
  stream.next = async (...args) => {
14819
15404
  try {
14820
15405
  const result = await runNextWithWrapper(
@@ -14866,11 +15451,7 @@ function patchStreamIfNeeded(stream, options) {
14866
15451
  stream.return = async (...args) => {
14867
15452
  if (!completed) {
14868
15453
  completed = true;
14869
- try {
14870
- await options.onComplete(chunks);
14871
- } catch (error2) {
14872
- console.error("Error in stream onComplete handler:", error2);
14873
- }
15454
+ await notifyCancellation();
14874
15455
  }
14875
15456
  return originalReturn(...args);
14876
15457
  };
@@ -14895,6 +15476,7 @@ function patchStreamIfNeeded(stream, options) {
14895
15476
  Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
14896
15477
  value: true
14897
15478
  });
15479
+ patchAbortIfPresent();
14898
15480
  return stream;
14899
15481
  } catch (error2) {
14900
15482
  console.warn("Failed to patch stream iterator methods:", error2);
@@ -14908,8 +15490,6 @@ function patchStreamIfNeeded(stream, options) {
14908
15490
  const patchedIteratorFn = function() {
14909
15491
  const iterator = originalIteratorFn.call(this);
14910
15492
  const originalNext = iterator.next.bind(iterator);
14911
- const chunks = [];
14912
- let completed = false;
14913
15493
  iterator.next = async function(...args) {
14914
15494
  try {
14915
15495
  const result = await runNextWithWrapper(
@@ -14962,11 +15542,7 @@ function patchStreamIfNeeded(stream, options) {
14962
15542
  iterator.return = async function(...args) {
14963
15543
  if (!completed) {
14964
15544
  completed = true;
14965
- try {
14966
- await options.onComplete(chunks);
14967
- } catch (error2) {
14968
- console.error("Error in stream onComplete handler:", error2);
14969
- }
15545
+ await notifyCancellation();
14970
15546
  }
14971
15547
  return originalReturn(...args);
14972
15548
  };
@@ -14995,6 +15571,7 @@ function patchStreamIfNeeded(stream, options) {
14995
15571
  value: true
14996
15572
  });
14997
15573
  stream[Symbol.asyncIterator] = patchedIteratorFn;
15574
+ patchAbortIfPresent();
14998
15575
  return stream;
14999
15576
  } catch (error2) {
15000
15577
  console.warn("Failed to patch stream:", error2);
@@ -15447,8 +16024,8 @@ function runWithAutoInstrumentationSuppressed(callback) {
15447
16024
  callback
15448
16025
  );
15449
16026
  }
15450
- function bindAutoInstrumentationSuppressionToStart(tracingChannel2) {
15451
- const startChannel = tracingChannel2.start;
16027
+ function bindAutoInstrumentationSuppressionToStart(tracingChannel) {
16028
+ const startChannel = tracingChannel.start;
15452
16029
  if (!startChannel) {
15453
16030
  return void 0;
15454
16031
  }
@@ -15559,9 +16136,9 @@ function ensureSpanStateForEvent(states, config3, event, channelName, instrument
15559
16136
  states.set(key, created);
15560
16137
  return created;
15561
16138
  }
15562
- function bindCurrentSpanStoreToStart(tracingChannel2, states, config3, channelName, instrumentationName) {
16139
+ function bindCurrentSpanStoreToStart(tracingChannel, states, config3, channelName, instrumentationName) {
15563
16140
  const state = _internalGetGlobalState();
15564
- const startChannel = tracingChannel2.start;
16141
+ const startChannel = tracingChannel.start;
15565
16142
  const contextManager = state?.contextManager;
15566
16143
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
15567
16144
  if (!currentSpanStore || !startChannel) {
@@ -15644,11 +16221,11 @@ function runStreamingErrorHook(args) {
15644
16221
  }
15645
16222
  }
15646
16223
  function traceAsyncChannel(channel2, config3) {
15647
- const tracingChannel2 = channel2.tracingChannel();
16224
+ const tracingChannel = channel2.tracingChannel();
15648
16225
  const states = /* @__PURE__ */ new WeakMap();
15649
16226
  const channelName = channel2.channelName;
15650
16227
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
15651
- tracingChannel2,
16228
+ tracingChannel,
15652
16229
  states,
15653
16230
  config3,
15654
16231
  channelName,
@@ -15704,18 +16281,18 @@ function traceAsyncChannel(channel2, config3) {
15704
16281
  logErrorAndEnd(states, event, channelName);
15705
16282
  }
15706
16283
  };
15707
- tracingChannel2.subscribe(handlers);
16284
+ tracingChannel.subscribe(handlers);
15708
16285
  return () => {
15709
16286
  unbindCurrentSpanStore?.();
15710
- tracingChannel2.unsubscribe(handlers);
16287
+ tracingChannel.unsubscribe(handlers);
15711
16288
  };
15712
16289
  }
15713
16290
  function traceStreamingChannel(channel2, config3) {
15714
- const tracingChannel2 = channel2.tracingChannel();
16291
+ const tracingChannel = channel2.tracingChannel();
15715
16292
  const states = /* @__PURE__ */ new WeakMap();
15716
16293
  const channelName = channel2.channelName;
15717
16294
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
15718
- tracingChannel2,
16295
+ tracingChannel,
15719
16296
  states,
15720
16297
  config3,
15721
16298
  channelName,
@@ -15743,6 +16320,33 @@ function traceStreamingChannel(channel2, config3) {
15743
16320
  const { span, startTime } = spanData;
15744
16321
  if (isAsyncIterable3(asyncEndEvent.result)) {
15745
16322
  let firstChunkTime;
16323
+ const handleStreamError = (error2) => {
16324
+ try {
16325
+ span.log({ error: error2 });
16326
+ } catch (loggingError) {
16327
+ debugLogger.error(
16328
+ `Error logging failure for ${channelName}:`,
16329
+ loggingError
16330
+ );
16331
+ }
16332
+ try {
16333
+ span.end();
16334
+ } catch (endingError) {
16335
+ debugLogger.error(
16336
+ `Error ending span for ${channelName}:`,
16337
+ endingError
16338
+ );
16339
+ }
16340
+ states.delete(event);
16341
+ runStreamingErrorHook({
16342
+ channelName,
16343
+ config: config3,
16344
+ error: error2,
16345
+ event: asyncEndEvent,
16346
+ span,
16347
+ startTime
16348
+ });
16349
+ };
15746
16350
  patchStreamIfNeeded(asyncEndEvent.result, {
15747
16351
  onChunk: () => {
15748
16352
  if (firstChunkTime === void 0) {
@@ -15822,33 +16426,12 @@ function traceStreamingChannel(channel2, config3) {
15822
16426
  });
15823
16427
  }
15824
16428
  },
15825
- onError: (error2) => {
15826
- try {
15827
- span.log({ error: error2 });
15828
- } catch (loggingError) {
15829
- debugLogger.error(
15830
- `Error logging failure for ${channelName}:`,
15831
- loggingError
15832
- );
15833
- }
15834
- try {
15835
- span.end();
15836
- } catch (endingError) {
15837
- debugLogger.error(
15838
- `Error ending span for ${channelName}:`,
15839
- endingError
15840
- );
15841
- }
15842
- states.delete(event);
15843
- runStreamingErrorHook({
15844
- channelName,
15845
- config: config3,
15846
- error: error2,
15847
- event: asyncEndEvent,
15848
- span,
15849
- startTime
15850
- });
15851
- }
16429
+ onCancel: () => {
16430
+ const error2 = new Error("Stream cancelled before completion");
16431
+ error2.name = "AbortError";
16432
+ handleStreamError(error2);
16433
+ },
16434
+ onError: handleStreamError
15852
16435
  });
15853
16436
  return;
15854
16437
  }
@@ -15926,18 +16509,18 @@ function traceStreamingChannel(channel2, config3) {
15926
16509
  }
15927
16510
  }
15928
16511
  };
15929
- tracingChannel2.subscribe(handlers);
16512
+ tracingChannel.subscribe(handlers);
15930
16513
  return () => {
15931
16514
  unbindCurrentSpanStore?.();
15932
- tracingChannel2.unsubscribe(handlers);
16515
+ tracingChannel.unsubscribe(handlers);
15933
16516
  };
15934
16517
  }
15935
16518
  function traceSyncStreamChannel(channel2, config3) {
15936
- const tracingChannel2 = channel2.tracingChannel();
16519
+ const tracingChannel = channel2.tracingChannel();
15937
16520
  const states = /* @__PURE__ */ new WeakMap();
15938
16521
  const channelName = channel2.channelName;
15939
16522
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
15940
- tracingChannel2,
16523
+ tracingChannel,
15941
16524
  states,
15942
16525
  config3,
15943
16526
  channelName,
@@ -16050,10 +16633,10 @@ function traceSyncStreamChannel(channel2, config3) {
16050
16633
  logErrorAndEnd(states, event, channelName);
16051
16634
  }
16052
16635
  };
16053
- tracingChannel2.subscribe(handlers);
16636
+ tracingChannel.subscribe(handlers);
16054
16637
  return () => {
16055
16638
  unbindCurrentSpanStore?.();
16056
- tracingChannel2.unsubscribe(handlers);
16639
+ tracingChannel.unsubscribe(handlers);
16057
16640
  };
16058
16641
  }
16059
16642
  function unsubscribeAll(unsubscribers) {
@@ -16233,16 +16816,26 @@ function defineChannels(pkg, channels, options) {
16233
16816
  const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
16234
16817
  if (spec.kind === "async") {
16235
16818
  const asyncSpec = spec;
16236
- const tracingChannel3 = () => isomorph_default.newTracingChannel(
16819
+ const tracingChannel2 = () => isomorph_default.newTracingChannel(
16237
16820
  fullChannelName
16238
16821
  );
16822
+ const intercept2 = (interceptor) => {
16823
+ const hook = tracingChannel2();
16824
+ return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
16825
+ };
16826
+ };
16239
16827
  return [
16240
16828
  key,
16241
16829
  {
16242
16830
  ...asyncSpec,
16243
16831
  instrumentationName,
16244
- tracingChannel: tracingChannel3,
16245
- tracePromise: (fn, context2) => tracingChannel3().tracePromise(
16832
+ intercept: intercept2,
16833
+ invoke: (target, thisArg, args, additional) => {
16834
+ const hook = tracingChannel2();
16835
+ return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
16836
+ },
16837
+ tracingChannel: tracingChannel2,
16838
+ tracePromise: (fn, context2) => tracingChannel2().tracePromise(
16246
16839
  fn,
16247
16840
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
16248
16841
  context2
@@ -16251,16 +16844,26 @@ function defineChannels(pkg, channels, options) {
16251
16844
  ];
16252
16845
  }
16253
16846
  const syncSpec = spec;
16254
- const tracingChannel2 = () => isomorph_default.newTracingChannel(
16847
+ const tracingChannel = () => isomorph_default.newTracingChannel(
16255
16848
  fullChannelName
16256
16849
  );
16850
+ const intercept = (interceptor) => {
16851
+ const hook = tracingChannel();
16852
+ return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
16853
+ };
16854
+ };
16257
16855
  return [
16258
16856
  key,
16259
16857
  {
16260
16858
  ...syncSpec,
16261
16859
  instrumentationName,
16262
- tracingChannel: tracingChannel2,
16263
- traceSync: (fn, context2) => tracingChannel2().traceSync(
16860
+ intercept,
16861
+ invoke: (target, thisArg, args, additional) => {
16862
+ const hook = tracingChannel();
16863
+ return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
16864
+ },
16865
+ tracingChannel,
16866
+ traceSync: (fn, context2) => tracingChannel().traceSync(
16264
16867
  fn,
16265
16868
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
16266
16869
  context2
@@ -17509,6 +18112,12 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
17509
18112
  return cacheTokens;
17510
18113
  }
17511
18114
 
18115
+ // src/wrappers/anthropic-session-collector.ts
18116
+ var sessionStreamCollectors = /* @__PURE__ */ new WeakMap();
18117
+ function registerAnthropicSessionStreamCollector(stream, collector) {
18118
+ sessionStreamCollectors.set(stream, collector);
18119
+ }
18120
+
17512
18121
  // src/instrumentation/plugins/anthropic-channels.ts
17513
18122
  var anthropicChannels = defineChannels(
17514
18123
  "@anthropic-ai/sdk",
@@ -17524,6 +18133,14 @@ var anthropicChannels = defineChannels(
17524
18133
  betaMessagesToolRunner: channel({
17525
18134
  channelName: "beta.messages.toolRunner",
17526
18135
  kind: "sync-stream"
18136
+ }),
18137
+ betaSessionsEventsStream: channel({
18138
+ channelName: "beta.sessions.events.stream",
18139
+ kind: "async"
18140
+ }),
18141
+ betaSessionsThreadsEventsStream: channel({
18142
+ channelName: "beta.sessions.threads.events.stream",
18143
+ kind: "async"
17527
18144
  })
17528
18145
  },
17529
18146
  { instrumentationName: INSTRUMENTATION_NAMES.ANTHROPIC }
@@ -17537,6 +18154,7 @@ var AnthropicPlugin = class extends BasePlugin {
17537
18154
  onEnable() {
17538
18155
  this.subscribeToAnthropicChannels();
17539
18156
  this.subscribeToAnthropicToolRunner();
18157
+ this.subscribeToAnthropicSessionStreams();
17540
18158
  }
17541
18159
  onDisable() {
17542
18160
  this.unsubscribers = unsubscribeAll(this.unsubscribers);
@@ -17592,7 +18210,7 @@ var AnthropicPlugin = class extends BasePlugin {
17592
18210
  );
17593
18211
  }
17594
18212
  subscribeToAnthropicToolRunner() {
17595
- const tracingChannel2 = anthropicChannels.betaMessagesToolRunner.tracingChannel();
18213
+ const tracingChannel = anthropicChannels.betaMessagesToolRunner.tracingChannel();
17596
18214
  const states = /* @__PURE__ */ new WeakMap();
17597
18215
  const handlers = {
17598
18216
  start: (event) => {
@@ -17649,12 +18267,416 @@ var AnthropicPlugin = class extends BasePlugin {
17649
18267
  states.delete(event);
17650
18268
  }
17651
18269
  };
17652
- tracingChannel2.subscribe(handlers);
18270
+ tracingChannel.subscribe(handlers);
17653
18271
  this.unsubscribers.push(() => {
17654
- tracingChannel2.unsubscribe(handlers);
18272
+ tracingChannel.unsubscribe(handlers);
17655
18273
  });
17656
18274
  }
18275
+ subscribeToAnthropicSessionStreams() {
18276
+ this.subscribeToAnthropicSessionStream(
18277
+ anthropicChannels.betaSessionsEventsStream,
18278
+ false
18279
+ );
18280
+ this.subscribeToAnthropicSessionStream(
18281
+ anthropicChannels.betaSessionsThreadsEventsStream,
18282
+ true
18283
+ );
18284
+ }
18285
+ subscribeToAnthropicSessionStream(channel2, isThread) {
18286
+ const tracingChannel = channel2.tracingChannel();
18287
+ const pending = /* @__PURE__ */ new WeakSet();
18288
+ const handlers = {
18289
+ start: (event) => {
18290
+ if (isAutoInstrumentationSuppressed()) {
18291
+ return;
18292
+ }
18293
+ pending.add(event);
18294
+ },
18295
+ asyncEnd: (event) => {
18296
+ if (!pending.delete(event)) {
18297
+ return;
18298
+ }
18299
+ const stream = event.result;
18300
+ if (!isAsyncIterable3(stream)) {
18301
+ return;
18302
+ }
18303
+ registerAnthropicSessionStreamCollector(stream, () => {
18304
+ wrapAnthropicSessionEventStream(stream, isThread);
18305
+ });
18306
+ },
18307
+ error: (event) => {
18308
+ pending.delete(event);
18309
+ }
18310
+ };
18311
+ tracingChannel.subscribe(handlers);
18312
+ this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
18313
+ }
17657
18314
  };
18315
+ function wrapAnthropicSessionEventStream(stream, isThread) {
18316
+ const state = {
18317
+ history: [],
18318
+ isThread,
18319
+ pendingInput: [],
18320
+ seenEventIds: /* @__PURE__ */ new Set()
18321
+ };
18322
+ patchStreamIfNeeded(stream, {
18323
+ onChunk: (event) => handleAnthropicSessionEvent(state, event),
18324
+ onComplete: () => finalizeAnthropicSessionTurn(state),
18325
+ onError: (error2) => finalizeAnthropicSessionTurn(state, error2)
18326
+ });
18327
+ return stream;
18328
+ }
18329
+ function handleAnthropicSessionEvent(state, event) {
18330
+ try {
18331
+ if (typeof event.id === "string" && event.type !== "event_delta" && state.seenEventIds.has(event.id)) {
18332
+ return;
18333
+ }
18334
+ if (typeof event.id === "string" && event.type !== "event_delta") {
18335
+ state.seenEventIds.add(event.id);
18336
+ }
18337
+ switch (event.type) {
18338
+ case "user.message":
18339
+ case "system.message":
18340
+ recordAnthropicSessionInput(
18341
+ state,
18342
+ event
18343
+ );
18344
+ break;
18345
+ case "session.status_running":
18346
+ if (!state.isThread) {
18347
+ ensureAnthropicSessionTurn(state);
18348
+ }
18349
+ break;
18350
+ case "session.thread_status_running":
18351
+ if (state.isThread) {
18352
+ ensureAnthropicSessionTurn(state);
18353
+ }
18354
+ break;
18355
+ case "span.model_request_start":
18356
+ if (typeof event.id === "string") {
18357
+ startAnthropicSessionModel(state, event.id);
18358
+ }
18359
+ break;
18360
+ case "event_delta":
18361
+ recordAnthropicSessionFirstToken(state, event);
18362
+ break;
18363
+ case "agent.message":
18364
+ recordAnthropicSessionMessage(
18365
+ state,
18366
+ event
18367
+ );
18368
+ break;
18369
+ case "agent.custom_tool_use":
18370
+ case "agent.mcp_tool_use":
18371
+ case "agent.tool_use":
18372
+ startAnthropicSessionTool(state, event);
18373
+ break;
18374
+ case "user.tool_confirmation":
18375
+ recordAnthropicSessionToolConfirmation(state, event);
18376
+ break;
18377
+ case "agent.mcp_tool_result":
18378
+ case "agent.tool_result":
18379
+ case "user.custom_tool_result":
18380
+ case "user.tool_result":
18381
+ finalizeAnthropicSessionTool(
18382
+ state,
18383
+ event
18384
+ );
18385
+ break;
18386
+ case "span.model_request_end":
18387
+ finalizeAnthropicSessionModel(
18388
+ state,
18389
+ event
18390
+ );
18391
+ break;
18392
+ case "session.status_idle":
18393
+ case "session.thread_status_idle": {
18394
+ if (event.type === "session.status_idle" && state.isThread || event.type === "session.thread_status_idle" && !state.isThread) {
18395
+ break;
18396
+ }
18397
+ const stopReason = isObject(event.stop_reason) ? event.stop_reason.type : void 0;
18398
+ if (stopReason === "end_turn") {
18399
+ finalizeAnthropicSessionTurn(state);
18400
+ } else if (stopReason === "retries_exhausted") {
18401
+ finalizeAnthropicSessionTurn(
18402
+ state,
18403
+ "Anthropic session retries exhausted"
18404
+ );
18405
+ }
18406
+ break;
18407
+ }
18408
+ case "session.error":
18409
+ finalizeAnthropicSessionTurn(state, event.error);
18410
+ break;
18411
+ case "session.deleted":
18412
+ case "session.status_terminated":
18413
+ case "session.thread_status_terminated":
18414
+ if (event.type === "session.deleted" || event.type === "session.status_terminated" && !state.isThread || event.type === "session.thread_status_terminated" && state.isThread) {
18415
+ finalizeAnthropicSessionTurn(state);
18416
+ }
18417
+ break;
18418
+ default:
18419
+ break;
18420
+ }
18421
+ } catch (error2) {
18422
+ debugLogger.debug("Error processing Anthropic Sessions event:", error2);
18423
+ }
18424
+ }
18425
+ function ensureAnthropicSessionTurn(state) {
18426
+ if (state.activeTurn) {
18427
+ return state.activeTurn;
18428
+ }
18429
+ const input = state.pendingInput;
18430
+ state.pendingInput = [];
18431
+ const span = startSpan(
18432
+ withSpanInstrumentationName(
18433
+ {
18434
+ event: {
18435
+ ...input.length > 0 ? { input } : {},
18436
+ metadata: { provider: "anthropic" }
18437
+ },
18438
+ name: state.isThread ? "anthropic.beta.sessions.thread.turn" : "anthropic.beta.sessions.turn",
18439
+ spanAttributes: { type: "task" /* TASK */ }
18440
+ },
18441
+ INSTRUMENTATION_NAMES.ANTHROPIC
18442
+ )
18443
+ );
18444
+ state.activeTurn = {
18445
+ activeTools: /* @__PURE__ */ new Map(),
18446
+ input: input.slice(),
18447
+ metrics: {},
18448
+ span
18449
+ };
18450
+ return state.activeTurn;
18451
+ }
18452
+ function recordAnthropicSessionInput(state, event) {
18453
+ const content = processAttachmentsInInput(event.content);
18454
+ const message = {
18455
+ role: event.type === "system.message" ? "system" : "user",
18456
+ content
18457
+ };
18458
+ state.history.push(message);
18459
+ if (state.activeTurn) {
18460
+ state.activeTurn.input.push(message);
18461
+ } else {
18462
+ state.pendingInput.push(message);
18463
+ }
18464
+ }
18465
+ function startAnthropicSessionModel(state, startEventId) {
18466
+ const turn = ensureAnthropicSessionTurn(state);
18467
+ if (turn.activeModel) {
18468
+ finalizeAnthropicSessionModelState(state, turn);
18469
+ }
18470
+ const span = withCurrent(
18471
+ turn.span,
18472
+ () => startSpan(
18473
+ withSpanInstrumentationName(
18474
+ {
18475
+ event: {
18476
+ ...state.history.length > 0 ? { input: state.history.slice() } : {},
18477
+ metadata: { provider: "anthropic" }
18478
+ },
18479
+ name: "anthropic.messages.create",
18480
+ spanAttributes: { type: "llm" /* LLM */ }
18481
+ },
18482
+ INSTRUMENTATION_NAMES.ANTHROPIC
18483
+ )
18484
+ )
18485
+ );
18486
+ turn.activeModel = {
18487
+ output: [],
18488
+ span,
18489
+ startEventId,
18490
+ startTime: getCurrentUnixTimestamp()
18491
+ };
18492
+ }
18493
+ function recordAnthropicSessionFirstToken(state, event) {
18494
+ const model = state.activeTurn?.activeModel;
18495
+ if (!model || model.firstTokenTime !== void 0 || !isObject(event.delta) || !isObject(event.delta.content) || typeof event.delta.content.text !== "string") {
18496
+ return;
18497
+ }
18498
+ model.firstTokenTime = getCurrentUnixTimestamp();
18499
+ }
18500
+ function recordAnthropicSessionMessage(state, event) {
18501
+ const turn = ensureAnthropicSessionTurn(state);
18502
+ const content = processAttachmentsInInput(
18503
+ event.content
18504
+ );
18505
+ if (turn.activeModel) {
18506
+ turn.activeModel.output.push(...content);
18507
+ } else {
18508
+ const output = { role: "assistant", content };
18509
+ turn.lastOutput = output;
18510
+ state.history.push(output);
18511
+ }
18512
+ }
18513
+ function startAnthropicSessionTool(state, event) {
18514
+ const turn = ensureAnthropicSessionTurn(state);
18515
+ if (turn.activeModel) {
18516
+ turn.activeModel.output.push({
18517
+ type: "tool_use",
18518
+ id: event.id,
18519
+ name: event.name,
18520
+ input: event.input
18521
+ });
18522
+ }
18523
+ const existing = turn.activeTools.get(event.id);
18524
+ if (existing) {
18525
+ existing.span.end();
18526
+ turn.activeTools.delete(event.id);
18527
+ }
18528
+ const span = withCurrent(
18529
+ turn.span,
18530
+ () => startSpan(
18531
+ withSpanInstrumentationName(
18532
+ {
18533
+ event: { input: event.input },
18534
+ name: event.name,
18535
+ spanAttributes: { type: "tool" /* TOOL */ }
18536
+ },
18537
+ INSTRUMENTATION_NAMES.ANTHROPIC
18538
+ )
18539
+ )
18540
+ );
18541
+ const toolState = {
18542
+ approval: event.evaluated_permission === "allow" ? "approved" : event.evaluated_permission === "deny" ? "denied" : void 0,
18543
+ span
18544
+ };
18545
+ turn.activeTools.set(event.id, toolState);
18546
+ if (toolState.approval === "denied") {
18547
+ finalizeAnthropicSessionToolState(toolState);
18548
+ turn.activeTools.delete(event.id);
18549
+ }
18550
+ }
18551
+ function recordAnthropicSessionToolConfirmation(state, event) {
18552
+ if (typeof event.tool_use_id !== "string" || event.result !== "allow" && event.result !== "deny") {
18553
+ return;
18554
+ }
18555
+ const turn = state.activeTurn;
18556
+ const tool = turn?.activeTools.get(event.tool_use_id);
18557
+ if (!turn || !tool) {
18558
+ return;
18559
+ }
18560
+ tool.approval = event.result === "allow" ? "approved" : "denied";
18561
+ if (tool.approval === "denied") {
18562
+ finalizeAnthropicSessionToolState(tool);
18563
+ turn.activeTools.delete(event.tool_use_id);
18564
+ }
18565
+ }
18566
+ function finalizeAnthropicSessionTool(state, event) {
18567
+ const toolUseId = event.tool_use_id ?? event.mcp_tool_use_id ?? event.custom_tool_use_id;
18568
+ if (!toolUseId) {
18569
+ return;
18570
+ }
18571
+ const content = processAttachmentsInInput(event.content);
18572
+ const turn = state.activeTurn;
18573
+ const tool = turn?.activeTools.get(toolUseId);
18574
+ if (turn && tool) {
18575
+ finalizeAnthropicSessionToolState(tool, event, content);
18576
+ turn.activeTools.delete(toolUseId);
18577
+ }
18578
+ const toolResult = {
18579
+ type: "tool_result",
18580
+ tool_use_id: toolUseId,
18581
+ ...content !== void 0 ? { content } : {},
18582
+ ...event.is_error === true ? { is_error: true } : {}
18583
+ };
18584
+ state.history.push({
18585
+ role: "user",
18586
+ content: [toolResult]
18587
+ });
18588
+ }
18589
+ function finalizeAnthropicSessionToolState(state, event, content = event?.content) {
18590
+ safeAnthropicSessionLog(state.span, {
18591
+ ...event?.is_error === true ? {
18592
+ error: content ?? "Anthropic session tool execution failed"
18593
+ } : {},
18594
+ ...state.approval ? { metadata: { tool_approval: state.approval } } : {},
18595
+ ...content !== void 0 ? { output: content } : {}
18596
+ });
18597
+ state.span.end();
18598
+ }
18599
+ function finalizeAnthropicSessionModel(state, event) {
18600
+ const turn = state.activeTurn;
18601
+ const model = turn?.activeModel;
18602
+ if (!turn || !model || model.startEventId !== event.model_request_start_id) {
18603
+ return;
18604
+ }
18605
+ finalizeAnthropicSessionModelState(state, turn, event);
18606
+ }
18607
+ function finalizeAnthropicSessionModelState(state, turn, event) {
18608
+ const model = turn.activeModel;
18609
+ if (!model) {
18610
+ return;
18611
+ }
18612
+ turn.activeModel = void 0;
18613
+ const metrics = event ? parseAnthropicSessionModelUsage(event.model_usage) : {};
18614
+ if (model.firstTokenTime !== void 0) {
18615
+ metrics.time_to_first_token = model.firstTokenTime - model.startTime;
18616
+ }
18617
+ const output = model.output.length > 0 ? { role: "assistant", content: model.output } : void 0;
18618
+ safeAnthropicSessionLog(model.span, {
18619
+ ...event?.is_error ? { error: "Anthropic session model request failed" } : {},
18620
+ ...Object.keys(metrics).length > 0 ? { metrics } : {},
18621
+ ...output ? { output } : {}
18622
+ });
18623
+ model.span.end();
18624
+ if (output) {
18625
+ turn.lastOutput = output;
18626
+ state.history.push(output);
18627
+ }
18628
+ for (const key of [
18629
+ "prompt_tokens",
18630
+ "completion_tokens",
18631
+ "tokens",
18632
+ "prompt_cached_tokens",
18633
+ "prompt_cache_creation_tokens"
18634
+ ]) {
18635
+ const value = metrics[key];
18636
+ if (typeof value === "number") {
18637
+ turn.metrics[key] = (turn.metrics[key] ?? 0) + value;
18638
+ }
18639
+ }
18640
+ }
18641
+ function parseAnthropicSessionModelUsage(usage) {
18642
+ const finalized = finalizeAnthropicTokens({
18643
+ completion_tokens: usage.output_tokens,
18644
+ prompt_cache_creation_tokens: usage.cache_creation_input_tokens,
18645
+ prompt_cached_tokens: usage.cache_read_input_tokens,
18646
+ prompt_tokens: usage.input_tokens
18647
+ });
18648
+ return Object.fromEntries(
18649
+ Object.entries(finalized).filter(
18650
+ (entry) => entry[1] !== void 0
18651
+ )
18652
+ );
18653
+ }
18654
+ function finalizeAnthropicSessionTurn(state, error2) {
18655
+ const turn = state.activeTurn;
18656
+ if (!turn) {
18657
+ return;
18658
+ }
18659
+ state.activeTurn = void 0;
18660
+ finalizeAnthropicSessionModelState(state, turn);
18661
+ for (const tool of turn.activeTools.values()) {
18662
+ finalizeAnthropicSessionToolState(tool);
18663
+ }
18664
+ turn.activeTools.clear();
18665
+ safeAnthropicSessionLog(turn.span, {
18666
+ ...error2 !== void 0 ? { error: error2 instanceof Error ? error2 : toLoggedError(error2) } : {},
18667
+ ...turn.input.length > 0 ? { input: turn.input } : {},
18668
+ ...turn.lastOutput ? { output: turn.lastOutput } : {},
18669
+ ...Object.keys(turn.metrics).length > 0 ? { metrics: turn.metrics } : {}
18670
+ });
18671
+ turn.span.end();
18672
+ }
18673
+ function safeAnthropicSessionLog(span, event) {
18674
+ try {
18675
+ span.log(event);
18676
+ } catch (error2) {
18677
+ debugLogger.debug("Error logging Anthropic Sessions span:", error2);
18678
+ }
18679
+ }
17658
18680
  function parseMetricsFromUsage2(usage) {
17659
18681
  if (!usage) {
17660
18682
  return {};
@@ -18563,8 +19585,8 @@ function registerHarnessSessionParent(session, parent) {
18563
19585
  function currentHarnessTurnParent() {
18564
19586
  return harnessTurnParentStore?.getStore() ?? wrapperTurnParents.get(currentSpan());
18565
19587
  }
18566
- function bindHarnessTurnParentToStart(tracingChannel2, parentFromEvent) {
18567
- const startChannel = tracingChannel2.start;
19588
+ function bindHarnessTurnParentToStart(tracingChannel, parentFromEvent) {
19589
+ const startChannel = tracingChannel.start;
18568
19590
  if (!startChannel) {
18569
19591
  return () => {
18570
19592
  };
@@ -19528,6 +20550,29 @@ var harnessAgentChannels = defineChannels(
19528
20550
  { instrumentationName: INSTRUMENTATION_NAMES.AI_SDK }
19529
20551
  );
19530
20552
 
20553
+ // src/instrumentation/plugins/cloudflare-think-context.ts
20554
+ var cloudflareThinkSpans = /* @__PURE__ */ new Map();
20555
+ function registerCloudflareThinkSpan(span) {
20556
+ if (span.spanId) {
20557
+ cloudflareThinkSpans.set(span.spanId, span);
20558
+ }
20559
+ }
20560
+ function unregisterCloudflareThinkSpan(span) {
20561
+ if (span.spanId) {
20562
+ cloudflareThinkSpans.delete(span.spanId);
20563
+ }
20564
+ }
20565
+ function currentCloudflareThinkSpan() {
20566
+ const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
20567
+ for (const parentSpanId of parentSpanIds) {
20568
+ const span = cloudflareThinkSpans.get(parentSpanId);
20569
+ if (span) {
20570
+ return span;
20571
+ }
20572
+ }
20573
+ return void 0;
20574
+ }
20575
+
19531
20576
  // src/instrumentation/plugins/ai-sdk-plugin.ts
19532
20577
  var DEFAULT_DENY_OUTPUT_PATHS = [
19533
20578
  // v3
@@ -19634,6 +20679,7 @@ var AISDKPlugin = class extends BasePlugin {
19634
20679
  traceStreamingChannel(aiSDKChannels.streamText, {
19635
20680
  name: "streamText",
19636
20681
  type: "function" /* FUNCTION */,
20682
+ shouldTrace: () => currentCloudflareThinkSpan() === void 0,
19637
20683
  extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19638
20684
  extractOutput: (result, endEvent) => processAISDKOutput(
19639
20685
  result,
@@ -19654,6 +20700,7 @@ var AISDKPlugin = class extends BasePlugin {
19654
20700
  traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
19655
20701
  name: "streamText",
19656
20702
  type: "function" /* FUNCTION */,
20703
+ shouldTrace: () => currentCloudflareThinkSpan() === void 0,
19657
20704
  extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19658
20705
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19659
20706
  defaultDenyOutputPaths: denyOutputPaths,
@@ -20639,6 +21686,23 @@ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOu
20639
21686
  metadata
20640
21687
  };
20641
21688
  }
21689
+ function prepareAISDKAgentCallInput(params, event, span, defaultDenyOutputPaths = DEFAULT_DENY_OUTPUT_PATHS) {
21690
+ const { input } = processAISDKWorkflowAgentCallInput(params);
21691
+ const metadata = extractMetadataFromCallParams(params, event.self);
21692
+ const childTracing = prepareAISDKChildTracing(
21693
+ params,
21694
+ event.self,
21695
+ span,
21696
+ defaultDenyOutputPaths,
21697
+ event.aiSDK,
21698
+ { agentOwner: true }
21699
+ );
21700
+ event.modelWrapped = childTracing.modelWrapped;
21701
+ if (childTracing.cleanup) {
21702
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
21703
+ }
21704
+ return { input, metadata };
21705
+ }
20642
21706
  function prepareAISDKEmbedInput(params, self) {
20643
21707
  return {
20644
21708
  input: { ...params },
@@ -20662,6 +21726,18 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
20662
21726
  }
20663
21727
  return metrics;
20664
21728
  }
21729
+ async function extractResolvedAISDKTokenMetrics(result) {
21730
+ for (const field of ["totalUsage", "usage"]) {
21731
+ try {
21732
+ const usage = await Promise.resolve(result[field]);
21733
+ if (usage !== void 0) {
21734
+ return extractTokenMetrics({ [field]: usage });
21735
+ }
21736
+ } catch {
21737
+ }
21738
+ }
21739
+ return extractTokenMetrics(result);
21740
+ }
20665
21741
  function hasModelChildTracing(event) {
20666
21742
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
20667
21743
  }
@@ -21479,13 +22555,15 @@ function patchAISDKStreamingResult(args) {
21479
22555
  const {
21480
22556
  defaultDenyOutputPaths,
21481
22557
  endEvent,
22558
+ forceTopLevelMetrics,
21482
22559
  onComplete,
21483
22560
  onCancel,
21484
22561
  onError,
21485
22562
  result,
21486
22563
  resolvePromiseUsage,
21487
22564
  span,
21488
- startTime
22565
+ startTime,
22566
+ transformOutput
21489
22567
  } = args;
21490
22568
  if (!result || typeof result !== "object") {
21491
22569
  return false;
@@ -21538,8 +22616,8 @@ function patchAISDKStreamingResult(args) {
21538
22616
  }
21539
22617
  outputLogged = true;
21540
22618
  try {
21541
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
21542
- if (resolvePromiseUsage) {
22619
+ const metrics = forceTopLevelMetrics ? await extractResolvedAISDKTokenMetrics(result) : extractTopLevelAISDKMetrics(result, endEvent);
22620
+ if (resolvePromiseUsage && !forceTopLevelMetrics) {
21543
22621
  try {
21544
22622
  const resultRecord2 = result;
21545
22623
  const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
@@ -21558,10 +22636,11 @@ function patchAISDKStreamingResult(args) {
21558
22636
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
21559
22637
  metrics.time_to_first_token = firstChunkTime - startTime;
21560
22638
  }
21561
- const output = await processAISDKStreamingOutput(
22639
+ const processedOutput = await processAISDKStreamingOutput(
21562
22640
  result,
21563
22641
  resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
21564
22642
  );
22643
+ const output = transformOutput ? transformOutput(processedOutput) : processedOutput;
21565
22644
  const metadata = buildResolvedMetadataPayload(result).metadata;
21566
22645
  try {
21567
22646
  span.log({
@@ -23983,6 +25062,295 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
23983
25062
  }
23984
25063
  };
23985
25064
 
25065
+ // src/instrumentation/plugins/cloudflare-think-channels.ts
25066
+ var cloudflareThinkChannels = defineChannels(
25067
+ "@cloudflare/think",
25068
+ {
25069
+ runInferenceLoop: channel({
25070
+ channelName: "Think.runInferenceLoop",
25071
+ kind: "async"
25072
+ })
25073
+ },
25074
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_THINK }
25075
+ );
25076
+
25077
+ // src/instrumentation/plugins/cloudflare-think-plugin.ts
25078
+ var THINK_STATE_ID = /* @__PURE__ */ Symbol.for("braintrust.cloudflare-think.state-id");
25079
+ var CloudflareThinkPlugin = class extends BasePlugin {
25080
+ statesBySpanId = /* @__PURE__ */ new Map();
25081
+ onEnable() {
25082
+ this.subscribeToThinkRuns();
25083
+ this.subscribeToAISDKStreamTextSync();
25084
+ this.subscribeToAISDKStreamTextAsync();
25085
+ }
25086
+ onDisable() {
25087
+ for (const unsubscribe of this.unsubscribers) {
25088
+ unsubscribe();
25089
+ }
25090
+ this.unsubscribers = [];
25091
+ for (const state of this.statesBySpanId.values()) {
25092
+ this.finishState(state);
25093
+ }
25094
+ this.statesBySpanId.clear();
25095
+ }
25096
+ subscribeToThinkRuns() {
25097
+ const channel2 = cloudflareThinkChannels.runInferenceLoop.tracingChannel();
25098
+ const states = /* @__PURE__ */ new WeakMap();
25099
+ const state = _internalGetGlobalState();
25100
+ const contextManager = state?.contextManager;
25101
+ const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
25102
+ const ensureState2 = (event) => {
25103
+ if (isAutoInstrumentationSuppressed()) {
25104
+ return void 0;
25105
+ }
25106
+ const existing = states.get(event);
25107
+ if (existing) {
25108
+ return existing;
25109
+ }
25110
+ const span = startSpan(
25111
+ withSpanInstrumentationName(
25112
+ {
25113
+ name: "Think.runTurn",
25114
+ spanAttributes: { type: "task" /* TASK */ }
25115
+ },
25116
+ INSTRUMENTATION_NAMES.CLOUDFLARE_THINK
25117
+ )
25118
+ );
25119
+ const runState = {
25120
+ aiResultPatched: false,
25121
+ fallbackInput: extractFallbackInput(event.self?.messages),
25122
+ finalized: false,
25123
+ inputLogged: false,
25124
+ span,
25125
+ startTime: getCurrentUnixTimestamp()
25126
+ };
25127
+ const metadata = {
25128
+ braintrust: {
25129
+ integration_name: "cloudflare-think",
25130
+ sdk_language: "typescript"
25131
+ }
25132
+ };
25133
+ if (typeof event.moduleVersion === "string") {
25134
+ metadata["cloudflare_think.version"] = event.moduleVersion;
25135
+ }
25136
+ span.log({ metadata });
25137
+ states.set(event, runState);
25138
+ if (span.spanId) {
25139
+ this.statesBySpanId.set(span.spanId, runState);
25140
+ }
25141
+ registerCloudflareThinkSpan(span);
25142
+ return runState;
25143
+ };
25144
+ if (contextManager && currentSpanStore && channel2.start) {
25145
+ channel2.start.bindStore(currentSpanStore, (event) => {
25146
+ const runState = ensureState2(event);
25147
+ return runState ? contextManager.wrapSpanForStore(runState.span) : currentSpanStore.getStore();
25148
+ });
25149
+ this.unsubscribers.push(
25150
+ () => channel2.start?.unbindStore(currentSpanStore)
25151
+ );
25152
+ }
25153
+ const handlers = {
25154
+ start: (event) => {
25155
+ ensureState2(event);
25156
+ },
25157
+ asyncEnd: (event) => {
25158
+ const runState = states.get(event);
25159
+ states.delete(event);
25160
+ if (!runState || runState.finalized || runState.aiResultPatched) {
25161
+ return;
25162
+ }
25163
+ this.finishState(runState, void 0, event.result);
25164
+ },
25165
+ error: (event) => {
25166
+ const runState = states.get(event);
25167
+ states.delete(event);
25168
+ if (runState) {
25169
+ this.finishState(runState, event.error);
25170
+ }
25171
+ }
25172
+ };
25173
+ channel2.subscribe(handlers);
25174
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
25175
+ }
25176
+ subscribeToAISDKStreamTextSync() {
25177
+ const channel2 = aiSDKChannels.streamTextSync.tracingChannel();
25178
+ const handlers = {
25179
+ start: (event) => {
25180
+ this.startAISDKStream(event);
25181
+ },
25182
+ end: (event) => {
25183
+ this.endAISDKStream(event);
25184
+ },
25185
+ error: (event) => {
25186
+ this.errorAISDKStream(event);
25187
+ }
25188
+ };
25189
+ channel2.subscribe(handlers);
25190
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
25191
+ }
25192
+ subscribeToAISDKStreamTextAsync() {
25193
+ const channel2 = aiSDKChannels.streamText.tracingChannel();
25194
+ const handlers = {
25195
+ start: (event) => {
25196
+ this.startAISDKStream(event);
25197
+ },
25198
+ asyncEnd: (event) => {
25199
+ this.endAISDKStream(event);
25200
+ },
25201
+ error: (event) => {
25202
+ this.errorAISDKStream(event);
25203
+ }
25204
+ };
25205
+ channel2.subscribe(handlers);
25206
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
25207
+ }
25208
+ startAISDKStream(event) {
25209
+ const runState = this.currentState();
25210
+ if (!runState || runState.finalized) {
25211
+ return;
25212
+ }
25213
+ try {
25214
+ const prepared = prepareAISDKAgentCallInput(
25215
+ event.arguments[0],
25216
+ event,
25217
+ runState.span
25218
+ );
25219
+ runState.span.log({
25220
+ input: extractThinkTaskInput(prepared.input),
25221
+ metadata: {
25222
+ ...prepared.metadata,
25223
+ braintrust: {
25224
+ integration_name: "cloudflare-think",
25225
+ sdk_language: "typescript"
25226
+ }
25227
+ }
25228
+ });
25229
+ runState.inputLogged = true;
25230
+ runState.aiEvent = event;
25231
+ Reflect.set(event, THINK_STATE_ID, runState.span.spanId);
25232
+ } catch (error2) {
25233
+ debugLogger.error(
25234
+ "Error preparing @cloudflare/think AI SDK tracing:",
25235
+ error2
25236
+ );
25237
+ }
25238
+ }
25239
+ endAISDKStream(event) {
25240
+ const runState = this.stateForAISDKEvent(event);
25241
+ if (!runState || runState.finalized) {
25242
+ return;
25243
+ }
25244
+ const patched = patchAISDKStreamingResult({
25245
+ defaultDenyOutputPaths: DEFAULT_DENY_OUTPUT_PATHS,
25246
+ endEvent: event,
25247
+ forceTopLevelMetrics: true,
25248
+ onComplete: () => this.releaseState(runState),
25249
+ result: event.result,
25250
+ span: runState.span,
25251
+ startTime: runState.startTime,
25252
+ transformOutput: extractThinkTaskOutput
25253
+ });
25254
+ runState.aiResultPatched = patched;
25255
+ if (!patched) {
25256
+ this.finishState(runState, void 0, event.result);
25257
+ }
25258
+ }
25259
+ errorAISDKStream(event) {
25260
+ const runState = this.stateForAISDKEvent(event);
25261
+ if (runState) {
25262
+ this.finishState(runState, event.error);
25263
+ }
25264
+ }
25265
+ currentState() {
25266
+ const parentIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
25267
+ for (const parentId of parentIds) {
25268
+ const state = this.statesBySpanId.get(parentId);
25269
+ if (state) {
25270
+ return state;
25271
+ }
25272
+ }
25273
+ return void 0;
25274
+ }
25275
+ stateForAISDKEvent(event) {
25276
+ const spanId = Reflect.get(event, THINK_STATE_ID);
25277
+ return typeof spanId === "string" ? this.statesBySpanId.get(spanId) : void 0;
25278
+ }
25279
+ finishState(state, error2, output) {
25280
+ if (state.finalized) {
25281
+ return;
25282
+ }
25283
+ state.finalized = true;
25284
+ try {
25285
+ if (!state.inputLogged && state.fallbackInput !== void 0) {
25286
+ state.span.log({ input: state.fallbackInput });
25287
+ }
25288
+ if (error2 !== void 0) {
25289
+ state.span.log({ error: error2 });
25290
+ } else if (output !== void 0) {
25291
+ state.span.log({ output: extractThinkTaskOutput(output) });
25292
+ }
25293
+ finalizeAISDKChildTracing(state.aiEvent);
25294
+ state.span.end();
25295
+ } finally {
25296
+ this.releaseState(state);
25297
+ }
25298
+ }
25299
+ releaseState(state) {
25300
+ state.finalized = true;
25301
+ unregisterCloudflareThinkSpan(state.span);
25302
+ if (state.span.spanId) {
25303
+ this.statesBySpanId.delete(state.span.spanId);
25304
+ }
25305
+ }
25306
+ };
25307
+ function extractFallbackInput(messages) {
25308
+ if (!Array.isArray(messages) || messages.length === 0) {
25309
+ return void 0;
25310
+ }
25311
+ let latestUserIndex = -1;
25312
+ for (let index = messages.length - 1; index >= 0; index--) {
25313
+ if (messages[index]?.role === "user") {
25314
+ latestUserIndex = index;
25315
+ break;
25316
+ }
25317
+ }
25318
+ const selected = latestUserIndex >= 0 ? messages.slice(latestUserIndex) : [];
25319
+ return selected.map((message) => ({
25320
+ role: message.role,
25321
+ content: message.content ?? message.parts
25322
+ }));
25323
+ }
25324
+ function extractThinkTaskOutput(output) {
25325
+ if (!isObject(output)) {
25326
+ return output;
25327
+ }
25328
+ if (typeof output.text === "string") {
25329
+ return { role: "assistant", content: output.text };
25330
+ }
25331
+ if (output.object !== void 0) {
25332
+ return output.object;
25333
+ }
25334
+ return output;
25335
+ }
25336
+ function extractThinkTaskInput(input) {
25337
+ if (!isObject(input)) {
25338
+ return input;
25339
+ }
25340
+ const system = input.instructions ?? input.system;
25341
+ if (Array.isArray(input.messages)) {
25342
+ return system === void 0 ? input.messages : [{ role: "system", content: system }, ...input.messages];
25343
+ }
25344
+ if (Array.isArray(input.prompt)) {
25345
+ return system === void 0 ? input.prompt : [{ role: "system", content: system }, ...input.prompt];
25346
+ }
25347
+ if (typeof input.prompt === "string") {
25348
+ const messages = [{ role: "user", content: input.prompt }];
25349
+ return system === void 0 ? messages : [{ role: "system", content: system }, ...messages];
25350
+ }
25351
+ return input;
25352
+ }
25353
+
23986
25354
  // src/instrumentation/plugins/cursor-sdk-channels.ts
23987
25355
  var cursorSDKChannels = defineChannels(
23988
25356
  "@cursor/sdk",
@@ -24030,7 +25398,7 @@ var CursorSDKPlugin = class extends BasePlugin {
24030
25398
  this.subscribeToAgentFactory(cursorSDKChannels.resume);
24031
25399
  }
24032
25400
  subscribeToAgentFactory(channel2) {
24033
- const tracingChannel2 = channel2.tracingChannel();
25401
+ const tracingChannel = channel2.tracingChannel();
24034
25402
  const handlers = {
24035
25403
  asyncEnd: (event) => {
24036
25404
  patchCursorAgentInPlace(event.result);
@@ -24038,9 +25406,9 @@ var CursorSDKPlugin = class extends BasePlugin {
24038
25406
  error: () => {
24039
25407
  }
24040
25408
  };
24041
- tracingChannel2.subscribe(handlers);
25409
+ tracingChannel.subscribe(handlers);
24042
25410
  this.unsubscribers.push(() => {
24043
- tracingChannel2.unsubscribe(handlers);
25411
+ tracingChannel.unsubscribe(handlers);
24044
25412
  });
24045
25413
  }
24046
25414
  subscribeToPrompt() {
@@ -25396,10 +26764,10 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25396
26764
  this.subscribeToInteractionsCreateChannel();
25397
26765
  }
25398
26766
  subscribeToGenerateContentChannel() {
25399
- const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
26767
+ const tracingChannel = googleGenAIChannels.generateContent.tracingChannel();
25400
26768
  const states = /* @__PURE__ */ new WeakMap();
25401
26769
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
25402
- tracingChannel2,
26770
+ tracingChannel,
25403
26771
  states,
25404
26772
  (event) => {
25405
26773
  const params = event.arguments[0];
@@ -25473,14 +26841,14 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25473
26841
  logErrorAndEndSpan(states, event);
25474
26842
  }
25475
26843
  };
25476
- tracingChannel2.subscribe(handlers);
26844
+ tracingChannel.subscribe(handlers);
25477
26845
  this.unsubscribers.push(() => {
25478
26846
  unbindCurrentSpanStore?.();
25479
- tracingChannel2.unsubscribe(handlers);
26847
+ tracingChannel.unsubscribe(handlers);
25480
26848
  });
25481
26849
  }
25482
26850
  subscribeToGenerateContentStreamChannel() {
25483
- const tracingChannel2 = googleGenAIChannels.generateContentStream.tracingChannel();
26851
+ const tracingChannel = googleGenAIChannels.generateContentStream.tracingChannel();
25484
26852
  const handlers = {
25485
26853
  start: (event) => {
25486
26854
  const streamEvent = event;
@@ -25501,16 +26869,16 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25501
26869
  error: () => {
25502
26870
  }
25503
26871
  };
25504
- tracingChannel2.subscribe(handlers);
26872
+ tracingChannel.subscribe(handlers);
25505
26873
  this.unsubscribers.push(() => {
25506
- tracingChannel2.unsubscribe(handlers);
26874
+ tracingChannel.unsubscribe(handlers);
25507
26875
  });
25508
26876
  }
25509
26877
  subscribeToEmbedContentChannel() {
25510
- const tracingChannel2 = googleGenAIChannels.embedContent.tracingChannel();
26878
+ const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
25511
26879
  const states = /* @__PURE__ */ new WeakMap();
25512
26880
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
25513
- tracingChannel2,
26881
+ tracingChannel,
25514
26882
  states,
25515
26883
  (event) => {
25516
26884
  const params = event.arguments[0];
@@ -25580,10 +26948,10 @@ var GoogleGenAIPlugin = class extends BasePlugin {
25580
26948
  logErrorAndEndSpan(states, event);
25581
26949
  }
25582
26950
  };
25583
- tracingChannel2.subscribe(handlers);
26951
+ tracingChannel.subscribe(handlers);
25584
26952
  this.unsubscribers.push(() => {
25585
26953
  unbindCurrentSpanStore?.();
25586
- tracingChannel2.unsubscribe(handlers);
26954
+ tracingChannel.unsubscribe(handlers);
25587
26955
  });
25588
26956
  }
25589
26957
  subscribeToInteractionsCreateChannel() {
@@ -25619,10 +26987,10 @@ function ensureSpanState(states, event, create) {
25619
26987
  states.set(event, created);
25620
26988
  return created;
25621
26989
  }
25622
- function bindCurrentSpanStoreToStart2(tracingChannel2, states, create) {
26990
+ function bindCurrentSpanStoreToStart2(tracingChannel, states, create) {
25623
26991
  const state = _internalGetGlobalState();
25624
26992
  const contextManager = state?.contextManager;
25625
- const startChannel = tracingChannel2.start;
26993
+ const startChannel = tracingChannel.start;
25626
26994
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
25627
26995
  if (!startChannel?.bindStore || !currentSpanStore) {
25628
26996
  return void 0;
@@ -26125,11 +27493,11 @@ function summarizeEmbedContentOutput(response) {
26125
27493
  };
26126
27494
  }
26127
27495
  function populateUsageMetrics(metrics, usage) {
26128
- if (usage.promptTokenCount !== void 0) {
26129
- metrics.prompt_tokens = usage.promptTokenCount;
27496
+ if (usage.promptTokenCount !== void 0 || usage.toolUsePromptTokenCount !== void 0) {
27497
+ metrics.prompt_tokens = (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0);
26130
27498
  }
26131
- if (usage.candidatesTokenCount !== void 0) {
26132
- metrics.completion_tokens = usage.candidatesTokenCount;
27499
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0) {
27500
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
26133
27501
  }
26134
27502
  if (usage.totalTokenCount !== void 0) {
26135
27503
  metrics.tokens = usage.totalTokenCount;
@@ -26140,13 +27508,26 @@ function populateUsageMetrics(metrics, usage) {
26140
27508
  if (usage.thoughtsTokenCount !== void 0) {
26141
27509
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
26142
27510
  }
27511
+ for (const detail of usage.promptTokensDetails ?? []) {
27512
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
27513
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
27514
+ }
27515
+ }
27516
+ for (const detail of usage.candidatesTokensDetails ?? []) {
27517
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
27518
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokenCount;
27519
+ }
27520
+ if (detail.modality === "IMAGE" && detail.tokenCount !== void 0) {
27521
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokenCount;
27522
+ }
27523
+ }
26143
27524
  }
26144
27525
  function populateInteractionUsageMetrics(metrics, usage) {
26145
27526
  if (typeof usage.total_input_tokens === "number") {
26146
27527
  metrics.prompt_tokens = usage.total_input_tokens;
26147
27528
  }
26148
27529
  if (typeof usage.total_output_tokens === "number") {
26149
- metrics.completion_tokens = usage.total_output_tokens;
27530
+ metrics.completion_tokens = usage.total_output_tokens + (typeof usage.total_thought_tokens === "number" ? usage.total_thought_tokens : 0);
26150
27531
  }
26151
27532
  if (typeof usage.total_tokens === "number") {
26152
27533
  metrics.tokens = usage.total_tokens;
@@ -26157,6 +27538,24 @@ function populateInteractionUsageMetrics(metrics, usage) {
26157
27538
  if (typeof usage.total_thought_tokens === "number") {
26158
27539
  metrics.completion_reasoning_tokens = usage.total_thought_tokens;
26159
27540
  }
27541
+ for (const detail of Array.isArray(usage.input_tokens_by_modality) ? usage.input_tokens_by_modality : []) {
27542
+ if (typeof detail?.modality === "string" && detail.modality.toLowerCase() === "audio" && typeof detail.tokens === "number") {
27543
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokens;
27544
+ }
27545
+ }
27546
+ for (const detail of Array.isArray(usage.output_tokens_by_modality) ? usage.output_tokens_by_modality : []) {
27547
+ if (typeof detail?.modality !== "string" || typeof detail.tokens !== "number") {
27548
+ continue;
27549
+ }
27550
+ switch (detail.modality.toLowerCase()) {
27551
+ case "audio":
27552
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokens;
27553
+ break;
27554
+ case "image":
27555
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokens;
27556
+ break;
27557
+ }
27558
+ }
26160
27559
  }
26161
27560
  function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
26162
27561
  const end = getCurrentUnixTimestamp();
@@ -26895,6 +28294,299 @@ function extractTextGenerationStreamMetadata(chunks) {
26895
28294
  return void 0;
26896
28295
  }
26897
28296
 
28297
+ // src/instrumentation/plugins/huggingface-transformers-channels.ts
28298
+ var SUPPORTED_TASKS = /* @__PURE__ */ new Set([
28299
+ "text-generation",
28300
+ "text2text-generation",
28301
+ "summarization",
28302
+ "feature-extraction",
28303
+ "question-answering"
28304
+ ]);
28305
+ var pipelineInfo = /* @__PURE__ */ new WeakMap();
28306
+ function isSupportedHuggingFaceTransformersTask(task) {
28307
+ return typeof task === "string" && SUPPORTED_TASKS.has(task);
28308
+ }
28309
+ function registerHuggingFaceTransformersPipeline(pipeline, task, model) {
28310
+ if (typeof task !== "string") {
28311
+ return;
28312
+ }
28313
+ const info = { task };
28314
+ if (typeof model === "string") {
28315
+ info.model = model;
28316
+ }
28317
+ pipelineInfo.set(pipeline, info);
28318
+ }
28319
+ function getHuggingFaceTransformersPipelineInfo(pipeline) {
28320
+ return pipeline ? pipelineInfo.get(pipeline) : void 0;
28321
+ }
28322
+ var huggingFaceTransformersChannels = defineChannels(
28323
+ "@huggingface/transformers",
28324
+ {
28325
+ pipeline: channel({
28326
+ channelName: "pipeline",
28327
+ kind: "async"
28328
+ }),
28329
+ pipelineCall: channel({
28330
+ channelName: "pipeline.call",
28331
+ kind: "async"
28332
+ })
28333
+ },
28334
+ { instrumentationName: INSTRUMENTATION_NAMES.HUGGINGFACE }
28335
+ );
28336
+
28337
+ // src/instrumentation/plugins/huggingface-transformers-plugin.ts
28338
+ var REQUEST_METADATA_KEYS = [
28339
+ "temperature",
28340
+ "top_p",
28341
+ "max_tokens",
28342
+ "stop"
28343
+ ];
28344
+ var HuggingFaceTransformersPlugin = class extends BasePlugin {
28345
+ onEnable() {
28346
+ this.subscribeToPipelineFactory();
28347
+ this.unsubscribers.push(
28348
+ traceAsyncChannel(huggingFaceTransformersChannels.pipelineCall, {
28349
+ name: (_args, event) => {
28350
+ const task = getTask(event);
28351
+ const operation = task?.replaceAll("-", "_") ?? "unknown";
28352
+ return `huggingface.transformers.${operation}`;
28353
+ },
28354
+ type: "llm" /* LLM */,
28355
+ shouldTrace: (_args, event) => isSupportedHuggingFaceTransformersTask(
28356
+ getTask(event)
28357
+ ),
28358
+ extractInput: (args, event) => ({
28359
+ input: extractInput(
28360
+ getTask(event),
28361
+ args
28362
+ ),
28363
+ metadata: extractMetadata(
28364
+ event,
28365
+ args
28366
+ )
28367
+ }),
28368
+ extractOutput: (result, event) => extractOutput(
28369
+ getTask(event),
28370
+ result
28371
+ ),
28372
+ extractMetrics: () => ({})
28373
+ })
28374
+ );
28375
+ }
28376
+ onDisable() {
28377
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
28378
+ }
28379
+ subscribeToPipelineFactory() {
28380
+ const channel2 = huggingFaceTransformersChannels.pipeline.tracingChannel();
28381
+ const handlers = {
28382
+ asyncEnd: (event) => {
28383
+ if (typeof event.result !== "function") {
28384
+ return;
28385
+ }
28386
+ registerHuggingFaceTransformersPipeline(
28387
+ event.result,
28388
+ event.arguments?.[0],
28389
+ event.arguments?.[1]
28390
+ );
28391
+ }
28392
+ };
28393
+ channel2.subscribe(handlers);
28394
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
28395
+ }
28396
+ };
28397
+ function getTask(event) {
28398
+ const self = event.self;
28399
+ const registeredTask = getHuggingFaceTransformersPipelineInfo(self)?.task;
28400
+ if (registeredTask !== void 0) {
28401
+ return registeredTask;
28402
+ }
28403
+ if (typeof self?.task === "string") {
28404
+ return self.task;
28405
+ }
28406
+ return void 0;
28407
+ }
28408
+ function extractMetadata(event, args) {
28409
+ const metadata = {
28410
+ provider: "huggingface"
28411
+ };
28412
+ const registeredModel = getHuggingFaceTransformersPipelineInfo(
28413
+ event.self
28414
+ )?.model;
28415
+ const model = registeredModel ?? modelIdentifier(event.self);
28416
+ if (model) {
28417
+ metadata.model = model;
28418
+ }
28419
+ const task = getTask(event);
28420
+ const options = task === "question-answering" ? args[2] : args[1];
28421
+ if (isObject(options)) {
28422
+ for (const key of REQUEST_METADATA_KEYS) {
28423
+ if (options[key] !== void 0) {
28424
+ metadata[key] = options[key];
28425
+ }
28426
+ }
28427
+ }
28428
+ return metadata;
28429
+ }
28430
+ function modelIdentifier(pipeline) {
28431
+ const model = pipeline?.model;
28432
+ if (!isObject(model)) {
28433
+ return void 0;
28434
+ }
28435
+ const config3 = isObject(model.config) ? model.config : void 0;
28436
+ for (const value of [
28437
+ config3?._name_or_path,
28438
+ config3?.name_or_path,
28439
+ config3?.model_id,
28440
+ config3?.modelId,
28441
+ model.name
28442
+ ]) {
28443
+ if (typeof value === "string" && value.length > 0) {
28444
+ return value;
28445
+ }
28446
+ }
28447
+ return void 0;
28448
+ }
28449
+ function extractInput(task, args) {
28450
+ switch (task) {
28451
+ case "feature-extraction":
28452
+ return args[0];
28453
+ case "question-answering": {
28454
+ const question = args[0];
28455
+ const context2 = args[1];
28456
+ if (Array.isArray(question) && Array.isArray(context2) && question.every((value) => typeof value === "string") && context2.every((value) => typeof value === "string")) {
28457
+ return question.map((value, index) => [
28458
+ {
28459
+ role: "user",
28460
+ content: `Context:
28461
+ ${context2[index] ?? ""}
28462
+
28463
+ Question:
28464
+ ${value}`
28465
+ }
28466
+ ]);
28467
+ }
28468
+ if (typeof question === "string" && typeof context2 === "string") {
28469
+ return [
28470
+ {
28471
+ role: "user",
28472
+ content: `Context:
28473
+ ${context2}
28474
+
28475
+ Question:
28476
+ ${question}`
28477
+ }
28478
+ ];
28479
+ }
28480
+ return { context: context2, question };
28481
+ }
28482
+ }
28483
+ const input = args[0];
28484
+ if (task === "text-generation" && isChat(input)) {
28485
+ return input;
28486
+ }
28487
+ if (task === "text-generation" && Array.isArray(input) && input.every(isChat)) {
28488
+ return input;
28489
+ }
28490
+ if (typeof input === "string") {
28491
+ return [{ role: "user", content: input }];
28492
+ }
28493
+ if (Array.isArray(input) && input.every((value) => typeof value === "string")) {
28494
+ return input.map((value) => [
28495
+ {
28496
+ role: "user",
28497
+ content: value
28498
+ }
28499
+ ]);
28500
+ }
28501
+ return input;
28502
+ }
28503
+ function isChat(value) {
28504
+ return Array.isArray(value) && value.length > 0 && value.every(
28505
+ (message) => isObject(message) && typeof message.role === "string" && "content" in message
28506
+ );
28507
+ }
28508
+ function extractOutput(task, result) {
28509
+ switch (task) {
28510
+ case "feature-extraction":
28511
+ return summarizeEmbedding(result);
28512
+ case "question-answering":
28513
+ return choicesFromAnswers(result);
28514
+ default:
28515
+ return choicesFromGenerations(result);
28516
+ }
28517
+ }
28518
+ function summarizeEmbedding(result) {
28519
+ if (!isObject(result) || !Array.isArray(result.dims)) {
28520
+ return void 0;
28521
+ }
28522
+ const { dims } = result;
28523
+ if (dims.length === 0 || !dims.every((dimension) => typeof dimension === "number")) {
28524
+ return void 0;
28525
+ }
28526
+ if (dims.length === 1) {
28527
+ return { embedding_length: dims[0] };
28528
+ }
28529
+ if (dims.length === 2) {
28530
+ return {
28531
+ embedding_count: dims[0],
28532
+ embedding_length: dims[1]
28533
+ };
28534
+ }
28535
+ return {
28536
+ embedding_batch_count: dims[0],
28537
+ embedding_count: dims[1],
28538
+ embedding_length: dims.at(-1) ?? 0
28539
+ };
28540
+ }
28541
+ function choicesFromAnswers(result) {
28542
+ const answers = Array.isArray(result) ? result.flat() : [result];
28543
+ const choices = answers.flatMap((answer, index) => {
28544
+ if (!isObject(answer) || typeof answer.answer !== "string") {
28545
+ return [];
28546
+ }
28547
+ return [
28548
+ {
28549
+ index,
28550
+ finish_reason: "stop",
28551
+ message: {
28552
+ role: "assistant",
28553
+ content: answer.answer
28554
+ }
28555
+ }
28556
+ ];
28557
+ });
28558
+ return choices.length > 0 ? choices : void 0;
28559
+ }
28560
+ function choicesFromGenerations(result) {
28561
+ const generations = Array.isArray(result) ? result.flat() : [result];
28562
+ const choices = generations.flatMap((generation, index) => {
28563
+ if (!isObject(generation)) {
28564
+ return [];
28565
+ }
28566
+ const generated = generation.generated_text ?? generation.summary_text;
28567
+ let content;
28568
+ if (typeof generated === "string") {
28569
+ content = generated;
28570
+ } else if (isChat(generated)) {
28571
+ content = generated.at(-1)?.content;
28572
+ }
28573
+ if (typeof content !== "string") {
28574
+ return [];
28575
+ }
28576
+ return [
28577
+ {
28578
+ index,
28579
+ finish_reason: "stop",
28580
+ message: {
28581
+ role: "assistant",
28582
+ content
28583
+ }
28584
+ }
28585
+ ];
28586
+ });
28587
+ return choices.length > 0 ? choices : void 0;
28588
+ }
28589
+
26898
28590
  // src/instrumentation/plugins/openrouter-agent-channels.ts
26899
28591
  var openRouterAgentChannels = defineChannels(
26900
28592
  "@openrouter/agent",
@@ -27294,7 +28986,7 @@ function isWrappedTool(tool) {
27294
28986
  return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
27295
28987
  }
27296
28988
  function traceToolExecution(args) {
27297
- const tracingChannel2 = openRouterAgentChannels.toolExecute.tracingChannel();
28989
+ const tracingChannel = openRouterAgentChannels.toolExecute.tracingChannel();
27298
28990
  const input = args.args.length > 0 ? args.args[0] : void 0;
27299
28991
  const event = {
27300
28992
  arguments: [input],
@@ -27304,33 +28996,33 @@ function traceToolExecution(args) {
27304
28996
  toolCallId: args.toolCallId,
27305
28997
  toolName: args.toolName
27306
28998
  };
27307
- tracingChannel2.start.publish(event);
28999
+ tracingChannel.start.publish(event);
27308
29000
  try {
27309
29001
  const result = args.execute();
27310
- return publishToolResult(tracingChannel2, event, result);
29002
+ return publishToolResult(tracingChannel, event, result);
27311
29003
  } catch (error2) {
27312
29004
  event.error = normalizeError(error2);
27313
- tracingChannel2.error.publish(event);
29005
+ tracingChannel.error.publish(event);
27314
29006
  throw error2;
27315
29007
  }
27316
29008
  }
27317
- function publishToolResult(tracingChannel2, event, result) {
29009
+ function publishToolResult(tracingChannel, event, result) {
27318
29010
  if (isPromiseLike(result)) {
27319
29011
  return result.then(
27320
29012
  (resolved) => {
27321
29013
  event.result = resolved;
27322
- tracingChannel2.asyncEnd.publish(event);
29014
+ tracingChannel.asyncEnd.publish(event);
27323
29015
  return resolved;
27324
29016
  },
27325
29017
  (error2) => {
27326
29018
  event.error = normalizeError(error2);
27327
- tracingChannel2.error.publish(event);
29019
+ tracingChannel.error.publish(event);
27328
29020
  throw error2;
27329
29021
  }
27330
29022
  );
27331
29023
  }
27332
29024
  event.result = result;
27333
- tracingChannel2.asyncEnd.publish(event);
29025
+ tracingChannel.asyncEnd.publish(event);
27334
29026
  return result;
27335
29027
  }
27336
29028
  function getToolCallId(context2) {
@@ -28236,7 +29928,7 @@ function isWrappedTool2(tool) {
28236
29928
  return Boolean(tool[OPENROUTER_WRAPPED_TOOL2]);
28237
29929
  }
28238
29930
  function traceToolExecution2(args) {
28239
- const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
29931
+ const tracingChannel = openRouterChannels.toolExecute.tracingChannel();
28240
29932
  const input = args.args.length > 0 ? args.args[0] : void 0;
28241
29933
  const event = {
28242
29934
  arguments: [input],
@@ -28246,33 +29938,33 @@ function traceToolExecution2(args) {
28246
29938
  toolCallId: args.toolCallId,
28247
29939
  toolName: args.toolName
28248
29940
  };
28249
- tracingChannel2.start.publish(event);
29941
+ tracingChannel.start.publish(event);
28250
29942
  try {
28251
29943
  const result = args.execute();
28252
- return publishToolResult2(tracingChannel2, event, result);
29944
+ return publishToolResult2(tracingChannel, event, result);
28253
29945
  } catch (error2) {
28254
29946
  event.error = normalizeError2(error2);
28255
- tracingChannel2.error.publish(event);
29947
+ tracingChannel.error.publish(event);
28256
29948
  throw error2;
28257
29949
  }
28258
29950
  }
28259
- function publishToolResult2(tracingChannel2, event, result) {
29951
+ function publishToolResult2(tracingChannel, event, result) {
28260
29952
  if (isPromiseLike(result)) {
28261
29953
  return result.then(
28262
29954
  (resolved) => {
28263
29955
  event.result = resolved;
28264
- tracingChannel2.asyncEnd.publish(event);
29956
+ tracingChannel.asyncEnd.publish(event);
28265
29957
  return resolved;
28266
29958
  },
28267
29959
  (error2) => {
28268
29960
  event.error = normalizeError2(error2);
28269
- tracingChannel2.error.publish(event);
29961
+ tracingChannel.error.publish(event);
28270
29962
  throw error2;
28271
29963
  }
28272
29964
  );
28273
29965
  }
28274
29966
  event.result = result;
28275
- tracingChannel2.asyncEnd.publish(event);
29967
+ tracingChannel.asyncEnd.publish(event);
28276
29968
  return result;
28277
29969
  }
28278
29970
  function getToolCallId2(context2) {
@@ -29424,6 +31116,470 @@ function aggregateMistralStreamChunks(chunks) {
29424
31116
  };
29425
31117
  }
29426
31118
 
31119
+ // src/instrumentation/plugins/ollama-channels.ts
31120
+ var ollamaChannels = defineChannels(
31121
+ "ollama",
31122
+ {
31123
+ chat: channel({
31124
+ channelName: "chat",
31125
+ kind: "async"
31126
+ }),
31127
+ generate: channel({
31128
+ channelName: "generate",
31129
+ kind: "async"
31130
+ }),
31131
+ embed: channel({
31132
+ channelName: "embed",
31133
+ kind: "async"
31134
+ })
31135
+ },
31136
+ { instrumentationName: INSTRUMENTATION_NAMES.OLLAMA }
31137
+ );
31138
+
31139
+ // src/instrumentation/plugins/ollama-plugin.ts
31140
+ var OllamaPlugin = class extends BasePlugin {
31141
+ onEnable() {
31142
+ this.unsubscribers.push(
31143
+ traceStreamingChannel(ollamaChannels.chat, {
31144
+ name: "ollama.chat",
31145
+ type: "llm" /* LLM */,
31146
+ extractInput: extractOllamaChatInput,
31147
+ extractOutput: (result, event) => extractOllamaChatOutput(
31148
+ result,
31149
+ countOllamaToolCalls(event?.arguments?.[0]?.messages)
31150
+ ),
31151
+ extractMetadata: extractOllamaResponseMetadata,
31152
+ extractMetrics: extractOllamaMetrics,
31153
+ aggregateChunks: aggregateOllamaChatChunks
31154
+ }),
31155
+ traceStreamingChannel(ollamaChannels.generate, {
31156
+ name: "ollama.generate",
31157
+ type: "llm" /* LLM */,
31158
+ extractInput: extractOllamaGenerateInput,
31159
+ extractOutput: extractOllamaGenerateOutput,
31160
+ extractMetadata: extractOllamaResponseMetadata,
31161
+ extractMetrics: extractOllamaMetrics,
31162
+ aggregateChunks: aggregateOllamaGenerateChunks
31163
+ }),
31164
+ traceAsyncChannel(ollamaChannels.embed, {
31165
+ name: "ollama.embed",
31166
+ type: "llm" /* LLM */,
31167
+ extractInput: extractOllamaEmbedInput,
31168
+ extractOutput: extractOllamaEmbedOutput,
31169
+ extractMetadata: extractOllamaResponseMetadata,
31170
+ extractMetrics: extractOllamaMetrics
31171
+ })
31172
+ );
31173
+ }
31174
+ onDisable() {
31175
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
31176
+ }
31177
+ };
31178
+ function isNonNegativeNumber(value) {
31179
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
31180
+ }
31181
+ function normalizeFinishReason(response, hasToolCalls = false) {
31182
+ if (hasToolCalls) {
31183
+ return "tool_calls";
31184
+ }
31185
+ return response?.done_reason || "stop";
31186
+ }
31187
+ function stringifyArguments(value) {
31188
+ if (typeof value === "string") {
31189
+ return value;
31190
+ }
31191
+ try {
31192
+ return JSON.stringify(value ?? {});
31193
+ } catch {
31194
+ return String(value);
31195
+ }
31196
+ }
31197
+ function syntheticToolCallId(name, index) {
31198
+ const normalizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_") || "tool";
31199
+ return `ollama_call_${normalizedName}_${index}`;
31200
+ }
31201
+ function normalizeToolCall(toolCall, index) {
31202
+ const name = toolCall.function?.name;
31203
+ if (typeof name !== "string" || name.length === 0) {
31204
+ return void 0;
31205
+ }
31206
+ return {
31207
+ id: typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : syntheticToolCallId(name, index),
31208
+ type: "function",
31209
+ function: {
31210
+ name,
31211
+ arguments: stringifyArguments(toolCall.function?.arguments)
31212
+ }
31213
+ };
31214
+ }
31215
+ function normalizeToolCalls(toolCalls, syntheticIdOffset = 0) {
31216
+ if (!Array.isArray(toolCalls)) {
31217
+ return [];
31218
+ }
31219
+ return toolCalls.flatMap((toolCall, index) => {
31220
+ const normalized = normalizeToolCall(toolCall, syntheticIdOffset + index);
31221
+ return normalized ? [normalized] : [];
31222
+ });
31223
+ }
31224
+ function countOllamaToolCalls(messages) {
31225
+ if (!Array.isArray(messages)) {
31226
+ return 0;
31227
+ }
31228
+ return messages.reduce(
31229
+ (count, message) => count + (isObject(message) && Array.isArray(message.tool_calls) ? message.tool_calls.length : 0),
31230
+ 0
31231
+ );
31232
+ }
31233
+ function imageBytes(value) {
31234
+ if (value instanceof Uint8Array) {
31235
+ return value;
31236
+ }
31237
+ if (value instanceof ArrayBuffer) {
31238
+ return new Uint8Array(value);
31239
+ }
31240
+ if (typeof value !== "string" || value.startsWith("data:")) {
31241
+ return void 0;
31242
+ }
31243
+ try {
31244
+ const decoded = atob(value.slice(0, 24));
31245
+ return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
31246
+ } catch {
31247
+ return void 0;
31248
+ }
31249
+ }
31250
+ function inferImageMediaType(value) {
31251
+ if (typeof value === "string") {
31252
+ const dataUrlType = value.match(/^data:(image\/[^;]+);base64,/i)?.[1];
31253
+ if (dataUrlType) {
31254
+ return dataUrlType;
31255
+ }
31256
+ }
31257
+ const bytes = imageBytes(value);
31258
+ if (!bytes) {
31259
+ return void 0;
31260
+ }
31261
+ if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
31262
+ return "image/png";
31263
+ }
31264
+ if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
31265
+ return "image/jpeg";
31266
+ }
31267
+ const signature = String.fromCharCode(...bytes.slice(0, 12));
31268
+ if (signature.startsWith("GIF87a") || signature.startsWith("GIF89a")) {
31269
+ return "image/gif";
31270
+ }
31271
+ if (signature.startsWith("RIFF") && signature.slice(8, 12) === "WEBP") {
31272
+ return "image/webp";
31273
+ }
31274
+ return void 0;
31275
+ }
31276
+ function normalizeTextAndImages(content, images) {
31277
+ if (!images || images.length === 0) {
31278
+ return { content };
31279
+ }
31280
+ const imageParts = [];
31281
+ const unrecognizedImages = [];
31282
+ for (const image of images) {
31283
+ let localImagePath;
31284
+ let localPathMediaType;
31285
+ if (typeof image === "string" && !/^data:/i.test(image) && !/^https?:\/\//i.test(image)) {
31286
+ const extension = image.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
31287
+ const extensionMediaType = {
31288
+ png: "image/png",
31289
+ jpg: "image/jpeg",
31290
+ jpeg: "image/jpeg",
31291
+ gif: "image/gif",
31292
+ webp: "image/webp"
31293
+ }[extension ?? ""];
31294
+ if (extensionMediaType && isomorph_default.statSync) {
31295
+ try {
31296
+ if (isomorph_default.statSync(image).isFile()) {
31297
+ localImagePath = image;
31298
+ localPathMediaType = extensionMediaType;
31299
+ }
31300
+ } catch {
31301
+ }
31302
+ }
31303
+ }
31304
+ const mediaType = localPathMediaType ?? inferImageMediaType(image);
31305
+ if (!mediaType) {
31306
+ unrecognizedImages.push(image);
31307
+ continue;
31308
+ }
31309
+ const processedImage = localImagePath ? new Attachment({
31310
+ data: localImagePath,
31311
+ filename: localImagePath.split(/[\\/]/).at(-1) ?? "image",
31312
+ contentType: mediaType
31313
+ }) : processInputAttachments({
31314
+ type: "image",
31315
+ image,
31316
+ mediaType
31317
+ }).image;
31318
+ imageParts.push({
31319
+ type: "image_url",
31320
+ image_url: { url: processedImage }
31321
+ });
31322
+ }
31323
+ return {
31324
+ content: imageParts.length > 0 ? [...content ? [{ type: "text", text: content }] : [], ...imageParts] : content,
31325
+ ...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
31326
+ };
31327
+ }
31328
+ function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
31329
+ if (typeof message.role !== "string") {
31330
+ return void 0;
31331
+ }
31332
+ const toolCalls = normalizeToolCalls(
31333
+ message.tool_calls,
31334
+ syntheticToolCallIdOffset
31335
+ );
31336
+ if (message.role === "tool") {
31337
+ const toolName = typeof message.tool_name === "string" && message.tool_name.length > 0 ? message.tool_name : "tool";
31338
+ return {
31339
+ role: "tool",
31340
+ tool_call_id: toolCallId ?? syntheticToolCallId(toolName, 0),
31341
+ content: typeof message.content === "string" ? message.content : ""
31342
+ };
31343
+ }
31344
+ const normalizedContent = normalizeTextAndImages(
31345
+ typeof message.content === "string" ? message.content || (toolCalls.length > 0 ? null : "") : toolCalls.length > 0 ? null : "",
31346
+ message.images
31347
+ );
31348
+ return {
31349
+ role: message.role,
31350
+ content: normalizedContent.content,
31351
+ ...typeof message.thinking === "string" && message.thinking.length > 0 ? { reasoning: message.thinking } : {},
31352
+ ...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
31353
+ ...normalizedContent.unrecognizedImages ? { images: normalizedContent.unrecognizedImages } : {}
31354
+ };
31355
+ }
31356
+ function normalizeMessages(messages) {
31357
+ if (!Array.isArray(messages)) {
31358
+ return [];
31359
+ }
31360
+ const pendingToolCallIds = /* @__PURE__ */ new Map();
31361
+ let syntheticToolCallIdOffset = 0;
31362
+ return messages.flatMap((message) => {
31363
+ if (!isObject(message)) {
31364
+ return [];
31365
+ }
31366
+ const ollamaMessage = message;
31367
+ let toolCallId;
31368
+ if (ollamaMessage.role === "tool") {
31369
+ const toolName = ollamaMessage.tool_name;
31370
+ if (typeof toolName === "string") {
31371
+ toolCallId = pendingToolCallIds.get(toolName)?.shift();
31372
+ }
31373
+ }
31374
+ const normalized = normalizeMessage(
31375
+ ollamaMessage,
31376
+ toolCallId,
31377
+ syntheticToolCallIdOffset
31378
+ );
31379
+ if (Array.isArray(ollamaMessage.tool_calls)) {
31380
+ syntheticToolCallIdOffset += ollamaMessage.tool_calls.length;
31381
+ }
31382
+ if (ollamaMessage.role === "assistant" && normalized) {
31383
+ const toolCalls = Array.isArray(normalized.tool_calls) ? normalized.tool_calls : [];
31384
+ for (const toolCall of toolCalls) {
31385
+ if (!isObject(toolCall) || !isObject(toolCall.function)) {
31386
+ continue;
31387
+ }
31388
+ const name = toolCall.function.name;
31389
+ const id = toolCall.id;
31390
+ if (typeof name === "string" && typeof id === "string") {
31391
+ const ids = pendingToolCallIds.get(name) ?? [];
31392
+ ids.push(id);
31393
+ pendingToolCallIds.set(name, ids);
31394
+ }
31395
+ }
31396
+ }
31397
+ return normalized ? [normalized] : [];
31398
+ });
31399
+ }
31400
+ function normalizeToolDefinition(tool) {
31401
+ const fn = tool.function;
31402
+ if (!fn || typeof fn.name !== "string" || fn.name.length === 0) {
31403
+ return void 0;
31404
+ }
31405
+ return {
31406
+ type: "function",
31407
+ function: {
31408
+ name: fn.name,
31409
+ ...typeof fn.description === "string" ? { description: fn.description } : {},
31410
+ ...isObject(fn.parameters) ? { parameters: fn.parameters } : {}
31411
+ }
31412
+ };
31413
+ }
31414
+ function extractToolsMetadata(tools) {
31415
+ if (!Array.isArray(tools)) {
31416
+ return {};
31417
+ }
31418
+ const normalized = tools.flatMap((tool) => {
31419
+ if (!isObject(tool)) {
31420
+ return [];
31421
+ }
31422
+ const definition = normalizeToolDefinition(tool);
31423
+ return definition ? [definition] : [];
31424
+ });
31425
+ return normalized.length > 0 ? { tools: normalized } : {};
31426
+ }
31427
+ function extractOptionsMetadata(options) {
31428
+ if (!isObject(options)) {
31429
+ return {};
31430
+ }
31431
+ const metadata = {};
31432
+ const mappings = [
31433
+ ["temperature", "temperature"],
31434
+ ["top_p", "top_p"],
31435
+ ["num_predict", "max_tokens"],
31436
+ ["frequency_penalty", "frequency_penalty"],
31437
+ ["presence_penalty", "presence_penalty"],
31438
+ ["stop", "stop"]
31439
+ ];
31440
+ for (const [source, target] of mappings) {
31441
+ if (options[source] !== void 0) {
31442
+ metadata[target] = options[source];
31443
+ }
31444
+ }
31445
+ return metadata;
31446
+ }
31447
+ function extractRequestMetadata(request) {
31448
+ return {
31449
+ provider: "ollama",
31450
+ ...typeof request?.model === "string" ? { model: request.model } : {},
31451
+ ...extractOptionsMetadata(request?.options),
31452
+ ...request?.format !== void 0 ? { response_format: request.format } : {}
31453
+ };
31454
+ }
31455
+ function extractOllamaChatInput([request]) {
31456
+ return {
31457
+ input: normalizeMessages(request.messages),
31458
+ metadata: {
31459
+ ...extractRequestMetadata(request),
31460
+ ...extractToolsMetadata(request.tools)
31461
+ }
31462
+ };
31463
+ }
31464
+ function extractOllamaGenerateInput([request]) {
31465
+ const normalizedPrompt = normalizeTextAndImages(
31466
+ typeof request.prompt === "string" ? request.prompt : "",
31467
+ Array.isArray(request.images) ? request.images : void 0
31468
+ );
31469
+ const input = [
31470
+ ...typeof request.system === "string" ? [{ role: "system", content: request.system }] : [],
31471
+ {
31472
+ role: "user",
31473
+ content: normalizedPrompt.content,
31474
+ ...typeof request.suffix === "string" ? { suffix: request.suffix } : {},
31475
+ ...normalizedPrompt.unrecognizedImages ? { images: normalizedPrompt.unrecognizedImages } : {}
31476
+ }
31477
+ ];
31478
+ return {
31479
+ input,
31480
+ metadata: extractRequestMetadata(request)
31481
+ };
31482
+ }
31483
+ function extractOllamaEmbedInput([request]) {
31484
+ return {
31485
+ input: request.input,
31486
+ metadata: extractRequestMetadata(request)
31487
+ };
31488
+ }
31489
+ function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
31490
+ if (!isObject(result) || !isObject(result.message)) {
31491
+ return void 0;
31492
+ }
31493
+ const message = normalizeMessage(
31494
+ result.message,
31495
+ void 0,
31496
+ syntheticToolCallIdOffset
31497
+ );
31498
+ if (!message) {
31499
+ return void 0;
31500
+ }
31501
+ const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
31502
+ return [
31503
+ {
31504
+ index: 0,
31505
+ finish_reason: normalizeFinishReason(result, toolCalls.length > 0),
31506
+ message
31507
+ }
31508
+ ];
31509
+ }
31510
+ function extractOllamaGenerateOutput(result) {
31511
+ if (!isObject(result) || typeof result.response !== "string") {
31512
+ return void 0;
31513
+ }
31514
+ return [
31515
+ {
31516
+ index: 0,
31517
+ finish_reason: normalizeFinishReason(result),
31518
+ message: {
31519
+ role: "assistant",
31520
+ content: result.response,
31521
+ ...typeof result.thinking === "string" && result.thinking.length > 0 ? { reasoning: result.thinking } : {}
31522
+ }
31523
+ }
31524
+ ];
31525
+ }
31526
+ function extractOllamaEmbedOutput(result) {
31527
+ const embedding = Array.isArray(result?.embeddings) ? result.embeddings[0] : void 0;
31528
+ return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
31529
+ }
31530
+ function extractOllamaResponseMetadata(result) {
31531
+ return typeof result?.model === "string" ? { model: result.model } : void 0;
31532
+ }
31533
+ function extractOllamaMetrics(result) {
31534
+ const metrics = {};
31535
+ const promptTokens = result?.prompt_eval_count;
31536
+ const completionTokens = result?.eval_count;
31537
+ if (isNonNegativeNumber(promptTokens)) {
31538
+ metrics.prompt_tokens = promptTokens;
31539
+ }
31540
+ if (isNonNegativeNumber(completionTokens)) {
31541
+ metrics.completion_tokens = completionTokens;
31542
+ }
31543
+ if (isNonNegativeNumber(promptTokens) || isNonNegativeNumber(completionTokens)) {
31544
+ metrics.tokens = (isNonNegativeNumber(promptTokens) ? promptTokens : 0) + (isNonNegativeNumber(completionTokens) ? completionTokens : 0);
31545
+ }
31546
+ return metrics;
31547
+ }
31548
+ function aggregateOllamaChatChunks(chunks, _result, event, _startTime) {
31549
+ const last = chunks.at(-1);
31550
+ const message = {
31551
+ role: "assistant",
31552
+ content: chunks.map((chunk) => chunk.message?.content ?? "").join(""),
31553
+ thinking: chunks.map((chunk) => chunk.message?.thinking ?? "").join(""),
31554
+ tool_calls: chunks.flatMap((chunk) => chunk.message?.tool_calls ?? [])
31555
+ };
31556
+ const response = {
31557
+ ...last,
31558
+ message
31559
+ };
31560
+ return {
31561
+ output: extractOllamaChatOutput(
31562
+ response,
31563
+ countOllamaToolCalls(event?.arguments?.[0]?.messages)
31564
+ ),
31565
+ metrics: extractOllamaMetrics(last ?? {}),
31566
+ metadata: extractOllamaResponseMetadata(last ?? {})
31567
+ };
31568
+ }
31569
+ function aggregateOllamaGenerateChunks(chunks, _result, _event, _startTime) {
31570
+ const last = chunks.at(-1);
31571
+ const response = {
31572
+ ...last,
31573
+ response: chunks.map((chunk) => chunk.response ?? "").join(""),
31574
+ thinking: chunks.map((chunk) => chunk.thinking ?? "").join("")
31575
+ };
31576
+ return {
31577
+ output: extractOllamaGenerateOutput(response),
31578
+ metrics: extractOllamaMetrics(last ?? {}),
31579
+ metadata: extractOllamaResponseMetadata(last ?? {})
31580
+ };
31581
+ }
31582
+
29427
31583
  // src/instrumentation/plugins/google-adk-channels.ts
29428
31584
  var googleADKChannels = defineChannels(
29429
31585
  "@google/adk",
@@ -29462,7 +31618,7 @@ var GoogleADKPlugin = class extends BasePlugin {
29462
31618
  this.activeAgentSpans.clear();
29463
31619
  }
29464
31620
  subscribeToRunnerRunAsync() {
29465
- const tracingChannel2 = googleADKChannels.runnerRunAsync.tracingChannel();
31621
+ const tracingChannel = googleADKChannels.runnerRunAsync.tracingChannel();
29466
31622
  const states = /* @__PURE__ */ new WeakMap();
29467
31623
  const createState = (event) => {
29468
31624
  const params = event.arguments[0] ?? {};
@@ -29493,7 +31649,7 @@ var GoogleADKPlugin = class extends BasePlugin {
29493
31649
  return { span, startTime, events: [], contextKey };
29494
31650
  };
29495
31651
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
29496
- tracingChannel2,
31652
+ tracingChannel,
29497
31653
  states,
29498
31654
  createState
29499
31655
  );
@@ -29545,14 +31701,14 @@ var GoogleADKPlugin = class extends BasePlugin {
29545
31701
  states.delete(event);
29546
31702
  }
29547
31703
  };
29548
- tracingChannel2.subscribe(handlers);
31704
+ tracingChannel.subscribe(handlers);
29549
31705
  this.unsubscribers.push(() => {
29550
31706
  unbindCurrentSpanStore?.();
29551
- tracingChannel2.unsubscribe(handlers);
31707
+ tracingChannel.unsubscribe(handlers);
29552
31708
  });
29553
31709
  }
29554
31710
  subscribeToAgentRunAsync() {
29555
- const tracingChannel2 = googleADKChannels.agentRunAsync.tracingChannel();
31711
+ const tracingChannel = googleADKChannels.agentRunAsync.tracingChannel();
29556
31712
  const states = /* @__PURE__ */ new WeakMap();
29557
31713
  const createState = (event) => {
29558
31714
  const parentContext = event.arguments[0];
@@ -29601,7 +31757,7 @@ var GoogleADKPlugin = class extends BasePlugin {
29601
31757
  return { span, startTime, events: [], contextKey, name: agentName };
29602
31758
  };
29603
31759
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
29604
- tracingChannel2,
31760
+ tracingChannel,
29605
31761
  states,
29606
31762
  createState
29607
31763
  );
@@ -29653,14 +31809,14 @@ var GoogleADKPlugin = class extends BasePlugin {
29653
31809
  states.delete(event);
29654
31810
  }
29655
31811
  };
29656
- tracingChannel2.subscribe(handlers);
31812
+ tracingChannel.subscribe(handlers);
29657
31813
  this.unsubscribers.push(() => {
29658
31814
  unbindCurrentSpanStore?.();
29659
- tracingChannel2.unsubscribe(handlers);
31815
+ tracingChannel.unsubscribe(handlers);
29660
31816
  });
29661
31817
  }
29662
31818
  subscribeToToolRunAsync() {
29663
- const tracingChannel2 = googleADKChannels.toolRunAsync.tracingChannel();
31819
+ const tracingChannel = googleADKChannels.toolRunAsync.tracingChannel();
29664
31820
  const states = /* @__PURE__ */ new WeakMap();
29665
31821
  const handlers = {
29666
31822
  start: (event) => {
@@ -29727,9 +31883,9 @@ var GoogleADKPlugin = class extends BasePlugin {
29727
31883
  states.delete(event);
29728
31884
  }
29729
31885
  };
29730
- tracingChannel2.subscribe(handlers);
31886
+ tracingChannel.subscribe(handlers);
29731
31887
  this.unsubscribers.push(() => {
29732
- tracingChannel2.unsubscribe(handlers);
31888
+ tracingChannel.unsubscribe(handlers);
29733
31889
  });
29734
31890
  }
29735
31891
  };
@@ -29805,10 +31961,10 @@ function bindAsyncIterableToCurrentSpan(stream, span) {
29805
31961
  }
29806
31962
  return stream;
29807
31963
  }
29808
- function bindCurrentSpanStoreToStart3(tracingChannel2, states, create) {
31964
+ function bindCurrentSpanStoreToStart3(tracingChannel, states, create) {
29809
31965
  const state = _internalGetGlobalState();
29810
31966
  const contextManager = state?.contextManager;
29811
- const startChannel = tracingChannel2.start;
31967
+ const startChannel = tracingChannel.start;
29812
31968
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
29813
31969
  if (!startChannel?.bindStore || !currentSpanStore) {
29814
31970
  return void 0;
@@ -30060,15 +32216,32 @@ function aggregateUsageFromEvents(events) {
30060
32216
  if (usage.thoughtsTokenCount !== void 0) {
30061
32217
  aggregated.thoughtsTokenCount = (aggregated.thoughtsTokenCount ?? 0) + usage.thoughtsTokenCount;
30062
32218
  }
32219
+ if (usage.toolUsePromptTokenCount !== void 0) {
32220
+ aggregated.toolUsePromptTokenCount = (aggregated.toolUsePromptTokenCount ?? 0) + usage.toolUsePromptTokenCount;
32221
+ }
32222
+ for (const detailsField of [
32223
+ "promptTokensDetails",
32224
+ "cacheTokensDetails",
32225
+ "candidatesTokensDetails",
32226
+ "toolUsePromptTokensDetails"
32227
+ ]) {
32228
+ const details = usage[detailsField];
32229
+ if (details !== void 0) {
32230
+ aggregated[detailsField] = [
32231
+ ...aggregated[detailsField] ?? [],
32232
+ ...details
32233
+ ];
32234
+ }
32235
+ }
30063
32236
  }
30064
32237
  return hasUsage ? aggregated : void 0;
30065
32238
  }
30066
32239
  function populateUsageMetrics2(metrics, usage) {
30067
- if (usage.promptTokenCount !== void 0) {
30068
- metrics.prompt_tokens = usage.promptTokenCount;
32240
+ if (usage.promptTokenCount !== void 0 || usage.toolUsePromptTokenCount !== void 0) {
32241
+ metrics.prompt_tokens = (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0);
30069
32242
  }
30070
- if (usage.candidatesTokenCount !== void 0) {
30071
- metrics.completion_tokens = usage.candidatesTokenCount;
32243
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0) {
32244
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
30072
32245
  }
30073
32246
  if (usage.totalTokenCount !== void 0) {
30074
32247
  metrics.tokens = usage.totalTokenCount;
@@ -30079,6 +32252,19 @@ function populateUsageMetrics2(metrics, usage) {
30079
32252
  if (usage.thoughtsTokenCount !== void 0) {
30080
32253
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
30081
32254
  }
32255
+ for (const detail of usage.promptTokensDetails ?? []) {
32256
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
32257
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
32258
+ }
32259
+ }
32260
+ for (const detail of usage.candidatesTokensDetails ?? []) {
32261
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
32262
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokenCount;
32263
+ }
32264
+ if (detail.modality === "IMAGE" && detail.tokenCount !== void 0) {
32265
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokenCount;
32266
+ }
32267
+ }
30082
32268
  }
30083
32269
  function cleanMetrics4(metrics) {
30084
32270
  const cleaned = {};
@@ -31644,10 +33830,10 @@ var GenkitPlugin = class extends BasePlugin {
31644
33830
  this.subscribeToActionStream();
31645
33831
  }
31646
33832
  subscribeToActionRun() {
31647
- const tracingChannel2 = genkitChannels.actionRun.tracingChannel();
33833
+ const tracingChannel = genkitChannels.actionRun.tracingChannel();
31648
33834
  const states = /* @__PURE__ */ new WeakMap();
31649
33835
  const unbindCurrentSpanStore = bindActionCurrentSpanStoreToStart(
31650
- tracingChannel2,
33836
+ tracingChannel,
31651
33837
  states,
31652
33838
  (event) => startActionRunSpan(event)
31653
33839
  );
@@ -31684,17 +33870,17 @@ var GenkitPlugin = class extends BasePlugin {
31684
33870
  states.delete(event);
31685
33871
  }
31686
33872
  };
31687
- tracingChannel2.subscribe(handlers);
33873
+ tracingChannel.subscribe(handlers);
31688
33874
  this.unsubscribers.push(() => {
31689
33875
  unbindCurrentSpanStore?.();
31690
- tracingChannel2.unsubscribe(handlers);
33876
+ tracingChannel.unsubscribe(handlers);
31691
33877
  });
31692
33878
  }
31693
33879
  subscribeToActionSpan() {
31694
- const tracingChannel2 = genkitCoreChannels.actionSpan.tracingChannel();
33880
+ const tracingChannel = genkitCoreChannels.actionSpan.tracingChannel();
31695
33881
  const states = /* @__PURE__ */ new WeakMap();
31696
33882
  const unbindCurrentSpanStore = bindActionCurrentSpanStoreToStart(
31697
- tracingChannel2,
33883
+ tracingChannel,
31698
33884
  states,
31699
33885
  (event) => startActionSpan(event)
31700
33886
  );
@@ -31732,10 +33918,10 @@ var GenkitPlugin = class extends BasePlugin {
31732
33918
  states.delete(event);
31733
33919
  }
31734
33920
  };
31735
- tracingChannel2.subscribe(handlers);
33921
+ tracingChannel.subscribe(handlers);
31736
33922
  this.unsubscribers.push(() => {
31737
33923
  unbindCurrentSpanStore?.();
31738
- tracingChannel2.unsubscribe(handlers);
33924
+ tracingChannel.unsubscribe(handlers);
31739
33925
  });
31740
33926
  }
31741
33927
  subscribeToActionStream() {
@@ -31804,10 +33990,10 @@ function ensureActionSpanState(states, event, create) {
31804
33990
  }
31805
33991
  return created;
31806
33992
  }
31807
- function bindActionCurrentSpanStoreToStart(tracingChannel2, states, create) {
33993
+ function bindActionCurrentSpanStoreToStart(tracingChannel, states, create) {
31808
33994
  const state = _internalGetGlobalState();
31809
33995
  const contextManager = state?.contextManager;
31810
- const startChannel = tracingChannel2.start;
33996
+ const startChannel = tracingChannel.start;
31811
33997
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
31812
33998
  if (!startChannel?.bindStore || !currentSpanStore) {
31813
33999
  return void 0;
@@ -33147,7 +35333,7 @@ var FlueObserveBridge = class {
33147
35333
  return;
33148
35334
  }
33149
35335
  const state = this.operationsById.get(event.operationId) ?? this.startSyntheticOperation(event);
33150
- const output = operationOutput(event);
35336
+ const output = operationOutput(event) ?? outputFromAgentTurn(state.latestAgentOutput);
33151
35337
  const metadata = {
33152
35338
  ...state.metadata,
33153
35339
  ...extractEventMetadata(event),
@@ -33156,7 +35342,7 @@ var FlueObserveBridge = class {
33156
35342
  };
33157
35343
  this.finishPendingChildrenForOperation(event, output);
33158
35344
  safeLog3(state.span, {
33159
- ...event.isError ? { error: toLoggedError(event.error) } : {},
35345
+ ...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
33160
35346
  metadata,
33161
35347
  metrics: durationMetrics2(event.durationMs),
33162
35348
  output
@@ -33187,7 +35373,7 @@ var FlueObserveBridge = class {
33187
35373
  };
33188
35374
  const parent = this.parentSpanForTurn(event);
33189
35375
  const span = startFlueSpan(parent, {
33190
- name: `llm:${model ?? event.purpose ?? "unknown"}`,
35376
+ name: "flue.turn",
33191
35377
  spanAttributes: { type: "llm" /* LLM */ },
33192
35378
  startTime: eventTime(event.timestamp),
33193
35379
  event: {
@@ -33231,6 +35417,12 @@ var FlueObserveBridge = class {
33231
35417
  },
33232
35418
  output
33233
35419
  });
35420
+ if (event.purpose === "agent" && event.operationId) {
35421
+ const operation = this.operationsById.get(event.operationId);
35422
+ if (operation) {
35423
+ operation.latestAgentOutput = output;
35424
+ }
35425
+ }
33234
35426
  safeEnd(state.span, eventTime(event.timestamp));
33235
35427
  this.turnsByKey.delete(key);
33236
35428
  }
@@ -33310,7 +35502,7 @@ var FlueObserveBridge = class {
33310
35502
  return;
33311
35503
  }
33312
35504
  safeLog3(state.span, {
33313
- ...event.isError ? { error: toLoggedError(event.result) } : {},
35505
+ ...event.isError ? { error: toLoggedError(event.errorInfo ?? event.result) } : {},
33314
35506
  metadata: {
33315
35507
  ...state.metadata,
33316
35508
  ...extractEventMetadata(event),
@@ -33356,6 +35548,7 @@ var FlueObserveBridge = class {
33356
35548
  ...event.usage ? { "flue.usage": event.usage } : {}
33357
35549
  };
33358
35550
  safeLog3(state.span, {
35551
+ ...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
33359
35552
  metadata,
33360
35553
  metrics: {
33361
35554
  ...durationMetrics2(event.durationMs),
@@ -33460,7 +35653,7 @@ var FlueObserveBridge = class {
33460
35653
  ...event.purpose ? { "flue.turn_purpose": event.purpose } : {}
33461
35654
  };
33462
35655
  const span = startFlueSpan(this.parentSpanForEvent(event), {
33463
- name: `llm:${model ?? event.purpose ?? "unknown"}`,
35656
+ name: "flue.turn",
33464
35657
  spanAttributes: { type: "llm" /* LLM */ },
33465
35658
  startTime: eventTime(event.timestamp),
33466
35659
  event: { metadata }
@@ -33592,7 +35785,10 @@ function extractEventMetadata(event, ctx) {
33592
35785
  return {
33593
35786
  ...event.runId ? { "flue.run_id": event.runId } : {},
33594
35787
  ...event.instanceId ? { "flue.instance_id": event.instanceId } : {},
35788
+ ...event.submissionId ? { "flue.submission_id": event.submissionId } : {},
33595
35789
  ...event.dispatchId ? { "flue.dispatch_id": event.dispatchId } : {},
35790
+ ...event.agentName ? { "flue.agent_name": event.agentName } : {},
35791
+ ...event.conversationId ? { "flue.conversation_id": event.conversationId } : {},
33596
35792
  ...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
33597
35793
  ...event.session ? { "flue.session": event.session } : {},
33598
35794
  ...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
@@ -33621,7 +35817,7 @@ function flueTurnRequestInput(event) {
33621
35817
  return event.request?.input ?? event.input;
33622
35818
  }
33623
35819
  function flueTurnRequestModel(event) {
33624
- return event.request?.model ?? event.model;
35820
+ return event.request?.requestedModel ?? event.request?.model ?? event.model;
33625
35821
  }
33626
35822
  function flueTurnRequestProvider(event) {
33627
35823
  return event.request?.providerName ?? event.provider ?? event.request?.providerId;
@@ -33630,10 +35826,10 @@ function flueTurnRequestApi(event) {
33630
35826
  return event.request?.api ?? event.api;
33631
35827
  }
33632
35828
  function flueTurnRequestReasoning(event) {
33633
- return event.request?.reasoning ?? event.reasoning;
35829
+ return event.request?.reasoningLevel ?? event.request?.reasoning ?? event.reasoning;
33634
35830
  }
33635
35831
  function flueTurnModel(event) {
33636
- return event.request?.model ?? event.model;
35832
+ return event.response?.responseModel ?? event.request?.requestedModel ?? event.request?.model ?? event.model;
33637
35833
  }
33638
35834
  function flueTurnProvider(event) {
33639
35835
  return event.request?.providerName ?? event.provider ?? event.request?.providerId;
@@ -33648,7 +35844,7 @@ function flueTurnOutput(event) {
33648
35844
  return event.response?.output ?? event.output;
33649
35845
  }
33650
35846
  function flueTurnStopReason(event) {
33651
- return event.response?.stopReason ?? event.stopReason;
35847
+ return event.response?.finishReason ?? event.response?.stopReason ?? event.stopReason;
33652
35848
  }
33653
35849
  function flueTurnError(event) {
33654
35850
  return event.response?.error ?? event.response?.errorInfo?.message ?? event.error;
@@ -33663,6 +35859,9 @@ function flueToolInput(event) {
33663
35859
  return event.input;
33664
35860
  }
33665
35861
  function flueToolOutput(event) {
35862
+ if (Object.hasOwn(event, "effectiveResult")) {
35863
+ return event.effectiveResult;
35864
+ }
33666
35865
  return event.output !== void 0 ? event.output : event.result;
33667
35866
  }
33668
35867
  function flueToolError(event) {
@@ -33670,10 +35869,36 @@ function flueToolError(event) {
33670
35869
  }
33671
35870
  function operationOutput(event) {
33672
35871
  if (event.operationKind === "prompt" || event.operationKind === "skill") {
33673
- return llmResultFromOperationResult(event.result);
35872
+ return outputFromAgentInvocation(event.agentOutput) ?? llmResultFromOperationResult(event.result);
33674
35873
  }
33675
35874
  return event.result ?? (event.operationKind === "compact" ? { completed: true } : void 0);
33676
35875
  }
35876
+ function outputFromAgentInvocation(output) {
35877
+ if (output?.type === "text") {
35878
+ return output.text;
35879
+ }
35880
+ if (output?.type === "data") {
35881
+ return output.data;
35882
+ }
35883
+ return void 0;
35884
+ }
35885
+ function outputFromAgentTurn(output) {
35886
+ if (!isObjectLike(output)) {
35887
+ return output;
35888
+ }
35889
+ const content = Reflect.get(output, "content");
35890
+ if (!Array.isArray(content)) {
35891
+ return output;
35892
+ }
35893
+ const text = content.flatMap((part) => {
35894
+ if (!isObjectLike(part) || Reflect.get(part, "type") !== "text") {
35895
+ return [];
35896
+ }
35897
+ const value = Reflect.get(part, "text");
35898
+ return typeof value === "string" ? [value] : [];
35899
+ });
35900
+ return text.length > 0 ? text.join("") : output;
35901
+ }
33677
35902
  function llmResultFromOperationResult(result) {
33678
35903
  if (!isObjectLike(result)) {
33679
35904
  return result;
@@ -33772,7 +35997,7 @@ function safeEnd(span, endTime) {
33772
35997
  }
33773
35998
  }
33774
35999
  function logInstrumentationError3(label, error2) {
33775
- console.error(`Error in ${label} instrumentation:`, error2);
36000
+ debugLogger.debug(`Error in ${label} instrumentation:`, error2);
33776
36001
  }
33777
36002
 
33778
36003
  // src/wrappers/langchain/callback-handler.ts
@@ -34169,7 +36394,7 @@ var LangChainPlugin = class extends BasePlugin {
34169
36394
  this.injectedManagers = /* @__PURE__ */ new WeakSet();
34170
36395
  }
34171
36396
  subscribeToConfigure(channel2) {
34172
- const tracingChannel2 = channel2.tracingChannel();
36397
+ const tracingChannel = channel2.tracingChannel();
34173
36398
  const handlers = {
34174
36399
  start: (event) => {
34175
36400
  injectHandlerIntoArguments(event.arguments);
@@ -34178,9 +36403,9 @@ var LangChainPlugin = class extends BasePlugin {
34178
36403
  this.injectHandler(event.result);
34179
36404
  }
34180
36405
  };
34181
- tracingChannel2.subscribe(handlers);
36406
+ tracingChannel.subscribe(handlers);
34182
36407
  this.unsubscribers.push(() => {
34183
- tracingChannel2.unsubscribe(handlers);
36408
+ tracingChannel.unsubscribe(handlers);
34184
36409
  });
34185
36410
  }
34186
36411
  injectHandler(result) {
@@ -34444,7 +36669,7 @@ var LangSmithPlugin = class extends BasePlugin {
34444
36669
  const inputs = preferOwnValue(run2, previous, "inputs");
34445
36670
  const outputs = preferOwnValue(run2, previous, "outputs");
34446
36671
  const error2 = errorMessage(preferOwnValue(run2, previous, "error"));
34447
- const metadata = extractMetadata(run2, previous);
36672
+ const metadata = extractMetadata2(run2, previous);
34448
36673
  const tags = extractTags(preferOwnValue(run2, previous, "tags"));
34449
36674
  const metrics = extractMetrics(run2, previous);
34450
36675
  span.log({
@@ -34549,7 +36774,7 @@ function mapRunType(runType) {
34549
36774
  return "task" /* TASK */;
34550
36775
  }
34551
36776
  }
34552
- function extractMetadata(run2, previous) {
36777
+ function extractMetadata2(run2, previous) {
34553
36778
  const extra = preferOwnValue(run2, previous, "extra");
34554
36779
  const rawMetadata = ownValue(extra, "metadata");
34555
36780
  if (!isRecord2(rawMetadata)) {
@@ -34701,12 +36926,13 @@ var piCodingAgentChannels = defineChannels(
34701
36926
  );
34702
36927
 
34703
36928
  // src/instrumentation/plugins/pi-coding-agent-plugin.ts
34704
- var piStreamPatchStates = /* @__PURE__ */ new WeakMap();
36929
+ var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
36930
+ var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
34705
36931
  var piPromptContextStore;
34706
36932
  var PiCodingAgentPlugin = class extends BasePlugin {
34707
36933
  activePromptStates = /* @__PURE__ */ new Set();
34708
36934
  onEnable() {
34709
- this.subscribeToPrompt();
36935
+ this.interceptPrompt();
34710
36936
  }
34711
36937
  onDisable() {
34712
36938
  for (const unsubscribe of this.unsubscribers) {
@@ -34714,65 +36940,74 @@ var PiCodingAgentPlugin = class extends BasePlugin {
34714
36940
  }
34715
36941
  this.unsubscribers = [];
34716
36942
  for (const state of [...this.activePromptStates]) {
34717
- void finalizePiPromptRun(state).catch((error2) => {
34718
- logInstrumentationError4("Pi Coding Agent disable cleanup", error2);
34719
- });
36943
+ finishPiPromptRun(state);
34720
36944
  }
34721
36945
  }
34722
- subscribeToPrompt() {
34723
- const channel2 = piCodingAgentChannels.prompt.tracingChannel();
34724
- const states = /* @__PURE__ */ new WeakMap();
34725
- const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(channel2);
34726
- const handlers = {
34727
- start: (event) => {
34728
- const state = startPiPromptRun(event, (state2) => {
34729
- this.activePromptStates.delete(state2);
34730
- });
34731
- if (state) {
34732
- this.activePromptStates.add(state);
34733
- states.set(event, state);
34734
- }
34735
- },
34736
- asyncEnd: async (event) => {
34737
- const state = states.get(event);
34738
- if (!state) {
34739
- return;
34740
- }
34741
- states.delete(event);
34742
- state.promptCallEnded = true;
34743
- if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
34744
- if (!state.sawStreamFn) {
34745
- state.queued = true;
34746
- if (!state.streamPatchState.queuedPromptStates.includes(state)) {
34747
- state.streamPatchState.queuedPromptStates.push(state);
34748
- }
36946
+ interceptPrompt() {
36947
+ this.unsubscribers.push(
36948
+ piCodingAgentChannels.prompt.intercept(
36949
+ (target, thisArg, args, additional) => {
36950
+ const invokeTarget = () => Reflect.apply(target, thisArg, args);
36951
+ let state;
36952
+ try {
36953
+ state = startPiPromptRun(
36954
+ {
36955
+ ...additional,
36956
+ arguments: args,
36957
+ self: thisArg
36958
+ },
36959
+ (finalizedState) => {
36960
+ this.activePromptStates.delete(finalizedState);
36961
+ }
36962
+ );
36963
+ } catch (error2) {
36964
+ logInstrumentationError4("Pi Coding Agent prompt start", error2);
34749
36965
  }
34750
- return;
34751
- }
34752
- await finalizePiPromptRun(state);
34753
- },
34754
- error: async (event) => {
34755
- const state = states.get(event);
34756
- if (!state) {
34757
- return;
36966
+ if (!state) {
36967
+ return runWithAutoInstrumentationSuppressed(invokeTarget);
36968
+ }
36969
+ this.activePromptStates.add(state);
36970
+ return promptContextStore().run(
36971
+ state,
36972
+ () => runWithAutoInstrumentationSuppressed(() => {
36973
+ let result;
36974
+ try {
36975
+ result = invokeTarget();
36976
+ } catch (error2) {
36977
+ finishPiPromptRun(state, error2);
36978
+ throw error2;
36979
+ }
36980
+ return Promise.resolve(result).then(
36981
+ (value) => {
36982
+ finishPiPromptCall(state);
36983
+ return value;
36984
+ },
36985
+ (error2) => {
36986
+ finishPiPromptRun(state, error2);
36987
+ throw error2;
36988
+ }
36989
+ );
36990
+ })
36991
+ );
34758
36992
  }
34759
- states.delete(event);
34760
- await finalizePiPromptRun(state, event.error);
34761
- }
34762
- };
34763
- channel2.subscribe(handlers);
34764
- this.unsubscribers.push(() => {
34765
- unbindAutoInstrumentationSuppression?.();
34766
- channel2.unsubscribe(handlers);
34767
- });
36993
+ )
36994
+ );
34768
36995
  }
34769
36996
  };
36997
+ function finishPiPromptCall(state) {
36998
+ state.promptCallEnded = true;
36999
+ if (state.deferCompletionUntilTurnEnd && !state.turnEnded) {
37000
+ return;
37001
+ }
37002
+ finishPiPromptRun(state);
37003
+ }
34770
37004
  function startPiPromptRun(event, onFinalize) {
34771
37005
  const session = extractSession(event);
34772
37006
  const agent = session?.agent;
34773
37007
  if (!session || !isPiAgent(agent)) {
34774
37008
  return void 0;
34775
37009
  }
37010
+ installPiAgentInstrumentation(agent);
34776
37011
  const metadata = {
34777
37012
  ...extractSessionMetadata(session),
34778
37013
  ...extractPromptOptionsMetadata(event.arguments[1]),
@@ -34794,9 +37029,7 @@ function startPiPromptRun(event, onFinalize) {
34794
37029
  INSTRUMENTATION_NAMES.PI_CODING_AGENT
34795
37030
  )
34796
37031
  );
34797
- const streamPatchState = installPiStreamPatch(agent);
34798
37032
  const options = event.arguments[1];
34799
- const promptText = event.arguments[0];
34800
37033
  const state = {
34801
37034
  activeLlmSpans: /* @__PURE__ */ new Set(),
34802
37035
  activeToolSpans: /* @__PURE__ */ new Map(),
@@ -34808,29 +37041,10 @@ function startPiPromptRun(event, onFinalize) {
34808
37041
  metrics: {},
34809
37042
  onFinalize,
34810
37043
  promptCallEnded: false,
34811
- ...typeof promptText === "string" ? { promptText } : {},
34812
- queued: false,
34813
37044
  span,
34814
- sawStreamFn: false,
34815
37045
  startTime: getCurrentUnixTimestamp(),
34816
- streamPatchState,
34817
37046
  turnEnded: false
34818
37047
  };
34819
- state.restorePromptContext = enterPiPromptContext(state);
34820
- streamPatchState.activePromptStates.add(state);
34821
- try {
34822
- state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
34823
- try {
34824
- await runWithAutoInstrumentationSuppressed(
34825
- () => handlePiAgentEvent(state, agentEvent)
34826
- );
34827
- } catch (error2) {
34828
- logInstrumentationError4("Pi Coding Agent event", error2);
34829
- }
34830
- });
34831
- } catch (error2) {
34832
- logInstrumentationError4("Pi Coding Agent event subscription", error2);
34833
- }
34834
37048
  return state;
34835
37049
  }
34836
37050
  function extractSession(event) {
@@ -34844,111 +37058,55 @@ function promptContextStore() {
34844
37058
  piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
34845
37059
  return piPromptContextStore;
34846
37060
  }
34847
- function currentPromptContextFrames() {
34848
- return promptContextStore().getStore()?.frames ?? [];
34849
- }
34850
37061
  function currentPiPromptState() {
34851
- const frames = currentPromptContextFrames();
34852
- return frames[frames.length - 1]?.state;
34853
- }
34854
- function enterPiPromptContext(state) {
34855
- const frame = {
34856
- id: /* @__PURE__ */ Symbol("braintrust.pi-coding-agent.prompt"),
34857
- state
34858
- };
34859
- promptContextStore().enterWith({
34860
- frames: [...currentPromptContextFrames(), frame]
34861
- });
34862
- return () => {
34863
- const frames = currentPromptContextFrames().filter(
34864
- (candidate) => candidate.id !== frame.id
34865
- );
34866
- promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
34867
- };
34868
- }
34869
- function installPiStreamPatch(agent) {
34870
- const existing = piStreamPatchStates.get(agent);
34871
- if (existing) {
34872
- if (agent.streamFn !== existing.wrappedStreamFn) {
34873
- debugLogger.debug(
34874
- "Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
34875
- );
34876
- }
34877
- return existing;
34878
- }
34879
- const patchState = {
34880
- activePromptStates: /* @__PURE__ */ new Set(),
34881
- agent,
34882
- originalStreamFn: agent.streamFn,
34883
- queuedPromptStates: [],
34884
- wrappedStreamFn: agent.streamFn
34885
- };
34886
- patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
34887
- agent.streamFn = patchState.wrappedStreamFn;
34888
- piStreamPatchStates.set(agent, patchState);
34889
- return patchState;
34890
- }
34891
- function resolveStreamPromptState(patchState, context2) {
34892
- let lastUserText;
34893
- if (Array.isArray(context2.messages)) {
34894
- for (let i = context2.messages.length - 1; i >= 0; i--) {
34895
- const message = context2.messages[i];
34896
- if (isPiUserMessage(message)) {
34897
- if (typeof message.content === "string") {
34898
- lastUserText = message.content;
34899
- } else {
34900
- lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
34901
- }
34902
- break;
34903
- }
34904
- }
34905
- }
34906
- if (lastUserText !== void 0) {
34907
- const queuedMatch = patchState.queuedPromptStates.find(
34908
- (state) => state.promptText === lastUserText
34909
- );
34910
- if (queuedMatch) {
34911
- return queuedMatch;
34912
- }
34913
- const matches = [...patchState.activePromptStates].filter(
34914
- (state) => state.promptText === lastUserText
37062
+ return promptContextStore().getStore();
37063
+ }
37064
+ function installPiAgentInstrumentation(agent) {
37065
+ const existing = piAgentPatchStates.get(agent);
37066
+ if (!existing || agent.streamFn !== existing.wrappedStreamFn) {
37067
+ const patchState = {
37068
+ originalStreamFn: agent.streamFn,
37069
+ wrappedStreamFn: agent.streamFn
37070
+ };
37071
+ patchState.wrappedStreamFn = makeInstrumentedStreamFn(
37072
+ agent,
37073
+ patchState.originalStreamFn
34915
37074
  );
34916
- if (matches.length === 1) {
34917
- return matches[0];
34918
- }
37075
+ agent.streamFn = patchState.wrappedStreamFn;
37076
+ piAgentPatchStates.set(agent, patchState);
34919
37077
  }
34920
- const contextState = currentPiPromptState();
34921
- if (contextState && patchState.activePromptStates.has(contextState) && (!contextState.queued || lastUserText !== void 0 && contextState.promptText === lastUserText)) {
34922
- return contextState;
37078
+ if (piAgentEventSubscriptions.has(agent)) {
37079
+ return;
34923
37080
  }
34924
- if (patchState.activePromptStates.size === 1) {
34925
- return [...patchState.activePromptStates][0];
37081
+ try {
37082
+ agent.subscribe(async (event) => {
37083
+ const state = currentPiPromptState();
37084
+ if (!state || state.agent !== agent || state.finalized) {
37085
+ return;
37086
+ }
37087
+ try {
37088
+ await runWithAutoInstrumentationSuppressed(
37089
+ () => handlePiAgentEvent(state, event)
37090
+ );
37091
+ } catch (error2) {
37092
+ logInstrumentationError4("Pi Coding Agent event", error2);
37093
+ }
37094
+ });
37095
+ piAgentEventSubscriptions.add(agent);
37096
+ } catch (error2) {
37097
+ logInstrumentationError4("Pi Coding Agent event subscription", error2);
34926
37098
  }
34927
- return void 0;
34928
37099
  }
34929
- function makeSharedInstrumentedStreamFn(patchState) {
37100
+ function makeInstrumentedStreamFn(agent, originalStreamFn) {
34930
37101
  return async function instrumentedPiStreamFn(model, context2, options) {
34931
- const state = resolveStreamPromptState(patchState, context2);
34932
- if (!state) {
34933
- const invokeOriginal = () => Reflect.apply(patchState.originalStreamFn, this, [
34934
- model,
34935
- context2,
34936
- options
34937
- ]);
34938
- return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
37102
+ const invokeOriginal = () => Reflect.apply(originalStreamFn, this, [model, context2, options]);
37103
+ const state = currentPiPromptState();
37104
+ if (!state || state.agent !== agent || state.finalized) {
37105
+ return invokeOriginal();
34939
37106
  }
34940
- state.sawStreamFn = true;
34941
- removeQueuedPromptState(state);
34942
- state.streamPatchState.eventPromptState = state;
34943
37107
  const llmState = await startPiLlmSpan(state, model, context2, options);
34944
37108
  try {
34945
- const stream = await runWithAutoInstrumentationSuppressed(
34946
- () => Reflect.apply(patchState.originalStreamFn, this, [
34947
- model,
34948
- context2,
34949
- options
34950
- ])
34951
- );
37109
+ const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
34952
37110
  return patchAssistantMessageStream(stream, state, llmState);
34953
37111
  } catch (error2) {
34954
37112
  finishPiLlmSpan(state, llmState, void 0, error2);
@@ -35095,13 +37253,6 @@ async function handlePiAgentEvent(state, event) {
35095
37253
  if (state.finalized) {
35096
37254
  return;
35097
37255
  }
35098
- const eventPromptState = state.streamPatchState.eventPromptState;
35099
- if (eventPromptState && eventPromptState !== state) {
35100
- return;
35101
- }
35102
- if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
35103
- return;
35104
- }
35105
37256
  switch (event.type) {
35106
37257
  case "message_end":
35107
37258
  if (isPiAssistantMessage(event.message)) {
@@ -35116,11 +37267,8 @@ async function handlePiAgentEvent(state, event) {
35116
37267
  addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
35117
37268
  }
35118
37269
  }
35119
- if (state.streamPatchState.eventPromptState === state) {
35120
- state.streamPatchState.eventPromptState = void 0;
35121
- }
35122
37270
  if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
35123
- await finalizePiPromptRun(state);
37271
+ finishPiPromptRun(state);
35124
37272
  }
35125
37273
  return;
35126
37274
  case "tool_execution_start":
@@ -35193,19 +37341,13 @@ function finishPiToolSpan(state, event) {
35193
37341
  }
35194
37342
  }
35195
37343
  }
35196
- async function finalizePiPromptRun(state, error2) {
37344
+ function finishPiPromptRun(state, error2) {
35197
37345
  if (state.finalized) {
35198
37346
  return;
35199
37347
  }
35200
37348
  state.finalized = true;
35201
37349
  state.onFinalize?.(state);
35202
- restorePiStreamFn(state);
35203
- try {
35204
- state.unsubscribeAgent?.();
35205
- } catch (unsubscribeError) {
35206
- logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
35207
- }
35208
- await finishOpenLlmSpans(state, error2);
37350
+ finishOpenLlmSpans(state, error2);
35209
37351
  finishOpenToolSpans(state, error2);
35210
37352
  const metadata = {
35211
37353
  ...state.metadata,
@@ -35222,34 +37364,14 @@ async function finalizePiPromptRun(state, error2) {
35222
37364
  output: state.output
35223
37365
  });
35224
37366
  } finally {
35225
- state.span.end();
35226
- }
35227
- }
35228
- function restorePiStreamFn(state) {
35229
- const patchState = state.streamPatchState;
35230
- patchState.activePromptStates.delete(state);
35231
- removeQueuedPromptState(state);
35232
- if (patchState.eventPromptState === state) {
35233
- patchState.eventPromptState = void 0;
35234
- }
35235
- state.restorePromptContext?.();
35236
- if (patchState.activePromptStates.size > 0) {
35237
- return;
35238
- }
35239
- if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
35240
- patchState.agent.streamFn = patchState.originalStreamFn;
35241
- }
35242
- piStreamPatchStates.delete(patchState.agent);
35243
- }
35244
- function removeQueuedPromptState(state) {
35245
- state.queued = false;
35246
- const queuedPromptStates = state.streamPatchState.queuedPromptStates;
35247
- const index = queuedPromptStates.indexOf(state);
35248
- if (index >= 0) {
35249
- queuedPromptStates.splice(index, 1);
37367
+ try {
37368
+ state.span.end();
37369
+ } catch (endError) {
37370
+ logInstrumentationError4("Pi Coding Agent prompt end", endError);
37371
+ }
35250
37372
  }
35251
37373
  }
35252
- async function finishOpenLlmSpans(state, error2) {
37374
+ function finishOpenLlmSpans(state, error2) {
35253
37375
  for (const llmState of [...state.activeLlmSpans]) {
35254
37376
  finishPiLlmSpan(state, llmState, void 0, error2);
35255
37377
  }
@@ -35330,7 +37452,7 @@ function normalizeAssistantMessage(message) {
35330
37452
  (part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
35331
37453
  ).join("");
35332
37454
  const toolCalls = message.content.flatMap(
35333
- (part) => part.type === "toolCall" ? [normalizeToolCall(part)] : []
37455
+ (part) => part.type === "toolCall" ? [normalizeToolCall2(part)] : []
35334
37456
  );
35335
37457
  return {
35336
37458
  role: "assistant",
@@ -35365,13 +37487,13 @@ function normalizeUserContent(content) {
35365
37487
  return part;
35366
37488
  });
35367
37489
  }
35368
- function normalizeToolCall(toolCall) {
37490
+ function normalizeToolCall2(toolCall) {
35369
37491
  return {
35370
37492
  id: toolCall.id,
35371
37493
  type: "function",
35372
37494
  function: {
35373
37495
  name: toolCall.name,
35374
- arguments: stringifyArguments(toolCall.arguments)
37496
+ arguments: stringifyArguments2(toolCall.arguments)
35375
37497
  }
35376
37498
  };
35377
37499
  }
@@ -35554,7 +37676,7 @@ function cleanMetrics5(metrics) {
35554
37676
  }
35555
37677
  return cleaned;
35556
37678
  }
35557
- function stringifyArguments(value) {
37679
+ function stringifyArguments2(value) {
35558
37680
  if (typeof value === "string") {
35559
37681
  return value;
35560
37682
  }
@@ -35680,9 +37802,9 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
35680
37802
  });
35681
37803
  }
35682
37804
  subscribeToMultiAgentStream(channel2, operation) {
35683
- const tracingChannel2 = channel2.tracingChannel();
37805
+ const tracingChannel = channel2.tracingChannel();
35684
37806
  const states = /* @__PURE__ */ new WeakMap();
35685
- const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(tracingChannel2);
37807
+ const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(tracingChannel);
35686
37808
  const handlers = {
35687
37809
  start: (event) => {
35688
37810
  const state = startMultiAgentStream(
@@ -35736,10 +37858,10 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
35736
37858
  states.delete(event);
35737
37859
  }
35738
37860
  };
35739
- tracingChannel2.subscribe(handlers);
37861
+ tracingChannel.subscribe(handlers);
35740
37862
  this.unsubscribers.push(() => {
35741
37863
  unbindAutoInstrumentationSuppression?.();
35742
- tracingChannel2.unsubscribe(handlers);
37864
+ tracingChannel.unsubscribe(handlers);
35743
37865
  });
35744
37866
  }
35745
37867
  };
@@ -35922,6 +38044,15 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
35922
38044
  logInstrumentationError5("Strands Agent SDK multi-agent event", error2);
35923
38045
  }
35924
38046
  }
38047
+ function buildModelSpanInput(event, attachmentCache) {
38048
+ const systemPrompt = typeof event.agent?.systemPrompt === "string" && event.agent.systemPrompt.length > 0 ? event.agent.systemPrompt : void 0;
38049
+ const processedMessages = Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(event.agent.messages, attachmentCache) : void 0;
38050
+ if (!systemPrompt) {
38051
+ return processedMessages;
38052
+ }
38053
+ const systemMessage = { role: "system", content: systemPrompt };
38054
+ return Array.isArray(processedMessages) ? [systemMessage, ...processedMessages] : [systemMessage];
38055
+ }
35925
38056
  function startModelSpan(state, event) {
35926
38057
  if (state.activeModel) {
35927
38058
  finalizeModelSpan(state);
@@ -35939,10 +38070,7 @@ function startModelSpan(state, event) {
35939
38070
  withSpanInstrumentationName(
35940
38071
  {
35941
38072
  event: {
35942
- input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
35943
- event.agent.messages,
35944
- state.attachmentCache
35945
- ) : void 0,
38073
+ input: buildModelSpanInput(event, state.attachmentCache),
35946
38074
  metadata
35947
38075
  },
35948
38076
  name: formatModelSpanName(model),
@@ -36582,6 +38710,532 @@ function logInstrumentationError5(context2, error2) {
36582
38710
  debugLogger.debug(`${context2}:`, error2);
36583
38711
  }
36584
38712
 
38713
+ // src/instrumentation/plugins/cloudflare-ai-chat-channels.ts
38714
+ var cloudflareAIChatChannels = defineChannels(
38715
+ "@cloudflare/ai-chat",
38716
+ {
38717
+ runExclusiveChatTurn: channel({
38718
+ channelName: "AIChatAgent._runExclusiveChatTurn",
38719
+ kind: "async"
38720
+ }),
38721
+ onChatResponse: channel({
38722
+ channelName: "AIChatAgent.onChatResponse",
38723
+ kind: "sync-stream"
38724
+ })
38725
+ },
38726
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_AI_CHAT }
38727
+ );
38728
+
38729
+ // src/instrumentation/plugins/cloudflare-ai-chat-instrumentation.ts
38730
+ var wrappedResponseHooks = /* @__PURE__ */ new WeakSet();
38731
+ function instrumentCloudflareAIChatResponseHook(agent) {
38732
+ try {
38733
+ const original = Reflect.get(agent, "onChatResponse");
38734
+ if (typeof original !== "function" || wrappedResponseHooks.has(original)) {
38735
+ return;
38736
+ }
38737
+ const wrapped = function(result) {
38738
+ const args = [result];
38739
+ return cloudflareAIChatChannels.onChatResponse.traceSync(
38740
+ () => Reflect.apply(original, this, args),
38741
+ {
38742
+ arguments: args,
38743
+ self: this
38744
+ }
38745
+ );
38746
+ };
38747
+ wrappedResponseHooks.add(wrapped);
38748
+ defineWrappedMethod(agent, "onChatResponse", original, wrapped);
38749
+ } catch (error2) {
38750
+ debugLogger.debug(
38751
+ "Failed to wrap @cloudflare/ai-chat response hook:",
38752
+ error2
38753
+ );
38754
+ }
38755
+ }
38756
+ function defineWrappedMethod(target, property, original, wrapped) {
38757
+ const ownDescriptor = Object.getOwnPropertyDescriptor(target, property);
38758
+ Object.defineProperty(target, property, {
38759
+ configurable: ownDescriptor?.configurable ?? true,
38760
+ enumerable: ownDescriptor?.enumerable ?? false,
38761
+ value: wrapped,
38762
+ writable: ownDescriptor && "writable" in ownDescriptor ? ownDescriptor.writable : true
38763
+ });
38764
+ try {
38765
+ Object.defineProperty(wrapped, "name", {
38766
+ configurable: true,
38767
+ value: original.name
38768
+ });
38769
+ } catch {
38770
+ }
38771
+ }
38772
+
38773
+ // src/instrumentation/plugins/cloudflare-ai-chat-plugin.ts
38774
+ var BLOCKED_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
38775
+ var RESPONSE_STATE_RETENTION_MS = 6e4;
38776
+ var CloudflareAIChatPlugin = class extends BasePlugin {
38777
+ activeStates = /* @__PURE__ */ new Set();
38778
+ activeTurns = /* @__PURE__ */ new WeakMap();
38779
+ eventStates = /* @__PURE__ */ new WeakMap();
38780
+ onEnable() {
38781
+ this.subscribeToResponseHook();
38782
+ this.subscribeToTurnRunner();
38783
+ }
38784
+ onDisable() {
38785
+ for (const unsubscribe of this.unsubscribers) {
38786
+ unsubscribe();
38787
+ }
38788
+ this.unsubscribers = [];
38789
+ for (const state of this.activeStates) {
38790
+ this.cleanupState(state);
38791
+ }
38792
+ this.activeStates.clear();
38793
+ }
38794
+ subscribeToTurnRunner() {
38795
+ const tracingChannel = cloudflareAIChatChannels.runExclusiveChatTurn.tracingChannel();
38796
+ const unbindCurrentSpanStore = this.bindCurrentSpanStore(tracingChannel);
38797
+ const handlers = {
38798
+ start: (event) => {
38799
+ this.ensureEventState(event);
38800
+ },
38801
+ asyncEnd: (event) => {
38802
+ this.finishEvent(event);
38803
+ },
38804
+ error: (event) => {
38805
+ this.finishEvent(event, event.error);
38806
+ }
38807
+ };
38808
+ tracingChannel.subscribe(handlers);
38809
+ this.unsubscribers.push(() => {
38810
+ unbindCurrentSpanStore?.();
38811
+ tracingChannel.unsubscribe(handlers);
38812
+ });
38813
+ }
38814
+ subscribeToResponseHook() {
38815
+ const tracingChannel = cloudflareAIChatChannels.onChatResponse.tracingChannel();
38816
+ const handlers = {
38817
+ start: (event) => {
38818
+ let state;
38819
+ try {
38820
+ const agent = asObject(event.self);
38821
+ const result = event.arguments[0];
38822
+ state = agent ? this.findResponseState(
38823
+ agent,
38824
+ stringValue3(ownValue2(result, "requestId"))
38825
+ ) : void 0;
38826
+ if (!state) {
38827
+ return;
38828
+ }
38829
+ state.responseObserved = true;
38830
+ const output = serializeMessage(ownValue2(result, "message"));
38831
+ const status = stringValue3(ownValue2(result, "status"));
38832
+ const error2 = ownValue2(result, "error");
38833
+ const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
38834
+ (message) => typeof output?.id !== "string" || message.id !== output.id
38835
+ );
38836
+ state.span.log({
38837
+ ...input !== void 0 ? { input } : {},
38838
+ ...output !== void 0 ? { output } : {},
38839
+ ...status === "error" && error2 !== void 0 ? { error: error2 } : {}
38840
+ });
38841
+ } catch (error2) {
38842
+ debugLogger.debug(
38843
+ "Failed to process @cloudflare/ai-chat response hook:",
38844
+ error2
38845
+ );
38846
+ } finally {
38847
+ if (state?.settled) {
38848
+ this.cleanupState(state);
38849
+ }
38850
+ }
38851
+ }
38852
+ };
38853
+ tracingChannel.subscribe(handlers);
38854
+ this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
38855
+ }
38856
+ bindCurrentSpanStore(tracingChannel) {
38857
+ const globalState = _internalGetGlobalState();
38858
+ const contextManager = globalState?.contextManager;
38859
+ const startChannel = tracingChannel.start;
38860
+ const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
38861
+ if (!startChannel || !currentSpanStore || !contextManager) {
38862
+ return void 0;
38863
+ }
38864
+ startChannel.bindStore(currentSpanStore, (event) => {
38865
+ const state = this.ensureEventState(event);
38866
+ return state ? contextManager.wrapSpanForStore(state.span) : currentSpanStore.getStore();
38867
+ });
38868
+ return () => startChannel.unbindStore(currentSpanStore);
38869
+ }
38870
+ ensureEventState(event) {
38871
+ const eventKey = event;
38872
+ const known = this.eventStates.get(eventKey);
38873
+ if (known) {
38874
+ return known;
38875
+ }
38876
+ try {
38877
+ const agent = asObject(event.self);
38878
+ const requestId = stringValue3(event.arguments[0]);
38879
+ const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
38880
+ const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
38881
+ const existing = activeForAgent?.get(key);
38882
+ const state = existing && !existing.settled ? existing : this.createTurnState(agent, key);
38883
+ if (existing && !existing.settled) {
38884
+ state.depth += 1;
38885
+ }
38886
+ this.eventStates.set(eventKey, state);
38887
+ this.bindTurnCallback(event, agent, state);
38888
+ if (agent) {
38889
+ instrumentCloudflareAIChatResponseHook(agent);
38890
+ }
38891
+ return state;
38892
+ } catch (error2) {
38893
+ debugLogger.debug(
38894
+ "Failed to start @cloudflare/ai-chat instrumentation:",
38895
+ error2
38896
+ );
38897
+ return void 0;
38898
+ }
38899
+ }
38900
+ createTurnState(agent, key) {
38901
+ const span = startSpan(
38902
+ withSpanInstrumentationName(
38903
+ {
38904
+ name: "AIChatAgent.onChatMessage",
38905
+ spanAttributes: { type: "task" /* TASK */ }
38906
+ },
38907
+ INSTRUMENTATION_NAMES.CLOUDFLARE_AI_CHAT
38908
+ )
38909
+ );
38910
+ const state = {
38911
+ agent,
38912
+ depth: 1,
38913
+ ended: false,
38914
+ key,
38915
+ responseObserved: false,
38916
+ settled: false,
38917
+ span
38918
+ };
38919
+ this.activeStates.add(state);
38920
+ if (agent) {
38921
+ this.getActiveTurns(agent).set(key, state);
38922
+ }
38923
+ return state;
38924
+ }
38925
+ bindTurnCallback(event, agent, state) {
38926
+ const callback = event.arguments[1];
38927
+ if (typeof callback !== "function") {
38928
+ return;
38929
+ }
38930
+ try {
38931
+ event.arguments[1] = function(...args) {
38932
+ return withCurrent(state.span, () => {
38933
+ try {
38934
+ const input = serializeMessages(readProperty(agent, "messages"));
38935
+ if (input !== void 0 && state.input === void 0) {
38936
+ state.input = input;
38937
+ state.span.log({ input });
38938
+ }
38939
+ } catch (error2) {
38940
+ debugLogger.debug(
38941
+ "Failed to capture @cloudflare/ai-chat messages:",
38942
+ error2
38943
+ );
38944
+ }
38945
+ return Reflect.apply(callback, this, args);
38946
+ });
38947
+ };
38948
+ } catch (error2) {
38949
+ debugLogger.debug(
38950
+ "Failed to bind @cloudflare/ai-chat turn callback context:",
38951
+ error2
38952
+ );
38953
+ }
38954
+ }
38955
+ finishEvent(event, error2) {
38956
+ const eventKey = event;
38957
+ const state = this.eventStates.get(eventKey);
38958
+ if (!state || state.ended) {
38959
+ return;
38960
+ }
38961
+ this.eventStates.delete(eventKey);
38962
+ if (error2 !== void 0 && state.pendingError === void 0) {
38963
+ state.pendingError = error2;
38964
+ }
38965
+ state.depth -= 1;
38966
+ if (state.depth === 0) {
38967
+ state.settled = true;
38968
+ this.endState(state);
38969
+ if (state.responseObserved || error2 !== void 0) {
38970
+ this.cleanupState(state);
38971
+ } else {
38972
+ state.cleanupTimer = setTimeout(
38973
+ () => this.cleanupState(state),
38974
+ RESPONSE_STATE_RETENTION_MS
38975
+ );
38976
+ if (typeof state.cleanupTimer === "object" && state.cleanupTimer !== null && "unref" in state.cleanupTimer && typeof state.cleanupTimer.unref === "function") {
38977
+ state.cleanupTimer.unref();
38978
+ }
38979
+ }
38980
+ }
38981
+ }
38982
+ endState(state) {
38983
+ if (state.ended) {
38984
+ return;
38985
+ }
38986
+ state.ended = true;
38987
+ try {
38988
+ if (state.pendingError !== void 0) {
38989
+ state.span.log({ error: state.pendingError });
38990
+ }
38991
+ } finally {
38992
+ state.span.end();
38993
+ }
38994
+ }
38995
+ cleanupState(state) {
38996
+ if (state.cleanupTimer !== void 0) {
38997
+ clearTimeout(state.cleanupTimer);
38998
+ state.cleanupTimer = void 0;
38999
+ }
39000
+ try {
39001
+ this.endState(state);
39002
+ } finally {
39003
+ this.activeStates.delete(state);
39004
+ if (state.agent) {
39005
+ const activeForAgent = this.activeTurns.get(state.agent);
39006
+ if (activeForAgent?.get(state.key) === state) {
39007
+ activeForAgent.delete(state.key);
39008
+ }
39009
+ }
39010
+ }
39011
+ }
39012
+ getActiveTurns(agent) {
39013
+ let turns = this.activeTurns.get(agent);
39014
+ if (!turns) {
39015
+ turns = /* @__PURE__ */ new Map();
39016
+ this.activeTurns.set(agent, turns);
39017
+ }
39018
+ return turns;
39019
+ }
39020
+ findResponseState(agent, requestId) {
39021
+ const turns = this.activeTurns.get(agent);
39022
+ if (!turns) {
39023
+ return void 0;
39024
+ }
39025
+ if (requestId !== void 0) {
39026
+ return turns.get(requestId);
39027
+ }
39028
+ const active = [...turns.values()];
39029
+ return active.length === 1 ? active[0] : void 0;
39030
+ }
39031
+ };
39032
+ function asObject(value) {
39033
+ return value !== null && (typeof value === "object" || typeof value === "function") ? value : void 0;
39034
+ }
39035
+ function readProperty(value, key) {
39036
+ const object = asObject(value);
39037
+ return object ? Reflect.get(object, key) : void 0;
39038
+ }
39039
+ function ownValue2(value, key) {
39040
+ const object = asObject(value);
39041
+ if (!object) {
39042
+ return void 0;
39043
+ }
39044
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
39045
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
39046
+ }
39047
+ function stringValue3(value) {
39048
+ return typeof value === "string" ? value : void 0;
39049
+ }
39050
+ function serializeMessages(value) {
39051
+ if (!Array.isArray(value)) {
39052
+ return void 0;
39053
+ }
39054
+ return value.flatMap((message) => {
39055
+ const serialized = serializeMessage(message);
39056
+ return serialized === void 0 ? [] : [serialized];
39057
+ });
39058
+ }
39059
+ function serializeMessage(value) {
39060
+ const message = asObject(value);
39061
+ if (!message) {
39062
+ return void 0;
39063
+ }
39064
+ const serialized = [];
39065
+ const id = ownValue2(message, "id");
39066
+ const role = ownValue2(message, "role");
39067
+ const parts = ownValue2(message, "parts");
39068
+ if (typeof id === "string") {
39069
+ serialized.push(["id", id]);
39070
+ }
39071
+ if (typeof role === "string") {
39072
+ serialized.push(["role", role]);
39073
+ }
39074
+ const sanitizedParts = sanitizeLoggedValue2(parts);
39075
+ if (sanitizedParts !== void 0) {
39076
+ serialized.push(["parts", sanitizedParts]);
39077
+ }
39078
+ return serialized.length > 0 ? Object.fromEntries(serialized) : void 0;
39079
+ }
39080
+ function sanitizeLoggedValue2(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
39081
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
39082
+ return value;
39083
+ }
39084
+ if (typeof value === "number") {
39085
+ return Number.isFinite(value) ? value : void 0;
39086
+ }
39087
+ const object = asObject(value);
39088
+ if (!object || depth >= 20 || typeof value === "function") {
39089
+ return void 0;
39090
+ }
39091
+ if (seen.has(object)) {
39092
+ return "[Circular]";
39093
+ }
39094
+ seen.add(object);
39095
+ if (Array.isArray(value)) {
39096
+ return value.map((entry) => sanitizeLoggedValue2(entry, seen, depth + 1));
39097
+ }
39098
+ const entries = [];
39099
+ for (const [key, descriptor] of Object.entries(
39100
+ Object.getOwnPropertyDescriptors(object)
39101
+ )) {
39102
+ if (BLOCKED_KEYS.has(key) || !descriptor.enumerable || !("value" in descriptor)) {
39103
+ continue;
39104
+ }
39105
+ const sanitized = sanitizeLoggedValue2(descriptor.value, seen, depth + 1);
39106
+ if (sanitized !== void 0) {
39107
+ entries.push([key, sanitized]);
39108
+ }
39109
+ }
39110
+ return Object.fromEntries(entries);
39111
+ }
39112
+
39113
+ // src/instrumentation/plugins/cloudflare-agents-channels.ts
39114
+ var cloudflareAgentsChannels = defineChannels(
39115
+ "agents",
39116
+ {
39117
+ runAgentTool: channel({
39118
+ channelName: "Agent.runAgentTool",
39119
+ kind: "async"
39120
+ })
39121
+ },
39122
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_AGENTS }
39123
+ );
39124
+
39125
+ // src/instrumentation/plugins/cloudflare-agents-plugin.ts
39126
+ var CLOUDFLARE_WORKERS_CONTEXT = {
39127
+ span_origin: {
39128
+ environment: { type: "server", name: "cloudflare_workers" }
39129
+ }
39130
+ };
39131
+ var CloudflareAgentsPlugin = class extends BasePlugin {
39132
+ onEnable() {
39133
+ const channel2 = cloudflareAgentsChannels.runAgentTool.tracingChannel();
39134
+ const spans = /* @__PURE__ */ new WeakMap();
39135
+ const handlers = {
39136
+ start: (event) => {
39137
+ try {
39138
+ const agentClass = event.arguments[0];
39139
+ const options = event.arguments[1];
39140
+ if (ownValue3(options, "detached")) {
39141
+ return;
39142
+ }
39143
+ const name = ownValue3(agentClass, "name");
39144
+ if (typeof name !== "string" || name.length === 0) {
39145
+ debugLogger.warn(
39146
+ "Skipping Cloudflare Agents runAgentTool span because the child agent class has no name."
39147
+ );
39148
+ return;
39149
+ }
39150
+ const span = _internalStartSpanWithContext(
39151
+ withSpanInstrumentationName(
39152
+ {
39153
+ name,
39154
+ spanAttributes: { type: "tool" /* TOOL */ },
39155
+ event: {
39156
+ input: ownValue3(options, "input")
39157
+ }
39158
+ },
39159
+ INSTRUMENTATION_NAMES.CLOUDFLARE_AGENTS
39160
+ ),
39161
+ CLOUDFLARE_WORKERS_CONTEXT
39162
+ );
39163
+ spans.set(event, span);
39164
+ } catch (error2) {
39165
+ logInstrumentationError6("start", error2);
39166
+ }
39167
+ },
39168
+ asyncEnd: (event) => {
39169
+ const span = spans.get(event);
39170
+ if (!span) {
39171
+ return;
39172
+ }
39173
+ spans.delete(event);
39174
+ try {
39175
+ const status = ownValue3(event.result, "status");
39176
+ if (status === "completed") {
39177
+ span.log({ output: ownValue3(event.result, "output") });
39178
+ } else {
39179
+ const error2 = ownValue3(event.result, "error");
39180
+ if (typeof error2 === "string") {
39181
+ span.log({ error: error2 });
39182
+ }
39183
+ }
39184
+ } catch (error2) {
39185
+ logInstrumentationError6("completion", error2);
39186
+ } finally {
39187
+ safelyEndSpan(span);
39188
+ }
39189
+ },
39190
+ error: (event) => {
39191
+ const span = spans.get(event);
39192
+ if (!span) {
39193
+ return;
39194
+ }
39195
+ spans.delete(event);
39196
+ try {
39197
+ span.log({ error: event.error });
39198
+ } catch (error2) {
39199
+ logInstrumentationError6("rejection", error2);
39200
+ } finally {
39201
+ safelyEndSpan(span);
39202
+ }
39203
+ }
39204
+ };
39205
+ channel2.subscribe(handlers);
39206
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
39207
+ }
39208
+ onDisable() {
39209
+ for (const unsubscribe of this.unsubscribers) {
39210
+ unsubscribe();
39211
+ }
39212
+ this.unsubscribers = [];
39213
+ }
39214
+ };
39215
+ function ownValue3(value, key) {
39216
+ if (!isObjectLike2(value)) {
39217
+ return void 0;
39218
+ }
39219
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
39220
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
39221
+ }
39222
+ function isObjectLike2(value) {
39223
+ return typeof value === "object" && value !== null || typeof value === "function";
39224
+ }
39225
+ function safelyEndSpan(span) {
39226
+ try {
39227
+ span.end();
39228
+ } catch (error2) {
39229
+ logInstrumentationError6("span end", error2);
39230
+ }
39231
+ }
39232
+ function logInstrumentationError6(operation, error2) {
39233
+ debugLogger.error(
39234
+ `Failed to process Cloudflare Agents ${operation} instrumentation:`,
39235
+ error2
39236
+ );
39237
+ }
39238
+
36585
39239
  // src/instrumentation/braintrust-plugin.ts
36586
39240
  var BraintrustPlugin = class extends BasePlugin {
36587
39241
  config;
@@ -36590,13 +39244,16 @@ var BraintrustPlugin = class extends BasePlugin {
36590
39244
  anthropicPlugin = null;
36591
39245
  aiSDKPlugin = null;
36592
39246
  claudeAgentSDKPlugin = null;
39247
+ cloudflareThinkPlugin = null;
36593
39248
  cursorSDKPlugin = null;
36594
39249
  openAIAgentsPlugin = null;
36595
39250
  googleGenAIPlugin = null;
36596
39251
  huggingFacePlugin = null;
39252
+ huggingFaceTransformersPlugin = null;
36597
39253
  openRouterPlugin = null;
36598
39254
  openRouterAgentPlugin = null;
36599
39255
  mistralPlugin = null;
39256
+ ollamaPlugin = null;
36600
39257
  googleADKPlugin = null;
36601
39258
  coherePlugin = null;
36602
39259
  groqPlugin = null;
@@ -36608,6 +39265,8 @@ var BraintrustPlugin = class extends BasePlugin {
36608
39265
  langSmithPlugin = null;
36609
39266
  piCodingAgentPlugin = null;
36610
39267
  strandsAgentSDKPlugin = null;
39268
+ cloudflareAIChatPlugin = null;
39269
+ cloudflareAgentsPlugin = null;
36611
39270
  constructor(config3 = {}) {
36612
39271
  super();
36613
39272
  this.config = config3;
@@ -36634,6 +39293,10 @@ var BraintrustPlugin = class extends BasePlugin {
36634
39293
  this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
36635
39294
  this.claudeAgentSDKPlugin.enable();
36636
39295
  }
39296
+ if (integrations.cloudflareThink !== false) {
39297
+ this.cloudflareThinkPlugin = new CloudflareThinkPlugin();
39298
+ this.cloudflareThinkPlugin.enable();
39299
+ }
36637
39300
  if (integrations.cursorSDK !== false && integrations.cursor !== false) {
36638
39301
  this.cursorSDKPlugin = new CursorSDKPlugin();
36639
39302
  this.cursorSDKPlugin.enable();
@@ -36649,6 +39312,8 @@ var BraintrustPlugin = class extends BasePlugin {
36649
39312
  if (integrations.huggingface !== false) {
36650
39313
  this.huggingFacePlugin = new HuggingFacePlugin();
36651
39314
  this.huggingFacePlugin.enable();
39315
+ this.huggingFaceTransformersPlugin = new HuggingFaceTransformersPlugin();
39316
+ this.huggingFaceTransformersPlugin.enable();
36652
39317
  }
36653
39318
  if (integrations.openrouter !== false) {
36654
39319
  this.openRouterPlugin = new OpenRouterPlugin();
@@ -36662,6 +39327,10 @@ var BraintrustPlugin = class extends BasePlugin {
36662
39327
  this.mistralPlugin = new MistralPlugin();
36663
39328
  this.mistralPlugin.enable();
36664
39329
  }
39330
+ if (integrations.ollama !== false) {
39331
+ this.ollamaPlugin = new OllamaPlugin();
39332
+ this.ollamaPlugin.enable();
39333
+ }
36665
39334
  if (integrations.googleADK !== false) {
36666
39335
  this.googleADKPlugin = new GoogleADKPlugin();
36667
39336
  this.googleADKPlugin.enable();
@@ -36694,6 +39363,14 @@ var BraintrustPlugin = class extends BasePlugin {
36694
39363
  this.strandsAgentSDKPlugin = new StrandsAgentSDKPlugin();
36695
39364
  this.strandsAgentSDKPlugin.enable();
36696
39365
  }
39366
+ if (integrations.cloudflareAIChat !== false) {
39367
+ this.cloudflareAIChatPlugin = new CloudflareAIChatPlugin();
39368
+ this.cloudflareAIChatPlugin.enable();
39369
+ }
39370
+ if (integrations.cloudflareAgents !== false) {
39371
+ this.cloudflareAgentsPlugin = new CloudflareAgentsPlugin();
39372
+ this.cloudflareAgentsPlugin.enable();
39373
+ }
36697
39374
  if (integrations.flue !== false) {
36698
39375
  this.fluePlugin = new FluePlugin();
36699
39376
  this.fluePlugin.enable();
@@ -36730,6 +39407,10 @@ var BraintrustPlugin = class extends BasePlugin {
36730
39407
  this.claudeAgentSDKPlugin.disable();
36731
39408
  this.claudeAgentSDKPlugin = null;
36732
39409
  }
39410
+ if (this.cloudflareThinkPlugin) {
39411
+ this.cloudflareThinkPlugin.disable();
39412
+ this.cloudflareThinkPlugin = null;
39413
+ }
36733
39414
  if (this.cursorSDKPlugin) {
36734
39415
  this.cursorSDKPlugin.disable();
36735
39416
  this.cursorSDKPlugin = null;
@@ -36746,6 +39427,10 @@ var BraintrustPlugin = class extends BasePlugin {
36746
39427
  this.huggingFacePlugin.disable();
36747
39428
  this.huggingFacePlugin = null;
36748
39429
  }
39430
+ if (this.huggingFaceTransformersPlugin) {
39431
+ this.huggingFaceTransformersPlugin.disable();
39432
+ this.huggingFaceTransformersPlugin = null;
39433
+ }
36749
39434
  if (this.openRouterPlugin) {
36750
39435
  this.openRouterPlugin.disable();
36751
39436
  this.openRouterPlugin = null;
@@ -36758,6 +39443,10 @@ var BraintrustPlugin = class extends BasePlugin {
36758
39443
  this.mistralPlugin.disable();
36759
39444
  this.mistralPlugin = null;
36760
39445
  }
39446
+ if (this.ollamaPlugin) {
39447
+ this.ollamaPlugin.disable();
39448
+ this.ollamaPlugin = null;
39449
+ }
36761
39450
  if (this.googleADKPlugin) {
36762
39451
  this.googleADKPlugin.disable();
36763
39452
  this.googleADKPlugin = null;
@@ -36790,6 +39479,14 @@ var BraintrustPlugin = class extends BasePlugin {
36790
39479
  this.strandsAgentSDKPlugin.disable();
36791
39480
  this.strandsAgentSDKPlugin = null;
36792
39481
  }
39482
+ if (this.cloudflareAIChatPlugin) {
39483
+ this.cloudflareAIChatPlugin.disable();
39484
+ this.cloudflareAIChatPlugin = null;
39485
+ }
39486
+ if (this.cloudflareAgentsPlugin) {
39487
+ this.cloudflareAgentsPlugin.disable();
39488
+ this.cloudflareAgentsPlugin = null;
39489
+ }
36793
39490
  if (this.fluePlugin) {
36794
39491
  this.fluePlugin.disable();
36795
39492
  this.fluePlugin = null;
@@ -36822,6 +39519,9 @@ var envIntegrationAliases = {
36822
39519
  strandsagentsdk: "strandsAgentSDK",
36823
39520
  "strands-agent-sdk": "strandsAgentSDK",
36824
39521
  "@strands-agents/sdk": "strandsAgentSDK",
39522
+ agents: "cloudflareAgents",
39523
+ "cloudflare-agents": "cloudflareAgents",
39524
+ cloudflareagents: "cloudflareAgents",
36825
39525
  anthropic: "anthropic",
36826
39526
  aisdk: "aisdk",
36827
39527
  "ai-sdk": "aisdk",
@@ -36829,6 +39529,10 @@ var envIntegrationAliases = {
36829
39529
  vercel: "vercel",
36830
39530
  claudeagentsdk: "claudeAgentSDK",
36831
39531
  "claude-agent-sdk": "claudeAgentSDK",
39532
+ cloudflareaichat: "cloudflareAIChat",
39533
+ "cloudflare-ai-chat": "cloudflareAIChat",
39534
+ "@cloudflare/ai-chat": "cloudflareAIChat",
39535
+ cloudflarethink: "cloudflareThink",
36832
39536
  cursor: "cursor",
36833
39537
  "cursor-sdk": "cursorSDK",
36834
39538
  cursorsdk: "cursorSDK",
@@ -36843,10 +39547,13 @@ var envIntegrationAliases = {
36843
39547
  "google-genai": "googleGenAI",
36844
39548
  googlegenai: "googleGenAI",
36845
39549
  huggingface: "huggingface",
39550
+ "@huggingface/transformers": "huggingface",
39551
+ transformers: "huggingface",
36846
39552
  openrouter: "openrouter",
36847
39553
  openrouteragent: "openrouterAgent",
36848
39554
  "openrouter-agent": "openrouterAgent",
36849
39555
  mistral: "mistral",
39556
+ ollama: "ollama",
36850
39557
  googleadk: "googleADK",
36851
39558
  "google-adk": "googleADK",
36852
39559
  cohere: "cohere",
@@ -36881,6 +39588,8 @@ function getDefaultInstrumentationIntegrations() {
36881
39588
  googleADK: true,
36882
39589
  huggingface: true,
36883
39590
  claudeAgentSDK: true,
39591
+ cloudflareAIChat: true,
39592
+ cloudflareThink: true,
36884
39593
  cursor: true,
36885
39594
  cursorSDK: true,
36886
39595
  flue: true,
@@ -36889,6 +39598,7 @@ function getDefaultInstrumentationIntegrations() {
36889
39598
  openrouter: true,
36890
39599
  openrouterAgent: true,
36891
39600
  mistral: true,
39601
+ ollama: true,
36892
39602
  cohere: true,
36893
39603
  groq: true,
36894
39604
  bedrock: true,
@@ -36900,7 +39610,8 @@ function getDefaultInstrumentationIntegrations() {
36900
39610
  langgraph: true,
36901
39611
  langsmith: true,
36902
39612
  piCodingAgent: true,
36903
- strandsAgentSDK: true
39613
+ strandsAgentSDK: true,
39614
+ cloudflareAgents: true
36904
39615
  };
36905
39616
  }
36906
39617
  function readDisabledInstrumentationEnvConfig(disabledList) {
@@ -36921,7 +39632,9 @@ function isInstrumentationIntegrationDisabled(integrations, ...names) {
36921
39632
  }
36922
39633
 
36923
39634
  // src/instrumentation/registry.ts
36924
- var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for("braintrust.registry");
39635
+ var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for(
39636
+ `braintrust.registry.global-hooks.v${GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION}`
39637
+ );
36925
39638
  function getSharedState() {
36926
39639
  const state = globalThis[/* @__PURE__ */ Symbol.for("braintrust-state")];
36927
39640
  return state && typeof state === "object" ? state : void 0;
@@ -37357,8 +40070,6 @@ function configureNode() {
37357
40070
  };
37358
40071
  isomorph_default.getCallerLocation = getCallerLocation;
37359
40072
  isomorph_default.newAsyncLocalStorage = () => new import_node_async_hooks.AsyncLocalStorage();
37360
- isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
37361
- patchTracingChannel(diagnostics_channel.tracingChannel);
37362
40073
  isomorph_default.processOn = (event, handler) => {
37363
40074
  process.on(event, handler);
37364
40075
  };