Java: Apply various fixes from API review (#5043)

### Motivation and Context

<!-- Thank you for your contribution to the semantic-kernel repo!
Please help reviewers and future users, providing the following
information:
  1. Why is this change required?
  2. What problem does it solve?
  3. What scenario does it contribute to?
  4. If it fixes an open issue, please link to the issue here.
-->

### Description

<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->

### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [ ] The code builds clean without any errors or warnings
- [ ] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [ ] All unit tests pass, and I have added new tests where possible
- [ ] I didn't break anyone 😄
This commit is contained in:
John Oliver
2024-02-15 22:07:45 +00:00
committed by GitHub
parent 31c9d5d186
commit 679bdb2180
12 changed files with 43 additions and 128 deletions
@@ -19,10 +19,8 @@ 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.services.chatcompletion.AuthorRole;
import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService;
import com.microsoft.semantickernel.services.chatcompletion.ChatHistory;
import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent;
import com.microsoft.semantickernel.contextvariables.ContextVariable;
import com.microsoft.semantickernel.contextvariables.ContextVariableTypes;
import com.microsoft.semantickernel.exceptions.AIException;
import com.microsoft.semantickernel.exceptions.SKException;
import com.microsoft.semantickernel.hooks.KernelHooks;
@@ -30,15 +28,15 @@ import com.microsoft.semantickernel.hooks.PreChatCompletionEvent;
import com.microsoft.semantickernel.orchestration.FunctionResult;
import com.microsoft.semantickernel.orchestration.FunctionResultMetadata;
import com.microsoft.semantickernel.orchestration.InvocationContext;
import com.microsoft.semantickernel.semanticfunctions.KernelFunction;
import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments;
import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
import com.microsoft.semantickernel.orchestration.ToolCallBehavior;
import com.microsoft.semantickernel.contextvariables.ContextVariable;
import com.microsoft.semantickernel.contextvariables.ContextVariableTypes;
import com.microsoft.semantickernel.semanticfunctions.KernelFunction;
import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments;
import com.microsoft.semantickernel.services.chatcompletion.AuthorRole;
import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService;
import com.microsoft.semantickernel.services.chatcompletion.ChatHistory;
import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -53,10 +51,10 @@ public class OpenAIChatCompletion implements ChatCompletionService {
private static final Logger LOGGER = LoggerFactory.getLogger(OpenAIChatCompletion.class);
private final OpenAIAsyncClient client;
private final Map<String, ContextVariable<?>> attributes;
@Nullable
private final String serviceId;
private final String modelId;
public OpenAIChatCompletion(
OpenAIAsyncClient client,
@@ -64,19 +62,13 @@ public class OpenAIChatCompletion implements ChatCompletionService {
@Nullable String serviceId) {
this.serviceId = serviceId;
this.client = client;
this.attributes = new HashMap<>();
attributes.put(MODEL_ID_KEY, ContextVariable.of(modelId));
this.modelId = modelId;
}
public static OpenAIChatCompletion.Builder builder() {
return new OpenAIChatCompletion.Builder();
}
@Override
public Map<String, ContextVariable<?>> getAttributes() {
return Collections.unmodifiableMap(attributes);
}
@Override
@Nullable
public String getServiceId() {
@@ -430,6 +422,12 @@ public class OpenAIChatCompletion implements ChatCompletionService {
}
@Nullable
@Override
public String getModelId() {
return modelId;
}
public static class Builder extends ChatCompletionService.Builder {
@Override
@@ -26,9 +26,9 @@ import reactor.core.publisher.Mono;
public class OpenAITextGenerationService implements TextGenerationService {
private final OpenAIAsyncClient client;
private final Map<String, ContextVariable<?>> attributes;
@Nullable
private final String serviceId;
private final String modelId;
/// <summary>
/// Creates a new <see cref="OpenAITextGenerationService"/> client instance supporting AAD auth
@@ -45,19 +45,13 @@ public class OpenAITextGenerationService implements TextGenerationService {
@Nullable String serviceId) {
this.serviceId = serviceId;
this.client = client;
attributes = new HashMap<>();
attributes.put(MODEL_ID_KEY, ContextVariable.of(modelId));
this.modelId = modelId;
}
public static Builder builder() {
return new Builder();
}
@Override
public Map<String, ContextVariable<?>> getAttributes() {
return Collections.unmodifiableMap(attributes);
}
@Override
@Nullable
public String getServiceId() {
@@ -162,6 +156,12 @@ public class OpenAITextGenerationService implements TextGenerationService {
return options;
}
@Nullable
@Override
public String getModelId() {
return modelId;
}
/**
* Builder for a TextGenerationService
*/
@@ -12,7 +12,7 @@ import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt;
import com.microsoft.semantickernel.services.AIService;
import com.microsoft.semantickernel.services.AIServiceSelection;
import com.microsoft.semantickernel.services.AiServiceCollection;
import com.microsoft.semantickernel.services.AIServiceCollection;
import com.microsoft.semantickernel.services.BaseAIServiceSelector;
import com.microsoft.semantickernel.services.textcompletion.TextGenerationService;
import java.util.Map;
@@ -84,7 +84,7 @@ public class Example62_CustomAIServiceSelector {
// A dumb AIServiceSelector that just returns the first service and execution settings it finds
static class CustomAIServiceSelector extends BaseAIServiceSelector {
public CustomAIServiceSelector(AiServiceCollection services) {
public CustomAIServiceSelector(AIServiceCollection services) {
super(services);
}
-4
View File
@@ -38,10 +38,6 @@
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
@@ -10,7 +10,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin;
import com.microsoft.semantickernel.services.AIService;
import com.microsoft.semantickernel.services.AIServiceSelection;
import com.microsoft.semantickernel.services.AIServiceSelector;
import com.microsoft.semantickernel.services.AiServiceCollection;
import com.microsoft.semantickernel.services.AIServiceCollection;
import com.microsoft.semantickernel.services.OrderedAIServiceSelector;
import com.microsoft.semantickernel.services.ServiceNotFoundException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -191,10 +191,10 @@ public class Kernel implements Buildable {
*/
public static class Builder implements SemanticKernelBuilder<Kernel> {
private final AiServiceCollection services = new AiServiceCollection();
private final AIServiceCollection services = new AIServiceCollection();
private final List<KernelPlugin> plugins = new ArrayList<>();
@Nullable
private Function<AiServiceCollection, AIServiceSelector> serviceSelectorProvider;
private Function<AIServiceCollection, AIServiceSelector> serviceSelectorProvider;
/**
* Adds a service to the kernel.
@@ -224,7 +224,7 @@ public class Kernel implements Buildable {
* @return {@code this} builder with the service selector provider set.
*/
public Kernel.Builder withServiceSelector(
Function<AiServiceCollection, AIServiceSelector> serviceSelector) {
Function<AIServiceCollection, AIServiceSelector> serviceSelector) {
this.serviceSelectorProvider = serviceSelector;
return this;
}
@@ -1,90 +1,28 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.services;
import com.microsoft.semantickernel.contextvariables.ContextVariable;
import java.util.Map;
import javax.annotation.Nullable;
/**
* Marker interface for AI services. {@code AIService}s are registered with the {@code Kernel}
* and are used to provide access to AI services.
* Marker interface for AI services. {@code AIService}s are registered with the {@code Kernel} and
* are used to provide access to AI services.
*/
public interface AIService {
/**
* Gets the attributes of the service.
* @return The attributes of the service.
*/
Map<String, ContextVariable<?>> getAttributes();
/**
* Key used to store the model identifier in the {@code attributes} map.
*/
String MODEL_ID_KEY = "ModelId";
/**
* Key used to store the endpoint in the {@code attributes} map.
*/
String ENDPOINT_KEY = "Endpoint";
/**
* Key used to store the API version in the {@code attributes} map.
*/
String API_VERSION_KEY = "ApiVersion";
/**
* Gets the model identifier from the {@code attributes} map.
* Gets the model identifier.
*
* @return The model identifier if it was specified in the service's attributes; otherwise,
* {@code null}.
*/
@Nullable
default String getModelId() {
return getAttribute(this, MODEL_ID_KEY);
}
/**
* Gets the endpoint from the {@code attributes} map.
*
* @return The endpoint if it was specified in the service's attributes; otherwise, {@code null}.
*/
@Nullable
default String getEndpoint() {
return getAttribute(this, ENDPOINT_KEY);
}
/**
* Gets the API version from the {@code attributes} map.
*
* @return The API version if it was specified in the service's attributes; otherwise, {@code null}.
*/
@Nullable
default String getApiVersion() {
return getAttribute(this, API_VERSION_KEY);
}
String getModelId();
/**
* Gets the service identifier.
*
* @return The service identifier.
*/
@Nullable
String getServiceId();
/**
* Get the named attribute from the service's attributes.
* @param service The service to get the attribute from.
* @param key The key of the attribute to get.
* @return The value of the attribute if it exists; otherwise, {@code null}.
*/
@Nullable
static String getAttribute(AIService service, String key) {
if (service.getAttributes() != null) {
ContextVariable<?> contextVariable = service.getAttributes().get(key);
if (contextVariable != null) {
return contextVariable.getValue(String.class);
}
}
return null;
}
}
@@ -2,6 +2,9 @@ package com.microsoft.semantickernel.services;
import java.util.HashMap;
public class AiServiceCollection extends HashMap<Class<? extends AIService>, AIService> {
/**
* A collection of AI services.
*/
public class AIServiceCollection extends HashMap<Class<? extends AIService>, AIService> {
}
@@ -14,14 +14,14 @@ import javax.annotation.Nullable;
*/
public abstract class BaseAIServiceSelector implements AIServiceSelector {
protected final AiServiceCollection services;
protected final AIServiceCollection services;
/**
* Initializes a new instance of the {@link BaseAIServiceSelector} class.
*
* @param services The services to select from.
*/
protected BaseAIServiceSelector(AiServiceCollection services) {
protected BaseAIServiceSelector(AIServiceCollection services) {
this.services = services;
}
@@ -29,7 +29,7 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector {
* class with an empty collection of services.
*/
public OrderedAIServiceSelector() {
super(new AiServiceCollection());
super(new AIServiceCollection());
}
/**
@@ -38,7 +38,7 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector {
*
* @param services The services to select from.
*/
public OrderedAIServiceSelector(AiServiceCollection services) {
public OrderedAIServiceSelector(AIServiceCollection services) {
super(services);
}
-5
View File
@@ -128,11 +128,6 @@
<artifactId>handlebars</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
@@ -1,14 +0,0 @@
{
"schema": 1,
"description": "Sample plugin with a model and service id",
"type": "completion",
"completion": {
"max_tokens": 150,
"temperature": 0.9,
"top_p": 0.0,
"presence_penalty": 0.6,
"frequency_penalty": 0.0,
"service_id": "a-service-id",
"model_id": "a-model-id"
}
}