fixes from review

This commit is contained in:
John Oliver
2024-02-07 22:55:58 +00:00
parent 5c10869c76
commit b205edfb93
12 changed files with 182 additions and 223 deletions
@@ -267,7 +267,7 @@ public class OpenAIChatCompletion implements ChatCompletionService {
String pluginName = parts.length > 0 ? parts[0] : "";
String fnName = parts.length > 1 ? parts[1] : "";
JsonNode parameters = jsonNode.get("parameters");
KernelFunction kernelFunction = kernel.getPlugins().getFunction(pluginName, fnName);
KernelFunction<?> kernelFunction = kernel.getPlugins().getFunction(pluginName, fnName);
if (kernelFunction == null) {
return Mono.empty();
}
@@ -285,7 +285,10 @@ public class OpenAIChatCompletion implements ChatCompletionService {
}
ContextVariableType<String> variableType = ContextVariableTypes.getGlobalVariableTypeForClass(
String.class);
return kernelFunction.invokeAsync(kernel, arguments, variableType);
return kernelFunction
.invokeAsync(kernel)
.withArguments(arguments)
.withResultType(variableType);
}
private static ChatCompletionsOptions getCompletionsOptions(
@@ -1,7 +1,5 @@
package com.microsoft.semantickernel.samples.plugins;
import java.util.List;
import com.microsoft.semantickernel.Kernel;
import com.microsoft.semantickernel.orchestration.KernelFunction;
import com.microsoft.semantickernel.orchestration.KernelFunctionArguments;
@@ -11,7 +9,7 @@ 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;
import java.util.List;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -125,18 +123,22 @@ public class ConversationSummaryPlugin {
return processAsync(this.conversationTopicsFunction, input, kernel);
}
private static Mono<String> processAsync(KernelFunction<String> func, String input, Kernel kernel) {
private static Mono<String> processAsync(KernelFunction<String> func, String input,
Kernel kernel) {
List<String> lines = TextChunker.splitPlainTextLines(input, MaxTokens);
List<String> paragraphs = TextChunker.splitPlainTextParagraphs(lines, MaxTokens);
return Flux.fromIterable(paragraphs)
.concatMap(paragraph -> {
// The first parameter is the input text.
return func.invokeAsync(kernel,
new KernelFunctionArguments.Builder()
.withInput(paragraph)
.build(),
ContextVariableTypes.getGlobalVariableTypeForClass(String.class));
return func.invokeAsync(kernel)
.withArguments(
new KernelFunctionArguments.Builder()
.withInput(paragraph)
.build()
)
.withResultType(
ContextVariableTypes.getGlobalVariableTypeForClass(String.class));
})
.reduce("", (acc, next) -> {
return acc + "\n" + next.getResult();
@@ -50,13 +50,12 @@ public class Example27_PromptFunctionsUsingChatGPT {
var func = KernelFunctionFactory.<String>createFromPrompt(
"List the two planets closest to '{{$input}}', excluding moons, using bullet points.");
var result = func.invokeAsync(
kernel,
var result = func.invokeAsync(kernel)
.withArguments(
KernelFunctionArguments.builder()
.withVariable("input", "Jupiter")
.build(),
ContextVariableTypes.getGlobalVariableTypeForClass(String.class)
)
.build())
.withResultType(ContextVariableTypes.getGlobalVariableTypeForClass(String.class))
.block();
System.out.println(result.getResult());
@@ -1,9 +1,5 @@
package com.microsoft.semantickernel.samples.syntaxexamples;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.OpenAIClientBuilder;
import com.azure.ai.openai.models.ChatCompletionsOptions;
@@ -25,7 +21,6 @@ import com.microsoft.semantickernel.hooks.KernelHooks;
import com.microsoft.semantickernel.hooks.PreChatCompletionEvent;
import com.microsoft.semantickernel.hooks.PromptRenderedEvent;
import com.microsoft.semantickernel.orchestration.FunctionResult;
import com.microsoft.semantickernel.orchestration.InvocationContext;
import com.microsoft.semantickernel.orchestration.KernelFunctionArguments;
import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
@@ -402,17 +397,11 @@ public class Example57_KernelHooks {
);
});
InvocationContext invocationContext = InvocationContext.builder()
.withKernelHooks(kernelHooks)
.build();
try {
// Invoke prompt to trigger execution hooks.
var result = kernel.invokeAsync(
writerFunction,
KernelFunctionArguments.builder().build(),
null,
invocationContext)
var result = kernel.invokeAsync(writerFunction)
.withArguments(KernelFunctionArguments.builder().build())
.addKernelHooks(kernelHooks)
.block();
System.out.println("Function Result: " + result.getResult());
} catch (Exception e) {
@@ -4,11 +4,8 @@ package com.microsoft.semantickernel;
import com.microsoft.semantickernel.builders.Buildable;
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
import com.microsoft.semantickernel.hooks.KernelHooks;
import com.microsoft.semantickernel.orchestration.FunctionResult;
import com.microsoft.semantickernel.orchestration.InvocationContext;
import com.microsoft.semantickernel.orchestration.FunctionInvocation;
import com.microsoft.semantickernel.orchestration.KernelFunction;
import com.microsoft.semantickernel.orchestration.KernelFunctionArguments;
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType;
import com.microsoft.semantickernel.plugin.KernelPlugin;
import com.microsoft.semantickernel.plugin.KernelPluginCollection;
import com.microsoft.semantickernel.semanticfunctions.PromptTemplate;
@@ -20,21 +17,15 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
/**
* Interface for the semantic kernel.
*/
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;
@@ -61,41 +52,8 @@ public class Kernel implements Buildable {
return invokeAsync(function);
}
public <T> Mono<FunctionResult<T>> invokeAsync(
KernelFunction<T> function,
@Nullable KernelFunctionArguments arguments,
@Nullable ContextVariableType<T> variableType,
@Nullable InvocationContext invocationContext) {
Objects.requireNonNull(function, "function");
// Ever other invokeAsync call should end up here...
// If there are hooks added to the global kernel hooks, create a new invocation context
// with the global hooks and the invocation context hooks merged together.
KernelHooks hooks = new KernelHooks(getGlobalKernelHooks());
if (!hooks.isEmpty()) {
if (invocationContext != null) {
hooks.append(invocationContext.getKernelHooks());
}
InvocationContext.Builder builder = InvocationContext.builder()
.withKernelHooks(hooks);
if (invocationContext != null) {
builder = builder
.withPromptExecutionSettings(invocationContext.getPromptExecutionSettings())
.withToolCallBehavior(invocationContext.getToolCallBehavior());
}
invocationContext = builder.build();
}
return function.invokeAsync(this, arguments, variableType, invocationContext);
}
public <T> FunctionInvocation<T> invokeAsync(KernelFunction<T> function) {
return new FunctionInvocation<>(this, function);
return function.invokeAsync(this);
}
@@ -104,6 +104,11 @@ public class KernelHooks {
return hooks.isEmpty();
}
public KernelHooks addHooks(KernelHooks hooks) {
this.hooks.putAll(hooks.getHooks());
return this;
}
public static class UnmodifiableKernelHooks extends KernelHooks {
private UnmodifiableKernelHooks(KernelHooks kernelHooks) {
@@ -1,14 +1,10 @@
package com.microsoft.semantickernel;
package com.microsoft.semantickernel.orchestration;
import com.microsoft.semantickernel.Kernel;
import com.microsoft.semantickernel.exceptions.SKException;
import com.microsoft.semantickernel.hooks.KernelHook;
import com.microsoft.semantickernel.hooks.KernelHooks;
import com.microsoft.semantickernel.hooks.KernelHooks.UnmodifiableKernelHooks;
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.PromptExecutionSettings;
import com.microsoft.semantickernel.orchestration.ToolCallBehavior;
import com.microsoft.semantickernel.orchestration.ToolCallBehavior.UnmodifiableToolCallBehavior;
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType;
@@ -25,20 +21,21 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
private static final Logger LOGGER = LoggerFactory.getLogger(FunctionInvocation.class);
private final KernelFunction<?> function;
private final Kernel kernel;
protected final KernelFunction<?> function;
protected final Kernel kernel;
@Nullable
private final ContextVariableType<T> resultType;
protected final ContextVariableType<T> resultType;
@Nullable
private KernelFunctionArguments arguments;
protected KernelFunctionArguments arguments;
@Nullable
private UnmodifiableKernelHooks hooks;
protected UnmodifiableKernelHooks hooks;
@Nullable
private PromptExecutionSettings promptExecutionSettings;
protected PromptExecutionSettings promptExecutionSettings;
@Nullable
private UnmodifiableToolCallBehavior toolCallBehavior;
private final ContextVariableTypes contextVariableTypes = new ContextVariableTypes();
protected UnmodifiableToolCallBehavior toolCallBehavior;
protected final ContextVariableTypes contextVariableTypes = new ContextVariableTypes();
public FunctionInvocation(
@@ -47,6 +44,7 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
this.function = function;
this.kernel = kernel;
this.resultType = null;
this.addKernelHooks(kernel.getGlobalKernelHooks());
}
public FunctionInvocation(
@@ -60,6 +58,7 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
if (resultType != null) {
contextVariableTypes.putConverter(resultType.getConverter());
}
this.addKernelHooks(kernel.getGlobalKernelHooks());
}
public FunctionInvocation<T> withArguments(
@@ -79,15 +78,25 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
function,
resultType)
.withArguments(arguments)
.withKernelHooks(hooks)
.addKernelHooks(hooks)
.withPromptExecutionSettings(promptExecutionSettings)
.withToolCallBehavior(toolCallBehavior);
}
public FunctionInvocation<T> withKernelHooks(
public FunctionInvocation<T> addKernelHook(@Nullable KernelHook hook) {
KernelHooks clone = new KernelHooks(this.hooks);
clone.addHook(hook);
this.hooks = unmodifiableClone(clone);
return this;
}
public FunctionInvocation<T> addKernelHooks(
@Nullable
KernelHooks hooks) {
this.hooks = unmodifiableClone(hooks);
if (hooks == null) {
return this;
}
this.hooks = unmodifiableClone(new KernelHooks(this.hooks).addHooks(hooks));
return this;
}
@@ -108,6 +117,25 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
return this;
}
public FunctionInvocation<T> withTypes(ContextVariableTypes contextVariableTypes) {
this.contextVariableTypes.putConverters(contextVariableTypes);
return this;
}
public FunctionInvocation<T> withInvocationContext(
@Nullable InvocationContext invocationContext) {
if (invocationContext == null) {
return this;
}
withTypes(invocationContext.getContextVariableTypes());
withToolCallBehavior(invocationContext.getToolCallBehavior());
withPromptExecutionSettings(invocationContext.getPromptExecutionSettings());
addKernelHooks(invocationContext.getKernelHooks());
return this;
}
@Override
public void subscribe(CoreSubscriber<? super FunctionResult<T>> coreSubscriber) {
performSubscribe(
@@ -124,32 +152,6 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
));
}
@Nullable
private static UnmodifiableToolCallBehavior unmodifiableClone(
@Nullable
ToolCallBehavior toolCallBehavior) {
if (toolCallBehavior instanceof UnmodifiableToolCallBehavior) {
return (UnmodifiableToolCallBehavior) toolCallBehavior;
} else if (toolCallBehavior != null) {
return toolCallBehavior.unmodifiableClone();
} else {
return null;
}
}
@Nullable
private static UnmodifiableKernelHooks unmodifiableClone(
@Nullable KernelHooks kernelHooks) {
if (kernelHooks instanceof UnmodifiableKernelHooks) {
return (UnmodifiableKernelHooks) kernelHooks;
} else if (kernelHooks != null) {
return kernelHooks.unmodifiableClone();
} else {
return null;
}
}
// Extracted to static to ensure mutable state is not used
private static <T> void performSubscribe(
CoreSubscriber<? super FunctionResult<T>> coreSubscriber,
@@ -162,7 +164,6 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
@Nullable
InvocationContext context
) {
if (variableType == null) {
LOGGER.debug(
"No variable type explicitly specified by calling 'withResultType' for function invocation: "
@@ -176,7 +177,7 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
new KernelFunctionArguments(arguments),
null,
new InvocationContext(context))
.handle(FunctionInvocation.convertToType(variableType))
.handle(convertToType(variableType))
.subscribe(coreSubscriber);
}
@@ -204,4 +205,29 @@ public class FunctionInvocation<T> extends Mono<FunctionResult<T>> {
};
}
@Nullable
private static UnmodifiableToolCallBehavior unmodifiableClone(
@Nullable
ToolCallBehavior toolCallBehavior) {
if (toolCallBehavior instanceof UnmodifiableToolCallBehavior) {
return (UnmodifiableToolCallBehavior) toolCallBehavior;
} else if (toolCallBehavior != null) {
return toolCallBehavior.unmodifiableClone();
} else {
return null;
}
}
@Nullable
private static UnmodifiableKernelHooks unmodifiableClone(
@Nullable KernelHooks kernelHooks) {
if (kernelHooks instanceof UnmodifiableKernelHooks) {
return (UnmodifiableKernelHooks) kernelHooks;
} else if (kernelHooks != null) {
return kernelHooks.unmodifiableClone();
} else {
return null;
}
}
}
@@ -1,39 +1,36 @@
// 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;
import com.microsoft.semantickernel.hooks.KernelHooks;
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableType;
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariableTypes;
import com.microsoft.semantickernel.semanticfunctions.InputVariable;
import com.microsoft.semantickernel.semanticfunctions.OutputVariable;
import com.microsoft.semantickernel.semanticfunctions.PromptTemplate;
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
*
* @param <T> The type of the result of the function
*/
// TODO: add example of using ContextVariableType to class documentation
public abstract class KernelFunction<T> implements Buildable {
/// <summary>
/// <summary>
/// Gets the metadata describing the function.
/// </summary>
/// <returns>An instance of <see cref="KernelFunctionMetadata"/> describing the function</returns>
private final KernelFunctionMetadata metadata;
private final KernelFunctionMetadata<?> metadata;
/// <summary>
/// Gets the prompt execution settings.
@@ -42,7 +39,7 @@ public abstract class KernelFunction<T> implements Buildable {
private final Map<String, PromptExecutionSettings> executionSettings;
protected KernelFunction(
KernelFunctionMetadata metadata,
KernelFunctionMetadata<?> metadata,
@Nullable
Map<String, PromptExecutionSettings> executionSettings) {
this.metadata = metadata;
@@ -56,7 +53,7 @@ public abstract class KernelFunction<T> implements Buildable {
* @return The name of the skill that this function is within
*/
public String getSkillName() {
return metadata.getName();
return metadata.getName();
}
/**
@@ -92,86 +89,52 @@ public abstract class KernelFunction<T> implements Buildable {
public String toManualString(boolean includeOutputs) {
throw new Todo();
}
public Map<String, PromptExecutionSettings> getExecutionSettings() {
return Collections.unmodifiableMap(executionSettings);
}
public KernelFunctionMetadata getMetadata() {
public KernelFunctionMetadata<?> getMetadata() {
return metadata;
}
/**
* Invokes this KernelFunction. This is the most typical use case.
*
* @param kernel The Kernel containing services, plugins, and other state for
* use throughout the operation.
* @param arguments The arguments to pass to the function's invocation
* @return The result of the function's execution.
* @see FunctionResult#getResultVariable()
*/
public Mono<FunctionResult<T>> invokeAsync(
Kernel kernel,
@Nullable KernelFunctionArguments arguments) {
return invokeAsync(kernel, arguments, null);
}
/**
* 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 {@code variableType} is
* not required for converting well-known types such as {@link String} and {@link Integer}
* which have pre-defined {@code ContextVariableType}s.
*
* @param kernel The Kernel containing services, plugins, and other state for
* use throughout the operation.
* @param arguments The arguments to pass to the function's invocation
* @param variableType The type of the {@link ContextVariable} returned in the {@link FunctionResult}
* @return The result of the function's execution.
* @see FunctionResult#getResultVariable()
* @see ContextVariableTypes#getDefaultVariableTypeForClass(Class)
*/
public Mono<FunctionResult<T>> invokeAsync(
Kernel kernel,
@Nullable KernelFunctionArguments arguments,
@Nullable ContextVariableType<T> variableType) {
return invokeAsync(kernel, arguments, variableType, null);
}
/**
* Invokes this KernelFunction.
* 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 {@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>
* The {@link InvocationContext} allows for customization of the
* behavior of function, including the ability to pass in {@link KernelHooks}
* {@link PromptExecutionSettings}, and {@link ToolCallBehavior}.
* <p>
* The difference between calling the {@code KernelFunction.invokeAsync} method
* directly and calling the {@code Kernel.invokeAsync} method is that the latter
* adds the {@link KernelHooks#getGlobalHooks() global KernelHooks} (if any)
* to the {@link InvocationContext}. Calling {@code KernelFunction.invokeAsync}
* directly does not add the global hooks.
* 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
* {@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>
* The {@link InvocationContext} allows for customization of the behavior of function, including
* the ability to pass in {@link KernelHooks} {@link PromptExecutionSettings}, and
* {@link ToolCallBehavior}.
* <p>
* The difference between calling the {@code KernelFunction.invokeAsync} method directly and
* calling the {@code Kernel.invokeAsync} method is that the latter adds the
* {@link KernelHooks#getGlobalHooks() global KernelHooks} (if any) to the
* {@link InvocationContext}. Calling {@code KernelFunction.invokeAsync} directly does not add
* the global hooks.
*
* @param kernel The Kernel containing services, plugins, and other state for
* use throughout the operation.
* @param arguments The arguments to pass to the function's invocation
* @param variableType The type of the {@link ContextVariable} returned in the {@link FunctionResult}
* @param kernel The Kernel containing services, plugins, and other state for use
* throughout the operation.
* @param arguments The arguments to pass to the function's invocation
* @param variableType The type of the {@link ContextVariable} returned in the
* {@link FunctionResult}
* @param invocationContext The arguments to pass to the function's invocation
* @return The result of the function's execution.
* @see FunctionResult#getResultVariable()
*/
public abstract Mono<FunctionResult<T>> invokeAsync(
*/
protected abstract Mono<FunctionResult<T>> invokeAsync(
Kernel kernel,
@Nullable KernelFunctionArguments arguments,
@Nullable ContextVariableType<T> variableType,
@Nullable InvocationContext invocationContext);
public FunctionInvocation<T> invokeAsync(Kernel kernel) {
return new FunctionInvocation<>(kernel, this);
}
public interface FromPromptBuilder<T> {
FromPromptBuilder<T> withName(@Nullable String name);
@@ -32,26 +32,35 @@ public class ContextVariableTypes {
new InstantContextVariableTypeConverter(),
new CompletionUsageContextVariableTypeConverter(),
new NumberVariableContextVariableTypeConverter<>(Byte.class, Byte::parseByte),
new NumberVariableContextVariableTypeConverter<>(byte.class, Byte::parseByte),
new NumberVariableContextVariableTypeConverter<>(Byte.class, Byte::parseByte,
Number::byteValue),
new NumberVariableContextVariableTypeConverter<>(byte.class, Byte::parseByte,
Number::byteValue),
new NumberVariableContextVariableTypeConverter<>(Integer.class, Integer::parseInt),
new NumberVariableContextVariableTypeConverter<>(Integer.class, Integer::parseInt,
Number::intValue),
new NumberVariableContextVariableTypeConverter<>(int.class, Integer::parseInt,
Number::intValue),
new NumberVariableContextVariableTypeConverter<>(int.class, Integer::parseInt),
new NumberVariableContextVariableTypeConverter<>(Long.class, Long::parseLong),
new NumberVariableContextVariableTypeConverter<>(long.class, Long::parseLong),
new NumberVariableContextVariableTypeConverter<>(Long.class, Long::parseLong,
Number::longValue),
new NumberVariableContextVariableTypeConverter<>(long.class, Long::parseLong,
Number::longValue),
new NumberVariableContextVariableTypeConverter<>(Double.class, Double::parseDouble),
new NumberVariableContextVariableTypeConverter<>(Double.class, Double::parseDouble,
Number::doubleValue),
new NumberVariableContextVariableTypeConverter<>(double.class, Double::parseDouble,
Number::doubleValue),
new NumberVariableContextVariableTypeConverter<>(double.class, Double::parseDouble),
new NumberVariableContextVariableTypeConverter<>(Float.class, Float::parseFloat,
Number::floatValue),
new NumberVariableContextVariableTypeConverter<>(float.class, Float::parseFloat,
Number::floatValue),
new NumberVariableContextVariableTypeConverter<>(Float.class, Float::parseFloat),
new NumberVariableContextVariableTypeConverter<>(float.class, Float::parseFloat),
new NumberVariableContextVariableTypeConverter<>(Short.class, Short::parseShort),
new NumberVariableContextVariableTypeConverter<>(short.class, Short::parseShort));
new NumberVariableContextVariableTypeConverter<>(Short.class, Short::parseShort,
Number::shortValue),
new NumberVariableContextVariableTypeConverter<>(short.class, Short::parseShort,
Number::shortValue));
DEFAULT_TYPES = new ContextVariableTypes(types);
}
@@ -159,4 +168,7 @@ public class ContextVariableTypes {
() -> new SKException("Unknown context variable type: " + aClass.getName()));
}
public void putConverters(ContextVariableTypes contextVariableTypes) {
this.variableTypes.putAll(contextVariableTypes.variableTypes);
}
}
@@ -9,13 +9,19 @@ import javax.annotation.Nullable;
public class NumberVariableContextVariableTypeConverter<T extends Number> extends
ContextVariableTypeConverter<T> {
public NumberVariableContextVariableTypeConverter(Class<T> clazz,
Function<String, T> fromPromptString) {
private final Function<Number, T> fromNumber;
public NumberVariableContextVariableTypeConverter(
Class<T> clazz,
Function<String, T> fromPromptString,
Function<Number, T> fromNumber
) {
super(
clazz,
s -> convert(s, clazz),
Number::toString,
fromPromptString);
this.fromNumber = fromNumber;
}
@Override
@@ -46,6 +52,11 @@ public class NumberVariableContextVariableTypeConverter<T extends Number> extend
if (obj != null) {
return obj;
}
if (s instanceof Number) {
return fromNumber.apply((Number) s);
}
if (s instanceof String) {
return fromPromptString((String) s);
}
@@ -76,16 +76,7 @@ public class KernelFunctionFromMethod<T> extends KernelFunction<T> {
return function.invoke(kernel, this, arguments, variableType, invocationContext);
}
@Override
public Mono<FunctionResult<T>> invokeAsync(
Kernel kernel,
@Nullable KernelFunctionArguments arguments,
@Nullable ContextVariableType<T> variableType) {
return super.invokeAsync(kernel, arguments, variableType);
}
public interface ImplementationFunc<T> {
Mono<FunctionResult<T>> invoke(
Kernel kernel,
KernelFunction<T> function,
@@ -340,7 +340,7 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
JsonNode parameters = jsonNode.get("parameters");
if (parameters != null) {
try {
KernelFunction<T> kernelFunction = null;
KernelFunction<T> kernelFunction;
try {
// unchecked cast
kernelFunction = (KernelFunction<T>) kernel.getPlugins()
@@ -379,7 +379,7 @@ public class KernelFunctionFromPrompt<T> extends KernelFunction<T> {
KernelFunctionArguments arguments = KernelFunctionArguments.builder()
.withVariables(variables)
.build();
return kernelFunction.invokeAsync(kernel, arguments);
return kernelFunction.invokeAsync(kernel).withArguments(arguments);
} catch (Exception e) {
return Mono.error(e);
}