Merge branch 'fluent-function-factory' into format-3

This commit is contained in:
John Oliver
2024-02-15 13:55:11 +00:00
56 changed files with 526 additions and 272 deletions
@@ -7,9 +7,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;
@@ -87,18 +87,15 @@ public class Example05_InlineFunctionDefinitionTest {
WireMockUtil.mockCompletionResponse("Translate this date ", "a-response-3");
var fixedFunction = KernelFunctionFactory.<String>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 = KernelFunction.<String>createFromPrompt(message)
.withDefaultExecutionSettings(
PromptExecutionSettings.builder()
.withMaxTokens(100)
.build())
.build();
FunctionResult<String> fixedFunctionResult = kernel
.invokeAsync(fixedFunction)
@@ -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,29 +36,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 = KernelFunction
.<String>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 = KernelFunction
.<String>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 = KernelFunction
.<String>createFromPrompt(PromptFunctionConstants.GetConversationTopicsDefinition)
.withDefaultExecutionSettings(settings)
.withName("conversationTopics")
.withDescription(
"Analyze a conversation transcript and extract key topics worth remembering.")
.build();
}
/// <summary>
@@ -8,9 +8,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;
@@ -94,18 +94,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 = KernelFunction.createFromPrompt(message)
.withDefaultExecutionSettings(
PromptExecutionSettings.builder()
.withMaxTokens(100)
.build())
.build();
FunctionResult<?> fixedFunctionResult = kernel
.invokeAsync(fixedFunction)
@@ -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.PromptExecutionSettings.Builder;
import com.microsoft.semantickernel.plugin.KernelFunctionFactory;
import com.microsoft.semantickernel.orchestration.KernelFunction;
import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
import com.microsoft.semantickernel.plugin.KernelPlugin;
import com.microsoft.semantickernel.plugin.KernelPluginFactory;
import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction;
@@ -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
.<String>createFromPrompt(
functionDefinition,
new Builder()
var kindOfDay = KernelFunction.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");
@@ -78,16 +78,16 @@ 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"),
@@ -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 {
@@ -46,8 +46,9 @@ public class Example27_PromptFunctionsUsingChatGPT {
.withAIService(ChatCompletionService.class, openAIChatCompletion)
.build();
var func = KernelFunctionFactory.<String>createFromPrompt(
"List the two planets closest to '{{$input}}', excluding moons, using bullet points.");
var func = KernelFunction.<String>createFromPrompt(
"List the two planets closest to '{{$input}}', excluding moons, using bullet points.")
.build();
var result = func.invokeAsync(kernel)
.withArguments(
@@ -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;
@@ -77,7 +77,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.
@@ -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}}";
@@ -163,6 +163,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;
};
@@ -7,8 +7,8 @@ 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;
@@ -86,10 +86,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 = KernelFunction
.createFromPrompt(promptConfig)
.build();
result = kernel.invokeAsync(func).block();
System.out.println(result.getResult());
@@ -21,7 +21,7 @@ public class Example60_AdvancedMethodFunctions {
new FunctionsChainingPlugin(),
FunctionsChainingPlugin.PluginName);
kernel.getPlugins().add(functions);
kernel.addPlugin(functions);
ContextVariableTypeConverter<MyCustomType> type = new ContextVariableTypeConverter<>(
MyCustomType.class,
@@ -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;
@@ -83,7 +84,7 @@ public class Example62_CustomAIServiceSelector {
// A dumb AIServiceSelector that just returns the first service and execution settings it finds
static class CustomAIServiceSelector extends BaseAIServiceSelector {
public CustomAIServiceSelector(Map<Class<? extends AIService>, AIService> services) {
public CustomAIServiceSelector(AiServiceCollection services) {
super(services);
}
@@ -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,8 +25,10 @@ public class Example69_MutableKernelPlugin {
System.out.println("======== Example69_MutableKernelPlugin ========");
KernelPlugin plugin = new KernelPlugin("Plugin", "Mutable plugin", null);
plugin.addFunction(KernelFunctionFactory.createFromMethod(
Time.class.getMethod("date"), new Time(), "dateFunction", null, null, null));
plugin.addFunction(KernelFunction.createFromMethod(
Time.class.getMethod("date"), new Time())
.withFunctionName("dateFunction")
.build());
Kernel kernel = Kernel.builder().build();
kernel.addPlugin(plugin);
@@ -7,15 +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.HashMap;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import javax.annotation.Nullable;
@@ -106,12 +108,11 @@ 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()
*/
@SuppressFBWarnings("EI_EXPOSE_REP")
public List<KernelPlugin> getPlugins() {
return plugins.getPlugins();
public Collection<KernelPlugin> getPlugins() {
return Collections.unmodifiableCollection(plugins.getPlugins());
}
/**
@@ -193,10 +194,10 @@ public class Kernel implements Buildable {
*/
public static class Builder implements SemanticKernelBuilder<Kernel> {
private final Map<Class<? extends AIService>, AIService> services = new HashMap<>();
private final AiServiceCollection services = new AiServiceCollection();
private final List<KernelPlugin> plugins = new ArrayList<>();
@Nullable
private Function<Map<Class<? extends AIService>, AIService>, AIServiceSelector> serviceSelectorProvider;
private Function<AiServiceCollection, AIServiceSelector> serviceSelectorProvider;
/**
* Adds a service to the kernel.
@@ -226,7 +227,7 @@ public class Kernel implements Buildable {
* @return {@code this} builder with the service selector provider set.
*/
public Kernel.Builder withServiceSelector(
Function<Map<Class<? extends AIService>, AIService>, AIServiceSelector> serviceSelector) {
Function<AiServiceCollection, AIServiceSelector> serviceSelector) {
this.serviceSelectorProvider = serviceSelector;
return this;
}
@@ -8,7 +8,7 @@ import javax.annotation.Nullable;
* Base class which represents the content returned by an AI service.
* @param <T> The type of the content.
*/
public abstract class KernelContent<T extends KernelContent<T>> {
public abstract class KernelContent<T> {
/*
* The inner content representation. Use this to bypass the current
@@ -16,7 +16,7 @@ public abstract class KernelContent<T extends KernelContent<T>> {
* Use it only if strictly necessary.
*/
@Nullable
private final Object innerContent;
private final T innerContent;
/**
* The model ID used to generate the content.
@@ -37,7 +37,7 @@ public abstract class KernelContent<T extends KernelContent<T>> {
* @param metadata The metadata associated with the content.
*/
public KernelContent(
@Nullable Object innerContent,
@Nullable T innerContent,
@Nullable String modelId,
@Nullable FunctionResultMetadata metadata) {
this.innerContent = innerContent;
@@ -50,7 +50,7 @@ public abstract class KernelContent<T extends KernelContent<T>> {
* @return The inner content representation.
*/
@Nullable
public Object getInnerContent() {
public T getInnerContent() {
return innerContent;
}
@@ -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<KernelPlugin> getPlugins() {
return new ArrayList<>(plugins.values());
Collection<KernelPlugin> getPlugins() {
return Collections.unmodifiableCollection(plugins.values());
}
/**
@@ -10,7 +10,7 @@ import javax.annotation.Nullable;
* Base class which represents the content returned by a streaming AI service.
* @param <T> The type of the content.
*/
public abstract class StreamingKernelContent<T extends KernelContent<T>> extends KernelContent<T> {
public abstract class StreamingKernelContent<T> extends KernelContent<T> {
/**
* In a scenario of multiple choices per request, this represents
@@ -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
*/
@@ -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;
@@ -15,20 +15,21 @@ import javax.annotation.Nullable;
/**
* Represents the content of a chat message
*/
public class ChatMessageContent extends KernelContent<ChatMessageContent> {
public class ChatMessageContent<T> extends KernelContent<T> {
private AuthorRole authorRole;
@Nullable
private String content;
@Nullable
private List<KernelContent<?>> items;
private List<KernelContent<T>> 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,
@@ -44,18 +45,19 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* 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,
String content,
@Nullable String modelId,
@Nullable String innerContent,
@Nullable T innerContent,
@Nullable Charset encoding,
@Nullable FunctionResultMetadata metadata) {
super(innerContent, modelId, metadata);
@@ -66,18 +68,19 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* 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<KernelContent<?>> items,
List<KernelContent<T>> items,
String modelId,
String innerContent,
T innerContent,
Charset encoding,
FunctionResultMetadata metadata) {
super(innerContent, modelId, metadata);
@@ -89,6 +92,7 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* Gets the author role that generated the content
*
* @return the author role that generated the content
*/
public AuthorRole getAuthorRole() {
@@ -97,6 +101,7 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* Sets the author role that generated the content
*
* @param authorRole the author role that generated the content
*/
public void setAuthorRole(AuthorRole authorRole) {
@@ -105,6 +110,7 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* Gets the content
*
* @return the content, which may be {@code null}
*/
@Nullable
@@ -115,6 +121,7 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* Sets the content
*
* @param content the content
*/
public void setContent(@Nullable String content) {
@@ -123,22 +130,25 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* Gets the {@code KernelContent} items that comprise the content.
*
* @return the items, which may be {@code null}
*/
public List<KernelContent<?>> getItems() {
public List<KernelContent<T>> getItems() {
return Collections.unmodifiableList(items);
}
/**
* Sets the {@code KernelContent} items that comprise the content.
*
* @param items the items
*/
public void setItems(List<KernelContent<?>> items) {
public void setItems(List<KernelContent<T>> items) {
this.items = new ArrayList<>(items);
}
/**
* Gets the encoding of the content
*
* @return the encoding, which may be {@code null}
*/
@Nullable
@@ -148,6 +158,7 @@ public class ChatMessageContent extends KernelContent<ChatMessageContent> {
/**
* Sets the encoding of the content
*
* @param encoding the encoding
*/
public void setEncoding(Charset encoding) {
@@ -13,10 +13,10 @@ import javax.annotation.Nullable;
/**
* Represents the content of a chat message that is streamed.
*
* @param <T> the type of the inner content
*/
public class StreamingChatMessageContent<T extends KernelContent<T>>
extends StreamingKernelContent<T> {
public class StreamingChatMessageContent<T> extends StreamingKernelContent<T> {
private final String content;
private final AuthorRole role;
@@ -24,7 +24,8 @@ public class StreamingChatMessageContent<T extends KernelContent<T>>
/**
* 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 +38,14 @@ public class StreamingChatMessageContent<T extends KernelContent<T>>
/**
* 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,
@@ -71,6 +73,7 @@ public class StreamingChatMessageContent<T extends KernelContent<T>>
/**
* Gets the role of the author of the message
*
* @return the role of the author of the message
*/
public AuthorRole getRole() {
@@ -79,6 +82,7 @@ public class StreamingChatMessageContent<T extends KernelContent<T>>
/**
* Gets the encoding of the message
*
* @return the encoding of the message
*/
public Charset getEncoding() {
@@ -87,6 +91,7 @@ public class StreamingChatMessageContent<T extends KernelContent<T>>
/**
* Sets the encoding of the message
*
* @param encoding the encoding of the message
* @return this instance
*/
@@ -33,6 +33,7 @@ public class KernelHooks {
/**
* Creates a copy of the {@link KernelHooks}.
*
* @param kernelHooks the hooks to copy
*/
public KernelHooks(@Nullable KernelHooks kernelHooks) {
@@ -43,8 +44,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<String, KernelHook<?>> hooks) {
@@ -54,6 +55,7 @@ public class KernelHooks {
/**
* Creates an unmodifiable copy of this {@link KernelHooks}.
*
* @return an unmodifiable copy of this {@link KernelHooks}
*/
public UnmodifiableKernelHooks unmodifiableClone() {
@@ -62,6 +64,7 @@ public class KernelHooks {
/**
* Gets the hooks in this collection.
*
* @return an unmodifiable map of the hooks
*/
private Map<String, KernelHook<?>> getHooks() {
@@ -70,6 +73,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
*/
@@ -80,6 +84,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
*/
@@ -90,6 +95,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
*/
@@ -100,6 +106,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
*/
@@ -110,6 +117,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
*/
@@ -120,8 +128,9 @@ public class KernelHooks {
/**
* Executes the hooks in this collection that accept the event.
*
* @param event the event to execute the hooks on
* @param <T> the type of the event
* @param <T> the type of the event
* @return the event after the hooks have been executed
*/
@SuppressWarnings("unchecked")
@@ -131,17 +140,21 @@ public class KernelHooks {
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<T>) hook).apply(event);
}
}
return event;
return ((KernelHook<T>) 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 +164,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 +176,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 +186,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 +201,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() {
@@ -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;
@@ -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;
@@ -0,0 +1,14 @@
package com.microsoft.semantickernel.implementation;
/**
* 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");
}
}
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.implementation;
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+$");
}
}
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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
@@ -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;
@@ -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;
@@ -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;
@@ -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 {
@@ -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 {
@@ -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;
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.implementation.tokenizer.blocks;
import com.microsoft.semantickernel.orchestration.KernelFunctionArguments;
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.
* @param variables Optional variables used to render the block
* @return Rendered content
*/
@Nullable
String render(@Nullable KernelFunctionArguments variables);
}
@@ -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;
@@ -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;
@@ -2,29 +2,29 @@
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;
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 <T> The type of the result of the function
* @see com.microsoft.semantickernel.semanticfunctions
@@ -99,6 +99,7 @@ public abstract class KernelFunction<T> 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<String, PromptExecutionSettings> getExecutionSettings() {
@@ -107,6 +108,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Get the metadata for the function.
*
* @return The metadata for the function
*/
public KernelFunctionMetadata<?> getMetadata() {
@@ -116,8 +118,8 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Invokes this KernelFunction.
* <p>
* 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.
* <p>
@@ -148,14 +150,60 @@ public abstract class KernelFunction<T> 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<T> invokeAsync(Kernel kernel) {
return new FunctionInvocation<>(kernel, this);
}
/**
* Creates a {@link KernelFunction} instance for a method, specified via a {@link Method}
* instance
*
* @param <T> 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 <T> KernelFunctionFromMethod.Builder<T> createFromMethod(
Method method,
Object target) {
return KernelFunctionFromMethod.<T>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 <T> The return type of the method
* @return The builder for creating a {@link KernelFunction} instance.
*/
public static <T> FromPromptBuilder<T> createFromPrompt(String prompt) {
return KernelFunctionFromPrompt.<T>builder()
.withTemplate(prompt);
}
/**
* Builder for creating a {@link KernelFunction} instance for a given
* {@link PromptTemplateConfig}.
*
* @param promptTemplateConfiguration The configuration for the prompt template.
* @param <T> The return type of the method
* @return The builder for creating a {@link KernelFunction} instance.
*/
public static <T> FromPromptBuilder<T> createFromPrompt(
PromptTemplateConfig promptTemplateConfiguration) {
return KernelFunctionFromPrompt.<T>builder()
.withPromptTemplateConfig(promptTemplateConfiguration);
}
/**
* Builder for creating a {@link KernelFunction} from a prompt.
*
@@ -183,6 +231,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Set the prompt template for the function.
*
* @param promptTemplate The prompt template for the function
* @return The builder
*/
@@ -191,6 +240,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Set the execution settings for the function.
*
* @param executionSettings The execution settings for the function
* @return The builder
*/
@@ -199,7 +249,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Set the default execution settings for the function.
*
*
* @param executionSettings The default execution settings for the function
* @return The builder
*/
@@ -208,7 +258,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Set the description of the function.
*
*
* @param description The description of the function
* @return The builder
*/
@@ -216,7 +266,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Set the template for the function.
*
*
* @param template The template for the function
* @return The builder
*/
@@ -224,12 +274,14 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Create a new KernelFunction instance from the builder.
*
* @return The new KernelFunction instance
*/
KernelFunction<T> build();
/**
* Set the template format for the function.
*
* @param templateFormat The template format for the function
* @return The builder
*/
@@ -237,6 +289,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Set the output variable for the function.
*
* @param outputVariable The output variable for the function
* @return The builder
*/
@@ -244,14 +297,16 @@ public abstract class KernelFunction<T> 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<T> 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
*/
@@ -260,6 +315,7 @@ public abstract class KernelFunction<T> implements Buildable {
/**
* Set the prompt template config used to build the function.
*
* @param promptTemplateConfig The prompt template config for the function
* @return The builder
*/
@@ -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,14 +60,13 @@ public class KernelPluginFactory {
annotation.returnDescription(),
returnType);
return KernelFunctionFactory
.createFromMethod(
method,
target,
annotation.name(),
annotation.description(),
getParameters(method),
kernelReturnParameterMetadata);
return KernelFunction
.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,8 +132,7 @@ public class KernelPluginFactory {
@Nullable List<KernelFunction<?>> functions) {
Map<String, KernelFunction<?>> 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);
}
@@ -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 <T> the return type of the function
*/
public class KernelFunctionFromMethod<T> extends KernelFunction<T> {
public class KernelFunctionFromMethod<T> extends KernelFunction<T> implements Buildable {
private final static Logger LOGGER = LoggerFactory.getLogger(KernelFunctionFromMethod.class);
@@ -89,10 +87,10 @@ public class KernelFunctionFromMethod<T> extends KernelFunction<T> {
/**
* 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
*/
@@ -107,13 +105,13 @@ public class KernelFunctionFromMethod<T> extends KernelFunction<T> {
/**
* 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 <T> the return type of the function
* @param <T> the return type of the function
* @return a new instance of {@link KernelFunctionFromMethod}
*/
@SuppressWarnings("unchecked")
@@ -576,4 +574,74 @@ public class KernelFunctionFromMethod<T> extends KernelFunction<T> {
defaultValue,
isRequired);
}
public static <T> Builder<T> builder() {
return new Builder<>();
}
public static class Builder<T> {
private Method method;
private Object target;
@Nullable
private String functionName;
@Nullable
private String description;
@Nullable
private List<KernelParameterMetadata<?>> parameters;
@Nullable
private KernelReturnParameterMetadata<?> returnParameter;
public Builder<T> withMethod(Method method) {
this.method = method;
return this;
}
public Builder<T> withTarget(Object target) {
this.target = target;
return this;
}
public Builder<T> withFunctionName(String functionName) {
this.functionName = functionName;
return this;
}
public Builder<T> withDescription(String description) {
this.description = description;
return this;
}
public Builder<T> withParameters(List<KernelParameterMetadata<?>> parameters) {
this.parameters = parameters;
return this;
}
public Builder<T> withReturnParameter(KernelReturnParameterMetadata<?> returnParameter) {
this.returnParameter = returnParameter;
return this;
}
public <T> KernelFunction<T> 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);
}
}
}
@@ -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;
@@ -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<T> extends KernelFunction<T> {
/**
* 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(
@@ -83,11 +79,11 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
}
/**
* 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 <T> the type of the return value of the function
* @param <T> the type of the return value of the function
* @return a new instance of {@link KernelFunction}
*/
public static <T> KernelFunction<T> create(
@@ -99,13 +95,13 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
/**
* 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 <T> 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 <T> the type of the return value of the function
* @return a new instance of {@link KernelFunction}
*/
public static <T> KernelFunction<T> create(
@@ -123,8 +119,8 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
* {@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 <T> the type of the return value of the function
* @param promptConfig the configuration for the prompt
* @param <T> the type of the return value of the function
* @return a new instance of {@link KernelFunction}
*/
public static <T> KernelFunction<T> create(
@@ -138,7 +134,7 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
private Flux<FunctionResult<T>> invokeInternalAsync(
Kernel kernel,
@Nullable KernelFunctionArguments arguments,
@Nullable KernelFunctionArguments argumentsIn,
@Nullable ContextVariableType<T> contextVariableType,
@Nullable InvocationContext invocationContext) {
@@ -152,7 +148,9 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
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<T> variableType = contextVariableType != null
@@ -161,7 +159,7 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
(Class<T>) this.getMetadata().getReturnParameter().getParameterType());
return this.template
.renderAsync(kernel, preRenderingHookResult.getArguments(), context)
.renderAsync(kernel, arguments, context)
.flatMapMany(prompt -> {
PromptRenderedEvent promptHookResult = kernelHooks
.executeHooks(new PromptRenderedEvent(this, arguments, prompt));
@@ -408,7 +406,8 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
/**
* Creates a {@link KernelFunction} instance for a prompt specified via a prompt template.
* @param <T> the type of the return value of the function
*
* @param <T> the type of the return value of the function
* @param promptTemplate the prompt template for the function
* @return a new instance of {@link KernelFunction}
*/
@@ -418,15 +417,18 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
}
/**
* 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 <T> 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 <T> the type of the return value of the function
* @return a new instance of {@link KernelFunction}
*/
@SuppressWarnings("unchecked")
@@ -458,6 +460,7 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
/**
* Creates a new instance of {@link Builder}.
*
* @param <T> The type of the return value of the function
* @return a new instance of {@link Builder}
*/
@@ -467,6 +470,7 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
/**
* A builder for creating a {@link KernelFunction} from a prompt template.
*
* @param <T> the type of the return value of the function
*/
public static final class Builder<T> implements FromPromptBuilder<T> {
@@ -489,7 +493,7 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
@Nullable
private PromptTemplateFactory promptTemplateFactory;
@Nullable
private PromptTemplateConfig functionModel;
private PromptTemplateConfig promptTemplateConfig;
@Override
public FromPromptBuilder<T> withName(@Nullable String name) {
@@ -585,22 +589,33 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
@Override
public FromPromptBuilder<T> withPromptTemplateConfig(
@Nullable PromptTemplateConfig functionModel) {
this.functionModel = functionModel;
@Nullable PromptTemplateConfig promptTemplateConfig) {
this.promptTemplateConfig = promptTemplateConfig;
return this;
}
@Override
public KernelFunction<T> 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,
promptTemplateConfig,
executionSettings);
}
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -0,0 +1,7 @@
package com.microsoft.semantickernel.services;
import java.util.HashMap;
public class AiServiceCollection extends HashMap<Class<? extends AIService>, AIService> {
}
@@ -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<Class<? extends AIService>, 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<Class<? extends AIService>, AIService> services) {
protected BaseAIServiceSelector(AiServiceCollection services) {
this.services = services;
}
@@ -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<Class<? extends AIService>, AIService> services) {
public OrderedAIServiceSelector(AiServiceCollection services) {
super(services);
}
@@ -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;
@@ -208,7 +209,7 @@ public class HandlebarsPromptTemplate implements PromptTemplate {
private static Handlebars.SafeString handleFunctions(Kernel kernel, Options options)
throws IOException {
StringBuilder sb = new StringBuilder("<functions>");
List<KernelPlugin> plugins = kernel.getPlugins();
Collection<KernelPlugin> plugins = kernel.getPlugins();
sb.append(options.fn(plugins));
sb.append("</functions>");
@@ -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<TextContent> {
/**
* 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.
*/
@@ -17,8 +19,13 @@ public class StreamingTextContent extends StreamingKernelContent<TextContent> {
}
@Override
@Nullable
public String getContent() {
return ((TextContent) getInnerContent()).getContent();
TextContent content = getInnerContent();
if (content == null) {
return null;
}
return content.getContent();
}
}
@@ -6,7 +6,7 @@ import com.microsoft.semantickernel.orchestration.FunctionResultMetadata;
/**
* Content from a text completion service.
*/
public class TextContent extends KernelContent<TextContent> {
public class TextContent extends KernelContent<String> {
private final String content;
@@ -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;
@@ -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 {