@mastra/langfuse 1.0.0-beta.10 → 1.0.0-beta.12

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,65 @@
1
1
  # @mastra/langfuse
2
2
 
3
+ ## 1.0.0-beta.12
4
+
5
+ ### Minor Changes
6
+
7
+ - Added `TrackingExporter` base class with improved handling for: ([#11870](https://github.com/mastra-ai/mastra/pull/11870))
8
+ - **Out-of-order span processing**: Spans that arrive before their parents are now queued and processed once dependencies are available
9
+ - **Delayed cleanup**: Trace data is retained briefly after spans end to handle late-arriving updates
10
+ - **Memory management**: Configurable limits on pending and total traces to prevent memory leaks
11
+
12
+ New configuration options on `TrackingExporterConfig`:
13
+ - `earlyQueueMaxAttempts` - Max retry attempts for queued events (default: 5)
14
+ - `earlyQueueTTLMs` - TTL for queued events in ms (default: 30000)
15
+ - `traceCleanupDelayMs` - Delay before cleaning up completed traces (default: 30000)
16
+ - `maxPendingCleanupTraces` - Soft cap on traces awaiting cleanup (default: 100)
17
+ - `maxTotalTraces` - Hard cap on total traces (default: 500)
18
+
19
+ Updated @mastra/braintrust, @mastra/langfuse, @mastra/langsmith, @mastra/posthog to use the new TrackingExporter
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [[`ebae12a`](https://github.com/mastra-ai/mastra/commit/ebae12a2dd0212e75478981053b148a2c246962d), [`c61a0a5`](https://github.com/mastra-ai/mastra/commit/c61a0a5de4904c88fd8b3718bc26d1be1c2ec6e7), [`69136e7`](https://github.com/mastra-ai/mastra/commit/69136e748e32f57297728a4e0f9a75988462f1a7), [`449aed2`](https://github.com/mastra-ai/mastra/commit/449aed2ba9d507b75bf93d427646ea94f734dfd1), [`eb648a2`](https://github.com/mastra-ai/mastra/commit/eb648a2cc1728f7678768dd70cd77619b448dab9), [`0131105`](https://github.com/mastra-ai/mastra/commit/0131105532e83bdcbb73352fc7d0879eebf140dc), [`9d5059e`](https://github.com/mastra-ai/mastra/commit/9d5059eae810829935fb08e81a9bb7ecd5b144a7), [`ef756c6`](https://github.com/mastra-ai/mastra/commit/ef756c65f82d16531c43f49a27290a416611e526), [`b00ccd3`](https://github.com/mastra-ai/mastra/commit/b00ccd325ebd5d9e37e34dd0a105caae67eb568f), [`3bdfa75`](https://github.com/mastra-ai/mastra/commit/3bdfa7507a91db66f176ba8221aa28dd546e464a), [`e770de9`](https://github.com/mastra-ai/mastra/commit/e770de941a287a49b1964d44db5a5763d19890a6), [`52e2716`](https://github.com/mastra-ai/mastra/commit/52e2716b42df6eff443de72360ae83e86ec23993), [`27b4040`](https://github.com/mastra-ai/mastra/commit/27b4040bfa1a95d92546f420a02a626b1419a1d6), [`610a70b`](https://github.com/mastra-ai/mastra/commit/610a70bdad282079f0c630e0d7bb284578f20151), [`8dc7f55`](https://github.com/mastra-ai/mastra/commit/8dc7f55900395771da851dc7d78d53ae84fe34ec), [`8379099`](https://github.com/mastra-ai/mastra/commit/8379099fc467af6bef54dd7f80c9bd75bf8bbddf), [`b06be72`](https://github.com/mastra-ai/mastra/commit/b06be7223d5ef23edc98c01a67ef713c6cc039f9), [`8c0ec25`](https://github.com/mastra-ai/mastra/commit/8c0ec25646c8a7df253ed1e5ff4863a0d3f1316c), [`ff4d9a6`](https://github.com/mastra-ai/mastra/commit/ff4d9a6704fc87b31a380a76ed22736fdedbba5a), [`69821ef`](https://github.com/mastra-ai/mastra/commit/69821ef806482e2c44e2197ac0b050c3fe3a5285), [`1ed5716`](https://github.com/mastra-ai/mastra/commit/1ed5716830867b3774c4a1b43cc0d82935f32b96), [`4186bdd`](https://github.com/mastra-ai/mastra/commit/4186bdd00731305726fa06adba0b076a1d50b49f), [`7aaf973`](https://github.com/mastra-ai/mastra/commit/7aaf973f83fbbe9521f1f9e7a4fd99b8de464617)]:
24
+ - @mastra/core@1.0.0-beta.22
25
+ - @mastra/observability@1.0.0-beta.11
26
+
27
+ ## 1.0.0-beta.11
28
+
29
+ ### Minor Changes
30
+
31
+ - feat(observability): add zero-config environment variable support for all exporters ([#11686](https://github.com/mastra-ai/mastra/pull/11686))
32
+
33
+ All observability exporters now support zero-config setup via environment variables. Set the appropriate environment variables and instantiate exporters with no configuration:
34
+ - **Langfuse**: `LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`, `LANGFUSE_BASE_URL`
35
+ - **Braintrust**: `BRAINTRUST_API_KEY`, `BRAINTRUST_ENDPOINT`
36
+ - **PostHog**: `POSTHOG_API_KEY`, `POSTHOG_HOST`
37
+ - **Arize/Phoenix**: `ARIZE_SPACE_ID`, `ARIZE_API_KEY`, `ARIZE_PROJECT_NAME`, `PHOENIX_ENDPOINT`, `PHOENIX_API_KEY`, `PHOENIX_PROJECT_NAME`
38
+ - **OTEL Providers**:
39
+ - Dash0: `DASH0_API_KEY`, `DASH0_ENDPOINT`, `DASH0_DATASET`
40
+ - SigNoz: `SIGNOZ_API_KEY`, `SIGNOZ_REGION`, `SIGNOZ_ENDPOINT`
41
+ - New Relic: `NEW_RELIC_LICENSE_KEY`, `NEW_RELIC_ENDPOINT`
42
+ - Traceloop: `TRACELOOP_API_KEY`, `TRACELOOP_DESTINATION_ID`, `TRACELOOP_ENDPOINT`
43
+ - Laminar: `LMNR_PROJECT_API_KEY`, `LAMINAR_ENDPOINT`
44
+
45
+ Example usage:
46
+
47
+ ```typescript
48
+ // Zero-config - reads from environment variables
49
+ new LangfuseExporter();
50
+ new BraintrustExporter();
51
+ new PosthogExporter();
52
+ new ArizeExporter();
53
+ new OtelExporter({ provider: { signoz: {} } });
54
+ ```
55
+
56
+ Explicit configuration still works and takes precedence over environment variables.
57
+
58
+ ### Patch Changes
59
+
60
+ - Updated dependencies [[`08766f1`](https://github.com/mastra-ai/mastra/commit/08766f15e13ac0692fde2a8bd366c2e16e4321df), [`ae8baf7`](https://github.com/mastra-ai/mastra/commit/ae8baf7d8adcb0ff9dac11880400452bc49b33ff), [`cfabdd4`](https://github.com/mastra-ai/mastra/commit/cfabdd4aae7a726b706942d6836eeca110fb6267), [`a0e437f`](https://github.com/mastra-ai/mastra/commit/a0e437fac561b28ee719e0302d72b2f9b4c138f0), [`bec5efd`](https://github.com/mastra-ai/mastra/commit/bec5efde96653ccae6604e68c696d1bc6c1a0bf5), [`9eedf7d`](https://github.com/mastra-ai/mastra/commit/9eedf7de1d6e0022a2f4e5e9e6fe1ec468f9b43c)]:
61
+ - @mastra/core@1.0.0-beta.21
62
+
3
63
  ## 1.0.0-beta.10
4
64
 
5
65
  ### Patch Changes
package/README.md CHANGED
@@ -10,22 +10,54 @@ npm install @mastra/langfuse
10
10
 
11
11
  ## Usage
12
12
 
13
+ ### Zero-Config Setup
14
+
15
+ The exporter automatically reads credentials from environment variables:
16
+
17
+ ```bash
18
+ # Required
19
+ LANGFUSE_PUBLIC_KEY=pk-lf-...
20
+ LANGFUSE_SECRET_KEY=sk-lf-...
21
+
22
+ # Optional - defaults to Langfuse cloud
23
+ LANGFUSE_BASE_URL=https://cloud.langfuse.com
24
+ ```
25
+
26
+ ```typescript
27
+ import { LangfuseExporter } from '@mastra/langfuse';
28
+
29
+ const mastra = new Mastra({
30
+ ...,
31
+ observability: {
32
+ configs: {
33
+ langfuse: {
34
+ serviceName: 'my-service',
35
+ exporters: [new LangfuseExporter()],
36
+ },
37
+ },
38
+ },
39
+ });
40
+ ```
41
+
42
+ ### Explicit Configuration
43
+
44
+ You can also pass credentials directly:
45
+
13
46
  ```typescript
14
47
  import { LangfuseExporter } from '@mastra/langfuse';
15
48
 
16
- // Use with Mastra
17
49
  const mastra = new Mastra({
18
50
  ...,
19
51
  observability: {
20
52
  configs: {
21
53
  langfuse: {
22
- serviceName: 'service',
54
+ serviceName: 'my-service',
23
55
  exporters: [
24
56
  new LangfuseExporter({
25
- publicKey: process.env.LANGFUSE_PUBLIC_KEY,
26
- secretKey: process.env.LANGFUSE_SECRET_KEY,
27
- baseUrl: process.env.LANGFUSE_BASE_URL, // Optional - defaults to Langfuse cloud
28
- realtime: true,
57
+ publicKey: 'pk-lf-...',
58
+ secretKey: 'sk-lf-...',
59
+ baseUrl: 'https://cloud.langfuse.com', // Optional
60
+ realtime: true, // Optional - flush after each event
29
61
  }),
30
62
  ],
31
63
  },
@@ -34,6 +66,16 @@ const mastra = new Mastra({
34
66
  });
35
67
  ```
36
68
 
69
+ ### Configuration Options
70
+
71
+ | Option | Type | Description |
72
+ | ----------- | --------- | ---------------------------------------------------------------------------- |
73
+ | `publicKey` | `string` | Langfuse public key. Defaults to `LANGFUSE_PUBLIC_KEY` env var |
74
+ | `secretKey` | `string` | Langfuse secret key. Defaults to `LANGFUSE_SECRET_KEY` env var |
75
+ | `baseUrl` | `string` | Langfuse host URL. Defaults to `LANGFUSE_BASE_URL` env var or Langfuse cloud |
76
+ | `realtime` | `boolean` | Flush after each event for immediate visibility. Defaults to `false` |
77
+ | `options` | `object` | Additional options to pass to the Langfuse client |
78
+
37
79
  ## Features
38
80
 
39
81
  ### Tracing
package/dist/index.cjs CHANGED
@@ -6,6 +6,8 @@ var observability = require('@mastra/observability');
6
6
  var langfuse = require('langfuse');
7
7
 
8
8
  // src/tracing.ts
9
+
10
+ // src/metrics.ts
9
11
  function formatUsageMetrics(usage) {
10
12
  if (!usage) return {};
11
13
  const metrics = {};
@@ -25,204 +27,106 @@ function formatUsageMetrics(usage) {
25
27
  if (usage.outputDetails?.reasoning !== void 0) {
26
28
  metrics.reasoning = usage.outputDetails.reasoning;
27
29
  }
28
- if (metrics.input && metrics.output) {
30
+ if (metrics.input != null && metrics.output != null) {
29
31
  metrics.total = metrics.input + metrics.output;
30
- if (metrics.cache_write_input_tokens) {
32
+ if (metrics.cache_write_input_tokens != null) {
31
33
  metrics.total += metrics.cache_write_input_tokens;
32
34
  }
33
35
  }
34
36
  return metrics;
35
37
  }
36
- var LangfuseExporter = class extends observability.BaseExporter {
38
+
39
+ // src/tracing.ts
40
+ var LangfuseExporter = class extends observability.TrackingExporter {
37
41
  name = "langfuse";
38
- client;
39
- realtime;
40
- traceMap = /* @__PURE__ */ new Map();
41
- constructor(config) {
42
- super(config);
43
- this.realtime = config.realtime ?? false;
44
- if (!config.publicKey || !config.secretKey) {
42
+ #client;
43
+ #realtime;
44
+ constructor(config = {}) {
45
+ const publicKey = config.publicKey ?? process.env.LANGFUSE_PUBLIC_KEY;
46
+ const secretKey = config.secretKey ?? process.env.LANGFUSE_SECRET_KEY;
47
+ const baseUrl = config.baseUrl ?? process.env.LANGFUSE_BASE_URL;
48
+ super({
49
+ ...config,
50
+ publicKey,
51
+ secretKey,
52
+ baseUrl
53
+ });
54
+ this.#realtime = config.realtime ?? false;
55
+ if (!publicKey || !secretKey) {
56
+ const publicKeySource = config.publicKey ? "from config" : process.env.LANGFUSE_PUBLIC_KEY ? "from env" : "missing";
57
+ const secretKeySource = config.secretKey ? "from config" : process.env.LANGFUSE_SECRET_KEY ? "from env" : "missing";
45
58
  this.setDisabled(
46
- `Missing required credentials (publicKey: ${!!config.publicKey}, secretKey: ${!!config.secretKey})`
59
+ `Missing required credentials (publicKey: ${publicKeySource}, secretKey: ${secretKeySource}). Set LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY environment variables or pass them in config.`
47
60
  );
48
- this.client = null;
49
61
  return;
50
62
  }
51
- this.client = new langfuse.Langfuse({
52
- publicKey: config.publicKey,
53
- secretKey: config.secretKey,
54
- baseUrl: config.baseUrl,
63
+ this.#client = new langfuse.Langfuse({
64
+ publicKey,
65
+ secretKey,
66
+ baseUrl,
55
67
  ...config.options
56
68
  });
57
69
  }
58
- async _exportTracingEvent(event) {
59
- if (event.exportedSpan.isEvent) {
60
- await this.handleEventSpan(event.exportedSpan);
61
- return;
62
- }
63
- switch (event.type) {
64
- case "span_started":
65
- await this.handleSpanStarted(event.exportedSpan);
66
- break;
67
- case "span_updated":
68
- await this.handleSpanUpdateOrEnd(event.exportedSpan, false);
69
- break;
70
- case "span_ended":
71
- await this.handleSpanUpdateOrEnd(event.exportedSpan, true);
72
- break;
73
- }
74
- if (this.realtime) {
75
- await this.client.flushAsync();
70
+ async _postExportTracingEvent() {
71
+ if (this.#realtime) {
72
+ await this.#client?.flushAsync();
76
73
  }
77
74
  }
78
- async handleSpanStarted(span) {
79
- if (span.isRootSpan) {
80
- this.initTrace(span);
81
- }
82
- const method = "handleSpanStarted";
83
- const traceData = this.getTraceData({ span, method });
84
- if (!traceData) {
85
- return;
86
- }
87
- if (!span.isRootSpan) {
88
- const langfuseData = span.metadata?.langfuse;
89
- traceData.spanMetadata.set(span.id, {
90
- parentSpanId: span.parentSpanId,
91
- langfusePrompt: langfuseData?.prompt
92
- });
93
- }
94
- const langfuseParent = this.getLangfuseParent({ traceData, span, method });
75
+ async _buildRoot(args) {
76
+ const { span } = args;
77
+ return this.#client?.trace(this.buildTracePayload(span));
78
+ }
79
+ async _buildEvent(args) {
80
+ const { span, traceData } = args;
81
+ const langfuseParent = traceData.getParentOrRoot({ span });
95
82
  if (!langfuseParent) {
96
83
  return;
97
84
  }
98
85
  const payload = this.buildSpanPayload(span, true, traceData);
99
- const langfuseSpan = span.type === observability$1.SpanType.MODEL_GENERATION ? langfuseParent.generation(payload) : langfuseParent.span(payload);
100
- traceData.spans.set(span.id, langfuseSpan);
101
- traceData.activeSpans.add(span.id);
102
- }
103
- async handleSpanUpdateOrEnd(span, isEnd) {
104
- const method = isEnd ? "handleSpanEnd" : "handleSpanUpdate";
105
- const traceData = this.getTraceData({ span, method });
106
- if (!traceData) {
107
- return;
108
- }
109
- const langfuseSpan = traceData.spans.get(span.id);
110
- if (!langfuseSpan) {
111
- if (isEnd && span.isEvent) {
112
- traceData.activeSpans.delete(span.id);
113
- if (traceData.activeSpans.size === 0) {
114
- this.traceMap.delete(span.traceId);
115
- }
116
- return;
117
- }
118
- this.logger.warn("Langfuse exporter: No Langfuse span found for span update/end", {
119
- traceId: span.traceId,
120
- spanId: span.id,
121
- spanName: span.name,
122
- spanType: span.type,
123
- isRootSpan: span.isRootSpan,
124
- parentSpanId: span.parentSpanId,
125
- method
126
- });
127
- return;
128
- }
129
- langfuseSpan.update(this.buildSpanPayload(span, false, traceData));
130
- if (isEnd) {
131
- traceData.activeSpans.delete(span.id);
132
- if (span.isRootSpan) {
133
- traceData.trace.update({ output: span.output });
134
- }
135
- if (traceData.activeSpans.size === 0) {
136
- this.traceMap.delete(span.traceId);
137
- }
138
- }
86
+ return langfuseParent.event(payload);
139
87
  }
140
- async handleEventSpan(span) {
141
- if (span.isRootSpan) {
142
- this.logger.debug("Langfuse exporter: Creating trace", {
143
- traceId: span.traceId,
144
- spanId: span.id,
145
- spanName: span.name,
146
- method: "handleEventSpan"
147
- });
148
- this.initTrace(span);
149
- }
150
- const method = "handleEventSpan";
151
- const traceData = this.getTraceData({ span, method });
152
- if (!traceData) {
153
- return;
154
- }
155
- const langfuseParent = this.getLangfuseParent({ traceData, span, method });
88
+ async _buildSpan(args) {
89
+ const { span, traceData } = args;
90
+ const langfuseParent = traceData.getParentOrRoot({ span });
156
91
  if (!langfuseParent) {
157
92
  return;
158
93
  }
159
94
  const payload = this.buildSpanPayload(span, true, traceData);
160
- const langfuseEvent = langfuseParent.event(payload);
161
- traceData.events.set(span.id, langfuseEvent);
162
- if (!span.endTime) {
163
- traceData.activeSpans.add(span.id);
164
- }
95
+ const langfuseSpan = span.type === observability$1.SpanType.MODEL_GENERATION ? langfuseParent.generation(payload) : langfuseParent.span(payload);
96
+ this.logger.debug(`${this.name}: built span`, {
97
+ traceId: span.traceId,
98
+ spanId: payload.id,
99
+ method: "_buildSpan"
100
+ });
101
+ return langfuseSpan;
165
102
  }
166
- initTrace(span) {
167
- if (this.traceMap.has(span.traceId)) {
168
- this.logger.debug("Langfuse exporter: Reusing existing trace from local map", {
103
+ async _updateSpan(args) {
104
+ const { span, traceData } = args;
105
+ const langfuseSpan = traceData.getSpan({ spanId: span.id });
106
+ if (langfuseSpan) {
107
+ this.logger.debug(`${this.name}: found span for update`, {
169
108
  traceId: span.traceId,
170
- spanId: span.id,
171
- spanName: span.name
109
+ spanId: langfuseSpan.id,
110
+ method: "_updateSpan"
172
111
  });
173
- return;
112
+ const updatePayload = this.buildSpanPayload(span, false, traceData);
113
+ langfuseSpan.update(updatePayload);
174
114
  }
175
- const trace = this.client.trace(this.buildTracePayload(span));
176
- const langfuseData = span.metadata?.langfuse;
177
- const spanMetadata = /* @__PURE__ */ new Map();
178
- spanMetadata.set(span.id, {
179
- parentSpanId: void 0,
180
- langfusePrompt: langfuseData?.prompt
181
- });
182
- this.traceMap.set(span.traceId, {
183
- trace,
184
- spans: /* @__PURE__ */ new Map(),
185
- spanMetadata,
186
- events: /* @__PURE__ */ new Map(),
187
- activeSpans: /* @__PURE__ */ new Set(),
188
- rootSpanId: span.id
189
- });
190
115
  }
191
- getTraceData(options) {
192
- const { span, method } = options;
193
- if (this.traceMap.has(span.traceId)) {
194
- return this.traceMap.get(span.traceId);
116
+ async _finishSpan(args) {
117
+ const { span, traceData } = args;
118
+ const langfuseSpan = traceData.getSpan({ spanId: span.id });
119
+ langfuseSpan?.update(this.buildSpanPayload(span, false, traceData));
120
+ if (span.isRootSpan) {
121
+ const langfuseRoot = traceData.getRoot();
122
+ langfuseRoot?.update({ output: span.output });
195
123
  }
196
- this.logger.warn("Langfuse exporter: No trace data found for span", {
197
- traceId: span.traceId,
198
- spanId: span.id,
199
- spanName: span.name,
200
- spanType: span.type,
201
- isRootSpan: span.isRootSpan,
202
- parentSpanId: span.parentSpanId,
203
- method
204
- });
205
124
  }
206
- getLangfuseParent(options) {
207
- const { traceData, span, method } = options;
208
- const parentId = span.parentSpanId;
209
- if (!parentId) {
210
- return traceData.trace;
211
- }
212
- if (traceData.spans.has(parentId)) {
213
- return traceData.spans.get(parentId);
214
- }
215
- if (traceData.events.has(parentId)) {
216
- return traceData.events.get(parentId);
217
- }
218
- this.logger.warn("Langfuse exporter: No parent data found for span", {
219
- traceId: span.traceId,
220
- spanId: span.id,
221
- spanName: span.name,
222
- spanType: span.type,
223
- isRootSpan: span.isRootSpan,
224
- parentSpanId: span.parentSpanId,
225
- method
125
+ async _abortSpan(args) {
126
+ const { span, reason } = args;
127
+ span.end({
128
+ level: "ERROR",
129
+ statusMessage: reason.message
226
130
  });
227
131
  }
228
132
  buildTracePayload(span) {
@@ -243,18 +147,27 @@ var LangfuseExporter = class extends observability.BaseExporter {
243
147
  return payload;
244
148
  }
245
149
  /**
246
- * Look up the Langfuse prompt from the closest parent span that has one.
150
+ * Look up the Langfuse prompt from the closest span that has one.
247
151
  * This enables prompt inheritance for MODEL_GENERATION spans when the prompt
248
152
  * is set on a parent span (e.g., AGENT_RUN) rather than directly on the generation.
153
+ * This enables prompt linking when:
154
+ * - A workflow calls multiple agents, each with different prompts
155
+ * - Nested agents have different prompts
156
+ * - The prompt is set on AGENT_RUN but MODEL_GENERATION inherits it
249
157
  */
250
- findParentLangfusePrompt(traceData, span) {
251
- let currentSpanId = span.parentSpanId;
158
+ findLangfusePrompt(traceData, span) {
159
+ let currentSpanId = span.id;
252
160
  while (currentSpanId) {
253
- const parentMetadata = traceData.spanMetadata.get(currentSpanId);
254
- if (parentMetadata?.langfusePrompt) {
255
- return parentMetadata.langfusePrompt;
161
+ const providerMetadata = traceData.getMetadata({ spanId: currentSpanId });
162
+ if (providerMetadata?.prompt) {
163
+ this.logger.debug(`${this.name}: found prompt in provider metadata`, {
164
+ traceId: span.traceId,
165
+ spanId: span.id,
166
+ prompt: providerMetadata?.prompt
167
+ });
168
+ return providerMetadata.prompt;
256
169
  }
257
- currentSpanId = parentMetadata?.parentSpanId;
170
+ currentSpanId = traceData.getParentId({ spanId: currentSpanId });
258
171
  }
259
172
  return void 0;
260
173
  }
@@ -264,19 +177,13 @@ var LangfuseExporter = class extends observability.BaseExporter {
264
177
  payload.id = span.id;
265
178
  payload.name = span.name;
266
179
  payload.startTime = span.startTime;
267
- if (span.input !== void 0) payload.input = span.input;
268
180
  }
181
+ if (span.input !== void 0) payload.input = span.input;
269
182
  if (span.output !== void 0) payload.output = span.output;
270
183
  if (span.endTime !== void 0) payload.endTime = span.endTime;
271
184
  const attributes = span.attributes ?? {};
272
- const resolvedTraceData = traceData ?? this.traceMap.get(span.traceId);
273
- let inheritedLangfusePrompt;
274
- if (span.type === observability$1.SpanType.MODEL_GENERATION && !span.metadata?.langfuse && resolvedTraceData) {
275
- inheritedLangfusePrompt = this.findParentLangfusePrompt(resolvedTraceData, span);
276
- }
277
185
  const metadata = {
278
- ...span.metadata,
279
- ...inheritedLangfusePrompt ? { langfuse: { prompt: inheritedLangfusePrompt } } : {}
186
+ ...span.metadata
280
187
  };
281
188
  const attributesToOmit = [];
282
189
  const metadataToOmit = [];
@@ -294,8 +201,7 @@ var LangfuseExporter = class extends observability.BaseExporter {
294
201
  payload.modelParameters = modelAttr.parameters;
295
202
  attributesToOmit.push("parameters");
296
203
  }
297
- const langfuseData = metadata.langfuse;
298
- const promptData = langfuseData?.prompt;
204
+ const promptData = this.findLangfusePrompt(traceData, span);
299
205
  const hasNameAndVersion = promptData?.name !== void 0 && promptData?.version !== void 0;
300
206
  const hasId = promptData?.id !== void 0;
301
207
  if (hasNameAndVersion || hasId) {
@@ -329,9 +235,9 @@ var LangfuseExporter = class extends observability.BaseExporter {
329
235
  scorerName,
330
236
  metadata
331
237
  }) {
332
- if (!this.client) return;
238
+ if (!this.#client) return;
333
239
  try {
334
- await this.client.score({
240
+ await this.#client.score({
335
241
  id: `${traceId}-${scorerName}`,
336
242
  traceId,
337
243
  observationId: spanId,
@@ -350,12 +256,10 @@ var LangfuseExporter = class extends observability.BaseExporter {
350
256
  });
351
257
  }
352
258
  }
353
- async shutdown() {
354
- if (this.client) {
355
- await this.client.shutdownAsync();
259
+ async _postShutdown() {
260
+ if (this.#client) {
261
+ await this.#client.shutdownAsync();
356
262
  }
357
- this.traceMap.clear();
358
- await super.shutdown();
359
263
  }
360
264
  };
361
265
 
@@ -378,7 +282,6 @@ function withLangfusePrompt(prompt) {
378
282
  }
379
283
 
380
284
  exports.LangfuseExporter = LangfuseExporter;
381
- exports.formatUsageMetrics = formatUsageMetrics;
382
285
  exports.withLangfusePrompt = withLangfusePrompt;
383
286
  //# sourceMappingURL=index.cjs.map
384
287
  //# sourceMappingURL=index.cjs.map