braintrust 3.20.0 → 3.22.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 (88) hide show
  1. package/NOTICE +20 -0
  2. package/README.md +6 -0
  3. package/dev/dist/index.d.mts +1338 -199
  4. package/dev/dist/index.d.ts +1338 -199
  5. package/dev/dist/index.js +2904 -997
  6. package/dev/dist/index.mjs +2418 -511
  7. package/dist/apply-auto-instrumentation.js +781 -199
  8. package/dist/apply-auto-instrumentation.mjs +588 -6
  9. package/dist/auto-instrumentations/bundler/esbuild.cjs +594 -2
  10. package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
  11. package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
  12. package/dist/auto-instrumentations/bundler/esbuild.mjs +3 -3
  13. package/dist/auto-instrumentations/bundler/next.cjs +594 -2
  14. package/dist/auto-instrumentations/bundler/next.mjs +4 -4
  15. package/dist/auto-instrumentations/bundler/rollup.cjs +594 -2
  16. package/dist/auto-instrumentations/bundler/rollup.d.mts +2 -2
  17. package/dist/auto-instrumentations/bundler/rollup.d.ts +2 -2
  18. package/dist/auto-instrumentations/bundler/rollup.mjs +3 -3
  19. package/dist/auto-instrumentations/bundler/vite.cjs +594 -2
  20. package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
  21. package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
  22. package/dist/auto-instrumentations/bundler/vite.mjs +3 -3
  23. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +593 -9
  24. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +68 -1
  25. package/dist/auto-instrumentations/bundler/webpack.cjs +594 -2
  26. package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
  27. package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
  28. package/dist/auto-instrumentations/bundler/webpack.mjs +4 -4
  29. package/dist/auto-instrumentations/{chunk-W4E36GIW.mjs → chunk-BRQX23KL.mjs} +16 -0
  30. package/dist/auto-instrumentations/chunk-M6DLIJ2Z.mjs +784 -0
  31. package/dist/auto-instrumentations/{chunk-K74TZGGM.mjs → chunk-T6J4C7LX.mjs} +1 -1
  32. package/dist/auto-instrumentations/{chunk-S4374IP6.mjs → chunk-TKRPRPGD.mjs} +4 -6
  33. package/dist/auto-instrumentations/chunk-VT6DDNKM.mjs +856 -0
  34. package/dist/auto-instrumentations/hook.mjs +824 -56
  35. package/dist/auto-instrumentations/index.cjs +16 -0
  36. package/dist/auto-instrumentations/index.d.mts +2 -3
  37. package/dist/auto-instrumentations/index.d.ts +2 -3
  38. package/dist/auto-instrumentations/index.mjs +1 -1
  39. package/dist/auto-instrumentations/loader/cjs-patch.cjs +578 -4
  40. package/dist/auto-instrumentations/loader/cjs-patch.d.mts +1 -1
  41. package/dist/auto-instrumentations/loader/cjs-patch.d.ts +1 -1
  42. package/dist/auto-instrumentations/loader/cjs-patch.mjs +3 -7
  43. package/dist/auto-instrumentations/loader/esm-hook.mjs +2 -6
  44. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.mts → plugin-D0KHwSJv.d.mts} +1 -1
  45. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.ts → plugin-G6fgxk1b.d.ts} +1 -1
  46. package/dist/auto-instrumentations/types-RNPaKi9o.d.mts +70 -0
  47. package/dist/auto-instrumentations/types-RNPaKi9o.d.ts +70 -0
  48. package/dist/browser.d.mts +4411 -719
  49. package/dist/browser.d.ts +4411 -719
  50. package/dist/browser.js +4274 -480
  51. package/dist/browser.mjs +4274 -480
  52. package/dist/{chunk-LPC4W2WX.js → chunk-BFGIH2ZJ.js} +4 -0
  53. package/dist/{chunk-Y7W7WP6H.mjs → chunk-KMGUTPB7.mjs} +4 -0
  54. package/dist/{chunk-POCCIJAL.js → chunk-MWVVR5LR.js} +3278 -1334
  55. package/dist/{chunk-F73OMF66.mjs → chunk-ZG2O3XVF.mjs} +2542 -598
  56. package/dist/cli.js +2338 -419
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +4274 -480
  60. package/dist/edge-light.mjs +4274 -480
  61. package/dist/index.d.mts +4926 -1234
  62. package/dist/index.d.ts +4926 -1234
  63. package/dist/index.js +2303 -435
  64. package/dist/index.mjs +1914 -46
  65. package/dist/instrumentation/index.d.mts +1026 -20
  66. package/dist/instrumentation/index.d.ts +1026 -20
  67. package/dist/instrumentation/index.js +3864 -483
  68. package/dist/instrumentation/index.mjs +3862 -483
  69. package/dist/vitest-evals-reporter.js +16 -16
  70. package/dist/vitest-evals-reporter.mjs +2 -2
  71. package/dist/workerd.d.mts +1 -1
  72. package/dist/workerd.d.ts +1 -1
  73. package/dist/workerd.js +4274 -480
  74. package/dist/workerd.mjs +4274 -480
  75. package/licenses/import-in-the-middle/LICENSE +201 -0
  76. package/licenses/import-in-the-middle/LICENSE-3rdparty.csv +4 -0
  77. package/licenses/import-in-the-middle/NOTICE +34 -0
  78. package/licenses/orchestrion-js/LICENSE +202 -0
  79. package/licenses/orchestrion-js/LICENSE-3rdparty.csv +8 -0
  80. package/licenses/orchestrion-js/NOTICE +3 -0
  81. package/licenses/require-in-the-middle/LICENSE +23 -0
  82. package/package.json +16 -4
  83. package/util/dist/index.d.mts +1 -0
  84. package/util/dist/index.d.ts +1 -0
  85. package/util/dist/index.js +4 -4
  86. package/util/dist/index.mjs +2 -2
  87. package/dist/auto-instrumentations/chunk-J57YF7WS.mjs +0 -208
  88. package/dist/auto-instrumentations/chunk-QFMACSOL.mjs +0 -280
package/dist/cli.js CHANGED
@@ -1232,7 +1232,7 @@ var require_package = __commonJS({
1232
1232
  "package.json"(exports2, module2) {
1233
1233
  module2.exports = {
1234
1234
  name: "braintrust",
1235
- version: "3.20.0",
1235
+ version: "3.22.0",
1236
1236
  description: "SDK for integrating Braintrust",
1237
1237
  repository: {
1238
1238
  type: "git",
@@ -1369,12 +1369,14 @@ var require_package = __commonJS({
1369
1369
  "util/dist/**/*",
1370
1370
  "bin/bt",
1371
1371
  "scripts/bt-helper.js",
1372
- "scripts/install.js"
1372
+ "scripts/install.js",
1373
+ "NOTICE",
1374
+ "licenses/**/*"
1373
1375
  ],
1374
1376
  scripts: {
1375
1377
  postinstall: "node ./scripts/install.js",
1376
1378
  build: 'cross-env NODE_OPTIONS="--max-old-space-size=8192" tsup',
1377
- "check:typings": "tsc --noEmit",
1379
+ "check:typings": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
1378
1380
  watch: "tsup --watch",
1379
1381
  clean: "rm -r dist/* && rm -r dev/dist/* && rm -r util/dist/*",
1380
1382
  docs: "typedoc --options typedoc.json src/node/index.ts",
@@ -1411,6 +1413,7 @@ var require_package = __commonJS({
1411
1413
  "@types/async": "^3.2.24",
1412
1414
  "@types/cli-progress": "^3.11.5",
1413
1415
  "@types/cors": "^2.8.17",
1416
+ "@types/esquery": "^1.5.4",
1414
1417
  "@types/express": "^5.0.0",
1415
1418
  "@types/http-errors": "^2.0.4",
1416
1419
  "@types/mustache": "^4.2.5",
@@ -1422,11 +1425,14 @@ var require_package = __commonJS({
1422
1425
  ai: "^6.0.0",
1423
1426
  async: "^3.2.5",
1424
1427
  "cross-env": "^7.0.3",
1428
+ "eslint-plugin-es-x": "9.7.0",
1429
+ "eslint-plugin-n": "^18.2.1",
1425
1430
  "eslint-plugin-node-import": "^1.0.5",
1426
1431
  openai: "6.25.0",
1427
1432
  rollup: "^4.60.3",
1428
1433
  tar: "^7.5.16",
1429
1434
  tinybench: "^4.0.1",
1435
+ "ts-declaration-location": "^1.0.7",
1430
1436
  tsup: "^8.5.1",
1431
1437
  tsx: "^4.21.0",
1432
1438
  typedoc: "^0.25.13",
@@ -1439,24 +1445,30 @@ var require_package = __commonJS({
1439
1445
  zod: "^3.25.34"
1440
1446
  },
1441
1447
  dependencies: {
1442
- "@apm-js-collab/code-transformer": "^0.12.0",
1443
1448
  "@next/env": "^14.2.3",
1444
1449
  "@vercel/functions": "^1.0.2",
1450
+ acorn: "^8.16.0",
1451
+ "acorn-import-attributes": "^1.9.5",
1445
1452
  ajv: "^8.20.0",
1446
1453
  argparse: "^2.0.1",
1454
+ astring: "^1.9.0",
1455
+ "cjs-module-lexer": "^2.2.0",
1447
1456
  "cli-progress": "^3.12.0",
1448
1457
  "cli-table3": "^0.6.5",
1449
1458
  cors: "^2.8.5",
1450
1459
  "dc-browser": "^1.0.4",
1451
1460
  dotenv: "^16.4.5",
1452
1461
  esbuild: "0.28.0",
1462
+ esquery: "^1.7.0",
1453
1463
  "eventsource-parser": "^1.1.2",
1454
1464
  express: "^5.2.1",
1455
1465
  "http-errors": "^2.0.0",
1466
+ meriyah: "^6.1.4",
1456
1467
  minimatch: "^10.2.5",
1457
1468
  "module-details-from-path": "^1.0.4",
1458
1469
  mustache: "^4.2.0",
1459
1470
  pluralize: "^8.0.0",
1471
+ semifies: "^1.0.0",
1460
1472
  "simple-git": "^3.36.0",
1461
1473
  "source-map": "^0.7.4",
1462
1474
  "termi-link": "^1.0.1",
@@ -1782,8 +1794,291 @@ var UUIDGenerator = class extends IDGenerator {
1782
1794
  return true;
1783
1795
  }
1784
1796
  };
1797
+ function generateHexId(bytes) {
1798
+ let result = "";
1799
+ for (let i = 0; i < bytes; i++) {
1800
+ result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
1801
+ }
1802
+ return result;
1803
+ }
1804
+ var OTELIDGenerator = class extends IDGenerator {
1805
+ getSpanId() {
1806
+ return generateHexId(8);
1807
+ }
1808
+ getTraceId() {
1809
+ return generateHexId(16);
1810
+ }
1811
+ shareRootSpanId() {
1812
+ return false;
1813
+ }
1814
+ };
1815
+ function parseEnvBool(name) {
1816
+ const raw = isomorph_default.getEnv(name);
1817
+ if (raw === void 0 || raw === null) {
1818
+ return false;
1819
+ }
1820
+ const normalized = raw.trim().toLowerCase();
1821
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
1822
+ }
1823
+ var _warnedLegacyUuidConflict = false;
1824
+ function resolveUseLegacyUuidIds() {
1825
+ const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
1826
+ if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
1827
+ if (legacy && !_warnedLegacyUuidConflict) {
1828
+ _warnedLegacyUuidConflict = true;
1829
+ debugLogger.warn(
1830
+ "BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
1831
+ );
1832
+ }
1833
+ return false;
1834
+ }
1835
+ return legacy;
1836
+ }
1785
1837
  function getIdGenerator() {
1786
- return globalThis.BRAINTRUST_ID_GENERATOR !== void 0 ? new globalThis.BRAINTRUST_ID_GENERATOR() : new UUIDGenerator();
1838
+ if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
1839
+ return new globalThis.BRAINTRUST_ID_GENERATOR();
1840
+ }
1841
+ return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
1842
+ }
1843
+
1844
+ // src/propagation.ts
1845
+ var TRACEPARENT_HEADER = "traceparent";
1846
+ var TRACESTATE_HEADER = "tracestate";
1847
+ var BAGGAGE_HEADER = "baggage";
1848
+ var BRAINTRUST_PARENT_KEY = "braintrust.parent";
1849
+ var DEFAULT_TRACE_FLAGS = "01";
1850
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
1851
+ var ZERO_TRACE_ID = "0".repeat(32);
1852
+ var ZERO_SPAN_ID = "0".repeat(16);
1853
+ var MAX_BAGGAGE_LENGTH = 8192;
1854
+ var MAX_BAGGAGE_MEMBERS = 64;
1855
+ var _utf8Encoder = new TextEncoder();
1856
+ function utf8ByteLength(value) {
1857
+ return _utf8Encoder.encode(value).length;
1858
+ }
1859
+ function capBaggageToMemberBoundary(value) {
1860
+ const totalBytes = utf8ByteLength(value);
1861
+ const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
1862
+ let commaCount = 0;
1863
+ for (let i = 0; i < value.length; i++) {
1864
+ if (value.charCodeAt(i) === 44) {
1865
+ commaCount++;
1866
+ }
1867
+ }
1868
+ const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
1869
+ if (withinBytes && withinMembers) {
1870
+ return value;
1871
+ }
1872
+ const kept = [];
1873
+ let length = 0;
1874
+ for (const rawMember of value.split(",")) {
1875
+ if (kept.length >= MAX_BAGGAGE_MEMBERS) {
1876
+ break;
1877
+ }
1878
+ const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
1879
+ if (length + cost > MAX_BAGGAGE_LENGTH) {
1880
+ break;
1881
+ }
1882
+ kept.push(rawMember);
1883
+ length += cost;
1884
+ }
1885
+ if (!kept.length) {
1886
+ return "";
1887
+ }
1888
+ return kept.join(",");
1889
+ }
1890
+ function isTraceContextHeaderTupleArray(value) {
1891
+ return Array.isArray(value) && value.every(
1892
+ (item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
1893
+ );
1894
+ }
1895
+ function isListHeader(name) {
1896
+ const lowered = name.toLowerCase();
1897
+ return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
1898
+ }
1899
+ function headerValueToString(value, name) {
1900
+ if (value === void 0 || value === null) {
1901
+ return void 0;
1902
+ }
1903
+ if (Array.isArray(value)) {
1904
+ const stringValues = value.filter((item) => {
1905
+ return typeof item === "string";
1906
+ });
1907
+ if (!stringValues.length) {
1908
+ return void 0;
1909
+ }
1910
+ return isListHeader(name) ? stringValues.join(",") : stringValues[0];
1911
+ }
1912
+ return typeof value === "string" ? value : String(value);
1913
+ }
1914
+ function getHeader(headers, name) {
1915
+ if (!headers) {
1916
+ return void 0;
1917
+ }
1918
+ if (isTraceContextHeaderTupleArray(headers)) {
1919
+ const lowered2 = name.toLowerCase();
1920
+ const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
1921
+ if (!matches.length) {
1922
+ return void 0;
1923
+ }
1924
+ return headerValueToString(matches, name);
1925
+ }
1926
+ const getter = headers.get;
1927
+ if (typeof getter === "function") {
1928
+ try {
1929
+ const value = headerValueToString(getter.call(headers, name), name);
1930
+ if (value !== void 0) {
1931
+ return value;
1932
+ }
1933
+ } catch {
1934
+ }
1935
+ }
1936
+ const nodeGetter = headers.getHeader;
1937
+ if (typeof nodeGetter === "function") {
1938
+ try {
1939
+ const value = headerValueToString(nodeGetter.call(headers, name), name);
1940
+ if (value !== void 0) {
1941
+ return value;
1942
+ }
1943
+ } catch {
1944
+ }
1945
+ }
1946
+ const headerBag = headers;
1947
+ const exact = headerValueToString(headerBag[name], name);
1948
+ if (exact !== void 0) {
1949
+ return exact;
1950
+ }
1951
+ const lowered = name.toLowerCase();
1952
+ for (const key of Object.keys(headers)) {
1953
+ if (key !== name && key.toLowerCase() === lowered) {
1954
+ const value = headerValueToString(headerBag[key], name);
1955
+ if (value !== void 0) {
1956
+ return value;
1957
+ }
1958
+ }
1959
+ }
1960
+ return void 0;
1961
+ }
1962
+ function isHex(value, length) {
1963
+ if (typeof value !== "string" || value.length !== length) {
1964
+ return false;
1965
+ }
1966
+ for (let i = 0; i < value.length; i++) {
1967
+ const c = value[i];
1968
+ const isDigit = c >= "0" && c <= "9";
1969
+ const isLowerHex = c >= "a" && c <= "f";
1970
+ if (!isDigit && !isLowerHex) {
1971
+ return false;
1972
+ }
1973
+ }
1974
+ return true;
1975
+ }
1976
+ function parseTraceparent(value) {
1977
+ if (!value || typeof value !== "string") {
1978
+ return void 0;
1979
+ }
1980
+ const match = TRACEPARENT_RE.exec(value.trim());
1981
+ if (!match) {
1982
+ return void 0;
1983
+ }
1984
+ const traceId = match[1];
1985
+ const spanId = match[2];
1986
+ const traceFlags = match[3];
1987
+ if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
1988
+ return void 0;
1989
+ }
1990
+ return { traceId, spanId, traceFlags };
1991
+ }
1992
+ function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
1993
+ if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
1994
+ return void 0;
1995
+ }
1996
+ if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
1997
+ return void 0;
1998
+ }
1999
+ const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
2000
+ return `00-${traceId}-${spanId}-${flags}`;
2001
+ }
2002
+ function percentEncode(value) {
2003
+ return encodeURIComponent(value);
2004
+ }
2005
+ function percentDecode(value) {
2006
+ if (!value.includes("%")) {
2007
+ return value;
2008
+ }
2009
+ try {
2010
+ return decodeURIComponent(value);
2011
+ } catch {
2012
+ return value;
2013
+ }
2014
+ }
2015
+ function parseBaggage(value) {
2016
+ const result = {};
2017
+ if (!value || typeof value !== "string") {
2018
+ return result;
2019
+ }
2020
+ const bounded = capBaggageToMemberBoundary(value);
2021
+ for (let member of bounded.split(",")) {
2022
+ member = member.trim();
2023
+ if (!member || !member.includes("=")) {
2024
+ continue;
2025
+ }
2026
+ member = member.split(";", 1)[0];
2027
+ const eq = member.indexOf("=");
2028
+ const key = percentDecode(member.slice(0, eq).trim());
2029
+ const val = member.slice(eq + 1).trim();
2030
+ if (!key) {
2031
+ continue;
2032
+ }
2033
+ result[key] = percentDecode(val);
2034
+ }
2035
+ return result;
2036
+ }
2037
+ function mergeBaggage(existing, braintrustParent) {
2038
+ let btMember = void 0;
2039
+ if (braintrustParent) {
2040
+ const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
2041
+ const encodedVal = percentEncode(String(braintrustParent));
2042
+ btMember = `${encodedKey}=${encodedVal}`;
2043
+ if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
2044
+ btMember = void 0;
2045
+ }
2046
+ }
2047
+ let byteBudget = MAX_BAGGAGE_LENGTH;
2048
+ let memberBudget = MAX_BAGGAGE_MEMBERS;
2049
+ if (btMember !== void 0) {
2050
+ byteBudget -= utf8ByteLength(btMember) + 1;
2051
+ memberBudget -= 1;
2052
+ }
2053
+ const relayed = [];
2054
+ let length = 0;
2055
+ if (existing && typeof existing === "string") {
2056
+ for (const rawMember of existing.split(",")) {
2057
+ const member = rawMember.trim();
2058
+ if (!member || !member.includes("=")) {
2059
+ continue;
2060
+ }
2061
+ const keyPart = member.split(";", 1)[0].split("=", 1)[0];
2062
+ const key = percentDecode(keyPart.trim());
2063
+ if (key === BRAINTRUST_PARENT_KEY) {
2064
+ continue;
2065
+ }
2066
+ if (relayed.length >= memberBudget) {
2067
+ break;
2068
+ }
2069
+ const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
2070
+ if (length + cost > byteBudget) {
2071
+ break;
2072
+ }
2073
+ relayed.push(member);
2074
+ length += cost;
2075
+ }
2076
+ }
2077
+ const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
2078
+ if (!members.length) {
2079
+ return void 0;
2080
+ }
2081
+ return members.join(",");
1787
2082
  }
1788
2083
 
1789
2084
  // util/db_fields.ts
@@ -2391,7 +2686,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
2391
2686
  case 3 /* PLAYGROUND_LOGS */:
2392
2687
  return { prompt_session_id: this.data.object_id, log_id: "x" };
2393
2688
  default:
2394
- const _ = this.data.object_type;
2689
+ this.data.object_type;
2395
2690
  throw new Error("Impossible");
2396
2691
  }
2397
2692
  }
@@ -2931,7 +3226,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
2931
3226
  case 3 /* PLAYGROUND_LOGS */:
2932
3227
  return { prompt_session_id: this.data.object_id, log_id: "x" };
2933
3228
  default:
2934
- const _ = this.data.object_type;
3229
+ this.data.object_type;
2935
3230
  throw new Error(`Invalid object_type ${this.data.object_type}`);
2936
3231
  }
2937
3232
  }
@@ -3126,7 +3421,8 @@ var AclObjectType = import_v36.z.union([
3126
3421
  "role",
3127
3422
  "org_member",
3128
3423
  "project_log",
3129
- "org_project"
3424
+ "org_project",
3425
+ "org_audit_logs"
3130
3426
  ]),
3131
3427
  import_v36.z.null()
3132
3428
  ]);
@@ -3152,6 +3448,17 @@ var Acl = import_v36.z.object({
3152
3448
  _object_org_id: import_v36.z.string().uuid(),
3153
3449
  created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
3154
3450
  });
3451
+ var Agent = import_v36.z.object({
3452
+ id: import_v36.z.string().uuid(),
3453
+ project_id: import_v36.z.string().uuid(),
3454
+ user_id: import_v36.z.string().uuid(),
3455
+ created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3456
+ name: import_v36.z.string(),
3457
+ slug: import_v36.z.string(),
3458
+ kind: import_v36.z.string(),
3459
+ description: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3460
+ metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional()
3461
+ });
3155
3462
  var AISecret = import_v36.z.object({
3156
3463
  id: import_v36.z.string().uuid(),
3157
3464
  created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
@@ -3298,6 +3605,7 @@ var AttachmentStatus = import_v36.z.object({
3298
3605
  upload_status: UploadStatus,
3299
3606
  error_message: import_v36.z.string().optional()
3300
3607
  });
3608
+ var AutomationStatus = import_v36.z.enum(["active", "paused"]);
3301
3609
  var FunctionTypeEnum = import_v36.z.enum([
3302
3610
  "llm",
3303
3611
  "scorer",
@@ -3343,7 +3651,9 @@ var TopicMapData = import_v36.z.object({
3343
3651
  topic_names: import_v36.z.record(import_v36.z.string()).optional(),
3344
3652
  generation_settings: TopicMapGenerationSettings.optional(),
3345
3653
  disable_reconciliation: import_v36.z.boolean().optional(),
3346
- distance_threshold: import_v36.z.number().optional()
3654
+ distance_threshold: import_v36.z.number().optional(),
3655
+ btql_filter: import_v36.z.string().optional(),
3656
+ automation_btql_filter: import_v36.z.string().optional()
3347
3657
  });
3348
3658
  var BatchedFacetData = import_v36.z.object({
3349
3659
  type: import_v36.z.literal("batched_facet"),
@@ -3417,19 +3727,30 @@ var CallEvent = import_v36.z.union([
3417
3727
  var ChatCompletionContentPartTextWithTitle = import_v36.z.object({
3418
3728
  text: import_v36.z.string().default(""),
3419
3729
  type: import_v36.z.literal("text"),
3420
- cache_control: import_v36.z.object({ type: import_v36.z.literal("ephemeral") }).optional()
3730
+ cache_control: import_v36.z.object({
3731
+ type: import_v36.z.literal("ephemeral"),
3732
+ ttl: import_v36.z.enum(["5m", "1h"]).optional()
3733
+ }).optional()
3421
3734
  });
3422
3735
  var ChatCompletionContentPartImageWithTitle = import_v36.z.object({
3423
3736
  image_url: import_v36.z.object({
3424
3737
  url: import_v36.z.string(),
3425
3738
  detail: import_v36.z.union([import_v36.z.literal("auto"), import_v36.z.literal("low"), import_v36.z.literal("high")]).optional()
3426
3739
  }),
3427
- type: import_v36.z.literal("image_url")
3740
+ type: import_v36.z.literal("image_url"),
3741
+ cache_control: import_v36.z.object({
3742
+ type: import_v36.z.literal("ephemeral"),
3743
+ ttl: import_v36.z.enum(["5m", "1h"]).optional()
3744
+ }).optional()
3428
3745
  });
3429
3746
  var ChatCompletionContentPartFileFile = import_v36.z.object({ file_data: import_v36.z.string(), filename: import_v36.z.string(), file_id: import_v36.z.string() }).partial();
3430
3747
  var ChatCompletionContentPartFileWithTitle = import_v36.z.object({
3431
3748
  file: ChatCompletionContentPartFileFile,
3432
- type: import_v36.z.literal("file")
3749
+ type: import_v36.z.literal("file"),
3750
+ cache_control: import_v36.z.object({
3751
+ type: import_v36.z.literal("ephemeral"),
3752
+ ttl: import_v36.z.enum(["5m", "1h"]).optional()
3753
+ }).optional()
3433
3754
  });
3434
3755
  var ChatCompletionContentPart = import_v36.z.union([
3435
3756
  ChatCompletionContentPartTextWithTitle,
@@ -3439,7 +3760,10 @@ var ChatCompletionContentPart = import_v36.z.union([
3439
3760
  var ChatCompletionContentPartText = import_v36.z.object({
3440
3761
  text: import_v36.z.string().default(""),
3441
3762
  type: import_v36.z.literal("text"),
3442
- cache_control: import_v36.z.object({ type: import_v36.z.literal("ephemeral") }).optional()
3763
+ cache_control: import_v36.z.object({
3764
+ type: import_v36.z.literal("ephemeral"),
3765
+ ttl: import_v36.z.enum(["5m", "1h"]).optional()
3766
+ }).optional()
3443
3767
  });
3444
3768
  var ChatCompletionMessageToolCall = import_v36.z.object({
3445
3769
  id: import_v36.z.string(),
@@ -3626,7 +3950,7 @@ var DatasetEvent = import_v36.z.object({
3626
3950
  origin: ObjectReferenceNullish.optional(),
3627
3951
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3628
3952
  audit_data: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3629
- facets: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
3953
+ facets: import_v36.z.union([import_v36.z.record(import_v36.z.union([import_v36.z.string(), import_v36.z.null()])), import_v36.z.null()]).optional(),
3630
3954
  classifications: import_v36.z.union([
3631
3955
  import_v36.z.record(
3632
3956
  import_v36.z.array(
@@ -3778,7 +4102,7 @@ var ExperimentEvent = import_v36.z.object({
3778
4102
  origin: ObjectReferenceNullish.optional(),
3779
4103
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3780
4104
  audit_data: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3781
- facets: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
4105
+ facets: import_v36.z.union([import_v36.z.record(import_v36.z.union([import_v36.z.string(), import_v36.z.null()])), import_v36.z.null()]).optional(),
3782
4106
  classifications: import_v36.z.union([
3783
4107
  import_v36.z.record(
3784
4108
  import_v36.z.array(
@@ -3916,7 +4240,8 @@ var PromptParserNullish = import_v36.z.union([
3916
4240
  use_cot: import_v36.z.boolean(),
3917
4241
  choice_scores: import_v36.z.record(import_v36.z.number().gte(0).lte(1)).optional(),
3918
4242
  choice: import_v36.z.array(import_v36.z.string()).optional(),
3919
- allow_no_match: import_v36.z.boolean().optional()
4243
+ allow_no_match: import_v36.z.boolean().optional(),
4244
+ allow_skip: import_v36.z.boolean().optional()
3920
4245
  }),
3921
4246
  import_v36.z.null()
3922
4247
  ]);
@@ -4246,6 +4571,9 @@ var Group = import_v36.z.object({
4246
4571
  var GroupScope = import_v36.z.object({
4247
4572
  type: import_v36.z.literal("group"),
4248
4573
  group_by: import_v36.z.string(),
4574
+ interval_seconds: import_v36.z.number().gte(1).optional(),
4575
+ max_traces: import_v36.z.number().int().gte(1).lte(64).optional(),
4576
+ placement: import_v36.z.enum(["first", "each"]),
4249
4577
  idle_seconds: import_v36.z.number().optional()
4250
4578
  });
4251
4579
  var IfExists = import_v36.z.enum(["error", "ignore", "replace"]);
@@ -4394,6 +4722,10 @@ var RetentionObjectType = import_v36.z.enum([
4394
4722
  "experiment",
4395
4723
  "dataset"
4396
4724
  ]);
4725
+ var TopicAutomationFacetModel = import_v36.z.union([
4726
+ import_v36.z.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
4727
+ import_v36.z.null()
4728
+ ]);
4397
4729
  var TopicMapFunctionAutomation = import_v36.z.object({
4398
4730
  function: SavedFunctionId.and(import_v36.z.unknown()),
4399
4731
  btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
@@ -4406,7 +4738,9 @@ var TopicAutomationDataScope = import_v36.z.union([
4406
4738
  ]);
4407
4739
  var TopicAutomationConfig = import_v36.z.object({
4408
4740
  event_type: import_v36.z.literal("topic"),
4741
+ status: AutomationStatus.optional(),
4409
4742
  sampling_rate: import_v36.z.number().gte(0).lte(1),
4743
+ facet_model: TopicAutomationFacetModel.optional(),
4410
4744
  facet_functions: import_v36.z.array(SavedFunctionId),
4411
4745
  topic_map_functions: import_v36.z.array(TopicMapFunctionAutomation),
4412
4746
  scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
@@ -4420,6 +4754,19 @@ var TopicAutomationConfig = import_v36.z.object({
4420
4754
  import_v36.z.null()
4421
4755
  ]).optional()
4422
4756
  });
4757
+ var TopicDigestAutomationConfig = import_v36.z.object({
4758
+ event_type: import_v36.z.literal("topic_digest"),
4759
+ status: AutomationStatus.optional(),
4760
+ window_seconds: import_v36.z.number().int().gte(3600).lte(2592e3).optional().default(86400),
4761
+ scheduled_time_minutes_utc: import_v36.z.number().int().gte(0).lte(1439),
4762
+ action: import_v36.z.object({
4763
+ type: import_v36.z.literal("slack"),
4764
+ workspace_id: import_v36.z.string(),
4765
+ channel: import_v36.z.string(),
4766
+ message_template: import_v36.z.string().optional()
4767
+ }),
4768
+ topic_map_function_ids: import_v36.z.array(import_v36.z.string()).max(10).optional()
4769
+ });
4423
4770
  var ProjectAutomation = import_v36.z.object({
4424
4771
  id: import_v36.z.string().uuid(),
4425
4772
  project_id: import_v36.z.string().uuid(),
@@ -4444,6 +4791,7 @@ var ProjectAutomation = import_v36.z.object({
4444
4791
  }),
4445
4792
  import_v36.z.object({
4446
4793
  event_type: import_v36.z.literal("btql_export"),
4794
+ status: AutomationStatus.optional(),
4447
4795
  export_definition: import_v36.z.union([
4448
4796
  import_v36.z.object({ type: import_v36.z.literal("log_traces") }),
4449
4797
  import_v36.z.object({ type: import_v36.z.literal("log_spans") }),
@@ -4466,6 +4814,21 @@ var ProjectAutomation = import_v36.z.object({
4466
4814
  ]),
4467
4815
  batch_size: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
4468
4816
  }),
4817
+ import_v36.z.object({
4818
+ event_type: import_v36.z.literal("async_query"),
4819
+ status: AutomationStatus.optional(),
4820
+ created_by_user_id: import_v36.z.string().uuid(),
4821
+ object_type: import_v36.z.enum([
4822
+ "project_logs",
4823
+ "experiment",
4824
+ "dataset",
4825
+ "playground_logs"
4826
+ ]),
4827
+ object_id: import_v36.z.string(),
4828
+ query: import_v36.z.string(),
4829
+ format: import_v36.z.literal("jsonl"),
4830
+ batch_size: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
4831
+ }),
4469
4832
  import_v36.z.object({
4470
4833
  event_type: import_v36.z.literal("retention"),
4471
4834
  object_type: RetentionObjectType,
@@ -4484,7 +4847,8 @@ var ProjectAutomation = import_v36.z.object({
4484
4847
  })
4485
4848
  ])
4486
4849
  }),
4487
- TopicAutomationConfig
4850
+ TopicAutomationConfig,
4851
+ TopicDigestAutomationConfig
4488
4852
  ])
4489
4853
  });
4490
4854
  var ProjectLogsEvent = import_v36.z.object({
@@ -4523,7 +4887,7 @@ var ProjectLogsEvent = import_v36.z.object({
4523
4887
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
4524
4888
  audit_data: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
4525
4889
  _async_scoring_state: import_v36.z.unknown().optional(),
4526
- facets: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
4890
+ facets: import_v36.z.union([import_v36.z.record(import_v36.z.union([import_v36.z.string(), import_v36.z.null()])), import_v36.z.null()]).optional(),
4527
4891
  classifications: import_v36.z.union([
4528
4892
  import_v36.z.record(
4529
4893
  import_v36.z.array(
@@ -4572,11 +4936,34 @@ var ProjectScoreCategories = import_v36.z.union([
4572
4936
  import_v36.z.array(import_v36.z.string()),
4573
4937
  import_v36.z.null()
4574
4938
  ]);
4939
+ var ProjectScoreCondition = import_v36.z.union([
4940
+ import_v36.z.object({
4941
+ when: import_v36.z.object({
4942
+ clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
4943
+ subspan_clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
4944
+ trace_clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()])
4945
+ }).partial(),
4946
+ behavior: import_v36.z.literal("hidden").optional().default("hidden")
4947
+ }),
4948
+ import_v36.z.null()
4949
+ ]);
4575
4950
  var ProjectScoreConfig = import_v36.z.union([
4576
4951
  import_v36.z.object({
4577
4952
  multi_select: import_v36.z.union([import_v36.z.boolean(), import_v36.z.null()]),
4578
4953
  destination: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
4579
- online: OnlineScoreConfig
4954
+ visibility: import_v36.z.union([
4955
+ import_v36.z.object({
4956
+ users: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
4957
+ groups: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()])
4958
+ }).partial(),
4959
+ import_v36.z.null()
4960
+ ]),
4961
+ online: OnlineScoreConfig,
4962
+ condition: ProjectScoreCondition,
4963
+ object_types: import_v36.z.union([
4964
+ import_v36.z.array(import_v36.z.enum(["project_logs", "dataset", "experiment"])),
4965
+ import_v36.z.null()
4966
+ ])
4580
4967
  }).partial(),
4581
4968
  import_v36.z.null()
4582
4969
  ]);
@@ -4761,8 +5148,7 @@ var User = import_v36.z.object({
4761
5148
  family_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4762
5149
  email: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4763
5150
  avatar_url: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4764
- created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4765
- last_active_at: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
5151
+ created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
4766
5152
  });
4767
5153
  var ViewDataSearch = import_v36.z.union([
4768
5154
  import_v36.z.object({
@@ -5428,13 +5814,23 @@ var LRUCache = class {
5428
5814
  * @returns The cached value if found, undefined otherwise.
5429
5815
  */
5430
5816
  get(key) {
5431
- const value = this.cache.get(key);
5432
- if (value === void 0) {
5817
+ const entry = this.cache.get(key);
5818
+ if (entry === void 0) {
5433
5819
  return void 0;
5434
5820
  }
5435
5821
  this.cache.delete(key);
5436
- this.cache.set(key, value);
5437
- return value;
5822
+ this.cache.set(key, entry);
5823
+ return entry.value;
5824
+ }
5825
+ /**
5826
+ * Checks whether a key exists and marks it as most recently used.
5827
+ */
5828
+ has(key) {
5829
+ if (!this.cache.has(key)) {
5830
+ return false;
5831
+ }
5832
+ this.get(key);
5833
+ return true;
5438
5834
  }
5439
5835
  /**
5440
5836
  * Stores a value in the cache.
@@ -5451,7 +5847,38 @@ var LRUCache = class {
5451
5847
  const first = this.cache.keys().next().value;
5452
5848
  this.cache.delete(first);
5453
5849
  }
5454
- this.cache.set(key, value);
5850
+ this.cache.set(key, { value });
5851
+ }
5852
+ /**
5853
+ * Removes an item from the cache.
5854
+ */
5855
+ delete(key) {
5856
+ return this.cache.delete(key);
5857
+ }
5858
+ /**
5859
+ * Iterates over cache entries from least to most recently used.
5860
+ */
5861
+ *entries() {
5862
+ for (const [key, entry] of this.cache) {
5863
+ yield [key, entry.value];
5864
+ }
5865
+ }
5866
+ /**
5867
+ * Iterates over cache keys from least to most recently used.
5868
+ */
5869
+ keys() {
5870
+ return this.cache.keys();
5871
+ }
5872
+ /**
5873
+ * Iterates over cache values from least to most recently used.
5874
+ */
5875
+ *values() {
5876
+ for (const entry of this.cache.values()) {
5877
+ yield entry.value;
5878
+ }
5879
+ }
5880
+ [Symbol.iterator]() {
5881
+ return this.entries();
5455
5882
  }
5456
5883
  /**
5457
5884
  * Removes all items from the cache.
@@ -6009,6 +6436,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
6009
6436
  return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
6010
6437
  }
6011
6438
  }
6439
+ var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
6440
+ "braintrust.initial-span-write-as-merge"
6441
+ );
6012
6442
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
6013
6443
  "braintrust.currentSpanStore"
6014
6444
  );
@@ -6049,7 +6479,10 @@ var BraintrustContextManager = class extends ContextManager {
6049
6479
  }
6050
6480
  };
6051
6481
  function getSpanComponentsClass() {
6052
- return globalThis.BRAINTRUST_SPAN_COMPONENT ? globalThis.BRAINTRUST_SPAN_COMPONENT : SpanComponentsV3;
6482
+ if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
6483
+ return globalThis.BRAINTRUST_SPAN_COMPONENT;
6484
+ }
6485
+ return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
6053
6486
  }
6054
6487
  function getContextManager() {
6055
6488
  return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
@@ -6085,6 +6518,9 @@ var NoopSpan = class {
6085
6518
  async export() {
6086
6519
  return "";
6087
6520
  }
6521
+ inject(carrier) {
6522
+ return carrier ?? {};
6523
+ }
6088
6524
  async permalink() {
6089
6525
  return NOOP_SPAN_PERMALINK;
6090
6526
  }
@@ -6135,6 +6571,10 @@ var loginSchema = import_v38.z.strictObject({
6135
6571
  debugLogLevelDisabled: import_v38.z.boolean().optional()
6136
6572
  });
6137
6573
  var stateNonce = 0;
6574
+ var V1_PROXY_SUFFIX = "/v1/proxy";
6575
+ function normalizeProxyConnUrl(proxyUrl) {
6576
+ return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
6577
+ }
6138
6578
  var BraintrustState = class _BraintrustState {
6139
6579
  constructor(loginParams) {
6140
6580
  this.loginParams = loginParams;
@@ -6405,7 +6845,10 @@ var BraintrustState = class _BraintrustState {
6405
6845
  if (!this.proxyUrl) {
6406
6846
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
6407
6847
  }
6408
- this._proxyConn = new HTTPConnection(this.proxyUrl, this.fetch);
6848
+ this._proxyConn = new HTTPConnection(
6849
+ normalizeProxyConnUrl(this.proxyUrl),
6850
+ this.fetch
6851
+ );
6409
6852
  }
6410
6853
  return this._proxyConn;
6411
6854
  }
@@ -7091,7 +7534,7 @@ async function permalink(slug, opts) {
7091
7534
  return state.appUrl;
7092
7535
  };
7093
7536
  try {
7094
- const components = getSpanComponentsClass().fromStr(slug);
7537
+ const components = SpanComponentsV4.fromStr(slug);
7095
7538
  const object_type = spanObjectTypeV3ToString(components.data.object_type);
7096
7539
  const [orgName, appUrl, object_id] = await Promise.all([
7097
7540
  getOrgName(),
@@ -7115,35 +7558,47 @@ function startSpanParentArgs(args) {
7115
7558
  let argParentObjectId = void 0;
7116
7559
  let argParentSpanIds = void 0;
7117
7560
  let argPropagatedEvent = void 0;
7118
- if (args.parent) {
7561
+ let argPropagatedState = void 0;
7562
+ const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
7563
+ if (parentSlug) {
7119
7564
  if (args.parentSpanIds) {
7120
7565
  throw new Error("Cannot specify both parent and parentSpanIds");
7121
7566
  }
7122
- const parentComponents = getSpanComponentsClass().fromStr(args.parent);
7567
+ const parentComponents = SpanComponentsV4.fromStr(parentSlug);
7123
7568
  if (args.parentObjectType !== parentComponents.data.object_type) {
7124
7569
  throw new Error(
7125
7570
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
7126
7571
  );
7127
7572
  }
7128
7573
  argParentObjectId = args.parentObjectId;
7129
- if (parentComponents.data.row_id) {
7574
+ if (parentComponents.data.row_id && parentSpanIdsUsable(
7575
+ parentComponents.data.span_id,
7576
+ parentComponents.data.root_span_id
7577
+ )) {
7130
7578
  argParentSpanIds = {
7131
7579
  spanId: parentComponents.data.span_id,
7132
7580
  rootSpanId: parentComponents.data.root_span_id
7133
7581
  };
7134
7582
  }
7135
7583
  argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
7584
+ const propagatedState = args.propagatedState ?? parentPropagatedState;
7585
+ if (propagatedState) {
7586
+ const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
7587
+ argPropagatedState = w3cState;
7588
+ }
7136
7589
  } else {
7137
7590
  argParentObjectId = args.parentObjectId;
7138
7591
  argParentSpanIds = args.parentSpanIds;
7139
7592
  argPropagatedEvent = args.propagatedEvent;
7593
+ argPropagatedState = args.propagatedState;
7140
7594
  }
7141
7595
  return {
7142
7596
  parentObjectType: args.parentObjectType,
7143
7597
  parentObjectId: argParentObjectId,
7144
7598
  parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
7145
7599
  parentSpanIds: argParentSpanIds,
7146
- propagatedEvent: argPropagatedEvent
7600
+ propagatedEvent: argPropagatedEvent,
7601
+ propagatedState: argPropagatedState
7147
7602
  };
7148
7603
  }
7149
7604
  var Logger = class {
@@ -7344,6 +7799,22 @@ var Logger = class {
7344
7799
  _getLinkBaseUrl() {
7345
7800
  return _getLinkBaseUrl(this.state, this._linkArgs);
7346
7801
  }
7802
+ /**
7803
+ * Return this logger's Braintrust parent string (`project_id:<id>` or
7804
+ * `project_name:<name>`) for the `braintrust.parent` baggage entry, or
7805
+ * undefined when it cannot be determined synchronously.
7806
+ */
7807
+ _getOtelParent() {
7808
+ const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
7809
+ if (id) {
7810
+ return `project_id:${id}`;
7811
+ }
7812
+ const name = this.computeMetadataArgs?.project_name;
7813
+ if (name) {
7814
+ return `project_name:${name}`;
7815
+ }
7816
+ return void 0;
7817
+ }
7347
7818
  };
7348
7819
  function castLogger(logger, asyncFlush) {
7349
7820
  if (logger === void 0) return void 0;
@@ -7438,12 +7909,12 @@ function stringifyWithOverflowMeta(item) {
7438
7909
  object_ids: pickLogs3OverflowObjectIds(record),
7439
7910
  is_delete: record[OBJECT_DELETE_FIELD] === true,
7440
7911
  input_row: {
7441
- byte_size: utf8ByteLength(str)
7912
+ byte_size: utf8ByteLength2(str)
7442
7913
  }
7443
7914
  }
7444
7915
  };
7445
7916
  }
7446
- function utf8ByteLength(value) {
7917
+ function utf8ByteLength2(value) {
7447
7918
  if (typeof TextEncoder !== "undefined") {
7448
7919
  return new TextEncoder().encode(value).length;
7449
7920
  }
@@ -7774,7 +8245,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
7774
8245
  }) {
7775
8246
  const conn = await this.apiConn.get();
7776
8247
  const dataStr = constructLogs3Data(items);
7777
- const payloadBytes = utf8ByteLength(dataStr);
8248
+ const payloadBytes = utf8ByteLength2(dataStr);
7778
8249
  const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
7779
8250
  if (this.allPublishPayloadsDir) {
7780
8251
  await _HTTPBackgroundLogger.writePayloadToDir({
@@ -8366,6 +8837,8 @@ function initDataset(projectOrOptions, optionalOptions) {
8366
8837
  const normalizedVersion = selection.version;
8367
8838
  const normalizedEnvironment = selection.environment;
8368
8839
  const normalizedSnapshotName = selection.snapshotName;
8840
+ const cliInternalBtql = globalThis.__bt_eval_internal_btql;
8841
+ const internalBtql = cliInternalBtql === void 0 ? _internal_btql : _internal_btql === void 0 ? cliInternalBtql : isObject(_internal_btql) ? { ...cliInternalBtql, ..._internal_btql } : _internal_btql;
8369
8842
  const state = stateArg ?? _globalState;
8370
8843
  const lazyMetadata = new LazyValue(
8371
8844
  async () => {
@@ -8417,7 +8890,7 @@ function initDataset(projectOrOptions, optionalOptions) {
8417
8890
  lazyMetadata,
8418
8891
  typeof resolvedVersion === "string" ? resolvedVersion : void 0,
8419
8892
  legacy,
8420
- _internal_btql,
8893
+ internalBtql,
8421
8894
  resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
8422
8895
  ...resolvedVersion instanceof LazyValue ? {
8423
8896
  lazyPinnedVersion: resolvedVersion
@@ -8628,23 +9101,256 @@ function currentSpan(options) {
8628
9101
  const state = options?.state ?? _globalState;
8629
9102
  return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
8630
9103
  }
8631
- function getSpanParentObject(options) {
9104
+ function getSpanParentObjectAndPropagatedState(options) {
8632
9105
  const state = options?.state ?? _globalState;
8633
9106
  const parentSpan = currentSpan({ state });
8634
9107
  if (!Object.is(parentSpan, NOOP_SPAN)) {
8635
- return parentSpan;
9108
+ return { parentObject: parentSpan, propagatedState: void 0 };
9109
+ }
9110
+ const parent = options?.parent ?? state.currentParent.getStore();
9111
+ const { parentSlug, propagatedState } = normalizeParent(parent, state);
9112
+ if (parentSlug) {
9113
+ return {
9114
+ parentObject: SpanComponentsV4.fromStr(parentSlug),
9115
+ propagatedState
9116
+ };
8636
9117
  }
8637
- const parentStr = options?.parent ?? state.currentParent.getStore();
8638
- if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
8639
9118
  const experiment = currentExperiment();
8640
9119
  if (experiment) {
8641
- return experiment;
9120
+ return { parentObject: experiment, propagatedState: void 0 };
8642
9121
  }
8643
9122
  const logger = currentLogger(options);
8644
9123
  if (logger) {
8645
- return logger;
9124
+ return { parentObject: logger, propagatedState: void 0 };
9125
+ }
9126
+ return { parentObject: NOOP_SPAN, propagatedState: void 0 };
9127
+ }
9128
+ function getSpanParentObject(options) {
9129
+ return getSpanParentObjectAndPropagatedState(options).parentObject;
9130
+ }
9131
+ function currentBraintrustParent(state) {
9132
+ const resolvedState = state ?? _globalState;
9133
+ const experiment = currentExperiment({ state: resolvedState });
9134
+ if (experiment) {
9135
+ try {
9136
+ return experiment._getOtelParent() ?? void 0;
9137
+ } catch {
9138
+ return void 0;
9139
+ }
9140
+ }
9141
+ const logger = currentLogger({ state: resolvedState });
9142
+ if (logger) {
9143
+ try {
9144
+ return logger._getOtelParent() ?? void 0;
9145
+ } catch {
9146
+ return void 0;
9147
+ }
9148
+ }
9149
+ return void 0;
9150
+ }
9151
+ function braintrustParentToComponents(braintrustParent) {
9152
+ if (!braintrustParent) {
9153
+ return void 0;
9154
+ }
9155
+ if (braintrustParent.startsWith("project_id:")) {
9156
+ const objectId = braintrustParent.slice("project_id:".length);
9157
+ return objectId ? {
9158
+ objectType: 2 /* PROJECT_LOGS */,
9159
+ objectId,
9160
+ computeArgs: void 0
9161
+ } : void 0;
8646
9162
  }
8647
- return NOOP_SPAN;
9163
+ if (braintrustParent.startsWith("project_name:")) {
9164
+ const name = braintrustParent.slice("project_name:".length);
9165
+ return name ? {
9166
+ objectType: 2 /* PROJECT_LOGS */,
9167
+ objectId: void 0,
9168
+ computeArgs: { project_name: name }
9169
+ } : void 0;
9170
+ }
9171
+ if (braintrustParent.startsWith("experiment_id:")) {
9172
+ const objectId = braintrustParent.slice("experiment_id:".length);
9173
+ return objectId ? {
9174
+ objectType: 1 /* EXPERIMENT */,
9175
+ objectId,
9176
+ computeArgs: void 0
9177
+ } : void 0;
9178
+ }
9179
+ return void 0;
9180
+ }
9181
+ function isMutableHeaderTupleArray(carrier) {
9182
+ return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
9183
+ }
9184
+ function setHeader(carrier, name, value) {
9185
+ if (isMutableHeaderTupleArray(carrier)) {
9186
+ const lowered2 = name.toLowerCase();
9187
+ for (let i = carrier.length - 1; i >= 0; i--) {
9188
+ if (carrier[i][0].toLowerCase() === lowered2) {
9189
+ carrier.splice(i, 1);
9190
+ }
9191
+ }
9192
+ carrier.push([name, value]);
9193
+ return;
9194
+ }
9195
+ const setter = carrier.set;
9196
+ if (typeof setter === "function") {
9197
+ const deleter = carrier.delete;
9198
+ if (typeof deleter === "function") {
9199
+ try {
9200
+ deleter.call(carrier, name);
9201
+ } catch {
9202
+ }
9203
+ }
9204
+ setter.call(carrier, name, value);
9205
+ return;
9206
+ }
9207
+ const nodeSetter = carrier.setHeader;
9208
+ if (typeof nodeSetter === "function") {
9209
+ const remover = carrier.removeHeader;
9210
+ if (typeof remover === "function") {
9211
+ try {
9212
+ remover.call(carrier, name);
9213
+ } catch {
9214
+ }
9215
+ }
9216
+ nodeSetter.call(carrier, name, value);
9217
+ return;
9218
+ }
9219
+ const headerSetter = carrier.header;
9220
+ if (typeof headerSetter === "function") {
9221
+ const deleter = carrier.delete;
9222
+ if (typeof deleter === "function") {
9223
+ try {
9224
+ deleter.call(carrier, name);
9225
+ } catch {
9226
+ }
9227
+ }
9228
+ const remover = carrier.removeHeader;
9229
+ if (typeof remover === "function") {
9230
+ try {
9231
+ remover.call(carrier, name);
9232
+ } catch {
9233
+ }
9234
+ }
9235
+ headerSetter.call(carrier, name, value);
9236
+ return;
9237
+ }
9238
+ const headerBag = carrier;
9239
+ const lowered = name.toLowerCase();
9240
+ for (const key of Object.keys(headerBag)) {
9241
+ if (key !== name && key.toLowerCase() === lowered) {
9242
+ delete headerBag[key];
9243
+ }
9244
+ }
9245
+ headerBag[name] = value;
9246
+ }
9247
+ function deleteHeader(carrier, name) {
9248
+ const lowered = name.toLowerCase();
9249
+ if (isMutableHeaderTupleArray(carrier)) {
9250
+ for (let i = carrier.length - 1; i >= 0; i--) {
9251
+ if (carrier[i][0].toLowerCase() === lowered) {
9252
+ carrier.splice(i, 1);
9253
+ }
9254
+ }
9255
+ return;
9256
+ }
9257
+ const deleter = carrier.delete;
9258
+ if (typeof deleter === "function") {
9259
+ try {
9260
+ deleter.call(carrier, name);
9261
+ return;
9262
+ } catch {
9263
+ }
9264
+ }
9265
+ const remover = carrier.removeHeader;
9266
+ if (typeof remover === "function") {
9267
+ try {
9268
+ remover.call(carrier, name);
9269
+ return;
9270
+ } catch {
9271
+ }
9272
+ }
9273
+ const headerBag = carrier;
9274
+ for (const key of Object.keys(headerBag)) {
9275
+ if (key.toLowerCase() === lowered) {
9276
+ delete headerBag[key];
9277
+ }
9278
+ }
9279
+ }
9280
+ function _injectIntoCarrier(carrier, args) {
9281
+ const traceFlags = args.propagatedState?.traceFlags;
9282
+ const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
9283
+ if (traceparent === void 0) {
9284
+ return;
9285
+ }
9286
+ setHeader(carrier, TRACEPARENT_HEADER, traceparent);
9287
+ const tracestate = args.propagatedState?.tracestate;
9288
+ if (tracestate) {
9289
+ setHeader(carrier, TRACESTATE_HEADER, tracestate);
9290
+ }
9291
+ const existing = getHeader(carrier, BAGGAGE_HEADER);
9292
+ const baggageValue = mergeBaggage(existing, args.braintrustParent);
9293
+ if (baggageValue !== void 0) {
9294
+ setHeader(carrier, BAGGAGE_HEADER, baggageValue);
9295
+ } else if (existing !== void 0) {
9296
+ deleteHeader(carrier, BAGGAGE_HEADER);
9297
+ }
9298
+ }
9299
+ function resolveW3cParent(context2, state) {
9300
+ const traceparent = getHeader(context2, TRACEPARENT_HEADER);
9301
+ const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
9302
+ if (parsed === void 0) {
9303
+ return { parentSlug: void 0, propagatedState: void 0 };
9304
+ }
9305
+ const { traceId, spanId, traceFlags } = parsed;
9306
+ let braintrustParent = void 0;
9307
+ const baggageValue = getHeader(context2, BAGGAGE_HEADER);
9308
+ if (baggageValue) {
9309
+ braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
9310
+ }
9311
+ if (!braintrustParent) {
9312
+ braintrustParent = currentBraintrustParent(state);
9313
+ }
9314
+ if (!braintrustParent) {
9315
+ debugLogger.warn(
9316
+ "Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
9317
+ );
9318
+ return { parentSlug: void 0, propagatedState: void 0 };
9319
+ }
9320
+ const parsedParent = braintrustParentToComponents(braintrustParent);
9321
+ if (parsedParent === void 0) {
9322
+ debugLogger.warn(
9323
+ `Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
9324
+ );
9325
+ return { parentSlug: void 0, propagatedState: void 0 };
9326
+ }
9327
+ const { objectType, objectId, computeArgs } = parsedParent;
9328
+ const tracestate = getHeader(context2, TRACESTATE_HEADER);
9329
+ const slug = new SpanComponentsV4({
9330
+ object_type: objectType,
9331
+ ...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
9332
+ row_id: "bt-propagation",
9333
+ // non-empty to enable span_id/root_span_id
9334
+ span_id: spanId,
9335
+ root_span_id: traceId
9336
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
9337
+ }).toStr();
9338
+ return {
9339
+ parentSlug: slug,
9340
+ propagatedState: { tracestate, traceFlags, braintrustParent }
9341
+ };
9342
+ }
9343
+ function normalizeParent(parent, state) {
9344
+ if (parent && typeof parent === "object") {
9345
+ return resolveW3cParent(parent, state);
9346
+ }
9347
+ return {
9348
+ parentSlug: parent ?? void 0,
9349
+ propagatedState: void 0
9350
+ };
9351
+ }
9352
+ function parentSpanIdsUsable(spanId, rootSpanId) {
9353
+ return Boolean(spanId) && Boolean(rootSpanId);
8648
9354
  }
8649
9355
  function logError(span, error2) {
8650
9356
  let errorMessage = "<error>";
@@ -8696,19 +9402,23 @@ async function flush(options) {
8696
9402
  }
8697
9403
  function startSpanAndIsLogger(args) {
8698
9404
  const state = args?.state ?? _globalState;
8699
- const parentObject = getSpanParentObject({
9405
+ const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
8700
9406
  asyncFlush: args?.asyncFlush,
8701
9407
  parent: args?.parent,
8702
9408
  state
8703
9409
  });
8704
9410
  if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
8705
- const parentSpanIds = parentObject.data.row_id ? {
9411
+ const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
9412
+ parentObject.data.span_id,
9413
+ parentObject.data.root_span_id
9414
+ ) ? {
8706
9415
  spanId: parentObject.data.span_id,
8707
9416
  rootSpanId: parentObject.data.root_span_id
8708
9417
  } : void 0;
9418
+ const { parent: _ignoredParent, ...spanArgs } = args ?? {};
8709
9419
  const span = new SpanImpl({
8710
9420
  state,
8711
- ...args,
9421
+ ...spanArgs,
8712
9422
  parentObjectType: parentObject.data.object_type,
8713
9423
  parentObjectId: new LazyValue(
8714
9424
  spanComponentsToObjectIdLambda(state, parentObject)
@@ -8716,7 +9426,8 @@ function startSpanAndIsLogger(args) {
8716
9426
  parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
8717
9427
  parentSpanIds,
8718
9428
  propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8719
- (parentObject.data.propagated_event ?? void 0)
9429
+ (parentObject.data.propagated_event ?? void 0),
9430
+ propagatedState
8720
9431
  });
8721
9432
  return {
8722
9433
  span,
@@ -8959,11 +9670,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
8959
9670
  var DEFAULT_FETCH_BATCH_SIZE = 1e3;
8960
9671
  var MAX_BTQL_ITERATIONS = 1e4;
8961
9672
  var ObjectFetcher = class {
8962
- constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
9673
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
8963
9674
  this.objectType = objectType;
8964
9675
  this.pinnedVersion = pinnedVersion;
8965
9676
  this.mutateRecord = mutateRecord;
8966
9677
  this._internal_btql = _internal_btql;
9678
+ this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
8967
9679
  }
8968
9680
  _fetchedData = void 0;
8969
9681
  get id() {
@@ -9022,7 +9734,7 @@ var ObjectFetcher = class {
9022
9734
  ...internalBtqlWithoutReservedQueryKeys
9023
9735
  },
9024
9736
  use_columnstore: false,
9025
- brainstore_realtime: true,
9737
+ brainstore_realtime: this._internalBrainstoreRealtime,
9026
9738
  query_source: `js_sdk_object_fetcher_${this.objectType}`,
9027
9739
  ...this.pinnedVersion !== void 0 ? {
9028
9740
  version: this.pinnedVersion
@@ -9371,6 +10083,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
9371
10083
  object_id: await this.id
9372
10084
  }).toStr();
9373
10085
  }
10086
+ /**
10087
+ * Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
10088
+ * the `braintrust.parent` baggage entry, or undefined when it cannot be
10089
+ * determined synchronously.
10090
+ */
10091
+ _getOtelParent() {
10092
+ const id = this.lazyId.getSync().value;
10093
+ return id ? `experiment_id:${id}` : void 0;
10094
+ }
9374
10095
  /**
9375
10096
  * Flush any pending rows to the server.
9376
10097
  */
@@ -9413,7 +10134,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9413
10134
  async *asDataset(options) {
9414
10135
  const records = this.fetch(options);
9415
10136
  for await (const record of records) {
9416
- if (record.root_span_id !== record.span_id) {
10137
+ const isRoot = record.is_root ?? record.root_span_id === record.span_id;
10138
+ if (!isRoot) {
9417
10139
  continue;
9418
10140
  }
9419
10141
  const { output, expected: expectedRecord, metadata } = record;
@@ -9475,9 +10197,16 @@ var SpanImpl = class _SpanImpl {
9475
10197
  _spanId;
9476
10198
  _rootSpanId;
9477
10199
  _spanParents;
10200
+ // Inbound W3C trace-context state (tracestate + raw traceparent flags) to
10201
+ // forward on outbound propagation. Captured at the span that received it (via
10202
+ // extractTraceContextFromHeaders) and inherited by all subspans, so that any
10203
+ // inject() within the trace re-emits the upstream state unchanged, per the W3C
10204
+ // Trace Context spec. Not interpreted.
10205
+ _propagatedState;
9478
10206
  kind = "span";
9479
10207
  constructor(args) {
9480
10208
  this._state = args.state;
10209
+ this._propagatedState = args.propagatedState;
9481
10210
  const spanAttributes = args.spanAttributes ?? {};
9482
10211
  const rawEvent = args.event ?? {};
9483
10212
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -9528,7 +10257,7 @@ var SpanImpl = class _SpanImpl {
9528
10257
  this._spanId = resolvedIds.spanId;
9529
10258
  this._rootSpanId = resolvedIds.rootSpanId;
9530
10259
  this._spanParents = resolvedIds.spanParents;
9531
- this.isMerge = false;
10260
+ this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
9532
10261
  this.logInternal({ event, internalData });
9533
10262
  this.isMerge = true;
9534
10263
  }
@@ -9593,7 +10322,7 @@ var SpanImpl = class _SpanImpl {
9593
10322
  tags: partialRecord.tags,
9594
10323
  span_id: this._spanId,
9595
10324
  span_parents: this._spanParents,
9596
- is_root: this._spanId === this._rootSpanId,
10325
+ is_root: !this._spanParents || this._spanParents.length === 0,
9597
10326
  span_attributes: partialRecord.span_attributes
9598
10327
  };
9599
10328
  this._state.spanCache.queueWrite(
@@ -9655,7 +10384,8 @@ var SpanImpl = class _SpanImpl {
9655
10384
  parentObjectId: this.parentObjectId,
9656
10385
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
9657
10386
  parentSpanIds,
9658
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
10387
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
10388
+ propagatedState: this._propagatedState
9659
10389
  })
9660
10390
  });
9661
10391
  }
@@ -9674,7 +10404,8 @@ var SpanImpl = class _SpanImpl {
9674
10404
  parentObjectId: this.parentObjectId,
9675
10405
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
9676
10406
  parentSpanIds,
9677
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
10407
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
10408
+ propagatedState: this._propagatedState
9678
10409
  }),
9679
10410
  spanId
9680
10411
  });
@@ -9702,6 +10433,42 @@ var SpanImpl = class _SpanImpl {
9702
10433
  propagated_event: this.propagatedEvent
9703
10434
  }).toStr();
9704
10435
  }
10436
+ /**
10437
+ * Return this span's Braintrust parent string (`project_id:<id>`,
10438
+ * `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
10439
+ * baggage entry, or undefined when it cannot be determined synchronously.
10440
+ */
10441
+ _getOtelParent() {
10442
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
10443
+ const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
10444
+ const name = this.parentComputeObjectMetadataArgs?.project_name;
10445
+ if (id) {
10446
+ return `project_id:${id}`;
10447
+ } else if (name) {
10448
+ return `project_name:${name}`;
10449
+ }
10450
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
10451
+ const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
10452
+ if (id) {
10453
+ return `experiment_id:${id}`;
10454
+ }
10455
+ }
10456
+ return void 0;
10457
+ }
10458
+ inject(carrier) {
10459
+ const resolvedCarrier = carrier ?? {};
10460
+ try {
10461
+ _injectIntoCarrier(resolvedCarrier, {
10462
+ traceId: this._rootSpanId,
10463
+ spanId: this._spanId,
10464
+ braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
10465
+ propagatedState: this._propagatedState
10466
+ });
10467
+ } catch (e) {
10468
+ debugLogger.warn(`Error injecting trace context: ${e}`);
10469
+ }
10470
+ return resolvedCarrier;
10471
+ }
9705
10472
  async permalink() {
9706
10473
  return await permalink(await this.export(), {
9707
10474
  state: this._state
@@ -9837,6 +10604,7 @@ var Dataset2 = class extends ObjectFetcher {
9837
10604
  _internal_btql
9838
10605
  );
9839
10606
  this.state = state;
10607
+ void this.__braintrust_dataset_marker;
9840
10608
  this.lazyMetadata = lazyMetadata;
9841
10609
  this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
9842
10610
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
@@ -10351,6 +11119,7 @@ var Prompt2 = class _Prompt {
10351
11119
  this.metadata = metadata;
10352
11120
  this.defaults = defaults;
10353
11121
  this.noTrace = noTrace;
11122
+ void this.__braintrust_prompt_marker;
10354
11123
  }
10355
11124
  parsedPromptData;
10356
11125
  hasParsedPromptData = false;
@@ -10587,6 +11356,7 @@ var Prompt2 = class _Prompt {
10587
11356
  var RemoteEvalParameters = class {
10588
11357
  constructor(metadata) {
10589
11358
  this.metadata = metadata;
11359
+ void this.__braintrust_parameters_marker;
10590
11360
  }
10591
11361
  __braintrust_parameters_marker = true;
10592
11362
  get id() {
@@ -11812,15 +12582,21 @@ async function invoke(args) {
11812
12582
 
11813
12583
  // src/trace.ts
11814
12584
  var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
11815
- constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false) {
12585
+ constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true) {
11816
12586
  const filterExpr = _SpanFetcher.buildFilter(
11817
12587
  rootSpanId,
11818
12588
  spanTypeFilter,
11819
12589
  includeScorers
11820
12590
  );
11821
- super(objectType, void 0, void 0, {
11822
- filter: filterExpr
11823
- });
12591
+ super(
12592
+ objectType,
12593
+ void 0,
12594
+ void 0,
12595
+ {
12596
+ filter: filterExpr
12597
+ },
12598
+ brainstoreRealtime
12599
+ );
11824
12600
  this._objectId = _objectId;
11825
12601
  this.rootSpanId = rootSpanId;
11826
12602
  this._state = _state;
@@ -11874,7 +12650,7 @@ var CachedSpanFetcher = class {
11874
12650
  spanCache = /* @__PURE__ */ new Map();
11875
12651
  allFetched = false;
11876
12652
  fetchFn;
11877
- constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {
12653
+ constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState, brainstoreRealtime = true) {
11878
12654
  if (typeof objectTypeOrFetchFn === "function") {
11879
12655
  this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
11880
12656
  } else {
@@ -11887,7 +12663,8 @@ var CachedSpanFetcher = class {
11887
12663
  rootSpanId,
11888
12664
  state,
11889
12665
  spanType,
11890
- includeScorers
12666
+ includeScorers,
12667
+ brainstoreRealtime
11891
12668
  );
11892
12669
  const rows = await fetcher.fetchedData();
11893
12670
  return rows.map((row) => ({
@@ -12708,7 +13485,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
12708
13485
  }
12709
13486
  };
12710
13487
  const parentStr = state.currentParent.getStore();
12711
- const parentComponents = parentStr ? SpanComponentsV3.fromStr(parentStr) : null;
13488
+ const parentComponents = typeof parentStr === "string" ? SpanComponentsV4.fromStr(parentStr) : null;
12712
13489
  const trace = state ? new LocalTrace({
12713
13490
  objectType: parentComponents ? spanObjectTypeV3ToTypedString(
12714
13491
  parentComponents.data.object_type
@@ -14539,6 +15316,22 @@ function runStreamingCompletionHook(args) {
14539
15316
  );
14540
15317
  }
14541
15318
  }
15319
+ function runStreamingErrorHook(args) {
15320
+ if (!args.config.onError) {
15321
+ return;
15322
+ }
15323
+ try {
15324
+ args.config.onError({
15325
+ channelName: args.channelName,
15326
+ error: args.error,
15327
+ event: args.event,
15328
+ span: args.span,
15329
+ startTime: args.startTime
15330
+ });
15331
+ } catch (error2) {
15332
+ debugLogger.error(`Error in onError hook for ${args.channelName}:`, error2);
15333
+ }
15334
+ }
14542
15335
  function traceAsyncChannel(channel2, config3) {
14543
15336
  const tracingChannel2 = channel2.tracingChannel();
14544
15337
  const states = /* @__PURE__ */ new WeakMap();
@@ -14700,6 +15493,14 @@ function traceStreamingChannel(channel2, config3) {
14700
15493
  }
14701
15494
  },
14702
15495
  onError: (error2) => {
15496
+ runStreamingErrorHook({
15497
+ channelName,
15498
+ config: config3,
15499
+ error: error2,
15500
+ event: asyncEndEvent,
15501
+ span,
15502
+ startTime
15503
+ });
14703
15504
  span.log({
14704
15505
  error: error2.message
14705
15506
  });
@@ -14757,6 +15558,17 @@ function traceStreamingChannel(channel2, config3) {
14757
15558
  }
14758
15559
  },
14759
15560
  error: (event) => {
15561
+ const spanData = states.get(event);
15562
+ if (spanData) {
15563
+ runStreamingErrorHook({
15564
+ channelName,
15565
+ config: config3,
15566
+ error: event.error,
15567
+ event,
15568
+ span: spanData.span,
15569
+ startTime: spanData.startTime
15570
+ });
15571
+ }
14760
15572
  logErrorAndEnd(states, event);
14761
15573
  }
14762
15574
  };
@@ -17119,14 +17931,45 @@ function serializeAISDKToolsForLogging(tools) {
17119
17931
  return serialized;
17120
17932
  }
17121
17933
 
17934
+ // src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
17935
+ var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
17936
+ "braintrust.ai-sdk.v7.telemetry-operation-key"
17937
+ );
17938
+
17939
+ // src/wrappers/ai-sdk/workflow-agent-context.ts
17940
+ var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
17941
+ function registerWorkflowAgentWrapperSpan(span) {
17942
+ if (span.spanId) {
17943
+ workflowAgentWrapperSpans.set(span.spanId, span);
17944
+ }
17945
+ }
17946
+ function unregisterWorkflowAgentWrapperSpan(span) {
17947
+ if (span.spanId) {
17948
+ workflowAgentWrapperSpans.delete(span.spanId);
17949
+ }
17950
+ }
17951
+ function currentWorkflowAgentWrapperSpan() {
17952
+ const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
17953
+ for (const parentSpanId of parentSpanIds) {
17954
+ const span = workflowAgentWrapperSpans.get(parentSpanId);
17955
+ if (span) {
17956
+ return span;
17957
+ }
17958
+ }
17959
+ return void 0;
17960
+ }
17961
+
17122
17962
  // src/wrappers/ai-sdk/telemetry.ts
17123
17963
  function braintrustAISDKTelemetry() {
17124
17964
  const operations = /* @__PURE__ */ new Map();
17965
+ const operationKeysByCallId = /* @__PURE__ */ new Map();
17966
+ const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
17125
17967
  const modelSpans = /* @__PURE__ */ new Map();
17126
17968
  const objectSpans = /* @__PURE__ */ new Map();
17127
17969
  const embedSpans = /* @__PURE__ */ new Map();
17128
17970
  const rerankSpans = /* @__PURE__ */ new Map();
17129
17971
  const toolSpans = /* @__PURE__ */ new Map();
17972
+ let workflowAgentOperationCounter = 0;
17130
17973
  const runSafely = (name, callback) => {
17131
17974
  try {
17132
17975
  callback();
@@ -17134,42 +17977,333 @@ function braintrustAISDKTelemetry() {
17134
17977
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error2);
17135
17978
  }
17136
17979
  };
17137
- const startChildSpan = (callId, name, type, event) => {
17138
- const parent = operations.get(callId)?.span;
17980
+ const startChildSpan = (operationKey, name, type, event) => {
17981
+ const parent = operations.get(operationKey)?.span;
17139
17982
  const spanArgs = {
17140
17983
  name,
17141
17984
  spanAttributes: { type },
17142
17985
  ...event ? { event } : {}
17143
17986
  };
17144
17987
  const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
17145
- const state = operations.get(callId);
17988
+ const state = operations.get(operationKey);
17146
17989
  if (state && type === "llm" /* LLM */) {
17147
17990
  state.hadModelChild = true;
17148
17991
  }
17149
17992
  return span;
17150
17993
  };
17994
+ const registerOperation = (state) => {
17995
+ operations.set(state.operationKey, state);
17996
+ const keys = operationKeysByCallId.get(state.callId) ?? [];
17997
+ keys.push(state.operationKey);
17998
+ operationKeysByCallId.set(state.callId, keys);
17999
+ };
18000
+ const deleteOperation = (operationKey) => {
18001
+ const state = operations.get(operationKey);
18002
+ if (!state) {
18003
+ return;
18004
+ }
18005
+ operations.delete(operationKey);
18006
+ if (workflowOperationKeyStore.getStore() === operationKey) {
18007
+ workflowOperationKeyStore.enterWith(void 0);
18008
+ }
18009
+ const keys = operationKeysByCallId.get(state.callId);
18010
+ if (!keys) {
18011
+ return;
18012
+ }
18013
+ const index = keys.indexOf(operationKey);
18014
+ if (index >= 0) {
18015
+ keys.splice(index, 1);
18016
+ }
18017
+ if (keys.length === 0) {
18018
+ operationKeysByCallId.delete(state.callId);
18019
+ }
18020
+ };
18021
+ const explicitOperationKey = (event) => {
18022
+ if (!isObject(event)) {
18023
+ return void 0;
18024
+ }
18025
+ const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
18026
+ return typeof key === "string" ? key : void 0;
18027
+ };
18028
+ const createOperationKey = (event, operationName) => {
18029
+ const explicit = explicitOperationKey(event);
18030
+ if (explicit) {
18031
+ return explicit;
18032
+ }
18033
+ if (operationName === "WorkflowAgent.stream") {
18034
+ workflowAgentOperationCounter += 1;
18035
+ return `${event.callId}:${workflowAgentOperationCounter}`;
18036
+ }
18037
+ return event.callId;
18038
+ };
18039
+ const operationKeyForCallId = (callId, mode = "active") => {
18040
+ const keys = operationKeysByCallId.get(callId);
18041
+ if (!keys || keys.length === 0) {
18042
+ return operations.has(callId) ? callId : void 0;
18043
+ }
18044
+ if (keys.length === 1) {
18045
+ return keys[0];
18046
+ }
18047
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
18048
+ if (wrapperSpan?.spanId) {
18049
+ const key = keys.find(
18050
+ (candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
18051
+ );
18052
+ if (key) {
18053
+ return key;
18054
+ }
18055
+ }
18056
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
18057
+ if (workflowOperationKey && keys.includes(workflowOperationKey)) {
18058
+ return workflowOperationKey;
18059
+ }
18060
+ if (callId === "workflow-agent") {
18061
+ return void 0;
18062
+ }
18063
+ return mode === "finish" ? keys[0] : keys[keys.length - 1];
18064
+ };
18065
+ const operationKeyFromEvent = (event, mode = "active") => {
18066
+ const explicit = explicitOperationKey(event);
18067
+ if (explicit && operations.has(explicit)) {
18068
+ return explicit;
18069
+ }
18070
+ if (isObject(event)) {
18071
+ const callId = event.callId;
18072
+ if (typeof callId === "string") {
18073
+ const operationKey = operationKeyForCallId(callId, mode);
18074
+ if (operationKey) {
18075
+ return operationKey;
18076
+ }
18077
+ const workflowOperationKey2 = workflowOperationKeyStore.getStore();
18078
+ if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
18079
+ return workflowOperationKey2;
18080
+ }
18081
+ return callId === "workflow-agent" ? void 0 : callId;
18082
+ }
18083
+ }
18084
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
18085
+ if (workflowOperationKey && operations.has(workflowOperationKey)) {
18086
+ return workflowOperationKey;
18087
+ }
18088
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
18089
+ if (wrapperSpan?.spanId) {
18090
+ for (const [operationKey, state] of operations) {
18091
+ if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
18092
+ return operationKey;
18093
+ }
18094
+ }
18095
+ }
18096
+ const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
18097
+ if (workflowAgentKeys?.length === 1) {
18098
+ return workflowAgentKeys[0];
18099
+ }
18100
+ if (operations.size === 1) {
18101
+ return operations.keys().next().value;
18102
+ }
18103
+ return void 0;
18104
+ };
18105
+ const closeOpenChildSpans = (operationKey, error2) => {
18106
+ const openModelSpans = modelSpans.get(operationKey);
18107
+ if (openModelSpans) {
18108
+ for (const span of openModelSpans) {
18109
+ if (error2 !== void 0) {
18110
+ logError(span, error2);
18111
+ }
18112
+ span.end();
18113
+ }
18114
+ modelSpans.delete(operationKey);
18115
+ }
18116
+ const openObjectSpan = objectSpans.get(operationKey);
18117
+ if (openObjectSpan) {
18118
+ if (error2 !== void 0) {
18119
+ logError(openObjectSpan, error2);
18120
+ }
18121
+ openObjectSpan.end();
18122
+ objectSpans.delete(operationKey);
18123
+ }
18124
+ for (const [embedCallId, embedState] of embedSpans) {
18125
+ if (embedState.operationKey === operationKey) {
18126
+ if (error2 !== void 0) {
18127
+ logError(embedState.span, error2);
18128
+ }
18129
+ embedState.span.end();
18130
+ embedSpans.delete(embedCallId);
18131
+ }
18132
+ }
18133
+ const openRerankSpan = rerankSpans.get(operationKey);
18134
+ if (openRerankSpan) {
18135
+ if (error2 !== void 0) {
18136
+ logError(openRerankSpan, error2);
18137
+ }
18138
+ openRerankSpan.end();
18139
+ rerankSpans.delete(operationKey);
18140
+ }
18141
+ for (const [toolCallId, toolState] of toolSpans) {
18142
+ if (toolState.operationKey === operationKey) {
18143
+ if (error2 !== void 0) {
18144
+ logError(toolState.span, error2);
18145
+ }
18146
+ toolState.span.end();
18147
+ toolSpans.delete(toolCallId);
18148
+ }
18149
+ }
18150
+ };
18151
+ const abortReasonFromEvent = (event) => {
18152
+ if (isObject(event)) {
18153
+ const abortEvent = event;
18154
+ if (abortEvent.error !== void 0) {
18155
+ return abortEvent.error;
18156
+ }
18157
+ if (abortEvent.reason !== void 0) {
18158
+ return abortEvent.reason;
18159
+ }
18160
+ }
18161
+ return new Error("AI SDK operation aborted");
18162
+ };
18163
+ const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
18164
+ const onObjectStepEnd = (event) => {
18165
+ runSafely("onObjectStepEnd", () => {
18166
+ const operationKey = operationKeyFromEvent(event);
18167
+ const span = operationKey ? objectSpans.get(operationKey) : void 0;
18168
+ if (!operationKey || !span) {
18169
+ return;
18170
+ }
18171
+ const result = {
18172
+ ...event,
18173
+ text: event.objectText
18174
+ };
18175
+ span.log({
18176
+ ...shouldRecordOutputs(event) ? {
18177
+ output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
18178
+ } : {},
18179
+ metrics: extractTokenMetrics(result)
18180
+ });
18181
+ span.end();
18182
+ objectSpans.delete(operationKey);
18183
+ });
18184
+ };
18185
+ const onEmbedEnd = (event) => {
18186
+ runSafely("onEmbedEnd", () => {
18187
+ const state = embedSpans.get(event.embedCallId);
18188
+ if (!state) {
18189
+ return;
18190
+ }
18191
+ const result = {
18192
+ ...event,
18193
+ embeddings: event.embeddings
18194
+ };
18195
+ state.span.log({
18196
+ ...shouldRecordOutputs(event) ? {
18197
+ output: processAISDKEmbeddingOutput(
18198
+ result,
18199
+ DEFAULT_DENY_OUTPUT_PATHS
18200
+ )
18201
+ } : {},
18202
+ metrics: extractTokenMetrics(result)
18203
+ });
18204
+ state.span.end();
18205
+ embedSpans.delete(event.embedCallId);
18206
+ });
18207
+ };
18208
+ const onRerankEnd = (event) => {
18209
+ runSafely("onRerankEnd", () => {
18210
+ const operationKey = operationKeyFromEvent(event);
18211
+ const span = operationKey ? rerankSpans.get(operationKey) : void 0;
18212
+ if (!operationKey || !span) {
18213
+ return;
18214
+ }
18215
+ const result = {
18216
+ ranking: event.ranking?.map((entry) => ({
18217
+ originalIndex: entry.index,
18218
+ score: entry.relevanceScore
18219
+ }))
18220
+ };
18221
+ span.log({
18222
+ ...shouldRecordOutputs(event) ? {
18223
+ output: processAISDKRerankOutput(
18224
+ result,
18225
+ DEFAULT_DENY_OUTPUT_PATHS
18226
+ )
18227
+ } : {}
18228
+ });
18229
+ span.end();
18230
+ rerankSpans.delete(operationKey);
18231
+ });
18232
+ };
18233
+ const onEnd = (event) => {
18234
+ runSafely("onEnd", () => {
18235
+ const operationKey = operationKeyFromEvent(event, "finish");
18236
+ const state = operationKey ? operations.get(operationKey) : void 0;
18237
+ if (!state) {
18238
+ return;
18239
+ }
18240
+ if (!state.ownsSpan) {
18241
+ deleteOperation(state.operationKey);
18242
+ return;
18243
+ }
18244
+ const result = finishResult(event, state.operationName);
18245
+ const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
18246
+ const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
18247
+ if (timeToFirstToken !== void 0) {
18248
+ metrics.time_to_first_token = timeToFirstToken;
18249
+ }
18250
+ state.span.log({
18251
+ ...shouldRecordOutputs(event) ? {
18252
+ output: finishOutput(result, state.operationName)
18253
+ } : {},
18254
+ metrics
18255
+ });
18256
+ state.span.end();
18257
+ deleteOperation(state.operationKey);
18258
+ });
18259
+ };
17151
18260
  return {
17152
18261
  onStart(event) {
17153
18262
  runSafely("onStart", () => {
17154
18263
  const operationName = operationNameFromId(event.operationId);
17155
- const span = startSpan({
18264
+ const workflowAgent = operationName === "WorkflowAgent.stream";
18265
+ const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
18266
+ const ownsSpan = !wrapperSpan;
18267
+ const span = ownsSpan ? startSpan({
17156
18268
  name: operationName,
17157
18269
  spanAttributes: { type: "function" /* FUNCTION */ }
17158
- });
17159
- operations.set(event.callId, {
18270
+ }) : wrapperSpan;
18271
+ const operationKey = createOperationKey(event, operationName);
18272
+ registerOperation({
18273
+ callId: event.callId,
17160
18274
  hadModelChild: false,
18275
+ loggedInput: false,
17161
18276
  operationName,
18277
+ operationKey,
18278
+ ownsSpan,
17162
18279
  span,
17163
18280
  startTime: getCurrentUnixTimestamp()
17164
18281
  });
17165
- const metadata = metadataFromEvent(event);
18282
+ if (!ownsSpan) {
18283
+ return;
18284
+ }
18285
+ if (workflowAgent) {
18286
+ workflowOperationKeyStore.enterWith(operationKey);
18287
+ }
18288
+ let metadata = metadataFromEvent(event);
17166
18289
  const logPayload = { metadata };
18290
+ const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
18291
+ if (workflowAgentCallInput) {
18292
+ metadata = {
18293
+ ...metadata,
18294
+ ...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
18295
+ };
18296
+ logPayload.metadata = metadata;
18297
+ }
17167
18298
  if (shouldRecordInputs(event)) {
17168
- const { input, outputPromise } = processAISDKCallInput(
17169
- operationInput(event, operationName)
17170
- );
18299
+ const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
18300
+ const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
17171
18301
  logPayload.input = input;
17172
- if (outputPromise && input && typeof input === "object") {
18302
+ const state = operations.get(operationKey);
18303
+ if (state) {
18304
+ state.loggedInput = hasPromptLikeInput(input);
18305
+ }
18306
+ if (outputPromise && !workflowAgent && input && typeof input === "object") {
17173
18307
  outputPromise.then((resolvedData) => {
17174
18308
  span.log({
17175
18309
  input: {
@@ -17186,41 +18320,67 @@ function braintrustAISDKTelemetry() {
17186
18320
  },
17187
18321
  onLanguageModelCallStart(event) {
17188
18322
  runSafely("onLanguageModelCallStart", () => {
17189
- const state = operations.get(event.callId);
17190
- const openSpans = modelSpans.get(event.callId);
17191
- if (openSpans) {
18323
+ const operationKey = operationKeyFromEvent(event);
18324
+ const state = operationKey ? operations.get(operationKey) : void 0;
18325
+ if (shouldSkipTelemetryChildren(state)) {
18326
+ return;
18327
+ }
18328
+ const operationName = state?.operationName ?? "generateText";
18329
+ const callInput = operationInput(event, operationName);
18330
+ const workflowAgent = operationName === "WorkflowAgent.stream";
18331
+ const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
18332
+ if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
18333
+ state.span.log({
18334
+ input: processedInput,
18335
+ metadata: {
18336
+ ...metadataFromEvent(event),
18337
+ ...extractWorkflowMetadataFromCallParams(callInput)
18338
+ }
18339
+ });
18340
+ state.loggedInput = true;
18341
+ }
18342
+ const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
18343
+ if (operationKey && openSpans) {
17192
18344
  for (const span2 of openSpans) {
17193
18345
  span2.end();
17194
18346
  }
17195
- modelSpans.delete(event.callId);
18347
+ modelSpans.delete(operationKey);
17196
18348
  }
17197
18349
  const span = startChildSpan(
17198
- event.callId,
17199
- state?.operationName === "streamText" ? "doStream" : "doGenerate",
18350
+ operationKey ?? event.callId,
18351
+ operationName === "streamText" ? "doStream" : "doGenerate",
17200
18352
  "llm" /* LLM */,
17201
18353
  {
17202
18354
  ...shouldRecordInputs(event) ? {
17203
- input: processAISDKCallInput(
17204
- operationInput(
17205
- event,
17206
- state?.operationName ?? "generateText"
17207
- )
17208
- ).input
18355
+ input: processedInput
17209
18356
  } : {},
17210
- metadata: metadataFromEvent(event)
18357
+ metadata: workflowAgent ? {
18358
+ ...metadataFromEvent(event),
18359
+ ...extractWorkflowMetadataFromCallParams(callInput)
18360
+ } : metadataFromEvent(event)
17211
18361
  }
17212
18362
  );
17213
- const spans = modelSpans.get(event.callId) ?? [];
18363
+ const spanKey = operationKey ?? event.callId;
18364
+ const spans = modelSpans.get(spanKey) ?? [];
17214
18365
  spans.push(span);
17215
- modelSpans.set(event.callId, spans);
18366
+ modelSpans.set(spanKey, spans);
17216
18367
  });
17217
18368
  },
17218
18369
  onLanguageModelCallEnd(event) {
17219
18370
  runSafely("onLanguageModelCallEnd", () => {
17220
- const span = shiftModelSpan(modelSpans, event.callId);
18371
+ const operationKey = operationKeyFromEvent(event);
18372
+ const state = operationKey ? operations.get(operationKey) : void 0;
18373
+ if (shouldSkipTelemetryChildren(state)) {
18374
+ return;
18375
+ }
18376
+ const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
17221
18377
  if (!span) {
17222
18378
  return;
17223
18379
  }
18380
+ const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
18381
+ if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
18382
+ state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
18383
+ }
17224
18384
  const result = {
17225
18385
  ...event,
17226
18386
  response: event.responseId ? { id: event.responseId } : void 0
@@ -17236,14 +18396,18 @@ function braintrustAISDKTelemetry() {
17236
18396
  },
17237
18397
  onObjectStepStart(event) {
17238
18398
  runSafely("onObjectStepStart", () => {
17239
- const state = operations.get(event.callId);
17240
- const openSpan = objectSpans.get(event.callId);
17241
- if (openSpan) {
18399
+ const operationKey = operationKeyFromEvent(event);
18400
+ const state = operationKey ? operations.get(operationKey) : void 0;
18401
+ if (shouldSkipTelemetryChildren(state)) {
18402
+ return;
18403
+ }
18404
+ const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
18405
+ if (operationKey && openSpan) {
17242
18406
  openSpan.end();
17243
- objectSpans.delete(event.callId);
18407
+ objectSpans.delete(operationKey);
17244
18408
  }
17245
18409
  const span = startChildSpan(
17246
- event.callId,
18410
+ operationKey ?? event.callId,
17247
18411
  state?.operationName === "streamObject" ? "doStream" : "doGenerate",
17248
18412
  "llm" /* LLM */,
17249
18413
  {
@@ -17255,40 +18419,25 @@ function braintrustAISDKTelemetry() {
17255
18419
  metadata: metadataFromEvent(event)
17256
18420
  }
17257
18421
  );
17258
- objectSpans.set(event.callId, span);
17259
- });
17260
- },
17261
- onObjectStepFinish(event) {
17262
- runSafely("onObjectStepFinish", () => {
17263
- const span = objectSpans.get(event.callId);
17264
- if (!span) {
17265
- return;
17266
- }
17267
- const result = {
17268
- ...event,
17269
- text: event.objectText
17270
- };
17271
- span.log({
17272
- ...shouldRecordOutputs(event) ? {
17273
- output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
17274
- } : {},
17275
- metrics: extractTokenMetrics(result)
17276
- });
17277
- span.end();
17278
- objectSpans.delete(event.callId);
18422
+ objectSpans.set(operationKey ?? event.callId, span);
17279
18423
  });
17280
18424
  },
18425
+ onObjectStepEnd,
17281
18426
  onEmbedStart(event) {
17282
18427
  runSafely("onEmbedStart", () => {
17283
- const state = operations.get(event.callId);
18428
+ const operationKey = operationKeyFromEvent(event);
18429
+ const state = operationKey ? operations.get(operationKey) : void 0;
18430
+ if (shouldSkipTelemetryChildren(state)) {
18431
+ return;
18432
+ }
17284
18433
  for (const [embedCallId, embedState] of embedSpans) {
17285
- if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
18434
+ if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
17286
18435
  embedState.span.end();
17287
18436
  embedSpans.delete(embedCallId);
17288
18437
  }
17289
18438
  }
17290
18439
  const span = startChildSpan(
17291
- event.callId,
18440
+ operationKey ?? event.callId,
17292
18441
  "doEmbed",
17293
18442
  "llm" /* LLM */,
17294
18443
  {
@@ -17301,44 +18450,27 @@ function braintrustAISDKTelemetry() {
17301
18450
  }
17302
18451
  );
17303
18452
  embedSpans.set(event.embedCallId, {
17304
- callId: event.callId,
18453
+ operationKey: operationKey ?? event.callId,
17305
18454
  span,
17306
18455
  values: event.values
17307
18456
  });
17308
18457
  });
17309
18458
  },
17310
- onEmbedFinish(event) {
17311
- runSafely("onEmbedFinish", () => {
17312
- const state = embedSpans.get(event.embedCallId);
17313
- if (!state) {
17314
- return;
17315
- }
17316
- const result = {
17317
- ...event,
17318
- embeddings: event.embeddings
17319
- };
17320
- state.span.log({
17321
- ...shouldRecordOutputs(event) ? {
17322
- output: processAISDKEmbeddingOutput(
17323
- result,
17324
- DEFAULT_DENY_OUTPUT_PATHS
17325
- )
17326
- } : {},
17327
- metrics: extractTokenMetrics(result)
17328
- });
17329
- state.span.end();
17330
- embedSpans.delete(event.embedCallId);
17331
- });
17332
- },
18459
+ onEmbedEnd,
17333
18460
  onRerankStart(event) {
17334
18461
  runSafely("onRerankStart", () => {
17335
- const openSpan = rerankSpans.get(event.callId);
17336
- if (openSpan) {
18462
+ const operationKey = operationKeyFromEvent(event);
18463
+ const state = operationKey ? operations.get(operationKey) : void 0;
18464
+ if (shouldSkipTelemetryChildren(state)) {
18465
+ return;
18466
+ }
18467
+ const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
18468
+ if (operationKey && openSpan) {
17337
18469
  openSpan.end();
17338
- rerankSpans.delete(event.callId);
18470
+ rerankSpans.delete(operationKey);
17339
18471
  }
17340
18472
  const span = startChildSpan(
17341
- event.callId,
18473
+ operationKey ?? event.callId,
17342
18474
  "doRerank",
17343
18475
  "llm" /* LLM */,
17344
18476
  {
@@ -17352,41 +18484,23 @@ function braintrustAISDKTelemetry() {
17352
18484
  metadata: metadataFromEvent(event)
17353
18485
  }
17354
18486
  );
17355
- rerankSpans.set(event.callId, span);
17356
- });
17357
- },
17358
- onRerankFinish(event) {
17359
- runSafely("onRerankFinish", () => {
17360
- const span = rerankSpans.get(event.callId);
17361
- if (!span) {
17362
- return;
17363
- }
17364
- const result = {
17365
- ranking: event.ranking?.map((entry) => ({
17366
- originalIndex: entry.index,
17367
- score: entry.relevanceScore
17368
- }))
17369
- };
17370
- span.log({
17371
- ...shouldRecordOutputs(event) ? {
17372
- output: processAISDKRerankOutput(
17373
- result,
17374
- DEFAULT_DENY_OUTPUT_PATHS
17375
- )
17376
- } : {}
17377
- });
17378
- span.end();
17379
- rerankSpans.delete(event.callId);
18487
+ rerankSpans.set(operationKey ?? event.callId, span);
17380
18488
  });
17381
18489
  },
18490
+ onRerankEnd,
17382
18491
  onToolExecutionStart(event) {
17383
18492
  runSafely("onToolExecutionStart", () => {
18493
+ const operationKey = operationKeyFromEvent(event);
18494
+ const state = operationKey ? operations.get(operationKey) : void 0;
18495
+ if (shouldSkipTelemetryChildren(state)) {
18496
+ return;
18497
+ }
17384
18498
  const toolCallId = event.toolCall.toolCallId;
17385
- if (!toolCallId) {
18499
+ if (!operationKey || !toolCallId) {
17386
18500
  return;
17387
18501
  }
17388
18502
  const span = startChildSpan(
17389
- event.callId,
18503
+ operationKey,
17390
18504
  event.toolCall.toolName || "tool",
17391
18505
  "tool" /* TOOL */,
17392
18506
  {
@@ -17400,7 +18514,7 @@ function braintrustAISDKTelemetry() {
17400
18514
  }
17401
18515
  }
17402
18516
  );
17403
- toolSpans.set(toolCallId, { callId: event.callId, span });
18517
+ toolSpans.set(toolCallId, { operationKey, span });
17404
18518
  });
17405
18519
  },
17406
18520
  onToolExecutionEnd(event) {
@@ -17411,14 +18525,17 @@ function braintrustAISDKTelemetry() {
17411
18525
  return;
17412
18526
  }
17413
18527
  const toolOutput = event.toolOutput;
17414
- if (toolOutput?.type === "tool-error") {
18528
+ const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
18529
+ if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
18530
+ const error2 = toolOutput?.error ?? workflowToolError;
17415
18531
  state.span.log({
17416
- error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
18532
+ error: error2 instanceof Error ? error2.message : String(error2),
17417
18533
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
17418
18534
  });
17419
18535
  } else {
18536
+ const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
17420
18537
  state.span.log({
17421
- ...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
18538
+ ...shouldRecordOutputs(event) ? { output } : {},
17422
18539
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
17423
18540
  });
17424
18541
  }
@@ -17432,83 +18549,46 @@ function braintrustAISDKTelemetry() {
17432
18549
  if (!callId) {
17433
18550
  return;
17434
18551
  }
17435
- const state = operations.get(callId);
18552
+ const operationKey = operationKeyForCallId(callId);
18553
+ const state = operationKey ? operations.get(operationKey) : void 0;
17436
18554
  if (!state || state.firstChunkTime !== void 0) {
17437
18555
  return;
17438
18556
  }
17439
18557
  state.firstChunkTime = getCurrentUnixTimestamp();
17440
18558
  });
17441
18559
  },
17442
- onFinish(event) {
17443
- runSafely("onFinish", () => {
17444
- const state = operations.get(event.callId);
17445
- if (!state) {
18560
+ onEnd,
18561
+ onAbort(event) {
18562
+ runSafely("onAbort", () => {
18563
+ const operationKey = operationKeyFromEvent(event, "finish");
18564
+ const state = operationKey ? operations.get(operationKey) : void 0;
18565
+ if (!operationKey || !state) {
17446
18566
  return;
17447
18567
  }
17448
- const result = finishResult(event, state.operationName);
17449
- const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
17450
- if (state.firstChunkTime !== void 0) {
17451
- metrics.time_to_first_token = state.firstChunkTime - state.startTime;
18568
+ const error2 = abortReasonFromEvent(event);
18569
+ closeOpenChildSpans(operationKey, error2);
18570
+ if (state.ownsSpan) {
18571
+ logError(state.span, error2);
18572
+ state.span.end();
17452
18573
  }
17453
- state.span.log({
17454
- ...shouldRecordOutputs(event) ? {
17455
- output: finishOutput(result, state.operationName)
17456
- } : {},
17457
- metrics
17458
- });
17459
- state.span.end();
17460
- operations.delete(event.callId);
18574
+ deleteOperation(operationKey);
17461
18575
  });
17462
18576
  },
17463
18577
  onError(event) {
17464
18578
  runSafely("onError", () => {
17465
18579
  const errorEvent = isObject(event) ? event : {};
17466
- const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
17467
- if (!callId) {
17468
- return;
17469
- }
17470
- const state = operations.get(callId);
17471
- if (!state) {
18580
+ const operationKey = operationKeyFromEvent(errorEvent, "finish");
18581
+ const state = operationKey ? operations.get(operationKey) : void 0;
18582
+ if (!operationKey || !state) {
17472
18583
  return;
17473
18584
  }
17474
18585
  const error2 = errorEvent.error ?? event;
17475
- const openModelSpans = modelSpans.get(callId);
17476
- if (openModelSpans) {
17477
- for (const span of openModelSpans) {
17478
- logError(span, error2);
17479
- span.end();
17480
- }
17481
- modelSpans.delete(callId);
17482
- }
17483
- const openObjectSpan = objectSpans.get(callId);
17484
- if (openObjectSpan) {
17485
- logError(openObjectSpan, error2);
17486
- openObjectSpan.end();
17487
- objectSpans.delete(callId);
17488
- }
17489
- for (const [embedCallId, embedState] of embedSpans) {
17490
- if (embedState.callId === callId) {
17491
- logError(embedState.span, error2);
17492
- embedState.span.end();
17493
- embedSpans.delete(embedCallId);
17494
- }
17495
- }
17496
- const openRerankSpan = rerankSpans.get(callId);
17497
- if (openRerankSpan) {
17498
- logError(openRerankSpan, error2);
17499
- openRerankSpan.end();
17500
- rerankSpans.delete(callId);
17501
- }
17502
- for (const [toolCallId, toolState] of toolSpans) {
17503
- if (toolState.callId === callId) {
17504
- logError(toolState.span, error2);
17505
- toolState.span.end();
17506
- toolSpans.delete(toolCallId);
17507
- }
18586
+ closeOpenChildSpans(operationKey, error2);
18587
+ if (state.ownsSpan) {
18588
+ logError(state.span, error2);
18589
+ state.span.end();
17508
18590
  }
17509
- logError(state.span, error2);
17510
- state.span.end();
17511
- operations.delete(callId);
18591
+ deleteOperation(operationKey);
17512
18592
  });
17513
18593
  },
17514
18594
  executeTool({ toolCallId, execute }) {
@@ -17523,7 +18603,16 @@ function shouldRecordInputs(event) {
17523
18603
  function shouldRecordOutputs(event) {
17524
18604
  return event.recordOutputs !== false;
17525
18605
  }
18606
+ function hasPromptLikeInput(input) {
18607
+ if (!isObject(input)) {
18608
+ return false;
18609
+ }
18610
+ return input.prompt !== void 0 || input.messages !== void 0;
18611
+ }
17526
18612
  function operationNameFromId(operationId) {
18613
+ if (operationId === "ai.workflowAgent.stream") {
18614
+ return "WorkflowAgent.stream";
18615
+ }
17527
18616
  return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
17528
18617
  }
17529
18618
  function modelFromEvent(event) {
@@ -17569,6 +18658,7 @@ function operationInput(event, operationName) {
17569
18658
  }
17570
18659
  return {
17571
18660
  model: modelFromEvent(event),
18661
+ instructions: event.instructions,
17572
18662
  system: event.system,
17573
18663
  prompt: event.prompt,
17574
18664
  messages: event.messages,
@@ -17617,6 +18707,30 @@ function finishResult(event, operationName) {
17617
18707
  }
17618
18708
  return event;
17619
18709
  }
18710
+ function extractTimeToFirstToken(result, state) {
18711
+ if (state.firstChunkTime !== void 0) {
18712
+ return state.firstChunkTime - state.startTime;
18713
+ }
18714
+ const performanceCandidates = [
18715
+ safePerformance(result),
18716
+ safePerformance(result.finalStep),
18717
+ ...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
18718
+ ];
18719
+ for (const performance of performanceCandidates) {
18720
+ const timeToFirstOutputMs = performance?.timeToFirstOutputMs;
18721
+ if (typeof timeToFirstOutputMs === "number") {
18722
+ return timeToFirstOutputMs / 1e3;
18723
+ }
18724
+ }
18725
+ return void 0;
18726
+ }
18727
+ function safePerformance(value) {
18728
+ if (!isObject(value)) {
18729
+ return void 0;
18730
+ }
18731
+ const performance = value.performance;
18732
+ return isObject(performance) ? performance : void 0;
18733
+ }
17620
18734
  function finishOutput(result, operationName) {
17621
18735
  if (operationName === "embed" || operationName === "embedMany") {
17622
18736
  return processAISDKEmbeddingOutput(
@@ -17693,6 +18807,10 @@ var aiSDKChannels = defineChannels("ai", {
17693
18807
  channelName: "ToolLoopAgent.stream",
17694
18808
  kind: "async"
17695
18809
  }),
18810
+ workflowAgentStream: channel({
18811
+ channelName: "WorkflowAgent.stream",
18812
+ kind: "async"
18813
+ }),
17696
18814
  v7CreateTelemetryDispatcher: channel({
17697
18815
  channelName: "createTelemetryDispatcher",
17698
18816
  kind: "sync-stream"
@@ -17703,14 +18821,19 @@ var aiSDKChannels = defineChannels("ai", {
17703
18821
  var DEFAULT_DENY_OUTPUT_PATHS = [
17704
18822
  // v3
17705
18823
  "roundtrips[].request.body",
18824
+ "roundtrips[].request.headers",
17706
18825
  "roundtrips[].response.headers",
17707
18826
  "rawResponse.headers",
17708
18827
  "responseMessages",
17709
18828
  // v5
17710
18829
  "request.body",
18830
+ "request.headers",
18831
+ "responses[].headers",
17711
18832
  "response.body",
17712
18833
  "response.headers",
17713
18834
  "steps[].request.body",
18835
+ "steps[].request.headers",
18836
+ "steps[].responses[].headers",
17714
18837
  "steps[].response.body",
17715
18838
  "steps[].response.headers"
17716
18839
  ];
@@ -17722,6 +18845,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
17722
18845
  var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
17723
18846
  "braintrust.ai-sdk.deny-output-paths"
17724
18847
  );
18848
+ var aiSDKV7TelemetryOperationCounter = 0;
18849
+ var TRANSPORT_PAYLOAD_ROOT_PATHS = [
18850
+ "rawResponse",
18851
+ "request",
18852
+ "response",
18853
+ "responses[]",
18854
+ "roundtrips[].request",
18855
+ "roundtrips[].response",
18856
+ "steps[].request",
18857
+ "steps[].response",
18858
+ "steps[].responses[]"
18859
+ ];
17725
18860
  var AI_SDK_V7_TELEMETRY_CALLBACKS = [
17726
18861
  "onStart",
17727
18862
  "onStepStart",
@@ -17730,14 +18865,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
17730
18865
  "onToolExecutionStart",
17731
18866
  "onToolExecutionEnd",
17732
18867
  "onChunk",
18868
+ "onStepEnd",
17733
18869
  "onStepFinish",
17734
18870
  "onObjectStepStart",
17735
- "onObjectStepFinish",
18871
+ "onObjectStepEnd",
17736
18872
  "onEmbedStart",
17737
- "onEmbedFinish",
18873
+ "onEmbedEnd",
17738
18874
  "onRerankStart",
17739
- "onRerankFinish",
17740
- "onFinish",
18875
+ "onRerankEnd",
18876
+ "onEnd",
18877
+ "onAbort",
17741
18878
  "onError"
17742
18879
  ];
17743
18880
  var AISDKPlugin = class extends BasePlugin {
@@ -17895,7 +19032,9 @@ var AISDKPlugin = class extends BasePlugin {
17895
19032
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
17896
19033
  name: "Agent.generate",
17897
19034
  type: "function" /* FUNCTION */,
17898
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19035
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19036
+ agentOwner: true
19037
+ }),
17899
19038
  extractOutput: (result, endEvent) => {
17900
19039
  finalizeAISDKChildTracing(endEvent);
17901
19040
  return processAISDKOutput(
@@ -17911,7 +19050,9 @@ var AISDKPlugin = class extends BasePlugin {
17911
19050
  traceStreamingChannel(aiSDKChannels.agentStream, {
17912
19051
  name: "Agent.stream",
17913
19052
  type: "function" /* FUNCTION */,
17914
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19053
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19054
+ agentOwner: true
19055
+ }),
17915
19056
  extractOutput: (result, endEvent) => processAISDKOutput(
17916
19057
  result,
17917
19058
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -17931,7 +19072,9 @@ var AISDKPlugin = class extends BasePlugin {
17931
19072
  traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
17932
19073
  name: "Agent.stream",
17933
19074
  type: "function" /* FUNCTION */,
17934
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19075
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19076
+ agentOwner: true
19077
+ }),
17935
19078
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
17936
19079
  defaultDenyOutputPaths: denyOutputPaths,
17937
19080
  endEvent,
@@ -17945,7 +19088,9 @@ var AISDKPlugin = class extends BasePlugin {
17945
19088
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
17946
19089
  name: "ToolLoopAgent.generate",
17947
19090
  type: "function" /* FUNCTION */,
17948
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19091
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19092
+ agentOwner: true
19093
+ }),
17949
19094
  extractOutput: (result, endEvent) => {
17950
19095
  finalizeAISDKChildTracing(endEvent);
17951
19096
  return processAISDKOutput(
@@ -17961,7 +19106,9 @@ var AISDKPlugin = class extends BasePlugin {
17961
19106
  traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
17962
19107
  name: "ToolLoopAgent.stream",
17963
19108
  type: "function" /* FUNCTION */,
17964
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19109
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19110
+ agentOwner: true
19111
+ }),
17965
19112
  extractOutput: (result, endEvent) => processAISDKOutput(
17966
19113
  result,
17967
19114
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -17977,6 +19124,42 @@ var AISDKPlugin = class extends BasePlugin {
17977
19124
  })
17978
19125
  })
17979
19126
  );
19127
+ this.unsubscribers.push(
19128
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
19129
+ name: "WorkflowAgent.stream",
19130
+ type: "function" /* FUNCTION */,
19131
+ extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
19132
+ params,
19133
+ event,
19134
+ span,
19135
+ denyOutputPaths
19136
+ ),
19137
+ extractOutput: (result, endEvent) => {
19138
+ finalizeAISDKChildTracing(endEvent);
19139
+ return processAISDKOutput(
19140
+ result,
19141
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
19142
+ );
19143
+ },
19144
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
19145
+ aggregateChunks: aggregateAISDKChunks,
19146
+ onComplete: ({ span }) => {
19147
+ unregisterWorkflowAgentWrapperSpan(span);
19148
+ },
19149
+ onError: ({ event, span }) => {
19150
+ finalizeAISDKChildTracing(event);
19151
+ unregisterWorkflowAgentWrapperSpan(span);
19152
+ },
19153
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19154
+ defaultDenyOutputPaths: denyOutputPaths,
19155
+ endEvent,
19156
+ onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
19157
+ result,
19158
+ span,
19159
+ startTime
19160
+ })
19161
+ })
19162
+ );
17980
19163
  }
17981
19164
  };
17982
19165
  function subscribeToAISDKV7TelemetryDispatcher() {
@@ -17988,7 +19171,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
17988
19171
  if (telemetryOptions?.isEnabled === false) {
17989
19172
  return;
17990
19173
  }
17991
- patchAISDKV7TelemetryDispatcher(event.result, telemetry);
19174
+ patchAISDKV7TelemetryDispatcher(
19175
+ event.result,
19176
+ telemetry,
19177
+ telemetryOptions
19178
+ );
17992
19179
  }
17993
19180
  };
17994
19181
  channel2.subscribe(handlers);
@@ -17996,7 +19183,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
17996
19183
  channel2.unsubscribe(handlers);
17997
19184
  };
17998
19185
  }
17999
- function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
19186
+ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
18000
19187
  if (!isObject(dispatcher)) {
18001
19188
  return;
18002
19189
  }
@@ -18005,6 +19192,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
18005
19192
  return;
18006
19193
  }
18007
19194
  dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
19195
+ let operationKey;
19196
+ const telemetryEventFields = {};
19197
+ if (typeof telemetryOptions?.recordInputs === "boolean") {
19198
+ telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
19199
+ }
19200
+ if (typeof telemetryOptions?.recordOutputs === "boolean") {
19201
+ telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
19202
+ }
19203
+ if (typeof telemetryOptions?.functionId === "string") {
19204
+ telemetryEventFields.functionId = telemetryOptions.functionId;
19205
+ }
19206
+ const eventWithOperationKey = (event) => {
19207
+ if (!isObject(event)) {
19208
+ return event;
19209
+ }
19210
+ const eventRecord = event;
19211
+ const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
19212
+ operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
19213
+ if (Object.keys(telemetryEventFields).length > 0) {
19214
+ const augmentedEvent = {
19215
+ ...telemetryEventFields,
19216
+ ...event
19217
+ };
19218
+ try {
19219
+ Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
19220
+ configurable: true,
19221
+ enumerable: false,
19222
+ value: operationKey
19223
+ });
19224
+ } catch {
19225
+ augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
19226
+ }
19227
+ return augmentedEvent;
19228
+ }
19229
+ try {
19230
+ Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
19231
+ configurable: true,
19232
+ enumerable: false,
19233
+ value: operationKey
19234
+ });
19235
+ return event;
19236
+ } catch {
19237
+ return {
19238
+ ...event,
19239
+ [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
19240
+ };
19241
+ }
19242
+ };
18008
19243
  for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
18009
19244
  const braintrustCallback = telemetry[key];
18010
19245
  if (typeof braintrustCallback !== "function") {
@@ -18013,11 +19248,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
18013
19248
  const existingCallback = dispatcherRecord[key];
18014
19249
  dispatcherRecord[key] = (event) => {
18015
19250
  const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
18016
- const braintrustResult = braintrustCallback.call(telemetry, event);
18017
- const pending = [existingResult, braintrustResult].filter(isPromiseLike);
18018
- if (pending.length > 0) {
18019
- return Promise.allSettled(pending).then(() => void 0);
19251
+ try {
19252
+ const braintrustResult = braintrustCallback.call(
19253
+ telemetry,
19254
+ eventWithOperationKey(event)
19255
+ );
19256
+ if (isPromiseLike(braintrustResult)) {
19257
+ void Promise.resolve(braintrustResult).catch(() => void 0);
19258
+ }
19259
+ } catch {
18020
19260
  }
19261
+ return existingResult;
18021
19262
  };
18022
19263
  }
18023
19264
  const braintrustExecuteTool = telemetry.executeTool;
@@ -18027,6 +19268,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
18027
19268
  const existingExecuteTool = dispatcherRecord.executeTool;
18028
19269
  dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
18029
19270
  ...args,
19271
+ ...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
18030
19272
  execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
18031
19273
  });
18032
19274
  }
@@ -18125,6 +19367,8 @@ var serializeOutputObject = (output, model) => {
18125
19367
  var processInputAttachmentsSync = (input) => {
18126
19368
  if (!input) return { input };
18127
19369
  const processed = { ...input };
19370
+ delete processed.headers;
19371
+ delete processed.experimental_output;
18128
19372
  if (input.messages && Array.isArray(input.messages)) {
18129
19373
  processed.messages = input.messages.map(processMessage);
18130
19374
  }
@@ -18158,10 +19402,10 @@ var processInputAttachmentsSync = (input) => {
18158
19402
  processed.output = serialized;
18159
19403
  }
18160
19404
  }
18161
- if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
18162
- processed.prepareCall = "[Function]";
18163
- }
18164
- return { input: processed, outputPromise };
19405
+ return {
19406
+ input: sanitizeAISDKCallInputValue(processed),
19407
+ outputPromise
19408
+ };
18165
19409
  };
18166
19410
  var processMessage = (message) => {
18167
19411
  if (!message || typeof message !== "object") return message;
@@ -18325,7 +19569,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
18325
19569
  function processAISDKCallInput(params) {
18326
19570
  return processInputAttachmentsSync(params);
18327
19571
  }
18328
- function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
19572
+ function processAISDKWorkflowAgentCallInput(params) {
19573
+ const processed = processAISDKCallInput(params);
19574
+ return {
19575
+ ...processed,
19576
+ input: extractWorkflowAgentInput(processed.input)
19577
+ };
19578
+ }
19579
+ function processAISDKWorkflowAgentModelCallInput(params) {
19580
+ const processed = processAISDKCallInput(params);
19581
+ return {
19582
+ ...processed,
19583
+ input: extractWorkflowAgentModelInput(processed.input)
19584
+ };
19585
+ }
19586
+ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
18329
19587
  const { input, outputPromise } = processAISDKCallInput(params);
18330
19588
  if (outputPromise && input && typeof input === "object") {
18331
19589
  outputPromise.then((resolvedData) => {
@@ -18344,7 +19602,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
18344
19602
  event.self,
18345
19603
  span,
18346
19604
  defaultDenyOutputPaths,
18347
- event.aiSDK
19605
+ event.aiSDK,
19606
+ childTracingOptions
19607
+ );
19608
+ event.modelWrapped = childTracing.modelWrapped;
19609
+ if (childTracing.cleanup) {
19610
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
19611
+ }
19612
+ return {
19613
+ input,
19614
+ metadata
19615
+ };
19616
+ }
19617
+ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
19618
+ registerWorkflowAgentWrapperSpan(span);
19619
+ const { input } = processAISDKWorkflowAgentCallInput(params);
19620
+ const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
19621
+ const childTracing = prepareAISDKChildTracing(
19622
+ params,
19623
+ event.self,
19624
+ span,
19625
+ defaultDenyOutputPaths,
19626
+ event.aiSDK,
19627
+ { agentOwner: true, workflowAgent: true }
18348
19628
  );
18349
19629
  event.modelWrapped = childTracing.modelWrapped;
18350
19630
  if (childTracing.cleanup) {
@@ -18381,6 +19661,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
18381
19661
  function hasModelChildTracing(event) {
18382
19662
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
18383
19663
  }
19664
+ function serializeToolExecutionInput(args) {
19665
+ return args.length > 0 ? args[0] : args;
19666
+ }
18384
19667
  function createAISDKIntegrationMetadata() {
18385
19668
  return {
18386
19669
  braintrust: {
@@ -18392,6 +19675,13 @@ function createAISDKIntegrationMetadata() {
18392
19675
  function resolveModelFromSelf(self) {
18393
19676
  return self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && self.settings?.model ? self.settings?.model : void 0;
18394
19677
  }
19678
+ function resolveToolsFromSelf(self) {
19679
+ if (!self || typeof self !== "object") {
19680
+ return void 0;
19681
+ }
19682
+ const selfRecord = self;
19683
+ return selfRecord.tools ?? selfRecord.settings?.tools;
19684
+ }
18395
19685
  function extractBaseMetadata(model, self) {
18396
19686
  const metadata = createAISDKIntegrationMetadata();
18397
19687
  const { model: modelId, provider } = serializeModelWithProvider(
@@ -18407,12 +19697,175 @@ function extractBaseMetadata(model, self) {
18407
19697
  }
18408
19698
  function extractMetadataFromCallParams(params, self) {
18409
19699
  const metadata = extractBaseMetadata(params.model, self);
18410
- const tools = serializeAISDKToolsForLogging(params.tools);
19700
+ const tools = serializeAISDKToolsForLogging(
19701
+ params.tools ?? resolveToolsFromSelf(self)
19702
+ );
18411
19703
  if (tools) {
18412
19704
  metadata.tools = tools;
18413
19705
  }
18414
19706
  return metadata;
18415
19707
  }
19708
+ function extractWorkflowMetadataFromCallParams(params, self) {
19709
+ const metadata = extractMetadataFromCallParams(params, self);
19710
+ const options = extractAISDKCallOptionsForMetadata(params);
19711
+ if (Object.keys(options).length > 0) {
19712
+ metadata.options = options;
19713
+ }
19714
+ return metadata;
19715
+ }
19716
+ function extractWorkflowAgentInput(params) {
19717
+ const input = {};
19718
+ if (params.instructions !== void 0) {
19719
+ input.instructions = params.instructions;
19720
+ }
19721
+ if (params.system !== void 0) {
19722
+ input.system = params.system;
19723
+ }
19724
+ if (Array.isArray(params.messages)) {
19725
+ return { ...input, messages: params.messages };
19726
+ }
19727
+ if (typeof params.prompt === "string") {
19728
+ return { ...input, prompt: params.prompt };
19729
+ }
19730
+ if (Array.isArray(params.prompt)) {
19731
+ return { ...input, prompt: params.prompt };
19732
+ }
19733
+ return input;
19734
+ }
19735
+ function extractWorkflowAgentModelInput(params) {
19736
+ const input = {};
19737
+ if (params.instructions !== void 0) {
19738
+ input.instructions = params.instructions;
19739
+ }
19740
+ if (params.system !== void 0) {
19741
+ input.system = params.system;
19742
+ }
19743
+ if (Array.isArray(params.messages)) {
19744
+ return { ...input, messages: params.messages };
19745
+ }
19746
+ if (typeof params.prompt === "string") {
19747
+ return { ...input, prompt: params.prompt };
19748
+ }
19749
+ if (Array.isArray(params.prompt)) {
19750
+ return { ...input, messages: params.prompt };
19751
+ }
19752
+ return input;
19753
+ }
19754
+ function sanitizeAISDKCallInputValue(value, depth = 0) {
19755
+ if (value === void 0 || typeof value === "function") {
19756
+ return void 0;
19757
+ }
19758
+ if (value === null || typeof value !== "object") {
19759
+ return value;
19760
+ }
19761
+ if (isPromiseLike(value)) {
19762
+ return "[Promise]";
19763
+ }
19764
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
19765
+ return "[AbortSignal]";
19766
+ }
19767
+ if (depth >= 8) {
19768
+ return "[Object]";
19769
+ }
19770
+ if (Array.isArray(value)) {
19771
+ return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
19772
+ }
19773
+ if (!isObject(value)) {
19774
+ return value;
19775
+ }
19776
+ const prototype = Object.getPrototypeOf(value);
19777
+ if (prototype !== Object.prototype && prototype !== null) {
19778
+ return value;
19779
+ }
19780
+ const sanitized = {};
19781
+ for (const [key, nested] of Object.entries(value)) {
19782
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
19783
+ continue;
19784
+ }
19785
+ const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
19786
+ if (sanitizedNested !== void 0) {
19787
+ sanitized[key] = sanitizedNested;
19788
+ }
19789
+ }
19790
+ return sanitized;
19791
+ }
19792
+ function extractAISDKCallOptionsForMetadata(params) {
19793
+ const options = {};
19794
+ const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
19795
+ "model",
19796
+ "instructions",
19797
+ "messages",
19798
+ "prompt",
19799
+ "system",
19800
+ "tools",
19801
+ "headers",
19802
+ "abortSignal",
19803
+ "signal",
19804
+ "experimental_output"
19805
+ ]);
19806
+ for (const [key, value] of Object.entries(params)) {
19807
+ if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
19808
+ continue;
19809
+ }
19810
+ const sanitized = sanitizeAISDKMetadataValue(value);
19811
+ if (sanitized !== void 0) {
19812
+ options[key] = sanitized;
19813
+ }
19814
+ }
19815
+ return options;
19816
+ }
19817
+ function sanitizeAISDKMetadataValue(value, depth = 0) {
19818
+ if (value === void 0) {
19819
+ return void 0;
19820
+ }
19821
+ if (typeof value === "function") {
19822
+ return "[Function]";
19823
+ }
19824
+ if (value === null || typeof value !== "object") {
19825
+ return value;
19826
+ }
19827
+ if (isPromiseLike(value)) {
19828
+ return "[Promise]";
19829
+ }
19830
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
19831
+ return "[AbortSignal]";
19832
+ }
19833
+ if (depth >= 8) {
19834
+ return "[Object]";
19835
+ }
19836
+ if (Array.isArray(value)) {
19837
+ return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
19838
+ }
19839
+ if (!isObject(value)) {
19840
+ return value;
19841
+ }
19842
+ const sanitized = {};
19843
+ for (const [key, nested] of Object.entries(value)) {
19844
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
19845
+ continue;
19846
+ }
19847
+ const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
19848
+ if (sanitizedNested !== void 0) {
19849
+ sanitized[key] = sanitizedNested;
19850
+ }
19851
+ }
19852
+ return sanitized;
19853
+ }
19854
+ function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
19855
+ if (!options.workflowAgent) {
19856
+ return {
19857
+ input: processAISDKCallInput(callOptions).input,
19858
+ metadata: baseMetadata
19859
+ };
19860
+ }
19861
+ return {
19862
+ input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
19863
+ metadata: {
19864
+ ...baseMetadata,
19865
+ ...extractWorkflowMetadataFromCallParams(callOptions)
19866
+ }
19867
+ };
19868
+ }
18416
19869
  function extractMetadataFromEmbedParams(params, self) {
18417
19870
  return extractBaseMetadata(params.model, self);
18418
19871
  }
@@ -18426,65 +19879,228 @@ function extractMetadataFromRerankParams(params, self) {
18426
19879
  }
18427
19880
  return metadata;
18428
19881
  }
18429
- function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
19882
+ function activeAISDKChildPatchEntry(entries) {
19883
+ const activeSpan = currentSpan();
19884
+ const activeSpanId = activeSpan.spanId;
19885
+ if (activeSpanId) {
19886
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19887
+ const entry = entries[index];
19888
+ if (entry?.activeSpanIds.has(activeSpanId)) {
19889
+ return entry;
19890
+ }
19891
+ }
19892
+ }
19893
+ const activeParentSpanIds = activeSpan.spanParents ?? [];
19894
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19895
+ const entry = entries[index];
19896
+ if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
19897
+ return entry;
19898
+ }
19899
+ }
19900
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19901
+ const entry = entries[index];
19902
+ if (entry?.parentSpan.spanId === activeSpanId) {
19903
+ return entry;
19904
+ }
19905
+ }
19906
+ return entries[entries.length - 1];
19907
+ }
19908
+ function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
19909
+ const activeSpanId = currentSpan().spanId;
19910
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
19911
+ return false;
19912
+ }
19913
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19914
+ const entry = entries[index];
19915
+ if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
19916
+ entry.activeSpanIds.add(nestedSpan.spanId);
19917
+ cleanup.push(() => {
19918
+ entry.activeSpanIds.delete(nestedSpan.spanId);
19919
+ });
19920
+ return true;
19921
+ }
19922
+ }
19923
+ return false;
19924
+ }
19925
+ function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
19926
+ const activeSpanId = currentSpan().spanId;
19927
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
19928
+ return;
19929
+ }
19930
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19931
+ const existingEntry = entries[index];
19932
+ if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
19933
+ entry.activeSpanIds.add(activeSpanId);
19934
+ cleanup.push(() => {
19935
+ entry.activeSpanIds.delete(activeSpanId);
19936
+ });
19937
+ return;
19938
+ }
19939
+ }
19940
+ }
19941
+ function closeOpenAISDKModelPatchSpans(entry) {
19942
+ for (const span of entry.openSpans) {
19943
+ span.end();
19944
+ }
19945
+ entry.openSpans.clear();
19946
+ }
19947
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
18430
19948
  const cleanup = [];
18431
- const patchedModels = /* @__PURE__ */ new WeakSet();
19949
+ const patchedModels = /* @__PURE__ */ new WeakMap();
18432
19950
  const patchedTools = /* @__PURE__ */ new WeakSet();
18433
19951
  let modelWrapped = false;
18434
19952
  const patchModel = (model) => {
18435
19953
  const resolvedModel = resolveAISDKModel(model, aiSDK);
18436
- if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
19954
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
18437
19955
  return resolvedModel;
18438
19956
  }
18439
- patchedModels.add(resolvedModel);
18440
- resolvedModel[AUTO_PATCHED_MODEL] = true;
19957
+ const existingWrappedModel = patchedModels.get(resolvedModel);
19958
+ if (existingWrappedModel) {
19959
+ modelWrapped = true;
19960
+ return existingWrappedModel;
19961
+ }
18441
19962
  modelWrapped = true;
19963
+ const modelRecord = resolvedModel;
19964
+ const entry = {
19965
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
19966
+ baseMetadata: buildAISDKChildMetadata(resolvedModel),
19967
+ childTracingOptions,
19968
+ denyOutputPaths,
19969
+ openSpans: /* @__PURE__ */ new Set(),
19970
+ parentSpan
19971
+ };
19972
+ const cleanupModelEntry = (state2, patchedModel) => {
19973
+ closeOpenAISDKModelPatchSpans(entry);
19974
+ const index = state2.entries.indexOf(entry);
19975
+ if (index >= 0) {
19976
+ state2.entries.splice(index, 1);
19977
+ }
19978
+ if (state2.entries.length > 0) {
19979
+ return;
19980
+ }
19981
+ patchedModel.doGenerate = state2.originalDoGenerate;
19982
+ patchedModel.doStream = state2.originalDoStream;
19983
+ delete patchedModel[AUTO_PATCHED_MODEL];
19984
+ };
19985
+ const existingState = modelRecord[AUTO_PATCHED_MODEL];
19986
+ if (existingState) {
19987
+ patchedModels.set(resolvedModel, resolvedModel);
19988
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
19989
+ existingState.entries,
19990
+ parentSpan,
19991
+ cleanup
19992
+ )) {
19993
+ return resolvedModel;
19994
+ }
19995
+ if (!childTracingOptions.agentOwner) {
19996
+ shadowActiveAISDKChildPatchEntry(
19997
+ existingState.entries,
19998
+ entry,
19999
+ parentSpan,
20000
+ cleanup
20001
+ );
20002
+ }
20003
+ existingState.entries.push(entry);
20004
+ cleanup.push(() => {
20005
+ cleanupModelEntry(existingState, modelRecord);
20006
+ });
20007
+ return resolvedModel;
20008
+ }
18442
20009
  const originalDoGenerate = resolvedModel.doGenerate;
18443
20010
  const originalDoStream = resolvedModel.doStream;
18444
- const baseMetadata = buildAISDKChildMetadata(resolvedModel);
18445
- resolvedModel.doGenerate = async function doGeneratePatched(options) {
18446
- return parentSpan.traced(
20011
+ const wrappedModel = Object.create(
20012
+ Object.getPrototypeOf(resolvedModel)
20013
+ );
20014
+ Object.defineProperties(
20015
+ wrappedModel,
20016
+ Object.getOwnPropertyDescriptors(resolvedModel)
20017
+ );
20018
+ const wrappedModelRecord = wrappedModel;
20019
+ const state = {
20020
+ entries: [entry],
20021
+ originalDoGenerate,
20022
+ originalDoStream
20023
+ };
20024
+ Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
20025
+ configurable: true,
20026
+ value: state
20027
+ });
20028
+ wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
20029
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
20030
+ if (!activeEntry) {
20031
+ return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
20032
+ }
20033
+ closeOpenAISDKModelPatchSpans(activeEntry);
20034
+ return activeEntry.parentSpan.traced(
18447
20035
  async (span) => {
18448
- const result = await Reflect.apply(
18449
- originalDoGenerate,
18450
- resolvedModel,
18451
- [options]
18452
- );
18453
- span.log({
18454
- output: processAISDKOutput(result, denyOutputPaths),
18455
- metrics: extractTokenMetrics(result),
18456
- ...buildResolvedMetadataPayload(result)
18457
- });
18458
- return result;
20036
+ activeEntry.openSpans.add(span);
20037
+ try {
20038
+ const result = await Reflect.apply(
20039
+ originalDoGenerate,
20040
+ resolvedModel,
20041
+ [callOptions]
20042
+ );
20043
+ const output = processAISDKOutput(
20044
+ result,
20045
+ activeEntry.denyOutputPaths
20046
+ );
20047
+ const metrics = extractTokenMetrics(result);
20048
+ const metadataPayload = buildResolvedMetadataPayload(result);
20049
+ const missingUsageMetadata = buildMissingUsageMetadata(
20050
+ output,
20051
+ metrics,
20052
+ "ai_sdk_result_missing_usage"
20053
+ );
20054
+ span.log({
20055
+ output,
20056
+ metrics,
20057
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
20058
+ });
20059
+ return result;
20060
+ } finally {
20061
+ activeEntry.openSpans.delete(span);
20062
+ }
18459
20063
  },
18460
20064
  {
18461
20065
  name: "doGenerate",
18462
20066
  spanAttributes: {
18463
20067
  type: "llm" /* LLM */
18464
20068
  },
18465
- event: {
18466
- input: processAISDKCallInput(options).input,
18467
- metadata: baseMetadata
18468
- }
20069
+ event: buildAISDKModelStartEvent(
20070
+ callOptions,
20071
+ activeEntry.baseMetadata,
20072
+ {
20073
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
20074
+ }
20075
+ )
18469
20076
  }
18470
20077
  );
18471
20078
  };
18472
20079
  if (originalDoStream) {
18473
- resolvedModel.doStream = async function doStreamPatched(options) {
18474
- const span = parentSpan.startSpan({
20080
+ wrappedModel.doStream = async function doStreamPatched(callOptions) {
20081
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
20082
+ if (!activeEntry) {
20083
+ return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
20084
+ }
20085
+ closeOpenAISDKModelPatchSpans(activeEntry);
20086
+ const span = activeEntry.parentSpan.startSpan({
18475
20087
  name: "doStream",
18476
20088
  spanAttributes: {
18477
20089
  type: "llm" /* LLM */
18478
20090
  },
18479
- event: {
18480
- input: processAISDKCallInput(options).input,
18481
- metadata: baseMetadata
18482
- }
20091
+ event: buildAISDKModelStartEvent(
20092
+ callOptions,
20093
+ activeEntry.baseMetadata,
20094
+ {
20095
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
20096
+ }
20097
+ )
18483
20098
  });
20099
+ activeEntry.openSpans.add(span);
18484
20100
  const streamStartTime = getCurrentUnixTimestamp();
18485
20101
  const result = await withCurrent(
18486
20102
  span,
18487
- () => Reflect.apply(originalDoStream, resolvedModel, [options])
20103
+ () => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
18488
20104
  );
18489
20105
  let firstChunkTime;
18490
20106
  const output = {};
@@ -18492,6 +20108,44 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18492
20108
  let reasoning = "";
18493
20109
  const toolCalls = [];
18494
20110
  let object = void 0;
20111
+ let streamSpanEnded = false;
20112
+ const logAndEndStreamSpan = (usageUnavailableReason) => {
20113
+ if (streamSpanEnded) {
20114
+ return;
20115
+ }
20116
+ output.text = text;
20117
+ output.reasoning = reasoning;
20118
+ output.toolCalls = toolCalls;
20119
+ if (object !== void 0) {
20120
+ output.object = object;
20121
+ }
20122
+ const metrics = extractTokenMetrics(output);
20123
+ if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
20124
+ metrics.time_to_first_token = Math.max(
20125
+ firstChunkTime - streamStartTime,
20126
+ 1e-6
20127
+ );
20128
+ }
20129
+ const metadataPayload = buildResolvedMetadataPayload(
20130
+ output
20131
+ );
20132
+ const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
20133
+ output,
20134
+ metrics,
20135
+ "ai_sdk_result_missing_usage"
20136
+ );
20137
+ span.log({
20138
+ output: processAISDKOutput(
20139
+ output,
20140
+ activeEntry.denyOutputPaths
20141
+ ),
20142
+ metrics,
20143
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
20144
+ });
20145
+ activeEntry.openSpans.delete(span);
20146
+ span.end();
20147
+ streamSpanEnded = true;
20148
+ };
18495
20149
  const transformStream = new TransformStream({
18496
20150
  transform(chunk, controller) {
18497
20151
  if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
@@ -18529,33 +20183,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18529
20183
  }
18530
20184
  break;
18531
20185
  case "finish":
18532
- output.text = text;
18533
- output.reasoning = reasoning;
18534
- output.toolCalls = toolCalls;
18535
20186
  output.finishReason = chunk.finishReason;
18536
20187
  output.usage = chunk.usage;
18537
- if (object !== void 0) {
18538
- output.object = object;
18539
- }
18540
- const metrics = extractTokenMetrics(output);
18541
- if (firstChunkTime !== void 0) {
18542
- metrics.time_to_first_token = Math.max(
18543
- firstChunkTime - streamStartTime,
18544
- 1e-6
18545
- );
18546
- }
18547
- span.log({
18548
- output: processAISDKOutput(
18549
- output,
18550
- denyOutputPaths
18551
- ),
18552
- metrics,
18553
- ...buildResolvedMetadataPayload(output)
18554
- });
18555
- span.end();
20188
+ logAndEndStreamSpan();
18556
20189
  break;
18557
20190
  }
18558
20191
  controller.enqueue(chunk);
20192
+ },
20193
+ flush() {
20194
+ logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
18559
20195
  }
18560
20196
  });
18561
20197
  return {
@@ -18565,32 +20201,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18565
20201
  };
18566
20202
  }
18567
20203
  cleanup.push(() => {
18568
- resolvedModel.doGenerate = originalDoGenerate;
18569
- if (originalDoStream) {
18570
- resolvedModel.doStream = originalDoStream;
18571
- }
18572
- delete resolvedModel[AUTO_PATCHED_MODEL];
20204
+ cleanupModelEntry(state, wrappedModelRecord);
18573
20205
  });
18574
- return resolvedModel;
20206
+ patchedModels.set(resolvedModel, wrappedModel);
20207
+ patchedModels.set(wrappedModel, wrappedModel);
20208
+ return wrappedModel;
18575
20209
  };
18576
20210
  const patchTool = (tool, name) => {
18577
- if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
20211
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
18578
20212
  return;
18579
20213
  }
18580
20214
  patchedTools.add(tool);
18581
- tool[AUTO_PATCHED_TOOL] = true;
18582
- const originalExecute = tool.execute;
20215
+ const toolRecord = tool;
20216
+ const entry = {
20217
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
20218
+ childTracingOptions,
20219
+ name,
20220
+ parentSpan
20221
+ };
20222
+ const cleanupToolEntry = (state2) => {
20223
+ const index = state2.entries.indexOf(entry);
20224
+ if (index >= 0) {
20225
+ state2.entries.splice(index, 1);
20226
+ }
20227
+ if (state2.entries.length > 0) {
20228
+ return;
20229
+ }
20230
+ tool.execute = state2.originalExecute;
20231
+ delete toolRecord[AUTO_PATCHED_TOOL];
20232
+ };
20233
+ const existingState = toolRecord[AUTO_PATCHED_TOOL];
20234
+ if (existingState) {
20235
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
20236
+ existingState.entries,
20237
+ parentSpan,
20238
+ cleanup
20239
+ )) {
20240
+ return;
20241
+ }
20242
+ if (!childTracingOptions.agentOwner) {
20243
+ shadowActiveAISDKChildPatchEntry(
20244
+ existingState.entries,
20245
+ entry,
20246
+ parentSpan,
20247
+ cleanup
20248
+ );
20249
+ }
20250
+ existingState.entries.push(entry);
20251
+ cleanup.push(() => {
20252
+ cleanupToolEntry(existingState);
20253
+ });
20254
+ return;
20255
+ }
20256
+ const originalExecute = toolRecord.execute;
20257
+ const state = {
20258
+ entries: [entry],
20259
+ originalExecute
20260
+ };
20261
+ toolRecord[AUTO_PATCHED_TOOL] = state;
18583
20262
  tool.execute = function executePatched(...args) {
20263
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
18584
20264
  const result = Reflect.apply(originalExecute, this, args);
20265
+ if (!activeEntry) {
20266
+ return result;
20267
+ }
18585
20268
  if (isAsyncGenerator2(result)) {
18586
20269
  return (async function* () {
18587
- const span = parentSpan.startSpan({
18588
- name,
20270
+ const span = activeEntry.parentSpan.startSpan({
20271
+ name: activeEntry.name,
18589
20272
  spanAttributes: {
18590
20273
  type: "tool" /* TOOL */
18591
20274
  }
18592
20275
  });
18593
- span.log({ input: args.length === 1 ? args[0] : args });
20276
+ span.log({ input: serializeToolExecutionInput(args) });
18594
20277
  try {
18595
20278
  let lastValue;
18596
20279
  for await (const value of result) {
@@ -18606,15 +20289,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18606
20289
  }
18607
20290
  })();
18608
20291
  }
18609
- return parentSpan.traced(
20292
+ return activeEntry.parentSpan.traced(
18610
20293
  async (span) => {
18611
- span.log({ input: args.length === 1 ? args[0] : args });
20294
+ span.log({ input: serializeToolExecutionInput(args) });
18612
20295
  const awaitedResult = await result;
18613
20296
  span.log({ output: awaitedResult });
18614
20297
  return awaitedResult;
18615
20298
  },
18616
20299
  {
18617
- name,
20300
+ name: activeEntry.name,
18618
20301
  spanAttributes: {
18619
20302
  type: "tool" /* TOOL */
18620
20303
  }
@@ -18622,8 +20305,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18622
20305
  );
18623
20306
  };
18624
20307
  cleanup.push(() => {
18625
- tool.execute = originalExecute;
18626
- delete tool[AUTO_PATCHED_TOOL];
20308
+ cleanupToolEntry(state);
18627
20309
  });
18628
20310
  };
18629
20311
  const patchTools = (tools) => {
@@ -18642,25 +20324,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18642
20324
  }
18643
20325
  };
18644
20326
  if (params && typeof params === "object") {
18645
- const patchedParamModel = patchModel(params.model);
18646
- if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
20327
+ const originalParamModel = params.model;
20328
+ const patchedParamModel = patchModel(originalParamModel);
20329
+ if (patchedParamModel && patchedParamModel !== originalParamModel) {
18647
20330
  params.model = patchedParamModel;
20331
+ cleanup.push(() => {
20332
+ params.model = originalParamModel;
20333
+ });
18648
20334
  }
18649
20335
  patchTools(params.tools);
18650
20336
  }
18651
20337
  if (self && typeof self === "object") {
18652
20338
  const selfRecord = self;
18653
20339
  if (selfRecord.model !== void 0) {
18654
- const patchedSelfModel = patchModel(selfRecord.model);
18655
- if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
20340
+ const originalSelfModel = selfRecord.model;
20341
+ const patchedSelfModel = patchModel(originalSelfModel);
20342
+ if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
18656
20343
  selfRecord.model = patchedSelfModel;
20344
+ cleanup.push(() => {
20345
+ selfRecord.model = originalSelfModel;
20346
+ });
18657
20347
  }
18658
20348
  }
20349
+ if (selfRecord.tools !== void 0) {
20350
+ patchTools(selfRecord.tools);
20351
+ }
18659
20352
  if (selfRecord.settings && typeof selfRecord.settings === "object") {
18660
20353
  if (selfRecord.settings.model !== void 0) {
18661
- const patchedSettingsModel = patchModel(selfRecord.settings.model);
18662
- if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
20354
+ const originalSettingsModel = selfRecord.settings.model;
20355
+ const patchedSettingsModel = patchModel(originalSettingsModel);
20356
+ if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
18663
20357
  selfRecord.settings.model = patchedSettingsModel;
20358
+ cleanup.push(() => {
20359
+ if (selfRecord.settings) {
20360
+ selfRecord.settings.model = originalSettingsModel;
20361
+ }
20362
+ });
18664
20363
  }
18665
20364
  }
18666
20365
  if (selfRecord.settings.tools !== void 0) {
@@ -18757,99 +20456,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
18757
20456
  return isObject(part) && typeof part.type !== "string";
18758
20457
  }
18759
20458
  function patchAISDKStreamingResult(args) {
18760
- const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
20459
+ const {
20460
+ defaultDenyOutputPaths,
20461
+ endEvent,
20462
+ onComplete,
20463
+ result,
20464
+ span,
20465
+ startTime
20466
+ } = args;
18761
20467
  if (!result || typeof result !== "object") {
18762
20468
  return false;
18763
20469
  }
18764
20470
  const resultRecord = result;
18765
20471
  attachKnownResultPromiseHandlers(resultRecord);
20472
+ let finalized = false;
20473
+ const finalize = () => {
20474
+ if (finalized) {
20475
+ return;
20476
+ }
20477
+ finalized = true;
20478
+ finalizeAISDKChildTracing(endEvent);
20479
+ span.end();
20480
+ onComplete?.();
20481
+ };
20482
+ let outputLogged = false;
20483
+ const logStreamingOutput = async (firstChunkTime) => {
20484
+ if (outputLogged) {
20485
+ return;
20486
+ }
20487
+ outputLogged = true;
20488
+ try {
20489
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
20490
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
20491
+ metrics.time_to_first_token = firstChunkTime - startTime;
20492
+ }
20493
+ const output = await processAISDKStreamingOutput(
20494
+ result,
20495
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
20496
+ );
20497
+ const metadata = buildResolvedMetadataPayload(result).metadata;
20498
+ span.log({
20499
+ output,
20500
+ ...metadata ? { metadata } : {},
20501
+ metrics
20502
+ });
20503
+ } catch (error2) {
20504
+ span.log({ error: toLoggedError(error2) });
20505
+ } finally {
20506
+ finalize();
20507
+ }
20508
+ };
20509
+ const createAsyncIterableHooks = () => {
20510
+ let firstChunkTime;
20511
+ return {
20512
+ onChunk: (chunk) => {
20513
+ if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
20514
+ firstChunkTime = getCurrentUnixTimestamp();
20515
+ }
20516
+ },
20517
+ onComplete: async () => {
20518
+ await logStreamingOutput(firstChunkTime);
20519
+ },
20520
+ onError: (error2) => {
20521
+ if (!outputLogged) {
20522
+ outputLogged = true;
20523
+ span.log({
20524
+ error: error2.message
20525
+ });
20526
+ }
20527
+ finalize();
20528
+ },
20529
+ onCancel: finalize
20530
+ };
20531
+ };
20532
+ const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
20533
+ const patchAsyncIterableField = (field) => {
20534
+ let descriptorOwner = resultRecord;
20535
+ let descriptor;
20536
+ while (descriptorOwner) {
20537
+ descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
20538
+ if (descriptor) {
20539
+ break;
20540
+ }
20541
+ descriptorOwner = Object.getPrototypeOf(descriptorOwner);
20542
+ }
20543
+ if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
20544
+ return false;
20545
+ }
20546
+ if ("value" in descriptor) {
20547
+ if (!isAsyncIterable3(descriptor.value)) {
20548
+ return false;
20549
+ }
20550
+ try {
20551
+ Object.defineProperty(resultRecord, field, {
20552
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
20553
+ enumerable: descriptor.enumerable,
20554
+ value: patchAsyncIterable(descriptor.value),
20555
+ writable: descriptor.writable
20556
+ });
20557
+ return true;
20558
+ } catch {
20559
+ return false;
20560
+ }
20561
+ }
20562
+ if (typeof descriptor.get !== "function") {
20563
+ return false;
20564
+ }
20565
+ const originalGet = descriptor.get;
20566
+ const originalSet = descriptor.set;
20567
+ try {
20568
+ Object.defineProperty(resultRecord, field, {
20569
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
20570
+ enumerable: descriptor.enumerable,
20571
+ get() {
20572
+ const stream = originalGet.call(this);
20573
+ return isAsyncIterable3(stream) ? patchAsyncIterable(stream) : stream;
20574
+ },
20575
+ ...originalSet ? {
20576
+ set(value) {
20577
+ originalSet.call(this, value);
20578
+ }
20579
+ } : {}
20580
+ });
20581
+ return true;
20582
+ } catch {
20583
+ return false;
20584
+ }
20585
+ };
20586
+ let patched = false;
18766
20587
  if (isReadableStreamLike(resultRecord.baseStream)) {
18767
- let firstChunkTime2;
18768
- const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
20588
+ let firstChunkTime;
20589
+ const transformedBaseStream = resultRecord.baseStream.pipeThrough(
18769
20590
  new TransformStream({
18770
20591
  transform(chunk, controller) {
18771
- if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
18772
- firstChunkTime2 = getCurrentUnixTimestamp();
20592
+ if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
20593
+ firstChunkTime = getCurrentUnixTimestamp();
18773
20594
  }
18774
20595
  controller.enqueue(chunk);
18775
20596
  },
18776
20597
  async flush() {
18777
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
18778
- if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
18779
- metrics.time_to_first_token = firstChunkTime2 - startTime;
18780
- }
18781
- const output = await processAISDKStreamingOutput(
18782
- result,
18783
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
18784
- );
18785
- const metadata = buildResolvedMetadataPayload(result).metadata;
18786
- span.log({
18787
- output,
18788
- ...metadata ? { metadata } : {},
18789
- metrics
18790
- });
18791
- finalizeAISDKChildTracing(endEvent);
18792
- span.end();
20598
+ await logStreamingOutput(firstChunkTime);
18793
20599
  }
18794
20600
  })
18795
20601
  );
20602
+ const reader = transformedBaseStream.getReader();
20603
+ const wrappedBaseStream = new ReadableStream({
20604
+ async pull(controller) {
20605
+ try {
20606
+ const { done, value } = await reader.read();
20607
+ if (done) {
20608
+ controller.close();
20609
+ return;
20610
+ }
20611
+ controller.enqueue(value);
20612
+ } catch (error2) {
20613
+ span.log({ error: toLoggedError(error2) });
20614
+ finalize();
20615
+ controller.error(error2);
20616
+ }
20617
+ },
20618
+ async cancel(reason) {
20619
+ try {
20620
+ finalize();
20621
+ } finally {
20622
+ await reader.cancel(reason);
20623
+ }
20624
+ }
20625
+ });
18796
20626
  Object.defineProperty(resultRecord, "baseStream", {
18797
20627
  configurable: true,
18798
20628
  enumerable: true,
18799
20629
  value: wrappedBaseStream,
18800
20630
  writable: true
18801
20631
  });
18802
- return true;
20632
+ patched = true;
18803
20633
  }
18804
- const streamField = findAsyncIterableField(resultRecord, [
20634
+ for (const field of [
18805
20635
  "partialObjectStream",
18806
20636
  "textStream",
18807
20637
  "fullStream",
18808
20638
  "stream"
18809
- ]);
18810
- if (!streamField) {
18811
- return false;
20639
+ ]) {
20640
+ patched = patchAsyncIterableField(field) || patched;
18812
20641
  }
18813
- let firstChunkTime;
18814
- const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
18815
- onChunk: (chunk) => {
18816
- if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
18817
- firstChunkTime = getCurrentUnixTimestamp();
18818
- }
18819
- },
18820
- onComplete: async () => {
18821
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
18822
- if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
18823
- metrics.time_to_first_token = firstChunkTime - startTime;
18824
- }
18825
- const output = await processAISDKStreamingOutput(
18826
- result,
18827
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
18828
- );
18829
- const metadata = buildResolvedMetadataPayload(result).metadata;
18830
- span.log({
18831
- output,
18832
- ...metadata ? { metadata } : {},
18833
- metrics
18834
- });
18835
- finalizeAISDKChildTracing(endEvent);
18836
- span.end();
18837
- },
18838
- onError: (error2) => {
18839
- span.log({
18840
- error: error2.message
18841
- });
18842
- finalizeAISDKChildTracing(endEvent);
18843
- span.end();
18844
- }
18845
- });
18846
- Object.defineProperty(resultRecord, streamField.field, {
18847
- configurable: true,
18848
- enumerable: true,
18849
- value: wrappedStream,
18850
- writable: true
18851
- });
18852
- return true;
20642
+ return patched;
18853
20643
  }
18854
20644
  function attachKnownResultPromiseHandlers(result) {
18855
20645
  const promiseLikeFields = [
@@ -18881,34 +20671,72 @@ function attachKnownResultPromiseHandlers(result) {
18881
20671
  }
18882
20672
  }
18883
20673
  function isReadableStreamLike(value) {
18884
- return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
18885
- }
18886
- function findAsyncIterableField(result, candidateFields) {
18887
- for (const field of candidateFields) {
18888
- try {
18889
- const stream = result[field];
18890
- if (isAsyncIterable3(stream)) {
18891
- return { field, stream };
20674
+ return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
20675
+ }
20676
+ function createPatchedReadableStream(stream, hooks) {
20677
+ let reader;
20678
+ let completed = false;
20679
+ return new ReadableStream({
20680
+ async pull(controller) {
20681
+ reader ??= stream.getReader();
20682
+ try {
20683
+ const { done, value } = await reader.read();
20684
+ if (done) {
20685
+ completed = true;
20686
+ await hooks.onComplete();
20687
+ controller.close();
20688
+ return;
20689
+ }
20690
+ hooks.onChunk(value);
20691
+ controller.enqueue(value);
20692
+ } catch (error2) {
20693
+ completed = true;
20694
+ hooks.onError(
20695
+ error2 instanceof Error ? error2 : new Error(String(error2))
20696
+ );
20697
+ controller.error(error2);
20698
+ }
20699
+ },
20700
+ async cancel(reason) {
20701
+ if (!completed) {
20702
+ completed = true;
20703
+ try {
20704
+ await hooks.onCancel?.();
20705
+ } catch {
20706
+ }
20707
+ }
20708
+ if (reader) {
20709
+ await reader.cancel(reason);
20710
+ } else if (stream.cancel) {
20711
+ await stream.cancel(reason);
18892
20712
  }
18893
- } catch {
18894
20713
  }
18895
- }
18896
- return null;
20714
+ });
18897
20715
  }
18898
20716
  function createPatchedAsyncIterable(stream, hooks) {
18899
20717
  return {
18900
20718
  async *[Symbol.asyncIterator]() {
20719
+ let completed = false;
18901
20720
  try {
18902
20721
  for await (const chunk of stream) {
18903
20722
  hooks.onChunk(chunk);
18904
20723
  yield chunk;
18905
20724
  }
20725
+ completed = true;
18906
20726
  await hooks.onComplete();
18907
20727
  } catch (error2) {
20728
+ completed = true;
18908
20729
  hooks.onError(
18909
20730
  error2 instanceof Error ? error2 : new Error(String(error2))
18910
20731
  );
18911
20732
  throw error2;
20733
+ } finally {
20734
+ if (!completed) {
20735
+ try {
20736
+ await hooks.onCancel?.();
20737
+ } catch {
20738
+ }
20739
+ }
18912
20740
  }
18913
20741
  }
18914
20742
  };
@@ -18983,6 +20811,40 @@ function buildResolvedMetadataPayload(result) {
18983
20811
  }
18984
20812
  return Object.keys(metadata).length > 0 ? { metadata } : {};
18985
20813
  }
20814
+ function mergeMetadataPayload(metadataPayload, extraMetadata) {
20815
+ if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
20816
+ return metadataPayload;
20817
+ }
20818
+ return {
20819
+ metadata: {
20820
+ ...metadataPayload.metadata ?? {},
20821
+ ...extraMetadata
20822
+ }
20823
+ };
20824
+ }
20825
+ function buildMissingUsageMetadata(output, metrics, reason) {
20826
+ if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
20827
+ return void 0;
20828
+ }
20829
+ return { usage_unavailable_reason: reason };
20830
+ }
20831
+ function hasLoggedOutput(output) {
20832
+ if (output === null || output === void 0) {
20833
+ return false;
20834
+ }
20835
+ if (Array.isArray(output)) {
20836
+ return output.length > 0;
20837
+ }
20838
+ if (typeof output === "object") {
20839
+ return Object.keys(output).length > 0;
20840
+ }
20841
+ return true;
20842
+ }
20843
+ function hasTokenUsageMetrics(metrics) {
20844
+ return Object.keys(metrics).some(
20845
+ (key) => key !== "estimated_cost" && key !== "time_to_first_token"
20846
+ );
20847
+ }
18986
20848
  function resolveAISDKModel(model, aiSDK) {
18987
20849
  if (typeof model !== "string") {
18988
20850
  return model;
@@ -19006,7 +20868,45 @@ function isAsyncGenerator2(value) {
19006
20868
  function processAISDKOutput(output, denyOutputPaths) {
19007
20869
  if (!output) return output;
19008
20870
  const merged = extractSerializableOutputFields(output);
19009
- return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
20871
+ const deleteOutputPaths = denyOutputPaths.filter(
20872
+ (path8) => path8.toLowerCase().endsWith("headers")
20873
+ );
20874
+ const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
20875
+ for (const path8 of TRANSPORT_PAYLOAD_ROOT_PATHS) {
20876
+ const stack = [{ obj: sanitized, keys: parsePath(path8) }];
20877
+ while (stack.length > 0) {
20878
+ const entry = stack.pop();
20879
+ if (!entry || entry.keys.length === 0) {
20880
+ continue;
20881
+ }
20882
+ const firstKey = entry.keys[0];
20883
+ const remainingKeys = entry.keys.slice(1);
20884
+ if (firstKey === "[]") {
20885
+ if (Array.isArray(entry.obj)) {
20886
+ for (const item of entry.obj) {
20887
+ stack.push({
20888
+ obj: item,
20889
+ keys: remainingKeys
20890
+ });
20891
+ }
20892
+ }
20893
+ continue;
20894
+ }
20895
+ if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
20896
+ continue;
20897
+ }
20898
+ const record = entry.obj;
20899
+ if (remainingKeys.length === 0) {
20900
+ record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
20901
+ continue;
20902
+ }
20903
+ stack.push({
20904
+ obj: record[firstKey],
20905
+ keys: remainingKeys
20906
+ });
20907
+ }
20908
+ }
20909
+ return normalizeAISDKLoggedOutput(sanitized);
19010
20910
  }
19011
20911
  function processAISDKEmbeddingOutput(output, denyOutputPaths) {
19012
20912
  if (!output || typeof output !== "object") {
@@ -19097,6 +20997,8 @@ function extractTokenMetrics(result) {
19097
20997
  );
19098
20998
  if (totalTokens !== void 0) {
19099
20999
  metrics.tokens = totalTokens;
21000
+ } else if (promptTokens !== void 0 && completionTokens !== void 0) {
21001
+ metrics.tokens = promptTokens + completionTokens;
19100
21002
  }
19101
21003
  const promptCachedTokens = firstNumber2(
19102
21004
  usage.inputTokens?.cacheRead,
@@ -19220,7 +21122,9 @@ function extractGetterValues(obj) {
19220
21122
  const getterValues = {};
19221
21123
  const getterNames = [
19222
21124
  "content",
21125
+ "messages",
19223
21126
  "text",
21127
+ "output",
19224
21128
  "object",
19225
21129
  "value",
19226
21130
  "values",
@@ -19260,7 +21164,9 @@ function extractGetterValues(obj) {
19260
21164
  function extractSerializableOutputFields(output) {
19261
21165
  const serialized = {};
19262
21166
  const directFieldNames = [
21167
+ "messages",
19263
21168
  "steps",
21169
+ "output",
19264
21170
  "request",
19265
21171
  "responseMessages",
19266
21172
  "warnings",
@@ -19442,7 +21348,7 @@ function parsePath(path8) {
19442
21348
  }
19443
21349
  return keys;
19444
21350
  }
19445
- function omitAtPath(obj, keys) {
21351
+ function omitAtPath(obj, keys, deleteLeaf = false) {
19446
21352
  if (keys.length === 0) return;
19447
21353
  const firstKey = keys[0];
19448
21354
  const remainingKeys = keys.slice(1);
@@ -19452,29 +21358,36 @@ function omitAtPath(obj, keys) {
19452
21358
  if (remainingKeys.length > 0) {
19453
21359
  omitAtPath(
19454
21360
  item,
19455
- remainingKeys
21361
+ remainingKeys,
21362
+ deleteLeaf
19456
21363
  );
19457
21364
  }
19458
21365
  });
19459
21366
  }
19460
21367
  } else if (remainingKeys.length === 0) {
19461
21368
  if (obj && typeof obj === "object" && firstKey in obj) {
19462
- obj[firstKey] = "<omitted>";
21369
+ if (deleteLeaf) {
21370
+ delete obj[firstKey];
21371
+ } else {
21372
+ obj[firstKey] = "<omitted>";
21373
+ }
19463
21374
  }
19464
21375
  } else {
19465
21376
  if (obj && typeof obj === "object" && firstKey in obj) {
19466
21377
  omitAtPath(
19467
21378
  obj[firstKey],
19468
- remainingKeys
21379
+ remainingKeys,
21380
+ deleteLeaf
19469
21381
  );
19470
21382
  }
19471
21383
  }
19472
21384
  }
19473
- function omit(obj, paths) {
21385
+ function omit(obj, paths, deletePaths = []) {
19474
21386
  const result = deepCopy(obj);
21387
+ const deletePathSet = new Set(deletePaths);
19475
21388
  for (const path8 of paths) {
19476
21389
  const keys = parsePath(path8);
19477
- omitAtPath(result, keys);
21390
+ omitAtPath(result, keys, deletePathSet.has(path8));
19478
21391
  }
19479
21392
  return result;
19480
21393
  }
@@ -33283,7 +35196,13 @@ var BraintrustObservabilityExporter = class {
33283
35196
  const args = {
33284
35197
  name: exported.name,
33285
35198
  spanAttributes: { type: spanTypeFor(exported.type) },
33286
- startTime: epochSeconds(exported.startTime)
35199
+ startTime: epochSeconds(exported.startTime),
35200
+ // Use the Mastra span id as the Braintrust row id so that
35201
+ // `logFeedback({ id: <mastra span id> })` (and Mastra's score events)
35202
+ // attach to the right row. Without this, `SpanImpl` auto-generates a
35203
+ // row id (`this._id = eventId ?? idGenerator.getSpanId()`) that no
35204
+ // external caller could know.
35205
+ event: { id: exported.id }
33287
35206
  };
33288
35207
  const parentRecord = exported.parentSpanId ? this.spans.get(exported.parentSpanId) : void 0;
33289
35208
  if (!this.capturedParent) {
@@ -35088,7 +37007,7 @@ var MAIN_ORIGIN = "https://www.braintrust.dev";
35088
37007
  var WHITELISTED_ORIGINS = [
35089
37008
  MAIN_ORIGIN,
35090
37009
  "https://www.braintrustdata.com",
35091
- new RegExp("https://.*.preview.braintrust.dev")
37010
+ new RegExp("^https://[^/]+\\.preview\\.braintrust\\.dev$")
35092
37011
  ].concat(
35093
37012
  process.env.WHITELISTED_ORIGIN ? [process.env.WHITELISTED_ORIGIN] : []
35094
37013
  ).concat(