@mastra/otel-exporter 1.4.8-alpha.1 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,23 +4,5 @@
4
4
  * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-input-messages
5
5
  * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-input-messages.json
6
6
  */
7
- /**
8
- * Convert an Input/Output string from a MastraSpan into a jsonified string that adheres to
9
- * OpenTelemetry gen_ai.input.messages and gen_ai.output.messages schema.
10
- * If parsing fails at any step, the original inputOutputString is returned unmodified.
11
- *
12
- * This conversion is best effort; It assumes a consistent shape for mastra messages, and converts
13
- * into the gen_ai input and output schemas as of October 20th, 2025.
14
- *
15
- * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-input-messages
16
- * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-input-messages.json
17
- * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-output-messages
18
- * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-output-messages.json
19
- *
20
- * @param inputOutputString a jsonified string that contains messages adhering to what appears to be
21
- * Mastra's message shape.
22
- * @returns a jsonified string that contains messages adhering to the OpenTelemetry gen_ai.input.messages and gen_ai.output.messages schema.
23
- * If parsing fails at any step, the original inputOutputString is returned unmodified.
24
- */
25
7
  export declare const convertMastraMessagesToGenAIMessages: (inputOutputString: string) => string;
26
8
  //# sourceMappingURL=gen-ai-messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gen-ai-messages.d.ts","sourceRoot":"","sources":["../src/gen-ai-messages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwEH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,oCAAoC,sBAAuB,MAAM,KAAG,MAyEhF,CAAC"}
1
+ {"version":3,"file":"gen-ai-messages.d.ts","sourceRoot":"","sources":["../src/gen-ai-messages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6IH,eAAO,MAAM,oCAAoC,sBAAuB,MAAM,KAAG,MA0BhF,CAAC"}
package/dist/index.cjs CHANGED
@@ -349,51 +349,65 @@ const isMastraMessage = (m) => {
349
349
  * @returns a jsonified string that contains messages adhering to the OpenTelemetry gen_ai.input.messages and gen_ai.output.messages schema.
350
350
  * If parsing fails at any step, the original inputOutputString is returned unmodified.
351
351
  */
352
+ const toGenAIMessage = (m) => {
353
+ const parts = Array.isArray(m.content) ? m.content.map((c) => {
354
+ switch (c.type) {
355
+ case "text": return {
356
+ type: "text",
357
+ content: c.text
358
+ };
359
+ case "tool-call": return {
360
+ type: "tool_call",
361
+ id: c.toolCallId,
362
+ name: c.toolName,
363
+ arguments: JSON.stringify(c.input)
364
+ };
365
+ case "tool-result": return {
366
+ type: "tool_call_response",
367
+ id: c.toolCallId,
368
+ name: c.toolName,
369
+ response: JSON.stringify(c.output.value)
370
+ };
371
+ }
372
+ }) : [{
373
+ type: "text",
374
+ content: m.content
375
+ }];
376
+ return {
377
+ role: m.role,
378
+ parts
379
+ };
380
+ };
381
+ const toGenAIOutputMessage = (output) => {
382
+ const parts = [];
383
+ const toolCalls = Array.isArray(output.toolCalls) ? output.toolCalls : [];
384
+ const text = typeof output.text === "string" ? output.text : void 0;
385
+ if (text !== void 0 && (text.length > 0 || toolCalls.length === 0)) parts.push({
386
+ type: "text",
387
+ content: text
388
+ });
389
+ for (const call of toolCalls) {
390
+ if (typeof call !== "object" || call == null) continue;
391
+ const c = call;
392
+ parts.push({
393
+ type: "tool_call",
394
+ id: String(c.toolCallId ?? ""),
395
+ name: String(c.toolName ?? ""),
396
+ arguments: JSON.stringify(c.args ?? c.input)
397
+ });
398
+ }
399
+ return {
400
+ role: "assistant",
401
+ parts
402
+ };
403
+ };
352
404
  const convertMastraMessagesToGenAIMessages = (inputOutputString) => {
353
405
  try {
354
406
  const parsedIO = JSON.parse(inputOutputString);
355
- if (typeof parsedIO !== "object" || parsedIO == null || !("messages" in parsedIO) && !("text" in parsedIO)) return inputOutputString;
356
- if ("text" in parsedIO) return JSON.stringify([{
357
- role: "assistant",
358
- parts: [{
359
- type: "text",
360
- content: parsedIO.text
361
- }]
362
- }]);
363
- if (Array.isArray(parsedIO.messages)) return JSON.stringify(parsedIO.messages.map((m) => {
364
- if (!isMastraMessage(m)) return m;
365
- const role = m.role;
366
- let parts = [];
367
- if (Array.isArray(m.content)) parts = m.content.map((c) => {
368
- switch (c.type) {
369
- case "text": return {
370
- type: "text",
371
- content: c.text
372
- };
373
- case "tool-call": return {
374
- type: "tool_call",
375
- id: c.toolCallId,
376
- name: c.toolName,
377
- arguments: JSON.stringify(c.input)
378
- };
379
- case "tool-result": return {
380
- type: "tool_call_response",
381
- id: c.toolCallId,
382
- name: c.toolName,
383
- response: JSON.stringify(c.output.value)
384
- };
385
- default: return c;
386
- }
387
- });
388
- else parts = [{
389
- type: "text",
390
- content: m.content
391
- }];
392
- return {
393
- role,
394
- parts
395
- };
396
- }));
407
+ if (typeof parsedIO !== "object" || parsedIO == null) return inputOutputString;
408
+ if (Array.isArray(parsedIO)) return parsedIO.every(isMastraMessage) ? JSON.stringify(parsedIO.map(toGenAIMessage)) : inputOutputString;
409
+ if ("text" in parsedIO || "toolCalls" in parsedIO) return JSON.stringify([toGenAIOutputMessage(parsedIO)]);
410
+ if ("messages" in parsedIO && Array.isArray(parsedIO.messages)) return JSON.stringify(parsedIO.messages.map((m) => isMastraMessage(m) ? toGenAIMessage(m) : m));
397
411
  return inputOutputString;
398
412
  } catch {
399
413
  return inputOutputString;