Skip to content

Commit 0e7c1e5

Browse files
committed
add support for llm message and tool calls
1 parent 27e9127 commit 0e7c1e5

File tree

1 file changed

+55
-3
lines changed

1 file changed

+55
-3
lines changed

dd-trace-core/src/main/java/datadog/trace/llmobs/writer/ddintake/LLMObsSpanMapper.java

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import datadog.communication.serialization.Writable;
66
import datadog.trace.api.DDTags;
77
import datadog.trace.api.intake.TrackType;
8+
import datadog.trace.api.llmobs.LLMObs;
89
import datadog.trace.api.llmobs.LLMObsTags;
910
import datadog.trace.bootstrap.instrumentation.api.InternalSpanTypes;
1011
import datadog.trace.bootstrap.instrumentation.api.Tags;
@@ -63,6 +64,15 @@ public class LLMObsSpanMapper implements RemoteMapper {
6364
private static final byte[] METRICS = "metrics".getBytes(StandardCharsets.UTF_8);
6465
private static final byte[] TAGS = "tags".getBytes(StandardCharsets.UTF_8);
6566

67+
private static final byte[] LLM_MESSAGE_ROLE = "role".getBytes(StandardCharsets.UTF_8);
68+
private static final byte[] LLM_MESSAGE_CONTENT = "content".getBytes(StandardCharsets.UTF_8);
69+
private static final byte[] LLM_MESSAGE_TOOL_CALLS = "tool_calls".getBytes(StandardCharsets.UTF_8);
70+
71+
private static final byte[] LLM_TOOL_CALL_NAME = "name".getBytes(StandardCharsets.UTF_8);
72+
private static final byte[] LLM_TOOL_CALL_TYPE = "type".getBytes(StandardCharsets.UTF_8);
73+
private static final byte[] LLM_TOOL_CALL_TOOL_ID = "tool_id".getBytes(StandardCharsets.UTF_8);
74+
private static final byte[] LLM_TOOL_CALL_ARGUMENTS = "arguments".getBytes(StandardCharsets.UTF_8);
75+
6676
private final LLMObsSpanMapper.MetaWriter metaWriter = new MetaWriter();
6777
private final int size;
6878

@@ -266,8 +276,50 @@ public void accept(Metadata metadata) {
266276
if (key.equals(INPUT) || key.equals(OUTPUT)) {
267277
if (!spanKind.equals(Tags.LLMOBS_LLM_SPAN_KIND)) {
268278
key += ".value";
279+
writable.writeString(key, null);
280+
writable.writeObject(val, null);
269281
} else {
282+
if (!(val instanceof List)) {
283+
LOGGER.warn("unexpectedly found incorrect type for LLM span IO {}, expecting list", val.getClass().getName());
284+
continue;
285+
}
286+
// llm span kind must have llm objects
287+
List<LLMObs.LLMMessage> messages = (List<LLMObs.LLMMessage>) val;
270288
key += ".messages";
289+
writable.writeString(key, null);
290+
writable.startArray(messages.size());
291+
for (LLMObs.LLMMessage message: messages) {
292+
List<LLMObs.ToolCall> toolCalls = message.getToolCalls();
293+
boolean hasToolCalls = null != toolCalls && !toolCalls.isEmpty();
294+
writable.startMap(hasToolCalls ? 3 : 2);
295+
writable.writeUTF8(LLM_MESSAGE_ROLE);
296+
writable.writeString(message.getRole(), null);
297+
writable.writeUTF8(LLM_MESSAGE_CONTENT);
298+
writable.writeString(message.getContent(), null);
299+
if (hasToolCalls) {
300+
writable.writeUTF8(LLM_MESSAGE_TOOL_CALLS);
301+
writable.startArray(toolCalls.size());
302+
for (LLMObs.ToolCall toolCall: toolCalls) {
303+
Map<String, Object> arguments = toolCall.getArguments();
304+
boolean hasArguments = null != arguments && !arguments.isEmpty();
305+
writable.startMap(hasArguments ? 4 : 3);
306+
writable.writeUTF8(LLM_TOOL_CALL_NAME);
307+
writable.writeString(toolCall.getName(), null);
308+
writable.writeUTF8(LLM_TOOL_CALL_TYPE);
309+
writable.writeString(toolCall.getType(), null);
310+
writable.writeUTF8(LLM_TOOL_CALL_TOOL_ID);
311+
writable.writeString(toolCall.getToolID(), null);
312+
if (hasArguments) {
313+
writable.writeUTF8(LLM_TOOL_CALL_ARGUMENTS);
314+
writable.startMap(arguments.size());
315+
for (Map.Entry<String, Object> argument : arguments.entrySet()) {
316+
writable.writeString(argument.getKey(), null);
317+
writable.writeObject(argument.getValue(), null);
318+
}
319+
}
320+
}
321+
}
322+
}
271323
}
272324
} else if (key.equals(LLMObsTags.METADATA) && val instanceof Map) {
273325
Map<String, Object> metadataMap = (Map) val;
@@ -277,10 +329,10 @@ public void accept(Metadata metadata) {
277329
writable.writeString(entry.getKey(), null);
278330
writable.writeObject(entry.getValue(), null);
279331
}
280-
continue;
332+
} else {
333+
writable.writeString(key, null);
334+
writable.writeObject(val, null);
281335
}
282-
writable.writeString(key, null);
283-
writable.writeObject(val, null);
284336
}
285337
}
286338
}

0 commit comments

Comments
 (0)