Java: Fix exception on stop sequence when using text completion (#2964)

Allow setting streaming type
Improve exceptions on native function invocation
This commit is contained in:
John Oliver
2023-09-25 14:54:50 +01:00
committed by GitHub
parent 2e8035e8d8
commit 428dadb200
5 changed files with 56 additions and 22 deletions
@@ -30,8 +30,12 @@ import reactor.core.publisher.Mono;
/** OpenAI chat completion client. */
public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<OpenAIChatHistory> {
public OpenAIChatCompletion(OpenAIAsyncClient client, String modelId) {
private CompletionType defaultCompletionType;
public OpenAIChatCompletion(
OpenAIAsyncClient client, String modelId, CompletionType defaultCompletionType) {
super(client, modelId);
this.defaultCompletionType = defaultCompletionType;
}
@Override
@@ -50,7 +54,7 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
@Override
public CompletionType defaultCompletionType() {
return CompletionType.STREAMING;
return defaultCompletionType;
}
public static class Builder implements ChatCompletion.Builder<OpenAIChatHistory> {
@@ -59,12 +63,18 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
@Nullable private OpenAIAsyncClient client;
@Nullable private String modelId;
private CompletionType defaultCompletionType = CompletionType.STREAMING;
public Builder withOpenAIClient(OpenAIAsyncClient client) {
this.client = client;
return this;
}
public Builder withDefaultCompletionType(CompletionType completionType) {
this.defaultCompletionType = completionType;
return this;
}
public Builder withModelId(String modelId) {
this.modelId = modelId;
return this;
@@ -78,7 +88,7 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
if (modelId == null) {
throw new NotSupportedException(ErrorCodes.NOT_SUPPORTED, "Model ID not set");
}
return new OpenAIChatCompletion(client, modelId);
return new OpenAIChatCompletion(client, modelId, defaultCompletionType);
}
}
@@ -7,13 +7,13 @@ import com.azure.ai.openai.models.Completions;
import com.azure.ai.openai.models.CompletionsOptions;
import com.microsoft.semantickernel.Verify;
import com.microsoft.semantickernel.ai.AIException;
import com.microsoft.semantickernel.chatcompletion.ChatRequestSettings;
import com.microsoft.semantickernel.connectors.ai.openai.azuresdk.ClientBase;
import com.microsoft.semantickernel.exceptions.NotSupportedException;
import com.microsoft.semantickernel.exceptions.NotSupportedException.ErrorCodes;
import com.microsoft.semantickernel.textcompletion.CompletionRequestSettings;
import com.microsoft.semantickernel.textcompletion.CompletionType;
import com.microsoft.semantickernel.textcompletion.TextCompletion;
import com.microsoft.semantickernel.textcompletion.TextCompletion.Builder;
import jakarta.inject.Inject;
import java.util.Collections;
import java.util.HashMap;
@@ -71,7 +71,7 @@ public class OpenAITextCompletion extends ClientBase implements TextCompletion {
@Override
public CompletionType defaultCompletionType() {
return CompletionType.STREAMING;
return defaultCompletionType;
}
private Flux<String> generateMessageStream(CompletionsOptions completionsOptions) {
@@ -115,17 +115,22 @@ public class OpenAITextCompletion extends ClientBase implements TextCompletion {
throw new AIException(AIException.ErrorCodes.INVALID_REQUEST, "Max tokens must be >0");
}
return new CompletionsOptions(Collections.singletonList(text))
.setMaxTokens(requestSettings.getMaxTokens())
.setTemperature(requestSettings.getTemperature())
.setTopP(requestSettings.getTopP())
.setFrequencyPenalty(requestSettings.getFrequencyPenalty())
.setPresencePenalty(requestSettings.getPresencePenalty())
.setModel(getModelId())
.setUser(requestSettings.getUser())
.setBestOf(requestSettings.getBestOf())
.setLogitBias(new HashMap<>())
.setStop(requestSettings.getStopSequences());
CompletionsOptions options =
new CompletionsOptions(Collections.singletonList(text))
.setMaxTokens(requestSettings.getMaxTokens())
.setTemperature(requestSettings.getTemperature())
.setTopP(requestSettings.getTopP())
.setFrequencyPenalty(requestSettings.getFrequencyPenalty())
.setPresencePenalty(requestSettings.getPresencePenalty())
.setModel(getModelId())
.setUser(requestSettings.getUser())
.setBestOf(requestSettings.getBestOf())
.setLogitBias(new HashMap<>());
if (requestSettings instanceof ChatRequestSettings) {
options = options.setStop(requestSettings.getStopSequences());
}
return options;
}
public static final class Builder implements TextCompletion.Builder {
@@ -17,6 +17,7 @@ import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
import com.microsoft.semantickernel.semanticfunctions.SemanticFunctionConfig;
import com.microsoft.semantickernel.skilldefinition.FunctionView;
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
import com.microsoft.semantickernel.skilldefinition.ReadOnlySkillCollection;
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
import com.microsoft.semantickernel.textcompletion.CompletionRequestSettings;
@@ -529,7 +530,17 @@ public class DefaultStepwisePlanner implements StepwisePlanner {
List<SKFunction<?>> availableFunctions = this.getAvailableFunctions();
Optional<SKFunction<?>> targetFunction =
availableFunctions.stream()
.filter(f -> f.toFullyQualifiedName().equals(actionName))
.filter(
f -> {
return f.toFullyQualifiedName().equals(actionName)
|| f.toFullyQualifiedName()
.equals(
ReadOnlySkillCollection.GlobalSkill
+ "."
+ actionName)
|| f.toFullyQualifiedName()
.equals("GLOBAL_FUNCTIONS." + actionName);
})
.findFirst();
if (!targetFunction.isPresent()) {
+2 -2
View File
@@ -67,6 +67,8 @@
<module>connectors/semantickernel-connectors-ai-openai</module>
<module>connectors/semantickernel-connectors-memory-sqlite</module>
<module>connectors/semantickernel-connectors-memory-azurecognitivesearch</module>
<module>connectors/semantickernel-connectors-memory-jdbc</module>
<module>connectors/semantickernel-connectors-memory-postgresql</module>
<module>extensions/semantickernel-planners</module>
<module>extensions/semantickernel-gpt3-tokenizer</module>
@@ -76,8 +78,6 @@
<module>semantickernel-bom</module>
<module>semantickernel-api</module>
<module>semantickernel-core</module>
<module>connectors/semantickernel-connectors-memory-jdbc</module>
<module>connectors/semantickernel-connectors-memory-postgresql</module>
</modules>
<dependencyManagement>
@@ -300,10 +300,18 @@ public class NativeSKFunction extends AbstractSkFunction<Void> {
} else {
return method.invoke(instance, args.toArray());
}
} catch (IllegalAccessException
| InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw new AIException(
ErrorCodes.INVALID_REQUEST, e.getMessage());
ErrorCodes.INVALID_REQUEST,
"Function threw an exception: "
+ method.getName(),
e.getCause());
} catch (IllegalAccessException e) {
throw new AIException(
ErrorCodes.INVALID_REQUEST,
"Unable to access function "
+ method.getName(),
e);
}
})
.subscribeOn(Schedulers.boundedElastic()));