@mastra/langsmith 0.0.0-remove-unused-model-providers-api-20251030210744 → 0.0.0-remove-ai-peer-dep-from-evals-20260105220639
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 +357 -4
- package/README.md +11 -1
- package/dist/index.cjs +63 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -32
- package/dist/index.js.map +1 -1
- package/dist/metrics.d.ts +5 -5
- package/dist/metrics.d.ts.map +1 -1
- package/dist/{ai-tracing.d.ts → tracing.d.ts} +13 -6
- package/dist/tracing.d.ts.map +1 -0
- package/package.json +16 -11
- package/dist/ai-tracing.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,58 +1,65 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var observability$1 = require('@mastra/core/observability');
|
|
4
|
+
var utils = require('@mastra/core/utils');
|
|
5
|
+
var observability = require('@mastra/observability');
|
|
4
6
|
var langsmith = require('langsmith');
|
|
5
7
|
|
|
6
|
-
// src/
|
|
8
|
+
// src/tracing.ts
|
|
7
9
|
|
|
8
10
|
// src/metrics.ts
|
|
9
|
-
function
|
|
11
|
+
function formatUsageMetrics(usage) {
|
|
10
12
|
const metrics = {};
|
|
11
|
-
if (
|
|
12
|
-
metrics.input_tokens =
|
|
13
|
-
} else if (modelAttr.usage?.promptTokens !== void 0) {
|
|
14
|
-
metrics.input_tokens = modelAttr.usage?.promptTokens;
|
|
13
|
+
if (usage?.inputTokens !== void 0) {
|
|
14
|
+
metrics.input_tokens = usage.inputTokens;
|
|
15
15
|
}
|
|
16
|
-
if (
|
|
17
|
-
metrics.output_tokens =
|
|
18
|
-
} else if (modelAttr.usage?.completionTokens !== void 0) {
|
|
19
|
-
metrics.output_tokens = modelAttr.usage?.completionTokens;
|
|
16
|
+
if (usage?.outputTokens !== void 0) {
|
|
17
|
+
metrics.output_tokens = usage.outputTokens;
|
|
20
18
|
}
|
|
21
|
-
if (
|
|
22
|
-
metrics.total_tokens =
|
|
23
|
-
} else if (typeof modelAttr.usage?.inputTokens === "number" && typeof modelAttr.usage?.outputTokens === "number") {
|
|
24
|
-
metrics.total_tokens = modelAttr.usage?.inputTokens + modelAttr.usage?.outputTokens;
|
|
19
|
+
if (metrics.input_tokens !== void 0 && metrics.output_tokens !== void 0) {
|
|
20
|
+
metrics.total_tokens = metrics.input_tokens + metrics.output_tokens;
|
|
25
21
|
}
|
|
26
|
-
if (
|
|
22
|
+
if (usage?.outputDetails?.reasoning !== void 0) {
|
|
27
23
|
metrics.output_token_details = {
|
|
28
24
|
...metrics.output_token_details ?? {},
|
|
29
|
-
reasoning_tokens:
|
|
25
|
+
reasoning_tokens: usage.outputDetails.reasoning
|
|
30
26
|
};
|
|
31
27
|
}
|
|
32
|
-
if (
|
|
28
|
+
if (usage?.inputDetails?.cacheRead !== void 0) {
|
|
33
29
|
metrics.input_token_details = {
|
|
34
30
|
...metrics.input_token_details ?? {},
|
|
35
|
-
cache_read:
|
|
31
|
+
cache_read: usage.inputDetails.cacheRead
|
|
36
32
|
};
|
|
37
33
|
}
|
|
38
|
-
if (
|
|
34
|
+
if (usage?.inputDetails?.cacheWrite !== void 0) {
|
|
39
35
|
metrics.input_token_details = {
|
|
40
36
|
...metrics.input_token_details ?? {},
|
|
41
|
-
cache_write:
|
|
37
|
+
cache_write: usage.inputDetails.cacheWrite
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (usage?.inputDetails?.audio !== void 0) {
|
|
41
|
+
metrics.input_token_details = {
|
|
42
|
+
...metrics.input_token_details ?? {},
|
|
43
|
+
audio: usage.inputDetails.audio
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (usage?.outputDetails?.audio !== void 0) {
|
|
47
|
+
metrics.output_token_details = {
|
|
48
|
+
...metrics.output_token_details ?? {},
|
|
49
|
+
audio: usage.outputDetails.audio
|
|
42
50
|
};
|
|
43
51
|
}
|
|
44
52
|
return metrics;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
// src/
|
|
55
|
+
// src/tracing.ts
|
|
48
56
|
var DEFAULT_SPAN_TYPE = "chain";
|
|
49
57
|
var SPAN_TYPE_EXCEPTIONS = {
|
|
50
|
-
[
|
|
51
|
-
[
|
|
52
|
-
[
|
|
53
|
-
[
|
|
54
|
-
[
|
|
55
|
-
[aiTracing.AISpanType.WORKFLOW_WAIT_EVENT]: "chain"
|
|
58
|
+
[observability$1.SpanType.MODEL_GENERATION]: "llm",
|
|
59
|
+
[observability$1.SpanType.TOOL_CALL]: "tool",
|
|
60
|
+
[observability$1.SpanType.MCP_TOOL_CALL]: "tool",
|
|
61
|
+
[observability$1.SpanType.WORKFLOW_CONDITIONAL_EVAL]: "chain",
|
|
62
|
+
[observability$1.SpanType.WORKFLOW_WAIT_EVENT]: "chain"
|
|
56
63
|
};
|
|
57
64
|
function mapSpanType(spanType) {
|
|
58
65
|
return SPAN_TYPE_EXCEPTIONS[spanType] ?? DEFAULT_SPAN_TYPE;
|
|
@@ -60,7 +67,7 @@ function mapSpanType(spanType) {
|
|
|
60
67
|
function isKVMap(value) {
|
|
61
68
|
return value != null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
62
69
|
}
|
|
63
|
-
var LangSmithExporter = class extends
|
|
70
|
+
var LangSmithExporter = class extends observability.BaseExporter {
|
|
64
71
|
name = "langsmith";
|
|
65
72
|
traceMap = /* @__PURE__ */ new Map();
|
|
66
73
|
config;
|
|
@@ -77,7 +84,7 @@ var LangSmithExporter = class extends aiTracing.BaseExporter {
|
|
|
77
84
|
this.client = config.client ?? new langsmith.Client(config);
|
|
78
85
|
this.config = config;
|
|
79
86
|
}
|
|
80
|
-
async
|
|
87
|
+
async _exportTracingEvent(event) {
|
|
81
88
|
if (event.exportedSpan.isEvent) {
|
|
82
89
|
await this.handleEventSpan(event.exportedSpan);
|
|
83
90
|
return;
|
|
@@ -95,6 +102,14 @@ var LangSmithExporter = class extends aiTracing.BaseExporter {
|
|
|
95
102
|
}
|
|
96
103
|
}
|
|
97
104
|
initializeRootSpan(span) {
|
|
105
|
+
if (this.traceMap.has(span.traceId)) {
|
|
106
|
+
this.logger.debug("LangSmith exporter: Reusing existing trace from local map", {
|
|
107
|
+
traceId: span.traceId,
|
|
108
|
+
spanId: span.id,
|
|
109
|
+
spanName: span.name
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
98
113
|
this.traceMap.set(span.traceId, { spans: /* @__PURE__ */ new Map(), activeIds: /* @__PURE__ */ new Set() });
|
|
99
114
|
}
|
|
100
115
|
async handleSpanStarted(span) {
|
|
@@ -159,6 +174,15 @@ var LangSmithExporter = class extends aiTracing.BaseExporter {
|
|
|
159
174
|
if (updatePayload.error != null) {
|
|
160
175
|
langsmithRunTree.error = updatePayload.error;
|
|
161
176
|
}
|
|
177
|
+
if (span.type === observability$1.SpanType.MODEL_GENERATION) {
|
|
178
|
+
const modelAttr = span.attributes ?? {};
|
|
179
|
+
if (modelAttr.completionStartTime !== void 0) {
|
|
180
|
+
langsmithRunTree.addEvent({
|
|
181
|
+
name: "new_token",
|
|
182
|
+
time: modelAttr.completionStartTime.toISOString()
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
162
186
|
if (isEnd) {
|
|
163
187
|
if (span.endTime) {
|
|
164
188
|
await langsmithRunTree.end({ endTime: span.endTime.getTime() / 1e3 });
|
|
@@ -251,6 +275,12 @@ var LangSmithExporter = class extends aiTracing.BaseExporter {
|
|
|
251
275
|
...span.metadata
|
|
252
276
|
}
|
|
253
277
|
};
|
|
278
|
+
if (this.config.projectName) {
|
|
279
|
+
payload.project_name = this.config.projectName;
|
|
280
|
+
}
|
|
281
|
+
if (span.isRootSpan && span.tags?.length) {
|
|
282
|
+
payload.tags = span.tags;
|
|
283
|
+
}
|
|
254
284
|
if (span.input !== void 0) {
|
|
255
285
|
payload.inputs = isKVMap(span.input) ? span.input : { input: span.input };
|
|
256
286
|
}
|
|
@@ -258,7 +288,7 @@ var LangSmithExporter = class extends aiTracing.BaseExporter {
|
|
|
258
288
|
payload.outputs = isKVMap(span.output) ? span.output : { output: span.output };
|
|
259
289
|
}
|
|
260
290
|
const attributes = span.attributes ?? {};
|
|
261
|
-
if (span.type ===
|
|
291
|
+
if (span.type === observability$1.SpanType.MODEL_GENERATION) {
|
|
262
292
|
const modelAttr = attributes;
|
|
263
293
|
if (modelAttr.model !== void 0) {
|
|
264
294
|
payload.metadata.ls_model_name = modelAttr.model;
|
|
@@ -266,11 +296,11 @@ var LangSmithExporter = class extends aiTracing.BaseExporter {
|
|
|
266
296
|
if (modelAttr.provider !== void 0) {
|
|
267
297
|
payload.metadata.ls_provider = modelAttr.provider;
|
|
268
298
|
}
|
|
269
|
-
payload.metadata.usage_metadata =
|
|
299
|
+
payload.metadata.usage_metadata = formatUsageMetrics(modelAttr.usage);
|
|
270
300
|
if (modelAttr.parameters !== void 0) {
|
|
271
301
|
payload.metadata.modelParameters = modelAttr.parameters;
|
|
272
302
|
}
|
|
273
|
-
const otherAttributes =
|
|
303
|
+
const otherAttributes = utils.omitKeys(attributes, ["model", "usage", "parameters", "completionStartTime"]);
|
|
274
304
|
payload.metadata = {
|
|
275
305
|
...payload.metadata,
|
|
276
306
|
...otherAttributes
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +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 {\n AITracingEvent,\n AnyExportedAISpan,\n ModelGenerationAttributes,\n BaseExporterConfig,\n} from '@mastra/core/ai-tracing';\nimport { AISpanType, omitKeys, BaseExporter } from '@mastra/core/ai-tracing';\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/metrics.ts","../src/tracing.ts"],"names":["SpanType","BaseExporter","Client","RunTree","omitKeys"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { UsageStats } from '@mastra/core/observability';\n\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}\n\n/**\n * Formats UsageStats to LangSmith's expected metric format.\n */\nexport function formatUsageMetrics(usage?: UsageStats): LangSmithUsageMetrics {\n const metrics: LangSmithUsageMetrics = {};\n\n if (usage?.inputTokens !== undefined) {\n metrics.input_tokens = usage.inputTokens;\n }\n\n if (usage?.outputTokens !== undefined) {\n metrics.output_tokens = usage.outputTokens;\n }\n\n // Compute total if we have both\n if (metrics.input_tokens !== undefined && metrics.output_tokens !== undefined) {\n metrics.total_tokens = metrics.input_tokens + metrics.output_tokens;\n }\n\n if (usage?.outputDetails?.reasoning !== undefined) {\n metrics.output_token_details = {\n ...(metrics.output_token_details ?? {}),\n reasoning_tokens: usage.outputDetails.reasoning,\n };\n }\n\n if (usage?.inputDetails?.cacheRead !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_read: usage.inputDetails.cacheRead,\n };\n }\n\n if (usage?.inputDetails?.cacheWrite !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_write: usage.inputDetails.cacheWrite,\n };\n }\n\n if (usage?.inputDetails?.audio !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n audio: usage.inputDetails.audio,\n };\n }\n\n if (usage?.outputDetails?.audio !== undefined) {\n metrics.output_token_details = {\n ...(metrics.output_token_details ?? {}),\n audio: usage.outputDetails.audio,\n };\n }\n\n return metrics;\n}\n","/**\n * LangSmith Exporter for Mastra Tracing\n *\n * This exporter sends observability data to LangSmith\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 { TracingEvent, AnyExportedSpan, ModelGenerationAttributes } from '@mastra/core/observability';\nimport { SpanType } from '@mastra/core/observability';\nimport { omitKeys } from '@mastra/core/utils';\nimport { BaseExporter } from '@mastra/observability';\nimport type { BaseExporterConfig } from '@mastra/observability';\nimport type { ClientConfig, RunTreeConfig } from 'langsmith';\nimport { Client, RunTree } from 'langsmith';\nimport type { KVMap } from 'langsmith/schemas';\nimport { formatUsageMetrics } from './metrics';\n\nexport interface LangSmithExporterConfig extends ClientConfig, BaseExporterConfig {\n /** LangSmith client instance */\n client?: Client;\n /**\n * The name of the LangSmith project to send traces to.\n * Overrides the LANGCHAIN_PROJECT environment variable.\n * If neither is set, traces are sent to the \"default\" project.\n */\n projectName?: string;\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<SpanType, 'llm' | 'tool' | 'chain'>> = {\n [SpanType.MODEL_GENERATION]: 'llm',\n [SpanType.TOOL_CALL]: 'tool',\n [SpanType.MCP_TOOL_CALL]: 'tool',\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: 'chain',\n [SpanType.WORKFLOW_WAIT_EVENT]: 'chain',\n};\n\n// Mapping function - returns valid LangSmith span types\nfunction mapSpanType(spanType: SpanType): '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 _exportTracingEvent(event: TracingEvent): 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: AnyExportedSpan) {\n // Check if trace already exists - reuse existing trace data\n if (this.traceMap.has(span.traceId)) {\n this.logger.debug('LangSmith exporter: Reusing existing trace from local map', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n });\n return;\n }\n\n this.traceMap.set(span.traceId, { spans: new Map(), activeIds: new Set() });\n }\n\n private async handleSpanStarted(span: AnyExportedSpan): 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: AnyExportedSpan, 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 // Add new_token event for TTFT tracking on MODEL_GENERATION spans\n if (span.type === SpanType.MODEL_GENERATION) {\n const modelAttr = (span.attributes ?? {}) as ModelGenerationAttributes;\n if (modelAttr.completionStartTime !== undefined) {\n langsmithRunTree.addEvent({\n name: 'new_token',\n time: modelAttr.completionStartTime.toISOString(),\n });\n }\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: AnyExportedSpan): 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: AnyExportedSpan; 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: AnyExportedSpan;\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: AnyExportedSpan): 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 // Add project name if configured\n if (this.config.projectName) {\n payload.project_name = this.config.projectName;\n }\n\n // Add tags for root spans\n if (span.isRootSpan && span.tags?.length) {\n payload.tags = span.tags;\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 === SpanType.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 = formatUsageMetrics(modelAttr.usage);\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', 'completionStartTime']);\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
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* LangSmith Observability Provider for Mastra
|
|
3
3
|
*
|
|
4
4
|
* This package provides LangSmith-specific observability features for Mastra applications.
|
|
5
|
-
* Currently includes
|
|
5
|
+
* Currently includes tracing support with plans for additional observability features.
|
|
6
6
|
*/
|
|
7
|
-
export * from './
|
|
7
|
+
export * from './tracing.js';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,56 +1,63 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpanType } from '@mastra/core/observability';
|
|
2
|
+
import { omitKeys } from '@mastra/core/utils';
|
|
3
|
+
import { BaseExporter } from '@mastra/observability';
|
|
2
4
|
import { Client, RunTree } from 'langsmith';
|
|
3
5
|
|
|
4
|
-
// src/
|
|
6
|
+
// src/tracing.ts
|
|
5
7
|
|
|
6
8
|
// src/metrics.ts
|
|
7
|
-
function
|
|
9
|
+
function formatUsageMetrics(usage) {
|
|
8
10
|
const metrics = {};
|
|
9
|
-
if (
|
|
10
|
-
metrics.input_tokens =
|
|
11
|
-
} else if (modelAttr.usage?.promptTokens !== void 0) {
|
|
12
|
-
metrics.input_tokens = modelAttr.usage?.promptTokens;
|
|
11
|
+
if (usage?.inputTokens !== void 0) {
|
|
12
|
+
metrics.input_tokens = usage.inputTokens;
|
|
13
13
|
}
|
|
14
|
-
if (
|
|
15
|
-
metrics.output_tokens =
|
|
16
|
-
} else if (modelAttr.usage?.completionTokens !== void 0) {
|
|
17
|
-
metrics.output_tokens = modelAttr.usage?.completionTokens;
|
|
14
|
+
if (usage?.outputTokens !== void 0) {
|
|
15
|
+
metrics.output_tokens = usage.outputTokens;
|
|
18
16
|
}
|
|
19
|
-
if (
|
|
20
|
-
metrics.total_tokens =
|
|
21
|
-
} else if (typeof modelAttr.usage?.inputTokens === "number" && typeof modelAttr.usage?.outputTokens === "number") {
|
|
22
|
-
metrics.total_tokens = modelAttr.usage?.inputTokens + modelAttr.usage?.outputTokens;
|
|
17
|
+
if (metrics.input_tokens !== void 0 && metrics.output_tokens !== void 0) {
|
|
18
|
+
metrics.total_tokens = metrics.input_tokens + metrics.output_tokens;
|
|
23
19
|
}
|
|
24
|
-
if (
|
|
20
|
+
if (usage?.outputDetails?.reasoning !== void 0) {
|
|
25
21
|
metrics.output_token_details = {
|
|
26
22
|
...metrics.output_token_details ?? {},
|
|
27
|
-
reasoning_tokens:
|
|
23
|
+
reasoning_tokens: usage.outputDetails.reasoning
|
|
28
24
|
};
|
|
29
25
|
}
|
|
30
|
-
if (
|
|
26
|
+
if (usage?.inputDetails?.cacheRead !== void 0) {
|
|
31
27
|
metrics.input_token_details = {
|
|
32
28
|
...metrics.input_token_details ?? {},
|
|
33
|
-
cache_read:
|
|
29
|
+
cache_read: usage.inputDetails.cacheRead
|
|
34
30
|
};
|
|
35
31
|
}
|
|
36
|
-
if (
|
|
32
|
+
if (usage?.inputDetails?.cacheWrite !== void 0) {
|
|
37
33
|
metrics.input_token_details = {
|
|
38
34
|
...metrics.input_token_details ?? {},
|
|
39
|
-
cache_write:
|
|
35
|
+
cache_write: usage.inputDetails.cacheWrite
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (usage?.inputDetails?.audio !== void 0) {
|
|
39
|
+
metrics.input_token_details = {
|
|
40
|
+
...metrics.input_token_details ?? {},
|
|
41
|
+
audio: usage.inputDetails.audio
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (usage?.outputDetails?.audio !== void 0) {
|
|
45
|
+
metrics.output_token_details = {
|
|
46
|
+
...metrics.output_token_details ?? {},
|
|
47
|
+
audio: usage.outputDetails.audio
|
|
40
48
|
};
|
|
41
49
|
}
|
|
42
50
|
return metrics;
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
// src/
|
|
53
|
+
// src/tracing.ts
|
|
46
54
|
var DEFAULT_SPAN_TYPE = "chain";
|
|
47
55
|
var SPAN_TYPE_EXCEPTIONS = {
|
|
48
|
-
[
|
|
49
|
-
[
|
|
50
|
-
[
|
|
51
|
-
[
|
|
52
|
-
[
|
|
53
|
-
[AISpanType.WORKFLOW_WAIT_EVENT]: "chain"
|
|
56
|
+
[SpanType.MODEL_GENERATION]: "llm",
|
|
57
|
+
[SpanType.TOOL_CALL]: "tool",
|
|
58
|
+
[SpanType.MCP_TOOL_CALL]: "tool",
|
|
59
|
+
[SpanType.WORKFLOW_CONDITIONAL_EVAL]: "chain",
|
|
60
|
+
[SpanType.WORKFLOW_WAIT_EVENT]: "chain"
|
|
54
61
|
};
|
|
55
62
|
function mapSpanType(spanType) {
|
|
56
63
|
return SPAN_TYPE_EXCEPTIONS[spanType] ?? DEFAULT_SPAN_TYPE;
|
|
@@ -75,7 +82,7 @@ var LangSmithExporter = class extends BaseExporter {
|
|
|
75
82
|
this.client = config.client ?? new Client(config);
|
|
76
83
|
this.config = config;
|
|
77
84
|
}
|
|
78
|
-
async
|
|
85
|
+
async _exportTracingEvent(event) {
|
|
79
86
|
if (event.exportedSpan.isEvent) {
|
|
80
87
|
await this.handleEventSpan(event.exportedSpan);
|
|
81
88
|
return;
|
|
@@ -93,6 +100,14 @@ var LangSmithExporter = class extends BaseExporter {
|
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
102
|
initializeRootSpan(span) {
|
|
103
|
+
if (this.traceMap.has(span.traceId)) {
|
|
104
|
+
this.logger.debug("LangSmith exporter: Reusing existing trace from local map", {
|
|
105
|
+
traceId: span.traceId,
|
|
106
|
+
spanId: span.id,
|
|
107
|
+
spanName: span.name
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
96
111
|
this.traceMap.set(span.traceId, { spans: /* @__PURE__ */ new Map(), activeIds: /* @__PURE__ */ new Set() });
|
|
97
112
|
}
|
|
98
113
|
async handleSpanStarted(span) {
|
|
@@ -157,6 +172,15 @@ var LangSmithExporter = class extends BaseExporter {
|
|
|
157
172
|
if (updatePayload.error != null) {
|
|
158
173
|
langsmithRunTree.error = updatePayload.error;
|
|
159
174
|
}
|
|
175
|
+
if (span.type === SpanType.MODEL_GENERATION) {
|
|
176
|
+
const modelAttr = span.attributes ?? {};
|
|
177
|
+
if (modelAttr.completionStartTime !== void 0) {
|
|
178
|
+
langsmithRunTree.addEvent({
|
|
179
|
+
name: "new_token",
|
|
180
|
+
time: modelAttr.completionStartTime.toISOString()
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
160
184
|
if (isEnd) {
|
|
161
185
|
if (span.endTime) {
|
|
162
186
|
await langsmithRunTree.end({ endTime: span.endTime.getTime() / 1e3 });
|
|
@@ -249,6 +273,12 @@ var LangSmithExporter = class extends BaseExporter {
|
|
|
249
273
|
...span.metadata
|
|
250
274
|
}
|
|
251
275
|
};
|
|
276
|
+
if (this.config.projectName) {
|
|
277
|
+
payload.project_name = this.config.projectName;
|
|
278
|
+
}
|
|
279
|
+
if (span.isRootSpan && span.tags?.length) {
|
|
280
|
+
payload.tags = span.tags;
|
|
281
|
+
}
|
|
252
282
|
if (span.input !== void 0) {
|
|
253
283
|
payload.inputs = isKVMap(span.input) ? span.input : { input: span.input };
|
|
254
284
|
}
|
|
@@ -256,7 +286,7 @@ var LangSmithExporter = class extends BaseExporter {
|
|
|
256
286
|
payload.outputs = isKVMap(span.output) ? span.output : { output: span.output };
|
|
257
287
|
}
|
|
258
288
|
const attributes = span.attributes ?? {};
|
|
259
|
-
if (span.type ===
|
|
289
|
+
if (span.type === SpanType.MODEL_GENERATION) {
|
|
260
290
|
const modelAttr = attributes;
|
|
261
291
|
if (modelAttr.model !== void 0) {
|
|
262
292
|
payload.metadata.ls_model_name = modelAttr.model;
|
|
@@ -264,11 +294,11 @@ var LangSmithExporter = class extends BaseExporter {
|
|
|
264
294
|
if (modelAttr.provider !== void 0) {
|
|
265
295
|
payload.metadata.ls_provider = modelAttr.provider;
|
|
266
296
|
}
|
|
267
|
-
payload.metadata.usage_metadata =
|
|
297
|
+
payload.metadata.usage_metadata = formatUsageMetrics(modelAttr.usage);
|
|
268
298
|
if (modelAttr.parameters !== void 0) {
|
|
269
299
|
payload.metadata.modelParameters = modelAttr.parameters;
|
|
270
300
|
}
|
|
271
|
-
const otherAttributes = omitKeys(attributes, ["model", "usage", "parameters"]);
|
|
301
|
+
const otherAttributes = omitKeys(attributes, ["model", "usage", "parameters", "completionStartTime"]);
|
|
272
302
|
payload.metadata = {
|
|
273
303
|
...payload.metadata,
|
|
274
304
|
...otherAttributes
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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 {\n AITracingEvent,\n AnyExportedAISpan,\n ModelGenerationAttributes,\n BaseExporterConfig,\n} from '@mastra/core/ai-tracing';\nimport { AISpanType, omitKeys, BaseExporter } from '@mastra/core/ai-tracing';\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/metrics.ts","../src/tracing.ts"],"names":[],"mappings":";;;;;;;;AAuBO,SAAS,mBAAmB,KAAA,EAA2C;AAC5E,EAAA,MAAM,UAAiC,EAAC;AAExC,EAAA,IAAI,KAAA,EAAO,gBAAgB,MAAA,EAAW;AACpC,IAAA,OAAA,CAAQ,eAAe,KAAA,CAAM,WAAA;AAAA,EAC/B;AAEA,EAAA,IAAI,KAAA,EAAO,iBAAiB,MAAA,EAAW;AACrC,IAAA,OAAA,CAAQ,gBAAgB,KAAA,CAAM,YAAA;AAAA,EAChC;AAGA,EAAA,IAAI,OAAA,CAAQ,YAAA,KAAiB,MAAA,IAAa,OAAA,CAAQ,kBAAkB,MAAA,EAAW;AAC7E,IAAA,OAAA,CAAQ,YAAA,GAAe,OAAA,CAAQ,YAAA,GAAe,OAAA,CAAQ,aAAA;AAAA,EACxD;AAEA,EAAA,IAAI,KAAA,EAAO,aAAA,EAAe,SAAA,KAAc,MAAA,EAAW;AACjD,IAAA,OAAA,CAAQ,oBAAA,GAAuB;AAAA,MAC7B,GAAI,OAAA,CAAQ,oBAAA,IAAwB,EAAC;AAAA,MACrC,gBAAA,EAAkB,MAAM,aAAA,CAAc;AAAA,KACxC;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,EAAO,YAAA,EAAc,SAAA,KAAc,MAAA,EAAW;AAChD,IAAA,OAAA,CAAQ,mBAAA,GAAsB;AAAA,MAC5B,GAAI,OAAA,CAAQ,mBAAA,IAAuB,EAAC;AAAA,MACpC,UAAA,EAAY,MAAM,YAAA,CAAa;AAAA,KACjC;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,EAAO,YAAA,EAAc,UAAA,KAAe,MAAA,EAAW;AACjD,IAAA,OAAA,CAAQ,mBAAA,GAAsB;AAAA,MAC5B,GAAI,OAAA,CAAQ,mBAAA,IAAuB,EAAC;AAAA,MACpC,WAAA,EAAa,MAAM,YAAA,CAAa;AAAA,KAClC;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,EAAO,YAAA,EAAc,KAAA,KAAU,MAAA,EAAW;AAC5C,IAAA,OAAA,CAAQ,mBAAA,GAAsB;AAAA,MAC5B,GAAI,OAAA,CAAQ,mBAAA,IAAuB,EAAC;AAAA,MACpC,KAAA,EAAO,MAAM,YAAA,CAAa;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,EAAO,aAAA,EAAe,KAAA,KAAU,MAAA,EAAW;AAC7C,IAAA,OAAA,CAAQ,oBAAA,GAAuB;AAAA,MAC7B,GAAI,OAAA,CAAQ,oBAAA,IAAwB,EAAC;AAAA,MACrC,KAAA,EAAO,MAAM,aAAA,CAAc;AAAA,KAC7B;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;;;ACxCA,IAAM,iBAAA,GAAoB,OAAA;AAG1B,IAAM,oBAAA,GAA4E;AAAA,EAChF,CAAC,QAAA,CAAS,gBAAgB,GAAG,KAAA;AAAA,EAC7B,CAAC,QAAA,CAAS,SAAS,GAAG,MAAA;AAAA,EACtB,CAAC,QAAA,CAAS,aAAa,GAAG,MAAA;AAAA,EAC1B,CAAC,QAAA,CAAS,yBAAyB,GAAG,OAAA;AAAA,EACtC,CAAC,QAAA,CAAS,mBAAmB,GAAG;AAClC,CAAA;AAGA,SAAS,YAAY,QAAA,EAA8C;AACjE,EAAA,OAAO,oBAAA,CAAqB,QAAQ,CAAA,IAAK,iBAAA;AAC3C;AAEA,SAAS,QAAQ,KAAA,EAAgC;AAC/C,EAAA,OAAO,KAAA,IAAS,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,EAAE,KAAA,YAAiB,IAAA,CAAA;AACnG;AAEO,IAAM,iBAAA,GAAN,cAAgC,YAAA,CAAa;AAAA,EAClD,IAAA,GAAO,WAAA;AAAA,EACC,QAAA,uBAAe,GAAA,EAAsB;AAAA,EACrC,MAAA;AAAA,EACA,MAAA;AAAA,EAER,YAAY,MAAA,EAAiC;AAC3C,IAAA,KAAA,CAAM,MAAM,CAAA;AAEZ,IAAA,MAAA,CAAO,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,iBAAA;AAE7C,IAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAClB,MAAA,IAAA,CAAK,YAAY,CAAA,sCAAA,EAAyC,CAAC,CAAC,MAAA,CAAO,MAAM,CAAA,CAAA,CAAG,CAAA;AAC5E,MAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,MAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,IAAI,OAAO,MAAM,CAAA;AAChD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA,EAEA,MAAgB,oBAAoB,KAAA,EAAoC;AACtE,IAAA,IAAI,KAAA,CAAM,aAAa,OAAA,EAAS;AAC9B,MAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,KAAA,CAAM,YAAY,CAAA;AAC7C,MAAA;AAAA,IACF;AAEA,IAAA,QAAQ,MAAM,IAAA;AAAM,MAClB,KAAK,cAAA;AACH,QAAA,MAAM,IAAA,CAAK,iBAAA,CAAkB,KAAA,CAAM,YAAY,CAAA;AAC/C,QAAA;AAAA,MACF,KAAK,cAAA;AACH,QAAA,MAAM,IAAA,CAAK,qBAAA,CAAsB,KAAA,CAAM,YAAA,EAAc,KAAK,CAAA;AAC1D,QAAA;AAAA,MACF,KAAK,YAAA;AACH,QAAA,MAAM,IAAA,CAAK,qBAAA,CAAsB,KAAA,CAAM,YAAA,EAAc,IAAI,CAAA;AACzD,QAAA;AAAA;AACJ,EACF;AAAA,EAEQ,mBAAmB,IAAA,EAAuB;AAEhD,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,2DAAA,EAA6D;AAAA,QAC7E,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,QAAQ,IAAA,CAAK,EAAA;AAAA,QACb,UAAU,IAAA,CAAK;AAAA,OAChB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,kBAAO,IAAI,GAAA,EAAI,EAAG,SAAA,kBAAW,IAAI,GAAA,IAAO,CAAA;AAAA,EAC5E;AAAA,EAEA,MAAc,kBAAkB,IAAA,EAAsC;AACpE,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,uCAAA,EAAyC,IAAA,CAAK,EAAA,EAAI,KAAK,IAAI,CAAA;AAC7E,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,IAAA,CAAK,mBAAmB,IAAI,CAAA;AAAA,IAC9B;AAEA,IAAA,MAAM,MAAA,GAAS,mBAAA;AACf,IAAA,MAAM,WAAW,IAAA,CAAK,WAAA,CAAY,EAAE,IAAA,EAAM,QAAQ,CAAA;AAClD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,QAAA,CAAS,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAAA,IAChC;AAEA,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,QAAA,EAAU,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAAA,MAC/B,GAAG,IAAA,CAAK,mBAAA,CAAoB,IAAI;AAAA,KAClC;AAEA,IAAA,MAAM,kBAAkB,IAAA,CAAK,kBAAA,CAAmB,EAAE,QAAA,EAAU,IAAA,EAAM,QAAQ,CAAA;AAC1E,IAAA,IAAI,gBAAA;AACJ,IAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,MAAA,gBAAA,GAAmB,IAAI,QAAQ,OAAO,CAAA;AAAA,IACxC,CAAA,MAAO;AACL,MAAA,gBAAA,GAAmB,eAAA,CAAgB,YAAY,OAAO,CAAA;AAAA,IACxD;AAEA,IAAA,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,gBAAgB,CAAA;AAE5C,IAAA,MAAM,iBAAiB,OAAA,EAAQ;AAAA,EACjC;AAAA,EAEA,MAAc,qBAAA,CAAsB,IAAA,EAAuB,KAAA,EAA+B;AACxF,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,2CAAA,EAA6C,IAAA,CAAK,IAAI,IAAA,CAAK,IAAA,EAAM,UAAU,KAAK,CAAA;AAClG,IAAA,MAAM,MAAA,GAAS,QAAQ,eAAA,GAAkB,kBAAA;AAEzC,IAAA,MAAM,WAAW,IAAA,CAAK,WAAA,CAAY,EAAE,IAAA,EAAM,QAAQ,CAAA;AAClD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,KAAK,EAAE,CAAA;AACnD,IAAA,IAAI,CAAC,gBAAA,EAAkB;AACrB,MAAA,IAAA,CAAK,MAAA,CAAO,KAAK,iEAAA,EAAmE;AAAA,QAClF,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,QAAQ,IAAA,CAAK,EAAA;AAAA,QACb,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,cAAc,IAAA,CAAK,YAAA;AAAA,QACnB;AAAA,OACD,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,mBAAA,CAAoB,IAAI,CAAA;AACnD,IAAA,gBAAA,CAAiB,QAAA,GAAW;AAAA,MAC1B,GAAG,gBAAA,CAAiB,QAAA;AAAA,MACpB,GAAG,aAAA,CAAc;AAAA,KACnB;AACA,IAAA,IAAI,aAAA,CAAc,UAAU,IAAA,EAAM;AAChC,MAAA,gBAAA,CAAiB,SAAS,aAAA,CAAc,MAAA;AAAA,IAC1C;AACA,IAAA,IAAI,aAAA,CAAc,WAAW,IAAA,EAAM;AACjC,MAAA,gBAAA,CAAiB,UAAU,aAAA,CAAc,OAAA;AAAA,IAC3C;AACA,IAAA,IAAI,aAAA,CAAc,SAAS,IAAA,EAAM;AAC/B,MAAA,gBAAA,CAAiB,QAAQ,aAAA,CAAc,KAAA;AAAA,IACzC;AAGA,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,gBAAA,EAAkB;AAC3C,MAAA,MAAM,SAAA,GAAa,IAAA,CAAK,UAAA,IAAc,EAAC;AACvC,MAAA,IAAI,SAAA,CAAU,wBAAwB,MAAA,EAAW;AAC/C,QAAA,gBAAA,CAAiB,QAAA,CAAS;AAAA,UACxB,IAAA,EAAM,WAAA;AAAA,UACN,IAAA,EAAM,SAAA,CAAU,mBAAA,CAAoB,WAAA;AAAY,SACjD,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,IAAI,KAAA,EAAO;AAET,MAAA,IAAI,KAAK,OAAA,EAAS;AAChB,QAAA,MAAM,gBAAA,CAAiB,IAAI,EAAE,OAAA,EAAS,KAAK,OAAA,CAAQ,OAAA,EAAQ,GAAI,GAAA,EAAM,CAAA;AAAA,MACvE,CAAA,MAAO;AACL,QAAA,MAAM,iBAAiB,GAAA,EAAI;AAAA,MAC7B;AACA,MAAA,MAAM,iBAAiB,QAAA,EAAS;AAGhC,MAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,QAAA,QAAA,CAAS,SAAA,CAAU,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAAA,MACnC;AAGA,MAAA,IAAI,QAAA,CAAS,SAAA,CAAU,IAAA,KAAS,CAAA,EAAG;AACjC,QAAA,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,gBAAgB,IAAA,EAAsC;AAClE,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,+CAAA,EAAiD;AAAA,QACjE,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,QAAQ,IAAA,CAAK,EAAA;AAAA,QACb,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,IAAA,CAAK,mBAAmB,IAAI,CAAA;AAAA,IAC9B;AAEA,IAAA,MAAM,MAAA,GAAS,iBAAA;AACf,IAAA,MAAM,WAAW,IAAA,CAAK,WAAA,CAAY,EAAE,IAAA,EAAM,QAAQ,CAAA;AAClD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,kBAAkB,IAAA,CAAK,kBAAA,CAAmB,EAAE,QAAA,EAAU,IAAA,EAAM,QAAQ,CAAA;AAC1E,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,GAAG,IAAA,CAAK,mBAAA,CAAoB,IAAI,CAAA;AAAA,MAChC,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,IAAA,EAAM,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAAA,MAC3B,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,OAAA,EAAQ,GAAI;AAAA,KACxC;AAEA,IAAA,IAAI,gBAAA;AACJ,IAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,MAAA,gBAAA,GAAmB,IAAI,QAAQ,OAAO,CAAA;AAAA,IACxC,CAAA,MAAO;AACL,MAAA,gBAAA,GAAmB,eAAA,CAAgB,YAAY,OAAO,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,iBAAiB,OAAA,EAAQ;AAE/B,IAAA,MAAM,gBAAA,CAAiB,IAAI,EAAE,OAAA,EAAS,KAAK,SAAA,CAAU,OAAA,EAAQ,GAAI,GAAA,EAAM,CAAA;AACvE,IAAA,MAAM,iBAAiB,QAAA,EAAS;AAAA,EAClC;AAAA,EAEQ,YAAY,OAAA,EAA0E;AAC5F,IAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAI,OAAA;AACzB,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA,EAAG;AACnC,MAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA;AAAA,IACvC;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,iDAAA,EAAmD;AAAA,MAClE,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,QAAQ,IAAA,CAAK,EAAA;AAAA,MACb,UAAU,IAAA,CAAK,IAAA;AAAA,MACf,UAAU,IAAA,CAAK,IAAA;AAAA,MACf,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB;AAAA,KACD,CAAA;AAAA,EACH;AAAA,EAEQ,mBAAmB,OAAA,EAIH;AACtB,IAAA,MAAM,EAAE,QAAA,EAAU,IAAA,EAAM,MAAA,EAAO,GAAI,OAAA;AAEnC,IAAA,MAAM,WAAW,IAAA,CAAK,YAAA;AACtB,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA,EAAG;AAChC,MAAA,OAAO,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AAAA,IACpC;AAEA,IAAA,IAAI,YAAY,CAAC,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA,EAAG;AAG7C,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,mDAAA,EAAqD;AAAA,MACpE,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,QAAQ,IAAA,CAAK,EAAA;AAAA,MACb,UAAU,IAAA,CAAK,IAAA;AAAA,MACf,UAAU,IAAA,CAAK,IAAA;AAAA,MACf,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB;AAAA,KACD,CAAA;AAAA,EACH;AAAA,EAEQ,oBAAoB,IAAA,EAA+C;AACzE,IAAA,MAAM,OAAA,GAAwD;AAAA,MAC5D,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,QAAA,EAAU;AAAA,QACR,kBAAkB,IAAA,CAAK,IAAA;AAAA,QACvB,GAAG,IAAA,CAAK;AAAA;AACV,KACF;AAGA,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,EAAa;AAC3B,MAAA,OAAA,CAAQ,YAAA,GAAe,KAAK,MAAA,CAAO,WAAA;AAAA,IACrC;AAGA,IAAA,IAAI,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ;AACxC,MAAA,OAAA,CAAQ,OAAO,IAAA,CAAK,IAAA;AAAA,IACtB;AAGA,IAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAW;AAC5B,MAAA,OAAA,CAAQ,MAAA,GAAS,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,GAAI,KAAK,KAAA,GAAQ,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM;AAAA,IAC1E;AAEA,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAW;AAC7B,MAAA,OAAA,CAAQ,OAAA,GAAU,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,GAAI,KAAK,MAAA,GAAS,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO;AAAA,IAC/E;AAEA,IAAA,MAAM,UAAA,GAAc,IAAA,CAAK,UAAA,IAAc,EAAC;AAExC,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,gBAAA,EAAkB;AAC3C,MAAA,MAAM,SAAA,GAAY,UAAA;AAGlB,MAAA,IAAI,SAAA,CAAU,UAAU,MAAA,EAAW;AAGjC,QAAA,OAAA,CAAQ,QAAA,CAAS,gBAAgB,SAAA,CAAU,KAAA;AAAA,MAC7C;AAGA,MAAA,IAAI,SAAA,CAAU,aAAa,MAAA,EAAW;AAGpC,QAAA,OAAA,CAAQ,QAAA,CAAS,cAAc,SAAA,CAAU,QAAA;AAAA,MAC3C;AAGA,MAAA,OAAA,CAAQ,QAAA,CAAS,cAAA,GAAiB,kBAAA,CAAmB,SAAA,CAAU,KAAK,CAAA;AAGpE,MAAA,IAAI,SAAA,CAAU,eAAe,MAAA,EAAW;AACtC,QAAA,OAAA,CAAQ,QAAA,CAAS,kBAAkB,SAAA,CAAU,UAAA;AAAA,MAC/C;AAGA,MAAA,MAAM,eAAA,GAAkB,SAAS,UAAA,EAAY,CAAC,SAAS,OAAA,EAAS,YAAA,EAAc,qBAAqB,CAAC,CAAA;AACpG,MAAA,OAAA,CAAQ,QAAA,GAAW;AAAA,QACjB,GAAG,OAAA,CAAQ,QAAA;AAAA,QACX,GAAG;AAAA,OACL;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,OAAA,CAAQ,QAAA,GAAW;AAAA,QACjB,GAAG,OAAA,CAAQ,QAAA;AAAA,QACX,GAAG;AAAA,OACL;AAAA,IACF;AAGA,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,OAAA,CAAQ,KAAA,GAAQ,KAAK,SAAA,CAAU,OAAA;AAC/B,MAAA,OAAA,CAAQ,QAAA,CAAS,eAAe,IAAA,CAAK,SAAA;AAAA,IACvC;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,QAAA,GAA0B;AAC9B,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,MAAA;AAAA,IACF;AAGA,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,QAAQ,CAAA,IAAK,KAAK,QAAA,EAAU;AAChD,MAAA,KAAA,MAAW,CAAC,OAAA,EAAS,OAAO,CAAA,IAAK,SAAS,KAAA,EAAO;AAC/C,QAAA,MAAM,QAAQ,GAAA,EAAI;AAClB,QAAA,MAAM,QAAQ,QAAA,EAAS;AAAA,MACzB;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AACpB,IAAA,MAAM,MAAM,QAAA,EAAS;AAAA,EACvB;AACF","file":"index.js","sourcesContent":["import type { UsageStats } from '@mastra/core/observability';\n\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}\n\n/**\n * Formats UsageStats to LangSmith's expected metric format.\n */\nexport function formatUsageMetrics(usage?: UsageStats): LangSmithUsageMetrics {\n const metrics: LangSmithUsageMetrics = {};\n\n if (usage?.inputTokens !== undefined) {\n metrics.input_tokens = usage.inputTokens;\n }\n\n if (usage?.outputTokens !== undefined) {\n metrics.output_tokens = usage.outputTokens;\n }\n\n // Compute total if we have both\n if (metrics.input_tokens !== undefined && metrics.output_tokens !== undefined) {\n metrics.total_tokens = metrics.input_tokens + metrics.output_tokens;\n }\n\n if (usage?.outputDetails?.reasoning !== undefined) {\n metrics.output_token_details = {\n ...(metrics.output_token_details ?? {}),\n reasoning_tokens: usage.outputDetails.reasoning,\n };\n }\n\n if (usage?.inputDetails?.cacheRead !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_read: usage.inputDetails.cacheRead,\n };\n }\n\n if (usage?.inputDetails?.cacheWrite !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n cache_write: usage.inputDetails.cacheWrite,\n };\n }\n\n if (usage?.inputDetails?.audio !== undefined) {\n metrics.input_token_details = {\n ...(metrics.input_token_details ?? {}),\n audio: usage.inputDetails.audio,\n };\n }\n\n if (usage?.outputDetails?.audio !== undefined) {\n metrics.output_token_details = {\n ...(metrics.output_token_details ?? {}),\n audio: usage.outputDetails.audio,\n };\n }\n\n return metrics;\n}\n","/**\n * LangSmith Exporter for Mastra Tracing\n *\n * This exporter sends observability data to LangSmith\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 { TracingEvent, AnyExportedSpan, ModelGenerationAttributes } from '@mastra/core/observability';\nimport { SpanType } from '@mastra/core/observability';\nimport { omitKeys } from '@mastra/core/utils';\nimport { BaseExporter } from '@mastra/observability';\nimport type { BaseExporterConfig } from '@mastra/observability';\nimport type { ClientConfig, RunTreeConfig } from 'langsmith';\nimport { Client, RunTree } from 'langsmith';\nimport type { KVMap } from 'langsmith/schemas';\nimport { formatUsageMetrics } from './metrics';\n\nexport interface LangSmithExporterConfig extends ClientConfig, BaseExporterConfig {\n /** LangSmith client instance */\n client?: Client;\n /**\n * The name of the LangSmith project to send traces to.\n * Overrides the LANGCHAIN_PROJECT environment variable.\n * If neither is set, traces are sent to the \"default\" project.\n */\n projectName?: string;\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<SpanType, 'llm' | 'tool' | 'chain'>> = {\n [SpanType.MODEL_GENERATION]: 'llm',\n [SpanType.TOOL_CALL]: 'tool',\n [SpanType.MCP_TOOL_CALL]: 'tool',\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: 'chain',\n [SpanType.WORKFLOW_WAIT_EVENT]: 'chain',\n};\n\n// Mapping function - returns valid LangSmith span types\nfunction mapSpanType(spanType: SpanType): '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 _exportTracingEvent(event: TracingEvent): 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: AnyExportedSpan) {\n // Check if trace already exists - reuse existing trace data\n if (this.traceMap.has(span.traceId)) {\n this.logger.debug('LangSmith exporter: Reusing existing trace from local map', {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n });\n return;\n }\n\n this.traceMap.set(span.traceId, { spans: new Map(), activeIds: new Set() });\n }\n\n private async handleSpanStarted(span: AnyExportedSpan): 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: AnyExportedSpan, 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 // Add new_token event for TTFT tracking on MODEL_GENERATION spans\n if (span.type === SpanType.MODEL_GENERATION) {\n const modelAttr = (span.attributes ?? {}) as ModelGenerationAttributes;\n if (modelAttr.completionStartTime !== undefined) {\n langsmithRunTree.addEvent({\n name: 'new_token',\n time: modelAttr.completionStartTime.toISOString(),\n });\n }\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: AnyExportedSpan): 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: AnyExportedSpan; 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: AnyExportedSpan;\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: AnyExportedSpan): 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 // Add project name if configured\n if (this.config.projectName) {\n payload.project_name = this.config.projectName;\n }\n\n // Add tags for root spans\n if (span.isRootSpan && span.tags?.length) {\n payload.tags = span.tags;\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 === SpanType.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 = formatUsageMetrics(modelAttr.usage);\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', 'completionStartTime']);\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/metrics.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UsageStats } from '@mastra/core/observability';
|
|
2
2
|
/**
|
|
3
3
|
* LangSmithUsageMetrics
|
|
4
4
|
*
|
|
@@ -15,9 +15,9 @@ export interface LangSmithUsageMetrics {
|
|
|
15
15
|
output_token_details?: {
|
|
16
16
|
[key: string]: number;
|
|
17
17
|
};
|
|
18
|
-
[key: string]: number | {
|
|
19
|
-
[key: string]: number;
|
|
20
|
-
} | undefined;
|
|
21
18
|
}
|
|
22
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Formats UsageStats to LangSmith's expected metric format.
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatUsageMetrics(usage?: UsageStats): LangSmithUsageMetrics;
|
|
23
23
|
//# sourceMappingURL=metrics.d.ts.map
|
package/dist/metrics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D;;;;;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;CACH;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,qBAAqB,CAoD5E"}
|