mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
Java: Add Java v1 core draft (#3969)
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone 😄 --------- Co-authored-by: David Grieve <[email protected]>
This commit is contained in:
co-authored by
David Grieve
parent
4b92bf679e
commit
8f0aae4b14
+8
-4
@@ -184,6 +184,11 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
|
||||
return internalCreateNewChat(instructions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenAIChatHistory createNewChat() {
|
||||
return internalCreateNewChat(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<String> generateMessageStream(
|
||||
OpenAIChatHistory chat, @Nullable ChatRequestSettings requestSettings) {
|
||||
@@ -237,11 +242,10 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
|
||||
* @return Chat object
|
||||
*/
|
||||
private static OpenAIChatHistory internalCreateNewChat(@Nullable String instructions) {
|
||||
if (instructions == null) {
|
||||
instructions = "";
|
||||
OpenAIChatHistory history = new OpenAIChatHistory(instructions);
|
||||
if (instructions != null && !instructions.isEmpty()) {
|
||||
history.addUserMessage(instructions);
|
||||
}
|
||||
OpenAIChatHistory history = new OpenAIChatHistory("Assistant is a large language model.");
|
||||
history.addUserMessage(instructions);
|
||||
return history;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -30,7 +30,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/** Standard Semantic Kernel callable plan. Plan is used to create trees of SKFunctions. */
|
||||
public class Plan extends AbstractSkFunction<CompletionRequestSettings> {
|
||||
public class Plan extends AbstractSkFunction {
|
||||
|
||||
private static final Pattern s_variablesRegex = Pattern.compile("\\$(\\w+)", Pattern.MULTILINE);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class Plan extends AbstractSkFunction<CompletionRequestSettings> {
|
||||
// Outputs for the plan, used to pass information to the caller
|
||||
private List<String> outputs = new ArrayList<>();
|
||||
|
||||
@Nullable private SKFunction<?> function = null;
|
||||
@Nullable private SKFunction function = null;
|
||||
|
||||
public Plan(
|
||||
String goal,
|
||||
@@ -69,7 +69,7 @@ public class Plan extends AbstractSkFunction<CompletionRequestSettings> {
|
||||
}
|
||||
|
||||
public Plan(
|
||||
SKFunction<?> function,
|
||||
SKFunction function,
|
||||
ContextVariables state,
|
||||
List<String> functionOutputs,
|
||||
KernelSkillsSupplier kernelSkillsSupplier) {
|
||||
@@ -88,7 +88,7 @@ public class Plan extends AbstractSkFunction<CompletionRequestSettings> {
|
||||
}
|
||||
|
||||
public Plan(
|
||||
SKFunction<?> function,
|
||||
SKFunction function,
|
||||
@Nullable ContextVariables parameters,
|
||||
ContextVariables state,
|
||||
List<String> functionOutputs,
|
||||
@@ -111,13 +111,13 @@ public class Plan extends AbstractSkFunction<CompletionRequestSettings> {
|
||||
}
|
||||
|
||||
public Plan(
|
||||
SKFunction<?> function,
|
||||
SKFunction function,
|
||||
List<String> functionOutputs,
|
||||
KernelSkillsSupplier kernelSkillsSupplier) {
|
||||
this(function, SKBuilders.variables().build(), functionOutputs, kernelSkillsSupplier);
|
||||
}
|
||||
|
||||
public Plan(SKFunction<?> function, KernelSkillsSupplier kernelSkillsSupplier) {
|
||||
public Plan(SKFunction function, KernelSkillsSupplier kernelSkillsSupplier) {
|
||||
this(function, SKBuilders.variables().build(), new ArrayList<>(), kernelSkillsSupplier);
|
||||
}
|
||||
|
||||
@@ -125,12 +125,12 @@ public class Plan extends AbstractSkFunction<CompletionRequestSettings> {
|
||||
String goal,
|
||||
ContextVariables parameters,
|
||||
KernelSkillsSupplier kernelSkillsSupplier,
|
||||
SKFunction<?>... steps) {
|
||||
SKFunction... steps) {
|
||||
this(goal, parameters, kernelSkillsSupplier);
|
||||
this.addSteps(steps);
|
||||
}
|
||||
|
||||
public Plan(String goal, KernelSkillsSupplier kernelSkillsSupplier, SKFunction<?>... steps) {
|
||||
public Plan(String goal, KernelSkillsSupplier kernelSkillsSupplier, SKFunction... steps) {
|
||||
this(goal, kernelSkillsSupplier);
|
||||
this.addSteps(steps);
|
||||
}
|
||||
@@ -176,7 +176,7 @@ public class Plan extends AbstractSkFunction<CompletionRequestSettings> {
|
||||
*
|
||||
* @param steps The steps to add to the current plan.
|
||||
*/
|
||||
public void addSteps(SKFunction<?>... steps) {
|
||||
public void addSteps(SKFunction... steps) {
|
||||
List<Plan> plans =
|
||||
Arrays.stream(steps)
|
||||
.map(step -> new Plan(step, getSkillsSupplier()))
|
||||
|
||||
+16
-17
@@ -47,8 +47,7 @@ public class DefaultSequentialPlannerSKContext {
|
||||
config = new SequentialPlannerRequestSettings();
|
||||
}
|
||||
|
||||
Mono<SortedSet<SKFunction<?>>> functions =
|
||||
getAvailableFunctionsAsync(config, semanticQuery);
|
||||
Mono<SortedSet<SKFunction>> functions = getAvailableFunctionsAsync(config, semanticQuery);
|
||||
|
||||
return functions.map(
|
||||
funcs ->
|
||||
@@ -67,7 +66,7 @@ public class DefaultSequentialPlannerSKContext {
|
||||
// functions</param>
|
||||
/// <returns>A list of functions that are available to the user based on the semantic query and
|
||||
// the excluded skills and functions.</returns>
|
||||
public Mono<SortedSet<SKFunction<?>>> getAvailableFunctionsAsync(
|
||||
public Mono<SortedSet<SKFunction>> getAvailableFunctionsAsync(
|
||||
SequentialPlannerRequestSettings config, @Nullable String semanticQuery) {
|
||||
Set<String> excludedSkills = config.getExcludedSkills();
|
||||
Set<String> excludedFunctions = config.getExcludedFunctions();
|
||||
@@ -76,14 +75,14 @@ public class DefaultSequentialPlannerSKContext {
|
||||
// context.ThrowIfSkillCollectionNotSet();
|
||||
|
||||
ReadOnlySkillCollection skills = delegate.getSkills();
|
||||
List<SKFunction<?>> functions;
|
||||
List<SKFunction> functions;
|
||||
if (skills != null) {
|
||||
functions = skills.getAllFunctions().getAll();
|
||||
} else {
|
||||
functions = Collections.emptyList();
|
||||
}
|
||||
|
||||
List<SKFunction<?>> availableFunctions =
|
||||
List<SKFunction> availableFunctions =
|
||||
functions.stream()
|
||||
/*
|
||||
// Is there any function that should be excluded?
|
||||
@@ -99,8 +98,8 @@ public class DefaultSequentialPlannerSKContext {
|
||||
&& !excludedFunctions.contains(s.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Comparator<SKFunction<?>> comparator =
|
||||
Comparator.<SKFunction<?>, String>comparing(SKFunction::getSkillName)
|
||||
Comparator<SKFunction> comparator =
|
||||
Comparator.<SKFunction, String>comparing(SKFunction::getSkillName)
|
||||
.thenComparing(SKFunction::getName);
|
||||
|
||||
if (semanticQuery == null
|
||||
@@ -110,7 +109,7 @@ public class DefaultSequentialPlannerSKContext {
|
||||
|| config.getRelevancyThreshold() == null) {
|
||||
// If no semantic query is provided, return all available functions.
|
||||
// If a Memory provider has not been registered, return all available functions.
|
||||
TreeSet<SKFunction<?>> result = new TreeSet<>(comparator);
|
||||
TreeSet<SKFunction> result = new TreeSet<>(comparator);
|
||||
result.addAll(availableFunctions);
|
||||
return Mono.just(result);
|
||||
} else {
|
||||
@@ -121,7 +120,7 @@ public class DefaultSequentialPlannerSKContext {
|
||||
SemanticTextMemory updatedMemory =
|
||||
updatedContext.getSemanticMemory();
|
||||
if (updatedMemory == null) {
|
||||
return Mono.just(new ArrayList<SKFunction<Void>>());
|
||||
return Mono.just(new ArrayList<SKFunction>());
|
||||
}
|
||||
// Search for functions that match the semantic query.
|
||||
return updatedMemory
|
||||
@@ -143,26 +142,26 @@ public class DefaultSequentialPlannerSKContext {
|
||||
.map(SKFunction::getName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<SKFunction<?>> missingFunctions =
|
||||
List<SKFunction> missingFunctions =
|
||||
getMissingFunctions(
|
||||
includedFunctions, availableFunctions, added);
|
||||
|
||||
ArrayList<SKFunction<?>> res = new ArrayList<>(memories);
|
||||
ArrayList<SKFunction> res = new ArrayList<>(memories);
|
||||
res.addAll(missingFunctions);
|
||||
return res;
|
||||
})
|
||||
.map(
|
||||
res -> {
|
||||
TreeSet<SKFunction<?>> result = new TreeSet<>(comparator);
|
||||
TreeSet<SKFunction> result = new TreeSet<>(comparator);
|
||||
result.addAll(availableFunctions);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static List<SKFunction<?>> getMissingFunctions(
|
||||
private static List<SKFunction> getMissingFunctions(
|
||||
Set<String> includedFunctions,
|
||||
List<SKFunction<?>> availableFunctions,
|
||||
List<SKFunction> availableFunctions,
|
||||
List<String> added) {
|
||||
return includedFunctions.stream()
|
||||
.filter(func -> !added.contains(func))
|
||||
@@ -173,8 +172,8 @@ public class DefaultSequentialPlannerSKContext {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Mono<? extends List<? extends SKFunction<?>>> getRelevantFunctionsAsync(
|
||||
List<SKFunction<?>> availableFunctions, List<MemoryQueryResult> memories) {
|
||||
public Mono<? extends List<? extends SKFunction>> getRelevantFunctionsAsync(
|
||||
List<SKFunction> availableFunctions, List<MemoryQueryResult> memories) {
|
||||
return Flux.fromIterable(memories)
|
||||
.map(
|
||||
memoryEntry ->
|
||||
@@ -195,7 +194,7 @@ public class DefaultSequentialPlannerSKContext {
|
||||
/// </summary>
|
||||
/// <param name="context">The SKContext to save the functions to.</param>
|
||||
/// <param name="availableFunctions">The available functions to save.</param>
|
||||
Mono<SKContext> rememberFunctionsAsync(List<SKFunction<?>> availableFunctions) {
|
||||
Mono<SKContext> rememberFunctionsAsync(List<SKFunction> availableFunctions) {
|
||||
// Check if the functions have already been saved to memory.
|
||||
if (delegate.getVariables().asMap().containsKey(PlanSKFunctionsAreRemembered)) {
|
||||
return Mono.just(delegate);
|
||||
|
||||
+9
-11
@@ -20,7 +20,6 @@ import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlySkillCollection;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionRequestSettings;
|
||||
import com.microsoft.semantickernel.util.EmbeddedResourceLoader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
@@ -94,7 +93,7 @@ public class DefaultStepwisePlanner implements StepwisePlanner {
|
||||
|
||||
private final Kernel kernel;
|
||||
private final StepwisePlannerConfig config;
|
||||
private final SKFunction<?> systemStepFunction;
|
||||
private final SKFunction systemStepFunction;
|
||||
private final SKContext context;
|
||||
private final ReadOnlyFunctionCollection nativeFunctions;
|
||||
|
||||
@@ -189,7 +188,7 @@ public class DefaultStepwisePlanner implements StepwisePlanner {
|
||||
|
||||
String functionDescriptions = this.getFunctionDescriptions();
|
||||
|
||||
SKFunction<?> planStep = nativeFunctions.getFunction("ExecutePlan", SKFunction.class);
|
||||
SKFunction planStep = nativeFunctions.getFunction("ExecutePlan", SKFunction.class);
|
||||
|
||||
ContextVariables parameters =
|
||||
SKBuilders.variables()
|
||||
@@ -527,8 +526,8 @@ public class DefaultStepwisePlanner implements StepwisePlanner {
|
||||
}
|
||||
|
||||
private Mono<String> invokeActionAsync(String actionName, Map<String, String> actionVariables) {
|
||||
List<SKFunction<?>> availableFunctions = this.getAvailableFunctions();
|
||||
Optional<SKFunction<?>> targetFunction =
|
||||
List<SKFunction> availableFunctions = this.getAvailableFunctions();
|
||||
Optional<SKFunction> targetFunction =
|
||||
availableFunctions.stream()
|
||||
.filter(
|
||||
f -> {
|
||||
@@ -548,7 +547,7 @@ public class DefaultStepwisePlanner implements StepwisePlanner {
|
||||
ErrorCodes.UNKNOWN_ERROR, "The function '" + actionName + "' was not found.");
|
||||
}
|
||||
|
||||
SKFunction<?> function =
|
||||
SKFunction function =
|
||||
kernel.getFunction(
|
||||
targetFunction.get().getSkillName(), targetFunction.get().getName());
|
||||
|
||||
@@ -575,7 +574,7 @@ public class DefaultStepwisePlanner implements StepwisePlanner {
|
||||
return actionContext;
|
||||
}
|
||||
|
||||
private List<SKFunction<?>> getAvailableFunctions() {
|
||||
private List<SKFunction> getAvailableFunctions() {
|
||||
return this.context.getSkills().getAllFunctions().getAll().stream()
|
||||
.filter(
|
||||
fun ->
|
||||
@@ -585,22 +584,21 @@ public class DefaultStepwisePlanner implements StepwisePlanner {
|
||||
.contains(fun.getName()))
|
||||
.sorted(
|
||||
(a, b) ->
|
||||
Comparator.<SKFunction<?>, String>comparing(
|
||||
SKFunction::getSkillName)
|
||||
Comparator.<SKFunction, String>comparing(SKFunction::getSkillName)
|
||||
.thenComparing(SKFunction::getName)
|
||||
.compare(a, b))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String getFunctionDescriptions() {
|
||||
List<SKFunction<?>> availableFunctions = this.getAvailableFunctions();
|
||||
List<SKFunction> availableFunctions = this.getAvailableFunctions();
|
||||
|
||||
return availableFunctions.stream()
|
||||
.map(x -> toManualString(Objects.requireNonNull(x.describe())))
|
||||
.collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
private SKFunction<CompletionRequestSettings> importStepwiseFunction(
|
||||
private SKFunction importStepwiseFunction(
|
||||
Kernel kernel, String promptTemplate, PromptTemplateConfig config) {
|
||||
PromptTemplate template =
|
||||
SKBuilders.promptTemplate()
|
||||
|
||||
+2
-1
@@ -183,9 +183,10 @@ public class TextMemorySkill {
|
||||
new MemoryException(MemoryException.ErrorCodes.UNKNOWN, "Memory not present"));
|
||||
}
|
||||
|
||||
// TODO: 1.0 fix cast
|
||||
// Validate parameters
|
||||
if (collection == null || collection.trim().isEmpty()) {
|
||||
collection = context.getVariables().get(TextMemorySkill.COLLECTION_PARAM);
|
||||
collection = (String) context.getVariables().get(TextMemorySkill.COLLECTION_PARAM);
|
||||
if (collection == null) collection = DEFAULT_COLLECTION;
|
||||
}
|
||||
final String _collection = collection;
|
||||
|
||||
+16
-16
@@ -64,22 +64,22 @@
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<!-- <module>connectors/semantickernel-connectors-ai-openai</module>
|
||||
<module>connectors/semantickernel-connectors-memory-sqlite</module>
|
||||
<module>connectors/semantickernel-connectors-ai-openai</module>
|
||||
<!-- <module>connectors/semantickernel-connectors-memory-sqlite</module>-->
|
||||
<module>connectors/semantickernel-connectors-memory-azurecognitivesearch</module>
|
||||
<module>connectors/semantickernel-connectors-memory-jdbc</module>
|
||||
<module>connectors/semantickernel-connectors-memory-postgresql</module>
|
||||
<module>connectors/semantickernel-connectors-memory-mysql</module> -->
|
||||
<!-- <module>connectors/semantickernel-connectors-memory-jdbc</module>-->
|
||||
<!-- <module>connectors/semantickernel-connectors-memory-postgresql</module>-->
|
||||
<!-- <module>connectors/semantickernel-connectors-memory-mysql</module>-->
|
||||
|
||||
<!-- <module>extensions/semantickernel-planners</module>
|
||||
<!-- <module>extensions/semantickernel-planners</module>-->
|
||||
<module>extensions/semantickernel-gpt3-tokenizer</module>
|
||||
<module>extensions/semantickernel-settings-loader</module> -->
|
||||
<module>extensions/semantickernel-settings-loader</module>
|
||||
|
||||
<!-- <module>plugins/semantickernel-plugin-core</module> -->
|
||||
<module>plugins/semantickernel-plugin-core</module>
|
||||
|
||||
<module>semantickernel-bom</module>
|
||||
<module>semantickernel-api</module>
|
||||
<!-- <module>semantickernel-core</module> -->
|
||||
<module>semantickernel-core</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -717,13 +717,13 @@
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>with-samples</id>
|
||||
<modules>
|
||||
<module>samples</module>
|
||||
<module>api-test</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<!-- <profile>-->
|
||||
<!-- <id>with-samples</id>-->
|
||||
<!-- <modules>-->
|
||||
<!-- <module>samples</module>-->
|
||||
<!-- <module>api-test</module>-->
|
||||
<!-- </modules>-->
|
||||
<!-- </profile>-->
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<properties>
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.microsoft.semantickernel.ai.embeddings.TextEmbeddingGeneration;
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
@@ -17,9 +12,13 @@ import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.plugin.Plugin;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunctionConfig;
|
||||
import com.microsoft.semantickernel.services.AIService;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlySkillCollection;
|
||||
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/** Interface for the semantic kernel. */
|
||||
@@ -53,7 +52,7 @@ public interface Kernel extends Buildable {
|
||||
*
|
||||
* @param pipeline List of functions
|
||||
* @return Result of the function composition
|
||||
* @apiNote Breaking change: s/SKFunction<?>/SKFunction/, s/Mono<SKContext>/Mono<KernelResult>/
|
||||
* @apiNote Breaking change: s/SKFunction/SKFunction/, s/Mono<SKContext>/Mono<KernelResult>/
|
||||
*/
|
||||
@Deprecated
|
||||
Mono<KernelResult> runAsync(SKFunction... pipeline);
|
||||
@@ -64,7 +63,7 @@ public interface Kernel extends Buildable {
|
||||
* @param input Input to process
|
||||
* @param pipeline List of functions
|
||||
* @return Result of the function composition
|
||||
* @apiNote Breaking change: s/SKFunction<?>/SKFunction/, s/Mono<SKContext>/Mono<KernelResult>/
|
||||
* @apiNote Breaking change: s/SKFunction/SKFunction/, s/Mono<SKContext>/Mono<KernelResult>/
|
||||
*/
|
||||
@Deprecated
|
||||
Mono<KernelResult> runAsync(String input, SKFunction... pipeline);
|
||||
@@ -75,19 +74,21 @@ public interface Kernel extends Buildable {
|
||||
* @param variables variables to initialise the context with
|
||||
* @param pipeline List of functions
|
||||
* @return Result of the function composition
|
||||
* @apiNote Breaking change: s/SKFunction<?>/SKFunction/, s/Mono<SKContext>/Mono<KernelResult>/
|
||||
* @apiNote Breaking change: s/SKFunction/SKFunction/, s/Mono<SKContext>/Mono<KernelResult>/
|
||||
*/
|
||||
Mono<KernelResult> runAsync(ContextVariables variables, SKFunction... pipeline);
|
||||
|
||||
/**
|
||||
* Run a pipeline composed of synchronous and asynchronous functions.
|
||||
*
|
||||
* @param streaming Whether to stream the results of the pipeline
|
||||
* @param variables variables to initialise the context with
|
||||
* @param pipeline List of functions
|
||||
* @return Result of the function composition
|
||||
* @since 1.0.0
|
||||
*/
|
||||
Mono<KernelResult> runAsync(boolean streaming, ContextVariables variables, SKFunction... pipeline);
|
||||
Mono<KernelResult> runAsync(
|
||||
boolean streaming, ContextVariables variables, SKFunction... pipeline);
|
||||
|
||||
/**
|
||||
* Register a semantic function on this kernel
|
||||
@@ -113,15 +114,20 @@ public interface Kernel extends Buildable {
|
||||
<T extends AIService> T getService(@Nullable String name, Class<T> clazz)
|
||||
throws KernelException;
|
||||
|
||||
/** Registers a semantic function on this kernel
|
||||
* @apiNote Breaking change: s/<RequestConfiguration, FunctionType extends SKFunction<RequestConfiguration>>/<FunctionType extends SKFunction>/
|
||||
*/
|
||||
/**
|
||||
* Registers a semantic function on this kernel
|
||||
*
|
||||
* @apiNote Breaking change: s/<RequestConfiguration, FunctionType extends
|
||||
* SKFunction>/<FunctionType extends SKFunction>/
|
||||
*/
|
||||
@Deprecated
|
||||
<FunctionType extends SKFunction>
|
||||
FunctionType registerSemanticFunction(FunctionType semanticFunctionDefinition);
|
||||
<FunctionType extends SKFunction> FunctionType registerSemanticFunction(
|
||||
FunctionType semanticFunctionDefinition);
|
||||
|
||||
/** Obtains a semantic function with the given name
|
||||
* @apiNote Breaking change: s/SKFunction<?>/SKFunction/
|
||||
/**
|
||||
* Obtains a semantic function with the given name
|
||||
*
|
||||
* @apiNote Breaking change: s/SKFunction/SKFunction/
|
||||
*/
|
||||
@Deprecated
|
||||
SKFunction getFunction(String skill, String function);
|
||||
@@ -130,6 +136,12 @@ public interface Kernel extends Buildable {
|
||||
return BuildersSingleton.INST.getInstance(Kernel.Builder.class);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
ReadOnlySkillCollection getSkills();
|
||||
|
||||
@Deprecated
|
||||
ReadOnlyFunctionCollection getSkill();
|
||||
|
||||
interface Builder extends SemanticKernelBuilder<Kernel> {
|
||||
/**
|
||||
* Set the kernel configuration
|
||||
@@ -244,6 +256,7 @@ public interface Kernel extends Buildable {
|
||||
|
||||
/**
|
||||
* Add plugins to the kernel to be built.
|
||||
*
|
||||
* @param plugins Plugins to add.
|
||||
* @return Updated kernel builder including the plugins.
|
||||
* @since 1.0.0
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.FunctionResult;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @since 1.0.0
|
||||
@@ -11,8 +11,8 @@ public interface KernelResult {
|
||||
|
||||
/**
|
||||
* Get the results from all functions in pipeline.
|
||||
*
|
||||
* @return The results from all functions in pipeline.
|
||||
*/
|
||||
Collection<FunctionResult> functionResults();
|
||||
|
||||
}
|
||||
|
||||
+2
-5
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.chatcompletion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.azure.ai.openai.models.ChatCompletions;
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
@@ -10,7 +8,7 @@ import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
|
||||
import com.microsoft.semantickernel.services.AIService;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@@ -36,7 +34,7 @@ public interface ChatCompletion<ChatHistoryType extends ChatHistory>
|
||||
*/
|
||||
ChatHistoryType createNewChat(String instructions);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a new empty chat instance
|
||||
*
|
||||
* @return Chat object
|
||||
@@ -44,7 +42,6 @@ public interface ChatCompletion<ChatHistoryType extends ChatHistory>
|
||||
*/
|
||||
ChatHistoryType createNewChat();
|
||||
|
||||
|
||||
Flux<String> generateMessageStream(
|
||||
ChatHistoryType chatHistory, @Nullable ChatRequestSettings requestSettings);
|
||||
|
||||
|
||||
+2
-4
@@ -90,13 +90,12 @@ public class ChatHistory {
|
||||
public void addMessage(AuthorRoles authorRole, String content) {
|
||||
this.messages.add(new Message(authorRole, content));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a message to the chat history with the user as the author
|
||||
*
|
||||
* @param content Message content
|
||||
* @since 1.0.0
|
||||
* @
|
||||
* @since 1.0.0 @
|
||||
*/
|
||||
public void addUserMessage(String content) {
|
||||
this.messages.add(new Message(AuthorRoles.User, content));
|
||||
@@ -111,5 +110,4 @@ public class ChatHistory {
|
||||
public void addAssistantMessage(String content) {
|
||||
this.messages.add(new Message(AuthorRoles.Assistant, content));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,13 +1,12 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.nativefunction;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import java.util.Collection;
|
||||
|
||||
public class NativeFunction {
|
||||
|
||||
public static Collection<SKFunction> getFunctionsFromObject(Object object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-6
@@ -105,12 +105,6 @@ public abstract class AbstractSKContext implements SKContext {
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SKContext appendToVariable(@Nonnull String key, @Nonnull String content) {
|
||||
variables.appendToVariable(key, content);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SKContext update(@Nonnull String content) {
|
||||
variables.update(content);
|
||||
|
||||
+16
-19
@@ -1,14 +1,6 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.orchestration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.memory.NullMemory;
|
||||
import com.microsoft.semantickernel.memory.SemanticTextMemory;
|
||||
@@ -17,12 +9,16 @@ import com.microsoft.semantickernel.skilldefinition.KernelSkillsSupplier;
|
||||
import com.microsoft.semantickernel.skilldefinition.ParameterView;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlySkillCollection;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/** Abstract implementation of the SKFunction interface. */
|
||||
public abstract class AbstractSkFunction
|
||||
implements SKFunction, RegistrableSkFunction {
|
||||
public abstract class AbstractSKFunction implements SKFunction, RegistrableSkFunction {
|
||||
|
||||
private final List<ParameterView> parameters;
|
||||
private final String skillName;
|
||||
@@ -41,7 +37,7 @@ public abstract class AbstractSkFunction
|
||||
* @param description The description of the function.
|
||||
* @param skillsSupplier The skill supplier.
|
||||
*/
|
||||
public AbstractSkFunction(
|
||||
public AbstractSKFunction(
|
||||
List<ParameterView> parameters,
|
||||
String skillName,
|
||||
String functionName,
|
||||
@@ -87,12 +83,12 @@ public abstract class AbstractSkFunction
|
||||
return skillsSupplier;
|
||||
}
|
||||
|
||||
/** @apiNote Breaking change: s/RequestConfiguration settings/Object settings/ */
|
||||
/**
|
||||
* @apiNote Breaking change: s/RequestConfiguration settings/Object settings/
|
||||
*/
|
||||
@Override
|
||||
public Mono<SKContext> invokeAsync(
|
||||
@Nullable String input,
|
||||
@Nullable SKContext context,
|
||||
@Nullable Object settings) {
|
||||
@Nullable String input, @Nullable SKContext context, @Nullable Object settings) {
|
||||
if (context == null) {
|
||||
assertSkillSupplierRegistered();
|
||||
|
||||
@@ -117,10 +113,11 @@ public abstract class AbstractSkFunction
|
||||
return invokeAsync(input, null, null);
|
||||
}
|
||||
|
||||
/** @apiNote Breaking change: s/RequestConfiguration settings/Object settings/ */
|
||||
/**
|
||||
* @apiNote Breaking change: s/RequestConfiguration settings/Object settings/
|
||||
*/
|
||||
@Override
|
||||
public Mono<SKContext> invokeAsync(
|
||||
@Nullable SKContext context, @Nullable Object settings) {
|
||||
public Mono<SKContext> invokeAsync(@Nullable SKContext context, @Nullable Object settings) {
|
||||
if (context == null) {
|
||||
context =
|
||||
SKBuilders.context()
|
||||
+3
-5
@@ -3,13 +3,11 @@ package com.microsoft.semantickernel.orchestration;
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Context Variables is a data structure that holds temporary data while a task is being performed.
|
||||
@@ -41,7 +39,7 @@ public interface ContextVariables extends Buildable {
|
||||
* @return input
|
||||
*/
|
||||
@Nullable
|
||||
String getInput();
|
||||
Object getInput();
|
||||
|
||||
/**
|
||||
* Create formatted string of the variables
|
||||
|
||||
+11
-10
@@ -1,55 +1,56 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.orchestration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
||||
/**
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface FunctionResult {
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of executed function.
|
||||
*
|
||||
* @return The name of executed function.
|
||||
*/
|
||||
String functionName();
|
||||
|
||||
/**
|
||||
* Get the name of the plugin containing the function.
|
||||
*
|
||||
* @return The name of the plugin containing the function.
|
||||
*/
|
||||
String pluginName();
|
||||
|
||||
/**
|
||||
* Get the metadata for storing additional information about function execution result.
|
||||
*
|
||||
* @return The metadata for storing additional information about function execution result.
|
||||
*/
|
||||
Map<String, Object> metadata();
|
||||
|
||||
/**
|
||||
* Get the function result.
|
||||
*
|
||||
* @return The function result.
|
||||
* @param <T> The type of the function result.
|
||||
*/
|
||||
<T> Mono<T> getValueAsync();
|
||||
Mono<String> getValueAsync();
|
||||
|
||||
/**
|
||||
* Get the function result.
|
||||
*
|
||||
* @return The function result.
|
||||
* @param <T> The type of the function result.
|
||||
*/
|
||||
<T> Flux<T> getStreamingValueAsync();
|
||||
Flux<String> getStreamingValueAsync();
|
||||
|
||||
/**
|
||||
* Get the function result.
|
||||
*
|
||||
* @return The function result.
|
||||
* @param <T> The type of the function result.
|
||||
*/
|
||||
<T> T getValue();
|
||||
|
||||
String getValue();
|
||||
|
||||
/**
|
||||
* Get typed data from metadata.
|
||||
|
||||
+1
-5
@@ -1,15 +1,13 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.orchestration;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
|
||||
import com.microsoft.semantickernel.memory.SemanticTextMemory;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlySkillCollection;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import reactor.util.annotation.Nullable;
|
||||
|
||||
/** Semantic Kernel context. */
|
||||
@@ -20,8 +18,6 @@ public interface SKContext extends Buildable {
|
||||
@Nullable SemanticTextMemory memory,
|
||||
@Nullable ReadOnlySkillCollection skills);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the result of the execution that produced this context. This will be the "input" entry
|
||||
* in the variables.
|
||||
|
||||
+25
-19
@@ -1,21 +1,19 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.orchestration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.KernelResult;
|
||||
import com.microsoft.semantickernel.memory.SemanticTextMemory;
|
||||
import com.microsoft.semantickernel.skilldefinition.FunctionView;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlySkillCollection;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Semantic Kernel callable function interface
|
||||
* @apiNote Breaking change: s/SKFunction<RequestConfiguration>/SKFunction/
|
||||
*
|
||||
* @apiNote Breaking change: s/SKFunction/SKFunction/
|
||||
*/
|
||||
public interface SKFunction {
|
||||
/**
|
||||
@@ -58,9 +56,7 @@ public interface SKFunction {
|
||||
/**
|
||||
* The type of the configuration argument that will be provided when the function is invoked
|
||||
*
|
||||
* @return The type
|
||||
@Nullable
|
||||
Class<RequestConfiguration> getType();
|
||||
* @return The type @Nullable Class<RequestConfiguration> getType();
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -70,8 +66,26 @@ public interface SKFunction {
|
||||
* @return an updated context with the result of the request
|
||||
*/
|
||||
@CheckReturnValue
|
||||
@Deprecated
|
||||
Mono<SKContext> invokeAsync(SKContext context);
|
||||
|
||||
/**
|
||||
* The type of the configuration argument that will be provided when the function is invoked
|
||||
*
|
||||
* @return The type @Nullable Class<RequestConfiguration> getType();
|
||||
*/
|
||||
|
||||
/**
|
||||
* Invokes the function with the given context and settings
|
||||
*
|
||||
* @param kernel Associated Kernel
|
||||
* @param variables Request variables
|
||||
* @param streaming Whether streaming is on or not
|
||||
* @return an updated context with the result of the request
|
||||
*/
|
||||
@CheckReturnValue
|
||||
Mono<FunctionResult> invokeAsync(Kernel kernel, ContextVariables variables, boolean streaming);
|
||||
|
||||
/**
|
||||
* Invokes the function with the given context and settings
|
||||
*
|
||||
@@ -82,16 +96,8 @@ public interface SKFunction {
|
||||
*/
|
||||
@CheckReturnValue
|
||||
@Deprecated
|
||||
Mono<SKContext> invokeAsync(SKContext context, @Nullable Object settings);
|
||||
Mono<SKContext> invokeAsync(SKContext context, @Nullable Object settings);
|
||||
|
||||
/**
|
||||
* @return The result of invoking the function.
|
||||
* @param kernel The kernel to invoke the function on
|
||||
* @param variables The variables to invoke the function with
|
||||
* @since 1.0.0
|
||||
*/
|
||||
Mono<FunctionResult> invokeAsync(Kernel kernel, Map<String,Object> variables);
|
||||
|
||||
/**
|
||||
* @return The name of the skill that this function is within
|
||||
*/
|
||||
|
||||
-10
@@ -19,16 +19,6 @@ public interface WritableContextVariables extends ContextVariables {
|
||||
*/
|
||||
ContextVariables setVariable(String key, Object content);
|
||||
|
||||
/**
|
||||
* Append to the variable's value
|
||||
*
|
||||
* @param key variable name
|
||||
* @param content value to append
|
||||
* @return Context for fluent calls
|
||||
* @apiNote Breaking change: s/String content/Object content/
|
||||
*/
|
||||
ContextVariables appendToVariable(String key, Object content);
|
||||
|
||||
/**
|
||||
* Updates the main input text with the new value after a function is complete.
|
||||
*
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface Plugin {
|
||||
String name();
|
||||
|
||||
+4
@@ -4,6 +4,7 @@ package com.microsoft.semantickernel.semanticfunctions;
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.ParameterView;
|
||||
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
|
||||
@@ -25,8 +26,11 @@ public interface PromptTemplate extends Buildable {
|
||||
* @param executionContext Kernel execution context helpers
|
||||
* @return Prompt rendered to string
|
||||
*/
|
||||
@Deprecated
|
||||
Mono<String> renderAsync(SKContext executionContext);
|
||||
|
||||
Mono<String> renderAsync(ContextVariables variables);
|
||||
|
||||
static Builder builder() {
|
||||
return BuildersSingleton.INST.getInstance(Builder.class);
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,14 +1,13 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.skilldefinition;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface KernelSkillsSupplier extends Supplier<ReadOnlySkillCollection> {
|
||||
|
||||
@Deprecated
|
||||
static KernelSkillsSupplier getInstance(Kernel kernel) {
|
||||
return null; //kernel::getSkills;
|
||||
return null; // kernel::getSkills;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,13 +1,11 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.skilldefinition;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
|
||||
public interface ReadOnlyFunctionCollection {
|
||||
|
||||
String getSkillName();
|
||||
|
||||
+6
-6
@@ -1,15 +1,13 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.skilldefinition;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import java.util.Map;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Skill collection interface.
|
||||
@@ -36,7 +34,9 @@ public interface ReadOnlySkillCollection extends Buildable {
|
||||
|
||||
ReadOnlyFunctionCollection getAllFunctions();
|
||||
|
||||
/** Get function with name from the global scope
|
||||
/**
|
||||
* Get function with name from the global scope
|
||||
*
|
||||
* @apiNote Breaking change: s/SKFunciton<?>/SKFunction/
|
||||
*/
|
||||
@Nullable
|
||||
|
||||
+11
@@ -4,6 +4,7 @@ package com.microsoft.semantickernel.templateengine;
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
import com.microsoft.semantickernel.builders.SemanticKernelBuilder;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.templateengine.blocks.Block;
|
||||
import java.util.List;
|
||||
@@ -34,6 +35,16 @@ public interface PromptTemplateEngine extends Buildable {
|
||||
*/
|
||||
Mono<String> renderAsync(String templateText, SKContext context);
|
||||
|
||||
/**
|
||||
* Given a prompt template, replace the variables with their values and execute the functions
|
||||
* replacing their reference with the function result
|
||||
*
|
||||
* @param templateText Prompt template (see skprompt.txt files)
|
||||
* @param variables ContextVariables with the associated values
|
||||
* @return The prompt template ready to be used for an AI request
|
||||
*/
|
||||
Mono<String> renderAsync(String templateText, ContextVariables variables);
|
||||
|
||||
/**
|
||||
* Given a prompt template string, extract all the blocks (text, variables, function calls)
|
||||
*
|
||||
|
||||
+2
-5
@@ -1,10 +1,6 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.textcompletion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.builders.BuildersSingleton;
|
||||
@@ -13,7 +9,8 @@ import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunctionConfig;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/** Semantic function for text completion */
|
||||
|
||||
@@ -81,15 +81,41 @@
|
||||
<artifactId>semantickernel-plugin-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-planners</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.microsoft.semantic-kernel</groupId>-->
|
||||
<!-- <artifactId>semantickernel-planners</artifactId>-->
|
||||
<!-- <scope>test</scope>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.inject</groupId>
|
||||
<artifactId>jakarta.inject-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.jknack</groupId>
|
||||
<artifactId>handlebars</artifactId>
|
||||
<version>4.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.15.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.15.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
<version>2.15.2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
+158
-155
@@ -3,36 +3,33 @@ package com.microsoft.semantickernel;
|
||||
|
||||
import com.microsoft.semantickernel.ai.AIException;
|
||||
import com.microsoft.semantickernel.ai.embeddings.TextEmbeddingGeneration;
|
||||
import com.microsoft.semantickernel.coreskills.SkillImporter;
|
||||
import com.microsoft.semantickernel.exceptions.SkillsNotFoundException;
|
||||
import com.microsoft.semantickernel.exceptions.SkillsNotFoundException.ErrorCodes;
|
||||
import com.microsoft.semantickernel.extensions.KernelExtensions;
|
||||
import com.microsoft.semantickernel.memory.MemoryConfiguration;
|
||||
import com.microsoft.semantickernel.memory.MemoryStore;
|
||||
import com.microsoft.semantickernel.memory.NullMemory;
|
||||
import com.microsoft.semantickernel.memory.SemanticTextMemory;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.RegistrableSkFunction;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.orchestration.*;
|
||||
import com.microsoft.semantickernel.plugin.Plugin;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunctionConfig;
|
||||
import com.microsoft.semantickernel.services.AIService;
|
||||
import com.microsoft.semantickernel.services.AIServiceCollection;
|
||||
import com.microsoft.semantickernel.services.AIServiceProvider;
|
||||
import com.microsoft.semantickernel.skilldefinition.DefaultSkillCollection;
|
||||
import com.microsoft.semantickernel.skilldefinition.FunctionNotFound;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlySkillCollection;
|
||||
import com.microsoft.semantickernel.templateengine.DefaultPromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class DefaultKernel implements Kernel {
|
||||
@@ -83,24 +80,31 @@ public class DefaultKernel implements Kernel {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <FunctionType extends SKFunction> FunctionType registerSemanticFunction(
|
||||
FunctionType semanticFunctionDefinition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KernelConfig getConfig() {
|
||||
return kernelConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <RequestConfiguration, FunctionType extends SKFunction<RequestConfiguration>>
|
||||
FunctionType registerSemanticFunction(FunctionType func) {
|
||||
if (!(func instanceof RegistrableSkFunction)) {
|
||||
throw new RuntimeException("This function does not implement RegistrableSkFunction");
|
||||
}
|
||||
((RegistrableSkFunction) func).registerOnKernel(this);
|
||||
defaultSkillCollection.addSemanticFunction(func);
|
||||
return func;
|
||||
}
|
||||
// @Override
|
||||
// public <RequestConfiguration, FunctionType extends SKFunction>
|
||||
// FunctionType registerSemanticFunction(FunctionType func) {
|
||||
// if (!(func instanceof RegistrableSkFunction)) {
|
||||
// throw new RuntimeException("This function does not implement
|
||||
// RegistrableSkFunction");
|
||||
// }
|
||||
// ((RegistrableSkFunction) func).registerOnKernel(this);
|
||||
// defaultSkillCollection.addSemanticFunction(func);
|
||||
// return func;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public SKFunction<?> getFunction(String skill, String function) {
|
||||
public SKFunction getFunction(String skill, String function) {
|
||||
return defaultSkillCollection.getFunction(skill, function, null);
|
||||
}
|
||||
|
||||
@@ -130,118 +134,129 @@ public class DefaultKernel implements Kernel {
|
||||
// value is empty functions are registered in the global namespace.</param>
|
||||
/// <returns>A list of all the semantic functions found in the directory, indexed by function
|
||||
// name.</returns>
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection importSkill(
|
||||
String skillName, Map<String, SemanticFunctionConfig> skills)
|
||||
throws SkillsNotFoundException {
|
||||
skills.entrySet().stream()
|
||||
.map(
|
||||
(entry) -> {
|
||||
return SKBuilders.completionFunctions()
|
||||
.withKernel(this)
|
||||
.withSkillName(skillName)
|
||||
.withFunctionName(entry.getKey())
|
||||
.withSemanticFunctionConfig(entry.getValue())
|
||||
.build();
|
||||
})
|
||||
.forEach(this::registerSemanticFunction);
|
||||
|
||||
ReadOnlyFunctionCollection collection = getSkill(skillName);
|
||||
if (collection == null) {
|
||||
throw new SkillsNotFoundException(ErrorCodes.SKILLS_NOT_FOUND);
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection importSkill(
|
||||
Object skillInstance, @Nullable String skillName) {
|
||||
if (skillInstance instanceof String) {
|
||||
throw new KernelException(
|
||||
KernelException.ErrorCodes.FUNCTION_NOT_AVAILABLE,
|
||||
"Called importSkill with a string argument, it is likely the intention was to"
|
||||
+ " call importSkillFromDirectory");
|
||||
}
|
||||
|
||||
if (skillName == null || skillName.isEmpty()) {
|
||||
skillName = ReadOnlySkillCollection.GlobalSkill;
|
||||
}
|
||||
|
||||
// skill = new Dictionary<string, ISKFunction>(StringComparer.OrdinalIgnoreCase);
|
||||
ReadOnlyFunctionCollection functions =
|
||||
SkillImporter.importSkill(skillInstance, skillName, () -> defaultSkillCollection);
|
||||
|
||||
DefaultSkillCollection newSkills =
|
||||
functions.getAll().stream()
|
||||
.reduce(
|
||||
new DefaultSkillCollection(),
|
||||
DefaultSkillCollection::addNativeFunction,
|
||||
DefaultSkillCollection::merge);
|
||||
|
||||
this.defaultSkillCollection.merge(newSkills);
|
||||
|
||||
return functions;
|
||||
}
|
||||
// @Override
|
||||
// public ReadOnlyFunctionCollection importSkill(
|
||||
// String skillName, Map<String, SemanticFunctionConfig> skills)
|
||||
// throws SkillsNotFoundException {
|
||||
// skills.entrySet().stream()
|
||||
// .map(
|
||||
// (entry) -> {
|
||||
// return SKBuilders.completionFunctions()
|
||||
// .withKernel(this)
|
||||
// .withSkillName(skillName)
|
||||
// .withFunctionName(entry.getKey())
|
||||
// .withSemanticFunctionConfig(entry.getValue())
|
||||
// .build();
|
||||
// })
|
||||
// .forEach(this::registerSemanticFunction);
|
||||
//
|
||||
// ReadOnlyFunctionCollection collection = getSkill(skillName);
|
||||
// if (collection == null) {
|
||||
// throw new SkillsNotFoundException(ErrorCodes.SKILLS_NOT_FOUND);
|
||||
// }
|
||||
// return collection;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ReadOnlyFunctionCollection importSkill(
|
||||
// Object skillInstance, @Nullable String skillName) {
|
||||
// if (skillInstance instanceof String) {
|
||||
// throw new KernelException(
|
||||
// KernelException.ErrorCodes.FUNCTION_NOT_AVAILABLE,
|
||||
// "Called importSkill with a string argument, it is likely the intention was
|
||||
// to"
|
||||
// + " call importSkillFromDirectory");
|
||||
// }
|
||||
//
|
||||
// if (skillName == null || skillName.isEmpty()) {
|
||||
// skillName = ReadOnlySkillCollection.GlobalSkill;
|
||||
// }
|
||||
//
|
||||
// // skill = new Dictionary<string, ISKFunction>(StringComparer.OrdinalIgnoreCase);
|
||||
// ReadOnlyFunctionCollection functions =
|
||||
// SkillImporter.importSkill(skillInstance, skillName, () ->
|
||||
// defaultSkillCollection);
|
||||
//
|
||||
// DefaultSkillCollection newSkills =
|
||||
// functions.getAll().stream()
|
||||
// .reduce(
|
||||
// new DefaultSkillCollection(),
|
||||
// DefaultSkillCollection::addNativeFunction,
|
||||
// DefaultSkillCollection::merge);
|
||||
//
|
||||
// this.defaultSkillCollection.merge(newSkills);
|
||||
//
|
||||
// return functions;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public ReadOnlySkillCollection getSkills() {
|
||||
return defaultSkillCollection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection getSkill() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionSKFunction.Builder getSemanticFunctionBuilder() {
|
||||
return SKBuilders.completionFunctions().withKernel(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection getSkill(String skillName) throws FunctionNotFound {
|
||||
ReadOnlyFunctionCollection functions = this.defaultSkillCollection.getFunctions(skillName);
|
||||
if (functions == null) {
|
||||
throw new FunctionNotFound(FunctionNotFound.ErrorCodes.FUNCTION_NOT_FOUND, skillName);
|
||||
}
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection importSkillFromDirectory(
|
||||
String skillName, String parentDirectory, String skillDirectoryName) {
|
||||
Map<String, SemanticFunctionConfig> skills =
|
||||
KernelExtensions.importSemanticSkillFromDirectory(
|
||||
parentDirectory, skillDirectoryName, promptTemplateEngine);
|
||||
return importSkill(skillName, skills);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importSkillsFromDirectory(String parentDirectory, String... skillNames) {
|
||||
Arrays.stream(skillNames)
|
||||
.forEach(
|
||||
skill -> {
|
||||
importSkillFromDirectory(skill, parentDirectory, skill);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection importSkillFromDirectory(
|
||||
String skillName, String parentDirectory) {
|
||||
return importSkillFromDirectory(skillName, parentDirectory, skillName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection importSkillFromResources(
|
||||
String pluginDirectory, String skillName, String functionName) {
|
||||
return importSkillFromResources(pluginDirectory, skillName, functionName, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyFunctionCollection importSkillFromResources(
|
||||
String pluginDirectory, String skillName, String functionName, @Nullable Class clazz)
|
||||
throws KernelException {
|
||||
Map<String, SemanticFunctionConfig> skills =
|
||||
KernelExtensions.importSemanticSkillFromResourcesDirectory(
|
||||
pluginDirectory, skillName, functionName, clazz, promptTemplateEngine);
|
||||
return importSkill(skillName, skills);
|
||||
}
|
||||
// @Override
|
||||
// public ReadOnlyFunctionCollection getSkill(String skillName) throws FunctionNotFound {
|
||||
// ReadOnlyFunctionCollection functions =
|
||||
// this.defaultSkillCollection.getFunctions(skillName);
|
||||
// if (functions == null) {
|
||||
// throw new FunctionNotFound(FunctionNotFound.ErrorCodes.FUNCTION_NOT_FOUND,
|
||||
// skillName);
|
||||
// }
|
||||
//
|
||||
// return functions;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ReadOnlyFunctionCollection importSkillFromDirectory(
|
||||
// String skillName, String parentDirectory, String skillDirectoryName) {
|
||||
// Map<String, SemanticFunctionConfig> skills =
|
||||
// KernelExtensions.importSemanticSkillFromDirectory(
|
||||
// parentDirectory, skillDirectoryName, promptTemplateEngine);
|
||||
// return importSkill(skillName, skills);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void importSkillsFromDirectory(String parentDirectory, String... skillNames) {
|
||||
// Arrays.stream(skillNames)
|
||||
// .forEach(
|
||||
// skill -> {
|
||||
// importSkillFromDirectory(skill, parentDirectory, skill);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ReadOnlyFunctionCollection importSkillFromDirectory(
|
||||
// String skillName, String parentDirectory) {
|
||||
// return importSkillFromDirectory(skillName, parentDirectory, skillName);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ReadOnlyFunctionCollection importSkillFromResources(
|
||||
// String pluginDirectory, String skillName, String functionName) {
|
||||
// return importSkillFromResources(pluginDirectory, skillName, functionName, null);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ReadOnlyFunctionCollection importSkillFromResources(
|
||||
// String pluginDirectory, String skillName, String functionName, @Nullable Class
|
||||
// clazz)
|
||||
// throws KernelException {
|
||||
// Map<String, SemanticFunctionConfig> skills =
|
||||
// KernelExtensions.importSemanticSkillFromResourcesDirectory(
|
||||
// pluginDirectory, skillName, functionName, clazz,
|
||||
// promptTemplateEngine);
|
||||
// return importSkill(skillName, skills);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public PromptTemplateEngine getPromptTemplateEngine() {
|
||||
@@ -258,54 +273,37 @@ public class DefaultKernel implements Kernel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SKContext> runAsync(SKFunction<?>... pipeline) {
|
||||
public Mono<KernelResult> runAsync(SKFunction... pipeline) {
|
||||
return runAsync(SKBuilders.variables().build(), pipeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SKContext> runAsync(String input, SKFunction<?>... pipeline) {
|
||||
public Mono<KernelResult> runAsync(String input, SKFunction... pipeline) {
|
||||
return runAsync(SKBuilders.variables().withInput(input).build(), pipeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<SKContext> runAsync(ContextVariables variables, SKFunction<?>... pipeline) {
|
||||
public Mono<KernelResult> runAsync(ContextVariables variables, SKFunction... pipeline) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<KernelResult> runAsync(
|
||||
boolean streaming, ContextVariables variables, SKFunction... pipeline) {
|
||||
// TODO: 1.0 support pipeline
|
||||
|
||||
if (pipeline == null || pipeline.length == 0) {
|
||||
throw new SKException("No parameters provided to pipeline");
|
||||
}
|
||||
// TODO: The SemanticTextMemory can be null, but there should be a way to provide it.
|
||||
// Not sure registerMemory is the right way.
|
||||
Mono<SKContext> pipelineBuilder =
|
||||
Mono.just(
|
||||
SKBuilders.context()
|
||||
.withVariables(variables)
|
||||
.withSkills(getSkills())
|
||||
.build());
|
||||
|
||||
List<Mono<FunctionResult>> results = new ArrayList<>();
|
||||
for (SKFunction f : Arrays.asList(pipeline)) {
|
||||
pipelineBuilder =
|
||||
pipelineBuilder
|
||||
.switchIfEmpty(
|
||||
Mono.fromCallable(
|
||||
() -> {
|
||||
// Previous pipeline did not produce a result
|
||||
return SKBuilders.context()
|
||||
.withVariables(variables)
|
||||
.withSkills(getSkills())
|
||||
.build();
|
||||
}))
|
||||
.flatMap(
|
||||
newContext -> {
|
||||
SKContext context =
|
||||
SKBuilders.context()
|
||||
.withVariables(newContext.getVariables())
|
||||
.withMemory(newContext.getSemanticMemory())
|
||||
.withSkills(newContext.getSkills())
|
||||
.build();
|
||||
return f.invokeAsync(context, null);
|
||||
});
|
||||
results.add(f.invokeAsync(this, variables, streaming));
|
||||
}
|
||||
|
||||
return pipelineBuilder;
|
||||
return Flux.merge(results)
|
||||
.collectList()
|
||||
.map(DefaultKernelResult::new);
|
||||
}
|
||||
|
||||
public static class Builder implements Kernel.Builder {
|
||||
@@ -464,6 +462,11 @@ public class DefaultKernel implements Kernel {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kernel.Builder withPlugins(Plugin... plugins) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the kernel
|
||||
*
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.microsoft.semantickernel;
|
||||
|
||||
import com.microsoft.semantickernel.KernelResult;
|
||||
import com.microsoft.semantickernel.orchestration.FunctionResult;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class DefaultKernelResult implements KernelResult {
|
||||
private Collection<FunctionResult> results;
|
||||
|
||||
public DefaultKernelResult(Collection<FunctionResult> results) {
|
||||
this.results = results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<FunctionResult> functionResults() {
|
||||
return this.results;
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.functions;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.FunctionResult;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunction;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SemanticFunctionResult implements FunctionResult {
|
||||
private Mono<String> valueAsync;
|
||||
private Flux<String> streamingValueAsync;
|
||||
private boolean isStreaming;
|
||||
private String functionName;
|
||||
private String pluginName;
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
public SemanticFunctionResult() {}
|
||||
|
||||
public SemanticFunctionResult(String pluginName, String functionName, Mono<String> valueAsync) {
|
||||
this.valueAsync = valueAsync;
|
||||
this.pluginName = pluginName;
|
||||
this.functionName = functionName;
|
||||
this.isStreaming = false;
|
||||
}
|
||||
|
||||
public SemanticFunctionResult(String pluginName, String functionName, Mono<String> valueAsync, Flux<String> streamingValueAsync) {
|
||||
this.pluginName = pluginName;
|
||||
this.functionName = functionName;
|
||||
this.valueAsync = valueAsync;
|
||||
this.isStreaming = true;
|
||||
this.streamingValueAsync = streamingValueAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pluginName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> metadata() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<String> getStreamingValueAsync() {
|
||||
return streamingValueAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> getValueAsync() {
|
||||
return valueAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return valueAsync.block();
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -32,8 +32,7 @@ import reactor.core.publisher.Mono;
|
||||
// cref="Action"/>,
|
||||
/// with additional methods required by the kernel.
|
||||
/// </summary>
|
||||
public class DefaultCompletionSKFunction
|
||||
extends DefaultSemanticSKFunction<CompletionRequestSettings>
|
||||
public class DefaultCompletionSKFunction extends DefaultSemanticSKFunction
|
||||
implements CompletionSKFunction {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCompletionSKFunction.class);
|
||||
@@ -138,9 +137,10 @@ public class DefaultCompletionSKFunction
|
||||
.skip(1) // Skip the first element, which is the initial context
|
||||
.concatMap(it -> it);
|
||||
|
||||
// TODO: fix
|
||||
return results.map(
|
||||
result -> {
|
||||
return result.getResult();
|
||||
return (String) result.getResult();
|
||||
})
|
||||
.collect(Collectors.joining("\n"))
|
||||
.map(context::update);
|
||||
@@ -148,8 +148,7 @@ public class DefaultCompletionSKFunction
|
||||
|
||||
// Run the semantic function
|
||||
@Override
|
||||
protected Mono<SKContext> invokeAsyncInternal(
|
||||
SKContext context, @Nullable CompletionRequestSettings settings) {
|
||||
protected Mono<SKContext> invokeAsyncInternal(SKContext context, @Nullable Object settings) {
|
||||
// TODO
|
||||
// this.VerifyIsSemantic();
|
||||
// this.ensureContextHasSkills(context);
|
||||
@@ -167,7 +166,8 @@ public class DefaultCompletionSKFunction
|
||||
throw new IllegalStateException("Failed to initialise aiService");
|
||||
}
|
||||
|
||||
CompletionRequestSettings finalSettings = settings;
|
||||
// TODO: 1.0 fix properly using settings object
|
||||
CompletionRequestSettings finalSettings = new CompletionRequestSettings(0.9, 0, 0, 0, 1000);
|
||||
|
||||
return function.run(this.aiService.get(), finalSettings, context)
|
||||
.map(
|
||||
@@ -257,11 +257,6 @@ public class DefaultCompletionSKFunction
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<CompletionRequestSettings> getType() {
|
||||
return CompletionRequestSettings.class;
|
||||
}
|
||||
|
||||
private static String randomFunctionName() {
|
||||
return "func" + UUID.randomUUID();
|
||||
}
|
||||
@@ -277,6 +272,11 @@ public class DefaultCompletionSKFunction
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<FunctionResult> invokeAsync(Kernel kernel, ContextVariables variables, boolean streaming) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class Builder implements CompletionSKFunction.Builder {
|
||||
|
||||
private Kernel kernel;
|
||||
|
||||
+13
-28
@@ -13,7 +13,7 @@ import reactor.util.annotation.NonNull;
|
||||
/// </summary>
|
||||
class DefaultContextVariables implements ContextVariables, WritableContextVariables {
|
||||
|
||||
private final CaseInsensitiveMap<String> variables;
|
||||
private final CaseInsensitiveMap<Object> variables;
|
||||
|
||||
/// <summary>
|
||||
/// In the simplest scenario, the data is an input string, stored here.
|
||||
@@ -24,37 +24,23 @@ class DefaultContextVariables implements ContextVariables, WritableContextVariab
|
||||
/// Constructor for context variables.
|
||||
/// </summary>
|
||||
/// <param name="content">Optional value for the main variable of the context.</param>
|
||||
DefaultContextVariables(@NonNull String content) {
|
||||
DefaultContextVariables(@NonNull Object content) {
|
||||
this.variables = new CaseInsensitiveMap<>();
|
||||
this.variables.put(MAIN_KEY, content);
|
||||
}
|
||||
|
||||
DefaultContextVariables(Map<String, String> variables) {
|
||||
DefaultContextVariables(Map<String, Object> variables) {
|
||||
this.variables = new CaseInsensitiveMap<>(variables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextVariables setVariable(@NonNull String key, @NonNull String content) {
|
||||
public ContextVariables setVariable(@NonNull String key, @NonNull Object content) {
|
||||
this.variables.put(key, content);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextVariables appendToVariable(@NonNull String key, @NonNull String content) {
|
||||
String existing = this.variables.get(key);
|
||||
|
||||
String newVal;
|
||||
if (existing == null) {
|
||||
newVal = content;
|
||||
} else {
|
||||
newVal = existing + content;
|
||||
}
|
||||
|
||||
return setVariable(key, newVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> asMap() {
|
||||
public Map<String, Object> asMap() {
|
||||
return Collections.unmodifiableMap(variables);
|
||||
}
|
||||
|
||||
@@ -66,7 +52,7 @@ class DefaultContextVariables implements ContextVariables, WritableContextVariab
|
||||
/// if the pipeline reached the end.</param>
|
||||
/// <returns>The current instance</returns>
|
||||
@Override
|
||||
public ContextVariables update(@NonNull String content) {
|
||||
public ContextVariables update(@NonNull Object content) {
|
||||
return setVariable(MAIN_KEY, content);
|
||||
}
|
||||
|
||||
@@ -82,7 +68,6 @@ class DefaultContextVariables implements ContextVariables, WritableContextVariab
|
||||
/// <param name="merge">Whether to merge and keep old data, or replace. False == discard old
|
||||
// data.</param>
|
||||
/// <returns>The current instance</returns>
|
||||
|
||||
@Override
|
||||
public DefaultContextVariables update(@NonNull ContextVariables newData, boolean merge) {
|
||||
/*
|
||||
@@ -112,7 +97,7 @@ class DefaultContextVariables implements ContextVariables, WritableContextVariab
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getInput() {
|
||||
public Object getInput() {
|
||||
return get(MAIN_KEY);
|
||||
}
|
||||
|
||||
@@ -132,28 +117,28 @@ class DefaultContextVariables implements ContextVariables, WritableContextVariab
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String get(String key) {
|
||||
public Object get(String key) {
|
||||
return variables.get(key);
|
||||
}
|
||||
|
||||
public static class WritableBuilder implements WritableContextVariables.Builder {
|
||||
@Override
|
||||
public WritableContextVariables build(Map<String, String> map) {
|
||||
public WritableContextVariables build(Map<String, Object> map) {
|
||||
return new DefaultContextVariables(map);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder implements ContextVariables.Builder {
|
||||
|
||||
private final Map<String, String> variables;
|
||||
private final Map<String, Object> variables;
|
||||
|
||||
public Builder() {
|
||||
variables = new CaseInsensitiveMap<>();
|
||||
this.variables.put(MAIN_KEY, "");
|
||||
// this.variables.put(MAIN_KEY, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextVariables.Builder withVariable(String key, String value) {
|
||||
public ContextVariables.Builder withVariable(String key, Object value) {
|
||||
variables.put(key, value);
|
||||
return this;
|
||||
}
|
||||
@@ -165,7 +150,7 @@ class DefaultContextVariables implements ContextVariables, WritableContextVariab
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder withVariables(Map<String, String> map) {
|
||||
public Builder withVariables(Map<String, Object> map) {
|
||||
variables.putAll(map);
|
||||
return this;
|
||||
}
|
||||
|
||||
+5
@@ -37,6 +37,11 @@ public class DefaultSKContext extends AbstractSKContext {
|
||||
return new DefaultSKContext(variables, memory, skillCollection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SKContext appendToVariable(String key, String content) {
|
||||
throw new RuntimeException("Append no longer supported in objects");
|
||||
}
|
||||
|
||||
public static class Builder implements SKContext.Builder {
|
||||
|
||||
private ContextVariables variables;
|
||||
|
||||
+2
-6
@@ -16,9 +16,7 @@ import reactor.core.publisher.Mono;
|
||||
// cref="Action"/>,
|
||||
/// with additional methods required by the kernel.
|
||||
/// </summary>
|
||||
public abstract class DefaultSemanticSKFunction<RequestConfiguration>
|
||||
extends AbstractSkFunction<RequestConfiguration>
|
||||
implements SKFunction<RequestConfiguration> {
|
||||
public abstract class DefaultSemanticSKFunction extends AbstractSKFunction implements SKFunction {
|
||||
|
||||
public DefaultSemanticSKFunction(
|
||||
List<ParameterView> parameters,
|
||||
@@ -37,9 +35,7 @@ public abstract class DefaultSemanticSKFunction<RequestConfiguration>
|
||||
|
||||
@Override
|
||||
public Mono<SKContext> invokeAsync(
|
||||
@Nullable String input,
|
||||
@Nullable SKContext context,
|
||||
@Nullable RequestConfiguration settings) {
|
||||
@Nullable String input, @Nullable SKContext context, @Nullable Object settings) {
|
||||
if (context == null) {
|
||||
assertSkillSupplierRegistered();
|
||||
context =
|
||||
|
||||
+7
-6
@@ -40,7 +40,7 @@ import reactor.core.scheduler.Schedulers;
|
||||
// cref="Action"/>,
|
||||
/// with additional methods required by the kernel.
|
||||
/// </summary>
|
||||
public class NativeSKFunction extends AbstractSkFunction<Void> {
|
||||
public class NativeSKFunction extends AbstractSKFunction {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NativeSKFunction.class);
|
||||
|
||||
@@ -76,8 +76,8 @@ public class NativeSKFunction extends AbstractSkFunction<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Void> getType() {
|
||||
return Void.class;
|
||||
public Mono<FunctionResult> invokeAsync(Kernel kernel, ContextVariables variables, boolean streaming) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,7 +152,7 @@ public class NativeSKFunction extends AbstractSkFunction<Void> {
|
||||
|
||||
// Run the native function
|
||||
@Override
|
||||
protected Mono<SKContext> invokeAsyncInternal(SKContext context, @Nullable Void settings) {
|
||||
protected Mono<SKContext> invokeAsyncInternal(SKContext context, @Nullable Object settings) {
|
||||
return this.function.run(context);
|
||||
}
|
||||
|
||||
@@ -352,11 +352,12 @@ public class NativeSKFunction extends AbstractSkFunction<Void> {
|
||||
Method method, SKContext context, Parameter parameter, Set<Parameter> inputArgs) {
|
||||
String variableName = getGetVariableName(parameter);
|
||||
|
||||
String arg = context.getVariables().get(variableName);
|
||||
// TODO: 1.0 fix cast
|
||||
String arg = (String) context.getVariables().get(variableName);
|
||||
if (arg == null) {
|
||||
// If this is bound to input get the input value
|
||||
if (inputArgs.contains(parameter)) {
|
||||
String input = context.getVariables().get(ContextVariables.MAIN_KEY);
|
||||
String input = (String) context.getVariables().get(ContextVariables.MAIN_KEY);
|
||||
if (input != null) {
|
||||
arg = input;
|
||||
}
|
||||
|
||||
+6
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.semanticfunctions;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.ParameterView;
|
||||
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
|
||||
@@ -68,6 +69,11 @@ public class DefaultPromptTemplate implements PromptTemplate {
|
||||
return templateEngine.renderAsync(this.promptTemplate, executionContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> renderAsync(ContextVariables variables) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final class Builder implements PromptTemplate.Builder {
|
||||
@Nullable private String promptTemplate = null;
|
||||
@Nullable private PromptTemplateConfig config = null;
|
||||
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.semanticfunctions;
|
||||
|
||||
import com.azure.core.exception.HttpResponseException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.builders.Buildable;
|
||||
import com.microsoft.semantickernel.functions.SemanticFunctionResult;
|
||||
import com.microsoft.semantickernel.orchestration.*;
|
||||
import com.microsoft.semantickernel.skilldefinition.FunctionView;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionRequestSettings;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class SemanticFunction extends DefaultSemanticSKFunction {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCompletionSKFunction.class);
|
||||
private String name;
|
||||
private String pluginName;
|
||||
private String description;
|
||||
private List<SemanticFunctionModel.ExecutionSettingsModel> executionSettings;
|
||||
private List<SemanticFunctionModel.VariableViewModel> inputParameters;
|
||||
private PromptTemplate promptTemplate;
|
||||
|
||||
public SemanticFunction(
|
||||
String name,
|
||||
String pluginName,
|
||||
String description,
|
||||
List<SemanticFunctionModel.ExecutionSettingsModel> executionSettings,
|
||||
PromptTemplate promptTemplate,
|
||||
List<SemanticFunctionModel.VariableViewModel> inputParameters) {
|
||||
super(Collections.emptyList(), name, name, description, null);
|
||||
this.name = name;
|
||||
this.pluginName = pluginName;
|
||||
this.description = description;
|
||||
this.executionSettings = executionSettings;
|
||||
this.promptTemplate = promptTemplate;
|
||||
this.inputParameters = inputParameters;
|
||||
}
|
||||
|
||||
public static SemanticFunction fromYaml(String filePath) throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
|
||||
InputStream inputStream =
|
||||
SemanticFunction.class.getClassLoader().getResourceAsStream(filePath);
|
||||
|
||||
SemanticFunctionModel functionModel =
|
||||
mapper.readValue(inputStream, SemanticFunctionModel.class);
|
||||
|
||||
return new Builder()
|
||||
.withName(functionModel.getName())
|
||||
.withInputParameters(functionModel.getInputVariables())
|
||||
.withPromptTemplate(
|
||||
new HandlebarsPromptTemplate(
|
||||
functionModel.getTemplate(), new HandlebarsPromptTemplateEngine()))
|
||||
.withPluginName(functionModel.getName()) // TODO: 1.0 add plugin name
|
||||
.withExecutionSettings(functionModel.getExecutionSettings())
|
||||
.withDescription(functionModel.getDescription())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<FunctionResult> invokeAsync(Kernel kernel, ContextVariables input, boolean streaming) {
|
||||
TextCompletion client = kernel.getService(null, TextCompletion.class);
|
||||
if (client == null) {
|
||||
throw new IllegalStateException("Failed to initialise aiService");
|
||||
}
|
||||
|
||||
// TODO: 1.0 check model pattern Id to select execution settings
|
||||
SemanticFunctionModel.ExecutionSettingsModel executionSettingsModel =
|
||||
this.executionSettings.get(0);
|
||||
|
||||
// TODO: 1.0 fix settings
|
||||
CompletionRequestSettings requestSettings = new CompletionRequestSettings(
|
||||
Double.valueOf(executionSettingsModel.getTemperature()), 0, 0, 0, 1000);
|
||||
|
||||
return this.promptTemplate
|
||||
.renderAsync(input)
|
||||
.flatMap(
|
||||
prompt ->
|
||||
performCompletionRequest(
|
||||
client, requestSettings, prompt ,streaming))
|
||||
.doOnError(
|
||||
ex -> {
|
||||
LOGGER.warn(
|
||||
"Something went wrong while rendering the semantic"
|
||||
+ " function or while executing the text"
|
||||
+ " completion. Function: {}.{}. Error: {}",
|
||||
getSkillName(),
|
||||
getName(),
|
||||
ex.getMessage());
|
||||
|
||||
// Common message when you attempt to send text completion
|
||||
// requests to a chat completion model:
|
||||
// "logprobs, best_of and echo parameters are not
|
||||
// available on gpt-35-turbo model"
|
||||
if (ex instanceof HttpResponseException
|
||||
&& ((HttpResponseException) ex)
|
||||
.getResponse()
|
||||
.getStatusCode()
|
||||
== 400
|
||||
&& ex.getMessage()
|
||||
.contains(
|
||||
"parameters are not available"
|
||||
+ " on")) {
|
||||
LOGGER.warn(
|
||||
"This error indicates that you have attempted"
|
||||
+ " to use a chat completion model in a"
|
||||
+ " text completion service. Try using a"
|
||||
+ " chat completion service instead when"
|
||||
+ " building your kernel, for instance when"
|
||||
+ " building your service use"
|
||||
+ " SKBuilders.chatCompletion() rather than"
|
||||
+ " SKBuilders.textCompletionService().");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<FunctionResult> performCompletionRequest(
|
||||
TextCompletion client, CompletionRequestSettings requestSettings, String prompt, boolean streaming) {
|
||||
|
||||
LOGGER.info("RENDERED PROMPT: \n{}", prompt);
|
||||
|
||||
if (streaming) {
|
||||
Flux<String> completionStream = client.completeStreamAsync(prompt, requestSettings);
|
||||
|
||||
return Mono.just(new SemanticFunctionResult(pluginName, name, completionStream.reduce(String::concat), completionStream));
|
||||
} else {
|
||||
Mono<String> completion = client.completeAsync(prompt, requestSettings)
|
||||
.map(list -> list.isEmpty() ? null : list.get(0));
|
||||
|
||||
return Mono.just(new SemanticFunctionResult(pluginName, name, completion));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FunctionView describe() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mono<SKContext> invokeAsyncInternal(SKContext context, @Nullable Object settings) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOnKernel(Kernel kernel) {
|
||||
|
||||
}
|
||||
|
||||
public static class Builder implements Buildable {
|
||||
private String name;
|
||||
private String pluginName;
|
||||
private String description;
|
||||
private List<SemanticFunctionModel.ExecutionSettingsModel> executionSettings;
|
||||
private PromptTemplate promptTemplate;
|
||||
private List<SemanticFunctionModel.VariableViewModel> inputParameters;
|
||||
|
||||
public Builder withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withPluginName(String pluginName) {
|
||||
this.pluginName = pluginName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withExecutionSettings(
|
||||
List<SemanticFunctionModel.ExecutionSettingsModel> executionSettings) {
|
||||
this.executionSettings = executionSettings;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withPromptTemplate(PromptTemplate promptTemplate) {
|
||||
this.promptTemplate = promptTemplate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withInputParameters(
|
||||
List<SemanticFunctionModel.VariableViewModel> inputParameters) {
|
||||
this.inputParameters = inputParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SemanticFunction build() {
|
||||
return new SemanticFunction(
|
||||
name,
|
||||
pluginName,
|
||||
description,
|
||||
executionSettings,
|
||||
promptTemplate,
|
||||
inputParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.semanticfunctions;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SemanticFunctionModel {
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("template")
|
||||
private String template;
|
||||
|
||||
@JsonProperty("template_format")
|
||||
private String templateFormat;
|
||||
|
||||
@JsonProperty("description")
|
||||
private String description;
|
||||
|
||||
@JsonProperty("input_variables")
|
||||
private List<VariableViewModel> inputVariables;
|
||||
|
||||
@JsonProperty("output_variable")
|
||||
private VariableViewModel outputVariable;
|
||||
|
||||
@JsonProperty("execution_settings")
|
||||
private List<ExecutionSettingsModel> executionSettings;
|
||||
|
||||
public SemanticFunctionModel() {}
|
||||
|
||||
public SemanticFunctionModel(
|
||||
String name,
|
||||
String template,
|
||||
String templateFormat,
|
||||
String description,
|
||||
List<VariableViewModel> inputVariables,
|
||||
VariableViewModel outputVariable,
|
||||
List<ExecutionSettingsModel> executionSettings) {
|
||||
this.name = name;
|
||||
this.template = template;
|
||||
this.templateFormat = templateFormat;
|
||||
this.description = description;
|
||||
this.inputVariables = inputVariables;
|
||||
this.outputVariable = outputVariable;
|
||||
this.executionSettings = executionSettings;
|
||||
}
|
||||
|
||||
public static class VariableViewModel {
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("type")
|
||||
private String type;
|
||||
|
||||
@JsonProperty("description")
|
||||
private String description;
|
||||
|
||||
@JsonProperty("default_value")
|
||||
private Object defaultValue;
|
||||
|
||||
@JsonProperty("is_required")
|
||||
private boolean isRequired;
|
||||
|
||||
public VariableViewModel() {}
|
||||
|
||||
public VariableViewModel(
|
||||
String name,
|
||||
String type,
|
||||
String description,
|
||||
Object defaultValue,
|
||||
boolean isRequired) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.description = description;
|
||||
this.defaultValue = defaultValue;
|
||||
this.isRequired = isRequired;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Object getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDefaultValue(Object defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return isRequired;
|
||||
}
|
||||
|
||||
public void setRequired(boolean required) {
|
||||
isRequired = required;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExecutionSettingsModel {
|
||||
@JsonProperty("model_id")
|
||||
private String modelId;
|
||||
|
||||
@JsonProperty("model_id_pattern")
|
||||
private String modelIdPattern;
|
||||
|
||||
@JsonProperty("service_id")
|
||||
private String serviceId;
|
||||
|
||||
@JsonProperty("temperature")
|
||||
private String temperature;
|
||||
|
||||
@JsonProperty("additional_properties")
|
||||
private final Map<String, Object> additionalProperties;
|
||||
|
||||
public Object get(String propertyName) {
|
||||
return additionalProperties.get(propertyName);
|
||||
}
|
||||
|
||||
public void set(String propertyName, Object value) {
|
||||
additionalProperties.put(propertyName, value);
|
||||
}
|
||||
|
||||
public ExecutionSettingsModel() {
|
||||
this.additionalProperties = new HashMap<>();
|
||||
}
|
||||
|
||||
public ExecutionSettingsModel(
|
||||
String modelId,
|
||||
String modelIdPattern,
|
||||
String serviceId,
|
||||
String temperature,
|
||||
Map<String, Object> additionalProperties) {
|
||||
this.modelId = modelId;
|
||||
this.modelIdPattern = modelIdPattern;
|
||||
this.serviceId = serviceId;
|
||||
this.temperature = temperature;
|
||||
this.additionalProperties = additionalProperties;
|
||||
}
|
||||
|
||||
public String getModelId() {
|
||||
return modelId;
|
||||
}
|
||||
|
||||
public void setModelId(String modelId) {
|
||||
this.modelId = modelId;
|
||||
}
|
||||
|
||||
public String getModelIdPattern() {
|
||||
return modelIdPattern;
|
||||
}
|
||||
|
||||
public void setModelIdPattern(String modelIdPattern) {
|
||||
this.modelIdPattern = modelIdPattern;
|
||||
}
|
||||
|
||||
public String getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
public void setServiceId(String serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
public String getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
public void setTemperature(String temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return additionalProperties;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public void setTemplate(String template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public String getTemplateFormat() {
|
||||
return templateFormat;
|
||||
}
|
||||
|
||||
public void setTemplateFormat(String templateFormat) {
|
||||
this.templateFormat = templateFormat;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public List<VariableViewModel> getInputVariables() {
|
||||
return inputVariables;
|
||||
}
|
||||
|
||||
public void setInputVariables(List<VariableViewModel> inputVariables) {
|
||||
this.inputVariables = inputVariables;
|
||||
}
|
||||
|
||||
public VariableViewModel getOutputVariable() {
|
||||
return outputVariable;
|
||||
}
|
||||
|
||||
public void setOutputVariable(VariableViewModel outputVariable) {
|
||||
this.outputVariable = outputVariable;
|
||||
}
|
||||
|
||||
public List<ExecutionSettingsModel> getExecutionSettings() {
|
||||
return executionSettings;
|
||||
}
|
||||
|
||||
public void setExecutionSettings(List<ExecutionSettingsModel> executionSettings) {
|
||||
this.executionSettings = executionSettings;
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -75,14 +75,13 @@ public class DefaultSkillCollection implements ReadOnlySkillCollection {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends SKFunction<?>> T getFunction(
|
||||
String funName, @Nullable Class<T> functionClazz) {
|
||||
public <T extends SKFunction> T getFunction(String funName, @Nullable Class<T> functionClazz) {
|
||||
return getFunction(GlobalSkill, funName, functionClazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends SKFunction<?>> T getFunction(
|
||||
public <T extends SKFunction> T getFunction(
|
||||
String skillName, String funName, @Nullable Class<T> functionClazz) {
|
||||
FunctionCollection skills = skillCollection.get(skillName.toLowerCase(Locale.ROOT));
|
||||
if (skills == null) {
|
||||
|
||||
+9
-9
@@ -15,16 +15,16 @@ import javax.annotation.Nullable;
|
||||
|
||||
/** A collection of functions. */
|
||||
public class FunctionCollection implements ReadOnlyFunctionCollection {
|
||||
private final CaseInsensitiveMap<SKFunction<?>> functionCollection;
|
||||
private final CaseInsensitiveMap<SKFunction> functionCollection;
|
||||
|
||||
private final String skillName;
|
||||
|
||||
private FunctionCollection(String skillName, Map<String, SKFunction<?>> functionCollection) {
|
||||
private FunctionCollection(String skillName, Map<String, SKFunction> functionCollection) {
|
||||
this.functionCollection = new CaseInsensitiveMap<>(functionCollection);
|
||||
this.skillName = skillName;
|
||||
}
|
||||
|
||||
public FunctionCollection(String skillName, List<? extends SKFunction<?>> functionCollection) {
|
||||
public FunctionCollection(String skillName, List<? extends SKFunction> functionCollection) {
|
||||
this(
|
||||
skillName,
|
||||
functionCollection.stream()
|
||||
@@ -41,7 +41,7 @@ public class FunctionCollection implements ReadOnlyFunctionCollection {
|
||||
public FunctionCollection(ReadOnlyFunctionCollection value) {
|
||||
this.skillName = value.getSkillName();
|
||||
this.functionCollection =
|
||||
new CaseInsensitiveMap<SKFunction<?>>(
|
||||
new CaseInsensitiveMap<SKFunction>(
|
||||
Collections.unmodifiableMap(
|
||||
value.getAll().stream()
|
||||
.collect(Collectors.toMap(SKFunction::getName, it -> it))));
|
||||
@@ -53,8 +53,8 @@ public class FunctionCollection implements ReadOnlyFunctionCollection {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SKFunction<?> getFunction(String functionName) {
|
||||
SKFunction<?> func = functionCollection.get(functionName.toLowerCase(Locale.ROOT));
|
||||
public SKFunction getFunction(String functionName) {
|
||||
SKFunction func = functionCollection.get(functionName.toLowerCase(Locale.ROOT));
|
||||
if (func == null) {
|
||||
throw new FunctionNotFound(
|
||||
FunctionNotFound.ErrorCodes.FUNCTION_NOT_FOUND, functionName);
|
||||
@@ -73,7 +73,7 @@ public class FunctionCollection implements ReadOnlyFunctionCollection {
|
||||
*/
|
||||
@Override
|
||||
public <T extends SKFunction> T getFunction(String functionName, @Nullable Class<T> clazz) {
|
||||
SKFunction<?> func = getFunction(functionName);
|
||||
SKFunction func = getFunction(functionName);
|
||||
if (clazz == null) {
|
||||
return (T) func;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class FunctionCollection implements ReadOnlyFunctionCollection {
|
||||
* @return An unmodifiable list of all functions
|
||||
*/
|
||||
@Override
|
||||
public List<SKFunction<?>> getAll() {
|
||||
public List<SKFunction> getAll() {
|
||||
return Collections.unmodifiableList(new ArrayList<>(functionCollection.values()));
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public class FunctionCollection implements ReadOnlyFunctionCollection {
|
||||
* @param functionInstance
|
||||
* @return Collection for fluent callse
|
||||
*/
|
||||
public FunctionCollection put(String functionName, SKFunction<?> functionInstance) {
|
||||
public FunctionCollection put(String functionName, SKFunction functionInstance) {
|
||||
this.functionCollection.put(functionName.toLowerCase(Locale.ROOT), functionInstance);
|
||||
return this;
|
||||
}
|
||||
|
||||
+7
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.templateengine;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.templateengine.blocks.Block;
|
||||
import com.microsoft.semantickernel.templateengine.blocks.CodeRendering;
|
||||
@@ -62,6 +63,12 @@ public class DefaultPromptTemplateEngine implements PromptTemplateEngine {
|
||||
return this.renderAsync(blocks, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> renderAsync(String templateText, ContextVariables variables) {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Mono<String> renderAsync(List<Block> blocks, SKContext context) {
|
||||
return Flux.fromIterable(blocks)
|
||||
|
||||
+3
-2
@@ -107,9 +107,10 @@ public final class CodeBlock extends Block implements CodeRendering {
|
||||
function.invokeWithCustomInputAsync(
|
||||
variables, context.getSemanticMemory(), context.getSkills());
|
||||
|
||||
// TODO: 1.0 fix cast
|
||||
return result.map(
|
||||
it -> {
|
||||
return it.getResult();
|
||||
return (String) it.getResult();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -120,7 +121,7 @@ public final class CodeBlock extends Block implements CodeRendering {
|
||||
// Function in the global skill
|
||||
if ((skillName == null || skillName.isEmpty())
|
||||
&& skills.hasFunction(fBlock.getFunctionName())) {
|
||||
SKFunction<?> function = skills.getFunction(fBlock.getFunctionName(), SKFunction.class);
|
||||
SKFunction function = skills.getFunction(fBlock.getFunctionName(), SKFunction.class);
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -33,7 +33,8 @@ public final class VarBlock extends Block implements TextRendering {
|
||||
"Variable rendering failed, the variable name is empty");
|
||||
}
|
||||
|
||||
String value = variables.asMap().get(name);
|
||||
// TODO: 1.0 fix cast
|
||||
String value = (String) variables.asMap().get(name);
|
||||
|
||||
if (value == null) {
|
||||
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.templateengine.handlebars;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplate;
|
||||
import com.microsoft.semantickernel.skilldefinition.ParameterView;
|
||||
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
|
||||
import java.util.List;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class HandlebarsPromptTemplate implements PromptTemplate {
|
||||
private String promptTemplate;
|
||||
private HandlebarsPromptTemplateEngine templateEngine;
|
||||
|
||||
public HandlebarsPromptTemplate(String promptTemplate, PromptTemplateEngine templateEngine) {
|
||||
this.promptTemplate = promptTemplate;
|
||||
this.templateEngine = (HandlebarsPromptTemplateEngine) templateEngine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ParameterView> getParameters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> renderAsync(SKContext skContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> renderAsync(ContextVariables variables) {
|
||||
return templateEngine.renderAsync(this.promptTemplate, variables);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.templateengine.handlebars;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.jknack.handlebars.Context;
|
||||
import com.github.jknack.handlebars.Handlebars;
|
||||
import com.github.jknack.handlebars.Helper;
|
||||
import com.github.jknack.handlebars.Options;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.templateengine.blocks.Block;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class HandlebarsPromptTemplateEngine implements PromptTemplateEngine {
|
||||
|
||||
@Override
|
||||
public Mono<String> renderAsync(String s, SKContext skContext) {
|
||||
throw new RuntimeException("SKContext not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Block> extractBlocks(String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> renderAsync(String promptTemplate, ContextVariables variables) {
|
||||
HandleBarsPromptTemplateHandler handler =
|
||||
new HandleBarsPromptTemplateHandler(promptTemplate);
|
||||
|
||||
return handler.render(variables);
|
||||
}
|
||||
|
||||
public static class HandleBarsPromptTemplateHandler {
|
||||
private final String template;
|
||||
private final Handlebars handlebars;
|
||||
|
||||
public HandleBarsPromptTemplateHandler(String template) {
|
||||
this.template = template;
|
||||
this.handlebars = new Handlebars();
|
||||
this.handlebars.registerHelper(
|
||||
"message",
|
||||
new Helper<Object>() {
|
||||
@Override
|
||||
public Object apply(Object context, Options options) throws IOException {
|
||||
String role = options.hash("role");
|
||||
String content = (String) options.fn(context);
|
||||
|
||||
// when message is inside a loop Context is Optional<ChatHistory.Message>
|
||||
// when message is not inside a loop Context is the UnmodifiableMap<String, Object> with all the variables
|
||||
if (context instanceof Optional) {
|
||||
ChatHistory.Message message = ((Optional<ChatHistory.Message>) context).orElse(null);
|
||||
if (role == null || role.isEmpty()) {
|
||||
role = message.getAuthorRoles()
|
||||
.toString()
|
||||
.toLowerCase();
|
||||
}
|
||||
content = message.getContent();
|
||||
}
|
||||
|
||||
if (role != null && !role.isEmpty()) {
|
||||
return new Handlebars.SafeString(
|
||||
String.format(
|
||||
"<message role=\"%s\">%s</message>",
|
||||
role, content));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: 1.0 Add more helpers
|
||||
}
|
||||
|
||||
public Mono<String> render(ContextVariables variables) {
|
||||
try {
|
||||
String result = handlebars.compileInline(template).apply(variables.asMap());
|
||||
return Mono.just(result);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -48,8 +48,8 @@ public class NativeSKFunctionTest {
|
||||
FunctionCollection skills =
|
||||
SkillImporter.importSkill(skill, "test", DefaultSkillCollection::new);
|
||||
ContextVariables variables = SKBuilders.variables().build();
|
||||
variables = variables.writableClone().appendToVariable("input", "foo");
|
||||
variables = variables.writableClone().appendToVariable("secondInput", "ignore");
|
||||
variables = variables.writableClone().setVariable("input", "foo");
|
||||
variables = variables.writableClone().setVariable("secondInput", "ignore");
|
||||
skills.getFunction("doSomething").invokeWithCustomInputAsync(variables, null, null).block();
|
||||
Mockito.verify(skill, Mockito.times(1)).doSomething("foo", "ignore");
|
||||
}
|
||||
@@ -68,8 +68,8 @@ public class NativeSKFunctionTest {
|
||||
FunctionCollection skills =
|
||||
SkillImporter.importSkill(skill, "test", DefaultSkillCollection::new);
|
||||
ContextVariables variables = SKBuilders.variables().build();
|
||||
variables = variables.writableClone().appendToVariable("anInput", "foo");
|
||||
variables = variables.writableClone().appendToVariable("secondInput", "ignore");
|
||||
variables = variables.writableClone().setVariable("anInput", "foo");
|
||||
variables = variables.writableClone().setVariable("secondInput", "ignore");
|
||||
skills.getFunction("doSomething").invokeWithCustomInputAsync(variables, null, null).block();
|
||||
Mockito.verify(skill, Mockito.times(1)).doSomething("foo", "ignore");
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class NativeSKFunctionTest {
|
||||
FunctionCollection skills =
|
||||
SkillImporter.importSkill(skill, "test", DefaultSkillCollection::new);
|
||||
ContextVariables variables =
|
||||
SKBuilders.variables().build().writableClone().appendToVariable("input", "foo");
|
||||
SKBuilders.variables().build().writableClone().setVariable("input", "foo");
|
||||
Assertions.assertThrows(
|
||||
AIException.class,
|
||||
() -> {
|
||||
|
||||
Reference in New Issue
Block a user