5
5
import datadog .communication .serialization .Writable ;
6
6
import datadog .trace .api .DDTags ;
7
7
import datadog .trace .api .intake .TrackType ;
8
+ import datadog .trace .api .llmobs .LLMObs ;
8
9
import datadog .trace .api .llmobs .LLMObsTags ;
9
10
import datadog .trace .bootstrap .instrumentation .api .InternalSpanTypes ;
10
11
import datadog .trace .bootstrap .instrumentation .api .Tags ;
@@ -63,6 +64,15 @@ public class LLMObsSpanMapper implements RemoteMapper {
63
64
private static final byte [] METRICS = "metrics" .getBytes (StandardCharsets .UTF_8 );
64
65
private static final byte [] TAGS = "tags" .getBytes (StandardCharsets .UTF_8 );
65
66
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
+
66
76
private final LLMObsSpanMapper .MetaWriter metaWriter = new MetaWriter ();
67
77
private final int size ;
68
78
@@ -266,8 +276,50 @@ public void accept(Metadata metadata) {
266
276
if (key .equals (INPUT ) || key .equals (OUTPUT )) {
267
277
if (!spanKind .equals (Tags .LLMOBS_LLM_SPAN_KIND )) {
268
278
key += ".value" ;
279
+ writable .writeString (key , null );
280
+ writable .writeObject (val , null );
269
281
} 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 ;
270
288
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
+ }
271
323
}
272
324
} else if (key .equals (LLMObsTags .METADATA ) && val instanceof Map ) {
273
325
Map <String , Object > metadataMap = (Map ) val ;
@@ -277,10 +329,10 @@ public void accept(Metadata metadata) {
277
329
writable .writeString (entry .getKey (), null );
278
330
writable .writeObject (entry .getValue (), null );
279
331
}
280
- continue ;
332
+ } else {
333
+ writable .writeString (key , null );
334
+ writable .writeObject (val , null );
281
335
}
282
- writable .writeString (key , null );
283
- writable .writeObject (val , null );
284
336
}
285
337
}
286
338
}
0 commit comments