From 51343114a4d5cdfaead724f329853dce5ac0ec90 Mon Sep 17 00:00:00 2001 From: gary-huang Date: Thu, 19 Sep 2024 15:45:33 -0400 Subject: [PATCH 1/4] add APIs for llm obs --- dd-trace-api/build.gradle | 4 + .../java/datadog/trace/api/llmobs/LLMObs.java | 60 +++++++ .../datadog/trace/api/llmobs/LLMObsSpan.java | 147 ++++++++++++++++++ .../trace/api/llmobs/noop/NoOpLLMObsSpan.java | 61 ++++++++ .../llmobs/noop/NoOpLLMObsSpanFactory.java | 38 +++++ 5 files changed, 310 insertions(+) create mode 100644 dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java create mode 100644 dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java create mode 100644 dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java create mode 100644 dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java diff --git a/dd-trace-api/build.gradle b/dd-trace-api/build.gradle index c4b00313208..9813c47ce02 100644 --- a/dd-trace-api/build.gradle +++ b/dd-trace-api/build.gradle @@ -32,6 +32,10 @@ excludedClassesCoverage += [ 'datadog.trace.api.profiling.ProfilingScope', 'datadog.trace.api.profiling.ProfilingContext', 'datadog.trace.api.profiling.ProfilingContextAttribute.NoOp', + 'datadog.trace.api.llmobs.LLMObs', + 'datadog.trace.api.llmobs.LLMObsSpan', + 'datadog.trace.api.llmobs.noop.NoOpLLMObsSpan', + 'datadog.trace.api.llmobs.noop.NoOpLLMObsSpanFactory', 'datadog.trace.api.experimental.DataStreamsCheckpointer', 'datadog.trace.api.experimental.DataStreamsCheckpointer.NoOp', 'datadog.trace.api.experimental.DataStreamsContextCarrier', diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java new file mode 100644 index 00000000000..02eb79a7d79 --- /dev/null +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java @@ -0,0 +1,60 @@ +package datadog.trace.api.llmobs; + +import datadog.trace.api.llmobs.noop.NoOpLLMObsSpanFactory; +import javax.annotation.Nullable; + +public class LLMObs { + private static LLMObsSpanFactory SPAN_FACTORY = NoOpLLMObsSpanFactory.INSTANCE; + + public static LLMObsSpan startLLMSpan( + String spanName, + String modelName, + String modelProvider, + @Nullable String mlApp, + @Nullable String sessionID) { + + return SPAN_FACTORY.startLLMSpan(spanName, modelName, modelProvider, mlApp, sessionID); + } + + public static LLMObsSpan startAgentSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + + return SPAN_FACTORY.startAgentSpan(spanName, mlApp, sessionID); + } + + public static LLMObsSpan startToolSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + + return SPAN_FACTORY.startToolSpan(spanName, mlApp, sessionID); + } + + public static LLMObsSpan startTaskSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + + return SPAN_FACTORY.startTaskSpan(spanName, mlApp, sessionID); + } + + public static LLMObsSpan startWorkflowSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + + return SPAN_FACTORY.startWorkflowSpan(spanName, mlApp, sessionID); + } + + public interface LLMObsSpanFactory { + LLMObsSpan startLLMSpan( + String spanName, + String modelName, + String modelProvider, + @Nullable String mlApp, + @Nullable String sessionID); + + LLMObsSpan startAgentSpan(String spanName, @Nullable String mlApp, @Nullable String sessionID); + + LLMObsSpan startToolSpan(String spanName, @Nullable String mlApp, @Nullable String sessionID); + + LLMObsSpan startTaskSpan(String spanName, @Nullable String mlApp, @Nullable String sessionID); + + LLMObsSpan startWorkflowSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID); + } +} diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java new file mode 100644 index 00000000000..af5eb204937 --- /dev/null +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java @@ -0,0 +1,147 @@ +package datadog.trace.api.llmobs; + +import java.util.List; +import java.util.Map; + +/** This interface represent an individual LLM Obs span. */ +public interface LLMObsSpan { + + /** + * Annotate the span with inputs and outputs + * + * @param inputData The input data of the span in the form of a list, for example a list of input + * messages + * @param outputData The output data of the span in the form of a list, for example a list of + * output messages + */ + void annotateIO(List> inputData, List> outputData); + + /** + * Annotate the span with inputs and outputs + * + * @param inputData The input data of the span in the form of a string + * @param outputData The output data of the span in the form of a string + */ + void annotateIO(String inputData, String outputData); + + /** + * Annotate the span with metadata + * + * @param metadata A map of JSON serializable key-value pairs that contains metadata information + * relevant to the input or output operation described by the span + */ + void setMetadata(Map metadata); + + /** + * Annotate the span with metrics + * + * @param metrics A map of JSON serializable keys and numeric values that users can add as metrics + * relevant to the operation described by the span (input_tokens, output_tokens, total_tokens, + * etc.). + */ + void setMetrics(Map metrics); + + /** + * Annotate the span with a single metric key value pair for the span’s context (number of tokens + * document length, etc). + * + * @param key the name of the metric + * @param value the value of the metric + */ + void setMetric(CharSequence key, int value); + + /** + * Annotate the span with a single metric key value pair for the span’s context (number of tokens + * document length, etc). + * + * @param key the name of the metric + * @param value the value of the metric + */ + void setMetric(CharSequence key, long value); + + /** + * Annotate the span with a single metric key value pair for the span’s context (number of tokens + * document length, etc). + * + * @param key the name of the metric + * @param value the value of the metric + */ + void setMetric(CharSequence key, double value); + + /** + * Annotate the span with tags + * + * @param tags An map of JSON serializable key-value pairs that users can add as tags regarding + * the span’s context (session, environment, system, versioning, etc.). + */ + void setTags(Map tags); + + /** + * Annotate the span with a single tag key value pair as a tag regarding the span’s context + * (session, environment, system, versioning, etc.). + * + * @param key the key of the tag + * @param value the value of the tag + */ + void setTag(String key, String value); + + /** + * Annotate the span with a single tag key value pair as a tag regarding the span’s context + * (session, environment, system, versioning, etc.). + * + * @param key the key of the tag + * @param value the value of the tag + */ + void setTag(String key, boolean value); + + /** + * Annotate the span with a single tag key value pair as a tag regarding the span’s context + * (session, environment, system, versioning, etc.). + * + * @param key the key of the tag + * @param value the value of the tag + */ + void setTag(String key, int value); + + /** + * Annotate the span with a single tag key value pair as a tag regarding the span’s context + * (session, environment, system, versioning, etc.). + * + * @param key the key of the tag + * @param value the value of the tag + */ + void setTag(String key, long value); + + /** + * Annotate the span with a single tag key value pair as a tag regarding the span’s context + * (session, environment, system, versioning, etc.). + * + * @param key the key of the tag + * @param value the value of the tag + */ + void setTag(String key, double value); + + /** + * Annotate the span to indicate that an error occurred + * + * @param error whether an error occurred + */ + void setError(boolean error); + + /** + * Annotate the span with an error message + * + * @param errorMessage the message of the error + */ + void setErrorMessage(String errorMessage); + + /** + * Annotate the span with a throwable + * + * @param throwable the errored throwable + */ + void addThrowable(Throwable throwable); + + /** Finishes (closes) a span */ + void finish(); +} diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java new file mode 100644 index 00000000000..f6752dc92fa --- /dev/null +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java @@ -0,0 +1,61 @@ +package datadog.trace.api.llmobs.noop; + +import datadog.trace.api.llmobs.LLMObsSpan; +import java.util.List; +import java.util.Map; + +public class NoOpLLMObsSpan implements LLMObsSpan { + public static final LLMObsSpan INSTANCE = new NoOpLLMObsSpan(); + + @Override + public void annotateIO( + List> inputData, List> outputData) {} + + @Override + public void annotateIO(String inputData, String outputData) {} + + @Override + public void setMetadata(Map metadata) {} + + @Override + public void setMetrics(Map metrics) {} + + @Override + public void setMetric(CharSequence key, int value) {} + + @Override + public void setMetric(CharSequence key, long value) {} + + @Override + public void setMetric(CharSequence key, double value) {} + + @Override + public void setTags(Map tags) {} + + @Override + public void setTag(String key, String value) {} + + @Override + public void setTag(String key, boolean value) {} + + @Override + public void setTag(String key, int value) {} + + @Override + public void setTag(String key, long value) {} + + @Override + public void setTag(String key, double value) {} + + @Override + public void setError(boolean error) {} + + @Override + public void setErrorMessage(String errorMessage) {} + + @Override + public void addThrowable(Throwable throwable) {} + + @Override + public void finish() {} +} diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java new file mode 100644 index 00000000000..5f0071b1a3e --- /dev/null +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java @@ -0,0 +1,38 @@ +package datadog.trace.api.llmobs.noop; + +import datadog.trace.api.llmobs.LLMObs; +import datadog.trace.api.llmobs.LLMObsSpan; +import javax.annotation.Nullable; + +public class NoOpLLMObsSpanFactory implements LLMObs.LLMObsSpanFactory { + public static final NoOpLLMObsSpanFactory INSTANCE = new NoOpLLMObsSpanFactory(); + + public LLMObsSpan startLLMSpan( + String spanName, + String modelName, + String modelProvider, + @Nullable String mlApp, + @Nullable String sessionID) { + return NoOpLLMObsSpan.INSTANCE; + } + + public LLMObsSpan startAgentSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + return NoOpLLMObsSpan.INSTANCE; + } + + public LLMObsSpan startToolSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + return NoOpLLMObsSpan.INSTANCE; + } + + public LLMObsSpan startTaskSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + return NoOpLLMObsSpan.INSTANCE; + } + + public LLMObsSpan startWorkflowSpan( + String spanName, @Nullable String mlApp, @Nullable String sessionID) { + return NoOpLLMObsSpan.INSTANCE; + } +} From b5c7a0a48972e352c4e73019c521ff217afff837 Mon Sep 17 00:00:00 2001 From: gary-huang Date: Thu, 6 Mar 2025 15:25:48 -0500 Subject: [PATCH 2/4] add llm message class to support llm spans --- dd-trace-api/build.gradle | 2 + .../java/datadog/trace/api/llmobs/LLMObs.java | 78 ++++++++++++++++++- .../datadog/trace/api/llmobs/LLMObsSpan.java | 10 +-- .../trace/api/llmobs/noop/NoOpLLMObsSpan.java | 4 +- 4 files changed, 85 insertions(+), 9 deletions(-) diff --git a/dd-trace-api/build.gradle b/dd-trace-api/build.gradle index 9813c47ce02..4175700c6ce 100644 --- a/dd-trace-api/build.gradle +++ b/dd-trace-api/build.gradle @@ -33,6 +33,8 @@ excludedClassesCoverage += [ 'datadog.trace.api.profiling.ProfilingContext', 'datadog.trace.api.profiling.ProfilingContextAttribute.NoOp', 'datadog.trace.api.llmobs.LLMObs', + 'datadog.trace.api.llmobs.LLMObs.LLMMessage', + 'datadog.trace.api.llmobs.LLMObs.ToolCall', 'datadog.trace.api.llmobs.LLMObsSpan', 'datadog.trace.api.llmobs.noop.NoOpLLMObsSpan', 'datadog.trace.api.llmobs.noop.NoOpLLMObsSpanFactory', diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java index 02eb79a7d79..cd7426a24c5 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java @@ -1,10 +1,14 @@ package datadog.trace.api.llmobs; import datadog.trace.api.llmobs.noop.NoOpLLMObsSpanFactory; +import java.util.List; +import java.util.Map; import javax.annotation.Nullable; public class LLMObs { - private static LLMObsSpanFactory SPAN_FACTORY = NoOpLLMObsSpanFactory.INSTANCE; + protected LLMObs() {} + + protected static LLMObsSpanFactory SPAN_FACTORY = NoOpLLMObsSpanFactory.INSTANCE; public static LLMObsSpan startLLMSpan( String spanName, @@ -57,4 +61,76 @@ LLMObsSpan startLLMSpan( LLMObsSpan startWorkflowSpan( String spanName, @Nullable String mlApp, @Nullable String sessionID); } + + public static class ToolCall { + private String name; + private String type; + private String toolID; + private Map arguments; + + public static ToolCall from( + String name, String type, String toolID, Map arguments) { + return new ToolCall(name, type, toolID, arguments); + } + + private ToolCall(String name, String type, String toolID, Map arguments) { + this.name = name; + this.type = type; + this.toolID = toolID; + this.arguments = arguments; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public String getToolID() { + return toolID; + } + + public Map getArguments() { + return arguments; + } + } + + public static class LLMMessage { + private String role; + private String content; + private List toolCalls; + + public static LLMMessage from(String role, String content, List toolCalls) { + return new LLMMessage(role, content, toolCalls); + } + + public static LLMMessage from(String role, String content) { + return new LLMMessage(role, content); + } + + private LLMMessage(String role, String content, List toolCalls) { + this.role = role; + this.content = content; + this.toolCalls = toolCalls; + } + + private LLMMessage(String role, String content) { + this.role = role; + this.content = content; + } + + public String getRole() { + return role; + } + + public String getContent() { + return content; + } + + public List getToolCalls() { + return toolCalls; + } + } } diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java index af5eb204937..80668eabd57 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObsSpan.java @@ -7,14 +7,12 @@ public interface LLMObsSpan { /** - * Annotate the span with inputs and outputs + * Annotate the span with inputs and outputs for LLM spans * - * @param inputData The input data of the span in the form of a list, for example a list of input - * messages - * @param outputData The output data of the span in the form of a list, for example a list of - * output messages + * @param inputMessages The input messages of the span in the form of a list + * @param outputMessages The output messages of the span in the form of a list */ - void annotateIO(List> inputData, List> outputData); + void annotateIO(List inputMessages, List outputMessages); /** * Annotate the span with inputs and outputs diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java index f6752dc92fa..a1b160616e7 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpan.java @@ -1,5 +1,6 @@ package datadog.trace.api.llmobs.noop; +import datadog.trace.api.llmobs.LLMObs; import datadog.trace.api.llmobs.LLMObsSpan; import java.util.List; import java.util.Map; @@ -8,8 +9,7 @@ public class NoOpLLMObsSpan implements LLMObsSpan { public static final LLMObsSpan INSTANCE = new NoOpLLMObsSpan(); @Override - public void annotateIO( - List> inputData, List> outputData) {} + public void annotateIO(List inputData, List outputData) {} @Override public void annotateIO(String inputData, String outputData) {} From 4126e2e888d22c03f1f024fa61d7fd8dbc7ffb20 Mon Sep 17 00:00:00 2001 From: gary-huang Date: Tue, 29 Apr 2025 16:57:56 -0400 Subject: [PATCH 3/4] follow java convention of naming Id instead of ID --- .../java/datadog/trace/api/llmobs/LLMObs.java | 44 +++++++++---------- .../llmobs/noop/NoOpLLMObsSpanFactory.java | 10 ++--- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java index cd7426a24c5..fd3e1f0a952 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/LLMObs.java @@ -15,33 +15,33 @@ public static LLMObsSpan startLLMSpan( String modelName, String modelProvider, @Nullable String mlApp, - @Nullable String sessionID) { + @Nullable String sessionId) { - return SPAN_FACTORY.startLLMSpan(spanName, modelName, modelProvider, mlApp, sessionID); + return SPAN_FACTORY.startLLMSpan(spanName, modelName, modelProvider, mlApp, sessionId); } public static LLMObsSpan startAgentSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { - return SPAN_FACTORY.startAgentSpan(spanName, mlApp, sessionID); + return SPAN_FACTORY.startAgentSpan(spanName, mlApp, sessionId); } public static LLMObsSpan startToolSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { - return SPAN_FACTORY.startToolSpan(spanName, mlApp, sessionID); + return SPAN_FACTORY.startToolSpan(spanName, mlApp, sessionId); } public static LLMObsSpan startTaskSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { - return SPAN_FACTORY.startTaskSpan(spanName, mlApp, sessionID); + return SPAN_FACTORY.startTaskSpan(spanName, mlApp, sessionId); } public static LLMObsSpan startWorkflowSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { - return SPAN_FACTORY.startWorkflowSpan(spanName, mlApp, sessionID); + return SPAN_FACTORY.startWorkflowSpan(spanName, mlApp, sessionId); } public interface LLMObsSpanFactory { @@ -50,33 +50,33 @@ LLMObsSpan startLLMSpan( String modelName, String modelProvider, @Nullable String mlApp, - @Nullable String sessionID); + @Nullable String sessionId); - LLMObsSpan startAgentSpan(String spanName, @Nullable String mlApp, @Nullable String sessionID); + LLMObsSpan startAgentSpan(String spanName, @Nullable String mlApp, @Nullable String sessionId); - LLMObsSpan startToolSpan(String spanName, @Nullable String mlApp, @Nullable String sessionID); + LLMObsSpan startToolSpan(String spanName, @Nullable String mlApp, @Nullable String sessionId); - LLMObsSpan startTaskSpan(String spanName, @Nullable String mlApp, @Nullable String sessionID); + LLMObsSpan startTaskSpan(String spanName, @Nullable String mlApp, @Nullable String sessionId); LLMObsSpan startWorkflowSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID); + String spanName, @Nullable String mlApp, @Nullable String sessionId); } public static class ToolCall { private String name; private String type; - private String toolID; + private String toolId; private Map arguments; public static ToolCall from( - String name, String type, String toolID, Map arguments) { - return new ToolCall(name, type, toolID, arguments); + String name, String type, String toolId, Map arguments) { + return new ToolCall(name, type, toolId, arguments); } - private ToolCall(String name, String type, String toolID, Map arguments) { + private ToolCall(String name, String type, String toolId, Map arguments) { this.name = name; this.type = type; - this.toolID = toolID; + this.toolId = toolId; this.arguments = arguments; } @@ -88,8 +88,8 @@ public String getType() { return type; } - public String getToolID() { - return toolID; + public String getToolId() { + return toolId; } public Map getArguments() { diff --git a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java index 5f0071b1a3e..080aa41bd82 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/llmobs/noop/NoOpLLMObsSpanFactory.java @@ -12,27 +12,27 @@ public LLMObsSpan startLLMSpan( String modelName, String modelProvider, @Nullable String mlApp, - @Nullable String sessionID) { + @Nullable String sessionId) { return NoOpLLMObsSpan.INSTANCE; } public LLMObsSpan startAgentSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { return NoOpLLMObsSpan.INSTANCE; } public LLMObsSpan startToolSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { return NoOpLLMObsSpan.INSTANCE; } public LLMObsSpan startTaskSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { return NoOpLLMObsSpan.INSTANCE; } public LLMObsSpan startWorkflowSpan( - String spanName, @Nullable String mlApp, @Nullable String sessionID) { + String spanName, @Nullable String mlApp, @Nullable String sessionId) { return NoOpLLMObsSpan.INSTANCE; } } From 27177c01eadd2a6bc158bb9473c97cd619d70ca9 Mon Sep 17 00:00:00 2001 From: gary-huang Date: Tue, 29 Apr 2025 18:17:12 -0400 Subject: [PATCH 4/4] add codeowners --- .github/CODEOWNERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5983b5d0bd2..791377393d2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -74,3 +74,9 @@ dd-trace-core/src/main/java/datadog/trace/core/datastreams @Dat dd-trace-core/src/test/groovy/datadog/trace/core/datastreams @DataDog/data-streams-monitoring internal-api/src/main/java/datadog/trace/api/datastreams @DataDog/data-streams-monitoring internal-api/src/test/groovy/datadog/trace/api/datastreams @DataDog/data-streams-monitoring + +# @DataDog/ml-observability +dd-trace-api/src/main/java/datadog/trace/api/llmobs/ @DataDog/ml-observability +dd-java-agent/agent-llmobs/ @DataDog/ml-observability +dd-trace-core/src/main/java/datadog/trace/llmobs/ @DataDog/ml-observability +dd-trace-core/src/test/groovy/datadog/trace/llmobs/ @DataDog/ml-observability