@mastra/datadog 1.2.1-alpha.1 → 1.2.1-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @mastra/datadog
2
2
 
3
+ ## 1.2.1-alpha.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed Datadog LLM output tool calls so they render as structured tool call blocks. ([#16789](https://github.com/mastra-ai/mastra/pull/16789))
8
+
9
+ - Updated dependencies [[`27fd1b7`](https://github.com/mastra-ai/mastra/commit/27fd1b79ac62eb7694f92587eb7d1be05b59be01), [`a702009`](https://github.com/mastra-ai/mastra/commit/a702009d3cfaa745120f501e21c783ed4d6a3072), [`8534d79`](https://github.com/mastra-ai/mastra/commit/8534d791fa1cb70fe1c19e2604c4b63cc10dd051), [`c78f8cd`](https://github.com/mastra-ai/mastra/commit/c78f8cd6222a86e6c60ae5210b6929ad5221b6fb), [`e146aad`](https://github.com/mastra-ai/mastra/commit/e146aadbba66c410ba0e74bac4c50135495cb8dd), [`1a0ec78`](https://github.com/mastra-ai/mastra/commit/1a0ec789a26cae443744e9abbd62ed6ee676af39), [`d52b6fe`](https://github.com/mastra-ai/mastra/commit/d52b6fe1c56853eb38864baae0bbfa75cc739ccb)]:
10
+ - @mastra/core@1.36.0-alpha.10
11
+
12
+ ## 1.2.1-alpha.2
13
+
14
+ ### Patch Changes
15
+
16
+ - Fixed Datadog LLM span input formatting to remove empty user messages. ([#16785](https://github.com/mastra-ai/mastra/pull/16785))
17
+
18
+ - Updated dependencies [[`ac79462`](https://github.com/mastra-ai/mastra/commit/ac79462b98f1062394c45093aa515b0766f27ee2), [`19281c7`](https://github.com/mastra-ai/mastra/commit/19281c70424f757219782de16c2699743c5e04d0)]:
19
+ - @mastra/core@1.36.0-alpha.5
20
+
3
21
  ## 1.2.1-alpha.1
4
22
 
5
23
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -104,7 +104,7 @@ function toDate(value) {
104
104
  }
105
105
  function safeStringify(data) {
106
106
  try {
107
- return JSON.stringify(data);
107
+ return JSON.stringify(data) ?? "";
108
108
  } catch {
109
109
  if (typeof data === "object" && data !== null) {
110
110
  return `[Non-serializable ${data.constructor?.name || "Object"}]`;
@@ -113,15 +113,50 @@ function safeStringify(data) {
113
113
  }
114
114
  }
115
115
  function isMessageArray(data) {
116
- return Array.isArray(data) && data.every((m) => m?.role && m?.content !== void 0);
116
+ return Array.isArray(data) && data.every((m) => m?.role && (m?.content !== void 0 || Array.isArray(m.toolCalls)));
117
+ }
118
+ function isModelDataSpan(spanType) {
119
+ return spanType === observability$1.SpanType.MODEL_GENERATION || spanType === observability$1.SpanType.MODEL_STEP || spanType === observability$1.SpanType.MODEL_INFERENCE;
117
120
  }
118
121
  function isGeminiContentArray(data) {
119
122
  return Array.isArray(data) && data.every((m) => m?.role && Array.isArray(m?.parts));
120
123
  }
124
+ function toMessageContent(content) {
125
+ return typeof content === "string" ? content : safeStringify(content);
126
+ }
121
127
  function toDatadogMessages(messages) {
122
- return messages.map((m) => ({
123
- role: m.role,
124
- content: typeof m.content === "string" ? m.content : safeStringify(m.content)
128
+ return messages.map((m) => {
129
+ const message = {
130
+ role: m.role,
131
+ content: m.content == null ? "" : toMessageContent(m.content)
132
+ };
133
+ if (m.toolCalls) {
134
+ message.toolCalls = m.toolCalls;
135
+ }
136
+ return message;
137
+ }).filter((m) => !(m.role === "user" && m.content.trim().length === 0));
138
+ }
139
+ function parseToolArguments(args) {
140
+ if (args == null) return void 0;
141
+ if (typeof args === "string") {
142
+ try {
143
+ const parsed = JSON.parse(args);
144
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
145
+ return parsed;
146
+ }
147
+ } catch {
148
+ }
149
+ return { value: args };
150
+ }
151
+ if (typeof args === "object" && !Array.isArray(args)) return args;
152
+ return { value: args };
153
+ }
154
+ function toDatadogToolCalls(toolCalls) {
155
+ return toolCalls.map((c) => ({
156
+ name: c?.toolName ?? c?.name ?? c?.function?.name ?? "unknown",
157
+ arguments: parseToolArguments(c?.args ?? c?.input ?? c?.function?.arguments),
158
+ toolId: c?.toolCallId ?? c?.toolId ?? c?.id,
159
+ type: c?.type === "function" ? c.type : "function"
125
160
  }));
126
161
  }
127
162
  function geminiContentToMessage(item) {
@@ -135,34 +170,34 @@ function geminiContentToMessage(item) {
135
170
  return { role: item.role, content: text };
136
171
  }
137
172
  function formatInput(input, spanType) {
138
- if (spanType === observability$1.SpanType.MODEL_GENERATION || spanType === observability$1.SpanType.MODEL_STEP) {
173
+ if (isModelDataSpan(spanType)) {
139
174
  if (isMessageArray(input)) {
140
175
  return toDatadogMessages(input);
141
176
  }
142
177
  if (isGeminiContentArray(input)) {
143
- return input.map(geminiContentToMessage);
178
+ return toDatadogMessages(input.map(geminiContentToMessage));
144
179
  }
145
180
  if (input && typeof input === "object" && !Array.isArray(input)) {
146
181
  if (isMessageArray(input.messages)) {
147
182
  return toDatadogMessages(input.messages);
148
183
  }
149
184
  if (isGeminiContentArray(input.messages)) {
150
- return input.messages.map(geminiContentToMessage);
185
+ return toDatadogMessages(input.messages.map(geminiContentToMessage));
151
186
  }
152
187
  if (isGeminiContentArray(input.contents)) {
153
- return input.contents.map(geminiContentToMessage);
188
+ return toDatadogMessages(input.contents.map(geminiContentToMessage));
154
189
  }
155
190
  }
156
191
  if (typeof input === "string") {
157
- return [{ role: "user", content: input }];
192
+ return toDatadogMessages([{ role: "user", content: input }]);
158
193
  }
159
- return [{ role: "user", content: safeStringify(input) }];
194
+ return toDatadogMessages([{ role: "user", content: safeStringify(input) }]);
160
195
  }
161
196
  if (typeof input === "string" || Array.isArray(input)) return input;
162
197
  return safeStringify(input);
163
198
  }
164
199
  function formatOutput(output, spanType) {
165
- if (spanType === observability$1.SpanType.MODEL_GENERATION || spanType === observability$1.SpanType.MODEL_STEP) {
200
+ if (isModelDataSpan(spanType)) {
166
201
  if (isMessageArray(output)) {
167
202
  return toDatadogMessages(output);
168
203
  }
@@ -170,16 +205,21 @@ function formatOutput(output, spanType) {
170
205
  return [{ role: "assistant", content: output }];
171
206
  }
172
207
  if (output && typeof output === "object") {
208
+ if (Array.isArray(output.toolCalls) && output.toolCalls.length > 0) {
209
+ return [
210
+ {
211
+ role: "assistant",
212
+ content: typeof output.text === "string" ? output.text : "",
213
+ toolCalls: toDatadogToolCalls(output.toolCalls)
214
+ }
215
+ ];
216
+ }
173
217
  if (typeof output.text === "string" && output.text.length > 0) {
174
218
  return [{ role: "assistant", content: output.text }];
175
219
  }
176
220
  if (output.object !== void 0) {
177
221
  return [{ role: "assistant", content: safeStringify(output.object) }];
178
222
  }
179
- if (Array.isArray(output.toolCalls) && output.toolCalls.length > 0) {
180
- const summary = output.toolCalls.map((c) => `[tool: ${c?.toolName ?? c?.name ?? "unknown"}]`).join("");
181
- return [{ role: "assistant", content: summary }];
182
- }
183
223
  }
184
224
  return [{ role: "assistant", content: safeStringify(output) }];
185
225
  }