🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@mastra/braintrust

Package Overview
Dependencies
Maintainers
7
Versions
596
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mastra/braintrust - npm Package Compare versions

Comparing version
1.2.4
to
1.3.0-alpha.0
+1
-1
dist/index.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/formatter.ts","../src/metrics.ts","../src/thread-reconstruction.ts","../src/tracing.ts"],"names":["SpanType","TrackingExporter","initLogger","currentSpan","omitKeys"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Message format conversion utilities for Braintrust.\n *\n * Converts AI SDK message format (v4/v5) to OpenAI Chat Completion format,\n * which Braintrust requires for proper rendering of threads.\n */\n\n// ==============================================================================\n// Utility functions\n// ==============================================================================\n\n/**\n * Remove null and undefined values from an object (shallow)\n */\nexport function removeNullish<T extends Record<string, unknown>>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null)) as Partial<T>;\n}\n\n// ==============================================================================\n// Type definitions for AI SDK message format conversion to OpenAI format\n// ==============================================================================\n\n/**\n * AI SDK content part types (both v4 and v5)\n */\ninterface AISDKTextPart {\n type: 'text';\n text: string;\n}\n\ninterface AISDKImagePart {\n type: 'image';\n image?: string | Uint8Array | URL;\n mimeType?: string;\n}\n\ninterface AISDKFilePart {\n type: 'file';\n data?: string | Uint8Array | URL;\n filename?: string;\n name?: string;\n mimeType?: string;\n}\n\ninterface AISDKReasoningPart {\n type: 'reasoning';\n text?: string;\n}\n\ninterface AISDKToolCallPart {\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n args?: unknown; // AI SDK v4\n input?: unknown; // AI SDK v5\n}\n\ninterface AISDKToolResultPart {\n type: 'tool-result';\n toolCallId: string;\n result?: unknown; // AI SDK v4\n output?: unknown; // AI SDK v5\n}\n\ntype AISDKContentPart =\n | AISDKTextPart\n | AISDKImagePart\n | AISDKFilePart\n | AISDKReasoningPart\n | AISDKToolCallPart\n | AISDKToolResultPart\n | { type: string; [key: string]: unknown }; // Catch-all for unknown types\n\n/**\n * AI SDK message format (input format for conversion)\n */\ninterface AISDKMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string | AISDKContentPart[];\n [key: string]: unknown; // Allow additional properties\n}\n\n/**\n * OpenAI Chat Completion tool call format\n */\nexport interface OpenAIToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * OpenAI Chat Completion message format (output format)\n */\nexport interface OpenAIMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string;\n tool_calls?: OpenAIToolCall[];\n tool_call_id?: string;\n [key: string]: unknown; // Allow additional properties\n}\n\n// ==============================================================================\n// Message conversion functions\n// ==============================================================================\n\n/**\n * Converts a content part to a string representation.\n * Handles text, image, file, reasoning, and other content types.\n */\nfunction convertContentPart(part: AISDKContentPart | null | undefined): string | null {\n if (!part || typeof part !== 'object') {\n return null;\n }\n\n switch (part.type) {\n case 'text':\n return (part as AISDKTextPart).text || null;\n\n case 'image':\n // Represent image content with a placeholder\n return '[image]';\n\n case 'file': {\n // Represent file content with filename if available\n const filePart = part as AISDKFilePart;\n if (filePart.filename || filePart.name) {\n return `[file: ${filePart.filename || filePart.name}]`;\n }\n return '[file]';\n }\n\n case 'reasoning': {\n // Represent reasoning/thinking content\n const reasoningPart = part as AISDKReasoningPart;\n if (typeof reasoningPart.text === 'string' && reasoningPart.text.length > 0) {\n return `[reasoning: ${reasoningPart.text.substring(0, 100)}${reasoningPart.text.length > 100 ? '...' : ''}]`;\n }\n return '[reasoning]';\n }\n\n case 'tool-call':\n // Tool calls are handled separately in assistant messages\n return null;\n\n case 'tool-result':\n // Tool results are handled separately in tool messages\n return null;\n\n default: {\n // For unknown types, try to extract any text-like content\n const unknownPart = part as { type?: string; text?: string; content?: string };\n if (typeof unknownPart.text === 'string') {\n return unknownPart.text;\n }\n if (typeof unknownPart.content === 'string') {\n return unknownPart.content;\n }\n // Represent unknown content type\n return `[${unknownPart.type || 'unknown'}]`;\n }\n }\n}\n\n/**\n * Serializes tool result data to a string for OpenAI format.\n */\nexport function serializeToolResult(resultData: unknown): string {\n if (typeof resultData === 'string') {\n return resultData;\n }\n if (resultData && typeof resultData === 'object' && 'value' in resultData) {\n const valueData = (resultData as { value: unknown }).value;\n return typeof valueData === 'string' ? valueData : JSON.stringify(valueData);\n }\n if (resultData === undefined || resultData === null) {\n return '';\n }\n try {\n return JSON.stringify(resultData);\n } catch {\n return '[unserializable result]';\n }\n}\n\n/**\n * Converts AI SDK message format to OpenAI Chat Completion format for Braintrust.\n *\n * Supports both AI SDK v4 and v5 formats:\n * - v4 uses 'args' for tool calls and 'result' for tool results\n * - v5 uses 'input' for tool calls and 'output' for tool results\n *\n * AI SDK format:\n * { role: \"user\", content: [{ type: \"text\", text: \"hello\" }] }\n * { role: \"assistant\", content: [{ type: \"text\", text: \"...\" }, { type: \"tool-call\", toolCallId: \"...\", toolName: \"...\", args: {...} }] }\n * { role: \"tool\", content: [{ type: \"tool-result\", toolCallId: \"...\", result: {...} }] }\n *\n * OpenAI format (what Braintrust expects):\n * { role: \"user\", content: \"hello\" }\n * { role: \"assistant\", content: \"...\", tool_calls: [{ id: \"...\", type: \"function\", function: { name: \"...\", arguments: \"...\" } }] }\n * { role: \"tool\", content: \"result\", tool_call_id: \"...\" }\n */\nexport function convertAISDKMessage(message: AISDKMessage | OpenAIMessage | unknown): OpenAIMessage | unknown {\n if (!message || typeof message !== 'object') {\n return message;\n }\n\n const { role, content, ...rest } = message as AISDKMessage;\n\n // If content is already a string, return as-is (already in OpenAI format)\n if (typeof content === 'string') {\n return message;\n }\n\n // If content is an array (AI SDK format), convert based on role\n if (Array.isArray(content)) {\n // Handle empty content arrays\n if (content.length === 0) {\n return { role, content: '', ...rest };\n }\n\n // For user/system messages, extract text and represent non-text content\n if (role === 'user' || role === 'system') {\n const contentParts = content.map((part: AISDKContentPart) => convertContentPart(part)).filter(Boolean);\n\n return {\n role,\n content: contentParts.length > 0 ? contentParts.join('\\n') : '',\n ...rest,\n };\n }\n\n // For assistant messages, extract text, non-text content, AND tool calls\n if (role === 'assistant') {\n const contentParts = content\n .filter((part: AISDKContentPart) => part?.type !== 'tool-call')\n .map((part: AISDKContentPart) => convertContentPart(part))\n .filter(Boolean);\n\n const toolCallParts = content.filter((part: AISDKContentPart) => part?.type === 'tool-call');\n\n const result: OpenAIMessage = {\n role,\n content: contentParts.length > 0 ? (contentParts as string[]).join('\\n') : '',\n ...rest,\n };\n\n // Add tool_calls array if there are tool calls\n if (toolCallParts.length > 0) {\n result.tool_calls = toolCallParts.map((tc: AISDKContentPart) => {\n const toolCall = tc as AISDKToolCallPart;\n const toolCallId = toolCall.toolCallId;\n const toolName = toolCall.toolName;\n // Support both v4 'args' and v5 'input'\n const args = toolCall.args ?? toolCall.input;\n\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else if (args !== undefined && args !== null) {\n argsString = JSON.stringify(args);\n } else {\n argsString = '{}';\n }\n\n return {\n id: toolCallId,\n type: 'function' as const,\n function: {\n name: toolName,\n arguments: argsString,\n },\n };\n });\n }\n\n return result;\n }\n\n // For tool messages, convert to OpenAI tool message format\n if (role === 'tool') {\n const toolResult = content.find((part): part is AISDKToolResultPart => part?.type === 'tool-result');\n if (toolResult) {\n // Support both v4 'result' and v5 'output' fields\n const resultData = toolResult.output ?? toolResult.result;\n const resultContent = serializeToolResult(resultData);\n\n return {\n role: 'tool',\n content: resultContent,\n tool_call_id: toolResult.toolCallId,\n } as OpenAIMessage;\n }\n }\n }\n\n return message;\n}\n","import type { UsageStats } from '@mastra/core/observability';\n\n/**\n * BraintrustUsageMetrics\n *\n * Canonical metric keys expected by Braintrust for LLM usage accounting.\n */\nexport interface BraintrustUsageMetrics {\n prompt_tokens?: number;\n completion_tokens?: number;\n tokens?: number;\n completion_reasoning_tokens?: number;\n prompt_cached_tokens?: number;\n prompt_cache_creation_tokens?: number;\n}\n\n/**\n * Formats UsageStats to Braintrust's expected metric format.\n */\nexport function formatUsageMetrics(usage?: UsageStats): BraintrustUsageMetrics {\n const metrics: BraintrustUsageMetrics = {};\n\n if (usage?.inputTokens !== undefined) {\n metrics.prompt_tokens = usage.inputTokens;\n }\n\n if (usage?.outputTokens !== undefined) {\n metrics.completion_tokens = usage.outputTokens;\n }\n\n // Compute total if we have both\n if (metrics.prompt_tokens !== undefined && metrics.completion_tokens !== undefined) {\n metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;\n }\n\n if (usage?.outputDetails?.reasoning !== undefined) {\n metrics.completion_reasoning_tokens = usage.outputDetails.reasoning;\n }\n\n if (usage?.inputDetails?.cacheRead !== undefined) {\n metrics.prompt_cached_tokens = usage.inputDetails.cacheRead;\n }\n\n if (usage?.inputDetails?.cacheWrite !== undefined) {\n metrics.prompt_cache_creation_tokens = usage.inputDetails.cacheWrite;\n }\n\n return metrics;\n}\n","/**\n * Thread view reconstruction for Braintrust.\n *\n * Reconstructs LLM output in OpenAI Chat Completion format by examining\n * child MODEL_STEP and TOOL_CALL spans. This enables Braintrust's Thread\n * view to properly display the full conversation flow including tool calls.\n *\n * See THREAD_VIEW_RECONSTRUCTION.md for details.\n */\n\nimport { removeNullish } from './formatter';\nimport type { OpenAIMessage } from './formatter';\n\n// ==============================================================================\n// Thread view reconstruction types\n// ==============================================================================\n\n/**\n * Tool call data accumulated from MODEL_STEP and TOOL_CALL spans\n */\nexport interface ThreadToolCall {\n toolCallId: string;\n toolName: string;\n args: unknown;\n result?: unknown; // filled in when TOOL_CALL ends\n startTime?: Date; // from TOOL_CALL span, for ordering multiple tool calls within a step\n}\n\n/**\n * Step data accumulated from MODEL_STEP spans for Thread view reconstruction\n */\nexport interface ThreadStepData {\n stepSpanId: string;\n stepIndex: number; // for ordering steps correctly\n text?: string;\n toolCalls?: ThreadToolCall[];\n}\n\n/**\n * Accumulated data for reconstructing Braintrust Thread view.\n * Populated for MODEL_GENERATION spans as child MODEL_STEP and TOOL_CALL spans complete.\n */\nexport type ThreadData = ThreadStepData[];\n\n/**\n * Tool result data stored when TOOL_CALL spans end (before MODEL_STEP ends)\n */\nexport interface PendingToolResult {\n result: unknown;\n startTime: Date;\n}\n\n// ==============================================================================\n// Thread view reconstruction\n// ==============================================================================\n\n/**\n * Reconstruct the Thread view output from accumulated threadData.\n * Converts to OpenAI Chat Completion message format.\n */\nexport function reconstructThreadOutput(threadData: ThreadData, originalOutput: unknown): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n\n // Sort steps by stepIndex\n const sortedSteps = [...threadData].sort((a, b) => a.stepIndex - b.stepIndex);\n\n for (const step of sortedSteps) {\n // Sort tool calls by startTime within each step\n const sortedToolCalls = step.toolCalls\n ? [...step.toolCalls].sort((a, b) => {\n if (!a.startTime || !b.startTime) return 0;\n return a.startTime.getTime() - b.startTime.getTime();\n })\n : [];\n\n if (sortedToolCalls.length > 0) {\n // Add assistant message with tool_calls\n messages.push({\n role: 'assistant',\n content: step.text || '',\n tool_calls: sortedToolCalls.map(tc => {\n // Clean null/undefined values from args before stringifying\n const cleanArgs =\n tc.args && typeof tc.args === 'object' && !Array.isArray(tc.args)\n ? removeNullish(tc.args as Record<string, unknown>)\n : tc.args;\n return {\n id: tc.toolCallId,\n type: 'function' as const,\n function: {\n name: tc.toolName,\n arguments: typeof cleanArgs === 'string' ? cleanArgs : JSON.stringify(cleanArgs),\n },\n };\n }),\n });\n\n // Add tool messages for each result\n for (const tc of sortedToolCalls) {\n if (tc.result !== undefined) {\n messages.push({\n role: 'tool',\n content: typeof tc.result === 'string' ? tc.result : JSON.stringify(tc.result),\n tool_call_id: tc.toolCallId,\n });\n }\n }\n } else if (step.text) {\n // Step with text only (final response)\n messages.push({\n role: 'assistant',\n content: step.text,\n });\n }\n }\n\n // If we have messages and the last one is a tool message,\n // add the final assistant text from original output\n if (messages.length > 0) {\n const lastMessage = messages[messages.length - 1]!;\n const originalText = (originalOutput as { text?: string })?.text;\n\n // If the last message is a tool response and we have final text, add it\n if (originalText && lastMessage.role === 'tool') {\n messages.push({\n role: 'assistant',\n content: originalText,\n });\n }\n }\n\n return messages;\n}\n","/**\n * Braintrust Exporter for Mastra Observability\n *\n * This exporter sends observability data to Braintrust.\n * Root spans become top-level Braintrust spans (no trace wrapper).\n * Events are handled as zero-duration spans with matching start/end times.\n */\n\nimport type { AnyExportedSpan, ModelGenerationAttributes, ScoreEvent, SpanErrorInfo } from '@mastra/core/observability';\nimport { SpanType } from '@mastra/core/observability';\nimport { omitKeys } from '@mastra/core/utils';\nimport { TrackingExporter } from '@mastra/observability';\nimport type { TraceData, TrackingExporterConfig } from '@mastra/observability';\nimport { initLogger, currentSpan } from 'braintrust';\nimport type { Span, Logger } from 'braintrust';\nimport { removeNullish, convertAISDKMessage, serializeToolResult } from './formatter';\nimport type { OpenAIMessage } from './formatter';\nimport { formatUsageMetrics } from './metrics';\nimport { reconstructThreadOutput } from './thread-reconstruction';\nimport type { ThreadData, ThreadStepData, PendingToolResult } from './thread-reconstruction';\n\n/**\n * Extended Braintrust span data that includes span type and thread reconstruction data\n */\ninterface BraintrustSpanData {\n span: Span;\n spanType: SpanType;\n threadData?: ThreadData; // only populated for MODEL_GENERATION spans\n // Tool results stored when TOOL_CALL ends (may arrive before MODEL_STEP ends)\n pendingToolResults?: Map<string, PendingToolResult>; // keyed by toolCallId\n}\n\nexport interface BraintrustExporterConfig extends TrackingExporterConfig {\n /**\n * Optional Braintrust logger instance.\n * When provided, enables integration with Braintrust contexts such as:\n * - Evals: Agent traces nest inside eval task spans\n * - logger.traced(): Agent traces nest inside traced spans\n * - Parent spans: Auto-detects and attaches to external Braintrust spans\n */\n braintrustLogger?: Logger<true>;\n\n /**\n * Optional resolver for the active Braintrust span.\n *\n * Pass Braintrust's `currentSpan` from the same package instance that creates\n * `Eval()` or `logger.traced()` spans when your app and Mastra may resolve\n * different copies of the `braintrust` package.\n */\n currentSpan?: () => Span | undefined;\n\n /** Braintrust API key. Required if logger is not provided. */\n apiKey?: string;\n /** Optional custom endpoint */\n endpoint?: string;\n /** Braintrust project name (default: 'mastra-tracing') */\n projectName?: string;\n /** Support tuning parameters */\n tuningParameters?: Record<string, any>;\n}\n\ntype BraintrustRoot = Logger<true> | Span;\ntype BraintrustSpan = BraintrustSpanData;\ntype BraintrustEvent = Span;\ntype BraintrustMetadata = unknown;\ntype BraintrustTraceData = TraceData<BraintrustRoot, BraintrustSpan, BraintrustEvent, BraintrustMetadata>;\n\n// Default span type for all spans\nconst DEFAULT_SPAN_TYPE = 'task';\n\n// Exceptions to the default mapping\nconst SPAN_TYPE_EXCEPTIONS: Partial<Record<SpanType, string>> = {\n [SpanType.MODEL_GENERATION]: 'llm',\n [SpanType.TOOL_CALL]: 'tool',\n [SpanType.MCP_TOOL_CALL]: 'tool',\n [SpanType.PROVIDER_TOOL_CALL]: 'tool',\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: 'function',\n [SpanType.WORKFLOW_WAIT_EVENT]: 'function',\n};\n\n// Mapping function - returns valid Braintrust span types\nfunction mapSpanType(spanType: SpanType): 'llm' | 'score' | 'function' | 'eval' | 'task' | 'tool' {\n return (SPAN_TYPE_EXCEPTIONS[spanType] as any) ?? DEFAULT_SPAN_TYPE;\n}\n\nexport class BraintrustExporter extends TrackingExporter<\n BraintrustRoot,\n BraintrustSpan,\n BraintrustEvent,\n BraintrustMetadata,\n BraintrustExporterConfig\n> {\n name = 'braintrust';\n\n // Flags and logger for context-aware mode\n #useProvidedLogger: boolean;\n #providedLogger?: Logger<true>;\n #localLogger?: Logger<true>;\n\n constructor(config: BraintrustExporterConfig = {}) {\n // Resolve env vars BEFORE calling super (config is readonly in base class)\n const resolvedApiKey = config.apiKey ?? process.env.BRAINTRUST_API_KEY;\n const resolvedEndpoint = config.endpoint ?? process.env.BRAINTRUST_ENDPOINT;\n\n super({\n ...config,\n apiKey: resolvedApiKey,\n endpoint: resolvedEndpoint,\n });\n\n this.#useProvidedLogger = !!config.braintrustLogger;\n\n if (this.#useProvidedLogger) {\n // Use provided logger - enables Braintrust context integration\n this.#providedLogger = config.braintrustLogger;\n } else {\n // Validate apiKey for creating loggers per trace\n if (!this.config.apiKey) {\n this.setDisabled(\n `Missing required API key. Set BRAINTRUST_API_KEY environment variable or pass apiKey in config.`,\n );\n return;\n }\n // lazy create logger on first rootSpan\n this.#localLogger = undefined;\n }\n }\n\n private async getLocalLogger(): Promise<Logger<true> | undefined> {\n if (this.#localLogger) {\n return this.#localLogger;\n }\n try {\n const logger = await initLogger({\n projectName: this.config.projectName ?? 'mastra-tracing',\n apiKey: this.config.apiKey,\n appUrl: this.config.endpoint,\n ...this.config.tuningParameters,\n });\n this.#localLogger = logger;\n return logger;\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to initialize logger', { error: err });\n this.setDisabled('Failed to initialize Braintrust logger');\n }\n }\n\n async onScoreEvent(event: ScoreEvent): Promise<void> {\n if (this.isDisabled) return;\n\n const { score } = event;\n const rowId = score.spanId ?? score.traceId;\n if (!rowId) {\n this.logger.debug('Braintrust exporter: skipping score with no spanId or traceId', {\n scorerId: score.scorerId,\n });\n return;\n }\n\n const logger = this.#useProvidedLogger ? this.#providedLogger : await this.getLocalLogger();\n if (!logger) return;\n\n const name = score.scorerName ?? score.scorerId;\n\n try {\n logger.logFeedback({\n id: rowId,\n scores: { [name]: score.score },\n ...(score.reason ? { comment: score.reason } : {}),\n metadata: {\n scorerId: score.scorerId,\n ...(score.scoreSource ? { scoreSource: score.scoreSource } : {}),\n ...(score.metadata ?? {}),\n },\n source: 'external',\n });\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to submit score', {\n error: err,\n traceId: score.traceId,\n spanId: score.spanId,\n scorerId: score.scorerId,\n });\n }\n }\n\n private startSpan(args: { parent: Span | Logger<true>; span: AnyExportedSpan }): BraintrustSpanData {\n const { parent, span } = args;\n const payload = this.buildSpanPayload(span);\n\n // Braintrust's startSpan() accepts data properties via the `event` parameter\n // which maps to StartSpanEventArgs (ExperimentLogPartialArgs & Partial<IdField>)\n // This includes: input, output, metadata, metrics, tags, scores, error, etc.\n const braintrustSpan = parent.startSpan({\n spanId: span.id,\n name: span.name,\n type: mapSpanType(span.type),\n startTime: span.startTime.getTime() / 1000,\n event: {\n id: span.id, // Use Mastra span ID as Braintrust row ID for logFeedback() compatibility\n ...payload,\n },\n });\n\n // Create BraintrustSpanData with span type for tree walking\n // Initialize threadData and pendingToolResults for MODEL_GENERATION spans (used for Thread view reconstruction)\n const isModelGeneration = span.type === SpanType.MODEL_GENERATION;\n return {\n span: braintrustSpan,\n spanType: span.type,\n threadData: isModelGeneration ? [] : undefined,\n pendingToolResults: isModelGeneration ? new Map() : undefined,\n };\n }\n\n protected override async _buildRoot(_args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustRoot | undefined> {\n if (this.#useProvidedLogger) {\n // Try to find a Braintrust span to attach to:\n // 1. Auto-detect from Braintrust's current span (logger.traced(), Eval(), etc.)\n // 2. Fall back to the configured logger\n let externalSpan: Span | undefined;\n try {\n externalSpan = this.config.currentSpan?.();\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to resolve configured currentSpan', { error: err });\n }\n externalSpan ??= currentSpan();\n\n // Check if it's a valid span (not the NOOP_SPAN)\n if (externalSpan && externalSpan.id) {\n // External span detected - attach Mastra traces to it\n return externalSpan;\n } else {\n // No external span - use provided logger\n return this.#providedLogger!;\n }\n } else {\n // Use the local logger\n return this.getLocalLogger();\n }\n }\n\n protected override async _buildSpan(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustSpanData | undefined> {\n const { span, traceData } = args;\n\n if (span.isRootSpan) {\n const root = traceData.getRoot();\n if (root) {\n return this.startSpan({ parent: root, span });\n }\n } else {\n const parent = traceData.getParent(args);\n if (parent) {\n // Parent could be BraintrustSpanData (has .span) or BraintrustRoot (Logger/Span, no .span)\n const parentSpan = 'span' in parent ? parent.span : parent;\n return this.startSpan({ parent: parentSpan, span });\n }\n }\n }\n\n protected override async _buildEvent(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<Span | undefined> {\n const spanData = await this._buildSpan(args);\n\n if (!spanData) {\n // parent doesn't exist and not creating rootSpan, return early data\n return;\n }\n\n spanData.span.end({ endTime: args.span.startTime.getTime() / 1000 });\n return spanData.span;\n }\n\n protected override async _updateSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n spanData.span.log(this.buildSpanPayload(span, false));\n }\n\n protected override async _finishSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n\n // Handle thread data accumulation for MODEL_STEP and TOOL_CALL spans\n if (span.type === SpanType.MODEL_STEP) {\n this.accumulateModelStepData(span, traceData);\n } else if (span.type === SpanType.TOOL_CALL) {\n this.accumulateToolCallResult(span, traceData);\n }\n\n // Build payload - for MODEL_GENERATION, may reconstruct output from threadData\n const payload =\n span.type === SpanType.MODEL_GENERATION\n ? this.buildModelGenerationPayload(span, spanData)\n : this.buildSpanPayload(span, false);\n\n spanData.span.log(payload);\n\n if (span.endTime) {\n spanData.span.end({ endTime: span.endTime.getTime() / 1000 });\n } else {\n spanData.span.end();\n }\n }\n\n protected override async _abortSpan(args: { span: BraintrustSpan; reason: SpanErrorInfo }): Promise<void> {\n const { span: spanData, reason } = args;\n spanData.span.log({\n error: reason.message,\n metadata: { errorDetails: reason },\n });\n spanData.span.end();\n }\n\n // ==============================================================================\n // Thread view reconstruction helpers\n // ==============================================================================\n\n /**\n * Walk up the tree to find the MODEL_GENERATION ancestor span.\n * Returns the BraintrustSpanData if found, undefined otherwise.\n */\n private findModelGenerationAncestor(spanId: string, traceData: BraintrustTraceData): BraintrustSpanData | undefined {\n let currentId: string | undefined = spanId;\n\n while (currentId) {\n const parentId = traceData.getParentId({ spanId: currentId });\n if (!parentId) return undefined;\n\n const parentSpanData = traceData.getSpan({ spanId: parentId });\n if (parentSpanData?.spanType === SpanType.MODEL_GENERATION) {\n return parentSpanData;\n }\n currentId = parentId;\n }\n\n return undefined;\n }\n\n /**\n * Accumulate MODEL_STEP data to the parent MODEL_GENERATION's threadData.\n * Called when a MODEL_STEP span ends.\n */\n private accumulateModelStepData(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.threadData) {\n return;\n }\n\n // Extract step data from MODEL_STEP output and attributes\n const output = span.output as\n | { text?: string; toolCalls?: Array<{ toolCallId: string; toolName: string; args: unknown }> }\n | undefined;\n const attributes = span.attributes as { stepIndex?: number } | undefined;\n\n const stepData: ThreadStepData = {\n stepSpanId: span.id,\n stepIndex: attributes?.stepIndex ?? 0,\n text: output?.text,\n toolCalls: output?.toolCalls?.map(tc => ({\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n args: tc.args,\n })),\n };\n\n modelGenSpanData.threadData.push(stepData);\n }\n\n /**\n * Store TOOL_CALL result in parent MODEL_GENERATION's pendingToolResults.\n * Called when a TOOL_CALL span ends.\n * Results are merged into threadData when MODEL_GENERATION ends.\n */\n private accumulateToolCallResult(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.pendingToolResults) {\n return;\n }\n\n // Extract tool call ID from TOOL_CALL span input\n const input = span.input as { toolCallId?: string } | undefined;\n const toolCallId = input?.toolCallId;\n if (!toolCallId) {\n return;\n }\n\n // Store the result for later merging\n modelGenSpanData.pendingToolResults.set(toolCallId, {\n result: span.output,\n startTime: span.startTime,\n });\n }\n\n /**\n * Build the payload for MODEL_GENERATION span, reconstructing output from threadData if available.\n */\n private buildModelGenerationPayload(span: AnyExportedSpan, spanData: BraintrustSpanData): Record<string, any> {\n const basePayload = this.buildSpanPayload(span, false);\n\n // Check if we have threadData with tool calls to reconstruct\n const threadData = spanData.threadData;\n if (!threadData || threadData.length === 0) {\n return basePayload;\n }\n\n // Merge pending tool results into threadData\n if (spanData.pendingToolResults && spanData.pendingToolResults.size > 0) {\n for (const step of threadData) {\n if (step.toolCalls) {\n for (const toolCall of step.toolCalls) {\n const pendingResult = spanData.pendingToolResults.get(toolCall.toolCallId);\n if (pendingResult) {\n toolCall.result = pendingResult.result;\n toolCall.startTime = pendingResult.startTime;\n }\n }\n }\n }\n }\n\n // Check if any step has tool calls\n const hasToolCalls = threadData.some(step => step.toolCalls && step.toolCalls.length > 0);\n if (!hasToolCalls) {\n return basePayload;\n }\n\n // Reconstruct output as OpenAI messages\n const reconstructedOutput = reconstructThreadOutput(threadData, span.output);\n return {\n ...basePayload,\n output: reconstructedOutput,\n };\n }\n\n /**\n * Transforms MODEL_GENERATION input to Braintrust Thread view format.\n * Converts AI SDK messages (v4/v5) to OpenAI Chat Completion format, which Braintrust requires\n * for proper rendering of threads (fixes #11023).\n */\n private transformInput(input: unknown, spanType: SpanType): unknown {\n if (spanType === SpanType.MODEL_GENERATION) {\n // If input is already an array of messages, convert AI SDK format to OpenAI format\n if (Array.isArray(input)) {\n return input.map((msg: unknown) => convertAISDKMessage(msg));\n }\n\n // If input has a messages array\n if (\n input &&\n typeof input === 'object' &&\n 'messages' in input &&\n Array.isArray((input as { messages: unknown[] }).messages)\n ) {\n return (input as { messages: unknown[] }).messages.map((msg: unknown) => convertAISDKMessage(msg));\n }\n }\n\n return input;\n }\n\n /**\n * Transforms MODEL_GENERATION output to Braintrust Thread view format.\n */\n private transformOutput(output: any, spanType: SpanType): any {\n if (spanType === SpanType.MODEL_GENERATION) {\n if (!output || typeof output !== 'object') {\n return output;\n }\n const { text, ...rest } = output;\n // Remove null/undefined values from rest to keep Thread view clean\n return { role: 'assistant', content: text, ...removeNullish(rest) };\n }\n\n return output;\n }\n\n private isToolSpan(span: AnyExportedSpan): boolean {\n return (\n span.type === SpanType.TOOL_CALL ||\n span.type === SpanType.MCP_TOOL_CALL ||\n span.type === SpanType.PROVIDER_TOOL_CALL\n );\n }\n\n private getToolName(span: AnyExportedSpan): string {\n if (span.entityName) {\n return span.entityName;\n }\n const match = /'([^']+)'/.exec(span.name);\n return match?.[1] ?? span.name;\n }\n\n private getToolCallId(span: AnyExportedSpan): string {\n const attrs = span.attributes as { toolCallId?: string } | undefined;\n return attrs?.toolCallId ?? (span.input as { toolCallId?: string } | undefined)?.toolCallId ?? span.id;\n }\n\n private toToolCallInput(span: AnyExportedSpan): OpenAIMessage[] {\n const args = span.input;\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else {\n try {\n argsString = JSON.stringify(args ?? {});\n } catch {\n argsString = '[unserializable result]';\n }\n }\n return [\n {\n role: 'assistant',\n content: '',\n tool_calls: [\n {\n id: this.getToolCallId(span),\n type: 'function',\n function: {\n name: this.getToolName(span),\n arguments: argsString,\n },\n },\n ],\n },\n ];\n }\n\n private toToolCallOutput(span: AnyExportedSpan): OpenAIMessage {\n return {\n role: 'tool',\n content: serializeToolResult(span.output),\n tool_call_id: this.getToolCallId(span),\n };\n }\n\n private buildSpanPayload(span: AnyExportedSpan, isCreate = true): Record<string, any> {\n const payload: Record<string, any> = {};\n\n const isToolType = this.isToolSpan(span);\n\n if (span.input !== undefined) {\n payload.input = isToolType ? this.toToolCallInput(span) : this.transformInput(span.input, span.type);\n }\n\n if (span.output !== undefined) {\n payload.output = isToolType ? this.toToolCallOutput(span) : this.transformOutput(span.output, span.type);\n }\n\n if (isCreate && span.isRootSpan && span.tags?.length) {\n payload.tags = span.tags;\n }\n\n // Initialize metrics and metadata objects\n payload.metrics = {};\n // Spread span.metadata first, then set spanType to prevent accidental override\n payload.metadata = {\n ...span.metadata,\n spanType: span.type,\n };\n\n if (isCreate) {\n payload.metadata['mastra-trace-id'] = span.traceId;\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 // Model goes to metadata\n if (modelAttr.model !== undefined) {\n payload.metadata.model = modelAttr.model;\n }\n\n // Provider goes to metadata (if provided by attributes)\n if (modelAttr.provider !== undefined) {\n payload.metadata.provider = modelAttr.provider;\n }\n\n // Prefer resolved model ID (e.g. \"claude-sonnet-4-5-20250929\") over\n // gateway aliases (e.g. \"claude-sonnet-4.5\") for accurate cost estimation\n if (modelAttr.responseModel !== undefined) {\n payload.metadata.model = modelAttr.responseModel;\n }\n\n // Usage/token info goes to metrics\n payload.metrics = formatUsageMetrics(modelAttr.usage);\n\n // Time to first token (TTFT) for streaming responses\n // Braintrust expects TTFT in seconds (not milliseconds)\n if (modelAttr.completionStartTime) {\n payload.metrics.time_to_first_token =\n (modelAttr.completionStartTime.getTime() - span.startTime.getTime()) / 1000;\n }\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, [\n 'model',\n 'responseModel',\n 'usage',\n 'parameters',\n 'completionStartTime',\n ]);\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 // Clean up empty metrics object\n if (Object.keys(payload.metrics).length === 0) {\n delete payload.metrics;\n }\n\n // Remove null/undefined values from metadata to keep Braintrust UI clean\n payload.metadata = removeNullish(payload.metadata);\n\n return payload;\n }\n}\n"]}
{"version":3,"sources":["../src/formatter.ts","../src/metrics.ts","../src/thread-reconstruction.ts","../src/tracing.ts"],"names":["SpanType","TrackingExporter","initLogger","currentSpan","omitKeys"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Message format conversion utilities for Braintrust.\n *\n * Converts AI SDK message format (v4/v5) to OpenAI Chat Completion format,\n * which Braintrust requires for proper rendering of threads.\n */\n\n// ==============================================================================\n// Utility functions\n// ==============================================================================\n\n/**\n * Remove null and undefined values from an object (shallow)\n */\nexport function removeNullish<T extends Record<string, unknown>>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null)) as Partial<T>;\n}\n\n// ==============================================================================\n// Type definitions for AI SDK message format conversion to OpenAI format\n// ==============================================================================\n\n/**\n * AI SDK content part types (both v4 and v5)\n */\ninterface AISDKTextPart {\n type: 'text';\n text: string;\n}\n\ninterface AISDKImagePart {\n type: 'image';\n image?: string | Uint8Array | URL;\n mimeType?: string;\n}\n\ninterface AISDKFilePart {\n type: 'file';\n data?: string | Uint8Array | URL;\n filename?: string;\n name?: string;\n mimeType?: string;\n}\n\ninterface AISDKReasoningPart {\n type: 'reasoning';\n text?: string;\n}\n\ninterface AISDKToolCallPart {\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n args?: unknown; // AI SDK v4\n input?: unknown; // AI SDK v5\n}\n\ninterface AISDKToolResultPart {\n type: 'tool-result';\n toolCallId: string;\n result?: unknown; // AI SDK v4\n output?: unknown; // AI SDK v5\n}\n\ntype AISDKContentPart =\n | AISDKTextPart\n | AISDKImagePart\n | AISDKFilePart\n | AISDKReasoningPart\n | AISDKToolCallPart\n | AISDKToolResultPart\n | { type: string; [key: string]: unknown }; // Catch-all for unknown types\n\n/**\n * AI SDK message format (input format for conversion)\n */\ninterface AISDKMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string | AISDKContentPart[];\n [key: string]: unknown; // Allow additional properties\n}\n\n/**\n * OpenAI Chat Completion tool call format\n */\nexport interface OpenAIToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * OpenAI Chat Completion message format (output format)\n */\nexport interface OpenAIMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string;\n tool_calls?: OpenAIToolCall[];\n tool_call_id?: string;\n [key: string]: unknown; // Allow additional properties\n}\n\n// ==============================================================================\n// Message conversion functions\n// ==============================================================================\n\n/**\n * Converts a content part to a string representation.\n * Handles text, image, file, reasoning, and other content types.\n */\nfunction convertContentPart(part: AISDKContentPart | null | undefined): string | null {\n if (!part || typeof part !== 'object') {\n return null;\n }\n\n switch (part.type) {\n case 'text':\n return (part as AISDKTextPart).text || null;\n\n case 'image':\n // Represent image content with a placeholder\n return '[image]';\n\n case 'file': {\n // Represent file content with filename if available\n const filePart = part as AISDKFilePart;\n if (filePart.filename || filePart.name) {\n return `[file: ${filePart.filename || filePart.name}]`;\n }\n return '[file]';\n }\n\n case 'reasoning': {\n // Represent reasoning/thinking content\n const reasoningPart = part as AISDKReasoningPart;\n if (typeof reasoningPart.text === 'string' && reasoningPart.text.length > 0) {\n return `[reasoning: ${reasoningPart.text.substring(0, 100)}${reasoningPart.text.length > 100 ? '...' : ''}]`;\n }\n return '[reasoning]';\n }\n\n case 'tool-call':\n // Tool calls are handled separately in assistant messages\n return null;\n\n case 'tool-result':\n // Tool results are handled separately in tool messages\n return null;\n\n default: {\n // For unknown types, try to extract any text-like content\n const unknownPart = part as { type?: string; text?: string; content?: string };\n if (typeof unknownPart.text === 'string') {\n return unknownPart.text;\n }\n if (typeof unknownPart.content === 'string') {\n return unknownPart.content;\n }\n // Represent unknown content type\n return `[${unknownPart.type || 'unknown'}]`;\n }\n }\n}\n\n/**\n * Serializes tool result data to a string for OpenAI format.\n */\nexport function serializeToolResult(resultData: unknown): string {\n if (typeof resultData === 'string') {\n return resultData;\n }\n if (resultData && typeof resultData === 'object' && 'value' in resultData) {\n const valueData = (resultData as { value: unknown }).value;\n return typeof valueData === 'string' ? valueData : JSON.stringify(valueData);\n }\n if (resultData === undefined || resultData === null) {\n return '';\n }\n try {\n return JSON.stringify(resultData);\n } catch {\n return '[unserializable result]';\n }\n}\n\n/**\n * Converts AI SDK message format to OpenAI Chat Completion format for Braintrust.\n *\n * Supports both AI SDK v4 and v5 formats:\n * - v4 uses 'args' for tool calls and 'result' for tool results\n * - v5 uses 'input' for tool calls and 'output' for tool results\n *\n * AI SDK format:\n * { role: \"user\", content: [{ type: \"text\", text: \"hello\" }] }\n * { role: \"assistant\", content: [{ type: \"text\", text: \"...\" }, { type: \"tool-call\", toolCallId: \"...\", toolName: \"...\", args: {...} }] }\n * { role: \"tool\", content: [{ type: \"tool-result\", toolCallId: \"...\", result: {...} }] }\n *\n * OpenAI format (what Braintrust expects):\n * { role: \"user\", content: \"hello\" }\n * { role: \"assistant\", content: \"...\", tool_calls: [{ id: \"...\", type: \"function\", function: { name: \"...\", arguments: \"...\" } }] }\n * { role: \"tool\", content: \"result\", tool_call_id: \"...\" }\n */\nexport function convertAISDKMessage(message: AISDKMessage | OpenAIMessage | unknown): OpenAIMessage | unknown {\n if (!message || typeof message !== 'object') {\n return message;\n }\n\n const { role, content, ...rest } = message as AISDKMessage;\n\n // If content is already a string, return as-is (already in OpenAI format)\n if (typeof content === 'string') {\n return message;\n }\n\n // If content is an array (AI SDK format), convert based on role\n if (Array.isArray(content)) {\n // Handle empty content arrays\n if (content.length === 0) {\n return { role, content: '', ...rest };\n }\n\n // For user/system messages, extract text and represent non-text content\n if (role === 'user' || role === 'system') {\n const contentParts = content.map((part: AISDKContentPart) => convertContentPart(part)).filter(Boolean);\n\n return {\n role,\n content: contentParts.length > 0 ? contentParts.join('\\n') : '',\n ...rest,\n };\n }\n\n // For assistant messages, extract text, non-text content, AND tool calls\n if (role === 'assistant') {\n const contentParts = content\n .filter((part: AISDKContentPart) => part?.type !== 'tool-call')\n .map((part: AISDKContentPart) => convertContentPart(part))\n .filter(Boolean);\n\n const toolCallParts = content.filter((part: AISDKContentPart) => part?.type === 'tool-call');\n\n const result: OpenAIMessage = {\n role,\n content: contentParts.length > 0 ? (contentParts as string[]).join('\\n') : '',\n ...rest,\n };\n\n // Add tool_calls array if there are tool calls\n if (toolCallParts.length > 0) {\n result.tool_calls = toolCallParts.map((tc: AISDKContentPart) => {\n const toolCall = tc as AISDKToolCallPart;\n const toolCallId = toolCall.toolCallId;\n const toolName = toolCall.toolName;\n // Support both v4 'args' and v5 'input'\n const args = toolCall.args ?? toolCall.input;\n\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else if (args !== undefined && args !== null) {\n argsString = JSON.stringify(args);\n } else {\n argsString = '{}';\n }\n\n return {\n id: toolCallId,\n type: 'function' as const,\n function: {\n name: toolName,\n arguments: argsString,\n },\n };\n });\n }\n\n return result;\n }\n\n // For tool messages, convert to OpenAI tool message format\n if (role === 'tool') {\n const toolResult = content.find((part): part is AISDKToolResultPart => part?.type === 'tool-result');\n if (toolResult) {\n // Support both v4 'result' and v5 'output' fields\n const resultData = toolResult.output ?? toolResult.result;\n const resultContent = serializeToolResult(resultData);\n\n return {\n role: 'tool',\n content: resultContent,\n tool_call_id: toolResult.toolCallId,\n } as OpenAIMessage;\n }\n }\n }\n\n return message;\n}\n","import type { UsageStats } from '@mastra/core/observability';\n\n/**\n * BraintrustUsageMetrics\n *\n * Canonical metric keys expected by Braintrust for LLM usage accounting.\n */\nexport interface BraintrustUsageMetrics {\n prompt_tokens?: number;\n completion_tokens?: number;\n tokens?: number;\n completion_reasoning_tokens?: number;\n prompt_cached_tokens?: number;\n prompt_cache_creation_tokens?: number;\n}\n\n/**\n * Formats UsageStats to Braintrust's expected metric format.\n */\nexport function formatUsageMetrics(usage?: UsageStats): BraintrustUsageMetrics {\n const metrics: BraintrustUsageMetrics = {};\n\n if (usage?.inputTokens !== undefined) {\n metrics.prompt_tokens = usage.inputTokens;\n }\n\n if (usage?.outputTokens !== undefined) {\n metrics.completion_tokens = usage.outputTokens;\n }\n\n // Compute total if we have both\n if (metrics.prompt_tokens !== undefined && metrics.completion_tokens !== undefined) {\n metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;\n }\n\n if (usage?.outputDetails?.reasoning !== undefined) {\n metrics.completion_reasoning_tokens = usage.outputDetails.reasoning;\n }\n\n if (usage?.inputDetails?.cacheRead !== undefined) {\n metrics.prompt_cached_tokens = usage.inputDetails.cacheRead;\n }\n\n if (usage?.inputDetails?.cacheWrite !== undefined) {\n metrics.prompt_cache_creation_tokens = usage.inputDetails.cacheWrite;\n }\n\n return metrics;\n}\n","/**\n * Thread view reconstruction for Braintrust.\n *\n * Reconstructs LLM output in OpenAI Chat Completion format by examining\n * child MODEL_STEP and TOOL_CALL spans. This enables Braintrust's Thread\n * view to properly display the full conversation flow including tool calls.\n *\n * See THREAD_VIEW_RECONSTRUCTION.md for details.\n */\n\nimport { removeNullish } from './formatter';\nimport type { OpenAIMessage } from './formatter';\n\n// ==============================================================================\n// Thread view reconstruction types\n// ==============================================================================\n\n/**\n * Tool call data accumulated from MODEL_STEP and TOOL_CALL spans\n */\nexport interface ThreadToolCall {\n toolCallId: string;\n toolName: string;\n args: unknown;\n result?: unknown; // filled in when TOOL_CALL ends\n startTime?: Date; // from TOOL_CALL span, for ordering multiple tool calls within a step\n}\n\n/**\n * Step data accumulated from MODEL_STEP spans for Thread view reconstruction\n */\nexport interface ThreadStepData {\n stepSpanId: string;\n stepIndex: number; // for ordering steps correctly\n text?: string;\n toolCalls?: ThreadToolCall[];\n}\n\n/**\n * Accumulated data for reconstructing Braintrust Thread view.\n * Populated for MODEL_GENERATION spans as child MODEL_STEP and TOOL_CALL spans complete.\n */\nexport type ThreadData = ThreadStepData[];\n\n/**\n * Tool result data stored when TOOL_CALL spans end (before MODEL_STEP ends)\n */\nexport interface PendingToolResult {\n result: unknown;\n startTime: Date;\n}\n\n// ==============================================================================\n// Thread view reconstruction\n// ==============================================================================\n\n/**\n * Reconstruct the Thread view output from accumulated threadData.\n * Converts to OpenAI Chat Completion message format.\n */\nexport function reconstructThreadOutput(threadData: ThreadData, originalOutput: unknown): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n\n // Sort steps by stepIndex\n const sortedSteps = [...threadData].sort((a, b) => a.stepIndex - b.stepIndex);\n\n for (const step of sortedSteps) {\n // Sort tool calls by startTime within each step\n const sortedToolCalls = step.toolCalls\n ? [...step.toolCalls].sort((a, b) => {\n if (!a.startTime || !b.startTime) return 0;\n return a.startTime.getTime() - b.startTime.getTime();\n })\n : [];\n\n if (sortedToolCalls.length > 0) {\n // Add assistant message with tool_calls\n messages.push({\n role: 'assistant',\n content: step.text || '',\n tool_calls: sortedToolCalls.map(tc => {\n // Clean null/undefined values from args before stringifying\n const cleanArgs =\n tc.args && typeof tc.args === 'object' && !Array.isArray(tc.args)\n ? removeNullish(tc.args as Record<string, unknown>)\n : tc.args;\n return {\n id: tc.toolCallId,\n type: 'function' as const,\n function: {\n name: tc.toolName,\n arguments: typeof cleanArgs === 'string' ? cleanArgs : JSON.stringify(cleanArgs),\n },\n };\n }),\n });\n\n // Add tool messages for each result\n for (const tc of sortedToolCalls) {\n if (tc.result !== undefined) {\n messages.push({\n role: 'tool',\n content: typeof tc.result === 'string' ? tc.result : JSON.stringify(tc.result),\n tool_call_id: tc.toolCallId,\n });\n }\n }\n } else if (step.text) {\n // Step with text only (final response)\n messages.push({\n role: 'assistant',\n content: step.text,\n });\n }\n }\n\n // If we have messages and the last one is a tool message,\n // add the final assistant text from original output\n if (messages.length > 0) {\n const lastMessage = messages[messages.length - 1]!;\n const originalText = (originalOutput as { text?: string })?.text;\n\n // If the last message is a tool response and we have final text, add it\n if (originalText && lastMessage.role === 'tool') {\n messages.push({\n role: 'assistant',\n content: originalText,\n });\n }\n }\n\n return messages;\n}\n","/**\n * Braintrust Exporter for Mastra Observability\n *\n * This exporter sends observability data to Braintrust.\n * Root spans become top-level Braintrust spans (no trace wrapper).\n * Events are handled as zero-duration spans with matching start/end times.\n */\n\nimport type { AnyExportedSpan, ModelGenerationAttributes, ScoreEvent, SpanErrorInfo } from '@mastra/core/observability';\nimport { SpanType } from '@mastra/core/observability';\nimport { omitKeys } from '@mastra/core/utils';\nimport { TrackingExporter } from '@mastra/observability';\nimport type { TraceData, TrackingExporterConfig } from '@mastra/observability';\nimport { initLogger, currentSpan } from 'braintrust';\nimport { removeNullish, convertAISDKMessage, serializeToolResult } from './formatter';\nimport type { OpenAIMessage } from './formatter';\nimport { formatUsageMetrics } from './metrics';\nimport { reconstructThreadOutput } from './thread-reconstruction';\nimport type { ThreadData, ThreadStepData, PendingToolResult } from './thread-reconstruction';\n\ntype BraintrustSpanType = 'llm' | 'score' | 'function' | 'eval' | 'task' | 'tool';\n\n/**\n * The subset of a Braintrust span used by the exporter.\n *\n * This structural interface lets applications provide spans from a different\n * compatible Braintrust SDK instance without coupling Mastra's public types to\n * a specific SDK version.\n */\nexport interface BraintrustSpan {\n id: string;\n startSpan(args: {\n spanId: string;\n name: string;\n type: BraintrustSpanType;\n startTime: number;\n event: Record<string, any>;\n }): BraintrustSpan;\n log(event: Record<string, any>): void;\n end(args?: { endTime?: number }): number;\n}\n\n/**\n * The subset of a Braintrust logger used by the exporter.\n *\n * Logger instances from compatible Braintrust SDK versions satisfy this\n * interface without sharing the same nominal SDK types as the exporter.\n */\nexport interface BraintrustLogger {\n startSpan(args: {\n spanId: string;\n name: string;\n type: BraintrustSpanType;\n startTime: number;\n event: Record<string, any>;\n }): BraintrustSpan;\n logFeedback(event: {\n id: string;\n scores: Record<string, number>;\n comment?: string;\n metadata?: Record<string, any>;\n source: 'external';\n }): void;\n}\n\n/**\n * Extended Braintrust span data that includes span type and thread reconstruction data\n */\ninterface BraintrustSpanData {\n span: BraintrustSpan;\n spanType: SpanType;\n threadData?: ThreadData; // only populated for MODEL_GENERATION spans\n // Tool results stored when TOOL_CALL ends (may arrive before MODEL_STEP ends)\n pendingToolResults?: Map<string, PendingToolResult>; // keyed by toolCallId\n}\n\nexport interface BraintrustExporterConfig extends TrackingExporterConfig {\n /**\n * Optional Braintrust logger instance.\n * When provided, enables integration with Braintrust contexts such as:\n * - Evals: Agent traces nest inside eval task spans\n * - logger.traced(): Agent traces nest inside traced spans\n * - Parent spans: Auto-detects and attaches to external Braintrust spans\n */\n braintrustLogger?: BraintrustLogger;\n\n /**\n * Optional resolver for the active Braintrust span.\n *\n * Pass Braintrust's `currentSpan` from the same package instance that creates\n * `Eval()` or `logger.traced()` spans when your app and Mastra may resolve\n * different copies of the `braintrust` package.\n */\n currentSpan?: () => BraintrustSpan | undefined;\n\n /** Braintrust API key. Required if logger is not provided. */\n apiKey?: string;\n /** Optional custom endpoint */\n endpoint?: string;\n /** Braintrust project name (default: 'mastra-tracing') */\n projectName?: string;\n /** Support tuning parameters */\n tuningParameters?: Record<string, any>;\n}\n\ntype BraintrustRoot = BraintrustLogger | BraintrustSpan;\ntype BraintrustTrackedSpan = BraintrustSpanData;\ntype BraintrustEvent = BraintrustSpan;\ntype BraintrustMetadata = unknown;\ntype BraintrustTraceData = TraceData<BraintrustRoot, BraintrustTrackedSpan, BraintrustEvent, BraintrustMetadata>;\n\n// Default span type for all spans\nconst DEFAULT_SPAN_TYPE = 'task';\n\n// Exceptions to the default mapping\nconst SPAN_TYPE_EXCEPTIONS: Partial<Record<SpanType, string>> = {\n [SpanType.MODEL_GENERATION]: 'llm',\n [SpanType.TOOL_CALL]: 'tool',\n [SpanType.MCP_TOOL_CALL]: 'tool',\n [SpanType.PROVIDER_TOOL_CALL]: 'tool',\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: 'function',\n [SpanType.WORKFLOW_WAIT_EVENT]: 'function',\n};\n\n// Mapping function - returns valid Braintrust span types\nfunction mapSpanType(spanType: SpanType): 'llm' | 'score' | 'function' | 'eval' | 'task' | 'tool' {\n return (SPAN_TYPE_EXCEPTIONS[spanType] as any) ?? DEFAULT_SPAN_TYPE;\n}\n\nexport class BraintrustExporter extends TrackingExporter<\n BraintrustRoot,\n BraintrustTrackedSpan,\n BraintrustEvent,\n BraintrustMetadata,\n BraintrustExporterConfig\n> {\n name = 'braintrust';\n\n // Flags and logger for context-aware mode\n #useProvidedLogger: boolean;\n #providedLogger?: BraintrustLogger;\n #localLogger?: BraintrustLogger;\n\n constructor(config: BraintrustExporterConfig = {}) {\n // Resolve env vars BEFORE calling super (config is readonly in base class)\n const resolvedApiKey = config.apiKey ?? process.env.BRAINTRUST_API_KEY;\n const resolvedEndpoint = config.endpoint ?? process.env.BRAINTRUST_ENDPOINT;\n\n super({\n ...config,\n apiKey: resolvedApiKey,\n endpoint: resolvedEndpoint,\n });\n\n this.#useProvidedLogger = !!config.braintrustLogger;\n\n if (this.#useProvidedLogger) {\n // Use provided logger - enables Braintrust context integration\n this.#providedLogger = config.braintrustLogger;\n } else {\n // Validate apiKey for creating loggers per trace\n if (!this.config.apiKey) {\n this.setDisabled(\n `Missing required API key. Set BRAINTRUST_API_KEY environment variable or pass apiKey in config.`,\n );\n return;\n }\n // lazy create logger on first rootSpan\n this.#localLogger = undefined;\n }\n }\n\n private async getLocalLogger(): Promise<BraintrustLogger | undefined> {\n if (this.#localLogger) {\n return this.#localLogger;\n }\n try {\n const logger = await initLogger({\n projectName: this.config.projectName ?? 'mastra-tracing',\n apiKey: this.config.apiKey,\n appUrl: this.config.endpoint,\n ...this.config.tuningParameters,\n });\n this.#localLogger = logger;\n return logger;\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to initialize logger', { error: err });\n this.setDisabled('Failed to initialize Braintrust logger');\n }\n }\n\n async onScoreEvent(event: ScoreEvent): Promise<void> {\n if (this.isDisabled) return;\n\n const { score } = event;\n const rowId = score.spanId ?? score.traceId;\n if (!rowId) {\n this.logger.debug('Braintrust exporter: skipping score with no spanId or traceId', {\n scorerId: score.scorerId,\n });\n return;\n }\n\n const logger = this.#useProvidedLogger ? this.#providedLogger : await this.getLocalLogger();\n if (!logger) return;\n\n const name = score.scorerName ?? score.scorerId;\n\n try {\n logger.logFeedback({\n id: rowId,\n scores: { [name]: score.score },\n ...(score.reason ? { comment: score.reason } : {}),\n metadata: {\n scorerId: score.scorerId,\n ...(score.scoreSource ? { scoreSource: score.scoreSource } : {}),\n ...(score.metadata ?? {}),\n },\n source: 'external',\n });\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to submit score', {\n error: err,\n traceId: score.traceId,\n spanId: score.spanId,\n scorerId: score.scorerId,\n });\n }\n }\n\n private startSpan(args: { parent: BraintrustSpan | BraintrustLogger; span: AnyExportedSpan }): BraintrustSpanData {\n const { parent, span } = args;\n const payload = this.buildSpanPayload(span);\n\n // Braintrust's startSpan() accepts data properties via the `event` parameter\n // which maps to StartSpanEventArgs (ExperimentLogPartialArgs & Partial<IdField>)\n // This includes: input, output, metadata, metrics, tags, scores, error, etc.\n const braintrustSpan = parent.startSpan({\n spanId: span.id,\n name: span.name,\n type: mapSpanType(span.type),\n startTime: span.startTime.getTime() / 1000,\n event: {\n id: span.id, // Use Mastra span ID as Braintrust row ID for logFeedback() compatibility\n ...payload,\n },\n });\n\n // Create BraintrustSpanData with span type for tree walking\n // Initialize threadData and pendingToolResults for MODEL_GENERATION spans (used for Thread view reconstruction)\n const isModelGeneration = span.type === SpanType.MODEL_GENERATION;\n return {\n span: braintrustSpan,\n spanType: span.type,\n threadData: isModelGeneration ? [] : undefined,\n pendingToolResults: isModelGeneration ? new Map() : undefined,\n };\n }\n\n protected override async _buildRoot(_args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustRoot | undefined> {\n if (this.#useProvidedLogger) {\n // Try to find a Braintrust span to attach to:\n // 1. Auto-detect from Braintrust's current span (logger.traced(), Eval(), etc.)\n // 2. Fall back to the configured logger\n let externalSpan: BraintrustSpan | undefined;\n try {\n externalSpan = this.config.currentSpan?.();\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to resolve configured currentSpan', { error: err });\n }\n externalSpan ??= currentSpan();\n\n // Check if it's a valid span (not the NOOP_SPAN)\n if (externalSpan && externalSpan.id) {\n // External span detected - attach Mastra traces to it\n return externalSpan;\n } else {\n // No external span - use provided logger\n return this.#providedLogger!;\n }\n } else {\n // Use the local logger\n return this.getLocalLogger();\n }\n }\n\n protected override async _buildSpan(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustSpanData | undefined> {\n const { span, traceData } = args;\n\n if (span.isRootSpan) {\n const root = traceData.getRoot();\n if (root) {\n return this.startSpan({ parent: root, span });\n }\n } else {\n const parent = traceData.getParent(args);\n if (parent) {\n // Parent could be BraintrustSpanData (has .span) or BraintrustRoot (Logger/Span, no .span)\n const parentSpan = 'span' in parent ? parent.span : parent;\n return this.startSpan({ parent: parentSpan, span });\n }\n }\n }\n\n protected override async _buildEvent(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustEvent | undefined> {\n const spanData = await this._buildSpan(args);\n\n if (!spanData) {\n // parent doesn't exist and not creating rootSpan, return early data\n return;\n }\n\n spanData.span.end({ endTime: args.span.startTime.getTime() / 1000 });\n return spanData.span;\n }\n\n protected override async _updateSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n spanData.span.log(this.buildSpanPayload(span, false));\n }\n\n protected override async _finishSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n\n // Handle thread data accumulation for MODEL_STEP and TOOL_CALL spans\n if (span.type === SpanType.MODEL_STEP) {\n this.accumulateModelStepData(span, traceData);\n } else if (span.type === SpanType.TOOL_CALL) {\n this.accumulateToolCallResult(span, traceData);\n }\n\n // Build payload - for MODEL_GENERATION, may reconstruct output from threadData\n const payload =\n span.type === SpanType.MODEL_GENERATION\n ? this.buildModelGenerationPayload(span, spanData)\n : this.buildSpanPayload(span, false);\n\n spanData.span.log(payload);\n\n if (span.endTime) {\n spanData.span.end({ endTime: span.endTime.getTime() / 1000 });\n } else {\n spanData.span.end();\n }\n }\n\n protected override async _abortSpan(args: { span: BraintrustTrackedSpan; reason: SpanErrorInfo }): Promise<void> {\n const { span: spanData, reason } = args;\n spanData.span.log({\n error: reason.message,\n metadata: { errorDetails: reason },\n });\n spanData.span.end();\n }\n\n // ==============================================================================\n // Thread view reconstruction helpers\n // ==============================================================================\n\n /**\n * Walk up the tree to find the MODEL_GENERATION ancestor span.\n * Returns the BraintrustSpanData if found, undefined otherwise.\n */\n private findModelGenerationAncestor(spanId: string, traceData: BraintrustTraceData): BraintrustSpanData | undefined {\n let currentId: string | undefined = spanId;\n\n while (currentId) {\n const parentId = traceData.getParentId({ spanId: currentId });\n if (!parentId) return undefined;\n\n const parentSpanData = traceData.getSpan({ spanId: parentId });\n if (parentSpanData?.spanType === SpanType.MODEL_GENERATION) {\n return parentSpanData;\n }\n currentId = parentId;\n }\n\n return undefined;\n }\n\n /**\n * Accumulate MODEL_STEP data to the parent MODEL_GENERATION's threadData.\n * Called when a MODEL_STEP span ends.\n */\n private accumulateModelStepData(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.threadData) {\n return;\n }\n\n // Extract step data from MODEL_STEP output and attributes\n const output = span.output as\n | { text?: string; toolCalls?: Array<{ toolCallId: string; toolName: string; args: unknown }> }\n | undefined;\n const attributes = span.attributes as { stepIndex?: number } | undefined;\n\n const stepData: ThreadStepData = {\n stepSpanId: span.id,\n stepIndex: attributes?.stepIndex ?? 0,\n text: output?.text,\n toolCalls: output?.toolCalls?.map(tc => ({\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n args: tc.args,\n })),\n };\n\n modelGenSpanData.threadData.push(stepData);\n }\n\n /**\n * Store TOOL_CALL result in parent MODEL_GENERATION's pendingToolResults.\n * Called when a TOOL_CALL span ends.\n * Results are merged into threadData when MODEL_GENERATION ends.\n */\n private accumulateToolCallResult(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.pendingToolResults) {\n return;\n }\n\n // Extract tool call ID from TOOL_CALL span input\n const input = span.input as { toolCallId?: string } | undefined;\n const toolCallId = input?.toolCallId;\n if (!toolCallId) {\n return;\n }\n\n // Store the result for later merging\n modelGenSpanData.pendingToolResults.set(toolCallId, {\n result: span.output,\n startTime: span.startTime,\n });\n }\n\n /**\n * Build the payload for MODEL_GENERATION span, reconstructing output from threadData if available.\n */\n private buildModelGenerationPayload(span: AnyExportedSpan, spanData: BraintrustSpanData): Record<string, any> {\n const basePayload = this.buildSpanPayload(span, false);\n\n // Check if we have threadData with tool calls to reconstruct\n const threadData = spanData.threadData;\n if (!threadData || threadData.length === 0) {\n return basePayload;\n }\n\n // Merge pending tool results into threadData\n if (spanData.pendingToolResults && spanData.pendingToolResults.size > 0) {\n for (const step of threadData) {\n if (step.toolCalls) {\n for (const toolCall of step.toolCalls) {\n const pendingResult = spanData.pendingToolResults.get(toolCall.toolCallId);\n if (pendingResult) {\n toolCall.result = pendingResult.result;\n toolCall.startTime = pendingResult.startTime;\n }\n }\n }\n }\n }\n\n // Check if any step has tool calls\n const hasToolCalls = threadData.some(step => step.toolCalls && step.toolCalls.length > 0);\n if (!hasToolCalls) {\n return basePayload;\n }\n\n // Reconstruct output as OpenAI messages\n const reconstructedOutput = reconstructThreadOutput(threadData, span.output);\n return {\n ...basePayload,\n output: reconstructedOutput,\n };\n }\n\n /**\n * Transforms MODEL_GENERATION input to Braintrust Thread view format.\n * Converts AI SDK messages (v4/v5) to OpenAI Chat Completion format, which Braintrust requires\n * for proper rendering of threads (fixes #11023).\n */\n private transformInput(input: unknown, spanType: SpanType): unknown {\n if (spanType === SpanType.MODEL_GENERATION) {\n // If input is already an array of messages, convert AI SDK format to OpenAI format\n if (Array.isArray(input)) {\n return input.map((msg: unknown) => convertAISDKMessage(msg));\n }\n\n // If input has a messages array\n if (\n input &&\n typeof input === 'object' &&\n 'messages' in input &&\n Array.isArray((input as { messages: unknown[] }).messages)\n ) {\n return (input as { messages: unknown[] }).messages.map((msg: unknown) => convertAISDKMessage(msg));\n }\n }\n\n return input;\n }\n\n /**\n * Transforms MODEL_GENERATION output to Braintrust Thread view format.\n */\n private transformOutput(output: any, spanType: SpanType): any {\n if (spanType === SpanType.MODEL_GENERATION) {\n if (!output || typeof output !== 'object') {\n return output;\n }\n const { text, ...rest } = output;\n // Remove null/undefined values from rest to keep Thread view clean\n return { role: 'assistant', content: text, ...removeNullish(rest) };\n }\n\n return output;\n }\n\n private isToolSpan(span: AnyExportedSpan): boolean {\n return (\n span.type === SpanType.TOOL_CALL ||\n span.type === SpanType.MCP_TOOL_CALL ||\n span.type === SpanType.PROVIDER_TOOL_CALL\n );\n }\n\n private getToolName(span: AnyExportedSpan): string {\n if (span.entityName) {\n return span.entityName;\n }\n const match = /'([^']+)'/.exec(span.name);\n return match?.[1] ?? span.name;\n }\n\n private getToolCallId(span: AnyExportedSpan): string {\n const attrs = span.attributes as { toolCallId?: string } | undefined;\n return attrs?.toolCallId ?? (span.input as { toolCallId?: string } | undefined)?.toolCallId ?? span.id;\n }\n\n private toToolCallInput(span: AnyExportedSpan): OpenAIMessage[] {\n const args = span.input;\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else {\n try {\n argsString = JSON.stringify(args ?? {});\n } catch {\n argsString = '[unserializable result]';\n }\n }\n return [\n {\n role: 'assistant',\n content: '',\n tool_calls: [\n {\n id: this.getToolCallId(span),\n type: 'function',\n function: {\n name: this.getToolName(span),\n arguments: argsString,\n },\n },\n ],\n },\n ];\n }\n\n private toToolCallOutput(span: AnyExportedSpan): OpenAIMessage {\n return {\n role: 'tool',\n content: serializeToolResult(span.output),\n tool_call_id: this.getToolCallId(span),\n };\n }\n\n private buildSpanPayload(span: AnyExportedSpan, isCreate = true): Record<string, any> {\n const payload: Record<string, any> = {};\n\n const isToolType = this.isToolSpan(span);\n\n if (span.input !== undefined) {\n payload.input = isToolType ? this.toToolCallInput(span) : this.transformInput(span.input, span.type);\n }\n\n if (span.output !== undefined) {\n payload.output = isToolType ? this.toToolCallOutput(span) : this.transformOutput(span.output, span.type);\n }\n\n if (isCreate && span.isRootSpan && span.tags?.length) {\n payload.tags = span.tags;\n }\n\n // Initialize metrics and metadata objects\n payload.metrics = {};\n // Spread span.metadata first, then set spanType to prevent accidental override\n payload.metadata = {\n ...span.metadata,\n spanType: span.type,\n };\n\n if (isCreate) {\n payload.metadata['mastra-trace-id'] = span.traceId;\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 // Model goes to metadata\n if (modelAttr.model !== undefined) {\n payload.metadata.model = modelAttr.model;\n }\n\n // Provider goes to metadata (if provided by attributes)\n if (modelAttr.provider !== undefined) {\n payload.metadata.provider = modelAttr.provider;\n }\n\n // Prefer resolved model ID (e.g. \"claude-sonnet-4-5-20250929\") over\n // gateway aliases (e.g. \"claude-sonnet-4.5\") for accurate cost estimation\n if (modelAttr.responseModel !== undefined) {\n payload.metadata.model = modelAttr.responseModel;\n }\n\n // Usage/token info goes to metrics\n payload.metrics = formatUsageMetrics(modelAttr.usage);\n\n // Time to first token (TTFT) for streaming responses\n // Braintrust expects TTFT in seconds (not milliseconds)\n if (modelAttr.completionStartTime) {\n payload.metrics.time_to_first_token =\n (modelAttr.completionStartTime.getTime() - span.startTime.getTime()) / 1000;\n }\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, [\n 'model',\n 'responseModel',\n 'usage',\n 'parameters',\n 'completionStartTime',\n ]);\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 // Clean up empty metrics object\n if (Object.keys(payload.metrics).length === 0) {\n delete payload.metrics;\n }\n\n // Remove null/undefined values from metadata to keep Braintrust UI clean\n payload.metadata = removeNullish(payload.metadata);\n\n return payload;\n }\n}\n"]}

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/formatter.ts","../src/metrics.ts","../src/thread-reconstruction.ts","../src/tracing.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Message format conversion utilities for Braintrust.\n *\n * Converts AI SDK message format (v4/v5) to OpenAI Chat Completion format,\n * which Braintrust requires for proper rendering of threads.\n */\n\n// ==============================================================================\n// Utility functions\n// ==============================================================================\n\n/**\n * Remove null and undefined values from an object (shallow)\n */\nexport function removeNullish<T extends Record<string, unknown>>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null)) as Partial<T>;\n}\n\n// ==============================================================================\n// Type definitions for AI SDK message format conversion to OpenAI format\n// ==============================================================================\n\n/**\n * AI SDK content part types (both v4 and v5)\n */\ninterface AISDKTextPart {\n type: 'text';\n text: string;\n}\n\ninterface AISDKImagePart {\n type: 'image';\n image?: string | Uint8Array | URL;\n mimeType?: string;\n}\n\ninterface AISDKFilePart {\n type: 'file';\n data?: string | Uint8Array | URL;\n filename?: string;\n name?: string;\n mimeType?: string;\n}\n\ninterface AISDKReasoningPart {\n type: 'reasoning';\n text?: string;\n}\n\ninterface AISDKToolCallPart {\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n args?: unknown; // AI SDK v4\n input?: unknown; // AI SDK v5\n}\n\ninterface AISDKToolResultPart {\n type: 'tool-result';\n toolCallId: string;\n result?: unknown; // AI SDK v4\n output?: unknown; // AI SDK v5\n}\n\ntype AISDKContentPart =\n | AISDKTextPart\n | AISDKImagePart\n | AISDKFilePart\n | AISDKReasoningPart\n | AISDKToolCallPart\n | AISDKToolResultPart\n | { type: string; [key: string]: unknown }; // Catch-all for unknown types\n\n/**\n * AI SDK message format (input format for conversion)\n */\ninterface AISDKMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string | AISDKContentPart[];\n [key: string]: unknown; // Allow additional properties\n}\n\n/**\n * OpenAI Chat Completion tool call format\n */\nexport interface OpenAIToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * OpenAI Chat Completion message format (output format)\n */\nexport interface OpenAIMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string;\n tool_calls?: OpenAIToolCall[];\n tool_call_id?: string;\n [key: string]: unknown; // Allow additional properties\n}\n\n// ==============================================================================\n// Message conversion functions\n// ==============================================================================\n\n/**\n * Converts a content part to a string representation.\n * Handles text, image, file, reasoning, and other content types.\n */\nfunction convertContentPart(part: AISDKContentPart | null | undefined): string | null {\n if (!part || typeof part !== 'object') {\n return null;\n }\n\n switch (part.type) {\n case 'text':\n return (part as AISDKTextPart).text || null;\n\n case 'image':\n // Represent image content with a placeholder\n return '[image]';\n\n case 'file': {\n // Represent file content with filename if available\n const filePart = part as AISDKFilePart;\n if (filePart.filename || filePart.name) {\n return `[file: ${filePart.filename || filePart.name}]`;\n }\n return '[file]';\n }\n\n case 'reasoning': {\n // Represent reasoning/thinking content\n const reasoningPart = part as AISDKReasoningPart;\n if (typeof reasoningPart.text === 'string' && reasoningPart.text.length > 0) {\n return `[reasoning: ${reasoningPart.text.substring(0, 100)}${reasoningPart.text.length > 100 ? '...' : ''}]`;\n }\n return '[reasoning]';\n }\n\n case 'tool-call':\n // Tool calls are handled separately in assistant messages\n return null;\n\n case 'tool-result':\n // Tool results are handled separately in tool messages\n return null;\n\n default: {\n // For unknown types, try to extract any text-like content\n const unknownPart = part as { type?: string; text?: string; content?: string };\n if (typeof unknownPart.text === 'string') {\n return unknownPart.text;\n }\n if (typeof unknownPart.content === 'string') {\n return unknownPart.content;\n }\n // Represent unknown content type\n return `[${unknownPart.type || 'unknown'}]`;\n }\n }\n}\n\n/**\n * Serializes tool result data to a string for OpenAI format.\n */\nexport function serializeToolResult(resultData: unknown): string {\n if (typeof resultData === 'string') {\n return resultData;\n }\n if (resultData && typeof resultData === 'object' && 'value' in resultData) {\n const valueData = (resultData as { value: unknown }).value;\n return typeof valueData === 'string' ? valueData : JSON.stringify(valueData);\n }\n if (resultData === undefined || resultData === null) {\n return '';\n }\n try {\n return JSON.stringify(resultData);\n } catch {\n return '[unserializable result]';\n }\n}\n\n/**\n * Converts AI SDK message format to OpenAI Chat Completion format for Braintrust.\n *\n * Supports both AI SDK v4 and v5 formats:\n * - v4 uses 'args' for tool calls and 'result' for tool results\n * - v5 uses 'input' for tool calls and 'output' for tool results\n *\n * AI SDK format:\n * { role: \"user\", content: [{ type: \"text\", text: \"hello\" }] }\n * { role: \"assistant\", content: [{ type: \"text\", text: \"...\" }, { type: \"tool-call\", toolCallId: \"...\", toolName: \"...\", args: {...} }] }\n * { role: \"tool\", content: [{ type: \"tool-result\", toolCallId: \"...\", result: {...} }] }\n *\n * OpenAI format (what Braintrust expects):\n * { role: \"user\", content: \"hello\" }\n * { role: \"assistant\", content: \"...\", tool_calls: [{ id: \"...\", type: \"function\", function: { name: \"...\", arguments: \"...\" } }] }\n * { role: \"tool\", content: \"result\", tool_call_id: \"...\" }\n */\nexport function convertAISDKMessage(message: AISDKMessage | OpenAIMessage | unknown): OpenAIMessage | unknown {\n if (!message || typeof message !== 'object') {\n return message;\n }\n\n const { role, content, ...rest } = message as AISDKMessage;\n\n // If content is already a string, return as-is (already in OpenAI format)\n if (typeof content === 'string') {\n return message;\n }\n\n // If content is an array (AI SDK format), convert based on role\n if (Array.isArray(content)) {\n // Handle empty content arrays\n if (content.length === 0) {\n return { role, content: '', ...rest };\n }\n\n // For user/system messages, extract text and represent non-text content\n if (role === 'user' || role === 'system') {\n const contentParts = content.map((part: AISDKContentPart) => convertContentPart(part)).filter(Boolean);\n\n return {\n role,\n content: contentParts.length > 0 ? contentParts.join('\\n') : '',\n ...rest,\n };\n }\n\n // For assistant messages, extract text, non-text content, AND tool calls\n if (role === 'assistant') {\n const contentParts = content\n .filter((part: AISDKContentPart) => part?.type !== 'tool-call')\n .map((part: AISDKContentPart) => convertContentPart(part))\n .filter(Boolean);\n\n const toolCallParts = content.filter((part: AISDKContentPart) => part?.type === 'tool-call');\n\n const result: OpenAIMessage = {\n role,\n content: contentParts.length > 0 ? (contentParts as string[]).join('\\n') : '',\n ...rest,\n };\n\n // Add tool_calls array if there are tool calls\n if (toolCallParts.length > 0) {\n result.tool_calls = toolCallParts.map((tc: AISDKContentPart) => {\n const toolCall = tc as AISDKToolCallPart;\n const toolCallId = toolCall.toolCallId;\n const toolName = toolCall.toolName;\n // Support both v4 'args' and v5 'input'\n const args = toolCall.args ?? toolCall.input;\n\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else if (args !== undefined && args !== null) {\n argsString = JSON.stringify(args);\n } else {\n argsString = '{}';\n }\n\n return {\n id: toolCallId,\n type: 'function' as const,\n function: {\n name: toolName,\n arguments: argsString,\n },\n };\n });\n }\n\n return result;\n }\n\n // For tool messages, convert to OpenAI tool message format\n if (role === 'tool') {\n const toolResult = content.find((part): part is AISDKToolResultPart => part?.type === 'tool-result');\n if (toolResult) {\n // Support both v4 'result' and v5 'output' fields\n const resultData = toolResult.output ?? toolResult.result;\n const resultContent = serializeToolResult(resultData);\n\n return {\n role: 'tool',\n content: resultContent,\n tool_call_id: toolResult.toolCallId,\n } as OpenAIMessage;\n }\n }\n }\n\n return message;\n}\n","import type { UsageStats } from '@mastra/core/observability';\n\n/**\n * BraintrustUsageMetrics\n *\n * Canonical metric keys expected by Braintrust for LLM usage accounting.\n */\nexport interface BraintrustUsageMetrics {\n prompt_tokens?: number;\n completion_tokens?: number;\n tokens?: number;\n completion_reasoning_tokens?: number;\n prompt_cached_tokens?: number;\n prompt_cache_creation_tokens?: number;\n}\n\n/**\n * Formats UsageStats to Braintrust's expected metric format.\n */\nexport function formatUsageMetrics(usage?: UsageStats): BraintrustUsageMetrics {\n const metrics: BraintrustUsageMetrics = {};\n\n if (usage?.inputTokens !== undefined) {\n metrics.prompt_tokens = usage.inputTokens;\n }\n\n if (usage?.outputTokens !== undefined) {\n metrics.completion_tokens = usage.outputTokens;\n }\n\n // Compute total if we have both\n if (metrics.prompt_tokens !== undefined && metrics.completion_tokens !== undefined) {\n metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;\n }\n\n if (usage?.outputDetails?.reasoning !== undefined) {\n metrics.completion_reasoning_tokens = usage.outputDetails.reasoning;\n }\n\n if (usage?.inputDetails?.cacheRead !== undefined) {\n metrics.prompt_cached_tokens = usage.inputDetails.cacheRead;\n }\n\n if (usage?.inputDetails?.cacheWrite !== undefined) {\n metrics.prompt_cache_creation_tokens = usage.inputDetails.cacheWrite;\n }\n\n return metrics;\n}\n","/**\n * Thread view reconstruction for Braintrust.\n *\n * Reconstructs LLM output in OpenAI Chat Completion format by examining\n * child MODEL_STEP and TOOL_CALL spans. This enables Braintrust's Thread\n * view to properly display the full conversation flow including tool calls.\n *\n * See THREAD_VIEW_RECONSTRUCTION.md for details.\n */\n\nimport { removeNullish } from './formatter';\nimport type { OpenAIMessage } from './formatter';\n\n// ==============================================================================\n// Thread view reconstruction types\n// ==============================================================================\n\n/**\n * Tool call data accumulated from MODEL_STEP and TOOL_CALL spans\n */\nexport interface ThreadToolCall {\n toolCallId: string;\n toolName: string;\n args: unknown;\n result?: unknown; // filled in when TOOL_CALL ends\n startTime?: Date; // from TOOL_CALL span, for ordering multiple tool calls within a step\n}\n\n/**\n * Step data accumulated from MODEL_STEP spans for Thread view reconstruction\n */\nexport interface ThreadStepData {\n stepSpanId: string;\n stepIndex: number; // for ordering steps correctly\n text?: string;\n toolCalls?: ThreadToolCall[];\n}\n\n/**\n * Accumulated data for reconstructing Braintrust Thread view.\n * Populated for MODEL_GENERATION spans as child MODEL_STEP and TOOL_CALL spans complete.\n */\nexport type ThreadData = ThreadStepData[];\n\n/**\n * Tool result data stored when TOOL_CALL spans end (before MODEL_STEP ends)\n */\nexport interface PendingToolResult {\n result: unknown;\n startTime: Date;\n}\n\n// ==============================================================================\n// Thread view reconstruction\n// ==============================================================================\n\n/**\n * Reconstruct the Thread view output from accumulated threadData.\n * Converts to OpenAI Chat Completion message format.\n */\nexport function reconstructThreadOutput(threadData: ThreadData, originalOutput: unknown): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n\n // Sort steps by stepIndex\n const sortedSteps = [...threadData].sort((a, b) => a.stepIndex - b.stepIndex);\n\n for (const step of sortedSteps) {\n // Sort tool calls by startTime within each step\n const sortedToolCalls = step.toolCalls\n ? [...step.toolCalls].sort((a, b) => {\n if (!a.startTime || !b.startTime) return 0;\n return a.startTime.getTime() - b.startTime.getTime();\n })\n : [];\n\n if (sortedToolCalls.length > 0) {\n // Add assistant message with tool_calls\n messages.push({\n role: 'assistant',\n content: step.text || '',\n tool_calls: sortedToolCalls.map(tc => {\n // Clean null/undefined values from args before stringifying\n const cleanArgs =\n tc.args && typeof tc.args === 'object' && !Array.isArray(tc.args)\n ? removeNullish(tc.args as Record<string, unknown>)\n : tc.args;\n return {\n id: tc.toolCallId,\n type: 'function' as const,\n function: {\n name: tc.toolName,\n arguments: typeof cleanArgs === 'string' ? cleanArgs : JSON.stringify(cleanArgs),\n },\n };\n }),\n });\n\n // Add tool messages for each result\n for (const tc of sortedToolCalls) {\n if (tc.result !== undefined) {\n messages.push({\n role: 'tool',\n content: typeof tc.result === 'string' ? tc.result : JSON.stringify(tc.result),\n tool_call_id: tc.toolCallId,\n });\n }\n }\n } else if (step.text) {\n // Step with text only (final response)\n messages.push({\n role: 'assistant',\n content: step.text,\n });\n }\n }\n\n // If we have messages and the last one is a tool message,\n // add the final assistant text from original output\n if (messages.length > 0) {\n const lastMessage = messages[messages.length - 1]!;\n const originalText = (originalOutput as { text?: string })?.text;\n\n // If the last message is a tool response and we have final text, add it\n if (originalText && lastMessage.role === 'tool') {\n messages.push({\n role: 'assistant',\n content: originalText,\n });\n }\n }\n\n return messages;\n}\n","/**\n * Braintrust Exporter for Mastra Observability\n *\n * This exporter sends observability data to Braintrust.\n * Root spans become top-level Braintrust spans (no trace wrapper).\n * Events are handled as zero-duration spans with matching start/end times.\n */\n\nimport type { AnyExportedSpan, ModelGenerationAttributes, ScoreEvent, SpanErrorInfo } from '@mastra/core/observability';\nimport { SpanType } from '@mastra/core/observability';\nimport { omitKeys } from '@mastra/core/utils';\nimport { TrackingExporter } from '@mastra/observability';\nimport type { TraceData, TrackingExporterConfig } from '@mastra/observability';\nimport { initLogger, currentSpan } from 'braintrust';\nimport type { Span, Logger } from 'braintrust';\nimport { removeNullish, convertAISDKMessage, serializeToolResult } from './formatter';\nimport type { OpenAIMessage } from './formatter';\nimport { formatUsageMetrics } from './metrics';\nimport { reconstructThreadOutput } from './thread-reconstruction';\nimport type { ThreadData, ThreadStepData, PendingToolResult } from './thread-reconstruction';\n\n/**\n * Extended Braintrust span data that includes span type and thread reconstruction data\n */\ninterface BraintrustSpanData {\n span: Span;\n spanType: SpanType;\n threadData?: ThreadData; // only populated for MODEL_GENERATION spans\n // Tool results stored when TOOL_CALL ends (may arrive before MODEL_STEP ends)\n pendingToolResults?: Map<string, PendingToolResult>; // keyed by toolCallId\n}\n\nexport interface BraintrustExporterConfig extends TrackingExporterConfig {\n /**\n * Optional Braintrust logger instance.\n * When provided, enables integration with Braintrust contexts such as:\n * - Evals: Agent traces nest inside eval task spans\n * - logger.traced(): Agent traces nest inside traced spans\n * - Parent spans: Auto-detects and attaches to external Braintrust spans\n */\n braintrustLogger?: Logger<true>;\n\n /**\n * Optional resolver for the active Braintrust span.\n *\n * Pass Braintrust's `currentSpan` from the same package instance that creates\n * `Eval()` or `logger.traced()` spans when your app and Mastra may resolve\n * different copies of the `braintrust` package.\n */\n currentSpan?: () => Span | undefined;\n\n /** Braintrust API key. Required if logger is not provided. */\n apiKey?: string;\n /** Optional custom endpoint */\n endpoint?: string;\n /** Braintrust project name (default: 'mastra-tracing') */\n projectName?: string;\n /** Support tuning parameters */\n tuningParameters?: Record<string, any>;\n}\n\ntype BraintrustRoot = Logger<true> | Span;\ntype BraintrustSpan = BraintrustSpanData;\ntype BraintrustEvent = Span;\ntype BraintrustMetadata = unknown;\ntype BraintrustTraceData = TraceData<BraintrustRoot, BraintrustSpan, BraintrustEvent, BraintrustMetadata>;\n\n// Default span type for all spans\nconst DEFAULT_SPAN_TYPE = 'task';\n\n// Exceptions to the default mapping\nconst SPAN_TYPE_EXCEPTIONS: Partial<Record<SpanType, string>> = {\n [SpanType.MODEL_GENERATION]: 'llm',\n [SpanType.TOOL_CALL]: 'tool',\n [SpanType.MCP_TOOL_CALL]: 'tool',\n [SpanType.PROVIDER_TOOL_CALL]: 'tool',\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: 'function',\n [SpanType.WORKFLOW_WAIT_EVENT]: 'function',\n};\n\n// Mapping function - returns valid Braintrust span types\nfunction mapSpanType(spanType: SpanType): 'llm' | 'score' | 'function' | 'eval' | 'task' | 'tool' {\n return (SPAN_TYPE_EXCEPTIONS[spanType] as any) ?? DEFAULT_SPAN_TYPE;\n}\n\nexport class BraintrustExporter extends TrackingExporter<\n BraintrustRoot,\n BraintrustSpan,\n BraintrustEvent,\n BraintrustMetadata,\n BraintrustExporterConfig\n> {\n name = 'braintrust';\n\n // Flags and logger for context-aware mode\n #useProvidedLogger: boolean;\n #providedLogger?: Logger<true>;\n #localLogger?: Logger<true>;\n\n constructor(config: BraintrustExporterConfig = {}) {\n // Resolve env vars BEFORE calling super (config is readonly in base class)\n const resolvedApiKey = config.apiKey ?? process.env.BRAINTRUST_API_KEY;\n const resolvedEndpoint = config.endpoint ?? process.env.BRAINTRUST_ENDPOINT;\n\n super({\n ...config,\n apiKey: resolvedApiKey,\n endpoint: resolvedEndpoint,\n });\n\n this.#useProvidedLogger = !!config.braintrustLogger;\n\n if (this.#useProvidedLogger) {\n // Use provided logger - enables Braintrust context integration\n this.#providedLogger = config.braintrustLogger;\n } else {\n // Validate apiKey for creating loggers per trace\n if (!this.config.apiKey) {\n this.setDisabled(\n `Missing required API key. Set BRAINTRUST_API_KEY environment variable or pass apiKey in config.`,\n );\n return;\n }\n // lazy create logger on first rootSpan\n this.#localLogger = undefined;\n }\n }\n\n private async getLocalLogger(): Promise<Logger<true> | undefined> {\n if (this.#localLogger) {\n return this.#localLogger;\n }\n try {\n const logger = await initLogger({\n projectName: this.config.projectName ?? 'mastra-tracing',\n apiKey: this.config.apiKey,\n appUrl: this.config.endpoint,\n ...this.config.tuningParameters,\n });\n this.#localLogger = logger;\n return logger;\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to initialize logger', { error: err });\n this.setDisabled('Failed to initialize Braintrust logger');\n }\n }\n\n async onScoreEvent(event: ScoreEvent): Promise<void> {\n if (this.isDisabled) return;\n\n const { score } = event;\n const rowId = score.spanId ?? score.traceId;\n if (!rowId) {\n this.logger.debug('Braintrust exporter: skipping score with no spanId or traceId', {\n scorerId: score.scorerId,\n });\n return;\n }\n\n const logger = this.#useProvidedLogger ? this.#providedLogger : await this.getLocalLogger();\n if (!logger) return;\n\n const name = score.scorerName ?? score.scorerId;\n\n try {\n logger.logFeedback({\n id: rowId,\n scores: { [name]: score.score },\n ...(score.reason ? { comment: score.reason } : {}),\n metadata: {\n scorerId: score.scorerId,\n ...(score.scoreSource ? { scoreSource: score.scoreSource } : {}),\n ...(score.metadata ?? {}),\n },\n source: 'external',\n });\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to submit score', {\n error: err,\n traceId: score.traceId,\n spanId: score.spanId,\n scorerId: score.scorerId,\n });\n }\n }\n\n private startSpan(args: { parent: Span | Logger<true>; span: AnyExportedSpan }): BraintrustSpanData {\n const { parent, span } = args;\n const payload = this.buildSpanPayload(span);\n\n // Braintrust's startSpan() accepts data properties via the `event` parameter\n // which maps to StartSpanEventArgs (ExperimentLogPartialArgs & Partial<IdField>)\n // This includes: input, output, metadata, metrics, tags, scores, error, etc.\n const braintrustSpan = parent.startSpan({\n spanId: span.id,\n name: span.name,\n type: mapSpanType(span.type),\n startTime: span.startTime.getTime() / 1000,\n event: {\n id: span.id, // Use Mastra span ID as Braintrust row ID for logFeedback() compatibility\n ...payload,\n },\n });\n\n // Create BraintrustSpanData with span type for tree walking\n // Initialize threadData and pendingToolResults for MODEL_GENERATION spans (used for Thread view reconstruction)\n const isModelGeneration = span.type === SpanType.MODEL_GENERATION;\n return {\n span: braintrustSpan,\n spanType: span.type,\n threadData: isModelGeneration ? [] : undefined,\n pendingToolResults: isModelGeneration ? new Map() : undefined,\n };\n }\n\n protected override async _buildRoot(_args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustRoot | undefined> {\n if (this.#useProvidedLogger) {\n // Try to find a Braintrust span to attach to:\n // 1. Auto-detect from Braintrust's current span (logger.traced(), Eval(), etc.)\n // 2. Fall back to the configured logger\n let externalSpan: Span | undefined;\n try {\n externalSpan = this.config.currentSpan?.();\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to resolve configured currentSpan', { error: err });\n }\n externalSpan ??= currentSpan();\n\n // Check if it's a valid span (not the NOOP_SPAN)\n if (externalSpan && externalSpan.id) {\n // External span detected - attach Mastra traces to it\n return externalSpan;\n } else {\n // No external span - use provided logger\n return this.#providedLogger!;\n }\n } else {\n // Use the local logger\n return this.getLocalLogger();\n }\n }\n\n protected override async _buildSpan(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustSpanData | undefined> {\n const { span, traceData } = args;\n\n if (span.isRootSpan) {\n const root = traceData.getRoot();\n if (root) {\n return this.startSpan({ parent: root, span });\n }\n } else {\n const parent = traceData.getParent(args);\n if (parent) {\n // Parent could be BraintrustSpanData (has .span) or BraintrustRoot (Logger/Span, no .span)\n const parentSpan = 'span' in parent ? parent.span : parent;\n return this.startSpan({ parent: parentSpan, span });\n }\n }\n }\n\n protected override async _buildEvent(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<Span | undefined> {\n const spanData = await this._buildSpan(args);\n\n if (!spanData) {\n // parent doesn't exist and not creating rootSpan, return early data\n return;\n }\n\n spanData.span.end({ endTime: args.span.startTime.getTime() / 1000 });\n return spanData.span;\n }\n\n protected override async _updateSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n spanData.span.log(this.buildSpanPayload(span, false));\n }\n\n protected override async _finishSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n\n // Handle thread data accumulation for MODEL_STEP and TOOL_CALL spans\n if (span.type === SpanType.MODEL_STEP) {\n this.accumulateModelStepData(span, traceData);\n } else if (span.type === SpanType.TOOL_CALL) {\n this.accumulateToolCallResult(span, traceData);\n }\n\n // Build payload - for MODEL_GENERATION, may reconstruct output from threadData\n const payload =\n span.type === SpanType.MODEL_GENERATION\n ? this.buildModelGenerationPayload(span, spanData)\n : this.buildSpanPayload(span, false);\n\n spanData.span.log(payload);\n\n if (span.endTime) {\n spanData.span.end({ endTime: span.endTime.getTime() / 1000 });\n } else {\n spanData.span.end();\n }\n }\n\n protected override async _abortSpan(args: { span: BraintrustSpan; reason: SpanErrorInfo }): Promise<void> {\n const { span: spanData, reason } = args;\n spanData.span.log({\n error: reason.message,\n metadata: { errorDetails: reason },\n });\n spanData.span.end();\n }\n\n // ==============================================================================\n // Thread view reconstruction helpers\n // ==============================================================================\n\n /**\n * Walk up the tree to find the MODEL_GENERATION ancestor span.\n * Returns the BraintrustSpanData if found, undefined otherwise.\n */\n private findModelGenerationAncestor(spanId: string, traceData: BraintrustTraceData): BraintrustSpanData | undefined {\n let currentId: string | undefined = spanId;\n\n while (currentId) {\n const parentId = traceData.getParentId({ spanId: currentId });\n if (!parentId) return undefined;\n\n const parentSpanData = traceData.getSpan({ spanId: parentId });\n if (parentSpanData?.spanType === SpanType.MODEL_GENERATION) {\n return parentSpanData;\n }\n currentId = parentId;\n }\n\n return undefined;\n }\n\n /**\n * Accumulate MODEL_STEP data to the parent MODEL_GENERATION's threadData.\n * Called when a MODEL_STEP span ends.\n */\n private accumulateModelStepData(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.threadData) {\n return;\n }\n\n // Extract step data from MODEL_STEP output and attributes\n const output = span.output as\n | { text?: string; toolCalls?: Array<{ toolCallId: string; toolName: string; args: unknown }> }\n | undefined;\n const attributes = span.attributes as { stepIndex?: number } | undefined;\n\n const stepData: ThreadStepData = {\n stepSpanId: span.id,\n stepIndex: attributes?.stepIndex ?? 0,\n text: output?.text,\n toolCalls: output?.toolCalls?.map(tc => ({\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n args: tc.args,\n })),\n };\n\n modelGenSpanData.threadData.push(stepData);\n }\n\n /**\n * Store TOOL_CALL result in parent MODEL_GENERATION's pendingToolResults.\n * Called when a TOOL_CALL span ends.\n * Results are merged into threadData when MODEL_GENERATION ends.\n */\n private accumulateToolCallResult(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.pendingToolResults) {\n return;\n }\n\n // Extract tool call ID from TOOL_CALL span input\n const input = span.input as { toolCallId?: string } | undefined;\n const toolCallId = input?.toolCallId;\n if (!toolCallId) {\n return;\n }\n\n // Store the result for later merging\n modelGenSpanData.pendingToolResults.set(toolCallId, {\n result: span.output,\n startTime: span.startTime,\n });\n }\n\n /**\n * Build the payload for MODEL_GENERATION span, reconstructing output from threadData if available.\n */\n private buildModelGenerationPayload(span: AnyExportedSpan, spanData: BraintrustSpanData): Record<string, any> {\n const basePayload = this.buildSpanPayload(span, false);\n\n // Check if we have threadData with tool calls to reconstruct\n const threadData = spanData.threadData;\n if (!threadData || threadData.length === 0) {\n return basePayload;\n }\n\n // Merge pending tool results into threadData\n if (spanData.pendingToolResults && spanData.pendingToolResults.size > 0) {\n for (const step of threadData) {\n if (step.toolCalls) {\n for (const toolCall of step.toolCalls) {\n const pendingResult = spanData.pendingToolResults.get(toolCall.toolCallId);\n if (pendingResult) {\n toolCall.result = pendingResult.result;\n toolCall.startTime = pendingResult.startTime;\n }\n }\n }\n }\n }\n\n // Check if any step has tool calls\n const hasToolCalls = threadData.some(step => step.toolCalls && step.toolCalls.length > 0);\n if (!hasToolCalls) {\n return basePayload;\n }\n\n // Reconstruct output as OpenAI messages\n const reconstructedOutput = reconstructThreadOutput(threadData, span.output);\n return {\n ...basePayload,\n output: reconstructedOutput,\n };\n }\n\n /**\n * Transforms MODEL_GENERATION input to Braintrust Thread view format.\n * Converts AI SDK messages (v4/v5) to OpenAI Chat Completion format, which Braintrust requires\n * for proper rendering of threads (fixes #11023).\n */\n private transformInput(input: unknown, spanType: SpanType): unknown {\n if (spanType === SpanType.MODEL_GENERATION) {\n // If input is already an array of messages, convert AI SDK format to OpenAI format\n if (Array.isArray(input)) {\n return input.map((msg: unknown) => convertAISDKMessage(msg));\n }\n\n // If input has a messages array\n if (\n input &&\n typeof input === 'object' &&\n 'messages' in input &&\n Array.isArray((input as { messages: unknown[] }).messages)\n ) {\n return (input as { messages: unknown[] }).messages.map((msg: unknown) => convertAISDKMessage(msg));\n }\n }\n\n return input;\n }\n\n /**\n * Transforms MODEL_GENERATION output to Braintrust Thread view format.\n */\n private transformOutput(output: any, spanType: SpanType): any {\n if (spanType === SpanType.MODEL_GENERATION) {\n if (!output || typeof output !== 'object') {\n return output;\n }\n const { text, ...rest } = output;\n // Remove null/undefined values from rest to keep Thread view clean\n return { role: 'assistant', content: text, ...removeNullish(rest) };\n }\n\n return output;\n }\n\n private isToolSpan(span: AnyExportedSpan): boolean {\n return (\n span.type === SpanType.TOOL_CALL ||\n span.type === SpanType.MCP_TOOL_CALL ||\n span.type === SpanType.PROVIDER_TOOL_CALL\n );\n }\n\n private getToolName(span: AnyExportedSpan): string {\n if (span.entityName) {\n return span.entityName;\n }\n const match = /'([^']+)'/.exec(span.name);\n return match?.[1] ?? span.name;\n }\n\n private getToolCallId(span: AnyExportedSpan): string {\n const attrs = span.attributes as { toolCallId?: string } | undefined;\n return attrs?.toolCallId ?? (span.input as { toolCallId?: string } | undefined)?.toolCallId ?? span.id;\n }\n\n private toToolCallInput(span: AnyExportedSpan): OpenAIMessage[] {\n const args = span.input;\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else {\n try {\n argsString = JSON.stringify(args ?? {});\n } catch {\n argsString = '[unserializable result]';\n }\n }\n return [\n {\n role: 'assistant',\n content: '',\n tool_calls: [\n {\n id: this.getToolCallId(span),\n type: 'function',\n function: {\n name: this.getToolName(span),\n arguments: argsString,\n },\n },\n ],\n },\n ];\n }\n\n private toToolCallOutput(span: AnyExportedSpan): OpenAIMessage {\n return {\n role: 'tool',\n content: serializeToolResult(span.output),\n tool_call_id: this.getToolCallId(span),\n };\n }\n\n private buildSpanPayload(span: AnyExportedSpan, isCreate = true): Record<string, any> {\n const payload: Record<string, any> = {};\n\n const isToolType = this.isToolSpan(span);\n\n if (span.input !== undefined) {\n payload.input = isToolType ? this.toToolCallInput(span) : this.transformInput(span.input, span.type);\n }\n\n if (span.output !== undefined) {\n payload.output = isToolType ? this.toToolCallOutput(span) : this.transformOutput(span.output, span.type);\n }\n\n if (isCreate && span.isRootSpan && span.tags?.length) {\n payload.tags = span.tags;\n }\n\n // Initialize metrics and metadata objects\n payload.metrics = {};\n // Spread span.metadata first, then set spanType to prevent accidental override\n payload.metadata = {\n ...span.metadata,\n spanType: span.type,\n };\n\n if (isCreate) {\n payload.metadata['mastra-trace-id'] = span.traceId;\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 // Model goes to metadata\n if (modelAttr.model !== undefined) {\n payload.metadata.model = modelAttr.model;\n }\n\n // Provider goes to metadata (if provided by attributes)\n if (modelAttr.provider !== undefined) {\n payload.metadata.provider = modelAttr.provider;\n }\n\n // Prefer resolved model ID (e.g. \"claude-sonnet-4-5-20250929\") over\n // gateway aliases (e.g. \"claude-sonnet-4.5\") for accurate cost estimation\n if (modelAttr.responseModel !== undefined) {\n payload.metadata.model = modelAttr.responseModel;\n }\n\n // Usage/token info goes to metrics\n payload.metrics = formatUsageMetrics(modelAttr.usage);\n\n // Time to first token (TTFT) for streaming responses\n // Braintrust expects TTFT in seconds (not milliseconds)\n if (modelAttr.completionStartTime) {\n payload.metrics.time_to_first_token =\n (modelAttr.completionStartTime.getTime() - span.startTime.getTime()) / 1000;\n }\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, [\n 'model',\n 'responseModel',\n 'usage',\n 'parameters',\n 'completionStartTime',\n ]);\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 // Clean up empty metrics object\n if (Object.keys(payload.metrics).length === 0) {\n delete payload.metrics;\n }\n\n // Remove null/undefined values from metadata to keep Braintrust UI clean\n payload.metadata = removeNullish(payload.metadata);\n\n return payload;\n }\n}\n"]}
{"version":3,"sources":["../src/formatter.ts","../src/metrics.ts","../src/thread-reconstruction.ts","../src/tracing.ts"],"names":[],"mappings":";;;;;;;;AAcO,SAAS,cAAiD,GAAA,EAAoB;AACnF,EAAA,OAAO,MAAA,CAAO,WAAA,CAAY,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAAE,MAAA,CAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,IAAK,IAAI,CAAC,CAAA;AAC7E;AAiGA,SAAS,mBAAmB,IAAA,EAA0D;AACpF,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACrC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,MAAA;AACH,MAAA,OAAQ,KAAuB,IAAA,IAAQ,IAAA;AAAA,IAEzC,KAAK,OAAA;AAEH,MAAA,OAAO,SAAA;AAAA,IAET,KAAK,MAAA,EAAQ;AAEX,MAAA,MAAM,QAAA,GAAW,IAAA;AACjB,MAAA,IAAI,QAAA,CAAS,QAAA,IAAY,QAAA,CAAS,IAAA,EAAM;AACtC,QAAA,OAAO,CAAA,OAAA,EAAU,QAAA,CAAS,QAAA,IAAY,QAAA,CAAS,IAAI,CAAA,CAAA,CAAA;AAAA,MACrD;AACA,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,IAEA,KAAK,WAAA,EAAa;AAEhB,MAAA,MAAM,aAAA,GAAgB,IAAA;AACtB,MAAA,IAAI,OAAO,aAAA,CAAc,IAAA,KAAS,YAAY,aAAA,CAAc,IAAA,CAAK,SAAS,CAAA,EAAG;AAC3E,QAAA,OAAO,CAAA,YAAA,EAAe,aAAA,CAAc,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,CAAA,EAAG,aAAA,CAAc,IAAA,CAAK,MAAA,GAAS,GAAA,GAAM,QAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,MAC3G;AACA,MAAA,OAAO,aAAA;AAAA,IACT;AAAA,IAEA,KAAK,WAAA;AAEH,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,aAAA;AAEH,MAAA,OAAO,IAAA;AAAA,IAET,SAAS;AAEP,MAAA,MAAM,WAAA,GAAc,IAAA;AACpB,MAAA,IAAI,OAAO,WAAA,CAAY,IAAA,KAAS,QAAA,EAAU;AACxC,QAAA,OAAO,WAAA,CAAY,IAAA;AAAA,MACrB;AACA,MAAA,IAAI,OAAO,WAAA,CAAY,OAAA,KAAY,QAAA,EAAU;AAC3C,QAAA,OAAO,WAAA,CAAY,OAAA;AAAA,MACrB;AAEA,MAAA,OAAO,CAAA,CAAA,EAAI,WAAA,CAAY,IAAA,IAAQ,SAAS,CAAA,CAAA,CAAA;AAAA,IAC1C;AAAA;AAEJ;AAKO,SAAS,oBAAoB,UAAA,EAA6B;AAC/D,EAAA,IAAI,OAAO,eAAe,QAAA,EAAU;AAClC,IAAA,OAAO,UAAA;AAAA,EACT;AACA,EAAA,IAAI,UAAA,IAAc,OAAO,UAAA,KAAe,QAAA,IAAY,WAAW,UAAA,EAAY;AACzE,IAAA,MAAM,YAAa,UAAA,CAAkC,KAAA;AACrD,IAAA,OAAO,OAAO,SAAA,KAAc,QAAA,GAAW,SAAA,GAAY,IAAA,CAAK,UAAU,SAAS,CAAA;AAAA,EAC7E;AACA,EAAA,IAAI,UAAA,KAAe,MAAA,IAAa,UAAA,KAAe,IAAA,EAAM;AACnD,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,UAAU,UAAU,CAAA;AAAA,EAClC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,yBAAA;AAAA,EACT;AACF;AAmBO,SAAS,oBAAoB,OAAA,EAA0E;AAC5G,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,EAAU;AAC3C,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,GAAG,MAAK,GAAI,OAAA;AAGnC,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,OAAO,OAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG;AAE1B,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,EAAA,EAAI,GAAG,IAAA,EAAK;AAAA,IACtC;AAGA,IAAA,IAAI,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,QAAA,EAAU;AACxC,MAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,KAA2B,mBAAmB,IAAI,CAAC,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AAErG,MAAA,OAAO;AAAA,QACL,IAAA;AAAA,QACA,SAAS,YAAA,CAAa,MAAA,GAAS,IAAI,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,GAAI,EAAA;AAAA,QAC7D,GAAG;AAAA,OACL;AAAA,IACF;AAGA,IAAA,IAAI,SAAS,WAAA,EAAa;AACxB,MAAA,MAAM,eAAe,OAAA,CAClB,MAAA,CAAO,CAAC,IAAA,KAA2B,MAAM,IAAA,KAAS,WAAW,CAAA,CAC7D,GAAA,CAAI,CAAC,IAAA,KAA2B,kBAAA,CAAmB,IAAI,CAAC,CAAA,CACxD,OAAO,OAAO,CAAA;AAEjB,MAAA,MAAM,gBAAgB,OAAA,CAAQ,MAAA,CAAO,CAAC,IAAA,KAA2B,IAAA,EAAM,SAAS,WAAW,CAAA;AAE3F,MAAA,MAAM,MAAA,GAAwB;AAAA,QAC5B,IAAA;AAAA,QACA,SAAS,YAAA,CAAa,MAAA,GAAS,IAAK,YAAA,CAA0B,IAAA,CAAK,IAAI,CAAA,GAAI,EAAA;AAAA,QAC3E,GAAG;AAAA,OACL;AAGA,MAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,QAAA,MAAA,CAAO,UAAA,GAAa,aAAA,CAAc,GAAA,CAAI,CAAC,EAAA,KAAyB;AAC9D,UAAA,MAAM,QAAA,GAAW,EAAA;AACjB,UAAA,MAAM,aAAa,QAAA,CAAS,UAAA;AAC5B,UAAA,MAAM,WAAW,QAAA,CAAS,QAAA;AAE1B,UAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,IAAQ,QAAA,CAAS,KAAA;AAEvC,UAAA,IAAI,UAAA;AACJ,UAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,YAAA,UAAA,GAAa,IAAA;AAAA,UACf,CAAA,MAAA,IAAW,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AAC9C,YAAA,UAAA,GAAa,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,UAClC,CAAA,MAAO;AACL,YAAA,UAAA,GAAa,IAAA;AAAA,UACf;AAEA,UAAA,OAAO;AAAA,YACL,EAAA,EAAI,UAAA;AAAA,YACJ,IAAA,EAAM,UAAA;AAAA,YACN,QAAA,EAAU;AAAA,cACR,IAAA,EAAM,QAAA;AAAA,cACN,SAAA,EAAW;AAAA;AACb,WACF;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,MAAA;AAAA,IACT;AAGA,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,MAAM,aAAa,OAAA,CAAQ,IAAA,CAAK,CAAC,IAAA,KAAsC,IAAA,EAAM,SAAS,aAAa,CAAA;AACnG,MAAA,IAAI,UAAA,EAAY;AAEd,QAAA,MAAM,UAAA,GAAa,UAAA,CAAW,MAAA,IAAU,UAAA,CAAW,MAAA;AACnD,QAAA,MAAM,aAAA,GAAgB,oBAAoB,UAAU,CAAA;AAEpD,QAAA,OAAO;AAAA,UACL,IAAA,EAAM,MAAA;AAAA,UACN,OAAA,EAAS,aAAA;AAAA,UACT,cAAc,UAAA,CAAW;AAAA,SAC3B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;;;ACzRO,SAAS,mBAAmB,KAAA,EAA4C;AAC7E,EAAA,MAAM,UAAkC,EAAC;AAEzC,EAAA,IAAI,KAAA,EAAO,gBAAgB,MAAA,EAAW;AACpC,IAAA,OAAA,CAAQ,gBAAgB,KAAA,CAAM,WAAA;AAAA,EAChC;AAEA,EAAA,IAAI,KAAA,EAAO,iBAAiB,MAAA,EAAW;AACrC,IAAA,OAAA,CAAQ,oBAAoB,KAAA,CAAM,YAAA;AAAA,EACpC;AAGA,EAAA,IAAI,OAAA,CAAQ,aAAA,KAAkB,MAAA,IAAa,OAAA,CAAQ,sBAAsB,MAAA,EAAW;AAClF,IAAA,OAAA,CAAQ,MAAA,GAAS,OAAA,CAAQ,aAAA,GAAgB,OAAA,CAAQ,iBAAA;AAAA,EACnD;AAEA,EAAA,IAAI,KAAA,EAAO,aAAA,EAAe,SAAA,KAAc,MAAA,EAAW;AACjD,IAAA,OAAA,CAAQ,2BAAA,GAA8B,MAAM,aAAA,CAAc,SAAA;AAAA,EAC5D;AAEA,EAAA,IAAI,KAAA,EAAO,YAAA,EAAc,SAAA,KAAc,MAAA,EAAW;AAChD,IAAA,OAAA,CAAQ,oBAAA,GAAuB,MAAM,YAAA,CAAa,SAAA;AAAA,EACpD;AAEA,EAAA,IAAI,KAAA,EAAO,YAAA,EAAc,UAAA,KAAe,MAAA,EAAW;AACjD,IAAA,OAAA,CAAQ,4BAAA,GAA+B,MAAM,YAAA,CAAa,UAAA;AAAA,EAC5D;AAEA,EAAA,OAAO,OAAA;AACT;;;ACYO,SAAS,uBAAA,CAAwB,YAAwB,cAAA,EAA0C;AACxG,EAAA,MAAM,WAA4B,EAAC;AAGnC,EAAA,MAAM,WAAA,GAAc,CAAC,GAAG,UAAU,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAS,CAAA;AAE5E,EAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAE9B,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,SAAA,GACzB,CAAC,GAAG,IAAA,CAAK,SAAS,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACjC,MAAA,IAAI,CAAC,CAAA,CAAE,SAAA,IAAa,CAAC,CAAA,CAAE,WAAW,OAAO,CAAA;AACzC,MAAA,OAAO,EAAE,SAAA,CAAU,OAAA,EAAQ,GAAI,CAAA,CAAE,UAAU,OAAA,EAAQ;AAAA,IACrD,CAAC,IACD,EAAC;AAEL,IAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAE9B,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,WAAA;AAAA,QACN,OAAA,EAAS,KAAK,IAAA,IAAQ,EAAA;AAAA,QACtB,UAAA,EAAY,eAAA,CAAgB,GAAA,CAAI,CAAA,EAAA,KAAM;AAEpC,UAAA,MAAM,YACJ,EAAA,CAAG,IAAA,IAAQ,OAAO,EAAA,CAAG,SAAS,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,IAAI,CAAA,GAC5D,cAAc,EAAA,CAAG,IAA+B,IAChD,EAAA,CAAG,IAAA;AACT,UAAA,OAAO;AAAA,YACL,IAAI,EAAA,CAAG,UAAA;AAAA,YACP,IAAA,EAAM,UAAA;AAAA,YACN,QAAA,EAAU;AAAA,cACR,MAAM,EAAA,CAAG,QAAA;AAAA,cACT,WAAW,OAAO,SAAA,KAAc,WAAW,SAAA,GAAY,IAAA,CAAK,UAAU,SAAS;AAAA;AACjF,WACF;AAAA,QACF,CAAC;AAAA,OACF,CAAA;AAGD,MAAA,KAAA,MAAW,MAAM,eAAA,EAAiB;AAChC,QAAA,IAAI,EAAA,CAAG,WAAW,MAAA,EAAW;AAC3B,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,IAAA,EAAM,MAAA;AAAA,YACN,OAAA,EAAS,OAAO,EAAA,CAAG,MAAA,KAAW,QAAA,GAAW,GAAG,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,MAAM,CAAA;AAAA,YAC7E,cAAc,EAAA,CAAG;AAAA,WAClB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAA,MAAA,IAAW,KAAK,IAAA,EAAM;AAEpB,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,WAAA;AAAA,QACN,SAAS,IAAA,CAAK;AAAA,OACf,CAAA;AAAA,IACH;AAAA,EACF;AAIA,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAC,CAAA;AAChD,IAAA,MAAM,eAAgB,cAAA,EAAsC,IAAA;AAG5D,IAAA,IAAI,YAAA,IAAgB,WAAA,CAAY,IAAA,KAAS,MAAA,EAAQ;AAC/C,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,WAAA;AAAA,QACN,OAAA,EAAS;AAAA,OACV,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAO,QAAA;AACT;;;ACpBA,IAAM,iBAAA,GAAoB,MAAA;AAG1B,IAAM,oBAAA,GAA0D;AAAA,EAC9D,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,kBAAkB,GAAG,MAAA;AAAA,EAC/B,CAAC,QAAA,CAAS,yBAAyB,GAAG,UAAA;AAAA,EACtC,CAAC,QAAA,CAAS,mBAAmB,GAAG;AAClC,CAAA;AAGA,SAAS,YAAY,QAAA,EAA6E;AAChG,EAAA,OAAQ,oBAAA,CAAqB,QAAQ,CAAA,IAAa,iBAAA;AACpD;AAEO,IAAM,kBAAA,GAAN,cAAiC,gBAAA,CAMtC;AAAA,EACA,IAAA,GAAO,YAAA;AAAA;AAAA,EAGP,kBAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EAEA,WAAA,CAAY,MAAA,GAAmC,EAAC,EAAG;AAEjD,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,kBAAA;AACpD,IAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,QAAA,IAAY,OAAA,CAAQ,GAAA,CAAI,mBAAA;AAExD,IAAA,KAAA,CAAM;AAAA,MACJ,GAAG,MAAA;AAAA,MACH,MAAA,EAAQ,cAAA;AAAA,MACR,QAAA,EAAU;AAAA,KACX,CAAA;AAED,IAAA,IAAA,CAAK,kBAAA,GAAqB,CAAC,CAAC,MAAA,CAAO,gBAAA;AAEnC,IAAA,IAAI,KAAK,kBAAA,EAAoB;AAE3B,MAAA,IAAA,CAAK,kBAAkB,MAAA,CAAO,gBAAA;AAAA,IAChC,CAAA,MAAO;AAEL,MAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ;AACvB,QAAA,IAAA,CAAK,WAAA;AAAA,UACH,CAAA,+FAAA;AAAA,SACF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAc,cAAA,GAAwD;AACpE,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,OAAO,IAAA,CAAK,YAAA;AAAA,IACd;AACA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW;AAAA,QAC9B,WAAA,EAAa,IAAA,CAAK,MAAA,CAAO,WAAA,IAAe,gBAAA;AAAA,QACxC,MAAA,EAAQ,KAAK,MAAA,CAAO,MAAA;AAAA,QACpB,MAAA,EAAQ,KAAK,MAAA,CAAO,QAAA;AAAA,QACpB,GAAG,KAAK,MAAA,CAAO;AAAA,OAChB,CAAA;AACD,MAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AACpB,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,OAAO,KAAA,CAAM,kDAAA,EAAoD,EAAE,KAAA,EAAO,KAAK,CAAA;AACpF,MAAA,IAAA,CAAK,YAAY,wCAAwC,CAAA;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,KAAA,EAAkC;AACnD,IAAA,IAAI,KAAK,UAAA,EAAY;AAErB,IAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,OAAA;AACpC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,+DAAA,EAAiE;AAAA,QACjF,UAAU,KAAA,CAAM;AAAA,OACjB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAS,IAAA,CAAK,kBAAA,GAAqB,KAAK,eAAA,GAAkB,MAAM,KAAK,cAAA,EAAe;AAC1F,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,UAAA,IAAc,KAAA,CAAM,QAAA;AAEvC,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,WAAA,CAAY;AAAA,QACjB,EAAA,EAAI,KAAA;AAAA,QACJ,QAAQ,EAAE,CAAC,IAAI,GAAG,MAAM,KAAA,EAAM;AAAA,QAC9B,GAAI,MAAM,MAAA,GAAS,EAAE,SAAS,KAAA,CAAM,MAAA,KAAW,EAAC;AAAA,QAChD,QAAA,EAAU;AAAA,UACR,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,GAAI,MAAM,WAAA,GAAc,EAAE,aAAa,KAAA,CAAM,WAAA,KAAgB,EAAC;AAAA,UAC9D,GAAI,KAAA,CAAM,QAAA,IAAY;AAAC,SACzB;AAAA,QACA,MAAA,EAAQ;AAAA,OACT,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,6CAAA,EAA+C;AAAA,QAC/D,KAAA,EAAO,GAAA;AAAA,QACP,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,UAAU,KAAA,CAAM;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,UAAU,IAAA,EAAgG;AAChH,IAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,IAAA;AACzB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,gBAAA,CAAiB,IAAI,CAAA;AAK1C,IAAA,MAAM,cAAA,GAAiB,OAAO,SAAA,CAAU;AAAA,MACtC,QAAQ,IAAA,CAAK,EAAA;AAAA,MACb,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,GAAA;AAAA,MACtC,KAAA,EAAO;AAAA,QACL,IAAI,IAAA,CAAK,EAAA;AAAA;AAAA,QACT,GAAG;AAAA;AACL,KACD,CAAA;AAID,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,gBAAA;AACjD,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,cAAA;AAAA,MACN,UAAU,IAAA,CAAK,IAAA;AAAA,MACf,UAAA,EAAY,iBAAA,GAAoB,EAAC,GAAI,MAAA;AAAA,MACrC,kBAAA,EAAoB,iBAAA,mBAAoB,IAAI,GAAA,EAAI,GAAI;AAAA,KACtD;AAAA,EACF;AAAA,EAEA,MAAyB,WAAW,KAAA,EAGI;AACtC,IAAA,IAAI,KAAK,kBAAA,EAAoB;AAI3B,MAAA,IAAI,YAAA;AACJ,MAAA,IAAI;AACF,QAAA,YAAA,GAAe,IAAA,CAAK,OAAO,WAAA,IAAc;AAAA,MAC3C,SAAS,GAAA,EAAK;AACZ,QAAA,IAAA,CAAK,OAAO,KAAA,CAAM,+DAAA,EAAiE,EAAE,KAAA,EAAO,KAAK,CAAA;AAAA,MACnG;AACA,MAAA,YAAA,KAAiB,WAAA,EAAY;AAG7B,MAAA,IAAI,YAAA,IAAgB,aAAa,EAAA,EAAI;AAEnC,QAAA,OAAO,YAAA;AAAA,MACT,CAAA,MAAO;AAEL,QAAA,OAAO,IAAA,CAAK,eAAA;AAAA,MACd;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,OAAO,KAAK,cAAA,EAAe;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAyB,WAAW,IAAA,EAGQ;AAC1C,IAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAU,GAAI,IAAA;AAE5B,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,MAAM,IAAA,GAAO,UAAU,OAAA,EAAQ;AAC/B,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,OAAO,KAAK,SAAA,CAAU,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAM,CAAA;AAAA,MAC9C;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AACvC,MAAA,IAAI,MAAA,EAAQ;AAEV,QAAA,MAAM,UAAA,GAAa,MAAA,IAAU,MAAA,GAAS,MAAA,CAAO,IAAA,GAAO,MAAA;AACpD,QAAA,OAAO,KAAK,SAAA,CAAU,EAAE,MAAA,EAAQ,UAAA,EAAY,MAAM,CAAA;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAyB,YAAY,IAAA,EAGI;AACvC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA;AAE3C,IAAA,IAAI,CAAC,QAAA,EAAU;AAEb,MAAA;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,IAAA,CAAK,GAAA,CAAI,EAAE,OAAA,EAAS,IAAA,CAAK,KAAK,SAAA,CAAU,OAAA,EAAQ,GAAI,GAAA,EAAM,CAAA;AACnE,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA,EAEA,MAAyB,YAAY,IAAA,EAAgF;AACnH,IAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAU,GAAI,IAAA;AAE5B,IAAA,MAAM,WAAW,SAAA,CAAU,OAAA,CAAQ,EAAE,MAAA,EAAQ,IAAA,CAAK,IAAI,CAAA;AACtD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA;AAAA,IACF;AACA,IAAA,QAAA,CAAS,KAAK,GAAA,CAAI,IAAA,CAAK,gBAAA,CAAiB,IAAA,EAAM,KAAK,CAAC,CAAA;AAAA,EACtD;AAAA,EAEA,MAAyB,YAAY,IAAA,EAAgF;AACnH,IAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAU,GAAI,IAAA;AAE5B,IAAA,MAAM,WAAW,SAAA,CAAU,OAAA,CAAQ,EAAE,MAAA,EAAQ,IAAA,CAAK,IAAI,CAAA;AACtD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,UAAA,EAAY;AACrC,MAAA,IAAA,CAAK,uBAAA,CAAwB,MAAM,SAAS,CAAA;AAAA,IAC9C,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,SAAA,EAAW;AAC3C,MAAA,IAAA,CAAK,wBAAA,CAAyB,MAAM,SAAS,CAAA;AAAA,IAC/C;AAGA,IAAA,MAAM,OAAA,GACJ,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,gBAAA,GACnB,IAAA,CAAK,2BAAA,CAA4B,IAAA,EAAM,QAAQ,CAAA,GAC/C,IAAA,CAAK,gBAAA,CAAiB,MAAM,KAAK,CAAA;AAEvC,IAAA,QAAA,CAAS,IAAA,CAAK,IAAI,OAAO,CAAA;AAEzB,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,QAAA,CAAS,IAAA,CAAK,IAAI,EAAE,OAAA,EAAS,KAAK,OAAA,CAAQ,OAAA,EAAQ,GAAI,GAAA,EAAM,CAAA;AAAA,IAC9D,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,KAAK,GAAA,EAAI;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAyB,WAAW,IAAA,EAA6E;AAC/G,IAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAO,GAAI,IAAA;AACnC,IAAA,QAAA,CAAS,KAAK,GAAA,CAAI;AAAA,MAChB,OAAO,MAAA,CAAO,OAAA;AAAA,MACd,QAAA,EAAU,EAAE,YAAA,EAAc,MAAA;AAAO,KAClC,CAAA;AACD,IAAA,QAAA,CAAS,KAAK,GAAA,EAAI;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,2BAAA,CAA4B,QAAgB,SAAA,EAAgE;AAClH,IAAA,IAAI,SAAA,GAAgC,MAAA;AAEpC,IAAA,OAAO,SAAA,EAAW;AAChB,MAAA,MAAM,WAAW,SAAA,CAAU,WAAA,CAAY,EAAE,MAAA,EAAQ,WAAW,CAAA;AAC5D,MAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AAEtB,MAAA,MAAM,iBAAiB,SAAA,CAAU,OAAA,CAAQ,EAAE,MAAA,EAAQ,UAAU,CAAA;AAC7D,MAAA,IAAI,cAAA,EAAgB,QAAA,KAAa,QAAA,CAAS,gBAAA,EAAkB;AAC1D,QAAA,OAAO,cAAA;AAAA,MACT;AACA,MAAA,SAAA,GAAY,QAAA;AAAA,IACd;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAA,CAAwB,MAAuB,SAAA,EAAsC;AAC3F,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,2BAAA,CAA4B,IAAA,CAAK,IAAI,SAAS,CAAA;AAC5E,IAAA,IAAI,CAAC,kBAAkB,UAAA,EAAY;AACjC,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AAGpB,IAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AAExB,IAAA,MAAM,QAAA,GAA2B;AAAA,MAC/B,YAAY,IAAA,CAAK,EAAA;AAAA,MACjB,SAAA,EAAW,YAAY,SAAA,IAAa,CAAA;AAAA,MACpC,MAAM,MAAA,EAAQ,IAAA;AAAA,MACd,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,GAAA,CAAI,CAAA,EAAA,MAAO;AAAA,QACvC,YAAY,EAAA,CAAG,UAAA;AAAA,QACf,UAAU,EAAA,CAAG,QAAA;AAAA,QACb,MAAM,EAAA,CAAG;AAAA,OACX,CAAE;AAAA,KACJ;AAEA,IAAA,gBAAA,CAAiB,UAAA,CAAW,KAAK,QAAQ,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,wBAAA,CAAyB,MAAuB,SAAA,EAAsC;AAC5F,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,2BAAA,CAA4B,IAAA,CAAK,IAAI,SAAS,CAAA;AAC5E,IAAA,IAAI,CAAC,kBAAkB,kBAAA,EAAoB;AACzC,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,IAAA,MAAM,aAAa,KAAA,EAAO,UAAA;AAC1B,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA;AAAA,IACF;AAGA,IAAA,gBAAA,CAAiB,kBAAA,CAAmB,IAAI,UAAA,EAAY;AAAA,MAClD,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,2BAAA,CAA4B,MAAuB,QAAA,EAAmD;AAC5G,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,gBAAA,CAAiB,IAAA,EAAM,KAAK,CAAA;AAGrD,IAAA,MAAM,aAAa,QAAA,CAAS,UAAA;AAC5B,IAAA,IAAI,CAAC,UAAA,IAAc,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAC1C,MAAA,OAAO,WAAA;AAAA,IACT;AAGA,IAAA,IAAI,QAAA,CAAS,kBAAA,IAAsB,QAAA,CAAS,kBAAA,CAAmB,OAAO,CAAA,EAAG;AACvE,MAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,QAAA,IAAI,KAAK,SAAA,EAAW;AAClB,UAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,YAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,kBAAA,CAAmB,GAAA,CAAI,SAAS,UAAU,CAAA;AACzE,YAAA,IAAI,aAAA,EAAe;AACjB,cAAA,QAAA,CAAS,SAAS,aAAA,CAAc,MAAA;AAChC,cAAA,QAAA,CAAS,YAAY,aAAA,CAAc,SAAA;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,MAAM,YAAA,GAAe,WAAW,IAAA,CAAK,CAAA,IAAA,KAAQ,KAAK,SAAA,IAAa,IAAA,CAAK,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA;AACxF,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,OAAO,WAAA;AAAA,IACT;AAGA,IAAA,MAAM,mBAAA,GAAsB,uBAAA,CAAwB,UAAA,EAAY,IAAA,CAAK,MAAM,CAAA;AAC3E,IAAA,OAAO;AAAA,MACL,GAAG,WAAA;AAAA,MACH,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,cAAA,CAAe,OAAgB,QAAA,EAA6B;AAClE,IAAA,IAAI,QAAA,KAAa,SAAS,gBAAA,EAAkB;AAE1C,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,QAAA,OAAO,MAAM,GAAA,CAAI,CAAC,GAAA,KAAiB,mBAAA,CAAoB,GAAG,CAAC,CAAA;AAAA,MAC7D;AAGA,MAAA,IACE,KAAA,IACA,OAAO,KAAA,KAAU,QAAA,IACjB,UAAA,IAAc,SACd,KAAA,CAAM,OAAA,CAAS,KAAA,CAAkC,QAAQ,CAAA,EACzD;AACA,QAAA,OAAQ,MAAkC,QAAA,CAAS,GAAA,CAAI,CAAC,GAAA,KAAiB,mBAAA,CAAoB,GAAG,CAAC,CAAA;AAAA,MACnG;AAAA,IACF;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAA,CAAgB,QAAa,QAAA,EAAyB;AAC5D,IAAA,IAAI,QAAA,KAAa,SAAS,gBAAA,EAAkB;AAC1C,MAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACzC,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,MAAM,EAAE,IAAA,EAAM,GAAG,IAAA,EAAK,GAAI,MAAA;AAE1B,MAAA,OAAO,EAAE,MAAM,WAAA,EAAa,OAAA,EAAS,MAAM,GAAG,aAAA,CAAc,IAAI,CAAA,EAAE;AAAA,IACpE;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,WAAW,IAAA,EAAgC;AACjD,IAAA,OACE,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,SAAA,IACvB,IAAA,CAAK,SAAS,QAAA,CAAS,aAAA,IACvB,IAAA,CAAK,IAAA,KAAS,QAAA,CAAS,kBAAA;AAAA,EAE3B;AAAA,EAEQ,YAAY,IAAA,EAA+B;AACjD,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,OAAO,IAAA,CAAK,UAAA;AAAA,IACd;AACA,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AACxC,IAAA,OAAO,KAAA,GAAQ,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA;AAAA,EAC5B;AAAA,EAEQ,cAAc,IAAA,EAA+B;AACnD,IAAA,MAAM,QAAQ,IAAA,CAAK,UAAA;AACnB,IAAA,OAAO,KAAA,EAAO,UAAA,IAAe,IAAA,CAAK,KAAA,EAA+C,cAAc,IAAA,CAAK,EAAA;AAAA,EACtG;AAAA,EAEQ,gBAAgB,IAAA,EAAwC;AAC9D,IAAA,MAAM,OAAO,IAAA,CAAK,KAAA;AAClB,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,MAAA,UAAA,GAAa,IAAA;AAAA,IACf,CAAA,MAAO;AACL,MAAA,IAAI;AACF,QAAA,UAAA,GAAa,IAAA,CAAK,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAAA,MACxC,CAAA,CAAA,MAAQ;AACN,QAAA,UAAA,GAAa,yBAAA;AAAA,MACf;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,WAAA;AAAA,QACN,OAAA,EAAS,EAAA;AAAA,QACT,UAAA,EAAY;AAAA,UACV;AAAA,YACE,EAAA,EAAI,IAAA,CAAK,aAAA,CAAc,IAAI,CAAA;AAAA,YAC3B,IAAA,EAAM,UAAA;AAAA,YACN,QAAA,EAAU;AAAA,cACR,IAAA,EAAM,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA;AAAA,cAC3B,SAAA,EAAW;AAAA;AACb;AACF;AACF;AACF,KACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,IAAA,EAAsC;AAC7D,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,mBAAA,CAAoB,IAAA,CAAK,MAAM,CAAA;AAAA,MACxC,YAAA,EAAc,IAAA,CAAK,aAAA,CAAc,IAAI;AAAA,KACvC;AAAA,EACF;AAAA,EAEQ,gBAAA,CAAiB,IAAA,EAAuB,QAAA,GAAW,IAAA,EAA2B;AACpF,IAAA,MAAM,UAA+B,EAAC;AAEtC,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA;AAEvC,IAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAW;AAC5B,MAAA,OAAA,CAAQ,KAAA,GAAQ,UAAA,GAAa,IAAA,CAAK,eAAA,CAAgB,IAAI,CAAA,GAAI,IAAA,CAAK,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,IAAI,CAAA;AAAA,IACrG;AAEA,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAW;AAC7B,MAAA,OAAA,CAAQ,MAAA,GAAS,UAAA,GAAa,IAAA,CAAK,gBAAA,CAAiB,IAAI,CAAA,GAAI,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,IAAI,CAAA;AAAA,IACzG;AAEA,IAAA,IAAI,QAAA,IAAY,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,MAAM,MAAA,EAAQ;AACpD,MAAA,OAAA,CAAQ,OAAO,IAAA,CAAK,IAAA;AAAA,IACtB;AAGA,IAAA,OAAA,CAAQ,UAAU,EAAC;AAEnB,IAAA,OAAA,CAAQ,QAAA,GAAW;AAAA,MACjB,GAAG,IAAA,CAAK,QAAA;AAAA,MACR,UAAU,IAAA,CAAK;AAAA,KACjB;AAEA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAA,CAAQ,QAAA,CAAS,iBAAiB,CAAA,GAAI,IAAA,CAAK,OAAA;AAAA,IAC7C;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;AACjC,QAAA,OAAA,CAAQ,QAAA,CAAS,QAAQ,SAAA,CAAU,KAAA;AAAA,MACrC;AAGA,MAAA,IAAI,SAAA,CAAU,aAAa,MAAA,EAAW;AACpC,QAAA,OAAA,CAAQ,QAAA,CAAS,WAAW,SAAA,CAAU,QAAA;AAAA,MACxC;AAIA,MAAA,IAAI,SAAA,CAAU,kBAAkB,MAAA,EAAW;AACzC,QAAA,OAAA,CAAQ,QAAA,CAAS,QAAQ,SAAA,CAAU,aAAA;AAAA,MACrC;AAGA,MAAA,OAAA,CAAQ,OAAA,GAAU,kBAAA,CAAmB,SAAA,CAAU,KAAK,CAAA;AAIpD,MAAA,IAAI,UAAU,mBAAA,EAAqB;AACjC,QAAA,OAAA,CAAQ,OAAA,CAAQ,uBACb,SAAA,CAAU,mBAAA,CAAoB,SAAQ,GAAI,IAAA,CAAK,SAAA,CAAU,OAAA,EAAQ,IAAK,GAAA;AAAA,MAC3E;AAGA,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;AAAA,QAC3C,OAAA;AAAA,QACA,eAAA;AAAA,QACA,OAAA;AAAA,QACA,YAAA;AAAA,QACA;AAAA,OACD,CAAA;AACD,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;AAGA,IAAA,IAAI,OAAO,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAA,CAAE,WAAW,CAAA,EAAG;AAC7C,MAAA,OAAO,OAAA,CAAQ,OAAA;AAAA,IACjB;AAGA,IAAA,OAAA,CAAQ,QAAA,GAAW,aAAA,CAAc,OAAA,CAAQ,QAAQ,CAAA;AAEjD,IAAA,OAAO,OAAA;AAAA,EACT;AACF","file":"index.js","sourcesContent":["/**\n * Message format conversion utilities for Braintrust.\n *\n * Converts AI SDK message format (v4/v5) to OpenAI Chat Completion format,\n * which Braintrust requires for proper rendering of threads.\n */\n\n// ==============================================================================\n// Utility functions\n// ==============================================================================\n\n/**\n * Remove null and undefined values from an object (shallow)\n */\nexport function removeNullish<T extends Record<string, unknown>>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null)) as Partial<T>;\n}\n\n// ==============================================================================\n// Type definitions for AI SDK message format conversion to OpenAI format\n// ==============================================================================\n\n/**\n * AI SDK content part types (both v4 and v5)\n */\ninterface AISDKTextPart {\n type: 'text';\n text: string;\n}\n\ninterface AISDKImagePart {\n type: 'image';\n image?: string | Uint8Array | URL;\n mimeType?: string;\n}\n\ninterface AISDKFilePart {\n type: 'file';\n data?: string | Uint8Array | URL;\n filename?: string;\n name?: string;\n mimeType?: string;\n}\n\ninterface AISDKReasoningPart {\n type: 'reasoning';\n text?: string;\n}\n\ninterface AISDKToolCallPart {\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n args?: unknown; // AI SDK v4\n input?: unknown; // AI SDK v5\n}\n\ninterface AISDKToolResultPart {\n type: 'tool-result';\n toolCallId: string;\n result?: unknown; // AI SDK v4\n output?: unknown; // AI SDK v5\n}\n\ntype AISDKContentPart =\n | AISDKTextPart\n | AISDKImagePart\n | AISDKFilePart\n | AISDKReasoningPart\n | AISDKToolCallPart\n | AISDKToolResultPart\n | { type: string; [key: string]: unknown }; // Catch-all for unknown types\n\n/**\n * AI SDK message format (input format for conversion)\n */\ninterface AISDKMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string | AISDKContentPart[];\n [key: string]: unknown; // Allow additional properties\n}\n\n/**\n * OpenAI Chat Completion tool call format\n */\nexport interface OpenAIToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * OpenAI Chat Completion message format (output format)\n */\nexport interface OpenAIMessage {\n role: 'user' | 'assistant' | 'system' | 'tool';\n content: string;\n tool_calls?: OpenAIToolCall[];\n tool_call_id?: string;\n [key: string]: unknown; // Allow additional properties\n}\n\n// ==============================================================================\n// Message conversion functions\n// ==============================================================================\n\n/**\n * Converts a content part to a string representation.\n * Handles text, image, file, reasoning, and other content types.\n */\nfunction convertContentPart(part: AISDKContentPart | null | undefined): string | null {\n if (!part || typeof part !== 'object') {\n return null;\n }\n\n switch (part.type) {\n case 'text':\n return (part as AISDKTextPart).text || null;\n\n case 'image':\n // Represent image content with a placeholder\n return '[image]';\n\n case 'file': {\n // Represent file content with filename if available\n const filePart = part as AISDKFilePart;\n if (filePart.filename || filePart.name) {\n return `[file: ${filePart.filename || filePart.name}]`;\n }\n return '[file]';\n }\n\n case 'reasoning': {\n // Represent reasoning/thinking content\n const reasoningPart = part as AISDKReasoningPart;\n if (typeof reasoningPart.text === 'string' && reasoningPart.text.length > 0) {\n return `[reasoning: ${reasoningPart.text.substring(0, 100)}${reasoningPart.text.length > 100 ? '...' : ''}]`;\n }\n return '[reasoning]';\n }\n\n case 'tool-call':\n // Tool calls are handled separately in assistant messages\n return null;\n\n case 'tool-result':\n // Tool results are handled separately in tool messages\n return null;\n\n default: {\n // For unknown types, try to extract any text-like content\n const unknownPart = part as { type?: string; text?: string; content?: string };\n if (typeof unknownPart.text === 'string') {\n return unknownPart.text;\n }\n if (typeof unknownPart.content === 'string') {\n return unknownPart.content;\n }\n // Represent unknown content type\n return `[${unknownPart.type || 'unknown'}]`;\n }\n }\n}\n\n/**\n * Serializes tool result data to a string for OpenAI format.\n */\nexport function serializeToolResult(resultData: unknown): string {\n if (typeof resultData === 'string') {\n return resultData;\n }\n if (resultData && typeof resultData === 'object' && 'value' in resultData) {\n const valueData = (resultData as { value: unknown }).value;\n return typeof valueData === 'string' ? valueData : JSON.stringify(valueData);\n }\n if (resultData === undefined || resultData === null) {\n return '';\n }\n try {\n return JSON.stringify(resultData);\n } catch {\n return '[unserializable result]';\n }\n}\n\n/**\n * Converts AI SDK message format to OpenAI Chat Completion format for Braintrust.\n *\n * Supports both AI SDK v4 and v5 formats:\n * - v4 uses 'args' for tool calls and 'result' for tool results\n * - v5 uses 'input' for tool calls and 'output' for tool results\n *\n * AI SDK format:\n * { role: \"user\", content: [{ type: \"text\", text: \"hello\" }] }\n * { role: \"assistant\", content: [{ type: \"text\", text: \"...\" }, { type: \"tool-call\", toolCallId: \"...\", toolName: \"...\", args: {...} }] }\n * { role: \"tool\", content: [{ type: \"tool-result\", toolCallId: \"...\", result: {...} }] }\n *\n * OpenAI format (what Braintrust expects):\n * { role: \"user\", content: \"hello\" }\n * { role: \"assistant\", content: \"...\", tool_calls: [{ id: \"...\", type: \"function\", function: { name: \"...\", arguments: \"...\" } }] }\n * { role: \"tool\", content: \"result\", tool_call_id: \"...\" }\n */\nexport function convertAISDKMessage(message: AISDKMessage | OpenAIMessage | unknown): OpenAIMessage | unknown {\n if (!message || typeof message !== 'object') {\n return message;\n }\n\n const { role, content, ...rest } = message as AISDKMessage;\n\n // If content is already a string, return as-is (already in OpenAI format)\n if (typeof content === 'string') {\n return message;\n }\n\n // If content is an array (AI SDK format), convert based on role\n if (Array.isArray(content)) {\n // Handle empty content arrays\n if (content.length === 0) {\n return { role, content: '', ...rest };\n }\n\n // For user/system messages, extract text and represent non-text content\n if (role === 'user' || role === 'system') {\n const contentParts = content.map((part: AISDKContentPart) => convertContentPart(part)).filter(Boolean);\n\n return {\n role,\n content: contentParts.length > 0 ? contentParts.join('\\n') : '',\n ...rest,\n };\n }\n\n // For assistant messages, extract text, non-text content, AND tool calls\n if (role === 'assistant') {\n const contentParts = content\n .filter((part: AISDKContentPart) => part?.type !== 'tool-call')\n .map((part: AISDKContentPart) => convertContentPart(part))\n .filter(Boolean);\n\n const toolCallParts = content.filter((part: AISDKContentPart) => part?.type === 'tool-call');\n\n const result: OpenAIMessage = {\n role,\n content: contentParts.length > 0 ? (contentParts as string[]).join('\\n') : '',\n ...rest,\n };\n\n // Add tool_calls array if there are tool calls\n if (toolCallParts.length > 0) {\n result.tool_calls = toolCallParts.map((tc: AISDKContentPart) => {\n const toolCall = tc as AISDKToolCallPart;\n const toolCallId = toolCall.toolCallId;\n const toolName = toolCall.toolName;\n // Support both v4 'args' and v5 'input'\n const args = toolCall.args ?? toolCall.input;\n\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else if (args !== undefined && args !== null) {\n argsString = JSON.stringify(args);\n } else {\n argsString = '{}';\n }\n\n return {\n id: toolCallId,\n type: 'function' as const,\n function: {\n name: toolName,\n arguments: argsString,\n },\n };\n });\n }\n\n return result;\n }\n\n // For tool messages, convert to OpenAI tool message format\n if (role === 'tool') {\n const toolResult = content.find((part): part is AISDKToolResultPart => part?.type === 'tool-result');\n if (toolResult) {\n // Support both v4 'result' and v5 'output' fields\n const resultData = toolResult.output ?? toolResult.result;\n const resultContent = serializeToolResult(resultData);\n\n return {\n role: 'tool',\n content: resultContent,\n tool_call_id: toolResult.toolCallId,\n } as OpenAIMessage;\n }\n }\n }\n\n return message;\n}\n","import type { UsageStats } from '@mastra/core/observability';\n\n/**\n * BraintrustUsageMetrics\n *\n * Canonical metric keys expected by Braintrust for LLM usage accounting.\n */\nexport interface BraintrustUsageMetrics {\n prompt_tokens?: number;\n completion_tokens?: number;\n tokens?: number;\n completion_reasoning_tokens?: number;\n prompt_cached_tokens?: number;\n prompt_cache_creation_tokens?: number;\n}\n\n/**\n * Formats UsageStats to Braintrust's expected metric format.\n */\nexport function formatUsageMetrics(usage?: UsageStats): BraintrustUsageMetrics {\n const metrics: BraintrustUsageMetrics = {};\n\n if (usage?.inputTokens !== undefined) {\n metrics.prompt_tokens = usage.inputTokens;\n }\n\n if (usage?.outputTokens !== undefined) {\n metrics.completion_tokens = usage.outputTokens;\n }\n\n // Compute total if we have both\n if (metrics.prompt_tokens !== undefined && metrics.completion_tokens !== undefined) {\n metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;\n }\n\n if (usage?.outputDetails?.reasoning !== undefined) {\n metrics.completion_reasoning_tokens = usage.outputDetails.reasoning;\n }\n\n if (usage?.inputDetails?.cacheRead !== undefined) {\n metrics.prompt_cached_tokens = usage.inputDetails.cacheRead;\n }\n\n if (usage?.inputDetails?.cacheWrite !== undefined) {\n metrics.prompt_cache_creation_tokens = usage.inputDetails.cacheWrite;\n }\n\n return metrics;\n}\n","/**\n * Thread view reconstruction for Braintrust.\n *\n * Reconstructs LLM output in OpenAI Chat Completion format by examining\n * child MODEL_STEP and TOOL_CALL spans. This enables Braintrust's Thread\n * view to properly display the full conversation flow including tool calls.\n *\n * See THREAD_VIEW_RECONSTRUCTION.md for details.\n */\n\nimport { removeNullish } from './formatter';\nimport type { OpenAIMessage } from './formatter';\n\n// ==============================================================================\n// Thread view reconstruction types\n// ==============================================================================\n\n/**\n * Tool call data accumulated from MODEL_STEP and TOOL_CALL spans\n */\nexport interface ThreadToolCall {\n toolCallId: string;\n toolName: string;\n args: unknown;\n result?: unknown; // filled in when TOOL_CALL ends\n startTime?: Date; // from TOOL_CALL span, for ordering multiple tool calls within a step\n}\n\n/**\n * Step data accumulated from MODEL_STEP spans for Thread view reconstruction\n */\nexport interface ThreadStepData {\n stepSpanId: string;\n stepIndex: number; // for ordering steps correctly\n text?: string;\n toolCalls?: ThreadToolCall[];\n}\n\n/**\n * Accumulated data for reconstructing Braintrust Thread view.\n * Populated for MODEL_GENERATION spans as child MODEL_STEP and TOOL_CALL spans complete.\n */\nexport type ThreadData = ThreadStepData[];\n\n/**\n * Tool result data stored when TOOL_CALL spans end (before MODEL_STEP ends)\n */\nexport interface PendingToolResult {\n result: unknown;\n startTime: Date;\n}\n\n// ==============================================================================\n// Thread view reconstruction\n// ==============================================================================\n\n/**\n * Reconstruct the Thread view output from accumulated threadData.\n * Converts to OpenAI Chat Completion message format.\n */\nexport function reconstructThreadOutput(threadData: ThreadData, originalOutput: unknown): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n\n // Sort steps by stepIndex\n const sortedSteps = [...threadData].sort((a, b) => a.stepIndex - b.stepIndex);\n\n for (const step of sortedSteps) {\n // Sort tool calls by startTime within each step\n const sortedToolCalls = step.toolCalls\n ? [...step.toolCalls].sort((a, b) => {\n if (!a.startTime || !b.startTime) return 0;\n return a.startTime.getTime() - b.startTime.getTime();\n })\n : [];\n\n if (sortedToolCalls.length > 0) {\n // Add assistant message with tool_calls\n messages.push({\n role: 'assistant',\n content: step.text || '',\n tool_calls: sortedToolCalls.map(tc => {\n // Clean null/undefined values from args before stringifying\n const cleanArgs =\n tc.args && typeof tc.args === 'object' && !Array.isArray(tc.args)\n ? removeNullish(tc.args as Record<string, unknown>)\n : tc.args;\n return {\n id: tc.toolCallId,\n type: 'function' as const,\n function: {\n name: tc.toolName,\n arguments: typeof cleanArgs === 'string' ? cleanArgs : JSON.stringify(cleanArgs),\n },\n };\n }),\n });\n\n // Add tool messages for each result\n for (const tc of sortedToolCalls) {\n if (tc.result !== undefined) {\n messages.push({\n role: 'tool',\n content: typeof tc.result === 'string' ? tc.result : JSON.stringify(tc.result),\n tool_call_id: tc.toolCallId,\n });\n }\n }\n } else if (step.text) {\n // Step with text only (final response)\n messages.push({\n role: 'assistant',\n content: step.text,\n });\n }\n }\n\n // If we have messages and the last one is a tool message,\n // add the final assistant text from original output\n if (messages.length > 0) {\n const lastMessage = messages[messages.length - 1]!;\n const originalText = (originalOutput as { text?: string })?.text;\n\n // If the last message is a tool response and we have final text, add it\n if (originalText && lastMessage.role === 'tool') {\n messages.push({\n role: 'assistant',\n content: originalText,\n });\n }\n }\n\n return messages;\n}\n","/**\n * Braintrust Exporter for Mastra Observability\n *\n * This exporter sends observability data to Braintrust.\n * Root spans become top-level Braintrust spans (no trace wrapper).\n * Events are handled as zero-duration spans with matching start/end times.\n */\n\nimport type { AnyExportedSpan, ModelGenerationAttributes, ScoreEvent, SpanErrorInfo } from '@mastra/core/observability';\nimport { SpanType } from '@mastra/core/observability';\nimport { omitKeys } from '@mastra/core/utils';\nimport { TrackingExporter } from '@mastra/observability';\nimport type { TraceData, TrackingExporterConfig } from '@mastra/observability';\nimport { initLogger, currentSpan } from 'braintrust';\nimport { removeNullish, convertAISDKMessage, serializeToolResult } from './formatter';\nimport type { OpenAIMessage } from './formatter';\nimport { formatUsageMetrics } from './metrics';\nimport { reconstructThreadOutput } from './thread-reconstruction';\nimport type { ThreadData, ThreadStepData, PendingToolResult } from './thread-reconstruction';\n\ntype BraintrustSpanType = 'llm' | 'score' | 'function' | 'eval' | 'task' | 'tool';\n\n/**\n * The subset of a Braintrust span used by the exporter.\n *\n * This structural interface lets applications provide spans from a different\n * compatible Braintrust SDK instance without coupling Mastra's public types to\n * a specific SDK version.\n */\nexport interface BraintrustSpan {\n id: string;\n startSpan(args: {\n spanId: string;\n name: string;\n type: BraintrustSpanType;\n startTime: number;\n event: Record<string, any>;\n }): BraintrustSpan;\n log(event: Record<string, any>): void;\n end(args?: { endTime?: number }): number;\n}\n\n/**\n * The subset of a Braintrust logger used by the exporter.\n *\n * Logger instances from compatible Braintrust SDK versions satisfy this\n * interface without sharing the same nominal SDK types as the exporter.\n */\nexport interface BraintrustLogger {\n startSpan(args: {\n spanId: string;\n name: string;\n type: BraintrustSpanType;\n startTime: number;\n event: Record<string, any>;\n }): BraintrustSpan;\n logFeedback(event: {\n id: string;\n scores: Record<string, number>;\n comment?: string;\n metadata?: Record<string, any>;\n source: 'external';\n }): void;\n}\n\n/**\n * Extended Braintrust span data that includes span type and thread reconstruction data\n */\ninterface BraintrustSpanData {\n span: BraintrustSpan;\n spanType: SpanType;\n threadData?: ThreadData; // only populated for MODEL_GENERATION spans\n // Tool results stored when TOOL_CALL ends (may arrive before MODEL_STEP ends)\n pendingToolResults?: Map<string, PendingToolResult>; // keyed by toolCallId\n}\n\nexport interface BraintrustExporterConfig extends TrackingExporterConfig {\n /**\n * Optional Braintrust logger instance.\n * When provided, enables integration with Braintrust contexts such as:\n * - Evals: Agent traces nest inside eval task spans\n * - logger.traced(): Agent traces nest inside traced spans\n * - Parent spans: Auto-detects and attaches to external Braintrust spans\n */\n braintrustLogger?: BraintrustLogger;\n\n /**\n * Optional resolver for the active Braintrust span.\n *\n * Pass Braintrust's `currentSpan` from the same package instance that creates\n * `Eval()` or `logger.traced()` spans when your app and Mastra may resolve\n * different copies of the `braintrust` package.\n */\n currentSpan?: () => BraintrustSpan | undefined;\n\n /** Braintrust API key. Required if logger is not provided. */\n apiKey?: string;\n /** Optional custom endpoint */\n endpoint?: string;\n /** Braintrust project name (default: 'mastra-tracing') */\n projectName?: string;\n /** Support tuning parameters */\n tuningParameters?: Record<string, any>;\n}\n\ntype BraintrustRoot = BraintrustLogger | BraintrustSpan;\ntype BraintrustTrackedSpan = BraintrustSpanData;\ntype BraintrustEvent = BraintrustSpan;\ntype BraintrustMetadata = unknown;\ntype BraintrustTraceData = TraceData<BraintrustRoot, BraintrustTrackedSpan, BraintrustEvent, BraintrustMetadata>;\n\n// Default span type for all spans\nconst DEFAULT_SPAN_TYPE = 'task';\n\n// Exceptions to the default mapping\nconst SPAN_TYPE_EXCEPTIONS: Partial<Record<SpanType, string>> = {\n [SpanType.MODEL_GENERATION]: 'llm',\n [SpanType.TOOL_CALL]: 'tool',\n [SpanType.MCP_TOOL_CALL]: 'tool',\n [SpanType.PROVIDER_TOOL_CALL]: 'tool',\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: 'function',\n [SpanType.WORKFLOW_WAIT_EVENT]: 'function',\n};\n\n// Mapping function - returns valid Braintrust span types\nfunction mapSpanType(spanType: SpanType): 'llm' | 'score' | 'function' | 'eval' | 'task' | 'tool' {\n return (SPAN_TYPE_EXCEPTIONS[spanType] as any) ?? DEFAULT_SPAN_TYPE;\n}\n\nexport class BraintrustExporter extends TrackingExporter<\n BraintrustRoot,\n BraintrustTrackedSpan,\n BraintrustEvent,\n BraintrustMetadata,\n BraintrustExporterConfig\n> {\n name = 'braintrust';\n\n // Flags and logger for context-aware mode\n #useProvidedLogger: boolean;\n #providedLogger?: BraintrustLogger;\n #localLogger?: BraintrustLogger;\n\n constructor(config: BraintrustExporterConfig = {}) {\n // Resolve env vars BEFORE calling super (config is readonly in base class)\n const resolvedApiKey = config.apiKey ?? process.env.BRAINTRUST_API_KEY;\n const resolvedEndpoint = config.endpoint ?? process.env.BRAINTRUST_ENDPOINT;\n\n super({\n ...config,\n apiKey: resolvedApiKey,\n endpoint: resolvedEndpoint,\n });\n\n this.#useProvidedLogger = !!config.braintrustLogger;\n\n if (this.#useProvidedLogger) {\n // Use provided logger - enables Braintrust context integration\n this.#providedLogger = config.braintrustLogger;\n } else {\n // Validate apiKey for creating loggers per trace\n if (!this.config.apiKey) {\n this.setDisabled(\n `Missing required API key. Set BRAINTRUST_API_KEY environment variable or pass apiKey in config.`,\n );\n return;\n }\n // lazy create logger on first rootSpan\n this.#localLogger = undefined;\n }\n }\n\n private async getLocalLogger(): Promise<BraintrustLogger | undefined> {\n if (this.#localLogger) {\n return this.#localLogger;\n }\n try {\n const logger = await initLogger({\n projectName: this.config.projectName ?? 'mastra-tracing',\n apiKey: this.config.apiKey,\n appUrl: this.config.endpoint,\n ...this.config.tuningParameters,\n });\n this.#localLogger = logger;\n return logger;\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to initialize logger', { error: err });\n this.setDisabled('Failed to initialize Braintrust logger');\n }\n }\n\n async onScoreEvent(event: ScoreEvent): Promise<void> {\n if (this.isDisabled) return;\n\n const { score } = event;\n const rowId = score.spanId ?? score.traceId;\n if (!rowId) {\n this.logger.debug('Braintrust exporter: skipping score with no spanId or traceId', {\n scorerId: score.scorerId,\n });\n return;\n }\n\n const logger = this.#useProvidedLogger ? this.#providedLogger : await this.getLocalLogger();\n if (!logger) return;\n\n const name = score.scorerName ?? score.scorerId;\n\n try {\n logger.logFeedback({\n id: rowId,\n scores: { [name]: score.score },\n ...(score.reason ? { comment: score.reason } : {}),\n metadata: {\n scorerId: score.scorerId,\n ...(score.scoreSource ? { scoreSource: score.scoreSource } : {}),\n ...(score.metadata ?? {}),\n },\n source: 'external',\n });\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to submit score', {\n error: err,\n traceId: score.traceId,\n spanId: score.spanId,\n scorerId: score.scorerId,\n });\n }\n }\n\n private startSpan(args: { parent: BraintrustSpan | BraintrustLogger; span: AnyExportedSpan }): BraintrustSpanData {\n const { parent, span } = args;\n const payload = this.buildSpanPayload(span);\n\n // Braintrust's startSpan() accepts data properties via the `event` parameter\n // which maps to StartSpanEventArgs (ExperimentLogPartialArgs & Partial<IdField>)\n // This includes: input, output, metadata, metrics, tags, scores, error, etc.\n const braintrustSpan = parent.startSpan({\n spanId: span.id,\n name: span.name,\n type: mapSpanType(span.type),\n startTime: span.startTime.getTime() / 1000,\n event: {\n id: span.id, // Use Mastra span ID as Braintrust row ID for logFeedback() compatibility\n ...payload,\n },\n });\n\n // Create BraintrustSpanData with span type for tree walking\n // Initialize threadData and pendingToolResults for MODEL_GENERATION spans (used for Thread view reconstruction)\n const isModelGeneration = span.type === SpanType.MODEL_GENERATION;\n return {\n span: braintrustSpan,\n spanType: span.type,\n threadData: isModelGeneration ? [] : undefined,\n pendingToolResults: isModelGeneration ? new Map() : undefined,\n };\n }\n\n protected override async _buildRoot(_args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustRoot | undefined> {\n if (this.#useProvidedLogger) {\n // Try to find a Braintrust span to attach to:\n // 1. Auto-detect from Braintrust's current span (logger.traced(), Eval(), etc.)\n // 2. Fall back to the configured logger\n let externalSpan: BraintrustSpan | undefined;\n try {\n externalSpan = this.config.currentSpan?.();\n } catch (err) {\n this.logger.error('Braintrust exporter: Failed to resolve configured currentSpan', { error: err });\n }\n externalSpan ??= currentSpan();\n\n // Check if it's a valid span (not the NOOP_SPAN)\n if (externalSpan && externalSpan.id) {\n // External span detected - attach Mastra traces to it\n return externalSpan;\n } else {\n // No external span - use provided logger\n return this.#providedLogger!;\n }\n } else {\n // Use the local logger\n return this.getLocalLogger();\n }\n }\n\n protected override async _buildSpan(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustSpanData | undefined> {\n const { span, traceData } = args;\n\n if (span.isRootSpan) {\n const root = traceData.getRoot();\n if (root) {\n return this.startSpan({ parent: root, span });\n }\n } else {\n const parent = traceData.getParent(args);\n if (parent) {\n // Parent could be BraintrustSpanData (has .span) or BraintrustRoot (Logger/Span, no .span)\n const parentSpan = 'span' in parent ? parent.span : parent;\n return this.startSpan({ parent: parentSpan, span });\n }\n }\n }\n\n protected override async _buildEvent(args: {\n span: AnyExportedSpan;\n traceData: BraintrustTraceData;\n }): Promise<BraintrustEvent | undefined> {\n const spanData = await this._buildSpan(args);\n\n if (!spanData) {\n // parent doesn't exist and not creating rootSpan, return early data\n return;\n }\n\n spanData.span.end({ endTime: args.span.startTime.getTime() / 1000 });\n return spanData.span;\n }\n\n protected override async _updateSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n spanData.span.log(this.buildSpanPayload(span, false));\n }\n\n protected override async _finishSpan(args: { span: AnyExportedSpan; traceData: BraintrustTraceData }): Promise<void> {\n const { span, traceData } = args;\n\n const spanData = traceData.getSpan({ spanId: span.id });\n if (!spanData) {\n return;\n }\n\n // Handle thread data accumulation for MODEL_STEP and TOOL_CALL spans\n if (span.type === SpanType.MODEL_STEP) {\n this.accumulateModelStepData(span, traceData);\n } else if (span.type === SpanType.TOOL_CALL) {\n this.accumulateToolCallResult(span, traceData);\n }\n\n // Build payload - for MODEL_GENERATION, may reconstruct output from threadData\n const payload =\n span.type === SpanType.MODEL_GENERATION\n ? this.buildModelGenerationPayload(span, spanData)\n : this.buildSpanPayload(span, false);\n\n spanData.span.log(payload);\n\n if (span.endTime) {\n spanData.span.end({ endTime: span.endTime.getTime() / 1000 });\n } else {\n spanData.span.end();\n }\n }\n\n protected override async _abortSpan(args: { span: BraintrustTrackedSpan; reason: SpanErrorInfo }): Promise<void> {\n const { span: spanData, reason } = args;\n spanData.span.log({\n error: reason.message,\n metadata: { errorDetails: reason },\n });\n spanData.span.end();\n }\n\n // ==============================================================================\n // Thread view reconstruction helpers\n // ==============================================================================\n\n /**\n * Walk up the tree to find the MODEL_GENERATION ancestor span.\n * Returns the BraintrustSpanData if found, undefined otherwise.\n */\n private findModelGenerationAncestor(spanId: string, traceData: BraintrustTraceData): BraintrustSpanData | undefined {\n let currentId: string | undefined = spanId;\n\n while (currentId) {\n const parentId = traceData.getParentId({ spanId: currentId });\n if (!parentId) return undefined;\n\n const parentSpanData = traceData.getSpan({ spanId: parentId });\n if (parentSpanData?.spanType === SpanType.MODEL_GENERATION) {\n return parentSpanData;\n }\n currentId = parentId;\n }\n\n return undefined;\n }\n\n /**\n * Accumulate MODEL_STEP data to the parent MODEL_GENERATION's threadData.\n * Called when a MODEL_STEP span ends.\n */\n private accumulateModelStepData(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.threadData) {\n return;\n }\n\n // Extract step data from MODEL_STEP output and attributes\n const output = span.output as\n | { text?: string; toolCalls?: Array<{ toolCallId: string; toolName: string; args: unknown }> }\n | undefined;\n const attributes = span.attributes as { stepIndex?: number } | undefined;\n\n const stepData: ThreadStepData = {\n stepSpanId: span.id,\n stepIndex: attributes?.stepIndex ?? 0,\n text: output?.text,\n toolCalls: output?.toolCalls?.map(tc => ({\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n args: tc.args,\n })),\n };\n\n modelGenSpanData.threadData.push(stepData);\n }\n\n /**\n * Store TOOL_CALL result in parent MODEL_GENERATION's pendingToolResults.\n * Called when a TOOL_CALL span ends.\n * Results are merged into threadData when MODEL_GENERATION ends.\n */\n private accumulateToolCallResult(span: AnyExportedSpan, traceData: BraintrustTraceData): void {\n const modelGenSpanData = this.findModelGenerationAncestor(span.id, traceData);\n if (!modelGenSpanData?.pendingToolResults) {\n return;\n }\n\n // Extract tool call ID from TOOL_CALL span input\n const input = span.input as { toolCallId?: string } | undefined;\n const toolCallId = input?.toolCallId;\n if (!toolCallId) {\n return;\n }\n\n // Store the result for later merging\n modelGenSpanData.pendingToolResults.set(toolCallId, {\n result: span.output,\n startTime: span.startTime,\n });\n }\n\n /**\n * Build the payload for MODEL_GENERATION span, reconstructing output from threadData if available.\n */\n private buildModelGenerationPayload(span: AnyExportedSpan, spanData: BraintrustSpanData): Record<string, any> {\n const basePayload = this.buildSpanPayload(span, false);\n\n // Check if we have threadData with tool calls to reconstruct\n const threadData = spanData.threadData;\n if (!threadData || threadData.length === 0) {\n return basePayload;\n }\n\n // Merge pending tool results into threadData\n if (spanData.pendingToolResults && spanData.pendingToolResults.size > 0) {\n for (const step of threadData) {\n if (step.toolCalls) {\n for (const toolCall of step.toolCalls) {\n const pendingResult = spanData.pendingToolResults.get(toolCall.toolCallId);\n if (pendingResult) {\n toolCall.result = pendingResult.result;\n toolCall.startTime = pendingResult.startTime;\n }\n }\n }\n }\n }\n\n // Check if any step has tool calls\n const hasToolCalls = threadData.some(step => step.toolCalls && step.toolCalls.length > 0);\n if (!hasToolCalls) {\n return basePayload;\n }\n\n // Reconstruct output as OpenAI messages\n const reconstructedOutput = reconstructThreadOutput(threadData, span.output);\n return {\n ...basePayload,\n output: reconstructedOutput,\n };\n }\n\n /**\n * Transforms MODEL_GENERATION input to Braintrust Thread view format.\n * Converts AI SDK messages (v4/v5) to OpenAI Chat Completion format, which Braintrust requires\n * for proper rendering of threads (fixes #11023).\n */\n private transformInput(input: unknown, spanType: SpanType): unknown {\n if (spanType === SpanType.MODEL_GENERATION) {\n // If input is already an array of messages, convert AI SDK format to OpenAI format\n if (Array.isArray(input)) {\n return input.map((msg: unknown) => convertAISDKMessage(msg));\n }\n\n // If input has a messages array\n if (\n input &&\n typeof input === 'object' &&\n 'messages' in input &&\n Array.isArray((input as { messages: unknown[] }).messages)\n ) {\n return (input as { messages: unknown[] }).messages.map((msg: unknown) => convertAISDKMessage(msg));\n }\n }\n\n return input;\n }\n\n /**\n * Transforms MODEL_GENERATION output to Braintrust Thread view format.\n */\n private transformOutput(output: any, spanType: SpanType): any {\n if (spanType === SpanType.MODEL_GENERATION) {\n if (!output || typeof output !== 'object') {\n return output;\n }\n const { text, ...rest } = output;\n // Remove null/undefined values from rest to keep Thread view clean\n return { role: 'assistant', content: text, ...removeNullish(rest) };\n }\n\n return output;\n }\n\n private isToolSpan(span: AnyExportedSpan): boolean {\n return (\n span.type === SpanType.TOOL_CALL ||\n span.type === SpanType.MCP_TOOL_CALL ||\n span.type === SpanType.PROVIDER_TOOL_CALL\n );\n }\n\n private getToolName(span: AnyExportedSpan): string {\n if (span.entityName) {\n return span.entityName;\n }\n const match = /'([^']+)'/.exec(span.name);\n return match?.[1] ?? span.name;\n }\n\n private getToolCallId(span: AnyExportedSpan): string {\n const attrs = span.attributes as { toolCallId?: string } | undefined;\n return attrs?.toolCallId ?? (span.input as { toolCallId?: string } | undefined)?.toolCallId ?? span.id;\n }\n\n private toToolCallInput(span: AnyExportedSpan): OpenAIMessage[] {\n const args = span.input;\n let argsString: string;\n if (typeof args === 'string') {\n argsString = args;\n } else {\n try {\n argsString = JSON.stringify(args ?? {});\n } catch {\n argsString = '[unserializable result]';\n }\n }\n return [\n {\n role: 'assistant',\n content: '',\n tool_calls: [\n {\n id: this.getToolCallId(span),\n type: 'function',\n function: {\n name: this.getToolName(span),\n arguments: argsString,\n },\n },\n ],\n },\n ];\n }\n\n private toToolCallOutput(span: AnyExportedSpan): OpenAIMessage {\n return {\n role: 'tool',\n content: serializeToolResult(span.output),\n tool_call_id: this.getToolCallId(span),\n };\n }\n\n private buildSpanPayload(span: AnyExportedSpan, isCreate = true): Record<string, any> {\n const payload: Record<string, any> = {};\n\n const isToolType = this.isToolSpan(span);\n\n if (span.input !== undefined) {\n payload.input = isToolType ? this.toToolCallInput(span) : this.transformInput(span.input, span.type);\n }\n\n if (span.output !== undefined) {\n payload.output = isToolType ? this.toToolCallOutput(span) : this.transformOutput(span.output, span.type);\n }\n\n if (isCreate && span.isRootSpan && span.tags?.length) {\n payload.tags = span.tags;\n }\n\n // Initialize metrics and metadata objects\n payload.metrics = {};\n // Spread span.metadata first, then set spanType to prevent accidental override\n payload.metadata = {\n ...span.metadata,\n spanType: span.type,\n };\n\n if (isCreate) {\n payload.metadata['mastra-trace-id'] = span.traceId;\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 // Model goes to metadata\n if (modelAttr.model !== undefined) {\n payload.metadata.model = modelAttr.model;\n }\n\n // Provider goes to metadata (if provided by attributes)\n if (modelAttr.provider !== undefined) {\n payload.metadata.provider = modelAttr.provider;\n }\n\n // Prefer resolved model ID (e.g. \"claude-sonnet-4-5-20250929\") over\n // gateway aliases (e.g. \"claude-sonnet-4.5\") for accurate cost estimation\n if (modelAttr.responseModel !== undefined) {\n payload.metadata.model = modelAttr.responseModel;\n }\n\n // Usage/token info goes to metrics\n payload.metrics = formatUsageMetrics(modelAttr.usage);\n\n // Time to first token (TTFT) for streaming responses\n // Braintrust expects TTFT in seconds (not milliseconds)\n if (modelAttr.completionStartTime) {\n payload.metrics.time_to_first_token =\n (modelAttr.completionStartTime.getTime() - span.startTime.getTime()) / 1000;\n }\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, [\n 'model',\n 'responseModel',\n 'usage',\n 'parameters',\n 'completionStartTime',\n ]);\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 // Clean up empty metrics object\n if (Object.keys(payload.metrics).length === 0) {\n delete payload.metrics;\n }\n\n // Remove null/undefined values from metadata to keep Braintrust UI clean\n payload.metadata = removeNullish(payload.metadata);\n\n return payload;\n }\n}\n"]}

@@ -12,9 +12,52 @@ /**

import type { TraceData, TrackingExporterConfig } from '@mastra/observability';
import type { Span, Logger } from 'braintrust';
import type { ThreadData, PendingToolResult } from './thread-reconstruction.js';
type BraintrustSpanType = 'llm' | 'score' | 'function' | 'eval' | 'task' | 'tool';
/**
* The subset of a Braintrust span used by the exporter.
*
* This structural interface lets applications provide spans from a different
* compatible Braintrust SDK instance without coupling Mastra's public types to
* a specific SDK version.
*/
export interface BraintrustSpan {
id: string;
startSpan(args: {
spanId: string;
name: string;
type: BraintrustSpanType;
startTime: number;
event: Record<string, any>;
}): BraintrustSpan;
log(event: Record<string, any>): void;
end(args?: {
endTime?: number;
}): number;
}
/**
* The subset of a Braintrust logger used by the exporter.
*
* Logger instances from compatible Braintrust SDK versions satisfy this
* interface without sharing the same nominal SDK types as the exporter.
*/
export interface BraintrustLogger {
startSpan(args: {
spanId: string;
name: string;
type: BraintrustSpanType;
startTime: number;
event: Record<string, any>;
}): BraintrustSpan;
logFeedback(event: {
id: string;
scores: Record<string, number>;
comment?: string;
metadata?: Record<string, any>;
source: 'external';
}): void;
}
/**
* Extended Braintrust span data that includes span type and thread reconstruction data
*/
interface BraintrustSpanData {
span: Span;
span: BraintrustSpan;
spanType: SpanType;

@@ -32,3 +75,3 @@ threadData?: ThreadData;

*/
braintrustLogger?: Logger<true>;
braintrustLogger?: BraintrustLogger;
/**

@@ -41,3 +84,3 @@ * Optional resolver for the active Braintrust span.

*/
currentSpan?: () => Span | undefined;
currentSpan?: () => BraintrustSpan | undefined;
/** Braintrust API key. Required if logger is not provided. */

@@ -52,8 +95,8 @@ apiKey?: string;

}
type BraintrustRoot = Logger<true> | Span;
type BraintrustSpan = BraintrustSpanData;
type BraintrustEvent = Span;
type BraintrustRoot = BraintrustLogger | BraintrustSpan;
type BraintrustTrackedSpan = BraintrustSpanData;
type BraintrustEvent = BraintrustSpan;
type BraintrustMetadata = unknown;
type BraintrustTraceData = TraceData<BraintrustRoot, BraintrustSpan, BraintrustEvent, BraintrustMetadata>;
export declare class BraintrustExporter extends TrackingExporter<BraintrustRoot, BraintrustSpan, BraintrustEvent, BraintrustMetadata, BraintrustExporterConfig> {
type BraintrustTraceData = TraceData<BraintrustRoot, BraintrustTrackedSpan, BraintrustEvent, BraintrustMetadata>;
export declare class BraintrustExporter extends TrackingExporter<BraintrustRoot, BraintrustTrackedSpan, BraintrustEvent, BraintrustMetadata, BraintrustExporterConfig> {
#private;

@@ -76,3 +119,3 @@ name: string;

traceData: BraintrustTraceData;
}): Promise<Span | undefined>;
}): Promise<BraintrustEvent | undefined>;
protected _updateSpan(args: {

@@ -87,3 +130,3 @@ span: AnyExportedSpan;

protected _abortSpan(args: {
span: BraintrustSpan;
span: BraintrustTrackedSpan;
reason: SpanErrorInfo;

@@ -90,0 +133,0 @@ }): Promise<void>;

@@ -1,1 +0,1 @@

{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"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"}
{
"name": "@mastra/braintrust",
"version": "1.2.4",
"version": "1.3.0-alpha.0",
"description": "Braintrust observability provider for Mastra - includes tracing and future observability features",

@@ -27,3 +27,3 @@ "type": "module",

"dependencies": {
"braintrust": "^2.2.2",
"braintrust": "^3.22.0",
"@mastra/observability": "1.16.1"

@@ -39,5 +39,5 @@ },

"vitest": "4.1.10",
"@mastra/core": "1.51.1-alpha.0",
"@observability/test-utils": "0.1.0",
"@internal/lint": "0.0.114",
"@mastra/core": "1.51.0",
"@observability/test-utils": "0.1.0",
"@internal/types-builder": "0.0.89"

@@ -44,0 +44,0 @@ },

@@ -69,10 +69,10 @@ # @mastra/braintrust

| Option | Type | Description |
| ------------------ | ------------------------- | -------------------------------------------------------------- |
| `apiKey` | `string` | Braintrust API key. Defaults to `BRAINTRUST_API_KEY` env var |
| `endpoint` | `string` | Custom endpoint URL. Defaults to `BRAINTRUST_ENDPOINT` env var |
| `projectName` | `string` | Project name. Defaults to `'mastra-tracing'` |
| `braintrustLogger` | `Logger<true>` | Optional Braintrust logger instance for context integration |
| `currentSpan` | `() => Span \| undefined` | Optional resolver from the app's Braintrust package instance |
| `tuningParameters` | `Record<string,any>` | Support tuning parameters |
| Option | Type | Description |
| ------------------ | ----------------------------------- | -------------------------------------------------------------- |
| `apiKey` | `string` | Braintrust API key. Defaults to `BRAINTRUST_API_KEY` env var |
| `endpoint` | `string` | Custom endpoint URL. Defaults to `BRAINTRUST_ENDPOINT` env var |
| `projectName` | `string` | Project name. Defaults to `'mastra-tracing'` |
| `braintrustLogger` | `BraintrustLogger` | Optional compatible Braintrust logger for context integration |
| `currentSpan` | `() => BraintrustSpan \| undefined` | Optional resolver from the app's Braintrust package instance |
| `tuningParameters` | `Record<string,any>` | Support tuning parameters |

@@ -79,0 +79,0 @@ ## Features

Sorry, the diff of this file is too big to display