braintrust 3.19.0 → 3.21.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 +2 -0
  3. package/dev/dist/index.d.mts +309 -199
  4. package/dev/dist/index.d.ts +309 -199
  5. package/dev/dist/index.js +2833 -987
  6. package/dev/dist/index.mjs +2294 -448
  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 +749 -45
  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 +1369 -848
  49. package/dist/browser.d.ts +1369 -848
  50. package/dist/browser.js +2735 -473
  51. package/dist/browser.mjs +2735 -473
  52. package/dist/{chunk-LPC4W2WX.js → chunk-BFGIH2ZJ.js} +4 -0
  53. package/dist/{chunk-37RLJF2U.js → chunk-FY7DAKA5.js} +3149 -1273
  54. package/dist/{chunk-Y7W7WP6H.mjs → chunk-KMGUTPB7.mjs} +4 -0
  55. package/dist/{chunk-VEQ2PCMC.mjs → chunk-O2P765XK.mjs} +2399 -523
  56. package/dist/cli.js +2267 -412
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +2735 -473
  60. package/dist/edge-light.mjs +2735 -473
  61. package/dist/index.d.mts +1848 -1327
  62. package/dist/index.d.ts +1848 -1327
  63. package/dist/index.js +754 -352
  64. package/dist/index.mjs +448 -46
  65. package/dist/instrumentation/index.d.mts +119 -21
  66. package/dist/instrumentation/index.d.ts +119 -21
  67. package/dist/instrumentation/index.js +2345 -512
  68. package/dist/instrumentation/index.mjs +2344 -512
  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 +2735 -473
  74. package/dist/workerd.mjs +2735 -473
  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 +13 -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.19.0",
1235
+ version: "3.21.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",
@@ -1439,24 +1441,31 @@ var require_package = __commonJS({
1439
1441
  zod: "^3.25.34"
1440
1442
  },
1441
1443
  dependencies: {
1442
- "@apm-js-collab/code-transformer": "^0.12.0",
1443
1444
  "@next/env": "^14.2.3",
1445
+ "@types/estree": "^1.0.8",
1444
1446
  "@vercel/functions": "^1.0.2",
1447
+ acorn: "^8.16.0",
1448
+ "acorn-import-attributes": "^1.9.5",
1445
1449
  ajv: "^8.20.0",
1446
1450
  argparse: "^2.0.1",
1451
+ astring: "^1.9.0",
1452
+ "cjs-module-lexer": "^2.2.0",
1447
1453
  "cli-progress": "^3.12.0",
1448
1454
  "cli-table3": "^0.6.5",
1449
1455
  cors: "^2.8.5",
1450
1456
  "dc-browser": "^1.0.4",
1451
1457
  dotenv: "^16.4.5",
1452
1458
  esbuild: "0.28.0",
1459
+ esquery: "^1.7.0",
1453
1460
  "eventsource-parser": "^1.1.2",
1454
1461
  express: "^5.2.1",
1455
1462
  "http-errors": "^2.0.0",
1463
+ meriyah: "^6.1.4",
1456
1464
  minimatch: "^10.2.5",
1457
1465
  "module-details-from-path": "^1.0.4",
1458
1466
  mustache: "^4.2.0",
1459
1467
  pluralize: "^8.0.0",
1468
+ semifies: "^1.0.0",
1460
1469
  "simple-git": "^3.36.0",
1461
1470
  "source-map": "^0.7.4",
1462
1471
  "termi-link": "^1.0.1",
@@ -1782,8 +1791,291 @@ var UUIDGenerator = class extends IDGenerator {
1782
1791
  return true;
1783
1792
  }
1784
1793
  };
1794
+ function generateHexId(bytes) {
1795
+ let result = "";
1796
+ for (let i = 0; i < bytes; i++) {
1797
+ result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
1798
+ }
1799
+ return result;
1800
+ }
1801
+ var OTELIDGenerator = class extends IDGenerator {
1802
+ getSpanId() {
1803
+ return generateHexId(8);
1804
+ }
1805
+ getTraceId() {
1806
+ return generateHexId(16);
1807
+ }
1808
+ shareRootSpanId() {
1809
+ return false;
1810
+ }
1811
+ };
1812
+ function parseEnvBool(name) {
1813
+ const raw = isomorph_default.getEnv(name);
1814
+ if (raw === void 0 || raw === null) {
1815
+ return false;
1816
+ }
1817
+ const normalized = raw.trim().toLowerCase();
1818
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
1819
+ }
1820
+ var _warnedLegacyUuidConflict = false;
1821
+ function resolveUseLegacyUuidIds() {
1822
+ const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
1823
+ if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
1824
+ if (legacy && !_warnedLegacyUuidConflict) {
1825
+ _warnedLegacyUuidConflict = true;
1826
+ debugLogger.warn(
1827
+ "BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
1828
+ );
1829
+ }
1830
+ return false;
1831
+ }
1832
+ return legacy;
1833
+ }
1785
1834
  function getIdGenerator() {
1786
- return globalThis.BRAINTRUST_ID_GENERATOR !== void 0 ? new globalThis.BRAINTRUST_ID_GENERATOR() : new UUIDGenerator();
1835
+ if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
1836
+ return new globalThis.BRAINTRUST_ID_GENERATOR();
1837
+ }
1838
+ return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
1839
+ }
1840
+
1841
+ // src/propagation.ts
1842
+ var TRACEPARENT_HEADER = "traceparent";
1843
+ var TRACESTATE_HEADER = "tracestate";
1844
+ var BAGGAGE_HEADER = "baggage";
1845
+ var BRAINTRUST_PARENT_KEY = "braintrust.parent";
1846
+ var DEFAULT_TRACE_FLAGS = "01";
1847
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
1848
+ var ZERO_TRACE_ID = "0".repeat(32);
1849
+ var ZERO_SPAN_ID = "0".repeat(16);
1850
+ var MAX_BAGGAGE_LENGTH = 8192;
1851
+ var MAX_BAGGAGE_MEMBERS = 64;
1852
+ var _utf8Encoder = new TextEncoder();
1853
+ function utf8ByteLength(value) {
1854
+ return _utf8Encoder.encode(value).length;
1855
+ }
1856
+ function capBaggageToMemberBoundary(value) {
1857
+ const totalBytes = utf8ByteLength(value);
1858
+ const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
1859
+ let commaCount = 0;
1860
+ for (let i = 0; i < value.length; i++) {
1861
+ if (value.charCodeAt(i) === 44) {
1862
+ commaCount++;
1863
+ }
1864
+ }
1865
+ const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
1866
+ if (withinBytes && withinMembers) {
1867
+ return value;
1868
+ }
1869
+ const kept = [];
1870
+ let length = 0;
1871
+ for (const rawMember of value.split(",")) {
1872
+ if (kept.length >= MAX_BAGGAGE_MEMBERS) {
1873
+ break;
1874
+ }
1875
+ const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
1876
+ if (length + cost > MAX_BAGGAGE_LENGTH) {
1877
+ break;
1878
+ }
1879
+ kept.push(rawMember);
1880
+ length += cost;
1881
+ }
1882
+ if (!kept.length) {
1883
+ return "";
1884
+ }
1885
+ return kept.join(",");
1886
+ }
1887
+ function isTraceContextHeaderTupleArray(value) {
1888
+ return Array.isArray(value) && value.every(
1889
+ (item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
1890
+ );
1891
+ }
1892
+ function isListHeader(name) {
1893
+ const lowered = name.toLowerCase();
1894
+ return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
1895
+ }
1896
+ function headerValueToString(value, name) {
1897
+ if (value === void 0 || value === null) {
1898
+ return void 0;
1899
+ }
1900
+ if (Array.isArray(value)) {
1901
+ const stringValues = value.filter((item) => {
1902
+ return typeof item === "string";
1903
+ });
1904
+ if (!stringValues.length) {
1905
+ return void 0;
1906
+ }
1907
+ return isListHeader(name) ? stringValues.join(",") : stringValues[0];
1908
+ }
1909
+ return typeof value === "string" ? value : String(value);
1910
+ }
1911
+ function getHeader(headers, name) {
1912
+ if (!headers) {
1913
+ return void 0;
1914
+ }
1915
+ if (isTraceContextHeaderTupleArray(headers)) {
1916
+ const lowered2 = name.toLowerCase();
1917
+ const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
1918
+ if (!matches.length) {
1919
+ return void 0;
1920
+ }
1921
+ return headerValueToString(matches, name);
1922
+ }
1923
+ const getter = headers.get;
1924
+ if (typeof getter === "function") {
1925
+ try {
1926
+ const value = headerValueToString(getter.call(headers, name), name);
1927
+ if (value !== void 0) {
1928
+ return value;
1929
+ }
1930
+ } catch {
1931
+ }
1932
+ }
1933
+ const nodeGetter = headers.getHeader;
1934
+ if (typeof nodeGetter === "function") {
1935
+ try {
1936
+ const value = headerValueToString(nodeGetter.call(headers, name), name);
1937
+ if (value !== void 0) {
1938
+ return value;
1939
+ }
1940
+ } catch {
1941
+ }
1942
+ }
1943
+ const headerBag = headers;
1944
+ const exact = headerValueToString(headerBag[name], name);
1945
+ if (exact !== void 0) {
1946
+ return exact;
1947
+ }
1948
+ const lowered = name.toLowerCase();
1949
+ for (const key of Object.keys(headers)) {
1950
+ if (key !== name && key.toLowerCase() === lowered) {
1951
+ const value = headerValueToString(headerBag[key], name);
1952
+ if (value !== void 0) {
1953
+ return value;
1954
+ }
1955
+ }
1956
+ }
1957
+ return void 0;
1958
+ }
1959
+ function isHex(value, length) {
1960
+ if (typeof value !== "string" || value.length !== length) {
1961
+ return false;
1962
+ }
1963
+ for (let i = 0; i < value.length; i++) {
1964
+ const c = value[i];
1965
+ const isDigit = c >= "0" && c <= "9";
1966
+ const isLowerHex = c >= "a" && c <= "f";
1967
+ if (!isDigit && !isLowerHex) {
1968
+ return false;
1969
+ }
1970
+ }
1971
+ return true;
1972
+ }
1973
+ function parseTraceparent(value) {
1974
+ if (!value || typeof value !== "string") {
1975
+ return void 0;
1976
+ }
1977
+ const match = TRACEPARENT_RE.exec(value.trim());
1978
+ if (!match) {
1979
+ return void 0;
1980
+ }
1981
+ const traceId = match[1];
1982
+ const spanId = match[2];
1983
+ const traceFlags = match[3];
1984
+ if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
1985
+ return void 0;
1986
+ }
1987
+ return { traceId, spanId, traceFlags };
1988
+ }
1989
+ function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
1990
+ if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
1991
+ return void 0;
1992
+ }
1993
+ if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
1994
+ return void 0;
1995
+ }
1996
+ const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
1997
+ return `00-${traceId}-${spanId}-${flags}`;
1998
+ }
1999
+ function percentEncode(value) {
2000
+ return encodeURIComponent(value);
2001
+ }
2002
+ function percentDecode(value) {
2003
+ if (!value.includes("%")) {
2004
+ return value;
2005
+ }
2006
+ try {
2007
+ return decodeURIComponent(value);
2008
+ } catch {
2009
+ return value;
2010
+ }
2011
+ }
2012
+ function parseBaggage(value) {
2013
+ const result = {};
2014
+ if (!value || typeof value !== "string") {
2015
+ return result;
2016
+ }
2017
+ const bounded = capBaggageToMemberBoundary(value);
2018
+ for (let member of bounded.split(",")) {
2019
+ member = member.trim();
2020
+ if (!member || !member.includes("=")) {
2021
+ continue;
2022
+ }
2023
+ member = member.split(";", 1)[0];
2024
+ const eq = member.indexOf("=");
2025
+ const key = percentDecode(member.slice(0, eq).trim());
2026
+ const val = member.slice(eq + 1).trim();
2027
+ if (!key) {
2028
+ continue;
2029
+ }
2030
+ result[key] = percentDecode(val);
2031
+ }
2032
+ return result;
2033
+ }
2034
+ function mergeBaggage(existing, braintrustParent) {
2035
+ let btMember = void 0;
2036
+ if (braintrustParent) {
2037
+ const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
2038
+ const encodedVal = percentEncode(String(braintrustParent));
2039
+ btMember = `${encodedKey}=${encodedVal}`;
2040
+ if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
2041
+ btMember = void 0;
2042
+ }
2043
+ }
2044
+ let byteBudget = MAX_BAGGAGE_LENGTH;
2045
+ let memberBudget = MAX_BAGGAGE_MEMBERS;
2046
+ if (btMember !== void 0) {
2047
+ byteBudget -= utf8ByteLength(btMember) + 1;
2048
+ memberBudget -= 1;
2049
+ }
2050
+ const relayed = [];
2051
+ let length = 0;
2052
+ if (existing && typeof existing === "string") {
2053
+ for (const rawMember of existing.split(",")) {
2054
+ const member = rawMember.trim();
2055
+ if (!member || !member.includes("=")) {
2056
+ continue;
2057
+ }
2058
+ const keyPart = member.split(";", 1)[0].split("=", 1)[0];
2059
+ const key = percentDecode(keyPart.trim());
2060
+ if (key === BRAINTRUST_PARENT_KEY) {
2061
+ continue;
2062
+ }
2063
+ if (relayed.length >= memberBudget) {
2064
+ break;
2065
+ }
2066
+ const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
2067
+ if (length + cost > byteBudget) {
2068
+ break;
2069
+ }
2070
+ relayed.push(member);
2071
+ length += cost;
2072
+ }
2073
+ }
2074
+ const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
2075
+ if (!members.length) {
2076
+ return void 0;
2077
+ }
2078
+ return members.join(",");
1787
2079
  }
1788
2080
 
1789
2081
  // util/db_fields.ts
@@ -2391,7 +2683,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
2391
2683
  case 3 /* PLAYGROUND_LOGS */:
2392
2684
  return { prompt_session_id: this.data.object_id, log_id: "x" };
2393
2685
  default:
2394
- const _ = this.data.object_type;
2686
+ this.data.object_type;
2395
2687
  throw new Error("Impossible");
2396
2688
  }
2397
2689
  }
@@ -2931,7 +3223,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
2931
3223
  case 3 /* PLAYGROUND_LOGS */:
2932
3224
  return { prompt_session_id: this.data.object_id, log_id: "x" };
2933
3225
  default:
2934
- const _ = this.data.object_type;
3226
+ this.data.object_type;
2935
3227
  throw new Error(`Invalid object_type ${this.data.object_type}`);
2936
3228
  }
2937
3229
  }
@@ -3126,7 +3418,8 @@ var AclObjectType = import_v36.z.union([
3126
3418
  "role",
3127
3419
  "org_member",
3128
3420
  "project_log",
3129
- "org_project"
3421
+ "org_project",
3422
+ "org_audit_logs"
3130
3423
  ]),
3131
3424
  import_v36.z.null()
3132
3425
  ]);
@@ -3152,6 +3445,17 @@ var Acl = import_v36.z.object({
3152
3445
  _object_org_id: import_v36.z.string().uuid(),
3153
3446
  created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
3154
3447
  });
3448
+ var Agent = import_v36.z.object({
3449
+ id: import_v36.z.string().uuid(),
3450
+ project_id: import_v36.z.string().uuid(),
3451
+ user_id: import_v36.z.string().uuid(),
3452
+ created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3453
+ name: import_v36.z.string(),
3454
+ slug: import_v36.z.string(),
3455
+ kind: import_v36.z.string(),
3456
+ description: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3457
+ metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional()
3458
+ });
3155
3459
  var AISecret = import_v36.z.object({
3156
3460
  id: import_v36.z.string().uuid(),
3157
3461
  created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
@@ -3298,6 +3602,7 @@ var AttachmentStatus = import_v36.z.object({
3298
3602
  upload_status: UploadStatus,
3299
3603
  error_message: import_v36.z.string().optional()
3300
3604
  });
3605
+ var AutomationStatus = import_v36.z.enum(["active", "paused"]);
3301
3606
  var FunctionTypeEnum = import_v36.z.enum([
3302
3607
  "llm",
3303
3608
  "scorer",
@@ -3343,7 +3648,9 @@ var TopicMapData = import_v36.z.object({
3343
3648
  topic_names: import_v36.z.record(import_v36.z.string()).optional(),
3344
3649
  generation_settings: TopicMapGenerationSettings.optional(),
3345
3650
  disable_reconciliation: import_v36.z.boolean().optional(),
3346
- distance_threshold: import_v36.z.number().optional()
3651
+ distance_threshold: import_v36.z.number().optional(),
3652
+ btql_filter: import_v36.z.string().optional(),
3653
+ automation_btql_filter: import_v36.z.string().optional()
3347
3654
  });
3348
3655
  var BatchedFacetData = import_v36.z.object({
3349
3656
  type: import_v36.z.literal("batched_facet"),
@@ -3626,7 +3933,7 @@ var DatasetEvent = import_v36.z.object({
3626
3933
  origin: ObjectReferenceNullish.optional(),
3627
3934
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3628
3935
  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(),
3936
+ 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
3937
  classifications: import_v36.z.union([
3631
3938
  import_v36.z.record(
3632
3939
  import_v36.z.array(
@@ -3778,7 +4085,7 @@ var ExperimentEvent = import_v36.z.object({
3778
4085
  origin: ObjectReferenceNullish.optional(),
3779
4086
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3780
4087
  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(),
4088
+ 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
4089
  classifications: import_v36.z.union([
3783
4090
  import_v36.z.record(
3784
4091
  import_v36.z.array(
@@ -3916,7 +4223,8 @@ var PromptParserNullish = import_v36.z.union([
3916
4223
  use_cot: import_v36.z.boolean(),
3917
4224
  choice_scores: import_v36.z.record(import_v36.z.number().gte(0).lte(1)).optional(),
3918
4225
  choice: import_v36.z.array(import_v36.z.string()).optional(),
3919
- allow_no_match: import_v36.z.boolean().optional()
4226
+ allow_no_match: import_v36.z.boolean().optional(),
4227
+ allow_skip: import_v36.z.boolean().optional()
3920
4228
  }),
3921
4229
  import_v36.z.null()
3922
4230
  ]);
@@ -4246,6 +4554,9 @@ var Group = import_v36.z.object({
4246
4554
  var GroupScope = import_v36.z.object({
4247
4555
  type: import_v36.z.literal("group"),
4248
4556
  group_by: import_v36.z.string(),
4557
+ interval_seconds: import_v36.z.number().gte(1).optional(),
4558
+ max_traces: import_v36.z.number().int().gte(1).lte(64).optional(),
4559
+ placement: import_v36.z.enum(["first", "each"]),
4249
4560
  idle_seconds: import_v36.z.number().optional()
4250
4561
  });
4251
4562
  var IfExists = import_v36.z.enum(["error", "ignore", "replace"]);
@@ -4394,6 +4705,10 @@ var RetentionObjectType = import_v36.z.enum([
4394
4705
  "experiment",
4395
4706
  "dataset"
4396
4707
  ]);
4708
+ var TopicAutomationFacetModel = import_v36.z.union([
4709
+ import_v36.z.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
4710
+ import_v36.z.null()
4711
+ ]);
4397
4712
  var TopicMapFunctionAutomation = import_v36.z.object({
4398
4713
  function: SavedFunctionId.and(import_v36.z.unknown()),
4399
4714
  btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
@@ -4406,7 +4721,9 @@ var TopicAutomationDataScope = import_v36.z.union([
4406
4721
  ]);
4407
4722
  var TopicAutomationConfig = import_v36.z.object({
4408
4723
  event_type: import_v36.z.literal("topic"),
4724
+ status: AutomationStatus.optional(),
4409
4725
  sampling_rate: import_v36.z.number().gte(0).lte(1),
4726
+ facet_model: TopicAutomationFacetModel.optional(),
4410
4727
  facet_functions: import_v36.z.array(SavedFunctionId),
4411
4728
  topic_map_functions: import_v36.z.array(TopicMapFunctionAutomation),
4412
4729
  scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
@@ -4420,6 +4737,19 @@ var TopicAutomationConfig = import_v36.z.object({
4420
4737
  import_v36.z.null()
4421
4738
  ]).optional()
4422
4739
  });
4740
+ var TopicDigestAutomationConfig = import_v36.z.object({
4741
+ event_type: import_v36.z.literal("topic_digest"),
4742
+ status: AutomationStatus.optional(),
4743
+ window_seconds: import_v36.z.number().int().gte(3600).lte(2592e3).optional().default(86400),
4744
+ scheduled_time_minutes_utc: import_v36.z.number().int().gte(0).lte(1439),
4745
+ action: import_v36.z.object({
4746
+ type: import_v36.z.literal("slack"),
4747
+ workspace_id: import_v36.z.string(),
4748
+ channel: import_v36.z.string(),
4749
+ message_template: import_v36.z.string().optional()
4750
+ }),
4751
+ topic_map_function_ids: import_v36.z.array(import_v36.z.string()).max(10).optional()
4752
+ });
4423
4753
  var ProjectAutomation = import_v36.z.object({
4424
4754
  id: import_v36.z.string().uuid(),
4425
4755
  project_id: import_v36.z.string().uuid(),
@@ -4444,6 +4774,7 @@ var ProjectAutomation = import_v36.z.object({
4444
4774
  }),
4445
4775
  import_v36.z.object({
4446
4776
  event_type: import_v36.z.literal("btql_export"),
4777
+ status: AutomationStatus.optional(),
4447
4778
  export_definition: import_v36.z.union([
4448
4779
  import_v36.z.object({ type: import_v36.z.literal("log_traces") }),
4449
4780
  import_v36.z.object({ type: import_v36.z.literal("log_spans") }),
@@ -4466,6 +4797,21 @@ var ProjectAutomation = import_v36.z.object({
4466
4797
  ]),
4467
4798
  batch_size: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
4468
4799
  }),
4800
+ import_v36.z.object({
4801
+ event_type: import_v36.z.literal("async_query"),
4802
+ status: AutomationStatus.optional(),
4803
+ created_by_user_id: import_v36.z.string().uuid(),
4804
+ object_type: import_v36.z.enum([
4805
+ "project_logs",
4806
+ "experiment",
4807
+ "dataset",
4808
+ "playground_logs"
4809
+ ]),
4810
+ object_id: import_v36.z.string(),
4811
+ query: import_v36.z.string(),
4812
+ format: import_v36.z.literal("jsonl"),
4813
+ batch_size: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
4814
+ }),
4469
4815
  import_v36.z.object({
4470
4816
  event_type: import_v36.z.literal("retention"),
4471
4817
  object_type: RetentionObjectType,
@@ -4484,7 +4830,8 @@ var ProjectAutomation = import_v36.z.object({
4484
4830
  })
4485
4831
  ])
4486
4832
  }),
4487
- TopicAutomationConfig
4833
+ TopicAutomationConfig,
4834
+ TopicDigestAutomationConfig
4488
4835
  ])
4489
4836
  });
4490
4837
  var ProjectLogsEvent = import_v36.z.object({
@@ -4523,7 +4870,7 @@ var ProjectLogsEvent = import_v36.z.object({
4523
4870
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
4524
4871
  audit_data: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
4525
4872
  _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(),
4873
+ 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
4874
  classifications: import_v36.z.union([
4528
4875
  import_v36.z.record(
4529
4876
  import_v36.z.array(
@@ -4572,11 +4919,34 @@ var ProjectScoreCategories = import_v36.z.union([
4572
4919
  import_v36.z.array(import_v36.z.string()),
4573
4920
  import_v36.z.null()
4574
4921
  ]);
4922
+ var ProjectScoreCondition = import_v36.z.union([
4923
+ import_v36.z.object({
4924
+ when: import_v36.z.object({
4925
+ clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
4926
+ subspan_clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
4927
+ trace_clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()])
4928
+ }).partial(),
4929
+ behavior: import_v36.z.literal("hidden").optional().default("hidden")
4930
+ }),
4931
+ import_v36.z.null()
4932
+ ]);
4575
4933
  var ProjectScoreConfig = import_v36.z.union([
4576
4934
  import_v36.z.object({
4577
4935
  multi_select: import_v36.z.union([import_v36.z.boolean(), import_v36.z.null()]),
4578
4936
  destination: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
4579
- online: OnlineScoreConfig
4937
+ visibility: import_v36.z.union([
4938
+ import_v36.z.object({
4939
+ users: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
4940
+ groups: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()])
4941
+ }).partial(),
4942
+ import_v36.z.null()
4943
+ ]),
4944
+ online: OnlineScoreConfig,
4945
+ condition: ProjectScoreCondition,
4946
+ object_types: import_v36.z.union([
4947
+ import_v36.z.array(import_v36.z.enum(["project_logs", "dataset", "experiment"])),
4948
+ import_v36.z.null()
4949
+ ])
4580
4950
  }).partial(),
4581
4951
  import_v36.z.null()
4582
4952
  ]);
@@ -4761,8 +5131,7 @@ var User = import_v36.z.object({
4761
5131
  family_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4762
5132
  email: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4763
5133
  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()
5134
+ created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
4766
5135
  });
4767
5136
  var ViewDataSearch = import_v36.z.union([
4768
5137
  import_v36.z.object({
@@ -6049,7 +6418,10 @@ var BraintrustContextManager = class extends ContextManager {
6049
6418
  }
6050
6419
  };
6051
6420
  function getSpanComponentsClass() {
6052
- return globalThis.BRAINTRUST_SPAN_COMPONENT ? globalThis.BRAINTRUST_SPAN_COMPONENT : SpanComponentsV3;
6421
+ if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
6422
+ return globalThis.BRAINTRUST_SPAN_COMPONENT;
6423
+ }
6424
+ return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
6053
6425
  }
6054
6426
  function getContextManager() {
6055
6427
  return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
@@ -6085,6 +6457,9 @@ var NoopSpan = class {
6085
6457
  async export() {
6086
6458
  return "";
6087
6459
  }
6460
+ inject(carrier) {
6461
+ return carrier ?? {};
6462
+ }
6088
6463
  async permalink() {
6089
6464
  return NOOP_SPAN_PERMALINK;
6090
6465
  }
@@ -6135,6 +6510,10 @@ var loginSchema = import_v38.z.strictObject({
6135
6510
  debugLogLevelDisabled: import_v38.z.boolean().optional()
6136
6511
  });
6137
6512
  var stateNonce = 0;
6513
+ var V1_PROXY_SUFFIX = "/v1/proxy";
6514
+ function normalizeProxyConnUrl(proxyUrl) {
6515
+ return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
6516
+ }
6138
6517
  var BraintrustState = class _BraintrustState {
6139
6518
  constructor(loginParams) {
6140
6519
  this.loginParams = loginParams;
@@ -6405,7 +6784,10 @@ var BraintrustState = class _BraintrustState {
6405
6784
  if (!this.proxyUrl) {
6406
6785
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
6407
6786
  }
6408
- this._proxyConn = new HTTPConnection(this.proxyUrl, this.fetch);
6787
+ this._proxyConn = new HTTPConnection(
6788
+ normalizeProxyConnUrl(this.proxyUrl),
6789
+ this.fetch
6790
+ );
6409
6791
  }
6410
6792
  return this._proxyConn;
6411
6793
  }
@@ -7091,7 +7473,7 @@ async function permalink(slug, opts) {
7091
7473
  return state.appUrl;
7092
7474
  };
7093
7475
  try {
7094
- const components = getSpanComponentsClass().fromStr(slug);
7476
+ const components = SpanComponentsV4.fromStr(slug);
7095
7477
  const object_type = spanObjectTypeV3ToString(components.data.object_type);
7096
7478
  const [orgName, appUrl, object_id] = await Promise.all([
7097
7479
  getOrgName(),
@@ -7115,35 +7497,47 @@ function startSpanParentArgs(args) {
7115
7497
  let argParentObjectId = void 0;
7116
7498
  let argParentSpanIds = void 0;
7117
7499
  let argPropagatedEvent = void 0;
7118
- if (args.parent) {
7500
+ let argPropagatedState = void 0;
7501
+ const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
7502
+ if (parentSlug) {
7119
7503
  if (args.parentSpanIds) {
7120
7504
  throw new Error("Cannot specify both parent and parentSpanIds");
7121
7505
  }
7122
- const parentComponents = getSpanComponentsClass().fromStr(args.parent);
7506
+ const parentComponents = SpanComponentsV4.fromStr(parentSlug);
7123
7507
  if (args.parentObjectType !== parentComponents.data.object_type) {
7124
7508
  throw new Error(
7125
7509
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
7126
7510
  );
7127
7511
  }
7128
7512
  argParentObjectId = args.parentObjectId;
7129
- if (parentComponents.data.row_id) {
7513
+ if (parentComponents.data.row_id && parentSpanIdsUsable(
7514
+ parentComponents.data.span_id,
7515
+ parentComponents.data.root_span_id
7516
+ )) {
7130
7517
  argParentSpanIds = {
7131
7518
  spanId: parentComponents.data.span_id,
7132
7519
  rootSpanId: parentComponents.data.root_span_id
7133
7520
  };
7134
7521
  }
7135
7522
  argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
7523
+ const propagatedState = args.propagatedState ?? parentPropagatedState;
7524
+ if (propagatedState) {
7525
+ const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
7526
+ argPropagatedState = w3cState;
7527
+ }
7136
7528
  } else {
7137
7529
  argParentObjectId = args.parentObjectId;
7138
7530
  argParentSpanIds = args.parentSpanIds;
7139
7531
  argPropagatedEvent = args.propagatedEvent;
7532
+ argPropagatedState = args.propagatedState;
7140
7533
  }
7141
7534
  return {
7142
7535
  parentObjectType: args.parentObjectType,
7143
7536
  parentObjectId: argParentObjectId,
7144
7537
  parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
7145
7538
  parentSpanIds: argParentSpanIds,
7146
- propagatedEvent: argPropagatedEvent
7539
+ propagatedEvent: argPropagatedEvent,
7540
+ propagatedState: argPropagatedState
7147
7541
  };
7148
7542
  }
7149
7543
  var Logger = class {
@@ -7344,6 +7738,22 @@ var Logger = class {
7344
7738
  _getLinkBaseUrl() {
7345
7739
  return _getLinkBaseUrl(this.state, this._linkArgs);
7346
7740
  }
7741
+ /**
7742
+ * Return this logger's Braintrust parent string (`project_id:<id>` or
7743
+ * `project_name:<name>`) for the `braintrust.parent` baggage entry, or
7744
+ * undefined when it cannot be determined synchronously.
7745
+ */
7746
+ _getOtelParent() {
7747
+ const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
7748
+ if (id) {
7749
+ return `project_id:${id}`;
7750
+ }
7751
+ const name = this.computeMetadataArgs?.project_name;
7752
+ if (name) {
7753
+ return `project_name:${name}`;
7754
+ }
7755
+ return void 0;
7756
+ }
7347
7757
  };
7348
7758
  function castLogger(logger, asyncFlush) {
7349
7759
  if (logger === void 0) return void 0;
@@ -7438,12 +7848,12 @@ function stringifyWithOverflowMeta(item) {
7438
7848
  object_ids: pickLogs3OverflowObjectIds(record),
7439
7849
  is_delete: record[OBJECT_DELETE_FIELD] === true,
7440
7850
  input_row: {
7441
- byte_size: utf8ByteLength(str)
7851
+ byte_size: utf8ByteLength2(str)
7442
7852
  }
7443
7853
  }
7444
7854
  };
7445
7855
  }
7446
- function utf8ByteLength(value) {
7856
+ function utf8ByteLength2(value) {
7447
7857
  if (typeof TextEncoder !== "undefined") {
7448
7858
  return new TextEncoder().encode(value).length;
7449
7859
  }
@@ -7774,7 +8184,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
7774
8184
  }) {
7775
8185
  const conn = await this.apiConn.get();
7776
8186
  const dataStr = constructLogs3Data(items);
7777
- const payloadBytes = utf8ByteLength(dataStr);
8187
+ const payloadBytes = utf8ByteLength2(dataStr);
7778
8188
  const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
7779
8189
  if (this.allPublishPayloadsDir) {
7780
8190
  await _HTTPBackgroundLogger.writePayloadToDir({
@@ -8366,6 +8776,8 @@ function initDataset(projectOrOptions, optionalOptions) {
8366
8776
  const normalizedVersion = selection.version;
8367
8777
  const normalizedEnvironment = selection.environment;
8368
8778
  const normalizedSnapshotName = selection.snapshotName;
8779
+ const cliInternalBtql = globalThis.__bt_eval_internal_btql;
8780
+ const internalBtql = cliInternalBtql === void 0 ? _internal_btql : _internal_btql === void 0 ? cliInternalBtql : isObject(_internal_btql) ? { ...cliInternalBtql, ..._internal_btql } : _internal_btql;
8369
8781
  const state = stateArg ?? _globalState;
8370
8782
  const lazyMetadata = new LazyValue(
8371
8783
  async () => {
@@ -8417,7 +8829,7 @@ function initDataset(projectOrOptions, optionalOptions) {
8417
8829
  lazyMetadata,
8418
8830
  typeof resolvedVersion === "string" ? resolvedVersion : void 0,
8419
8831
  legacy,
8420
- _internal_btql,
8832
+ internalBtql,
8421
8833
  resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
8422
8834
  ...resolvedVersion instanceof LazyValue ? {
8423
8835
  lazyPinnedVersion: resolvedVersion
@@ -8628,23 +9040,256 @@ function currentSpan(options) {
8628
9040
  const state = options?.state ?? _globalState;
8629
9041
  return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
8630
9042
  }
8631
- function getSpanParentObject(options) {
9043
+ function getSpanParentObjectAndPropagatedState(options) {
8632
9044
  const state = options?.state ?? _globalState;
8633
9045
  const parentSpan = currentSpan({ state });
8634
9046
  if (!Object.is(parentSpan, NOOP_SPAN)) {
8635
- return parentSpan;
9047
+ return { parentObject: parentSpan, propagatedState: void 0 };
9048
+ }
9049
+ const parent = options?.parent ?? state.currentParent.getStore();
9050
+ const { parentSlug, propagatedState } = normalizeParent(parent, state);
9051
+ if (parentSlug) {
9052
+ return {
9053
+ parentObject: SpanComponentsV4.fromStr(parentSlug),
9054
+ propagatedState
9055
+ };
8636
9056
  }
8637
- const parentStr = options?.parent ?? state.currentParent.getStore();
8638
- if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
8639
9057
  const experiment = currentExperiment();
8640
9058
  if (experiment) {
8641
- return experiment;
9059
+ return { parentObject: experiment, propagatedState: void 0 };
8642
9060
  }
8643
9061
  const logger = currentLogger(options);
8644
9062
  if (logger) {
8645
- return logger;
9063
+ return { parentObject: logger, propagatedState: void 0 };
8646
9064
  }
8647
- return NOOP_SPAN;
9065
+ return { parentObject: NOOP_SPAN, propagatedState: void 0 };
9066
+ }
9067
+ function getSpanParentObject(options) {
9068
+ return getSpanParentObjectAndPropagatedState(options).parentObject;
9069
+ }
9070
+ function currentBraintrustParent(state) {
9071
+ const resolvedState = state ?? _globalState;
9072
+ const experiment = currentExperiment({ state: resolvedState });
9073
+ if (experiment) {
9074
+ try {
9075
+ return experiment._getOtelParent() ?? void 0;
9076
+ } catch {
9077
+ return void 0;
9078
+ }
9079
+ }
9080
+ const logger = currentLogger({ state: resolvedState });
9081
+ if (logger) {
9082
+ try {
9083
+ return logger._getOtelParent() ?? void 0;
9084
+ } catch {
9085
+ return void 0;
9086
+ }
9087
+ }
9088
+ return void 0;
9089
+ }
9090
+ function braintrustParentToComponents(braintrustParent) {
9091
+ if (!braintrustParent) {
9092
+ return void 0;
9093
+ }
9094
+ if (braintrustParent.startsWith("project_id:")) {
9095
+ const objectId = braintrustParent.slice("project_id:".length);
9096
+ return objectId ? {
9097
+ objectType: 2 /* PROJECT_LOGS */,
9098
+ objectId,
9099
+ computeArgs: void 0
9100
+ } : void 0;
9101
+ }
9102
+ if (braintrustParent.startsWith("project_name:")) {
9103
+ const name = braintrustParent.slice("project_name:".length);
9104
+ return name ? {
9105
+ objectType: 2 /* PROJECT_LOGS */,
9106
+ objectId: void 0,
9107
+ computeArgs: { project_name: name }
9108
+ } : void 0;
9109
+ }
9110
+ if (braintrustParent.startsWith("experiment_id:")) {
9111
+ const objectId = braintrustParent.slice("experiment_id:".length);
9112
+ return objectId ? {
9113
+ objectType: 1 /* EXPERIMENT */,
9114
+ objectId,
9115
+ computeArgs: void 0
9116
+ } : void 0;
9117
+ }
9118
+ return void 0;
9119
+ }
9120
+ function isMutableHeaderTupleArray(carrier) {
9121
+ return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
9122
+ }
9123
+ function setHeader(carrier, name, value) {
9124
+ if (isMutableHeaderTupleArray(carrier)) {
9125
+ const lowered2 = name.toLowerCase();
9126
+ for (let i = carrier.length - 1; i >= 0; i--) {
9127
+ if (carrier[i][0].toLowerCase() === lowered2) {
9128
+ carrier.splice(i, 1);
9129
+ }
9130
+ }
9131
+ carrier.push([name, value]);
9132
+ return;
9133
+ }
9134
+ const setter = carrier.set;
9135
+ if (typeof setter === "function") {
9136
+ const deleter = carrier.delete;
9137
+ if (typeof deleter === "function") {
9138
+ try {
9139
+ deleter.call(carrier, name);
9140
+ } catch {
9141
+ }
9142
+ }
9143
+ setter.call(carrier, name, value);
9144
+ return;
9145
+ }
9146
+ const nodeSetter = carrier.setHeader;
9147
+ if (typeof nodeSetter === "function") {
9148
+ const remover = carrier.removeHeader;
9149
+ if (typeof remover === "function") {
9150
+ try {
9151
+ remover.call(carrier, name);
9152
+ } catch {
9153
+ }
9154
+ }
9155
+ nodeSetter.call(carrier, name, value);
9156
+ return;
9157
+ }
9158
+ const headerSetter = carrier.header;
9159
+ if (typeof headerSetter === "function") {
9160
+ const deleter = carrier.delete;
9161
+ if (typeof deleter === "function") {
9162
+ try {
9163
+ deleter.call(carrier, name);
9164
+ } catch {
9165
+ }
9166
+ }
9167
+ const remover = carrier.removeHeader;
9168
+ if (typeof remover === "function") {
9169
+ try {
9170
+ remover.call(carrier, name);
9171
+ } catch {
9172
+ }
9173
+ }
9174
+ headerSetter.call(carrier, name, value);
9175
+ return;
9176
+ }
9177
+ const headerBag = carrier;
9178
+ const lowered = name.toLowerCase();
9179
+ for (const key of Object.keys(headerBag)) {
9180
+ if (key !== name && key.toLowerCase() === lowered) {
9181
+ delete headerBag[key];
9182
+ }
9183
+ }
9184
+ headerBag[name] = value;
9185
+ }
9186
+ function deleteHeader(carrier, name) {
9187
+ const lowered = name.toLowerCase();
9188
+ if (isMutableHeaderTupleArray(carrier)) {
9189
+ for (let i = carrier.length - 1; i >= 0; i--) {
9190
+ if (carrier[i][0].toLowerCase() === lowered) {
9191
+ carrier.splice(i, 1);
9192
+ }
9193
+ }
9194
+ return;
9195
+ }
9196
+ const deleter = carrier.delete;
9197
+ if (typeof deleter === "function") {
9198
+ try {
9199
+ deleter.call(carrier, name);
9200
+ return;
9201
+ } catch {
9202
+ }
9203
+ }
9204
+ const remover = carrier.removeHeader;
9205
+ if (typeof remover === "function") {
9206
+ try {
9207
+ remover.call(carrier, name);
9208
+ return;
9209
+ } catch {
9210
+ }
9211
+ }
9212
+ const headerBag = carrier;
9213
+ for (const key of Object.keys(headerBag)) {
9214
+ if (key.toLowerCase() === lowered) {
9215
+ delete headerBag[key];
9216
+ }
9217
+ }
9218
+ }
9219
+ function _injectIntoCarrier(carrier, args) {
9220
+ const traceFlags = args.propagatedState?.traceFlags;
9221
+ const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
9222
+ if (traceparent === void 0) {
9223
+ return;
9224
+ }
9225
+ setHeader(carrier, TRACEPARENT_HEADER, traceparent);
9226
+ const tracestate = args.propagatedState?.tracestate;
9227
+ if (tracestate) {
9228
+ setHeader(carrier, TRACESTATE_HEADER, tracestate);
9229
+ }
9230
+ const existing = getHeader(carrier, BAGGAGE_HEADER);
9231
+ const baggageValue = mergeBaggage(existing, args.braintrustParent);
9232
+ if (baggageValue !== void 0) {
9233
+ setHeader(carrier, BAGGAGE_HEADER, baggageValue);
9234
+ } else if (existing !== void 0) {
9235
+ deleteHeader(carrier, BAGGAGE_HEADER);
9236
+ }
9237
+ }
9238
+ function resolveW3cParent(context2, state) {
9239
+ const traceparent = getHeader(context2, TRACEPARENT_HEADER);
9240
+ const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
9241
+ if (parsed === void 0) {
9242
+ return { parentSlug: void 0, propagatedState: void 0 };
9243
+ }
9244
+ const { traceId, spanId, traceFlags } = parsed;
9245
+ let braintrustParent = void 0;
9246
+ const baggageValue = getHeader(context2, BAGGAGE_HEADER);
9247
+ if (baggageValue) {
9248
+ braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
9249
+ }
9250
+ if (!braintrustParent) {
9251
+ braintrustParent = currentBraintrustParent(state);
9252
+ }
9253
+ if (!braintrustParent) {
9254
+ debugLogger.warn(
9255
+ "Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
9256
+ );
9257
+ return { parentSlug: void 0, propagatedState: void 0 };
9258
+ }
9259
+ const parsedParent = braintrustParentToComponents(braintrustParent);
9260
+ if (parsedParent === void 0) {
9261
+ debugLogger.warn(
9262
+ `Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
9263
+ );
9264
+ return { parentSlug: void 0, propagatedState: void 0 };
9265
+ }
9266
+ const { objectType, objectId, computeArgs } = parsedParent;
9267
+ const tracestate = getHeader(context2, TRACESTATE_HEADER);
9268
+ const slug = new SpanComponentsV4({
9269
+ object_type: objectType,
9270
+ ...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
9271
+ row_id: "bt-propagation",
9272
+ // non-empty to enable span_id/root_span_id
9273
+ span_id: spanId,
9274
+ root_span_id: traceId
9275
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
9276
+ }).toStr();
9277
+ return {
9278
+ parentSlug: slug,
9279
+ propagatedState: { tracestate, traceFlags, braintrustParent }
9280
+ };
9281
+ }
9282
+ function normalizeParent(parent, state) {
9283
+ if (parent && typeof parent === "object") {
9284
+ return resolveW3cParent(parent, state);
9285
+ }
9286
+ return {
9287
+ parentSlug: parent ?? void 0,
9288
+ propagatedState: void 0
9289
+ };
9290
+ }
9291
+ function parentSpanIdsUsable(spanId, rootSpanId) {
9292
+ return Boolean(spanId) && Boolean(rootSpanId);
8648
9293
  }
8649
9294
  function logError(span, error2) {
8650
9295
  let errorMessage = "<error>";
@@ -8696,19 +9341,23 @@ async function flush(options) {
8696
9341
  }
8697
9342
  function startSpanAndIsLogger(args) {
8698
9343
  const state = args?.state ?? _globalState;
8699
- const parentObject = getSpanParentObject({
9344
+ const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
8700
9345
  asyncFlush: args?.asyncFlush,
8701
9346
  parent: args?.parent,
8702
9347
  state
8703
9348
  });
8704
9349
  if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
8705
- const parentSpanIds = parentObject.data.row_id ? {
9350
+ const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
9351
+ parentObject.data.span_id,
9352
+ parentObject.data.root_span_id
9353
+ ) ? {
8706
9354
  spanId: parentObject.data.span_id,
8707
9355
  rootSpanId: parentObject.data.root_span_id
8708
9356
  } : void 0;
9357
+ const { parent: _ignoredParent, ...spanArgs } = args ?? {};
8709
9358
  const span = new SpanImpl({
8710
9359
  state,
8711
- ...args,
9360
+ ...spanArgs,
8712
9361
  parentObjectType: parentObject.data.object_type,
8713
9362
  parentObjectId: new LazyValue(
8714
9363
  spanComponentsToObjectIdLambda(state, parentObject)
@@ -8716,7 +9365,8 @@ function startSpanAndIsLogger(args) {
8716
9365
  parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
8717
9366
  parentSpanIds,
8718
9367
  propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8719
- (parentObject.data.propagated_event ?? void 0)
9368
+ (parentObject.data.propagated_event ?? void 0),
9369
+ propagatedState
8720
9370
  });
8721
9371
  return {
8722
9372
  span,
@@ -8959,11 +9609,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
8959
9609
  var DEFAULT_FETCH_BATCH_SIZE = 1e3;
8960
9610
  var MAX_BTQL_ITERATIONS = 1e4;
8961
9611
  var ObjectFetcher = class {
8962
- constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
9612
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
8963
9613
  this.objectType = objectType;
8964
9614
  this.pinnedVersion = pinnedVersion;
8965
9615
  this.mutateRecord = mutateRecord;
8966
9616
  this._internal_btql = _internal_btql;
9617
+ this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
8967
9618
  }
8968
9619
  _fetchedData = void 0;
8969
9620
  get id() {
@@ -9022,7 +9673,7 @@ var ObjectFetcher = class {
9022
9673
  ...internalBtqlWithoutReservedQueryKeys
9023
9674
  },
9024
9675
  use_columnstore: false,
9025
- brainstore_realtime: true,
9676
+ brainstore_realtime: this._internalBrainstoreRealtime,
9026
9677
  query_source: `js_sdk_object_fetcher_${this.objectType}`,
9027
9678
  ...this.pinnedVersion !== void 0 ? {
9028
9679
  version: this.pinnedVersion
@@ -9371,6 +10022,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
9371
10022
  object_id: await this.id
9372
10023
  }).toStr();
9373
10024
  }
10025
+ /**
10026
+ * Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
10027
+ * the `braintrust.parent` baggage entry, or undefined when it cannot be
10028
+ * determined synchronously.
10029
+ */
10030
+ _getOtelParent() {
10031
+ const id = this.lazyId.getSync().value;
10032
+ return id ? `experiment_id:${id}` : void 0;
10033
+ }
9374
10034
  /**
9375
10035
  * Flush any pending rows to the server.
9376
10036
  */
@@ -9413,7 +10073,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9413
10073
  async *asDataset(options) {
9414
10074
  const records = this.fetch(options);
9415
10075
  for await (const record of records) {
9416
- if (record.root_span_id !== record.span_id) {
10076
+ const isRoot = record.is_root ?? record.root_span_id === record.span_id;
10077
+ if (!isRoot) {
9417
10078
  continue;
9418
10079
  }
9419
10080
  const { output, expected: expectedRecord, metadata } = record;
@@ -9475,9 +10136,16 @@ var SpanImpl = class _SpanImpl {
9475
10136
  _spanId;
9476
10137
  _rootSpanId;
9477
10138
  _spanParents;
10139
+ // Inbound W3C trace-context state (tracestate + raw traceparent flags) to
10140
+ // forward on outbound propagation. Captured at the span that received it (via
10141
+ // extractTraceContextFromHeaders) and inherited by all subspans, so that any
10142
+ // inject() within the trace re-emits the upstream state unchanged, per the W3C
10143
+ // Trace Context spec. Not interpreted.
10144
+ _propagatedState;
9478
10145
  kind = "span";
9479
10146
  constructor(args) {
9480
10147
  this._state = args.state;
10148
+ this._propagatedState = args.propagatedState;
9481
10149
  const spanAttributes = args.spanAttributes ?? {};
9482
10150
  const rawEvent = args.event ?? {};
9483
10151
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -9593,7 +10261,7 @@ var SpanImpl = class _SpanImpl {
9593
10261
  tags: partialRecord.tags,
9594
10262
  span_id: this._spanId,
9595
10263
  span_parents: this._spanParents,
9596
- is_root: this._spanId === this._rootSpanId,
10264
+ is_root: !this._spanParents || this._spanParents.length === 0,
9597
10265
  span_attributes: partialRecord.span_attributes
9598
10266
  };
9599
10267
  this._state.spanCache.queueWrite(
@@ -9655,7 +10323,8 @@ var SpanImpl = class _SpanImpl {
9655
10323
  parentObjectId: this.parentObjectId,
9656
10324
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
9657
10325
  parentSpanIds,
9658
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
10326
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
10327
+ propagatedState: this._propagatedState
9659
10328
  })
9660
10329
  });
9661
10330
  }
@@ -9674,7 +10343,8 @@ var SpanImpl = class _SpanImpl {
9674
10343
  parentObjectId: this.parentObjectId,
9675
10344
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
9676
10345
  parentSpanIds,
9677
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
10346
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
10347
+ propagatedState: this._propagatedState
9678
10348
  }),
9679
10349
  spanId
9680
10350
  });
@@ -9702,6 +10372,42 @@ var SpanImpl = class _SpanImpl {
9702
10372
  propagated_event: this.propagatedEvent
9703
10373
  }).toStr();
9704
10374
  }
10375
+ /**
10376
+ * Return this span's Braintrust parent string (`project_id:<id>`,
10377
+ * `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
10378
+ * baggage entry, or undefined when it cannot be determined synchronously.
10379
+ */
10380
+ _getOtelParent() {
10381
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
10382
+ const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
10383
+ const name = this.parentComputeObjectMetadataArgs?.project_name;
10384
+ if (id) {
10385
+ return `project_id:${id}`;
10386
+ } else if (name) {
10387
+ return `project_name:${name}`;
10388
+ }
10389
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
10390
+ const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
10391
+ if (id) {
10392
+ return `experiment_id:${id}`;
10393
+ }
10394
+ }
10395
+ return void 0;
10396
+ }
10397
+ inject(carrier) {
10398
+ const resolvedCarrier = carrier ?? {};
10399
+ try {
10400
+ _injectIntoCarrier(resolvedCarrier, {
10401
+ traceId: this._rootSpanId,
10402
+ spanId: this._spanId,
10403
+ braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
10404
+ propagatedState: this._propagatedState
10405
+ });
10406
+ } catch (e) {
10407
+ debugLogger.warn(`Error injecting trace context: ${e}`);
10408
+ }
10409
+ return resolvedCarrier;
10410
+ }
9705
10411
  async permalink() {
9706
10412
  return await permalink(await this.export(), {
9707
10413
  state: this._state
@@ -9837,6 +10543,7 @@ var Dataset2 = class extends ObjectFetcher {
9837
10543
  _internal_btql
9838
10544
  );
9839
10545
  this.state = state;
10546
+ void this.__braintrust_dataset_marker;
9840
10547
  this.lazyMetadata = lazyMetadata;
9841
10548
  this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
9842
10549
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
@@ -10351,6 +11058,7 @@ var Prompt2 = class _Prompt {
10351
11058
  this.metadata = metadata;
10352
11059
  this.defaults = defaults;
10353
11060
  this.noTrace = noTrace;
11061
+ void this.__braintrust_prompt_marker;
10354
11062
  }
10355
11063
  parsedPromptData;
10356
11064
  hasParsedPromptData = false;
@@ -10587,6 +11295,7 @@ var Prompt2 = class _Prompt {
10587
11295
  var RemoteEvalParameters = class {
10588
11296
  constructor(metadata) {
10589
11297
  this.metadata = metadata;
11298
+ void this.__braintrust_parameters_marker;
10590
11299
  }
10591
11300
  __braintrust_parameters_marker = true;
10592
11301
  get id() {
@@ -11812,15 +12521,21 @@ async function invoke(args) {
11812
12521
 
11813
12522
  // src/trace.ts
11814
12523
  var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
11815
- constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false) {
12524
+ constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true) {
11816
12525
  const filterExpr = _SpanFetcher.buildFilter(
11817
12526
  rootSpanId,
11818
12527
  spanTypeFilter,
11819
12528
  includeScorers
11820
12529
  );
11821
- super(objectType, void 0, void 0, {
11822
- filter: filterExpr
11823
- });
12530
+ super(
12531
+ objectType,
12532
+ void 0,
12533
+ void 0,
12534
+ {
12535
+ filter: filterExpr
12536
+ },
12537
+ brainstoreRealtime
12538
+ );
11824
12539
  this._objectId = _objectId;
11825
12540
  this.rootSpanId = rootSpanId;
11826
12541
  this._state = _state;
@@ -11874,7 +12589,7 @@ var CachedSpanFetcher = class {
11874
12589
  spanCache = /* @__PURE__ */ new Map();
11875
12590
  allFetched = false;
11876
12591
  fetchFn;
11877
- constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {
12592
+ constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState, brainstoreRealtime = true) {
11878
12593
  if (typeof objectTypeOrFetchFn === "function") {
11879
12594
  this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
11880
12595
  } else {
@@ -11887,7 +12602,8 @@ var CachedSpanFetcher = class {
11887
12602
  rootSpanId,
11888
12603
  state,
11889
12604
  spanType,
11890
- includeScorers
12605
+ includeScorers,
12606
+ brainstoreRealtime
11891
12607
  );
11892
12608
  const rows = await fetcher.fetchedData();
11893
12609
  return rows.map((row) => ({
@@ -12708,7 +13424,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
12708
13424
  }
12709
13425
  };
12710
13426
  const parentStr = state.currentParent.getStore();
12711
- const parentComponents = parentStr ? SpanComponentsV3.fromStr(parentStr) : null;
13427
+ const parentComponents = typeof parentStr === "string" ? SpanComponentsV4.fromStr(parentStr) : null;
12712
13428
  const trace = state ? new LocalTrace({
12713
13429
  objectType: parentComponents ? spanObjectTypeV3ToTypedString(
12714
13430
  parentComponents.data.object_type
@@ -14539,6 +15255,22 @@ function runStreamingCompletionHook(args) {
14539
15255
  );
14540
15256
  }
14541
15257
  }
15258
+ function runStreamingErrorHook(args) {
15259
+ if (!args.config.onError) {
15260
+ return;
15261
+ }
15262
+ try {
15263
+ args.config.onError({
15264
+ channelName: args.channelName,
15265
+ error: args.error,
15266
+ event: args.event,
15267
+ span: args.span,
15268
+ startTime: args.startTime
15269
+ });
15270
+ } catch (error2) {
15271
+ debugLogger.error(`Error in onError hook for ${args.channelName}:`, error2);
15272
+ }
15273
+ }
14542
15274
  function traceAsyncChannel(channel2, config3) {
14543
15275
  const tracingChannel2 = channel2.tracingChannel();
14544
15276
  const states = /* @__PURE__ */ new WeakMap();
@@ -14700,6 +15432,14 @@ function traceStreamingChannel(channel2, config3) {
14700
15432
  }
14701
15433
  },
14702
15434
  onError: (error2) => {
15435
+ runStreamingErrorHook({
15436
+ channelName,
15437
+ config: config3,
15438
+ error: error2,
15439
+ event: asyncEndEvent,
15440
+ span,
15441
+ startTime
15442
+ });
14703
15443
  span.log({
14704
15444
  error: error2.message
14705
15445
  });
@@ -14757,6 +15497,17 @@ function traceStreamingChannel(channel2, config3) {
14757
15497
  }
14758
15498
  },
14759
15499
  error: (event) => {
15500
+ const spanData = states.get(event);
15501
+ if (spanData) {
15502
+ runStreamingErrorHook({
15503
+ channelName,
15504
+ config: config3,
15505
+ error: event.error,
15506
+ event,
15507
+ span: spanData.span,
15508
+ startTime: spanData.startTime
15509
+ });
15510
+ }
14760
15511
  logErrorAndEnd(states, event);
14761
15512
  }
14762
15513
  };
@@ -17119,14 +17870,45 @@ function serializeAISDKToolsForLogging(tools) {
17119
17870
  return serialized;
17120
17871
  }
17121
17872
 
17873
+ // src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
17874
+ var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
17875
+ "braintrust.ai-sdk.v7.telemetry-operation-key"
17876
+ );
17877
+
17878
+ // src/wrappers/ai-sdk/workflow-agent-context.ts
17879
+ var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
17880
+ function registerWorkflowAgentWrapperSpan(span) {
17881
+ if (span.spanId) {
17882
+ workflowAgentWrapperSpans.set(span.spanId, span);
17883
+ }
17884
+ }
17885
+ function unregisterWorkflowAgentWrapperSpan(span) {
17886
+ if (span.spanId) {
17887
+ workflowAgentWrapperSpans.delete(span.spanId);
17888
+ }
17889
+ }
17890
+ function currentWorkflowAgentWrapperSpan() {
17891
+ const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
17892
+ for (const parentSpanId of parentSpanIds) {
17893
+ const span = workflowAgentWrapperSpans.get(parentSpanId);
17894
+ if (span) {
17895
+ return span;
17896
+ }
17897
+ }
17898
+ return void 0;
17899
+ }
17900
+
17122
17901
  // src/wrappers/ai-sdk/telemetry.ts
17123
17902
  function braintrustAISDKTelemetry() {
17124
17903
  const operations = /* @__PURE__ */ new Map();
17904
+ const operationKeysByCallId = /* @__PURE__ */ new Map();
17905
+ const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
17125
17906
  const modelSpans = /* @__PURE__ */ new Map();
17126
17907
  const objectSpans = /* @__PURE__ */ new Map();
17127
17908
  const embedSpans = /* @__PURE__ */ new Map();
17128
17909
  const rerankSpans = /* @__PURE__ */ new Map();
17129
17910
  const toolSpans = /* @__PURE__ */ new Map();
17911
+ let workflowAgentOperationCounter = 0;
17130
17912
  const runSafely = (name, callback) => {
17131
17913
  try {
17132
17914
  callback();
@@ -17134,42 +17916,333 @@ function braintrustAISDKTelemetry() {
17134
17916
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error2);
17135
17917
  }
17136
17918
  };
17137
- const startChildSpan = (callId, name, type, event) => {
17138
- const parent = operations.get(callId)?.span;
17919
+ const startChildSpan = (operationKey, name, type, event) => {
17920
+ const parent = operations.get(operationKey)?.span;
17139
17921
  const spanArgs = {
17140
17922
  name,
17141
17923
  spanAttributes: { type },
17142
17924
  ...event ? { event } : {}
17143
17925
  };
17144
17926
  const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
17145
- const state = operations.get(callId);
17927
+ const state = operations.get(operationKey);
17146
17928
  if (state && type === "llm" /* LLM */) {
17147
17929
  state.hadModelChild = true;
17148
17930
  }
17149
17931
  return span;
17150
17932
  };
17933
+ const registerOperation = (state) => {
17934
+ operations.set(state.operationKey, state);
17935
+ const keys = operationKeysByCallId.get(state.callId) ?? [];
17936
+ keys.push(state.operationKey);
17937
+ operationKeysByCallId.set(state.callId, keys);
17938
+ };
17939
+ const deleteOperation = (operationKey) => {
17940
+ const state = operations.get(operationKey);
17941
+ if (!state) {
17942
+ return;
17943
+ }
17944
+ operations.delete(operationKey);
17945
+ if (workflowOperationKeyStore.getStore() === operationKey) {
17946
+ workflowOperationKeyStore.enterWith(void 0);
17947
+ }
17948
+ const keys = operationKeysByCallId.get(state.callId);
17949
+ if (!keys) {
17950
+ return;
17951
+ }
17952
+ const index = keys.indexOf(operationKey);
17953
+ if (index >= 0) {
17954
+ keys.splice(index, 1);
17955
+ }
17956
+ if (keys.length === 0) {
17957
+ operationKeysByCallId.delete(state.callId);
17958
+ }
17959
+ };
17960
+ const explicitOperationKey = (event) => {
17961
+ if (!isObject(event)) {
17962
+ return void 0;
17963
+ }
17964
+ const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
17965
+ return typeof key === "string" ? key : void 0;
17966
+ };
17967
+ const createOperationKey = (event, operationName) => {
17968
+ const explicit = explicitOperationKey(event);
17969
+ if (explicit) {
17970
+ return explicit;
17971
+ }
17972
+ if (operationName === "WorkflowAgent.stream") {
17973
+ workflowAgentOperationCounter += 1;
17974
+ return `${event.callId}:${workflowAgentOperationCounter}`;
17975
+ }
17976
+ return event.callId;
17977
+ };
17978
+ const operationKeyForCallId = (callId, mode = "active") => {
17979
+ const keys = operationKeysByCallId.get(callId);
17980
+ if (!keys || keys.length === 0) {
17981
+ return operations.has(callId) ? callId : void 0;
17982
+ }
17983
+ if (keys.length === 1) {
17984
+ return keys[0];
17985
+ }
17986
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
17987
+ if (wrapperSpan?.spanId) {
17988
+ const key = keys.find(
17989
+ (candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
17990
+ );
17991
+ if (key) {
17992
+ return key;
17993
+ }
17994
+ }
17995
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
17996
+ if (workflowOperationKey && keys.includes(workflowOperationKey)) {
17997
+ return workflowOperationKey;
17998
+ }
17999
+ if (callId === "workflow-agent") {
18000
+ return void 0;
18001
+ }
18002
+ return mode === "finish" ? keys[0] : keys[keys.length - 1];
18003
+ };
18004
+ const operationKeyFromEvent = (event, mode = "active") => {
18005
+ const explicit = explicitOperationKey(event);
18006
+ if (explicit && operations.has(explicit)) {
18007
+ return explicit;
18008
+ }
18009
+ if (isObject(event)) {
18010
+ const callId = event.callId;
18011
+ if (typeof callId === "string") {
18012
+ const operationKey = operationKeyForCallId(callId, mode);
18013
+ if (operationKey) {
18014
+ return operationKey;
18015
+ }
18016
+ const workflowOperationKey2 = workflowOperationKeyStore.getStore();
18017
+ if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
18018
+ return workflowOperationKey2;
18019
+ }
18020
+ return callId === "workflow-agent" ? void 0 : callId;
18021
+ }
18022
+ }
18023
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
18024
+ if (workflowOperationKey && operations.has(workflowOperationKey)) {
18025
+ return workflowOperationKey;
18026
+ }
18027
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
18028
+ if (wrapperSpan?.spanId) {
18029
+ for (const [operationKey, state] of operations) {
18030
+ if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
18031
+ return operationKey;
18032
+ }
18033
+ }
18034
+ }
18035
+ const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
18036
+ if (workflowAgentKeys?.length === 1) {
18037
+ return workflowAgentKeys[0];
18038
+ }
18039
+ if (operations.size === 1) {
18040
+ return operations.keys().next().value;
18041
+ }
18042
+ return void 0;
18043
+ };
18044
+ const closeOpenChildSpans = (operationKey, error2) => {
18045
+ const openModelSpans = modelSpans.get(operationKey);
18046
+ if (openModelSpans) {
18047
+ for (const span of openModelSpans) {
18048
+ if (error2 !== void 0) {
18049
+ logError(span, error2);
18050
+ }
18051
+ span.end();
18052
+ }
18053
+ modelSpans.delete(operationKey);
18054
+ }
18055
+ const openObjectSpan = objectSpans.get(operationKey);
18056
+ if (openObjectSpan) {
18057
+ if (error2 !== void 0) {
18058
+ logError(openObjectSpan, error2);
18059
+ }
18060
+ openObjectSpan.end();
18061
+ objectSpans.delete(operationKey);
18062
+ }
18063
+ for (const [embedCallId, embedState] of embedSpans) {
18064
+ if (embedState.operationKey === operationKey) {
18065
+ if (error2 !== void 0) {
18066
+ logError(embedState.span, error2);
18067
+ }
18068
+ embedState.span.end();
18069
+ embedSpans.delete(embedCallId);
18070
+ }
18071
+ }
18072
+ const openRerankSpan = rerankSpans.get(operationKey);
18073
+ if (openRerankSpan) {
18074
+ if (error2 !== void 0) {
18075
+ logError(openRerankSpan, error2);
18076
+ }
18077
+ openRerankSpan.end();
18078
+ rerankSpans.delete(operationKey);
18079
+ }
18080
+ for (const [toolCallId, toolState] of toolSpans) {
18081
+ if (toolState.operationKey === operationKey) {
18082
+ if (error2 !== void 0) {
18083
+ logError(toolState.span, error2);
18084
+ }
18085
+ toolState.span.end();
18086
+ toolSpans.delete(toolCallId);
18087
+ }
18088
+ }
18089
+ };
18090
+ const abortReasonFromEvent = (event) => {
18091
+ if (isObject(event)) {
18092
+ const abortEvent = event;
18093
+ if (abortEvent.error !== void 0) {
18094
+ return abortEvent.error;
18095
+ }
18096
+ if (abortEvent.reason !== void 0) {
18097
+ return abortEvent.reason;
18098
+ }
18099
+ }
18100
+ return new Error("AI SDK operation aborted");
18101
+ };
18102
+ const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
18103
+ const onObjectStepEnd = (event) => {
18104
+ runSafely("onObjectStepEnd", () => {
18105
+ const operationKey = operationKeyFromEvent(event);
18106
+ const span = operationKey ? objectSpans.get(operationKey) : void 0;
18107
+ if (!operationKey || !span) {
18108
+ return;
18109
+ }
18110
+ const result = {
18111
+ ...event,
18112
+ text: event.objectText
18113
+ };
18114
+ span.log({
18115
+ ...shouldRecordOutputs(event) ? {
18116
+ output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
18117
+ } : {},
18118
+ metrics: extractTokenMetrics(result)
18119
+ });
18120
+ span.end();
18121
+ objectSpans.delete(operationKey);
18122
+ });
18123
+ };
18124
+ const onEmbedEnd = (event) => {
18125
+ runSafely("onEmbedEnd", () => {
18126
+ const state = embedSpans.get(event.embedCallId);
18127
+ if (!state) {
18128
+ return;
18129
+ }
18130
+ const result = {
18131
+ ...event,
18132
+ embeddings: event.embeddings
18133
+ };
18134
+ state.span.log({
18135
+ ...shouldRecordOutputs(event) ? {
18136
+ output: processAISDKEmbeddingOutput(
18137
+ result,
18138
+ DEFAULT_DENY_OUTPUT_PATHS
18139
+ )
18140
+ } : {},
18141
+ metrics: extractTokenMetrics(result)
18142
+ });
18143
+ state.span.end();
18144
+ embedSpans.delete(event.embedCallId);
18145
+ });
18146
+ };
18147
+ const onRerankEnd = (event) => {
18148
+ runSafely("onRerankEnd", () => {
18149
+ const operationKey = operationKeyFromEvent(event);
18150
+ const span = operationKey ? rerankSpans.get(operationKey) : void 0;
18151
+ if (!operationKey || !span) {
18152
+ return;
18153
+ }
18154
+ const result = {
18155
+ ranking: event.ranking?.map((entry) => ({
18156
+ originalIndex: entry.index,
18157
+ score: entry.relevanceScore
18158
+ }))
18159
+ };
18160
+ span.log({
18161
+ ...shouldRecordOutputs(event) ? {
18162
+ output: processAISDKRerankOutput(
18163
+ result,
18164
+ DEFAULT_DENY_OUTPUT_PATHS
18165
+ )
18166
+ } : {}
18167
+ });
18168
+ span.end();
18169
+ rerankSpans.delete(operationKey);
18170
+ });
18171
+ };
18172
+ const onEnd = (event) => {
18173
+ runSafely("onEnd", () => {
18174
+ const operationKey = operationKeyFromEvent(event, "finish");
18175
+ const state = operationKey ? operations.get(operationKey) : void 0;
18176
+ if (!state) {
18177
+ return;
18178
+ }
18179
+ if (!state.ownsSpan) {
18180
+ deleteOperation(state.operationKey);
18181
+ return;
18182
+ }
18183
+ const result = finishResult(event, state.operationName);
18184
+ const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
18185
+ const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
18186
+ if (timeToFirstToken !== void 0) {
18187
+ metrics.time_to_first_token = timeToFirstToken;
18188
+ }
18189
+ state.span.log({
18190
+ ...shouldRecordOutputs(event) ? {
18191
+ output: finishOutput(result, state.operationName)
18192
+ } : {},
18193
+ metrics
18194
+ });
18195
+ state.span.end();
18196
+ deleteOperation(state.operationKey);
18197
+ });
18198
+ };
17151
18199
  return {
17152
18200
  onStart(event) {
17153
18201
  runSafely("onStart", () => {
17154
18202
  const operationName = operationNameFromId(event.operationId);
17155
- const span = startSpan({
18203
+ const workflowAgent = operationName === "WorkflowAgent.stream";
18204
+ const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
18205
+ const ownsSpan = !wrapperSpan;
18206
+ const span = ownsSpan ? startSpan({
17156
18207
  name: operationName,
17157
18208
  spanAttributes: { type: "function" /* FUNCTION */ }
17158
- });
17159
- operations.set(event.callId, {
18209
+ }) : wrapperSpan;
18210
+ const operationKey = createOperationKey(event, operationName);
18211
+ registerOperation({
18212
+ callId: event.callId,
17160
18213
  hadModelChild: false,
18214
+ loggedInput: false,
17161
18215
  operationName,
18216
+ operationKey,
18217
+ ownsSpan,
17162
18218
  span,
17163
18219
  startTime: getCurrentUnixTimestamp()
17164
18220
  });
17165
- const metadata = metadataFromEvent(event);
18221
+ if (!ownsSpan) {
18222
+ return;
18223
+ }
18224
+ if (workflowAgent) {
18225
+ workflowOperationKeyStore.enterWith(operationKey);
18226
+ }
18227
+ let metadata = metadataFromEvent(event);
17166
18228
  const logPayload = { metadata };
18229
+ const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
18230
+ if (workflowAgentCallInput) {
18231
+ metadata = {
18232
+ ...metadata,
18233
+ ...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
18234
+ };
18235
+ logPayload.metadata = metadata;
18236
+ }
17167
18237
  if (shouldRecordInputs(event)) {
17168
- const { input, outputPromise } = processAISDKCallInput(
17169
- operationInput(event, operationName)
17170
- );
18238
+ const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
18239
+ const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
17171
18240
  logPayload.input = input;
17172
- if (outputPromise && input && typeof input === "object") {
18241
+ const state = operations.get(operationKey);
18242
+ if (state) {
18243
+ state.loggedInput = hasPromptLikeInput(input);
18244
+ }
18245
+ if (outputPromise && !workflowAgent && input && typeof input === "object") {
17173
18246
  outputPromise.then((resolvedData) => {
17174
18247
  span.log({
17175
18248
  input: {
@@ -17186,41 +18259,67 @@ function braintrustAISDKTelemetry() {
17186
18259
  },
17187
18260
  onLanguageModelCallStart(event) {
17188
18261
  runSafely("onLanguageModelCallStart", () => {
17189
- const state = operations.get(event.callId);
17190
- const openSpans = modelSpans.get(event.callId);
17191
- if (openSpans) {
18262
+ const operationKey = operationKeyFromEvent(event);
18263
+ const state = operationKey ? operations.get(operationKey) : void 0;
18264
+ if (shouldSkipTelemetryChildren(state)) {
18265
+ return;
18266
+ }
18267
+ const operationName = state?.operationName ?? "generateText";
18268
+ const callInput = operationInput(event, operationName);
18269
+ const workflowAgent = operationName === "WorkflowAgent.stream";
18270
+ const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
18271
+ if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
18272
+ state.span.log({
18273
+ input: processedInput,
18274
+ metadata: {
18275
+ ...metadataFromEvent(event),
18276
+ ...extractWorkflowMetadataFromCallParams(callInput)
18277
+ }
18278
+ });
18279
+ state.loggedInput = true;
18280
+ }
18281
+ const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
18282
+ if (operationKey && openSpans) {
17192
18283
  for (const span2 of openSpans) {
17193
18284
  span2.end();
17194
18285
  }
17195
- modelSpans.delete(event.callId);
18286
+ modelSpans.delete(operationKey);
17196
18287
  }
17197
18288
  const span = startChildSpan(
17198
- event.callId,
17199
- state?.operationName === "streamText" ? "doStream" : "doGenerate",
18289
+ operationKey ?? event.callId,
18290
+ operationName === "streamText" ? "doStream" : "doGenerate",
17200
18291
  "llm" /* LLM */,
17201
18292
  {
17202
18293
  ...shouldRecordInputs(event) ? {
17203
- input: processAISDKCallInput(
17204
- operationInput(
17205
- event,
17206
- state?.operationName ?? "generateText"
17207
- )
17208
- ).input
18294
+ input: processedInput
17209
18295
  } : {},
17210
- metadata: metadataFromEvent(event)
18296
+ metadata: workflowAgent ? {
18297
+ ...metadataFromEvent(event),
18298
+ ...extractWorkflowMetadataFromCallParams(callInput)
18299
+ } : metadataFromEvent(event)
17211
18300
  }
17212
18301
  );
17213
- const spans = modelSpans.get(event.callId) ?? [];
18302
+ const spanKey = operationKey ?? event.callId;
18303
+ const spans = modelSpans.get(spanKey) ?? [];
17214
18304
  spans.push(span);
17215
- modelSpans.set(event.callId, spans);
18305
+ modelSpans.set(spanKey, spans);
17216
18306
  });
17217
18307
  },
17218
18308
  onLanguageModelCallEnd(event) {
17219
18309
  runSafely("onLanguageModelCallEnd", () => {
17220
- const span = shiftModelSpan(modelSpans, event.callId);
18310
+ const operationKey = operationKeyFromEvent(event);
18311
+ const state = operationKey ? operations.get(operationKey) : void 0;
18312
+ if (shouldSkipTelemetryChildren(state)) {
18313
+ return;
18314
+ }
18315
+ const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
17221
18316
  if (!span) {
17222
18317
  return;
17223
18318
  }
18319
+ const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
18320
+ if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
18321
+ state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
18322
+ }
17224
18323
  const result = {
17225
18324
  ...event,
17226
18325
  response: event.responseId ? { id: event.responseId } : void 0
@@ -17236,14 +18335,18 @@ function braintrustAISDKTelemetry() {
17236
18335
  },
17237
18336
  onObjectStepStart(event) {
17238
18337
  runSafely("onObjectStepStart", () => {
17239
- const state = operations.get(event.callId);
17240
- const openSpan = objectSpans.get(event.callId);
17241
- if (openSpan) {
18338
+ const operationKey = operationKeyFromEvent(event);
18339
+ const state = operationKey ? operations.get(operationKey) : void 0;
18340
+ if (shouldSkipTelemetryChildren(state)) {
18341
+ return;
18342
+ }
18343
+ const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
18344
+ if (operationKey && openSpan) {
17242
18345
  openSpan.end();
17243
- objectSpans.delete(event.callId);
18346
+ objectSpans.delete(operationKey);
17244
18347
  }
17245
18348
  const span = startChildSpan(
17246
- event.callId,
18349
+ operationKey ?? event.callId,
17247
18350
  state?.operationName === "streamObject" ? "doStream" : "doGenerate",
17248
18351
  "llm" /* LLM */,
17249
18352
  {
@@ -17255,40 +18358,25 @@ function braintrustAISDKTelemetry() {
17255
18358
  metadata: metadataFromEvent(event)
17256
18359
  }
17257
18360
  );
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);
18361
+ objectSpans.set(operationKey ?? event.callId, span);
17279
18362
  });
17280
18363
  },
18364
+ onObjectStepEnd,
17281
18365
  onEmbedStart(event) {
17282
18366
  runSafely("onEmbedStart", () => {
17283
- const state = operations.get(event.callId);
18367
+ const operationKey = operationKeyFromEvent(event);
18368
+ const state = operationKey ? operations.get(operationKey) : void 0;
18369
+ if (shouldSkipTelemetryChildren(state)) {
18370
+ return;
18371
+ }
17284
18372
  for (const [embedCallId, embedState] of embedSpans) {
17285
- if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
18373
+ if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
17286
18374
  embedState.span.end();
17287
18375
  embedSpans.delete(embedCallId);
17288
18376
  }
17289
18377
  }
17290
18378
  const span = startChildSpan(
17291
- event.callId,
18379
+ operationKey ?? event.callId,
17292
18380
  "doEmbed",
17293
18381
  "llm" /* LLM */,
17294
18382
  {
@@ -17301,44 +18389,27 @@ function braintrustAISDKTelemetry() {
17301
18389
  }
17302
18390
  );
17303
18391
  embedSpans.set(event.embedCallId, {
17304
- callId: event.callId,
18392
+ operationKey: operationKey ?? event.callId,
17305
18393
  span,
17306
18394
  values: event.values
17307
18395
  });
17308
18396
  });
17309
18397
  },
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
- },
18398
+ onEmbedEnd,
17333
18399
  onRerankStart(event) {
17334
18400
  runSafely("onRerankStart", () => {
17335
- const openSpan = rerankSpans.get(event.callId);
17336
- if (openSpan) {
18401
+ const operationKey = operationKeyFromEvent(event);
18402
+ const state = operationKey ? operations.get(operationKey) : void 0;
18403
+ if (shouldSkipTelemetryChildren(state)) {
18404
+ return;
18405
+ }
18406
+ const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
18407
+ if (operationKey && openSpan) {
17337
18408
  openSpan.end();
17338
- rerankSpans.delete(event.callId);
18409
+ rerankSpans.delete(operationKey);
17339
18410
  }
17340
18411
  const span = startChildSpan(
17341
- event.callId,
18412
+ operationKey ?? event.callId,
17342
18413
  "doRerank",
17343
18414
  "llm" /* LLM */,
17344
18415
  {
@@ -17352,41 +18423,23 @@ function braintrustAISDKTelemetry() {
17352
18423
  metadata: metadataFromEvent(event)
17353
18424
  }
17354
18425
  );
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);
18426
+ rerankSpans.set(operationKey ?? event.callId, span);
17380
18427
  });
17381
18428
  },
18429
+ onRerankEnd,
17382
18430
  onToolExecutionStart(event) {
17383
18431
  runSafely("onToolExecutionStart", () => {
18432
+ const operationKey = operationKeyFromEvent(event);
18433
+ const state = operationKey ? operations.get(operationKey) : void 0;
18434
+ if (shouldSkipTelemetryChildren(state)) {
18435
+ return;
18436
+ }
17384
18437
  const toolCallId = event.toolCall.toolCallId;
17385
- if (!toolCallId) {
18438
+ if (!operationKey || !toolCallId) {
17386
18439
  return;
17387
18440
  }
17388
18441
  const span = startChildSpan(
17389
- event.callId,
18442
+ operationKey,
17390
18443
  event.toolCall.toolName || "tool",
17391
18444
  "tool" /* TOOL */,
17392
18445
  {
@@ -17400,7 +18453,7 @@ function braintrustAISDKTelemetry() {
17400
18453
  }
17401
18454
  }
17402
18455
  );
17403
- toolSpans.set(toolCallId, { callId: event.callId, span });
18456
+ toolSpans.set(toolCallId, { operationKey, span });
17404
18457
  });
17405
18458
  },
17406
18459
  onToolExecutionEnd(event) {
@@ -17411,14 +18464,17 @@ function braintrustAISDKTelemetry() {
17411
18464
  return;
17412
18465
  }
17413
18466
  const toolOutput = event.toolOutput;
17414
- if (toolOutput?.type === "tool-error") {
18467
+ const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
18468
+ if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
18469
+ const error2 = toolOutput?.error ?? workflowToolError;
17415
18470
  state.span.log({
17416
- error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
18471
+ error: error2 instanceof Error ? error2.message : String(error2),
17417
18472
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
17418
18473
  });
17419
18474
  } else {
18475
+ const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
17420
18476
  state.span.log({
17421
- ...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
18477
+ ...shouldRecordOutputs(event) ? { output } : {},
17422
18478
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
17423
18479
  });
17424
18480
  }
@@ -17432,83 +18488,46 @@ function braintrustAISDKTelemetry() {
17432
18488
  if (!callId) {
17433
18489
  return;
17434
18490
  }
17435
- const state = operations.get(callId);
18491
+ const operationKey = operationKeyForCallId(callId);
18492
+ const state = operationKey ? operations.get(operationKey) : void 0;
17436
18493
  if (!state || state.firstChunkTime !== void 0) {
17437
18494
  return;
17438
18495
  }
17439
18496
  state.firstChunkTime = getCurrentUnixTimestamp();
17440
18497
  });
17441
18498
  },
17442
- onFinish(event) {
17443
- runSafely("onFinish", () => {
17444
- const state = operations.get(event.callId);
17445
- if (!state) {
18499
+ onEnd,
18500
+ onAbort(event) {
18501
+ runSafely("onAbort", () => {
18502
+ const operationKey = operationKeyFromEvent(event, "finish");
18503
+ const state = operationKey ? operations.get(operationKey) : void 0;
18504
+ if (!operationKey || !state) {
17446
18505
  return;
17447
18506
  }
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;
18507
+ const error2 = abortReasonFromEvent(event);
18508
+ closeOpenChildSpans(operationKey, error2);
18509
+ if (state.ownsSpan) {
18510
+ logError(state.span, error2);
18511
+ state.span.end();
17452
18512
  }
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);
18513
+ deleteOperation(operationKey);
17461
18514
  });
17462
18515
  },
17463
18516
  onError(event) {
17464
18517
  runSafely("onError", () => {
17465
18518
  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) {
18519
+ const operationKey = operationKeyFromEvent(errorEvent, "finish");
18520
+ const state = operationKey ? operations.get(operationKey) : void 0;
18521
+ if (!operationKey || !state) {
17472
18522
  return;
17473
18523
  }
17474
18524
  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
- }
18525
+ closeOpenChildSpans(operationKey, error2);
18526
+ if (state.ownsSpan) {
18527
+ logError(state.span, error2);
18528
+ state.span.end();
17508
18529
  }
17509
- logError(state.span, error2);
17510
- state.span.end();
17511
- operations.delete(callId);
18530
+ deleteOperation(operationKey);
17512
18531
  });
17513
18532
  },
17514
18533
  executeTool({ toolCallId, execute }) {
@@ -17523,7 +18542,16 @@ function shouldRecordInputs(event) {
17523
18542
  function shouldRecordOutputs(event) {
17524
18543
  return event.recordOutputs !== false;
17525
18544
  }
18545
+ function hasPromptLikeInput(input) {
18546
+ if (!isObject(input)) {
18547
+ return false;
18548
+ }
18549
+ return input.prompt !== void 0 || input.messages !== void 0;
18550
+ }
17526
18551
  function operationNameFromId(operationId) {
18552
+ if (operationId === "ai.workflowAgent.stream") {
18553
+ return "WorkflowAgent.stream";
18554
+ }
17527
18555
  return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
17528
18556
  }
17529
18557
  function modelFromEvent(event) {
@@ -17569,6 +18597,7 @@ function operationInput(event, operationName) {
17569
18597
  }
17570
18598
  return {
17571
18599
  model: modelFromEvent(event),
18600
+ instructions: event.instructions,
17572
18601
  system: event.system,
17573
18602
  prompt: event.prompt,
17574
18603
  messages: event.messages,
@@ -17617,6 +18646,30 @@ function finishResult(event, operationName) {
17617
18646
  }
17618
18647
  return event;
17619
18648
  }
18649
+ function extractTimeToFirstToken(result, state) {
18650
+ if (state.firstChunkTime !== void 0) {
18651
+ return state.firstChunkTime - state.startTime;
18652
+ }
18653
+ const performanceCandidates = [
18654
+ safePerformance(result),
18655
+ safePerformance(result.finalStep),
18656
+ ...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
18657
+ ];
18658
+ for (const performance of performanceCandidates) {
18659
+ const timeToFirstOutputMs = performance?.timeToFirstOutputMs;
18660
+ if (typeof timeToFirstOutputMs === "number") {
18661
+ return timeToFirstOutputMs / 1e3;
18662
+ }
18663
+ }
18664
+ return void 0;
18665
+ }
18666
+ function safePerformance(value) {
18667
+ if (!isObject(value)) {
18668
+ return void 0;
18669
+ }
18670
+ const performance = value.performance;
18671
+ return isObject(performance) ? performance : void 0;
18672
+ }
17620
18673
  function finishOutput(result, operationName) {
17621
18674
  if (operationName === "embed" || operationName === "embedMany") {
17622
18675
  return processAISDKEmbeddingOutput(
@@ -17693,6 +18746,10 @@ var aiSDKChannels = defineChannels("ai", {
17693
18746
  channelName: "ToolLoopAgent.stream",
17694
18747
  kind: "async"
17695
18748
  }),
18749
+ workflowAgentStream: channel({
18750
+ channelName: "WorkflowAgent.stream",
18751
+ kind: "async"
18752
+ }),
17696
18753
  v7CreateTelemetryDispatcher: channel({
17697
18754
  channelName: "createTelemetryDispatcher",
17698
18755
  kind: "sync-stream"
@@ -17703,14 +18760,19 @@ var aiSDKChannels = defineChannels("ai", {
17703
18760
  var DEFAULT_DENY_OUTPUT_PATHS = [
17704
18761
  // v3
17705
18762
  "roundtrips[].request.body",
18763
+ "roundtrips[].request.headers",
17706
18764
  "roundtrips[].response.headers",
17707
18765
  "rawResponse.headers",
17708
18766
  "responseMessages",
17709
18767
  // v5
17710
18768
  "request.body",
18769
+ "request.headers",
18770
+ "responses[].headers",
17711
18771
  "response.body",
17712
18772
  "response.headers",
17713
18773
  "steps[].request.body",
18774
+ "steps[].request.headers",
18775
+ "steps[].responses[].headers",
17714
18776
  "steps[].response.body",
17715
18777
  "steps[].response.headers"
17716
18778
  ];
@@ -17722,6 +18784,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
17722
18784
  var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
17723
18785
  "braintrust.ai-sdk.deny-output-paths"
17724
18786
  );
18787
+ var aiSDKV7TelemetryOperationCounter = 0;
18788
+ var TRANSPORT_PAYLOAD_ROOT_PATHS = [
18789
+ "rawResponse",
18790
+ "request",
18791
+ "response",
18792
+ "responses[]",
18793
+ "roundtrips[].request",
18794
+ "roundtrips[].response",
18795
+ "steps[].request",
18796
+ "steps[].response",
18797
+ "steps[].responses[]"
18798
+ ];
17725
18799
  var AI_SDK_V7_TELEMETRY_CALLBACKS = [
17726
18800
  "onStart",
17727
18801
  "onStepStart",
@@ -17730,14 +18804,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
17730
18804
  "onToolExecutionStart",
17731
18805
  "onToolExecutionEnd",
17732
18806
  "onChunk",
18807
+ "onStepEnd",
17733
18808
  "onStepFinish",
17734
18809
  "onObjectStepStart",
17735
- "onObjectStepFinish",
18810
+ "onObjectStepEnd",
17736
18811
  "onEmbedStart",
17737
- "onEmbedFinish",
18812
+ "onEmbedEnd",
17738
18813
  "onRerankStart",
17739
- "onRerankFinish",
17740
- "onFinish",
18814
+ "onRerankEnd",
18815
+ "onEnd",
18816
+ "onAbort",
17741
18817
  "onError"
17742
18818
  ];
17743
18819
  var AISDKPlugin = class extends BasePlugin {
@@ -17895,7 +18971,9 @@ var AISDKPlugin = class extends BasePlugin {
17895
18971
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
17896
18972
  name: "Agent.generate",
17897
18973
  type: "function" /* FUNCTION */,
17898
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
18974
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
18975
+ agentOwner: true
18976
+ }),
17899
18977
  extractOutput: (result, endEvent) => {
17900
18978
  finalizeAISDKChildTracing(endEvent);
17901
18979
  return processAISDKOutput(
@@ -17911,7 +18989,9 @@ var AISDKPlugin = class extends BasePlugin {
17911
18989
  traceStreamingChannel(aiSDKChannels.agentStream, {
17912
18990
  name: "Agent.stream",
17913
18991
  type: "function" /* FUNCTION */,
17914
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
18992
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
18993
+ agentOwner: true
18994
+ }),
17915
18995
  extractOutput: (result, endEvent) => processAISDKOutput(
17916
18996
  result,
17917
18997
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -17931,7 +19011,9 @@ var AISDKPlugin = class extends BasePlugin {
17931
19011
  traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
17932
19012
  name: "Agent.stream",
17933
19013
  type: "function" /* FUNCTION */,
17934
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19014
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19015
+ agentOwner: true
19016
+ }),
17935
19017
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
17936
19018
  defaultDenyOutputPaths: denyOutputPaths,
17937
19019
  endEvent,
@@ -17945,7 +19027,9 @@ var AISDKPlugin = class extends BasePlugin {
17945
19027
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
17946
19028
  name: "ToolLoopAgent.generate",
17947
19029
  type: "function" /* FUNCTION */,
17948
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19030
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19031
+ agentOwner: true
19032
+ }),
17949
19033
  extractOutput: (result, endEvent) => {
17950
19034
  finalizeAISDKChildTracing(endEvent);
17951
19035
  return processAISDKOutput(
@@ -17961,7 +19045,9 @@ var AISDKPlugin = class extends BasePlugin {
17961
19045
  traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
17962
19046
  name: "ToolLoopAgent.stream",
17963
19047
  type: "function" /* FUNCTION */,
17964
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
19048
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
19049
+ agentOwner: true
19050
+ }),
17965
19051
  extractOutput: (result, endEvent) => processAISDKOutput(
17966
19052
  result,
17967
19053
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -17977,6 +19063,42 @@ var AISDKPlugin = class extends BasePlugin {
17977
19063
  })
17978
19064
  })
17979
19065
  );
19066
+ this.unsubscribers.push(
19067
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
19068
+ name: "WorkflowAgent.stream",
19069
+ type: "function" /* FUNCTION */,
19070
+ extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
19071
+ params,
19072
+ event,
19073
+ span,
19074
+ denyOutputPaths
19075
+ ),
19076
+ extractOutput: (result, endEvent) => {
19077
+ finalizeAISDKChildTracing(endEvent);
19078
+ return processAISDKOutput(
19079
+ result,
19080
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
19081
+ );
19082
+ },
19083
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
19084
+ aggregateChunks: aggregateAISDKChunks,
19085
+ onComplete: ({ span }) => {
19086
+ unregisterWorkflowAgentWrapperSpan(span);
19087
+ },
19088
+ onError: ({ event, span }) => {
19089
+ finalizeAISDKChildTracing(event);
19090
+ unregisterWorkflowAgentWrapperSpan(span);
19091
+ },
19092
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19093
+ defaultDenyOutputPaths: denyOutputPaths,
19094
+ endEvent,
19095
+ onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
19096
+ result,
19097
+ span,
19098
+ startTime
19099
+ })
19100
+ })
19101
+ );
17980
19102
  }
17981
19103
  };
17982
19104
  function subscribeToAISDKV7TelemetryDispatcher() {
@@ -17988,7 +19110,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
17988
19110
  if (telemetryOptions?.isEnabled === false) {
17989
19111
  return;
17990
19112
  }
17991
- patchAISDKV7TelemetryDispatcher(event.result, telemetry);
19113
+ patchAISDKV7TelemetryDispatcher(
19114
+ event.result,
19115
+ telemetry,
19116
+ telemetryOptions
19117
+ );
17992
19118
  }
17993
19119
  };
17994
19120
  channel2.subscribe(handlers);
@@ -17996,7 +19122,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
17996
19122
  channel2.unsubscribe(handlers);
17997
19123
  };
17998
19124
  }
17999
- function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
19125
+ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
18000
19126
  if (!isObject(dispatcher)) {
18001
19127
  return;
18002
19128
  }
@@ -18005,6 +19131,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
18005
19131
  return;
18006
19132
  }
18007
19133
  dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
19134
+ let operationKey;
19135
+ const telemetryEventFields = {};
19136
+ if (typeof telemetryOptions?.recordInputs === "boolean") {
19137
+ telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
19138
+ }
19139
+ if (typeof telemetryOptions?.recordOutputs === "boolean") {
19140
+ telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
19141
+ }
19142
+ if (typeof telemetryOptions?.functionId === "string") {
19143
+ telemetryEventFields.functionId = telemetryOptions.functionId;
19144
+ }
19145
+ const eventWithOperationKey = (event) => {
19146
+ if (!isObject(event)) {
19147
+ return event;
19148
+ }
19149
+ const eventRecord = event;
19150
+ const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
19151
+ operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
19152
+ if (Object.keys(telemetryEventFields).length > 0) {
19153
+ const augmentedEvent = {
19154
+ ...telemetryEventFields,
19155
+ ...event
19156
+ };
19157
+ try {
19158
+ Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
19159
+ configurable: true,
19160
+ enumerable: false,
19161
+ value: operationKey
19162
+ });
19163
+ } catch {
19164
+ augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
19165
+ }
19166
+ return augmentedEvent;
19167
+ }
19168
+ try {
19169
+ Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
19170
+ configurable: true,
19171
+ enumerable: false,
19172
+ value: operationKey
19173
+ });
19174
+ return event;
19175
+ } catch {
19176
+ return {
19177
+ ...event,
19178
+ [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
19179
+ };
19180
+ }
19181
+ };
18008
19182
  for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
18009
19183
  const braintrustCallback = telemetry[key];
18010
19184
  if (typeof braintrustCallback !== "function") {
@@ -18013,11 +19187,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
18013
19187
  const existingCallback = dispatcherRecord[key];
18014
19188
  dispatcherRecord[key] = (event) => {
18015
19189
  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);
19190
+ try {
19191
+ const braintrustResult = braintrustCallback.call(
19192
+ telemetry,
19193
+ eventWithOperationKey(event)
19194
+ );
19195
+ if (isPromiseLike(braintrustResult)) {
19196
+ void Promise.resolve(braintrustResult).catch(() => void 0);
19197
+ }
19198
+ } catch {
18020
19199
  }
19200
+ return existingResult;
18021
19201
  };
18022
19202
  }
18023
19203
  const braintrustExecuteTool = telemetry.executeTool;
@@ -18027,6 +19207,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
18027
19207
  const existingExecuteTool = dispatcherRecord.executeTool;
18028
19208
  dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
18029
19209
  ...args,
19210
+ ...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
18030
19211
  execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
18031
19212
  });
18032
19213
  }
@@ -18125,6 +19306,8 @@ var serializeOutputObject = (output, model) => {
18125
19306
  var processInputAttachmentsSync = (input) => {
18126
19307
  if (!input) return { input };
18127
19308
  const processed = { ...input };
19309
+ delete processed.headers;
19310
+ delete processed.experimental_output;
18128
19311
  if (input.messages && Array.isArray(input.messages)) {
18129
19312
  processed.messages = input.messages.map(processMessage);
18130
19313
  }
@@ -18158,10 +19341,10 @@ var processInputAttachmentsSync = (input) => {
18158
19341
  processed.output = serialized;
18159
19342
  }
18160
19343
  }
18161
- if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
18162
- processed.prepareCall = "[Function]";
18163
- }
18164
- return { input: processed, outputPromise };
19344
+ return {
19345
+ input: sanitizeAISDKCallInputValue(processed),
19346
+ outputPromise
19347
+ };
18165
19348
  };
18166
19349
  var processMessage = (message) => {
18167
19350
  if (!message || typeof message !== "object") return message;
@@ -18325,7 +19508,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
18325
19508
  function processAISDKCallInput(params) {
18326
19509
  return processInputAttachmentsSync(params);
18327
19510
  }
18328
- function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
19511
+ function processAISDKWorkflowAgentCallInput(params) {
19512
+ const processed = processAISDKCallInput(params);
19513
+ return {
19514
+ ...processed,
19515
+ input: extractWorkflowAgentInput(processed.input)
19516
+ };
19517
+ }
19518
+ function processAISDKWorkflowAgentModelCallInput(params) {
19519
+ const processed = processAISDKCallInput(params);
19520
+ return {
19521
+ ...processed,
19522
+ input: extractWorkflowAgentModelInput(processed.input)
19523
+ };
19524
+ }
19525
+ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
18329
19526
  const { input, outputPromise } = processAISDKCallInput(params);
18330
19527
  if (outputPromise && input && typeof input === "object") {
18331
19528
  outputPromise.then((resolvedData) => {
@@ -18344,7 +19541,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
18344
19541
  event.self,
18345
19542
  span,
18346
19543
  defaultDenyOutputPaths,
18347
- event.aiSDK
19544
+ event.aiSDK,
19545
+ childTracingOptions
19546
+ );
19547
+ event.modelWrapped = childTracing.modelWrapped;
19548
+ if (childTracing.cleanup) {
19549
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
19550
+ }
19551
+ return {
19552
+ input,
19553
+ metadata
19554
+ };
19555
+ }
19556
+ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
19557
+ registerWorkflowAgentWrapperSpan(span);
19558
+ const { input } = processAISDKWorkflowAgentCallInput(params);
19559
+ const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
19560
+ const childTracing = prepareAISDKChildTracing(
19561
+ params,
19562
+ event.self,
19563
+ span,
19564
+ defaultDenyOutputPaths,
19565
+ event.aiSDK,
19566
+ { agentOwner: true, workflowAgent: true }
18348
19567
  );
18349
19568
  event.modelWrapped = childTracing.modelWrapped;
18350
19569
  if (childTracing.cleanup) {
@@ -18381,6 +19600,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
18381
19600
  function hasModelChildTracing(event) {
18382
19601
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
18383
19602
  }
19603
+ function serializeToolExecutionInput(args) {
19604
+ return args.length > 0 ? args[0] : args;
19605
+ }
18384
19606
  function createAISDKIntegrationMetadata() {
18385
19607
  return {
18386
19608
  braintrust: {
@@ -18392,6 +19614,13 @@ function createAISDKIntegrationMetadata() {
18392
19614
  function resolveModelFromSelf(self) {
18393
19615
  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
19616
  }
19617
+ function resolveToolsFromSelf(self) {
19618
+ if (!self || typeof self !== "object") {
19619
+ return void 0;
19620
+ }
19621
+ const selfRecord = self;
19622
+ return selfRecord.tools ?? selfRecord.settings?.tools;
19623
+ }
18395
19624
  function extractBaseMetadata(model, self) {
18396
19625
  const metadata = createAISDKIntegrationMetadata();
18397
19626
  const { model: modelId, provider } = serializeModelWithProvider(
@@ -18407,12 +19636,175 @@ function extractBaseMetadata(model, self) {
18407
19636
  }
18408
19637
  function extractMetadataFromCallParams(params, self) {
18409
19638
  const metadata = extractBaseMetadata(params.model, self);
18410
- const tools = serializeAISDKToolsForLogging(params.tools);
19639
+ const tools = serializeAISDKToolsForLogging(
19640
+ params.tools ?? resolveToolsFromSelf(self)
19641
+ );
18411
19642
  if (tools) {
18412
19643
  metadata.tools = tools;
18413
19644
  }
18414
19645
  return metadata;
18415
19646
  }
19647
+ function extractWorkflowMetadataFromCallParams(params, self) {
19648
+ const metadata = extractMetadataFromCallParams(params, self);
19649
+ const options = extractAISDKCallOptionsForMetadata(params);
19650
+ if (Object.keys(options).length > 0) {
19651
+ metadata.options = options;
19652
+ }
19653
+ return metadata;
19654
+ }
19655
+ function extractWorkflowAgentInput(params) {
19656
+ const input = {};
19657
+ if (params.instructions !== void 0) {
19658
+ input.instructions = params.instructions;
19659
+ }
19660
+ if (params.system !== void 0) {
19661
+ input.system = params.system;
19662
+ }
19663
+ if (Array.isArray(params.messages)) {
19664
+ return { ...input, messages: params.messages };
19665
+ }
19666
+ if (typeof params.prompt === "string") {
19667
+ return { ...input, prompt: params.prompt };
19668
+ }
19669
+ if (Array.isArray(params.prompt)) {
19670
+ return { ...input, prompt: params.prompt };
19671
+ }
19672
+ return input;
19673
+ }
19674
+ function extractWorkflowAgentModelInput(params) {
19675
+ const input = {};
19676
+ if (params.instructions !== void 0) {
19677
+ input.instructions = params.instructions;
19678
+ }
19679
+ if (params.system !== void 0) {
19680
+ input.system = params.system;
19681
+ }
19682
+ if (Array.isArray(params.messages)) {
19683
+ return { ...input, messages: params.messages };
19684
+ }
19685
+ if (typeof params.prompt === "string") {
19686
+ return { ...input, prompt: params.prompt };
19687
+ }
19688
+ if (Array.isArray(params.prompt)) {
19689
+ return { ...input, messages: params.prompt };
19690
+ }
19691
+ return input;
19692
+ }
19693
+ function sanitizeAISDKCallInputValue(value, depth = 0) {
19694
+ if (value === void 0 || typeof value === "function") {
19695
+ return void 0;
19696
+ }
19697
+ if (value === null || typeof value !== "object") {
19698
+ return value;
19699
+ }
19700
+ if (isPromiseLike(value)) {
19701
+ return "[Promise]";
19702
+ }
19703
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
19704
+ return "[AbortSignal]";
19705
+ }
19706
+ if (depth >= 8) {
19707
+ return "[Object]";
19708
+ }
19709
+ if (Array.isArray(value)) {
19710
+ return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
19711
+ }
19712
+ if (!isObject(value)) {
19713
+ return value;
19714
+ }
19715
+ const prototype = Object.getPrototypeOf(value);
19716
+ if (prototype !== Object.prototype && prototype !== null) {
19717
+ return value;
19718
+ }
19719
+ const sanitized = {};
19720
+ for (const [key, nested] of Object.entries(value)) {
19721
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
19722
+ continue;
19723
+ }
19724
+ const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
19725
+ if (sanitizedNested !== void 0) {
19726
+ sanitized[key] = sanitizedNested;
19727
+ }
19728
+ }
19729
+ return sanitized;
19730
+ }
19731
+ function extractAISDKCallOptionsForMetadata(params) {
19732
+ const options = {};
19733
+ const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
19734
+ "model",
19735
+ "instructions",
19736
+ "messages",
19737
+ "prompt",
19738
+ "system",
19739
+ "tools",
19740
+ "headers",
19741
+ "abortSignal",
19742
+ "signal",
19743
+ "experimental_output"
19744
+ ]);
19745
+ for (const [key, value] of Object.entries(params)) {
19746
+ if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
19747
+ continue;
19748
+ }
19749
+ const sanitized = sanitizeAISDKMetadataValue(value);
19750
+ if (sanitized !== void 0) {
19751
+ options[key] = sanitized;
19752
+ }
19753
+ }
19754
+ return options;
19755
+ }
19756
+ function sanitizeAISDKMetadataValue(value, depth = 0) {
19757
+ if (value === void 0) {
19758
+ return void 0;
19759
+ }
19760
+ if (typeof value === "function") {
19761
+ return "[Function]";
19762
+ }
19763
+ if (value === null || typeof value !== "object") {
19764
+ return value;
19765
+ }
19766
+ if (isPromiseLike(value)) {
19767
+ return "[Promise]";
19768
+ }
19769
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
19770
+ return "[AbortSignal]";
19771
+ }
19772
+ if (depth >= 8) {
19773
+ return "[Object]";
19774
+ }
19775
+ if (Array.isArray(value)) {
19776
+ return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
19777
+ }
19778
+ if (!isObject(value)) {
19779
+ return value;
19780
+ }
19781
+ const sanitized = {};
19782
+ for (const [key, nested] of Object.entries(value)) {
19783
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
19784
+ continue;
19785
+ }
19786
+ const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
19787
+ if (sanitizedNested !== void 0) {
19788
+ sanitized[key] = sanitizedNested;
19789
+ }
19790
+ }
19791
+ return sanitized;
19792
+ }
19793
+ function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
19794
+ if (!options.workflowAgent) {
19795
+ return {
19796
+ input: processAISDKCallInput(callOptions).input,
19797
+ metadata: baseMetadata
19798
+ };
19799
+ }
19800
+ return {
19801
+ input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
19802
+ metadata: {
19803
+ ...baseMetadata,
19804
+ ...extractWorkflowMetadataFromCallParams(callOptions)
19805
+ }
19806
+ };
19807
+ }
18416
19808
  function extractMetadataFromEmbedParams(params, self) {
18417
19809
  return extractBaseMetadata(params.model, self);
18418
19810
  }
@@ -18426,65 +19818,228 @@ function extractMetadataFromRerankParams(params, self) {
18426
19818
  }
18427
19819
  return metadata;
18428
19820
  }
18429
- function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
19821
+ function activeAISDKChildPatchEntry(entries) {
19822
+ const activeSpan = currentSpan();
19823
+ const activeSpanId = activeSpan.spanId;
19824
+ if (activeSpanId) {
19825
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19826
+ const entry = entries[index];
19827
+ if (entry?.activeSpanIds.has(activeSpanId)) {
19828
+ return entry;
19829
+ }
19830
+ }
19831
+ }
19832
+ const activeParentSpanIds = activeSpan.spanParents ?? [];
19833
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19834
+ const entry = entries[index];
19835
+ if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
19836
+ return entry;
19837
+ }
19838
+ }
19839
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19840
+ const entry = entries[index];
19841
+ if (entry?.parentSpan.spanId === activeSpanId) {
19842
+ return entry;
19843
+ }
19844
+ }
19845
+ return entries[entries.length - 1];
19846
+ }
19847
+ function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
19848
+ const activeSpanId = currentSpan().spanId;
19849
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
19850
+ return false;
19851
+ }
19852
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19853
+ const entry = entries[index];
19854
+ if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
19855
+ entry.activeSpanIds.add(nestedSpan.spanId);
19856
+ cleanup.push(() => {
19857
+ entry.activeSpanIds.delete(nestedSpan.spanId);
19858
+ });
19859
+ return true;
19860
+ }
19861
+ }
19862
+ return false;
19863
+ }
19864
+ function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
19865
+ const activeSpanId = currentSpan().spanId;
19866
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
19867
+ return;
19868
+ }
19869
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
19870
+ const existingEntry = entries[index];
19871
+ if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
19872
+ entry.activeSpanIds.add(activeSpanId);
19873
+ cleanup.push(() => {
19874
+ entry.activeSpanIds.delete(activeSpanId);
19875
+ });
19876
+ return;
19877
+ }
19878
+ }
19879
+ }
19880
+ function closeOpenAISDKModelPatchSpans(entry) {
19881
+ for (const span of entry.openSpans) {
19882
+ span.end();
19883
+ }
19884
+ entry.openSpans.clear();
19885
+ }
19886
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
18430
19887
  const cleanup = [];
18431
- const patchedModels = /* @__PURE__ */ new WeakSet();
19888
+ const patchedModels = /* @__PURE__ */ new WeakMap();
18432
19889
  const patchedTools = /* @__PURE__ */ new WeakSet();
18433
19890
  let modelWrapped = false;
18434
19891
  const patchModel = (model) => {
18435
19892
  const resolvedModel = resolveAISDKModel(model, aiSDK);
18436
- if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
19893
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
18437
19894
  return resolvedModel;
18438
19895
  }
18439
- patchedModels.add(resolvedModel);
18440
- resolvedModel[AUTO_PATCHED_MODEL] = true;
19896
+ const existingWrappedModel = patchedModels.get(resolvedModel);
19897
+ if (existingWrappedModel) {
19898
+ modelWrapped = true;
19899
+ return existingWrappedModel;
19900
+ }
18441
19901
  modelWrapped = true;
19902
+ const modelRecord = resolvedModel;
19903
+ const entry = {
19904
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
19905
+ baseMetadata: buildAISDKChildMetadata(resolvedModel),
19906
+ childTracingOptions,
19907
+ denyOutputPaths,
19908
+ openSpans: /* @__PURE__ */ new Set(),
19909
+ parentSpan
19910
+ };
19911
+ const cleanupModelEntry = (state2, patchedModel) => {
19912
+ closeOpenAISDKModelPatchSpans(entry);
19913
+ const index = state2.entries.indexOf(entry);
19914
+ if (index >= 0) {
19915
+ state2.entries.splice(index, 1);
19916
+ }
19917
+ if (state2.entries.length > 0) {
19918
+ return;
19919
+ }
19920
+ patchedModel.doGenerate = state2.originalDoGenerate;
19921
+ patchedModel.doStream = state2.originalDoStream;
19922
+ delete patchedModel[AUTO_PATCHED_MODEL];
19923
+ };
19924
+ const existingState = modelRecord[AUTO_PATCHED_MODEL];
19925
+ if (existingState) {
19926
+ patchedModels.set(resolvedModel, resolvedModel);
19927
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
19928
+ existingState.entries,
19929
+ parentSpan,
19930
+ cleanup
19931
+ )) {
19932
+ return resolvedModel;
19933
+ }
19934
+ if (!childTracingOptions.agentOwner) {
19935
+ shadowActiveAISDKChildPatchEntry(
19936
+ existingState.entries,
19937
+ entry,
19938
+ parentSpan,
19939
+ cleanup
19940
+ );
19941
+ }
19942
+ existingState.entries.push(entry);
19943
+ cleanup.push(() => {
19944
+ cleanupModelEntry(existingState, modelRecord);
19945
+ });
19946
+ return resolvedModel;
19947
+ }
18442
19948
  const originalDoGenerate = resolvedModel.doGenerate;
18443
19949
  const originalDoStream = resolvedModel.doStream;
18444
- const baseMetadata = buildAISDKChildMetadata(resolvedModel);
18445
- resolvedModel.doGenerate = async function doGeneratePatched(options) {
18446
- return parentSpan.traced(
19950
+ const wrappedModel = Object.create(
19951
+ Object.getPrototypeOf(resolvedModel)
19952
+ );
19953
+ Object.defineProperties(
19954
+ wrappedModel,
19955
+ Object.getOwnPropertyDescriptors(resolvedModel)
19956
+ );
19957
+ const wrappedModelRecord = wrappedModel;
19958
+ const state = {
19959
+ entries: [entry],
19960
+ originalDoGenerate,
19961
+ originalDoStream
19962
+ };
19963
+ Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
19964
+ configurable: true,
19965
+ value: state
19966
+ });
19967
+ wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
19968
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
19969
+ if (!activeEntry) {
19970
+ return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
19971
+ }
19972
+ closeOpenAISDKModelPatchSpans(activeEntry);
19973
+ return activeEntry.parentSpan.traced(
18447
19974
  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;
19975
+ activeEntry.openSpans.add(span);
19976
+ try {
19977
+ const result = await Reflect.apply(
19978
+ originalDoGenerate,
19979
+ resolvedModel,
19980
+ [callOptions]
19981
+ );
19982
+ const output = processAISDKOutput(
19983
+ result,
19984
+ activeEntry.denyOutputPaths
19985
+ );
19986
+ const metrics = extractTokenMetrics(result);
19987
+ const metadataPayload = buildResolvedMetadataPayload(result);
19988
+ const missingUsageMetadata = buildMissingUsageMetadata(
19989
+ output,
19990
+ metrics,
19991
+ "ai_sdk_result_missing_usage"
19992
+ );
19993
+ span.log({
19994
+ output,
19995
+ metrics,
19996
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
19997
+ });
19998
+ return result;
19999
+ } finally {
20000
+ activeEntry.openSpans.delete(span);
20001
+ }
18459
20002
  },
18460
20003
  {
18461
20004
  name: "doGenerate",
18462
20005
  spanAttributes: {
18463
20006
  type: "llm" /* LLM */
18464
20007
  },
18465
- event: {
18466
- input: processAISDKCallInput(options).input,
18467
- metadata: baseMetadata
18468
- }
20008
+ event: buildAISDKModelStartEvent(
20009
+ callOptions,
20010
+ activeEntry.baseMetadata,
20011
+ {
20012
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
20013
+ }
20014
+ )
18469
20015
  }
18470
20016
  );
18471
20017
  };
18472
20018
  if (originalDoStream) {
18473
- resolvedModel.doStream = async function doStreamPatched(options) {
18474
- const span = parentSpan.startSpan({
20019
+ wrappedModel.doStream = async function doStreamPatched(callOptions) {
20020
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
20021
+ if (!activeEntry) {
20022
+ return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
20023
+ }
20024
+ closeOpenAISDKModelPatchSpans(activeEntry);
20025
+ const span = activeEntry.parentSpan.startSpan({
18475
20026
  name: "doStream",
18476
20027
  spanAttributes: {
18477
20028
  type: "llm" /* LLM */
18478
20029
  },
18479
- event: {
18480
- input: processAISDKCallInput(options).input,
18481
- metadata: baseMetadata
18482
- }
20030
+ event: buildAISDKModelStartEvent(
20031
+ callOptions,
20032
+ activeEntry.baseMetadata,
20033
+ {
20034
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
20035
+ }
20036
+ )
18483
20037
  });
20038
+ activeEntry.openSpans.add(span);
18484
20039
  const streamStartTime = getCurrentUnixTimestamp();
18485
20040
  const result = await withCurrent(
18486
20041
  span,
18487
- () => Reflect.apply(originalDoStream, resolvedModel, [options])
20042
+ () => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
18488
20043
  );
18489
20044
  let firstChunkTime;
18490
20045
  const output = {};
@@ -18492,6 +20047,44 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18492
20047
  let reasoning = "";
18493
20048
  const toolCalls = [];
18494
20049
  let object = void 0;
20050
+ let streamSpanEnded = false;
20051
+ const logAndEndStreamSpan = (usageUnavailableReason) => {
20052
+ if (streamSpanEnded) {
20053
+ return;
20054
+ }
20055
+ output.text = text;
20056
+ output.reasoning = reasoning;
20057
+ output.toolCalls = toolCalls;
20058
+ if (object !== void 0) {
20059
+ output.object = object;
20060
+ }
20061
+ const metrics = extractTokenMetrics(output);
20062
+ if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
20063
+ metrics.time_to_first_token = Math.max(
20064
+ firstChunkTime - streamStartTime,
20065
+ 1e-6
20066
+ );
20067
+ }
20068
+ const metadataPayload = buildResolvedMetadataPayload(
20069
+ output
20070
+ );
20071
+ const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
20072
+ output,
20073
+ metrics,
20074
+ "ai_sdk_result_missing_usage"
20075
+ );
20076
+ span.log({
20077
+ output: processAISDKOutput(
20078
+ output,
20079
+ activeEntry.denyOutputPaths
20080
+ ),
20081
+ metrics,
20082
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
20083
+ });
20084
+ activeEntry.openSpans.delete(span);
20085
+ span.end();
20086
+ streamSpanEnded = true;
20087
+ };
18495
20088
  const transformStream = new TransformStream({
18496
20089
  transform(chunk, controller) {
18497
20090
  if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
@@ -18529,33 +20122,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18529
20122
  }
18530
20123
  break;
18531
20124
  case "finish":
18532
- output.text = text;
18533
- output.reasoning = reasoning;
18534
- output.toolCalls = toolCalls;
18535
20125
  output.finishReason = chunk.finishReason;
18536
20126
  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();
20127
+ logAndEndStreamSpan();
18556
20128
  break;
18557
20129
  }
18558
20130
  controller.enqueue(chunk);
20131
+ },
20132
+ flush() {
20133
+ logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
18559
20134
  }
18560
20135
  });
18561
20136
  return {
@@ -18565,32 +20140,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18565
20140
  };
18566
20141
  }
18567
20142
  cleanup.push(() => {
18568
- resolvedModel.doGenerate = originalDoGenerate;
18569
- if (originalDoStream) {
18570
- resolvedModel.doStream = originalDoStream;
18571
- }
18572
- delete resolvedModel[AUTO_PATCHED_MODEL];
20143
+ cleanupModelEntry(state, wrappedModelRecord);
18573
20144
  });
18574
- return resolvedModel;
20145
+ patchedModels.set(resolvedModel, wrappedModel);
20146
+ patchedModels.set(wrappedModel, wrappedModel);
20147
+ return wrappedModel;
18575
20148
  };
18576
20149
  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]) {
20150
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
18578
20151
  return;
18579
20152
  }
18580
20153
  patchedTools.add(tool);
18581
- tool[AUTO_PATCHED_TOOL] = true;
18582
- const originalExecute = tool.execute;
20154
+ const toolRecord = tool;
20155
+ const entry = {
20156
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
20157
+ childTracingOptions,
20158
+ name,
20159
+ parentSpan
20160
+ };
20161
+ const cleanupToolEntry = (state2) => {
20162
+ const index = state2.entries.indexOf(entry);
20163
+ if (index >= 0) {
20164
+ state2.entries.splice(index, 1);
20165
+ }
20166
+ if (state2.entries.length > 0) {
20167
+ return;
20168
+ }
20169
+ tool.execute = state2.originalExecute;
20170
+ delete toolRecord[AUTO_PATCHED_TOOL];
20171
+ };
20172
+ const existingState = toolRecord[AUTO_PATCHED_TOOL];
20173
+ if (existingState) {
20174
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
20175
+ existingState.entries,
20176
+ parentSpan,
20177
+ cleanup
20178
+ )) {
20179
+ return;
20180
+ }
20181
+ if (!childTracingOptions.agentOwner) {
20182
+ shadowActiveAISDKChildPatchEntry(
20183
+ existingState.entries,
20184
+ entry,
20185
+ parentSpan,
20186
+ cleanup
20187
+ );
20188
+ }
20189
+ existingState.entries.push(entry);
20190
+ cleanup.push(() => {
20191
+ cleanupToolEntry(existingState);
20192
+ });
20193
+ return;
20194
+ }
20195
+ const originalExecute = toolRecord.execute;
20196
+ const state = {
20197
+ entries: [entry],
20198
+ originalExecute
20199
+ };
20200
+ toolRecord[AUTO_PATCHED_TOOL] = state;
18583
20201
  tool.execute = function executePatched(...args) {
20202
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
18584
20203
  const result = Reflect.apply(originalExecute, this, args);
20204
+ if (!activeEntry) {
20205
+ return result;
20206
+ }
18585
20207
  if (isAsyncGenerator2(result)) {
18586
20208
  return (async function* () {
18587
- const span = parentSpan.startSpan({
18588
- name,
20209
+ const span = activeEntry.parentSpan.startSpan({
20210
+ name: activeEntry.name,
18589
20211
  spanAttributes: {
18590
20212
  type: "tool" /* TOOL */
18591
20213
  }
18592
20214
  });
18593
- span.log({ input: args.length === 1 ? args[0] : args });
20215
+ span.log({ input: serializeToolExecutionInput(args) });
18594
20216
  try {
18595
20217
  let lastValue;
18596
20218
  for await (const value of result) {
@@ -18606,15 +20228,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18606
20228
  }
18607
20229
  })();
18608
20230
  }
18609
- return parentSpan.traced(
20231
+ return activeEntry.parentSpan.traced(
18610
20232
  async (span) => {
18611
- span.log({ input: args.length === 1 ? args[0] : args });
20233
+ span.log({ input: serializeToolExecutionInput(args) });
18612
20234
  const awaitedResult = await result;
18613
20235
  span.log({ output: awaitedResult });
18614
20236
  return awaitedResult;
18615
20237
  },
18616
20238
  {
18617
- name,
20239
+ name: activeEntry.name,
18618
20240
  spanAttributes: {
18619
20241
  type: "tool" /* TOOL */
18620
20242
  }
@@ -18622,8 +20244,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18622
20244
  );
18623
20245
  };
18624
20246
  cleanup.push(() => {
18625
- tool.execute = originalExecute;
18626
- delete tool[AUTO_PATCHED_TOOL];
20247
+ cleanupToolEntry(state);
18627
20248
  });
18628
20249
  };
18629
20250
  const patchTools = (tools) => {
@@ -18642,25 +20263,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
18642
20263
  }
18643
20264
  };
18644
20265
  if (params && typeof params === "object") {
18645
- const patchedParamModel = patchModel(params.model);
18646
- if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
20266
+ const originalParamModel = params.model;
20267
+ const patchedParamModel = patchModel(originalParamModel);
20268
+ if (patchedParamModel && patchedParamModel !== originalParamModel) {
18647
20269
  params.model = patchedParamModel;
20270
+ cleanup.push(() => {
20271
+ params.model = originalParamModel;
20272
+ });
18648
20273
  }
18649
20274
  patchTools(params.tools);
18650
20275
  }
18651
20276
  if (self && typeof self === "object") {
18652
20277
  const selfRecord = self;
18653
20278
  if (selfRecord.model !== void 0) {
18654
- const patchedSelfModel = patchModel(selfRecord.model);
18655
- if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
20279
+ const originalSelfModel = selfRecord.model;
20280
+ const patchedSelfModel = patchModel(originalSelfModel);
20281
+ if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
18656
20282
  selfRecord.model = patchedSelfModel;
20283
+ cleanup.push(() => {
20284
+ selfRecord.model = originalSelfModel;
20285
+ });
18657
20286
  }
18658
20287
  }
20288
+ if (selfRecord.tools !== void 0) {
20289
+ patchTools(selfRecord.tools);
20290
+ }
18659
20291
  if (selfRecord.settings && typeof selfRecord.settings === "object") {
18660
20292
  if (selfRecord.settings.model !== void 0) {
18661
- const patchedSettingsModel = patchModel(selfRecord.settings.model);
18662
- if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
20293
+ const originalSettingsModel = selfRecord.settings.model;
20294
+ const patchedSettingsModel = patchModel(originalSettingsModel);
20295
+ if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
18663
20296
  selfRecord.settings.model = patchedSettingsModel;
20297
+ cleanup.push(() => {
20298
+ if (selfRecord.settings) {
20299
+ selfRecord.settings.model = originalSettingsModel;
20300
+ }
20301
+ });
18664
20302
  }
18665
20303
  }
18666
20304
  if (selfRecord.settings.tools !== void 0) {
@@ -18757,99 +20395,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
18757
20395
  return isObject(part) && typeof part.type !== "string";
18758
20396
  }
18759
20397
  function patchAISDKStreamingResult(args) {
18760
- const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
20398
+ const {
20399
+ defaultDenyOutputPaths,
20400
+ endEvent,
20401
+ onComplete,
20402
+ result,
20403
+ span,
20404
+ startTime
20405
+ } = args;
18761
20406
  if (!result || typeof result !== "object") {
18762
20407
  return false;
18763
20408
  }
18764
20409
  const resultRecord = result;
18765
20410
  attachKnownResultPromiseHandlers(resultRecord);
20411
+ let finalized = false;
20412
+ const finalize = () => {
20413
+ if (finalized) {
20414
+ return;
20415
+ }
20416
+ finalized = true;
20417
+ finalizeAISDKChildTracing(endEvent);
20418
+ span.end();
20419
+ onComplete?.();
20420
+ };
20421
+ let outputLogged = false;
20422
+ const logStreamingOutput = async (firstChunkTime) => {
20423
+ if (outputLogged) {
20424
+ return;
20425
+ }
20426
+ outputLogged = true;
20427
+ try {
20428
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
20429
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
20430
+ metrics.time_to_first_token = firstChunkTime - startTime;
20431
+ }
20432
+ const output = await processAISDKStreamingOutput(
20433
+ result,
20434
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
20435
+ );
20436
+ const metadata = buildResolvedMetadataPayload(result).metadata;
20437
+ span.log({
20438
+ output,
20439
+ ...metadata ? { metadata } : {},
20440
+ metrics
20441
+ });
20442
+ } catch (error2) {
20443
+ span.log({ error: toLoggedError(error2) });
20444
+ } finally {
20445
+ finalize();
20446
+ }
20447
+ };
20448
+ const createAsyncIterableHooks = () => {
20449
+ let firstChunkTime;
20450
+ return {
20451
+ onChunk: (chunk) => {
20452
+ if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
20453
+ firstChunkTime = getCurrentUnixTimestamp();
20454
+ }
20455
+ },
20456
+ onComplete: async () => {
20457
+ await logStreamingOutput(firstChunkTime);
20458
+ },
20459
+ onError: (error2) => {
20460
+ if (!outputLogged) {
20461
+ outputLogged = true;
20462
+ span.log({
20463
+ error: error2.message
20464
+ });
20465
+ }
20466
+ finalize();
20467
+ },
20468
+ onCancel: finalize
20469
+ };
20470
+ };
20471
+ const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
20472
+ const patchAsyncIterableField = (field) => {
20473
+ let descriptorOwner = resultRecord;
20474
+ let descriptor;
20475
+ while (descriptorOwner) {
20476
+ descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
20477
+ if (descriptor) {
20478
+ break;
20479
+ }
20480
+ descriptorOwner = Object.getPrototypeOf(descriptorOwner);
20481
+ }
20482
+ if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
20483
+ return false;
20484
+ }
20485
+ if ("value" in descriptor) {
20486
+ if (!isAsyncIterable3(descriptor.value)) {
20487
+ return false;
20488
+ }
20489
+ try {
20490
+ Object.defineProperty(resultRecord, field, {
20491
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
20492
+ enumerable: descriptor.enumerable,
20493
+ value: patchAsyncIterable(descriptor.value),
20494
+ writable: descriptor.writable
20495
+ });
20496
+ return true;
20497
+ } catch {
20498
+ return false;
20499
+ }
20500
+ }
20501
+ if (typeof descriptor.get !== "function") {
20502
+ return false;
20503
+ }
20504
+ const originalGet = descriptor.get;
20505
+ const originalSet = descriptor.set;
20506
+ try {
20507
+ Object.defineProperty(resultRecord, field, {
20508
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
20509
+ enumerable: descriptor.enumerable,
20510
+ get() {
20511
+ const stream = originalGet.call(this);
20512
+ return isAsyncIterable3(stream) ? patchAsyncIterable(stream) : stream;
20513
+ },
20514
+ ...originalSet ? {
20515
+ set(value) {
20516
+ originalSet.call(this, value);
20517
+ }
20518
+ } : {}
20519
+ });
20520
+ return true;
20521
+ } catch {
20522
+ return false;
20523
+ }
20524
+ };
20525
+ let patched = false;
18766
20526
  if (isReadableStreamLike(resultRecord.baseStream)) {
18767
- let firstChunkTime2;
18768
- const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
20527
+ let firstChunkTime;
20528
+ const transformedBaseStream = resultRecord.baseStream.pipeThrough(
18769
20529
  new TransformStream({
18770
20530
  transform(chunk, controller) {
18771
- if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
18772
- firstChunkTime2 = getCurrentUnixTimestamp();
20531
+ if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
20532
+ firstChunkTime = getCurrentUnixTimestamp();
18773
20533
  }
18774
20534
  controller.enqueue(chunk);
18775
20535
  },
18776
20536
  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();
20537
+ await logStreamingOutput(firstChunkTime);
18793
20538
  }
18794
20539
  })
18795
20540
  );
20541
+ const reader = transformedBaseStream.getReader();
20542
+ const wrappedBaseStream = new ReadableStream({
20543
+ async pull(controller) {
20544
+ try {
20545
+ const { done, value } = await reader.read();
20546
+ if (done) {
20547
+ controller.close();
20548
+ return;
20549
+ }
20550
+ controller.enqueue(value);
20551
+ } catch (error2) {
20552
+ span.log({ error: toLoggedError(error2) });
20553
+ finalize();
20554
+ controller.error(error2);
20555
+ }
20556
+ },
20557
+ async cancel(reason) {
20558
+ try {
20559
+ finalize();
20560
+ } finally {
20561
+ await reader.cancel(reason);
20562
+ }
20563
+ }
20564
+ });
18796
20565
  Object.defineProperty(resultRecord, "baseStream", {
18797
20566
  configurable: true,
18798
20567
  enumerable: true,
18799
20568
  value: wrappedBaseStream,
18800
20569
  writable: true
18801
20570
  });
18802
- return true;
20571
+ patched = true;
18803
20572
  }
18804
- const streamField = findAsyncIterableField(resultRecord, [
20573
+ for (const field of [
18805
20574
  "partialObjectStream",
18806
20575
  "textStream",
18807
20576
  "fullStream",
18808
20577
  "stream"
18809
- ]);
18810
- if (!streamField) {
18811
- return false;
20578
+ ]) {
20579
+ patched = patchAsyncIterableField(field) || patched;
18812
20580
  }
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;
20581
+ return patched;
18853
20582
  }
18854
20583
  function attachKnownResultPromiseHandlers(result) {
18855
20584
  const promiseLikeFields = [
@@ -18881,34 +20610,72 @@ function attachKnownResultPromiseHandlers(result) {
18881
20610
  }
18882
20611
  }
18883
20612
  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 };
20613
+ return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
20614
+ }
20615
+ function createPatchedReadableStream(stream, hooks) {
20616
+ let reader;
20617
+ let completed = false;
20618
+ return new ReadableStream({
20619
+ async pull(controller) {
20620
+ reader ??= stream.getReader();
20621
+ try {
20622
+ const { done, value } = await reader.read();
20623
+ if (done) {
20624
+ completed = true;
20625
+ await hooks.onComplete();
20626
+ controller.close();
20627
+ return;
20628
+ }
20629
+ hooks.onChunk(value);
20630
+ controller.enqueue(value);
20631
+ } catch (error2) {
20632
+ completed = true;
20633
+ hooks.onError(
20634
+ error2 instanceof Error ? error2 : new Error(String(error2))
20635
+ );
20636
+ controller.error(error2);
20637
+ }
20638
+ },
20639
+ async cancel(reason) {
20640
+ if (!completed) {
20641
+ completed = true;
20642
+ try {
20643
+ await hooks.onCancel?.();
20644
+ } catch {
20645
+ }
20646
+ }
20647
+ if (reader) {
20648
+ await reader.cancel(reason);
20649
+ } else if (stream.cancel) {
20650
+ await stream.cancel(reason);
18892
20651
  }
18893
- } catch {
18894
20652
  }
18895
- }
18896
- return null;
20653
+ });
18897
20654
  }
18898
20655
  function createPatchedAsyncIterable(stream, hooks) {
18899
20656
  return {
18900
20657
  async *[Symbol.asyncIterator]() {
20658
+ let completed = false;
18901
20659
  try {
18902
20660
  for await (const chunk of stream) {
18903
20661
  hooks.onChunk(chunk);
18904
20662
  yield chunk;
18905
20663
  }
20664
+ completed = true;
18906
20665
  await hooks.onComplete();
18907
20666
  } catch (error2) {
20667
+ completed = true;
18908
20668
  hooks.onError(
18909
20669
  error2 instanceof Error ? error2 : new Error(String(error2))
18910
20670
  );
18911
20671
  throw error2;
20672
+ } finally {
20673
+ if (!completed) {
20674
+ try {
20675
+ await hooks.onCancel?.();
20676
+ } catch {
20677
+ }
20678
+ }
18912
20679
  }
18913
20680
  }
18914
20681
  };
@@ -18983,6 +20750,40 @@ function buildResolvedMetadataPayload(result) {
18983
20750
  }
18984
20751
  return Object.keys(metadata).length > 0 ? { metadata } : {};
18985
20752
  }
20753
+ function mergeMetadataPayload(metadataPayload, extraMetadata) {
20754
+ if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
20755
+ return metadataPayload;
20756
+ }
20757
+ return {
20758
+ metadata: {
20759
+ ...metadataPayload.metadata ?? {},
20760
+ ...extraMetadata
20761
+ }
20762
+ };
20763
+ }
20764
+ function buildMissingUsageMetadata(output, metrics, reason) {
20765
+ if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
20766
+ return void 0;
20767
+ }
20768
+ return { usage_unavailable_reason: reason };
20769
+ }
20770
+ function hasLoggedOutput(output) {
20771
+ if (output === null || output === void 0) {
20772
+ return false;
20773
+ }
20774
+ if (Array.isArray(output)) {
20775
+ return output.length > 0;
20776
+ }
20777
+ if (typeof output === "object") {
20778
+ return Object.keys(output).length > 0;
20779
+ }
20780
+ return true;
20781
+ }
20782
+ function hasTokenUsageMetrics(metrics) {
20783
+ return Object.keys(metrics).some(
20784
+ (key) => key !== "estimated_cost" && key !== "time_to_first_token"
20785
+ );
20786
+ }
18986
20787
  function resolveAISDKModel(model, aiSDK) {
18987
20788
  if (typeof model !== "string") {
18988
20789
  return model;
@@ -19006,7 +20807,45 @@ function isAsyncGenerator2(value) {
19006
20807
  function processAISDKOutput(output, denyOutputPaths) {
19007
20808
  if (!output) return output;
19008
20809
  const merged = extractSerializableOutputFields(output);
19009
- return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
20810
+ const deleteOutputPaths = denyOutputPaths.filter(
20811
+ (path8) => path8.toLowerCase().endsWith("headers")
20812
+ );
20813
+ const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
20814
+ for (const path8 of TRANSPORT_PAYLOAD_ROOT_PATHS) {
20815
+ const stack = [{ obj: sanitized, keys: parsePath(path8) }];
20816
+ while (stack.length > 0) {
20817
+ const entry = stack.pop();
20818
+ if (!entry || entry.keys.length === 0) {
20819
+ continue;
20820
+ }
20821
+ const firstKey = entry.keys[0];
20822
+ const remainingKeys = entry.keys.slice(1);
20823
+ if (firstKey === "[]") {
20824
+ if (Array.isArray(entry.obj)) {
20825
+ for (const item of entry.obj) {
20826
+ stack.push({
20827
+ obj: item,
20828
+ keys: remainingKeys
20829
+ });
20830
+ }
20831
+ }
20832
+ continue;
20833
+ }
20834
+ if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
20835
+ continue;
20836
+ }
20837
+ const record = entry.obj;
20838
+ if (remainingKeys.length === 0) {
20839
+ record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
20840
+ continue;
20841
+ }
20842
+ stack.push({
20843
+ obj: record[firstKey],
20844
+ keys: remainingKeys
20845
+ });
20846
+ }
20847
+ }
20848
+ return normalizeAISDKLoggedOutput(sanitized);
19010
20849
  }
19011
20850
  function processAISDKEmbeddingOutput(output, denyOutputPaths) {
19012
20851
  if (!output || typeof output !== "object") {
@@ -19097,6 +20936,8 @@ function extractTokenMetrics(result) {
19097
20936
  );
19098
20937
  if (totalTokens !== void 0) {
19099
20938
  metrics.tokens = totalTokens;
20939
+ } else if (promptTokens !== void 0 && completionTokens !== void 0) {
20940
+ metrics.tokens = promptTokens + completionTokens;
19100
20941
  }
19101
20942
  const promptCachedTokens = firstNumber2(
19102
20943
  usage.inputTokens?.cacheRead,
@@ -19220,7 +21061,9 @@ function extractGetterValues(obj) {
19220
21061
  const getterValues = {};
19221
21062
  const getterNames = [
19222
21063
  "content",
21064
+ "messages",
19223
21065
  "text",
21066
+ "output",
19224
21067
  "object",
19225
21068
  "value",
19226
21069
  "values",
@@ -19260,7 +21103,9 @@ function extractGetterValues(obj) {
19260
21103
  function extractSerializableOutputFields(output) {
19261
21104
  const serialized = {};
19262
21105
  const directFieldNames = [
21106
+ "messages",
19263
21107
  "steps",
21108
+ "output",
19264
21109
  "request",
19265
21110
  "responseMessages",
19266
21111
  "warnings",
@@ -19442,7 +21287,7 @@ function parsePath(path8) {
19442
21287
  }
19443
21288
  return keys;
19444
21289
  }
19445
- function omitAtPath(obj, keys) {
21290
+ function omitAtPath(obj, keys, deleteLeaf = false) {
19446
21291
  if (keys.length === 0) return;
19447
21292
  const firstKey = keys[0];
19448
21293
  const remainingKeys = keys.slice(1);
@@ -19452,29 +21297,36 @@ function omitAtPath(obj, keys) {
19452
21297
  if (remainingKeys.length > 0) {
19453
21298
  omitAtPath(
19454
21299
  item,
19455
- remainingKeys
21300
+ remainingKeys,
21301
+ deleteLeaf
19456
21302
  );
19457
21303
  }
19458
21304
  });
19459
21305
  }
19460
21306
  } else if (remainingKeys.length === 0) {
19461
21307
  if (obj && typeof obj === "object" && firstKey in obj) {
19462
- obj[firstKey] = "<omitted>";
21308
+ if (deleteLeaf) {
21309
+ delete obj[firstKey];
21310
+ } else {
21311
+ obj[firstKey] = "<omitted>";
21312
+ }
19463
21313
  }
19464
21314
  } else {
19465
21315
  if (obj && typeof obj === "object" && firstKey in obj) {
19466
21316
  omitAtPath(
19467
21317
  obj[firstKey],
19468
- remainingKeys
21318
+ remainingKeys,
21319
+ deleteLeaf
19469
21320
  );
19470
21321
  }
19471
21322
  }
19472
21323
  }
19473
- function omit(obj, paths) {
21324
+ function omit(obj, paths, deletePaths = []) {
19474
21325
  const result = deepCopy(obj);
21326
+ const deletePathSet = new Set(deletePaths);
19475
21327
  for (const path8 of paths) {
19476
21328
  const keys = parsePath(path8);
19477
- omitAtPath(result, keys);
21329
+ omitAtPath(result, keys, deletePathSet.has(path8));
19478
21330
  }
19479
21331
  return result;
19480
21332
  }
@@ -29523,15 +31375,18 @@ function observeFlue(event, ctx) {
29523
31375
  getObserveBridge().handle(event, ctx);
29524
31376
  }
29525
31377
  var interceptFlueExecution = (operation, ctx, next) => getObserveBridge().intercept(operation, ctx, next);
29526
- var braintrustFlueObserver = Object.assign(
29527
- observeFlue,
29528
- {
31378
+ function braintrustFlueInstrumentation() {
31379
+ return {
29529
31380
  dispose() {
29530
31381
  },
29531
31382
  interceptor: interceptFlueExecution,
29532
31383
  key: FLUE_INSTRUMENTATION_KEY,
29533
31384
  observe: observeFlue
29534
- }
31385
+ };
31386
+ }
31387
+ var braintrustFlueObserver = Object.assign(
31388
+ observeFlue,
31389
+ braintrustFlueInstrumentation()
29535
31390
  );
29536
31391
  var FluePlugin = class extends BasePlugin {
29537
31392
  onEnable() {
@@ -35085,7 +36940,7 @@ var MAIN_ORIGIN = "https://www.braintrust.dev";
35085
36940
  var WHITELISTED_ORIGINS = [
35086
36941
  MAIN_ORIGIN,
35087
36942
  "https://www.braintrustdata.com",
35088
- new RegExp("https://.*.preview.braintrust.dev")
36943
+ new RegExp("^https://[^/]+\\.preview\\.braintrust\\.dev$")
35089
36944
  ].concat(
35090
36945
  process.env.WHITELISTED_ORIGIN ? [process.env.WHITELISTED_ORIGIN] : []
35091
36946
  ).concat(