Skip to content

Commit 57212c6

Browse files
committed
:TestOpenAiLlmObs::test_chat_completion[java-test-ml-app-tcp-False] PASSED
1 parent 85dbbf2 commit 57212c6

File tree

1 file changed

+72
-17
lines changed
  • dd-java-agent/instrumentation/openai-java/openai-java-1.0/src/main/java/datadog/trace/instrumentation/openai_java

1 file changed

+72
-17
lines changed

dd-java-agent/instrumentation/openai-java/openai-java-1.0/src/main/java/datadog/trace/instrumentation/openai_java/OpenAiDecorator.java

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import com.openai.models.chat.completions.ChatCompletion;
99
import com.openai.models.chat.completions.ChatCompletionChunk;
1010
import com.openai.models.chat.completions.ChatCompletionCreateParams;
11+
import com.openai.models.chat.completions.ChatCompletionMessage;
12+
import com.openai.models.chat.completions.ChatCompletionMessageParam;
1113
import com.openai.models.completions.Completion;
1214
import com.openai.models.completions.CompletionCreateParams;
15+
import com.openai.models.completions.CompletionUsage;
1316
import com.openai.models.embeddings.CreateEmbeddingResponse;
1417
import com.openai.models.embeddings.EmbeddingCreateParams;
1518
import com.openai.models.responses.Response;
@@ -127,22 +130,13 @@ public void decorateWithCompletion(AgentSpan span, Completion completion) {
127130
.collect(Collectors.toList());
128131
span.setTag("_ml_obs_tag.output", output);
129132

130-
completion
131-
.usage()
132-
.ifPresent(
133-
u -> {
134-
span.setTag("_ml_obs_metric.input_tokens", u.promptTokens());
135-
span.setTag("_ml_obs_metric.output_tokens", u.completionTokens());
136-
span.setTag("_ml_obs_metric.total_tokens", u.totalTokens());
137-
});
133+
completion.usage().ifPresent(usage -> OpenAiDecorator.annotateWithCompletionUsage(span, usage));
138134
}
139135

140136
public void decorateWithCompletions(AgentSpan span, List<Completion> completions) {
141137
if (!completions.isEmpty()) {
142138
decorateWithCompletion(span, completions.get(0));
143139
}
144-
145-
// TODO set LLMObs tags (not visible to APM)
146140
}
147141

148142
public void decorateWithHttpResponse(AgentSpan span, HttpResponse response) {
@@ -206,20 +200,81 @@ public void decorateChatCompletion(AgentSpan span, ChatCompletionCreateParams pa
206200
return;
207201
}
208202
span.setTag(REQUEST_MODEL, params.model().asString()); // TODO extract model, might not be set
203+
204+
span.setTag(
205+
"_ml_obs_tag.input",
206+
params.messages().stream().map(OpenAiDecorator::llmMessage).collect(Collectors.toList()));
207+
208+
Map<String, Object> metadata = new HashMap<>();
209+
params.maxTokens().ifPresent(v -> metadata.put("max_tokens", v));
210+
// params.maxCompletionTokens().ifPresent(v -> metadata.put("max_tokens", v));
211+
params.temperature().ifPresent(v -> metadata.put("temperature", v));
212+
span.setTag("_ml_obs_tag.metadata", metadata);
213+
}
214+
215+
private static LLMObs.LLMMessage llmMessage(ChatCompletionMessageParam m) {
216+
String role = "unknown";
217+
String content = null;
218+
if (m.isAssistant()) {
219+
role = "assistant";
220+
content = m.asAssistant().content().map(v -> v.text().orElse(null)).orElse(null);
221+
} else if (m.isDeveloper()) {
222+
role = "developer";
223+
content = m.asDeveloper().content().text().orElse(null);
224+
} else if (m.isSystem()) {
225+
role = "system";
226+
content = m.asSystem().content().text().orElse(null);
227+
} else if (m.isTool()) {
228+
role = "tool";
229+
content = m.asTool().content().text().orElse(null);
230+
} else if (m.isUser()) {
231+
role = "user";
232+
content = m.asUser().content().text().orElse(null);
233+
}
234+
return LLMObs.LLMMessage.from(role, content);
209235
}
210236

211237
public void decorateWithChatCompletion(AgentSpan span, ChatCompletion completion) {
212-
span.setTag(RESPONSE_MODEL, completion.model());
238+
String modelName = completion.model();
239+
span.setTag(RESPONSE_MODEL, modelName);
213240

214-
// TODO set LLMObs tags (not visible to APM)
241+
span.setTag("_ml_obs_tag.model_name", modelName);
242+
span.setTag("_ml_obs_tag.model_provider", "openai");
243+
// span.setTag("_ml_obs_tag.model_version", ); // TODO split and set version, e.g.
244+
// gpt-3.5-turbo-instruct:20230824-v2c
245+
246+
List<LLMObs.LLMMessage> output =
247+
completion.choices().stream()
248+
.map(OpenAiDecorator::llmMessage)
249+
.collect(Collectors.toList());
250+
span.setTag("_ml_obs_tag.output", output);
251+
252+
completion.usage().ifPresent(usage -> OpenAiDecorator.annotateWithCompletionUsage(span, usage));
253+
}
254+
255+
private static void annotateWithCompletionUsage(AgentSpan span, CompletionUsage usage) {
256+
span.setTag("_ml_obs_metric.input_tokens", usage.promptTokens());
257+
span.setTag("_ml_obs_metric.output_tokens", usage.completionTokens());
258+
span.setTag("_ml_obs_metric.total_tokens", usage.totalTokens());
259+
}
260+
261+
private static LLMObs.LLMMessage llmMessage(ChatCompletion.Choice choice) {
262+
ChatCompletionMessage msg = choice.message();
263+
Optional<?> roleOpt = msg._role().asString();
264+
String role = "unknown";
265+
if (roleOpt.isPresent()) {
266+
role = String.valueOf(roleOpt.get());
267+
}
268+
String content = msg.content().orElse(null);
269+
return LLMObs.LLMMessage.from(role, content);
215270
}
216271

217272
public void decorateWithChatCompletionChunks(AgentSpan span, List<ChatCompletionChunk> chunks) {
218273
if (!chunks.isEmpty()) {
219274
span.setTag(RESPONSE_MODEL, chunks.get(0).model());
220275
}
221276

222-
// TODO set LLMObs tags (not visible to APM)
277+
// TODO set LLMObs tags
223278
}
224279

225280
public void decorateEmbedding(AgentSpan span, EmbeddingCreateParams params) {
@@ -231,13 +286,13 @@ public void decorateEmbedding(AgentSpan span, EmbeddingCreateParams params) {
231286
}
232287
span.setTag(REQUEST_MODEL, params.model().asString()); // TODO extract model, might not be set
233288

234-
// TODO set LLMObs tags (not visible to APM)
289+
// TODO set LLMObs tags
235290
}
236291

237292
public void decorateWithEmbedding(AgentSpan span, CreateEmbeddingResponse response) {
238293
span.setTag(RESPONSE_MODEL, response.model());
239294

240-
// TODO set LLMObs tags (not visible to APM)
295+
// TODO set LLMObs tags
241296
}
242297

243298
public void decorateResponse(AgentSpan span, ResponseCreateParams params) {
@@ -256,7 +311,7 @@ public void decorateResponse(AgentSpan span, ResponseCreateParams params) {
256311
public void decorateWithResponse(AgentSpan span, Response response) {
257312
span.setTag(RESPONSE_MODEL, extractResponseModel(response._model()));
258313

259-
// TODO set LLMObs tags (not visible to APM)
314+
// TODO set LLMObs tags
260315
}
261316

262317
private String extractResponseModel(JsonField<ResponsesModel> model) {
@@ -292,6 +347,6 @@ public void decorateWithResponseStreamEvent(AgentSpan span, List<ResponseStreamE
292347
// span.setTag(RESPONSE_MODEL, responseStreamEvent.res()); // TODO there is no model
293348
}
294349

295-
// TODO set LLMObs tags (not visible to APM)
350+
// TODO set LLMObs tags
296351
}
297352
}

0 commit comments

Comments
 (0)