@mastra/braintrust 1.0.0-beta.1 → 1.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,135 @@
1
1
  # @mastra/braintrust
2
2
 
3
+ ## 1.0.0-beta.11
4
+
5
+ ### Minor Changes
6
+
7
+ - Formats messages in MODEL_GENERATION spans properly so the Thread view renders correctly. ([#11613](https://github.com/mastra-ai/mastra/pull/11613))
8
+
9
+ ### Patch Changes
10
+
11
+ - Add embedded documentation support for Mastra packages ([#11472](https://github.com/mastra-ai/mastra/pull/11472))
12
+
13
+ Mastra packages now include embedded documentation in the published npm package under `dist/docs/`. This enables coding agents and AI assistants to understand and use the framework by reading documentation directly from `node_modules`.
14
+
15
+ Each package includes:
16
+ - **SKILL.md** - Entry point explaining the package's purpose and capabilities
17
+ - **SOURCE_MAP.json** - Machine-readable index mapping exports to types and implementation files
18
+ - **Topic folders** - Conceptual documentation organized by feature area
19
+
20
+ Documentation is driven by the `packages` frontmatter field in MDX files, which maps docs to their corresponding packages. CI validation ensures all docs include this field.
21
+
22
+ - Improves AI SDK message conversion for Braintrust Thread view: ([#11673](https://github.com/mastra-ai/mastra/pull/11673))
23
+ - Adds support for non-text content types (images, files, reasoning) with informative placeholders
24
+ - Handles both AI SDK v4 `result` and v5 `output` fields for tool results
25
+ - Gracefully handles empty content arrays and unknown content types
26
+ - Adds comprehensive TypeScript type definitions for message conversion
27
+
28
+ - Updated dependencies [[`d2d3e22`](https://github.com/mastra-ai/mastra/commit/d2d3e22a419ee243f8812a84e3453dd44365ecb0), [`bc72b52`](https://github.com/mastra-ai/mastra/commit/bc72b529ee4478fe89ecd85a8be47ce0127b82a0), [`05b8bee`](https://github.com/mastra-ai/mastra/commit/05b8bee9e50e6c2a4a2bf210eca25ee212ca24fa), [`c042bd0`](https://github.com/mastra-ai/mastra/commit/c042bd0b743e0e86199d0cb83344ca7690e34a9c), [`940a2b2`](https://github.com/mastra-ai/mastra/commit/940a2b27480626ed7e74f55806dcd2181c1dd0c2), [`e0941c3`](https://github.com/mastra-ai/mastra/commit/e0941c3d7fc75695d5d258e7008fd5d6e650800c), [`0c0580a`](https://github.com/mastra-ai/mastra/commit/0c0580a42f697cd2a7d5973f25bfe7da9055038a), [`28f5f89`](https://github.com/mastra-ai/mastra/commit/28f5f89705f2409921e3c45178796c0e0d0bbb64), [`e601b27`](https://github.com/mastra-ai/mastra/commit/e601b272c70f3a5ecca610373aa6223012704892), [`3d3366f`](https://github.com/mastra-ai/mastra/commit/3d3366f31683e7137d126a3a57174a222c5801fb), [`5a4953f`](https://github.com/mastra-ai/mastra/commit/5a4953f7d25bb15ca31ed16038092a39cb3f98b3), [`eb9e522`](https://github.com/mastra-ai/mastra/commit/eb9e522ce3070a405e5b949b7bf5609ca51d7fe2), [`20e6f19`](https://github.com/mastra-ai/mastra/commit/20e6f1971d51d3ff6dd7accad8aaaae826d540ed), [`8a6734a`](https://github.com/mastra-ai/mastra/commit/8a6734a9b3eb192ada1f723d248b08b2258dd6b3), [`4f0b3c6`](https://github.com/mastra-ai/mastra/commit/4f0b3c66f196c06448487f680ccbb614d281e2f7), [`74c4f22`](https://github.com/mastra-ai/mastra/commit/74c4f22ed4c71e72598eacc346ba95cdbc00294f), [`81b6a8f`](https://github.com/mastra-ai/mastra/commit/81b6a8ff79f49a7549d15d66624ac1a0b8f5f971), [`e4d366a`](https://github.com/mastra-ai/mastra/commit/e4d366aeb500371dd4210d6aa8361a4c21d87034), [`a4f010b`](https://github.com/mastra-ai/mastra/commit/a4f010b22e4355a5fdee70a1fe0f6e4a692cc29e), [`73b0bb3`](https://github.com/mastra-ai/mastra/commit/73b0bb394dba7c9482eb467a97ab283dbc0ef4db), [`5627a8c`](https://github.com/mastra-ai/mastra/commit/5627a8c6dc11fe3711b3fa7a6ffd6eb34100a306), [`3ff45d1`](https://github.com/mastra-ai/mastra/commit/3ff45d10e0c80c5335a957ab563da72feb623520), [`251df45`](https://github.com/mastra-ai/mastra/commit/251df4531407dfa46d805feb40ff3fb49769f455), [`f894d14`](https://github.com/mastra-ai/mastra/commit/f894d148946629af7b1f452d65a9cf864cec3765), [`c2b9547`](https://github.com/mastra-ai/mastra/commit/c2b9547bf435f56339f23625a743b2147ab1c7a6), [`580b592`](https://github.com/mastra-ai/mastra/commit/580b5927afc82fe460dfdf9a38a902511b6b7e7f), [`58e3931`](https://github.com/mastra-ai/mastra/commit/58e3931af9baa5921688566210f00fb0c10479fa), [`08bb631`](https://github.com/mastra-ai/mastra/commit/08bb631ae2b14684b2678e3549d0b399a6f0561e), [`4fba91b`](https://github.com/mastra-ai/mastra/commit/4fba91bec7c95911dc28e369437596b152b04cd0), [`12b0cc4`](https://github.com/mastra-ai/mastra/commit/12b0cc4077d886b1a552637dedb70a7ade93528c)]:
29
+ - @mastra/core@1.0.0-beta.20
30
+ - @mastra/observability@1.0.0-beta.10
31
+
32
+ ## 1.0.0-beta.10
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies [[`51fec93`](https://github.com/mastra-ai/mastra/commit/51fec93ffd2f167b1247c23e5c04ed24e369ff75), [`5947fcd`](https://github.com/mastra-ai/mastra/commit/5947fcdd425531f29f9422026d466c2ee3113c93)]:
37
+ - @mastra/observability@1.0.0-beta.9
38
+ - @mastra/core@1.0.0-beta.18
39
+
40
+ ## 1.0.0-beta.9
41
+
42
+ ### Patch Changes
43
+
44
+ - Updated dependencies [[`3d93a15`](https://github.com/mastra-ai/mastra/commit/3d93a15796b158c617461c8b98bede476ebb43e2), [`efe406a`](https://github.com/mastra-ai/mastra/commit/efe406a1353c24993280ebc2ed61dd9f65b84b26), [`119e5c6`](https://github.com/mastra-ai/mastra/commit/119e5c65008f3e5cfca954eefc2eb85e3bf40da4), [`74e504a`](https://github.com/mastra-ai/mastra/commit/74e504a3b584eafd2f198001c6a113bbec589fd3), [`e33fdbd`](https://github.com/mastra-ai/mastra/commit/e33fdbd07b33920d81e823122331b0c0bee0bb59), [`929f69c`](https://github.com/mastra-ai/mastra/commit/929f69c3436fa20dd0f0e2f7ebe8270bd82a1529), [`8a73529`](https://github.com/mastra-ai/mastra/commit/8a73529ca01187f604b1f3019d0a725ac63ae55f)]:
45
+ - @mastra/core@1.0.0-beta.16
46
+ - @mastra/observability@1.0.0-beta.8
47
+
48
+ ## 1.0.0-beta.8
49
+
50
+ ### Patch Changes
51
+
52
+ - dependencies updates: ([#11389](https://github.com/mastra-ai/mastra/pull/11389))
53
+ - Updated dependency [`braintrust@^1.1.0` ↗︎](https://www.npmjs.com/package/braintrust/v/1.1.0) (from `^0.4.9`, in `dependencies`)
54
+ - Updated dependencies [[`33a4d2e`](https://github.com/mastra-ai/mastra/commit/33a4d2e4ed8af51f69256232f00c34d6b6b51d48), [`4aaa844`](https://github.com/mastra-ai/mastra/commit/4aaa844a4f19d054490f43638a990cc57bda8d2f), [`4a1a6cb`](https://github.com/mastra-ai/mastra/commit/4a1a6cb3facad54b2bb6780b00ce91d6de1edc08), [`31d13d5`](https://github.com/mastra-ai/mastra/commit/31d13d5fdc2e2380e2e3ee3ec9fb29d2a00f265d), [`4c62166`](https://github.com/mastra-ai/mastra/commit/4c621669f4a29b1f443eca3ba70b814afa286266), [`7bcbf10`](https://github.com/mastra-ai/mastra/commit/7bcbf10133516e03df964b941f9a34e9e4ab4177), [`4353600`](https://github.com/mastra-ai/mastra/commit/43536005a65988a8eede236f69122e7f5a284ba2), [`6986fb0`](https://github.com/mastra-ai/mastra/commit/6986fb064f5db6ecc24aa655e1d26529087b43b3), [`053e979`](https://github.com/mastra-ai/mastra/commit/053e9793b28e970086b0507f7f3b76ea32c1e838), [`e26dc9c`](https://github.com/mastra-ai/mastra/commit/e26dc9c3ccfec54ae3dc3e2b2589f741f9ae60a6), [`55edf73`](https://github.com/mastra-ai/mastra/commit/55edf7302149d6c964fbb7908b43babfc2b52145), [`27c0009`](https://github.com/mastra-ai/mastra/commit/27c0009777a6073d7631b0eb7b481d94e165b5ca), [`dee388d`](https://github.com/mastra-ai/mastra/commit/dee388dde02f2e63c53385ae69252a47ab6825cc), [`3f3fc30`](https://github.com/mastra-ai/mastra/commit/3f3fc3096f24c4a26cffeecfe73085928f72aa63), [`d90ea65`](https://github.com/mastra-ai/mastra/commit/d90ea6536f7aa51c6545a4e9215b55858e98e16d), [`d171e55`](https://github.com/mastra-ai/mastra/commit/d171e559ead9f52ec728d424844c8f7b164c4510), [`10c2735`](https://github.com/mastra-ai/mastra/commit/10c27355edfdad1ee2b826b897df74125eb81fb8), [`1924cf0`](https://github.com/mastra-ai/mastra/commit/1924cf06816e5e4d4d5333065ec0f4bb02a97799), [`b339816`](https://github.com/mastra-ai/mastra/commit/b339816df0984d0243d944ac2655d6ba5f809cde)]:
55
+ - @mastra/core@1.0.0-beta.15
56
+ - @mastra/observability@1.0.0-beta.7
57
+
58
+ ## 1.0.0-beta.7
59
+
60
+ ### Patch Changes
61
+
62
+ - Updated dependencies [[`4f94ed8`](https://github.com/mastra-ai/mastra/commit/4f94ed8177abfde3ec536e3574883e075423350c), [`ac3cc23`](https://github.com/mastra-ai/mastra/commit/ac3cc2397d1966bc0fc2736a223abc449d3c7719), [`a86f4df`](https://github.com/mastra-ai/mastra/commit/a86f4df0407311e0d2ea49b9a541f0938810d6a9), [`029540c`](https://github.com/mastra-ai/mastra/commit/029540ca1e582fc2dd8d288ecd4a9b0f31a954ef), [`f1bbc94`](https://github.com/mastra-ai/mastra/commit/f1bbc941934a4806f5512b3fb1507c77420336b1), [`66741d1`](https://github.com/mastra-ai/mastra/commit/66741d1a99c4f42cf23a16109939e8348ac6852e), [`01b20fe`](https://github.com/mastra-ai/mastra/commit/01b20fefb7c67c2b7d79417598ef4e60256d1225), [`0dbf199`](https://github.com/mastra-ai/mastra/commit/0dbf199110f22192ce5c95b1c8148d4872b4d119), [`a7ce182`](https://github.com/mastra-ai/mastra/commit/a7ce1822a8785ce45d62dd5c911af465e144f7d7)]:
63
+ - @mastra/core@1.0.0-beta.14
64
+ - @mastra/observability@1.0.0-beta.6
65
+
66
+ ## 1.0.0-beta.6
67
+
68
+ ### Patch Changes
69
+
70
+ - Updated dependencies [[`d5ed981`](https://github.com/mastra-ai/mastra/commit/d5ed981c8701c1b8a27a5f35a9a2f7d9244e695f), [`9650cce`](https://github.com/mastra-ai/mastra/commit/9650cce52a1d917ff9114653398e2a0f5c3ba808), [`932d63d`](https://github.com/mastra-ai/mastra/commit/932d63dd51be9c8bf1e00e3671fe65606c6fb9cd), [`b760b73`](https://github.com/mastra-ai/mastra/commit/b760b731aca7c8a3f041f61d57a7f125ae9cb215), [`695a621`](https://github.com/mastra-ai/mastra/commit/695a621528bdabeb87f83c2277cf2bb084c7f2b4), [`2b459f4`](https://github.com/mastra-ai/mastra/commit/2b459f466fd91688eeb2a44801dc23f7f8a887ab), [`486352b`](https://github.com/mastra-ai/mastra/commit/486352b66c746602b68a95839f830de14c7fb8c0), [`09e4bae`](https://github.com/mastra-ai/mastra/commit/09e4bae18dd5357d2ae078a4a95a2af32168ab08), [`24b76d8`](https://github.com/mastra-ai/mastra/commit/24b76d8e17656269c8ed09a0c038adb9cc2ae95a), [`243a823`](https://github.com/mastra-ai/mastra/commit/243a8239c5906f5c94e4f78b54676793f7510ae3), [`486352b`](https://github.com/mastra-ai/mastra/commit/486352b66c746602b68a95839f830de14c7fb8c0), [`c61fac3`](https://github.com/mastra-ai/mastra/commit/c61fac3add96f0dcce0208c07415279e2537eb62), [`6f14f70`](https://github.com/mastra-ai/mastra/commit/6f14f706ccaaf81b69544b6c1b75ab66a41e5317), [`09e4bae`](https://github.com/mastra-ai/mastra/commit/09e4bae18dd5357d2ae078a4a95a2af32168ab08), [`4524734`](https://github.com/mastra-ai/mastra/commit/45247343e384717a7c8404296275c56201d6470f), [`2a53598`](https://github.com/mastra-ai/mastra/commit/2a53598c6d8cfeb904a7fc74e57e526d751c8fa6), [`c7cd3c7`](https://github.com/mastra-ai/mastra/commit/c7cd3c7a187d7aaf79e2ca139de328bf609a14b4), [`5a632bd`](https://github.com/mastra-ai/mastra/commit/5a632bdf7b78953b664f5e038e98d4ba5f971e47), [`847c212`](https://github.com/mastra-ai/mastra/commit/847c212caba7df0d6f2fc756b494ac3c75c3720d), [`6f941c4`](https://github.com/mastra-ai/mastra/commit/6f941c438ca5f578619788acc7608fc2e23bd176)]:
71
+ - @mastra/core@1.0.0-beta.12
72
+ - @mastra/observability@1.0.0-beta.5
73
+
74
+ ## 1.0.0-beta.5
75
+
76
+ ### Patch Changes
77
+
78
+ - Fixed CachedToken tracking in all Observability Exporters. Also fixed TimeToFirstToken in Langfuse, Braintrust, PostHog exporters. Fixed trace formatting in Posthog Exporter. ([#11029](https://github.com/mastra-ai/mastra/pull/11029))
79
+
80
+ - Updated dependencies [[`edb07e4`](https://github.com/mastra-ai/mastra/commit/edb07e49283e0c28bd094a60e03439bf6ecf0221), [`b7e17d3`](https://github.com/mastra-ai/mastra/commit/b7e17d3f5390bb5a71efc112204413656fcdc18d), [`261473a`](https://github.com/mastra-ai/mastra/commit/261473ac637e633064a22076671e2e02b002214d), [`5d7000f`](https://github.com/mastra-ai/mastra/commit/5d7000f757cd65ea9dc5b05e662fd83dfd44e932), [`4f0331a`](https://github.com/mastra-ai/mastra/commit/4f0331a79bf6eb5ee598a5086e55de4b5a0ada03), [`8a000da`](https://github.com/mastra-ai/mastra/commit/8a000da0c09c679a2312f6b3aa05b2ca78ca7393)]:
81
+ - @mastra/core@1.0.0-beta.10
82
+ - @mastra/observability@1.0.0-beta.4
83
+
84
+ ## 1.0.0-beta.4
85
+
86
+ ### Patch Changes
87
+
88
+ - Fix traceMap overwrite when multiple root spans share the same traceId ([#10903](https://github.com/mastra-ai/mastra/pull/10903))
89
+
90
+ Previously, when multiple root spans shared the same traceId (e.g., multiple `agent.stream` calls in the same trace), the trace data would be overwritten instead of reused. This could cause spans to be orphaned or lost.
91
+
92
+ Now both exporters check if a trace already exists before creating a new one, matching the behavior of the Langfuse and PostHog exporters.
93
+
94
+ - Updated dependencies [[`0d41fe2`](https://github.com/mastra-ai/mastra/commit/0d41fe245355dfc66d61a0d9c85d9400aac351ff), [`6b3ba91`](https://github.com/mastra-ai/mastra/commit/6b3ba91494cc10394df96782f349a4f7b1e152cc), [`7907fd1`](https://github.com/mastra-ai/mastra/commit/7907fd1c5059813b7b870b81ca71041dc807331b)]:
95
+ - @mastra/core@1.0.0-beta.8
96
+
97
+ ## 1.0.0-beta.3
98
+
99
+ ### Patch Changes
100
+
101
+ - Add time-to-first-token (TTFT) support for Braintrust integration ([#10840](https://github.com/mastra-ai/mastra/pull/10840))
102
+
103
+ Adds `time_to_first_token` metric to Braintrust spans, populated from the `completionStartTime` attribute captured when the first streaming chunk arrives.
104
+
105
+ ```typescript
106
+ // time_to_first_token is now automatically sent to Braintrust
107
+ // as part of span metrics during streaming
108
+ const result = await agent.stream('Hello');
109
+ ```
110
+
111
+ - Fix Braintrust Thread view not displaying LLM messages correctly ([#10794](https://github.com/mastra-ai/mastra/pull/10794))
112
+
113
+ Transforms LLM input/output format to match Braintrust's expected format for Thread view. Input is unwrapped from `{ messages: [...] }` to direct array format, and output is unwrapped from `{ content: '...' }` to direct string format.
114
+
115
+ - Fixed Braintrust span nesting so root spans correctly show as the trace name. ([#10876](https://github.com/mastra-ai/mastra/pull/10876))
116
+
117
+ - Updated dependencies [[`6c59a40`](https://github.com/mastra-ai/mastra/commit/6c59a40e0ad160467bd13d63a8a287028d75b02d), [`3076c67`](https://github.com/mastra-ai/mastra/commit/3076c6778b18988ae7d5c4c5c466366974b2d63f), [`85d7ee1`](https://github.com/mastra-ai/mastra/commit/85d7ee18ff4e14d625a8a30ec6656bb49804989b), [`c6c1092`](https://github.com/mastra-ai/mastra/commit/c6c1092f8fbf76109303f69e000e96fd1960c4ce), [`81dc110`](https://github.com/mastra-ai/mastra/commit/81dc11008d147cf5bdc8996ead1aa61dbdebb6fc), [`7aedb74`](https://github.com/mastra-ai/mastra/commit/7aedb74883adf66af38e270e4068fd42e7a37036), [`8f02d80`](https://github.com/mastra-ai/mastra/commit/8f02d800777397e4b45d7f1ad041988a8b0c6630), [`d7aad50`](https://github.com/mastra-ai/mastra/commit/d7aad501ce61646b76b4b511e558ac4eea9884d0), [`ce0a73a`](https://github.com/mastra-ai/mastra/commit/ce0a73abeaa75b10ca38f9e40a255a645d50ebfb), [`a02e542`](https://github.com/mastra-ai/mastra/commit/a02e542d23179bad250b044b17ff023caa61739f), [`a372c64`](https://github.com/mastra-ai/mastra/commit/a372c640ad1fd12e8f0613cebdc682fc156b4d95), [`8846867`](https://github.com/mastra-ai/mastra/commit/8846867ffa9a3746767618e314bebac08eb77d87), [`0bada2f`](https://github.com/mastra-ai/mastra/commit/0bada2f2c1234932cf30c1c47a719ffb64b801c5), [`42a42cf`](https://github.com/mastra-ai/mastra/commit/42a42cf3132b9786feecbb8c13c583dce5b0e198), [`cc60ff6`](https://github.com/mastra-ai/mastra/commit/cc60ff616541a3b0fb531a7e469bf9ae7bb90528), [`ae08bf0`](https://github.com/mastra-ai/mastra/commit/ae08bf0ebc6a4e4da992b711c4a389c32ba84cf4), [`21735a7`](https://github.com/mastra-ai/mastra/commit/21735a7ef306963554a69a89b44f06c3bcd85141), [`1d877b8`](https://github.com/mastra-ai/mastra/commit/1d877b8d7b536a251c1a7a18db7ddcf4f68d6f8b)]:
118
+ - @mastra/observability@1.0.0-beta.3
119
+ - @mastra/core@1.0.0-beta.7
120
+
121
+ ## 1.0.0-beta.2
122
+
123
+ ### Minor Changes
124
+
125
+ - Adds trace tagging support to the BrainTrust and Langfuse tracing exporters. ([#10765](https://github.com/mastra-ai/mastra/pull/10765))
126
+
127
+ ### Patch Changes
128
+
129
+ - Updated dependencies [[`ac0d2f4`](https://github.com/mastra-ai/mastra/commit/ac0d2f4ff8831f72c1c66c2be809706d17f65789), [`1a0d3fc`](https://github.com/mastra-ai/mastra/commit/1a0d3fc811482c9c376cdf79ee615c23bae9b2d6), [`85a628b`](https://github.com/mastra-ai/mastra/commit/85a628b1224a8f64cd82ea7f033774bf22df7a7e), [`c237233`](https://github.com/mastra-ai/mastra/commit/c23723399ccedf7f5744b3f40997b79246bfbe64), [`15f9e21`](https://github.com/mastra-ai/mastra/commit/15f9e216177201ea6e3f6d0bfb063fcc0953444f), [`ff94dea`](https://github.com/mastra-ai/mastra/commit/ff94dea935f4e34545c63bcb6c29804732698809), [`5b2ff46`](https://github.com/mastra-ai/mastra/commit/5b2ff4651df70c146523a7fca773f8eb0a2272f8), [`db41688`](https://github.com/mastra-ai/mastra/commit/db4168806d007417e2e60b4f68656dca4e5f40c9), [`103586c`](https://github.com/mastra-ai/mastra/commit/103586cb23ebcd2466c7f68a71674d37cc10e263), [`5ca599d`](https://github.com/mastra-ai/mastra/commit/5ca599d0bb59a1595f19f58473fcd67cc71cef58), [`bff1145`](https://github.com/mastra-ai/mastra/commit/bff114556b3cbadad9b2768488708f8ad0e91475), [`5c8ca24`](https://github.com/mastra-ai/mastra/commit/5c8ca247094e0cc2cdbd7137822fb47241f86e77), [`e191844`](https://github.com/mastra-ai/mastra/commit/e1918444ca3f80e82feef1dad506cd4ec6e2875f), [`22553f1`](https://github.com/mastra-ai/mastra/commit/22553f11c63ee5e966a9c034a349822249584691), [`7237163`](https://github.com/mastra-ai/mastra/commit/72371635dbf96a87df4b073cc48fc655afbdce3d), [`2500740`](https://github.com/mastra-ai/mastra/commit/2500740ea23da067d6e50ec71c625ab3ce275e64), [`873ecbb`](https://github.com/mastra-ai/mastra/commit/873ecbb517586aa17d2f1e99283755b3ebb2863f), [`4f9bbe5`](https://github.com/mastra-ai/mastra/commit/4f9bbe5968f42c86f4930b8193de3c3c17e5bd36), [`02e51fe`](https://github.com/mastra-ai/mastra/commit/02e51feddb3d4155cfbcc42624fd0d0970d032c0), [`8f3fa3a`](https://github.com/mastra-ai/mastra/commit/8f3fa3a652bb77da092f913ec51ae46e3a7e27dc), [`cd29ad2`](https://github.com/mastra-ai/mastra/commit/cd29ad23a255534e8191f249593849ed29160886), [`bdf4d8c`](https://github.com/mastra-ai/mastra/commit/bdf4d8cdc656d8a2c21d81834bfa3bfa70f56c16), [`854e3da`](https://github.com/mastra-ai/mastra/commit/854e3dad5daac17a91a20986399d3a51f54bf68b), [`ce18d38`](https://github.com/mastra-ai/mastra/commit/ce18d38678c65870350d123955014a8432075fd9), [`cccf9c8`](https://github.com/mastra-ai/mastra/commit/cccf9c8b2d2dfc1a5e63919395b83d78c89682a0), [`61a5705`](https://github.com/mastra-ai/mastra/commit/61a570551278b6743e64243b3ce7d73de915ca8a), [`db70a48`](https://github.com/mastra-ai/mastra/commit/db70a48aeeeeb8e5f92007e8ede52c364ce15287), [`f0fdc14`](https://github.com/mastra-ai/mastra/commit/f0fdc14ee233d619266b3d2bbdeea7d25cfc6d13), [`db18bc9`](https://github.com/mastra-ai/mastra/commit/db18bc9c3825e2c1a0ad9a183cc9935f6691bfa1), [`9b37b56`](https://github.com/mastra-ai/mastra/commit/9b37b565e1f2a76c24f728945cc740c2b09be9da), [`41a23c3`](https://github.com/mastra-ai/mastra/commit/41a23c32f9877d71810f37e24930515df2ff7a0f), [`5d171ad`](https://github.com/mastra-ai/mastra/commit/5d171ad9ef340387276b77c2bb3e83e83332d729), [`f03ae60`](https://github.com/mastra-ai/mastra/commit/f03ae60500fe350c9d828621006cdafe1975fdd8), [`d1e74a0`](https://github.com/mastra-ai/mastra/commit/d1e74a0a293866dece31022047f5dbab65a304d0), [`39e7869`](https://github.com/mastra-ai/mastra/commit/39e7869bc7d0ee391077ce291474d8a84eedccff), [`5761926`](https://github.com/mastra-ai/mastra/commit/57619260c4a2cdd598763abbacd90de594c6bc76), [`c900fdd`](https://github.com/mastra-ai/mastra/commit/c900fdd504c41348efdffb205cfe80d48c38fa33), [`604a79f`](https://github.com/mastra-ai/mastra/commit/604a79fecf276e26a54a3fe01bb94e65315d2e0e), [`887f0b4`](https://github.com/mastra-ai/mastra/commit/887f0b4746cdbd7cb7d6b17ac9f82aeb58037ea5), [`2562143`](https://github.com/mastra-ai/mastra/commit/256214336b4faa78646c9c1776612393790d8784), [`ef11a61`](https://github.com/mastra-ai/mastra/commit/ef11a61920fa0ed08a5b7ceedd192875af119749)]:
130
+ - @mastra/core@1.0.0-beta.6
131
+ - @mastra/observability@1.0.0-beta.2
132
+
3
133
  ## 1.0.0-beta.1
4
134
 
5
135
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -8,29 +8,25 @@ var braintrust = require('braintrust');
8
8
  // src/tracing.ts
9
9
 
10
10
  // src/metrics.ts
11
- function normalizeUsageMetrics(modelAttr) {
11
+ function formatUsageMetrics(usage) {
12
12
  const metrics = {};
13
- if (modelAttr.usage?.inputTokens !== void 0) {
14
- metrics.prompt_tokens = modelAttr.usage?.inputTokens;
15
- } else if (modelAttr.usage?.promptTokens !== void 0) {
16
- metrics.prompt_tokens = modelAttr.usage?.promptTokens;
13
+ if (usage?.inputTokens !== void 0) {
14
+ metrics.prompt_tokens = usage.inputTokens;
17
15
  }
18
- if (modelAttr.usage?.outputTokens !== void 0) {
19
- metrics.completion_tokens = modelAttr.usage?.outputTokens;
20
- } else if (modelAttr.usage?.completionTokens !== void 0) {
21
- metrics.completion_tokens = modelAttr.usage?.completionTokens;
16
+ if (usage?.outputTokens !== void 0) {
17
+ metrics.completion_tokens = usage.outputTokens;
22
18
  }
23
- if (modelAttr.usage?.totalTokens !== void 0) {
24
- metrics.tokens = modelAttr.usage?.totalTokens;
19
+ if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
20
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
25
21
  }
26
- if (modelAttr.usage?.reasoningTokens !== void 0) {
27
- metrics.completion_reasoning_tokens = modelAttr.usage?.reasoningTokens;
22
+ if (usage?.outputDetails?.reasoning !== void 0) {
23
+ metrics.completion_reasoning_tokens = usage.outputDetails.reasoning;
28
24
  }
29
- if (modelAttr.usage?.promptCacheHitTokens !== void 0) {
30
- metrics.prompt_cached_tokens = modelAttr.usage?.promptCacheHitTokens;
25
+ if (usage?.inputDetails?.cacheRead !== void 0) {
26
+ metrics.prompt_cached_tokens = usage.inputDetails.cacheRead;
31
27
  }
32
- if (modelAttr.usage?.promptCacheMissTokens !== void 0) {
33
- metrics.prompt_cache_creation_tokens = modelAttr.usage?.promptCacheMissTokens;
28
+ if (usage?.inputDetails?.cacheWrite !== void 0) {
29
+ metrics.prompt_cache_creation_tokens = usage.inputDetails.cacheWrite;
34
30
  }
35
31
  return metrics;
36
32
  }
@@ -40,7 +36,6 @@ var MASTRA_TRACE_ID_METADATA_KEY = "mastra-trace-id";
40
36
  var DEFAULT_SPAN_TYPE = "task";
41
37
  var SPAN_TYPE_EXCEPTIONS = {
42
38
  [observability$1.SpanType.MODEL_GENERATION]: "llm",
43
- [observability$1.SpanType.MODEL_CHUNK]: "llm",
44
39
  [observability$1.SpanType.TOOL_CALL]: "tool",
45
40
  [observability$1.SpanType.MCP_TOOL_CALL]: "tool",
46
41
  [observability$1.SpanType.WORKFLOW_CONDITIONAL_EVAL]: "function",
@@ -111,20 +106,17 @@ var BraintrustExporter = class extends observability.BaseExporter {
111
106
  return;
112
107
  }
113
108
  const payload = this.buildSpanPayload(span);
114
- const shouldOmitParentIds = spanData.isExternal && !span.parentSpanId;
115
109
  const braintrustSpan = braintrustParent.startSpan({
116
110
  spanId: span.id,
117
111
  name: span.name,
118
112
  type: mapSpanType(span.type),
119
- ...shouldOmitParentIds ? {} : {
120
- parentSpanIds: span.parentSpanId ? { spanId: span.parentSpanId, rootSpanId: span.traceId } : { spanId: span.traceId, rootSpanId: span.traceId }
121
- },
122
113
  ...payload
123
114
  });
124
115
  braintrustSpan.log({
125
116
  metadata: {
126
117
  [MASTRA_TRACE_ID_METADATA_KEY]: span.traceId
127
- }
118
+ },
119
+ ...span.isRootSpan && span.tags?.length ? { tags: span.tags } : {}
128
120
  });
129
121
  spanData.spans.set(span.id, braintrustSpan);
130
122
  }
@@ -190,50 +182,60 @@ var BraintrustExporter = class extends observability.BaseExporter {
190
182
  spanId: span.id,
191
183
  name: span.name,
192
184
  type: mapSpanType(span.type),
193
- parentSpanIds: span.parentSpanId ? { spanId: span.parentSpanId, rootSpanId: span.traceId } : { spanId: span.traceId, rootSpanId: span.traceId },
194
185
  startTime: span.startTime.getTime() / 1e3,
195
186
  ...payload
196
187
  });
197
188
  braintrustSpan.end({ endTime: span.startTime.getTime() / 1e3 });
198
189
  }
199
- /**
200
- * Creates a new logger per trace using config credentials
201
- */
202
- async initLoggerPerTrace(span) {
203
- const logger = await braintrust.initLogger({
204
- projectName: this.config.projectName ?? "mastra-tracing",
205
- apiKey: this.config.apiKey,
206
- appUrl: this.config.endpoint,
207
- ...this.config.tuningParameters
208
- });
209
- this.traceMap.set(span.traceId, {
190
+ initTraceMap(params) {
191
+ const { traceId, isExternal, logger } = params;
192
+ if (this.traceMap.has(traceId)) {
193
+ this.logger.debug("Braintrust exporter: Reusing existing trace from local map", { traceId });
194
+ return;
195
+ }
196
+ this.traceMap.set(traceId, {
210
197
  logger,
211
198
  spans: /* @__PURE__ */ new Map(),
212
199
  activeIds: /* @__PURE__ */ new Set(),
213
- isExternal: false
200
+ isExternal
214
201
  });
215
202
  }
203
+ /**
204
+ * Creates a new logger per trace using config credentials
205
+ */
206
+ async initLoggerPerTrace(span) {
207
+ if (this.traceMap.has(span.traceId)) {
208
+ this.logger.debug("Braintrust exporter: Reusing existing trace from local map", { traceId: span.traceId });
209
+ return;
210
+ }
211
+ try {
212
+ const loggerInstance = await braintrust.initLogger({
213
+ projectName: this.config.projectName ?? "mastra-tracing",
214
+ apiKey: this.config.apiKey,
215
+ appUrl: this.config.endpoint,
216
+ ...this.config.tuningParameters
217
+ });
218
+ this.initTraceMap({ logger: loggerInstance, isExternal: false, traceId: span.traceId });
219
+ } catch (err) {
220
+ this.logger.error("Braintrust exporter: Failed to initialize logger", { error: err, traceId: span.traceId });
221
+ this.setDisabled("Failed to initialize Braintrust logger");
222
+ }
223
+ }
216
224
  /**
217
225
  * Uses provided logger and detects external Braintrust spans.
218
226
  * If a Braintrust span is detected (from logger.traced() or Eval()), attaches to it.
219
227
  * Otherwise, uses the provided logger instance.
220
228
  */
221
229
  async initLoggerOrUseContext(span) {
230
+ if (this.traceMap.has(span.traceId)) {
231
+ this.logger.debug("Braintrust exporter: Reusing existing trace from local map", { traceId: span.traceId });
232
+ return;
233
+ }
222
234
  const braintrustSpan = braintrust.currentSpan();
223
235
  if (braintrustSpan && braintrustSpan.id) {
224
- this.traceMap.set(span.traceId, {
225
- logger: braintrustSpan,
226
- spans: /* @__PURE__ */ new Map(),
227
- activeIds: /* @__PURE__ */ new Set(),
228
- isExternal: true
229
- });
236
+ this.initTraceMap({ logger: braintrustSpan, isExternal: true, traceId: span.traceId });
230
237
  } else {
231
- this.traceMap.set(span.traceId, {
232
- logger: this.providedLogger,
233
- spans: /* @__PURE__ */ new Map(),
234
- activeIds: /* @__PURE__ */ new Set(),
235
- isExternal: false
236
- });
238
+ this.initTraceMap({ logger: this.providedLogger, isExternal: false, traceId: span.traceId });
237
239
  }
238
240
  }
239
241
  getSpanData(options) {
@@ -273,13 +275,186 @@ var BraintrustExporter = class extends observability.BaseExporter {
273
275
  method
274
276
  });
275
277
  }
278
+ /**
279
+ * Converts AI SDK message format to OpenAI Chat Completion format for Braintrust.
280
+ *
281
+ * Supports both AI SDK v4 and v5 formats:
282
+ * - v4 uses 'args' for tool calls and 'result' for tool results
283
+ * - v5 uses 'input' for tool calls and 'output' for tool results
284
+ *
285
+ * AI SDK format:
286
+ * { role: "user", content: [{ type: "text", text: "hello" }] }
287
+ * { role: "assistant", content: [{ type: "text", text: "..." }, { type: "tool-call", toolCallId: "...", toolName: "...", args: {...} }] }
288
+ * { role: "tool", content: [{ type: "tool-result", toolCallId: "...", result: {...} }] }
289
+ *
290
+ * OpenAI format (what Braintrust expects):
291
+ * { role: "user", content: "hello" }
292
+ * { role: "assistant", content: "...", tool_calls: [{ id: "...", type: "function", function: { name: "...", arguments: "..." } }] }
293
+ * { role: "tool", content: "result", tool_call_id: "..." }
294
+ */
295
+ convertAISDKMessage(message) {
296
+ if (!message || typeof message !== "object") {
297
+ return message;
298
+ }
299
+ const { role, content, ...rest } = message;
300
+ if (typeof content === "string") {
301
+ return message;
302
+ }
303
+ if (Array.isArray(content)) {
304
+ if (content.length === 0) {
305
+ return { role, content: "", ...rest };
306
+ }
307
+ if (role === "user" || role === "system") {
308
+ const contentParts = content.map((part) => this.convertContentPart(part)).filter(Boolean);
309
+ return {
310
+ role,
311
+ content: contentParts.length > 0 ? contentParts.join("\n") : "",
312
+ ...rest
313
+ };
314
+ }
315
+ if (role === "assistant") {
316
+ const contentParts = content.filter((part) => part?.type !== "tool-call").map((part) => this.convertContentPart(part)).filter(Boolean);
317
+ const toolCallParts = content.filter((part) => part?.type === "tool-call");
318
+ const result = {
319
+ role,
320
+ content: contentParts.length > 0 ? contentParts.join("\n") : "",
321
+ ...rest
322
+ };
323
+ if (toolCallParts.length > 0) {
324
+ result.tool_calls = toolCallParts.map((tc) => {
325
+ const toolCallId = tc.toolCallId;
326
+ const toolName = tc.toolName;
327
+ const args = tc.args ?? tc.input;
328
+ let argsString;
329
+ if (typeof args === "string") {
330
+ argsString = args;
331
+ } else if (args !== void 0 && args !== null) {
332
+ argsString = JSON.stringify(args);
333
+ } else {
334
+ argsString = "{}";
335
+ }
336
+ return {
337
+ id: toolCallId,
338
+ type: "function",
339
+ function: {
340
+ name: toolName,
341
+ arguments: argsString
342
+ }
343
+ };
344
+ });
345
+ }
346
+ return result;
347
+ }
348
+ if (role === "tool") {
349
+ const toolResult = content.find((part) => part?.type === "tool-result");
350
+ if (toolResult) {
351
+ const resultData = toolResult.output ?? toolResult.result;
352
+ const resultContent = this.serializeToolResult(resultData);
353
+ return {
354
+ role: "tool",
355
+ content: resultContent,
356
+ tool_call_id: toolResult.toolCallId
357
+ };
358
+ }
359
+ }
360
+ }
361
+ return message;
362
+ }
363
+ /**
364
+ * Converts a content part to a string representation.
365
+ * Handles text, image, file, reasoning, and other content types.
366
+ */
367
+ convertContentPart(part) {
368
+ if (!part || typeof part !== "object") {
369
+ return null;
370
+ }
371
+ switch (part.type) {
372
+ case "text":
373
+ return part.text || null;
374
+ case "image":
375
+ return "[image]";
376
+ case "file": {
377
+ const filePart = part;
378
+ if (filePart.filename || filePart.name) {
379
+ return `[file: ${filePart.filename || filePart.name}]`;
380
+ }
381
+ return "[file]";
382
+ }
383
+ case "reasoning": {
384
+ const reasoningPart = part;
385
+ if (typeof reasoningPart.text === "string" && reasoningPart.text.length > 0) {
386
+ return `[reasoning: ${reasoningPart.text.substring(0, 100)}${reasoningPart.text.length > 100 ? "..." : ""}]`;
387
+ }
388
+ return "[reasoning]";
389
+ }
390
+ case "tool-call":
391
+ return null;
392
+ case "tool-result":
393
+ return null;
394
+ default: {
395
+ const unknownPart = part;
396
+ if (typeof unknownPart.text === "string") {
397
+ return unknownPart.text;
398
+ }
399
+ if (typeof unknownPart.content === "string") {
400
+ return unknownPart.content;
401
+ }
402
+ return `[${unknownPart.type || "unknown"}]`;
403
+ }
404
+ }
405
+ }
406
+ /**
407
+ * Serializes tool result data to a string for OpenAI format.
408
+ */
409
+ serializeToolResult(resultData) {
410
+ if (typeof resultData === "string") {
411
+ return resultData;
412
+ }
413
+ if (resultData && typeof resultData === "object" && "value" in resultData) {
414
+ return typeof resultData.value === "string" ? resultData.value : JSON.stringify(resultData.value);
415
+ }
416
+ if (resultData === void 0 || resultData === null) {
417
+ return "";
418
+ }
419
+ try {
420
+ return JSON.stringify(resultData);
421
+ } catch {
422
+ return "[unserializable result]";
423
+ }
424
+ }
425
+ /**
426
+ * Transforms MODEL_GENERATION input to Braintrust Thread view format.
427
+ * Converts AI SDK messages (v4/v5) to OpenAI Chat Completion format, which Braintrust requires
428
+ * for proper rendering of threads (fixes #11023).
429
+ */
430
+ transformInput(input, spanType) {
431
+ if (spanType === observability$1.SpanType.MODEL_GENERATION) {
432
+ if (Array.isArray(input)) {
433
+ return input.map((msg) => this.convertAISDKMessage(msg));
434
+ }
435
+ if (input && Array.isArray(input.messages)) {
436
+ return input.messages.map((msg) => this.convertAISDKMessage(msg));
437
+ }
438
+ }
439
+ return input;
440
+ }
441
+ /**
442
+ * Transforms MODEL_GENERATION output to Braintrust Thread view format.
443
+ */
444
+ transformOutput(output, spanType) {
445
+ if (spanType === observability$1.SpanType.MODEL_GENERATION) {
446
+ const { text, ...rest } = output;
447
+ return { role: "assistant", content: text, ...rest };
448
+ }
449
+ return output;
450
+ }
276
451
  buildSpanPayload(span) {
277
452
  const payload = {};
278
453
  if (span.input !== void 0) {
279
- payload.input = span.input;
454
+ payload.input = this.transformInput(span.input, span.type);
280
455
  }
281
456
  if (span.output !== void 0) {
282
- payload.output = span.output;
457
+ payload.output = this.transformOutput(span.output, span.type);
283
458
  }
284
459
  payload.metrics = {};
285
460
  payload.metadata = {
@@ -295,11 +470,14 @@ var BraintrustExporter = class extends observability.BaseExporter {
295
470
  if (modelAttr.provider !== void 0) {
296
471
  payload.metadata.provider = modelAttr.provider;
297
472
  }
298
- payload.metrics = normalizeUsageMetrics(modelAttr);
473
+ payload.metrics = formatUsageMetrics(modelAttr.usage);
474
+ if (modelAttr.completionStartTime) {
475
+ payload.metrics.time_to_first_token = (modelAttr.completionStartTime.getTime() - span.startTime.getTime()) / 1e3;
476
+ }
299
477
  if (modelAttr.parameters !== void 0) {
300
478
  payload.metadata.modelParameters = modelAttr.parameters;
301
479
  }
302
- const otherAttributes = utils.omitKeys(attributes, ["model", "usage", "parameters"]);
480
+ const otherAttributes = utils.omitKeys(attributes, ["model", "usage", "parameters", "completionStartTime"]);
303
481
  payload.metadata = {
304
482
  ...payload.metadata,
305
483
  ...otherAttributes