From 7af8b909fa73ac8167f79239309aefe6592392b9 Mon Sep 17 00:00:00 2001 From: David Grieve Date: Wed, 14 Feb 2024 14:12:55 -0500 Subject: [PATCH 1/3] Java: SK v1 javadoc (#4990) ### Motivation and Context ### Description ### Contribution Checklist - [ ] 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 :smile: --- .../Example30_ChatWithPrompts.java | 3 +- .../syntaxexamples/Example57_KernelHooks.java | 2 +- .../microsoft/semantickernel/AIService.java | 28 ++- .../com/microsoft/semantickernel/Kernel.java | 127 +++++++++-- .../semantickernel/KernelContent.java | 55 ++++- .../KernelPluginCollection.java | 40 ++++ .../ServiceNotFoundException.java | 10 - .../StreamingKernelContent.java | 55 +++-- .../semantickernel/TextAIService.java | 4 + .../com/microsoft/semantickernel/Todo.java | 9 + .../com/microsoft/semantickernel/Verify.java | 18 ++ .../semantickernel/builders/Buildable.java | 5 +- .../builders/SemanticKernelBuilder.java | 5 +- .../builders/ServiceLoadUtil.java | 14 ++ .../chatcompletion/AuthorRole.java | 15 +- .../chatcompletion/ChatCompletionService.java | 41 ++++ .../chatcompletion/ChatHistory.java | 76 ++++++- .../chatcompletion/ChatMessageContent.java | 66 +++++- .../StreamingChatMessageContent.java | 39 +++- .../connectors/WebSearchEngineConnector.java | 25 ++- .../exceptions/ConfigurationException.java | 41 +++- .../exceptions/NotSupportedException.java | 42 ---- .../hooks/FunctionInvokedEvent.java | 32 ++- .../hooks/FunctionInvokingEvent.java | 31 ++- .../semantickernel/hooks/KernelHook.java | 33 ++- .../semantickernel/hooks/KernelHookEvent.java | 3 + .../semantickernel/hooks/KernelHooks.java | 98 ++++++++- .../hooks/PreChatCompletionEvent.java | 11 + .../hooks/PromptRenderedEvent.java | 27 ++- .../hooks/PromptRenderingEvent.java | 25 ++- .../orchestration/FunctionInvocation.java | 87 +++++++- .../orchestration/FunctionResult.java | 39 +++- .../orchestration/FunctionResultMetadata.java | 53 +++++ .../orchestration/InvocationContext.java | 68 +++++- .../orchestration/KernelFunction.java | 132 ++++++++++-- .../KernelFunctionArguments.java | 37 +++- .../orchestration/KernelFunctionMetadata.java | 42 +++- .../orchestration/KernelFunctionYaml.java | 36 +++- .../PromptExecutionSettings.java | 204 +++++++++++++++--- .../orchestration/ToolCallBehavior.java | 137 +++++++++++- .../contextvariables/CaseInsensitiveMap.java | 12 ++ .../contextvariables/ContextVariable.java | 107 +++++++++ .../contextvariables/ContextVariableType.java | 21 ++ .../ContextVariableTypeConverter.java | 77 +++++++ .../ContextVariableTypes.java | 78 ++++++- ...nVariableContextVariableTypeConverter.java | 13 +- ...rVariableContextVariableTypeConverter.java | 18 +- ...yVariableContextVariableTypeConverter.java | 16 +- ...tionUsageContextVariableTypeConverter.java | 10 + .../DateTimeContextVariableTypeConverter.java | 11 + .../InstantContextVariableTypeConverter.java | 11 + ...rVariableContextVariableTypeConverter.java | 16 +- ...gVariableContextVariableTypeConverter.java | 11 +- ...dVariableContextVariableTypeConverter.java | 10 + .../plugin/KernelFunctionFactory.java | 68 ++++-- .../plugin/KernelParameterMetadata.java | 38 +++- .../semantickernel/plugin/KernelPlugin.java | 37 ++++ .../plugin/KernelPluginFactory.java | 101 +++++---- .../plugin/KernelReturnParameterMetadata.java | 21 ++ .../semantickernel/plugin/Plugin.java | 34 ++- .../annotations/DefineKernelFunction.java | 28 +++ .../annotations/KernelFunctionParameter.java | 29 ++- .../plugin/annotations/SKSample.java | 29 ++- .../AggregatorPromptTemplateFactory.java | 11 + .../HandlebarsPromptTemplateFactory.java | 9 + .../semanticfunctions/InputVariable.java | 67 ++++-- .../KernelFunctionFromMethod.java | 78 +++++-- .../KernelFunctionFromPrompt.java | 119 +++++++--- .../KernelPromptTemplateFactory.java | 7 +- .../MethodDetails.java | 48 ++++- .../semanticfunctions/OutputVariable.java | 20 +- .../semanticfunctions/PromptTemplate.java | 19 +- .../PromptTemplateConfig.java | 148 ++++++++++++- .../PromptTemplateFactory.java | 33 +++ .../services/AIServiceSelection.java | 4 +- .../services/AIServiceSelector.java | 13 +- .../services/BaseAIServiceSelector.java | 34 ++- .../services/NamedServiceProvider.java | 6 +- .../services/OrderedAIServiceSelector.java | 63 ++++-- .../services/ServiceNotFoundException.java | 17 ++ .../handlebars/HandlebarsPromptTemplate.java | 10 +- .../semantickernel/CodeTokenizer.java | 64 +++--- .../semantickernel/DefaultPromptTemplate.java | 34 +-- .../semantickernel/TemplateException.java | 25 +-- .../semantickernel/TemplateTokenizer.java | 72 +++---- .../semantickernel/blocks/BlockTypes.java | 6 + .../semantickernel/blocks/CodeBlock.java | 9 + .../semantickernel/blocks/CodeRendering.java | 5 + .../blocks/FunctionIdBlock.java | 22 +- .../semantickernel/blocks/TextRendering.java | 21 +- .../textcompletion/StreamingTextContent.java | 14 ++ .../textcompletion/TextContent.java | 14 ++ .../textcompletion/TextGenerationService.java | 31 ++- .../util/EmbeddedResourceLoader.java | 18 ++ 94 files changed, 3070 insertions(+), 582 deletions(-) delete mode 100644 java/semantickernel-api/src/main/java/com/microsoft/semantickernel/ServiceNotFoundException.java delete mode 100644 java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/NotSupportedException.java rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{orchestration => semanticfunctions}/MethodDetails.java (54%) create mode 100644 java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/ServiceNotFoundException.java diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java index 0e8b70414d..b752ce8fa5 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java @@ -5,7 +5,6 @@ import com.azure.ai.openai.OpenAIClientBuilder; import com.azure.core.credential.AzureKeyCredential; import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; -import com.microsoft.semantickernel.ServiceNotFoundException; import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.chatcompletion.ChatHistory; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; @@ -14,7 +13,9 @@ import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.TimePlugin; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; +import com.microsoft.semantickernel.services.ServiceNotFoundException; import com.microsoft.semantickernel.util.EmbeddedResourceLoader; + import java.io.FileNotFoundException; import java.time.ZoneId; import java.time.ZonedDateTime; diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java index 462c78ecf3..3800e4e1cd 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java @@ -222,7 +222,7 @@ public class Example57_KernelHooks { String result = (String) event.getResult().getResult(); result = result.replaceAll("[aeiouAEIOU0-9]", "*"); - return new FunctionInvokedEvent<>( + return new FunctionInvokedEvent( event.getFunction(), event.getArguments(), new FunctionResult<>( diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/AIService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/AIService.java index 614f251137..d9c6ba13e2 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/AIService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/AIService.java @@ -2,14 +2,21 @@ package com.microsoft.semantickernel; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; + import java.util.Map; + import javax.annotation.Nullable; /** - * Marker interface for 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> getAttributes(); /** @@ -32,7 +39,7 @@ public interface AIService { * Gets the model identifier from the {@code attributes} map. * * @return The model identifier if it was specified in the service's attributes; otherwise, - * null. + * {@code null}. */ @Nullable default String getModelId() { @@ -42,7 +49,7 @@ public interface AIService { /** * Gets the endpoint from the {@code attributes} map. * - * @return The endpoint if it was specified in the service's attributes; otherwise, null. + * @return The endpoint if it was specified in the service's attributes; otherwise, {@code null}. */ @Nullable default String getEndpoint() { @@ -52,19 +59,26 @@ public interface AIService { /** * Gets the API version from the {@code attributes} map. * - * @return The API version if it was specified in the service's attributes; otherwise, null. + * @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); } + /** + * Gets the service identifier. + * @return The service identifier. + */ @Nullable String getServiceId(); - /// - /// Gets the specified attribute. - /// + /** + * 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) { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java index a201e47385..403187abdc 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java @@ -10,6 +10,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.services.AIServiceSelection; import com.microsoft.semantickernel.services.AIServiceSelector; import com.microsoft.semantickernel.services.OrderedAIServiceSelector; +import com.microsoft.semantickernel.services.ServiceNotFoundException; import java.util.ArrayList; import java.util.HashMap; @@ -19,22 +20,26 @@ import java.util.function.Function; import javax.annotation.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** - * Interface for the semantic kernel. + * Provides state for use throughout a Semantic Kernel workload. + *

+ * An instance of {@code Kernel} is passed through to every function invocation and service call + * throughout the system, providing to each the ability to access shared state and services. */ public class Kernel implements Buildable { - private static final Logger LOGGER = LoggerFactory.getLogger(Kernel.class); - private final AIServiceSelector serviceSelector; private final KernelPluginCollection plugins; private final KernelHooks globalKernelHooks; + /** + * Initializes a new instance of {@code Kernel}. + * @param serviceSelector The {@code AIServiceSelector} used to query for services available through the kernel. + * @param plugins The collection of plugins available through the kernel. If {@code null}, an empty collection will be used. + * @param globalKernelHooks The global hooks to be used throughout the kernel. If {@code null}, an empty collection will be used. + */ public Kernel( AIServiceSelector serviceSelector, @Nullable List plugins, @@ -49,6 +54,16 @@ public class Kernel implements Buildable { this.globalKernelHooks = new KernelHooks(globalKernelHooks); } + /** + * Invokes a {@code KernelFunction} function by name. + * @param The return type of the function. + * @param pluginName The name of the plugin containing the function. + * @param functionName The name of the function to invoke. + * @return The result of the function invocation. + * @throws IllegalArgumentException if the plugin or function is not found. + * @see KernelFunction#invokeAsync(Kernel) + * @see KernelPluginCollection#getFunction(String, String) + */ @SuppressWarnings({"rawtypes", "unchecked"}) public FunctionInvocation invokeAsync( String pluginName, @@ -57,42 +72,100 @@ public class Kernel implements Buildable { return invokeAsync(function); } + /** + * Invokes a {@code KernelFunction}. + * @param The return type of the function. + * @param function The function to invoke. + * @return The result of the function invocation. + * @see KernelFunction#invokeAsync(Kernel) + */ public FunctionInvocation invokeAsync(KernelFunction function) { return function.invokeAsync(this); } - public void addPlugin(KernelPlugin plugin) { + /** + * This method is used to add plugins to the kernel after it has been created. + * If a plugin with the same name already exists, it will be replaced. + * @param plugin The plugin to add. + * @return {@code this} kernel with the plugin added. + */ + public Kernel addPlugin(KernelPlugin plugin) { plugins.add(plugin); + return this; } + /** + * Gets the plugin with the specified name. + * @param pluginName The name of the plugin to get. + * @return The plugin with the specified name, or {@code null} if no such plugin exists. + */ @Nullable public KernelPlugin getPlugin(String pluginName) { return plugins.getPlugin(pluginName); } + /** + * Gets the plugins that were added to the kernel. + * @return The plugins available through the kernel. + * @see Kernel#getPlugins() + */ + @SuppressFBWarnings("EI_EXPOSE_REP") public List getPlugins() { return plugins.getPlugins(); } + /** + * Gets the function with the specified name from the plugin with the specified name. + * @param The return type of the function. + * @param pluginName The name of the plugin containing the function. + * @param functionName The name of the function to get. + * @return The function with the specified name from the plugin with the specified name. + * @throws IllegalArgumentException if the plugin or function is not found. + * @see KernelPluginCollection#getFunction(String, String) + */ @SuppressWarnings("unchecked") public KernelFunction getFunction(String pluginName, String functionName) { return (KernelFunction)plugins.getFunction(pluginName, functionName); } + /** + * Gets the functions available through the kernel. Functions are collected from all plugins + * available through the kernel. + * @return The functions available through the kernel. + * @see Kernel#getPlugins() + * @see Kernel.Builder#withPlugin(KernelPlugin) + */ public List> getFunctions() { return plugins.getFunctions(); } + /** + * Get the {@code KernelHooks} used throughout the kernel. + * These {@code KernelHooks} are used in addition to any hooks provided to a function. + * @return The {@code KernelHooks} used throughout the kernel. + * @see KernelFunction#invokeAsync(Kernel, KernelFunctionArguments, ContextVariableType, InvocationContext) + */ + @SuppressFBWarnings("EI_EXPOSE_REP") + public KernelHooks getGlobalKernelHooks() { + return globalKernelHooks; + } + + /** + * Get the AIServiceSelector used to query for services available through the kernel. + * @return The AIServiceSelector used to query for services available through the kernel. + */ public AIServiceSelector getServiceSelector() { return serviceSelector; } - - @SuppressFBWarnings("EI_EXPOSE_REP") - public KernelHooks getGlobalKernelHooks() { - return globalKernelHooks; - } - + /** + * Get the service of the specified type from the kernel. + * @param The type of the service to get. + * @param clazz The class of the service to get. + * @return The service of the specified type from the kernel. + * @throws ServiceNotFoundException if the service is not found. + * @see com.microsoft.semantickernel.services.AIServiceSelector#trySelectAIService(Class, KernelFunction, KernelFunctionArguments) + */ public T getService(Class clazz) throws ServiceNotFoundException { AIServiceSelection selector = serviceSelector .trySelectAIService( @@ -108,11 +181,18 @@ public class Kernel implements Buildable { return selector.getService(); } + /** + * Get the fluent builder for creating a new instance of {@code Kernel}. + * @return The fluent builder for creating a new instance of {@code Kernel}. + */ public static Kernel.Builder builder() { return new Kernel.Builder(); } + /** + * A fluent builder for creating a new instance of {@code Kernel}. + */ public static class Builder implements SemanticKernelBuilder { private final Map, AIService> services = new HashMap<>(); @@ -120,22 +200,43 @@ public class Kernel implements Buildable { @Nullable private Function, AIService>, AIServiceSelector> serviceSelectorProvider; + /** + * Adds a service to the kernel. + * @param The type of the service to add. + * @param clazz The class of the service to add. + * @param aiService The service to add. + * @return {@code this} builder with the service added. + */ public Builder withAIService(Class clazz, T aiService) { services.put(clazz, aiService); return this; } + /** + * Adds a plugin to the kernel. + * @param plugin The plugin to add. + * @return {@code this} builder with the plugin added. + */ public Kernel.Builder withPlugin(KernelPlugin plugin) { plugins.add(plugin); return this; } + /** + * Sets the service selector provider for the kernel. + * @param serviceSelector The service selector provider for the kernel. + * @return {@code this} builder with the service selector provider set. + */ public Kernel.Builder withServiceSelector( Function, AIService>, AIServiceSelector> serviceSelector) { this.serviceSelectorProvider = serviceSelector; return this; } + /** + * Builds a new instance of {@code Kernel} with the services and plugins provided. + * @return A new instance of {@code Kernel}. + */ @Override public Kernel build() { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java index 51bd1fe9c8..a879f1b0fc 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java @@ -1,17 +1,41 @@ package com.microsoft.semantickernel; import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; + import javax.annotation.Nullable; +/** + * Base class which represents the content returned by an AI service. + * @param The type of the content. + */ public abstract class KernelContent> { + /* + * The inner content representation. Use this to bypass the current + * abstraction. The usage of this property is considered "unsafe". + * Use it only if strictly necessary. + */ @Nullable - private Object innerContent; + private final Object innerContent; + + /** + * The model ID used to generate the content. + */ @Nullable private final String modelId; - @Nullable - private FunctionResultMetadata metadata; + /** + * The metadata associated with the content. + */ + @Nullable + private final FunctionResultMetadata metadata; + + /** + * Initializes a new instance of the {@link KernelContent} class. + * @param innerContent The inner content representation. + * @param modelId The model identifier used to generate the content. + * @param metadata The metadata associated with the content. + */ public KernelContent( @Nullable Object innerContent, @@ -22,31 +46,40 @@ public abstract class KernelContent> { ) { this.innerContent = innerContent; this.modelId = modelId; - if (metadata != null) { - this.metadata = metadata; - } - } - - KernelContent setInnerContent(@Nullable Object innerContent) { - this.innerContent = innerContent; - return this; + this.metadata = metadata; } + /** + * Gets the inner content representation. + * @return The inner content representation. + */ @Nullable public Object getInnerContent() { return innerContent; } + /** + * Gets the model identifier used to generate the content. + * @return The model identifier used to generate the content. + */ @Nullable public String getModelId() { return modelId; } + /** + * Gets the metadata associated with the content. + * @return The metadata associated with the content. + */ @Nullable public FunctionResultMetadata getMetadata() { return metadata; } + /** + * Gets the content returned by the AI service. + * @return The content. + */ @Nullable public abstract String getContent(); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java index 31d0adc0a3..76c92cc32b 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java @@ -13,19 +13,37 @@ import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * A collection of {@link KernelPlugin} instances. + */ class KernelPluginCollection { private static final Logger LOGGER = LoggerFactory.getLogger(KernelPluginCollection.class); private final Map plugins = new CaseInsensitiveMap<>(); + /** + * Initialize a new instance of the {@link KernelPluginCollection} + * class with an empty collection of plugins. + */ KernelPluginCollection() { } + /** + * Initialize a new instance of the {@link KernelPluginCollection} + * class from a collection of plugins. + */ KernelPluginCollection(List plugins) { plugins.forEach(plugin -> this.plugins.put(plugin.getName(), plugin)); } + /** + * Gets the function with the given name from the plugin with the given name. + * @param pluginName The name of the plugin containing the function. + * @param functionName The name of the function to get. + * @return The function with the given name from the plugin with the given name. + * @throws IllegalArgumentException If the plugin or function is not found. + */ KernelFunction getFunction(String pluginName, String functionName) { KernelPlugin plugin = plugins.get(pluginName); if (plugin == null) { @@ -40,12 +58,20 @@ class KernelPluginCollection { return function; } + /** + * Gets all functions from all plugins. + * @return A list of all functions from all plugins. + */ List> getFunctions() { return plugins.values().stream() .flatMap(plugin -> plugin.getFunctions().values().stream()) .collect(Collectors.toList()); } + /** + * Gets all function metadata from all plugins. + * @return A list of all function metadata from all plugins. + */ List> getFunctionsMetadata() { return plugins.values().stream() .flatMap(plugin -> plugin.getFunctions().values().stream()) @@ -53,14 +79,28 @@ class KernelPluginCollection { .collect(Collectors.toList()); } + /** + * Gets all plugins that were added to the kernel. + * @return The plugins available through the kernel. + */ List getPlugins() { return new ArrayList<>(plugins.values()); } + /** + * Gets the plugin with the specified name. + * @param pluginName The name of the plugin to get. + * @return The plugin with the specified name, or {@code null} if no such plugin exists. + */ KernelPlugin getPlugin(String pluginName) { return plugins.get(pluginName); } + /** + * Adds a plugin to the collection. + * If a plugin with the same name already exists, it will be replaced. + * @param plugin The plugin to add. + */ void add(KernelPlugin plugin) { if (plugins.containsKey(plugin.getName())) { LOGGER.warn("Plugin {} already exists, overwriting existing plugin", plugin.getName()); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/ServiceNotFoundException.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/ServiceNotFoundException.java deleted file mode 100644 index bbb127271d..0000000000 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/ServiceNotFoundException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.microsoft.semantickernel; - -import com.microsoft.semantickernel.exceptions.SKCheckedException; - -public class ServiceNotFoundException extends SKCheckedException { - - public ServiceNotFoundException(String s) { - super(s); - } -} diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java index 198b64e866..786a6a161d 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java @@ -1,45 +1,44 @@ package com.microsoft.semantickernel; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; + import java.util.Map; + import javax.annotation.Nullable; -public abstract class StreamingKernelContent { +/** + * Base class which represents the content returned by a streaming AI service. + * @param The type of the content. + */ +public abstract class StreamingKernelContent> extends KernelContent { - ///

- /// The inner content representation. Use this to bypass the current abstraction. - /// - /// - /// The usage of this property is considered "unsafe". Use it only if strictly necessary. - /// - @Nullable - private final T innerContent; - - /// - /// In a scenario of multiple choices per request, this represents zero-based index of the choice in the streaming sequence - /// + /** + * In a scenario of multiple choices per request, this represents + * the zero-based index of the choice in the streaming sequence + */ private final int choiceIndex; - /// - /// The model ID used to generate the content. - /// - @Nullable - private String modelId; - - /// - /// The metadata associated with the content. - /// - @Nullable - private final Map> metadata; - + /** + * Initializes a new instance of the {@link StreamingKernelContent} class. + * @param innerContent The inner content representation. + * @param choiceIndex The zero-based index of the choice in the streaming sequence. + * @param modelId The model identifier used to generate the content. + * @param metadata The metadata associated with the content. + */ protected StreamingKernelContent( @Nullable T innerContent, int choiceIndex, @Nullable String modelId, @Nullable Map> metadata) { - this.innerContent = innerContent; + super(innerContent, modelId, null); this.choiceIndex = choiceIndex; - this.modelId = modelId; - this.metadata = metadata; + } + + /** + * Gets the zero-based index of the choice in the streaming sequence. + * @return The zero-based index of the choice in the streaming sequence. + */ + public int getChoiceIndex() { + return choiceIndex; } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java index 95a85d6b8d..08b971e7da 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java @@ -5,5 +5,9 @@ package com.microsoft.semantickernel; * Marker interface for Text AI services, typically Chat or Text generation for OpenAI */ public interface TextAIService extends AIService { + + /** + * The maximum number of results per prompt + */ int MAX_RESULTS_PER_PROMPT = 128; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Todo.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Todo.java index 2b5f8e2385..454ace072e 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Todo.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Todo.java @@ -1,5 +1,14 @@ package com.microsoft.semantickernel; +/** + * This is used as a placeholder for methods that are not yet implemented. + */ public class Todo extends RuntimeException { + /** + * Initializes a new instance of the {@link Todo} class. + */ + public Todo() { + super("TODO: Implement this method"); + } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Verify.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Verify.java index 7713801c1e..d36c827236 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Verify.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Verify.java @@ -3,16 +3,34 @@ package com.microsoft.semantickernel; import javax.annotation.Nullable; +/** + * Provides methods for verifying the state of objects and strings in + * a consistent manner. + */ public class Verify { + /** + * Verifies that the given object is not {@code null}. + * @param object The object to verify. + */ public static void notNull(Object object) { assert object != null; } + /** + * Verifies that the given object is {@code null} or empty. + * @param s The String to verify. + * @return true if the object is {@code null} or empty; otherwise, false. + */ public static boolean isNullOrEmpty(@Nullable String s) { return s == null || s.isEmpty(); } + /** + * Verifies that the given object is {@code null} or contains only whitespace. + * @param s The String to verify. + * @return true if the object is {@code null} or whitespace; otherwise, false. + */ public static boolean isNullOrWhiteSpace(String s) { return s == null || s.matches("^\\w+$"); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/Buildable.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/Buildable.java index b04296b6c2..5d1deb22ef 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/Buildable.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/Buildable.java @@ -2,7 +2,8 @@ package com.microsoft.semantickernel.builders; /** - * A marker interface for all classes that are buildable, typically via obtaining a builder from - * {@link com.microsoft.semantickernel.SKBuilders}. + * A marker interface for all classes that are buildable. By convention, {@code Buildable} + * classes will have a {@code public static Builder builder()} method for obtaining a + * {@link SemanticKernelBuilder} for the given class. */ public interface Buildable {} diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/SemanticKernelBuilder.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/SemanticKernelBuilder.java index 784e460b5a..96e596e6a1 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/SemanticKernelBuilder.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/SemanticKernelBuilder.java @@ -2,10 +2,9 @@ package com.microsoft.semantickernel.builders; /** - * Interface for all builders that create Buildable objects. Typically, these builders can be - * obtained via {@link com.microsoft.semantickernel.SKBuilders}. + * Interface for all builders that create Buildable objects. * - * @param + * @param the type of {@code Buildable} to build. */ public interface SemanticKernelBuilder { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/ServiceLoadUtil.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/ServiceLoadUtil.java index 7e6c77ed5d..6a74f2b457 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/ServiceLoadUtil.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/ServiceLoadUtil.java @@ -11,6 +11,11 @@ import java.util.function.Supplier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * This class is used for loading services that are not directly referenced + * in the code, but are instead loaded using the ServiceLoader pattern. + * + */ public class ServiceLoadUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceLoadUtil.class); @@ -18,6 +23,15 @@ public class ServiceLoadUtil { private ServiceLoadUtil() { } + /** + * Finds a service loader for the given class and returns a supplier for it. + * + * @param clazz The class to find a service loader for. + * @param The type of the class to find a service loader for. + * @param alternativeClassName The name of the alternative class to load if the service loader + * is not found. + * @return A {@code java.util.function.Supplier} for the service loader. + */ public static Supplier findServiceLoader(Class clazz, String alternativeClassName) { List services = findAllServiceLoaders(clazz); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/AuthorRole.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/AuthorRole.java index 07913ab888..c41f24c888 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/AuthorRole.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/AuthorRole.java @@ -6,9 +6,22 @@ package com.microsoft.semantickernel.chatcompletion; */ public enum AuthorRole { + /** + * A system message helps set the behavior of the assistant. + */ SYSTEM("system"), + /** + * An assistant message is a message generated by the assistant. + */ ASSISTANT("assistant"), + /** + * A user message is a message generated by the user. + */ USER("user"), + + /** + * A tool message is a message generated by a tool. + */ TOOL("tool"); @Override @@ -18,7 +31,7 @@ public enum AuthorRole { private final String role; - AuthorRole(String role) { + private AuthorRole(String role) { this.role = role; } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java index 8ea823f6b6..4dcc40a518 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java @@ -9,30 +9,65 @@ import com.microsoft.semantickernel.builders.Buildable; import com.microsoft.semantickernel.builders.SemanticKernelBuilder; import com.microsoft.semantickernel.builders.ServiceLoadUtil; import com.microsoft.semantickernel.orchestration.InvocationContext; + import java.util.List; + import javax.annotation.Nullable; + import reactor.core.publisher.Mono; +/** + * Chat completion service interface. + */ public interface ChatCompletionService extends Buildable, TextAIService { + /** + * Gets the chat message contents asynchronously using + * {@code ChatHistory} to support a turn-based conversation. + * Typically, the resulting chat message contents is appended + * to the {@code chatHistory} to continue the conversation. + * + * @param chatHistory the chat history + * @param kernel the kernel + * @param invocationContext the invocation context + * @return the chat message contents + */ Mono> getChatMessageContentsAsync( ChatHistory chatHistory, @Nullable Kernel kernel, @Nullable InvocationContext invocationContext ); + /** + * Gets the chat message contents asynchronously using a prompt. + * + * @param prompt the prompt + * @param kernel the kernel + * @param invocationContext the invocation context + * @return the chat message contents + */ Mono> getChatMessageContentsAsync( String prompt, @Nullable Kernel kernel, @Nullable InvocationContext invocationContext ); + /** + * Get a builder for creating a {@code ChatCompletionService}. The builder loads a service + * that implements the {@link ChatCompletionService.Builder} interface. + * @return a builder for creating a {@code ChatCompletionService} + */ static Builder builder() { return ServiceLoadUtil.findServiceLoader(Builder.class, "com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion$Builder") .get(); } + /** + * Builder API for creating a {@link ChatCompletionService}. Concrete implementations of + * {@link ChatCompletionService} must implement the {@link SemanticKernelBuilder#build()} + * method. + */ abstract class Builder implements SemanticKernelBuilder { @Nullable @@ -68,6 +103,12 @@ public interface ChatCompletionService extends Buildable, TextAIService { return this; } + /** + * Sets the service ID to use with the ChatCompletion service. + * + * @param serviceId the service ID to use with the ChatCompletion service + * @return this builder + */ public Builder withServiceId(String serviceId) { this.serviceId = serviceId; return this; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatHistory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatHistory.java index 591341e1b3..1f4b556a0c 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatHistory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatHistory.java @@ -1,19 +1,17 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.chatcompletion; +import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; + import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Spliterator; import java.util.function.Consumer; -import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; -import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; - /** * Provides a history of messages between the User, Assistant and System */ @@ -23,10 +21,19 @@ public class ChatHistory implements Iterable { private final List chatMessageContents; + /** + * The default constructor adds an "Assistant is a large language model." + * system message to the chat history + */ public ChatHistory() { this(DEFAULT_CHAT_SYSTEM_PROMPT); } + /** + * Constructor that adds the given system instructions to the chat history. + * + * @param instructions The instructions to add to the chat history + */ public ChatHistory(String instructions) { this.chatMessageContents = new ArrayList<>(); this.chatMessageContents.add( @@ -37,6 +44,11 @@ public class ChatHistory implements Iterable { ); } + /** + * Constructor that adds the given chat message contents to the chat history. + * + * @param chatMessageContents The chat message contents to add to the chat history + */ public ChatHistory(List chatMessageContents) { this.chatMessageContents = new ArrayList<>(chatMessageContents); } @@ -62,46 +74,100 @@ public class ChatHistory implements Iterable { return Optional.of(chatMessageContents.get(chatMessageContents.size() - 1)); } + /** + * Add all messages from the given chat history to this chat history + * + * @param value The chat history to add to this chat history + */ public void addAll(ChatHistory value) { this.chatMessageContents.addAll(value.getMessages()); } + /** + * Create an {@code Iterator} from the chat history. + */ @Override public Iterator iterator() { return chatMessageContents.iterator(); } + /** + * Perform the given action for each message in the chat history + * + * @param action The action to perform for each message in the chat history + */ @Override public void forEach(Consumer action) { chatMessageContents.forEach(action); } + /** + * Create a {@code Spliterator} from the chat history + */ @Override public Spliterator spliterator() { return chatMessageContents.spliterator(); } + /** + * Add a message to the chat history + * + * @param authorRole The role of the author of the message + * @param content The content of the message + * @param encoding The encoding of the message + * @param metadata The metadata of the message + */ public void addMessage(AuthorRole authorRole, String content, Charset encoding, FunctionResultMetadata metadata) { chatMessageContents.add( new ChatMessageContent(authorRole, content, null, null, encoding, metadata)); } - + /** + * Add a message to the chat history + * + * @param authorRole The role of the author of the message + * @param content The content of the message + */ public void addMessage(AuthorRole authorRole, String content) { chatMessageContents.add( new ChatMessageContent(authorRole, content, null, null, null, null)); } + /** + * Add a message to the chat history + * + * @param content The content of the message + */ public void addMessage(ChatMessageContent content) { chatMessageContents.add(content); } + /** + * Add a user message to the chat history + * + * @param content The content of the user message + */ public void addUserMessage(String content) { addMessage(AuthorRole.USER, content); } + /** + * Add an assistant message to the chat history + * + * @param content The content of the assistant message + */ public void addAssistantMessage(String content) { addMessage(AuthorRole.ASSISTANT, content); } + + /** + * Add an system message to the chat history + * + * @param content The content of the system message + */ + public void addSystemMessage(String content) { + addMessage(AuthorRole.SYSTEM, content); + } + } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java index 20b96d6975..748c7b0786 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java @@ -3,23 +3,33 @@ package com.microsoft.semantickernel.chatcompletion; import com.microsoft.semantickernel.KernelContent; import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; + import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; + import javax.annotation.Nullable; +/** + * Represents the content of a chat message + */ public class ChatMessageContent extends KernelContent { private AuthorRole authorRole; @Nullable private String content; @Nullable - private List items; + private List> items; @Nullable private Charset encoding; + /** + * Creates a new instance of the {@link ChatMessageContent} class. + * @param authorRole the author role that generated the content + * @param content the content + */ public ChatMessageContent( AuthorRole authorRole, String content @@ -33,6 +43,15 @@ public class ChatMessageContent extends KernelContent { null); } + /** + * Creates a new instance of the {@link ChatMessageContent} class. + * @param authorRole the author role that generated the content + * @param content the content + * @param modelId the model id + * @param innerContent the inner content + * @param encoding the encoding + * @param metadata the metadata + */ public ChatMessageContent( AuthorRole authorRole, String content, @@ -51,6 +70,15 @@ public class ChatMessageContent extends KernelContent { this.encoding = encoding != null ? encoding : StandardCharsets.UTF_8; } + /** + * Creates a new instance of the {@link ChatMessageContent} class. + * @param authorRole the author role that generated the content + * @param items the items + * @param modelId the model id + * @param innerContent the inner content + * @param encoding the encoding + * @param metadata the metadata + */ public ChatMessageContent( AuthorRole authorRole, List> items, @@ -66,37 +94,69 @@ public class ChatMessageContent extends KernelContent { this.items = new ArrayList<>(items); } + /** + * Gets the author role that generated the content + * @return the author role that generated the content + */ public AuthorRole getAuthorRole() { return authorRole; } + /** + * Sets the author role that generated the content + * @param authorRole the author role that generated the content + */ public void setAuthorRole(AuthorRole authorRole) { this.authorRole = authorRole; } + /** + * Gets the content + * @return the content, which may be {@code null} + */ @Nullable @Override public String getContent() { return content; } + /** + * Sets the content + * @param content the content + */ public void setContent(@Nullable String content) { this.content = content; } - public List getItems() { + /** + * Gets the {@code KernelContent} items that comprise the content. + * @return the items, which may be {@code null} + */ + public List> getItems() { return Collections.unmodifiableList(items); } - public void setItems(List items) { + /** + * Sets the {@code KernelContent} items that comprise the content. + * @param items the items + */ + public void setItems(List> items) { this.items = new ArrayList<>(items); } + /** + * Gets the encoding of the content + * @return the encoding, which may be {@code null} + */ @Nullable public Charset getEncoding() { return encoding; } + /** + * Sets the encoding of the content + * @param encoding the encoding + */ public void setEncoding(Charset encoding) { this.encoding = encoding; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java index b534e0aac8..e3c36c3e74 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java @@ -1,19 +1,32 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.chatcompletion; +import com.microsoft.semantickernel.KernelContent; import com.microsoft.semantickernel.StreamingKernelContent; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; + import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Map; + import javax.annotation.Nullable; -public class StreamingChatMessageContent extends StreamingKernelContent { +/** + * Represents the content of a chat message that is streamed. + * @param the type of the inner content + */ +public class StreamingChatMessageContent> extends StreamingKernelContent { private final String content; private final AuthorRole role; private Charset encoding; + /** + * Creates a new instance of the {@link StreamingChatMessageContent} class. + * @param role the author role that generated the content + * @param content the content + * @param modelId the model id + */ public StreamingChatMessageContent( AuthorRole role, String content, @@ -22,6 +35,16 @@ public class StreamingChatMessageContent extends StreamingKernelContent { this(role, content, null, 0, modelId, null, null); } + /** + * Creates a new instance of the {@link StreamingChatMessageContent} class. + * @param role the author role that generated the content + * @param content the content + * @param innerContent the inner content + * @param choiceIndex the choice index + * @param modelId the model id + * @param encoding the encoding + * @param metadata the metadata + */ public StreamingChatMessageContent( AuthorRole role, String content, @@ -45,18 +68,32 @@ public class StreamingChatMessageContent extends StreamingKernelContent { return content != null ? content : ""; } + @Override public String getContent() { return content; } + /** + * Gets the role of the author of the message + * @return the role of the author of the message + */ public AuthorRole getRole() { return role; } + /** + * Gets the encoding of the message + * @return the encoding of the message + */ public Charset getEncoding() { return encoding; } + /** + * Sets the encoding of the message + * @param encoding the encoding of the message + * @return this instance + */ public StreamingChatMessageContent setEncoding(Charset encoding) { this.encoding = encoding; return this; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/connectors/WebSearchEngineConnector.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/connectors/WebSearchEngineConnector.java index 365672dc45..99f23a3c95 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/connectors/WebSearchEngineConnector.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/connectors/WebSearchEngineConnector.java @@ -1,15 +1,34 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.connectors; -import reactor.core.publisher.Mono; - import java.util.List; -public interface WebSearchEngineConnector { +import reactor.core.publisher.Mono; +/** + * Web search engine connector interface. + */ +public interface WebSearchEngineConnector { + /** + * Represents a web page. + */ interface WebPage { + /** + * Gets the name of the web page. + * @return The name of the web page. + */ String getName(); + + /** + * Gets the URL of the web page. + * @return The URL of the web page. + */ String getUrl(); + + /** + * Gets the snippet of the web page. + * @return The snippet of the web page. + */ String getSnippet(); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/ConfigurationException.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/ConfigurationException.java index 873053dc8e..8771ee4a3d 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/ConfigurationException.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/ConfigurationException.java @@ -5,21 +5,37 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; /** - * Kernel logic exception + * An exception that is thrown when there is an error with the + * Semantic Kernel configuration. */ public class ConfigurationException extends SKCheckedException { @Nonnull private final ErrorCodes errorCode; + /** + * Creates a new instance of the {@link ConfigurationException} class. + * @param error the error code + */ public ConfigurationException(@Nonnull ErrorCodes error) { this(error, null, null); } + /** + * Creates a new instance of the {@link ConfigurationException} class. + * @param errorCode the error code + * @param message the message + */ public ConfigurationException(@Nonnull ErrorCodes errorCode, @Nullable String message) { this(errorCode, message, null); } + /** + * Creates a new instance of the {@link ConfigurationException} class. + * @param errorCode the error code + * @param message the message + * @param innerException the inner exception + */ public ConfigurationException( @Nonnull ErrorCodes errorCode, @Nullable String message, @@ -28,17 +44,31 @@ public class ConfigurationException extends SKCheckedException { this.errorCode = errorCode; } + /** + * Gets the error code. + * @return the error code + */ public ErrorCodes getErrorCode() { return errorCode; } + /** + * ErrorCodes for this exception. + */ public enum ErrorCodes { + /** Unknown error */ UNKNOWN_ERROR("Unknown error"), + /** Could not find configuration file */ CONFIGURATION_NOT_FOUND("Could not find configuration file"), + /** Could not parse or load configuration file */ COULD_NOT_READ_CONFIGURATION("Could not parse or load configuration file"), + + /** Could not find any valid configuration settings */ NO_VALID_CONFIGURATIONS_FOUND("Could not find any valid configuration settings"), + + /** Could not find value for configuration key */ VALUE_NOT_FOUND("Could not find value for configuration key"); private final String message; @@ -47,10 +77,19 @@ public class ConfigurationException extends SKCheckedException { this.message = message; } + /** + * Gets the message for the error code. + * @return the message for the error code + */ public String getMessage() { return message; } + /** + * Format the message with the given parameter. + * @param param helpful information + * @return the formatted message + */ public String getMessage(String param) { return String.format(message, param); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/NotSupportedException.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/NotSupportedException.java deleted file mode 100644 index 7f0596121a..0000000000 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/exceptions/NotSupportedException.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.exceptions; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class NotSupportedException extends SKException { - - private final ErrorCodes errorCode; - - public NotSupportedException(@Nonnull ErrorCodes errorCode) { - this(errorCode, null, null); - } - - public NotSupportedException(@Nonnull ErrorCodes errorCode, @Nullable String message) { - this(errorCode, message, null); - } - - public NotSupportedException( - @Nonnull ErrorCodes errorCode, @Nullable String message, @Nullable Throwable cause) { - super(formatDefaultMessage(errorCode.getMessage(), message), cause); - this.errorCode = errorCode; - } - - public ErrorCodes getErrorCode() { - return errorCode; - } - - public enum ErrorCodes { - NOT_SUPPORTED("Not Supported"); - - final String message; - - ErrorCodes(String message) { - this.message = message; - } - - String getMessage() { - return message; - } - } -} diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java index 01ac63209a..d7041dd90b 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java @@ -1,22 +1,32 @@ package com.microsoft.semantickernel.hooks; -import javax.annotation.Nullable; - import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; +import javax.annotation.Nullable; + import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +/** + * Represents a KernelHookEvent that is raised after a function is invoked. + * @param The type of the function result + */ public class FunctionInvokedEvent implements KernelHookEvent { - private final KernelFunction function; + private final KernelFunction function; @Nullable private final KernelFunctionArguments arguments; private final FunctionResult result; + /** + * Creates a new instance of the {@link FunctionInvokedEvent} class. + * @param function the function + * @param arguments the arguments + * @param result the result + */ public FunctionInvokedEvent( - KernelFunction function, + KernelFunction function, @Nullable KernelFunctionArguments arguments, FunctionResult result) { this.function = function; @@ -24,16 +34,28 @@ public class FunctionInvokedEvent implements KernelHookEvent { this.result = result; } - public KernelFunction getFunction() { + /** + * Gets the function that was invoked. + * @return the function + */ + public KernelFunction getFunction() { return function; } + /** + * Gets the arguments that were passed to the function. + * @return the arguments + */ @SuppressFBWarnings("EI_EXPOSE_REP") @Nullable public KernelFunctionArguments getArguments() { return arguments; } + /** + * Gets the result of the function invocation. + * @return the result + */ @SuppressFBWarnings("EI_EXPOSE_REP") public FunctionResult getResult() { return result; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java index 4f5e4f40ec..874d3bee12 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java @@ -1,27 +1,46 @@ package com.microsoft.semantickernel.hooks; -import javax.annotation.Nullable; - import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; +import javax.annotation.Nullable; + import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -public class FunctionInvokingEvent implements KernelHookEvent { +/** + * Represents a KernelHookEvent that is raised before a function is invoked. + * This event is raised before the function is invoked, and can be used to + * by a {@code KernelHook} to modify the arguments before the function is invoked. + * @param The type of the KernelFunction being invoked + */ +public class FunctionInvokingEvent implements KernelHookEvent { - private final KernelFunction function; + private final KernelFunction function; private final KernelFunctionArguments arguments; - public FunctionInvokingEvent(KernelFunction function, + /** + * Creates a new instance of the FunctionInvokingEvent class. + * @param function The function that is being invoked + * @param arguments The arguments that are being passed to the function + */ + public FunctionInvokingEvent(KernelFunction function, @Nullable KernelFunctionArguments arguments) { this.function = function; this.arguments = arguments != null ? new KernelFunctionArguments(arguments) : new KernelFunctionArguments(); } - public KernelFunction getFunction() { + /** + * Gets the function that is being invoked. + * @return the function + */ + public KernelFunction getFunction() { return function; } + /** + * Gets the arguments that are being passed to the function. + * @return the arguments + */ @SuppressFBWarnings("EI_EXPOSE_REP") public KernelFunctionArguments getArguments() { return arguments; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHook.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHook.java index be649fa47b..472c6b4fc6 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHook.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHook.java @@ -2,10 +2,17 @@ package com.microsoft.semantickernel.hooks; import com.azure.ai.openai.models.ChatCompletionsOptions; import com.azure.ai.openai.models.ChatRequestMessage; + import java.util.List; import java.util.function.Function; import java.util.function.Predicate; +/** + * Represents a hook that can be used to intercept and modify arguments to {@code KernelFunction}s. + * A {@code KernelHook} implements a {@code Predicate} that determines if the hook is interested + * in a particular event, and a {@code Function} that can be used to modify the event. The + * @param The type of the event that the hook is interested in + */ public interface KernelHook extends Predicate, Function { @@ -20,7 +27,10 @@ public interface KernelHook extends Predicate { + /** + * A hook that accepts {@link FunctionInvokingEvent} + */ + interface FunctionInvokingHook extends KernelHook> { @Override default boolean test(KernelHookEvent arguments) { @@ -28,7 +38,10 @@ public interface KernelHook extends Predicate { + /** + * A hook that accepts {@link FunctionInvokedEvent} + */ + interface FunctionInvokedHook extends KernelHook> { @Override default boolean test(KernelHookEvent arguments) { @@ -36,6 +49,9 @@ public interface KernelHook extends Predicate { @Override @@ -44,6 +60,9 @@ public interface KernelHook extends Predicate { @Override @@ -52,6 +71,10 @@ public interface KernelHook extends Predicate { @Override @@ -59,6 +82,12 @@ public interface KernelHook extends Predicate messages) { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHookEvent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHookEvent.java index ae78e8b2e6..5695efb1b0 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHookEvent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHookEvent.java @@ -1,5 +1,8 @@ package com.microsoft.semantickernel.hooks; +/** + * A marker interface for events that can be intercepted by a {@link KernelHook}. + */ public interface KernelHookEvent { } \ No newline at end of file diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java index f47bb7fbcd..2cd0111a8b 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java @@ -5,6 +5,7 @@ import com.microsoft.semantickernel.hooks.KernelHook.FunctionInvokingHook; import com.microsoft.semantickernel.hooks.KernelHook.PreChatCompletionHook; import com.microsoft.semantickernel.hooks.KernelHook.PromptRenderedHook; import com.microsoft.semantickernel.hooks.KernelHook.PromptRenderingHook; + import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -13,16 +14,27 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.UUID; import java.util.function.Function; + import javax.annotation.Nullable; +/** + * Represents a collection of hooks that can be used to intercept and modify events in the kernel. + */ public class KernelHooks { private final Map> hooks; + /** + * Creates a new instance of the {@link KernelHooks} class. + */ public KernelHooks() { this.hooks = new HashMap<>(); } + /** + * Creates a copy of the {@link KernelHooks}. + * @param kernelHooks the hooks to copy + */ public KernelHooks(@Nullable KernelHooks kernelHooks) { this(); if (kernelHooks != null) { @@ -30,44 +42,89 @@ public class KernelHooks { } } + /** + * Creates a new instance of the {@link KernelHooks} class + * from the given hooks. + * @param hooks the hooks to add + */ public KernelHooks(Map> hooks) { this(); this.hooks.putAll(hooks); } + /** + * Creates an unmodifiable copy of this {@link KernelHooks}. + * @return an unmodifiable copy of this {@link KernelHooks} + */ public UnmodifiableKernelHooks unmodifiableClone() { return new UnmodifiableKernelHooks(this); } + + /** + * Gets the hooks in this collection. + * @return an unmodifiable map of the hooks + */ private Map> getHooks() { return Collections.unmodifiableMap(hooks); } + /** + * Add a {@link FunctionInvokingHook} to the collection of hooks. + * @param function the function to add + * @return the key of the hook in the collection + */ public String addFunctionInvokingHook( - Function function) { + Function, FunctionInvokingEvent> function) { return addHook((FunctionInvokingHook) function::apply); } + /** + * Add a {@link FunctionInvokedHook} to the collection of hooks. + * @param function the function to add + * @return the key of the hook in the collection + */ public String addFunctionInvokedHook( Function, FunctionInvokedEvent> function) { return addHook((FunctionInvokedHook) function::apply); } + /** + * Add a {@link PreChatCompletionHook} to the collection of hooks. + * @param function the function to add + * @return the key of the hook in the collection + */ public String addPreChatCompletionHook( Function function) { return addHook((PreChatCompletionHook) function::apply); } + /** + * Add a {@link PromptRenderedHook} to the collection of hooks. + * @param function the function to add + * @return the key of the hook in the collection + */ public String addPromptRenderedHook( Function function) { return addHook((PromptRenderedHook) function::apply); } + /** + * Add a {@link PromptRenderingHook} to the collection of hooks. + * @param function the function to add + * @return the key of the hook in the collection + */ public String addPromptRenderingHook( Function function) { return addHook((PromptRenderingHook) function::apply); } + /** + * Executes the hooks in this collection that accept the event. + * @param event the event to execute the hooks on + * @param the type of the event + * @return the event after the hooks have been executed + */ @SuppressWarnings("unchecked") public T executeHooks(T event) { SortedSet> hooks = new TreeSet<>(Comparator.comparingInt(KernelHook::getPriority)); @@ -83,20 +140,41 @@ public class KernelHooks { return event; } + /** + * Add a {@link KernelHook} to the collection of hooks. + * @param hook the hook to add + * @return the key of the hook in the collection + */ public String addHook(KernelHook hook) { return addHook(UUID.randomUUID().toString(), hook); } + /** + * Add a {@link KernelHook} to the collection of hooks. + * @param hookName the key of the hook in the collection + * @param hook the hook to add + * @return the key of the hook in the collection + */ public String addHook(String hookName, KernelHook hook) { hooks.put(hookName, hook); return hookName; } + /** + * Remove a hook from the collection of hooks. + * @param hookName the key of the hook in the collection + * @return the removed hook, or {@code null} if the hook was not found + */ public KernelHook removeHook(String hookName) { return hooks.remove(hookName); } - public KernelHooks append(@Nullable KernelHooks kernelHooks) { + /** + * Appends the given hooks to this collection. + * @param kernelHooks the hooks to append + * @return this instance of the {@link KernelHooks} class + */ + public KernelHooks addHooks(@Nullable KernelHooks kernelHooks) { if (kernelHooks == null) { return this; } @@ -105,15 +183,17 @@ public class KernelHooks { return this; } + /** + * Determines if this collection of hooks is empty. + * @return {@code true} if the collection is empty, otherwise {@code false} + */ public boolean isEmpty() { return hooks.isEmpty(); } - public KernelHooks addHooks(KernelHooks hooks) { - this.hooks.putAll(hooks.getHooks()); - return this; - } - + /** + * A wrapper for KernelHooks that disables mutating methods. + */ public static class UnmodifiableKernelHooks extends KernelHooks { private UnmodifiableKernelHooks(KernelHooks kernelHooks) { @@ -122,7 +202,7 @@ public class KernelHooks { @Override public String addFunctionInvokingHook( - Function function) { + Function, FunctionInvokingEvent> function) { throw new UnsupportedOperationException("unmodifiable instance of KernelHooks"); } @@ -161,7 +241,7 @@ public class KernelHooks { } @Override - public KernelHooks append(@Nullable KernelHooks kernelHooks) { + public KernelHooks addHooks(@Nullable KernelHooks kernelHooks) { throw new UnsupportedOperationException("unmodifiable instance of KernelHooks"); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreChatCompletionEvent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreChatCompletionEvent.java index 64154d67da..f3f3589c5e 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreChatCompletionEvent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreChatCompletionEvent.java @@ -2,14 +2,25 @@ package com.microsoft.semantickernel.hooks; import com.azure.ai.openai.models.ChatCompletionsOptions; +/** + * Represents a KernelHookEvent that is raised before a chat completion is invoked. + */ public class PreChatCompletionEvent implements KernelHookEvent { private final ChatCompletionsOptions options; + /** + * Creates a new instance of the {@link PreChatCompletionEvent} class. + * @param options the chat completion options + */ public PreChatCompletionEvent(ChatCompletionsOptions options) { this.options = options; } + /** + * Gets the chat completion options. + * @return the options + */ public ChatCompletionsOptions getOptions() { return options; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java index 213ec1968a..c2c23a6c33 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java @@ -2,15 +2,26 @@ package com.microsoft.semantickernel.hooks; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import javax.annotation.Nullable; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +/** + * Represents a KernelHookEvent that is raised after a prompt is rendered. + */ public class PromptRenderedEvent implements KernelHookEvent { - private final KernelFunction function; + private final KernelFunction function; private final KernelFunctionArguments arguments; private final String prompt; + /** + * Creates a new instance of the {@link PromptRenderedEvent} class. + * @param function the function + * @param arguments the arguments + * @param prompt the prompt + */ public PromptRenderedEvent( KernelFunction function, @Nullable @@ -22,15 +33,27 @@ public class PromptRenderedEvent implements KernelHookEvent { this.prompt = prompt; } + /** + * Gets the function that was invoked. + * @return the function + */ public KernelFunction getFunction() { return function; } + /** + * Gets the arguments that were passed to the function. + * @return the arguments + */ @SuppressFBWarnings("EI_EXPOSE_REP") public KernelFunctionArguments getArguments() { return arguments; } + /** + * Gets the prompt that was rendered. + * @return the prompt + */ @SuppressFBWarnings("EI_EXPOSE_REP") public String getPrompt() { return prompt; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java index 35f5669058..f62737071d 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java @@ -3,23 +3,40 @@ package com.microsoft.semantickernel.hooks; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +/** + * Represents a KernelHookEvent that is raised after a prompt is rendered. + */ public class PromptRenderingEvent implements KernelHookEvent { - private final KernelFunction function; + private final KernelFunctionfunction; private final KernelFunctionArguments arguments; - public PromptRenderingEvent(KernelFunction function, @Nullable KernelFunctionArguments arguments) { + /** + * Creates a new instance of the {@link PromptRenderingEvent} class. + * @param function the function + * @param arguments the arguments + */ + public PromptRenderingEvent(KernelFunctionfunction, @Nullable KernelFunctionArguments arguments) { this.function = function; this.arguments = arguments != null ? new KernelFunctionArguments(arguments) : new KernelFunctionArguments(); } - public KernelFunction getFunction() { + /** + * Gets the function that was invoked. + * @return the function + */ + public KernelFunctiongetFunction() { return function; } + /** + * Gets the arguments that were passed to the function. + * @return the arguments + */ @SuppressFBWarnings("EI_EXPOSE_REP") public KernelFunctionArguments getArguments() { return arguments; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java index d52b50840f..437b9d21a6 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java @@ -9,15 +9,23 @@ import com.microsoft.semantickernel.orchestration.ToolCallBehavior.UnmodifiableT import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import java.util.function.BiConsumer; + import javax.annotation.Nullable; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import reactor.core.CoreSubscriber; import reactor.core.publisher.Mono; import reactor.core.publisher.SynchronousSink; +/** + * {@code FunctionInvocation} supports fluent invocation of a function in the kernel. + * @param The type of the result of the function invocation. + */ public class FunctionInvocation extends Mono> { private static final Logger LOGGER = LoggerFactory.getLogger(FunctionInvocation.class); @@ -38,7 +46,11 @@ public class FunctionInvocation extends Mono> { protected UnmodifiableToolCallBehavior toolCallBehavior; protected final ContextVariableTypes contextVariableTypes = new ContextVariableTypes(); - + /** + * Create a new function invocation. + * @param kernel The kernel to invoke the function on. + * @param function The function to invoke. + */ @SuppressFBWarnings("EI_EXPOSE_REP2") public FunctionInvocation( Kernel kernel, @@ -49,6 +61,12 @@ public class FunctionInvocation extends Mono> { this.addKernelHooks(kernel.getGlobalKernelHooks()); } + /** + * Create a new function invocation. + * @param kernel The kernel to invoke the function on. + * @param function The function to invoke. + * @param resultType The type of the result of the function invocation. + */ @SuppressFBWarnings("EI_EXPOSE_REP2") public FunctionInvocation( Kernel kernel, @@ -64,6 +82,11 @@ public class FunctionInvocation extends Mono> { this.addKernelHooks(kernel.getGlobalKernelHooks()); } + /** + * Supply arguments to the function invocation. + * @param arguments The arguments to supply to the function invocation. + * @return this {@code FunctionInvocation} for fluent chaining. + */ public FunctionInvocation withArguments( @Nullable KernelFunctionArguments arguments) { @@ -75,6 +98,12 @@ public class FunctionInvocation extends Mono> { return this; } + /** + * Supply the result type of function invocation. + * @param resultType The arguments to supply to the function invocation. + * @param The type of the result of the function invocation. + * @return A new {@code FunctionInvocation} for fluent chaining. + */ public FunctionInvocation withResultType(ContextVariableType resultType) { return new FunctionInvocation<>( kernel, @@ -86,7 +115,12 @@ public class FunctionInvocation extends Mono> { .withToolCallBehavior(toolCallBehavior); } - public FunctionInvocation addKernelHook(@Nullable KernelHook hook) { + /** + * Add a kernel hook to the function invocation. + * @param hook The kernel hook to add. + * @return this {@code FunctionInvocation} for fluent chaining. + */ + public FunctionInvocation addKernelHook(@Nullable KernelHook hook) { if (hook == null) { return this; } @@ -96,6 +130,11 @@ public class FunctionInvocation extends Mono> { return this; } + /** + * Add kernel hooks to the function invocation. + * @param hooks The kernel hooks to add. + * @return this {@code FunctionInvocation} for fluent chaining. + */ public FunctionInvocation addKernelHooks( @Nullable KernelHooks hooks) { @@ -106,6 +145,11 @@ public class FunctionInvocation extends Mono> { return this; } + /** + * Supply prompt execution settings to the function invocation. + * @param promptExecutionSettings The prompt execution settings to supply to the function invocation. + * @return this {@code FunctionInvocation} for fluent chaining. + */ public FunctionInvocation withPromptExecutionSettings( @Nullable PromptExecutionSettings promptExecutionSettings) { @@ -113,22 +157,59 @@ public class FunctionInvocation extends Mono> { return this; } + /** + * Supply tool call behavior to the function invocation. + * @param toolCallBehavior The tool call behavior to supply to the function invocation. + * @return this {@code FunctionInvocation} for fluent chaining. + */ public FunctionInvocation withToolCallBehavior(@Nullable ToolCallBehavior toolCallBehavior) { this.toolCallBehavior = unmodifiableClone(toolCallBehavior); return this; } + /** + * Supply a type converter to the function invocation. + * @param typeConverter The type converter to supply to the function invocation. + * @return this {@code FunctionInvocation} for fluent chaining. + */ public FunctionInvocation withTypeConverter(ContextVariableType typeConverter) { contextVariableTypes.putConverter(typeConverter.getConverter()); return this; } + /** + * Supply a context variable type to the function invocation. + * @param contextVariableTypes The context variable types to supply to the function invocation. + * @return this {@code FunctionInvocation} for fluent chaining. + */ public FunctionInvocation withTypes(ContextVariableTypes contextVariableTypes) { this.contextVariableTypes.putConverters(contextVariableTypes); return this; } + /** + * Use an invocation context variable to supply the types, tool call behavior, + * prompt execution settings, and kernel hooks to the function invocation. + * @param invocationContext The invocation context to supply to the function invocation. + * @return this {@code FunctionInvocation} for fluent chaining. + */ + public FunctionInvocation withInvocationContext( + @Nullable InvocationContext invocationContext) { + if (invocationContext == null) { + return this; + } + withTypes(invocationContext.getContextVariableTypes()); + withToolCallBehavior(invocationContext.getToolCallBehavior()); + withPromptExecutionSettings(invocationContext.getPromptExecutionSettings()); + addKernelHooks(invocationContext.getKernelHooks()); + return this; + } + + /** + * This method hanldes the reactive stream when the KernelFunciton is invoked. + * @param coreSubscriber The subscriber to subscribe to the function invocation. + */ @Override public void subscribe(CoreSubscriber> coreSubscriber) { performSubscribe( diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResult.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResult.java index a475fab343..ca645211c0 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResult.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResult.java @@ -1,13 +1,28 @@ package com.microsoft.semantickernel.orchestration; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; + import javax.annotation.Nullable; +/** + * The result of a function invocation. + *

+ * This class is used to return the result of a function invocation. It contains the result of the + * function invocation and metadata about the result. + * + * @param The type of the result of the function invocation. + */ public class FunctionResult { private final ContextVariable result; private final FunctionResultMetadata metadata; + /** + * Create a new instance of FunctionResult. + * + * @param result The result of the function invocation. + * @param metadata Metadata about the result of the function invocation. + */ public FunctionResult( ContextVariable result, @Nullable FunctionResultMetadata metadata) { @@ -15,27 +30,43 @@ public class FunctionResult { this.metadata = metadata == null ? FunctionResultMetadata.empty() : metadata; } + /** + * Create a new instance of FunctionResult with no metadata. + * + * @param of The result of the function invocation. + */ public FunctionResult(ContextVariable of) { this(of, FunctionResultMetadata.empty()); } /** - * Get the result of the function invocation. - *

- * NOTE: IF YOU GET ClassCastException FROM THIS TRY ADDING withResultType() TO THE FUNCTION - * INVOCATION + * Get the result of the function invocation. + * NOTE: If you get a ClassCastException from this method, + * try adding a result type with + * {@link FunctionInvocation#withResultType(ContextVariableType)} * * @return The result of the function invocation. + * @throws ClassCastException If the result is not of the expected type. */ @Nullable public T getResult() { return result.getValue(); } + /** + * Get the result of the function invocation. + * + * @return The result of the function invocation. + */ public ContextVariable getResultVariable() { return result; } + /** + * Get the metadata about the result of the function invocation. + * + * @return The metadata about the result of the function invocation. + */ public FunctionResultMetadata getMetadata() { return metadata; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResultMetadata.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResultMetadata.java index d04d5bb781..bf11603244 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResultMetadata.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionResultMetadata.java @@ -3,26 +3,54 @@ package com.microsoft.semantickernel.orchestration; import com.azure.ai.openai.models.CompletionsUsage; import com.microsoft.semantickernel.orchestration.contextvariables.CaseInsensitiveMap; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; + import java.time.OffsetDateTime; + import javax.annotation.Nullable; +/** + * Metadata about the result of a function invocation. + *

+ * This class is used to return metadata about the result of a function invocation. + */ public class FunctionResultMetadata { + /** The key for id metadata. */ public static final String ID = "id"; + + /** The key for usage metadata. */ public static final String USAGE = "usage"; + + /** The key for createdAt metadata. */ public static final String CREATED_AT = "createdAt"; private final CaseInsensitiveMap> metadata; + /** + * Create a new instance of FunctionResultMetadata. + */ public FunctionResultMetadata() { this.metadata = new CaseInsensitiveMap<>(); } + /** + * Create a new instance of FunctionResultMetadata. + * + * @param metadata Metadata about the result of the function invocation. + */ public FunctionResultMetadata(CaseInsensitiveMap> metadata) { this.metadata = new CaseInsensitiveMap<>(metadata); } + /** + * Create a new instance of FunctionResultMetadata. + * + * @param id The id of the result of the function invocation. + * @param usage The usage of the result of the function invocation. + * @param createdAt The time the result was created. + * @return A new instance of FunctionResultMetadata. + */ public static FunctionResultMetadata build( String id, CompletionsUsage usage, @@ -36,14 +64,29 @@ public class FunctionResultMetadata { return new FunctionResultMetadata(metadata); } + /** + * Create a new instance of FunctionResultMetadata with no metadata. + * + * @return A new instance of FunctionResultMetadata. + */ public static FunctionResultMetadata empty() { return new FunctionResultMetadata(new CaseInsensitiveMap<>()); } + /** + * Get the metadata about the result of the function invocation. + * + * @return The metadata about the result of the function invocation. + */ public CaseInsensitiveMap> getMetadata() { return new CaseInsensitiveMap<>(metadata); } + /** + * Get the id of the result of the function invocation. + * + * @return The id of the result of the function invocation. + */ @Nullable public String getId() { ContextVariable id = metadata.get(ID); @@ -53,6 +96,11 @@ public class FunctionResultMetadata { return id.getValue(String.class); } + /** + * Get the usage of the result of the function invocation. + * + * @return The usage of the result of the function invocation. + */ @Nullable public CompletionsUsage getUsage() { ContextVariable usage = metadata.get(USAGE); @@ -62,6 +110,11 @@ public class FunctionResultMetadata { return usage.getValue(CompletionsUsage.class); } + /** + * Get the time the result was created. + * + * @return The time the result was created. + */ @Nullable public OffsetDateTime getCreatedAt() { ContextVariable createdAt = metadata.get(CREATED_AT); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java index ea4db1fbdf..571d8575b8 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java @@ -7,11 +7,15 @@ import com.microsoft.semantickernel.hooks.KernelHooks.UnmodifiableKernelHooks; import com.microsoft.semantickernel.orchestration.ToolCallBehavior.UnmodifiableToolCallBehavior; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import javax.annotation.Nullable; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + /** - * Context passed to a Kernel or KernelFunction invoke + * Context passed to a Kernel or KernelFunction invoke. This class is primarily for + * internal use. The preferred way to supply a context is to use the discrete "with" + * methods in {@link FunctionInvocation}. */ public class InvocationContext implements Buildable { @@ -23,6 +27,14 @@ public class InvocationContext implements Buildable { private final UnmodifiableToolCallBehavior toolCallBehavior; private final ContextVariableTypes contextVariableTypes; + /** + * Create a new instance of InvocationContext. + * + * @param hooks The hooks to use for the invocation. + * @param promptExecutionSettings The settings for prompt execution. + * @param toolCallBehavior The behavior for tool calls. + * @param contextVariableTypes The types of context variables. + */ public InvocationContext( @Nullable KernelHooks hooks, @Nullable PromptExecutionSettings promptExecutionSettings, @@ -38,6 +50,9 @@ public class InvocationContext implements Buildable { } } + /** + * Create a new instance of InvocationContext. + */ public InvocationContext() { this.hooks = null; this.promptExecutionSettings = null; @@ -45,6 +60,11 @@ public class InvocationContext implements Buildable { this.contextVariableTypes = new ContextVariableTypes(); } + /** + * Create a new instance of InvocationContext. + * + * @param context The context to copy. + */ public InvocationContext(@Nullable InvocationContext context) { if (context == null) { this.hooks = null; @@ -59,27 +79,47 @@ public class InvocationContext implements Buildable { } } + /** + * Get the hooks to use for the invocation. + * @return The hooks to use for the invocation. + */ @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "returns UnmodifiableKernelHooks") @Nullable public UnmodifiableKernelHooks getKernelHooks() { return hooks; } + /** + * Get the settings for prompt execution. + * @return The settings for prompt execution. + */ @Nullable public PromptExecutionSettings getPromptExecutionSettings() { return promptExecutionSettings; } + /** + * Get the behavior for tool calls. + * @return The behavior for tool calls. + */ @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "returns UnmodifiableToolCallBehavior") @Nullable public UnmodifiableToolCallBehavior getToolCallBehavior() { return toolCallBehavior; } + /** + * Get the types of context variables. + * @return The types of context variables. + */ public ContextVariableTypes getContextVariableTypes() { return new ContextVariableTypes(contextVariableTypes); } + /** + * Create a new {@link Builder} for building an instance of {@code InvocationContext}. + * @return the new Builder. + */ public static Builder builder() { return new Builder(); } @@ -110,6 +150,9 @@ public class InvocationContext implements Buildable { } } + /** + * Builder for {@link InvocationContext}. + */ public static class Builder implements SemanticKernelBuilder { @Nullable @@ -123,12 +166,22 @@ public class InvocationContext implements Buildable { private final ContextVariableTypes contextVariableTypes = new ContextVariableTypes(); + /** + * Add kernel hooks to the builder. + * @param hooks the hooks to add. + * @return this {@link Builder} + */ public Builder withKernelHooks( @Nullable KernelHooks hooks) { this.hooks = unmodifiableClone(hooks); return this; } + /** + * Add prompt execution settings to the builder. + * @param promptExecutionSettings the settings to add. + * @return this {@link Builder} + */ public Builder withPromptExecutionSettings( @Nullable PromptExecutionSettings promptExecutionSettings) { @@ -136,6 +189,11 @@ public class InvocationContext implements Buildable { return this; } + /** + * Add tool call behavior to the builder. + * @param toolCallBehavior the behavior to add. + * @return this {@link Builder} + */ public Builder withToolCallBehavior( @Nullable ToolCallBehavior toolCallBehavior) { @@ -143,6 +201,11 @@ public class InvocationContext implements Buildable { return this; } + /** + * Add a context variable type converter to the builder. + * @param converter the converter to add. + * @return this {@link Builder} + */ public Builder withContextVariableConverter(ContextVariableTypeConverter converter) { this.contextVariableTypes.putConverter( converter @@ -150,6 +213,7 @@ public class InvocationContext implements Buildable { return this; } + @Override public InvocationContext build() { return new InvocationContext(hooks, promptExecutionSettings, toolCallBehavior, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java index fc0a814607..6e0ddac217 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java @@ -1,13 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.orchestration; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.Todo; import com.microsoft.semantickernel.builders.Buildable; @@ -17,30 +10,42 @@ import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariab import com.microsoft.semantickernel.semanticfunctions.InputVariable; import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nullable; + import reactor.core.publisher.Mono; /** - * Semantic Kernel callable function interface + * Semantic Kernel callable function interface. The Semantic Kernel creates + * {@code KernelFunction}s from prompts, templates, or plugin methods. * * @param The type of the result of the function + * @see com.microsoft.semantickernel.semanticfunctions + * @see com.microsoft.semantickernel.plugin + * @see com.microsoft.semantickernel.plugin.annotations */ -// TODO: add example of using ContextVariableType to class documentation public abstract class KernelFunction implements Buildable { - ///

- /// Gets the metadata describing the function. - /// - /// An instance of describing the function private final KernelFunctionMetadata metadata; - /// - /// Gets the prompt execution settings. - /// @Nullable private final Map executionSettings; + /** + * Create a new instance of KernelFunction. + * + * @param metadata The metadata for the function + * @param executionSettings The execution settings for the function + * @see com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt + * @see com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromMethod + */ protected KernelFunction( KernelFunctionMetadata metadata, @Nullable @@ -93,10 +98,18 @@ public abstract class KernelFunction implements Buildable { throw new Todo(); } + /** + * Get an unmodifiable map of the execution settings for the function. + * @return An unmodifiable map of the execution settings for the function + */ public Map getExecutionSettings() { return Collections.unmodifiableMap(executionSettings); } + /** + * Get the metadata for the function. + * @return The metadata for the function + */ public KernelFunctionMetadata getMetadata() { return metadata; } @@ -134,42 +147,127 @@ public abstract class KernelFunction implements Buildable { @Nullable ContextVariableType variableType, @Nullable InvocationContext invocationContext); + /** + * Invokes this KernelFunction. + * @param kernel The Kernel containing services, plugins, and other state for use + * throughout the operation. + * @return The result of the function's execution. + */ public FunctionInvocation invokeAsync(Kernel kernel) { return new FunctionInvocation<>(kernel, this); } + /** + * Builder for creating a {@link KernelFunction} from a prompt. + * + * @param The type of the result of the function + * @see com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt.Builder + */ public interface FromPromptBuilder { + /** + * Set the name of the function. + * + * @param name The name of the function + * @return The builder + */ FromPromptBuilder withName(@Nullable String name); + /** + * Set the input parameters for the function. + * + * @param inputVariables The input parameters for the function + * @return The builder + */ FromPromptBuilder withInputParameters( @Nullable List inputVariables); + /** + * Set the prompt template for the function. + * @param promptTemplate The prompt template for the function + * @return The builder + */ FromPromptBuilder withPromptTemplate( @Nullable PromptTemplate promptTemplate); + /** + * Set the execution settings for the function. + * @param executionSettings The execution settings for the function + * @return The builder + */ FromPromptBuilder withExecutionSettings( @Nullable Map executionSettings); + /** + * Set the default execution settings for the function. + * + * @param executionSettings The default execution settings for the function + * @return The builder + */ FromPromptBuilder withDefaultExecutionSettings( @Nullable PromptExecutionSettings executionSettings); + /** + * Set the description of the function. + * + * @param description The description of the function + * @return The builder + */ FromPromptBuilder withDescription(@Nullable String description); + /** + * Set the template for the function. + * + * @param template The template for the function + * @return The builder + */ FromPromptBuilder withTemplate(@Nullable String template); + /** + * Create a new KernelFunction instance from the builder. + * @return The new KernelFunction instance + */ KernelFunction build(); + /** + * Set the template format for the function. + * @param templateFormat The template format for the function + * @return The builder + */ FromPromptBuilder withTemplateFormat(String templateFormat); + /** + * Set the output variable for the function. + * @param outputVariable The output variable for the function + * @return The builder + */ FromPromptBuilder withOutputVariable(@Nullable OutputVariable outputVariable); + /** + * Set the output variable for the function. + * @param description The description of the output variable + * @param type The type of the output variable + * @return The builder + */ FromPromptBuilder withOutputVariable(@Nullable String description, String type); - + /** + * Set the prompt template factory used to build the function. + * @param promptTemplateFactory The prompt template factory for the function + * @return The builder + */ FromPromptBuilder withPromptTemplateFactory( @Nullable PromptTemplateFactory promptTemplateFactory); + + /** + * Set the prompt template config used to build the function. + * @param promptTemplateConfig The prompt template config for the function + * @return The builder + */ + FromPromptBuilder withPromptTemplateConfig( + @Nullable PromptTemplateConfig promptTemplateConfig); + } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionArguments.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionArguments.java index e0c699e5d9..fc3a5bfd1e 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionArguments.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionArguments.java @@ -8,16 +8,18 @@ import com.microsoft.semantickernel.orchestration.contextvariables.CaseInsensiti import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; + import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; + import javax.annotation.Nullable; + import reactor.util.annotation.NonNull; /** - * Context Variables is a data structure that holds temporary data while a task is being performed. - * It is accessed by functions in the pipeline. + * Arguments to a kernel function. */ public class KernelFunctionArguments implements Buildable, Map> { @@ -28,6 +30,11 @@ public class KernelFunctionArguments implements Buildable, Map> variables; + /** + * Create a new instance of KernelFunctionArguments. + * + * @param variables The variables to use for the function invocation. + */ public KernelFunctionArguments( @Nullable Map> variables) { @@ -38,12 +45,19 @@ public class KernelFunctionArguments implements Buildable, Map content) { this.variables = new CaseInsensitiveMap<>(); this.variables.put(MAIN_KEY, content); } - + /** + * Create a new instance of KernelFunctionArguments. + */ public KernelFunctionArguments() { this.variables = new CaseInsensitiveMap<>(); } @@ -109,6 +123,11 @@ public class KernelFunctionArguments implements Buildable, Map> variables; + /** + * Create a new instance of Builder. + */ public Builder() { variables = new HashMap<>(); this.variables.put(MAIN_KEY, ContextVariable.of("")); @@ -194,6 +221,7 @@ public class KernelFunctionArguments implements Buildable, Map Type of the value * @return {$code this} Builder for fluent coding */ public Builder withInput(ContextVariable content) { @@ -216,6 +244,7 @@ public class KernelFunctionArguments implements Buildable, Map Type of the value * @return {$code this} Builder for fluent coding * @throws SKException if the content cannot be converted to a ContextVariable */ @@ -245,6 +274,7 @@ public class KernelFunctionArguments implements Buildable, Map Type of the value * @return {$code this} Builder for fluent coding */ public Builder withVariable(String key, ContextVariable value) { @@ -270,6 +300,7 @@ public class KernelFunctionArguments implements Buildable, Map Type of the value * @return {$code this} Builder for fluent coding * @throws SKException if the value cannot be converted to a ContextVariable */ diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionMetadata.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionMetadata.java index dc93fd6703..47383b4fdc 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionMetadata.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionMetadata.java @@ -1,29 +1,35 @@ package com.microsoft.semantickernel.orchestration; +import com.microsoft.semantickernel.plugin.KernelParameterMetadata; +import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.Nullable; -import com.microsoft.semantickernel.plugin.KernelParameterMetadata; -import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; - +/** + * Metadata about a kernel function. + * + * @param The type of the return value of the function. + */ public class KernelFunctionMetadata { - /// The name of the function. private final String name; - /// The description of the function. @Nullable private final String description; - /// The function's parameters. private final List> parameters; - - - /// The function's return parameter. private final KernelReturnParameterMetadata returnParameter; - + /** + * Create a new instance of KernelFunctionMetadata. + * + * @param name The name of the function. + * @param description The description of the function. + * @param parameters The parameters of the function. + * @param returnParameter The return parameter of the function. + */ public KernelFunctionMetadata( String name, @Nullable @@ -42,19 +48,35 @@ public class KernelFunctionMetadata { this.returnParameter = returnParameter; } + /** + * Get the name of the function. + * @return The name of the function. + */ public String getName() { return name; } + /** + * Get the parameters of the function. + * @return The parameters of the function. + */ public List> getParameters() { return Collections.unmodifiableList(parameters); } + /** + * Get the description of the function. + * @return The description of the function. + */ @Nullable public String getDescription() { return description; } + /** + * Get the return parameter of the function. + * @return The return parameter of the function. + */ public KernelReturnParameterMetadata getReturnParameter() { return returnParameter; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionYaml.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionYaml.java index 6b5e2563e9..1aa76d1cbe 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionYaml.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunctionYaml.java @@ -7,22 +7,28 @@ import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Path; + import javax.annotation.Nullable; +/** + * A class for creating a {@link KernelFunction} instance from a YAML representation of a prompt function. + */ public class KernelFunctionYaml { - /// - /// Creates a instance for a prompt function using the specified markdown text. - /// - /// YAML representation of the to use to create the prompt function - /// >Prompt template factory. - /// The to use for logging. If null, no logging will be performed. - /// The created . + /** + * Create a KernelFunction instance for a prompt function using the specified markdown text. + * @param yaml YAML representation of the PromptTemplateConfig to use to create the prompt function + * @param promptTemplateFactory Prompt template factory. + * @param The return type of the function. + * @return The created KernelFunction. + * @throws IOException If an error occurs while reading the YAML. + */ public static KernelFunction fromPromptYaml( String yaml, @Nullable PromptTemplateFactory promptTemplateFactory @@ -31,6 +37,13 @@ public class KernelFunctionYaml { return fromYaml(targetStream, promptTemplateFactory); } + /** + * Create a KernelFunction instance for a prompt function using the specified markdown text. + * @param yaml YAML representation of the PromptTemplateConfig to use to create the prompt function + * @param The return type of the function. + * @return The created KernelFunction. + * @throws IOException If an error occurs while reading the YAML. + */ public static KernelFunction fromPromptYaml( String yaml ) throws IOException { @@ -38,13 +51,20 @@ public class KernelFunctionYaml { return fromYaml(targetStream, null); } + /** + * Create a KernelFunction instance for a prompt function using the specified markdown text. + * @param filePath Path to the YAML representation of the PromptTemplateConfig to use to create the prompt function + * @param The return type of the function. + * @return The created KernelFunction. + * @throws IOException If an error occurs while reading the YAML. + */ public static KernelFunction fromYaml(Path filePath) throws IOException { InputStream inputStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream(filePath.toString()); return fromYaml(inputStream, null); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) private static KernelFunction fromYaml( InputStream inputStream, @Nullable PromptTemplateFactory promptTemplateFactory diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/PromptExecutionSettings.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/PromptExecutionSettings.java index 4e0a9b50c0..12fae11147 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/PromptExecutionSettings.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/PromptExecutionSettings.java @@ -2,13 +2,18 @@ package com.microsoft.semantickernel.orchestration; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; + import javax.annotation.Nullable; +/** + * Configuration settings for prompt execution. + */ public class PromptExecutionSettings { public static final String DEFAULT_SERVICE_ID = "default"; @@ -33,18 +38,8 @@ public class PromptExecutionSettings { private static final String RESULTS_PER_PROMPT = "results_per_prompt"; private static final String TOKEN_SELECTION_BIASES = "token_selection_biases"; - /// - /// Service identifier. - /// This identifies a service and is set when the AI service is registered. - /// private final String serviceId; - - /// - /// Model identifier. - /// This identifies the AI model these settings are configured for e.g., gpt-4, gpt-3.5-turbo - /// private final String modelId; - private final double temperature; private final double topP; private final double presencePenalty; @@ -55,13 +50,23 @@ public class PromptExecutionSettings { private final String user; @Nullable private final List stopSequences; + private Map tokenSelectionBiases; - /// - /// Modify the likelihood of specified tokens appearing in the completion. - /// s - @Nullable - public Map tokenSelectionBiases; - + /** + * Create a new instance of PromptExecutionSettings. + * @param serviceId The id of the AI service to use for prompt execution. + * @param modelId The id of the model to use for prompt execution. + * @param temperature The temperature setting for prompt execution. + * @param topP The topP setting for prompt execution. + * @param presencePenalty The presence penalty setting for prompt execution. + * @param frequencyPenalty The frequency penalty setting for prompt execution. + * @param maxTokens The maximum number of tokens to generate in the output. + * @param resultsPerPrompt The number of results to generate for each prompt. + * @param bestOf The best of setting for prompt execution. + * @param user The user to associate with the prompt execution. + * @param stopSequences The stop sequences to use for prompt execution. + * @param tokenSelectionBiases The token selection biases to use for prompt execution. + */ @JsonCreator public PromptExecutionSettings( @JsonProperty(SERVICE_ID) String serviceId, @@ -80,72 +85,127 @@ public class PromptExecutionSettings { @JsonProperty(TOKEN_SELECTION_BIASES) Map tokenSelectionBiases) { this.serviceId = serviceId; this.modelId = modelId; - this.temperature = temperature; - this.topP = topP; - this.presencePenalty = presencePenalty; - this.frequencyPenalty = frequencyPenalty; - this.maxTokens = maxTokens; - this.resultsPerPrompt = resultsPerPrompt; - this.bestOf = bestOf; + this.temperature = clamp(temperature, 0d, 2d, DEFAULT_TEMPERATURE); + this.topP = clamp(topP, 0d, 1d, DEFAULT_TOP_P); + this.presencePenalty = clamp(presencePenalty, -2d, 2d, DEFAULT_PRESENCE_PENALTY); + this.frequencyPenalty = clamp(frequencyPenalty, -2d, 2d, DEFAULT_FREQUENCY_PENALTY); + this.maxTokens = clamp(maxTokens, 1, Integer.MAX_VALUE); + this.resultsPerPrompt = clamp(resultsPerPrompt, 1, Integer.MAX_VALUE); + this.bestOf = clamp(bestOf, 1, Integer.MAX_VALUE); ; this.user = user; this.stopSequences = stopSequences != null ? new ArrayList<>(stopSequences) : Collections.emptyList(); this.tokenSelectionBiases = - tokenSelectionBiases != null ? new HashMap<>(tokenSelectionBiases) + tokenSelectionBiases != null + ? new HashMap<>(tokenSelectionBiases) : Collections.emptyMap(); + this.tokenSelectionBiases.replaceAll((k, v) -> clamp(v, -100, 100)); } + /** + * Get the id of the AI service to use for prompt execution. + * @return The id of the AI service to use for prompt execution. + */ @JsonProperty(SERVICE_ID) public String getServiceId() { return serviceId; } + /** + * Get the id of the model to use for prompt execution. + * @return The id of the model to use for prompt execution. + */ @JsonProperty(MODEL_ID) public String getModelId() { return modelId; } + /** + * The temperature setting controls the randomness of the output. Lower values produce more + * deterministic outputs, while higher values produce more random outputs. + * @return The temperature setting. + */ @JsonProperty(TEMPERATURE) public double getTemperature() { return Double.isNaN(temperature) ? DEFAULT_TEMPERATURE : temperature; } + /** + * The topP setting controls how many different words or phrases are considered to predict the + * next token. The value is a probability threshold, and the model considers the most likely + * tokens whose cumulative probability mass is greater than the threshold. For example, if the + * value is 0.1, the model considers only the tokens that make up the top 10% of the cumulative + * probability mass. + * @return The topP setting. + */ @JsonProperty(TOP_P) public double getTopP() { return topP; } + /** + * Presence penalty encourages the model to use a more or less diverse range of tokens in the output. + * A higher value means that the model will try to use a greater variety of tokens + * in the ouput. + * @return The presence penalty setting. + */ @JsonProperty(PRESENCE_PENALTY) public double getPresencePenalty() { return presencePenalty; } + /** + * Frequency penalty encourages the model to avoid repeating the same token in the output. + * A higher value means that the model will be less likely to repeat a token. + * + * @return The frequency penalty setting. + */ @JsonProperty(FREQUENCY_PENALTY) public double getFrequencyPenalty() { return frequencyPenalty; } + /** + * The maximum number of tokens to generate in the output. + * @return The maximum number of tokens to generate in the output. + */ @JsonProperty(MAX_TOKENS) public int getMaxTokens() { return maxTokens; } + /** + * The number of results to generate for each prompt. + * @return The number of results to generate for each prompt. + */ @JsonProperty(RESULTS_PER_PROMPT) public int getResultsPerPrompt() { return resultsPerPrompt; } + /** + * The log probability threshold for a result to be considered. + * @return The log probability threshold for a result to be considered. + */ @JsonProperty(BEST_OF) public int getBestOf() { // TODO: not present in com.azure:azure-ai-openai return bestOf; } + /** + * The user to associate with the prompt execution. + * @return The user to associate with the prompt execution. + */ @JsonProperty(USER) public String getUser() { return user; } + /** + * The stop sequences to use for prompt execution. + * @return The stop sequences to use for prompt execution. + */ @JsonProperty(STOP_SEQUENCES) @Nullable public List getStopSequences() { @@ -155,6 +215,12 @@ public class PromptExecutionSettings { return null; } + /** + * The token selection biases to use for prompt execution. The key is the token id + * from the tokenizer, and the value is the bias. A negative bias will make the model less likely + * to use the token, and a positive bias will make the model more likely to use the token. + * @return The token selection biases to use for prompt execution. + */ @JsonProperty(TOKEN_SELECTION_BIASES) @Nullable public Map getTokenSelectionBiases() { @@ -164,25 +230,48 @@ public class PromptExecutionSettings { return null; } + /** + * Create a new builder for PromptExecutionSettings. + * @return A new builder for PromptExecutionSettings. + */ public static Builder builder() { return new Builder(); } + /** + * Builder for PromptExecutionSettings. + */ public static class Builder { Map settings = new HashMap<>(); + /** + * Set the id of the AI service to use for prompt execution. + * @param serviceId The id of the AI service to use for prompt execution. + * @return This builder. + */ public Builder withServiceId(String serviceId) { settings.put(SERVICE_ID, serviceId); return this; } + /** + * Set the id of the model to use for prompt execution. + * @param modelId The id of the model to use for prompt execution. + * @return This builder. + */ public Builder withModelId(String modelId) { settings.put(MODEL_ID, modelId); return this; } + /** + * Set the temperature setting for prompt execution. The value is + * clamped to the range [0.0, 2.0], and the default is 1.0. + * @param temperature The temperature setting for prompt execution. + * @return This builder. + */ public Builder withTemperature(double temperature) { if (!Double.isNaN(temperature)) { settings.put(TEMPERATURE, temperature); @@ -190,6 +279,12 @@ public class PromptExecutionSettings { return this; } + /** + * Set the topP setting for prompt execution. The value is clamped to the range [0.0, 1.0], + * and the default is 1.0. + * @param topP The topP setting for prompt execution. + * @return This builder. + */ public Builder withTopP(double topP) { if (!Double.isNaN(topP)) { settings.put(TOP_P, topP); @@ -197,6 +292,12 @@ public class PromptExecutionSettings { return this; } + /** + * Set the presence penalty setting for prompt execution. The value is clamped to the range + * [-2.0, 2.0], and the default is 0.0. + * @param presencePenalty The presence penalty setting for prompt execution. + * @return This builder. + */ public Builder withPresencePenalty(double presencePenalty) { if (!Double.isNaN(presencePenalty)) { settings.put(PRESENCE_PENALTY, presencePenalty); @@ -204,6 +305,12 @@ public class PromptExecutionSettings { return this; } + /** + * Set the frequency penalty setting for prompt execution. The value is clamped to the range + * [-2.0, 2.0], and the default is 0.0. + * @param frequencyPenalty The frequency penalty setting for prompt execution. + * @return This builder. + */ public Builder withFrequencyPenalty(double frequencyPenalty) { if (!Double.isNaN(frequencyPenalty)) { settings.put(FREQUENCY_PENALTY, frequencyPenalty); @@ -211,26 +318,54 @@ public class PromptExecutionSettings { return this; } + /** + * Set the maximum number of tokens to generate in the output. The value is clamped to the + * range [1, Integer.MAX_VALUE], and the default is 256. + * @param maxTokens The maximum number of tokens to generate in the output. + * @return This builder. + */ public Builder withMaxTokens(int maxTokens) { settings.put(MAX_TOKENS, maxTokens); return this; } + /** + * Set the number of results to generate for each prompt. The value is clamped to the + * range [1, Integer.MAX_VALUE], and the default is 1. + * @param resultsPerPrompt The number of results to generate for each prompt. + * @return This builder. + */ public Builder withResultsPerPrompt(int resultsPerPrompt) { settings.put(RESULTS_PER_PROMPT, resultsPerPrompt); return this; } + /** + * Set the best of setting for prompt execution. The value is clamped to the + * range [1, Integer.MAX_VALUE], and the default is 1. + * @param bestOf The best of setting for prompt execution. + * @return This builder. + */ public Builder withBestOf(int bestOf) { settings.put(BEST_OF, bestOf); return this; } + /** + * Set the user to associate with the prompt execution. + * @param user The user to associate with the prompt execution. + * @return This builder. + */ public Builder withUser(String user) { settings.put(USER, user); return this; } + /** + * Set the stop sequences to use for prompt execution. + * @param stopSequences The stop sequences to use for prompt execution. + * @return This builder. + */ @SuppressWarnings("unchecked") public Builder withStopSequences(List stopSequences) { if (stopSequences != null) { @@ -240,6 +375,12 @@ public class PromptExecutionSettings { return this; } + /** + * Set the token selection biases to use for prompt execution. The bias values + * are clamped to the range [-100, 100]. + * @param tokenSelectionBiases The token selection biases to use for prompt execution. + * @return This builder. + */ @SuppressWarnings("unchecked") public Builder withTokenSelectionBiases(Map tokenSelectionBiases) { if (tokenSelectionBiases != null) { @@ -249,6 +390,10 @@ public class PromptExecutionSettings { return this; } + /** + * Build the PromptExecutionSettings. + * @return A new PromptExecutionSettings from this builder. + */ @SuppressWarnings("unchecked") public PromptExecutionSettings build() { return new PromptExecutionSettings( @@ -268,4 +413,15 @@ public class PromptExecutionSettings { ); } } + + private static double clamp(double value, double min, double max, double defaultValue) { + if (Double.isNaN(value)) { + return defaultValue; + } + return Math.max(min, Math.min(max, value)); + } + + private static int clamp(int value, int min, int max) { + return Math.max(min, Math.min(max, value)); + } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/ToolCallBehavior.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/ToolCallBehavior.java index 7b54ed206c..1f261f42f1 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/ToolCallBehavior.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/ToolCallBehavior.java @@ -15,7 +15,7 @@ public class ToolCallBehavior { private final boolean required; private final boolean enabled; - FunctionCallBehavior(KernelFunction function, boolean required, boolean enabled) { + FunctionCallBehavior(KernelFunction function, boolean required, boolean enabled) { this.required = required; this.enabled = enabled; } @@ -28,7 +28,7 @@ public class ToolCallBehavior { return enabled; } - static String getKey(KernelFunction function) { + static String getKey(KernelFunction function) { return getKey(function.getPluginName(), function.getName()); } @@ -41,30 +41,70 @@ public class ToolCallBehavior { private final Map functionSettings = new HashMap<>(); private final Map settings = new HashMap<>(); + /** + * Create a new instance of ToolCallBehavior with defaults. + */ public ToolCallBehavior() { } + /** + * Create a copy of the other ToolCallBehavior. + * + * @param toolCallBehavior The behavior to copy. + */ public ToolCallBehavior(ToolCallBehavior toolCallBehavior) { flags.putAll(toolCallBehavior.flags); functionSettings.putAll(toolCallBehavior.functionSettings); settings.putAll(toolCallBehavior.settings); } + /** + * Create an unmodifiable copy of this ToolCallBehavior. + * @return An unmodifiable copy of this ToolCallBehavior. + */ public UnmodifiableToolCallBehavior unmodifiableClone() { return new UnmodifiableToolCallBehavior(this); } + /** + * Enable or disable kernel functions. If kernel functions + * are disabled, they will not be passed to the model. This + * is the default behavior. + * + * @param enable Whether to enable kernel functions. + * @return This ToolCallBehavior. + */ public ToolCallBehavior kernelFunctions(boolean enable) { setFlag("kernelFunctions", enable); return this; } + /** + * Enable or disable auto-invocation. If auto-invocation is + * enabled, the model may request that the Semantic Kernel + * invoke functions and return the value to the model. The + * default behavior is to disable auto-invocation. + * + * @param enable Whether to enable auto-invocation. + * @return This ToolCallBehavior. + */ public ToolCallBehavior autoInvoke(boolean enable) { - setFlag("autoInvoke", true); + setFlag("autoInvoke", enable); return this; } - public ToolCallBehavior requireFunction(KernelFunction function, boolean require) { + /** + * Require or not require a function to be called. If a function + * is required, it will be called. If it is not required, it may + * be called if {@code auto-invcation} is enabled. Whether the functions + * are passed to the model is controlled by whether {@code kernelFunctions} + * is enabled. By default, no functions are required. + * + * @param function The function to require or not require. + * @param require Whether to require the function. + * @return This ToolCallBehavior. + */ + public ToolCallBehavior requireFunction(KernelFunction function, boolean require) { if (function != null) { String key = FunctionCallBehavior.getKey(function); functionSettings.compute( @@ -81,7 +121,18 @@ public class ToolCallBehavior { return this; } - public ToolCallBehavior enableFunction(KernelFunction function, boolean enable) { + /** + * Enable or disable a function. If a function is enabled, it + * may be called. If it is not enabled, it will not be called. + * By default, all functions are enabled. Whether the functions + * are passed to the model is controlled by whether {@code kernelFunctions} + * is enabled. + * + * @param function The function to enable or disable. + * @param enable Whether to enable the function. + * @return This ToolCallBehavior. + */ + public ToolCallBehavior enableFunction(KernelFunction function, boolean enable) { if (function != null) { String key = FunctionCallBehavior.getKey(function); functionSettings.compute( @@ -98,26 +149,55 @@ public class ToolCallBehavior { return this; } + /** + * Set the maximum number of times that auto-invocation will be attempted. + * If auto-invocation is enabled, the model may request that the Semantic Kernel + * invoke functions and return the value to the model. If the maximum number of + * attempts is reached, the model will be notified that the function could not be + * invoked. The default maximum number of attempts is 5. + * + * @param maximumAutoInvokeAttempts The maximum number of attempts. + * @return This ToolCallBehavior. + */ public ToolCallBehavior maximumAutoInvokeAttempts(int maximumAutoInvokeAttempts) { setSetting("maximumAutoInvokeAttempts", maximumAutoInvokeAttempts); return this; } + /** + * Check whether kernel functions are enabled. + * @return Whether kernel functions are enabled. + */ public boolean kernelFunctionsEnabled() { return getFlag("kernelFunctions"); } + /** + * Check whether auto-invocation is enabled. + * @return Whether auto-invocation is enabled. + */ public boolean autoInvokeEnabled() { return getFlag("autoInvoke"); } - public boolean functionRequired(KernelFunction function) { + /** + * Check whether the given function is required. + * @param function The function to check. + * @return Whether the function is required. + */ + public boolean functionRequired(KernelFunction function) { if (function != null) { return functionRequired(function.getPluginName(), function.getName()); } return false; } + /** + * Check whether the given function is required. + * @param pluginName The name of the skill that the function is in. + * @param functionName The name of the function. + * @return Whether the function is required. + */ public boolean functionRequired(String pluginName, String functionName) { String key = FunctionCallBehavior.getKey(pluginName, functionName); if (functionSettings.containsKey(key)) { @@ -126,7 +206,12 @@ public class ToolCallBehavior { return false; } - public boolean functionEnabled(KernelFunction function) { + /** + * Check whether the given function is enabled. + * @param function The function to check. + * @return Whether the function is enabled. + */ + public boolean functionEnabled(KernelFunction function) { if (function != null) { return functionEnabled(function.getPluginName(), function.getName()); @@ -134,6 +219,12 @@ public class ToolCallBehavior { return functionSettings.isEmpty(); } + /** + * Check whether the given function is enabled. + * @param pluginName The name of the skill that the function is in. + * @param functionName The name of the function. + * @return Whether the function is enabled. + */ public boolean functionEnabled(String pluginName, String functionName) { String key = FunctionCallBehavior.getKey(pluginName, functionName); @@ -143,26 +234,54 @@ public class ToolCallBehavior { return functionSettings.isEmpty(); } + /** + * Get the maximum number of times that auto-invocation will be attempted. + * @return The maximum number of attempts. + */ public int maximumAutoInvokeAttempts() { return getSetting("maximumAutoInvokeAttempts", DEFAULT_MAXIMUM_AUTO_INVOKE_ATTEMPTS); } + /** + * Set a flag. + * @param key The key for the flag + * @param value The value for the flag + */ protected void setFlag(String key, boolean value) { flags.put(key, value); } + /** + * Set a setting. + * @param key The key for the setting + * @param value The value for the setting + */ protected void setSetting(String key, int value) { settings.put(key, value); } + /** + * Get a flag. + * @param key The key for the flag + * @return The value for the flag + */ protected boolean getFlag(String key) { return flags.getOrDefault(key, false); } + /** + * Get a setting. + * @param key The key for the setting + * @param defaultValue The default value for the setting + * @return The value for the setting + */ protected int getSetting(String key, int defaultValue) { return settings.getOrDefault(key, defaultValue); } + /** + * An unmodifiable instance of ToolCallBehavior. + */ public static class UnmodifiableToolCallBehavior extends ToolCallBehavior { protected UnmodifiableToolCallBehavior(ToolCallBehavior toolCallBehavior) { @@ -180,12 +299,12 @@ public class ToolCallBehavior { } @Override - public final ToolCallBehavior requireFunction(KernelFunction function, boolean require) { + public final ToolCallBehavior requireFunction(KernelFunction function, boolean require) { throw new UnsupportedOperationException("unmodifiable instance of ToolCallBehavior"); } @Override - public final ToolCallBehavior enableFunction(KernelFunction function, boolean enable) { + public final ToolCallBehavior enableFunction(KernelFunction function, boolean enable) { throw new UnsupportedOperationException("unmodifiable instance of ToolCallBehavior"); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/CaseInsensitiveMap.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/CaseInsensitiveMap.java index 134b069879..c96757900d 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/CaseInsensitiveMap.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/CaseInsensitiveMap.java @@ -7,15 +7,27 @@ import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; + import javax.annotation.Nullable; +/** + * A {@code java.util.HashMap} in which the keys are case-insensitive. + * @param the type of the value + */ public class CaseInsensitiveMap extends HashMap { + /** + * Creates a new instance of the {@link CaseInsensitiveMap} class. + * @param kvMap the map + */ public CaseInsensitiveMap(Map kvMap) { super(); putAll(kvMap); } + /** + * Creates a new instance of the {@link CaseInsensitiveMap} class. + */ public CaseInsensitiveMap() { super(); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariable.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariable.java index 16f50f648e..71415fe2de 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariable.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariable.java @@ -4,11 +4,19 @@ package com.microsoft.semantickernel.orchestration.contextvariables; import com.azure.ai.openai.models.CompletionsUsage; import com.microsoft.semantickernel.exceptions.SKException; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter.NoopConverter; + import java.time.OffsetDateTime; import java.util.Collections; import java.util.Objects; + import javax.annotation.Nullable; +/** + * A context variable wraps an arbitrary value and a {@code ContextVariableType}. + * {@code ContextVariableType} is used throughout the Semantic Kernel for passing + * arguments to functions and as function return types. + * @param the type of the context variable + */ public class ContextVariable { private final ContextVariableType type; @@ -16,6 +24,11 @@ public class ContextVariable { @Nullable private final T value; + /** + * Creates a new instance of the {@link ContextVariable} class. + * @param type the type + * @param value the value + */ public ContextVariable( ContextVariableType type, @Nullable T value) { @@ -23,6 +36,14 @@ public class ContextVariable { this.value = value; } + /** + * Converts the given value to the requested result type. + * @param the type of the requested result + * @param the type of the input value + * @param it the input value + * @param requestedResultType the requested result type + * @return the converted value + */ public static ContextVariable convert( @Nullable U it, @@ -34,6 +55,20 @@ public class ContextVariable { ); } + /** + * Converts the given value to the requested result type. The {@code ContextVariableTypes} + * parameter is used to find the appropriate converter for the input value and the requested + * result type. + * + * @param the type of the requested result + * @param the type of the input value + * @param it the input value + * @param requestedResultType the requested result type + * @param contextVariableTypes the context variable types + * @return the converted value + * @throws SKException if a type converter cannot be found, or the input value + * cannot be converted to the requested result type + */ public static ContextVariable convert( @Nullable U it, @@ -126,6 +161,15 @@ public class ContextVariable { throw new SKException("Unable to convert " + it.getClass() + " to " + requestedResultType); } + /** + * Creates a new instance of the {@link ContextVariable} class without using strong typing. + * + * @param value the value + * @param clazz the class + * @param types the types + * @return the new instance + */ + @SuppressWarnings({"rawtypes", "unchecked" }) public static ContextVariable untypedOf( @Nullable Object value, Class clazz, @@ -135,27 +179,62 @@ public class ContextVariable { return new ContextVariable(type, value); } + /** + * Convenience method for creating a {@code ContextVariable} from the + * given {@code CompletionsUsage} instance. + * @param x the value + * @return the new instance + */ public static ContextVariable of(CompletionsUsage x) { return ofValue(x); } + /** + * Convenience method for creating a {@code ContextVariable} from the + * given {@code OffsetDateTime} instance. + * @param x the value + * @return the new instance + */ public static ContextVariable of(OffsetDateTime x) { return ofValue(x); } + /** + * Convenience method for creating a {@code ContextVariable} from the + * given {@code String} instance. + * @param value the value + * @return the new instance + */ public static ContextVariable of(String value) { return ofValue(value); } + /** + * Convenience method for creating a {@code ContextVariable} from the + * given object. + * @param x the object + * @return the new instance + */ public static ContextVariable ofGlobalType(Object x) { return ofValue(x); } + /** + * Get the value of the context variable. + * @return the value + */ @Nullable public T getValue() { return value; } + /** + * Get the value of the context variable. + * @param clazz the class + * @param the type of the value + * @return the value + * @throws SKException if the value cannot be cast to the requested type + */ @Nullable public U getValue(Class clazz) { try { @@ -166,18 +245,39 @@ public class ContextVariable { } } + /** + * Get the type of the context variable. + * @return the type + */ public ContextVariableType getType() { return type; } + /** + * Use the given {@code ContextVariableTypeConverter} to convert the + * value of this {@code ContextVariable} to a prompt string. This method + * is useful when the convert of this {@code ContextVariableType} does + * not create the expected prompt string. + * @param converter the converter to use when converting the value + * @return the value of this {@code ContextVariable} as a prompt string + */ public String toPromptString(ContextVariableTypeConverter converter) { return converter.toPromptString(value); } + /** + * Use the convert of the type of this {@code ContextVariable} to convert + * the value of this {@code ContextVariable} to a prompt string. + * @return the value of this {@code ContextVariable} as a prompt string + */ public String toPromptString() { return toPromptString(type.getConverter()); } + /** + * Returns true if the value of this {@code ContextVariable} is {@code null} or empty. + * @return true if the value is {@code null} or empty + */ public boolean isEmpty() { return value == null || value.toString().isEmpty(); } @@ -195,6 +295,13 @@ public class ContextVariable { return new ContextVariable<>(type, value); } + /** + * Creates a new instance of the {@link ContextVariable} class. + * @param value the value + * @param converter the converter + * @param the type of the value + * @return the new instance + */ public static ContextVariable of(T value, ContextVariableTypeConverter converter) { Objects.requireNonNull(value, "value cannot be null"); Objects.requireNonNull(converter, "converter cannot be null"); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableType.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableType.java index 3d8a182bd5..6a9aba0b68 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableType.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableType.java @@ -2,21 +2,42 @@ package com.microsoft.semantickernel.orchestration.contextvariables; import javax.annotation.Nullable; +/** + * A type of context variable, with a converter to convert objects to the type. + * + * @param The type of the context variable. + */ public class ContextVariableType { private final ContextVariableTypeConverter contextVariableTypeConverter; private final Class clazz; + /** + * Create a new context variable type. + * + * @param contextVariableTypeConverter The converter to convert objects to the type. + * @param clazz The class of the type + */ public ContextVariableType(ContextVariableTypeConverter contextVariableTypeConverter, Class clazz) { this.contextVariableTypeConverter = contextVariableTypeConverter; this.clazz = clazz; } + /** + * Get the converter for this type. + * + * @return The converter for this type. + */ public ContextVariableTypeConverter getConverter() { return contextVariableTypeConverter; } + /** + * Get the class of the type. + * + * @return The class of the type. + */ public Class getClazz() { return clazz; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypeConverter.java index 5a99836f21..8e7dd23e05 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypeConverter.java @@ -11,6 +11,11 @@ import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * A converter for a context variable type. This class is used to convert objects to and from a + * prompt string, and to convert objects to the type of the context variable. + * @param the type of the context variable + */ public class ContextVariableTypeConverter { private static final Logger LOGGER = LoggerFactory.getLogger( @@ -22,15 +27,38 @@ public class ContextVariableTypeConverter { private final Function fromPromptString; private final List> toObjects; + /** + * A converter from one type to another. + * @param the source type + * @param the target type + */ public interface Converter { + /** + * Convert the object to the target type. + * @param t the object to convert + * @return the converted object + */ U toObject(T t); + /** + * Get the class of the target type. + * @return the class of the target type + */ Class getTargetType(); } + /** + * A converter that does no conversion. This converter is often used as a default when no + * other conveter can be found for the type. + * @param the type of the context variable + */ public static class NoopConverter extends ContextVariableTypeConverter { + /** + * Create a new noop converter. + * @param clazz the class of the type + */ public NoopConverter(Class clazz) { super( clazz, @@ -46,6 +74,11 @@ public class ContextVariableTypeConverter { } } + /** + * A base class for concrete implementations of {@link ContextVariableTypeConverter.Converter}. + * @param the source type + * @param the target type + */ public static abstract class DefaultConverter implements Converter { private final Class targetType; @@ -60,6 +93,13 @@ public class ContextVariableTypeConverter { } } + /** + * Create a new context variable type converter. + * @param clazz the class of the type + * @param fromObject a function to convert an object to the type + * @param toPromptString a function to convert the type to a prompt string + * @param fromPromptString a function to convert a prompt string to the type + */ public ContextVariableTypeConverter( Class clazz, Function fromObject, @@ -68,6 +108,14 @@ public class ContextVariableTypeConverter { this(clazz, fromObject, toPromptString, fromPromptString, Collections.emptyList()); } + /** + * Create a new context variable type converter. + * @param clazz the class of the type + * @param fromObject a function to convert an object to the type + * @param toPromptString a function to convert the type to a prompt string + * @param fromPromptString a function to convert a prompt string to the type + * @param toObjects a list of converters to convert the type to other types + */ public ContextVariableTypeConverter( Class clazz, Function fromObject, @@ -82,6 +130,13 @@ public class ContextVariableTypeConverter { } + /** + * Use this converter to convert the object to the type of the context variable. + * @param the type to convert to + * @param t the object to convert + * @param clazz the class of the type to convert to + * @return the converted object + */ @Nullable @SuppressWarnings("unchecked") public U toObject(@Nullable Object t, Class clazz) { @@ -111,6 +166,12 @@ public class ContextVariableTypeConverter { return null; } + /** + * Convert the object to the type of the context variable using the {@code fromObject} function + * provided to the constructor. + * @param s the object to convert + * @return the converted object + */ @Nullable public T fromObject(@Nullable Object s) { if (s == null) { @@ -119,6 +180,12 @@ public class ContextVariableTypeConverter { return fromObject.apply(s); } + /** + * Convert the type to a prompt string using the {@code toPromptString} function provided to the + * constructor. + * @param t the type to convert + * @return the prompt string + */ public String toPromptString(@Nullable T t) { if (t == null) { return ""; @@ -126,6 +193,12 @@ public class ContextVariableTypeConverter { return toPromptString.apply(t); } + /** + * Convert the prompt string to the type using the {@code fromPromptString} function provided to + * the constructor. + * @param t the prompt string to convert + * @return the type + */ @Nullable public T fromPromptString(@Nullable String t) { if (t == null) { @@ -134,6 +207,10 @@ public class ContextVariableTypeConverter { return fromPromptString.apply(t); } + /** + * Get the class of the type. + * @return the class of the type + */ public Class getType() { return clazz; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypes.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypes.java index 5c011999e6..5bc0c131c1 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypes.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/ContextVariableTypes.java @@ -1,12 +1,5 @@ package com.microsoft.semantickernel.orchestration.contextvariables; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - import com.microsoft.semantickernel.exceptions.SKException; import com.microsoft.semantickernel.orchestration.contextvariables.converters.BooleanVariableContextVariableTypeConverter; import com.microsoft.semantickernel.orchestration.contextvariables.converters.CharacterVariableContextVariableTypeConverter; @@ -18,6 +11,16 @@ import com.microsoft.semantickernel.orchestration.contextvariables.converters.Nu import com.microsoft.semantickernel.orchestration.contextvariables.converters.StringVariableContextVariableTypeConverter; import com.microsoft.semantickernel.orchestration.contextvariables.converters.VoidVariableContextVariableTypeConverter; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nullable; + +/** + * A collection of context variable types, with converters to convert objects to the types. + */ public class ContextVariableTypes { private static final ContextVariableTypes DEFAULT_TYPES; @@ -69,28 +72,58 @@ public class ContextVariableTypes { private final Map, ContextVariableType> variableTypes; + /** + * Create a new collection of context variable types. + * + * @param converters The converters to use to convert objects to the types. + */ public ContextVariableTypes(List> converters) { variableTypes = new HashMap<>(); converters.forEach(this::putConverter); } + /** + * Create a new collection of context variable types. + */ public ContextVariableTypes() { variableTypes = new HashMap<>(); } + /** + * Create a new collection of context variable types. + * + * @param contextVariableTypes The collection of context variable types to copy. + */ public ContextVariableTypes(ContextVariableTypes contextVariableTypes) { this.variableTypes = new HashMap<>(contextVariableTypes.variableTypes); } + /** + * Add a converter to the global collection of context variable type converters. + * @param conveter The converter to add. + * @see #getGlobalVariableTypeForClass(Class) + */ public static void addGlobalConverter( - ContextVariableTypeConverter type) { - DEFAULT_TYPES.putConverter(type); + ContextVariableTypeConverter conveter) { + DEFAULT_TYPES.putConverter(conveter); } + /** + * Get the global context variable type for the given class. + * @param aClass The class to get the context variable type for. + * @param The type of the context variable. + * @return The context variable type for the given class. + * @see #addGlobalConverter(ContextVariableTypeConverter) + */ public static ContextVariableType getGlobalVariableTypeForClass(Class aClass) { return DEFAULT_TYPES.getVariableTypeForClass(aClass); } + /** + * Add a converter to this {@code ContextVariableTypes} instance. + * @param The type of the context variable. + * @param contextVariableTypeConverter the converter to add. + */ public void putConverter( ContextVariableTypeConverter contextVariableTypeConverter) { variableTypes.put(contextVariableTypeConverter.getType(), @@ -98,6 +131,13 @@ public class ContextVariableTypes { contextVariableTypeConverter.getType())); } + /** + * Convert the given object to the given class, if possible. + * @param the type to convert to + * @param s the object to convert + * @param clazz the class of the type to convert to + * @return the converted object, or {@code null} if the object cannot be converted + */ @Nullable @SuppressWarnings("unchecked") public static T convert(@Nullable Object s, Class clazz) { @@ -113,6 +153,13 @@ public class ContextVariableTypes { } + /** + * Get the context variable type for the given class. + * @param aClass The class to get the context variable type for. + * @param The type of the context variable. + * @return The context variable type for the given class + * @throws SKException if the type cannot be found. + */ @SuppressWarnings("unchecked") public ContextVariableType getVariableTypeForClass(Class aClass) { try { @@ -122,6 +169,14 @@ public class ContextVariableTypes { } } + /** + * Get the context variable type for the given class or for a type that is assignable + * from the given class. its super class. + * @param aClass The class to get the context variable type for. + * @param The type of the context variable. + * @return The context variable type for the given class. + * @throws SKException if the type cannot be found. + */ @SuppressWarnings("unchecked") public ContextVariableType getVariableTypeForSuperClass(Class aClass) { try { @@ -131,7 +186,6 @@ public class ContextVariableTypes { } } - @SuppressWarnings("unchecked") private ContextVariableType getVariableTypeForClassInternal(Class aClass) { ContextVariableType contextVariableType = variableTypes.get(aClass); @@ -170,6 +224,10 @@ public class ContextVariableTypes { () -> new SKException("Unknown context variable type: " + aClass.getName())); } + /** + * Add all the converters from the given collection to this collection. + * @param contextVariableTypes The collection of converters to add. + */ public void putConverters(ContextVariableTypes contextVariableTypes) { this.variableTypes.putAll(contextVariableTypes.variableTypes); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/BooleanVariableContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/BooleanVariableContextVariableTypeConverter.java index 5a0a233bba..7429d2fe9d 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/BooleanVariableContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/BooleanVariableContextVariableTypeConverter.java @@ -1,12 +1,21 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; +import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; import static com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes.convert; -import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; - +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@link Boolean} variables. Use + * {@code ContextVariableTypes.getDefaultVariableTypeForClass(Boolean.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class BooleanVariableContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Initializes a new instance of the {@link BooleanVariableContextVariableTypeConverter} class. + */ public BooleanVariableContextVariableTypeConverter() { super( Boolean.class, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CharacterVariableContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CharacterVariableContextVariableTypeConverter.java index e8b84a26ed..924130425b 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CharacterVariableContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CharacterVariableContextVariableTypeConverter.java @@ -1,21 +1,33 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; - import static com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes.convert; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code java.lang.Character} variables. Use + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(Character.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class CharacterVariableContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Initializes a new instance of the {@link CharacterVariableContextVariableTypeConverter} class. + */ public CharacterVariableContextVariableTypeConverter() { super( Character.class, s -> convert(s, Character.class), Object::toString, - CharacterVariableContextVariableTypeConverter::charToPromptString); + CharacterVariableContextVariableTypeConverter::charFromPromptString); } - static Character charToPromptString(String s) { + /* + * Converts a prompt string to a Character. + */ + static Character charFromPromptString(String s) { if (s.length() != 1) { throw new IllegalArgumentException("Cannot convert string to character: " + s); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/ChatHistoryVariableContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/ChatHistoryVariableContextVariableTypeConverter.java index 95dcb0fa0e..dd5e6efcad 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/ChatHistoryVariableContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/ChatHistoryVariableContextVariableTypeConverter.java @@ -1,13 +1,22 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; -import static com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes.convert; - import com.microsoft.semantickernel.chatcompletion.ChatHistory; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; +import static com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes.convert; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code com.microsoft.semantickernel.chathistory.ChatHistory} variables. Use + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(ChatHistory.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class ChatHistoryVariableContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Initializes a new instance of the {@link ChatHistoryVariableContextVariableTypeConverter} class. + */ public ChatHistoryVariableContextVariableTypeConverter() { super( ChatHistory.class, @@ -20,6 +29,9 @@ public class ChatHistoryVariableContextVariableTypeConverter extends ); } + /* + * Converts a {@link ChatHistory} to an XML string. + */ private static String toXmlString(ChatHistory chatHistory) { return chatHistory .getMessages() diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CompletionUsageContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CompletionUsageContextVariableTypeConverter.java index c17f6a9525..cce1d0bfd6 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CompletionUsageContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/CompletionUsageContextVariableTypeConverter.java @@ -3,9 +3,19 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; import com.azure.ai.openai.models.CompletionsUsage; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code com.azure.ai.openai.models.CompletionsUsage} variables. Use + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(CompletionsUsage.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class CompletionUsageContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Creates a new instance of the {@link CompletionUsageContextVariableTypeConverter} class. + */ public CompletionUsageContextVariableTypeConverter() { super( CompletionsUsage.class, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/DateTimeContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/DateTimeContextVariableTypeConverter.java index bb97fb4f65..9b48051465 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/DateTimeContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/DateTimeContextVariableTypeConverter.java @@ -1,14 +1,25 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; + import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.util.Arrays; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code java.time.OffsetDateTime} variables. Use + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(OffsetDateTime.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class DateTimeContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Creates a new instance of the {@link DateTimeContextVariableTypeConverter} class. + */ public DateTimeContextVariableTypeConverter() { super( OffsetDateTime.class, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/InstantContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/InstantContextVariableTypeConverter.java index 9aae5c0c1f..d69ebe836a 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/InstantContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/InstantContextVariableTypeConverter.java @@ -1,12 +1,23 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; + import java.time.Instant; import java.time.OffsetDateTime; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code java.time.Instant} variables. Use + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(Instant.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class InstantContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Creates a new instance of the {@link InstantContextVariableTypeConverter} class. + */ public InstantContextVariableTypeConverter() { super( Instant.class, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/NumberVariableContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/NumberVariableContextVariableTypeConverter.java index 7fb297aab5..d887db9227 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/NumberVariableContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/NumberVariableContextVariableTypeConverter.java @@ -1,16 +1,30 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; +import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; import static com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes.convert; -import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; import java.util.function.Function; + import javax.annotation.Nullable; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code java.lang.Number} type variables. Use, for example, + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(Integer.class)} + * to get an instance of this class that works with the {@code Integer} type. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class NumberVariableContextVariableTypeConverter extends ContextVariableTypeConverter { private final Function fromNumber; + /** + * Creates a new instance of the {@link NumberVariableContextVariableTypeConverter} class. + * @param clazz the class + * @param fromPromptString the function to convert from a prompt string + * @param fromNumber the function to convert from a number + */ public NumberVariableContextVariableTypeConverter( Class clazz, Function fromPromptString, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/StringVariableContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/StringVariableContextVariableTypeConverter.java index e7a0b32e20..f9e34f7ba8 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/StringVariableContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/StringVariableContextVariableTypeConverter.java @@ -1,12 +1,21 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; - import static com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes.convert; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code java.lang.String} variables. Use + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(String.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class StringVariableContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Creates a new instance of the {@link StringVariableContextVariableTypeConverter} class. + */ public StringVariableContextVariableTypeConverter() { super( String.class, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/VoidVariableContextVariableTypeConverter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/VoidVariableContextVariableTypeConverter.java index 6da7b3db8f..aef94db7c2 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/VoidVariableContextVariableTypeConverter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/contextvariables/converters/VoidVariableContextVariableTypeConverter.java @@ -2,9 +2,19 @@ package com.microsoft.semantickernel.orchestration.contextvariables.converters; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; +/** + * A {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter} + * for {@code java.lang.Void} types. Use + * {@code ContextVariableTypes.getGlobalVariableTypeForClass(Void.class)} + * to get an instance of this class. + * @see com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes#getGlobalVariableTypeForClass(Class) + */ public class VoidVariableContextVariableTypeConverter extends ContextVariableTypeConverter { + /** + * Creates a new instance of the {@link VoidVariableContextVariableTypeConverter} class. + */ public VoidVariableContextVariableTypeConverter() { super( Void.class, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java index 6395c84bdb..35286ab9f7 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java @@ -1,12 +1,5 @@ package com.microsoft.semantickernel.plugin; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromMethod; @@ -16,21 +9,30 @@ import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nullable; + +/** + * Factory for creating {@link KernelFunction} instances. + */ public class KernelFunctionFactory { - - /// - /// Creates a instance for a method, specified via an instance - /// and an optional target object if the method is an instance method. - /// - /// The method to be represented via the created . - /// The target object for the if it represents an instance method. This should be null if and only if is a static method. - /// Optional function name. If null, it will default to one derived from the method represented by . - /// Optional description of the method. If null, it will default to one derived from the method represented by , if possible (e.g. via a on the method). - /// Optional parameter descriptions. If null, it will default to one derived from the method represented by . - /// Optional return parameter description. If null, it will default to one derived from the method represented by . - /// The to use for logging. If null, no logging will be performed. - /// The created wrapper for . + /** + * Creates a {@link KernelFunction} instance for a method, specified via a {@link Method} instance + * @param The return type of the method. + * @param method The method to be represented via the created {@link KernelFunction}. + * @param target The target object for the {@code method} if it represents an instance method. This should be {@code null} if and only if {@code method} is a static method. + * @param functionName Optional function name. If {@code null}, it will default to one derived from the method represented by {@code method}. + * @param description Optional description of the method. If {@code null}, it will default to one derived from the method represented by {@code method}, + * if possible (e.g. via a {@link com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction} on the method). + * @param parameters Optional parameter descriptions. If {@code null}, it will default to one derived from the method represented by {@code method}. + * @param returnParameter Optional return parameter description. If {@code null}, it will default to one derived from the method represented by {@code method}. + * @return The created {@link KernelFunction} wrapper for {@code method}. + */ public static KernelFunction createFromMethod( Method method, Object target, @@ -47,6 +49,7 @@ public class KernelFunctionFactory { * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. * * @param promptTemplate Prompt template for the function. + * @param Type of the value that the function will return * @return The created {@link KernelFunction} for invoking the prompt. */ public static KernelFunction createFromPrompt(String promptTemplate) { @@ -59,14 +62,15 @@ public class KernelFunctionFactory { * @param promptTemplate Prompt template for the function. * @param executionSettings Default execution settings to use when invoking this prompt * function. - * @param functionName The name to use for the function. If null, it will default to a + * @param functionName The name to use for the function. If {@code null}, it will default to a * randomly generated name. * @param description The description to use for the function. * @param templateFormat The template format of {@code promptTemplate}. This must be - * provided if {@code promptTemplateFactory} is not null. + * provided if {@code promptTemplateFactory} is not {@code null}. * @param promptTemplateFactory The {@link PromptTemplateFactory} to use when interpreting the - * {@code promptTemplate} into a {@link PromptTemplate}. If null, a + * {@code promptTemplate} into a {@link PromptTemplate}. If {@code null}, a * default factory will be used. + * @param Type of the value that the function will return * @return The created {@link KernelFunction} for invoking the prompt. */ public static KernelFunction createFromPrompt( @@ -85,6 +89,16 @@ public class KernelFunctionFactory { promptTemplateFactory); } + /** + * Creates a {@link KernelFunction} instance for a prompt specified via a {@link PromptTemplateConfig}. + * + * @param promptConfig A prompt template configuration for the function. + * @param promptTemplateFactory The {@code PromptTemplateFactory} to use when interpreting + * the prompt template configuration into a {@link PromptTemplate}. + * If {@code null}, a default factory will be used. + * @param Type of the value that the function will return + * @return The created {@link KernelFunction} for invoking the prompt. + */ public static KernelFunction createFromPrompt( PromptTemplateConfig promptConfig, @Nullable PromptTemplateFactory promptTemplateFactory) { @@ -97,6 +111,14 @@ public class KernelFunctionFactory { promptConfig); } + /** + * Creates a {@link KernelFunction} instance for a prompt specified via a {@link PromptTemplateConfig}. + * + * @param promptConfig A prompt template configuration for the function. + * @param promptTemplate The prompt template to use when creating the function. + * @param Type of the value that the function will return + * @return The created {@link KernelFunction} for invoking the prompt. + */ public static KernelFunction create( PromptTemplate promptTemplate, PromptTemplateConfig promptConfig) { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelParameterMetadata.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelParameterMetadata.java index 83ed62c927..cc282802ba 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelParameterMetadata.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelParameterMetadata.java @@ -2,11 +2,15 @@ package com.microsoft.semantickernel.plugin; import javax.annotation.Nullable; +/** + * Metadata for a parameter to a kernel function. The Semantic Kernel creates + * this metadata from the annotations on the method that defines the function, + * or by introspection of a Java method. + * @param The type of the parameter. + */ public class KernelParameterMetadata { - /// The name of the parameter. private final String name; - /// The description of the parameter. @Nullable private final String description; @Nullable @@ -14,6 +18,14 @@ public class KernelParameterMetadata { private final boolean isRequired; private final Class parameterType; + /** + * Creates a new instance of the {@link KernelParameterMetadata} class. + * @param name The name of the parameter. + * @param description The description of the parameter. + * @param parameterType The type of the parameter. + * @param defaultValue The default value of the parameter. + * @param isRequired Whether the parameter is required. + */ public KernelParameterMetadata( String name, @Nullable @@ -29,27 +41,45 @@ public class KernelParameterMetadata { this.parameterType = parameterType; } + /** + * Gets the name of the parameter. + * @return The name of the parameter. + */ public String getName() { return name; } + /** + * Gets the description of the parameter. + * @return The description of the parameter. + */ @Nullable public String getDescription() { return description; } + /** + * Gets the default value of the parameter. + * @return The default value of the parameter. + */ @Nullable public String getDefaultValue() { return defaultValue; } + /** + * Gets whether the parameter is required. + * @return Whether the parameter is required. + */ public boolean isRequired() { return isRequired; } + /** + * Gets the type of the parameter. + * @return The type of the parameter. + */ public Class getType() { return parameterType; } - - //private KernelJsonSchema schema; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPlugin.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPlugin.java index 21b8fa3794..6cdf50e874 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPlugin.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPlugin.java @@ -2,11 +2,16 @@ package com.microsoft.semantickernel.plugin; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.contextvariables.CaseInsensitiveMap; + import java.util.Collections; import java.util.Iterator; import java.util.Map; + import javax.annotation.Nullable; +/** + * A plugin contains a collection of functions that can be invoked by the Semantic Kernel. + */ public class KernelPlugin implements Iterable> { private final String name; @@ -15,6 +20,12 @@ public class KernelPlugin implements Iterable> { private final CaseInsensitiveMap> functions; + /** + * Creates a new instance of the {@link KernelPlugin} class. + * @param name The name of the plugin. + * @param description The description of the plugin. + * @param plugins The functions in the plugin. + */ public KernelPlugin( String name, @Nullable @@ -28,29 +39,55 @@ public class KernelPlugin implements Iterable> { } } + /** + * Adds a function to the plugin. + * @param function The function to add. + */ public void addFunction(KernelFunction function) { functions.put(function.getName(), function); } + /** + * Gets the functions in the plugin. + * @return The functions in the plugin. + */ public Map> getFunctions() { return Collections.unmodifiableMap(functions); } + /** + * Gets a function by name. + * @param functionName The name of the function. + * @param The return type of the function. + * @return The function with the specified name, or {@code null} if no such function exists. + */ @Nullable @SuppressWarnings("unchecked") public KernelFunction get(String functionName) { return (KernelFunction) functions.get(functionName); } + /** + * Get an {@code Iterator} that iterates over the functions of this plugin. + * @return An {@code Iterator} that iterates over the functions of this plugin. + */ @Override public Iterator> iterator() { return functions.values().iterator(); } + /** + * Gets the name of the plugin. + * @return The name of the plugin. + */ public String getName() { return name; } + /** + * Gets the description of the plugin. + * @return The description of the plugin. + */ @Nullable public String getDescription() { return description; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java index 5e6104f22d..6155e69869 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java @@ -1,5 +1,19 @@ package com.microsoft.semantickernel.plugin; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.semantickernel.exceptions.SKException; +import com.microsoft.semantickernel.orchestration.KernelFunction; +import com.microsoft.semantickernel.orchestration.contextvariables.CaseInsensitiveMap; +import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; +import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter; +import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; +import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactory; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; +import com.microsoft.semantickernel.util.EmbeddedResourceLoader; +import com.microsoft.semantickernel.util.EmbeddedResourceLoader.ResourceLocation; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -20,36 +34,25 @@ import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.microsoft.semantickernel.exceptions.SKException; -import com.microsoft.semantickernel.orchestration.KernelFunction; -import com.microsoft.semantickernel.orchestration.contextvariables.CaseInsensitiveMap; -import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; -import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; -import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactory; -import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; -import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; -import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; -import com.microsoft.semantickernel.util.EmbeddedResourceLoader; -import com.microsoft.semantickernel.util.EmbeddedResourceLoader.ResourceLocation; - +/** + * Factory for creating {@link KernelPlugin} instances. {@code KernelPlugin}s can be + * created from a Java object, from loading a directory of plugins, or from loading plugins + * from a resource. + */ public class KernelPluginFactory { private static final Logger LOGGER = LoggerFactory.getLogger(KernelPluginFactory.class); private static final String CONFIG_FILE = "config.json"; private static final String PROMPT_FILE = "skprompt.txt"; - /// Creates a plugin that wraps the specified target object. - /// The instance of the class to be wrapped. - /// - /// Name of the plugin for function collection and prompt templates. If the value is null, a plugin name is derived from the type of the . - /// - /// The to use for logging. If null, no logging will be performed. - /// - /// Public methods decorated with will be included in the plugin. - /// Attributed methods must all have different names; overloads are not supported. - /// + /** + * Creates a plugin that wraps the specified target object. Methods decorated with + * {@code {@literal @}DefineSKFunction} will be included in the plugin. + * + * @param target The instance of the class to be wrapped. + * @param pluginName Name of the plugin for function collection and prompt templates. If the value is {@code null}, a plugin name is derived from the type of the target. + * @return The new plugin. + */ public static KernelPlugin createFromObject(Object target, String pluginName) { List> methods = Arrays.stream(target.getClass().getMethods()) .filter(method -> method.isAnnotationPresent(DefineKernelFunction.class)) @@ -110,27 +113,25 @@ public class KernelPluginFactory { return returnType; } - /// Initializes the new plugin from the provided name and function collection. - /// The name for the plugin. - /// The initial functions to be available as part of the plugin. - /// is null. - /// is an invalid plugin name. - /// contains a null function. - /// contains two functions with the same name. + /** + * Creates a plugin from the provided name and function collection. + * @param pluginName The name for the plugin. + * @param functions The initial functions to be available as part of the plugin. + * @return The new plugin. + */ public static KernelPlugin createFromFunctions( String pluginName, @Nullable List> functions) { return createFromFunctions(pluginName, null, functions); } - /// Initializes the new plugin from the provided name, description, and function collection. - /// The name for the plugin. - /// A description of the plugin. - /// The initial functions to be available as part of the plugin. - /// is null. - /// is an invalid plugin name. - /// contains a null function. - /// contains two functions with the same name. + /** + * Initializes the new plugin from the provided name, description, and function collection. + * @param pluginName The name for the plugin. + * @param description A description of the plugin. + * @param functions The initial functions to be available as part of the plugin. + * @return The new plugin. + */ public static KernelPlugin createFromFunctions(String pluginName, @Nullable String description, @Nullable List> functions) { Map> funcs = new HashMap<>(); @@ -157,7 +158,15 @@ public class KernelPluginFactory { }).collect(Collectors.toList()); } - + /** + * Imports a plugin from a directory. The directory should contain subdirectories, each of which + * contains a prompt template and a configuration file. The configuration file should be named + * "config.json" and the prompt template should be named "skprompt.txt". + * @param parentDirectory The parent directory containing the plugin directories. + * @param pluginDirectoryName The name of the plugin directory. + * @param promptTemplateFactory The factory to use for creating prompt templates. + * @return The imported plugin. + */ public static KernelPlugin importPluginFromDirectory(Path parentDirectory, String pluginDirectoryName, PromptTemplateFactory promptTemplateFactory) { @@ -252,6 +261,18 @@ public class KernelPluginFactory { .build(); } + /** + * Imports a plugin from a resource directory, which may be on the classpath or filesystem. + * The directory should contain subdirectories, each of which + * contains a prompt template and a configuration file. The configuration file should be named + * "config.json" and the prompt template should be named "skprompt.txt". + * @param parentDirectory The parent directory containing the plugin directories. + * @param pluginDirectoryName The name of the plugin directory. + * @param functionName The name of the function to import. + * @param promptTemplateFactory The factory to use for creating prompt templates. + * @param clazz The class to use for loading resources. + * @return The imported plugin. + */ @Nullable public static KernelPlugin importPluginFromResourcesDirectory( String parentDirectory, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelReturnParameterMetadata.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelReturnParameterMetadata.java index 6098c3cfa6..a19b86e0f4 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelReturnParameterMetadata.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelReturnParameterMetadata.java @@ -2,12 +2,23 @@ package com.microsoft.semantickernel.plugin; import javax.annotation.Nullable; +/** + * Metadata for a return parameter of a {@link com.microsoft.semantickernel.orchestration.KernelFunction}. + * + * @param the type of the return parameter + */ public class KernelReturnParameterMetadata { @Nullable private final String description; private final Class parameterType; + /** + * Creates a new instance of {@link KernelReturnParameterMetadata}. + * + * @param description the description of the return parameter + * @param parameterType the type of the return parameter + */ public KernelReturnParameterMetadata( @Nullable String description, @@ -16,11 +27,21 @@ public class KernelReturnParameterMetadata { this.parameterType = parameterType; } + /** + * Gets the description of the return parameter. + * + * @return the description of the return parameter + */ @Nullable public String getDescription() { return description; } + /** + * Gets the type of the return parameter. + * + * @return the type of the return parameter + */ public Class getParameterType() { return parameterType; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/Plugin.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/Plugin.java index eb2163806c..b5d7fd0a7a 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/Plugin.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/Plugin.java @@ -2,31 +2,57 @@ package com.microsoft.semantickernel.plugin; import com.microsoft.semantickernel.orchestration.KernelFunction; + import java.util.Arrays; import java.util.Collections; import java.util.List; +/** + * A plugin contains one or more {@link KernelFunction}s. + */ public class Plugin { private final String name; - private final List functions; + private final List> functions; - public Plugin(String name, KernelFunction... functions) { + /** + * Creates a new instance of {@link Plugin}. + * + * @param name the name of the plugin + * @param functions the functions of the plugin + */ + public Plugin(String name, KernelFunction... functions) { this.name = name; this.functions = functions != null ? Collections.unmodifiableList(Arrays.asList(functions)) : Collections.emptyList(); } - public Plugin(String name, List functions) { + /** + * Creates a new instance of {@link Plugin}. + * + * @param name the name of the plugin + * @param functions the functions of the plugin + */ + public Plugin(String name, List> functions) { this(name, functions != null ? functions.toArray(new KernelFunction[0]) : new KernelFunction[0]); } + /** + * Gets the name of the plugin. + * + * @return the name of the plugin + */ public String name() { return name; } - public List functions() { + /** + * Gets the functions of the plugin. + * + * @return the functions of the plugin + */ + public List> functions() { return Collections.unmodifiableList(functions); } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/DefineKernelFunction.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/DefineKernelFunction.java index 58c88a5d89..639a226207 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/DefineKernelFunction.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/DefineKernelFunction.java @@ -10,13 +10,41 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DefineKernelFunction { + + /** + * The description of what the function does. The description should + * be short and concise. The model uses the description to + * determine whether the function is a good match for use to + * complete a prompt. If the model is not selecting a function + * when it should be, consider adding more detail to the description. + * @return the description of the function, or an empty string if no description is provided. + */ String description() default ""; + /** + * The name of the function. + * @return the name of the function, or an empty string if no name is provided. + */ String name() default ""; + /** + * The fully qualified class name of the return value of the function, for example, "java.lang.String". + * If this parameter is not provided, the model will attempt to infer the return type from the method signature. + * @return the fully qualified class name of the return value of the function + */ String returnType() default ""; + /** + * The description of the return value of the function. The description should be short and concise. + * @return the description of the return value of the function, or an empty string if no description is provided. + */ String returnDescription() default ""; + /** + * Examples of how to use the function. The examples should be short and concise. The Semantic Kernel + * can use the examples to help the model understand how the function is used. + * @return Examples of how to use the function, or an empty array if no examples are provided. + */ + SKSample[] samples() default {}; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/KernelFunctionParameter.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/KernelFunctionParameter.java index fe09521da6..7a61d7d432 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/KernelFunctionParameter.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/KernelFunctionParameter.java @@ -11,19 +11,44 @@ import java.lang.annotation.Target; @Target(ElementType.PARAMETER) public @interface KernelFunctionParameter { + /** + * A special value that is used to indicate that no default value is provided. + */ String NO_DEFAULT_VALUE = "SKFunctionParameters__NO_INPUT_PROVIDED"; + /** + * The description of the parameter. The description should be short and concise. + * The model uses the description to determine what value to pass to the function. + * + * @return the description of the parameter, or an empty string if no description is provided. + */ String description() default ""; + /** + * The name of the parameter. This element is required. + * @return the name of the parameter, or an empty string if no name is provided. + */ String name(); + /** + * The default value of the parameter. If no value is set, {@code null} will be passed as the value to this argument. + * @return the default value of the parameter, or {@link NO_DEFAULT_VALUE} if no default value is provided. + */ String defaultValue() default NO_DEFAULT_VALUE; /** - * If required is false, no value is set, and no default value is provided, null will be passed - * as this argument. + * Whether a value is required for this argument. If required is false, the model is free to choose + * whether or not to provide a value. If the model does not provide a value, the default value is used. + * @return whether a value is required for this argument. */ boolean required() default true; + /** + * The type of the parameter. The Semantic Kernel will use the type to find a + * {@link com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType} + * to convert the value from a prompt string to the correct argument type. The type defaults to + * {@link String} if not provided. + * @return the type of the parameter + */ Class type() default String.class; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/SKSample.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/SKSample.java index c7ef71c8f5..946a1bb51c 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/SKSample.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/annotations/SKSample.java @@ -7,12 +7,39 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * @since 1.0.0 + * Annotation that decorates an {@link DefineKernelFunction} annotation to provide examples of how to use the function. + * For example: + *

+ * {@literal @}DefineSKFunction(
+ *    name = "add",
+ *    description = "Adds two numbers together",
+ *    returnType = "java.lang.Integer",
+ *    returnDescription = "The sum of the two numbers",
+ *    samples = {
+ *        {@literal @}SKSample(inputs = "{\"number1\":1, \"number2\":2", output = "3")
+ *     }
+ *  )
+ * public static double add(
+ *       {@literal @}SKFunctionParameters(description="The first number to add", name="number1") double number1,
+ *       {@literal @}SKFunctionParameters(description="The second number to add", name="number2") double number2
+ *   )
+ *   {
+ *       return number1 + number2;
+ *   }
+ * 
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SKSample { + /** + * An example of inputs to the function. + * @return An example of inputs to the function. + */ String inputs(); + /** + * An example output of the function given the inputs. + * @return An example output of the function given the inputs. + */ String output(); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/AggregatorPromptTemplateFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/AggregatorPromptTemplateFactory.java index 668f846687..fcfe13e942 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/AggregatorPromptTemplateFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/AggregatorPromptTemplateFactory.java @@ -2,12 +2,23 @@ package com.microsoft.semantickernel.semanticfunctions; import java.util.ArrayList; import java.util.List; + import reactor.util.annotation.NonNull; +/** + * An collection of {@link PromptTemplateFactory} instances. The + * factory will try to create a {@link PromptTemplate} using each + * factory in the collection until one is successful. + */ public class AggregatorPromptTemplateFactory implements PromptTemplateFactory { private final List templateFactories; + /** + * Creates a new instance of {@link AggregatorPromptTemplateFactory}. + * + * @param templateFactories the factories to aggregate + */ public AggregatorPromptTemplateFactory(List templateFactories) { this.templateFactories = new ArrayList<>(templateFactories); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/HandlebarsPromptTemplateFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/HandlebarsPromptTemplateFactory.java index f2574dbfd5..5b115ed696 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/HandlebarsPromptTemplateFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/HandlebarsPromptTemplateFactory.java @@ -1,11 +1,20 @@ package com.microsoft.semantickernel.semanticfunctions; import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate; + import java.util.Locale; + import reactor.util.annotation.NonNull; +/** + * A factory for creating a {@link HandlebarsPromptTemplate} instance for + * a {@code PromptTemplateConfig} that uses the handlebars template format. + */ public class HandlebarsPromptTemplateFactory implements PromptTemplateFactory { + /** + * The handlebars template format. + */ public static final String HANDLEBARS_TEMPLATE_FORMAT = "handlebars"; @Override diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/InputVariable.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/InputVariable.java index d0a259196f..33ca056f50 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/InputVariable.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/InputVariable.java @@ -3,8 +3,12 @@ package com.microsoft.semantickernel.semanticfunctions; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.microsoft.semantickernel.exceptions.SKException; + import javax.annotation.Nullable; +/** + * Metadata for an input variable of a {@link com.microsoft.semantickernel.orchestration.KernelFunction}. + */ public class InputVariable { private String name; @@ -15,6 +19,11 @@ public class InputVariable { private String defaultValue; private boolean isRequired; + /** + * Creates a new instance of {@link InputVariable}. + * + * @param name the name of the input variable + */ public InputVariable(String name) { this.name = name; this.type = String.class.getName(); @@ -23,6 +32,15 @@ public class InputVariable { this.isRequired = true; } + /** + * Creates a new instance of {@link InputVariable}. + * + * @param name the name of the input variable + * @param type the type of the input variable + * @param description the description of the input variable + * @param defaultValue the default value of the input variable + * @param isRequired whether the input variable is required + */ @JsonCreator public InputVariable( @JsonProperty("name") @@ -48,55 +66,58 @@ public class InputVariable { this.isRequired = isRequired; } + /** + * Gets the name of the input variable. + * @return the name of the input variable + */ public String getName() { return name; } - public void setName(String name) { - this.name = name; - } - + /** + * Gets the type of the input variable. + * @return the type of the input variable + */ public String getType() { return type; } - public void setType(String type) { - this.type = type; - } - + /** + * Gets the description of the input variable. + * @return the description of the input variable + */ @Nullable public String getDescription() { return description; } - public void setDescription(String description) { - this.description = description; - } - + /** + * Gets the default value of the input variable. + * @return the default value of the input variable + */ @Nullable public String getDefaultValue() { return defaultValue; } - - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } - + /** + * Gets whether the input variable is required. + * @return whether the input variable is required + */ public boolean isRequired() { return isRequired; } - public void setRequired(boolean required) { - isRequired = required; - } - + /** + * Gets the class of the type of the input variable. + * @return the class of the type of the input variable + */ public Class getTypeClass() { try { return Thread.currentThread().getContextClassLoader().loadClass(type); } catch (ClassNotFoundException e) { throw new SKException( - "Could not load class for type: " + type + " when for input variable " + name + - ", note this needs to be a fully qualified class name, i.e 'java.lang.String'."); + "Could not load class for type: " + type + " for input variable " + name + + ". This needs to be a fully qualified class name, e.g. 'java.lang.String'."); } } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java index f322daf25e..a79fd198ab 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java @@ -1,5 +1,27 @@ package com.microsoft.semantickernel.semanticfunctions; +import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.exceptions.AIException; +import com.microsoft.semantickernel.exceptions.AIException.ErrorCodes; +import com.microsoft.semantickernel.exceptions.SKException; +import com.microsoft.semantickernel.hooks.FunctionInvokedEvent; +import com.microsoft.semantickernel.hooks.FunctionInvokingEvent; +import com.microsoft.semantickernel.hooks.KernelHooks; +import com.microsoft.semantickernel.orchestration.FunctionResult; +import com.microsoft.semantickernel.orchestration.InvocationContext; +import com.microsoft.semantickernel.orchestration.KernelFunction; +import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; +import com.microsoft.semantickernel.orchestration.KernelFunctionMetadata; +import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; +import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType; +import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; +import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter.NoopConverter; +import com.microsoft.semantickernel.plugin.KernelParameterMetadata; +import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; +import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; +import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter; +import static com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter.NO_DEFAULT_VALUE; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -15,32 +37,16 @@ import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.microsoft.semantickernel.Kernel; -import com.microsoft.semantickernel.exceptions.AIException; -import com.microsoft.semantickernel.exceptions.AIException.ErrorCodes; -import com.microsoft.semantickernel.exceptions.SKException; -import com.microsoft.semantickernel.hooks.FunctionInvokedEvent; -import com.microsoft.semantickernel.hooks.FunctionInvokingEvent; -import com.microsoft.semantickernel.hooks.KernelHooks; -import com.microsoft.semantickernel.orchestration.FunctionResult; -import com.microsoft.semantickernel.orchestration.InvocationContext; -import com.microsoft.semantickernel.orchestration.KernelFunction; -import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; -import com.microsoft.semantickernel.orchestration.KernelFunctionMetadata; -import com.microsoft.semantickernel.orchestration.MethodDetails; -import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; -import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType; -import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter; -import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypeConverter.NoopConverter; -import com.microsoft.semantickernel.plugin.KernelParameterMetadata; -import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; -import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; -import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter; -import static com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter.NO_DEFAULT_VALUE; - import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; +/** + * A {@link KernelFunction} that is created from a method. This class is used to create a + * {@link KernelFunction} from a method that is annotated with {@link DefineKernelFunction} + * and {@link KernelFunctionParameter}. + * + * @param the return type of the function + */ public class KernelFunctionFromMethod extends KernelFunction { private final static Logger LOGGER = LoggerFactory.getLogger(KernelFunctionFromMethod.class); @@ -79,7 +85,21 @@ public class KernelFunctionFromMethod extends KernelFunction { return function.invoke(kernel, this, arguments, variableType, invocationContext); } + /** + * Concrete implementation of the abstract method in KernelFunction. {@inheritDoc} + */ public interface ImplementationFunc { + + /** + * Invokes the function. + * + * @param kernel the kernel to invoke the function on + * @param function the function to invoke + * @param arguments the arguments to the function + * @param variableType the variable type of the function + * @param invocationContext the invocation context + * @return a {@link Mono} that emits the result of the function invocation + */ Mono> invoke( Kernel kernel, KernelFunction function, @@ -89,6 +109,18 @@ public class KernelFunctionFromMethod extends KernelFunction { } + /** + * Creates a new instance of {@link KernelFunctionFromMethod} from a method. + * + * @param method the method to create the function from + * @param target the instance of the class that the method is a member of + * @param functionName the name of the function + * @param description the description of the function + * @param parameters the parameters of the function + * @param returnParameter the return parameter of the function + * @param the return type of the function + * @return a new instance of {@link KernelFunctionFromMethod} + */ @SuppressWarnings("unchecked") public static KernelFunction create( Method method, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index e9657be9b7..211ac30cb5 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -42,19 +42,31 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +/** + * A {@link KernelFunction} implementation that is created from a prompt template. + * + * @param the type of the return value of the function + */ public class KernelFunctionFromPrompt extends KernelFunction { private static final Logger LOGGER = LoggerFactory.getLogger(KernelFunctionFromPrompt.class); private final PromptTemplate template; + /** + * Creates a new instance of {@link KernelFunctionFromPrompt}. + * + * @param template the prompt template to use for the function + * @param promptConfig the configuration for the prompt + * @param executionSettings the execution settings to use when invoking the function + */ public KernelFunctionFromPrompt( PromptTemplate template, PromptTemplateConfig promptConfig, @Nullable Map executionSettings) { super( - new KernelFunctionMetadata( + new KernelFunctionMetadata<>( getName(promptConfig), promptConfig.getDescription(), promptConfig.getKernelParametersMetadata(), @@ -73,20 +85,37 @@ public class KernelFunctionFromPrompt extends KernelFunction { } } + /** + * Creates a new instance of {@link KernelFunctionFromPrompt} from a + * {@code PromptTemplateConfig}. + * + * @param promptConfig the configuration for the prompt + * @param the type of the return value of the function + * @return a new instance of {@link KernelFunction} + */ public static KernelFunction create( - PromptTemplateConfig promptConfig - ) { + PromptTemplateConfig promptConfig) { return create( promptConfig, null ); } + /** + * Creates a new instance of {@link KernelFunctionFromPrompt} from a + * {@code PromptTemplateConfig}, using the {@code PropmptTemplateFactory} + * to create the prompt template. If {@code promptTemplateFactory} is {@code null}, + * a default factory will be used. + * + * @param promptConfig the configuration for the prompt + * @param promptTemplateFactory the prompt template factory to use for creating the prompt template + * @param the type of the return value of the function + * @return a new instance of {@link KernelFunction} + */ public static KernelFunction create( PromptTemplateConfig promptConfig, @Nullable - PromptTemplateFactory promptTemplateFactory - ) { + PromptTemplateFactory promptTemplateFactory) { if (promptTemplateFactory == null) { promptTemplateFactory = new KernelPromptTemplateFactory(); } @@ -94,7 +123,15 @@ public class KernelFunctionFromPrompt extends KernelFunction { return create(promptTemplateFactory.tryCreate(promptConfig), promptConfig); } - + /** + * Creates a new instance of {@link KernelFunctionFromPrompt} from a + * {@code PromptTemplateConfig}, using the provided prompt template. + * + * @param promptTemplate the prompt template to use for the function + * @param promptConfig the configuration for the prompt + * @param the type of the return value of the function + * @return a new instance of {@link KernelFunction} + */ public static KernelFunction create( PromptTemplate promptTemplate, PromptTemplateConfig promptConfig) { @@ -391,22 +428,29 @@ public class KernelFunctionFromPrompt extends KernelFunction { return Mono.empty(); } + /** + * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. + * @param the type of the return value of the function + * @param promptTemplate the prompt template for the function + * @return a new instance of {@link KernelFunction} + */ public static KernelFunction create( String promptTemplate) { return create(promptTemplate, null, null, null, null, null); } - /// - /// Creates a instance for a prompt specified via a prompt template. - /// - /// Prompt template for the function, defined using the template format. - /// Default execution settings to use when invoking this prompt function. - /// A name for the given function. The name can be referenced in templates and used by the pipeline planner. - /// The description to use for the function. - /// Optional format of the template. Must be provided if a prompt template factory is provided - /// Optional: Prompt template factory - /// Logger factory - /// A function ready to use + /** + * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. + * If any of the optional parameters are {@code null}, default values will be used. + * @param promptTemplate the prompt template for the function + * @param executionSettings the default execution settings to use when invoking this prompt function + * @param functionName the name of the function + * @param description the description of the function + * @param templateFormat the format of the template + * @param promptTemplateFactory the prompt template factory to use for creating the prompt template + * @param the type of the return value of the function + * @return a new instance of {@link KernelFunction} + */ @SuppressWarnings("unchecked") public static KernelFunction create( String promptTemplate, @@ -434,10 +478,19 @@ public class KernelFunctionFromPrompt extends KernelFunction { .build(); } + /** + * Creates a new instance of {@link Builder}. + * @param The type of the return value of the function + * @return a new instance of {@link Builder} + */ public static Builder builder() { return new Builder<>(); } + /** + * A builder for creating a {@link KernelFunction} from a prompt template. + * @param the type of the return value of the function + */ public static final class Builder implements FromPromptBuilder { @Nullable @@ -457,6 +510,8 @@ public class KernelFunctionFromPrompt extends KernelFunction { private OutputVariable outputVariable; @Nullable private PromptTemplateFactory promptTemplateFactory; + @Nullable + private PromptTemplateConfig functionModel; @Override @@ -554,9 +609,27 @@ public class KernelFunctionFromPrompt extends KernelFunction { return this; } + @Override + public FromPromptBuilder withPromptTemplateConfig( + @Nullable + PromptTemplateConfig functionModel) { + this.functionModel = functionModel; + return this; + } + @Override public KernelFunction build() { + if (functionModel != null) { + if (promptTemplate == null) { + throw new IllegalStateException("A PromptTemplate must be provided when building with a PromptTemplateConfig"); + } + return new KernelFunctionFromPrompt<>( + promptTemplate, + functionModel, + executionSettings); + } + if (template == null) { throw new IllegalStateException("Template must be provided"); } @@ -584,17 +657,5 @@ public class KernelFunctionFromPrompt extends KernelFunction { } - public KernelFunction build(PromptTemplateConfig functionModel) { - - if (promptTemplate == null) { - throw new IllegalStateException("Template must be provided"); - } - - return new KernelFunctionFromPrompt<>( - promptTemplate, - functionModel, - executionSettings - ); - } } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java index dda485e3d5..92602df415 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java @@ -2,12 +2,17 @@ package com.microsoft.semantickernel.semanticfunctions; import static com.microsoft.semantickernel.semanticfunctions.HandlebarsPromptTemplateFactory.HANDLEBARS_TEMPLATE_FORMAT; import static com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT; - import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate; import com.microsoft.semantickernel.templateengine.semantickernel.DefaultPromptTemplate; + import java.util.Locale; + import javax.annotation.Nonnull; +/** + * Factory for creating prompt templates. This factory creates the appropriate + * prompt template based on the template format. + */ public class KernelPromptTemplateFactory implements PromptTemplateFactory { @Override diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/MethodDetails.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/MethodDetails.java similarity index 54% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/MethodDetails.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/MethodDetails.java index 6f62d4a94c..48b280e588 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/MethodDetails.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/MethodDetails.java @@ -1,4 +1,8 @@ -package com.microsoft.semantickernel.orchestration; +package com.microsoft.semantickernel.semanticfunctions; + +import com.microsoft.semantickernel.plugin.KernelParameterMetadata; +import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; +import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromMethod.ImplementationFunc; import java.util.ArrayList; import java.util.Collections; @@ -6,24 +10,32 @@ import java.util.List; import javax.annotation.Nullable; -import com.microsoft.semantickernel.plugin.KernelParameterMetadata; -import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromMethod.ImplementationFunc; - +/** + * Metadata for a method that can be used as a kernel function. + */ public class MethodDetails { private final String name; @Nullable private final String description; - private final ImplementationFunc function; + private final ImplementationFunc function; private final List> parameters; private final KernelReturnParameterMetadata returnParameter; + /** + * Constructor. + * + * @param name The name of the method. + * @param description The description of the method. + * @param function The function that implements the method. + * @param parameters The parameters of the method. + * @param returnParameter The return parameter of the method. + */ public MethodDetails( String name, @Nullable String description, - ImplementationFunc function, + ImplementationFunc function, List> parameters, KernelReturnParameterMetadata returnParameter) { this.name = name; @@ -33,23 +45,43 @@ public class MethodDetails { this.returnParameter = returnParameter; } + /** + * Get the name of the method. + * @return The name of the method. + */ public String getName() { return name; } + /** + * Get the description of the method. + * @return The description of the method. + */ @Nullable public String getDescription() { return description; } - public ImplementationFunc getFunction() { + /** + * Get the function that implements the method. This is an internal detail. + * @return The function that implements the method. + */ + public ImplementationFunc getFunction() { return function; } + /** + * Get the parameters of the method. + * @return The parameters of the method. + */ public List> getParameters() { return Collections.unmodifiableList(parameters); } + /** + * Get the return parameter of the method. + * @return The return parameter of the method. + */ public KernelReturnParameterMetadata getReturnParameter() { return returnParameter; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/OutputVariable.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/OutputVariable.java index 6528a2dc33..f830bf4535 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/OutputVariable.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/OutputVariable.java @@ -3,8 +3,12 @@ package com.microsoft.semantickernel.semanticfunctions; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.microsoft.semantickernel.exceptions.SKException; + import javax.annotation.Nullable; +/** + * Metadata for an output variable of a kernel function. + */ public class OutputVariable { @Nullable @@ -12,6 +16,12 @@ public class OutputVariable { private final String type; + /** + * Constructor. + * + * @param description The description of the output variable. + * @param type The type of the output variable. + */ @JsonCreator public OutputVariable( @Nullable @@ -24,17 +34,25 @@ public class OutputVariable { this.type = type; } + /** + * Get the description of the output variable. + * @return The description of the output variable. + */ @Nullable public String getDescription() { return description; } + /** + * Get the type of the output variable. + * @return The type of the output variable. + */ public Class getType() { try { return this.getClass().getClassLoader().loadClass(type); } catch (ClassNotFoundException e) { throw new SKException("Requested output type could not be found: " + type - + ", note this needs to be a fully qualified class name, i.e 'java.lang.String'."); + + ". This needs to be a fully qualified class name, e.g. 'java.lang.String'."); } } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java index 9c589abac8..016298e322 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java @@ -1,25 +1,28 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.semanticfunctions; + import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.builders.Buildable; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; + import javax.annotation.Nullable; + import reactor.core.publisher.Mono; /** - * Interface for prompt template + * Represents a prompt template that can be rendered to a string. */ public interface PromptTemplate extends Buildable { - /// - /// Render the template using the information in the context - /// - /// The containing services, plugins, and other state for use throughout the operation. - /// The arguments. - /// The to monitor for cancellation requests. The default is . - /// Prompt rendered to string + /** + * Renders the template using the supplied {@code Kernel}, {@code KernelFunctionArguments}, and {@code InvocationContext}. + * @param kernel The {@link Kernel} containing services, plugins, and other state for use throughout the operation. + * @param arguments The arguments to use to satisfy any input variables in the prompt template. + * @param context The {@link InvocationContext} which carries optional information for the prompt rendering. + * @return The rendered prompt. + */ Mono renderAsync( Kernel kernel, @Nullable KernelFunctionArguments arguments, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateConfig.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateConfig.java index ba1d15b4b8..d76cee4512 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateConfig.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateConfig.java @@ -10,19 +10,37 @@ import com.microsoft.semantickernel.exceptions.SKException; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.plugin.KernelParameterMetadata; import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; + import javax.annotation.Nullable; +/** + * Metadata for a prompt template. + */ @JsonIgnoreProperties(ignoreUnknown = true) public class PromptTemplateConfig { + /** + * The current prompt template config schema version. + */ public static final int CURRENT_SCHEMA = 1; + + /** + * The default name for a prompt template config. + */ public static final String DEFAULT_CONFIG_NAME = "default"; + + /** + * The default template format for a prompt template config. + */ + public static final String SEMANTIC_KERNEL_TEMPLATE_FORMAT = "semantic-kernel"; + @Nullable private String name; private String template; @@ -34,8 +52,11 @@ public class PromptTemplateConfig { private OutputVariable outputVariable; private Map executionSettings; - public static final String SEMANTIC_KERNEL_TEMPLATE_FORMAT = "semantic-kernel"; - + /** + * Constructor for a prompt template config + * + * @param template Template string + */ public PromptTemplateConfig(String template) { this( CURRENT_SCHEMA, @@ -49,6 +70,18 @@ public class PromptTemplateConfig { ); } + /** + * Constructor for a prompt template config + * + * @param schema Schema version + * @param name Name of the template + * @param template Template string + * @param templateFormat Template format + * @param description Description of the template + * @param inputVariables Input variables + * @param outputVariable Output variable + * @param executionSettings Execution settings + */ @JsonCreator public PromptTemplateConfig( @JsonProperty("schema") @@ -132,6 +165,11 @@ public class PromptTemplateConfig { ); } + /** + * Copy constructor. + * + * @param promptTemplate The prompt template to copy. + */ public PromptTemplateConfig(PromptTemplateConfig promptTemplate) { this( promptTemplate.name, @@ -144,6 +182,11 @@ public class PromptTemplateConfig { ); } + /** + * Get the parameters metadata. + * + * @return The parameters metadata. + */ public List> getKernelParametersMetadata() { if (inputVariables == null) { return Collections.emptyList(); @@ -159,6 +202,11 @@ public class PromptTemplateConfig { .collect(Collectors.toList()); } + /** + * Get the return parameter metadata. + * + * @return The return parameter metadata. + */ public KernelReturnParameterMetadata getKernelReturnParameterMetadata() { if (outputVariable == null) { return new KernelReturnParameterMetadata<>("", String.class); @@ -170,62 +218,132 @@ public class PromptTemplateConfig { ); } - public void addInputVariable(InputVariable inputVariable) { + /** + * Add an input variable to the prompt template config. + * + * @param inputVariable The input variable to add. + * @return {@code this} prompt template config. + */ + public PromptTemplateConfig addInputVariable(InputVariable inputVariable) { inputVariables.add(inputVariable); + return this; } + /** + * Get the name of the prompt template config. + * @return The name of the prompt template config. + */ @Nullable public String getName() { return name; } + /** + * Set the name of the prompt template config. + * @param name The name of the prompt template config. + * @return {@code this} prompt template config. + */ public PromptTemplateConfig setName(String name) { this.name = name; return this; } + /** + * Get the template of the prompt template config. + * @return The template of the prompt template config. + */ public String getTemplate() { return template; } - public void setTemplate(String template) { + /** + * Set the template of the prompt template config. + * @param template The template of the prompt template config. + * @return {@code this} prompt template config. + */ + public PromptTemplateConfig setTemplate(String template) { this.template = template; + return this; } + /** + * Get the template format of the prompt template config. + * @return The template format of the prompt template config. + */ public String getTemplateFormat() { return templateFormat; } - public void setTemplateFormat(String templateFormat) { + /** + * Set the template format of the prompt template config. + * @param templateFormat The template format of the prompt template config. + * @return {@code this} prompt template config. + */ + public PromptTemplateConfig setTemplateFormat(String templateFormat) { this.templateFormat = templateFormat; + return this; } + /** + * Get the description of the prompt template config. + * @return The description of the prompt template config. + */ @Nullable public String getDescription() { return description; } - public void setDescription(String description) { + /** + * Set the description of the prompt template config. + * @param description The description of the prompt template config. + * @return {@code this} prompt template config. + */ + public PromptTemplateConfig setDescription(String description) { this.description = description; + return this; } + /** + * Get the inputVariables of the prompt template config. + * @return The input variables of the prompt template config. + */ public List getInputVariables() { return Collections.unmodifiableList(inputVariables); } - public void setInputVariables(List inputVariables) { + /** + * Set the inputVariables of the prompt template config. + * @param inputVariables The input variables of the prompt template config. + * @return {@code this} prompt template config. + */ + public PromptTemplateConfig setInputVariables(List inputVariables) { this.inputVariables = new ArrayList<>(inputVariables); + return this; } + /** + * Get the output variable of the prompt template config. + * @return The output variable of the prompt template config. + */ @Nullable public OutputVariable getOutputVariable() { return outputVariable; } - public void setOutputVariable(OutputVariable outputVariable) { + /** + * Set the output variable of the prompt template config. + * @param outputVariable The output variable of the prompt template config. + * @return {@code this} prompt template config. + */ + public PromptTemplateConfig setOutputVariable(OutputVariable outputVariable) { this.outputVariable = outputVariable; + return this; } + /** + * Get the prompt execution settings of the prompt template config. + * @return The prompt execution settings of the prompt template config. + */ @Nullable public Map getExecutionSettings() { if (executionSettings != null) { @@ -235,10 +353,22 @@ public class PromptTemplateConfig { } - public void setExecutionSettings(Map executionSettings) { + /** + * Set the prompt execution settings of the prompt template config. + * @param executionSettings The prompt execution settings of the prompt template config. + * @return {@code this} prompt template config. + */ + public PromptTemplateConfig setExecutionSettings(Map executionSettings) { this.executionSettings = new HashMap<>(executionSettings); + return this; } + /** + * Deserialize the JSON string to a PromptTemplateConfig. + * @param json The JSON string to parse + * @return The PromptTemplateConfig object + * @throws SKException If the prompt template config cannot be deserialized. + */ public static PromptTemplateConfig parseFromJson(String json) throws SKException { try { return new ObjectMapper().readValue(json, PromptTemplateConfig.class); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactory.java index 8e190d5f89..c761346184 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactory.java @@ -2,16 +2,49 @@ package com.microsoft.semantickernel.semanticfunctions; import javax.annotation.Nullable; +/** + * The interface that a {@code PromptTemplateFactory} implementation must provide. + */ public interface PromptTemplateFactory { + /** + * Create a prompt template, if possible, from the given configuration. + * If the {@code PromptTemplateConfig} is not supported, the method should throw an + * {@code UnknownTemplateFormatException}. + * + * @param templateConfig The configuration for the prompt template. + * @return The prompt template. + * @throws UnknownTemplateFormatException If the template format is not supported. + * @see PromptTemplateConfig#getTemplateFormat() + */ PromptTemplate tryCreate(PromptTemplateConfig templateConfig); + /** + * Create a prompt template, if possible, from the given configuration. + * This is a convenience method that wraps the + * {@link KernelPromptTemplateFactory#tryCreate(PromptTemplateConfig)} + * method. + * + * @param templateConfig The configuration for the prompt template. + * @return The prompt template. + * @throws UnknownTemplateFormatException If the template format is not supported. + * @see PromptTemplateConfig#getTemplateFormat() + */ static PromptTemplate build(PromptTemplateConfig templateConfig) { return new KernelPromptTemplateFactory().tryCreate(templateConfig); } + /** + * Exception thrown when the template format is not supported. + * @see PromptTemplateConfig#getTemplateFormat() + */ class UnknownTemplateFormatException extends IllegalArgumentException { + /** + * Constructor. + * + * @param templateFormat The template format that is not supported. + */ public UnknownTemplateFormatException(@Nullable String templateFormat) { super("Unknown template format: " + templateFormat); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java index b83ec0b590..daed186763 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java @@ -19,7 +19,7 @@ public class AIServiceSelection { * Creates a new AI service selection. * * @param service The selected AI service. - * @param settings The settings associated with the selected service. This may be null even if a + * @param settings The settings associated with the selected service. This may be {@code null} even if a * service is selected.. */ public AIServiceSelection(T service, @Nullable PromptExecutionSettings settings) { @@ -39,7 +39,7 @@ public class AIServiceSelection { /** * Gets the settings associated with the selected service. * - * @return The settings associated with the selected service. This may be null even if a service + * @return The settings associated with the selected service. This may be {@code null} even if a service * is selected. */ @Nullable diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java index 158fd6e604..ae08beeab3 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java @@ -16,22 +16,21 @@ public interface AIServiceSelector { /** * Resolves an {@link AIService} and associated and - * {@link com.microsoft.semantickernel.orchestration.PromptExecutionSettings} from the specified - * {@link com.microsoft.semantickernel.Kernel} based on the associated {@link KernelFunction} - * and {@link KernelFunctionArguments}. + * {@link com.microsoft.semantickernel.orchestration.PromptExecutionSettings} based on the + * associated {@link KernelFunction} and {@link KernelFunctionArguments}. * * @param serviceType The type of service to select. This must be the same type with which the * service was registered in the {@link AIServiceSelection} - * @param function - * @param arguments - * @return + * @param function The KernelFunction to use to select the service, or {@code null}. + * @param arguments The KernelFunctionArguments to use to select the service, or {@code null}. + * @param The type of service to select. + * @return An {@code AIServiceSelection} containing the selected service and associated PromptExecutionSettings. */ @Nullable AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments ); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java index fb8cdee176..0374bfa7cd 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java @@ -5,16 +5,25 @@ import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; import java.util.Map; + import javax.annotation.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +/** + * Base class for {@link AIServiceSelector} implementations which provides a + * {@code Map} based collection from which an {@link AIService} can be selected. + * The {@link #trySelectAIService(Class, KernelFunction, KernelFunctionArguments)} + * method has been implemented. Child classes must implement the method + * {@link #trySelectAIService(Class, KernelFunction, KernelFunctionArguments, Map)}. + */ public abstract class BaseAIServiceSelector implements AIServiceSelector { - private static final Logger LOGGER = LoggerFactory.getLogger(BaseAIServiceSelector.class); - protected final Map, AIService> services; + /** + * Initializes a new instance of the {@link BaseAIServiceSelector} class. + * + * @param services The services to select from. + */ protected BaseAIServiceSelector(Map, AIService> services) { this.services = services; } @@ -25,20 +34,29 @@ public abstract class BaseAIServiceSelector implements AIServiceSelector { Class serviceType, @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments ) { return trySelectAIService(serviceType, function, arguments, services); } + /** + * Resolves an {@link AIService} from the {@code services} argument using + * the specified {@code function} and {@code arguments} for selection. + * + * @param serviceType The type of service to select. This must be the same type with which the + * service was registered in the {@link AIServiceSelection} + * @param function The KernelFunction to use to select the service, or {@code null}. + * @param arguments The KernelFunctionArguments to use to select the service, or {@code null}. + * @param services The services to select from. + * @param The type of service to select. + * @return + */ @Nullable - public abstract AIServiceSelection trySelectAIService( + protected abstract AIServiceSelection trySelectAIService( Class serviceType, - @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments, Map, AIService> services); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/NamedServiceProvider.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/NamedServiceProvider.java index 529e0949ab..9e50965b5f 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/NamedServiceProvider.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/NamedServiceProvider.java @@ -9,12 +9,12 @@ import javax.annotation.Nullable; */ public interface NamedServiceProvider { /** - * Gets the service of the specified type and name, or null if not found. + * Gets the service of the specified type and name, or {@code null} if not found. * - * @param name The name of the service, or null for the default service. + * @param name The name of the service, or {@code null} for the default service. * @param clazz The type of the service. * @param The specific type of the service - * @return The service instance, or null if not found. + * @return The service instance, or {@code null} if not found. */ @Nullable public U getService(@Nullable String name, Class clazz); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java index 0fd2e41767..eb2f13a1bc 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java @@ -1,5 +1,13 @@ package com.microsoft.semantickernel.services; +import com.microsoft.semantickernel.AIService; +import com.microsoft.semantickernel.Verify; +import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; +import com.microsoft.semantickernel.orchestration.KernelFunction; +import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; +import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import com.microsoft.semantickernel.textcompletion.TextGenerationService; + import java.util.HashMap; import java.util.List; import java.util.Map; @@ -11,22 +19,30 @@ import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.microsoft.semantickernel.AIService; -import com.microsoft.semantickernel.Verify; -import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; -import com.microsoft.semantickernel.orchestration.KernelFunction; -import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; -import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.textcompletion.TextGenerationService; - +/** + * Implementation of {@link com.microsoft.semantickernel.services.AIServiceSelector} that + * selects the AI service based on the order of the execution settings. + * Uses the service id or model id to select the preferred service provider and then + * returns the service and associated execution settings. + */ public class OrderedAIServiceSelector extends BaseAIServiceSelector { private static final Logger LOGGER = LoggerFactory.getLogger(OrderedAIServiceSelector.class); + /** + * Initializes a new instance of the {@link OrderedAIServiceSelector} + * class with an empty collection of services. + */ public OrderedAIServiceSelector() { super(new HashMap<>()); } + /** + * Initializes a new instance of the {@link OrderedAIServiceSelector} + * class with the specified services. + * + * @param services The services to select from. + */ public OrderedAIServiceSelector(Map, AIService> services) { super(services); } @@ -35,10 +51,8 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector { @Override public AIServiceSelection trySelectAIService( Class serviceType, - @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments, Map, AIService> services) { @@ -159,6 +173,13 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector { } + /** + * Gets the service with the specified service id. + * + * @param serviceId The service id. + * @return The service with the specified service id, or {@code null} if no such service exists. + * @see AIService#getServiceId() + */ @Nullable public AIService getService(String serviceId) { return services @@ -169,8 +190,16 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector { .orElseGet(() -> null); } + /** + * Gets the service of the specified type. + * + * @param clazz The type of service to get. + * @param The type of service to get. + * @return The service of the specified type, or {@code null} if no such service exists. + */ @Nullable - public T getService(Class clazz) { + @SuppressWarnings("unchecked") + public T getService(Class clazz) { T service = (T) services.get(clazz); if (service == null) { @@ -194,13 +223,19 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector { return service; } + /** + * Gets the first service of the specified type, or that is an instance of the specified type. + * + * @param serviceType The type of service to get. + * @return The first service of the specified type, or {@code null} if no such service exists. + */ @Nullable AIService getAnyService(Class serviceType) { - List services = getServices(serviceType); - if (services.isEmpty()) { + List matchingServices = getServices(serviceType); + if (matchingServices.isEmpty()) { return null; } - return services.get(0); + return matchingServices.get(0); } private List getServices(Class serviceType) { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/ServiceNotFoundException.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/ServiceNotFoundException.java new file mode 100644 index 0000000000..7046109dda --- /dev/null +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/ServiceNotFoundException.java @@ -0,0 +1,17 @@ +package com.microsoft.semantickernel.services; + +import com.microsoft.semantickernel.exceptions.SKCheckedException; + +/** + * Exception thrown when a service is not found. + */ +public class ServiceNotFoundException extends SKCheckedException { + + /** + * Initializes a new instance of the {@link ServiceNotFoundException} class. + * @param s A message which describes the service that could not be found. + */ + public ServiceNotFoundException(String s) { + super(s); + } +} diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java index e80877fe2d..74665845a2 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java @@ -31,10 +31,18 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import reactor.core.publisher.Mono; +/** + * A prompt template that uses the Handlebars template engine to render prompts. + */ public class HandlebarsPromptTemplate implements PromptTemplate { private final PromptTemplateConfig promptTemplate; + /** + * Initializes a new instance of the {@link HandlebarsPromptTemplate} class. + * + * @param promptTemplate The prompt template configuration. + */ public HandlebarsPromptTemplate( @Nonnull PromptTemplateConfig promptTemplate) { this.promptTemplate = new PromptTemplateConfig(promptTemplate); @@ -160,7 +168,7 @@ public class HandlebarsPromptTemplate implements PromptTemplate { } } - public static class HandleBarsPromptTemplateHandler { + private static class HandleBarsPromptTemplateHandler { private final String template; private final Handlebars handlebars; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizer.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizer.java index efcfccfb56..e98b61f3c9 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizer.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizer.java @@ -9,36 +9,37 @@ import com.microsoft.semantickernel.templateengine.semantickernel.blocks.NamedAr import com.microsoft.semantickernel.templateengine.semantickernel.blocks.Symbols; import com.microsoft.semantickernel.templateengine.semantickernel.blocks.ValBlock; import com.microsoft.semantickernel.templateengine.semantickernel.blocks.VarBlock; + import java.util.ArrayList; import java.util.Collections; import java.util.List; + import javax.annotation.Nullable; -/// -/// Simple tokenizer used for default SK template code language. -/// -/// BNF parsed by TemplateTokenizer: -/// [template] ::= "" | [block] | [block] [template] -/// [block] ::= [sk-block] | [text-block] -/// [sk-block] ::= "{{" [variable] "}}" | "{{" [value] "}}" | "{{" [function-call] "}}" -/// [text-block] ::= [any-char] | [any-char] [text-block] -/// [any-char] ::= any char -/// -/// BNF parsed by CodeTokenizer: -/// [template] ::= "" | [variable] " " [template] | [value] " " [template] | [function-call] " -// " [template] -/// [variable] ::= "$" [valid-name] -/// [value] ::= "'" [text] "'" | '"' [text] '"' -/// [function-call] ::= [function-id] | [function-id] [parameter] -/// [parameter] ::= [variable] | [value] -/// -/// BNF parsed by dedicated blocks -/// [function-id] ::= [valid-name] | [valid-name] "." [valid-name] -/// [valid-name] ::= [valid-symbol] | [valid-symbol] [valid-name] -/// [valid-symbol] ::= [letter] | [digit] | "_" -/// [letter] ::= "a" | "b" ... | "z" | "A" | "B" ... | "Z" -/// [digit] ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" -/// +/** + * Simple tokenizer used for default SK template code language. + * + * BNF parsed by TemplateTokenizer: + * [template] ::= "" | [block] | [block] [template] + * [block] ::= [sk-block] | [text-block] + * [sk-block] ::= "{{" [variable] "}}" | "{{" [value] "}}" | "{{" [function-call] "}}" + * [text-block] ::= [any-char] | [any-char] [text-block] + * [any-char] ::= any char + * + * BNF parsed by CodeTokenizer: + * [template] ::= "" | [variable] " " [template] | [value] " " [template] | [function-call] " + * [variable] ::= "$" [valid-name] + * [value] ::= "'" [text] "'" | '"' [text] '"' + * [function-call] ::= [function-id] | [function-id] [parameter] + * [parameter] ::= [variable] | [value] + * + * BNF parsed by dedicated blocks + * [function-id] ::= [valid-name] | [valid-name] "." [valid-name] + * [valid-name] ::= [valid-symbol] | [valid-symbol] [valid-name] + * [valid-symbol] ::= [letter] | [digit] | "_" + * [letter] ::= "a" | "b" ... | "z" | "A" | "B" ... | "Z" + * [digit] ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + */ public class CodeTokenizer { private enum TokenTypes { @@ -52,14 +53,17 @@ public class CodeTokenizer { } } + /** + * Initializes a new instance of the {@link CodeTokenizer} class. + */ public CodeTokenizer() { } - /// - /// Tokenize a code block, without checking for syntax errors - /// - /// Text to parse - /// A list of blocks + /** + * Tokenize a code block, without checking for syntax errors + * @param text Text to parse + * @return A list of blocks + */ public List tokenize(String text) { if (text == null) { return new ArrayList<>(); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/DefaultPromptTemplate.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/DefaultPromptTemplate.java index 907a0110db..d92ef82a36 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/DefaultPromptTemplate.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/DefaultPromptTemplate.java @@ -15,32 +15,39 @@ import com.microsoft.semantickernel.templateengine.semantickernel.blocks.CodeRen import com.microsoft.semantickernel.templateengine.semantickernel.blocks.NamedArgBlock; import com.microsoft.semantickernel.templateengine.semantickernel.blocks.TextRendering; import com.microsoft.semantickernel.templateengine.semantickernel.blocks.VarBlock; + import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; + import javax.annotation.Nonnull; import javax.annotation.Nullable; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -/// -/// Prompt template. -/// +/** + * The default prompt template. + */ public class DefaultPromptTemplate implements PromptTemplate { private final PromptTemplateConfig promptTemplate; + /** + * Create a new prompt template. + * @param promptTemplateConfig The prompt template configuration. + */ public DefaultPromptTemplate( - @Nonnull PromptTemplateConfig promptTemplate) { - this.promptTemplate = new PromptTemplateConfig(promptTemplate); + @Nonnull PromptTemplateConfig promptTemplateConfig) { + this.promptTemplate = new PromptTemplateConfig(promptTemplateConfig); } - /// - /// Given a prompt template string, extract all the blocks (text, variables, function calls) - /// - /// A list of all the blocks, ie the template tokenized in text, variables and function calls + /* + * Given a prompt template string, extract all the blocks (text, variables, function calls) + * @return A list of all the blocks, ie the template tokenized in text, variables and function calls + */ private List extractBlocks() { String templateText = promptTemplate.getTemplate(); @@ -60,10 +67,11 @@ public class DefaultPromptTemplate implements PromptTemplate { } - /// - /// Augments 's with any variables - /// not already contained there but that are referenced in the prompt template. - /// + /** + * Augments the prompt template with any variables + * not already contained there but that are referenced in the prompt template. + * @param blocks The blocks to search for input variables. + */ @SuppressWarnings("NullAway") private void addMissingInputVariables(List blocks) { // Add all of the existing input variables to our known set. We'll avoid adding any diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateException.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateException.java index 33a29440c5..96e54a2937 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateException.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateException.java @@ -2,9 +2,13 @@ package com.microsoft.semantickernel.templateengine.semantickernel; import com.microsoft.semantickernel.exceptions.SKException; + import javax.annotation.Nonnull; import javax.annotation.Nullable; +/** + * Exception thrown when a template error occurs. + */ public class TemplateException extends SKException { @Nonnull @@ -50,9 +54,8 @@ public class TemplateException extends SKException { // spotless:off /** - *

* Gets the error code for this exception. - *

+ * @return The error code. */ //spotless:on public ErrorCodes getErrorCode() { @@ -62,53 +65,41 @@ public class TemplateException extends SKException { // spotless:off /** - *

* Error codes for {@code TemplateException}. - *

*/ //spotless:on public enum ErrorCodes { // spotless:off /** - *

* Unknown error. - *

*/ //spotless:on UNKNOWN_ERROR("Unknown error"), // spotless:off /** - *

* Syntax error, the template syntax used is not valid. - *

*/ //spotless:on SYNTAX_ERROR("Syntax error, the template syntax used is not valid"), // spotless:off /** - *

* The block type produced be the tokenizer was not expected. - *

*/ UNEXPECTED_BLOCK_TYPE("The block type produced be the tokenizer was not expected"), //spotless:off /** - *

* The template requires an unknown function. - *

*/ //spotless:on FUNCTION_NOT_FOUND("The template requires an unknown function"), // spotless:off /** - *

* The template execution failed, e.g. a function call threw an exception. - *

*/ //spotless:on RUNTIME_ERROR("The template execution failed, e.g. a function call threw an exception"); @@ -119,6 +110,12 @@ public class TemplateException extends SKException { this.message = message; } + // spotless:off + /** + * Gets the message for the error code. + * @return The error code message + */ + //spotless:on public String getMessage() { return message; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateTokenizer.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateTokenizer.java index 10baf9606f..9963b5b52e 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateTokenizer.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateTokenizer.java @@ -9,48 +9,38 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -/// -/// Simple tokenizer used for default SK template language. -/// -/// BNF parsed by TemplateTokenizer: -/// [template] ::= "" | [block] | [block] [template] -/// [block] ::= [sk-block] | [text-block] -/// [sk-block] ::= "{{" [variable] "}}" | "{{" [value] "}}" | "{{" [function-call] "}}" -/// [text-block] ::= [any-char] | [any-char] [text-block] -/// [any-char] ::= any char -/// -/// BNF parsed by CodeTokenizer: -/// [template] ::= "" | [variable] " " [template] | [value] " " [template] | [function-call] " -// " [template] -/// [variable] ::= "$" [valid-name] -/// [value] ::= "'" [text] "'" | '"' [text] '"' -/// [function-call] ::= [function-id] | [function-id] [parameter] -/// [parameter] ::= [variable] | [value] -/// -/// BNF parsed by dedicated blocks -/// [function-id] ::= [valid-name] | [valid-name] "." [valid-name] -/// [valid-name] ::= [valid-symbol] | [valid-symbol] [valid-name] -/// [valid-symbol] ::= [letter] | [digit] | "_" -/// [letter] ::= "a" | "b" ... | "z" | "A" | "B" ... | "Z" -/// [digit] ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" -/// +/** + * Simple tokenizer used for default SK template language. + * + * BNF parsed by TemplateTokenizer: + * [template] ::= "" | [block] | [block] [template] + * [block] ::= [sk-block] | [text-block] + * [sk-block] ::= "{{" [variable] "}}" | "{{" [value] "}}" | "{{" [function-call] "}}" + * [text-block] ::= [any-char] | [any-char] [text-block] + * [any-char] ::= any char + * + * BNF parsed by CodeTokenizer: + * [template] ::= "" | [variable] " " [template] | [value] " " [template] | [function-call] " + * + * [variable] ::= "$" [valid-name] + * [value] ::= "'" [text] "'" | '"' [text] '"' + * [function-call] ::= [function-id] | [function-id] [parameter] + * [parameter] ::= [variable] | [value] + * + * BNF parsed by dedicated blocks + * [function-id] ::= [valid-name] | [valid-name] "." [valid-name] + * [valid-name] ::= [valid-symbol] | [valid-symbol] [valid-name] + * [valid-symbol] ::= [letter] | [digit] | "_" + * [letter] ::= "a" | "b" ... | "z" | "A" | "B" ... | "Z" + * [digit] ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + */ public class TemplateTokenizer { - /* - /// - /// Create a new instance of SK tokenizer - /// - /// - public TemplateTokenizer(ILogger? log = null) - { - this._log = log ?? NullLogger.Instance; - this._codeTokenizer = new CodeTokenizer(this._log); - } - */ - /// - /// Extract blocks from the given text - /// - /// Text to parse - /// List of blocks found in the text + + /** + * Extract blocks from the given text + * @param text Text to parse + * @return List of blocks found in the text + */ public List tokenize(String text) { // An empty block consists of 4 chars: "{{}}" int EMPTY_CODE_BLOCK_LENGTH = 4; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/BlockTypes.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/BlockTypes.java index 0257bf6d62..5730c588fa 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/BlockTypes.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/BlockTypes.java @@ -1,6 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +/** + * Block types + */ public enum BlockTypes { /** * Undefined block type @@ -26,6 +29,9 @@ public enum BlockTypes { * Function block type */ FunctionId(5), + /** + * Named argument block type + */ NamedArg(6); BlockTypes(int i) { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeBlock.java index 95adf627c7..6c4a2070b8 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeBlock.java @@ -24,11 +24,20 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; +/** + * Represents a code block. + */ public final class CodeBlock extends Block implements CodeRendering { private static final Logger LOGGER = LoggerFactory.getLogger(CodeBlock.class); private final List tokens; + /** + * Initializes a new instance of the {@link CodeBlock} class. + * + * @param tokens The tokens. + * @param content The content. + */ public CodeBlock(List tokens, String content) { super(content, BlockTypes.Code); this.tokens = Collections.unmodifiableList(tokens); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeRendering.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeRendering.java index 28f5994125..9a52f3c236 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeRendering.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeRendering.java @@ -4,7 +4,9 @@ package com.microsoft.semantickernel.templateengine.semantickernel.blocks; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; + import javax.annotation.Nullable; + import reactor.core.publisher.Mono; /** @@ -17,7 +19,10 @@ public interface CodeRendering { * * @param kernel Kernel to use for rendering * @param arguments Optional arguments used to render the block + * @param context Optional context used to render the block, + * typically used to pass {code KernelHooks} to the render method. * @return Rendered content + * @see com.microsoft.semantickernel.hooks.KernelHooks */ Mono renderCodeAsync( Kernel kernel, diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/FunctionIdBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/FunctionIdBlock.java index d58d8bf30e..910c90058b 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/FunctionIdBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/FunctionIdBlock.java @@ -1,15 +1,23 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.templateengine.semantickernel.blocks; -import javax.annotation.Nullable; - import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; +import javax.annotation.Nullable; + +/** + * Represents a function identifier block. + */ public final class FunctionIdBlock extends Block implements TextRendering { private final String skillName; private final String functionName; + /** + * Initializes a new instance of the {@link FunctionIdBlock} class. + * + * @param content The content. + */ public FunctionIdBlock(String content) { super(content, BlockTypes.FunctionId); @@ -61,10 +69,20 @@ public final class FunctionIdBlock extends Block implements TextRendering { return value.matches("^.*\\..*\\..*$"); } + /** + * Get the plugin name. + * + * @return The plugin name. + */ public String getPluginName() { return skillName; } + /** + * Get the function name. + * + * @return The function name. + */ public String getFunctionName() { return functionName; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextRendering.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextRendering.java index ee71edc074..1bfce58155 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextRendering.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextRendering.java @@ -1,19 +1,20 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.templateengine.semantickernel.blocks; -import javax.annotation.Nullable; - import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; -/// -/// Interface of static blocks that don't need async IO to be rendered. -/// +import javax.annotation.Nullable; + +/** + * Interface of static blocks that don't need async IO to be rendered. + */ public interface TextRendering { - /// - /// Render the block using only the given variables. - /// - /// Optional variables used to render the block - /// Rendered content + + /** + * Render the block using only the given variables. + * @param variables Optional variables used to render the block + * @return Rendered content + */ @Nullable String render(@Nullable KernelFunctionArguments variables); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java index cd67402c6c..baf123f9c4 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java @@ -2,10 +2,24 @@ package com.microsoft.semantickernel.textcompletion; import com.microsoft.semantickernel.StreamingKernelContent; +/** + * StreamingTextContent is a wrapper for TextContent that allows for streaming. + */ public class StreamingTextContent extends StreamingKernelContent { + /** + * Initializes a new instance of the {@code StreamingTextContent} class with a provided text content. + * + * @param content The text content. + */ public StreamingTextContent(TextContent content) { super(content, 0, null, null); } + + @Override + public String getContent() { + return ((TextContent)getInnerContent()).getContent(); + } + } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java index 6867094bb8..b07f1c7159 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java @@ -3,10 +3,20 @@ package com.microsoft.semantickernel.textcompletion; import com.microsoft.semantickernel.KernelContent; import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; +/** + * Content from a text completion service. + */ public class TextContent extends KernelContent { private final String content; + /** + * Initializes a new instance of the {@code TextContent} class with a provided content, model ID, and metadata. + * + * @param content The content. + * @param modelId The model ID. + * @param metadata The metadata. + */ public TextContent( String content, String modelId, @@ -15,6 +25,10 @@ public class TextContent extends KernelContent { this.content = content; } + /** + * Gets the content. + * @return The content. + */ public String getValue() { return content; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java index 5adb97ba6d..cdacc65459 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java @@ -8,8 +8,11 @@ import com.microsoft.semantickernel.builders.Buildable; import com.microsoft.semantickernel.builders.SemanticKernelBuilder; import com.microsoft.semantickernel.builders.ServiceLoadUtil; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; + import java.util.List; + import javax.annotation.Nullable; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -23,6 +26,8 @@ public interface TextGenerationService extends Buildable, TextAIService { * * @param prompt The prompt to complete. * @param executionSettings Request settings for the completion API + * @param kernel The {@code Kernel} containing services, plugins, and other state for + * use throughout the operation. * @return Text generated by the remote model */ Mono> getTextContentsAsync( @@ -36,8 +41,8 @@ public interface TextGenerationService extends Buildable, TextAIService { * * @param prompt The prompt to complete. * @param executionSettings The AI execution settings (optional). - * @param kernel The containing services, plugins, and other - * state for use throughout the operation. + * @param kernel The {@code Kernel} containing services, plugins, and other state for + * use throughout the operation. * @return Streaming list of different completion streaming string updates generated by the * remote model */ @@ -46,6 +51,10 @@ public interface TextGenerationService extends Buildable, TextAIService { @Nullable PromptExecutionSettings executionSettings, @Nullable Kernel kernel); + /** + * Get the builder for the TextGenerationService + * @return The builder + */ static Builder builder() { return ServiceLoadUtil.findServiceLoader(Builder.class, "com.microsoft.semantickernel.aiservices.openai.textcompletion.OpenAITextGenerationService$Builder") @@ -65,16 +74,34 @@ public interface TextGenerationService extends Buildable, TextAIService { @Nullable protected String serviceId; + /** + * Sets the model ID for the service + * + * @param modelId The model ID + * @return The builder + */ public Builder withModelId(String modelId) { this.modelId = modelId; return this; } + /** + * Sets the OpenAI client for the service + * + * @param client The OpenAI client + * @return The builder + */ public Builder withOpenAIAsyncClient(OpenAIAsyncClient client) { this.client = client; return this; } + /** + * Sets the service ID for the service + * + * @param serviceId The service ID + * @return The builder + */ public Builder withServiceId(String serviceId) { this.serviceId = serviceId; return this; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/util/EmbeddedResourceLoader.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/util/EmbeddedResourceLoader.java index b54b80df29..69e34d6cd2 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/util/EmbeddedResourceLoader.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/util/EmbeddedResourceLoader.java @@ -14,11 +14,26 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; +/** + * Utility class for loading resources from the classpath or filesystem. + */ public class EmbeddedResourceLoader { + /** + * Enum for specifying the location of the resource + */ public enum ResourceLocation { + /** + * Load from the classpath + */ CLASSPATH, + /** + * Load from the filesystem + */ FILESYSTEM, + /** + * Load from the classpath root + */ CLASSPATH_ROOT } @@ -26,6 +41,7 @@ public class EmbeddedResourceLoader { * Loads a file to a string from the classpath using getResourceAsStream * * @param fileName Filename to read + * @param clazz Class to use for classpath loading * @return File content * @throws FileNotFoundException Error in case the file doesn't exist */ @@ -37,6 +53,8 @@ public class EmbeddedResourceLoader { * Loads a file to a string from the classpath, classpath root or filesystem * * @param fileName Filename to read + * @param clazz Class to use for classpath loading + * @param locations Locations to search for the file * @return File content * @throws FileNotFoundException Error in case the file doesn't exist */ From 14142051dd1d896700ba367d4993c8621cd136ff Mon Sep 17 00:00:00 2001 From: John Oliver <1615532+johnoliver@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:32:22 +0000 Subject: [PATCH 2/3] Make KernelFunctionFactory calls fluent. Fix some hook related bugs --- ...xample05_InlineFunctionDefinitionTest.java | 22 ++- .../plugins/ConversationSummaryPlugin.java | 41 +++-- .../Example05_InlineFunctionDefinition.java | 22 ++- .../Example06_TemplateLanguage.java | 19 +-- ...mple10_DescribeAllPluginsAndFunctions.java | 6 +- ...Example27_PromptFunctionsUsingChatGPT.java | 3 +- .../Example30_ChatWithPrompts.java | 2 +- ...eMethodFunctionsWithMultipleArguments.java | 2 +- .../syntaxexamples/Example57_KernelHooks.java | 1 + .../Example58_ConfigureExecutionSettings.java | 10 +- .../Example60_AdvancedMethodFunctions.java | 2 +- .../Example69_MutableKernelPlugin.java | 4 +- .../com/microsoft/semantickernel/Kernel.java | 7 +- .../KernelPluginCollection.java | 6 +- .../semantickernel/hooks/KernelHooks.java | 44 ++++-- .../orchestration/KernelFunction.java | 30 ++-- .../plugin/KernelFunctionFactory.java | 148 ++++-------------- .../plugin/KernelPluginFactory.java | 15 +- .../KernelFunctionFromMethod.java | 104 +++++++++--- .../KernelFunctionFromPrompt.java | 88 ++++++----- .../handlebars/HandlebarsPromptTemplate.java | 3 +- 21 files changed, 303 insertions(+), 276 deletions(-) diff --git a/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java b/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java index 5d4aedfdf7..e6237258aa 100644 --- a/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java +++ b/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java @@ -89,19 +89,15 @@ public class Example05_InlineFunctionDefinitionTest { WireMockUtil.mockCompletionResponse("Translate this date ", "a-response-3"); - var fixedFunction = KernelFunctionFactory.createFromPrompt( - "Translate this date " + DateTimeFormatter - .ISO_LOCAL_DATE - .withZone(ZoneOffset.UTC) - .format(Instant.now()) - + " to French format", - new PromptExecutionSettings.Builder() - .withMaxTokens(100) - .build(), - null, - null, - null, - null); + var date = DateTimeFormatter.ISO_LOCAL_DATE.withZone(ZoneOffset.UTC) + .format(Instant.ofEpochSecond(1)); + var message = "Translate this date " + date + " to French format"; + var fixedFunction = KernelFunctionFactory.createFromPrompt(message) + .withDefaultExecutionSettings( + PromptExecutionSettings.builder() + .withMaxTokens(100) + .build()) + .build(); FunctionResult fixedFunctionResult = kernel .invokeAsync(fixedFunction) diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java index c95c28481f..54af4e9d2b 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java @@ -37,29 +37,28 @@ public class ConversationSummaryPlugin { .withTopP(0.5) .build(); - this.summarizeConversationFunction = KernelFunctionFactory.createFromPrompt( - PromptFunctionConstants.SummarizeConversationDefinition, - settings, - "summarizeConversation", - "Given a section of a conversation transcript, summarize the part of the conversation.", - null, - null); + this.summarizeConversationFunction = KernelFunctionFactory + .createFromPrompt(PromptFunctionConstants.SummarizeConversationDefinition) + .withDefaultExecutionSettings(settings) + .withName("summarizeConversation") + .withDescription( + "Given a section of a conversation transcript, summarize the part of the conversation.") + .build(); - this.conversationActionItemsFunction = KernelFunctionFactory.createFromPrompt( - PromptFunctionConstants.GetConversationActionItemsDefinition, - settings, - "conversationActionItems", - "Given a section of a conversation transcript, identify action items.", - null, - null); + this.conversationActionItemsFunction = KernelFunctionFactory + .createFromPrompt(PromptFunctionConstants.GetConversationActionItemsDefinition) + .withDefaultExecutionSettings(settings) + .withName("conversationActionItems") + .withDescription("Given a section of a conversation transcript, identify action items.") + .build(); - this.conversationTopicsFunction = KernelFunctionFactory.createFromPrompt( - PromptFunctionConstants.GetConversationTopicsDefinition, - settings, - "conversationTopics", - "Analyze a conversation transcript and extract key topics worth remembering.", - null, - null); + this.conversationTopicsFunction = KernelFunctionFactory + .createFromPrompt(PromptFunctionConstants.GetConversationTopicsDefinition) + .withDefaultExecutionSettings(settings) + .withName("conversationTopics") + .withDescription( + "Analyze a conversation transcript and extract key topics worth remembering.") + .build(); } /// diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java index b0869fd01c..637a3867d7 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java @@ -96,19 +96,15 @@ public class Example05_InlineFunctionDefinition { .block(); System.out.println(result.getResult()); - var fixedFunction = KernelFunctionFactory.createFromPrompt( - "Translate this date " + DateTimeFormatter - .ISO_LOCAL_DATE - .withZone(ZoneOffset.UTC) - .format(Instant.ofEpochSecond(1)) - + " to French format", - PromptExecutionSettings.builder() - .withMaxTokens(100) - .build(), - null, - null, - null, - null); + var date = DateTimeFormatter.ISO_LOCAL_DATE.withZone(ZoneOffset.UTC) + .format(Instant.ofEpochSecond(1)); + var message = "Translate this date " + date + " to French format"; + var fixedFunction = KernelFunctionFactory.createFromPrompt(message) + .withDefaultExecutionSettings( + PromptExecutionSettings.builder() + .withMaxTokens(100) + .build()) + .build(); FunctionResult fixedFunctionResult = kernel .invokeAsync(fixedFunction) diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java index 89122c17c1..3d60a77cf4 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java @@ -7,7 +7,7 @@ import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.aiservices.openai.textcompletion.OpenAITextGenerationService; import com.microsoft.semantickernel.exceptions.ConfigurationException; -import com.microsoft.semantickernel.orchestration.PromptExecutionSettings.Builder; +import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.plugin.KernelFunctionFactory; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; @@ -70,7 +70,7 @@ public class Example06_TemplateLanguage { KernelPlugin time = KernelPluginFactory.createFromObject( new Time(), "time"); - kernel.getPlugins().add(time); + kernel.addPlugin(time); // Prompt Function invoking time.Date and time.Time method functions String functionDefinition = """ @@ -91,16 +91,13 @@ public class Example06_TemplateLanguage { var renderedPrompt = promptTemplate.renderAsync(kernel, null, null).block(); System.out.println(renderedPrompt); - var kindOfDay = KernelFunctionFactory - .createFromPrompt( - functionDefinition, - new Builder() + var kindOfDay = KernelFunctionFactory.createFromPrompt(functionDefinition) + .withDefaultExecutionSettings( + PromptExecutionSettings.builder() .withMaxTokens(100) - .build(), - null, - null, - "semantic-kernel", - null); + .build()) + .withTemplateFormat(PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT) + .build(); // Show the result System.out.println("--- Prompt Function result"); diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example10_DescribeAllPluginsAndFunctions.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example10_DescribeAllPluginsAndFunctions.java index 58319ee52c..8205b25fd2 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example10_DescribeAllPluginsAndFunctions.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example10_DescribeAllPluginsAndFunctions.java @@ -99,18 +99,18 @@ public class Example10_DescribeAllPluginsAndFunctions { .withAIService(TextGenerationService.class, textGenerationService) .build(); - kernel.getPlugins().add( + kernel.addPlugin( KernelPluginFactory.createFromObject( new StaticTextPlugin(), "StaticTextPlugin") ); // Import another native plugin - kernel.getPlugins().add( + kernel.addPlugin( KernelPluginFactory.createFromObject( new TextPlugin(), "AnotherTextPlugin") ); - kernel.getPlugins().add( + kernel.addPlugin( KernelPluginFactory .importPluginFromDirectory( Path.of(PLUGIN_DIR, "java/samples/sample-code/src/main/resources/Plugins"), diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java index a422d492da..37534bc2d3 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java @@ -48,7 +48,8 @@ public class Example27_PromptFunctionsUsingChatGPT { .build(); var func = KernelFunctionFactory.createFromPrompt( - "List the two planets closest to '{{$input}}', excluding moons, using bullet points."); + "List the two planets closest to '{{$input}}', excluding moons, using bullet points.") + .build(); var result = func.invokeAsync(kernel) .withArguments( diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java index b752ce8fa5..c2f46d4445 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java @@ -75,7 +75,7 @@ public class Example30_ChatWithPrompts { // We could also use a variable, this is just to show that the prompt can invoke functions. KernelPlugin timePlugin = KernelPluginFactory.createFromObject( new TimePlugin(), "time"); - kernel.getPlugins().add(timePlugin); + kernel.addPlugin(timePlugin); // Adding required arguments referenced by the prompt templates. diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example56_TemplateMethodFunctionsWithMultipleArguments.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example56_TemplateMethodFunctionsWithMultipleArguments.java index 3e5589703c..59c3881bc6 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example56_TemplateMethodFunctionsWithMultipleArguments.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example56_TemplateMethodFunctionsWithMultipleArguments.java @@ -58,7 +58,7 @@ public class Example56_TemplateMethodFunctionsWithMultipleArguments { // Load native plugin into the kernel function collection, sharing its functions with prompt templates // Functions loaded here are available as "text.*" - kernel.getPlugins().add(KernelPluginFactory.createFromObject(new TextPlugin(), "text")); + kernel.addPlugin(KernelPluginFactory.createFromObject(new TextPlugin(), "text")); // Prompt Function invoking text.Concat method function with named arguments input and input2 where input is a string and input2 is set to a variable from context called word2. String functionDefinition = "Write a haiku about the following: {{text.Concat input='Harry' input2=$word2}}"; diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java index 3800e4e1cd..619e365d35 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java @@ -165,6 +165,7 @@ public class Example57_KernelHooks { PromptRenderingHook myRenderingHandler = event -> { System.out.println( event.getFunction().getName() + " : Prompt Rendering Handler - Triggered"); + event.getArguments().put("style", ContextVariable.of("Seinfeld")); return event; }; diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java index d3444457dc..696cb2f1a2 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java @@ -12,6 +12,7 @@ import com.microsoft.semantickernel.plugin.KernelFunctionFactory; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; +import com.microsoft.semantickernel.templateengine.semantickernel.DefaultPromptTemplate; public class Example58_ConfigureExecutionSettings { @@ -87,10 +88,13 @@ public class Example58_ConfigureExecutionSettings { } }""".stripIndent(); - var promptConfig = PromptTemplateConfig.parseFromJson(configPayload); - promptConfig.setTemplate(prompt); + var promptConfig = PromptTemplateConfig + .parseFromJson(configPayload) + .setTemplate(prompt); - var func = KernelFunctionFactory.createFromPrompt(promptConfig, null); + var func = KernelFunctionFactory + .createFromPrompt(promptConfig) + .build(); result = kernel.invokeAsync(func).block(); System.out.println(result.getResult()); diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example60_AdvancedMethodFunctions.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example60_AdvancedMethodFunctions.java index 3c1709716c..3e81818fb2 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example60_AdvancedMethodFunctions.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example60_AdvancedMethodFunctions.java @@ -21,7 +21,7 @@ public class Example60_AdvancedMethodFunctions { new FunctionsChainingPlugin(), FunctionsChainingPlugin.PluginName); - kernel.getPlugins().add(functions); + kernel.addPlugin(functions); ContextVariableTypeConverter type = new ContextVariableTypeConverter<>( MyCustomType.class, diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java index 186c10daf9..d18358389a 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java @@ -26,7 +26,9 @@ public class Example69_MutableKernelPlugin { KernelPlugin plugin = new KernelPlugin("Plugin", "Mutable plugin", null); plugin.addFunction(KernelFunctionFactory.createFromMethod( - Time.class.getMethod("date"), new Time(), "dateFunction", null, null, null)); + Time.class.getMethod("date"), new Time()) + .withFunctionName("dateFunction") + .build()); Kernel kernel = Kernel.builder().build(); kernel.addPlugin(plugin); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java index 403187abdc..ad8237fa92 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java @@ -13,6 +13,8 @@ import com.microsoft.semantickernel.services.OrderedAIServiceSelector; import com.microsoft.semantickernel.services.ServiceNotFoundException; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -109,9 +111,8 @@ public class Kernel implements Buildable { * @return The plugins available through the kernel. * @see Kernel#getPlugins() */ - @SuppressFBWarnings("EI_EXPOSE_REP") - public List getPlugins() { - return plugins.getPlugins(); + public Collection getPlugins() { + return Collections.unmodifiableCollection(plugins.getPlugins()); } /** diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java index 76c92cc32b..b45dc96864 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelPluginCollection.java @@ -6,6 +6,8 @@ import com.microsoft.semantickernel.orchestration.contextvariables.CaseInsensiti import com.microsoft.semantickernel.plugin.KernelPlugin; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -83,8 +85,8 @@ class KernelPluginCollection { * Gets all plugins that were added to the kernel. * @return The plugins available through the kernel. */ - List getPlugins() { - return new ArrayList<>(plugins.values()); + Collection getPlugins() { + return Collections.unmodifiableCollection(plugins.values()); } /** diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java index 2cd0111a8b..2d30e3312e 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/KernelHooks.java @@ -5,7 +5,6 @@ import com.microsoft.semantickernel.hooks.KernelHook.FunctionInvokingHook; import com.microsoft.semantickernel.hooks.KernelHook.PreChatCompletionHook; import com.microsoft.semantickernel.hooks.KernelHook.PromptRenderedHook; import com.microsoft.semantickernel.hooks.KernelHook.PromptRenderingHook; - import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -14,7 +13,6 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.UUID; import java.util.function.Function; - import javax.annotation.Nullable; /** @@ -33,6 +31,7 @@ public class KernelHooks { /** * Creates a copy of the {@link KernelHooks}. + * * @param kernelHooks the hooks to copy */ public KernelHooks(@Nullable KernelHooks kernelHooks) { @@ -43,8 +42,8 @@ public class KernelHooks { } /** - * Creates a new instance of the {@link KernelHooks} class - * from the given hooks. + * Creates a new instance of the {@link KernelHooks} class from the given hooks. + * * @param hooks the hooks to add */ public KernelHooks(Map> hooks) { @@ -54,15 +53,17 @@ public class KernelHooks { /** * Creates an unmodifiable copy of this {@link KernelHooks}. + * * @return an unmodifiable copy of this {@link KernelHooks} */ public UnmodifiableKernelHooks unmodifiableClone() { return new UnmodifiableKernelHooks(this); } - + /** * Gets the hooks in this collection. + * * @return an unmodifiable map of the hooks */ private Map> getHooks() { @@ -71,6 +72,7 @@ public class KernelHooks { /** * Add a {@link FunctionInvokingHook} to the collection of hooks. + * * @param function the function to add * @return the key of the hook in the collection */ @@ -81,6 +83,7 @@ public class KernelHooks { /** * Add a {@link FunctionInvokedHook} to the collection of hooks. + * * @param function the function to add * @return the key of the hook in the collection */ @@ -91,6 +94,7 @@ public class KernelHooks { /** * Add a {@link PreChatCompletionHook} to the collection of hooks. + * * @param function the function to add * @return the key of the hook in the collection */ @@ -101,6 +105,7 @@ public class KernelHooks { /** * Add a {@link PromptRenderedHook} to the collection of hooks. + * * @param function the function to add * @return the key of the hook in the collection */ @@ -111,6 +116,7 @@ public class KernelHooks { /** * Add a {@link PromptRenderingHook} to the collection of hooks. + * * @param function the function to add * @return the key of the hook in the collection */ @@ -121,27 +127,33 @@ public class KernelHooks { /** * Executes the hooks in this collection that accept the event. + * * @param event the event to execute the hooks on - * @param the type of the event + * @param the type of the event * @return the event after the hooks have been executed */ @SuppressWarnings("unchecked") public T executeHooks(T event) { - SortedSet> hooks = new TreeSet<>(Comparator.comparingInt(KernelHook::getPriority)); + SortedSet> hooks = new TreeSet<>( + Comparator.comparingInt(KernelHook::getPriority)); hooks.addAll(this.hooks.values()); - for (KernelHook hook : hooks) { - if (hook.test(event)) { + return this.hooks.values() + .stream() + .filter(hook -> hook.test(event)) + .sorted(Comparator.comparingInt(KernelHook::getPriority)) + .reduce(event, (event2, hook) -> { // unchecked cast - event = ((KernelHook) hook).apply(event); - } - } - return event; + return ((KernelHook) hook).apply(event2); + }, (a, b) -> { + throw new UnsupportedOperationException("No merging for hooks"); + }); } /** * Add a {@link KernelHook} to the collection of hooks. + * * @param hook the hook to add * @return the key of the hook in the collection */ @@ -151,8 +163,9 @@ public class KernelHooks { /** * Add a {@link KernelHook} to the collection of hooks. + * * @param hookName the key of the hook in the collection - * @param hook the hook to add + * @param hook the hook to add * @return the key of the hook in the collection */ public String addHook(String hookName, KernelHook hook) { @@ -162,6 +175,7 @@ public class KernelHooks { /** * Remove a hook from the collection of hooks. + * * @param hookName the key of the hook in the collection * @return the removed hook, or {@code null} if the hook was not found */ @@ -171,6 +185,7 @@ public class KernelHooks { /** * Appends the given hooks to this collection. + * * @param kernelHooks the hooks to append * @return this instance of the {@link KernelHooks} class */ @@ -185,6 +200,7 @@ public class KernelHooks { /** * Determines if this collection of hooks is empty. + * * @return {@code true} if the collection is empty, otherwise {@code false} */ public boolean isEmpty() { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java index 6e0ddac217..31b6b273b1 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java @@ -12,19 +12,16 @@ import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; - import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.annotation.Nullable; - import reactor.core.publisher.Mono; /** - * Semantic Kernel callable function interface. The Semantic Kernel creates - * {@code KernelFunction}s from prompts, templates, or plugin methods. + * Semantic Kernel callable function interface. The Semantic Kernel creates {@code KernelFunction}s + * from prompts, templates, or plugin methods. * * @param The type of the result of the function * @see com.microsoft.semantickernel.semanticfunctions @@ -100,6 +97,7 @@ public abstract class KernelFunction implements Buildable { /** * Get an unmodifiable map of the execution settings for the function. + * * @return An unmodifiable map of the execution settings for the function */ public Map getExecutionSettings() { @@ -108,6 +106,7 @@ public abstract class KernelFunction implements Buildable { /** * Get the metadata for the function. + * * @return The metadata for the function */ public KernelFunctionMetadata getMetadata() { @@ -149,8 +148,9 @@ public abstract class KernelFunction implements Buildable { /** * Invokes this KernelFunction. - * @param kernel The Kernel containing services, plugins, and other state for use - * throughout the operation. + * + * @param kernel The Kernel containing services, plugins, and other state for use throughout the + * operation. * @return The result of the function's execution. */ public FunctionInvocation invokeAsync(Kernel kernel) { @@ -184,6 +184,7 @@ public abstract class KernelFunction implements Buildable { /** * Set the prompt template for the function. + * * @param promptTemplate The prompt template for the function * @return The builder */ @@ -192,6 +193,7 @@ public abstract class KernelFunction implements Buildable { /** * Set the execution settings for the function. + * * @param executionSettings The execution settings for the function * @return The builder */ @@ -201,7 +203,7 @@ public abstract class KernelFunction implements Buildable { /** * Set the default execution settings for the function. - * + * * @param executionSettings The default execution settings for the function * @return The builder */ @@ -211,7 +213,7 @@ public abstract class KernelFunction implements Buildable { /** * Set the description of the function. - * + * * @param description The description of the function * @return The builder */ @@ -219,7 +221,7 @@ public abstract class KernelFunction implements Buildable { /** * Set the template for the function. - * + * * @param template The template for the function * @return The builder */ @@ -227,12 +229,14 @@ public abstract class KernelFunction implements Buildable { /** * Create a new KernelFunction instance from the builder. + * * @return The new KernelFunction instance */ KernelFunction build(); /** * Set the template format for the function. + * * @param templateFormat The template format for the function * @return The builder */ @@ -240,6 +244,7 @@ public abstract class KernelFunction implements Buildable { /** * Set the output variable for the function. + * * @param outputVariable The output variable for the function * @return The builder */ @@ -247,14 +252,16 @@ public abstract class KernelFunction implements Buildable { /** * Set the output variable for the function. + * * @param description The description of the output variable - * @param type The type of the output variable + * @param type The type of the output variable * @return The builder */ FromPromptBuilder withOutputVariable(@Nullable String description, String type); /** * Set the prompt template factory used to build the function. + * * @param promptTemplateFactory The prompt template factory for the function * @return The builder */ @@ -263,6 +270,7 @@ public abstract class KernelFunction implements Buildable { /** * Set the prompt template config used to build the function. + * * @param promptTemplateConfig The prompt template config for the function * @return The builder */ diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java index 35286ab9f7..0e5eac8a9a 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java @@ -1,20 +1,11 @@ package com.microsoft.semantickernel.plugin; import com.microsoft.semantickernel.orchestration.KernelFunction; -import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import com.microsoft.semantickernel.orchestration.KernelFunction.FromPromptBuilder; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromMethod; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; -import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactory; -import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; -import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; - import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; /** * Factory for creating {@link KernelFunction} instances. @@ -22,119 +13,48 @@ import javax.annotation.Nullable; public class KernelFunctionFactory { /** - * Creates a {@link KernelFunction} instance for a method, specified via a {@link Method} instance - * @param The return type of the method. + * Creates a {@link KernelFunction} instance for a method, specified via a {@link Method} + * instance + * + * @param The return type of the method. * @param method The method to be represented via the created {@link KernelFunction}. - * @param target The target object for the {@code method} if it represents an instance method. This should be {@code null} if and only if {@code method} is a static method. - * @param functionName Optional function name. If {@code null}, it will default to one derived from the method represented by {@code method}. - * @param description Optional description of the method. If {@code null}, it will default to one derived from the method represented by {@code method}, - * if possible (e.g. via a {@link com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction} on the method). - * @param parameters Optional parameter descriptions. If {@code null}, it will default to one derived from the method represented by {@code method}. - * @param returnParameter Optional return parameter description. If {@code null}, it will default to one derived from the method represented by {@code method}. + * @param target The target object for the {@code method} if it represents an instance method. + * This should be {@code null} if and only if {@code method} is a static method. * @return The created {@link KernelFunction} wrapper for {@code method}. */ - public static KernelFunction createFromMethod( + + public static KernelFunctionFromMethod.Builder createFromMethod( Method method, - Object target, - @Nullable String functionName, - @Nullable String description, - @Nullable List> parameters, - @Nullable KernelReturnParameterMetadata returnParameter) { - return KernelFunctionFromMethod.create(method, target, functionName, description, - parameters, returnParameter); + Object target) { + return KernelFunctionFromMethod.builder() + .withMethod(method) + .withTarget(target); + } + + /** + * Creates a {@link KernelFunction} instance based on a given prompt + * + * @param prompt The prompt to be used for the created {@link KernelFunction}. + * @param The return type of the method + * @return The builder for creating a {@link KernelFunction} instance. + */ + public static FromPromptBuilder createFromPrompt(String prompt) { + return KernelFunctionFromPrompt.builder() + .withTemplate(prompt); } /** - * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. + * Builder for creating a {@link KernelFunction} instance for a given + * {@link PromptTemplateConfig}. * - * @param promptTemplate Prompt template for the function. - * @param Type of the value that the function will return - * @return The created {@link KernelFunction} for invoking the prompt. + * @param promptTemplateConfiguration The configuration for the prompt template. + * @param The return type of the method + * @return The builder for creating a {@link KernelFunction} instance. */ - public static KernelFunction createFromPrompt(String promptTemplate) { - return createFromPrompt(promptTemplate, null, null, null, null, null); - } - - /** - * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. - * - * @param promptTemplate Prompt template for the function. - * @param executionSettings Default execution settings to use when invoking this prompt - * function. - * @param functionName The name to use for the function. If {@code null}, it will default to a - * randomly generated name. - * @param description The description to use for the function. - * @param templateFormat The template format of {@code promptTemplate}. This must be - * provided if {@code promptTemplateFactory} is not {@code null}. - * @param promptTemplateFactory The {@link PromptTemplateFactory} to use when interpreting the - * {@code promptTemplate} into a {@link PromptTemplate}. If {@code null}, a - * default factory will be used. - * @param Type of the value that the function will return - * @return The created {@link KernelFunction} for invoking the prompt. - */ - public static KernelFunction createFromPrompt( - String promptTemplate, - @Nullable PromptExecutionSettings executionSettings, - @Nullable String functionName, - @Nullable String description, - @Nullable String templateFormat, - @Nullable PromptTemplateFactory promptTemplateFactory) { - return KernelFunctionFromPrompt.create( - promptTemplate, - createSettingsDictionary(executionSettings), - functionName, - description, - templateFormat, - promptTemplateFactory); - } - - /** - * Creates a {@link KernelFunction} instance for a prompt specified via a {@link PromptTemplateConfig}. - * - * @param promptConfig A prompt template configuration for the function. - * @param promptTemplateFactory The {@code PromptTemplateFactory} to use when interpreting - * the prompt template configuration into a {@link PromptTemplate}. - * If {@code null}, a default factory will be used. - * @param Type of the value that the function will return - * @return The created {@link KernelFunction} for invoking the prompt. - */ - public static KernelFunction createFromPrompt( - PromptTemplateConfig promptConfig, - @Nullable PromptTemplateFactory promptTemplateFactory) { - - if (promptTemplateFactory == null) { - promptTemplateFactory = new KernelPromptTemplateFactory(); - } - - return KernelFunctionFactory.create(promptTemplateFactory.tryCreate(promptConfig), - promptConfig); - } - - /** - * Creates a {@link KernelFunction} instance for a prompt specified via a {@link PromptTemplateConfig}. - * - * @param promptConfig A prompt template configuration for the function. - * @param promptTemplate The prompt template to use when creating the function. - * @param Type of the value that the function will return - * @return The created {@link KernelFunction} for invoking the prompt. - */ - public static KernelFunction create( - PromptTemplate promptTemplate, - PromptTemplateConfig promptConfig) { - return new KernelFunctionFromPrompt<>( - promptTemplate, - promptConfig, - null); - } - - private static Map createSettingsDictionary( - @Nullable - PromptExecutionSettings executionSettings) { - HashMap map = new HashMap<>(); - if (executionSettings != null) { - map.put("default", executionSettings); - } - return map; + public static FromPromptBuilder createFromPrompt( + PromptTemplateConfig promptTemplateConfiguration) { + return KernelFunctionFromPrompt.builder() + .withPromptTemplateConfig(promptTemplateConfiguration); } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java index 6155e69869..19746c8ad7 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java @@ -64,13 +64,12 @@ public class KernelPluginFactory { returnType); return KernelFunctionFactory - .createFromMethod( - method, - target, - annotation.name(), - annotation.description(), - getParameters(method), - kernelReturnParameterMetadata); + .createFromMethod(method, target) + .withFunctionName(annotation.name()) + .withDescription(annotation.description()) + .withParameters(getParameters(method)) + .withReturnParameter(kernelReturnParameterMetadata) + .build(); }).collect(ArrayList::new, (list, it) -> list.add(it), (a, b) -> a.addAll(b)); return createFromFunctions(pluginName, methods); @@ -136,7 +135,7 @@ public class KernelPluginFactory { @Nullable List> functions) { Map> funcs = new HashMap<>(); if (functions != null) { - funcs = functions.stream().collect(Collectors.toMap(KernelFunction::getName, f -> f)); + funcs = functions.stream().collect(Collectors.toMap(KernelFunction::getName, f -> f)); } return new KernelPlugin(pluginName, description, funcs); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java index a79fd198ab..61a280013f 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java @@ -1,6 +1,9 @@ package com.microsoft.semantickernel.semanticfunctions; +import static com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter.NO_DEFAULT_VALUE; + import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.builders.Buildable; import com.microsoft.semantickernel.exceptions.AIException; import com.microsoft.semantickernel.exceptions.AIException.ErrorCodes; import com.microsoft.semantickernel.exceptions.SKException; @@ -20,8 +23,6 @@ import com.microsoft.semantickernel.plugin.KernelParameterMetadata; import com.microsoft.semantickernel.plugin.KernelReturnParameterMetadata; import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter; -import static com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter.NO_DEFAULT_VALUE; - import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -31,23 +32,20 @@ import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; - import javax.annotation.Nullable; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; /** * A {@link KernelFunction} that is created from a method. This class is used to create a - * {@link KernelFunction} from a method that is annotated with {@link DefineKernelFunction} - * and {@link KernelFunctionParameter}. + * {@link KernelFunction} from a method that is annotated with {@link DefineKernelFunction} and + * {@link KernelFunctionParameter}. * * @param the return type of the function */ -public class KernelFunctionFromMethod extends KernelFunction { +public class KernelFunctionFromMethod extends KernelFunction implements Buildable { private final static Logger LOGGER = LoggerFactory.getLogger(KernelFunctionFromMethod.class); @@ -93,10 +91,10 @@ public class KernelFunctionFromMethod extends KernelFunction { /** * Invokes the function. * - * @param kernel the kernel to invoke the function on - * @param function the function to invoke - * @param arguments the arguments to the function - * @param variableType the variable type of the function + * @param kernel the kernel to invoke the function on + * @param function the function to invoke + * @param arguments the arguments to the function + * @param variableType the variable type of the function * @param invocationContext the invocation context * @return a {@link Mono} that emits the result of the function invocation */ @@ -112,13 +110,13 @@ public class KernelFunctionFromMethod extends KernelFunction { /** * Creates a new instance of {@link KernelFunctionFromMethod} from a method. * - * @param method the method to create the function from - * @param target the instance of the class that the method is a member of - * @param functionName the name of the function - * @param description the description of the function - * @param parameters the parameters of the function + * @param method the method to create the function from + * @param target the instance of the class that the method is a member of + * @param functionName the name of the function + * @param description the description of the function + * @param parameters the parameters of the function * @param returnParameter the return parameter of the function - * @param the return type of the function + * @param the return type of the function * @return a new instance of {@link KernelFunctionFromMethod} */ @SuppressWarnings("unchecked") @@ -590,4 +588,74 @@ public class KernelFunctionFromMethod extends KernelFunction { isRequired ); } + + public static Builder builder() { + return new Builder<>(); + } + + public static class Builder { + + private Method method; + private Object target; + @Nullable + private String functionName; + @Nullable + private String description; + @Nullable + private List> parameters; + @Nullable + private KernelReturnParameterMetadata returnParameter; + + public Builder withMethod(Method method) { + this.method = method; + return this; + } + + public Builder withTarget(Object target) { + this.target = target; + return this; + } + + public Builder withFunctionName(String functionName) { + this.functionName = functionName; + return this; + } + + public Builder withDescription(String description) { + this.description = description; + return this; + } + + public Builder withParameters(List> parameters) { + this.parameters = parameters; + return this; + } + + public Builder withReturnParameter(KernelReturnParameterMetadata returnParameter) { + this.returnParameter = returnParameter; + return this; + } + + public KernelFunction build() { + + if (method == null) { + throw new SKException( + "To build a KernelFunctionFromMethod, a method must be provided"); + } + + if (target == null) { + throw new SKException( + "To build a plugin object must be provided"); + } + + return KernelFunctionFromMethod.create( + method, + target, + functionName, + description, + parameters, + returnParameter); + } + + } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index 211ac30cb5..396e41f3cc 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -26,19 +26,15 @@ import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariab import com.microsoft.semantickernel.plugin.KernelParameterMetadata; import com.microsoft.semantickernel.services.AIServiceSelection; import com.microsoft.semantickernel.textcompletion.TextGenerationService; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; - import javax.annotation.Nullable; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -56,8 +52,8 @@ public class KernelFunctionFromPrompt extends KernelFunction { /** * Creates a new instance of {@link KernelFunctionFromPrompt}. * - * @param template the prompt template to use for the function - * @param promptConfig the configuration for the prompt + * @param template the prompt template to use for the function + * @param promptConfig the configuration for the prompt * @param executionSettings the execution settings to use when invoking the function */ public KernelFunctionFromPrompt( @@ -86,11 +82,11 @@ public class KernelFunctionFromPrompt extends KernelFunction { } /** - * Creates a new instance of {@link KernelFunctionFromPrompt} from a + * Creates a new instance of {@link KernelFunctionFromPrompt} from a * {@code PromptTemplateConfig}. * * @param promptConfig the configuration for the prompt - * @param the type of the return value of the function + * @param the type of the return value of the function * @return a new instance of {@link KernelFunction} */ public static KernelFunction create( @@ -103,13 +99,13 @@ public class KernelFunctionFromPrompt extends KernelFunction { /** * Creates a new instance of {@link KernelFunctionFromPrompt} from a - * {@code PromptTemplateConfig}, using the {@code PropmptTemplateFactory} - * to create the prompt template. If {@code promptTemplateFactory} is {@code null}, - * a default factory will be used. + * {@code PromptTemplateConfig}, using the {@code PropmptTemplateFactory} to create the prompt + * template. If {@code promptTemplateFactory} is {@code null}, a default factory will be used. * - * @param promptConfig the configuration for the prompt - * @param promptTemplateFactory the prompt template factory to use for creating the prompt template - * @param the type of the return value of the function + * @param promptConfig the configuration for the prompt + * @param promptTemplateFactory the prompt template factory to use for creating the prompt + * template + * @param the type of the return value of the function * @return a new instance of {@link KernelFunction} */ public static KernelFunction create( @@ -128,8 +124,8 @@ public class KernelFunctionFromPrompt extends KernelFunction { * {@code PromptTemplateConfig}, using the provided prompt template. * * @param promptTemplate the prompt template to use for the function - * @param promptConfig the configuration for the prompt - * @param the type of the return value of the function + * @param promptConfig the configuration for the prompt + * @param the type of the return value of the function * @return a new instance of {@link KernelFunction} */ public static KernelFunction create( @@ -144,7 +140,7 @@ public class KernelFunctionFromPrompt extends KernelFunction { private Flux> invokeInternalAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelFunctionArguments argumentsIn, @Nullable ContextVariableType contextVariableType, @Nullable InvocationContext invocationContext) { @@ -158,7 +154,9 @@ public class KernelFunctionFromPrompt extends KernelFunction { assert kernelHooks != null : "getGlobalKernelHooks() should never return null"; PromptRenderingEvent preRenderingHookResult = kernelHooks - .executeHooks(new PromptRenderingEvent(this, arguments)); + .executeHooks(new PromptRenderingEvent(this, argumentsIn)); + + KernelFunctionArguments arguments = preRenderingHookResult.getArguments(); // TOOD: put in method, add catch for classcastexception, fallback to noopconverter ContextVariableType variableType = contextVariableType != null @@ -169,7 +167,7 @@ public class KernelFunctionFromPrompt extends KernelFunction { return this .template - .renderAsync(kernel, preRenderingHookResult.getArguments(), context) + .renderAsync(kernel, arguments, context) .flatMapMany(prompt -> { PromptRenderedEvent promptHookResult = kernelHooks .executeHooks(new PromptRenderedEvent(this, arguments, prompt)); @@ -430,7 +428,8 @@ public class KernelFunctionFromPrompt extends KernelFunction { /** * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. - * @param the type of the return value of the function + * + * @param the type of the return value of the function * @param promptTemplate the prompt template for the function * @return a new instance of {@link KernelFunction} */ @@ -440,15 +439,18 @@ public class KernelFunctionFromPrompt extends KernelFunction { } /** - * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. - * If any of the optional parameters are {@code null}, default values will be used. - * @param promptTemplate the prompt template for the function - * @param executionSettings the default execution settings to use when invoking this prompt function - * @param functionName the name of the function - * @param description the description of the function - * @param templateFormat the format of the template - * @param promptTemplateFactory the prompt template factory to use for creating the prompt template - * @param the type of the return value of the function + * Creates a {@link KernelFunction} instance for a prompt specified via a prompt template. If + * any of the optional parameters are {@code null}, default values will be used. + * + * @param promptTemplate the prompt template for the function + * @param executionSettings the default execution settings to use when invoking this prompt + * function + * @param functionName the name of the function + * @param description the description of the function + * @param templateFormat the format of the template + * @param promptTemplateFactory the prompt template factory to use for creating the prompt + * template + * @param the type of the return value of the function * @return a new instance of {@link KernelFunction} */ @SuppressWarnings("unchecked") @@ -480,6 +482,7 @@ public class KernelFunctionFromPrompt extends KernelFunction { /** * Creates a new instance of {@link Builder}. + * * @param The type of the return value of the function * @return a new instance of {@link Builder} */ @@ -489,6 +492,7 @@ public class KernelFunctionFromPrompt extends KernelFunction { /** * A builder for creating a {@link KernelFunction} from a prompt template. + * * @param the type of the return value of the function */ public static final class Builder implements FromPromptBuilder { @@ -511,7 +515,7 @@ public class KernelFunctionFromPrompt extends KernelFunction { @Nullable private PromptTemplateFactory promptTemplateFactory; @Nullable - private PromptTemplateConfig functionModel; + private PromptTemplateConfig promptTemplateConfig; @Override @@ -612,21 +616,33 @@ public class KernelFunctionFromPrompt extends KernelFunction { @Override public FromPromptBuilder withPromptTemplateConfig( @Nullable - PromptTemplateConfig functionModel) { - this.functionModel = functionModel; + PromptTemplateConfig promptTemplateConfig) { + this.promptTemplateConfig = promptTemplateConfig; return this; } @Override public KernelFunction build() { - if (functionModel != null) { + if (templateFormat == null) { + templateFormat = PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT; + } + + if (name == null) { + name = UUID.randomUUID().toString(); + } + + if (promptTemplateFactory == null) { + promptTemplateFactory = new KernelPromptTemplateFactory(); + } + + if (promptTemplateConfig != null) { if (promptTemplate == null) { - throw new IllegalStateException("A PromptTemplate must be provided when building with a PromptTemplateConfig"); + promptTemplate = promptTemplateFactory.tryCreate(promptTemplateConfig); } return new KernelFunctionFromPrompt<>( - promptTemplate, - functionModel, + promptTemplate, + promptTemplateConfig, executionSettings); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java index 74665845a2..49b5eb3484 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java @@ -19,6 +19,7 @@ import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -210,7 +211,7 @@ public class HandlebarsPromptTemplate implements PromptTemplate { private static Handlebars.SafeString handleFunctions(Kernel kernel, Options options) throws IOException { StringBuilder sb = new StringBuilder(""); - List plugins = kernel.getPlugins(); + Collection plugins = kernel.getPlugins(); sb.append(options.fn(plugins)); sb.append(""); From 73caad5286d24781ad71b211eacb1d96d620dc25 Mon Sep 17 00:00:00 2001 From: John Oliver <1615532+johnoliver@users.noreply.github.com> Date: Thu, 15 Feb 2024 13:46:46 +0000 Subject: [PATCH 3/3] Removed KernelFunctionFactory. Added AiServiceCollection. Relocated internel classes to implementation package --- ...xample05_InlineFunctionDefinitionTest.java | 4 +- .../plugins/ConversationSummaryPlugin.java | 7 +-- .../Example05_InlineFunctionDefinition.java | 4 +- .../Example06_TemplateLanguage.java | 4 +- ...Example27_PromptFunctionsUsingChatGPT.java | 4 +- .../Example30_ChatWithPrompts.java | 2 +- .../Example58_ConfigureExecutionSettings.java | 5 +- .../Example62_CustomAIServiceSelector.java | 5 +- .../Example69_MutableKernelPlugin.java | 4 +- .../com/microsoft/semantickernel/Kernel.java | 12 ++-- .../semantickernel/KernelContent.java | 8 +-- .../StreamingKernelContent.java | 2 +- .../semantickernel/TextAIService.java | 2 + .../chatcompletion/ChatCompletionService.java | 2 +- .../chatcompletion/ChatMessageContent.java | 49 ++++++++------- .../StreamingChatMessageContent.java | 25 ++++---- .../EmbeddedResourceLoader.java | 2 +- .../ServiceLoadUtil.java | 2 +- .../{ => implementation}/Todo.java | 2 +- .../{ => implementation}/Verify.java | 2 +- .../tokenizer}/CodeTokenizer.java | 17 +++--- .../tokenizer}/DefaultPromptTemplate.java | 17 +++--- .../tokenizer}/TemplateTokenizer.java | 11 ++-- .../tokenizer}/blocks/Block.java | 2 +- .../tokenizer}/blocks/BlockTypes.java | 2 +- .../tokenizer}/blocks/CodeBlock.java | 2 +- .../tokenizer}/blocks/CodeRendering.java | 2 +- .../tokenizer}/blocks/FunctionIdBlock.java | 2 +- .../tokenizer}/blocks/NamedArgBlock.java | 6 +- .../tokenizer}/blocks/Symbols.java | 2 +- .../tokenizer}/blocks/TextBlock.java | 2 +- .../tokenizer}/blocks/TextRendering.java | 2 +- .../tokenizer}/blocks/ValBlock.java | 2 +- .../tokenizer}/blocks/VarBlock.java | 2 +- .../orchestration/KernelFunction.java | 56 ++++++++++++++++- .../plugin/KernelFunctionFactory.java | 60 ------------------- .../plugin/KernelPluginFactory.java | 9 +-- .../KernelFunctionFromPrompt.java | 2 +- .../KernelPromptTemplateFactory.java | 2 +- .../{ => services}/AIService.java | 2 +- .../services/AIServiceSelection.java | 1 - .../services/AIServiceSelector.java | 1 - .../services/AiServiceCollection.java | 7 +++ .../services/BaseAIServiceSelector.java | 5 +- .../services/OrderedAIServiceSelector.java | 8 +-- .../textcompletion/StreamingTextContent.java | 11 +++- .../textcompletion/TextContent.java | 2 +- .../textcompletion/TextGenerationService.java | 2 +- .../semantickernel/CodeTokenizerTest.java | 7 ++- 49 files changed, 203 insertions(+), 190 deletions(-) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{util => implementation}/EmbeddedResourceLoader.java (98%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{builders => implementation}/ServiceLoadUtil.java (98%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{ => implementation}/Todo.java (84%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{ => implementation}/Verify.java (95%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/CodeTokenizer.java (95%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/DefaultPromptTemplate.java (87%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/TemplateTokenizer.java (95%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/Block.java (93%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/BlockTypes.java (87%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/CodeBlock.java (99%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/CodeRendering.java (93%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/FunctionIdBlock.java (96%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/NamedArgBlock.java (95%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/Symbols.java (88%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/TextBlock.java (89%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/TextRendering.java (87%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/ValBlock.java (96%) rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{templateengine/semantickernel => implementation/tokenizer}/blocks/VarBlock.java (97%) delete mode 100644 java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java rename java/semantickernel-api/src/main/java/com/microsoft/semantickernel/{ => services}/AIService.java (98%) create mode 100644 java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AiServiceCollection.java diff --git a/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java b/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java index e6237258aa..e36628c2e7 100644 --- a/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java +++ b/java/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/syntaxexamples/Example05_InlineFunctionDefinitionTest.java @@ -8,9 +8,9 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.orchestration.FunctionResult; +import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.plugin.KernelFunctionFactory; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.textcompletion.TextGenerationService; import java.time.Instant; @@ -92,7 +92,7 @@ public class Example05_InlineFunctionDefinitionTest { var date = DateTimeFormatter.ISO_LOCAL_DATE.withZone(ZoneOffset.UTC) .format(Instant.ofEpochSecond(1)); var message = "Translate this date " + date + " to French format"; - var fixedFunction = KernelFunctionFactory.createFromPrompt(message) + var fixedFunction = KernelFunction.createFromPrompt(message) .withDefaultExecutionSettings( PromptExecutionSettings.builder() .withMaxTokens(100) diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java index 54af4e9d2b..960d6a524e 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java @@ -5,7 +5,6 @@ import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes; -import com.microsoft.semantickernel.plugin.KernelFunctionFactory; import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter; import com.microsoft.semantickernel.text.TextChunker; @@ -37,7 +36,7 @@ public class ConversationSummaryPlugin { .withTopP(0.5) .build(); - this.summarizeConversationFunction = KernelFunctionFactory + this.summarizeConversationFunction = KernelFunction .createFromPrompt(PromptFunctionConstants.SummarizeConversationDefinition) .withDefaultExecutionSettings(settings) .withName("summarizeConversation") @@ -45,14 +44,14 @@ public class ConversationSummaryPlugin { "Given a section of a conversation transcript, summarize the part of the conversation.") .build(); - this.conversationActionItemsFunction = KernelFunctionFactory + this.conversationActionItemsFunction = KernelFunction .createFromPrompt(PromptFunctionConstants.GetConversationActionItemsDefinition) .withDefaultExecutionSettings(settings) .withName("conversationActionItems") .withDescription("Given a section of a conversation transcript, identify action items.") .build(); - this.conversationTopicsFunction = KernelFunctionFactory + this.conversationTopicsFunction = KernelFunction .createFromPrompt(PromptFunctionConstants.GetConversationTopicsDefinition) .withDefaultExecutionSettings(settings) .withName("conversationTopics") diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java index 637a3867d7..a71a6f3c7e 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example05_InlineFunctionDefinition.java @@ -9,9 +9,9 @@ import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.exceptions.ConfigurationException; import com.microsoft.semantickernel.orchestration.FunctionResult; +import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.plugin.KernelFunctionFactory; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.textcompletion.TextGenerationService; import java.time.Instant; @@ -99,7 +99,7 @@ public class Example05_InlineFunctionDefinition { var date = DateTimeFormatter.ISO_LOCAL_DATE.withZone(ZoneOffset.UTC) .format(Instant.ofEpochSecond(1)); var message = "Translate this date " + date + " to French format"; - var fixedFunction = KernelFunctionFactory.createFromPrompt(message) + var fixedFunction = KernelFunction.createFromPrompt(message) .withDefaultExecutionSettings( PromptExecutionSettings.builder() .withMaxTokens(100) diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java index 3d60a77cf4..41327ea5d3 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example06_TemplateLanguage.java @@ -7,8 +7,8 @@ import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.aiservices.openai.textcompletion.OpenAITextGenerationService; import com.microsoft.semantickernel.exceptions.ConfigurationException; +import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.plugin.KernelFunctionFactory; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; @@ -91,7 +91,7 @@ public class Example06_TemplateLanguage { var renderedPrompt = promptTemplate.renderAsync(kernel, null, null).block(); System.out.println(renderedPrompt); - var kindOfDay = KernelFunctionFactory.createFromPrompt(functionDefinition) + var kindOfDay = KernelFunction.createFromPrompt(functionDefinition) .withDefaultExecutionSettings( PromptExecutionSettings.builder() .withMaxTokens(100) diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java index 37534bc2d3..679e1deac9 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example27_PromptFunctionsUsingChatGPT.java @@ -6,9 +6,9 @@ import com.azure.core.credential.AzureKeyCredential; import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; +import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes; -import com.microsoft.semantickernel.plugin.KernelFunctionFactory; public class Example27_PromptFunctionsUsingChatGPT { @@ -47,7 +47,7 @@ public class Example27_PromptFunctionsUsingChatGPT { .withAIService(ChatCompletionService.class, openAIChatCompletion) .build(); - var func = KernelFunctionFactory.createFromPrompt( + var func = KernelFunction.createFromPrompt( "List the two planets closest to '{{$input}}', excluding moons, using bullet points.") .build(); diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java index c2f46d4445..b3ed31473b 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example30_ChatWithPrompts.java @@ -14,7 +14,7 @@ import com.microsoft.semantickernel.samples.plugins.TimePlugin; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; import com.microsoft.semantickernel.services.ServiceNotFoundException; -import com.microsoft.semantickernel.util.EmbeddedResourceLoader; +import com.microsoft.semantickernel.implementation.EmbeddedResourceLoader; import java.io.FileNotFoundException; import java.time.ZoneId; diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java index 696cb2f1a2..cb4ab077b3 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example58_ConfigureExecutionSettings.java @@ -7,12 +7,11 @@ import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; +import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.plugin.KernelFunctionFactory; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; -import com.microsoft.semantickernel.templateengine.semantickernel.DefaultPromptTemplate; public class Example58_ConfigureExecutionSettings { @@ -92,7 +91,7 @@ public class Example58_ConfigureExecutionSettings { .parseFromJson(configPayload) .setTemplate(prompt); - var func = KernelFunctionFactory + var func = KernelFunction .createFromPrompt(promptConfig) .build(); diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java index 75a767a46d..44b9c9cbf7 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java @@ -4,7 +4,8 @@ import com.azure.ai.openai.OpenAIAsyncClient; import com.azure.ai.openai.OpenAIClientBuilder; import com.azure.core.credential.AzureKeyCredential; import com.azure.core.credential.KeyCredential; -import com.microsoft.semantickernel.AIService; +import com.microsoft.semantickernel.services.AIService; +import com.microsoft.semantickernel.services.AiServiceCollection; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.orchestration.KernelFunction; @@ -84,7 +85,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(Map, AIService> services) { + public CustomAIServiceSelector(AiServiceCollection services) { super(services); } diff --git a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java index d18358389a..24bb4cada3 100644 --- a/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java +++ b/java/samples/sample-code/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example69_MutableKernelPlugin.java @@ -1,7 +1,7 @@ package com.microsoft.semantickernel.samples.syntaxexamples; import com.microsoft.semantickernel.Kernel; -import com.microsoft.semantickernel.plugin.KernelFunctionFactory; +import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; @@ -25,7 +25,7 @@ public class Example69_MutableKernelPlugin { System.out.println("======== Example69_MutableKernelPlugin ========"); KernelPlugin plugin = new KernelPlugin("Plugin", "Mutable plugin", null); - plugin.addFunction(KernelFunctionFactory.createFromMethod( + plugin.addFunction(KernelFunction.createFromMethod( Time.class.getMethod("date"), new Time()) .withFunctionName("dateFunction") .build()); diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java index ad8237fa92..7dc7d66ad2 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java @@ -7,17 +7,17 @@ import com.microsoft.semantickernel.hooks.KernelHooks; import com.microsoft.semantickernel.orchestration.FunctionInvocation; import com.microsoft.semantickernel.orchestration.KernelFunction; 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.OrderedAIServiceSelector; import com.microsoft.semantickernel.services.ServiceNotFoundException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.function.Function; import javax.annotation.Nullable; @@ -108,7 +108,7 @@ public class Kernel implements Buildable { /** * Gets the plugins that were added to the kernel. - * @return The plugins available through the kernel. + * @return The plugins available through the kernel (unmodifiable list). * @see Kernel#getPlugins() */ public Collection getPlugins() { @@ -196,10 +196,10 @@ public class Kernel implements Buildable { */ public static class Builder implements SemanticKernelBuilder { - private final Map, AIService> services = new HashMap<>(); + private final AiServiceCollection services = new AiServiceCollection(); private final List plugins = new ArrayList<>(); @Nullable - private Function, AIService>, AIServiceSelector> serviceSelectorProvider; + private Function serviceSelectorProvider; /** * Adds a service to the kernel. @@ -229,7 +229,7 @@ public class Kernel implements Buildable { * @return {@code this} builder with the service selector provider set. */ public Kernel.Builder withServiceSelector( - Function, AIService>, AIServiceSelector> serviceSelector) { + Function serviceSelector) { this.serviceSelectorProvider = serviceSelector; return this; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java index a879f1b0fc..830647a9a7 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/KernelContent.java @@ -8,7 +8,7 @@ import javax.annotation.Nullable; * Base class which represents the content returned by an AI service. * @param The type of the content. */ -public abstract class KernelContent> { +public abstract class KernelContent { /* * The inner content representation. Use this to bypass the current @@ -16,7 +16,7 @@ public abstract class KernelContent> { * Use it only if strictly necessary. */ @Nullable - private final Object innerContent; + private final T innerContent; /** * The model ID used to generate the content. @@ -38,7 +38,7 @@ public abstract class KernelContent> { */ public KernelContent( @Nullable - Object innerContent, + T innerContent, @Nullable String modelId, @Nullable @@ -54,7 +54,7 @@ public abstract class KernelContent> { * @return The inner content representation. */ @Nullable - public Object getInnerContent() { + public T getInnerContent() { return innerContent; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java index 786a6a161d..381d461ec3 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/StreamingKernelContent.java @@ -10,7 +10,7 @@ import javax.annotation.Nullable; * Base class which represents the content returned by a streaming AI service. * @param The type of the content. */ -public abstract class StreamingKernelContent> extends KernelContent { +public abstract class StreamingKernelContent extends KernelContent { /** * In a scenario of multiple choices per request, this represents diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java index 08b971e7da..3e1a7e56fc 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/TextAIService.java @@ -1,6 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel; +import com.microsoft.semantickernel.services.AIService; + /** * Marker interface for Text AI services, typically Chat or Text generation for OpenAI */ diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java index 4dcc40a518..0dd53a7424 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatCompletionService.java @@ -7,7 +7,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.TextAIService; import com.microsoft.semantickernel.builders.Buildable; import com.microsoft.semantickernel.builders.SemanticKernelBuilder; -import com.microsoft.semantickernel.builders.ServiceLoadUtil; +import com.microsoft.semantickernel.implementation.ServiceLoadUtil; import com.microsoft.semantickernel.orchestration.InvocationContext; import java.util.List; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java index 748c7b0786..890e0ecbe0 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/ChatMessageContent.java @@ -3,32 +3,31 @@ package com.microsoft.semantickernel.chatcompletion; import com.microsoft.semantickernel.KernelContent; import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; - import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; - import javax.annotation.Nullable; /** * Represents the content of a chat message */ -public class ChatMessageContent extends KernelContent { +public class ChatMessageContent extends KernelContent { private AuthorRole authorRole; @Nullable private String content; @Nullable - private List> items; + private List> items; @Nullable private Charset encoding; /** * Creates a new instance of the {@link ChatMessageContent} class. + * * @param authorRole the author role that generated the content - * @param content the content + * @param content the content */ public ChatMessageContent( AuthorRole authorRole, @@ -45,12 +44,13 @@ public class ChatMessageContent extends KernelContent { /** * Creates a new instance of the {@link ChatMessageContent} class. - * @param authorRole the author role that generated the content - * @param content the content - * @param modelId the model id + * + * @param authorRole the author role that generated the content + * @param content the content + * @param modelId the model id * @param innerContent the inner content - * @param encoding the encoding - * @param metadata the metadata + * @param encoding the encoding + * @param metadata the metadata */ public ChatMessageContent( AuthorRole authorRole, @@ -58,7 +58,7 @@ public class ChatMessageContent extends KernelContent { @Nullable String modelId, @Nullable - String innerContent, + T innerContent, @Nullable Charset encoding, @Nullable @@ -72,18 +72,19 @@ public class ChatMessageContent extends KernelContent { /** * Creates a new instance of the {@link ChatMessageContent} class. - * @param authorRole the author role that generated the content - * @param items the items - * @param modelId the model id + * + * @param authorRole the author role that generated the content + * @param items the items + * @param modelId the model id * @param innerContent the inner content - * @param encoding the encoding - * @param metadata the metadata + * @param encoding the encoding + * @param metadata the metadata */ public ChatMessageContent( AuthorRole authorRole, - List> items, + List> items, String modelId, - String innerContent, + T innerContent, Charset encoding, FunctionResultMetadata metadata ) { @@ -96,6 +97,7 @@ public class ChatMessageContent extends KernelContent { /** * Gets the author role that generated the content + * * @return the author role that generated the content */ public AuthorRole getAuthorRole() { @@ -104,6 +106,7 @@ public class ChatMessageContent extends KernelContent { /** * Sets the author role that generated the content + * * @param authorRole the author role that generated the content */ public void setAuthorRole(AuthorRole authorRole) { @@ -112,6 +115,7 @@ public class ChatMessageContent extends KernelContent { /** * Gets the content + * * @return the content, which may be {@code null} */ @Nullable @@ -122,6 +126,7 @@ public class ChatMessageContent extends KernelContent { /** * Sets the content + * * @param content the content */ public void setContent(@Nullable String content) { @@ -130,22 +135,25 @@ public class ChatMessageContent extends KernelContent { /** * Gets the {@code KernelContent} items that comprise the content. + * * @return the items, which may be {@code null} */ - public List> getItems() { + public List> getItems() { return Collections.unmodifiableList(items); } /** * Sets the {@code KernelContent} items that comprise the content. + * * @param items the items */ - public void setItems(List> items) { + public void setItems(List> items) { this.items = new ArrayList<>(items); } /** * Gets the encoding of the content + * * @return the encoding, which may be {@code null} */ @Nullable @@ -155,6 +163,7 @@ public class ChatMessageContent extends KernelContent { /** * Sets the encoding of the content + * * @param encoding the encoding */ public void setEncoding(Charset encoding) { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java index e3c36c3e74..b219684c95 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/chatcompletion/StreamingChatMessageContent.java @@ -1,21 +1,19 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.chatcompletion; -import com.microsoft.semantickernel.KernelContent; import com.microsoft.semantickernel.StreamingKernelContent; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; - import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Map; - import javax.annotation.Nullable; /** * Represents the content of a chat message that is streamed. + * * @param the type of the inner content */ -public class StreamingChatMessageContent> extends StreamingKernelContent { +public class StreamingChatMessageContent extends StreamingKernelContent { private final String content; private final AuthorRole role; @@ -23,7 +21,8 @@ public class StreamingChatMessageContent> extends Str /** * Creates a new instance of the {@link StreamingChatMessageContent} class. - * @param role the author role that generated the content + * + * @param role the author role that generated the content * @param content the content * @param modelId the model id */ @@ -37,13 +36,14 @@ public class StreamingChatMessageContent> extends Str /** * Creates a new instance of the {@link StreamingChatMessageContent} class. - * @param role the author role that generated the content - * @param content the content + * + * @param role the author role that generated the content + * @param content the content * @param innerContent the inner content - * @param choiceIndex the choice index - * @param modelId the model id - * @param encoding the encoding - * @param metadata the metadata + * @param choiceIndex the choice index + * @param modelId the model id + * @param encoding the encoding + * @param metadata the metadata */ public StreamingChatMessageContent( AuthorRole role, @@ -75,6 +75,7 @@ public class StreamingChatMessageContent> extends Str /** * Gets the role of the author of the message + * * @return the role of the author of the message */ public AuthorRole getRole() { @@ -83,6 +84,7 @@ public class StreamingChatMessageContent> extends Str /** * Gets the encoding of the message + * * @return the encoding of the message */ public Charset getEncoding() { @@ -91,6 +93,7 @@ public class StreamingChatMessageContent> extends Str /** * Sets the encoding of the message + * * @param encoding the encoding of the message * @return this instance */ diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/util/EmbeddedResourceLoader.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/EmbeddedResourceLoader.java similarity index 98% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/util/EmbeddedResourceLoader.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/EmbeddedResourceLoader.java index 69e34d6cd2..c2ac84de28 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/util/EmbeddedResourceLoader.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/EmbeddedResourceLoader.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.util; +package com.microsoft.semantickernel.implementation; import java.io.BufferedReader; import java.io.File; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/ServiceLoadUtil.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/ServiceLoadUtil.java similarity index 98% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/ServiceLoadUtil.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/ServiceLoadUtil.java index 6a74f2b457..18db6d1997 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/builders/ServiceLoadUtil.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/ServiceLoadUtil.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.builders; +package com.microsoft.semantickernel.implementation; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Todo.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/Todo.java similarity index 84% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Todo.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/Todo.java index 454ace072e..bfcfa85f0c 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Todo.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/Todo.java @@ -1,4 +1,4 @@ -package com.microsoft.semantickernel; +package com.microsoft.semantickernel.implementation; /** * This is used as a placeholder for methods that are not yet implemented. diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Verify.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/Verify.java similarity index 95% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Verify.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/Verify.java index d36c827236..afe441310d 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/Verify.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/Verify.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel; +package com.microsoft.semantickernel.implementation; import javax.annotation.Nullable; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizer.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/CodeTokenizer.java similarity index 95% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizer.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/CodeTokenizer.java index e98b61f3c9..fd023fa7b1 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizer.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/CodeTokenizer.java @@ -1,14 +1,15 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel; +package com.microsoft.semantickernel.implementation.tokenizer; -import com.microsoft.semantickernel.Verify; +import com.microsoft.semantickernel.implementation.Verify; import com.microsoft.semantickernel.exceptions.SKException; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.Block; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.FunctionIdBlock; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.NamedArgBlock; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.Symbols; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.ValBlock; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.VarBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.Block; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.FunctionIdBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.NamedArgBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.Symbols; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.ValBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.VarBlock; +import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException; import java.util.ArrayList; import java.util.Collections; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/DefaultPromptTemplate.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/DefaultPromptTemplate.java similarity index 87% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/DefaultPromptTemplate.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/DefaultPromptTemplate.java index d92ef82a36..c79e25c345 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/DefaultPromptTemplate.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/DefaultPromptTemplate.java @@ -1,20 +1,21 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel; +package com.microsoft.semantickernel.implementation.tokenizer; import com.microsoft.semantickernel.Kernel; -import com.microsoft.semantickernel.Verify; +import com.microsoft.semantickernel.implementation.Verify; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; import com.microsoft.semantickernel.semanticfunctions.InputVariable; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; +import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException; import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException.ErrorCodes; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.Block; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.BlockTypes; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.CodeRendering; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.NamedArgBlock; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.TextRendering; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.VarBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.Block; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.BlockTypes; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.CodeRendering; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.NamedArgBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.TextRendering; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.VarBlock; import java.util.HashSet; import java.util.List; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateTokenizer.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/TemplateTokenizer.java similarity index 95% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateTokenizer.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/TemplateTokenizer.java index 9963b5b52e..5afc2f4515 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/TemplateTokenizer.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/TemplateTokenizer.java @@ -1,10 +1,11 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel; +package com.microsoft.semantickernel.implementation.tokenizer; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.Block; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.CodeBlock; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.Symbols; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.TextBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.Block; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.CodeBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.Symbols; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.TextBlock; +import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/Block.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/Block.java similarity index 93% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/Block.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/Block.java index d4edfc29cc..3a8e1f33b9 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/Block.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/Block.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import javax.annotation.Nullable; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/BlockTypes.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/BlockTypes.java similarity index 87% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/BlockTypes.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/BlockTypes.java index 5730c588fa..f2ad3ca746 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/BlockTypes.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/BlockTypes.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; /** * Block types diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/CodeBlock.java similarity index 99% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeBlock.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/CodeBlock.java index 6c4a2070b8..4cd3661f66 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/CodeBlock.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.exceptions.SKException; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeRendering.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/CodeRendering.java similarity index 93% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeRendering.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/CodeRendering.java index 9a52f3c236..94aa93f826 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/CodeRendering.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/CodeRendering.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.orchestration.InvocationContext; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/FunctionIdBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/FunctionIdBlock.java similarity index 96% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/FunctionIdBlock.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/FunctionIdBlock.java index 910c90058b..d7dca4e585 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/FunctionIdBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/FunctionIdBlock.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/NamedArgBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/NamedArgBlock.java similarity index 95% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/NamedArgBlock.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/NamedArgBlock.java index 57ed8a7390..04c6380c1d 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/NamedArgBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/NamedArgBlock.java @@ -1,4 +1,4 @@ -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import javax.annotation.Nullable; @@ -6,9 +6,9 @@ import com.microsoft.semantickernel.exceptions.SKException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.microsoft.semantickernel.Verify; +import com.microsoft.semantickernel.implementation.Verify; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; -import static com.microsoft.semantickernel.templateengine.semantickernel.blocks.BlockTypes.NamedArg; +import static com.microsoft.semantickernel.implementation.tokenizer.blocks.BlockTypes.NamedArg; public class NamedArgBlock extends Block implements TextRendering { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/Symbols.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/Symbols.java similarity index 88% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/Symbols.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/Symbols.java index 94d1529556..352998277f 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/Symbols.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/Symbols.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; public class Symbols { diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/TextBlock.java similarity index 89% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextBlock.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/TextBlock.java index 03423551eb..e9c319d05a 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/TextBlock.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import javax.annotation.Nullable; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextRendering.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/TextRendering.java similarity index 87% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextRendering.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/TextRendering.java index 1bfce58155..45ebf69796 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/TextRendering.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/TextRendering.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/ValBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/ValBlock.java similarity index 96% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/ValBlock.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/ValBlock.java index 5addd3c427..c907a21777 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/ValBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/ValBlock.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/VarBlock.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/VarBlock.java similarity index 97% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/VarBlock.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/VarBlock.java index 121b6aaabf..17163f1f3f 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/semantickernel/blocks/VarBlock.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/tokenizer/blocks/VarBlock.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel.templateengine.semantickernel.blocks; +package com.microsoft.semantickernel.implementation.tokenizer.blocks; import javax.annotation.Nullable; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java index 31b6b273b1..3e3392bd9e 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/KernelFunction.java @@ -2,16 +2,19 @@ package com.microsoft.semantickernel.orchestration; import com.microsoft.semantickernel.Kernel; -import com.microsoft.semantickernel.Todo; +import com.microsoft.semantickernel.implementation.Todo; import com.microsoft.semantickernel.builders.Buildable; import com.microsoft.semantickernel.hooks.KernelHooks; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType; import com.microsoft.semantickernel.semanticfunctions.InputVariable; +import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromMethod; +import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; +import java.lang.reflect.Method; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -116,8 +119,8 @@ public abstract class KernelFunction implements Buildable { /** * Invokes this KernelFunction. *

- * If the {@code variableType} parameter is provided, the {@link ContextVarialbeType} is used to - * convert the result of the function to the the appropriate {@link FunctionResultType}. The + * If the {@code variableType} parameter is provided, the {@link ContextVariableType} is used to + * convert the result of the function to the appropriate {@link FunctionResult}. The * {@code variableType} is not required for converting well-known types such as {@link String} * and {@link Integer} which have pre-defined {@code ContextVariableType}s. *

@@ -157,6 +160,53 @@ public abstract class KernelFunction implements Buildable { return new FunctionInvocation<>(kernel, this); } + + /** + * Creates a {@link KernelFunction} instance for a method, specified via a {@link Method} + * instance + * + * @param The return type of the method. + * @param method The method to be represented via the created {@link KernelFunction}. + * @param target The target object for the {@code method} if it represents an instance method. + * This should be {@code null} if and only if {@code method} is a static method. + * @return The created {@link KernelFunction} wrapper for {@code method}. + */ + + public static KernelFunctionFromMethod.Builder createFromMethod( + Method method, + Object target) { + return KernelFunctionFromMethod.builder() + .withMethod(method) + .withTarget(target); + } + + /** + * Creates a {@link KernelFunction} instance based on a given prompt + * + * @param prompt The prompt to be used for the created {@link KernelFunction}. + * @param The return type of the method + * @return The builder for creating a {@link KernelFunction} instance. + */ + public static FromPromptBuilder createFromPrompt(String prompt) { + return KernelFunctionFromPrompt.builder() + .withTemplate(prompt); + } + + + /** + * Builder for creating a {@link KernelFunction} instance for a given + * {@link PromptTemplateConfig}. + * + * @param promptTemplateConfiguration The configuration for the prompt template. + * @param The return type of the method + * @return The builder for creating a {@link KernelFunction} instance. + */ + public static FromPromptBuilder createFromPrompt( + PromptTemplateConfig promptTemplateConfiguration) { + return KernelFunctionFromPrompt.builder() + .withPromptTemplateConfig(promptTemplateConfiguration); + } + /** * Builder for creating a {@link KernelFunction} from a prompt. * diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java deleted file mode 100644 index 0e5eac8a9a..0000000000 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelFunctionFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.microsoft.semantickernel.plugin; - -import com.microsoft.semantickernel.orchestration.KernelFunction; -import com.microsoft.semantickernel.orchestration.KernelFunction.FromPromptBuilder; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromMethod; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; -import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; -import java.lang.reflect.Method; - -/** - * Factory for creating {@link KernelFunction} instances. - */ -public class KernelFunctionFactory { - - /** - * Creates a {@link KernelFunction} instance for a method, specified via a {@link Method} - * instance - * - * @param The return type of the method. - * @param method The method to be represented via the created {@link KernelFunction}. - * @param target The target object for the {@code method} if it represents an instance method. - * This should be {@code null} if and only if {@code method} is a static method. - * @return The created {@link KernelFunction} wrapper for {@code method}. - */ - - public static KernelFunctionFromMethod.Builder createFromMethod( - Method method, - Object target) { - return KernelFunctionFromMethod.builder() - .withMethod(method) - .withTarget(target); - } - - /** - * Creates a {@link KernelFunction} instance based on a given prompt - * - * @param prompt The prompt to be used for the created {@link KernelFunction}. - * @param The return type of the method - * @return The builder for creating a {@link KernelFunction} instance. - */ - public static FromPromptBuilder createFromPrompt(String prompt) { - return KernelFunctionFromPrompt.builder() - .withTemplate(prompt); - } - - - /** - * Builder for creating a {@link KernelFunction} instance for a given - * {@link PromptTemplateConfig}. - * - * @param promptTemplateConfiguration The configuration for the prompt template. - * @param The return type of the method - * @return The builder for creating a {@link KernelFunction} instance. - */ - public static FromPromptBuilder createFromPrompt( - PromptTemplateConfig promptTemplateConfiguration) { - return KernelFunctionFromPrompt.builder() - .withPromptTemplateConfig(promptTemplateConfiguration); - } -} diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java index 19746c8ad7..c9abe3eaf4 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/plugin/KernelPluginFactory.java @@ -2,6 +2,8 @@ package com.microsoft.semantickernel.plugin; import com.fasterxml.jackson.databind.ObjectMapper; import com.microsoft.semantickernel.exceptions.SKException; +import com.microsoft.semantickernel.implementation.EmbeddedResourceLoader; +import com.microsoft.semantickernel.implementation.EmbeddedResourceLoader.ResourceLocation; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.contextvariables.CaseInsensitiveMap; import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction; @@ -11,9 +13,6 @@ import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactor import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; -import com.microsoft.semantickernel.util.EmbeddedResourceLoader; -import com.microsoft.semantickernel.util.EmbeddedResourceLoader.ResourceLocation; - import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -27,9 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; - import javax.annotation.Nullable; - import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,7 +60,7 @@ public class KernelPluginFactory { annotation.returnDescription(), returnType); - return KernelFunctionFactory + return KernelFunction .createFromMethod(method, target) .withFunctionName(annotation.name()) .withDescription(annotation.description()) diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index 396e41f3cc..df1f4063e4 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -4,7 +4,7 @@ import com.azure.core.exception.HttpResponseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.microsoft.semantickernel.AIService; +import com.microsoft.semantickernel.services.AIService; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.TextAIService; import com.microsoft.semantickernel.chatcompletion.AuthorRole; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java index 92602df415..eeece64dc7 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelPromptTemplateFactory.java @@ -3,7 +3,7 @@ package com.microsoft.semantickernel.semanticfunctions; import static com.microsoft.semantickernel.semanticfunctions.HandlebarsPromptTemplateFactory.HANDLEBARS_TEMPLATE_FORMAT; import static com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT; import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate; -import com.microsoft.semantickernel.templateengine.semantickernel.DefaultPromptTemplate; +import com.microsoft.semantickernel.implementation.tokenizer.DefaultPromptTemplate; import java.util.Locale; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/AIService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIService.java similarity index 98% rename from java/semantickernel-api/src/main/java/com/microsoft/semantickernel/AIService.java rename to java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIService.java index d9c6ba13e2..b077d432e6 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/AIService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIService.java @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -package com.microsoft.semantickernel; +package com.microsoft.semantickernel.services; import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java index daed186763..bd15df16c9 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelection.java @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.services; -import com.microsoft.semantickernel.AIService; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import javax.annotation.Nullable; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java index ae08beeab3..99d1773420 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.services; -import com.microsoft.semantickernel.AIService; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AiServiceCollection.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AiServiceCollection.java new file mode 100644 index 0000000000..e4db1417ab --- /dev/null +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AiServiceCollection.java @@ -0,0 +1,7 @@ +package com.microsoft.semantickernel.services; + +import java.util.HashMap; + +public class AiServiceCollection extends HashMap, AIService> { + +} diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java index 0374bfa7cd..96c4f1a3cd 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java @@ -1,6 +1,5 @@ package com.microsoft.semantickernel.services; -import com.microsoft.semantickernel.AIService; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; @@ -17,14 +16,14 @@ import javax.annotation.Nullable; */ public abstract class BaseAIServiceSelector implements AIServiceSelector { - protected final Map, AIService> services; + protected final AiServiceCollection services; /** * Initializes a new instance of the {@link BaseAIServiceSelector} class. * * @param services The services to select from. */ - protected BaseAIServiceSelector(Map, AIService> services) { + protected BaseAIServiceSelector(AiServiceCollection services) { this.services = services; } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java index eb2f13a1bc..9d723ff337 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java @@ -1,14 +1,12 @@ package com.microsoft.semantickernel.services; -import com.microsoft.semantickernel.AIService; -import com.microsoft.semantickernel.Verify; +import com.microsoft.semantickernel.implementation.Verify; import com.microsoft.semantickernel.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.orchestration.KernelFunction; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.textcompletion.TextGenerationService; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -34,7 +32,7 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector { * class with an empty collection of services. */ public OrderedAIServiceSelector() { - super(new HashMap<>()); + super(new AiServiceCollection()); } /** @@ -43,7 +41,7 @@ public class OrderedAIServiceSelector extends BaseAIServiceSelector { * * @param services The services to select from. */ - public OrderedAIServiceSelector(Map, AIService> services) { + public OrderedAIServiceSelector(AiServiceCollection services) { super(services); } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java index baf123f9c4..368a0b95a3 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/StreamingTextContent.java @@ -1,6 +1,7 @@ package com.microsoft.semantickernel.textcompletion; import com.microsoft.semantickernel.StreamingKernelContent; +import javax.annotation.Nullable; /** * StreamingTextContent is a wrapper for TextContent that allows for streaming. @@ -8,7 +9,8 @@ import com.microsoft.semantickernel.StreamingKernelContent; public class StreamingTextContent extends StreamingKernelContent { /** - * Initializes a new instance of the {@code StreamingTextContent} class with a provided text content. + * Initializes a new instance of the {@code StreamingTextContent} class with a provided text + * content. * * @param content The text content. */ @@ -18,8 +20,13 @@ public class StreamingTextContent extends StreamingKernelContent { @Override + @Nullable public String getContent() { - return ((TextContent)getInnerContent()).getContent(); + TextContent content = getInnerContent(); + if (content == null) { + return null; + } + return content.getContent(); } } diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java index b07f1c7159..248f48583c 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextContent.java @@ -6,7 +6,7 @@ import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; /** * Content from a text completion service. */ -public class TextContent extends KernelContent { +public class TextContent extends KernelContent { private final String content; diff --git a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java index cdacc65459..3e542d4495 100644 --- a/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java +++ b/java/semantickernel-api/src/main/java/com/microsoft/semantickernel/textcompletion/TextGenerationService.java @@ -6,7 +6,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.TextAIService; import com.microsoft.semantickernel.builders.Buildable; import com.microsoft.semantickernel.builders.SemanticKernelBuilder; -import com.microsoft.semantickernel.builders.ServiceLoadUtil; +import com.microsoft.semantickernel.implementation.ServiceLoadUtil; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import java.util.List; diff --git a/java/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java b/java/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java index 68c556c6a1..8bb666c525 100644 --- a/java/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java +++ b/java/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java @@ -3,13 +3,14 @@ package com.microsoft.semantickernel.templateengine.semantickernel; import java.util.List; +import com.microsoft.semantickernel.implementation.tokenizer.CodeTokenizer; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.microsoft.semantickernel.orchestration.KernelFunctionArguments; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.Block; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.FunctionIdBlock; -import com.microsoft.semantickernel.templateengine.semantickernel.blocks.NamedArgBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.Block; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.FunctionIdBlock; +import com.microsoft.semantickernel.implementation.tokenizer.blocks.NamedArgBlock; public class CodeTokenizerTest {