diff --git a/java/aiservices/openai/pom.xml b/java/aiservices/openai/pom.xml index e73f63d790..3aa692f4aa 100644 --- a/java/aiservices/openai/pom.xml +++ b/java/aiservices/openai/pom.xml @@ -42,7 +42,15 @@ 1.0-2 provided - + + + + src/main/resources + true + + + + diff --git a/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/OpenAIRequestSettings.java b/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/OpenAIRequestSettings.java new file mode 100644 index 0000000000..a1666fddc4 --- /dev/null +++ b/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/OpenAIRequestSettings.java @@ -0,0 +1,50 @@ +package com.microsoft.semantickernel.aiservices.openai; + +import com.azure.core.http.HttpHeaderName; +import com.azure.core.http.rest.RequestOptions; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import org.slf4j.Logger; + +public final class OpenAIRequestSettings { + + private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger( + OpenAIRequestSettings.class); + + private static final String SEMANTIC_KERNEL_VERSION_PROPERTY_NAME = "semantic-kernel.version"; + private static final String SEMANTIC_KERNEL_VERSION_PROPERTIES_FILE = "semantic-kernel-version.properties"; + private static final String version; + + + static { + version = loadVersion(); + } + + private static String loadVersion() { + + String version = "Java/unknown"; + + try (InputStream settingsFile = OpenAIRequestSettings.class.getResourceAsStream( + SEMANTIC_KERNEL_VERSION_PROPERTIES_FILE)) { + + Properties props = new Properties(); + props.load(settingsFile); + if (props.containsKey(SEMANTIC_KERNEL_VERSION_PROPERTY_NAME)) { + String skVersion = props.getProperty(SEMANTIC_KERNEL_VERSION_PROPERTY_NAME); + if (skVersion != null && !skVersion.isEmpty()) { + return "Java/" + skVersion; + } + } + } catch (IOException e) { + //Ignore + LOGGER.trace("Failed to load Semantic Kernel version from properties file", e); + } + return version; + } + + public static RequestOptions getRequestOptions() { + return new RequestOptions() + .setHeader(HttpHeaderName.fromString("Semantic-Kernel-Version"), version); + } +} diff --git a/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java b/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java index 9d42a0212b..150e44084e 100644 --- a/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java +++ b/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java @@ -21,12 +21,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.aiservices.openai.OpenAIRequestSettings; import com.microsoft.semantickernel.chatcompletion.AuthorRole; import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.chatcompletion.ChatHistory; import com.microsoft.semantickernel.chatcompletion.ChatMessageContent; import com.microsoft.semantickernel.chatcompletion.StreamingChatMessageContent; import com.microsoft.semantickernel.exceptions.AIException; +import com.microsoft.semantickernel.exceptions.AIException.ErrorCodes; import com.microsoft.semantickernel.exceptions.SKException; import com.microsoft.semantickernel.hooks.KernelHooks; import com.microsoft.semantickernel.hooks.PreChatCompletionEvent; @@ -165,7 +167,15 @@ public class OpenAIChatCompletion implements ChatCompletionService { .getOptions(); return client - .getChatCompletions(getModelId(), options) + .getChatCompletionsWithResponse(getModelId(), options, + OpenAIRequestSettings.getRequestOptions()) + .flatMap(completionsResult -> { + if (completionsResult.getStatusCode() >= 400) { + return Mono.error(new AIException(ErrorCodes.SERVICE_ERROR, + "Request failed: " + completionsResult.getStatusCode())); + } + return Mono.just(completionsResult.getValue()); + }) .filter(choices -> choices.getChoices() != null && !choices.getChoices().isEmpty()) .map(this::accumulateResponses) .map(responses -> diff --git a/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/textcompletion/OpenAITextGenerationService.java b/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/textcompletion/OpenAITextGenerationService.java index c0db75c824..96dedce0fb 100644 --- a/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/textcompletion/OpenAITextGenerationService.java +++ b/java/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/textcompletion/OpenAITextGenerationService.java @@ -4,7 +4,9 @@ import com.azure.ai.openai.OpenAIAsyncClient; import com.azure.ai.openai.models.CompletionsOptions; import com.azure.ai.openai.models.CompletionsUsage; import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.aiservices.openai.OpenAIRequestSettings; import com.microsoft.semantickernel.exceptions.AIException; +import com.microsoft.semantickernel.exceptions.AIException.ErrorCodes; import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; @@ -90,9 +92,16 @@ public class OpenAITextGenerationService implements TextGenerationService { CompletionsOptions completionsOptions = getCompletionsOptions(text, requestSettings); return client - .getCompletions(getModelId(), completionsOptions) + .getCompletionsWithResponse(getModelId(), completionsOptions, + OpenAIRequestSettings.getRequestOptions()) + .flatMap(completionsResult -> { + if (completionsResult.getStatusCode() >= 400) { + return Mono.error(new AIException(ErrorCodes.SERVICE_ERROR, + "Request failed: " + completionsResult.getStatusCode())); + } + return Mono.just(completionsResult.getValue()); + }) .map(completions -> { - FunctionResultMetadata metadata = FunctionResultMetadata.build( completions.getId(), completions.getUsage(), diff --git a/java/aiservices/openai/src/main/resources/com/microsoft/semantickernel/aiservices/openai/semantic-kernel-version.properties b/java/aiservices/openai/src/main/resources/com/microsoft/semantickernel/aiservices/openai/semantic-kernel-version.properties new file mode 100644 index 0000000000..73220f4f85 --- /dev/null +++ b/java/aiservices/openai/src/main/resources/com/microsoft/semantickernel/aiservices/openai/semantic-kernel-version.properties @@ -0,0 +1 @@ +semantic-kernel.version=${project.version} \ No newline at end of file