@mastra/langsmith 0.0.0-agent-error-handling-20251023180025
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 +162 -0
- package/LICENSE.md +15 -0
- package/README.md +44 -0
- package/dist/ai-tracing.d.ts +33 -0
- package/dist/ai-tracing.d.ts.map +1 -0
- package/dist/index.cjs +308 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +306 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics.d.ts +23 -0
- package/dist/metrics.d.ts.map +1 -0
- package/package.json +62 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# @mastra/langsmith
|
|
2
|
+
|
|
3
|
+
## 0.0.0-agent-error-handling-20251023180025
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Rename LLM span types and attributes to use Model prefix ([#9105](https://github.com/mastra-ai/mastra/pull/9105))
|
|
8
|
+
|
|
9
|
+
BREAKING CHANGE: This release renames AI tracing span types and attribute interfaces to use the "Model" prefix instead of "LLM":
|
|
10
|
+
- `AISpanType.LLM_GENERATION` → `AISpanType.MODEL_GENERATION`
|
|
11
|
+
- `AISpanType.LLM_STEP` → `AISpanType.MODEL_STEP`
|
|
12
|
+
- `AISpanType.LLM_CHUNK` → `AISpanType.MODEL_CHUNK`
|
|
13
|
+
- `LLMGenerationAttributes` → `ModelGenerationAttributes`
|
|
14
|
+
- `LLMStepAttributes` → `ModelStepAttributes`
|
|
15
|
+
- `LLMChunkAttributes` → `ModelChunkAttributes`
|
|
16
|
+
- `InternalSpans.LLM` → `InternalSpans.MODEL`
|
|
17
|
+
|
|
18
|
+
This change better reflects that these span types apply to all AI models, not just Large Language Models.
|
|
19
|
+
|
|
20
|
+
Migration guide:
|
|
21
|
+
- Update all imports: `import { ModelGenerationAttributes } from '@mastra/core/ai-tracing'`
|
|
22
|
+
- Update span type references: `AISpanType.MODEL_GENERATION`
|
|
23
|
+
- Update InternalSpans usage: `InternalSpans.MODEL`
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [[`f743dbb`](https://github.com/mastra-ai/mastra/commit/f743dbb8b40d1627b5c10c0e6fc154f4ebb6e394), [`5df9cce`](https://github.com/mastra-ai/mastra/commit/5df9cce1a753438413f64c11eeef8f845745c2a8), [`149c99e`](https://github.com/mastra-ai/mastra/commit/149c99e55de947e9a4bdaa76bb83dca7f96b61f8), [`2c4438b`](https://github.com/mastra-ai/mastra/commit/2c4438b87817ab7eed818c7990fef010475af1a3)]:
|
|
28
|
+
- @mastra/core@0.0.0-agent-error-handling-20251023180025
|
|
29
|
+
|
|
30
|
+
## 0.0.6
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Fix a `ERR_MODULE_NOT_FOUND` error that was caused by a bad import to `@mastra/core/dist/ai-tracing/exporters/index.js` ([#9129](https://github.com/mastra-ai/mastra/pull/9129))
|
|
35
|
+
|
|
36
|
+
- Updated dependencies []:
|
|
37
|
+
- @mastra/core@0.22.1
|
|
38
|
+
|
|
39
|
+
## 0.0.6-alpha.0
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- Fix a `ERR_MODULE_NOT_FOUND` error that was caused by a bad import to `@mastra/core/dist/ai-tracing/exporters/index.js` ([#9129](https://github.com/mastra-ai/mastra/pull/9129))
|
|
44
|
+
|
|
45
|
+
- Updated dependencies []:
|
|
46
|
+
- @mastra/core@0.22.1-alpha.0
|
|
47
|
+
|
|
48
|
+
## 0.0.5
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Update peerdeps to 0.23.0-0 ([#9043](https://github.com/mastra-ai/mastra/pull/9043))
|
|
53
|
+
|
|
54
|
+
- Updated dependencies [[`c67ca32`](https://github.com/mastra-ai/mastra/commit/c67ca32e3c2cf69bfc146580770c720220ca44ac), [`efb5ed9`](https://github.com/mastra-ai/mastra/commit/efb5ed946ae7f410bc68c9430beb4b010afd25ec), [`dbc9e12`](https://github.com/mastra-ai/mastra/commit/dbc9e1216ba575ba59ead4afb727a01215f7de4f), [`99e41b9`](https://github.com/mastra-ai/mastra/commit/99e41b94957cdd25137d3ac12e94e8b21aa01b68), [`c28833c`](https://github.com/mastra-ai/mastra/commit/c28833c5b6d8e10eeffd7f7d39129d53b8bca240), [`8ea07b4`](https://github.com/mastra-ai/mastra/commit/8ea07b4bdc73e4218437dbb6dcb0f4b23e745a44), [`ba201b8`](https://github.com/mastra-ai/mastra/commit/ba201b8f8feac4c72350f2dbd52c13c7297ba7b0), [`f053e89`](https://github.com/mastra-ai/mastra/commit/f053e89160dbd0bd3333fc3492f68231b5c7c349), [`4fc4136`](https://github.com/mastra-ai/mastra/commit/4fc413652866a8d2240694fddb2562e9edbb70df), [`b78e04d`](https://github.com/mastra-ai/mastra/commit/b78e04d935a16ecb1e59c5c96e564903527edddd), [`d10baf5`](https://github.com/mastra-ai/mastra/commit/d10baf5a3c924f2a6654e23a3e318ed03f189b76), [`038c55a`](https://github.com/mastra-ai/mastra/commit/038c55a7090fc1b1513a966386d3072617f836ac), [`182f045`](https://github.com/mastra-ai/mastra/commit/182f0458f25bd70aa774e64fd923c8a483eddbf1), [`9a1a485`](https://github.com/mastra-ai/mastra/commit/9a1a4859b855e37239f652bf14b1ecd1029b8c4e), [`9257233`](https://github.com/mastra-ai/mastra/commit/9257233c4ffce09b2bedc2a9adbd70d7a83fa8e2), [`7620d2b`](https://github.com/mastra-ai/mastra/commit/7620d2bddeb4fae4c3c0a0b4e672969795fca11a), [`b2365f0`](https://github.com/mastra-ai/mastra/commit/b2365f038dd4c5f06400428b224af963f399ad50), [`0f1a4c9`](https://github.com/mastra-ai/mastra/commit/0f1a4c984fb4b104b2f0b63ba18c9fa77f567700), [`9029ba3`](https://github.com/mastra-ai/mastra/commit/9029ba34459c8859fed4c6b73efd8e2d0021e7ba), [`426cc56`](https://github.com/mastra-ai/mastra/commit/426cc561c85ae76a112ded2385532a91f9f9f074), [`00931fb`](https://github.com/mastra-ai/mastra/commit/00931fb1a21aa42c4fbc20c2c40dd62466b8fc8f), [`e473bfe`](https://github.com/mastra-ai/mastra/commit/e473bfe416c0b8e876973c2b6a6f13c394b7a93f), [`b78e04d`](https://github.com/mastra-ai/mastra/commit/b78e04d935a16ecb1e59c5c96e564903527edddd), [`2db6160`](https://github.com/mastra-ai/mastra/commit/2db6160e2022ff8827c15d30157e684683b934b5), [`8aeea37`](https://github.com/mastra-ai/mastra/commit/8aeea37efdde347c635a67fed56794943b7f74ec), [`02fe153`](https://github.com/mastra-ai/mastra/commit/02fe15351d6021d214da48ec982a0e9e4150bcee), [`648e2ca`](https://github.com/mastra-ai/mastra/commit/648e2ca42da54838c6ccbdaadc6fadd808fa6b86), [`74567b3`](https://github.com/mastra-ai/mastra/commit/74567b3d237ae3915cd0bca3cf55fa0a64e4e4a4), [`b65c5e0`](https://github.com/mastra-ai/mastra/commit/b65c5e0fe6f3c390a9a8bbcf69304d972c3a4afb), [`15a1733`](https://github.com/mastra-ai/mastra/commit/15a1733074cee8bd37370e1af34cd818e89fa7ac), [`fc2a774`](https://github.com/mastra-ai/mastra/commit/fc2a77468981aaddc3e77f83f0c4ad4a4af140da), [`4e08933`](https://github.com/mastra-ai/mastra/commit/4e08933625464dfde178347af5b6278fcf34188e)]:
|
|
55
|
+
- @mastra/core@0.22.0
|
|
56
|
+
|
|
57
|
+
## 0.0.5-alpha.0
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- Update peerdeps to 0.23.0-0 ([#9043](https://github.com/mastra-ai/mastra/pull/9043))
|
|
62
|
+
|
|
63
|
+
- Updated dependencies [[`efb5ed9`](https://github.com/mastra-ai/mastra/commit/efb5ed946ae7f410bc68c9430beb4b010afd25ec), [`8ea07b4`](https://github.com/mastra-ai/mastra/commit/8ea07b4bdc73e4218437dbb6dcb0f4b23e745a44), [`ba201b8`](https://github.com/mastra-ai/mastra/commit/ba201b8f8feac4c72350f2dbd52c13c7297ba7b0), [`4fc4136`](https://github.com/mastra-ai/mastra/commit/4fc413652866a8d2240694fddb2562e9edbb70df), [`b78e04d`](https://github.com/mastra-ai/mastra/commit/b78e04d935a16ecb1e59c5c96e564903527edddd), [`d10baf5`](https://github.com/mastra-ai/mastra/commit/d10baf5a3c924f2a6654e23a3e318ed03f189b76), [`038c55a`](https://github.com/mastra-ai/mastra/commit/038c55a7090fc1b1513a966386d3072617f836ac), [`182f045`](https://github.com/mastra-ai/mastra/commit/182f0458f25bd70aa774e64fd923c8a483eddbf1), [`7620d2b`](https://github.com/mastra-ai/mastra/commit/7620d2bddeb4fae4c3c0a0b4e672969795fca11a), [`b2365f0`](https://github.com/mastra-ai/mastra/commit/b2365f038dd4c5f06400428b224af963f399ad50), [`9029ba3`](https://github.com/mastra-ai/mastra/commit/9029ba34459c8859fed4c6b73efd8e2d0021e7ba), [`426cc56`](https://github.com/mastra-ai/mastra/commit/426cc561c85ae76a112ded2385532a91f9f9f074), [`00931fb`](https://github.com/mastra-ai/mastra/commit/00931fb1a21aa42c4fbc20c2c40dd62466b8fc8f), [`e473bfe`](https://github.com/mastra-ai/mastra/commit/e473bfe416c0b8e876973c2b6a6f13c394b7a93f), [`b78e04d`](https://github.com/mastra-ai/mastra/commit/b78e04d935a16ecb1e59c5c96e564903527edddd), [`648e2ca`](https://github.com/mastra-ai/mastra/commit/648e2ca42da54838c6ccbdaadc6fadd808fa6b86), [`b65c5e0`](https://github.com/mastra-ai/mastra/commit/b65c5e0fe6f3c390a9a8bbcf69304d972c3a4afb)]:
|
|
64
|
+
- @mastra/core@0.22.0-alpha.1
|
|
65
|
+
|
|
66
|
+
## 0.0.4
|
|
67
|
+
|
|
68
|
+
### Patch Changes
|
|
69
|
+
|
|
70
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8619](https://github.com/mastra-ai/mastra/pull/8619))
|
|
71
|
+
|
|
72
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8557](https://github.com/mastra-ai/mastra/pull/8557))
|
|
73
|
+
|
|
74
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8626](https://github.com/mastra-ai/mastra/pull/8626))
|
|
75
|
+
|
|
76
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8686](https://github.com/mastra-ai/mastra/pull/8686))
|
|
77
|
+
|
|
78
|
+
- Updated dependencies [[`1ed9670`](https://github.com/mastra-ai/mastra/commit/1ed9670d3ca50cb60dc2e517738c5eef3968ed27), [`b5a66b7`](https://github.com/mastra-ai/mastra/commit/b5a66b748a14fc8b3f63b04642ddb9621fbcc9e0), [`f59fc1e`](https://github.com/mastra-ai/mastra/commit/f59fc1e406b8912e692f6bff6cfd4754cc8d165c), [`158381d`](https://github.com/mastra-ai/mastra/commit/158381d39335be934b81ef8a1947bccace492c25), [`a1799bc`](https://github.com/mastra-ai/mastra/commit/a1799bcc1b5a1cdc188f2ac0165f17a1c4ac6f7b), [`6ff6094`](https://github.com/mastra-ai/mastra/commit/6ff60946f4ecfebdeef6e21d2b230c2204f2c9b8), [`fb703b9`](https://github.com/mastra-ai/mastra/commit/fb703b9634eeaff1a6eb2b5531ce0f9e8fb04727), [`37a2314`](https://github.com/mastra-ai/mastra/commit/37a23148e0e5a3b40d4f9f098b194671a8a49faf), [`7b1ef57`](https://github.com/mastra-ai/mastra/commit/7b1ef57fc071c2aa2a2e32905b18cd88719c5a39), [`05a9dee`](https://github.com/mastra-ai/mastra/commit/05a9dee3d355694d28847bfffb6289657fcf7dfa), [`e3c1077`](https://github.com/mastra-ai/mastra/commit/e3c107763aedd1643d3def5df450c235da9ff76c), [`1908ca0`](https://github.com/mastra-ai/mastra/commit/1908ca0521f90e43779cc29ab590173ca560443c), [`1bccdb3`](https://github.com/mastra-ai/mastra/commit/1bccdb33eb90cbeba2dc5ece1c2561fb774b26b6), [`5ef944a`](https://github.com/mastra-ai/mastra/commit/5ef944a3721d93105675cac2b2311432ff8cc393), [`d6b186f`](https://github.com/mastra-ai/mastra/commit/d6b186fb08f1caf1b86f73d3a5ee88fb999ca3be), [`ee68e82`](https://github.com/mastra-ai/mastra/commit/ee68e8289ea4408d29849e899bc6e78b3bd4e843), [`228228b`](https://github.com/mastra-ai/mastra/commit/228228b0b1de9291cb8887587f5cea1a8757ebad), [`ea33930`](https://github.com/mastra-ai/mastra/commit/ea339301e82d6318257720d811b043014ee44064), [`65493b3`](https://github.com/mastra-ai/mastra/commit/65493b31c36f6fdb78f9679f7e1ecf0c250aa5ee), [`a998b8f`](https://github.com/mastra-ai/mastra/commit/a998b8f858091c2ec47683e60766cf12d03001e4), [`b5a66b7`](https://github.com/mastra-ai/mastra/commit/b5a66b748a14fc8b3f63b04642ddb9621fbcc9e0), [`8a37bdd`](https://github.com/mastra-ai/mastra/commit/8a37bddb6d8614a32c5b70303d583d80c620ea61), [`135d6f2`](https://github.com/mastra-ai/mastra/commit/135d6f22a326ed1dffff858700669dff09d2c9eb)]:
|
|
79
|
+
- @mastra/core@0.21.0
|
|
80
|
+
|
|
81
|
+
## 0.0.4-alpha.0
|
|
82
|
+
|
|
83
|
+
### Patch Changes
|
|
84
|
+
|
|
85
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8619](https://github.com/mastra-ai/mastra/pull/8619))
|
|
86
|
+
|
|
87
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8557](https://github.com/mastra-ai/mastra/pull/8557))
|
|
88
|
+
|
|
89
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8626](https://github.com/mastra-ai/mastra/pull/8626))
|
|
90
|
+
|
|
91
|
+
- Update peer dependencies to match core package version bump (0.21.0) ([#8686](https://github.com/mastra-ai/mastra/pull/8686))
|
|
92
|
+
|
|
93
|
+
- Updated dependencies [[`b5a66b7`](https://github.com/mastra-ai/mastra/commit/b5a66b748a14fc8b3f63b04642ddb9621fbcc9e0), [`7b1ef57`](https://github.com/mastra-ai/mastra/commit/7b1ef57fc071c2aa2a2e32905b18cd88719c5a39), [`ee68e82`](https://github.com/mastra-ai/mastra/commit/ee68e8289ea4408d29849e899bc6e78b3bd4e843), [`228228b`](https://github.com/mastra-ai/mastra/commit/228228b0b1de9291cb8887587f5cea1a8757ebad), [`ea33930`](https://github.com/mastra-ai/mastra/commit/ea339301e82d6318257720d811b043014ee44064), [`b5a66b7`](https://github.com/mastra-ai/mastra/commit/b5a66b748a14fc8b3f63b04642ddb9621fbcc9e0), [`135d6f2`](https://github.com/mastra-ai/mastra/commit/135d6f22a326ed1dffff858700669dff09d2c9eb), [`59d036d`](https://github.com/mastra-ai/mastra/commit/59d036d4c2706b430b0e3f1f1e0ee853ce16ca04)]:
|
|
94
|
+
- @mastra/core@0.21.0-alpha.0
|
|
95
|
+
|
|
96
|
+
## 0.0.3
|
|
97
|
+
|
|
98
|
+
### Patch Changes
|
|
99
|
+
|
|
100
|
+
- dependencies updates: ([#8560](https://github.com/mastra-ai/mastra/pull/8560))
|
|
101
|
+
- Updated dependency [`langsmith@>=0.3.72` ↗︎](https://www.npmjs.com/package/langsmith/v/0.3.72) (from `>=0.3.71`, in `dependencies`)
|
|
102
|
+
- Updated dependencies [[`c621613`](https://github.com/mastra-ai/mastra/commit/c621613069173c69eb2c3ef19a5308894c6549f0), [`12b1189`](https://github.com/mastra-ai/mastra/commit/12b118942445e4de0dd916c593e33ec78dc3bc73), [`4783b30`](https://github.com/mastra-ai/mastra/commit/4783b3063efea887825514b783ba27f67912c26d), [`076b092`](https://github.com/mastra-ai/mastra/commit/076b0924902ff0f49d5712d2df24c4cca683713f), [`2aee9e7`](https://github.com/mastra-ai/mastra/commit/2aee9e7d188b8b256a4ddc203ccefb366b4867fa), [`c582906`](https://github.com/mastra-ai/mastra/commit/c5829065a346260f96c4beb8af131b94804ae3ad), [`fa2eb96`](https://github.com/mastra-ai/mastra/commit/fa2eb96af16c7d433891a73932764960d3235c1d), [`ee9108f`](https://github.com/mastra-ai/mastra/commit/ee9108fa29bb8368fc23df158c9f0645b2d7b65c), [`4783b30`](https://github.com/mastra-ai/mastra/commit/4783b3063efea887825514b783ba27f67912c26d), [`a739d0c`](https://github.com/mastra-ai/mastra/commit/a739d0c8b37cd89569e04a6ca0827083c6167e19), [`603e927`](https://github.com/mastra-ai/mastra/commit/603e9279db8bf8a46caf83881c6b7389ccffff7e), [`cd45982`](https://github.com/mastra-ai/mastra/commit/cd4598291cda128a88738734ae6cbef076ebdebd), [`874f74d`](https://github.com/mastra-ai/mastra/commit/874f74da4b1acf6517f18132d035612c3ecc394a), [`b728a45`](https://github.com/mastra-ai/mastra/commit/b728a45ab3dba59da0f5ee36b81fe246659f305d), [`0baf2ba`](https://github.com/mastra-ai/mastra/commit/0baf2bab8420277072ef1f95df5ea7b0a2f61fe7), [`10e633a`](https://github.com/mastra-ai/mastra/commit/10e633a07d333466d9734c97acfc3dbf757ad2d0), [`a6d69c5`](https://github.com/mastra-ai/mastra/commit/a6d69c5fb50c0875b46275811fece5862f03c6a0), [`84199af`](https://github.com/mastra-ai/mastra/commit/84199af8673f6f9cb59286ffb5477a41932775de), [`7f431af`](https://github.com/mastra-ai/mastra/commit/7f431afd586b7d3265075e73106eb73167edbb86), [`26e968d`](https://github.com/mastra-ai/mastra/commit/26e968db2171ded9e4d47aa1b4f19e1e771158d0), [`cbd3fb6`](https://github.com/mastra-ai/mastra/commit/cbd3fb65adb03a7c0df193cb998aed5ac56675ee)]:
|
|
103
|
+
- @mastra/core@0.20.1
|
|
104
|
+
|
|
105
|
+
## 0.0.3-alpha.0
|
|
106
|
+
|
|
107
|
+
### Patch Changes
|
|
108
|
+
|
|
109
|
+
- dependencies updates: ([#8560](https://github.com/mastra-ai/mastra/pull/8560))
|
|
110
|
+
- Updated dependency [`langsmith@>=0.3.72` ↗︎](https://www.npmjs.com/package/langsmith/v/0.3.72) (from `>=0.3.71`, in `dependencies`)
|
|
111
|
+
- Updated dependencies [[`ee9108f`](https://github.com/mastra-ai/mastra/commit/ee9108fa29bb8368fc23df158c9f0645b2d7b65c)]:
|
|
112
|
+
- @mastra/core@0.20.1-alpha.2
|
|
113
|
+
|
|
114
|
+
## 0.0.2
|
|
115
|
+
|
|
116
|
+
### Patch Changes
|
|
117
|
+
|
|
118
|
+
- Breaking change to move the agent.streamVNext/generateVNext implementation to the default stream/generate. The old stream/generate have now been moved to streamLegacy and generateLegacy ([#8097](https://github.com/mastra-ai/mastra/pull/8097))
|
|
119
|
+
|
|
120
|
+
- Updated dependencies [[`00cb6bd`](https://github.com/mastra-ai/mastra/commit/00cb6bdf78737c0fac14a5a0c7b532a11e38558a), [`869ba22`](https://github.com/mastra-ai/mastra/commit/869ba222e1d6b58fc1b65e7c9fd55ca4e01b8c2f), [`1b73665`](https://github.com/mastra-ai/mastra/commit/1b73665e8e23f5c09d49fcf3e7d709c75259259e), [`f7d7475`](https://github.com/mastra-ai/mastra/commit/f7d747507341aef60ed39e4b49318db1f86034a6), [`084b77b`](https://github.com/mastra-ai/mastra/commit/084b77b2955960e0190af8db3f77138aa83ed65c), [`a93ff84`](https://github.com/mastra-ai/mastra/commit/a93ff84b5e1af07ee236ac8873dac9b49aa5d501), [`bc5aacb`](https://github.com/mastra-ai/mastra/commit/bc5aacb646d468d325327e36117129f28cd13bf6), [`6b5af12`](https://github.com/mastra-ai/mastra/commit/6b5af12ce9e09066e0c32e821c203a6954498bea), [`bf60e4a`](https://github.com/mastra-ai/mastra/commit/bf60e4a89c515afd9570b7b79f33b95e7d07c397), [`d41aee5`](https://github.com/mastra-ai/mastra/commit/d41aee526d124e35f42720a08e64043229193679), [`e8fe13c`](https://github.com/mastra-ai/mastra/commit/e8fe13c4b4c255a42520127797ec394310f7c919), [`3ca833d`](https://github.com/mastra-ai/mastra/commit/3ca833dc994c38e3c9b4f9b4478a61cd8e07b32a), [`1edb8d1`](https://github.com/mastra-ai/mastra/commit/1edb8d1cfb963e72a12412990fb9170936c9904c), [`fbf6e32`](https://github.com/mastra-ai/mastra/commit/fbf6e324946332d0f5ed8930bf9d4d4479cefd7a), [`4753027`](https://github.com/mastra-ai/mastra/commit/4753027ee889288775c6958bdfeda03ff909af67)]:
|
|
121
|
+
- @mastra/core@0.20.0
|
|
122
|
+
|
|
123
|
+
## 0.0.2-alpha.0
|
|
124
|
+
|
|
125
|
+
### Patch Changes
|
|
126
|
+
|
|
127
|
+
- Breaking change to move the agent.streamVNext/generateVNext implementation to the default stream/generate. The old stream/generate have now been moved to streamLegacy and generateLegacy ([#8097](https://github.com/mastra-ai/mastra/pull/8097))
|
|
128
|
+
|
|
129
|
+
- Updated dependencies [[`00cb6bd`](https://github.com/mastra-ai/mastra/commit/00cb6bdf78737c0fac14a5a0c7b532a11e38558a), [`869ba22`](https://github.com/mastra-ai/mastra/commit/869ba222e1d6b58fc1b65e7c9fd55ca4e01b8c2f), [`1b73665`](https://github.com/mastra-ai/mastra/commit/1b73665e8e23f5c09d49fcf3e7d709c75259259e), [`f7d7475`](https://github.com/mastra-ai/mastra/commit/f7d747507341aef60ed39e4b49318db1f86034a6), [`084b77b`](https://github.com/mastra-ai/mastra/commit/084b77b2955960e0190af8db3f77138aa83ed65c), [`a93ff84`](https://github.com/mastra-ai/mastra/commit/a93ff84b5e1af07ee236ac8873dac9b49aa5d501), [`bc5aacb`](https://github.com/mastra-ai/mastra/commit/bc5aacb646d468d325327e36117129f28cd13bf6), [`6b5af12`](https://github.com/mastra-ai/mastra/commit/6b5af12ce9e09066e0c32e821c203a6954498bea), [`bf60e4a`](https://github.com/mastra-ai/mastra/commit/bf60e4a89c515afd9570b7b79f33b95e7d07c397), [`d41aee5`](https://github.com/mastra-ai/mastra/commit/d41aee526d124e35f42720a08e64043229193679), [`e8fe13c`](https://github.com/mastra-ai/mastra/commit/e8fe13c4b4c255a42520127797ec394310f7c919), [`3ca833d`](https://github.com/mastra-ai/mastra/commit/3ca833dc994c38e3c9b4f9b4478a61cd8e07b32a), [`1edb8d1`](https://github.com/mastra-ai/mastra/commit/1edb8d1cfb963e72a12412990fb9170936c9904c), [`fbf6e32`](https://github.com/mastra-ai/mastra/commit/fbf6e324946332d0f5ed8930bf9d4d4479cefd7a), [`4753027`](https://github.com/mastra-ai/mastra/commit/4753027ee889288775c6958bdfeda03ff909af67)]:
|
|
130
|
+
- @mastra/core@0.20.0-alpha.0
|
|
131
|
+
|
|
132
|
+
## 0.0.1
|
|
133
|
+
|
|
134
|
+
### Patch Changes
|
|
135
|
+
|
|
136
|
+
- dependencies updates: ([#8317](https://github.com/mastra-ai/mastra/pull/8317))
|
|
137
|
+
- Updated dependency [`langsmith@>=0.3.71` ↗︎](https://www.npmjs.com/package/langsmith/v/0.3.71) (from `>=0.3.69`, in `dependencies`)
|
|
138
|
+
|
|
139
|
+
- Update peer deps ([#8154](https://github.com/mastra-ai/mastra/pull/8154))
|
|
140
|
+
|
|
141
|
+
- Initial commit ([#8160](https://github.com/mastra-ai/mastra/pull/8160))
|
|
142
|
+
|
|
143
|
+
- Updated dependencies [[`dc099b4`](https://github.com/mastra-ai/mastra/commit/dc099b40fb31147ba3f362f98d991892033c4c67), [`504438b`](https://github.com/mastra-ai/mastra/commit/504438b961bde211071186bba63a842c4e3db879), [`b342a68`](https://github.com/mastra-ai/mastra/commit/b342a68e1399cf1ece9ba11bda112db89d21118c), [`a7243e2`](https://github.com/mastra-ai/mastra/commit/a7243e2e58762667a6e3921e755e89d6bb0a3282), [`7fceb0a`](https://github.com/mastra-ai/mastra/commit/7fceb0a327d678e812f90f5387c5bc4f38bd039e), [`303a9c0`](https://github.com/mastra-ai/mastra/commit/303a9c0d7dd58795915979f06a0512359e4532fb), [`df64f9e`](https://github.com/mastra-ai/mastra/commit/df64f9ef814916fff9baedd861c988084e7c41de), [`370f8a6`](https://github.com/mastra-ai/mastra/commit/370f8a6480faec70fef18d72e5f7538f27004301), [`809eea0`](https://github.com/mastra-ai/mastra/commit/809eea092fa80c3f69b9eaf078d843b57fd2a88e), [`683e5a1`](https://github.com/mastra-ai/mastra/commit/683e5a1466e48b686825b2c11f84680f296138e4), [`3679378`](https://github.com/mastra-ai/mastra/commit/3679378673350aa314741dc826f837b1984149bc), [`7775bc2`](https://github.com/mastra-ai/mastra/commit/7775bc20bb1ad1ab24797fb420e4f96c65b0d8ec), [`623ffaf`](https://github.com/mastra-ai/mastra/commit/623ffaf2d969e11e99a0224633cf7b5a0815c857), [`9fc1613`](https://github.com/mastra-ai/mastra/commit/9fc16136400186648880fd990119ac15f7c02ee4), [`61f62aa`](https://github.com/mastra-ai/mastra/commit/61f62aa31bc88fe4ddf8da6240dbcfbeb07358bd), [`db1891a`](https://github.com/mastra-ai/mastra/commit/db1891a4707443720b7cd8a260dc7e1d49b3609c), [`e8f379d`](https://github.com/mastra-ai/mastra/commit/e8f379d390efa264c4e0874f9ac0cf8839b07777), [`652066b`](https://github.com/mastra-ai/mastra/commit/652066bd1efc6bb6813ba950ed1d7573e8b7d9d4), [`3e292ba`](https://github.com/mastra-ai/mastra/commit/3e292ba00837886d5d68a34cbc0d9b703c991883), [`418c136`](https://github.com/mastra-ai/mastra/commit/418c1366843d88e491bca3f87763899ce855ca29), [`ea8d386`](https://github.com/mastra-ai/mastra/commit/ea8d386cd8c5593664515fd5770c06bf2aa980ef), [`67b0f00`](https://github.com/mastra-ai/mastra/commit/67b0f005b520335c71fb85cbaa25df4ce8484a81), [`c2a4919`](https://github.com/mastra-ai/mastra/commit/c2a4919ba6797d8bdb1509e02287496eef69303e), [`c84b7d0`](https://github.com/mastra-ai/mastra/commit/c84b7d093c4657772140cbfd2b15ef72f3315ed5), [`0130986`](https://github.com/mastra-ai/mastra/commit/0130986fc62d0edcc626dd593282661dbb9af141)]:
|
|
144
|
+
- @mastra/core@0.19.0
|
|
145
|
+
|
|
146
|
+
## 0.0.1-alpha.1
|
|
147
|
+
|
|
148
|
+
### Patch Changes
|
|
149
|
+
|
|
150
|
+
- Update peer deps ([#8154](https://github.com/mastra-ai/mastra/pull/8154))
|
|
151
|
+
|
|
152
|
+
- Updated dependencies [[`504438b`](https://github.com/mastra-ai/mastra/commit/504438b961bde211071186bba63a842c4e3db879), [`a7243e2`](https://github.com/mastra-ai/mastra/commit/a7243e2e58762667a6e3921e755e89d6bb0a3282), [`7fceb0a`](https://github.com/mastra-ai/mastra/commit/7fceb0a327d678e812f90f5387c5bc4f38bd039e), [`df64f9e`](https://github.com/mastra-ai/mastra/commit/df64f9ef814916fff9baedd861c988084e7c41de), [`809eea0`](https://github.com/mastra-ai/mastra/commit/809eea092fa80c3f69b9eaf078d843b57fd2a88e), [`683e5a1`](https://github.com/mastra-ai/mastra/commit/683e5a1466e48b686825b2c11f84680f296138e4), [`3679378`](https://github.com/mastra-ai/mastra/commit/3679378673350aa314741dc826f837b1984149bc), [`7775bc2`](https://github.com/mastra-ai/mastra/commit/7775bc20bb1ad1ab24797fb420e4f96c65b0d8ec), [`db1891a`](https://github.com/mastra-ai/mastra/commit/db1891a4707443720b7cd8a260dc7e1d49b3609c), [`e8f379d`](https://github.com/mastra-ai/mastra/commit/e8f379d390efa264c4e0874f9ac0cf8839b07777), [`652066b`](https://github.com/mastra-ai/mastra/commit/652066bd1efc6bb6813ba950ed1d7573e8b7d9d4), [`ea8d386`](https://github.com/mastra-ai/mastra/commit/ea8d386cd8c5593664515fd5770c06bf2aa980ef), [`c2a4919`](https://github.com/mastra-ai/mastra/commit/c2a4919ba6797d8bdb1509e02287496eef69303e), [`0130986`](https://github.com/mastra-ai/mastra/commit/0130986fc62d0edcc626dd593282661dbb9af141)]:
|
|
153
|
+
- @mastra/core@0.19.0-alpha.1
|
|
154
|
+
|
|
155
|
+
## 0.0.1-alpha.0
|
|
156
|
+
|
|
157
|
+
### Patch Changes
|
|
158
|
+
|
|
159
|
+
- Initial commit ([#8160](https://github.com/mastra-ai/mastra/pull/8160))
|
|
160
|
+
|
|
161
|
+
- Updated dependencies [[`dc099b4`](https://github.com/mastra-ai/mastra/commit/dc099b40fb31147ba3f362f98d991892033c4c67), [`b342a68`](https://github.com/mastra-ai/mastra/commit/b342a68e1399cf1ece9ba11bda112db89d21118c), [`303a9c0`](https://github.com/mastra-ai/mastra/commit/303a9c0d7dd58795915979f06a0512359e4532fb), [`370f8a6`](https://github.com/mastra-ai/mastra/commit/370f8a6480faec70fef18d72e5f7538f27004301), [`623ffaf`](https://github.com/mastra-ai/mastra/commit/623ffaf2d969e11e99a0224633cf7b5a0815c857), [`9fc1613`](https://github.com/mastra-ai/mastra/commit/9fc16136400186648880fd990119ac15f7c02ee4), [`61f62aa`](https://github.com/mastra-ai/mastra/commit/61f62aa31bc88fe4ddf8da6240dbcfbeb07358bd), [`3e292ba`](https://github.com/mastra-ai/mastra/commit/3e292ba00837886d5d68a34cbc0d9b703c991883), [`418c136`](https://github.com/mastra-ai/mastra/commit/418c1366843d88e491bca3f87763899ce855ca29), [`c84b7d0`](https://github.com/mastra-ai/mastra/commit/c84b7d093c4657772140cbfd2b15ef72f3315ed5)]:
|
|
162
|
+
- @mastra/core@0.18.1-alpha.0
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Kepler Software, Inc.
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @mastra/langsmith
|
|
2
|
+
|
|
3
|
+
LangSmith AI Observability exporter for Mastra applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @mastra/langsmith
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { LangSmithExporter } from '@mastra/langsmith';
|
|
15
|
+
|
|
16
|
+
// Set process.env.LANGSMITH_TRACING = "true";
|
|
17
|
+
|
|
18
|
+
// Use with Mastra
|
|
19
|
+
const mastra = new Mastra({
|
|
20
|
+
...,
|
|
21
|
+
observability: {
|
|
22
|
+
configs: {
|
|
23
|
+
langsmith: {
|
|
24
|
+
serviceName: 'service',
|
|
25
|
+
exporters: [
|
|
26
|
+
new LangSmithExporter({
|
|
27
|
+
apiKey: process.env.LANGSMITH_API_KEY, // Defaults to process.env.LANGSMITH_API_KEY
|
|
28
|
+
}),
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
### AI Tracing
|
|
39
|
+
|
|
40
|
+
- **Automatic span mapping**: Root spans become LangSmith traces
|
|
41
|
+
- **Type-specific metadata**: Extracts relevant metadata for each span type (agents, tools, workflows)
|
|
42
|
+
- **Error tracking**: Automatic error status and message tracking
|
|
43
|
+
- **Hierarchical traces**: Maintains parent-child relationships
|
|
44
|
+
- **Event span support**: Zero-duration spans for event-type traces
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangSmith Exporter for Mastra AI Tracing
|
|
3
|
+
*
|
|
4
|
+
* This exporter sends tracing data to LangSmith for AI observability.
|
|
5
|
+
* Root spans become top-level LangSmith RunTrees (no trace wrapper).
|
|
6
|
+
* Events are handled as zero-duration RunTrees with matching start/end times.
|
|
7
|
+
*/
|
|
8
|
+
import type { AITracingEvent } from '@mastra/core/ai-tracing';
|
|
9
|
+
import { BaseExporter } from '@mastra/core/ai-tracing/exporters';
|
|
10
|
+
import type { BaseExporterConfig } from '@mastra/core/ai-tracing/exporters';
|
|
11
|
+
import type { ClientConfig } from 'langsmith';
|
|
12
|
+
import { Client } from 'langsmith';
|
|
13
|
+
export interface LangSmithExporterConfig extends ClientConfig, BaseExporterConfig {
|
|
14
|
+
/** LangSmith client instance */
|
|
15
|
+
client?: Client;
|
|
16
|
+
}
|
|
17
|
+
export declare class LangSmithExporter extends BaseExporter {
|
|
18
|
+
name: string;
|
|
19
|
+
private traceMap;
|
|
20
|
+
private config;
|
|
21
|
+
private client;
|
|
22
|
+
constructor(config: LangSmithExporterConfig);
|
|
23
|
+
protected _exportEvent(event: AITracingEvent): Promise<void>;
|
|
24
|
+
private initializeRootSpan;
|
|
25
|
+
private handleSpanStarted;
|
|
26
|
+
private handleSpanUpdateOrEnd;
|
|
27
|
+
private handleEventSpan;
|
|
28
|
+
private getSpanData;
|
|
29
|
+
private getLangSmithParent;
|
|
30
|
+
private buildRunTreePayload;
|
|
31
|
+
shutdown(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=ai-tracing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tracing.d.ts","sourceRoot":"","sources":["../src/ai-tracing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAgD,MAAM,yBAAyB,CAAC;AAE5G,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAW,MAAM,WAAW,CAAC;AAI5C,MAAM,WAAW,uBAAwB,SAAQ,YAAY,EAAE,kBAAkB;IAC/E,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6BD,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,IAAI,SAAe;IACnB,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,uBAAuB;cAgB3B,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlE,OAAO,CAAC,kBAAkB;YAIZ,iBAAiB;YAoCjB,qBAAqB;YA2DrB,eAAe;IAsC7B,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,mBAAmB;IAoErB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAehC"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var aiTracing = require('@mastra/core/ai-tracing');
|
|
4
|
+
var exporters = require('@mastra/core/ai-tracing/exporters');
|
|
5
|
+
var langsmith = require('langsmith');
|
|
6
|
+
|
|
7
|
+
// src/ai-tracing.ts
|
|
8
|
+
|
|
9
|
+
// src/metrics.ts
|
|
10
|
+
function normalizeUsageMetrics(modelAttr) {
|
|
11
|
+
const metrics = {};
|
|
12
|
+
if (modelAttr.usage?.inputTokens !== void 0) {
|
|
13
|
+
metrics.input_tokens = modelAttr.usage?.inputTokens;
|
|
14
|
+
} else if (modelAttr.usage?.promptTokens !== void 0) {
|
|
15
|
+
metrics.input_tokens = modelAttr.usage?.promptTokens;
|
|
16
|
+
}
|
|
17
|
+
if (modelAttr.usage?.outputTokens !== void 0) {
|
|
18
|
+
metrics.output_tokens = modelAttr.usage?.outputTokens;
|
|
19
|
+
} else if (modelAttr.usage?.completionTokens !== void 0) {
|
|
20
|
+
metrics.output_tokens = modelAttr.usage?.completionTokens;
|
|
21
|
+
}
|
|
22
|
+
if (modelAttr.usage?.totalTokens !== void 0) {
|
|
23
|
+
metrics.total_tokens = modelAttr.usage?.totalTokens;
|
|
24
|
+
} else if (typeof modelAttr.usage?.inputTokens === "number" && typeof modelAttr.usage?.outputTokens === "number") {
|
|
25
|
+
metrics.total_tokens = modelAttr.usage?.inputTokens + modelAttr.usage?.outputTokens;
|
|
26
|
+
}
|
|
27
|
+
if (modelAttr.usage?.reasoningTokens !== void 0) {
|
|
28
|
+
metrics.output_token_details = {
|
|
29
|
+
...metrics.output_token_details ?? {},
|
|
30
|
+
reasoning_tokens: modelAttr.usage?.reasoningTokens
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (modelAttr.usage?.promptCacheHitTokens !== void 0) {
|
|
34
|
+
metrics.input_token_details = {
|
|
35
|
+
...metrics.input_token_details ?? {},
|
|
36
|
+
cache_read: modelAttr.usage?.promptCacheHitTokens
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (modelAttr.usage?.promptCacheMissTokens !== void 0) {
|
|
40
|
+
metrics.input_token_details = {
|
|
41
|
+
...metrics.input_token_details ?? {},
|
|
42
|
+
cache_write: modelAttr.usage?.promptCacheMissTokens
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return metrics;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/ai-tracing.ts
|
|
49
|
+
var DEFAULT_SPAN_TYPE = "chain";
|
|
50
|
+
var SPAN_TYPE_EXCEPTIONS = {
|
|
51
|
+
[aiTracing.AISpanType.MODEL_GENERATION]: "llm",
|
|
52
|
+
[aiTracing.AISpanType.MODEL_CHUNK]: "llm",
|
|
53
|
+
[aiTracing.AISpanType.TOOL_CALL]: "tool",
|
|
54
|
+
[aiTracing.AISpanType.MCP_TOOL_CALL]: "tool",
|
|
55
|
+
[aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL]: "chain",
|
|
56
|
+
[aiTracing.AISpanType.WORKFLOW_WAIT_EVENT]: "chain"
|
|
57
|
+
};
|
|
58
|
+
function mapSpanType(spanType) {
|
|
59
|
+
return SPAN_TYPE_EXCEPTIONS[spanType] ?? DEFAULT_SPAN_TYPE;
|
|
60
|
+
}
|
|
61
|
+
function isKVMap(value) {
|
|
62
|
+
return value != null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
63
|
+
}
|
|
64
|
+
var LangSmithExporter = class extends exporters.BaseExporter {
|
|
65
|
+
name = "langsmith";
|
|
66
|
+
traceMap = /* @__PURE__ */ new Map();
|
|
67
|
+
config;
|
|
68
|
+
client;
|
|
69
|
+
constructor(config) {
|
|
70
|
+
super(config);
|
|
71
|
+
config.apiKey = config.apiKey ?? process.env.LANGSMITH_API_KEY;
|
|
72
|
+
if (!config.apiKey) {
|
|
73
|
+
this.setDisabled(`Missing required credentials (apiKey: ${!!config.apiKey})`);
|
|
74
|
+
this.config = null;
|
|
75
|
+
this.client = null;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
this.client = config.client ?? new langsmith.Client(config);
|
|
79
|
+
this.config = config;
|
|
80
|
+
}
|
|
81
|
+
async _exportEvent(event) {
|
|
82
|
+
if (event.exportedSpan.isEvent) {
|
|
83
|
+
await this.handleEventSpan(event.exportedSpan);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
switch (event.type) {
|
|
87
|
+
case "span_started":
|
|
88
|
+
await this.handleSpanStarted(event.exportedSpan);
|
|
89
|
+
break;
|
|
90
|
+
case "span_updated":
|
|
91
|
+
await this.handleSpanUpdateOrEnd(event.exportedSpan, false);
|
|
92
|
+
break;
|
|
93
|
+
case "span_ended":
|
|
94
|
+
await this.handleSpanUpdateOrEnd(event.exportedSpan, true);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
initializeRootSpan(span) {
|
|
99
|
+
this.traceMap.set(span.traceId, { spans: /* @__PURE__ */ new Map(), activeIds: /* @__PURE__ */ new Set() });
|
|
100
|
+
}
|
|
101
|
+
async handleSpanStarted(span) {
|
|
102
|
+
this.logger.debug("LangSmith exporter: handleSpanStarted", span.id, span.name);
|
|
103
|
+
if (span.isRootSpan) {
|
|
104
|
+
this.initializeRootSpan(span);
|
|
105
|
+
}
|
|
106
|
+
const method = "handleSpanStarted";
|
|
107
|
+
const spanData = this.getSpanData({ span, method });
|
|
108
|
+
if (!spanData) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!span.isEvent) {
|
|
112
|
+
spanData.activeIds.add(span.id);
|
|
113
|
+
}
|
|
114
|
+
const payload = {
|
|
115
|
+
name: span.name,
|
|
116
|
+
run_type: mapSpanType(span.type),
|
|
117
|
+
...this.buildRunTreePayload(span)
|
|
118
|
+
};
|
|
119
|
+
const langsmithParent = this.getLangSmithParent({ spanData, span, method });
|
|
120
|
+
let langsmithRunTree;
|
|
121
|
+
if (!langsmithParent) {
|
|
122
|
+
langsmithRunTree = new langsmith.RunTree(payload);
|
|
123
|
+
} else {
|
|
124
|
+
langsmithRunTree = langsmithParent.createChild(payload);
|
|
125
|
+
}
|
|
126
|
+
spanData.spans.set(span.id, langsmithRunTree);
|
|
127
|
+
await langsmithRunTree.postRun();
|
|
128
|
+
}
|
|
129
|
+
async handleSpanUpdateOrEnd(span, isEnd) {
|
|
130
|
+
this.logger.debug("LangSmith exporter: handleSpanUpdateOrEnd", span.id, span.name, "isEnd:", isEnd);
|
|
131
|
+
const method = isEnd ? "handleSpanEnd" : "handleSpanUpdate";
|
|
132
|
+
const spanData = this.getSpanData({ span, method });
|
|
133
|
+
if (!spanData) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const langsmithRunTree = spanData.spans.get(span.id);
|
|
137
|
+
if (!langsmithRunTree) {
|
|
138
|
+
this.logger.warn("LangSmith exporter: No LangSmith span found for span update/end", {
|
|
139
|
+
traceId: span.traceId,
|
|
140
|
+
spanId: span.id,
|
|
141
|
+
spanName: span.name,
|
|
142
|
+
spanType: span.type,
|
|
143
|
+
isRootSpan: span.isRootSpan,
|
|
144
|
+
parentSpanId: span.parentSpanId,
|
|
145
|
+
method
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const updatePayload = this.buildRunTreePayload(span);
|
|
150
|
+
langsmithRunTree.metadata = {
|
|
151
|
+
...langsmithRunTree.metadata,
|
|
152
|
+
...updatePayload.metadata
|
|
153
|
+
};
|
|
154
|
+
if (updatePayload.inputs != null) {
|
|
155
|
+
langsmithRunTree.inputs = updatePayload.inputs;
|
|
156
|
+
}
|
|
157
|
+
if (updatePayload.outputs != null) {
|
|
158
|
+
langsmithRunTree.outputs = updatePayload.outputs;
|
|
159
|
+
}
|
|
160
|
+
if (updatePayload.error != null) {
|
|
161
|
+
langsmithRunTree.error = updatePayload.error;
|
|
162
|
+
}
|
|
163
|
+
if (isEnd) {
|
|
164
|
+
if (span.endTime) {
|
|
165
|
+
await langsmithRunTree.end({ endTime: span.endTime.getTime() / 1e3 });
|
|
166
|
+
} else {
|
|
167
|
+
await langsmithRunTree.end();
|
|
168
|
+
}
|
|
169
|
+
await langsmithRunTree.patchRun();
|
|
170
|
+
if (!span.isEvent) {
|
|
171
|
+
spanData.activeIds.delete(span.id);
|
|
172
|
+
}
|
|
173
|
+
if (spanData.activeIds.size === 0) {
|
|
174
|
+
this.traceMap.delete(span.traceId);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async handleEventSpan(span) {
|
|
179
|
+
if (span.isRootSpan) {
|
|
180
|
+
this.logger.debug("LangSmith exporter: Creating logger for event", {
|
|
181
|
+
traceId: span.traceId,
|
|
182
|
+
spanId: span.id,
|
|
183
|
+
spanName: span.name,
|
|
184
|
+
method: "handleEventSpan"
|
|
185
|
+
});
|
|
186
|
+
this.initializeRootSpan(span);
|
|
187
|
+
}
|
|
188
|
+
const method = "handleEventSpan";
|
|
189
|
+
const spanData = this.getSpanData({ span, method });
|
|
190
|
+
if (!spanData) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const langsmithParent = this.getLangSmithParent({ spanData, span, method });
|
|
194
|
+
const payload = {
|
|
195
|
+
...this.buildRunTreePayload(span),
|
|
196
|
+
name: span.name,
|
|
197
|
+
type: mapSpanType(span.type),
|
|
198
|
+
startTime: span.startTime.getTime() / 1e3
|
|
199
|
+
};
|
|
200
|
+
let langsmithRunTree;
|
|
201
|
+
if (!langsmithParent) {
|
|
202
|
+
langsmithRunTree = new langsmith.RunTree(payload);
|
|
203
|
+
} else {
|
|
204
|
+
langsmithRunTree = langsmithParent.createChild(payload);
|
|
205
|
+
}
|
|
206
|
+
await langsmithRunTree.postRun();
|
|
207
|
+
await langsmithRunTree.end({ endTime: span.startTime.getTime() / 1e3 });
|
|
208
|
+
await langsmithRunTree.patchRun();
|
|
209
|
+
}
|
|
210
|
+
getSpanData(options) {
|
|
211
|
+
const { span, method } = options;
|
|
212
|
+
if (this.traceMap.has(span.traceId)) {
|
|
213
|
+
return this.traceMap.get(span.traceId);
|
|
214
|
+
}
|
|
215
|
+
this.logger.warn("LangSmith exporter: No span data found for span", {
|
|
216
|
+
traceId: span.traceId,
|
|
217
|
+
spanId: span.id,
|
|
218
|
+
spanName: span.name,
|
|
219
|
+
spanType: span.type,
|
|
220
|
+
isRootSpan: span.isRootSpan,
|
|
221
|
+
parentSpanId: span.parentSpanId,
|
|
222
|
+
method
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
getLangSmithParent(options) {
|
|
226
|
+
const { spanData, span, method } = options;
|
|
227
|
+
const parentId = span.parentSpanId;
|
|
228
|
+
if (!parentId) {
|
|
229
|
+
return void 0;
|
|
230
|
+
}
|
|
231
|
+
if (spanData.spans.has(parentId)) {
|
|
232
|
+
return spanData.spans.get(parentId);
|
|
233
|
+
}
|
|
234
|
+
if (parentId && !spanData.spans.has(parentId)) {
|
|
235
|
+
return void 0;
|
|
236
|
+
}
|
|
237
|
+
this.logger.warn("LangSmith exporter: No parent data found for span", {
|
|
238
|
+
traceId: span.traceId,
|
|
239
|
+
spanId: span.id,
|
|
240
|
+
spanName: span.name,
|
|
241
|
+
spanType: span.type,
|
|
242
|
+
isRootSpan: span.isRootSpan,
|
|
243
|
+
parentSpanId: span.parentSpanId,
|
|
244
|
+
method
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
buildRunTreePayload(span) {
|
|
248
|
+
const payload = {
|
|
249
|
+
client: this.client,
|
|
250
|
+
metadata: {
|
|
251
|
+
mastra_span_type: span.type,
|
|
252
|
+
...span.metadata
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
if (span.input !== void 0) {
|
|
256
|
+
payload.inputs = isKVMap(span.input) ? span.input : { input: span.input };
|
|
257
|
+
}
|
|
258
|
+
if (span.output !== void 0) {
|
|
259
|
+
payload.outputs = isKVMap(span.output) ? span.output : { output: span.output };
|
|
260
|
+
}
|
|
261
|
+
const attributes = span.attributes ?? {};
|
|
262
|
+
if (span.type === aiTracing.AISpanType.MODEL_GENERATION) {
|
|
263
|
+
const modelAttr = attributes;
|
|
264
|
+
if (modelAttr.model !== void 0) {
|
|
265
|
+
payload.metadata.ls_model_name = modelAttr.model;
|
|
266
|
+
}
|
|
267
|
+
if (modelAttr.provider !== void 0) {
|
|
268
|
+
payload.metadata.ls_provider = modelAttr.provider;
|
|
269
|
+
}
|
|
270
|
+
payload.metadata.usage_metadata = normalizeUsageMetrics(modelAttr);
|
|
271
|
+
if (modelAttr.parameters !== void 0) {
|
|
272
|
+
payload.metadata.modelParameters = modelAttr.parameters;
|
|
273
|
+
}
|
|
274
|
+
const otherAttributes = aiTracing.omitKeys(attributes, ["model", "usage", "parameters"]);
|
|
275
|
+
payload.metadata = {
|
|
276
|
+
...payload.metadata,
|
|
277
|
+
...otherAttributes
|
|
278
|
+
};
|
|
279
|
+
} else {
|
|
280
|
+
payload.metadata = {
|
|
281
|
+
...payload.metadata,
|
|
282
|
+
...attributes
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (span.errorInfo) {
|
|
286
|
+
payload.error = span.errorInfo.message;
|
|
287
|
+
payload.metadata.errorDetails = span.errorInfo;
|
|
288
|
+
}
|
|
289
|
+
return payload;
|
|
290
|
+
}
|
|
291
|
+
async shutdown() {
|
|
292
|
+
if (!this.config) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
for (const [_traceId, spanData] of this.traceMap) {
|
|
296
|
+
for (const [_spanId, runTree] of spanData.spans) {
|
|
297
|
+
await runTree.end();
|
|
298
|
+
await runTree.patchRun();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
this.traceMap.clear();
|
|
302
|
+
await super.shutdown();
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
exports.LangSmithExporter = LangSmithExporter;
|
|
307
|
+
//# sourceMappingURL=index.cjs.map
|
|
308
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/metrics.ts","../src/ai-tracing.ts"],"names":["AISpanType","BaseExporter","Client","RunTree","omitKeys"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ModelGenerationAttributes } from '@mastra/core/ai-tracing';\n/**\n * LangSmithUsageMetrics\n *\n * Canonical metric keys expected by LangSmith for LLM usage accounting.\n * See: https://docs.langchain.com/langsmith/log-llm-trace#provide-token-and-cost-information\n */\nexport interface LangSmithUsageMetrics {\n input_tokens?: number;\n output_tokens?: number;\n total_tokens?: number;\n input_token_details?: {\n [key: string]: number;\n };\n output_token_details?: {\n [key: string]: number;\n };\n [key: string]: number | { [key: string]: number } | undefined;\n}\n\nexport function normalizeUsageMetrics(modelAttr: ModelGenerationAttributes): LangSmithUsageMetrics {\n const metrics: LangSmithUsageMetrics = {};\n\n if (modelAttr.usage?.inputTokens !== undefined) {\n metrics.input_tokens = modelAttr.usage?.inputTokens;\n } else if (modelAttr.usage?.promptTokens !== undefined) {\n metrics.input_tokens = modelAttr.usage?.promptTokens;\n }\n\n if (modelAttr.usage?.outputTokens !== undefined) {\n metrics.output_tokens = modelAttr.usage?.outputTokens;\n } else if (modelAttr.usage?.completionTokens !== undefined) {\n metrics.output_tokens = modelAttr.usage?.completionTokens;\n }\n\n if (modelAttr.usage?.totalTokens !== undefined) {\n metrics.total_tokens = modelAttr.usage?.totalTokens;\n } else if (typeof modelAttr.usage?.inputTokens === 'number' && typeof modelAttr.usage?.outputTokens === 'number') {\n metrics.total_tokens = modelAttr.usage?.inputTokens + modelAttr.usage?.outputTokens;\n }\n if (modelAttr.usage?.reasoningTokens !== undefined) {\n metrics.output_token_details = {\n ...(metrics.output_token_details ?? {}),\n reasoning_tokens: modelAttr.usage?.reasoningTokens,\n };\n }\n if (modelAttr.usage?.promptCacheHitTokens !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_read: modelAttr.usage?.promptCacheHitTokens,\n };\n }\n if (modelAttr.usage?.promptCacheMissTokens !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_write: modelAttr.usage?.promptCacheMissTokens,\n };\n }\n\n return metrics;\n}\n","/**\n * LangSmith Exporter for Mastra AI Tracing\n *\n * This exporter sends tracing data to LangSmith for AI observability.\n * Root spans become top-level LangSmith RunTrees (no trace wrapper).\n * Events are handled as zero-duration RunTrees with matching start/end times.\n */\n\nimport type { AITracingEvent, AnyExportedAISpan, ModelGenerationAttributes } from '@mastra/core/ai-tracing';\nimport { AISpanType, omitKeys } from '@mastra/core/ai-tracing';\nimport { BaseExporter } from '@mastra/core/ai-tracing/exporters';\nimport type { BaseExporterConfig } from '@mastra/core/ai-tracing/exporters';\nimport type { ClientConfig, RunTreeConfig } from 'langsmith';\nimport { Client, RunTree } from 'langsmith';\nimport type { KVMap } from 'langsmith/schemas';\nimport { normalizeUsageMetrics } from './metrics';\n\nexport interface LangSmithExporterConfig extends ClientConfig, BaseExporterConfig {\n /** LangSmith client instance */\n client?: Client;\n}\n\ntype SpanData = {\n spans: Map<string, RunTree>; // Maps span.id to LangSmith RunTrees\n activeIds: Set<string>; // Tracks started (non-event) spans not yet ended, including root\n};\n\n// Default span type for all spans\nconst DEFAULT_SPAN_TYPE = 'chain';\n\n// Exceptions to the default mapping\nconst SPAN_TYPE_EXCEPTIONS: Partial<Record<AISpanType, 'llm' | 'tool' | 'chain'>> = {\n [AISpanType.MODEL_GENERATION]: 'llm',\n [AISpanType.MODEL_CHUNK]: 'llm',\n [AISpanType.TOOL_CALL]: 'tool',\n [AISpanType.MCP_TOOL_CALL]: 'tool',\n [AISpanType.WORKFLOW_CONDITIONAL_EVAL]: 'chain',\n [AISpanType.WORKFLOW_WAIT_EVENT]: 'chain',\n};\n\n// Mapping function - returns valid LangSmith span types\nfunction mapSpanType(spanType: AISpanType): 'llm' | 'tool' | 'chain' {\n return SPAN_TYPE_EXCEPTIONS[spanType] ?? DEFAULT_SPAN_TYPE;\n}\n\nfunction isKVMap(value: unknown): value is KVMap {\n return value != null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);\n}\n\nexport class LangSmithExporter extends BaseExporter {\n name = 'langsmith';\n private traceMap = new Map<string, SpanData>();\n private config: LangSmithExporterConfig;\n private client: Client;\n\n constructor(config: LangSmithExporterConfig) {\n super(config);\n\n config.apiKey = config.apiKey ?? process.env.LANGSMITH_API_KEY;\n\n if (!config.apiKey) {\n this.setDisabled(`Missing required credentials (apiKey: ${!!config.apiKey})`);\n this.config = null as any;\n this.client = null as any;\n return;\n }\n\n this.client = config.client ?? new Client(config);\n this.config = config;\n }\n\n protected async _exportEvent(event: AITracingEvent): Promise<void> {\n if (event.exportedSpan.isEvent) {\n await this.handleEventSpan(event.exportedSpan);\n return;\n }\n\n switch (event.type) {\n case 'span_started':\n await this.handleSpanStarted(event.exportedSpan);\n break;\n case 'span_updated':\n await this.handleSpanUpdateOrEnd(event.exportedSpan, false);\n break;\n case 'span_ended':\n await this.handleSpanUpdateOrEnd(event.exportedSpan, true);\n break;\n }\n }\n\n private initializeRootSpan(span: AnyExportedAISpan) {\n this.traceMap.set(span.traceId, { spans: new Map(), activeIds: new Set() });\n }\n\n private async handleSpanStarted(span: AnyExportedAISpan): Promise<void> {\n this.logger.debug('LangSmith exporter: handleSpanStarted', span.id, span.name);\n if (span.isRootSpan) {\n this.initializeRootSpan(span);\n }\n\n const method = 'handleSpanStarted';\n const spanData = this.getSpanData({ span, method });\n if (!spanData) {\n return;\n }\n\n // Refcount: track active non-event spans (including root)\n if (!span.isEvent) {\n spanData.activeIds.add(span.id);\n }\n\n const payload = {\n name: span.name,\n run_type: mapSpanType(span.type),\n ...this.buildRunTreePayload(span),\n };\n\n const langsmithParent = this.getLangSmithParent({ spanData, span, method });\n let langsmithRunTree: RunTree;\n if (!langsmithParent) {\n langsmithRunTree = new RunTree(payload);\n } else {\n langsmithRunTree = langsmithParent.createChild(payload);\n }\n\n spanData.spans.set(span.id, langsmithRunTree);\n\n await langsmithRunTree.postRun();\n }\n\n private async handleSpanUpdateOrEnd(span: AnyExportedAISpan, isEnd: boolean): Promise<void> {\n this.logger.debug('LangSmith exporter: handleSpanUpdateOrEnd', span.id, span.name, 'isEnd:', isEnd);\n const method = isEnd ? 'handleSpanEnd' : 'handleSpanUpdate';\n\n const spanData = this.getSpanData({ span, method });\n if (!spanData) {\n return;\n }\n\n const langsmithRunTree = spanData.spans.get(span.id);\n if (!langsmithRunTree) {\n this.logger.warn('LangSmith exporter: No LangSmith span found for span update/end', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n spanType: span.type,\n isRootSpan: span.isRootSpan,\n parentSpanId: span.parentSpanId,\n method,\n });\n return;\n }\n\n const updatePayload = this.buildRunTreePayload(span);\n langsmithRunTree.metadata = {\n ...langsmithRunTree.metadata,\n ...updatePayload.metadata,\n };\n if (updatePayload.inputs != null) {\n langsmithRunTree.inputs = updatePayload.inputs;\n }\n if (updatePayload.outputs != null) {\n langsmithRunTree.outputs = updatePayload.outputs;\n }\n if (updatePayload.error != null) {\n langsmithRunTree.error = updatePayload.error;\n }\n\n if (isEnd) {\n // End the span with the correct endTime (convert milliseconds to seconds)\n if (span.endTime) {\n await langsmithRunTree.end({ endTime: span.endTime.getTime() / 1000 });\n } else {\n await langsmithRunTree.end();\n }\n await langsmithRunTree.patchRun();\n\n // Refcount: mark this span as ended\n if (!span.isEvent) {\n spanData.activeIds.delete(span.id);\n }\n\n // If no more active spans remain for this trace, clean up the trace entry\n if (spanData.activeIds.size === 0) {\n this.traceMap.delete(span.traceId);\n }\n }\n }\n\n private async handleEventSpan(span: AnyExportedAISpan): Promise<void> {\n if (span.isRootSpan) {\n this.logger.debug('LangSmith exporter: Creating logger for event', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n method: 'handleEventSpan',\n });\n this.initializeRootSpan(span);\n }\n\n const method = 'handleEventSpan';\n const spanData = this.getSpanData({ span, method });\n if (!spanData) {\n return;\n }\n\n const langsmithParent = this.getLangSmithParent({ spanData, span, method });\n const payload = {\n ...this.buildRunTreePayload(span),\n name: span.name,\n type: mapSpanType(span.type),\n startTime: span.startTime.getTime() / 1000,\n };\n\n let langsmithRunTree: RunTree;\n if (!langsmithParent) {\n langsmithRunTree = new RunTree(payload);\n } else {\n langsmithRunTree = langsmithParent.createChild(payload);\n }\n\n await langsmithRunTree.postRun();\n\n await langsmithRunTree.end({ endTime: span.startTime.getTime() / 1000 });\n await langsmithRunTree.patchRun();\n }\n\n private getSpanData(options: { span: AnyExportedAISpan; method: string }): SpanData | undefined {\n const { span, method } = options;\n if (this.traceMap.has(span.traceId)) {\n return this.traceMap.get(span.traceId);\n }\n\n this.logger.warn('LangSmith exporter: No span data found for span', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n spanType: span.type,\n isRootSpan: span.isRootSpan,\n parentSpanId: span.parentSpanId,\n method,\n });\n }\n\n private getLangSmithParent(options: {\n spanData: SpanData;\n span: AnyExportedAISpan;\n method: string;\n }): RunTree | undefined {\n const { spanData, span, method } = options;\n\n const parentId = span.parentSpanId;\n if (!parentId) {\n return undefined;\n }\n\n if (spanData.spans.has(parentId)) {\n return spanData.spans.get(parentId);\n }\n\n if (parentId && !spanData.spans.has(parentId)) {\n // This means the parent exists but isn't tracked as a LangSmith span,\n // which happens when the parent is the root span\n return undefined;\n }\n\n this.logger.warn('LangSmith exporter: No parent data found for span', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n spanType: span.type,\n isRootSpan: span.isRootSpan,\n parentSpanId: span.parentSpanId,\n method,\n });\n }\n\n private buildRunTreePayload(span: AnyExportedAISpan): Partial<RunTreeConfig> {\n const payload: Partial<RunTreeConfig> & { metadata: KVMap } = {\n client: this.client,\n metadata: {\n mastra_span_type: span.type,\n ...span.metadata,\n },\n };\n\n // Core span data\n if (span.input !== undefined) {\n payload.inputs = isKVMap(span.input) ? span.input : { input: span.input };\n }\n\n if (span.output !== undefined) {\n payload.outputs = isKVMap(span.output) ? span.output : { output: span.output };\n }\n\n const attributes = (span.attributes ?? {}) as Record<string, any>;\n\n if (span.type === AISpanType.MODEL_GENERATION) {\n const modelAttr = attributes as ModelGenerationAttributes;\n\n // See: https://docs.langchain.com/langsmith/log-llm-trace\n if (modelAttr.model !== undefined) {\n // Note - this should map to a model name recognized by LangSmith\n // eg “gpt-4o-mini”, “claude-3-opus-20240307”, etc.\n payload.metadata.ls_model_name = modelAttr.model;\n }\n\n // Provider goes to metadata (if provided by attributes)\n if (modelAttr.provider !== undefined) {\n // Note - this should map to a provider name recognized by\n // LangSmith eg “openai”, “anthropic”, etc.\n payload.metadata.ls_provider = modelAttr.provider;\n }\n\n // Usage/token info goes to metrics\n payload.metadata.usage_metadata = normalizeUsageMetrics(modelAttr);\n\n // Model parameters go to metadata\n if (modelAttr.parameters !== undefined) {\n payload.metadata.modelParameters = modelAttr.parameters;\n }\n\n // Other LLM attributes go to metadata\n const otherAttributes = omitKeys(attributes, ['model', 'usage', 'parameters']);\n payload.metadata = {\n ...payload.metadata,\n ...otherAttributes,\n };\n } else {\n // For non-LLM spans, put all attributes in metadata\n payload.metadata = {\n ...payload.metadata,\n ...attributes,\n };\n }\n\n // Handle errors\n if (span.errorInfo) {\n payload.error = span.errorInfo.message;\n payload.metadata.errorDetails = span.errorInfo;\n }\n\n return payload;\n }\n\n async shutdown(): Promise<void> {\n if (!this.config) {\n return;\n }\n\n // End all active spans\n for (const [_traceId, spanData] of this.traceMap) {\n for (const [_spanId, runTree] of spanData.spans) {\n await runTree.end();\n await runTree.patchRun();\n }\n }\n this.traceMap.clear();\n await super.shutdown();\n }\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangSmith Observability Provider for Mastra
|
|
3
|
+
*
|
|
4
|
+
* This package provides LangSmith-specific observability features for Mastra applications.
|
|
5
|
+
* Currently includes AI tracing support with plans for additional observability features.
|
|
6
|
+
*/
|
|
7
|
+
export * from './ai-tracing.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { AISpanType, omitKeys } from '@mastra/core/ai-tracing';
|
|
2
|
+
import { BaseExporter } from '@mastra/core/ai-tracing/exporters';
|
|
3
|
+
import { Client, RunTree } from 'langsmith';
|
|
4
|
+
|
|
5
|
+
// src/ai-tracing.ts
|
|
6
|
+
|
|
7
|
+
// src/metrics.ts
|
|
8
|
+
function normalizeUsageMetrics(modelAttr) {
|
|
9
|
+
const metrics = {};
|
|
10
|
+
if (modelAttr.usage?.inputTokens !== void 0) {
|
|
11
|
+
metrics.input_tokens = modelAttr.usage?.inputTokens;
|
|
12
|
+
} else if (modelAttr.usage?.promptTokens !== void 0) {
|
|
13
|
+
metrics.input_tokens = modelAttr.usage?.promptTokens;
|
|
14
|
+
}
|
|
15
|
+
if (modelAttr.usage?.outputTokens !== void 0) {
|
|
16
|
+
metrics.output_tokens = modelAttr.usage?.outputTokens;
|
|
17
|
+
} else if (modelAttr.usage?.completionTokens !== void 0) {
|
|
18
|
+
metrics.output_tokens = modelAttr.usage?.completionTokens;
|
|
19
|
+
}
|
|
20
|
+
if (modelAttr.usage?.totalTokens !== void 0) {
|
|
21
|
+
metrics.total_tokens = modelAttr.usage?.totalTokens;
|
|
22
|
+
} else if (typeof modelAttr.usage?.inputTokens === "number" && typeof modelAttr.usage?.outputTokens === "number") {
|
|
23
|
+
metrics.total_tokens = modelAttr.usage?.inputTokens + modelAttr.usage?.outputTokens;
|
|
24
|
+
}
|
|
25
|
+
if (modelAttr.usage?.reasoningTokens !== void 0) {
|
|
26
|
+
metrics.output_token_details = {
|
|
27
|
+
...metrics.output_token_details ?? {},
|
|
28
|
+
reasoning_tokens: modelAttr.usage?.reasoningTokens
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (modelAttr.usage?.promptCacheHitTokens !== void 0) {
|
|
32
|
+
metrics.input_token_details = {
|
|
33
|
+
...metrics.input_token_details ?? {},
|
|
34
|
+
cache_read: modelAttr.usage?.promptCacheHitTokens
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (modelAttr.usage?.promptCacheMissTokens !== void 0) {
|
|
38
|
+
metrics.input_token_details = {
|
|
39
|
+
...metrics.input_token_details ?? {},
|
|
40
|
+
cache_write: modelAttr.usage?.promptCacheMissTokens
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return metrics;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/ai-tracing.ts
|
|
47
|
+
var DEFAULT_SPAN_TYPE = "chain";
|
|
48
|
+
var SPAN_TYPE_EXCEPTIONS = {
|
|
49
|
+
[AISpanType.MODEL_GENERATION]: "llm",
|
|
50
|
+
[AISpanType.MODEL_CHUNK]: "llm",
|
|
51
|
+
[AISpanType.TOOL_CALL]: "tool",
|
|
52
|
+
[AISpanType.MCP_TOOL_CALL]: "tool",
|
|
53
|
+
[AISpanType.WORKFLOW_CONDITIONAL_EVAL]: "chain",
|
|
54
|
+
[AISpanType.WORKFLOW_WAIT_EVENT]: "chain"
|
|
55
|
+
};
|
|
56
|
+
function mapSpanType(spanType) {
|
|
57
|
+
return SPAN_TYPE_EXCEPTIONS[spanType] ?? DEFAULT_SPAN_TYPE;
|
|
58
|
+
}
|
|
59
|
+
function isKVMap(value) {
|
|
60
|
+
return value != null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
61
|
+
}
|
|
62
|
+
var LangSmithExporter = class extends BaseExporter {
|
|
63
|
+
name = "langsmith";
|
|
64
|
+
traceMap = /* @__PURE__ */ new Map();
|
|
65
|
+
config;
|
|
66
|
+
client;
|
|
67
|
+
constructor(config) {
|
|
68
|
+
super(config);
|
|
69
|
+
config.apiKey = config.apiKey ?? process.env.LANGSMITH_API_KEY;
|
|
70
|
+
if (!config.apiKey) {
|
|
71
|
+
this.setDisabled(`Missing required credentials (apiKey: ${!!config.apiKey})`);
|
|
72
|
+
this.config = null;
|
|
73
|
+
this.client = null;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.client = config.client ?? new Client(config);
|
|
77
|
+
this.config = config;
|
|
78
|
+
}
|
|
79
|
+
async _exportEvent(event) {
|
|
80
|
+
if (event.exportedSpan.isEvent) {
|
|
81
|
+
await this.handleEventSpan(event.exportedSpan);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
switch (event.type) {
|
|
85
|
+
case "span_started":
|
|
86
|
+
await this.handleSpanStarted(event.exportedSpan);
|
|
87
|
+
break;
|
|
88
|
+
case "span_updated":
|
|
89
|
+
await this.handleSpanUpdateOrEnd(event.exportedSpan, false);
|
|
90
|
+
break;
|
|
91
|
+
case "span_ended":
|
|
92
|
+
await this.handleSpanUpdateOrEnd(event.exportedSpan, true);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
initializeRootSpan(span) {
|
|
97
|
+
this.traceMap.set(span.traceId, { spans: /* @__PURE__ */ new Map(), activeIds: /* @__PURE__ */ new Set() });
|
|
98
|
+
}
|
|
99
|
+
async handleSpanStarted(span) {
|
|
100
|
+
this.logger.debug("LangSmith exporter: handleSpanStarted", span.id, span.name);
|
|
101
|
+
if (span.isRootSpan) {
|
|
102
|
+
this.initializeRootSpan(span);
|
|
103
|
+
}
|
|
104
|
+
const method = "handleSpanStarted";
|
|
105
|
+
const spanData = this.getSpanData({ span, method });
|
|
106
|
+
if (!spanData) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!span.isEvent) {
|
|
110
|
+
spanData.activeIds.add(span.id);
|
|
111
|
+
}
|
|
112
|
+
const payload = {
|
|
113
|
+
name: span.name,
|
|
114
|
+
run_type: mapSpanType(span.type),
|
|
115
|
+
...this.buildRunTreePayload(span)
|
|
116
|
+
};
|
|
117
|
+
const langsmithParent = this.getLangSmithParent({ spanData, span, method });
|
|
118
|
+
let langsmithRunTree;
|
|
119
|
+
if (!langsmithParent) {
|
|
120
|
+
langsmithRunTree = new RunTree(payload);
|
|
121
|
+
} else {
|
|
122
|
+
langsmithRunTree = langsmithParent.createChild(payload);
|
|
123
|
+
}
|
|
124
|
+
spanData.spans.set(span.id, langsmithRunTree);
|
|
125
|
+
await langsmithRunTree.postRun();
|
|
126
|
+
}
|
|
127
|
+
async handleSpanUpdateOrEnd(span, isEnd) {
|
|
128
|
+
this.logger.debug("LangSmith exporter: handleSpanUpdateOrEnd", span.id, span.name, "isEnd:", isEnd);
|
|
129
|
+
const method = isEnd ? "handleSpanEnd" : "handleSpanUpdate";
|
|
130
|
+
const spanData = this.getSpanData({ span, method });
|
|
131
|
+
if (!spanData) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const langsmithRunTree = spanData.spans.get(span.id);
|
|
135
|
+
if (!langsmithRunTree) {
|
|
136
|
+
this.logger.warn("LangSmith exporter: No LangSmith span found for span update/end", {
|
|
137
|
+
traceId: span.traceId,
|
|
138
|
+
spanId: span.id,
|
|
139
|
+
spanName: span.name,
|
|
140
|
+
spanType: span.type,
|
|
141
|
+
isRootSpan: span.isRootSpan,
|
|
142
|
+
parentSpanId: span.parentSpanId,
|
|
143
|
+
method
|
|
144
|
+
});
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const updatePayload = this.buildRunTreePayload(span);
|
|
148
|
+
langsmithRunTree.metadata = {
|
|
149
|
+
...langsmithRunTree.metadata,
|
|
150
|
+
...updatePayload.metadata
|
|
151
|
+
};
|
|
152
|
+
if (updatePayload.inputs != null) {
|
|
153
|
+
langsmithRunTree.inputs = updatePayload.inputs;
|
|
154
|
+
}
|
|
155
|
+
if (updatePayload.outputs != null) {
|
|
156
|
+
langsmithRunTree.outputs = updatePayload.outputs;
|
|
157
|
+
}
|
|
158
|
+
if (updatePayload.error != null) {
|
|
159
|
+
langsmithRunTree.error = updatePayload.error;
|
|
160
|
+
}
|
|
161
|
+
if (isEnd) {
|
|
162
|
+
if (span.endTime) {
|
|
163
|
+
await langsmithRunTree.end({ endTime: span.endTime.getTime() / 1e3 });
|
|
164
|
+
} else {
|
|
165
|
+
await langsmithRunTree.end();
|
|
166
|
+
}
|
|
167
|
+
await langsmithRunTree.patchRun();
|
|
168
|
+
if (!span.isEvent) {
|
|
169
|
+
spanData.activeIds.delete(span.id);
|
|
170
|
+
}
|
|
171
|
+
if (spanData.activeIds.size === 0) {
|
|
172
|
+
this.traceMap.delete(span.traceId);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async handleEventSpan(span) {
|
|
177
|
+
if (span.isRootSpan) {
|
|
178
|
+
this.logger.debug("LangSmith exporter: Creating logger for event", {
|
|
179
|
+
traceId: span.traceId,
|
|
180
|
+
spanId: span.id,
|
|
181
|
+
spanName: span.name,
|
|
182
|
+
method: "handleEventSpan"
|
|
183
|
+
});
|
|
184
|
+
this.initializeRootSpan(span);
|
|
185
|
+
}
|
|
186
|
+
const method = "handleEventSpan";
|
|
187
|
+
const spanData = this.getSpanData({ span, method });
|
|
188
|
+
if (!spanData) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const langsmithParent = this.getLangSmithParent({ spanData, span, method });
|
|
192
|
+
const payload = {
|
|
193
|
+
...this.buildRunTreePayload(span),
|
|
194
|
+
name: span.name,
|
|
195
|
+
type: mapSpanType(span.type),
|
|
196
|
+
startTime: span.startTime.getTime() / 1e3
|
|
197
|
+
};
|
|
198
|
+
let langsmithRunTree;
|
|
199
|
+
if (!langsmithParent) {
|
|
200
|
+
langsmithRunTree = new RunTree(payload);
|
|
201
|
+
} else {
|
|
202
|
+
langsmithRunTree = langsmithParent.createChild(payload);
|
|
203
|
+
}
|
|
204
|
+
await langsmithRunTree.postRun();
|
|
205
|
+
await langsmithRunTree.end({ endTime: span.startTime.getTime() / 1e3 });
|
|
206
|
+
await langsmithRunTree.patchRun();
|
|
207
|
+
}
|
|
208
|
+
getSpanData(options) {
|
|
209
|
+
const { span, method } = options;
|
|
210
|
+
if (this.traceMap.has(span.traceId)) {
|
|
211
|
+
return this.traceMap.get(span.traceId);
|
|
212
|
+
}
|
|
213
|
+
this.logger.warn("LangSmith exporter: No span data found for span", {
|
|
214
|
+
traceId: span.traceId,
|
|
215
|
+
spanId: span.id,
|
|
216
|
+
spanName: span.name,
|
|
217
|
+
spanType: span.type,
|
|
218
|
+
isRootSpan: span.isRootSpan,
|
|
219
|
+
parentSpanId: span.parentSpanId,
|
|
220
|
+
method
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
getLangSmithParent(options) {
|
|
224
|
+
const { spanData, span, method } = options;
|
|
225
|
+
const parentId = span.parentSpanId;
|
|
226
|
+
if (!parentId) {
|
|
227
|
+
return void 0;
|
|
228
|
+
}
|
|
229
|
+
if (spanData.spans.has(parentId)) {
|
|
230
|
+
return spanData.spans.get(parentId);
|
|
231
|
+
}
|
|
232
|
+
if (parentId && !spanData.spans.has(parentId)) {
|
|
233
|
+
return void 0;
|
|
234
|
+
}
|
|
235
|
+
this.logger.warn("LangSmith exporter: No parent data found for span", {
|
|
236
|
+
traceId: span.traceId,
|
|
237
|
+
spanId: span.id,
|
|
238
|
+
spanName: span.name,
|
|
239
|
+
spanType: span.type,
|
|
240
|
+
isRootSpan: span.isRootSpan,
|
|
241
|
+
parentSpanId: span.parentSpanId,
|
|
242
|
+
method
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
buildRunTreePayload(span) {
|
|
246
|
+
const payload = {
|
|
247
|
+
client: this.client,
|
|
248
|
+
metadata: {
|
|
249
|
+
mastra_span_type: span.type,
|
|
250
|
+
...span.metadata
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
if (span.input !== void 0) {
|
|
254
|
+
payload.inputs = isKVMap(span.input) ? span.input : { input: span.input };
|
|
255
|
+
}
|
|
256
|
+
if (span.output !== void 0) {
|
|
257
|
+
payload.outputs = isKVMap(span.output) ? span.output : { output: span.output };
|
|
258
|
+
}
|
|
259
|
+
const attributes = span.attributes ?? {};
|
|
260
|
+
if (span.type === AISpanType.MODEL_GENERATION) {
|
|
261
|
+
const modelAttr = attributes;
|
|
262
|
+
if (modelAttr.model !== void 0) {
|
|
263
|
+
payload.metadata.ls_model_name = modelAttr.model;
|
|
264
|
+
}
|
|
265
|
+
if (modelAttr.provider !== void 0) {
|
|
266
|
+
payload.metadata.ls_provider = modelAttr.provider;
|
|
267
|
+
}
|
|
268
|
+
payload.metadata.usage_metadata = normalizeUsageMetrics(modelAttr);
|
|
269
|
+
if (modelAttr.parameters !== void 0) {
|
|
270
|
+
payload.metadata.modelParameters = modelAttr.parameters;
|
|
271
|
+
}
|
|
272
|
+
const otherAttributes = omitKeys(attributes, ["model", "usage", "parameters"]);
|
|
273
|
+
payload.metadata = {
|
|
274
|
+
...payload.metadata,
|
|
275
|
+
...otherAttributes
|
|
276
|
+
};
|
|
277
|
+
} else {
|
|
278
|
+
payload.metadata = {
|
|
279
|
+
...payload.metadata,
|
|
280
|
+
...attributes
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
if (span.errorInfo) {
|
|
284
|
+
payload.error = span.errorInfo.message;
|
|
285
|
+
payload.metadata.errorDetails = span.errorInfo;
|
|
286
|
+
}
|
|
287
|
+
return payload;
|
|
288
|
+
}
|
|
289
|
+
async shutdown() {
|
|
290
|
+
if (!this.config) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
for (const [_traceId, spanData] of this.traceMap) {
|
|
294
|
+
for (const [_spanId, runTree] of spanData.spans) {
|
|
295
|
+
await runTree.end();
|
|
296
|
+
await runTree.patchRun();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
this.traceMap.clear();
|
|
300
|
+
await super.shutdown();
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export { LangSmithExporter };
|
|
305
|
+
//# sourceMappingURL=index.js.map
|
|
306
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/metrics.ts","../src/ai-tracing.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ModelGenerationAttributes } from '@mastra/core/ai-tracing';\n/**\n * LangSmithUsageMetrics\n *\n * Canonical metric keys expected by LangSmith for LLM usage accounting.\n * See: https://docs.langchain.com/langsmith/log-llm-trace#provide-token-and-cost-information\n */\nexport interface LangSmithUsageMetrics {\n input_tokens?: number;\n output_tokens?: number;\n total_tokens?: number;\n input_token_details?: {\n [key: string]: number;\n };\n output_token_details?: {\n [key: string]: number;\n };\n [key: string]: number | { [key: string]: number } | undefined;\n}\n\nexport function normalizeUsageMetrics(modelAttr: ModelGenerationAttributes): LangSmithUsageMetrics {\n const metrics: LangSmithUsageMetrics = {};\n\n if (modelAttr.usage?.inputTokens !== undefined) {\n metrics.input_tokens = modelAttr.usage?.inputTokens;\n } else if (modelAttr.usage?.promptTokens !== undefined) {\n metrics.input_tokens = modelAttr.usage?.promptTokens;\n }\n\n if (modelAttr.usage?.outputTokens !== undefined) {\n metrics.output_tokens = modelAttr.usage?.outputTokens;\n } else if (modelAttr.usage?.completionTokens !== undefined) {\n metrics.output_tokens = modelAttr.usage?.completionTokens;\n }\n\n if (modelAttr.usage?.totalTokens !== undefined) {\n metrics.total_tokens = modelAttr.usage?.totalTokens;\n } else if (typeof modelAttr.usage?.inputTokens === 'number' && typeof modelAttr.usage?.outputTokens === 'number') {\n metrics.total_tokens = modelAttr.usage?.inputTokens + modelAttr.usage?.outputTokens;\n }\n if (modelAttr.usage?.reasoningTokens !== undefined) {\n metrics.output_token_details = {\n ...(metrics.output_token_details ?? {}),\n reasoning_tokens: modelAttr.usage?.reasoningTokens,\n };\n }\n if (modelAttr.usage?.promptCacheHitTokens !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_read: modelAttr.usage?.promptCacheHitTokens,\n };\n }\n if (modelAttr.usage?.promptCacheMissTokens !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_write: modelAttr.usage?.promptCacheMissTokens,\n };\n }\n\n return metrics;\n}\n","/**\n * LangSmith Exporter for Mastra AI Tracing\n *\n * This exporter sends tracing data to LangSmith for AI observability.\n * Root spans become top-level LangSmith RunTrees (no trace wrapper).\n * Events are handled as zero-duration RunTrees with matching start/end times.\n */\n\nimport type { AITracingEvent, AnyExportedAISpan, ModelGenerationAttributes } from '@mastra/core/ai-tracing';\nimport { AISpanType, omitKeys } from '@mastra/core/ai-tracing';\nimport { BaseExporter } from '@mastra/core/ai-tracing/exporters';\nimport type { BaseExporterConfig } from '@mastra/core/ai-tracing/exporters';\nimport type { ClientConfig, RunTreeConfig } from 'langsmith';\nimport { Client, RunTree } from 'langsmith';\nimport type { KVMap } from 'langsmith/schemas';\nimport { normalizeUsageMetrics } from './metrics';\n\nexport interface LangSmithExporterConfig extends ClientConfig, BaseExporterConfig {\n /** LangSmith client instance */\n client?: Client;\n}\n\ntype SpanData = {\n spans: Map<string, RunTree>; // Maps span.id to LangSmith RunTrees\n activeIds: Set<string>; // Tracks started (non-event) spans not yet ended, including root\n};\n\n// Default span type for all spans\nconst DEFAULT_SPAN_TYPE = 'chain';\n\n// Exceptions to the default mapping\nconst SPAN_TYPE_EXCEPTIONS: Partial<Record<AISpanType, 'llm' | 'tool' | 'chain'>> = {\n [AISpanType.MODEL_GENERATION]: 'llm',\n [AISpanType.MODEL_CHUNK]: 'llm',\n [AISpanType.TOOL_CALL]: 'tool',\n [AISpanType.MCP_TOOL_CALL]: 'tool',\n [AISpanType.WORKFLOW_CONDITIONAL_EVAL]: 'chain',\n [AISpanType.WORKFLOW_WAIT_EVENT]: 'chain',\n};\n\n// Mapping function - returns valid LangSmith span types\nfunction mapSpanType(spanType: AISpanType): 'llm' | 'tool' | 'chain' {\n return SPAN_TYPE_EXCEPTIONS[spanType] ?? DEFAULT_SPAN_TYPE;\n}\n\nfunction isKVMap(value: unknown): value is KVMap {\n return value != null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);\n}\n\nexport class LangSmithExporter extends BaseExporter {\n name = 'langsmith';\n private traceMap = new Map<string, SpanData>();\n private config: LangSmithExporterConfig;\n private client: Client;\n\n constructor(config: LangSmithExporterConfig) {\n super(config);\n\n config.apiKey = config.apiKey ?? process.env.LANGSMITH_API_KEY;\n\n if (!config.apiKey) {\n this.setDisabled(`Missing required credentials (apiKey: ${!!config.apiKey})`);\n this.config = null as any;\n this.client = null as any;\n return;\n }\n\n this.client = config.client ?? new Client(config);\n this.config = config;\n }\n\n protected async _exportEvent(event: AITracingEvent): Promise<void> {\n if (event.exportedSpan.isEvent) {\n await this.handleEventSpan(event.exportedSpan);\n return;\n }\n\n switch (event.type) {\n case 'span_started':\n await this.handleSpanStarted(event.exportedSpan);\n break;\n case 'span_updated':\n await this.handleSpanUpdateOrEnd(event.exportedSpan, false);\n break;\n case 'span_ended':\n await this.handleSpanUpdateOrEnd(event.exportedSpan, true);\n break;\n }\n }\n\n private initializeRootSpan(span: AnyExportedAISpan) {\n this.traceMap.set(span.traceId, { spans: new Map(), activeIds: new Set() });\n }\n\n private async handleSpanStarted(span: AnyExportedAISpan): Promise<void> {\n this.logger.debug('LangSmith exporter: handleSpanStarted', span.id, span.name);\n if (span.isRootSpan) {\n this.initializeRootSpan(span);\n }\n\n const method = 'handleSpanStarted';\n const spanData = this.getSpanData({ span, method });\n if (!spanData) {\n return;\n }\n\n // Refcount: track active non-event spans (including root)\n if (!span.isEvent) {\n spanData.activeIds.add(span.id);\n }\n\n const payload = {\n name: span.name,\n run_type: mapSpanType(span.type),\n ...this.buildRunTreePayload(span),\n };\n\n const langsmithParent = this.getLangSmithParent({ spanData, span, method });\n let langsmithRunTree: RunTree;\n if (!langsmithParent) {\n langsmithRunTree = new RunTree(payload);\n } else {\n langsmithRunTree = langsmithParent.createChild(payload);\n }\n\n spanData.spans.set(span.id, langsmithRunTree);\n\n await langsmithRunTree.postRun();\n }\n\n private async handleSpanUpdateOrEnd(span: AnyExportedAISpan, isEnd: boolean): Promise<void> {\n this.logger.debug('LangSmith exporter: handleSpanUpdateOrEnd', span.id, span.name, 'isEnd:', isEnd);\n const method = isEnd ? 'handleSpanEnd' : 'handleSpanUpdate';\n\n const spanData = this.getSpanData({ span, method });\n if (!spanData) {\n return;\n }\n\n const langsmithRunTree = spanData.spans.get(span.id);\n if (!langsmithRunTree) {\n this.logger.warn('LangSmith exporter: No LangSmith span found for span update/end', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n spanType: span.type,\n isRootSpan: span.isRootSpan,\n parentSpanId: span.parentSpanId,\n method,\n });\n return;\n }\n\n const updatePayload = this.buildRunTreePayload(span);\n langsmithRunTree.metadata = {\n ...langsmithRunTree.metadata,\n ...updatePayload.metadata,\n };\n if (updatePayload.inputs != null) {\n langsmithRunTree.inputs = updatePayload.inputs;\n }\n if (updatePayload.outputs != null) {\n langsmithRunTree.outputs = updatePayload.outputs;\n }\n if (updatePayload.error != null) {\n langsmithRunTree.error = updatePayload.error;\n }\n\n if (isEnd) {\n // End the span with the correct endTime (convert milliseconds to seconds)\n if (span.endTime) {\n await langsmithRunTree.end({ endTime: span.endTime.getTime() / 1000 });\n } else {\n await langsmithRunTree.end();\n }\n await langsmithRunTree.patchRun();\n\n // Refcount: mark this span as ended\n if (!span.isEvent) {\n spanData.activeIds.delete(span.id);\n }\n\n // If no more active spans remain for this trace, clean up the trace entry\n if (spanData.activeIds.size === 0) {\n this.traceMap.delete(span.traceId);\n }\n }\n }\n\n private async handleEventSpan(span: AnyExportedAISpan): Promise<void> {\n if (span.isRootSpan) {\n this.logger.debug('LangSmith exporter: Creating logger for event', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n method: 'handleEventSpan',\n });\n this.initializeRootSpan(span);\n }\n\n const method = 'handleEventSpan';\n const spanData = this.getSpanData({ span, method });\n if (!spanData) {\n return;\n }\n\n const langsmithParent = this.getLangSmithParent({ spanData, span, method });\n const payload = {\n ...this.buildRunTreePayload(span),\n name: span.name,\n type: mapSpanType(span.type),\n startTime: span.startTime.getTime() / 1000,\n };\n\n let langsmithRunTree: RunTree;\n if (!langsmithParent) {\n langsmithRunTree = new RunTree(payload);\n } else {\n langsmithRunTree = langsmithParent.createChild(payload);\n }\n\n await langsmithRunTree.postRun();\n\n await langsmithRunTree.end({ endTime: span.startTime.getTime() / 1000 });\n await langsmithRunTree.patchRun();\n }\n\n private getSpanData(options: { span: AnyExportedAISpan; method: string }): SpanData | undefined {\n const { span, method } = options;\n if (this.traceMap.has(span.traceId)) {\n return this.traceMap.get(span.traceId);\n }\n\n this.logger.warn('LangSmith exporter: No span data found for span', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n spanType: span.type,\n isRootSpan: span.isRootSpan,\n parentSpanId: span.parentSpanId,\n method,\n });\n }\n\n private getLangSmithParent(options: {\n spanData: SpanData;\n span: AnyExportedAISpan;\n method: string;\n }): RunTree | undefined {\n const { spanData, span, method } = options;\n\n const parentId = span.parentSpanId;\n if (!parentId) {\n return undefined;\n }\n\n if (spanData.spans.has(parentId)) {\n return spanData.spans.get(parentId);\n }\n\n if (parentId && !spanData.spans.has(parentId)) {\n // This means the parent exists but isn't tracked as a LangSmith span,\n // which happens when the parent is the root span\n return undefined;\n }\n\n this.logger.warn('LangSmith exporter: No parent data found for span', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n spanType: span.type,\n isRootSpan: span.isRootSpan,\n parentSpanId: span.parentSpanId,\n method,\n });\n }\n\n private buildRunTreePayload(span: AnyExportedAISpan): Partial<RunTreeConfig> {\n const payload: Partial<RunTreeConfig> & { metadata: KVMap } = {\n client: this.client,\n metadata: {\n mastra_span_type: span.type,\n ...span.metadata,\n },\n };\n\n // Core span data\n if (span.input !== undefined) {\n payload.inputs = isKVMap(span.input) ? span.input : { input: span.input };\n }\n\n if (span.output !== undefined) {\n payload.outputs = isKVMap(span.output) ? span.output : { output: span.output };\n }\n\n const attributes = (span.attributes ?? {}) as Record<string, any>;\n\n if (span.type === AISpanType.MODEL_GENERATION) {\n const modelAttr = attributes as ModelGenerationAttributes;\n\n // See: https://docs.langchain.com/langsmith/log-llm-trace\n if (modelAttr.model !== undefined) {\n // Note - this should map to a model name recognized by LangSmith\n // eg “gpt-4o-mini”, “claude-3-opus-20240307”, etc.\n payload.metadata.ls_model_name = modelAttr.model;\n }\n\n // Provider goes to metadata (if provided by attributes)\n if (modelAttr.provider !== undefined) {\n // Note - this should map to a provider name recognized by\n // LangSmith eg “openai”, “anthropic”, etc.\n payload.metadata.ls_provider = modelAttr.provider;\n }\n\n // Usage/token info goes to metrics\n payload.metadata.usage_metadata = normalizeUsageMetrics(modelAttr);\n\n // Model parameters go to metadata\n if (modelAttr.parameters !== undefined) {\n payload.metadata.modelParameters = modelAttr.parameters;\n }\n\n // Other LLM attributes go to metadata\n const otherAttributes = omitKeys(attributes, ['model', 'usage', 'parameters']);\n payload.metadata = {\n ...payload.metadata,\n ...otherAttributes,\n };\n } else {\n // For non-LLM spans, put all attributes in metadata\n payload.metadata = {\n ...payload.metadata,\n ...attributes,\n };\n }\n\n // Handle errors\n if (span.errorInfo) {\n payload.error = span.errorInfo.message;\n payload.metadata.errorDetails = span.errorInfo;\n }\n\n return payload;\n }\n\n async shutdown(): Promise<void> {\n if (!this.config) {\n return;\n }\n\n // End all active spans\n for (const [_traceId, spanData] of this.traceMap) {\n for (const [_spanId, runTree] of spanData.spans) {\n await runTree.end();\n await runTree.patchRun();\n }\n }\n this.traceMap.clear();\n await super.shutdown();\n }\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ModelGenerationAttributes } from '@mastra/core/ai-tracing';
|
|
2
|
+
/**
|
|
3
|
+
* LangSmithUsageMetrics
|
|
4
|
+
*
|
|
5
|
+
* Canonical metric keys expected by LangSmith for LLM usage accounting.
|
|
6
|
+
* See: https://docs.langchain.com/langsmith/log-llm-trace#provide-token-and-cost-information
|
|
7
|
+
*/
|
|
8
|
+
export interface LangSmithUsageMetrics {
|
|
9
|
+
input_tokens?: number;
|
|
10
|
+
output_tokens?: number;
|
|
11
|
+
total_tokens?: number;
|
|
12
|
+
input_token_details?: {
|
|
13
|
+
[key: string]: number;
|
|
14
|
+
};
|
|
15
|
+
output_token_details?: {
|
|
16
|
+
[key: string]: number;
|
|
17
|
+
};
|
|
18
|
+
[key: string]: number | {
|
|
19
|
+
[key: string]: number;
|
|
20
|
+
} | undefined;
|
|
21
|
+
}
|
|
22
|
+
export declare function normalizeUsageMetrics(modelAttr: ModelGenerationAttributes): LangSmithUsageMetrics;
|
|
23
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;IACF,oBAAoB,CAAC,EAAE;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC/D;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,yBAAyB,GAAG,qBAAqB,CAwCjG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mastra/langsmith",
|
|
3
|
+
"version": "0.0.0-agent-error-handling-20251023180025",
|
|
4
|
+
"description": "Langsmith observability provider for Mastra - includes AI tracing and future observability features",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"CHANGELOG.md"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"require": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.cjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"langsmith": ">=0.3.72"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@ai-sdk/openai": "^2.0.35",
|
|
31
|
+
"@microsoft/api-extractor": "^7.52.8",
|
|
32
|
+
"@types/node": "^20.19.0",
|
|
33
|
+
"dotenv": "^17.2.2",
|
|
34
|
+
"eslint": "^9.37.0",
|
|
35
|
+
"tsup": "^8.5.0",
|
|
36
|
+
"typescript": "^5.8.3",
|
|
37
|
+
"vitest": "^3.2.4",
|
|
38
|
+
"zod": "^3.25.76",
|
|
39
|
+
"@internal/lint": "0.0.0-agent-error-handling-20251023180025",
|
|
40
|
+
"@internal/types-builder": "0.0.0-agent-error-handling-20251023180025",
|
|
41
|
+
"@mastra/core": "0.0.0-agent-error-handling-20251023180025"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@mastra/core": "0.0.0-agent-error-handling-20251023180025"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://mastra.ai",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/mastra-ai/mastra.git",
|
|
50
|
+
"directory": "observability/langsmith"
|
|
51
|
+
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/mastra-ai/mastra/issues"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsup --silent --config tsup.config.ts",
|
|
57
|
+
"build:watch": "pnpm build --watch",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"test:watch": "vitest watch",
|
|
60
|
+
"lint": "eslint ."
|
|
61
|
+
}
|
|
62
|
+
}
|