-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix support for OpenAI developer messages #539
Changes from all commits
aa1573b
8e050f4
f87d31b
a05ea5d
057b95d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
import com.openai.models.ChatCompletionAssistantMessageParam; | ||
import com.openai.models.ChatCompletionContentPartText; | ||
import com.openai.models.ChatCompletionCreateParams; | ||
import com.openai.models.ChatCompletionDeveloperMessageParam; | ||
import com.openai.models.ChatCompletionMessage; | ||
import com.openai.models.ChatCompletionMessageParam; | ||
import com.openai.models.ChatCompletionMessageToolCall; | ||
|
@@ -40,10 +41,14 @@ | |
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.logging.Level; | ||
import java.util.stream.Collectors; | ||
|
||
public class ChatCompletionEventsHelper { | ||
|
||
private static final java.util.logging.Logger LOG = | ||
java.util.logging.Logger.getLogger(ChatCompletionEventsHelper.class.getName()); | ||
|
||
private static final Logger EV_LOGGER = | ||
GlobalOpenTelemetry.get().getLogsBridge().get(Constants.INSTRUMENTATION_NAME); | ||
|
||
|
@@ -66,6 +71,14 @@ public static void emitPromptLogEvents( | |
if (settings.captureMessageContent) { | ||
putIfNotEmpty(bodyBuilder, "content", contentToString(sysMsg.content())); | ||
} | ||
} else if (concreteMessageParam instanceof ChatCompletionDeveloperMessageParam) { | ||
ChatCompletionDeveloperMessageParam sysMsg = | ||
(ChatCompletionDeveloperMessageParam) concreteMessageParam; | ||
eventType = "gen_ai.system.message"; | ||
putIfNotEmpty(bodyBuilder, "role", "developer"); | ||
if (settings.captureMessageContent) { | ||
putIfNotEmpty(bodyBuilder, "content", contentToString(sysMsg.content())); | ||
} | ||
} else if (concreteMessageParam instanceof ChatCompletionUserMessageParam) { | ||
ChatCompletionUserMessageParam userMsg = | ||
(ChatCompletionUserMessageParam) concreteMessageParam; | ||
|
@@ -102,7 +115,8 @@ public static void emitPromptLogEvents( | |
bodyBuilder.put("id", toolMsg.toolCallId()); | ||
} | ||
} else { | ||
throw new IllegalStateException("Unhandled type : " + msg.getClass().getName()); | ||
LOG.log(Level.WARNING, "Unhandled OpenAI message type will be dropped: {0}", msg); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would previously cause the instrumentation to fail, which is a bit too strict. |
||
continue; | ||
} | ||
newEvent(eventType).setBody(bodyBuilder.build()).emit(); | ||
} | ||
|
@@ -119,9 +133,7 @@ private static String contentToString(ChatCompletionToolMessageParam.Content con | |
if (text != null) { | ||
return text; | ||
} else if (content.isArrayOfContentParts()) { | ||
return content.asArrayOfContentParts().stream() | ||
.map(ChatCompletionContentPartText::text) | ||
.collect(Collectors.joining()); | ||
return joinContentParts(content.asArrayOfContentParts()); | ||
} else { | ||
throw new IllegalStateException("Unhandled content type for " + content); | ||
} | ||
|
@@ -146,14 +158,29 @@ private static String contentToString(ChatCompletionSystemMessageParam.Content c | |
if (text != null) { | ||
return text; | ||
} else if (content.isArrayOfContentParts()) { | ||
return content.asArrayOfContentParts().stream() | ||
.map(ChatCompletionContentPartText::text) | ||
.collect(Collectors.joining()); | ||
return joinContentParts(content.asArrayOfContentParts()); | ||
} else { | ||
throw new IllegalStateException("Unhandled content type for " + content); | ||
} | ||
} | ||
|
||
private static String contentToString(ChatCompletionDeveloperMessageParam.Content content) { | ||
String text = ApiAdapter.get().asText(content); | ||
if (text != null) { | ||
return text; | ||
} else if (content.isArrayOfContentParts()) { | ||
return joinContentParts(content.asArrayOfContentParts()); | ||
} else { | ||
throw new IllegalStateException("Unhandled content type for " + content); | ||
} | ||
} | ||
|
||
private static String joinContentParts(List<ChatCompletionContentPartText> contentParts) { | ||
return contentParts.stream() | ||
.map(ChatCompletionContentPartText::text) | ||
.collect(Collectors.joining()); | ||
} | ||
|
||
private static String contentToString(ChatCompletionUserMessageParam.Content content) { | ||
String text = ApiAdapter.get().asText(content); | ||
if (text != null) { | ||
|
@@ -228,7 +255,7 @@ private static LogRecordBuilder newEvent(String name) { | |
private static Value<?> buildToolCallEventObject(ChatCompletionMessageToolCall call) { | ||
Map<String, Value<?>> result = new HashMap<>(); | ||
result.put("id", Value.of(call.id())); | ||
result.put("type", Value.of(call._type().toString())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was not detected by muzzle: In some versions inbetween |
||
result.put("type", Value.of("function")); // "function" is the only currently supported type | ||
result.put("function", buildFunctionEventObject(call.function())); | ||
return Value.of(result); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ | |
import com.openai.models.ChatCompletionAssistantMessageParam; | ||
import com.openai.models.ChatCompletionContentPart; | ||
import com.openai.models.ChatCompletionCreateParams; | ||
import com.openai.models.ChatCompletionDeveloperMessageParam; | ||
import com.openai.models.ChatCompletionMessageParam; | ||
import com.openai.models.ChatCompletionSystemMessageParam; | ||
import com.openai.models.ChatCompletionToolMessageParam; | ||
|
@@ -38,6 +39,9 @@ public Object extractConcreteCompletionMessageParam(ChatCompletionMessageParam b | |
if (base.isChatCompletionSystemMessageParam()) { | ||
return base.asChatCompletionSystemMessageParam(); | ||
} | ||
if (base.isChatCompletionDeveloperMessageParam()) { | ||
return base.asChatCompletionDeveloperMessageParam(); | ||
} | ||
if (base.isChatCompletionUserMessageParam()) { | ||
return base.asChatCompletionUserMessageParam(); | ||
} | ||
|
@@ -47,7 +51,7 @@ public Object extractConcreteCompletionMessageParam(ChatCompletionMessageParam b | |
if (base.isChatCompletionToolMessageParam()) { | ||
return base.asChatCompletionToolMessageParam(); | ||
} | ||
throw new IllegalStateException("Unhandled message param type: " + base); | ||
return null; | ||
} | ||
|
||
@Override | ||
|
@@ -61,11 +65,11 @@ public String extractText(ChatCompletionContentPart part) { | |
@Override | ||
public String extractType(ChatCompletionCreateParams.ResponseFormat val) { | ||
if (val.isResponseFormatText()) { | ||
return val.asResponseFormatText()._type().toString(); | ||
return "text"; | ||
} else if (val.isResponseFormatJsonObject()) { | ||
return val.asResponseFormatJsonObject()._type().toString(); | ||
return "json_object"; | ||
} else if (val.isResponseFormatJsonSchema()) { | ||
return val.asResponseFormatJsonSchema()._type().toString(); | ||
return "json_schema"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For some versions |
||
} | ||
return null; | ||
} | ||
|
@@ -93,6 +97,11 @@ public String asText(ChatCompletionSystemMessageParam.Content content) { | |
return content.isTextContent() ? content.asTextContent() : null; | ||
} | ||
|
||
@Override | ||
public String asText(ChatCompletionDeveloperMessageParam.Content content) { | ||
return content.isTextContent() ? content.asTextContent() : null; | ||
} | ||
|
||
@Override | ||
public String asText(ChatCompletionAssistantMessageParam.Content content) { | ||
return content.isTextContent() ? content.asTextContent() : null; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. where the SDK isn't explicit in how these map to json, we make a good guess